From 63a7a93aba64685aa220a67a512c0600e02abdca Mon Sep 17 00:00:00 2001
From: Pascal Syma
Date: Sun, 7 Dec 2025 12:40:54 +0100
Subject: [PATCH] Solve 2025-07
---
2025/07/2025-07.run.xml | 7 ++++++
2025/07/index.test.ts | 27 ++++++++++++++++++++++
2025/07/index.ts | 51 +++++++++++++++++++++++++++++++++++++++++
2025/07/run.ts | 12 ++++++++++
utils/multi-map.ts | 12 ++++++++++
5 files changed, 109 insertions(+)
create mode 100644 2025/07/2025-07.run.xml
create mode 100644 2025/07/index.test.ts
create mode 100644 2025/07/index.ts
create mode 100644 2025/07/run.ts
diff --git a/2025/07/2025-07.run.xml b/2025/07/2025-07.run.xml
new file mode 100644
index 0000000..99b7111
--- /dev/null
+++ b/2025/07/2025-07.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2025/07/index.test.ts b/2025/07/index.test.ts
new file mode 100644
index 0000000..c6b3718
--- /dev/null
+++ b/2025/07/index.test.ts
@@ -0,0 +1,27 @@
+import { describe, expect, it } from 'bun:test';
+import { solveFirst, solveSecond } from './index.ts';
+
+describe('2025-07', () => {
+ const testInput = `.......S.......
+...............
+.......^.......
+...............
+......^.^......
+...............
+.....^.^.^.....
+...............
+....^.^...^....
+...............
+...^.^...^.^...
+...............
+..^...^.....^..
+...............
+.^.^.^.^.^...^.
+...............`;
+ it('first', () => {
+ expect(solveFirst(testInput)).toBe(21);
+ });
+ it('second', () => {
+ expect(solveSecond(testInput)).toBe(40);
+ });
+});
diff --git a/2025/07/index.ts b/2025/07/index.ts
new file mode 100644
index 0000000..d01875f
--- /dev/null
+++ b/2025/07/index.ts
@@ -0,0 +1,51 @@
+import { MultiMap } from '../../utils/multi-map.ts';
+
+export function solveFirst(input: string): number {
+ const rows = input.split('\n');
+ const start = rows[0].indexOf('S');
+
+ const beams = new Set([start]);
+
+ let splits = 0;
+ for (let y = 1; y < rows.length; y++) {
+ const newBeams: number[] = [];
+ beams.forEach((beam) => {
+ if (rows[y][beam] === '.' || beam >= rows[y].length) {
+ return;
+ }
+ if (rows[y][beam] === '^') {
+ splits++;
+ beams.delete(beam);
+ newBeams.push(beam - 1);
+ newBeams.push(beam + 1);
+ }
+ });
+ newBeams.forEach((b) => beams.add(b));
+ }
+
+ return splits;
+}
+
+export function solveSecond(input: string): number {
+ const rows = input.split('\n');
+ const start = rows[0].indexOf('S');
+
+ return solveDown(rows, 1, start);
+}
+
+const cache = new MultiMap();
+function solveDown(map: string[], startY: number, startX: number): number {
+ if (cache.multiHas(startY, startX)) {
+ return cache.multiGet(startY, startX)!;
+ }
+ for (let y = startY; y < map.length; y++) {
+ if (map[y][startX] === '^') {
+ return cache.multiSet(
+ solveDown(map, y + 1, startX - 1) + solveDown(map, y + 1, startX + 1),
+ startY,
+ startX
+ );
+ }
+ }
+ return 1;
+}
diff --git a/2025/07/run.ts b/2025/07/run.ts
new file mode 100644
index 0000000..88783cd
--- /dev/null
+++ b/2025/07/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);
diff --git a/utils/multi-map.ts b/utils/multi-map.ts
index 5d85e59..e729c6b 100644
--- a/utils/multi-map.ts
+++ b/utils/multi-map.ts
@@ -11,6 +11,18 @@ export class MultiMap extends Map {
}
return this.get(firstKey) as V;
}
+ multiHas(...keys: K): boolean {
+ const firstKey = keys[0];
+ const otherKeys = keys.slice(1);
+ if (!this.has(firstKey)) {
+ return false;
+ }
+
+ if (otherKeys.length > 0) {
+ return (this.get(firstKey)! as MultiMap).multiHas(...otherKeys);
+ }
+ return this.has(firstKey);
+ }
multiSet(value: V, ...keys: K) {
const firstKey = keys[0];