diff --git a/src/day11_p2.gleam b/src/day11_p2.gleam index 695c9e3..3a23c33 100644 --- a/src/day11_p2.gleam +++ b/src/day11_p2.gleam @@ -3,32 +3,48 @@ import gleam/int import gleam/io import gleam/iterator import gleam/list.{filter, filter_map, fold, map, reverse} +import gleam/pair +import gleam/result import gleam/string import stdin.{stdin} pub fn main() { stdin() |> read_input - |> blink_n(25) - |> list.length + |> blink_all_n(75) |> io.debug } -fn blink_n(stones: List(Int), remaining: Int) -> List(Int) { - io.debug(remaining) - let memo = dict.new() +fn blink_all_n(stones: List(Int), times: Int) -> Int { + stones + |> 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( - memo: Dict(Int, List(Int)), + memo: Dict(#(Int, Int), Int), + total: Int, stone: Int, -) -> #(Dict(Int, List(Int)), List(Int)) { - case dict.get(memo, stone) { - Ok(lst) -> #(memo, lst) - _ -> { - let res = blink_stone(stone) - #(dict.insert(memo, stone, res), res) - } + times: Int, +) -> #(Dict(#(Int, Int), Int), Int) { + case times { + 0 -> #(memo, total + 1) + _ -> + case dict.get(memo, #(stone, times)) { + Ok(count) -> #(memo, total + count) + _ -> { + blink_stone(stone) + |> 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) { let #(first, second) = digits |> list.split(index / 2) - let assert Ok(first) = int.undigits(first, 10) - let assert Ok(second) = int.undigits(second, 10) - [first, second] + let assert Ok(out) = + [first, second] + |> map(fn(x) { int.undigits(x, 10) }) + |> result.all + out } fn read_input(it: iterator.Iterator(String)) -> List(Int) {