diff --git a/2024/08/2024-08.run.xml b/2024/08/2024-08.run.xml new file mode 100644 index 0000000..4c31942 --- /dev/null +++ b/2024/08/2024-08.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2024/08/index.test.ts b/2024/08/index.test.ts new file mode 100644 index 0000000..c5d859d --- /dev/null +++ b/2024/08/index.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst, solveSecond } from './index.ts'; + +describe('2024-08', () => { + const testInput = `............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............`; + it('first', () => { + expect(solveFirst(testInput)).toBe(14); + }); + it('second', () => { + const secondTest = `T......... +...T...... +.T........ +.......... +.......... +.......... +.......... +.......... +.......... +..........`; + expect(solveSecond(testInput)).toBe(34); + expect(solveSecond(secondTest)).toBe(9); + }); +}); diff --git a/2024/08/index.ts b/2024/08/index.ts new file mode 100644 index 0000000..1d7b89c --- /dev/null +++ b/2024/08/index.ts @@ -0,0 +1,81 @@ +import { combinations, unique } from '../../utils/array.ts'; +import { inBounds, isCoordinateEqual } from '../../utils/coordinates.ts'; + +export function solveFirst(input: string): number { + const rows = input.split('\n'); + + const antennas = new Map(); + + for (let y = 0; y < rows.length; y++) { + for (let x = 0; x < rows[y].length; x++) { + const digit = rows[y][x]; + if (digit === '.') { + continue; + } + const entry = antennas.get(digit) || []; + entry.push([x, y]); + antennas.set(digit, entry); + } + } + const antiNodes: [number, number][] = []; + + // console.log(rows); + // console.log(antennas); + antennas.forEach((positions) => { + combinations(positions).forEach(({ a, b }) => + antiNodes.push([a[0] - (b[0] - a[0]), a[1] - (b[1] - a[1])]) + ); + }); + + const validAntiNodes = antiNodes + .filter(inBounds(rows[0].length, rows.length)) + .filter(unique(isCoordinateEqual)); + + // validAntiNodes.forEach(([x, y]) => rows[y][x] === '.' && replaceChar(rows, x, y, '#')); + // + // console.log(rows.join('\n')); + return validAntiNodes.length; +} + +export function solveSecond(input: string): number { + const rows = input.split('\n'); + + const antennas = new Map(); + + const yMax = rows.length; + const xMax = rows[0].length; + + for (let y = 0; y < yMax; y++) { + for (let x = 0; x < xMax; x++) { + const digit = rows[y][x]; + if (digit === '.') { + continue; + } + const entry = antennas.get(digit) || []; + entry.push([x, y]); + antennas.set(digit, entry); + } + } + const antiNodes: [number, number][] = []; + + antennas.forEach((positions) => { + combinations(positions).forEach(({ a, b }) => { + for (let y = 0; y < yMax; y++) { + antiNodes.push([a[0] + (b[0] - a[0]) * y, a[1] + (b[1] - a[1]) * y]); + } + }); + }); + + const validAntiNodes = antiNodes + .filter(inBounds(rows[0].length, rows.length)) + .filter(unique(isCoordinateEqual)); + + // console.log(validAntiNodes); + // validAntiNodes.forEach( + // ([x, y]) => rows[y][x] === '.' && replaceChar(rows, x, y, '#') + // ); + // + // console.log(rows.join('\n')); + + return validAntiNodes.length; +} diff --git a/2024/08/run.ts b/2024/08/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2024/08/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);