summaryrefslogtreecommitdiff
path: root/2021/day4/src/main.rs
blob: 4b2f9b3ffcb52477a351a4c56834ef4e5c64e725 (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
99
100
101
102
103
104
105
106
107
use std::fs::File;
use std::io::{BufRead, BufReader};

fn part1(grids: &Vec<Vec<u32>>, mut inputs: Vec<u32>) -> u32 {
    let mut values = Vec::<u32>::new();

    for _ in 0..4 {
        values.push(inputs.remove(0));
    }

    let mut winner: i8 = -1;
    for input in inputs {
        if winner >= 0 {
            break;
        }
        values.push(input);
        for i in 0..grids.len() {
            // Search by rows
            for j in [0, 5, 10, 15, 20] {
                let mut n = 0;
                for k in 0..5 {
                    let x = grids[i][j + k];
                    if values.iter().any(|&i| i == x) {
                        n += 1;
                    }
                }
                if n == 5 {
                    winner = i as i8;
                }
            }

            // Search by cols
            if winner < 0 {
                for j in 0..5 {
                    let mut n = 0;
                    for k in [0, 5, 10, 15, 20] {
                        let x = grids[i][j + k];
                        if values.iter().any(|&i| i == x) {
                            n += 1;
                        }
                    }
                    if n == 5 {
                        winner = i as i8;
                    }
                }
            }

            if winner >= 0 {
                break;
            }
        }
    }

    let mut sum = 0;
    for x in &grids[winner as usize] {
        if values.iter().any(|&i| i == *x) {
            continue;
        }

        sum += x;
    }

    sum * values.pop().unwrap()
}

fn main() -> std::io::Result<()> {
    let file = File::open("input.txt")?;
    let reader = BufReader::new(file);
    let mut lines = reader.lines();

    let inputs: Vec<_> = lines
        .next()
        .unwrap()
        .unwrap()
        .trim()
        .split(',')
        .map(|x| x.parse::<u32>().unwrap())
        .collect::<Vec<u32>>();

    let mut grids: Vec<Vec<u32>> = vec![];
    let mut n: usize = 0;

    lines.next(); // Ignore the first empty line
    while let Some(line) = lines.next() {
        let mut line = line.unwrap();
        grids.push(Vec::with_capacity(5 * 5));

        for _ in 0..5 {
            grids[n].extend(
                line.trim()
                    .split(' ')
                    .filter(|x| !x.is_empty())
                    .map(|x| x.parse::<u32>().unwrap())
                    .collect::<Vec<u32>>(),
            );
            line = match lines.next() {
                Some(x) => x.unwrap(),
                None => "".to_string(),
            };
        }
        n += 1;
    }

    println!("{}", part1(&grids, inputs.clone()));

    Ok(())
}