aoc2020/day11/part1/main.d

205 lines
3.8 KiB
D
Raw Permalink Normal View History

2020-12-19 12:15:13 +01:00
import std;
void main()
{
File("input", "r").byLineCopy.array.calculateNumberOfOccupiedSeatsStable.writeln;
}
auto calculateValidNeighbouringSeatPositions(size_t i, size_t j, size_t height, size_t width)
{
return [
tuple(i - 1, j - 1), tuple(i - 1, j), tuple(i - 1, j + 1), tuple(i,
j - 1), tuple(i, j + 1), tuple(i + 1, j - 1), tuple(i + 1, j),
tuple(i + 1, j + 1)
].filter!(position => position[0] >= 0 && position[0] < height
&& position[1] >= 0 && position[1] < width);
}
auto calculateNewSeatState(const char seat, ulong numberOfOccupiedNeighbouringSeats)
{
if (seat == '#' && numberOfOccupiedNeighbouringSeats >= 4)
{
return 'L';
}
else if (seat == 'L' && numberOfOccupiedNeighbouringSeats == 0)
{
return '#';
}
else
{
return seat;
}
}
auto calculateNextSeatOccupation(const char[][] seats)
{
if (seats.empty || seats.front.empty)
{
return seats;
}
immutable height = seats.length;
immutable width = seats.front.length;
return seats.enumerate.map!((indexedRow) {
immutable i = indexedRow.index;
const row = indexedRow.value;
return row.byChar.enumerate.map!((indexedSeat) {
immutable j = indexedSeat.index;
immutable seat = indexedSeat.value;
immutable numberOfOccupiedNeighbouringSeats = calculateValidNeighbouringSeatPositions(i,
j, height, width).map!(position => seats[position[0]][position[1]])
.filter!(it => it == '#')
.count;
return seat.calculateNewSeatState(numberOfOccupiedNeighbouringSeats);
}).array;
}).array;
}
unittest
{
auto input = `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`.dup.split("\n");
assert(input.calculateNextSeatOccupation.join("\n") == `#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##`);
}
unittest
{
auto input = `#.##.##.##
#######.##
#.#.#..#..
####.##.##
#.##.##.##
#.#####.##
..#.#.....
##########
#.######.#
#.#####.##`.dup.split("\n");
assert(input.calculateNextSeatOccupation.join("\n") == `#.LL.L#.##
#LLLLLL.L#
L.L.L..L..
#LLL.LL.L#
#.LL.LL.LL
#.LLLL#.##
..L.L.....
#LLLLLLLL#
#.LLLLLL.L
#.#LLLL.##`);
}
unittest
{
auto input = `#.LL.L#.##
#LLLLLL.L#
L.L.L..L..
#LLL.LL.L#
#.LL.LL.LL
#.LLLL#.##
..L.L.....
#LLLLLLLL#
#.LLLLLL.L
#.#LLLL.##`.dup.split("\n");
assert(input.calculateNextSeatOccupation.join("\n") == `#.##.L#.##
#L###LL.L#
L.#.#..#..
#L##.##.L#
#.##.LL.LL
#.###L#.##
..#.#.....
#L######L#
#.LL###L.L
#.#L###.##`);
}
unittest
{
auto input = `#.##.L#.##
#L###LL.L#
L.#.#..#..
#L##.##.L#
#.##.LL.LL
#.###L#.##
..#.#.....
#L######L#
#.LL###L.L
#.#L###.##`.dup.split("\n");
assert(input.calculateNextSeatOccupation.join("\n") == `#.#L.L#.##
#LLL#LL.L#
L.L.L..#..
#LLL.##.L#
#.LL.LL.LL
#.LL#L#.##
..L.L.....
#L#LLLL#L#
#.LLLLLL.L
#.#L#L#.##`);
}
unittest
{
auto input = `#.#L.L#.##
#LLL#LL.L#
L.L.L..#..
#LLL.##.L#
#.LL.LL.LL
#.LL#L#.##
..L.L.....
#L#LLLL#L#
#.LLLLLL.L
#.#L#L#.##`.dup.split("\n");
assert(input.calculateNextSeatOccupation.join("\n") == `#.#L.L#.##
#LLL#LL.L#
L.#.L..#..
#L##.##.L#
#.#L.LL.LL
#.#L#L#.##
..L.L.....
#L#L##L#L#
#.LLLLLL.L
#.#L#L#.##`);
}
auto calculateNumberOfOccupiedSeatsStable(const char[][] seats)
{
return recurrence!((seats, n) => seats[n - 1].calculateNextSeatOccupation)(seats).slide(2)
.map!array
.find!((pair) => pair[0] == pair[1])
.front
.front
.join
.filter!(seat => seat == '#')
.count;
}
unittest
{
auto input = `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`.dup.split("\n");
assert(input.calculateNumberOfOccupiedSeatsStable == 37);
}