Day 2: Red-Nosed Reports

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://blocks.programming.dev/ if you prefer sending it through a URL

FAQ

  • Gobbel2000@programming.dev
    link
    fedilink
    English
    arrow-up
    4
    ·
    10 days ago

    Rust

    The function is_sorted_by on Iterators turned out helpful for compactly finding if a report is safe. In part 2 I simply tried the same with each element removed, since all reports are very short.

    fn parse(input: String) -> Vec<Vec<i32>> {
        input.lines()
            .map(|l| l.split_whitespace().map(|w| w.parse().unwrap()).collect())
            .collect()
    }
    
    fn is_safe(report: impl DoubleEndedIterator<Item=i32> + Clone) -> bool {
        let safety = |a: &i32, b: &i32| (1..=3).contains(&(b - a));
        report.clone().is_sorted_by(safety) || report.rev().is_sorted_by(safety)
    }
    
    fn part1(input: String) {
        let reports = parse(input);
        let safe = reports.iter().filter(|r| is_safe(r.iter().copied())).count();
        println!("{safe}");
    }
    
    fn is_safe2(report: &[i32]) -> bool {
        (0..report.len()).any(|i| {  // Try with each element removed
            is_safe(report.iter().enumerate().filter(|(j, _)| *j != i).map(|(_, n)| *n))
        })
    }
    
    fn part2(input: String) {
        let reports = parse(input);
        let safe = reports.iter().filter(|r| is_safe2(r)).count();
        println!("{safe}");
    }
    
    util::aoc_main!();