Advent of Code solutions
at main 86 lines 2.3 kB view raw
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").