add sources

This commit is contained in:
Alexander Zhirov 2023-02-26 01:19:12 +03:00
parent fcd25eea52
commit 7ce631a648
21 changed files with 548 additions and 2 deletions

View file

@ -0,0 +1,33 @@
bool find1(int[] haystack, int needle)
{
foreach (v; haystack)
{
if (v == needle)
{
return true;
}
}
return false;
}
int[] find2(int[] haystack, int needle)
{
while (haystack.length > 0 && haystack[0] != needle)
{
haystack = haystack[1 .. $];
}
return haystack;
}
unittest
{
int[] a = [];
assert(find2(a, 5) == []);
a = [ 1, 2, 3 ];
assert(find2(a, 0) == []);
assert(find2(a, 1).length == 3);
assert(find2(a, 2).length == 2);
assert(a[0 .. $ - find2(a, 3).length] == [ 1, 2 ]);
}

View file

@ -0,0 +1,21 @@
import std.conv;
import std.stdio : stdout;
void write(T...)(T args)
{
foreach (arg; args)
{
stdout.rawWrite(to!string(arg));
}
}
void writeln(T...)(T args)
{
write(args, '\n');
stdout.flush();
}
void main()
{
writeln(5, "здравствуй", 4.2);
}

View file

@ -0,0 +1,19 @@
import std.stdio, std.typecons;
void fun(T...)(T args)
{
// Создать кортеж, чтобы "упаковать" все аргументы в одно значение
gun(tuple(args));
}
void gun(T)(T value)
{
// Расширить кортеж и получить исходное множество параметров
writeln(value.expand);
}
void main()
{
fun(1); // Все в порядке
fun(1, 2.2); // Все в порядке
}

View file

@ -0,0 +1,16 @@
import std.stdio;
void testing(T...)(T values)
{
writeln("Переданных аргументов: ", values.length, ".");
// Обращение к каждому индексу и каждому значению
foreach (i, value; values)
{
writeln(i, ": ", typeid(T[i]), " ", value);
}
}
void main()
{
testing(5, "здравствуй", 4.2);
}

View file

@ -0,0 +1,34 @@
import core.stdc.stdarg, std.conv;
extern(C) string cToString(string type, ...)
{
va_list args_list;
va_start(args_list, type);
scope(exit) va_end(args_list);
switch (type)
{
case "int":
auto int_val = va_arg!int(args_list);
return to!string(int_val);
case "double":
auto double_val = va_arg!double(args_list);
return to!string(double_val);
case "complex":
auto re_val = va_arg!double(args_list);
auto im_val = va_arg!double(args_list);
return to!string(re_val) ~ " + " ~ to!string(im_val) ~ "i";
case "string":
return va_arg!string(args_list);
default:
assert(0, "Незнакомый тип");
}
}
unittest
{
assert(cToString("int", 5) == "5");
assert(cToString("double", 2.0) == "2");
assert(cToString("string", "Test string") == "Test string");
assert(cToString("complex", 3.5, 2.7) == "3.5 + 2.7i");
}

View file

@ -0,0 +1,68 @@
import core.stdc.stdarg, std.conv;
string dToString(string type, ...)
{
va_list args_list;
va_copy(args_list, _argptr);
scope(exit) va_end(args_list);
switch (type) {
case "int":
assert(_arguments.length == 1 && _arguments[0] is typeid(int), "Аргумент должен иметь тип int.");
auto int_val = va_arg!int(args_list);
return to!string(int_val);
case "double":
assert(_arguments.length == 1 && _arguments[0] is typeid(double), "Аргумент должен иметь тип double.");
auto double_val = va_arg!double(args_list);
return to!string(double_val);
case "complex":
assert(_arguments.length == 2 && _arguments[0] is typeid(double) && _arguments[1] is typeid(double), "Для типа complex должны быть переданы два аргумента типа double.");
auto re_val = va_arg!double(args_list);
auto im_val = va_arg!double(args_list);
return to!string(re_val) ~ " + " ~ to!string(im_val) ~ "i";
case "string":
assert(_arguments.length == 1 && _arguments[0] is typeid(string), "Аргумент должен иметь тип string.");
return va_arg!string(args_list).idup;
default:
assert(0);
}
}
unittest
{
assert(dToString("int", 5) == "5");
assert(dToString("double", 2.0) == "2");
assert(dToString("string", "Test string") == "Test string");
assert(dToString("complex", 3.5, 2.7) == "3.5 + 2.7i");
}
import std.stdio, std.variant;
void pseudoVariadic(Variant[] vars)
{
foreach (var; vars)
{
if (var.type == typeid(string))
{
writeln("Строка: ", var.get!string);
}
else if (var.type == typeid(int))
{
writeln("Целое число: ", var.get!int);
}
else
{
writeln("Незнакомый тип: ", var.type);
}
}
}
void templatedVariadic(T...)(T args)
{
pseudoVariadic(variantArray(args));
}
void main()
{
templatedVariadic("Здравствуй, мир!", 42);
}

