diff options
Diffstat (limited to 'gleam/aoc2017/src/aoc_2017/day_12.gleam')
-rw-r--r-- | gleam/aoc2017/src/aoc_2017/day_12.gleam | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gleam/aoc2017/src/aoc_2017/day_12.gleam b/gleam/aoc2017/src/aoc_2017/day_12.gleam new file mode 100644 index 0000000..a9d73c5 --- /dev/null +++ b/gleam/aoc2017/src/aoc_2017/day_12.gleam @@ -0,0 +1,44 @@ +import gleam/dict +import gleam/list +import gleam/set.{type Set} +import gleam/string + +type Pipes = + dict.Dict(String, List(String)) + +pub fn parse(input: String) -> Pipes { + use acc, row <- list.fold(string.split(input, "\n"), dict.new()) + let assert Ok(#(from, to)) = string.split_once(row, " <-> ") + let to_nodes = string.split(to, ", ") + dict.insert(acc, from, to_nodes) +} + +pub fn pt_1(input: Pipes) { + next_nodes("0", input, set.new()) |> set.size() +} + +pub fn pt_2(input: Pipes) { + count_groups(dict.keys(input), input, 0) +} + +fn next_nodes(current: String, pipes: Pipes, found: Set(String)) { + let assert Ok(to_nodes) = dict.get(pipes, current) + + use acc, node <- list.fold(to_nodes, found) + case set.contains(found, node) { + False -> acc |> set.insert(node) |> next_nodes(node, pipes, _) + True -> acc + } +} + +fn count_groups(all_nodes: List(String), pipes: Pipes, count: Int) { + case all_nodes { + [] -> count + [first, ..] -> { + let next_subgraph = next_nodes(first, pipes, set.new()) + let remaining = + list.filter(all_nodes, fn(n) { !set.contains(next_subgraph, n) }) + count_groups(remaining, pipes, count + 1) + } + } +} |