diff --git a/functions/src/day11.ts b/functions/src/day11.ts new file mode 100644 index 0000000..71103a6 --- /dev/null +++ b/functions/src/day11.ts @@ -0,0 +1,128 @@ +import Day from "./day"; + +class Day11 implements Day { + + part1(input: string[]): number | string { + + const grid = OctopusGrid.parse(input); + + let flashTotal = 0; + for (let i = 0; i < 100; i++) { + flashTotal += grid.runStep(); + } + return flashTotal; + } + + part2(input: string[]): number | string { + const grid = OctopusGrid.parse(input); + + let lastFlash = 0; + let step = 0; + while(lastFlash !== 100) { + lastFlash = grid.runStep(); + step++; + } + return step; + } + +} + +class OctopusGrid { + grid: number[]; + maxX: number; + maxY: number; + + constructor(grid: number[], width: number) { + + this.grid = grid; + this.maxX = width; + this.maxY = grid.length / width; + + } + + static parse(input: string[]): OctopusGrid { + + const grid = input.map(l => l.split("").map(s => parseInt(s))) + .reduce((a, b) => [...a, ...b]) + const width = input[0].length; + + return new OctopusGrid(grid, width); + } + + runStep(): number { + + // First, the energy level of each octopus increases by 1. + this.grid = this.grid.map(o => o + 1); + + // Then, any octopus with an energy level greater than 9 flashes. This increases the energy level of all adjacent + // octopuses by 1, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy + // level greater than 9, it also flashes. This process continues as long as new octopuses keep having their energy + // level increased beyond 9. (An octopus can only flash at most once per step.) + const flashGrid = Array(this.grid.length).fill(false); + + for (let y = 0; y < this.maxY; y++) { + for (let x = 0; x < this.maxX; x++) { + const i = this.index(x, y); + const cur = this.grid[i]; + if (cur > 9 && !flashGrid[i]) { + this.flash(x, y, flashGrid); + } + } + } + + // Finally, any octopus that flashed during this step has its energy level set to 0, as it used all of its energy to flash. + for (let y = 0; y < this.maxY; y++) { + for (let x = 0; x < this.maxX; x++) { + const i = this.index(x, y); + if (flashGrid[i]) { + this.grid[i] = 0; + } + } + } + + return flashGrid.filter(f => f).length; + } + + flash(x: number, y: number, flashGrid: boolean[]) { + + flashGrid[this.index(x, y)] = true; + + // Charge and if needed flash all neighbors + for (let ny = y - 1; ny <= y + 1; ny++) { + for (let nx = x - 1; nx <= x + 1 ; nx++) { + this.chargeAndFlashIfNeeded(nx, ny, flashGrid); + } + } + } + + chargeAndFlashIfNeeded(x: number, y: number, flashGrid: boolean[]) { + // Short circuit for octopuses outside the grid + if (x < 0 || x >= this.maxX || y < 0 || y >= this.maxY) return; + + const i = this.index(x, y); + this.grid[i] += 1; + if (this.grid[i] > 9 && !flashGrid[i]) { + this.flash(x, y, flashGrid) + } + } + + index(x: number, y: number): number { + return x + y * this.maxX; + } + + toString(): string { + + let lines = []; + for (let y = 0; y < this.maxY; y++) { + let line = ""; + for (let x = 0; x < this.maxX; x++) { + line += this.grid[this.index(x, y)]; + } + lines.push(line); + } + + return lines.join("\n"); + } +} + +export default Day11; diff --git a/functions/src/index.ts b/functions/src/index.ts index 2470077..9fd3376 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -12,6 +12,7 @@ import Day7 from "./day7"; import Day8 from "./day8"; import Day9 from "./day9"; import Day10 from "./day10"; +import Day11 from "./day11"; // // Start writing Firebase Functions @@ -38,6 +39,7 @@ export const day = { 8: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day8(), request, response) }), 9: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day9(), request, response) }), 10: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day10(), request, response) }), + 11: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day11(), request, response) }), } diff --git a/input/day/11-example.http b/input/day/11-example.http new file mode 100644 index 0000000..48e8137 --- /dev/null +++ b/input/day/11-example.http @@ -0,0 +1,15 @@ +POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-11 +Content-Type: text/plain + +5483143223 +2745854711 +5264556173 +6141336146 +6357385478 +4167524645 +2176841721 +6882881134 +4846848554 +5283751526 + +### diff --git a/input/day/11.http b/input/day/11.http new file mode 100644 index 0000000..09e962d --- /dev/null +++ b/input/day/11.http @@ -0,0 +1,15 @@ +POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-11 +Content-Type: text/plain + +2524255331 +1135625881 +2838353863 +1662312365 +6847835825 +2185684367 +6874212831 +5387247811 +2255482875 +8528557131 + +###