Skip to content

Commit feb49a8

Browse files
committed
Use fast wheel
1 parent 6dcf99c commit feb49a8

File tree

3 files changed

+50
-22
lines changed

3 files changed

+50
-22
lines changed

src/main.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clap::{App, Arg};
22
use rayon::prelude::*;
33
use std::fs::File;
4-
use std::io::{Write};
4+
use std::io::Write;
55

66
use icfpc::models::*;
77
use icfpc::parse::read_all_inputs;
@@ -37,15 +37,14 @@ fn main() {
3737

3838
let inputs = read_all_inputs(&input_root);
3939
inputs.into_par_iter().for_each(|input| {
40+
eprintln!("{}", input.output_file_name());
4041
let mut output_file: Box<Write> = match output_root {
4142
Some(output_root) => {
4243
let output_path = format!("{}/{}", output_root, input.output_file_name());
4344
let output_file = File::create(&output_path).unwrap();
4445
Box::new(output_file)
4546
}
46-
None => {
47-
Box::new(std::io::stdout())
48-
}
47+
None => Box::new(std::io::stdout()),
4948
};
5049
solve(input.task, &mut output_file);
5150
});

src/models.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,22 @@ impl Point {
1313
Point { x, y }
1414
}
1515

16-
pub fn add(&self, p: &Point) -> Point {
16+
pub fn add(self, p: Point) -> Point {
1717
Point::new(self.x + p.x, self.y + p.y)
1818
}
1919

20-
pub fn move_with(&self, kind: &Move) -> Point {
20+
pub fn move_with(self, kind: &Move) -> Point {
2121
let (x, y) = (self.x, self.y);
2222
match kind {
2323
Move::MoveUp => Point::new(x, y + 1),
2424
Move::MoveDown => Point::new(x, y - 1),
2525
Move::MoveRight => Point::new(x + 1, y),
2626
Move::MoveLeft => Point::new(x - 1, y),
27-
_ => *self,
27+
_ => self,
2828
}
2929
}
3030

31-
pub fn revert_with(&self, kind: &Move) -> Point {
31+
pub fn revert_with(self, kind: &Move) -> Point {
3232
let (x, y) = (self.x, self.y);
3333
match kind {
3434
Move::MoveUp => Point::new(x, y - 1),
@@ -78,7 +78,7 @@ impl Map {
7878
let min_x = cmp::min(p.x, q.x);
7979
let max_x = cmp::max(p.x, q.x);
8080
for x in min_x..max_x {
81-
cross_y_map.entry(x).or_insert_with(|| Vec::new()).push(p.y);
81+
cross_y_map.entry(x).or_insert_with(Vec::new).push(p.y);
8282
}
8383
}
8484
}
@@ -135,7 +135,7 @@ pub enum Move {
135135
MoveDown,
136136
MoveLeft,
137137
MoveRight,
138-
Noop
138+
Noop,
139139
}
140140

141141
#[derive(Debug, Clone)]
@@ -144,6 +144,7 @@ pub enum Command {
144144
TurnRight,
145145
TurnLeft,
146146
NewHand(Point),
147+
FastWheel,
147148
}
148149

149150
impl fmt::Display for Command {
@@ -157,6 +158,7 @@ impl fmt::Display for Command {
157158
Command::TurnRight => write!(f, "E"),
158159
Command::TurnLeft => write!(f, "Q"),
159160
Command::NewHand(p) => write!(f, "B({}, {})", p.x, p.y),
161+
Command::FastWheel => write!(f, "F"),
160162
}
161163
}
162164
}

src/solve.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ pub fn solve_small(task: Task) -> Vec<Command> {
6666
Point::new(0, 1),
6767
]);
6868
let mut hand_count = 0;
69+
let mut fast_wheel_count = 0;
70+
let mut fast_wheel_turns = 0;
6971

7072
while remaining > 0 {
7173
while hand_count > 0 && !new_bodies.is_empty() {
@@ -74,16 +76,26 @@ pub fn solve_small(task: Task) -> Vec<Command> {
7476
bodies_diff.push(new_hand);
7577
res.push(Command::NewHand(new_hand));
7678
}
79+
if fast_wheel_count > 0 && fast_wheel_turns == 0 {
80+
fast_wheel_count -= 1;
81+
res.push(Command::FastWheel);
82+
fast_wheel_turns = 50;
83+
}
7784

78-
let mut data: Matrix<Option<Move>> = Matrix::new(width, height, None);
85+
let mut data: Matrix<Option<(Move, usize)>> = Matrix::new(width, height, None);
7986
let mut queue = VecDeque::new();
8087
queue.push_back(cp);
81-
data.set(cp, Some(Move::Noop));
88+
data.set(cp, Some((Move::Noop, 0)));
8289
let mut reached = false;
8390
while let Some(c) = queue.pop_front() {
91+
let cost = match data.get(c) {
92+
Some(Some((_, cost))) => *cost,
93+
_ => panic!("no data is expected"),
94+
};
95+
8496
let bodies = bodies_diff
8597
.iter()
86-
.map(|diff| c.add(diff))
98+
.map(|diff| c.add(*diff))
8799
.collect::<Vec<_>>();
88100
let not_passed = bodies.iter().any(|p| {
89101
if let Some(false) = passed.get(*p) {
@@ -102,18 +114,29 @@ pub fn solve_small(task: Task) -> Vec<Command> {
102114
let mut local_cmds = Vec::new();
103115
let mut iter = c;
104116
while iter != cp {
105-
if let Some(Some(BoosterType::NewHand)) = booster_map.get(iter) {
106-
booster_map.set(iter, None);
107-
hand_count += 1;
117+
match booster_map.get(iter) {
118+
Some(Some(BoosterType::NewHand)) => {
119+
booster_map.set(iter, None);
120+
hand_count += 1;
121+
}
122+
Some(Some(BoosterType::FastMove)) => {
123+
booster_map.set(iter, None);
124+
fast_wheel_count += 1;
125+
}
126+
_ => {}
108127
}
109-
if let Some(Some(mv)) = data.get(iter) {
128+
let (mv, cost) = match data.get(iter) {
129+
Some(Some((mv, cost))) => (mv, cost),
130+
_ => panic!("no data"),
131+
};
132+
iter = iter.revert_with(mv);
133+
if *cost - 1 < fast_wheel_turns {
110134
iter = iter.revert_with(mv);
111-
local_cmds.push(Command::Move(mv.clone()));
112-
} else {
113-
panic!("cannot revert command");
114135
}
136+
local_cmds.push(Command::Move(mv.clone()));
115137
}
116138
local_cmds.reverse();
139+
fast_wheel_count -= std::cmp::min(fast_wheel_count, local_cmds.len());
117140
res.extend(local_cmds);
118141

119142
cp = c;
@@ -122,10 +145,14 @@ pub fn solve_small(task: Task) -> Vec<Command> {
122145
}
123146
moves.shuffle(&mut rng);
124147
for m in &moves {
125-
let nc = c.move_with(m);
148+
let nc = if cost < fast_wheel_turns {
149+
c.move_with(m).move_with(m)
150+
} else {
151+
c.move_with(m)
152+
};
126153
if let Some(None) = data.get(nc) {
127154
if let Some(true) = valid.get(nc) {
128-
data.set(nc, Some(m.clone()));
155+
data.set(nc, Some((m.clone(), cost + 1)));
129156
queue.push_back(nc);
130157
}
131158
}

0 commit comments

Comments
 (0)