diff --git a/2024/src/2024/day12/day12.test.ts b/2024/src/2024/day12/day12.test.ts index b6fe845..94e4f9d 100644 --- a/2024/src/2024/day12/day12.test.ts +++ b/2024/src/2024/day12/day12.test.ts @@ -2,10 +2,10 @@ import {part1, part2} from "./day12"; describe('2024 Day 12', () => { test('Part 1', async () => { - expect(await part1('testInput1')).toEqual(772); - expect(await part1('testInput2')).toEqual(140); - expect(await part1('testInput2')).toEqual(1930); - expect(await part1('input')).toEqual(44444); + expect(await part1('testInput1')).toEqual(140); + expect(await part1('testInput2')).toEqual(772); + expect(await part1('testInput3')).toEqual(1930); + expect(await part1('input')).toEqual(1424006); }); test('Part 2', async () => { diff --git a/2024/src/2024/day12/day12.ts b/2024/src/2024/day12/day12.ts index 91c3d61..6cce3d9 100644 --- a/2024/src/2024/day12/day12.ts +++ b/2024/src/2024/day12/day12.ts @@ -1,7 +1,6 @@ import path from "node:path"; import {readInputLineByLine} from "@utils/io"; -import {Coord, getNeighborCoords, getNeighbors, Grid, readLinesToGrid} from "@utils/grid"; -import * as module from "node:module"; +import {Coord, getNeighborCoords, Grid, readLinesToGrid} from "@utils/grid"; export async function part1(inputFile: string) { return await day12(inputFile, calcAreaAndPerimeter); @@ -19,20 +18,44 @@ async function day12(inputFile: string, calcFn?: (grid: Grid) => number) { } function calcAreaAndPerimeter(grid: Grid) { - let sum = 0; - const perimeterMap: Map = new Map(); - const areaMap: Map = new Map(); - - for (const [coord, cell] of grid) { - const neighbors = getNeighbors(Coord.deserialize(coord), grid); - const perimeter = 4 - neighbors.filter(n => n === cell).length; - perimeterMap.set(cell, (perimeterMap.get(cell) || 0) + perimeter); - areaMap.set(cell, (areaMap.get(cell) || 0) + 1); + const visited = new Set(); + + function floodFill(start: Coord) { + const stack: Coord[] = [start]; + const fieldId = grid.get(start.serialize()); + let area = 0; + let perimeter = 0; + + while (stack.length > 0) { + const current = stack.pop()!; + const currentStr = current.serialize(); + if (visited.has(currentStr)) + continue; + + visited.add(currentStr); + area++; + + for (const neighbor of getNeighborCoords(current)) { + if (grid.get(neighbor.serialize()) === fieldId) { + if (!visited.has(neighbor.serialize())) { + stack.push(neighbor); + } + } else { + perimeter++; + } + } + } + return { area, perimeter } } - for (let [key, value] of perimeterMap) { - sum += value * areaMap.get(key)!; + let totalCost = 0; + + for (const key of grid.keys()) { + if (!visited.has(key)) { + const { area, perimeter } = floodFill(Coord.deserialize(key))!; + totalCost += area * perimeter; + } } - return sum; + return totalCost; } \ No newline at end of file diff --git a/2024/src/2024/day12/testInput1 b/2024/src/2024/day12/testInput1 index cc213c5..cc5f968 100644 --- a/2024/src/2024/day12/testInput1 +++ b/2024/src/2024/day12/testInput1 @@ -1,5 +1,4 @@ -OOOOO -OXOXO -OOOOO -OXOXO -OOOOO \ No newline at end of file +AAAA +BBCD +BBCC +EEEC \ No newline at end of file diff --git a/2024/src/2024/day12/testInput2 b/2024/src/2024/day12/testInput2 index cc5f968..cc213c5 100644 --- a/2024/src/2024/day12/testInput2 +++ b/2024/src/2024/day12/testInput2 @@ -1,4 +1,5 @@ -AAAA -BBCD -BBCC -EEEC \ No newline at end of file +OOOOO +OXOXO +OOOOO +OXOXO +OOOOO \ No newline at end of file