day13
This commit is contained in:
parent
e93670512c
commit
20631cf4cd
3 changed files with 92 additions and 4 deletions
6
Makefile
6
Makefile
|
@ -1,7 +1,5 @@
|
|||
MMCFLAGS := \
|
||||
--infer-all --warn-unused-imports
|
||||
# this seems to break day7 for some absolutely bizarre reason
|
||||
# -s asm_fast.par.gc.stseg
|
||||
MMCFLAGS := --infer-all --no-inform-inferred --warn-unused-imports \
|
||||
-s asm_fast.par.gc.stseg
|
||||
|
||||
all: aoc
|
||||
|
||||
|
|
4
aoc.m
4
aoc.m
|
@ -47,6 +47,8 @@ run_day(Day, Part, Lines, Out) :-
|
|||
:- import_module day9.
|
||||
:- import_module day10.
|
||||
:- import_module day11.
|
||||
% :- import_module day12.
|
||||
:- import_module day13.
|
||||
|
||||
:- pred solution(int::in, sol::out(sol)) is semidet.
|
||||
solution(1, day1.run).
|
||||
|
@ -60,3 +62,5 @@ solution(8, day8.run).
|
|||
solution(9, day9.run).
|
||||
solution(10, day10.run).
|
||||
solution(11, day11.run).
|
||||
% solution(12, day12.run).
|
||||
solution(13, day13.run).
|
||||
|
|
86
day13.m
Normal file
86
day13.m
Normal file
|
@ -0,0 +1,86 @@
|
|||
:- module day13.
|
||||
:- interface.
|
||||
:- import_module basics.
|
||||
|
||||
:- pred run(part::in, lines::in, answer::out) is cc_multi.
|
||||
|
||||
:- implementation.
|
||||
:- import_module int.
|
||||
:- import_module string.
|
||||
:- import_module list.
|
||||
|
||||
:- type packet ---> i(int); l(list(packet)).
|
||||
:- type packets == {packet, packet}.
|
||||
|
||||
|
||||
:- pred packets(list(packets)::out, lines::in) is nondet.
|
||||
packets(Ps, Lines) :- packets(Ps, to_char_list(join_list("", Lines)), []).
|
||||
|
||||
:- pred packets(list(packets)::out, chars::in, chars::out) is multi.
|
||||
packets([{P, Q} | Rest]) --> packet(P), packet(Q), packets(Rest).
|
||||
packets([]) --> [].
|
||||
|
||||
:- pred packet(packet::out, chars::in, chars::out) is nondet.
|
||||
:- import_module day4.
|
||||
packet(i(I)) --> day4.number(I).
|
||||
packet(l(Ps)) --> ['['], inner(Ps), [']'].
|
||||
|
||||
:- pred inner(list(packet)::out, chars::in, chars::out) is multi.
|
||||
inner(Ps) --> inner1(Ps).
|
||||
inner([]) --> [].
|
||||
|
||||
:- pred inner1(list(packet)::out, chars::in, chars::out) is nondet.
|
||||
inner1([P | Ps]) --> packet(P), (if [','] then inner1(Ps) else {Ps = []}).
|
||||
|
||||
|
||||
:- pred cmps(list(packet)::in, list(packet)::in, comparison_result::out) is det.
|
||||
cmps([], [], =).
|
||||
cmps([], [_|_], <).
|
||||
cmps([_|_], [], >).
|
||||
cmps([P|Ps], [Q|Qs], C) :-
|
||||
cmp(P, Q, C1), (if C1 = (=) then cmps(Ps, Qs, C) else C = C1).
|
||||
|
||||
:- pred cmp(packet::in, packet::in, comparison_result::out) is det.
|
||||
cmp(i(I), i(J), C) :- compare(C, I, J).
|
||||
cmp(l(Ps), l(Qs), C) :- cmps(Ps, Qs, C).
|
||||
cmp(i(I), l(Qs), C) :- cmps([i(I)], Qs, C).
|
||||
cmp(l(Ps), i(J), C) :- cmps(Ps, [i(J)], C).
|
||||
|
||||
:- func cmp(packet, packet) = comparison_result.
|
||||
cmp(P, Q) = C :- cmp(P, Q, C).
|
||||
|
||||
:- pred ok(packets::in) is semidet.
|
||||
ok({P, Q}) :- not cmp(P, Q, >).
|
||||
|
||||
div1 = l([l([i(2)])]).
|
||||
div2 = l([l([i(6)])]).
|
||||
|
||||
:- pred divider(packet::in) is semidet.
|
||||
divider(div1). divider(div2).
|
||||
|
||||
:- mode unary == (pred(in) is semidet).
|
||||
|
||||
:- pred indices(pred(T)::unary, int::in, list(T)::in, list(int)::out) is det.
|
||||
indices(_, _, [], []).
|
||||
indices(P, I, [X|Xs], Is) :-
|
||||
indices(P, I + 1, Xs, Is0),
|
||||
(if P(X) then Is = [I|Is0] else Is = Is0).
|
||||
|
||||
:- pred indices(pred(T)::unary, list(T)::in, list(int)::out) is det.
|
||||
indices(P, Xs, Is) :- indices(P, 1, Xs, Is).
|
||||
|
||||
|
||||
:- func merge(list(packets)) = list(packet).
|
||||
merge(Ps) = foldl(func({X, Y}, Zs) = [X,Y|Zs], Ps, []).
|
||||
|
||||
:- pragma no_determinism_warning(run/3).
|
||||
run(one, Lines, int(sum(Is))) :-
|
||||
if packets(Ps, Lines) then
|
||||
indices(ok, Ps, Is)
|
||||
else
|
||||
die("bad input").
|
||||
run(two, Lines, int(prod(Is))) :-
|
||||
if packets(Pairs, Lines) then
|
||||
indices(divider, sort(cmp, [div1, div2 | merge(Pairs)]), Is)
|
||||
else
|
||||
die("bad input").
|
Loading…
Reference in a new issue