This commit is contained in:
rhiannon morris 2023-12-09 15:15:31 +01:00
parent f0ee8610e9
commit 507cdc8891
4 changed files with 181 additions and 5 deletions

79
day3.pl Normal file
View file

@ -0,0 +1,79 @@
char(X, L, C0, L, C) -->
[X0], {X0 \= 0'\n, char_code(X, X0), C is C0 + 1}, !.
digit(D, L0, C0, L, C) --> char(D, L0, C0, L, C), {char_type(D, digit)}.
digits([D|Ds], L0, C0, L, C) -->
digit(D, L0, C0, L1, C1),
digits0(Ds, L1, C1, L, C).
digits0(Ds, L0, C0, L, C) --> digits(Ds, L0, C0, L, C).
digits0([], L, C, L, C) --> [].
newline(L0, _, L, 0) --> "\n", {L is L0 + 1}.
num(n(N, L-C0-C1), L, C0, L, C) -->
digits(Ds, L, C0, L, C), !,
{number_chars(N, Ds), C1 is C - 1}.
dot(L0, C0, L, C) --> char('.', L0, C0, L, C).
sym(s(X, L-C0), L, C0, L, C) -->
char(X, L, C0, L, C),
{\+ char_type(X, digit), X \= '.'}.
thing(X, L0, C0, L, C) --> num(X, L0, C0, L, C).
thing(X, L0, C0, L, C) --> sym(X, L0, C0, L, C).
nonthing(L0, C0, L, C) --> dot(L0, C0, L, C).
nonthing(L0, C0, L, C) --> newline(L0, C0, L, C).
input([], L, C, L, C) --> [].
input([I|Is], L0, C0, L, C) -->
thing(I, L0, C0, L1, C1), !,
input(Is, L1, C1, L, C).
input(Is, L0, C0, L, C) -->
nonthing(L0, C0, L1, C1), !,
input(Is, L1, C1, L, C).
input(Is) --> input(Is, 0, 0, _, _).
adjacent(LN-CN0-CN1, LS-CS) :-
LLo is LN - 1, LHi is LN + 1, LS >= LLo, LS =< LHi,
CLo is CN0 - 1, CHi is CN1 + 1, CS >= CLo, CS =< CHi.
part_number(N) :-
n(N, NLoc), s(_, SLoc), adjacent(NLoc, SLoc).
number_next_to(N, SLoc) :-
n(N, NLoc), adjacent(NLoc, SLoc).
gear(Ratio) :-
s('*', SLoc),
bagof(N, number_next_to(N, SLoc), [A, B]),
Ratio is A * B.
parse_setup(File) :- parse(File, Items), setup(Items).
parse(File, Items) :- phrase_from_file(input(Items), File), !.
setup(Items) :-
transaction((abolish(n/2), abolish(s/2), maplist(assert, Items))).
:- dynamic n/2, s/2.
sum(Xs, X) :- foldl(plus, Xs, 0, X).
part1(File) :-
parse_setup(File),
bagof(N, part_number(N), Ns),
sum(Ns, Total),
writeln(Total).
part2(File) :-
parse_setup(File),
bagof(R, gear(R), Rs),
sum(Rs, Total),
writeln(Total).

View file

@ -29,8 +29,8 @@ def split-line : ω.String → Line =
def mem : ω. → ω.(List ) → Bool = def mem : ω. → ω.(List ) → Bool =
λ n ⇒ list.foldlω Bool 'false (λ b n' ⇒ bool.or b (nat.eq n n')) λ n ⇒ list.foldlω Bool 'false (λ b n' ⇒ bool.or b (nat.eq n n'))
def all-members : ω.(List ) → ω.(List ) → List = def all-members : ω.Line → List =
λ g w ⇒ list.filter (λ n ⇒ mem n w) g λ ln ⇒ list.filter (λ n ⇒ mem n (snd ln)) (fst ln)
def score-from-len : ω.(List ) → = def score-from-len : ω.(List ) → =
λ xs ⇒ λ xs ⇒
@ -39,16 +39,63 @@ def score-from-len : ω.(List ) → =
(list.uncons xs) (list.uncons xs)
def score : ω.Line → = def score : ω.Line → =
λ ln ⇒ score-from-len (all-members (fst ln) (snd ln)) λ ln ⇒ score-from-len (all-members ln)
def total-score : ω.(List Line) → = def total-score : ω.(List Line) → =
list.foldlω Line 0 (λ n l ⇒ nat.plus n (score l)) list.foldlω Line 0 (λ n l ⇒ nat.plus n (score l))
def part1 =
io.bindω String True
(io.read-fileω "in/day4")
(λ s ⇒ io.dump (List Line)
(letω lines = string.split (char.eq char.newline) s;
lines = list.mapω String Line split-line lines in
lines))
def0 Copies : ★ = List
def CNil = list.Nil
def CCons = list.Cons
def decr-copies : Copies → × Copies =
let0 Ret : ★ = × Copies in
list.foldr Ret (1, CNil)
(λ cur nrest ⇒
case nrest return Ret of { (n, rest) ⇒
case cur return Ret of {
0 ⇒ (n, rest);
succ cur ⇒ (succ n, CCons cur rest)
}})
def new-copies : → ω. → Copies → Copies =
λ count value cs ⇒
case count return Copies of {
0 ⇒ cs;
succ _, cs' ⇒ CCons value cs'
}
def total-cards : ω.(List Line) → =
λ lines ⇒
let 0.State : ★ = × Copies;
ω.start : State = (0, CNil);
ω.next : ω.State → ω.Line → State =
λ st ln ⇒
letω total = fst st;
nc = decr-copies (snd st);
copies-this = fst nc;
copies-rest = snd nc;
score1 = list.length (all-members ln);
copies-out = new-copies copies-this score1 copies-rest;
total' = nat.plus total copies-this in
(total', copies-out) in
fst (list.foldlω Line State start next lines)
#[main] #[main]
def main = def part2 =
io.bindω String True io.bindω String True
(io.read-fileω "in/day4") (io.read-fileω "in/day4")
(λ s ⇒ io.dump (λ s ⇒ io.dump
(letω lines = string.split (char.eq char.newline) s; (letω lines = string.split (char.eq char.newline) s;
lines = list.mapω String Line split-line lines in lines = list.mapω String Line split-line lines in
total-score lines)) total-cards lines))

50
unfinished/day8.quox Normal file
View file

@ -0,0 +1,50 @@
load "bool.quox"
load "string.quox"
load "maybe.quox"
load "io.quox"
def if = bool.if
def Nil = list.Nil; def Cons = list.Cons
def0 Direction : ★ = {left, right}
namespace direction {
def from-char : Char → Maybe Direction =
λ c ⇒
let0 Res = Maybe Direction in
letω L = char.from- 0x4C; R = char.from- 0x52 in
case char.dup c return Res of { [c] ⇒
if Res (char.eq c L) (Just Direction 'left)
(if Res (char.eq c R) (Just Direction 'right)
(Nothing Direction))
}
-- skips unknown characters, e.g. spaces
def from-string : String → List Direction =
let0 Res = List Direction in
λ str ⇒
list.foldr Char Res (Nil Direction)
(λ c ⇒ maybe.fold Direction (Res → Res)
(λ lst ⇒ lst) (Cons Direction) (from-char c))
(string.to-list str)
}
def which : 0.(A : ★) → ω.(A × A) → Direction → A =
λ A xy d ⇒ case d return A of { 'left ⇒ fst xy; 'right ⇒ snd xy }
def lookup : 0.(A B : ★) → ω.(ω.A → Bool) → ω.(List (A × B)) → Maybe B =
λ A B p ⇒
list.foldlω (A × B) (Maybe B) (Nothing B)
(λ st x ⇒ maybe.foldω B (Maybe B)
(if (Maybe B) (p (fst x)) (Just B (snd x)) (Nothing B))
(λ ok ⇒ Just B ok) st)
def0 Map : ★ = List (String × String × String)
def next : ω.Map → ω.String → ω.Direction → Maybe String =
λ map here d ⇒
maybe.foldω (String × String) (Maybe String)
(Nothing String)
(λ res ⇒ Just String (which String res d))
(lookup String (String × String) (string.eq here) map)