day 9
This commit is contained in:
parent
49134bff05
commit
e4d2bbeb49
2 changed files with 132 additions and 13 deletions
|
@ -22,25 +22,29 @@ fn calculate_checksum(filemap: Dict(Int, Int)) -> Int {
|
|||
}
|
||||
|
||||
fn compact(filemap: Dict(Int, Int)) -> Dict(Int, Int) {
|
||||
filemap
|
||||
|> dict.keys
|
||||
let keys =
|
||||
filemap
|
||||
|> dict.keys
|
||||
|> list.sort(int.compare)
|
||||
|
||||
let to_move = keys |> list.reverse
|
||||
|
||||
keys
|
||||
|> find_gaps
|
||||
|> list.fold_until(filemap, fn(acc, gap) {
|
||||
case
|
||||
acc
|
||||
|> dict.keys
|
||||
|> list.reverse
|
||||
|> list.first
|
||||
{
|
||||
Ok(x) if x <= gap -> Stop(acc)
|
||||
Ok(x) ->
|
||||
case dict.get(acc, x) {
|
||||
Ok(val) -> Continue(acc |> dict.delete(x) |> dict.insert(gap, val))
|
||||
|> list.fold_until(#(filemap, to_move), fn(acc, gap) {
|
||||
let #(fmap, fdata) = acc
|
||||
case fdata {
|
||||
[x, ..] if x <= gap -> Stop(acc)
|
||||
[x, ..rest] ->
|
||||
case dict.get(fmap, x) {
|
||||
Ok(val) ->
|
||||
Continue(#(fmap |> dict.delete(x) |> dict.insert(gap, val), rest))
|
||||
_ -> Stop(acc)
|
||||
}
|
||||
_ -> Stop(acc)
|
||||
}
|
||||
})
|
||||
|> pair.first
|
||||
}
|
||||
|
||||
fn find_gaps(nums: List(Int)) -> List(Int) {
|
||||
|
|
115
src/day9_p2.gleam
Normal file
115
src/day9_p2.gleam
Normal file
|
@ -0,0 +1,115 @@
|
|||
import gleam/int
|
||||
import gleam/io
|
||||
import gleam/iterator
|
||||
import gleam/list.{fold, map}
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
import stdin.{stdin}
|
||||
|
||||
pub fn main() {
|
||||
stdin()
|
||||
|> read_input
|
||||
|> compact
|
||||
|> calculate_checksum
|
||||
|> io.debug
|
||||
}
|
||||
|
||||
fn calculate_checksum(filemap: List(Segment)) -> Int {
|
||||
filemap
|
||||
|> fold(0, fn(acc, next) {
|
||||
case next {
|
||||
File(pos, index, size) -> {
|
||||
list.range(pos, pos + size - 1)
|
||||
|> fold(acc, fn(total, x) { total + x * index })
|
||||
}
|
||||
_ -> acc
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn compact(filemap: List(Segment)) -> List(Segment) {
|
||||
filemap
|
||||
|> list.reverse
|
||||
|> fold(filemap, fn(acc, next) {
|
||||
case next {
|
||||
File(pos, index, size) -> {
|
||||
let next_gap =
|
||||
list.find(acc, fn(x) {
|
||||
case x {
|
||||
Gap(gap_pos, gap_size) if gap_pos < pos && gap_size >= size ->
|
||||
True
|
||||
_ -> False
|
||||
}
|
||||
})
|
||||
|
||||
case next_gap {
|
||||
Ok(Gap(gap_pos, _)) -> fill_gap(acc, gap_pos, index, size)
|
||||
_ -> acc
|
||||
}
|
||||
}
|
||||
_ -> acc
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn fill_gap(
|
||||
segments: List(Segment),
|
||||
gap_pos: Int,
|
||||
file_index: Int,
|
||||
file_size: Int,
|
||||
) -> List(Segment) {
|
||||
segments
|
||||
|> fold([], fn(acc, s) {
|
||||
case s {
|
||||
Gap(pos, size) if pos == gap_pos && size == file_size -> [
|
||||
File(pos, file_index, file_size),
|
||||
..acc
|
||||
]
|
||||
Gap(pos, size) if pos == gap_pos -> [
|
||||
Gap(pos + file_size, size - file_size),
|
||||
File(pos, file_index, file_size),
|
||||
..acc
|
||||
]
|
||||
File(pos, index, size) if file_index == index -> [Gap(pos, size), ..acc]
|
||||
_ -> [s, ..acc]
|
||||
}
|
||||
})
|
||||
|> list.reverse
|
||||
}
|
||||
|
||||
pub type Segment {
|
||||
File(position: Int, index: Int, size: Int)
|
||||
Gap(position: Int, size: Int)
|
||||
}
|
||||
|
||||
fn read_input(it: iterator.Iterator(String)) -> List(Segment) {
|
||||
let assert Ok(numbers) =
|
||||
it
|
||||
|> iterator.to_list
|
||||
|> map(fn(line) {
|
||||
line
|
||||
|> string.trim
|
||||
|> string.to_graphemes
|
||||
|> map(int.parse)
|
||||
})
|
||||
|> list.flatten
|
||||
|> result.all
|
||||
|
||||
numbers
|
||||
|> list.index_fold(#([], 0, 0), fn(acc, size, i) {
|
||||
let #(segments, index, position) = acc
|
||||
case i % 2 == 0 {
|
||||
True -> #(
|
||||
[File(position, index, size), ..segments],
|
||||
index + 1,
|
||||
position + size,
|
||||
)
|
||||
False -> #([Gap(position, size), ..segments], index, position + size)
|
||||
}
|
||||
})
|
||||
|> fn(x) {
|
||||
let #(segments, _, _) = x
|
||||
segments
|
||||
}
|
||||
|> list.reverse
|
||||
}
|
Loading…
Reference in a new issue