day9
This commit is contained in:
parent
daf58d9bca
commit
b0b6df2d40
4 changed files with 114 additions and 3 deletions
6
aoc.bqn
6
aoc.bqn
|
@ -55,9 +55,9 @@ Day7 ⇐ {𝕩, "mercury only"!0}
|
|||
Day8 ⇐ {
|
||||
_rots ← {F‿x←𝔽‿𝕩, >{F⌾𝕏x}¨⟨⊢,⍉,⌽˘,⍉⌽⟩}
|
||||
A ← {+´⥊ ∨˝ ∧´∘(⊑>1⊸↓)¨ 𝕩}
|
||||
B ← {⌈´⥊ ×˝ {1⊑⎊(1-˜≠𝕩)/ (⊑≤⊢) 𝕩}¨ 𝕩}
|
||||
(A⋈B) ¯1⊸↓∘↓˘_rots '0'-˜ >•FLines 𝕩
|
||||
B ← {⌈´⥊ ×˝ {1⊑⎊(1-˜≠𝕩) (/⊢≥⊑) 𝕩}¨ 𝕩}
|
||||
(A⋈B) (¯1↓↓)˘_rots '0'-˜ >•FLines 𝕩
|
||||
}
|
||||
# ⟨ 1843 180000 ⟩
|
||||
|
||||
# •Show Day8 ⊑•args
|
||||
Day9 ⇐ {𝕩, "mercury only"!0}
|
||||
|
|
2
aoc.m
2
aoc.m
|
@ -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).
|
||||
|
|
8
basics.m
8
basics.m
|
@ -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
101
day9.m
Normal 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")
|
||||
).
|
Loading…
Reference in a new issue