aoc23/19/part1.pl
2023-12-19 01:10:33 -08:00

55 lines
1.7 KiB
Prolog

:- use_module(library(pio)).
:- use_module(library(dcg/basics)).
:- initialization(main, main).
main([FileName|_]) :-
input(FileName, Workflows, Parts),
concurrent_maplist(wf(Workflows, in), Parts, Scores),
sum_list(Scores, Score),
write(Score), nl.
wf(_, accept, [x-X, m-M, a-A, s-S], Score) :- Score is X + M + A + S, !.
wf(_, reject, _Part, 0) :- !.
wf(Workflows, WorkflowName, Part, Score) :-
member(WorkflowName-Rules, Workflows),
rule(Workflows, Rules, Part, Score).
rule(Workflows, [EndRule], Part, Score) :- wf(Workflows, EndRule, Part, Score).
rule(Workflows, [Attr-Cond-N-Dest|Rules], Part, Score) :-
( satisfy(Attr-Cond-N, Part)
-> wf(Workflows, Dest, Part, Score)
; rule(Workflows, Rules, Part, Score)
).
satisfy(Attr-Cond-N, Part) :- member(Attr-M, Part), call(Cond, M, N).
% input parsing stuff below
input(FileName, Workflows, Parts) :-
phrase_from_file((workflows(Workflows), parts(Parts)), FileName).
workflows([]) --> "\n", !.
workflows([Name-Rules|Ws]) -->
string_without("{", NameStr), "{", rules(Rules), "}\n", workflows(Ws),
{atom_codes(Name, NameStr)}.
rules([End]) --> dest(End).
rules([Rule|Rules]) --> rule(Rule), ",", rules(Rules).
rule(Attr-Cond-N-Dest) --> attr(Attr), cond(Cond), number(N), ":", dest(Dest).
attr(x) --> "x".
attr(m) --> "m".
attr(a) --> "a".
attr(s) --> "s".
cond('>') --> ">".
cond('<') --> "<".
dest(reject) --> "R", !.
dest(accept) --> "A", !.
dest(Dest) --> endrule(Dest).
endrule(Rule) --> string_without(",}", RuleStr), {atom_codes(Rule, RuleStr)}.
parts([]) --> eos, !.
parts([[x-X, m-M, a-A, s-S]|Parts]) -->
"{x=", number(X), ",m=", number(M), ",a=", number(A), ",s=", number(S),
"}\n", parts(Parts).