From 86a11722822b25f3e3a70a4de44239ac97ae3d0a Mon Sep 17 00:00:00 2001 From: Joshua Seigler Date: Thu, 12 Dec 2024 13:26:52 -0500 Subject: [PATCH] day 12, part 1 only --- .aocrunner.json | 6 +- README.md | 16 ++-- src/day12/README.md | 9 +++ src/day12/index.ts | 185 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 src/day12/README.md create mode 100644 src/day12/index.ts diff --git a/.aocrunner.json b/.aocrunner.json index 61e78cf..31cd60c 100644 --- a/.aocrunner.json +++ b/.aocrunner.json @@ -175,9 +175,11 @@ }, { "part1": { - "solved": false, + "solved": true, "result": null, - "attempts": [], + "attempts": [ + "813344" + ], "time": null }, "part2": { diff --git a/README.md b/README.md index cfc84f5..da1c8d9 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ [![Day](https://badgen.net/badge/09/%E2%98%85%E2%98%85/green)](src/day09) [![Day](https://badgen.net/badge/10/%E2%98%85%E2%98%85/green)](src/day10) [![Day](https://badgen.net/badge/11/%E2%98%85%E2%98%85/green)](src/day11) -![Day](https://badgen.net/badge/12/%E2%98%86%E2%98%86/gray) +[![Day](https://badgen.net/badge/12/%E2%98%85%E2%98%86/yellow)](src/day12) ![Day](https://badgen.net/badge/13/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/14/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/15/%E2%98%86%E2%98%86/gray) @@ -139,16 +139,16 @@ Both parts: 11.016ms ``` Day 11 -Time part 1: 54.46ms -Time part 2: 130.251ms -Both parts: 184.711ms +Time part 1: 4.472ms +Time part 2: 126.218ms +Both parts: 130.69ms ``` ``` Day 12 -Time part 1: - +Time part 1: 197.261ms Time part 2: - -Both parts: - +Both parts: 197.261ms ``` ``` @@ -243,8 +243,8 @@ Both parts: - ``` ``` -Total stars: 22/50 -Total time: 38569.05ms +Total stars: 23/50 +Total time: 38712.29ms ``` diff --git a/src/day12/README.md b/src/day12/README.md new file mode 100644 index 0000000..31f66b7 --- /dev/null +++ b/src/day12/README.md @@ -0,0 +1,9 @@ +# 🎄 Advent of Code 2024 - day 12 🎄 + +## Info + +Task description: [link](https://adventofcode.com/2024/day/12) + +## Notes + +... \ No newline at end of file diff --git a/src/day12/index.ts b/src/day12/index.ts new file mode 100644 index 0000000..81191ca --- /dev/null +++ b/src/day12/index.ts @@ -0,0 +1,185 @@ +import run from "aocrunner" + +const parseInput = (rawInput: string) => rawInput.split('\n').map(line => line.split('')) + +const directions = [ + [-1, 0], // up + [0, 1], // right + [1, 0], // down + [0, -1] // left +] +const getNeighbors = (r: number, c: number) => { + return directions.map(([dr, dc]) => [r + dr, c + dc]) +} + +const getKey = (items: unknown[]) => { + return items.join(',') +} +type Key = ReturnType + +type Region = { + symbol: string + area: number + perimeter: number + plots: Key[] +} + +const part1 = (rawInput: string) => { + const input = parseInput(rawInput) + let regions = new Set() + + input.forEach((row, r) => { + row.forEach((symbol, c) => { + const key = getKey([r, c]) + const neighbors = getNeighbors(r, c).map(getKey) + let touches = 0 + let matchingRegions: Region[] = [] + regions.forEach(region => { + if (region.symbol !== symbol) return + const newTouches = region.plots.filter(c => neighbors.includes(c)).length + if (newTouches > 0) { + touches += newTouches + matchingRegions.push(region) + regions.delete(region) + } + }) + const newRegion = matchingRegions.reduce((acc, cur) => { + acc.area += cur.area + acc.perimeter += cur.perimeter + acc.plots.push(...cur.plots) + return acc + }, { + symbol, + area: 1, + perimeter: 4 - 2 * touches, + plots: [key], + }) + regions.add(newRegion) + }) + }) + return Array.from(regions).reduce((total, region) => total + region.perimeter * region.area, 0) +} + +const part2 = (rawInput: string) => { + const input = parseInput(rawInput) + let regions = new Set() + + input.forEach((row, r) => { + row.forEach((symbol, c) => { + const key = getKey([r, c]) + const neighbors = getNeighbors(r, c).map(getKey) + let touches = 0 + let matchingRegions: Region[] = [] + regions.forEach(region => { + if (region.symbol !== symbol) return + const newTouches = region.plots.filter(c => neighbors.includes(c)).length + if (newTouches > 0) { + touches += newTouches + matchingRegions.push(region) + regions.delete(region) + } + }) + const newRegion = matchingRegions.reduce((acc, cur) => { + acc.area += cur.area + acc.perimeter += cur.perimeter + acc.plots.push(...cur.plots) + return acc + }, { + symbol, + area: 1, + perimeter: 4 - 2 * touches, + plots: [key], + }) + regions.add(newRegion) + }) + }) + + return Array.from(regions).reduce((total, { + symbol, + plots, + area, + }) => { + let corners = 0 + plots.forEach(plot => { + const [r, c] = plot.split(',').map(Number) + const boundaries = getNeighbors(r, c).map(getKey).map((k, i) => plots.includes(k) ? '' : i).join('') + switch(boundaries) { + case '0123': + corners += 4 + break + case '01': + case '12': + case '23': + case '03': + corners += 1 + break + case '012': + case '123': + case '023': + case '013': + corners += 2 + break + } + }) + console.log(`Region of ${symbol} with ${corners} sides`) + return total + corners * area + }, 0) +} + +run({ +// part1: { +// tests: [ +// { +// input: `AAAA +// BBCD +// BBCC +// EEEC`, +// expected: 140, +// }, +// { +// input: `OOOOO +// OXOXO +// OOOOO +// OXOXO +// OOOOO`, expected: 772 +// }, +// { +// input: `RRRRIICCFF +// RRRRIICCCF +// VVRRRCCFFF +// VVRCCCJFFF +// VVVVCJJCFE +// VVIVCCJJEE +// VVIIICJJEE +// MIIIIIJJEE +// MIIISIJEEE +// MMMISSJEEE`, +// expected: 1930 +// } +// ], +// solution: part1, +// }, + part2: { + tests: [ + { + input: `AAAA +BBCD +BBCC +EEEC`, + expected: 80, + }, + { + input: `AAAAAA +AAABBA +AAABBA +ABBAAA +ABBAAA +AAAAAA`, + expected: 1206, + } + ], + solution: part2, + }, + trimTestInputs: true, + onlyTests: true, +})