Skip to content

Commit e74f874

Browse files
committed
Add solution
1 parent f228d80 commit e74f874

File tree

1 file changed

+44
-25
lines changed

1 file changed

+44
-25
lines changed

src/solve.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub struct State<'a> {
9696
valid: Matrix<bool>,
9797
passed: Matrix<bool>,
9898
booster_map: Matrix<Option<BoosterType>>,
99+
remaining_hand: usize,
99100
remaining_clone: usize,
100101
remaining_pass: usize,
101102
hand_count: usize,
@@ -112,6 +113,7 @@ impl<'a> State<'a> {
112113
let height = task.height;
113114

114115
let mut remaining_pass = 0;
116+
let mut remaining_hand = 0;
115117
let mut remaining_clone = 0;
116118
let mut booster_map = Matrix::new(width, height, None);
117119
let mut passed = Matrix::new(width, height, true);
@@ -125,8 +127,10 @@ impl<'a> State<'a> {
125127

126128
for b in &task.boosters {
127129
booster_map.set(b.point, Some(b.kind.clone()));
128-
if let BoosterType::Cloning = b.kind {
129-
remaining_clone += 1;
130+
match b.kind {
131+
BoosterType::Cloning => remaining_clone += 1,
132+
BoosterType::NewHand => remaining_hand += 1,
133+
_ => {}
130134
}
131135
}
132136

@@ -156,6 +160,7 @@ impl<'a> State<'a> {
156160
valid,
157161
passed,
158162
booster_map,
163+
remaining_hand,
159164
remaining_clone,
160165
remaining_pass,
161166
hand_count,
@@ -167,37 +172,50 @@ impl<'a> State<'a> {
167172

168173
fn is_goal(&self, robot_idx: usize, goal: Point) -> bool {
169174
if self.remaining_clone > 0 {
170-
match self.booster_map.get(goal) {
175+
return match self.booster_map.get(goal) {
171176
Some(Some(BoosterType::Cloning)) => true,
172177
_ => false,
173-
}
174-
} else if self.clone_count > 0 {
175-
match self.booster_map.get(goal) {
176-
Some(Some(BoosterType::Spawn)) => true,
177-
_ => false,
178-
}
179-
} else {
180-
let not_passed = self.robots[robot_idx]
181-
.bodies_diff
182-
.iter()
183-
.map(|diff| goal + *diff)
184-
.any(|p| match self.passed.get(p) {
185-
Some(false) => true,
186-
_ => false,
187-
});
188-
189-
let is_booster = match self.booster_map.get(goal) {
190-
Some(Some(BoosterType::NewHand)) => true,
191-
_ => false,
192178
};
179+
}
193180

194-
let is_valid = match self.valid.get(goal) {
195-
Some(true) => true,
181+
if self.clone_count > 0 {
182+
return match self.booster_map.get(goal) {
183+
Some(Some(BoosterType::Spawn)) => true,
196184
_ => false,
197185
};
186+
}
198187

199-
is_valid && (not_passed || is_booster)
188+
if self.remaining_hand > 0 {
189+
if let Some((first_robot_index, _)) = self.robots.iter().enumerate().find(|(_, r)| !r.new_bodies.is_empty()) {
190+
if robot_idx == first_robot_index {
191+
return match self.booster_map.get(goal) {
192+
Some(Some(BoosterType::NewHand)) => true,
193+
_ => false,
194+
};
195+
}
196+
}
200197
}
198+
199+
let not_passed = self.robots[robot_idx]
200+
.bodies_diff
201+
.iter()
202+
.map(|diff| goal + *diff)
203+
.any(|p| match self.passed.get(p) {
204+
Some(false) => true,
205+
_ => false,
206+
});
207+
208+
let is_booster = match self.booster_map.get(goal) {
209+
Some(Some(BoosterType::NewHand)) => true,
210+
_ => false,
211+
};
212+
213+
let is_valid = match self.valid.get(goal) {
214+
Some(true) => true,
215+
_ => false,
216+
};
217+
218+
is_valid && (not_passed || is_booster)
201219
}
202220

203221
fn find_shortest_path(&self, robot_idx: usize, start: Point) -> Option<Vec<Move>> {
@@ -255,6 +273,7 @@ impl<'a> State<'a> {
255273
if let Some(Some(kind)) = self.booster_map.get(current_point) {
256274
match kind {
257275
BoosterType::NewHand => {
276+
self.remaining_hand -= 1;
258277
self.hand_count += 1;
259278
self.booster_map.set(current_point, None);
260279
}

0 commit comments

Comments
 (0)