aboutsummaryrefslogtreecommitdiff
path: root/aoc2017-gleam/src/aoc_2017
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2017-gleam/src/aoc_2017')
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_7.gleam72
1 files changed, 69 insertions, 3 deletions
diff --git a/aoc2017-gleam/src/aoc_2017/day_7.gleam b/aoc2017-gleam/src/aoc_2017/day_7.gleam
index 593282b..a289fa5 100644
--- a/aoc2017-gleam/src/aoc_2017/day_7.gleam
+++ b/aoc2017-gleam/src/aoc_2017/day_7.gleam
@@ -1,7 +1,7 @@
+import gleam/dict.{type Dict}
import gleam/int
-import gleam/io
import gleam/list
-import gleam/option.{None, Some}
+import gleam/option.{Some}
import gleam/regex.{type Match, Match}
import gleam/set
import gleam/string
@@ -38,5 +38,71 @@ pub fn pt_1(input: List(Program)) {
}
pub fn pt_2(input: List(Program)) {
- todo as "part 2 not implemented"
+ let weights =
+ input |> list.map(fn(p) { #(p.name, p.weight) }) |> dict.from_list
+
+ let supporters =
+ input
+ |> list.filter_map(fn(p) {
+ case list.is_empty(p.supporting) {
+ True -> Error(Nil)
+ False -> Ok(#(p.name, p.supporting))
+ }
+ })
+ |> dict.from_list
+
+ supporters
+ |> dict.keys()
+ |> list.filter_map(fn(name) {
+ let branch_weights =
+ name
+ |> branch_weights(weights, supporters)
+ |> fn(tup: #(String, List(#(Int, String)))) { tup.1 }
+
+ case
+ branch_weights
+ |> list.map(fn(tup: #(Int, String)) { tup.0 })
+ |> list.unique
+ |> list.length
+ {
+ 2 -> Ok(#(name, branch_weights))
+ _ -> Error(Nil)
+ }
+ })
+
+ // [
+ // #("hmgrlpj", [#(2078, "drjmjug"), #(2070, "nigdlq"), #(2070, "omytneg"), ...]),
+ // #("smaygo", [#(14564, "hmgrlpj"), #(14556, "fbnbt"), #(14556, "nfdvsc")])
+ // #("eugwuhl", [#(48292, "smaygo"), #(48284, "pvvbn"), #(48284, "hgizeb"), ...]),
+ // ]
+ //
+ // by inspection, eugwuhl -> smaygo -> hmgrlpj -> drjmjug; changing drjmjug will fix the tower
+
+ let assert Ok(w) = dict.get(weights, "drjmjug")
+ w - 8
+}
+
+fn branch_weights(
+ name: String,
+ weights: Dict(String, Int),
+ supporting: Dict(String, List(String)),
+) -> #(String, List(#(Int, String))) {
+ let supported = case dict.get(supporting, name) {
+ Ok(supported) -> supported
+ Error(_) -> []
+ }
+
+ let supported_weights =
+ list.map(supported, fn(s) {
+ let assert Ok(weight) = dict.get(weights, s)
+ let children_weights =
+ s
+ |> branch_weights(weights, supporting)
+ |> fn(tup: #(String, List(#(Int, String)))) { tup.1 }
+ |> list.map(fn(tup: #(Int, String)) { tup.0 })
+ weight + int.sum(children_weights)
+ })
+ |> list.zip(supported)
+
+ #(name, supported_weights)
}