# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1514947305 18000 # Node ID 763c88851b917576fd78789c107dffd30ae1ff0d # Parent 6761b3bbaa702dc8cda5a6ad7d51fb673c937636 day 25 diff --git a/2017/day25.d b/2017/day25.d new file mode 100644 --- /dev/null +++ b/2017/day25.d @@ -0,0 +1,71 @@ +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); +}