Skip to content

Commit 499bcd1

Browse files
committed
feat: 2025 Day 10 Part 2
closes #13
1 parent baccd69 commit 499bcd1

6 files changed

Lines changed: 157 additions & 53 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

2025/day/10/part/2/solve.mts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import process from "node:process";
2+
import { text } from "node:stream/consumers";
3+
import { init } from "z3-solver";
4+
import { parseManual } from "../../manuals.ts";
5+
6+
export default async function solve(input: string) {
7+
const manual = parseManual(input);
8+
const { Context } = await init();
9+
let sum = 0;
10+
for (const { buttons, requirements } of manual) {
11+
const { Int, Optimize } = Context("main");
12+
const variables = buttons.map((_, i) => Int.const(`b${i}`));
13+
const optimize = new Optimize();
14+
optimize.add(
15+
...requirements.map((requirement, lightIndex) =>
16+
buttons.keys()
17+
.filter((buttonIndex) => buttons[buttonIndex].includes(lightIndex))
18+
.map((buttonIndex) => variables[buttonIndex])
19+
.reduce((a, b) => a.add(b), Int.val(0))
20+
.eq(Int.val(requirement))
21+
),
22+
...variables.map((variable) => variable.ge(0)),
23+
);
24+
const sumExpression = variables.reduce((a, x) => a.add(x), Int.val(0));
25+
optimize.minimize(sumExpression);
26+
if (await optimize.check() !== "sat") throw new Error("No solution found");
27+
sum += +optimize.model().eval(sumExpression);
28+
}
29+
return sum;
30+
}
31+
32+
const input = await text(process.stdin);
33+
const output = await solve(input);
34+
console.log(output);

2025/day/10/part/2/solve.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("example", async () => {
6+
const input = `\
7+
[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
8+
[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
9+
[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}`;
10+
11+
assertEquals(await solve(input), 33);
12+
});

2025/day/10/part/2/solve.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/** delegates to Node.js until https://github.com/denoland/deno/issues/17171 is fixed */
2+
export default async function solve(input: string) {
3+
const command = new Deno.Command("node", {
4+
args: [`${import.meta.dirname}/solve.mts`],
5+
stdin: "piped",
6+
stdout: "piped",
7+
});
8+
9+
const child = command.spawn();
10+
const writer = child.stdin.getWriter();
11+
await writer.write(new TextEncoder().encode(input));
12+
writer.releaseLock();
13+
await child.stdin.close();
14+
15+
const { stdout } = await child.output();
16+
return +new TextDecoder().decode(stdout);
17+
}

deno.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{
2+
"nodeModulesDir": "auto",
23
"tasks": {
34
"prepare": "cp -r :year/day/:day",
45
"serve": "deno run -A main.ts",
56
"solve": "./bin/aoc.ts solve"
67
},
78
"imports": {
89
"@deno/emit": "jsr:@deno/emit@^0.46.0",
9-
"@graph-algorithm/minimum-cut": "https://esm.sh/@graph-algorithm/minimum-cut@2.0.0",
10+
"@graph-algorithm/minimum-cut": "npm:@graph-algorithm/minimum-cut@^2.0.0",
1011
"@lib/": "./lib/",
1112
"@std/assert": "jsr:@std/assert@^1.0.9",
1213
"@std/cli": "jsr:@std/cli@^1.0.8",
@@ -15,6 +16,7 @@
1516
"@std/fs": "jsr:@std/fs@^1.0.6",
1617
"@std/path": "jsr:@std/path@^1.0.8",
1718
"nerdamer": "npm:nerdamer@^1.1.13",
18-
"pretty-ms": "npm:pretty-ms@^9.3.0"
19+
"pretty-ms": "npm:pretty-ms@^9.3.0",
20+
"z3-solver": "npm:z3-solver@^4.15.4"
1921
}
2022
}

deno.lock

Lines changed: 89 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)