Mercurial > hg > aoc
changeset 10:bd993cf00e2f
day 10
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 11 Dec 2017 19:50:57 -0500 |
parents | 18e7ffa83a14 |
children | 66707d1400b4 |
files | 2017/day10.d |
diffstat | 1 files changed, 48 insertions(+), 0 deletions(-) [+] |
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); +}