diff options
author | J.J <thechairman@thechairman.info> | 2024-05-30 21:49:58 -0400 |
---|---|---|
committer | J.J <thechairman@thechairman.info> | 2024-05-30 21:49:58 -0400 |
commit | 231c2b688d1e6cf0846d46e883da30e042a9c6cf (patch) | |
tree | 98a6d3a461fe190b38b2cf33a708a1d01703fa70 /aoc2023-gleam/src/day15 | |
parent | fe088aa5778dcdbaab4dd8d4a7395a91c444b45c (diff) | |
parent | a2c2b728ec6051323ed937f54816089cd2ae9d20 (diff) | |
download | gleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.tar.gz gleam_aoc-231c2b688d1e6cf0846d46e883da30e042a9c6cf.zip |
Merge branch 'main' of https://github.com/hunkyjimpjorps/AdventOfCode
Diffstat (limited to 'aoc2023-gleam/src/day15')
-rw-r--r-- | aoc2023-gleam/src/day15/.gitignore | 1 | ||||
-rw-r--r-- | aoc2023-gleam/src/day15/solve.gleam | 104 |
2 files changed, 105 insertions, 0 deletions
diff --git a/aoc2023-gleam/src/day15/.gitignore b/aoc2023-gleam/src/day15/.gitignore new file mode 100644 index 0000000..ae40cea --- /dev/null +++ b/aoc2023-gleam/src/day15/.gitignore @@ -0,0 +1 @@ +input.txt
\ No newline at end of file diff --git a/aoc2023-gleam/src/day15/solve.gleam b/aoc2023-gleam/src/day15/solve.gleam new file mode 100644 index 0000000..a7d250c --- /dev/null +++ b/aoc2023-gleam/src/day15/solve.gleam @@ -0,0 +1,104 @@ +import adglent.{First, Second} +import gleam/io +import gleam/string +import gleam/list +import gleam/int +import gleam/dict.{type Dict} +import gleam/option.{None, Some} + +fn split(input: String) -> List(String) { + input + |> string.split(",") +} + +fn hash_algorithm(str: String) -> Int { + let codepoints = + str + |> string.to_utf_codepoints() + |> list.map(string.utf_codepoint_to_int) + use acc, c <- list.fold(codepoints, 0) + let assert Ok(acc) = int.modulo({ acc + c } * 17, 256) + acc +} + +pub fn part1(input: String) -> String { + input + |> split + |> list.fold(0, fn(acc, str) { acc + hash_algorithm(str) }) + |> string.inspect +} + +type Instruction { + Remove(label: String) + Insert(label: String, focal: Int) +} + +fn read_instruction(str: String) -> Instruction { + case string.split(str, "=") { + [label, focal_str] -> { + let assert Ok(focal) = int.parse(focal_str) + Insert(label, focal) + } + _ -> Remove(string.drop_right(str, 1)) + } +} + +fn parse_instructions(insts: List(String)) -> Dict(Int, List(#(String, Int))) { + use acc, inst <- list.fold(insts, dict.new()) + case read_instruction(inst) { + Remove(label) -> remove_lens(acc, label) + Insert(label, focal) -> insert_lens(acc, label, focal) + } +} + +fn remove_lens(boxes, label) { + use v <- dict.update(boxes, hash_algorithm(label)) + case v { + Some(lenses) -> + case list.key_pop(lenses, label) { + Ok(#(_, updated)) -> updated + Error(Nil) -> lenses + } + None -> [] + } +} + +fn insert_lens(boxes, label, focal) { + use v <- dict.update(boxes, hash_algorithm(label)) + case v { + Some(lenses) -> list.key_set(lenses, label, focal) + None -> [#(label, focal)] + } +} + +fn focusing_power(boxes: Dict(Int, List(#(String, Int)))) -> Int { + use acc, k, v <- dict.fold(boxes, 0) + let box_acc = { + use acc, lens, i <- list.index_fold(v, 0) + acc + lens.1 * { i + 1 } + } + acc + { k + 1 } * box_acc +} + +pub fn part2(input: String) -> String { + input + |> split + |> parse_instructions + |> focusing_power + |> string.inspect +} + +pub fn main() { + let assert Ok(part) = adglent.get_part() + let assert Ok(input) = adglent.get_input("15") + case part { + First -> + part1(input) + |> adglent.inspect + |> io.println + Second -> + part2(input) + |> adglent.inspect + |> io.println + } +} |