view 2017/day23.d @ 30:c64fab7ed515

day 23: moar functional (lol)
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Tue, 02 Jan 2018 16:39:49 -0500
parents f2c11215006d
children
line wrap: on
line source

import std.stdio;
import std.array: array;
import std.string: split;
import std.conv: to, ConvException;

import std.math: sqrt;
import std.range: iota, stride;
import std.algorithm: filter, any;

auto isComposite(long p) {
  return iota(2, sqrt(cast(double) p)).filter!(x => p % x == 0).any;
}

auto runProgram(string[] opcodes, bool shortcircuit=false) {

  long ip = 0;
  long[char] regs;
  long mult = 0;

  if (shortcircuit) {
    regs['a'] = 1;
  }

  while(0 <= ip && ip < opcodes.length) {
    auto opcode = opcodes[ip].split;
    auto op = opcode[0];
    auto reg = opcode[1][0];
    long val = 0;
    if (opcode.length > 2) {
      try {
        val = to!long(opcode[2]);
      }
      catch(ConvException){
        val = regs.get(opcode[2][0], 0);
      }
    }

    if (ip > 7 && shortcircuit) {
      auto low = regs['b'], hi = regs['c'];
      auto step = -to!long(opcodes[30].split[2]);
      return iota(low, hi+1).stride(step).filter!(isComposite).array.length;
    }

    switch(op) {
    case "set":
      regs[reg] = val;
      goto default;
    case "sub":
      regs[reg] = regs.get(reg, 0) - val;
      goto default;
    case "mul":
      regs[reg] = regs.get(reg, 0) * val;
      mult++;
      goto default;
    case "jnz":
      long cmp;
      try {
        cmp = to!long(opcode[1]);
      }
      catch(ConvException) {
        cmp = regs.get(reg, 0);
      }
      if (cmp != 0) {
        ip += val;
        break;
      }
      goto default;
    default:
      ip++;
    }
  }
  return(mult);
}

void main(string[] args) {
  auto opcodes = File(args[1]).byLineCopy.array.dup;
  writeln(runProgram(opcodes));
  writeln(runProgram(opcodes, true));
}