import { Dusa } from "https://unpkg.com/dusa@0.0.10/lib/client.js";
const INPUT = `
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....
`
.trim()
.split("\n")
.map((line) => line.trim().split(""));
const PROGRAM = `
# AOC Day 11
#builtin NAT_SUCC s
#builtin INT_TIMES times
#builtin INT_PLUS plus
#builtin INT_MINUS minus
# Process input to get X, Y coordinates
charAt X Y is Ch :-
field _ "map" is List,
field List Y is Cols,
field Cols X is Ch.
width is W :- field _ "width" is W.
expansionFactor is F :- field _ "expansionFactor" is F.
# Use default reasoning to find out which rows/cols have stars
hasStar y Y is { false? } :- charAt _ Y is _.
hasStar y Y is true :- charAt _ Y is "#".
hasStar x X is { false? } :- charAt X _ is _.
hasStar x X is true :- charAt X _ is "#".
needsRemap x 0 0.
needsRemap y 0 0.
remap Axis Old is (minus (plus New expansionFactor) 1) :-
needsRemap Axis Old New,
hasStar Axis Old is false.
remap Axis Old is New :-
needsRemap Axis Old New,
hasStar Axis Old is true.
needsRemap Axis (s Old) (s New) :-
remap Axis Old is New.
starAt (remap x X) (remap y Y) :-
charAt X Y is "#".
starDist (tuple X YA X YB) is (minus YA YB) :-
starAt X YA,
starAt X YB,
YA > YB.
starDist (tuple XA YA XB YB) is (plus (minus XA XB) (minus YA YB)) :-
starAt XA YA,
starAt XB YB,
XA > XB, YA >= YB.
starDist (tuple XA YA XB YB) is (plus (minus XA XB) (minus YB YA)) :-
starAt XA YA,
starAt XB YB,
XA > XB, YA < YB.
`;
for (const expansionFactor of [2, 10, 100, 1000000]) {
const dusa = new Dusa(PROGRAM);
dusa.load({ map: INPUT, width: INPUT[0].length, expansionFactor }, "field");
const solution = dusa.sample();
let accum = 0n;
for (const [_, dist] of solution.lookup("starDist")) {
accum += dist;
}
console.log(accum);
}