diff --git a/sample/day11-sample.txt b/sample/day11-sample.txt new file mode 100644 index 0000000..9b26c84 --- /dev/null +++ b/sample/day11-sample.txt @@ -0,0 +1 @@ +125 17 diff --git a/src/day11_p1.gleam b/src/day11_p1.gleam new file mode 100644 index 0000000..9aeb95e --- /dev/null +++ b/src/day11_p1.gleam @@ -0,0 +1,60 @@ +import gleam/int +import gleam/io +import gleam/iterator +import gleam/list.{filter, filter_map, map, reverse} +import gleam/result +import gleam/string +import stdin.{stdin} + +pub fn main() { + stdin() + |> read_input + |> blink_n(25) + |> list.length + |> io.debug +} + +fn blink_n(stones: List(Int), remaining: Int) -> List(Int) { + case remaining { + 0 -> stones + n -> blink_n(blink(stones), n - 1) + } +} + +fn blink(stones: List(Int)) -> List(Int) { + stones |> map(blink_stone) |> list.flatten +} + +fn blink_stone(stone: Int) -> List(Int) { + let assert Ok(digits) = int.digits(stone, 10) + let digit_num = digits |> list.length + case digits, digit_num { + [0], _ -> [1] + _, num if num % 2 == 0 -> digits |> split_half(digit_num) + _, _ -> [stone * 2024] + } +} + +fn split_half(digits: List(Int), index: Int) -> List(Int) { + let #(first, second) = digits |> list.split(index / 2) + 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) { + it + |> iterator.fold([[]], fn(acc, line) { + case string.trim(line) { + "" -> acc + str -> { + [str |> string.split(" ") |> filter_map(int.parse), ..acc] + } + } + }) + |> filter(fn(l) { list.length(l) > 0 }) + |> reverse + |> list.flatten +} diff --git a/src/day11_p2.gleam b/src/day11_p2.gleam new file mode 100644 index 0000000..695c9e3 --- /dev/null +++ b/src/day11_p2.gleam @@ -0,0 +1,65 @@ +import gleam/dict.{type Dict} +import gleam/int +import gleam/io +import gleam/iterator +import gleam/list.{filter, filter_map, fold, map, reverse} +import gleam/string +import stdin.{stdin} + +pub fn main() { + stdin() + |> read_input + |> blink_n(25) + |> list.length + |> io.debug +} + +fn blink_n(stones: List(Int), remaining: Int) -> List(Int) { + io.debug(remaining) + let memo = dict.new() +} + +fn blink_memo( + memo: Dict(Int, List(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) + } + } +} + +fn blink_stone(stone: Int) -> List(Int) { + let assert Ok(digits) = int.digits(stone, 10) + let digit_num = digits |> list.length + case digits, digit_num { + [0], _ -> [1] + _, num if num % 2 == 0 -> digits |> split_half(digit_num) + _, _ -> [stone * 2024] + } +} + +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] +} + +fn read_input(it: iterator.Iterator(String)) -> List(Int) { + it + |> iterator.fold([[]], fn(acc, line) { + case string.trim(line) { + "" -> acc + str -> { + [str |> string.split(" ") |> filter_map(int.parse), ..acc] + } + } + }) + |> filter(fn(l) { list.length(l) > 0 }) + |> reverse + |> list.flatten +}