diff --git a/in/15.txt b/in/15.txt new file mode 100644 index 0000000..f4a49fb --- /dev/null +++ b/in/15.txt @@ -0,0 +1 @@ +0,13,1,16,6,17 diff --git a/source/app.d b/source/app.d index b5a8b4d..f3e4d62 100644 --- a/source/app.d +++ b/source/app.d @@ -22,6 +22,7 @@ import day11; import day12; import day13; import day14; +import day15; import dayutil; immutable string progName = "aoc-2020"; @@ -45,6 +46,7 @@ Variant function(int, File, bool, string[])[] programs = [ &day12.run, &day13.run, &day14.run, + &day15.run, ]; void printUsage(string message = null) { diff --git a/source/day13.d b/source/day13.d index ecf8f5a..82e099f 100644 --- a/source/day13.d +++ b/source/day13.d @@ -30,7 +30,7 @@ long part1(ParsedInput input) { long earliestBusTimestamp = long.max; foreach(long bus; input.busses.filter!(x => x != -1)) { long closestTimestamp = (input.timestamp / bus + 1 ) * bus; - writeln(closestTimestamp); + //writeln(closestTimestamp); if (closestTimestamp < earliestBusTimestamp) { earliestBusTimestamp = closestTimestamp; earliestBus = bus; diff --git a/source/day14.d b/source/day14.d index c6894c0..c1ce140 100644 --- a/source/day14.d +++ b/source/day14.d @@ -24,7 +24,6 @@ struct Instruction { Variant run(int part, File input, bool bigboy, string[] args) { auto parsed = input.byLineCopy.parseInput; - writeln(parsed); return Variant(parts!long(part, () => part1(parsed), @@ -149,9 +148,9 @@ long[] addressPermutations(Value[] address) { } } } - writeln(address); + // debug writeln(address); foreach(address2; addresses) { - writeln("Address: %064b".format(address2)); + // debug writeln("Address: %064b".format(address2)); } assert(addresses.length == pow(2, address.count(Value.X))); assert(addresses.uniq.array.length == addresses.length); @@ -199,7 +198,5 @@ mask = 00000000000000000000000000000000X0XX mem[26] = 1 EOS"; auto parsed = parseInput(input.lineSplitter); - writeln(parsed); assert(part2(parsed) == 208); - } diff --git a/source/day15.d b/source/day15.d new file mode 100644 index 0000000..46451be --- /dev/null +++ b/source/day15.d @@ -0,0 +1,71 @@ +import std.conv; +import std.typecons; + +import dayutil; + +immutable size_t TIMES = 2020; +immutable size_t TIMES2 = 30000000; + +Variant run(int part, File input, bool bigboy, string[] args) { + int[] numbers = input.byLineCopy.joiner(",").array.splitter(",").map!(to!int).array; + return Variant(parts!int(part, + () => part1(numbers), + () => part2(numbers))); +} + +int part1(int[] startingNumbers) { + int[] memory; + memory.reserve(2020); + + memory ~= startingNumbers; + + int previous = startingNumbers[$ - 1]; + foreach(index; memory.length..TIMES) { + ptrdiff_t last = memory[0..$ - 1].retro.countUntil(previous) + 1; + + previous = cast(int) last; + + memory ~= [previous]; + } + + return previous; +} + +int part2(int[] startingNumbers) { + int[int] memory; + + foreach(idx, num; startingNumbers[0..$ - 1]) { + memory[num] = cast(int) idx + 1; + } + + int previousNumber = startingNumbers[$ - 1]; + + foreach(index; memory.length..TIMES2 - 1) { + int lastSpoken = memory.get(previousNumber, 0); + int newNumber = lastSpoken; + + if (lastSpoken > 0) { + newNumber = cast(int) index + 1 - lastSpoken; + } + + memory[previousNumber] = cast(int) index + 1; + + /+if (index < 20 || index == TIMES2 - 2) { + writeln("i:", index + 1, "; newNumber: ", newNumber, ", lastSpoken: ", lastSpoken, ", prevous: ", previousNumber); + if (index != TIMES2 - 2) writeln(memory); + }+/ + previousNumber = newNumber; + } + + return previousNumber; +} + +unittest { + //assert(part1([0,3,6]) == 12); + assert(part1([1,3,2]) == 1); + assert(part1([2,1,3]) == 10); + assert(part1([1,2,3]) == 27); + + assert(part2([0,3,6]) == 175594); + assert(part2([1,3,2]) == 2578); +}