day 11 (p2 wip)

This commit is contained in:
Hamcha 2024-12-11 17:58:42 +01:00
parent 063600a919
commit 5d472b9e16
3 changed files with 126 additions and 0 deletions

1
sample/day11-sample.txt Normal file
View file

@ -0,0 +1 @@
125 17

60
src/day11_p1.gleam Normal file
View file

@ -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
}

65
src/day11_p2.gleam Normal file
View file

@ -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
}