DEVELOPMENT ENVIRONMENT

~liljamo/aoc2024

ref: e7712b210e6f57dad3ec2170862538c4ee3b118e aoc2024/src/day4/mod.rs -rw-r--r-- 4.2 KiB
e7712b21Jonni Liljamo chore: clippy, because i can't just keep ignoring it a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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 c in &input {
            col.push(c[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)
}