diff --git a/sample/day9-sample.txt b/sample/day9-sample.txt new file mode 100644 index 0000000..f96c390 --- /dev/null +++ b/sample/day9-sample.txt @@ -0,0 +1 @@ +2333133121414131402 diff --git a/sample/day9-sample2.txt b/sample/day9-sample2.txt new file mode 100644 index 0000000..0235404 --- /dev/null +++ b/sample/day9-sample2.txt @@ -0,0 +1 @@ +3782 diff --git a/src/day3_p1.gleam b/src/day3_p1.gleam index 983555d..0ceec43 100644 --- a/src/day3_p1.gleam +++ b/src/day3_p1.gleam @@ -91,7 +91,6 @@ fn read_num(str: String) -> Option(#(Int, String)) { fn read_input(it: iterator.Iterator(String)) -> String { it - |> iterator.fold([], fn(acc, line) { [line, ..acc] }) - |> reverse + |> iterator.to_list |> join(with: "") } diff --git a/src/day3_p2.gleam b/src/day3_p2.gleam index 2aff4cb..6c5c8ba 100644 --- a/src/day3_p2.gleam +++ b/src/day3_p2.gleam @@ -90,7 +90,6 @@ fn read_num(str: String) -> Option(#(Int, String)) { fn read_input(it: iterator.Iterator(String)) -> String { it - |> iterator.fold([], fn(acc, line) { [line, ..acc] }) - |> reverse + |> iterator.to_list |> join(with: "") } diff --git a/src/day9_p1.gleam b/src/day9_p1.gleam new file mode 100644 index 0000000..5d739c1 --- /dev/null +++ b/src/day9_p1.gleam @@ -0,0 +1,83 @@ +import gleam/bool +import gleam/dict.{type Dict} +import gleam/int +import gleam/io +import gleam/iterator +import gleam/list.{Continue, Stop, filter, fold, map} +import gleam/pair +import gleam/result +import gleam/string +import stdin.{stdin} + +pub fn main() { + stdin() + |> read_input + |> compact + |> calculate_checksum + |> io.debug +} + +fn calculate_checksum(filemap: Dict(Int, Int)) -> Int { + filemap |> dict.fold(0, fn(acc, k, v) { acc + k * v }) +} + +fn compact(filemap: Dict(Int, Int)) -> Dict(Int, Int) { + filemap + |> dict.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)) + _ -> Stop(acc) + } + _ -> Stop(acc) + } + }) +} + +fn find_gaps(nums: List(Int)) -> List(Int) { + // Assume ordered list + let assert [max, ..] = nums |> list.reverse + + list.range(0, max - 1) + |> filter(fn(n) { nums |> list.contains(n) |> bool.negate }) +} + +fn read_input(it: iterator.Iterator(String)) -> Dict(Int, Int) { + 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, []), fn(acc, n, i) { + let #(position, files) = acc + case i % 2 == 0 { + True -> #(position + n, [#(position, n), ..files]) + False -> #(position + n, files) + } + }) + |> pair.second + |> list.reverse + |> list.index_fold(dict.new(), fn(acc, file, i) { + let #(position, size) = file + + list.range(position, position + size - 1) + |> fold(acc, fn(dic, pos) { dict.insert(dic, pos, i) }) + }) +}