Best of days, worst of days!
My solution ended up totally generic between part 1 and part 2, I just needed to add a fact expansionFactor is N
, where N
is 2
for part 1 and 1000000
for part 2, as well as a fact charAt X Y is "#"
or charAt X Y is "."
depending on what the character is.
Dusa’s default reasoning is great for saying which rows and columns have stars or not:
**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 "#".**
Then we remap the old X and Y coordinates to new X and Y coordinates based on whether rows are empty and full.
**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.**
Stars are just remapped chars.
**starAt (remap x X) (remap y Y) :-
charAt X Y is "#".**
Initially I calculated the distance between pairs of stars in Dusa and then added them up in Dusa, using a lexicographic ordering to avoid double-counting stars in both directions
Here’s the program on val.town
This was the first time I got OOM errors from Dusa! Remembering all the different ways of comparing all n^2 star pairs was too much.
This is probably the most logic I’ve put in JavaScript yet: there’s no need to keep all the pairs of stars in memory, so we can just run the accumulator in JavaScript:
function bigabs(x) {
return x < 0 ? -x : x;
}
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();
const stars = [...solution.lookup("starAt")];
let accum = 0n;
for (const [index, [x1, y1]] of stars.entries()) {
for (const [x2, y2] of stars.slice(index + 1)) {
accum += bigabs(x1 - x2) + bigabs(y1 - y2);
}
}
console.log(accum);
}
Here’s the program on val.town
Definitely the first day I got OOM errors!