From c543c6f4ac64a2c9801c18a99ac16e290fcf7e90 Mon Sep 17 00:00:00 2001 From: Pascal Syma Date: Tue, 10 Dec 2024 13:00:45 +0100 Subject: [PATCH] Solve 2024-09 (partly) --- 2024/09/2024-09.run.xml | 7 +++ 2024/09/index.test.ts | 16 ++++++ 2024/09/index.ts | 120 ++++++++++++++++++++++++++++++++++++++++ 2024/09/run.ts | 12 ++++ 4 files changed, 155 insertions(+) create mode 100644 2024/09/2024-09.run.xml create mode 100644 2024/09/index.test.ts create mode 100644 2024/09/index.ts create mode 100644 2024/09/run.ts diff --git a/2024/09/2024-09.run.xml b/2024/09/2024-09.run.xml new file mode 100644 index 0000000..3a22b07 --- /dev/null +++ b/2024/09/2024-09.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2024/09/index.test.ts b/2024/09/index.test.ts new file mode 100644 index 0000000..e3a61d2 --- /dev/null +++ b/2024/09/index.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst, solveSecond } from './index.ts'; + +describe('2024-09', () => { + const testInput = `2333133121414131402`; + it('first', () => { + expect(solveFirst('12345')).toBe( + 0 * 0 + 1 * 2 + 2 * 2 + 3 * 1 + 4 * 1 + 5 * 1 + 6 * 2 + 7 * 2 + 8 * 2 + ); + expect(solveFirst(testInput)).toBe(1928); + expect(solveFirst('233313312141413140256')).toBe(3383); + }); + it('second', () => { + expect(solveSecond(testInput)).toBe(2858); + }); +}); diff --git a/2024/09/index.ts b/2024/09/index.ts new file mode 100644 index 0000000..02a77d9 --- /dev/null +++ b/2024/09/index.ts @@ -0,0 +1,120 @@ +import { sumArray } from '../../utils/array.ts'; + +export function solveFirst(input: string): number { + const finalPositions = decompressInput(input); + + let l = 0; + let r = finalPositions.length - 1; + while (l < r) { + if (finalPositions[l] !== -1) { + l++; + continue; + } + + if (finalPositions[r] === -1) { + r--; + continue; + } + + finalPositions[l] = finalPositions[r]; + finalPositions[r] = -1; + l++; + r--; + } + + return sumArray(finalPositions.map((v, i) => (v > 0 ? v * i : 0))); +} + +function decompressInput(input: string) { + const len = input.length; + const finalPositions: number[] = []; + + for (let i = 0; i < len; i++) { + const amount = Number(input[i]); + + const id = i % 2 === 0 ? Math.floor(i / 2) : -1; + for (let j = 0; j < amount; j++) { + finalPositions.push(id); + } + } + return finalPositions; +} + +function getSpaceMap(memory: number[]) { + const spaces = Array.from({ length: 10 }, () => [] as number[]); + + let i = 0; + while (i < memory.length) { + if (memory[i] >= 0) { + // not a space + i++; + continue; + } + + let size = 0; + while (memory[i] < 0) { + size++; + i++; + } + + // push start position + spaces[size].push(i - size); + } + + return spaces; +} + +export function solveSecond(input: string): number { + const finalPositions = decompressInput(input); + const spaces = getSpaceMap(finalPositions); + + // TODO: theres bug in her somewhere + + let moved: number[] = []; + let r = finalPositions.length - 1; + while (r > 0) { + if (finalPositions[r] < 0) { + // spaces can't be moved + r--; + continue; + } + + let size = 0; + const id = finalPositions[r]; + while (finalPositions[r] === id) { + r--; + size++; + } + + const firstFreeSpaceSize = spaces.findIndex( + (sp, si) => si >= size && sp.length > 0 && sp[0] < r + ); + + if (firstFreeSpaceSize < 0) { + continue; + } + + const spaceIdx = spaces[firstFreeSpaceSize].shift()!; + + if (moved.includes(id)) { + continue; + } + moved.push(id); + for (let i = 0; i < size; i++) { + finalPositions[r + i + 1] = -1; + finalPositions[spaceIdx + i] = id; + } + + const spaceDiff = firstFreeSpaceSize - size; + if (spaceDiff > 0) { + spaces[spaceDiff].push(spaceIdx + firstFreeSpaceSize - spaceDiff); + spaces[spaceDiff].sort((a, b) => a - b); + } + + // r = position; + } + + // console.log(finalPositions); + + return sumArray(finalPositions.map((v, i) => (v > 0 ? v * i : 0))); +} diff --git a/2024/09/run.ts b/2024/09/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2024/09/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);