DEVELOPMENT ENVIRONMENT

~liljamo/aoc2024

9de0f35a56cf7917ccb7d134a52d3dbf0165f433 — Jonni Liljamo a month ago 6eea51e
feat: day4
3 files changed, 180 insertions(+), 0 deletions(-)

A input/day4/example
A src/day4/mod.rs
M src/main.rs
A input/day4/example => input/day4/example +10 -0
@@ 0,0 1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX

A src/day4/mod.rs => src/day4/mod.rs +161 -0
@@ 0,0 1,161 @@
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 input: Vec<Vec<char>> = vec![];
    for line in reader.lines() {
        input.push(line?.chars().collect());
    }

    let xmas = "XMAS".as_bytes();
    let samx = "SAMX".as_bytes();

    let mut answer: i32 = 0;
    for line in &input {
        answer += String::from_iter(line)
            .as_bytes()
            .windows(4)
            .filter(|&w| w == xmas || w == samx)
            .count() as i32;
    }

    for y in 0..input[0].len() {
        let mut col = vec![];
        for x in 0..input.len() {
            col.push(input[x][y]);
        }
        answer += String::from_iter(col)
            .as_bytes()
            .windows(4)
            .filter(|&w| w == xmas || w == samx)
            .count() as i32;
    }

    let len = input.len();
    for i in 0..len * 2 {
        let mut diag = vec![];
        for y in 0..i + 1 {
            let x = i - y;
            if x < len && y < len {
                //print!("{} ", input[x][y]);
                diag.push(input[x][y]);
            }
        }
        answer += String::from_iter(diag)
            .as_bytes()
            .windows(4)
            .filter(|&w| w == xmas || w == samx)
            .count() as i32;
        //println!();
    }

    let len = input.len();
    input.reverse();
    for i in 0..len * 2 {
        let mut diag = vec![];
        for y in 0..i + 1 {
            let x = i - y;
            if x < len && y < len {
                //print!("{} ", input[x][y]);
                diag.push(input[x][y]);
            }
        }
        answer += String::from_iter(diag)
            .as_bytes()
            .windows(4)
            .filter(|&w| w == xmas || w == samx)
            .count() as i32;
        //println!();
    }

    Ok(answer)
}

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

    let mut input: Vec<Vec<char>> = vec![];
    for line in reader.lines() {
        input.push(line?.chars().collect());
    }

    let mut fucking_windows = vec![];
    let row_windows = input.windows(3).collect::<Vec<_>>();
    for row_window in row_windows {
        let col_windows_one = row_window[0].windows(3).collect::<Vec<_>>();
        let col_windows_two = row_window[1].windows(3).collect::<Vec<_>>();
        let col_windows_three = row_window[2].windows(3).collect::<Vec<_>>();

        for i in 0..col_windows_one.len() {
            let window = vec![col_windows_one[i], col_windows_two[i], col_windows_three[i]];
            fucking_windows.push(window);
        }
    }

    let mas = "MAS".as_bytes();
    let sam = "SAM".as_bytes();
    let mut answer: i32 = 0;
    for mut window in fucking_windows {
        let mut found_diag = false;
        let mut found_diag_rev = false;

        let len = window.len();
        for i in 0..len * 2 {
            let mut diag = vec![];
            for y in 0..i + 1 {
                let x = i - y;
                if x < len && y < len {
                    diag.push(window[x][y]);
                }
            }
            if String::from_iter(diag)
                .as_bytes()
                .windows(3)
                .filter(|&w| w == mas || w == sam)
                .count()
                > 0
            {
                found_diag = true;
            }
        }

        let len = window.len();
        window.reverse();
        for i in 0..len * 2 {
            let mut diag = vec![];
            for y in 0..i + 1 {
                let x = i - y;
                if x < len && y < len {
                    diag.push(window[x][y]);
                }
            }
            if String::from_iter(diag)
                .as_bytes()
                .windows(3)
                .filter(|&w| w == mas || w == sam)
                .count()
                > 0
            {
                found_diag_rev = true;
            }
        }

        if found_diag && found_diag_rev {
            answer += 1;
        }
    }

    Ok(answer)
}

M src/main.rs => src/main.rs +9 -0
@@ 1,5 1,6 @@
#![allow(clippy::comparison_chain)]
#![allow(clippy::while_let_loop)]
#![allow(clippy::needless_range_loop)]
use std::path::PathBuf;

use clap::{Parser, Subcommand};


@@ 7,6 8,7 @@ use clap::{Parser, Subcommand};
mod day1;
mod day2;
mod day3;
mod day4;

#[derive(Parser)]
struct Args {


@@ 28,6 30,10 @@ enum DayArgs {
        #[arg(short)]
        input: PathBuf,
    },
    Day4 {
        #[arg(short)]
        input: PathBuf,
    },
}

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


@@ 43,6 49,9 @@ fn main() -> anyhow::Result<()> {
        DayArgs::Day3 { input } => {
            day3::solve(&input)?;
        }
        DayArgs::Day4 { input } => {
            day4::solve(&input)?;
        }
    }

    Ok(())