View file

@ -0,0 +1,32 @@
import std.stdio;
ulong fib1(uint n)
{
return n < 2 ? n : fib1(n - 1) + fib1(n - 2);
}
ulong fib2(uint n)
{
ulong iter(uint i, ulong fib_1, ulong fib_2)
{
return i == n ? fib_2 : iter(i + 1, fib_1 + fib_2, fib_1);
}
return iter(0, 1, 0);
}
pure ulong fib3(uint n)
{
ulong fib_1 = 1, fib_2 = 0;
foreach (i; 0 .. n)
{
auto t = fib_1;
fib_1 += fib_2;
fib_2 = t;
}
return fib_2;
}
void main()
{
writeln(fib3(40));
}

View file

@ -0,0 +1,16 @@
import std.stdio;
pure bool leapYear(uint y)
{
return (y % 4) == 0 && (y % 100 || (y % 400) == 0);
}
pure uint daysInYear(uint y)
{
return 365 + leapYear(y);
}
void main()
{
writeln(daysInYear(2022));
}

View file

@ -0,0 +1,11 @@
ref int bump(ref int x)
{
return ++x;
}
unittest
{
int x = 1;
bump(bump(x)); // Два увеличения на 1
assert(x == 3);
}

View file

@ -0,0 +1,16 @@
// Вы­чис­ля­ет ча­ст­ное и ос­та­ток от де­ле­ния для ар­гу­мен­тов a и b.
// Воз­вра­ща­ет ча­ст­ное по зна­че­нию, а ос­та­ток в па­ра­мет­ре rem.
int divrem(int a, int b, out int rem)
{
assert(b != 0);
rem = a % b;
return a / b;
}
unittest
{
int r;
int d = divrem(5, 2, r);
assert(d == 2 && r == 1);
}

View file

@ -0,0 +1,26 @@
void fun(int x)
{
x += 42;
}
void gun(int[] x)
{
x = [ 1, 2, 3 ];
}
void hun(int[] x)
{
x[0] = x[1];
}
unittest
{
int x = 10;
fun(x);
assert(x == 10); // Ничего не изменилось
int[] y = [ 10, 20, 30 ];
gun(y);
assert(y == [ 10, 20, 30 ]); // Ничего не изменилось
hun(y);
assert(y == [ 20, 20, 30 ]); // Изменилось!
}

View file

@ -0,0 +1,18 @@
T[] find(T)(T[] haystack, T needle)
{
while (haystack.length > 0 && haystack[0] != needle)
{
haystack = haystack[1 .. $];
}
return haystack;
}
unittest
{
// Проверка способностей к обобщению
double[] d = [ 1.5, 2.4 ];
assert(find(d, 1.0) == null);
assert(find(d, 1.5) == d);
string[] s = [ "one", "two" ];
assert(find(s, "two") == [ "two" ]);
}

View file

@ -0,0 +1,15 @@
T[] find(T, E)(T[] haystack, E needle)
if (is(typeof(haystack[0] != needle) == bool))
{
while (haystack.length > 0 && haystack[0] != needle)
{
haystack = haystack[1 .. $];
}
return haystack;
}
unittest
{
// assert(find([1, 2, 3], "Hello"));
assert(find([1, 2, 3], 1.0));
}

View file

@ -0,0 +1,27 @@
import std.stdio;
void transmogrify(uint value)
{
writeln("Вызов функции с uint: ", value);
}
void transmogrify(long value)
{
writeln("Вызов функции с long: ", value);
}
void transmogrify(T)(T value)
{
writeln("Вызов функции с T: ", value);
}
unittest
{
transmogrify(42); // Вы­зы­ва­ет transmogrify(uint)
transmogrify("hello"); // Вы­зы­ва­ет transmogrify(T), T=string
transmogrify(1.1); // Вы­зы­ва­ет transmogrify(T), T=double
// Вызов функции с uint: 42
// Вызов функции с T: hello
// Вызов функции с T: 1.1
}

