diff --git a/11/part1.pl b/11/part1.pl index abadb50..a4ef28d 100644 --- a/11/part1.pl +++ b/11/part1.pl @@ -1,34 +1,31 @@ :- 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). +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. +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]. -% 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). +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]. + +add_vectors([], [], []). +add_vectors([A | V1], [B | V2], [C | V]) :- C is A + B, add_vectors(V1, V2, V). input(FileName, Map) :- phrase_from_file(lines(Map), FileName). lines([]) --> eos, !. diff --git a/11/part2.pl b/11/part2.pl index 76994cd..4740f40 100644 --- a/11/part2.pl +++ b/11/part2.pl @@ -1,34 +1,31 @@ :- 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). +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. +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]. -% 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). +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]. + +add_vectors([], [], []). +add_vectors([A | V1], [B | V2], [C | V]) :- C is A + B, add_vectors(V1, V2, V). input(FileName, Map) :- phrase_from_file(lines(Map), FileName). lines([]) --> eos, !.