DEVELOPMENT ENVIRONMENT

~liljamo/aoc2024

849a172cb5a7c9112602c0ef98510654801e2f15 — Jonni Liljamo a month ago 9de0f35
feat: day5
3 files changed, 151 insertions(+), 0 deletions(-)

A input/day5/example
A src/day5/mod.rs
M src/main.rs
A input/day5/example => input/day5/example +28 -0
@@ 0,0 1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13

75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

A src/day5/mod.rs => src/day5/mod.rs +115 -0
@@ 0,0 1,115 @@
use std::{
    fs::File,
    io::{BufRead, BufReader},
    path::Path,
};

pub fn solve(input: &Path) -> anyhow::Result<()> {
    println!("part one: {}", part_one(input)?);
    println!("part two: {}", part_two(input)?);

    Ok(())
}

fn part_one(input: &Path) -> anyhow::Result<i32> {
    let reader = BufReader::new(File::open(input)?);

    let mut reading_rules = true;
    let mut rules = vec![];
    let mut pages_to_update = vec![];
    for line in reader.lines() {
        let line = line?;
        if line.is_empty() {
            reading_rules = false;
            continue;
        }
        if reading_rules {
            rules.push(
                line.split("|")
                    .map(|s| s.parse::<i32>().unwrap())
                    .collect::<Vec<i32>>(),
            )
        } else {
            pages_to_update.push(
                line.split(",")
                    .map(|s| s.parse::<i32>().unwrap())
                    .collect::<Vec<i32>>(),
            )
        }
    }

    let mut answer = 0;
    for pages in pages_to_update {
        if is_in_order(&pages, &rules) {
            answer += pages[pages.len() / 2];
        }
    }
    Ok(answer)
}

fn is_in_order(pages: &[i32], rules: &[Vec<i32>]) -> bool {
    for (left_index, page) in pages.iter().enumerate() {
        for rule in rules.iter().filter(|&r| r[0] == *page) {
            if let Some(right_index) = pages.iter().position(|n| *n == rule[1]) {
                if right_index < left_index {
                    return false;
                }
            }
        }
    }
    true
}

fn part_two(input: &Path) -> anyhow::Result<i32> {
    let reader = BufReader::new(File::open(input)?);

    let mut reading_rules = true;
    let mut rules = vec![];
    let mut pages_to_update = vec![];
    for line in reader.lines() {
        let line = line?;
        if line.is_empty() {
            reading_rules = false;
            continue;
        }
        if reading_rules {
            rules.push(
                line.split("|")
                    .map(|s| s.parse::<i32>().unwrap())
                    .collect::<Vec<i32>>(),
            )
        } else {
            pages_to_update.push(
                line.split(",")
                    .map(|s| s.parse::<i32>().unwrap())
                    .collect::<Vec<i32>>(),
            )
        }
    }

    let mut answer = 0;
    for pages in pages_to_update
        .iter()
        .filter(|pages| !is_in_order(pages, &rules))
    {
        answer += ordered(pages, &rules)[pages.len() / 2];
    }
    Ok(answer)
}

fn ordered(pages: &[i32], rules: &[Vec<i32>]) -> Vec<i32> {
    let mut pages = pages.to_owned();
    'w: while !is_in_order(&pages, rules) {
        for (left_index, page) in pages.iter().enumerate() {
            for rule in rules.iter().filter(|&r| r[0] == *page) {
                if let Some(right_index) = pages.iter().position(|n| *n == rule[1]) {
                    if right_index < left_index {
                        pages.swap(right_index, left_index);
                        continue 'w;
                    }
                }
            }
        }
    }
    pages
}

M src/main.rs => src/main.rs +8 -0
@@ 9,6 9,7 @@ mod day1;
mod day2;
mod day3;
mod day4;
mod day5;

#[derive(Parser)]
struct Args {


@@ 34,6 35,10 @@ enum DayArgs {
        #[arg(short)]
        input: PathBuf,
    },
    Day5 {
        #[arg(short)]
        input: PathBuf,
    },
}

fn main() -> anyhow::Result<()> {


@@ 52,6 57,9 @@ fn main() -> anyhow::Result<()> {
        DayArgs::Day4 { input } => {
            day4::solve(&input)?;
        }
        DayArgs::Day5 { input } => {
            day5::solve(&input)?;
        }
    }

    Ok(())