summaryrefslogtreecommitdiff
path: root/2024/day04.rs
blob: 67f18b9f1abb38c756c1c8ecafaf770cea872202 (plain)
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
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use itertools::Itertools;
use std::cmp::max;
use std::env;
use std::fs::File;
use std::io::Read;

fn xmas(s: &[char], xy: &[(usize, usize)], m: &Vec<Vec<char>>) -> usize {
    let mut count = 0;
    let mx: usize = xy.iter().fold(0, |a, (x, y)| max(a, *x));
    let my: usize = xy.iter().fold(0, |a, (x, y)| max(a, *y));
    for r in 0..m.len() - my {
        for c in 0..m[0].len() - mx {
            if xy
                .iter()
                .enumerate()
                .map(|(n, (x, y))| m[r + y][c + x] == s[n])
                .all(|a| a)
            {
                count += 1;
            }
        }
    }
    count
}

fn cross_mas(m: &Vec<Vec<char>>) -> usize {
    let mut count = 0;
    for y in 1..m.len() - 1 {
        for x in 1..m[0].len() - 1 {
            if m[y][x] != 'A' {
                continue;
            }
            let a = [
                m[y - 1][x - 1],
                m[y - 1][x + 1],
                m[y + 1][x + 1],
                m[y + 1][x - 1],
            ];
            let mut m = ['M', 'M', 'S', 'S'];
            for r in 0..4 {
                if a == m {
                    count += 1;
                    break;
                }
                m.rotate_right(1);
            }
        }
    }
    count
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let filename = if args.len() == 1 {
        "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl"
    } else {
        args[1].clone()
    };
    let mut f = File::open(filename).expect("cannot open file");
    let mut content = String::new();
    f.read_to_string(&mut content).expect("cannot read file");
    let lines = content.trim_end().split("\n");

    let mut m: Vec<Vec<char>> = Vec::new();
    for line in lines {
        let mut l: Vec<char> = Vec::new();
        for c in line.bytes() {
            l.push(c as char)
        }
        m.push(l)
    }
    //println!("{:?}", m);

    let ly = m.len();
    let lx = m[0].len();

    let s: Vec<char> = "XMAS".chars().collect();
    let sr: Vec<char> = s.clone().into_iter().rev().collect();
    let horiz: [(usize, usize); 4] = [(0, 0), (1, 0), (2, 0), (3, 0)];
    let vert: [(usize, usize); 4] = [(0, 0), (0, 1), (0, 2), (0, 3)];
    let diag1: [(usize, usize); 4] = [(0, 0), (1, 1), (2, 2), (3, 3)];
    let diag2: [(usize, usize); 4] = [(3, 0), (2, 1), (1, 2), (0, 3)];
    let res1: usize = [s, sr]
        .into_iter()
        .cartesian_product([horiz, vert, diag1, diag2].into_iter())
        .map(|(s, d)| xmas(&s, &d, &m))
        .sum();

    let res2 = cross_mas(&m);

    println!("res1: {}", res1);
    println!("res2: {}", res2);
    assert_eq!(res1, 2575);
    assert_eq!(res2, 2041);
}