This commit is contained in:
rhiannon morris 2022-12-09 12:18:58 +01:00
parent daf58d9bca
commit b0b6df2d40
4 changed files with 114 additions and 3 deletions

View File

@ -55,9 +55,9 @@ Day7 ⇐ {𝕩, "mercury only"!0}
Day8 {
_rots {Fx𝔽𝕩, >{F𝕏x}¨,,˘,}
A {+´ ˝ ´(>1)¨ 𝕩}
B {´ ×˝ {1(1-˜𝕩)/ () 𝕩}¨ 𝕩}
(AB) ¯1˘_rots '0'-˜ >•FLines 𝕩
B {´ ×˝ {1(1-˜𝕩) (/) 𝕩}¨ 𝕩}
(AB) (¯1)˘_rots '0'-˜ >•FLines 𝕩
}
# ⟨ 1843 180000 ⟩
# •Show Day8 ⊑•args
Day9 {𝕩, "mercury only"!0}

2
aoc.m
View File

@ -46,6 +46,7 @@ run_day(Day, Part, Lines, Out) :-
:- import_module day6.
:- import_module day7.
:- import_module day8.
:- import_module day9.
:- pred solution(int::in, sol::out(sol)) is semidet.
solution(1, day1.run).
@ -56,3 +57,4 @@ solution(5, day5.run).
solution(6, day6.run).
solution(7, day7.run).
solution(8, day8.run).
solution(9, day9.run).

View File

@ -6,6 +6,8 @@
:- mode part(in, out) is semidet.
:- mode part(out, in) is det.
:- func part(part, T, T) = T.
:- import_module io.
:- import_module list.
@ -33,6 +35,7 @@
:- import_module int.
:- func sum(list(int)) = int.
:- func replicate(int, T) = list(T).
:- import_module maybe.
@ -45,6 +48,9 @@
part("1", one).
part("2", two).
part(one, X, _) = X.
part(two, _, Y) = Y.
:- import_module exception.
@ -71,6 +77,8 @@ read_lines_need(File, Lines, !IO) :-
sum(Xs) = foldl(plus, Xs, 0).
replicate(N, X) = Out :-
if N = 0 then Out = [] else Out = [X | replicate(N - 1, X)].
to_int_may(Str) = Out :-
if to_int(Str, N) then Out = yes(N) else Out = no.

101
day9.m Normal file
View File

@ -0,0 +1,101 @@
:- module day9.
:- interface.
:- import_module basics.
:- import_module univ.
:- pred run(part::in, lines::in, univ::out) is cc_multi.
:- implementation.
:- import_module int.
:- import_module string.
:- import_module list.
:- import_module set_bbbtree.
:- type set(T) == set_bbbtree(T).
:- type coord ---> c(x :: int, y :: int).
:- type rope == list(coord).
:- type direction ---> up; down; left; right.
:- pred to_direction(string, direction).
:- mode to_direction(in, out) is semidet.
:- mode to_direction(out, in) is det.
to_direction("U", up).
to_direction("D", down).
to_direction("L", left).
to_direction("R", right).
:- pred orth(direction::in, direction::in) is semidet.
orth(A, B) :-
((A = up ; A = down), (B = left ; B = right));
((A = left ; A = right), (B = up ; B = down)).
:- pred line(string::in, list(direction)::out) is semidet.
line(Str, replicate(N, D)) :-
words(Str) = [DD, NN],
to_direction(DD, D),
to_int(NN, N).
:- pred move_head(direction::out, coord::in, coord::out) is multi.
move_head(up, c(X, Y), c(X, Y+1)).
move_head(down, c(X, Y), c(X, Y-1)).
move_head(left, c(X, Y), c(X-1, Y)).
move_head(right, c(X, Y), c(X+1, Y)).
:- pred ok(coord::in, coord::in) is semidet.
ok(A, B) :- abs(A^x - B^x) =< 1, abs(A^y - B^y) =< 1.
:- pred ok(rope::in) is semidet.
ok([]). ok([_]).
ok([A, B | Rest]) :- ok(A, B), ok([B | Rest]).
:- pred same_rc(coord::in, coord::in) is semidet.
same_rc(A, B) :- A^x = B^x ; A^y = B^y.
:- pred move_tail1(coord::in, coord::in, coord::out) is nondet.
move_tail1(H, !T) :- ok(H, !.T).
move_tail1(H, !T) :-
if same_rc(H, !.T) then
move_head(_, !T),
ok(H, !.T)
else
move_head(D1, !T),
move_head(D2, !T),
orth(D1, D2),
ok(H, !.T).
:- pred move_tail(coord::in, rope::in, rope::out) is nondet.
move_tail(_, [], []).
move_tail(H, [!.T | !.Ts], [!:T | !:Ts]) :-
move_tail1(H, !T),
move_tail(!.T, !Ts).
:- pred move(direction::in, rope::in, rope::out) is nondet.
move(_, [], []).
move(D, [!.H | !.T], [!:H | !:T]) :-
move_head(D, !H),
move_tail(!.H, !T).
:- type seen == set(coord).
:- pred next(direction, rope, rope, seen, seen).
:- mode next(in, in, out, in, out) is nondet.
next(D, !Rope, !Seen) :-
move(D, !Rope),
last(!.Rope, Tail),
insert(Tail, !Seen).
:- pred run0(part::in, lines::in, int::out) is cc_nondet.
run0(Part, Lines, Out) :-
Start = replicate(part(Part, 2, 10), c(0, 0)),
map(line, Lines, Dirs),
foldl2(next, condense(Dirs), Start, _, init, End),
count(End, Out).
run(Part, Lines, univ(Out)) :-
disable_warning [no_solution_disjunct] (
not run0(Part, Lines, Out) => die("bad input")
).