d12p2. It was actually good; swipl's memoization table just didn't work.
This commit is contained in:
parent
b2affa1b5c
commit
da1707b365
@ -1,3 +1,4 @@
|
|||||||
|
% Usage: swipl part1.pl input.txt
|
||||||
:- use_module(library(pio)).
|
:- use_module(library(pio)).
|
||||||
:- use_module(library(dcg/basics)).
|
:- use_module(library(dcg/basics)).
|
||||||
:- initialization(main, main).
|
:- initialization(main, main).
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
:- 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).
|
|
65
12/part2.pl
Normal file
65
12/part2.pl
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
% Usage: swipl part2.pl input.txt
|
||||||
|
:- use_module(library(pio)).
|
||||||
|
:- use_module(library(dcg/basics)).
|
||||||
|
:- initialization(main, main).
|
||||||
|
|
||||||
|
test :- main(['test.txt']).
|
||||||
|
|
||||||
|
main([FileName | _]) :-
|
||||||
|
input(FileName, Lines),
|
||||||
|
concurrent_maplist(resolve_repeated, Lines, Ns),
|
||||||
|
sum_list(Ns, Count),
|
||||||
|
writef('Res=%w\n', [Count]).
|
||||||
|
|
||||||
|
resolve_repeated(Line-Bads, N) :-
|
||||||
|
append([Line, [?], Line, [?], Line, [?], Line, [?], Line], L5),
|
||||||
|
append([Bads, Bads, Bads, Bads, Bads], B5),
|
||||||
|
abolish_private_tables, table(resolve/2),
|
||||||
|
resolve(L5-B5, N).
|
||||||
|
|
||||||
|
% Bads is list of contiguous blocks of bad items in Xs; w/unks resolved in Y.
|
||||||
|
resolve([]-[], 1).
|
||||||
|
resolve([o|Xs]-Bads, Y) :- resolve(Xs-Bads, Y).
|
||||||
|
resolve([?|Xs]-Bads, Y) :-
|
||||||
|
findall(N, (resolve([o|Xs]-Bads, N); resolve([#|Xs]-Bads, N)), Ys),
|
||||||
|
sum_list(Ys, Y).
|
||||||
|
resolve([#|Xs]-[N|Bads], Y) :-
|
||||||
|
length(BadsUnks, N),
|
||||||
|
( append(BadsUnks, [], [#|Xs]),
|
||||||
|
RemainingXs = []
|
||||||
|
; append(BadsUnks, [Next|RemainingXs], [#|Xs]), (Next = o; Next = ?)
|
||||||
|
),
|
||||||
|
bads_or_unks(BadsUnks),
|
||||||
|
resolve(RemainingXs-Bads, Y).
|
||||||
|
|
||||||
|
% List contains all bads or unks
|
||||||
|
bads_or_unks([]).
|
||||||
|
bads_or_unks([#|List]) :- bads_or_unks(List).
|
||||||
|
bads_or_unks([?|List]) :- bads_or_unks(List).
|
||||||
|
|
||||||
|
% List contains exactly N bad items.
|
||||||
|
nbads([], 0).
|
||||||
|
nbads([#|List], N) :- N > 0, Remain is N - 1, nbads(List, Remain).
|
||||||
|
|
||||||
|
processed_line(1, Line-Bads, NewLine-NewBads) :-
|
||||||
|
append(Line, [o], NewLine),
|
||||||
|
NewBads = Bads.
|
||||||
|
|
||||||
|
% read input file into [(o;#;?)]-[list of bad runs]
|
||||||
|
input(FileName, Lines) :- phrase_from_file(lines(Lines), FileName).
|
||||||
|
|
||||||
|
lines([]) --> eos.
|
||||||
|
lines([Status-Parity|Lines]) --> status(Status), parity(Parity), lines(Lines).
|
||||||
|
|
||||||
|
status([]) --> " ".
|
||||||
|
status([o]) --> all_dots, " ".
|
||||||
|
status([o, #|Cdr]) --> all_dots, "#", status(Cdr).
|
||||||
|
status([o, ?|Cdr]) --> all_dots, "?", status(Cdr).
|
||||||
|
status([#|Cdr]) --> "#", status(Cdr).
|
||||||
|
status([?|Cdr]) --> "?", status(Cdr).
|
||||||
|
|
||||||
|
all_dots --> ".".
|
||||||
|
all_dots --> ".", all_dots.
|
||||||
|
|
||||||
|
parity([N]) --> number(N), ("\n"; eos).
|
||||||
|
parity([N|Cdr]) --> number(N), ",", parity(Cdr).
|
Loading…
Reference in New Issue
Block a user