aboutsummaryrefslogtreecommitdiff
path: root/gleam/aoc2017/src/aoc_2017/day_12.gleam
diff options
context:
space:
mode:
Diffstat (limited to 'gleam/aoc2017/src/aoc_2017/day_12.gleam')
-rw-r--r--gleam/aoc2017/src/aoc_2017/day_12.gleam44
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)
+ }
+ }
+}