Mercurial > hg > aoc
view 2017/day25.d @ 32:763c88851b91
day 25
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 02 Jan 2018 21:41:45 -0500 |
parents | |
children |
line wrap: on
line source
import std.stdio; import std.format: formattedRead; import std.algorithm: sum; struct Branch { bool writeval; int movedir; char newstate; } struct Instruction { Branch if0; Branch if1; } auto branchFmt = " - Write the value %d. - Move one slot to the %s. - Continue with state %s. "; auto parseBranch(File f) { int writeval; string movedir; char newstate; f.readf(branchFmt, &writeval, &movedir, &newstate); return Branch(writeval ? true : false, movedir == "left" ? -1 : 1, newstate); } auto parseInstructions(File f) { Instruction[char] instructions; while(!f.eof) { char state; f.readf("In state %s:\n", &state); f.readln; // "If the current value is 0:" auto if0 = f.parseBranch; f.readln; // "If the current value is 1:" auto if1 = f.parseBranch; f.readln; // Blank line instructions[state] = Instruction(if0, if1); } return instructions; } auto runProgram(File f) { char state; f.readf("Begin in state %s.\n", &state); long steps; f.readf("Perform a diagnostic checksum after %d steps.\n\n", &steps); Instruction[char] instructions = f.parseInstructions; long ip = 0; bool[long] tape; foreach(_; 0..steps) { auto inst = instructions[state]; auto branch = tape.get(ip, false) ? inst.if1 : inst.if0; tape[ip] = branch.writeval; ip += branch.movedir; state = branch.newstate; } return tape.values.sum; } void main(string[] args){ auto checkSum = runProgram(File(args[1])); writeln(checkSum); }