aboutsummaryrefslogtreecommitdiff
path: root/aoc-2020-gleam/src/days
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-02-20 19:07:32 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-02-20 19:07:32 +0100
commit9c94df2676e8b857eac6c94e827086bf0e8cb850 (patch)
treec2e274434dc6788d4693ccaf001da326fc6ab522 /aoc-2020-gleam/src/days
parent58a01f64f8807668f5a403bf45579a62524c8791 (diff)
downloadgleam_aoc2020-9c94df2676e8b857eac6c94e827086bf0e8cb850.tar.gz
gleam_aoc2020-9c94df2676e8b857eac6c94e827086bf0e8cb850.zip
Finish day 6
Diffstat (limited to 'aoc-2020-gleam/src/days')
-rw-r--r--aoc-2020-gleam/src/days/day06.gleam92
1 files changed, 92 insertions, 0 deletions
diff --git a/aoc-2020-gleam/src/days/day06.gleam b/aoc-2020-gleam/src/days/day06.gleam
new file mode 100644
index 0000000..9308166
--- /dev/null
+++ b/aoc-2020-gleam/src/days/day06.gleam
@@ -0,0 +1,92 @@
+import gleam/io
+import gleam/int
+import gleam/string
+import gleam/list
+import gleam/set.{Set}
+import ext/resultx
+import util/parser as p
+import util/input_util
+
+type Answers =
+ Set(String)
+
+type Group =
+ List(Answers)
+
+type Input =
+ List(Group)
+
+fn alphabet() -> Set(String) {
+ set.from_list(string.to_graphemes("abcdefghijklmnopqrstuvwxyz"))
+}
+
+fn parse_input(text: String) -> Input {
+ let answers_parser =
+ p.string1_until_whitespace()
+ |> p.map(fn(answer_string) {
+ answer_string
+ |> string.to_graphemes
+ |> set.from_list
+ })
+ |> p.labeled(with: "answers")
+
+ let group_parser =
+ answers_parser
+ |> p.separated1(by: p.whitespace_grapheme())
+ |> p.labeled(with: "group")
+
+ let input_parser =
+ group_parser
+ |> p.separated1(by: p.string_literal("\n\n"))
+ |> p.then_skip(p.optional(p.whitespace_grapheme()))
+ |> p.labeled(with: "input")
+
+ text
+ |> p.parse_entire(with: input_parser)
+ |> resultx.force_unwrap
+}
+
+fn fold_group(
+ over group: Group,
+ from initial: Set(String),
+ with fun: fn(Set(String), Set(String)) -> Set(String),
+) -> Int {
+ group
+ |> list.fold(from: initial, with: fun)
+ |> set.size
+}
+
+fn answered_by_anyone(in group: Group) -> Int {
+ fold_group(over: group, from: set.new(), with: set.union)
+}
+
+fn answered_by_everyone(in group: Group) -> Int {
+ fold_group(over: group, from: alphabet(), with: set.intersection)
+}
+
+fn solve(text: String, with folder: fn(Group) -> Int) -> Int {
+ text
+ |> parse_input
+ |> list.map(with: folder)
+ |> int.sum
+}
+
+fn part1(text: String) -> Int {
+ solve(text, with: answered_by_anyone)
+}
+
+fn part2(text: String) -> Int {
+ solve(text, with: answered_by_everyone)
+}
+
+pub fn run() -> Nil {
+ let test = input_util.read_text("test06")
+ assert 11 = part1(test)
+ assert 6 = part2(test)
+
+ let input = input_util.read_text("day06")
+ io.debug(part1(input))
+ io.debug(part2(input))
+
+ Nil
+}