aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

common.rs (2447B)


      1 use std::cmp::max;
      2 
      3 pub const SCREEN_WIDTH: usize = 7;
      4 pub const SCREEN_HEIGHT: usize = 100000;
      5 
      6 pub struct Screen {
      7     pub cell: [[bool; SCREEN_WIDTH]; SCREEN_HEIGHT],
      8     pub top: usize
      9 }
     10 
     11 #[derive(Debug)]
     12 pub struct Rock {
     13     pub a: Vec<(usize, usize)>,
     14     pub h: usize
     15 }
     16 
     17 pub fn get_rocks() -> Vec<Rock> {
     18     vec![
     19         Rock { a: vec![(0, 0), (0, 1), (0, 2), (0, 3)], h: 1 },
     20         Rock { a: vec![(0, 1), (1, 0), (1, 1), (1, 2), (2, 1)], h: 3 },
     21         Rock { a: vec![(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)], h: 3 },
     22         Rock { a: vec![(0, 0), (1, 0), (2, 0), (3, 0)], h: 4 },
     23         Rock { a: vec![(0, 0), (0, 1), (1, 0), (1, 1)], h: 2 }
     24     ]
     25 }
     26 
     27 fn in_bounds(position: (i32, i32)) -> bool {
     28     position.0 >= 0 && position.1 >= 0 && position.1 < SCREEN_WIDTH as i32
     29 }
     30 
     31 impl Screen {
     32     pub fn new() -> Screen {
     33         Screen {
     34             cell: [[false; SCREEN_WIDTH]; SCREEN_HEIGHT],
     35             top: 0
     36         }
     37     }
     38 
     39     fn allowed(&self, rock: &Rock, p: (i32, i32)) -> bool {
     40         for r in &rock.a {
     41             let (i, j) = (r.0 as i32 + p.0, r.1 as i32 + p.1);
     42             if !in_bounds((i, j)) || self.cell[i as usize][j as usize] {
     43                 return false;
     44             }
     45         }
     46         true
     47     }
     48 
     49     fn draw(&mut self, rock: &Rock, p: (usize, usize), b: bool) {
     50         for r in &rock.a {
     51             self.cell[r.0 + p.0][r.1 + p.1] = b;
     52         }
     53     }
     54 
     55     fn move_rock(&mut self, r: &Rock, p: (usize, usize), d: (i32, i32)) -> (usize, usize) {
     56         let newpos = (p.0 as i32 + d.0, p.1 as i32 + d.1);
     57         if !self.allowed(r, newpos) { return p; }
     58         let newpos = (newpos.0 as usize, newpos.1 as usize);
     59         newpos
     60     }
     61 
     62     pub fn drop_rock(&mut self, r: &Rock, t: &mut usize, gas: &str) {
     63         let mut p = (self.top + 3, 2);
     64         loop {
     65             let d = gas.chars().nth(*t % gas.len()).unwrap();
     66             let d = if d == '>' { (0, 1) } else { (0, -1) };
     67             p = self.move_rock(r, p, d);
     68             *t += 1;
     69             let q = self.move_rock(r, p, (-1, 0));
     70             if p == q { break; } else { p = q; }
     71         }
     72         self.draw(r, p, true);
     73         self.top = max(self.top, p.0 + r.h);
     74     }
     75 
     76     #[allow(dead_code)]
     77     pub fn print(&self) {
     78         for i in (0..=self.top).rev() {
     79             for j in 0..SCREEN_WIDTH {
     80                 print!("{}", if self.cell[i][j] { '#' } else { '.' })
     81             }
     82             println!(" {i}");
     83         }
     84     }
     85 }