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.zip(with: list.drop(report, 1)) |> 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([]) }