Skip to content

Commit 69b1cf5

Browse files
committed
this would have been easier on a spreadsheet (i kinda forgot how to do pathfinding for a while on part 1 and was trying to do a bfs search but uuh… there are a lot of paths). anyway 40s runtime for part 2… not great
ok wait come on i thought advent of code problems were supposed to have some unique twist thing today's is literally the *example* for a https://github.com/bgrins/javascript-astar js a* library. like come on. literally take the output of that and subtract graph[0][0]. seriously? anyway it was fine. also i tried to prompt copilot to solve the entire problem for me but i wasn't fast enough at evaluating ok well day15.3 has what i should have done
1 parent 361e9c5 commit 69b1cf5

File tree

8 files changed

+946
-1
lines changed

8 files changed

+946
-1
lines changed

2021/solutions/day15/astar.js

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.

2021/solutions/day15/day15.1.ts

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import {fhmain} from "../../../src/fheader";
2+
fhmain(__filename);
3+
/*
4+
input: string, lines: string[], dblines: string[][]
5+
copy(text: string) → clipboard
6+
error(message: string) → thrown error
7+
-5..mod(3) → @mod(-5, 3)
8+
*/
9+
10+
// Cardinals:
11+
// [[1,0],[-1,0],[0,1],[0,-1]]
12+
// +Diagonals:
13+
// [[1,0],[-1,0],[0,1],[0,-1],[-1,-1],[-1,1],[1,-1],[1,1]]
14+
15+
export {};
16+
17+
const practice = `
18+
1163751742
19+
1381373672
20+
2136511328
21+
3694931569
22+
7463417111
23+
1319128137
24+
1359912421
25+
3125421639
26+
1293138521
27+
2311944581
28+
`;
29+
// input = practice;
30+
input = input.trim();
31+
32+
33+
const board = makeBoard(Infinity);
34+
input.split("\n").forEach((line, y) => {
35+
line.split("").forEach((c, x) => {
36+
board.set([x, y], +c);
37+
});
38+
});
39+
40+
const fastestPathToPoint = makeBoard(Infinity);
41+
42+
// function calculateRisk(path: Point2D[]): number {
43+
// let res = 0;
44+
// for(const step of path) {
45+
// res += board.get(step);
46+
// }
47+
// res -= board.get(path[0]!);
48+
// return res;
49+
// }
50+
51+
fastestPathToPoint.set([0, 0], 0);
52+
53+
function step() {
54+
let dv = false;
55+
fastestPathToPoint.forEach((v, pos) => {
56+
const c = board.get(pos);
57+
let min = v;
58+
for(const orth of cardinals) {
59+
const val = fastestPathToPoint.get(pos.add(orth)) + c;
60+
if(val < min) min = val;
61+
}
62+
if(min !== v && isFinite(min)) {
63+
dv = true;
64+
fastestPathToPoint.set(pos, min);
65+
}
66+
// console.log(pos, min);
67+
});
68+
return dv;
69+
}
70+
71+
while(step()) {}
72+
fastestPathToPoint.print(v => !isFinite(v) ? " " : "!").dwth(log);
73+
74+
const minv = vec(input.split("\n")[0].length - 1, input.split("\n").length - 1);
75+
76+
console.log(fastestPathToPoint.get(minv)); // expect=619
77+
78+
79+
80+
81+
82+
83+
type nobi = number | bigint;
84+
type Board<T> = {
85+
get(pos: Point2D): T;
86+
set(pos: Point2D, t: T): void;
87+
clear(): void;
88+
forEach(visitor: (v: T, pos: Point2D) => void): void;
89+
print(printer?: (v: T, pos: Point2D) => string | nobi): string;
90+
copy(): Board<T>;
91+
};
92+
function makeBoard<T>(fill: T): Board<T> {
93+
// it would be useful if board could center at 0,0 and expand infinitely
94+
let board: T[][] = [];
95+
let limits:
96+
| { min: Point2D, max: Point2D }
97+
| undefined;
98+
let reso: Board<T> = {
99+
clear: () => {
100+
board = [];
101+
},
102+
get: (pos) => {
103+
if (!limits) return fill;
104+
if (
105+
pos.op(limits.min, (a, b) => a < b).some(w => w) ||
106+
pos.op(limits.max, (a, b) => a > b).some(w => w)
107+
) return fill;
108+
if (!board[pos.y]) return fill;
109+
let bval = board[pos.y][pos.x];
110+
return bval === undefined ? fill : bval;
111+
},
112+
set: (pos, v) => {
113+
if (!limits) {
114+
limits = {min: dupe(pos), max: dupe(pos)};
115+
}
116+
limits.min = pos.op(limits.min, (a, b) => Math.min(a, b));
117+
limits.max = pos.op(limits.max, (a, b) => Math.max(a, b));
118+
if (!board[pos.y]) board[pos.y] = [];
119+
board[pos.y][pos.x] = v;
120+
},
121+
forEach: visitor => {
122+
if (!limits) return;
123+
const miny = limits.min.y - 1;
124+
const maxy = limits.max.y + 1;
125+
const minx = limits.min.x - 1;
126+
const maxx = limits.max.x + 1;
127+
for (let y = miny; y <= maxy; y++) {
128+
for (let x = minx; x <= maxx; x++) {
129+
visitor(reso.get([x, y]), [x, y]);
130+
}
131+
}
132+
},
133+
copy: () => {
134+
let nb = makeBoard<T>(fill);
135+
reso.forEach((v, pos) => nb.set(pos, v));
136+
return nb;
137+
},
138+
print: (printer = v => v as any): string => {
139+
// ratelimit print
140+
if (!limits) return "*no board to print*";
141+
let ylength = 0;
142+
for (let y = limits.min.y - 1; y <= limits.max.y + 1; y++) {
143+
ylength = Math.max(y.toString().length, ylength);
144+
}
145+
const resc: string[] = [];
146+
let llen: number = limits.max.x - limits.min.x + 3;
147+
for (let y = limits.min.y - 1; y <= limits.max.y + 1; y++) {
148+
let line = "";
149+
for (let x = limits.min.x - 1; x <= limits.max.x + 1; x++) {
150+
line += printer(reso.get([x, y]), [x, y]);
151+
}
152+
if(line.length > llen) llen = line.length;
153+
resc.push(y.toString().padStart(ylength, " ") + " | " + line + " |");
154+
}
155+
resc.unshift(
156+
" ".repeat(ylength) +
157+
" .-" +
158+
"-".repeat(llen) +
159+
"-. " + (limits.min.y - 1) + " .. " + (limits.max.y + 1),
160+
);
161+
resc.push(
162+
" ".repeat(ylength) +
163+
" '-" +
164+
"-".repeat(llen) +
165+
"-'",
166+
);
167+
return resc.join("\n");
168+
},
169+
};
170+
return reso;
171+
}

