aboutsummaryrefslogtreecommitdiff
path: root/2022/17/common.rs
diff options
context:
space:
mode:
Diffstat (limited to '2022/17/common.rs')
-rw-r--r--2022/17/common.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/2022/17/common.rs b/2022/17/common.rs
new file mode 100644
index 0000000..d27ec3a
--- /dev/null
+++ b/2022/17/common.rs
@@ -0,0 +1,85 @@
1use std::cmp::max;
2
3pub const SCREEN_WIDTH: usize = 7;
4pub const SCREEN_HEIGHT: usize = 100000;
5
6pub struct Screen {
7 pub cell: [[bool; SCREEN_WIDTH]; SCREEN_HEIGHT],
8 pub top: usize
9}
10
11#[derive(Debug)]
12pub struct Rock {
13 pub a: Vec<(usize, usize)>,
14 pub h: usize
15}
16
17pub 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
27fn in_bounds(position: (i32, i32)) -> bool {
28 position.0 >= 0 && position.1 >= 0 && position.1 < SCREEN_WIDTH as i32
29}
30
31impl 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}

Generated with cgit - Back to sebastiano.tronto.net