diff 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 diff
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);
+}