Created
December 16, 2017 13:31
-
-
Save namachan10777/5ded4006636008ea67971837e05cae77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
import std.math; | |
import std.algorithm.comparison; | |
struct List(alias N, T) { | |
private T[] arr; | |
auto opIndex(I : Interger!(B, T), alias B, alias T)(in I idx) { | |
static if (B >= 0 && T < N) { | |
return arr[idx.value]; | |
} | |
else { | |
static assert (false, "Out of range"); | |
} | |
} | |
} | |
auto nil(T)() { | |
return List!(0, T)(); | |
} | |
auto cons (L : List!(N, T), alias N, T)(L list, T x) { | |
return List!(N+1, T)(list.arr ~ x); | |
} | |
auto hd (L : List!(N, T), alias N, T)(L list) { | |
static assert (N > 0); | |
return list.arr[$-1]; | |
} | |
auto tl (L : List!(N, T), alias N, T)(L list) { | |
static assert (N > 0); | |
return List!(N-1, T)(list.arr[0..$-1]); | |
} | |
auto join(L1 : List!(N1, T), L2 : List!(N2, T), alias N1, alias N2, T)(L1 l1, L2 l2) { | |
return List!(N1+N2, T)(l1.arr ~ l2.arr); | |
} | |
auto idx (alias IDX, L : List!(N, T), alias N, T)(L list) { | |
static assert (IDX > 0 && IDX < N); | |
return list.arr[IDX]; | |
} | |
unittest { | |
auto list0 = nil!int; | |
auto list1 = list0.cons(0); | |
auto list2 = list0.cons(0).cons(1).cons(2).cons(3); | |
// list0.hd; //compile error | |
assert (list1.hd == 0); | |
// list0.tl; //compile error | |
assert (list1.tl == nil!int); | |
// list1.tl.hd; //compile error | |
assert (list2.idx!2 == 2); | |
// list2.idx!4 //compile error | |
} | |
struct Interger(alias B, alias T) { | |
static if (B >= 0) { | |
ulong value; | |
} | |
else { | |
long value; | |
} | |
auto opBinary(string op, I : Interger!(XB, XT), alias XB, alias XT)(I x) { | |
static if (op == "+") { | |
enum NEW_B = B+XB; | |
enum NEW_T = T+XT; | |
return Interger!(NEW_B, NEW_T)(value+x.value); | |
} | |
else static if (op == "-") { | |
enum NEW_B = B-XB; | |
enum NEW_T = T-XT; | |
return Interger!(NEW_B, NEW_T)(value-x.value); | |
} | |
else static if (op == "*") { | |
enum NEW_B = min(B*XB, B*XT, T*XB, T*XT); | |
enum NEW_T = max(B*XB, B*XT, T*XB, T*XT); | |
return Interger!(NEW_B, NEW_T)(value*x.value); | |
} | |
else static if (op == "/") { | |
static if (XB == 0 && XT == 0) { | |
static assert (false); | |
} | |
else static if (XB == 0) { | |
enum NEW_B = min(B/XT, T/XT); | |
enum NEW_T = max(B/XT, T/XT); | |
} | |
else static if (XT == 0) { | |
enum NEW_T = max(B/XB, T/XB); | |
enum NEW_B = max(B/XB, T/XB); | |
} | |
else { | |
enum NEW_T = max(B/XB, T/XB, B/XT, T/XT); | |
enum NEW_B = max(B/XB, T/XB, B/XT, T/XT); | |
} | |
return Interger!(NEW_B, NEW_T)(value/x.value); | |
} | |
else static if (op == "%") { | |
static if (B < 0 && T < 0) { | |
enum NEW_B = -max(abs(XB), abs(XT)); | |
enum NEW_T = 0; | |
} | |
else static if (B < 0) { | |
enum NEW_B = -max(abs(XB), abs(XT)); | |
enum NEW_T = max(abs(XB), abs(XT)); | |
} | |
else { | |
enum NEW_B = 0; | |
enum NEW_T = max(abs(XB), abs(XT)); | |
} | |
return Interger!(NEW_B, NEW_T)(value/x.value); | |
} | |
} | |
} | |
auto interger(alias N)() { | |
return Interger!(N, N)(N); | |
} | |
struct IndexRange(alias B, alias T) { | |
long idx = B; | |
bool empty() { | |
return idx > T; | |
} | |
auto front() { | |
return Interger!(B, T)(idx); | |
} | |
void popFront() { | |
++idx; | |
} | |
} | |
auto rng(alias B, alias T)() { | |
return IndexRange!(B, T-1)(); | |
} | |
unittest { | |
auto i1 = Interger!(0, 10)(5); | |
auto i2 = Interger!(0, 3)(2); | |
auto l = nil!int.cons(0).cons(1).cons(2).cons(3).cons(4).cons(5).cons(6); | |
/+foreach (i; rng!(-3, 0)) { | |
writeln(l[i]); | |
} | |
foreach (i; rng!(-3, 0)) { | |
writeln(l[i+interger!3]); | |
}+/ | |
foreach (i; rng!(-3, 0)) { | |
writeln(i); | |
writeln((i+interger!3)*interger!2); | |
writeln(l[(i+interger!3)*interger!2]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment