Skip to content

Commit a1fc2e8

Browse files
committed
add days 17.1
1 parent 8752ce3 commit a1fc2e8

File tree

2 files changed

+211
-2
lines changed

2 files changed

+211
-2
lines changed

input17.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>

src/day17.rs

Lines changed: 210 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,221 @@
1+
use std::collections::HashSet;
2+
13
use super::*;
24

5+
enum Move {
6+
Left,
7+
Right,
8+
}
9+
10+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
11+
struct Coords(usize, usize);
12+
13+
impl Coords {
14+
fn push_right(&mut self) {
15+
self.0 += 1;
16+
}
17+
fn push_left(&mut self) {
18+
self.0 -= 1;
19+
}
20+
fn push_down(&mut self) {
21+
self.1 -= 1;
22+
}
23+
fn set_entry(&mut self, level: usize) {
24+
self.1 += level;
25+
}
26+
}
27+
28+
#[derive(Debug)]
29+
struct Rock {
30+
fills: Vec<Coords>,
31+
}
32+
33+
impl Rock {
34+
fn clone(&self) -> Rock {
35+
Rock {
36+
fills: self.fills.to_vec(),
37+
}
38+
}
39+
fn push_right(&mut self, blocked: &HashSet<Coords>) {
40+
if self.most_right() < 6
41+
&& !self.fills.to_vec().iter_mut().any(|c| {
42+
c.push_right();
43+
blocked.contains(c)
44+
})
45+
{
46+
self.fills.iter_mut().for_each(|c| c.push_right());
47+
}
48+
}
49+
50+
fn push_left(&mut self, blocked: &HashSet<Coords>) {
51+
if self.most_left() > 0
52+
&& !self.fills.to_vec().iter_mut().any(|c| {
53+
c.push_left();
54+
blocked.contains(c)
55+
})
56+
{
57+
self.fills.iter_mut().for_each(|c| c.push_left());
58+
}
59+
}
60+
61+
fn set_entry(&mut self, level: usize) {
62+
self.fills.iter_mut().for_each(|c| c.set_entry(level));
63+
}
64+
65+
fn push_down(&mut self, blocked: &HashSet<Coords>) -> bool {
66+
let most_deep = self.most_deep();
67+
// println!("a{:?}, {:?}", &self, most_deep);
68+
if *most_deep.iter().min().unwrap() > 0
69+
&& !self.fills.to_vec().iter_mut().any(|c| {
70+
c.push_down();
71+
blocked.contains(c)
72+
})
73+
{
74+
self.fills.iter_mut().for_each(|c| c.push_down());
75+
true
76+
} else {
77+
false
78+
}
79+
}
80+
81+
fn most_right(&self) -> usize {
82+
self.fills.iter().map(|c| c.0).max().unwrap()
83+
}
84+
85+
fn most_left(&self) -> usize {
86+
self.fills.iter().map(|c| c.0).min().unwrap()
87+
}
88+
89+
fn most_deep(&self) -> Vec<usize> {
90+
(0..7)
91+
.into_iter()
92+
.map(|i| {
93+
self.fills
94+
.iter()
95+
.find(|c| c.0 == i)
96+
.map(|c| c.1)
97+
.unwrap_or(usize::MAX)
98+
})
99+
.collect::<Vec<usize>>()
100+
}
101+
}
102+
103+
struct Board {
104+
highest: Vec<usize>,
105+
}
106+
107+
impl Board {
108+
fn get_entry(&self) -> usize {
109+
self.highest.iter().max().unwrap() + 4
110+
}
111+
fn get_highest(&self) -> usize {
112+
*self.highest.iter().max().unwrap()
113+
}
114+
}
115+
3116
pub fn solve(filename: String) {
4117
if let Ok(lines) = read_lines(&filename) {
5118
// Consumes the iterator, returns an (Optional) String
119+
let mut board = Board {
120+
highest: vec![0, 0, 0, 0, 0, 0, 0],
121+
};
122+
let rocks = vec![
123+
// ..0123.
124+
Rock {
125+
fills: vec![Coords(2, 0), Coords(3, 0), Coords(4, 0), Coords(5, 0)],
126+
},
127+
// ...4...
128+
// ..123..
129+
// ...0...
130+
Rock {
131+
fills: vec![
132+
Coords(3, 0),
133+
Coords(2, 1),
134+
Coords(3, 1),
135+
Coords(4, 1),
136+
Coords(3, 2),
137+
],
138+
},
139+
// ....4..
140+
// ....3..
141+
// ..012..
142+
Rock {
143+
fills: vec![
144+
Coords(2, 0),
145+
Coords(3, 0),
146+
Coords(4, 0),
147+
Coords(4, 1),
148+
Coords(4, 2),
149+
],
150+
},
151+
// ..3....
152+
// ..2....
153+
// ..1....
154+
// ..0....
155+
Rock {
156+
fills: vec![Coords(2, 0), Coords(2, 1), Coords(2, 2), Coords(2, 3)],
157+
},
158+
// ..23...
159+
// ..01...
160+
Rock {
161+
fills: vec![Coords(2, 0), Coords(3, 0), Coords(2, 1), Coords(3, 1)],
162+
},
163+
];
6164
for line in lines {
7165
if let Ok(ip) = line {
8-
println!("{}", ip)
166+
let movements: Vec<Move> = ip
167+
.chars()
168+
.map(|c| match c {
169+
'>' => Move::Right,
170+
'<' => Move::Left,
171+
_ => panic!("unsupported"),
172+
})
173+
.collect();
174+
let mut rocks_count = 0;
175+
let mut counter = 0;
176+
let mut blocked: HashSet<Coords> = HashSet::new();
177+
blocked.insert(Coords(0, 0));
178+
blocked.insert(Coords(1, 0));
179+
blocked.insert(Coords(2, 0));
180+
blocked.insert(Coords(3, 0));
181+
blocked.insert(Coords(4, 0));
182+
blocked.insert(Coords(5, 0));
183+
blocked.insert(Coords(6, 0));
184+
let mut last = 0;
185+
while rocks_count < 2022 {
186+
let mut rock = rocks[rocks_count % rocks.len()].clone();
187+
rock.set_entry(board.get_entry());
188+
// println!("->{:?}", rock);
189+
loop {
190+
match movements[counter % movements.len()] {
191+
Move::Left => {
192+
rock.push_left(&blocked);
193+
}
194+
Move::Right => {
195+
rock.push_right(&blocked);
196+
}
197+
}
198+
counter += 1;
199+
if !rock.push_down(&blocked) {
200+
for fill in rock.fills {
201+
board.highest[fill.0] = board.highest[fill.0].max(fill.1);
202+
blocked.insert(fill);
203+
}
204+
break;
205+
}
206+
}
207+
rocks_count += 1;
208+
if rocks_count % (rocks.len() * movements.len()) == 0 {
209+
println!("{}: {} ({})", rocks_count, board.get_highest(), board.get_highest() - last);
210+
last = board.get_highest();
211+
}
212+
if rocks_count == 2022 {
213+
println!("{}", board.get_highest());
214+
}
215+
// println!("{}: {:?}", rocks_count, board.highest);
216+
}
217+
println!("{}", board.get_highest());
9218
}
10219
}
11220
}
12221
}
13-

0 commit comments

Comments
 (0)