aoc2023/day3.quox

97 lines
2.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}