faster d11

This commit is contained in:
Duy Truong 2023-12-11 12:33:06 -08:00
parent 330c51da3a
commit 6707722fa8
4 changed files with 124 additions and 48 deletions

35
11/part1.naive.pl Normal file
View File

@ -0,0 +1,35 @@
:- op(700, xfx, before).
:- table galaxy/2.
:- table no_galaxy_row/2.
:- table no_galaxy_col/2.
:- use_module(library(pio)).
:- initialization(start, main).
start :-
input('input.txt', Map),
findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B,
distance(Map, A, B, Dist)),
Dists),
sum_list(Dists, Answer),
writef('Answer=%w\n', [Answer]).
distance(Map, X1-Y1, X2-Y2, Dist) :-
findall(X, no_galaxy_row(Map, X), EmptyXs),
findall(Y, no_galaxy_col(Map, Y), EmptyYs),
include(between(X1, X2), EmptyXs, ExpandedX), length(ExpandedX, RowsToAdd),
include(between(Y1, Y2), EmptyYs, ExpandedY), length(ExpandedY, ColsToAdd),
Dist is abs(X1 - X2) + abs(Y1 - Y2) + RowsToAdd + ColsToAdd.
between(End1, End2, N) :- End1 < N, N < End2; End1 > N, N > End2.
no_galaxy_row(Map, X) :- nth0(X, Map, Row), maplist([46]>>(true), Row).
no_galaxy_col(Map, Y) :- maplist({Y}/[Row]>>(nth0(Y, Row, 46)), Map).
galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35).
before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2.
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
lines([]) --> eos, !.
lines([Line|Lines]) --> line(Line), lines(Lines).
eos([], []).
line([]) --> ( "\n" ; eos ), !.
line([L|Ls]) --> [L], line(Ls).

View File

@ -1,35 +1,38 @@
:- op(700, xfx, before).
:- table galaxy/2.
:- table no_galaxy_row/2.
:- table no_galaxy_col/2.
:- use_module(library(pio)). :- use_module(library(pio)).
:- initialization(start, main). :- initialization(main, main).
start :- :- table galaxies/3.
input('input.txt', Map),
findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B, main([FileName | _]) :-
distance(Map, A, B, Dist)), 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), Dists),
sum_list(Dists, Answer), % Sum of manhattan distances is sum of distances on all axes.
writef('Answer=%w\n', [Answer]). sum_list(Dists, Sum),
writef('Answer=%t\n', [Sum]).
distance(Map, X1-Y1, X2-Y2, Dist) :- distance(Axis, Map, X1, X2, Dist) :-
findall(X, no_galaxy_row(Map, X), EmptyXs), true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2),
findall(Y, no_galaxy_col(Map, Y), EmptyYs), Dist is abs(TrueX1 - TrueX2).
include(between(X1, X2), EmptyXs, ExpandedX), length(ExpandedX, RowsToAdd),
include(between(Y1, Y2), EmptyYs, ExpandedY), length(ExpandedY, ColsToAdd),
Dist is abs(X1 - X2) + abs(Y1 - Y2) + RowsToAdd + ColsToAdd.
between(End1, End2, N) :- End1 < N, N < End2; End1 > N, N > End2. true_coord(Axis, Map, X, TrueX) :-
no_galaxy_row(Map, X) :- nth0(X, Map, Row), maplist([46]>>(true), Row). findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows),
no_galaxy_col(Map, Y) :- maplist({Y}/[Row]>>(nth0(Y, Row, 46)), Map). length(EmptyRows, ToAdd),
TrueX is X + ToAdd.
galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35). % galaxies(Axis, Map, X-Count): There are Count galaxies at coordinate X on Axis
before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2. 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). input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
lines([]) --> eos, !. lines([]) --> eos, !.
lines([Line|Lines]) --> line(Line), lines(Lines). lines([Line|Lines]) --> line(Line), lines(Lines).
eos([], []).
line([]) --> ( "\n" ; eos ), !. line([]) --> ( "\n" ; eos ), !.
line([L|Ls]) --> [L], line(Ls). line([L|Ls]) --> ([C], {C =:= 35 -> L = 1; L = 0}), line(Ls).
eos([], []).

