From 20bcd886006ee5cab05b772dd96a00a049d78daa Mon Sep 17 00:00:00 2001 From: Joshua Seigler Date: Tue, 10 Dec 2024 02:04:30 -0500 Subject: [PATCH] day 10 --- .aocrunner.json | 12 ++-- README.md | 18 +++--- src/day10/README.md | 9 +++ src/day10/index.ts | 136 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 src/day10/README.md create mode 100644 src/day10/index.ts diff --git a/.aocrunner.json b/.aocrunner.json index 8a2e086..e83d838 100644 --- a/.aocrunner.json +++ b/.aocrunner.json @@ -145,16 +145,16 @@ }, { "part1": { - "solved": false, - "result": null, + "solved": true, + "result": "782", "attempts": [], - "time": null + "time": 6.147158 }, "part2": { - "solved": false, - "result": null, + "solved": true, + "result": "1694", "attempts": [], - "time": null + "time": 4.868614 } }, { diff --git a/README.md b/README.md index a975eb6..09eb59d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [![Day](https://badgen.net/badge/07/%E2%98%85%E2%98%85/green)](src/day07) [![Day](https://badgen.net/badge/08/%E2%98%85%E2%98%85/green)](src/day08) [![Day](https://badgen.net/badge/09/%E2%98%85%E2%98%85/green)](src/day09) -![Day](https://badgen.net/badge/10/%E2%98%86%E2%98%86/gray) +[![Day](https://badgen.net/badge/10/%E2%98%85%E2%98%85/green)](src/day10) ![Day](https://badgen.net/badge/11/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/12/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/13/%E2%98%86%E2%98%86/gray) @@ -125,16 +125,16 @@ Both parts: 1.863ms ``` Day 09 -Time part 1: 239.635ms -Time part 2: 53.494ms -Both parts: 293.129ms +Time part 1: 236.521ms +Time part 2: 51.928ms +Both parts: 288.449ms ``` ``` Day 10 -Time part 1: - -Time part 2: - -Both parts: - +Time part 1: 6.148ms +Time part 2: 4.028ms +Both parts: 10.176ms ``` ``` @@ -243,8 +243,8 @@ Both parts: - ``` ``` -Total stars: 18/50 -Total time: 38378.002ms +Total stars: 20/50 +Total time: 38383.499ms ``` diff --git a/src/day10/README.md b/src/day10/README.md new file mode 100644 index 0000000..9e7a6f6 --- /dev/null +++ b/src/day10/README.md @@ -0,0 +1,9 @@ +# 🎄 Advent of Code 2024 - day 10 🎄 + +## Info + +Task description: [link](https://adventofcode.com/2024/day/10) + +## Notes + +... \ No newline at end of file diff --git a/src/day10/index.ts b/src/day10/index.ts new file mode 100644 index 0000000..94ba612 --- /dev/null +++ b/src/day10/index.ts @@ -0,0 +1,136 @@ +import run from "aocrunner" + +const parseInput = (rawInput: string) => rawInput.split('\n').map(line => line.split('').map(Number)) + +const directions = [ + [-1, 0], // up + [0, 1], // right + [1, 0], // down + [0, -1] // left +] + +const sum = (a,b) => a + b + +const getKey = (r: number, c: number) => `${r},${c}` +type Key = ReturnType + +const part1 = (rawInput: string) => { + const input = parseInput(rawInput) + const trailheads: Key[] = [] + const exitsMap = new Map() + const get = (r: number, c: number) => { + return (input[r] ?? [])[c] + } + input.forEach((row, r) => { + row.forEach((alt, c) => { + const key = getKey(r, c) + if (alt === 0) { + trailheads.push(key) + } + const outs: Key[] = [] + directions.forEach(([dr, dc]) => { + if (get(r + dr, c + dc) === alt + 1) { + outs.push(getKey(r + dr, c + dc)) + } + }) + exitsMap.set(key, outs) + }) + }) + const reachablePeaks = new Map>() + const hike = (key: Key, alt: number = 0): Set => { + let ans = reachablePeaks.get(key) + if (ans !== undefined) return ans + ans = new Set() + if (alt === 9) { + ans.add(key) + reachablePeaks.set(key, ans) + return ans + } + const branches = (exitsMap.get(key) ?? []).map(k => hike(k,alt+1)) + branches.forEach(peaks => { + peaks.forEach(peak => ans.add(peak)) + }) + reachablePeaks.set(key, ans) + return ans + } + return trailheads.map(t => hike(t).size).reduce(sum, 0) +} + +const part2 = (rawInput: string) => { + const input = parseInput(rawInput) + const trailheads: Key[] = [] + const exitsMap = new Map() + const get = (r: number, c: number) => { + return (input[r] ?? [])[c] + } + input.forEach((row, r) => { + row.forEach((alt, c) => { + const key = getKey(r, c) + if (alt === 0) { + trailheads.push(key) + } + const outs: Key[] = [] + directions.forEach(([dr, dc]) => { + if (get(r + dr, c + dc) === alt + 1) { + outs.push(getKey(r + dr, c + dc)) + } + }) + exitsMap.set(key, outs) + }) + }) + const cache = new Map() + const hike = (key: Key, alt: number): number => { + if (alt === 9) { + return 1 + } + let ans = cache.get(key) + if (ans !== undefined) return ans + const exitTotals = (exitsMap.get(key) ?? []).map(k => hike(k,alt+1)) + ans = exitTotals.reduce(sum, 0) + cache.set(key, ans) + return ans + } + return trailheads.map(t => hike(t,0)).reduce(sum, 0) +} + +run({ + part1: { + tests: [ + { + input: `0123 +1234 +8765 +9876`, + expected: 1, + }, + ], + solution: part1, + }, + part2: { + tests: [ + { + input: `012345 +123456 +234567 +345678 +4.6789 +56789.`, +expected: 227 + }, + { + input: `89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732`, + expected: 81, + }, + ], + solution: part2, + }, + trimTestInputs: true, + onlyTests: false, +})