@@ -3,6 +3,92 @@ use std::collections::HashMap;
33use std:: fmt;
44use std:: ops:: Add ;
55
6+ #[ derive( Debug , Clone , Copy , Eq , PartialEq , Hash ) ]
7+ pub struct Place ( Point , Direction ) ;
8+
9+ impl Place {
10+ pub fn new ( p : Point , d : Direction ) -> Place {
11+ Place ( p, d)
12+ }
13+
14+ pub fn move_with ( & self , m : & Move ) -> Place {
15+ Place :: new ( self . 0 . move_with ( m) , self . 1 . move_with ( m) )
16+ }
17+
18+ pub fn revert_with ( & self , m : & Move ) -> Place {
19+ Place :: new ( self . 0 . revert_with ( m) , self . 1 . revert_with ( m) )
20+ }
21+
22+ pub fn point ( & self ) -> Point {
23+ self . 0
24+ }
25+
26+ pub fn dir ( & self ) -> Direction {
27+ self . 1
28+ }
29+
30+ pub fn hand ( & self , r : Point ) -> Point {
31+ self . 0 + self . 1 . convert ( r)
32+ }
33+ }
34+
35+ #[ derive( Debug , Clone , Copy , Eq , PartialEq , Hash ) ]
36+ pub enum Direction {
37+ Left ,
38+ Up ,
39+ Right ,
40+ Down ,
41+ }
42+
43+ impl Direction {
44+ pub fn turn_right ( self ) -> Direction {
45+ match self {
46+ Direction :: Left => Direction :: Up ,
47+ Direction :: Up => Direction :: Right ,
48+ Direction :: Right => Direction :: Down ,
49+ Direction :: Down => Direction :: Left ,
50+ }
51+ }
52+ pub fn turn_left ( self ) -> Direction {
53+ match self {
54+ Direction :: Left => Direction :: Down ,
55+ Direction :: Up => Direction :: Left ,
56+ Direction :: Right => Direction :: Up ,
57+ Direction :: Down => Direction :: Right ,
58+ }
59+ }
60+ pub fn convert ( self , p : Point ) -> Point {
61+ match self {
62+ Direction :: Right => p,
63+ Direction :: Up => Point :: new ( -p. y , p. x ) ,
64+ Direction :: Left => Point :: new ( -p. x , -p. y ) ,
65+ Direction :: Down => Point :: new ( p. y , -p. x ) ,
66+ }
67+ }
68+ pub fn move_with ( self , kind : & Move ) -> Direction {
69+ match kind {
70+ Move :: MoveUp => self ,
71+ Move :: MoveDown => self ,
72+ Move :: MoveRight => self ,
73+ Move :: MoveLeft => self ,
74+ Move :: Noop => self ,
75+ Move :: TurnLeft => self . turn_left ( ) ,
76+ Move :: TurnRight => self . turn_right ( ) ,
77+ }
78+ }
79+ pub fn revert_with ( self , kind : & Move ) -> Direction {
80+ match kind {
81+ Move :: MoveUp => self ,
82+ Move :: MoveDown => self ,
83+ Move :: MoveRight => self ,
84+ Move :: MoveLeft => self ,
85+ Move :: Noop => self ,
86+ Move :: TurnLeft => self . turn_right ( ) ,
87+ Move :: TurnRight => self . turn_left ( ) ,
88+ }
89+ }
90+ }
91+
692#[ derive( Debug , Clone , Copy , Eq , PartialEq , Hash ) ]
793pub struct Point {
894 pub x : i32 ,
@@ -36,7 +122,9 @@ impl Point {
36122 Move :: MoveDown => Point :: new ( x, y - 1 ) ,
37123 Move :: MoveRight => Point :: new ( x + 1 , y) ,
38124 Move :: MoveLeft => Point :: new ( x - 1 , y) ,
39- Move :: Noop => Point :: new ( x, y) ,
125+ Move :: Noop => self ,
126+ Move :: TurnLeft => self ,
127+ Move :: TurnRight => self ,
40128 }
41129 }
42130
@@ -47,12 +135,14 @@ impl Point {
47135 Move :: MoveDown => Point :: new ( x, y + 1 ) ,
48136 Move :: MoveRight => Point :: new ( x - 1 , y) ,
49137 Move :: MoveLeft => Point :: new ( x + 1 , y) ,
50- Move :: Noop => Point :: new ( x, y) ,
138+ Move :: Noop => self ,
139+ Move :: TurnLeft => self ,
140+ Move :: TurnRight => self ,
51141 }
52142 }
53143}
54144
55- pub enum Direction {
145+ pub enum LineDirection {
56146 Verticle ,
57147 Horizontal ,
58148}
@@ -88,16 +178,16 @@ impl Map {
88178 self . 0 . iter ( ) . map ( |p| p. y ) . max ( ) . unwrap ( ) as usize + 1
89179 }
90180
91- pub fn iter_lines ( & self ) -> Vec < ( Direction , Point , Point ) > {
181+ pub fn iter_lines ( & self ) -> Vec < ( LineDirection , Point , Point ) > {
92182 let mut iter = self . 0 . iter ( ) . cloned ( ) . cycle ( ) . peekable ( ) ;
93183 let mut res = Vec :: new ( ) ;
94184 for _ in 0 ..self . 0 . len ( ) {
95185 let cur = iter. next ( ) . unwrap ( ) ;
96186 let next = * iter. peek ( ) . unwrap ( ) ;
97187 if cur. x == next. x {
98- res. push ( ( Direction :: Verticle , cur, next) ) ;
188+ res. push ( ( LineDirection :: Verticle , cur, next) ) ;
99189 } else if cur. y == next. y {
100- res. push ( ( Direction :: Horizontal , cur, next) ) ;
190+ res. push ( ( LineDirection :: Horizontal , cur, next) ) ;
101191 } else {
102192 unreachable ! ( ) ;
103193 }
@@ -110,7 +200,7 @@ impl Map {
110200 let g_max_x = self . 0 . iter ( ) . map ( |p| p. x ) . max ( ) . unwrap ( ) ;
111201 let mut cross_y_map = HashMap :: new ( ) ;
112202 for ( dir, p, q) in self . iter_lines ( ) {
113- if let Direction :: Horizontal = dir {
203+ if let LineDirection :: Horizontal = dir {
114204 let min_x = cmp:: min ( p. x , q. x ) ;
115205 let max_x = cmp:: max ( p. x , q. x ) ;
116206 for x in min_x..max_x {
@@ -227,13 +317,13 @@ pub enum Move {
227317 MoveLeft ,
228318 MoveRight ,
229319 Noop ,
320+ TurnLeft ,
321+ TurnRight ,
230322}
231323
232324#[ derive( Debug , Clone , Eq , PartialEq ) ]
233325pub enum Command {
234326 Move ( Move ) ,
235- TurnRight ,
236- TurnLeft ,
237327 NewHand ( Point ) ,
238328 FastWheel ,
239329 Drill ,
@@ -242,6 +332,7 @@ pub enum Command {
242332 Cloning ,
243333}
244334
335+
245336impl fmt:: Display for Command {
246337 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
247338 match self {
@@ -250,8 +341,8 @@ impl fmt::Display for Command {
250341 Command :: Move ( Move :: MoveLeft ) => write ! ( f, "A" ) ,
251342 Command :: Move ( Move :: MoveRight ) => write ! ( f, "D" ) ,
252343 Command :: Move ( Move :: Noop ) => write ! ( f, "Z" ) ,
253- Command :: TurnRight => write ! ( f, "E" ) ,
254- Command :: TurnLeft => write ! ( f, "Q" ) ,
344+ Command :: Move ( Move :: TurnRight ) => write ! ( f, "E" ) ,
345+ Command :: Move ( Move :: TurnLeft ) => write ! ( f, "Q" ) ,
255346 Command :: NewHand ( p) => write ! ( f, "B({},{})" , p. x, p. y) ,
256347 Command :: FastWheel => write ! ( f, "F" ) ,
257348 Command :: Drill => write ! ( f, "L" ) ,
0 commit comments