aboutsummaryrefslogtreecommitdiff
path: root/aoc-2020-gleam/src/days
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-02-22 13:01:06 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-02-22 13:01:06 +0100
commite83a0b8b0c71dbbce6b3cdb87c77b2740b9f79f8 (patch)
tree06225c03aacf6d5b0c813dfaa3efc961e917bfde /aoc-2020-gleam/src/days
parent6eaf758850feebd8cfc97c3ead2de2625465a326 (diff)
downloadgleam_aoc2020-e83a0b8b0c71dbbce6b3cdb87c77b2740b9f79f8.tar.gz
gleam_aoc2020-e83a0b8b0c71dbbce6b3cdb87c77b2740b9f79f8.zip
Finish first part of day 7
Diffstat (limited to 'aoc-2020-gleam/src/days')
-rw-r--r--aoc-2020-gleam/src/days/day07.gleam80
1 files changed, 80 insertions, 0 deletions
diff --git a/aoc-2020-gleam/src/days/day07.gleam b/aoc-2020-gleam/src/days/day07.gleam
new file mode 100644
index 0000000..eee817f
--- /dev/null
+++ b/aoc-2020-gleam/src/days/day07.gleam
@@ -0,0 +1,80 @@
+import gleam/io
+import gleam/list
+import gleam/function as fun
+import gleam/pair
+import gleam/iterator as iter
+import gleam/map.{Map}
+import ext/resultx as resx
+import ext/iteratorx as iterx
+import util/graph
+import util/input_util
+import util/parser as p
+
+const special_bag = "shiny gold"
+
+type BagEdge =
+ #(String, Int)
+
+type BagGraph =
+ Map(String, List(BagEdge))
+
+fn parse_graph(lines: List(String)) -> BagGraph {
+ let bag_type_parser =
+ [p.str1_until_ws(), p.ws_gc(), p.str1_until_ws()]
+ |> p.str_of_seq
+ |> p.labeled(with: "bag_type")
+
+ let line_parser =
+ bag_type_parser
+ |> p.then_skip(p.literal(" bags contain "))
+ |> p.then(p.or(
+ p.int()
+ |> p.then_skip(p.ws_gc())
+ |> p.then(bag_type_parser)
+ |> p.map(with: pair.swap)
+ |> p.then_skip(p.ws_gc())
+ |> p.then_skip(p.then(p.literal("bag"), p.opt(p.literal("s"))))
+ |> p.sep1(by: p.literal(", ")),
+ else: p.literal("no other bags")
+ |> p.map(fun.constant([])),
+ ))
+ |> p.then_skip(p.literal("."))
+
+ lines
+ |> list.map(with: fun.compose(
+ p.parse_entire(_, with: line_parser),
+ resx.force_unwrap,
+ ))
+ |> map.from_list
+}
+
+fn part1(lines: List(String)) -> Int {
+ let graph = parse_graph(lines)
+ let neighbours = fn(bag) {
+ graph
+ |> map.get(bag)
+ |> resx.force_unwrap
+ |> list.map(with: pair.first)
+ |> iter.from_list
+ }
+
+ graph
+ |> map.keys
+ |> iter.from_list
+ |> iter.filter(for: fn(bag) { bag != special_bag })
+ |> iterx.count(satisfying: fn(start) {
+ start
+ |> graph.dfs(with: neighbours)
+ |> iter.any(fn(bag) { bag == special_bag })
+ })
+}
+
+pub fn run() -> Nil {
+ let test = input_util.read_lines("test07")
+ assert 4 = part1(test)
+
+ let input = input_util.read_lines("day07")
+ io.debug(part1(input))
+
+ Nil
+}