2021/solutions/day15/day15.2.ts

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import {fhmain} from "../../../src/fheader";
2+
fhmain(__filename);
3+
/*
4+
input: string, lines: string[], dblines: string[][]
5+
copy(text: string) → clipboard
6+
error(message: string) → thrown error
7+
-5..mod(3) → @mod(-5, 3)
8+
*/
9+
10+
// Cardinals:
11+
// [[1,0],[-1,0],[0,1],[0,-1]]
12+
// +Diagonals:
13+
// [[1,0],[-1,0],[0,1],[0,-1],[-1,-1],[-1,1],[1,-1],[1,1]]
14+
15+
export {};
16+
17+
const practice = `
18+
1163751742
19+
1381373672
20+
2136511328
21+
3694931569
22+
7463417111
23+
1319128137
24+
1359912421
25+
3125421639
26+
1293138521
27+
2311944581
28+
`;
29+
// input = practice;
30+
input = input.trim();
31+
32+
33+
const b0 = makeBoard(Infinity);
34+
input.split("\n").forEach((line, y) => {
35+
line.split("").forEach((c, x) => {
36+
b0.set([x, y], +c);
37+
});
38+
});
39+
40+
const board = makeBoard(Infinity);
41+
42+
43+
44+
let minv = vec(input.split("\n")[0].length, input.split("\n").length);
45+
46+
b0.forEach((tile, pos) => {
47+
if(!isFinite(tile)) return;
48+
49+
range(5).forEach((x) => {
50+
range(5).forEach((y) => {
51+
const dist = (x + y);
52+
board.set(pos.add(vec(x, y).mul(minv)), (((tile + dist) - 1) % 9) + 1);
53+
});
54+
});
55+
});
56+
57+
minv = minv.mul(vec(5, 5)).sub(vec(1, 1));
58+
59+
60+
const fastestPathToPoint = makeBoard(Infinity);
61+
62+
fastestPathToPoint.set([0, 0], 0);
63+
64+
function step() {
65+
let dv = false;
66+
fastestPathToPoint.forEach((v, pos) => {
67+
const c = board.get(pos);
68+
let min = v;
69+
for(const orth of cardinals) {
70+
const val = fastestPathToPoint.get(pos.add(orth)) + c;
71+
if(val < min) min = val;
72+
}
73+
if(min !== v && isFinite(min)) {
74+
dv = true;
75+
fastestPathToPoint.set(pos, min);
76+
}
77+
// console.log(pos, min);
78+
});
79+
return dv;
80+
}
81+
82+
while(step()) {}
83+
fastestPathToPoint.print(v => !isFinite(v) ? " " : "!").dwth(log);
84+
85+
console.log(fastestPathToPoint.get(minv)); // expect-slow expect=2922
86+
87+
88+
89+
90+
type nobi = number | bigint;
91+
type Board<T> = {
92+
get(pos: Point2D): T;
93+
set(pos: Point2D, t: T): void;
94+
clear(): void;
95+
forEach(visitor: (v: T, pos: Point2D) => void): void;
96+
print(printer?: (v: T, pos: Point2D) => string | nobi): string;
97+
copy(): Board<T>;
98+
};
99+
function makeBoard<T>(fill: T): Board<T> {
100+
// it would be useful if board could center at 0,0 and expand infinitely
101+
let board: T[][] = [];
102+
let limits:
103+
| { min: Point2D, max: Point2D }
104+
| undefined;
105+
let reso: Board<T> = {
106+
clear: () => {
107+
board = [];
108+
},
109+
get: (pos) => {
110+
if (!limits) return fill;
111+
if (
112+
pos.op(limits.min, (a, b) => a < b).some(w => w) ||
113+
pos.op(limits.max, (a, b) => a > b).some(w => w)
114+
) return fill;
115+
if (!board[pos.y]) return fill;
116+
let bval = board[pos.y][pos.x];
117+
return bval === undefined ? fill : bval;
118+
},
119+
set: (pos, v) => {
120+
if (!limits) {
121+
limits = {min: dupe(pos), max: dupe(pos)};
122+
}
123+
limits.min = pos.op(limits.min, (a, b) => Math.min(a, b));
124+
limits.max = pos.op(limits.max, (a, b) => Math.max(a, b));
125+
if (!board[pos.y]) board[pos.y] = [];
126+
board[pos.y][pos.x] = v;
127+
},
128+
// need a map instead of foreach this is dumb
129+
forEach: visitor => {
130+
if (!limits) return;
131+
const miny = limits.min.y - 1;
132+
const maxy = limits.max.y + 1;
133+
const minx = limits.min.x - 1;
134+
const maxx = limits.max.x + 1;
135+
for (let y = miny; y <= maxy; y++) {
136+
for (let x = minx; x <= maxx; x++) {
137+
visitor(reso.get([x, y]), [x, y]);
138+
}
139+
}
140+
},
141+
copy: () => {
142+
let nb = makeBoard<T>(fill);
143+
reso.forEach((v, pos) => nb.set(pos, v));
144+
return nb;
145+
},
146+
print: (printer = v => v as any): string => {
147+
// ratelimit print
148+
if (!limits) return "*no board to print*";
149+
let ylength = 0;
150+
for (let y = limits.min.y - 1; y <= limits.max.y + 1; y++) {
151+
ylength = Math.max(y.toString().length, ylength);
152+
}
153+
const resc: string[] = [];
154+
let llen: number = limits.max.x - limits.min.x + 3;
155+
for (let y = limits.min.y - 1; y <= limits.max.y + 1; y++) {
156+
let line = "";
157+
for (let x = limits.min.x - 1; x <= limits.max.x + 1; x++) {
158+
line += printer(reso.get([x, y]), [x, y]);
159+
}
160+
if(line.length > llen) llen = line.length;
161+
resc.push(y.toString().padStart(ylength, " ") + " | " + line + " |");
162+
}
163+
resc.unshift(
164+
" ".repeat(ylength) +
165+
" .-" +
166+
"-".repeat(llen) +
167+
"-. " + (limits.min.y - 1) + " .. " + (limits.max.y + 1),
168+
);
169+
resc.push(
170+
" ".repeat(ylength) +
171+
" '-" +
172+
"-".repeat(llen) +
173+
"-'",
174+
);
175+
return resc.join("\n");
176+
},
177+
};
178+
return reso;
179+
}

