aoc2023/day9.quox

79 lines
2.6 KiB
Plaintext
Raw Normal View History

2023-12-12 14:37:05 -05:00
load "bool.quox"
load "list.quox"
load "maybe.quox"
load "int.quox"
def0 Int = scheme-int.Int
def zz = scheme-int.from- 0
def step : ω.(List Int) → List Int =
λ xs ⇒
list.zip-with-uneven Int Int Int (λ m n ⇒ scheme-int.minus n m)
xs (list.tail-or-nil Int xs)
def all-zero : ω.(List Int) → Bool =
list.foldlω Int Bool 'true (λ b n ⇒ bool.and b (scheme-int.eq n zz))
def last : 0.(A : ★) → ω.(List A) → Maybe A =
λ A ⇒ list.foldrω A (Maybe A) (Nothing A) (λ x y ⇒ maybe.or A y (Just A x))
def0 last-ok : last (4, 1, 4, 8, 5, 'nil) ≡ Just 5 : Maybe =
δ 𝑖 ⇒ Just 5
def last-or-0 : ω.(List Int) → Int =
λ xs ⇒ maybe.fold Int Int zz (λ x ⇒ x) (last Int xs)
def next-entry : ω.(List ) → Int =
λ xs ⇒
letω fuel = fst xs in
letω xs = list.map Int scheme-int.from- xs in
let result : Int =
caseω fuel return ω.(List Int) → Int of {
0 ⇒ λ _ ⇒ zz;
succ _, ω.rec ⇒ λ this ⇒
bool.if Int (all-zero this) zz
(letω next : List Int = step this in
letω diff : Int = rec next in
scheme-int.plus diff (last-or-0 this))
} xs in
result
def sumZ = list.foldr Int Int zz scheme-int.plus
{-
def0 ok-1 : next-entry (6, 0, 3, 6, 9, 12, 15, 'nil) ≡ 18 : = δ _ ⇒ 18
def0 ok-2 : next-entry (6, 1, 3, 6, 10, 15, 21, 'nil) ≡ 28 : = δ _ ⇒ 28
def0 ok-3 : next-entry (6, 10, 13, 16, 21, 30, 45, 'nil) ≡ 68 : = δ _ ⇒ 68
-}
load "io.quox"
load "string.quox"
def read-file : ω.String → IO [ω.List (List )] =
λ path ⇒
letω split-lines : ω.String → List String =
string.split (λ c ⇒ char.eq c char.newline);
split-numbers : ω.String → List = λ str ⇒
let words = string.split char.ws? str in
list.map String string.to--or-0 words;
split-file : ω.String → [ω. List (List )] = λ str ⇒
[list.mapω String (List ) split-numbers (split-lines str)] in
io.mapω String [ω.List (List )] split-file (io.read-fileω path)
def FILE : String = "in/day9"
#[main]
def part1 =
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump Int (sumZ (list.mapω (List ) Int next-entry lists)))
def part2 : IO True =
letω next-entry-r : ω.(List ) → Int = λ xs ⇒ next-entry (list.reverse xs) in
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump Int (sumZ (list.mapω (List ) Int next-entry-r lists)))