improved d11 implementation
This commit is contained in:
parent
6707722fa8
commit
963c06b3ba
41
11/part1.pl
41
11/part1.pl
@ -1,35 +1,34 @@
|
||||
:- use_module(library(pio)).
|
||||
:- initialization(main, main).
|
||||
|
||||
:- table galaxies/3.
|
||||
|
||||
main([FileName | _]) :-
|
||||
input(FileName, Map),
|
||||
findall(Dist,
|
||||
( galaxies(Axis, Map, A-ACount), ACount =\= 0,
|
||||
galaxies(Axis, Map, B-BCount), BCount =\= 0,
|
||||
A < B,
|
||||
distance(Axis, Map, A, B, DistPair),
|
||||
Dist is DistPair * ACount * BCount),
|
||||
Dists),
|
||||
% Sum of manhattan distances is sum of distances on all axes.
|
||||
findall(Dist, distance(_, Map, _, Dist), Dists),
|
||||
sum_list(Dists, Sum),
|
||||
writef('Answer=%t\n', [Sum]).
|
||||
|
||||
distance(Axis, Map, X1, X2, Dist) :-
|
||||
true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2),
|
||||
Dist is abs(TrueX1 - TrueX2).
|
||||
% Dist is distance along Axis in Map between two row/col A & B (after expansion)
|
||||
distance(Axis, Map, A-B, Dist) :-
|
||||
true_coords(Axis, Map, TrueNs),
|
||||
member(A-ACount, TrueNs), member(B-BCount, TrueNs), A < B,
|
||||
Dist is (B - A) * ACount * BCount.
|
||||
|
||||
true_coord(Axis, Map, X, TrueX) :-
|
||||
findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows),
|
||||
length(EmptyRows, ToAdd),
|
||||
TrueX is X + ToAdd.
|
||||
% TrueXs is the list of all true coordinates along Axis in Map
|
||||
true_coords(x, Map, TrueXs) :-
|
||||
NextX = [Row, LastX-_, X-Count]>>(
|
||||
sum_list(Row, Count),
|
||||
(Count = 0 -> X is LastX + 2; X is LastX + 1)),
|
||||
scanl(NextX, Map, -1-0, Xs), Xs = [_ | TrueXs].
|
||||
true_coords(y, [FirstRow | Map], TrueYs) :-
|
||||
foldl(add_vectors, Map, FirstRow, CountY),
|
||||
NextY = [Count, LastY-_, Y-Count]>>(
|
||||
Count = 0 -> Y is LastY + 2; Y is LastY + 1),
|
||||
scanl(NextY, CountY, -1-0, Ys), Ys = [_ | TrueYs].
|
||||
|
||||
% galaxies(Axis, Map, X-Count): There are Count galaxies at coordinate X on Axis
|
||||
galaxies(x, Map, X-Count) :- nth0(X, Map, Row), foldl(plus, Row, 0, Count).
|
||||
galaxies(y, Map, Y-Count) :-
|
||||
foldl({Y}/[Row, V0, V]>>(nth0(Y, Row, C), V is V0 + C), Map, 0, Count).
|
||||
add_vectors([], [], []).
|
||||
add_vectors([A | V1], [B | V2], [C | V]) :- C is A + B, add_vectors(V1, V2, V).
|
||||
|
||||
% Read file into 2D array Map. 1 corresponding to a galaxy and 0 otherwise.
|
||||
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
|
||||
lines([]) --> eos, !.
|
||||
lines([Line|Lines]) --> line(Line), lines(Lines).
|
||||
|
41
11/part2.pl
41
11/part2.pl
@ -1,35 +1,34 @@
|
||||
:- use_module(library(pio)).
|
||||
:- initialization(main, main).
|
||||
|
||||
:- table galaxies/3.
|
||||
|
||||
main([FileName | _]) :-
|
||||
input(FileName, Map),
|
||||
findall(Dist,
|
||||
( galaxies(Axis, Map, A-ACount), ACount =\= 0,
|
||||
galaxies(Axis, Map, B-BCount), BCount =\= 0,
|
||||
A < B,
|
||||
distance(Axis, Map, A, B, DistPair),
|
||||
Dist is DistPair * ACount * BCount),
|
||||
Dists),
|
||||
% Sum of manhattan distances is sum of distances on all axes.
|
||||
findall(Dist, distance(_, Map, _, Dist), Dists),
|
||||
sum_list(Dists, Sum),
|
||||
writef('Answer=%t\n', [Sum]).
|
||||
|
||||
distance(Axis, Map, X1, X2, Dist) :-
|
||||
true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2),
|
||||
Dist is abs(TrueX1 - TrueX2).
|
||||
% Dist is distance along Axis in Map between two row/col A & B (after expansion)
|
||||
distance(Axis, Map, A-B, Dist) :-
|
||||
true_coords(Axis, Map, TrueNs),
|
||||
member(A-ACount, TrueNs), member(B-BCount, TrueNs), A < B,
|
||||
Dist is (B - A) * ACount * BCount.
|
||||
|
||||
true_coord(Axis, Map, X, TrueX) :-
|
||||
findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows),
|
||||
length(EmptyRows, ToAdd),
|
||||
TrueX is X + ToAdd*999999.
|
||||
% TrueXs is the list of all true coordinates along Axis in Map
|
||||
true_coords(x, Map, TrueXs) :-
|
||||
NextX = [Row, LastX-_, X-Count]>>(
|
||||
sum_list(Row, Count),
|
||||
(Count = 0 -> X is LastX + 1000000; X is LastX + 1)),
|
||||
scanl(NextX, Map, -1-0, Xs), Xs = [_ | TrueXs].
|
||||
true_coords(y, [FirstRow | Map], TrueYs) :-
|
||||
foldl(add_vectors, Map, FirstRow, CountY),
|
||||
NextY = [Count, LastY-_, Y-Count]>>(
|
||||
Count = 0 -> Y is LastY + 1000000; Y is LastY + 1),
|
||||
scanl(NextY, CountY, -1-0, Ys), Ys = [_ | TrueYs].
|
||||
|
||||
% galaxies(Axis, Map, X-Count): There are Count galaxies at coordinate X on Axis
|
||||
galaxies(x, Map, X-Count) :- nth0(X, Map, Row), foldl(plus, Row, 0, Count).
|
||||
galaxies(y, Map, Y-Count) :-
|
||||
foldl({Y}/[Row, V0, V]>>(nth0(Y, Row, C), V is V0 + C), Map, 0, Count).
|
||||
add_vectors([], [], []).
|
||||
add_vectors([A | V1], [B | V2], [C | V]) :- C is A + B, add_vectors(V1, V2, V).
|
||||
|
||||
% Read file into 2D array Map. 1 corresponding to a galaxy and 0 otherwise.
|
||||
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
|
||||
lines([]) --> eos, !.
|
||||
lines([Line|Lines]) --> line(Line), lines(Lines).
|
||||
|
Loading…
Reference in New Issue
Block a user