From 333561b6c2dc8d7dae5440062a723affb3a08ec2 Mon Sep 17 00:00:00 2001 From: Michael Preisach Date: Thu, 24 May 2018 20:35:07 +0200 Subject: [PATCH] level 3 working --- src/main.rs | 243 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 207 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index bd5200d..5d25ad7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,16 @@ fn main() { println!("Hello, world!"); } -pub const DEBUG : bool = true; +pub const DEBUG : bool = false; pub struct Trail { waypoints: Vec, directions: Vec, + min: Point, + max: Point, + distance: i32, + area: i32, + size: i32, } impl Trail { @@ -14,6 +19,11 @@ impl Trail { Trail { waypoints: 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, }; - self.directions.push(Direction::North); - self.waypoints.push(Point{x: 0, y: 0}); + self.distance = self.walk_rec(plan, steps, Direction::North, Point{x: 0, y: 0}); - da.dist = self.walk(plan, steps); - - let mut min = Point{x: 0, y: 0}; - let mut max = Point{x: 0, y: 0}; - for i in &self.waypoints { - if i.x < min.x { - min.x = i.x; - } - 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); + self.calc_min(); + self.calc_max(); + self.calc_area(); + self.calc_size(); + da.dist = self.distance; + da.area = self.area; + da.size = self.size; da } else { DistArea{dist:0, area:0, size:0} } } - fn walk(&mut self, mut plan: Vec, steps: i32) -> i32 { + fn walk_rec(&mut self, mut plan: Vec, steps: i32, mut dir: Direction, mut pos: Point) -> i32 { if steps == 0 { 0 } else { @@ -68,8 +65,7 @@ impl Trail { Err(_) => 0, 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 c in part.chars() { match c { @@ -78,32 +74,166 @@ impl Trail { if DEBUG { println!("F, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir); } + self.directions.push(dir); + self.waypoints.push(pos); stepcount += 1; }, 'L' => { dir = Direction::turn_left(dir); if DEBUG { - print!("L"); + println!("L, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir); } }, 'R' => { dir = Direction::turn_right(dir); 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 } } + + 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)] @@ -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)] pub struct Point { x: i32, @@ -268,7 +439,7 @@ mod tests { let mut trail = Trail::new(); let mut res = trail.start(input); - assert_eq!(res.size, 12); + assert_eq!(res.size, 9); } #[test] @@ -277,7 +448,7 @@ mod tests { let mut trail = Trail::new(); let mut res = trail.start(input); - assert_eq!(res.size, 12); + assert_eq!(res.size, 22); } #[test] @@ -286,7 +457,7 @@ mod tests { let mut trail = Trail::new(); let mut res = trail.start(input); - assert_eq!(res.size, 12); + assert_eq!(res.size, 115); } #[test] @@ -295,7 +466,7 @@ mod tests { let mut trail = Trail::new(); let mut res = trail.start(input); - assert_eq!(res.size, 12); + assert_eq!(res.size, 2190); } #[test] @@ -304,6 +475,6 @@ mod tests { let mut trail = Trail::new(); let mut res = trail.start(input); - assert_eq!(res.size, 12); + assert_eq!(res.size, 1156); } -} \ No newline at end of file +}