aoc2023/day3.quox

97 lines
2.7 KiB
Plaintext
Raw Normal View History

2023-12-06 21:47:23 -05:00
load "string.quox"
def0 Symbol : ★ = Char × × -- value, x, y
def0 Number : ★ = × × × -- value, start_x, end_x, y
namespace symbol {
def value : ω.Symbol → Char = λ s ⇒ fst s
def x : ω.Symbol → = λ s ⇒ fst (snd s)
def y : ω.Symbol → = λ s ⇒ snd (snd s)
}
namespace number {
def value : ω.Number → = λ n ⇒ fst n
def sx : ω.Number → = λ n ⇒ fst (snd n)
def ex : ω.Number → = λ n ⇒ fst (snd (snd n))
def y : ω.Number → = λ n ⇒ snd (snd (snd n))
}
namespace element {
def0 Tag : ★ = {symbol, number}
def0 Body : Tag → ★ =
λ t ⇒ case t return ★ of { 'symbol ⇒ Symbol; 'number ⇒ Number }
}
def0 Element : ★ = (t : element.Tag) × element.Body t
def make-symbol : (value : Char) → (x y : ) → Element =
λ c x y ⇒ ('symbol, c, x, y)
def make-number : (value start_x end_x y : ) → Element =
λ v sx ex y ⇒ ('number, v, sx, ex, y)
def dot = char.from- 0x2e
def adj-x : ω.(nx sx ex : ) → Bool =
λ nx sx ex ⇒ bool.and (nat.ge (succ nx) sx) (nat.le nx (succ ex))
def adj-y : ω.(ny sy : ) → Bool =
λ ny sy ⇒ bool.and (nat.ge (succ ny) sy) (nat.le ny (succ sy))
def adjacent : ω.Symbol → ω.Number → Bool =
λ s n ⇒
bool.and (adj-x (symbol.x s) (number.sx n) (number.ex n))
(adj-y (symbol.y s) (number.y n))
def any : 0.(A : ★) → ω.(ω.A → Bool) → ω.(List A) → Bool =
λ A p ⇒ list.foldlω A Bool 'false (λ b x ⇒ bool.or b (p x))
def is-label : ω.(List Symbol) → ω.Number → Bool =
λ ss n ⇒ any Symbol (λ s ⇒ adjacent s n) ss
namespace read {
def0 Digits : ★ = Maybe (List )
def0 State : ★ =
-- current number, x, y
Digits × × ×
-- stuff seen so far
List Number × List Symbol
def Cons = list.Cons
def Nil = list.Nil
def add-digit : → Digits → Digits =
λ d ds ⇒
maybe.fold (List ) ( → Digits)
(λ d ⇒ Just (List ) (Cons d (Nil )))
(λ ds d ⇒ Just (List ) (Cons d ds))
ds d
def next-col : State → State =
λ s ⇒
case s return State of { (ds, rest) ⇒
case rest return State of { (x, rest) ⇒ (ds, succ x, rest) }
}
def next-row : State → State =
λ s ⇒
case s return State of { (ds, rest) ⇒
case rest return State of { (x, rest) ⇒
nat.drop State x
(case rest return State of { (y, rest) ⇒ (ds, 0, succ y, rest) })
}
}
def seen-digit : Char → State → State =
λ c s ⇒
case s return State of {
(ds, rest) ⇒ (add-digit (char.digit c) ds, rest)
}
}