diff --git a/2024/gleam/gleam.toml b/2024/gleam/gleam.toml index e299b57..d557422 100644 --- a/2024/gleam/gleam.toml +++ b/2024/gleam/gleam.toml @@ -14,6 +14,4 @@ version = "1.0.0" [dependencies] gleam_stdlib = ">= 0.34.0 and < 2.0.0" - -[dev-dependencies] -gleeunit = ">= 1.0.0 and < 2.0.0" +stdin = ">= 1.1.4 and < 2.0.0" diff --git a/2024/gleam/manifest.toml b/2024/gleam/manifest.toml new file mode 100644 index 0000000..b4522e0 --- /dev/null +++ b/2024/gleam/manifest.toml @@ -0,0 +1,11 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" }, + { name = "stdin", version = "1.1.4", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "stdin", source = "hex", outer_checksum = "04C04035F2A4CEEFB023837249649CD25F9A9CF5A45F9947C4D0462428A4677D" }, +] + +[requirements] +gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } +stdin = { version = ">= 1.1.4 and < 2.0.0" } diff --git a/2024/gleam/src/aoc/day_two.gleam b/2024/gleam/src/aoc/day_two.gleam new file mode 100644 index 0000000..7d26e7b --- /dev/null +++ b/2024/gleam/src/aoc/day_two.gleam @@ -0,0 +1,58 @@ +import gleam/int +import gleam/io +import gleam/iterator +import gleam/list +import gleam/pair +import gleam/result +import gleam/string +import stdin.{stdin} + +type Report = + List(Int) + +pub fn main() { + let reports = stdin() |> iterator.to_list() |> list.map(with: parse_report) + + let part1 = list.count(reports, is_safe) |> int.to_string() + let part2 = list.count(reports, is_safe_with_damper) |> int.to_string() + + io.print("Part 1: ") + io.println(part1) + io.print("Part 2: ") + io.println(part2) +} + +fn is_safe(report: Report) -> Bool { + let diffs = + report + |> list.window_by_2() + |> list.map(fn(p) { pair.first(p) - pair.second(p) }) + + list.all(diffs, fn(n) { 1 <= n && n <= 3 }) + || list.all(diffs, fn(n) { -3 <= n && n <= -1 }) +} + +fn is_safe_with_damper(report: Report) -> Bool { + is_safe(report) + || report + |> reports_with_a_single_level_removed() + |> list.any(is_safe) +} + +fn reports_with_a_single_level_removed(report: Report) -> List(Report) { + let len = list.length(report) + let idxs = list.range(0, len - 1) + + use i <- list.map(idxs) + let assert #(head, [_, ..tail]) = list.split(report, i) + list.append(head, tail) +} + +fn parse_report(str: String) -> Report { + str + |> string.trim() + |> string.split(" ") + |> list.map(int.parse) + |> result.all() + |> result.unwrap([]) +}