RosettaCodeData/Task/Gray-code/D/gray-code-2.d

39 lines
1 KiB
D
Raw Permalink Normal View History

2015-02-20 00:35:01 -05:00
import std.stdio, std.algorithm;
2013-04-10 21:29:02 -07:00
2015-02-20 00:35:01 -05:00
T[] gray(int N : 1, T)() pure nothrow {
return [T(0), 1];
}
2013-04-10 21:29:02 -07:00
2015-02-20 00:35:01 -05:00
/// Recursively generate gray encoding mapping table.
T[] gray(int N, T)() pure nothrow if (N <= T.sizeof * 8) {
enum T M = T(2) ^^ (N - 1);
2013-04-10 21:29:02 -07:00
T[] g = gray!(N - 1, T)();
2015-02-20 00:35:01 -05:00
foreach (immutable i; 0 .. M)
2013-04-10 21:29:02 -07:00
g ~= M + g[M - i - 1];
return g;
}
2015-02-20 00:35:01 -05:00
T[][] grayDict(int N, T)() pure nothrow {
2013-04-10 21:29:02 -07:00
T[][] dict = [gray!(N, T)(), [0]];
2015-02-20 00:35:01 -05:00
// Append inversed gray encoding mapping.
foreach (immutable i; 1 .. dict[0].length)
2017-09-23 10:01:46 +02:00
dict[1] ~= cast(T)countUntil(dict[0], i);
2013-04-10 21:29:02 -07:00
return dict;
}
2015-02-20 00:35:01 -05:00
enum M { Encode = 0, Decode = 1 }
2013-04-10 21:29:02 -07:00
2015-02-20 00:35:01 -05:00
T gray(int N, T)(in T n, in int mode=M.Encode) pure nothrow {
// Generated at compile time.
2013-04-10 21:29:02 -07:00
enum dict = grayDict!(N, T)();
return dict[mode][n];
}
void main() {
2015-02-20 00:35:01 -05:00
foreach (immutable i; 0 .. 32) {
2013-04-10 21:29:02 -07:00
immutable encoded = gray!(5)(i, M.Encode);
immutable decoded = gray!(5)(encoded, M.Decode);
writefln("%2d: %5b => %5b : %2d", i, i, encoded, decoded);
}
}