2021/solutions/day15/day15.3.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {fhmain} from "../../../src/fheader";
2+
fhmain(__filename);
3+
/*
4+
input: string, lines: string[], dblines: string[][]
5+
copy(text: string) → clipboard
6+
error(message: string) → thrown error
7+
-5..mod(3) → @mod(-5, 3)
8+
*/
9+
10+
// Cardinals:
11+
// [[1,0],[-1,0],[0,1],[0,-1]]
12+
// +Diagonals:
13+
// [[1,0],[-1,0],[0,1],[0,-1],[-1,-1],[-1,1],[1,-1],[1,1]]
14+
15+
export {};
16+
17+
const practice = `
18+
1163751742
19+
1381373672
20+
2136511328
21+
3694931569
22+
7463417111
23+
1319128137
24+
1359912421
25+
3125421639
26+
1293138521
27+
2311944581
28+
`;
29+
// input = practice;
30+
input = input.trim();
31+
32+
import * as as from "./astar.js";
33+
34+
const graph = new as.Graph(input.split("\n").map(line => line.split("").map(Number)));
35+
36+
const start = graph.grid[0][0];
37+
const end = graph.grid[graph.grid.length - 1][graph.grid[0].length - 1];
38+
const result = as.astar.search(graph, start, end);
39+
40+
console.log(result.reduce((t, w) => t + w.weight, 0)); // expect=619

0 commit comments

Comments
 (0)