aoc2023/day9.quox
2023-12-12 20:37:05 +01:00

78 lines
2.6 KiB
Text
Raw Permalink 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 "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)))