2023-12-15 02:17:21 -06:00
|
|
|
:- use_module(library(pio)).
|
|
|
|
:- use_module(library(dcg/basics)).
|
|
|
|
:- use_module(library(clpfd)).
|
|
|
|
:- initialization(main, main).
|
|
|
|
|
|
|
|
main([FileName|_]) :-
|
|
|
|
input(FileName, Actions),
|
|
|
|
perform_all(Actions, Boxes),
|
2023-12-15 02:39:55 -06:00
|
|
|
findall(Power, power_of_some_lens(Boxes, Power), Powers),
|
2023-12-15 02:17:21 -06:00
|
|
|
sum_list(Powers, Answer),
|
|
|
|
writef('Answer=%t\n', [Answer]).
|
|
|
|
|
2023-12-15 02:39:55 -06:00
|
|
|
power_of_some_lens(Boxes, Power) :-
|
|
|
|
nth1(BoxI, Boxes, _-Box),
|
|
|
|
nth1(LensI, Box, _-Focal),
|
|
|
|
Power is BoxI * LensI * Focal.
|
|
|
|
|
2023-12-15 02:17:21 -06:00
|
|
|
perform_all(Actions, FinalBoxes) :-
|
|
|
|
length(EmptyBoxes, 256),
|
|
|
|
foldl([N-[], N, NextN]>>(NextN is N + 1), EmptyBoxes, 0, _),
|
|
|
|
foldl(perform, Actions, EmptyBoxes, FinalBoxes).
|
|
|
|
|
|
|
|
perform(BoxN-Action-Label, Before, After) :-
|
|
|
|
nth0(BoxN, Before, BoxN-Box),
|
|
|
|
call(Action, Label, Box, NewBox),
|
|
|
|
select(BoxN-Box, Before, BoxN-NewBox, After).
|
|
|
|
|
|
|
|
remove(_, [], []).
|
|
|
|
remove(Label, [Label-_|Box], Box) :- !.
|
|
|
|
remove(Label, [Lens|Box], [Lens|NewBox]) :- remove(Label, Box, NewBox).
|
|
|
|
|
2023-12-15 02:39:55 -06:00
|
|
|
add(Focal, Label, Box, NewBox) :- select(Label-_, Box, Label-Focal, NewBox), !.
|
|
|
|
add(Focal, Label, Box, NewBox) :- append(Box, [Label-Focal], NewBox).
|
2023-12-15 02:17:21 -06:00
|
|
|
|
|
|
|
% Input stuff. [0-(add-1)-"rn", 3-remove-"cm", ...]
|
|
|
|
input(Name, Actions) :- phrase_from_file(insts(Actions), Name).
|
|
|
|
|
|
|
|
insts([]) --> (eos; "\n"), !.
|
|
|
|
insts([Box-Action-LabelS|Items]) -->
|
|
|
|
item(Label-Action), insts(Items),
|
|
|
|
{reverse(Label, Rev), hash(Rev, Box), string_codes(LabelS, Label)}.
|
|
|
|
|
|
|
|
item([]-remove) --> "-", (","; "\n"; eos), !.
|
|
|
|
item([]-add(N)) --> "=", number(N), (","; "\n"; eos), !.
|
|
|
|
item([C|Chars]-X) --> [C], item(Chars-X).
|
|
|
|
|
|
|
|
hash([], 0).
|
|
|
|
hash([C|Str], Hash) :- hash(Str, Prev), Hash is (Prev + C)*17 mod 256.
|