diff options
author | Hunky Jimpjorps <thechairman@thechairman.info> | 2023-12-08 09:42:13 -0500 |
---|---|---|
committer | Hunky Jimpjorps <thechairman@thechairman.info> | 2023-12-08 09:42:13 -0500 |
commit | df2f2fd140f188dfb5df68b44e397a8855e79f02 (patch) | |
tree | 9bb603eba8a3c46848bc59a6c5ba1c73ed34759c /aoc2023/src | |
parent | 82c3ecec3de5111b460910bafe141b3aed478676 (diff) | |
parent | b51dd4b3768bce0209733ef2562cb96e5330d3c6 (diff) | |
download | gleam_aoc-df2f2fd140f188dfb5df68b44e397a8855e79f02.tar.gz gleam_aoc-df2f2fd140f188dfb5df68b44e397a8855e79f02.zip |
Merge branch 'main' of https://github.com/hunkyjimpjorps/AdventOfCode
Diffstat (limited to 'aoc2023/src')
-rw-r--r-- | aoc2023/src/day8/.gitignore | 1 | ||||
-rw-r--r-- | aoc2023/src/day8/solve.gleam | 90 |
2 files changed, 91 insertions, 0 deletions
diff --git a/aoc2023/src/day8/.gitignore b/aoc2023/src/day8/.gitignore new file mode 100644 index 0000000..ae40cea --- /dev/null +++ b/aoc2023/src/day8/.gitignore @@ -0,0 +1 @@ +input.txt
\ No newline at end of file diff --git a/aoc2023/src/day8/solve.gleam b/aoc2023/src/day8/solve.gleam new file mode 100644 index 0000000..cbd2f6a --- /dev/null +++ b/aoc2023/src/day8/solve.gleam @@ -0,0 +1,90 @@ +import adglent.{First, Second} +import gleam/bool +import gleam/dict.{type Dict} +import gleam/io +import gleam/iterator.{type Iterator, Next} +import gleam/list +import gleam/option.{Some} +import gleam/string +import gleam/regex.{type Match, Match} +import gleam_community/maths/arithmetics + +type Paths { + Paths(to_left: String, to_right: String) +} + +type Maze = + Dict(String, Paths) + +fn parse(input: String) -> #(Iterator(String), Dict(String, Paths)) { + let [directions_str, maze_str] = string.split(input, "\n\n") + + let directions = + directions_str + |> string.to_graphemes() + |> iterator.from_list + |> iterator.cycle + + let assert Ok(re) = regex.from_string("(...) = \\((...), (...)\\)") + let maze = + maze_str + |> string.split("\n") + |> list.map(fn(str) { + let assert [Match(submatches: [Some(name), Some(left), Some(right)], ..)] = + regex.scan(re, str) + #(name, Paths(left, right)) + }) + |> dict.from_list + + #(directions, maze) +} + +fn to_next_step( + current: String, + stop_at: String, + count: Int, + directions: Iterator(String), + maze: Maze, +) -> Int { + use <- bool.guard(string.ends_with(current, stop_at), count) + let assert Next(next_direction, rest_directions) = iterator.step(directions) + let assert Ok(paths) = dict.get(maze, current) + case next_direction { + "L" -> paths.to_left + "R" -> paths.to_right + } + |> to_next_step(stop_at, count + 1, rest_directions, maze) +} + +pub fn part1(input: String) -> Int { + let #(directions, maze) = parse(input) + + to_next_step("AAA", "ZZZ", 0, directions, maze) +} + +pub fn part2(input: String) -> Int { + let #(directions, maze) = parse(input) + + use acc, name <- list.fold(dict.keys(maze), 1) + case string.ends_with(name, "A") { + False -> acc + True -> + to_next_step(name, "Z", 0, directions, maze) + |> arithmetics.lcm(acc) + } +} + +pub fn main() { + let assert Ok(part) = adglent.get_part() + let assert Ok(input) = adglent.get_input("8") + case part { + First -> + part1(input) + |> adglent.inspect + |> io.println + Second -> + part2(input) + |> adglent.inspect + |> io.println + } +} |