import std; void main() { "input".slurp!(string, int)("%s %s").executeProgramAndReturnAcc.writeln; } alias Instruction = Tuple!(string, int); alias Program = Instruction[]; auto executeProgramAndReturnAcc(Program program) { int accumulator; // dfmt off alias operation = void delegate(ref ulong ip, int arg); operation[string] operations = [ "nop" : (scope ref size_t ip, int arg) {ip += 1;}, "acc" : (scope ref size_t ip, int arg) { accumulator += arg; ip += 1; }, "jmp" : (scope ref size_t ip, int arg) {ip += arg;} ]; // dfmt on void[0][size_t] seenIPs; size_t ip = 0; while (ip !in seenIPs) { seenIPs[ip] = []; operations[program[ip][0]](ip, program[ip][1]); } return accumulator; } unittest { auto program = `nop +0 acc +1 jmp +4 acc +3 jmp -3 acc -99 acc +1 jmp -4 acc +6`.splitter("\n").filter!(not!empty) .map!((line) { auto opAndArg = line.split(" "); return tuple(opAndArg[0], opAndArg[1].to!int); }) .array; assert(program.executeProgramAndReturnAcc == 5); }