35
11/part2.naive.pl Normal file
View File

@ -0,0 +1,35 @@
:- op(700, xfx, before).
:- table galaxy/2.
:- table no_galaxy_row/2.
:- table no_galaxy_col/2.
:- use_module(library(pio)).
:- initialization(start, main).
start :-
input('input.txt', Map),
findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B,
distance(Map, A, B, Dist)),
Dists),
sum_list(Dists, Answer),
writef('Answer=%w\n', [Answer]).
distance(Map, X1-Y1, X2-Y2, Dist) :-
findall(X, no_galaxy_row(Map, X), EmptyXs),
findall(Y, no_galaxy_col(Map, Y), EmptyYs),
include(between(X1, X2), EmptyXs, ExpandedX), length(ExpandedX, RowsToAdd),
include(between(Y1, Y2), EmptyYs, ExpandedY), length(ExpandedY, ColsToAdd),
Dist is abs(X1 - X2) + abs(Y1 - Y2) + RowsToAdd*999999 + ColsToAdd*999999.
between(End1, End2, N) :- End1 < N, N < End2; End1 > N, N > End2.
no_galaxy_row(Map, X) :- nth0(X, Map, Row), maplist([46]>>(true), Row).
no_galaxy_col(Map, Y) :- maplist({Y}/[Row]>>(nth0(Y, Row, 46)), Map).
galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35).
before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2.
input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
lines([]) --> eos, !.
lines([Line|Lines]) --> line(Line), lines(Lines).
eos([], []).
line([]) --> ( "\n" ; eos ), !.
line([L|Ls]) --> [L], line(Ls).

View File

@ -1,35 +1,38 @@
:- op(700, xfx, before).
:- table galaxy/2.
:- table no_galaxy_row/2.
:- table no_galaxy_col/2.
:- use_module(library(pio)). :- use_module(library(pio)).
:- initialization(start, main). :- initialization(main, main).
start :- :- table galaxies/3.
input('input.txt', Map),
findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B, main([FileName | _]) :-
distance(Map, A, B, Dist)), 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), Dists),
sum_list(Dists, Answer), % Sum of manhattan distances is sum of distances on all axes.
writef('Answer=%w\n', [Answer]). sum_list(Dists, Sum),
writef('Answer=%t\n', [Sum]).
distance(Map, X1-Y1, X2-Y2, Dist) :- distance(Axis, Map, X1, X2, Dist) :-
findall(X, no_galaxy_row(Map, X), EmptyXs), true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2),
findall(Y, no_galaxy_col(Map, Y), EmptyYs), Dist is abs(TrueX1 - TrueX2).
include(between(X1, X2), EmptyXs, ExpandedX), length(ExpandedX, RowsToAdd),
include(between(Y1, Y2), EmptyYs, ExpandedY), length(ExpandedY, ColsToAdd),
Dist is abs(X1 - X2) + abs(Y1 - Y2) + RowsToAdd*999999 + ColsToAdd*999999.
between(End1, End2, N) :- End1 < N, N < End2; End1 > N, N > End2. true_coord(Axis, Map, X, TrueX) :-
no_galaxy_row(Map, X) :- nth0(X, Map, Row), maplist([46]>>(true), Row). findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows),
no_galaxy_col(Map, Y) :- maplist({Y}/[Row]>>(nth0(Y, Row, 46)), Map). length(EmptyRows, ToAdd),
TrueX is X + ToAdd*999999.
galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35). % galaxies(Axis, Map, X-Count): There are Count galaxies at coordinate X on Axis
before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2. 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). input(FileName, Map) :- phrase_from_file(lines(Map), FileName).
lines([]) --> eos, !. lines([]) --> eos, !.
lines([Line|Lines]) --> line(Line), lines(Lines). lines([Line|Lines]) --> line(Line), lines(Lines).
eos([], []).
line([]) --> ( "\n" ; eos ), !. line([]) --> ( "\n" ; eos ), !.
line([L|Ls]) --> [L], line(Ls). line([L|Ls]) --> ([C], {C =:= 35 -> L = 1; L = 0}), line(Ls).
eos([], []).