main.rs (2967B)
1 const BOARD_SIZE: usize = 5;
2
3 #[derive(Clone, Copy)]
4 struct Board {
5 numbers: [i32; BOARD_SIZE * BOARD_SIZE],
6 marked: [bool; BOARD_SIZE * BOARD_SIZE],
7 pub won: bool,
8 }
9
10 impl Board {
11 fn new(input: &[String]) -> Board {
12 let mut numbers = [0; BOARD_SIZE * BOARD_SIZE];
13 for i in 0..BOARD_SIZE {
14 for (j, x) in input[i]
15 .split_ascii_whitespace()
16 .map(|x| x.parse::<i32>().unwrap())
17 .enumerate()
18 {
19 numbers[i * BOARD_SIZE + j] = x;
20 }
21 }
22 Board {
23 numbers: numbers,
24 marked: [false; BOARD_SIZE * BOARD_SIZE],
25 won: false,
26 }
27 }
28
29 fn mark(&mut self, draw: i32) {
30 if self.won {
31 return;
32 }
33 if let Some(pos) = self.numbers.iter().position(|&x| x == draw) {
34 self.marked[pos] = true;
35 }
36 for i in 0..BOARD_SIZE {
37 if (0..BOARD_SIZE).all(|x| self.marked[i * BOARD_SIZE + x])
38 || (0..BOARD_SIZE).all(|x| self.marked[x * BOARD_SIZE + i])
39 {
40 self.won = true;
41 return;
42 }
43 }
44 }
45
46 fn score(&self) -> Option<i32> {
47 if self.won {
48 Some(
49 self.numbers
50 .iter()
51 .enumerate()
52 .filter_map(|(i, x)| if self.marked[i] { None } else { Some(x) })
53 .sum(),
54 )
55 } else {
56 None
57 }
58 }
59 }
60
61 fn main() {
62 let input = std::fs::read_to_string("input.txt")
63 .unwrap()
64 .trim()
65 .split('\n')
66 .filter_map(|x| {
67 if x.len() > 0 {
68 Some(x.to_string())
69 } else {
70 None
71 }
72 })
73 .collect::<Vec<String>>();
74 let draws = input[0]
75 .split(',')
76 .map(|x| x.parse::<i32>().unwrap())
77 .collect::<Vec<_>>();
78 let boards = input[1..]
79 .chunks(BOARD_SIZE)
80 .map(|x| Board::new(x))
81 .collect::<Vec<_>>();
82 // 74320
83 println!("Part 1 : {}", part_1(&draws, &boards));
84 // 17884
85 println!("Part 2 : {}", part_2(&draws, &boards));
86 }
87
88 fn part_1(draws: &Vec<i32>, boards: &Vec<Board>) -> i32 {
89 let mut boards = boards.clone();
90 for draw in draws {
91 for board in boards.iter_mut() {
92 board.mark(*draw);
93 if let Some(score) = board.score() {
94 return score * draw;
95 }
96 }
97 }
98 0
99 }
100
101 fn part_2(draws: &Vec<i32>, boards: &Vec<Board>) -> i32 {
102 let mut boards = boards.clone();
103 let mut last_score = 0;
104 for draw in draws {
105 for board in boards.iter_mut() {
106 if !board.won {
107 board.mark(*draw);
108 if let Some(score) = board.score() {
109 last_score = score * draw;
110 }
111 }
112 }
113 }
114 last_score
115 }