2023-12-12 14:37:05 -05:00
|
|
|
:- use_module(library(dcg/basics)).
|
|
|
|
:- use_module(library(dcg/high_order)).
|
|
|
|
|
2023-12-14 13:45:59 -05:00
|
|
|
:- table ok/3.
|
|
|
|
ok([], [], []).
|
|
|
|
ok([0'.|Ts], Cs, [0'.|Rs]) :-
|
|
|
|
ok(Ts, Cs, Rs).
|
|
|
|
ok([0'#|Ts], [C|Cs], [0'#|Rs]) :-
|
|
|
|
C1 is C - 1,
|
|
|
|
fill(Ts, C1, Rs, Ts1, Rs1),
|
|
|
|
ok(Ts1, Cs, Rs1).
|
|
|
|
ok([0'?|Ts], Cs, [0'.|Rs]) :-
|
|
|
|
ok(Ts, Cs, Rs).
|
|
|
|
ok([0'?|Ts], [C|Cs], [0'#|Rs]) :-
|
|
|
|
C1 is C - 1,
|
|
|
|
fill(Ts, C1, Rs, Ts1, Rs1),
|
|
|
|
ok(Ts1, Cs, Rs1).
|
|
|
|
|
|
|
|
|
|
|
|
:- table fill/5.
|
|
|
|
fill([], 0, [], [], []) :- !.
|
|
|
|
fill([T|Ts], 0, [0'.|Rs], Ts, Rs) :- !, can_empty(T).
|
2023-12-12 14:37:05 -05:00
|
|
|
fill([T|Ts], C, [0'#|Rs], Ts1, Rs1) :-
|
|
|
|
C > 0, C1 is C - 1,
|
2023-12-14 13:45:59 -05:00
|
|
|
can_fill(T), !, fill(Ts, C1, Rs, Ts1, Rs1).
|
2023-12-12 14:37:05 -05:00
|
|
|
|
|
|
|
can_fill(0'#).
|
|
|
|
can_fill(0'?).
|
|
|
|
|
|
|
|
can_empty(0'.).
|
|
|
|
can_empty(0'?).
|
|
|
|
|
|
|
|
count(T, C, N) :- bagof(S, ok(T, C, S), Ss), length(Ss, N).
|
|
|
|
count(T-C, N) :- count(T, C, N).
|
|
|
|
|
|
|
|
examples1 :-
|
|
|
|
count(`???.###`, [1, 1, 3], 1),
|
|
|
|
count(`.??..??...?##.`, [1, 1, 3], 4),
|
|
|
|
count(`?#?#?#?#?#?#?#?`, [1, 3, 1, 6], 1),
|
|
|
|
count(`????.#...#...`, [4, 1, 1], 1),
|
|
|
|
count(`????.######..#####.`, [1, 6, 5], 4),
|
|
|
|
count(`?###????????`, [3, 2, 1], 10).
|
|
|
|
|
|
|
|
|
|
|
|
file(Lines) --> sequence(line, Lines).
|
|
|
|
line(T-C) --> template(T), " ", clues(C), blanks.
|
|
|
|
template(T) --> sequence(tchar, T).
|
|
|
|
tchar(T) --> [T], {member(T, `?#.`)}.
|
|
|
|
clues(C) --> sequence(number, ",", C).
|
|
|
|
|
|
|
|
|
|
|
|
part1(File) :-
|
|
|
|
phrase_from_file(file(TCs), File), !,
|
|
|
|
maplist(count, TCs, Ns),
|
|
|
|
foldl(plus, Ns, 0, N),
|
|
|
|
writeln(N).
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
2023-12-14 13:45:59 -05:00
|
|
|
% oof ouch my memory ☹
|
2023-12-12 14:37:05 -05:00
|
|
|
|
2023-12-14 13:45:59 -05:00
|
|
|
count_unfold(T, C, N) :-
|
2023-12-12 14:37:05 -05:00
|
|
|
unfold_template(T, T1),
|
|
|
|
unfold_clues(C, C1),
|
2023-12-14 13:45:59 -05:00
|
|
|
count(T1, C1, N).
|
2023-12-12 14:37:05 -05:00
|
|
|
|
|
|
|
unfold_template(T, R) :- unfold_template(5, T, R).
|
|
|
|
unfold_template(1, T, T) :- !.
|
|
|
|
unfold_template(N, T, R) :-
|
|
|
|
N > 1, N1 is N - 1,
|
|
|
|
unfold_template(N1, T, R1),
|
|
|
|
append(T, [0'?|R1], R).
|
|
|
|
|
|
|
|
unfold_clues(C, R) :- unfold_clues(5, C, R).
|
|
|
|
unfold_clues(1, C, C) :- !.
|
|
|
|
unfold_clues(N, C, R) :-
|
|
|
|
N > 1, N1 is N - 1,
|
|
|
|
unfold_clues(N1, C, R1),
|
|
|
|
append(C, R1, R).
|
|
|
|
|
|
|
|
examples2 :-
|
2023-12-14 13:45:59 -05:00
|
|
|
count_unfold(`???.###`, [1,1,3], 1),
|
|
|
|
count_unfold(`.??..??...?##.`, [1,1,3], 16384),
|
|
|
|
count_unfold(`?#?#?#?#?#?#?#?`, [1,3,1,6], 1),
|
|
|
|
count_unfold(`????.#...#...`, [4,1,1], 16),
|
|
|
|
count_unfold(`????.######..#####.`, [1,6,5], 2500),
|
|
|
|
count_unfold(`?###????????`, [3,2,1], 506250),
|
|
|
|
abolish_all_tables.
|
|
|
|
|
|
|
|
|
|
|
|
count_unfold_all(Ls, Ns) :-
|
|
|
|
length(Ls, Len),
|
|
|
|
count_unfold_all(1, Len, Ls, Ns).
|
|
|
|
count_unfold_all(_, _, [], []) :- !, abolish_all_tables.
|
|
|
|
count_unfold_all(I, Len, [T0-C0|Ls], [N|Ns]) :-
|
|
|
|
abolish_all_tables,
|
|
|
|
unfold_template(T0, T), unfold_clues(C0, C),
|
|
|
|
length(T, LenT), length(C, LenC), wildcards(T, W),
|
|
|
|
format("[~d/~d] ~w ~w ~w > ", [I, Len, 'T'(LenT), 'C'(LenC), 'W'(W)]), flush,
|
|
|
|
!, call_time(count(T, C, N), Time), !,
|
|
|
|
format("[~2fs] ~d~n", [Time.wall, N]),
|
|
|
|
I1 is I + 1,
|
|
|
|
count_unfold_all(I1, Len, Ls, Ns).
|
|
|
|
|
|
|
|
wildcards(T, N) :-
|
|
|
|
setof(I, nth0(I, T, 0'?), Is), length(Is, N).
|
2023-12-12 14:37:05 -05:00
|
|
|
|
|
|
|
part2(File) :-
|
2023-12-14 13:45:59 -05:00
|
|
|
abolish_all_tables,
|
|
|
|
writeln(go),
|
|
|
|
set_prolog_flag(stack_limit, 18_000_000_000),
|
|
|
|
set_prolog_flag(table_space, 40_000_000_000),
|
2023-12-12 14:37:05 -05:00
|
|
|
phrase_from_file(file(TCs), File), !,
|
2023-12-14 13:45:59 -05:00
|
|
|
count_unfold_all(TCs, Ns),
|
2023-12-12 14:37:05 -05:00
|
|
|
foldl(plus, Ns, 0, N),
|
|
|
|
writeln(N).
|
|
|
|
|
|
|
|
*/
|
2023-12-14 13:45:59 -05:00
|
|
|
|
|
|
|
% vim: set ft=prolog :
|