aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2022/14/a.rs22
-rw-r--r--2022/14/b.rs22
-rw-r--r--2022/14/common.rs129
3 files changed, 173 insertions, 0 deletions
diff --git a/2022/14/a.rs b/2022/14/a.rs
new file mode 100644
index 0000000..e775c23
--- /dev/null
+++ b/2022/14/a.rs
@@ -0,0 +1,22 @@
1mod common;
2use common::*;
3
4fn drop(map: &mut Map, i: (usize, usize)) -> bool {
5 let (x, y) = i;
6 if y > map.ymax { return false; }
7
8 for j in vec![(x, y+1), (x-1, y+1), (x+1, y+1)].into_iter() {
9 if !map.at(j) { return drop(map, j); }
10 }
11
12 map[i] = true;
13 true
14}
15
16fn main() {
17 let mut map = read_map_from_stdin();
18 let mut i = 0;
19 while drop(&mut map, (500, 0)) { i+= 1; }
20 //map.print();
21 println!("{i}");
22}
diff --git a/2022/14/b.rs b/2022/14/b.rs
new file mode 100644
index 0000000..f8a4829
--- /dev/null
+++ b/2022/14/b.rs
@@ -0,0 +1,22 @@
1mod common;
2use common::*;
3
4fn drop(map: &mut Map, i: (usize, usize)) -> bool {
5 let (x, y) = i;
6 if y < map.ymax {
7 for j in vec![(x, y+1), (x-1, y+1), (x+1, y+1)].into_iter() {
8 if !map.at(j) { return drop(map, j); }
9 }
10 }
11
12 map[i] = true;
13 !map.at((500, 0)) // Returns false after filling the last -> off by 1
14}
15
16fn main() {
17 let mut map = read_map_from_stdin();
18 let mut i = 0;
19 while drop(&mut map, (500, 0)) { i += 1; }
20 //map.print();
21 println!("{}", i+1);
22}
diff --git a/2022/14/common.rs b/2022/14/common.rs
new file mode 100644
index 0000000..40f32bb
--- /dev/null
+++ b/2022/14/common.rs
@@ -0,0 +1,129 @@
1use std::cmp::{min, max};
2use std::ops::{Index, IndexMut};
3
4pub struct Map {
5 cells: Vec<Vec<bool>>,
6 pub xmin: usize,
7 pub xmax: usize,
8 pub ymin: usize,
9 pub ymax: usize
10}
11
12fn line_from_str(s: &str) -> Vec<(usize, usize)> {
13 let mut line = vec![];
14 let mut i = 0;
15 while i < s.len() {
16 let mut j = s[i..].find(',').unwrap();
17 let x = s[i..i+j].parse::<usize>().unwrap();
18 i += j+1;
19 j = s[i..].find(|c| c == ' ' || c == '\n').unwrap();
20 let y = s[i..i+j].parse::<usize>().unwrap();
21 i += j+4;
22 line.push((x, y));
23 }
24 line
25}
26
27impl Index<(usize, usize)> for Map {
28 type Output = bool;
29 fn index(&self, i: (usize, usize)) -> &bool {
30 self.validate_index(i);
31 &self.cells[i.1-self.ymin][i.0-self.xmin]
32 }
33}
34
35impl IndexMut<(usize, usize)> for Map {
36 fn index_mut(&mut self, i: (usize, usize)) -> &mut bool {
37 self.validate_index(i);
38 &mut self.cells[i.1-self.ymin][i.0-self.xmin]
39 }
40}
41
42impl Map {
43 fn in_bounds(&self, i: (usize, usize)) -> bool {
44 i.0 >= self.xmin && i.0 <= self.xmax &&
45 i.1 >= self.ymin && i.1 <= self.ymax
46 }
47
48 fn validate_index(&self, i: (usize, usize)) {
49 if !self.in_bounds(i) {
50 panic!("Out of bounds: {} {} outside [{}, {}]x[{}, {}]",
51 i.0, i.1, self.xmin, self.xmax, self.ymin, self.ymax);
52 }
53 }
54
55 pub fn at(&self, i: (usize, usize)) -> bool {
56 self.in_bounds(i) && self[i]
57 }
58
59 fn set_bounds(&mut self, lines: &Vec<Vec<(usize, usize)>>) {
60 for l in lines {
61 for p in l {
62 self.xmin = min(self.xmin, p.0);
63 self.xmax = max(self.xmax, p.0);
64 self.ymin = min(self.ymin, p.1);
65 self.ymax = max(self.ymax, p.1+1);
66 }
67 }
68
69 // Part 2 requires a larger map
70 self.xmin = min(self.xmin, 500 - self.ymax - 1);
71 self.xmax = max(self.xmax, 500 + self.ymax + 1);
72 self.cells = vec![
73 vec![false; self.xmax-self.xmin+1]; self.ymax-self.ymin+1
74 ];
75 }
76
77 fn fill_line(&mut self, line: &Vec<(usize, usize)>) {
78 for i in 0..line.len()-1 {
79 if line[i].0 == line[i+1].0 {
80 let y0 = min(line[i].1, line[i+1].1);
81 let y1 = max(line[i].1, line[i+1].1);
82 for y in y0..=y1 {
83 self[(line[i].0, y)] = true;
84 }
85 } else {
86 let x0 = min(line[i].0, line[i+1].0);
87 let x1 = max(line[i].0, line[i+1].0);
88 for x in x0..=x1 {
89 self[(x, line[i].1)] = true;
90 }
91 }
92 }
93 }
94
95 fn from_lines(lines: &Vec<Vec<(usize, usize)>>) -> Map {
96 let mut map = Map {
97 cells: vec![],
98 xmin: 500,
99 xmax: 500,
100 ymin: 0,
101 ymax: 0
102 };
103 map.set_bounds(lines);
104 for l in lines { map.fill_line(l); }
105 map
106 }
107
108 #[allow(dead_code)]
109 pub fn print(&self) {
110 println!("x: {} to {}", self.xmin, self.xmax);
111 println!("y: {} to {}", self.ymin, self.ymax);
112 for v in &self.cells {
113 for b in v {
114 print!("{}", if *b { '#' } else { '.' });
115 }
116 println!();
117 }
118 }
119}
120
121pub fn read_map_from_stdin() -> Map {
122 let mut lines = Vec::<Vec<(usize, usize)>>::new();
123 let mut s = String::new();
124 while std::io::stdin().read_line(&mut s).unwrap() > 0 {
125 lines.push(line_from_str(&s));
126 s.clear();
127 }
128 Map::from_lines(&lines)
129}

Generated with cgit - Back to sebastiano.tronto.net