aoc23/11/day11.pl

42 lines
1.6 KiB
Perl
Raw Normal View History

2023-12-11 21:14:46 -06:00
% usase: swipl day11.pl input.txt 1000000
2023-12-11 01:48:51 -06:00
:- use_module(library(pio)).
2023-12-11 14:33:06 -06:00
:- initialization(main, main).
2023-12-11 01:48:51 -06:00
2023-12-11 21:14:46 -06:00
main([FileName, ExpandFactorArg | _]) :-
2023-12-11 14:33:06 -06:00
input(FileName, Map),
2023-12-11 21:14:46 -06:00
atom_number(ExpandFactorArg, ExpandFactor),
findall(Dist, distance(_, Map, _, ExpandFactor, Dist), Dists),
2023-12-11 14:33:06 -06:00
sum_list(Dists, Sum),
writef('Answer=%t\n', [Sum]).
2023-12-11 01:48:51 -06:00
2023-12-11 19:16:18 -06:00
% Dist is distance along Axis in Map between two row/col A & B (after expansion)
2023-12-11 21:14:46 -06:00
distance(Axis, Map, A-B, ExpandFactor, Dist) :-
true_coords(Axis, Map, ExpandFactor, TrueNs),
2023-12-11 19:16:18 -06:00
member(A-ACount, TrueNs), member(B-BCount, TrueNs), A < B,
Dist is (B - A) * ACount * BCount.
2023-12-11 01:48:51 -06:00
2023-12-11 21:14:46 -06:00
% TrueXs is the list of all coordinates after expanion along Axis in Map
true_coords(x, Map, ExpandFactor, TrueXs) :-
NextX = {ExpandFactor}/[Row, LastX-_, X-Count]>>(
2023-12-11 19:16:18 -06:00
sum_list(Row, Count),
2023-12-11 21:14:46 -06:00
(Count = 0 -> X is LastX + ExpandFactor; X is LastX + 1)),
2023-12-11 19:16:18 -06:00
scanl(NextX, Map, -1-0, Xs), Xs = [_ | TrueXs].
2023-12-11 21:14:46 -06:00
true_coords(y, [FirstRow | Map], ExpandFactor, TrueYs) :-
2023-12-11 19:16:18 -06:00
foldl(add_vectors, Map, FirstRow, CountY),
2023-12-11 21:14:46 -06:00
NextY = {ExpandFactor}/[Count, LastY-_, Y-Count]>>(
Count = 0 -> Y is LastY + ExpandFactor; Y is LastY + 1),
2023-12-11 19:16:18 -06:00
scanl(NextY, CountY, -1-0, Ys), Ys = [_ | TrueYs].
2023-12-11 01:48:51 -06:00
2023-12-11 19:16:18 -06:00
add_vectors([], [], []).
add_vectors([A | V1], [B | V2], [C | V]) :- C is A + B, add_vectors(V1, V2, V).
2023-12-11 01:48:51 -06:00
2023-12-11 19:16:18 -06:00
% Read file into 2D array Map. 1 corresponding to a galaxy and 0 otherwise.
2023-12-11 01:48:51 -06:00
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
2023-12-11 21:14:46 -06:00
lines([]) --> eos.
2023-12-11 01:48:51 -06:00
lines([Line|Lines]) --> line(Line), lines(Lines).
2023-12-11 21:14:46 -06:00
line([]) --> "\n" ; eos.
line([1|Ls]) --> "#", line(Ls).
line([0|Ls]) --> ".", line(Ls).
2023-12-11 14:33:06 -06:00
eos([], []).