mirror of
https://github.com/HenkKalkwater/aoc-2020
synced 2025-09-05 17:52:44 +00:00
Added day 8
This commit is contained in:
parent
a321a1a7b4
commit
c138d30ea1
4 changed files with 770 additions and 1 deletions
|
@ -14,6 +14,7 @@ import day4;
|
|||
import day5;
|
||||
import day6;
|
||||
import day7;
|
||||
import day8;
|
||||
import dayutil;
|
||||
|
||||
immutable string progName = "aoc-2020";
|
||||
|
@ -26,6 +27,7 @@ Variant function(int, File, bool, string[])[] programs = [
|
|||
&day5.run,
|
||||
&day6.run,
|
||||
&day7.run,
|
||||
&day8.run,
|
||||
];
|
||||
|
||||
void printUsage(string name) {
|
||||
|
|
154
source/day8.d
Normal file
154
source/day8.d
Normal file
|
@ -0,0 +1,154 @@
|
|||
import std.array;
|
||||
import std.algorithm;
|
||||
import std.conv;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
import std.traits;
|
||||
import std.variant;
|
||||
|
||||
import dayutil;
|
||||
|
||||
Variant run(int part, File input, bool bigboy, string[] args) {
|
||||
Instruction[] instructions = readInput(input.byLine);
|
||||
|
||||
Variant result = parts!int(part,
|
||||
() => part1(instructions),
|
||||
() => part2(instructions));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum Memomic {
|
||||
NOP,
|
||||
ACC,
|
||||
JMP
|
||||
}
|
||||
|
||||
struct Instruction {
|
||||
Memomic memomic;
|
||||
int arg;
|
||||
}
|
||||
|
||||
Instruction[] readInput(R)(R range) if (isInputRange!R && isSomeString!(ElementType!R)) {
|
||||
return range.map!((text) {
|
||||
Instruction instruction;
|
||||
switch(text[0..3]) {
|
||||
case "nop":
|
||||
instruction.memomic = Memomic.NOP;
|
||||
break;
|
||||
case "acc":
|
||||
instruction.memomic = Memomic.ACC;
|
||||
break;
|
||||
case "jmp":
|
||||
instruction.memomic = Memomic.JMP;
|
||||
break;
|
||||
default:
|
||||
writeln("unknown instruction: ", text[0..3]);
|
||||
break;
|
||||
}
|
||||
//int sign = text[4] == '+' ? 1 : -1;
|
||||
// to!int correctly handles + and -
|
||||
instruction.arg = to!int(text[4..$]);
|
||||
return instruction;
|
||||
}).array;
|
||||
}
|
||||
|
||||
int part1(ref Instruction[] instrs) {
|
||||
int acc = 0;
|
||||
int pc = 0;
|
||||
int[] visited;
|
||||
|
||||
while(!visited.canFind(pc)) {
|
||||
Instruction curInstr = instrs[pc];
|
||||
writeln(pc, curInstr);
|
||||
visited ~= [pc];
|
||||
switch(curInstr.memomic) {
|
||||
case Memomic.NOP:
|
||||
pc += 1;
|
||||
break;
|
||||
case Memomic.ACC:
|
||||
pc += 1;
|
||||
acc += curInstr.arg;
|
||||
break;
|
||||
case Memomic.JMP:
|
||||
pc += curInstr.arg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
unittest {
|
||||
string input = q"EOS
|
||||
nop +0
|
||||
acc +1
|
||||
jmp +4
|
||||
acc +3
|
||||
jmp -3
|
||||
acc -99
|
||||
acc +1
|
||||
jmp -4
|
||||
acc +6
|
||||
EOS";
|
||||
auto instrs = readInput(input.lineSplitter);
|
||||
assert(part1(instrs) == 5);
|
||||
}
|
||||
|
||||
int part2(ref Instruction[] instrs) {
|
||||
bool finishes(ref Instruction[] instrs, out int acc) {
|
||||
int pc = 0;
|
||||
int[] visited;
|
||||
|
||||
while(!visited.canFind(pc)) {
|
||||
Instruction curInstr = instrs[pc];
|
||||
writeln(pc, curInstr);
|
||||
visited ~= [pc];
|
||||
switch(curInstr.memomic) {
|
||||
case Memomic.NOP:
|
||||
pc += 1;
|
||||
break;
|
||||
case Memomic.ACC:
|
||||
pc += 1;
|
||||
acc += curInstr.arg;
|
||||
break;
|
||||
case Memomic.JMP:
|
||||
pc += curInstr.arg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (pc == instrs.length) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int acc;
|
||||
// O(n^2) go brrr
|
||||
for(size_t i = 0; i < instrs.length; i++) {
|
||||
if (instrs[i].memomic == Memomic.ACC) continue;
|
||||
Instruction[] dup = instrs.dup;
|
||||
dup[i].memomic = dup[i].memomic == Memomic.NOP ? Memomic.JMP : Memomic.NOP;
|
||||
if (finishes(dup, acc)) return acc;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
unittest {
|
||||
string input = q"EOS
|
||||
nop +0
|
||||
acc +1
|
||||
jmp +4
|
||||
acc +3
|
||||
jmp -3
|
||||
acc -99
|
||||
acc +1
|
||||
jmp -4
|
||||
acc +6
|
||||
EOS";
|
||||
auto instrs = readInput(input.lineSplitter);
|
||||
assert(part2(instrs) == 8);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue