This commit is contained in:
Hamcha 2024-12-12 10:49:48 +01:00
parent 5d472b9e16
commit 401a086a71

View file

@ -3,31 +3,47 @@ import gleam/int
import gleam/io import gleam/io
import gleam/iterator import gleam/iterator
import gleam/list.{filter, filter_map, fold, map, reverse} import gleam/list.{filter, filter_map, fold, map, reverse}
import gleam/pair
import gleam/result
import gleam/string import gleam/string
import stdin.{stdin} import stdin.{stdin}
pub fn main() { pub fn main() {
stdin() stdin()
|> read_input |> read_input
|> blink_n(25) |> blink_all_n(75)
|> list.length
|> io.debug |> io.debug
} }
fn blink_n(stones: List(Int), remaining: Int) -> List(Int) { fn blink_all_n(stones: List(Int), times: Int) -> Int {
io.debug(remaining) stones
let memo = dict.new() |> fold(#(dict.new(), 0), fn(acc, x) {
let #(memo, total) = acc
blink_memo(memo, total, x, times)
})
|> pair.second
} }
// This is awful, everyone hates this!!
fn blink_memo( fn blink_memo(
memo: Dict(Int, List(Int)), memo: Dict(#(Int, Int), Int),
total: Int,
stone: Int, stone: Int,
) -> #(Dict(Int, List(Int)), List(Int)) { times: Int,
case dict.get(memo, stone) { ) -> #(Dict(#(Int, Int), Int), Int) {
Ok(lst) -> #(memo, lst) case times {
0 -> #(memo, total + 1)
_ ->
case dict.get(memo, #(stone, times)) {
Ok(count) -> #(memo, total + count)
_ -> { _ -> {
let res = blink_stone(stone) blink_stone(stone)
#(dict.insert(memo, stone, res), res) |> fold(#(memo, total), fn(acc, x) {
let #(new_memo, new_total) = acc
let #(memo_3, count) = blink_memo(new_memo, 0, x, times - 1)
#(dict.insert(memo_3, #(x, times - 1), count), new_total + count)
})
}
} }
} }
} }
@ -44,9 +60,11 @@ fn blink_stone(stone: Int) -> List(Int) {
fn split_half(digits: List(Int), index: Int) -> List(Int) { fn split_half(digits: List(Int), index: Int) -> List(Int) {
let #(first, second) = digits |> list.split(index / 2) let #(first, second) = digits |> list.split(index / 2)
let assert Ok(first) = int.undigits(first, 10) let assert Ok(out) =
let assert Ok(second) = int.undigits(second, 10)
[first, second] [first, second]
|> map(fn(x) { int.undigits(x, 10) })
|> result.all
out
} }
fn read_input(it: iterator.Iterator(String)) -> List(Int) { fn read_input(it: iterator.Iterator(String)) -> List(Int) {