mirror of
https://github.com/HenkKalkwater/aoc-2020
synced 2025-09-05 09:52:44 +00:00
Add day 11
This commit is contained in:
parent
ddbdb8e69d
commit
da60757f0e
4 changed files with 277 additions and 1 deletions
|
@ -18,6 +18,7 @@ import day7;
|
|||
import day8;
|
||||
import day9;
|
||||
import day10;
|
||||
import day11;
|
||||
import dayutil;
|
||||
|
||||
immutable string progName = "aoc-2020";
|
||||
|
@ -37,6 +38,7 @@ Variant function(int, File, bool, string[])[] programs = [
|
|||
&day8.run,
|
||||
&day9.run,
|
||||
&day10.run,
|
||||
&day11.run,
|
||||
];
|
||||
|
||||
void printUsage(string message = null) {
|
||||
|
|
|
@ -27,7 +27,6 @@ size_t part1(T)(SortedRange!(T[]) numbers) {
|
|||
}
|
||||
// Device adapter is always rated 3 volts higher
|
||||
gap3++;
|
||||
writeln(gap1, ", ", gap3);
|
||||
return gap1 * gap3;
|
||||
}
|
||||
|
||||
|
|
183
source/day11.d
Normal file
183
source/day11.d
Normal file
|
@ -0,0 +1,183 @@
|
|||
import std.array;
|
||||
import std.algorithm;
|
||||
import std.range;
|
||||
import std.string;
|
||||
import std.stdio;
|
||||
import std.traits;
|
||||
import std.variant;
|
||||
|
||||
import dayutil;
|
||||
|
||||
enum Spot {
|
||||
FLOOR,
|
||||
EMPTY,
|
||||
TAKEN
|
||||
}
|
||||
|
||||
Variant run(int part, File input, bool bigboy, string[] args) {
|
||||
Spot[][] spots = parseInput(input.byLineCopy);
|
||||
|
||||
return Variant(parts!size_t(part,
|
||||
() => part1(spots),
|
||||
() => part2(spots)));
|
||||
}
|
||||
|
||||
Spot[][] parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) {
|
||||
return range.map!(row => row.map!((spot) {
|
||||
switch(spot) {
|
||||
case '.':
|
||||
return Spot.FLOOR;
|
||||
case 'L':
|
||||
return Spot.EMPTY;
|
||||
case '#':
|
||||
return Spot.TAKEN;
|
||||
default:
|
||||
assert(false, "Unknown type");
|
||||
}
|
||||
}).array).array;
|
||||
}
|
||||
|
||||
size_t part1(Spot[][] input) {
|
||||
Spot[][] prev = input.dup;
|
||||
do {
|
||||
foreach (i, row; input.enumerate) {
|
||||
prev[i] = row.dup;
|
||||
}
|
||||
//prev = input.dup;
|
||||
for (int y = 0; y < input.length; y++) {
|
||||
for (int x = 0; x < input[y].length; x++) {
|
||||
if(input[y][x] == Spot.FLOOR) continue;
|
||||
|
||||
uint adjacent_taken = 0;
|
||||
for (int dy = max(0, y - 1); dy <= min(prev.length - 1, y + 1); dy++) {
|
||||
for (int dx = max(0, x - 1); dx <= min(prev[y].length - 1, x + 1); dx++) {
|
||||
if (dx == x && dy == y) continue;
|
||||
switch(prev[dy][dx]) {
|
||||
case Spot.TAKEN:
|
||||
adjacent_taken++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
import std.format;
|
||||
if (adjacent_taken == 0) {
|
||||
input[y][x] = Spot.TAKEN;
|
||||
} else if (adjacent_taken >= 4) {
|
||||
input[y][x] = Spot.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} while(!prev.equal(input));
|
||||
|
||||
return input.joiner.count(Spot.TAKEN);
|
||||
}
|
||||
|
||||
|
||||
unittest {
|
||||
import std.format;
|
||||
string layout = q"EOS
|
||||
L.LL.LL.LL
|
||||
LLLLLLL.LL
|
||||
L.L.L..L..
|
||||
LLLL.LL.LL
|
||||
L.LL.LL.LL
|
||||
L.LLLLL.LL
|
||||
..L.L.....
|
||||
LLLLLLLLLL
|
||||
L.LLLLLL.L
|
||||
L.LLLLL.LL
|
||||
EOS";
|
||||
size_t result = parseInput(layout.lineSplitter).part1();
|
||||
assert(result == 37, "Result is %d (expected 37)".format(result));
|
||||
}
|
||||
|
||||
size_t part2(Spot[][] input) {
|
||||
Spot[][] prev = input.dup;
|
||||
do {
|
||||
foreach (i, row; input.enumerate) {
|
||||
prev[i] = row.dup;
|
||||
}
|
||||
//prev = input.dup;
|
||||
for (int y = 0; y < prev.length; y++) {
|
||||
for (int x = 0; x < prev[y].length; x++) {
|
||||
if(prev[y][x] == Spot.FLOOR) {
|
||||
//debug write('.');
|
||||
continue;
|
||||
}
|
||||
import std.format;
|
||||
|
||||
int adjacent_taken = 0;
|
||||
for (int dy = -1; dy <= 1; dy++) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
if (dx == 0 && dy == 0) continue;
|
||||
|
||||
Spot spot;
|
||||
int i = 1;
|
||||
do {
|
||||
int nx = x + i * dx;
|
||||
int ny = y + i * dy;
|
||||
i++;
|
||||
if (ny < 0 || ny >= prev.length || nx < 0 || nx >= prev[ny].length) {
|
||||
//debug write("\x1B[41m");
|
||||
spot = Spot.EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
spot = prev[ny][nx];
|
||||
} while(spot == Spot.FLOOR);
|
||||
|
||||
if (spot == Spot.TAKEN) {
|
||||
adjacent_taken++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//debug write(adjacent_taken);
|
||||
//debug write("\x1B[0m");
|
||||
if (adjacent_taken == 0) {
|
||||
input[y][x] = Spot.TAKEN;
|
||||
} else if (adjacent_taken >= 5) {
|
||||
input[y][x] = Spot.EMPTY;
|
||||
}
|
||||
}
|
||||
//debug writeln();
|
||||
}
|
||||
//debug writeln();
|
||||
|
||||
/+debug {
|
||||
void printSpots(Spot[][] flop) {
|
||||
foreach(row; flop) {
|
||||
foreach(seat; row) {
|
||||
write(seat == Spot.TAKEN ? '#' : (seat == Spot.EMPTY ? 'L' : '.'));
|
||||
}
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
printSpots(input);
|
||||
}+/
|
||||
} while(!prev.equal(input));
|
||||
|
||||
return input.joiner.count(Spot.TAKEN);
|
||||
}
|
||||
|
||||
unittest {
|
||||
import std.format;
|
||||
string layout = q"EOS
|
||||
L.LL.LL.LL
|
||||
LLLLLLL.LL
|
||||
L.L.L..L..
|
||||
LLLL.LL.LL
|
||||
L.LL.LL.LL
|
||||
L.LLLLL.LL
|
||||
..L.L.....
|
||||
LLLLLLLLLL
|
||||
L.LLLLLL.L
|
||||
L.LLLLL.LL
|
||||
EOS";
|
||||
size_t result = parseInput(layout.lineSplitter).part2();
|
||||
assert(result == 26, "Result is %d (expected 26)".format(result));
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue