Skip to content
Permalink
Browse files

Fix slowness

  • Loading branch information...
ichyo committed Jun 22, 2019
1 parent be7f354 commit e5382a8a459c7d18384e6b13288711ec58fc9abf
Showing with 48 additions and 44 deletions.
  1. +27 −22 src/models.rs
  2. +17 −16 src/solve.rs
  3. +4 −6 src/utils.rs
@@ -17,24 +17,24 @@ impl Point {
Point::new(self.x + p.x, self.y + p.y)
}

pub fn move_with(&self, command: Command) -> Point {
pub fn move_with(&self, kind: &Move) -> Point {
let (x, y) = (self.x, self.y);
match command {
Command::MoveUp => Point::new(x, y + 1),
Command::MoveDown => Point::new(x, y - 1),
Command::MoveRight => Point::new(x + 1, y),
Command::MoveLeft => Point::new(x - 1, y),
match kind {
Move::MoveUp => Point::new(x, y + 1),
Move::MoveDown => Point::new(x, y - 1),
Move::MoveRight => Point::new(x + 1, y),
Move::MoveLeft => Point::new(x - 1, y),
_ => *self,
}
}

pub fn revert_with(&self, command: Command) -> Point {
pub fn revert_with(&self, kind: &Move) -> Point {
let (x, y) = (self.x, self.y);
match command {
Command::MoveUp => Point::new(x, y - 1),
Command::MoveDown => Point::new(x, y + 1),
Command::MoveRight => Point::new(x - 1, y),
Command::MoveLeft => Point::new(x + 1, y),
match kind {
Move::MoveUp => Point::new(x, y - 1),
Move::MoveDown => Point::new(x, y + 1),
Move::MoveRight => Point::new(x - 1, y),
Move::MoveLeft => Point::new(x + 1, y),
_ => unreachable!(),
}
}
@@ -99,7 +99,7 @@ impl Map {
}
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub enum BoosterType {
NewHand,
FastMove,
@@ -109,7 +109,7 @@ pub enum BoosterType {
Unknown,
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub struct Booster {
pub kind: BoosterType,
pub point: Point,
@@ -129,13 +129,18 @@ pub struct Task {
pub boosters: Vec<Booster>,
}

#[derive(Debug, Clone, Copy)]
pub enum Command {
#[derive(Debug, Clone)]
pub enum Move {
MoveUp,
MoveDown,
MoveLeft,
MoveRight,
Noop,
Noop
}

#[derive(Debug, Clone)]
pub enum Command {
Move(Move),
TurnRight,
TurnLeft,
NewHand(Point),
@@ -144,11 +149,11 @@ pub enum Command {
impl fmt::Display for Command {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Command::MoveUp => write!(f, "W"),
Command::MoveDown => write!(f, "S"),
Command::MoveLeft => write!(f, "A"),
Command::MoveRight => write!(f, "D"),
Command::Noop => write!(f, "Z"),
Command::Move(Move::MoveUp) => write!(f, "W"),
Command::Move(Move::MoveDown) => write!(f, "S"),
Command::Move(Move::MoveLeft) => write!(f, "A"),
Command::Move(Move::MoveRight) => write!(f, "D"),
Command::Move(Move::Noop) => write!(f, "Z"),
Command::TurnRight => write!(f, "E"),
Command::TurnLeft => write!(f, "Q"),
Command::NewHand(p) => write!(f, "B({}, {})", p.x, p.y),
@@ -26,8 +26,8 @@ pub fn solve_small(task: Task) -> Vec<Command> {
remaining += 1;
}

for &b in &task.boosters {
booster_map.set(b.point, Some(b.kind));
for b in &task.boosters {
booster_map.set(b.point, Some(b.kind.clone()));
}

for o in &task.obstacles {
@@ -41,10 +41,10 @@ pub fn solve_small(task: Task) -> Vec<Command> {
}

let mut moves = [
Command::MoveUp,
Command::MoveDown,
Command::MoveLeft,
Command::MoveRight,
Move::MoveUp,
Move::MoveDown,
Move::MoveLeft,
Move::MoveRight,
];
let mut res = Vec::new();
let mut cp = task.initial;
@@ -71,14 +71,14 @@ pub fn solve_small(task: Task) -> Vec<Command> {
while hand_count > 0 && !new_bodies.is_empty() {
let new_hand = new_bodies.pop_front().unwrap();
hand_count -= 1;
//bodies_diff.push(new_hand);
bodies_diff.push(new_hand);
res.push(Command::NewHand(new_hand));
}

let mut data = Matrix::new(width, height, None);
let mut data: Matrix<Option<Move>> = Matrix::new(width, height, None);
let mut queue = VecDeque::new();
queue.push_back(cp);
data.set(cp, Some(Command::Noop));
data.set(cp, Some(Move::Noop));
let mut reached = false;
while let Some(c) = queue.pop_front() {
let bodies = bodies_diff
@@ -102,15 +102,16 @@ pub fn solve_small(task: Task) -> Vec<Command> {
let mut local_cmds = Vec::new();
let mut iter = c;
while iter != cp {
/*
if let Some(Some(BoosterType::NewHand)) = booster_map.get(iter) {
booster_map.set(iter, None);
hand_count += 1;
}
*/
let cmd = data.get(iter).unwrap().unwrap();
local_cmds.push(cmd);
iter = iter.revert_with(cmd);
if let Some(Some(mv)) = data.get(iter) {
iter = iter.revert_with(mv);
local_cmds.push(Command::Move(mv.clone()));
} else {
panic!("cannot revert command");
}
}
local_cmds.reverse();
res.extend(local_cmds);
@@ -121,10 +122,10 @@ pub fn solve_small(task: Task) -> Vec<Command> {
}
moves.shuffle(&mut rng);
for m in &moves {
let nc = c.move_with(*m);
let nc = c.move_with(m);
if let Some(None) = data.get(nc) {
if let Some(true) = valid.get(nc) {
data.set(nc, Some(*m));
data.set(nc, Some(m.clone()));
queue.push_back(nc);
}
}
@@ -6,7 +6,7 @@ pub struct Matrix<T> {
inner: Vec<T>,
}

impl<T: Copy> Matrix<T> {
impl<T: Clone> Matrix<T> {
pub fn new(width: usize, height: usize, init: T) -> Matrix<T> {
let n = width * height;
Matrix {
@@ -16,9 +16,9 @@ impl<T: Copy> Matrix<T> {
}
}

pub fn get(&self, p: Point) -> Option<T> {
pub fn get(&self, p: Point) -> Option<&T> {
if p.x >= 0 && p.y >= 0 && (p.x as usize) < self.width && (p.y as usize) < self.height {
Some(self.inner[p.y as usize * self.width + p.x as usize])
Some(&self.inner[p.y as usize * self.width + p.x as usize])
} else {
None
}
@@ -34,9 +34,7 @@ impl<T: Copy> Matrix<T> {

pub fn try_set(&mut self, p: Point, value: T) -> Option<T> {
if let Some(r) = self.get_mut(p) {
let old = *r;
*r = value;
Some(old)
Some(std::mem::replace(r, value))
} else {
None
}

0 comments on commit e5382a8

Please sign in to comment.
You can’t perform that action at this time.