From 0d09d361f60c6c6d97c3b29bba7c966307c3273d Mon Sep 17 00:00:00 2001 From: Pascal Syma Date: Tue, 10 Dec 2024 14:03:35 +0100 Subject: [PATCH] Solve 2024-10 --- 2024/10/2024-10.run.xml | 7 +++ 2024/10/index.test.ts | 80 +++++++++++++++++++++++++++++++++ 2024/10/index.ts | 98 +++++++++++++++++++++++++++++++++++++++++ 2024/10/run.ts | 12 +++++ 4 files changed, 197 insertions(+) create mode 100644 2024/10/2024-10.run.xml create mode 100644 2024/10/index.test.ts create mode 100644 2024/10/index.ts create mode 100644 2024/10/run.ts diff --git a/2024/10/2024-10.run.xml b/2024/10/2024-10.run.xml new file mode 100644 index 0000000..260478e --- /dev/null +++ b/2024/10/2024-10.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2024/10/index.test.ts b/2024/10/index.test.ts new file mode 100644 index 0000000..29573d7 --- /dev/null +++ b/2024/10/index.test.ts @@ -0,0 +1,80 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst, solveSecond } from './index.ts'; + +describe('2024-10', () => { + const testInput = `89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732`; + it('first', () => { + expect( + solveFirst(`0123 +1234 +8765 +9876`) + ).toBe(1); + expect( + solveFirst(`...0... +...1... +...2... +6543456 +7.....7 +8.....8 +9.....9`) + ).toBe(2); + expect( + solveFirst(`..90..9 +...1.98 +...2..7 +6543456 +765.987 +876.... +987....`) + ).toBe(4); + expect( + solveFirst(`10..9.. +2...8.. +3...7.. +4567654 +...8..3 +...9..2 +.....01`) + ).toBe(3); + + expect(solveFirst(testInput)).toBe(36); + }); + it('second', () => { + expect( + solveSecond(`.....0. +..4321. +..5..2. +..6543. +..7..4. +..8765. +..9....`) + ).toBe(3); + + expect( + solveSecond(`..90..9 +...1.98 +...2..7 +6543456 +765.987 +876.... +987....`) + ).toBe(13); + expect( + solveSecond(`012345 +123456 +234567 +345678 +4.6789 +56789.`) + ).toBe(227); + expect(solveSecond(testInput)).toBe(81); + }); +}); diff --git a/2024/10/index.ts b/2024/10/index.ts new file mode 100644 index 0000000..d7178ef --- /dev/null +++ b/2024/10/index.ts @@ -0,0 +1,98 @@ +import { sumArray, unique } from '../../utils/array.ts'; +import { + type Coordinates, + findCoordsOfDigit, + getAdjacent, + isCoordinateEqual +} from '../../utils/coordinates.ts'; + +export function getScoreOfHead( + rows: string[], + startX: number, + startY: number, + startDigit = 0 +): Coordinates { + if (startDigit >= 9) { + return [[startX, startY]]; + } + + const top = rows[startY - 1]?.[startX]; + const right = rows[startY]?.[startX + 1]; + const down = rows[startY + 1]?.[startX]; + const left = rows[startY]?.[startX - 1]; + + let found: Coordinates = []; + const lookFor = startDigit + 1; + + if (top && Number(top) === lookFor) { + found.push(...getScoreOfHead(rows, startX, startY - 1, lookFor)); + } + if (right && Number(right) === lookFor) { + found.push(...getScoreOfHead(rows, startX + 1, startY, lookFor)); + } + if (down && Number(down) === lookFor) { + found.push(...getScoreOfHead(rows, startX, startY + 1, lookFor)); + } + if (left && Number(left) === lookFor) { + found.push(...getScoreOfHead(rows, startX - 1, startY, lookFor)); + } + + return found; +} + +export function solveFirst(input: string): number { + const rows = input.split('\n'); + + const trailHeads = findCoordsOfDigit(rows, '0'); + + const scores = trailHeads.map( + ([startX, startY]) => + getScoreOfHead(rows, startX, startY).filter(unique(isCoordinateEqual)) + .length + ); + + return sumArray(scores); +} + +export function getRatingOfHead( + rows: string[], + startX: number, + startY: number, + startDigit = 0 +): Coordinates[] { + if (startDigit >= 9) { + return [[[startX, startY]]]; + } + + const { top, right, left, down } = getAdjacent(rows, startX, startY); + + let found: Coordinates[] = []; + const lookFor = startDigit + 1; + + if (top && Number(top) === lookFor) { + found.push(...getRatingOfHead(rows, startX, startY - 1, lookFor)); + } + if (right && Number(right) === lookFor) { + found.push(...getRatingOfHead(rows, startX + 1, startY, lookFor)); + } + if (down && Number(down) === lookFor) { + found.push(...getRatingOfHead(rows, startX, startY + 1, lookFor)); + } + if (left && Number(left) === lookFor) { + found.push(...getRatingOfHead(rows, startX - 1, startY, lookFor)); + } + + return found; +} + +export function solveSecond(input: string): number { + const rows = input.split('\n'); + + const trailHeads = findCoordsOfDigit(rows, '0'); + + const scores = trailHeads.map( + ([startX, startY]) => getRatingOfHead(rows, startX, startY).length + ); + + return sumArray(scores); +} diff --git a/2024/10/run.ts b/2024/10/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2024/10/run.ts @@ -0,0 +1,12 @@ +import { join } from 'path'; +import { solveFirst, solveSecond } from './index.ts'; + +const input = await Bun.file(join(__dirname, 'input.txt')).text(); + +const firstAnswer = solveFirst(input); + +console.log(firstAnswer); + +const secondAnswer = solveSecond(input); + +console.log(secondAnswer);