diff 2017/day10.d @ 10:bd993cf00e2f

day 10
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Mon, 11 Dec 2017 19:50:57 -0500
parents
children 990a4fa2aebe
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/2017/day10.d
@@ -0,0 +1,48 @@
+import std.stdio;
+import std.range: iota, array, chunks;
+import std.algorithm: invert=reverse, map, reduce;
+import std.conv: to;
+import std.format: format;
+import std.string: join;
+
+void reverse(int Size)(ref int[Size] twine, int a, int b) {
+  a = a % Size;
+  b = b % Size;
+  if (a <= b) {
+    invert(twine[a..b]);
+  }
+  else {
+    auto result = twine[a..$] ~ twine[0..b];
+    invert(result);
+    twine[a..$] = result[0..Size-a];
+    twine[0..b] = result[Size-a..$];
+  }
+}
+
+auto knotUp(int Size)(int[] lengths, int[Size] twine) {
+  static pos = 0, skip = 0;
+  foreach(length; lengths) {
+    reverse(twine, pos, pos+length);
+    pos += length + skip;
+    skip++;
+  }
+  return twine;
+}
+
+auto getHash(int Size, int Rounds, int ChunkSize)(int[] lengths)
+  if( Size % ChunkSize == 0)
+{
+  int[Size] twine = iota(0, Size).array;
+  for(int i = 0; i < Rounds; i++) {
+    twine = knotUp(lengths, twine);
+  }
+  return twine.array.chunks(ChunkSize).map!(
+      x => format("%02x", reduce!((a,b) => a ^ b)(x[0], x[1..$]))
+  ).join;
+}
+
+void main(string[] args){
+  int[] lengths = to!(int[])(cast(ubyte[]) args[1]) ~ [17, 31, 73, 47, 23];
+  auto hash = getHash!(256, 64, 16)(lengths);
+  writeln(hash);
+}