advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

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 }