1
0
Fork 0
mirror of https://github.com/HenkKalkwater/aoc-2020 synced 2025-09-08 10:42:45 +00:00

Add day 14 part 1

This commit is contained in:
Chris Josten 2020-12-14 07:04:16 +01:00
parent 0ae8e76553
commit 8a5bbcefdc
Signed by: chris
GPG key ID: 1795A594046530AB
4 changed files with 692 additions and 1 deletions

View file

@ -21,6 +21,7 @@ import day10;
import day11;
import day12;
import day13;
import day14;
import dayutil;
immutable string progName = "aoc-2020";
@ -43,6 +44,7 @@ Variant function(int, File, bool, string[])[] programs = [
&day11.run,
&day12.run,
&day13.run,
&day14.run,
];
void printUsage(string message = null) {

View file

@ -87,7 +87,6 @@ long part2(ParsedInput input) {
for(; (time + bus.index) % bus.value != 0; time += step) {}
step *= bus.value;
}
writeln(time);
return time;
}

136
source/day14.d Normal file
View file

@ -0,0 +1,136 @@
import std.conv;
import dayutil;
immutable int MEM_SIZE = 36;
enum Operation {
WRITE_BITMASK,
WRITE_MEM
}
enum Value {
ZERO,
ONE,
X,
}
struct Instruction {
Operation op;
long address;
Value[] value;
}
Variant run(int part, File input, bool bigboy, string[] args) {
auto parsed = input.byLineCopy.parseInput;
writeln(parsed);
return Variant(parts!long(part,
() => part1(parsed),
() => part2(parsed)));
}
Instruction[] parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) {
return range.map!((x) {
Instruction instr;
if (x.startsWith("mask = ")) {
instr.op = Operation.WRITE_BITMASK;
instr.value.reserve(x.length - 8);
foreach(c; x[7..$]) {
switch(c) {
case 'X':
instr.value ~= [Value.X];
break;
case '1':
instr.value ~= [Value.ONE];
break;
case '0':
instr.value ~= [Value.ZERO];
break;
default:
assert(false, "Invalid input");
}
}
} else {
instr.op = Operation.WRITE_MEM;
size_t secondBracket = x.countUntil(']');
instr.address = to!long(x[4..secondBracket]);
long tmp = to!long(x[secondBracket + 4..$]);
instr.value = toStupidBinary(tmp);
}
return instr;
}).array;
}
Value[] toStupidBinary(long val) {
Value[] result;
while (val != 0) {
result ~= [(val & 1) == 1 ? Value.ONE : Value.ZERO];
val >>= 1;
}
result.length = MEM_SIZE;
return result.reverse;
}
long fromStupidBinary(Value[] val) {
long result;
foreach(bit; val) {
result <<= 1;
if (bit == Value.ONE) {
result |= 1;
}
}
return result;
}
long part1(Instruction[] instructions) {
Value[] bitmask;
long[long] memory;
foreach(instruction; instructions) {
final switch(instruction.op) {
case Operation.WRITE_BITMASK:
bitmask = instruction.value;
break;
case Operation.WRITE_MEM:
Value[] tmp = instruction.value;
foreach(ref bit, mask; lockstep(tmp.retro, bitmask.retro)) {
final switch(mask) {
case Value.ZERO:
bit = Value.ZERO;
break;
case Value.ONE:
bit = Value.ONE;
break;
case Value.X: break;
}
}
//writeln(tmp);
memory[instruction.address] = fromStupidBinary(tmp);
break;
}
}
long sum = 0;
foreach(e; memory.byValue()) {
//writeln(e);
sum += e;
}
return sum;
}
int part2(Range)(Range range) if (isInputRange!Range) {
return 0;
}
unittest {
string input = q"EOS
mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
mem[8] = 11
mem[7] = 101
mem[8] = 0
EOS";
auto parsed = parseInput(input.lineSplitter);
writeln(parsed);
writeln(part1(parsed.save));
assert(part1(parsed.save) == 165);
}