Skip to content
Permalink
Browse files

Use hand:

  • Loading branch information...
ichyo committed Jun 22, 2019
1 parent f152a42 commit b06ca0381c3e5408ca2cf33c824d3b2fa958f6fb
Showing with 51 additions and 17 deletions.
  1. +2 −2 src/bin/score.rs
  2. +4 −0 src/models.rs
  3. +32 −12 src/solve.rs
  4. +13 −3 src/utils.rs
@@ -46,14 +46,14 @@ fn score_small(task: Task, output_len: usize) -> ScoreInfo {
let mut passed = Matrix::new(width as usize, height as usize, true);
let mut valid = Matrix::new(width as usize, height as usize, false);

for p in &map_points {
for &p in &map_points {
passed.set(p, false);
valid.set(p, true);
remaining += 1;
}

for o in &task.obstacles {
for p in o.enumerate_points().iter() {
for &p in o.enumerate_points().iter() {
if let Some(true) = valid.get(p) {
valid.set(p, false);
passed.set(p, true);
@@ -13,6 +13,10 @@ impl Point {
Point { x, y }
}

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

pub fn move_with(&self, command: Command) -> Point {
let (x, y) = (self.x, self.y);
match command {
@@ -19,14 +19,14 @@ pub fn solve_small(task: Task) -> Vec<Command> {
let mut passed = Matrix::new(width, height, true);
let mut valid = Matrix::new(width, height, false);

for p in &map_points {
for &p in &map_points {
passed.set(p, false);
valid.set(p, true);
remaining += 1;
}

for o in &task.obstacles {
for p in o.enumerate_points().iter() {
for &p in o.enumerate_points().iter() {
if let Some(true) = valid.get(p) {
valid.set(p, false);
passed.set(p, true);
@@ -43,25 +43,45 @@ pub fn solve_small(task: Task) -> Vec<Command> {
];
let mut res = Vec::new();
let mut cp = task.initial;
if !passed.get(&cp).unwrap() {
passed.set(&cp, true);
if !passed.get(cp).unwrap() {
passed.set(cp, true);
remaining -= 1;
}
let bodies_diff = vec![
Point::new(0, 0),
Point::new(1, 1),
Point::new(1, 0),
Point::new(1, -1),
];
while remaining > 0 {
let mut data = Matrix::new(width, height, None);
let mut queue = VecDeque::new();
queue.push_back(cp);
data.set(&cp, Some(Command::Noop));
data.set(cp, Some(Command::Noop));
let mut reached = false;
while let Some(c) = queue.pop_front() {
if !passed.get(&c).unwrap() {
passed.set(&c, true);
remaining -= 1;
let bodies = bodies_diff
.iter()
.map(|diff| c.add(diff))
.collect::<Vec<_>>();
let not_passed = bodies.iter().any(|p| {
if let Some(false) = passed.get(*p) {
true
} else {
false
}
});
if not_passed {
for body in bodies {
if let Some(false) = passed.try_set(body, true) {
remaining -= 1;
}
}

let mut local_cmds = Vec::new();
let mut iter = c;
while iter != cp {
let cmd = data.get(&iter).unwrap().unwrap();
let cmd = data.get(iter).unwrap().unwrap();
local_cmds.push(cmd);
iter = iter.revert_with(cmd);
}
@@ -75,9 +95,9 @@ pub fn solve_small(task: Task) -> Vec<Command> {
moves.shuffle(&mut rng);
for m in &moves {
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));
if let Some(None) = data.get(nc) {
if let Some(true) = valid.get(nc) {
data.set(nc, Some(*m));
queue.push_back(nc);
}
}
@@ -16,23 +16,33 @@ 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])
} else {
None
}
}

pub fn get_mut(&mut self, p: &Point) -> Option<&mut T> {
pub fn get_mut(&mut self, p: Point) -> Option<&mut T> {
if p.x >= 0 && p.y >= 0 && (p.x as usize) < self.width && (p.y as usize) < self.height {
Some(&mut self.inner[p.y as usize * self.width + p.x as usize])
} else {
None
}
}

pub fn set(&mut self, p: &Point, value: 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)
} else {
None
}
}

pub fn set(&mut self, p: Point, value: T) {
if let Some(r) = self.get_mut(p) {
*r = value;
} else {

0 comments on commit b06ca03

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