Mercurial > hg > aoc
view 2017/day10/app.d @ 33:bc652fa0a645
Move all solutions to per-day subdirs
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 09 Jan 2018 21:50:37 -0500 |
parents | 2017/day10.d@990a4fa2aebe |
children |
line wrap: on
line source
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 pos = 0, skip = 0; auto knotUp(int Size)(int[] lengths, int[Size] twine) { foreach(length; lengths) { reverse(twine, pos, pos+length); pos = (pos + length + skip) % Size; skip = (skip + 1) % Size; } return twine; } auto calcHash(int Size=256, int Rounds=64, int ChunkSize=16)(string input) if( Size % ChunkSize == 0) { int[] lengths = to!(int[])(cast(ubyte [])(input)); static salt = [17, 31, 73, 47, 23]; lengths ~= salt; int[Size] twine = iota(0, Size).array; for(int i = 0; i < Rounds; i++) { twine = knotUp(lengths, twine); } pos=skip=0; return twine.array.chunks(ChunkSize).map!( x => reduce!((a,b) => a ^ b)(x[0], x[1..$]) ).array.to!(ubyte[Size/ChunkSize]); } auto getHash(int Size=256, int Rounds=64, int ChunkSize=16)(string input) if( Size % ChunkSize == 0) { auto hash = calcHash!(Size, Rounds, ChunkSize)(input); return hash.array.map!(x => format("%02x", x)).join; } version(standalone) { void main(string[] args){ auto hash = getHash(args[1]); writeln(hash); } }