@ -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 < String > = 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 ) ;
}
if left % 2 ! = 0 | | left = = 0 {
return false ;
println ! ( "left {} " , left ) ;
}
f = self . waypoints . clone ( ) . into_iter ( ) . enumerate ( ) . filter ( | & ( _ , p ) | p . y = = point . y & & p . x > point . x ) ;
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 ] ) ;
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 {
right + = 1 ;
if DEBUG {
print ! ( "{:?} {:?} " , p , self . directions [ i ] ) ;
print ! ( "{:?} {:?}; " , p , self . directions [ i ] ) ;
}
}
}
if DEBUG {
println ! ( "- {} " , left ) ;
println ! ( "right {} " , right ) ;
}
if right % 2 = = 0 & & right > 0 {
return true ;
}
}
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 {
bottom + = 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 {
bottom + = 1 ;
if DEBUG {
print ! ( "{:?} {:?}; " , p , self . directions [ i ] ) ;
}
}
}
if DEBUG {
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 ] ) ;
}
}
right % 2 = = 0 & & right > 0
}
if DEBUG {
println ! ( "top {} " , top ) ;
}
if top % 2 = = 0 & & top > 0 {
return true ;
}
}
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 ) ;
}
}