aoc23/12/part2.naive.pl
2023-12-12 01:15:01 -08:00

64 lines
2.0 KiB
Prolog

:- 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).