cleanup + bqn

This commit is contained in:
rhiannon morris 2022-12-10 09:42:22 +01:00
parent 66e6052e5e
commit d7b45f85d2
3 changed files with 39 additions and 27 deletions

View File

@ -61,3 +61,12 @@ Day8 ⇐ {
# ⟨ 1843 180000 ⟩
Day9 {𝕩, "mercury only"!0}
Day10 {
Line 0 ·•BQN 5
A (+´ 19) (×1+)
B " █" (1|-)()˘
(AB) 40 +` 1»Line¨ •FLines 𝕩
}
# ⟨ 13060 "FJUBULRZ" ⟩
# (but the string is a big banner)

View File

@ -13,6 +13,10 @@
:- pred output(answer::in, io::di, io::uo) is det.
:- func ite((pred), T, T) = T.
:- mode ite((pred) is semidet, in, in) = out is det.
:- import_module list.
:- import_module string.
@ -40,6 +44,8 @@
:- func sum(list(int)) = int.
:- func replicate(int, T) = list(T).
:- func map_index(func(int, T) = U, list(T)) = list(U).
:- import_module maybe.
@ -59,6 +65,10 @@ output(int(I), !IO) :- write_int(I, !IO), nl(!IO).
output(string(S), !IO) :- write_string(S, !IO), nl(!IO).
output(lines(Ss), !IO) :- write_list(Ss, "\n", write_string, !IO), nl(!IO).
ite(P, T, E) = X :- if P then X = T else X = E.
:- import_module exception.
:- type die ---> death(string).
@ -87,5 +97,12 @@ sum(Xs) = foldl(plus, Xs, 0).
replicate(N, X) = Out :-
if N = 0 then Out = [] else Out = [X | replicate(N - 1, X)].
:- func map_index(int, func(int, T) = U, list(T)) = list(U).
map_index(_, _, []) = [].
map_index(I, F, [X | Xs]) = [F(I, X) | map_index(I+1, F, Xs)].
map_index(F, Xs) = map_index(0, F, Xs).
to_int_may(Str) = Out :-
if to_int(Str, N) then Out = yes(N) else Out = no.

40
day10.m
View File

@ -20,43 +20,29 @@ line(addx(N)) --> ["addx", X], {to_int(X, N)}.
line(Str, I) :- line(I, words(Str), []).
:- type reg == int.
:- type cycle == int.
:- type reg == int.
:- type signal == int.
:- pred regs(reg::in, list(instr)::in, list(reg)::out) is det.
regs(_, [], []).
regs(R, [noop | Is], [R | Ss]) :-
regs(R, Is, Ss).
regs(R, [addx(N) | Is], [R, R | Ss]) :-
regs(R + N, Is, Ss).
:- func regs(reg, list(instr)) = list(reg).
regs(_, []) = [].
regs(R, [noop | Is]) = [R | regs(R, Is)].
regs(R, [addx(N) | Is]) = [R, R | regs(R + N, Is)].
:- pred regs(lines::in, list(signal)::out) is semidet.
regs(Lines, Signals) :-
map(line, Lines, Instrs),
regs(1, Instrs, Signals).
:- func signals(cycle, list(reg)) = list(reg).
signals(_, []) = [].
signals(C, [R | Rs]) = [C * R | signals(C + 1, Rs)].
:- func regs(list(instr)) = list(reg).
regs(Is) = regs(1, Is).
:- func signals(list(reg)) = list(reg).
signals(Rs) = signals(1, Rs).
:- func render1(cycle, list(reg)) = list(char).
render1(_, []) = [].
render1(C, [R | Rs]) = [X | Xs] :-
(if abs(R - C) =< 1 then X = '' else X = ' '),
Xs = render1((C + 1) mod 40, Rs).
signals(Rs) = map_index(func(I, R) = (I+1) * R, Rs).
:- func render(list(reg)) = lines.
render(Rs) = map(from_char_list, chunk(render1(0, Rs), 40)).
render(Rs) = map(from_char_list, chunk(map_index(Render1, Rs), 40)) :-
Render1 = (func(C, R) = ite(abs(R - C mod 40) =< 1, '', ' ')).
:- pragma no_determinism_warning(run/3).
run(Part, Lines, Out) :-
if regs(Lines, Regs)
then
if map(line, Lines, Instrs) then
Regs = regs(Instrs),
require_complete_switch [Part]
( Part = one,
Indices = [20, 60, 100, 140, 180, 220],
Out = int(sum(map(det_index1(signals(Regs)), Indices)))