import util import gleam/list import gleam/int import gleam/dict.{type Dict} import gleam/result.{unwrap} fn read_file(filepath: String) -> List(List(Int)) { filepath |> util.slurp() |> util.parse_with(util.splarse) } pub fn solve(filepath: String) { let parsed_file = read_file(filepath) #(solve_part1(parsed_file), solve_part2(parsed_file)) } fn calc_diff(num_list: List(Int)) -> Int { case num_list { [a, b] -> int.absolute_value(b - a) _ -> 0 } } fn calc_all_diffs(number_lists: List(List(Int)), res: List(Int)) -> List(Int) { case number_lists { [[a, ..rest_a], [b, ..rest_b]] -> calc_all_diffs([rest_a, rest_b], [int.absolute_value(b - a), ..res]) [[], []] -> res _ -> [0] } } pub fn solve_part1(parsed_file: List(List(Int))) { parsed_file |> list.transpose |> list.map(with: fn(x) { list.sort(x, by: int.compare) }) |> calc_all_diffs([]) |> list.reduce(fn(a, b) { a + b}) } pub fn solve_part2(parsed_file: List(List(Int))) { let number_sets = list.transpose(parsed_file) let occurences: Dict(Int, Int) = { case number_sets { [_, b] -> util.frequencies(b) _ -> dict.new() } } let first_nums = { case list.first(number_sets) { Ok(v) -> v Error(_) -> [] } } list.fold(first_nums, 0, fn(acc, a) { case dict.get(occurences, a) { Ok(v) -> acc + a * v Error(_) -> acc } }) }