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