From 6707722fa8632743cb33384a7e21c3b625d1850e Mon Sep 17 00:00:00 2001 From: Duy Truong Date: Mon, 11 Dec 2023 12:33:06 -0800 Subject: [PATCH] faster d11 --- 11/part1.naive.pl | 35 ++++++++++++++++++++++++++++++++ 11/part1.pl | 51 +++++++++++++++++++++++++---------------------- 11/part2.naive.pl | 35 ++++++++++++++++++++++++++++++++ 11/part2.pl | 51 +++++++++++++++++++++++++---------------------- 4 files changed, 124 insertions(+), 48 deletions(-) create mode 100644 11/part1.naive.pl create mode 100644 11/part2.naive.pl diff --git a/11/part1.naive.pl b/11/part1.naive.pl new file mode 100644 index 0000000..aacc0b0 --- /dev/null +++ b/11/part1.naive.pl @@ -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). diff --git a/11/part1.pl b/11/part1.pl index aacc0b0..abadb50 100644 --- a/11/part1.pl +++ b/11/part1.pl @@ -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)). -:- initialization(start, main). +:- initialization(main, main). -start :- - input('input.txt', Map), - findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B, - distance(Map, A, B, Dist)), +:- 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_list(Dists, Answer), - writef('Answer=%w\n', [Answer]). + % Sum of manhattan distances is sum of distances on all axes. + sum_list(Dists, Sum), + writef('Answer=%t\n', [Sum]). -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. +distance(Axis, Map, X1, X2, Dist) :- + true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2), + Dist is abs(TrueX1 - TrueX2). -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). +true_coord(Axis, Map, X, TrueX) :- + findall(E, (call(galaxies, Axis, Map, E-0), E < X), EmptyRows), + length(EmptyRows, ToAdd), + TrueX is X + ToAdd. -galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35). -before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2. +% 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). -eos([], []). line([]) --> ( "\n" ; eos ), !. -line([L|Ls]) --> [L], line(Ls). +line([L|Ls]) --> ([C], {C =:= 35 -> L = 1; L = 0}), line(Ls). +eos([], []). diff --git a/11/part2.naive.pl b/11/part2.naive.pl new file mode 100644 index 0000000..e384365 --- /dev/null +++ b/11/part2.naive.pl @@ -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). diff --git a/11/part2.pl b/11/part2.pl index e384365..76994cd 100644 --- a/11/part2.pl +++ b/11/part2.pl @@ -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)). -:- initialization(start, main). +:- initialization(main, main). -start :- - input('input.txt', Map), - findall(Dist, (galaxy(Map, A), galaxy(Map, B), A before B, - distance(Map, A, B, Dist)), +:- 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_list(Dists, Answer), - writef('Answer=%w\n', [Answer]). + % Sum of manhattan distances is sum of distances on all axes. + sum_list(Dists, Sum), + writef('Answer=%t\n', [Sum]). -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. +distance(Axis, Map, X1, X2, Dist) :- + true_coord(Axis, Map, X1, TrueX1), true_coord(Axis, Map, X2, TrueX2), + Dist is abs(TrueX1 - TrueX2). -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). +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. -galaxy(Map, X-Y) :- nth0(X, Map, Row), nth0(Y, Row, 35). -before(X1-Y1, X2-Y2) :- X1 < X2; X1 =:= X2, Y1 < Y2. +% 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). -eos([], []). line([]) --> ( "\n" ; eos ), !. -line([L|Ls]) --> [L], line(Ls). +line([L|Ls]) --> ([C], {C =:= 35 -> L = 1; L = 0}), line(Ls). +eos([], []).