:- 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. 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). true_coord(Axis, Map, X, TrueX) :- findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows), length(EmptyRows, ToAdd), TrueX is X + ToAdd. % 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). input(FileName, Map) :- phrase_from_file(lines(Map), FileName). lines([]) --> eos, !. lines([Line|Lines]) --> line(Line), lines(Lines). line([]) --> ( "\n" ; eos ), !. line([L|Ls]) --> ([C], {C =:= 35 -> L = 1; L = 0}), line(Ls). eos([], []).