Browse Source

level 3 working

master
Michael Preisach 8 years ago
parent
commit
333561b6c2
  1. 241
      src/main.rs

241
src/main.rs

@ -2,11 +2,16 @@ fn main() {
println!("Hello, world!"); println!("Hello, world!");
} }
pub const DEBUG : bool = true; pub const DEBUG : bool = false;
pub struct Trail { pub struct Trail {
waypoints: Vec<Point>, waypoints: Vec<Point>,
directions: Vec<Direction>, directions: Vec<Direction>,
min: Point,
max: Point,
distance: i32,
area: i32,
size: i32,
} }
impl Trail { impl Trail {
@ -14,6 +19,11 @@ impl Trail {
Trail { Trail {
waypoints: Vec::new(), waypoints: Vec::new(),
directions: Vec::new(), directions: Vec::new(),
min: Point{x: 0, y: 0},
max: Point{x: 0, y: 0},
distance: 0,
area: 0,
size: 0,
} }
} }
@ -30,35 +40,22 @@ impl Trail {
Ok(i) => i, Ok(i) => i,
}; };
self.directions.push(Direction::North); self.distance = self.walk_rec(plan, steps, Direction::North, Point{x: 0, y: 0});
self.waypoints.push(Point{x: 0, y: 0});
da.dist = self.walk(plan, steps); self.calc_min();
self.calc_max();
let mut min = Point{x: 0, y: 0}; self.calc_area();
let mut max = Point{x: 0, y: 0}; self.calc_size();
for i in &self.waypoints { da.dist = self.distance;
if i.x < min.x { da.area = self.area;
min.x = i.x; da.size = self.size;
}
if i.y < min.y {
min.y = i.y;
}
if i.x > max.x {
max.x = i.x;
}
if i.y > max.y {
max.y = i.y;
}
}
da.area = (max.x - min.x) * (max.y - min.y);
da da
} else { } else {
DistArea{dist:0, area:0, size:0} DistArea{dist:0, area:0, size:0}
} }
} }
fn walk(&mut self, mut plan: Vec<String>, steps: i32) -> i32 { fn walk_rec(&mut self, mut plan: Vec<String>, steps: i32, mut dir: Direction, mut pos: Point) -> i32 {
if steps == 0 { if steps == 0 {
0 0
} else { } else {
@ -68,8 +65,7 @@ impl Trail {
Err(_) => 0, Err(_) => 0,
Ok(i) => i, Ok(i) => i,
}; };
let mut dir = self.directions.last().unwrap().clone();
let mut pos = self.waypoints.last().unwrap().clone();
for _i in 0 .. count { for _i in 0 .. count {
for c in part.chars() { for c in part.chars() {
match c { match c {
@ -78,32 +74,166 @@ impl Trail {
if DEBUG { if DEBUG {
println!("F, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir); println!("F, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir);
} }
self.directions.push(dir);
self.waypoints.push(pos);
stepcount += 1; stepcount += 1;
}, },
'L' => { 'L' => {
dir = Direction::turn_left(dir); dir = Direction::turn_left(dir);
if DEBUG { if DEBUG {
print!("L"); println!("L, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir);
} }
}, },
'R' => { 'R' => {
dir = Direction::turn_right(dir); dir = Direction::turn_right(dir);
if DEBUG { if DEBUG {
print!("R"); println!("R, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir);
} }
}, },
_ => (), _ => (),
} }
self.directions.push(dir);
self.waypoints.push(pos);
} }
} }
stepcount += self.walk(plan, steps - 1); stepcount += self.walk_rec(plan, steps - 1, dir, pos);
stepcount stepcount
} }
} }
fn calc_min(&mut self) {
self.min = Point{x:0, y:0};
for i in &self.waypoints {
if i.x < self.min.x {
self.min.x = i.x;
}
if i.y < self.min.y {
self.min.y = i.y;
}
}
}
fn calc_max(&mut self) {
self.max = Point{x:0, y:0};
for i in &self.waypoints {
if i.x > self.max.x {
self.max.x = i.x;
}
if i.y > self.max.y {
self.max.y = i.y;
}
}
}
fn calc_area(&mut self) {
self.area = (self.max.x - self.min.x) * (self.max.y - self.min.y);
}
fn calc_size(&mut self) {
for i in self.min.x .. self.max.x {
for j in self.min.y .. self.max.y {
if self.is_in_area(Point{x: i, y: j}) {
self.size += 1;
if DEBUG {
println!("p: ({},{})", i, j);
}
}
}
}
}
fn is_in_area(&self, point: Point) -> bool {
let mut left = 0;
let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y && p.x <= point.x);
for (i, p) in f {
if self.directions[i] == Direction::South {
left += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y+1 && p.x <= point.x);
for (i, p) in f {
if self.directions[i] == Direction::North {
left += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
if DEBUG {
println!("- {} ", left);
}
left % 2 == 1
}
fn calc_pocket(&mut self) {
for i in self.min.x .. self.max.x {
for j in self.min.y .. self.max.y {
if self.is_in_pocket(Point{x: i, y: j}) {
self.size += 1;
if DEBUG {
println!("p: ({},{})", i, j);
}
}
}
}
}
fn is_in_pocket(&self, point: Point) -> bool {
let mut left = 0;
let mut right = 0;
let mut top = 0;
let mut down = 0;
let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y && p.x <= point.x);
for (i, p) in f {
if self.directions[i] == Direction::South {
left += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y+1 && p.x <= point.x);
for (i, p) in f {
if self.directions[i] == Direction::North {
left += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
if DEBUG {
println!("- {} ", left);
}
if left % 2 != 0 || left == 0 {
return false;
}
f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y && p.x > point.x);
for (i, p) in f {
if self.directions[i] == Direction::South {
right += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y+1 && p.x > point.x);
for (i, p) in f {
if self.directions[i] == Direction::North {
right += 1;
if DEBUG {
print!("{:?} {:?} ", p, self.directions[i]);
}
}
}
if DEBUG {
println!("- {} ", left);
}
right % 2 == 0 && right > 0
}
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -133,6 +263,47 @@ impl Direction {
} }
} }
impl PartialEq for Direction {
fn eq(&self, other: &Direction) -> bool {
match self {
&Direction::North => {
match other {
&Direction::North => true,
&Direction::East => false,
&Direction::South => false,
&Direction::West => false,
}
},
&Direction::East => {
match other {
&Direction::North => false,
&Direction::East => true,
&Direction::South => false,
&Direction::West => false,
}
},
&Direction::South => {
match other {
&Direction::North => false,
&Direction::East => false,
&Direction::South => true,
&Direction::West => false,
}
},
&Direction::West => {
match other {
&Direction::North => false,
&Direction::East => false,
&Direction::South => false,
&Direction::West => true,
}
},
}
}
}
impl Eq for Direction {}
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct Point { pub struct Point {
x: i32, x: i32,
@ -268,7 +439,7 @@ mod tests {
let mut trail = Trail::new(); let mut trail = Trail::new();
let mut res = trail.start(input); let mut res = trail.start(input);
assert_eq!(res.size, 12); assert_eq!(res.size, 9);
} }
#[test] #[test]
@ -277,7 +448,7 @@ mod tests {
let mut trail = Trail::new(); let mut trail = Trail::new();
let mut res = trail.start(input); let mut res = trail.start(input);
assert_eq!(res.size, 12); assert_eq!(res.size, 22);
} }
#[test] #[test]
@ -286,7 +457,7 @@ mod tests {
let mut trail = Trail::new(); let mut trail = Trail::new();
let mut res = trail.start(input); let mut res = trail.start(input);
assert_eq!(res.size, 12); assert_eq!(res.size, 115);
} }
#[test] #[test]
@ -295,7 +466,7 @@ mod tests {
let mut trail = Trail::new(); let mut trail = Trail::new();
let mut res = trail.start(input); let mut res = trail.start(input);
assert_eq!(res.size, 12); assert_eq!(res.size, 2190);
} }
#[test] #[test]
@ -304,6 +475,6 @@ mod tests {
let mut trail = Trail::new(); let mut trail = Trail::new();
let mut res = trail.start(input); let mut res = trail.start(input);
assert_eq!(res.size, 12); assert_eq!(res.size, 1156);
} }
} }
Loading…
Cancel
Save