diff --git a/12/part2.naive.pl b/12/part2.naive.pl new file mode 100644 index 0000000..f11f0af --- /dev/null +++ b/12/part2.naive.pl @@ -0,0 +1,63 @@ +:- use_module(library(pio)). +:- use_module(library(dcg/basics)). +:- initialization(main, main). +:- table nbads/2. +:- table bads_or_unks/1. +% :- table resolve/3. + +test :- main(['test.txt']). + +main([FileName | _]) :- + input(FileName, Lines), + % TrySolve = [Line-Bads, Prev, Curr]>>( + % writef('%t, %t', [Line, Bads]), + % resolve(Line, Bads, N), + % Curr is Prev + N, + % writef(' --> %t\n', [N])), + % foldl(TrySolve, Lines, 0, Ns), + TrySolve = [Line-Bads, N]>>( + resolve(Line, Bads, N), + writef('%t <-- %t, %t\n', [N, Line, Bads])), + concurrent_maplist(TrySolve, Lines, Ns), + sum_list(Ns, Count), + writef('\nRes=%w, %w\n', [Ns, Count]). + +% Bads is list of contiguous blocks of bad items in Xs; w/unks resolved in Y. +resolve([], [], 1). +resolve([good|Xs], Bads, Y) :- resolve(Xs, Bads, Y). +resolve([unk|Xs], Bads, Y) :- + convlist({Xs, Bads}/[Choice, Yx]>>(resolve([Choice|Xs], Bads, Yx)), + [good, bad], Ys), + sum_list(Ys, Y). +resolve([bad|Xs], [N|Bads], Y) :- + length(BadsUnks, N), + append(BadsUnks, [Next|RemainingXs], [bad|Xs]), + (Next = good; Next = unk), + bads_or_unks(BadsUnks), + resolve(RemainingXs, Bads, Y). + +% List contains all bads or unks +bads_or_unks([]). +bads_or_unks([bad|List]) :- bads_or_unks(List). +bads_or_unks([unk|List]) :- bads_or_unks(List). + +% List contains exactly N bad items. +nbads([], 0). +nbads([bad|List], N) :- N > 0, Remain is N - 1, nbads(List, Remain). + +% read input file into [(good;bad;unk)]-[list of bad runs] +input(FileName, Lines) :- phrase_from_file(lines(Lines), FileName). + +lines([]) --> eos. +lines([Status-Parity|Lines]) --> + (status(S), {append([S, [unk], S, [unk], S, [unk], S, [unk], S, [good]], Status)}), + (parity(P), {append([P, P, P, P, P], Parity)}), + lines(Lines). + +status([]) --> " ". +status([good|Cdr]) --> ".", status(Cdr). +status([bad|Cdr]) --> "#", status(Cdr). +status([unk|Cdr]) --> "?", status(Cdr). + +parity([N]) --> number(N), ("\n"; eos). +parity([N|Cdr]) --> number(N), ",", parity(Cdr).