1
0
Fork 0
advent-of-code/2024/gleam/src/aoc/day_two.gleam

58 lines
1.3 KiB
Gleam

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([])
}