Advent of Code solutions
1:- use_module(library(clpfd)).
2:- use_module(library(dcg/basics)).
3
4lights --> ".", !, lights.
5lights --> "#", !, lights.
6lights --> [].
7
8integers([N | Ns]) --> integer(N), ",", !, integers(Ns).
9integers([N]) --> integer(N).
10
11target --> "[", lights, "]".
12
13buttons([B | Bs]) --> "(", integers(B), ") ", !, buttons(Bs).
14buttons([]) --> [].
15
16joltage(B) --> "{", integers(B), "}".
17
18machine(machine(Joltage, Buttons)) --> target, " ", buttons(Buttons), joltage(Joltage).
19
20machines([]) --> [].
21machines([M | Ms]) --> machine(M), "\n", machines(Ms).
22
23button_effect(I, Button, Times, Times) :- member(I, Button), !.
24button_effect(_, _, _, 0).
25
26joltage_adds_up(Buttons, Presses, I, V) :-
27 length(Buttons, Len),
28 length(Amounts, Len),
29 sum(Amounts, #=, V),
30 maplist(button_effect(I), Buttons, Presses, Amounts)
31 .
32
33max_list(N, [N]).
34max_list(Max, [N | List]) :- max_list(M, List), Max is max(N, M).
35
36min_list(N, [N]).
37min_list(Min, [N | List]) :- min_list(M, List), Min is min(N, M).
38
39flip_nth0(List, N, Nth) :- nth0(N, List, Nth).
40
41limit_presses(Joltage, Button, Limit) :-
42 maplist(flip_nth0(Joltage), Button, Targets),
43 min_list(MinJoltage, Targets),
44 Limit in 0..MinJoltage.
45
46solve_in(N, Joltage, Buttons, Presses) :-
47 length(Joltage, Len),
48 length(Buttons, LenButtons),
49 length(Presses, LenButtons),
50 sum(Presses, #=, N),
51 maplist(limit_presses(Joltage), Buttons, Presses),
52 Max is Len - 1,
53 numlist(0, Max, Indexes),
54 maplist(joltage_adds_up(Buttons, Presses), Indexes, Joltage).
55
56print_domain([]) :- write("\n").
57print_domain([P | Ps]) :-
58 fd_dom(P, S),
59 write(S),
60 write(" "),
61 print_domain(Ps).
62
63solve_machine(N, machine(Joltage, Buttons)) :-
64 max_list(MinPress, Joltage),
65 N #>= MinPress,
66 sum(Joltage, #>=, N),
67 solve_in(N, Joltage, Buttons, Presses),
68 print_domain([N | Presses]),
69 once(labeling([bisect, ff, min(N)], [N | Presses])),
70 !,
71 write(found(N)),
72 write("\n").
73
74solve_total(0, []) :- !.
75solve_total(N, [Machine | Machines]) :-
76 solve_machine(A, Machine),
77 solve_total(B, Machines),
78 N is A + B.
79
80main :-
81 read_stream_to_codes(user_input, Input),
82 string_codes(Input, InputCodes),
83 phrase(machines(Machines), InputCodes),
84 solve_total(Total, Machines),
85 write("Answer: "),
86 write(Total), write("\n").