Skip to content

Commit 75f8f06

Browse files
committed
Use teleport
1 parent 4845ddc commit 75f8f06

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/models.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ pub enum Command {
151151
NewHand(Point),
152152
FastWheel,
153153
Drill,
154+
ResetBeacon,
155+
ShiftBeacon(Point),
154156
}
155157

156158
impl fmt::Display for Command {
@@ -166,6 +168,8 @@ impl fmt::Display for Command {
166168
Command::NewHand(p) => write!(f, "B({}, {})", p.x, p.y),
167169
Command::FastWheel => write!(f, "F"),
168170
Command::Drill => write!(f, "L"),
171+
Command::ResetBeacon => write!(f, "R"),
172+
Command::ShiftBeacon(p) => write!(f, "T({}, {})", p.x, p.y)
169173
}
170174
}
171175
}

src/solve.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ fn update_point(
8989
passed: &mut Matrix<bool>,
9090
booster_map: &mut Matrix<Option<BoosterType>>,
9191
hand_count: &mut usize,
92+
tele_count: &mut usize,
9293
remaining: &mut usize,
9394
) {
9495
bodies_diff.iter().map(|diff| point + *diff).for_each(|b| {
@@ -100,6 +101,7 @@ fn update_point(
100101
if let Some(Some(kind)) = booster_map.get(point) {
101102
match kind {
102103
BoosterType::NewHand => *hand_count += 1,
104+
BoosterType::Teleports => *tele_count += 1,
103105
BoosterType::Drill => {}
104106
_ => {}
105107
}
@@ -156,6 +158,8 @@ pub fn solve_small(task: Task) -> Vec<Command> {
156158
]);
157159

158160
let mut hand_count = 0;
161+
let mut tele_count = 0;
162+
let mut tele_points = Vec::new();
159163

160164
while remaining > 0 {
161165
while hand_count > 0 && !new_bodies.is_empty() {
@@ -164,15 +168,24 @@ pub fn solve_small(task: Task) -> Vec<Command> {
164168
bodies_diff.push(new_hand);
165169
res.push(Command::NewHand(new_hand));
166170
}
171+
172+
if tele_count > 0 {
173+
tele_points.push(current_point);
174+
tele_count -= 1;
175+
res.push(Command::ResetBeacon);
176+
}
177+
167178
update_point(
168179
current_point,
169180
&bodies_diff,
170181
&mut passed,
171182
&mut booster_map,
172183
&mut hand_count,
184+
&mut tele_count,
173185
&mut remaining,
174186
);
175-
let moves = find_shortest_path(
187+
188+
let base_moves = find_shortest_path(
176189
width,
177190
height,
178191
&valid,
@@ -181,6 +194,34 @@ pub fn solve_small(task: Task) -> Vec<Command> {
181194
&bodies_diff,
182195
&booster_map,
183196
);
197+
198+
let tele_moves = tele_points
199+
.iter()
200+
.map(|start| {
201+
(
202+
start,
203+
find_shortest_path(
204+
width,
205+
height,
206+
&valid,
207+
&passed,
208+
*start,
209+
&bodies_diff,
210+
&booster_map,
211+
),
212+
)
213+
})
214+
.min_by_key(|(_, v)| v.len());
215+
216+
let moves = match tele_moves {
217+
Some((tele_point, ref tele_moves)) if tele_moves.len() + 1 < base_moves.len() => {
218+
res.push(Command::ShiftBeacon(*tele_point));
219+
current_point = *tele_point;
220+
tele_moves
221+
}
222+
_ => &base_moves,
223+
};
224+
184225
for m in moves {
185226
current_point = current_point.move_with(&m);
186227
update_point(
@@ -189,9 +230,10 @@ pub fn solve_small(task: Task) -> Vec<Command> {
189230
&mut passed,
190231
&mut booster_map,
191232
&mut hand_count,
233+
&mut tele_count,
192234
&mut remaining,
193235
);
194-
res.push(Command::Move(m));
236+
res.push(Command::Move(m.clone()));
195237
}
196238
}
197239

0 commit comments

Comments
 (0)