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 := \
|
MMCFLAGS := --infer-all --no-inform-inferred --warn-unused-imports \
|
||||||
--infer-all --warn-unused-imports
|
-s asm_fast.par.gc.stseg
|
||||||
# this seems to break day7 for some absolutely bizarre reason
|
|
||||||
# -s asm_fast.par.gc.stseg
|
|
||||||
|
|
||||||
all: aoc
|
all: aoc
|
||||||
|
|
||||||
|
|
4
aoc.m
4
aoc.m
|
@ -47,6 +47,8 @@ run_day(Day, Part, Lines, Out) :-
|
||||||
:- import_module day9.
|
:- import_module day9.
|
||||||
:- import_module day10.
|
:- import_module day10.
|
||||||
:- import_module day11.
|
:- import_module day11.
|
||||||
|
% :- import_module day12.
|
||||||
|
:- import_module day13.
|
||||||
|
|
||||||
:- pred solution(int::in, sol::out(sol)) is semidet.
|
:- pred solution(int::in, sol::out(sol)) is semidet.
|
||||||
solution(1, day1.run).
|
solution(1, day1.run).
|
||||||
|
@ -60,3 +62,5 @@ solution(8, day8.run).
|
||||||
solution(9, day9.run).
|
solution(9, day9.run).
|
||||||
solution(10, day10.run).
|
solution(10, day10.run).
|
||||||
solution(11, day11.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