summaryrefslogtreecommitdiffstats
path: root/2021/day4/src/main.rs
blob: 4b6150f001793583d5a83fa52bcbb72fa68fff45 (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
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.len() != 2 {
        eprintln!("Usage: {} filename", args[0]);
        std::process::exit(1);
    }

    let filename = &args[1];

    let file = File::open(filename).unwrap_or_else(|_| panic!("No such file: {}", filename));
    let reader = BufReader::new(file);

    let mut fd = reader.lines();
    let mut called_numbers: Vec<i32> = Vec::new();

    if let Ok(called_nums) = fd.next().unwrap() {
        called_numbers = called_nums.split(",").map(|x| x.parse().unwrap()).collect();
    }

    fd.next(); /* Skip the empty line */

    let mut boards: Vec<(Vec<(i32, bool)>, bool)> = Vec::new();

    'outer: loop {
        let mut miniboard: Vec<(i32, bool)> = Vec::new();
        for _ in 0..5 {
            /* New Board */
            if let Some(maybe_line) = fd.next() {
                if let Ok(line) = maybe_line {
                    for (a, b) in line
                        .split_whitespace()
                        .map(|x| x.parse().unwrap())
                        .zip([false].iter().cycle())
                    {
                        miniboard.push((a, *b));
                    }
                }
            } else {
                break 'outer;
            }
        }
        boards.push((miniboard.clone(), false));
        fd.next(); /* Skip the empty line */
    }

    for bingo in called_numbers {
        for (board, _) in boards.iter_mut() {
            for (num, mark) in board.iter_mut() {
                if *num == bingo {
                    *mark = true;
                }
            }
        }

        let mut count;
        for (board, won) in boards.iter_mut() {
            for row in 0..5 {
                count = 0;
                for i in row * 5..(row * 5) + 5 {
                    if board[i].1 {
                        count += 1;
                    }
                }
                if count == 5 {
                    *won = true;
                }
            }

            for column in 0..5 {
                count = 0;
                for i in (0..5).map(|x| 5 * x + column) {
                    if board[i].1 {
                        count += 1;
                    }
                }
                if count == 5 {
                    *won = true;
                }
            }
        }
        if boards.len() == 1 {
            let mut score: i32 = 0;
            if let Some(board) = boards.get(0) {
                for (winnynum, marked) in board.0.iter() {
                    if !marked {
                        score += winnynum;
                    }
                }
                println!("score: {}", score * bingo);
            }
        }
        boards.retain(|x| !x.1);
    }
}