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