View file

@ -0,0 +1,20 @@
T1[] find(T1, T2)(T1[] longer, T2[] shorter)
if (is(typeof(longer[0 .. 1] == shorter) : bool))
{
while (longer.length >= shorter.length)
{
if (longer[0 .. shorter.length] == shorter)
{
break;
}
longer = longer[1 .. $];
}
return longer;
}
unittest
{
double[] d1 = [ 6.0, 1.5, 2.25, 3 ];
float[] d2 = [ 1.5, 2.25 ];
assert(find(d1, d2) == d1[1 .. $]);
}

View file

@ -0,0 +1,24 @@
import std.stdio;
T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0])) break;
}
return input;
}
unittest
{
int[] a = [ 1, 2, 3, 4, -5, 3, -4 ];
// Найти первое отрицательное число
auto b = find!(function bool(int x) { return x < 0; })(a).dup;
writeln(b);
auto c = find!((x) { return x > 0; })(b);
writeln(c);
string[] str = ["one", "two", "ab", "three", "four"];
auto d = find!((x) { return x.length == 2; })(str);
writeln(d);
}

View file

@ -0,0 +1,34 @@
import std.stdio;
T[] find(alias pred, T)(T[] input)
if (is(typeof(pred(input[0])) == bool))
{
for (; input.length > 0; input = input[1 .. $])
{
if (pred(input[0])) break;
}
return input;
}
unittest
{
int zero = 0;
bool isTypeLow(int x)
{
return x < zero;
}
static bool isTypeBig(int x)
{
// Из-за static zero не будет видно внутри функции
return x > zero;
}
int[] a = [ 1, 2, 3, 4, -5, 3, -4 ];
// Найти первое отрицательное число
auto b = find!(isTypeLow)(a).dup;
writeln(b);
auto c = find!(isTypeBig)(b);
writeln(c);
}

View file

@ -0,0 +1,15 @@
import std.algorithm;
T[] delegate(T[]) finder(T)(T x)
if (is(typeof(x == x) == bool))
{
return delegate(T[] a) { return find(a, x); };
}
unittest
{
auto d = finder(5);
assert(d([1, 3, 5, 7, 9]) == [ 5, 7, 9 ]);
d = finder(10);
assert(d([1, 3, 5, 7, 9]) == []);
}

View file

@ -0,0 +1,21 @@
import std.stdio;
@property bool empty(T)(T[] a) { return a.length == 0; }
@property ref T front(T)(T[] a) { return a[0]; }
void popFront(T)(ref T[] a) { a = a[1 .. $]; }
R find(R, T)(R haystack, T needle)
if (is(typeof(haystack.front != needle) == bool))
{
while (!haystack.empty && haystack.front != needle)
{
haystack.popFront();
}
return haystack;
}
unittest
{
writeln(find([1, 2, 3], 2.0));
assert(find([1, 2, 3], 1.0));
}

View file

@ -0,0 +1,40 @@
// import std.range;
// V reduce(alias fun, V, R)(V x, R range)
// if (isInputRange!R && is(typeof(x = fun(x, range.front))))
// {
// for (; !range.empty; range.popFront())
// {
// x = fun(x, range.front);
// }
// return x;
// }
@property bool empty(T)(T[] a) { return a.length == 0; }
@property ref T front(T)(T[] a) { return a[0]; }
void popFront(T)(ref T[] a) { a = a[1 .. $]; }
V reduce(alias fun, V, R)(V x, R range)
if (is(typeof(x = fun(x, range.front)))
&& is(typeof(range.empty) == bool)
&& is(typeof(range.popFront())))
{
for (; !range.empty; range.popFront())
{
x = fun(x, range.front);
}
return x;
}
unittest
{
int[] r = [ 10, 14, 3, 5, 23 ];
// Вычислить сумму всех элементов
int sum = reduce!((a, b) { return a + b; })(0, r);
assert(sum == 55);
// Вычислить минимум
int min = reduce!((a, b) { return a < b ? a : b; })(r[0], r);
assert(min == 3);
}