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 }