diff --git a/src/main.rs b/src/main.rs index 5d25ad7..48547fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ pub struct Trail { distance: i32, area: i32, size: i32, + pocket: i32, } impl Trail { @@ -24,12 +25,13 @@ impl Trail { distance: 0, area: 0, size: 0, + pocket: 0, } } pub fn start(&mut self, way: String) -> DistArea { if !way.is_empty() { - let mut da = DistArea{dist: 0, area: 0, size: 0}; + let mut da = DistArea{dist: 0, area: 0, size: 0, pocket: 0}; let split = way.split_whitespace(); let mut plan : Vec = Vec::new(); for s in split { @@ -46,12 +48,14 @@ impl Trail { self.calc_max(); self.calc_area(); self.calc_size(); + self.calc_pocket(); da.dist = self.distance; da.area = self.area; da.size = self.size; + da.pocket = self.pocket; da } else { - DistArea{dist:0, area:0, size:0} + DistArea{dist:0, area:0, size:0, pocket: 0} } } @@ -171,68 +175,123 @@ impl Trail { fn calc_pocket(&mut self) { for i in self.min.x .. self.max.x { for j in self.min.y .. self.max.y { + if DEBUG { + println!("pocket: p: ({},{})", i, j); + } if self.is_in_pocket(Point{x: i, y: j}) { - self.size += 1; + self.pocket += 1; if DEBUG { - println!("p: ({},{})", i, j); + println!("({},{}) is in pocket", 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 bottom = 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]); + print!("{:?} {:?}; ", p, self.directions[i]); } } } - f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y+1 && p.x <= point.x); + 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]); + print!("{:?} {:?}; ", p, self.directions[i]); } } } if DEBUG { - println!("- {} ", left); + println!("left {} ", left); } - if left % 2 != 0 || left == 0 { - return false; + if left % 2 == 0 && 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 { + right += 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 { + right += 1; + if DEBUG { + print!("{:?} {:?}; ", p, self.directions[i]); + } + } + } + if DEBUG { + println!("right {} ", right); + } + + if right % 2 == 0 && right > 0 { + return true; + } } - f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y && p.x > point.x); + let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.x == point.x && p.y <= point.y); for (i, p) in f { - if self.directions[i] == Direction::South { - right += 1; + if self.directions[i] == Direction::West { + bottom += 1; if DEBUG { - print!("{:?} {:?} ", p, self.directions[i]); + print!("{:?} {:?}; ", p, self.directions[i]); } } } - f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.y == point.y+1 && p.x > point.x); + let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_,p)| p.x == point.x+1 && p.y <= point.y); for (i, p) in f { - if self.directions[i] == Direction::North { - right += 1; + if self.directions[i] == Direction::East { + bottom += 1; if DEBUG { - print!("{:?} {:?} ", p, self.directions[i]); + print!("{:?} {:?}; ", p, self.directions[i]); } } } if DEBUG { - println!("- {} ", left); + println!("bottom {} ", bottom); + } + + if bottom % 2 == 0 && bottom > 0 { + let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_, p)| p.x == point.x && p.y > point.y); + for (i, p) in f { + if self.directions[i] == Direction::West { + top += 1; + if DEBUG { + print!("{:?} {:?}; ", p, self.directions[i]); + } + } + } + let mut f = self.waypoints.clone().into_iter().enumerate().filter(|&(_, p)| p.x == point.x + 1 && p.y > point.y); + for (i, p) in f { + if self.directions[i] == Direction::East { + top += 1; + if DEBUG { + print!("{:?} {:?}; ", p, self.directions[i]); + } + } + } + if DEBUG { + println!("top {} ", top); + } + if top % 2 == 0 && top > 0 { + return true; + } } - right % 2 == 0 && right > 0 + false } } @@ -326,6 +385,7 @@ pub struct DistArea { pub dist: i32, pub area: i32, pub size: i32, + pub pocket: i32, } impl PartialEq for DistArea { @@ -333,6 +393,7 @@ impl PartialEq for DistArea { let mut res = self.dist == other.dist; res &= self.area == other.area; res &= self.size == other.size; + res &= self.pocket == other.pocket; res } } @@ -477,4 +538,49 @@ mod tests { assert_eq!(res.size, 1156); } + + #[test] + fn level4_1() { + let input = String::from("1 FFFR 4"); + let mut trail = Trail::new(); + let mut res = trail.start(input); + + assert_eq!(res.pocket, 0); + } + + #[test] + fn level4_2() { + let input = String::from("9 F 6 R 1 F 4 RFF 2 LFF 1 LFFFR 1 F 2 R 1 F 5"); + let mut trail = Trail::new(); + let mut res = trail.start(input); + + assert_eq!(res.pocket, 4); + } + + #[test] + fn level4_3() { + let input = String::from("14 L 1 FR 1 FFFFFL 1 FFFFL 1 F 12 L 1 F 12 L 1 F 12 L 1 FFFFL 1 FFFFFFFFR 1 FFFR 1 FFFL 1"); + let mut trail = Trail::new(); + let mut res = trail.start(input); + + assert_eq!(res.pocket, 29); + } + + #[test] + fn level4_4() { + let input = String::from("32 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFLFFF 3 R 1 FFFFFF 3 L 1 FFFRFLFLFRFF 2 R 1 FFFRFLFLFRFF 3 R 1 FFFFFF 1 L 1 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFFLFLFRFF 2 L 1 FFLFRFRFFLFLFRFF 3 R 1 FFRFLFLFFRFRFLFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1 FFFFFF 3 R 1 FFFRFLFLFRFF 5 R 1 FFLFRFRFLFFF 1 L 1 FFLFRFRFFLFLFRFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1"); + let mut trail = Trail::new(); + let mut res = trail.start(input); + + assert_eq!(res.pocket, 111); + } + + #[test] + fn level4_5() { + let input = String::from("10 FFLFRFRFFLFLFRFF 5 L 1 FFFRFLFLFRFF 4 L 1 FFLFRFRFFLFLFRFF 8 L 1 FFLFRFRFFLFLFRFF 4 L 1 FFFFFF 3 R 1"); + let mut trail = Trail::new(); + let mut res = trail.start(input); + + assert_eq!(res.pocket, 102); + } }