main.rs (3329B)
1 fn main() { 2 println!("Hello, world!"); 3 } 4 5 mod rover { 6 #[derive(Debug, PartialEq, Copy, Clone)] 7 pub enum Facing { N, E, S, W } 8 #[derive(Debug, PartialEq, Copy, Clone)] 9 pub enum Rotation { Left, Right } 10 11 #[derive(Debug, PartialEq, Copy, Clone)] 12 pub struct Rover(pub i32, pub i32, pub Facing); 13 14 fn velocity(direction : &Facing) -> (i32, i32) { 15 match direction { 16 Facing::N => ( 0, -1), 17 Facing::E => ( 1, 0), 18 Facing::S => ( 0, 1), 19 Facing::W => (-1, 0) 20 } 21 } 22 23 fn next_direction(direction : Facing) -> Facing { 24 match direction { 25 Facing::N => Facing::W, 26 Facing::W => Facing::S, 27 Facing::S => Facing::E, 28 Facing::E => Facing::N, 29 } 30 } 31 32 impl Rover { 33 pub fn forward(&self) -> Rover { 34 let Rover(lon, lat, direction) = self; 35 let (xoff, yoff) = velocity(&direction); 36 Rover(lon + xoff, lat + yoff, *direction) 37 } 38 39 pub fn backward(&self) -> Rover { 40 let Rover(lon, lat, direction) = self; 41 let (xoff, yoff) = velocity(&direction); 42 Rover(lon - xoff, lat - yoff, *direction) 43 } 44 45 pub fn rotate(&self, rotation: Rotation) -> Rover { 46 let Rover(lon, lat, direction) = self; 47 let new_direction = match rotation { 48 Rotation::Left => { 49 next_direction(*direction) 50 }, 51 Rotation::Right => { 52 next_direction( 53 next_direction( 54 next_direction(*direction) 55 ) 56 ) 57 } 58 }; 59 Rover(*lon, *lat, new_direction) 60 } 61 } 62 } 63 64 65 mod driver { 66 use super::rover; 67 68 fn perform_command(command: &str, rover: &rover::Rover) -> rover::Rover { 69 match command { 70 "f" => rover.forward(), 71 "b" => rover.backward(), 72 "l" => rover.rotate(rover::Rotation::Left), 73 "r" => rover.rotate(rover::Rotation::Right), 74 _ => rover.clone() 75 } 76 } 77 78 pub fn execute(rover: &rover::Rover, commands: &str) -> rover::Rover { 79 if commands.is_empty() { 80 rover.clone() 81 } else { 82 let (now, later) = commands.split_at(1); 83 execute(&perform_command(now, rover), later) 84 } 85 } 86 } 87 88 #[cfg(test)] 89 mod tests { 90 use super::driver; 91 use super::rover::{Rover, Facing,Rotation}; 92 93 #[test] 94 fn move_north() { 95 let r = Rover(1, 1, Facing::N); 96 assert_eq!(r.forward(), 97 Rover(1, 0, Facing::N)); 98 99 let r = Rover(1, 3, Facing::N); 100 assert_eq!(r.forward(), 101 Rover(1, 2, Facing::N)); 102 } 103 104 #[test] 105 fn move_south() { 106 let r = Rover(1, 1, Facing::S); 107 assert_eq!(r.forward(), 108 Rover(1, 2, Facing::S)); 109 } 110 111 #[test] 112 fn move_west() { 113 let r = Rover(1, 1, Facing::W); 114 assert_eq!(r.forward(), 115 Rover(0, 1, Facing::W)); 116 } 117 118 #[test] 119 fn move_east() { 120 let r = Rover(1, 1, Facing::E); 121 assert_eq!(r.forward(), 122 Rover(2, 1, Facing::E)); 123 } 124 125 #[test] 126 fn move_backward() { 127 let r = Rover(1, 1, Facing::E); 128 let r2 = r.forward(); 129 assert_eq!(r2.backward(), r); 130 } 131 132 #[test] 133 fn spin_left() { 134 let r = Rover(1, 1, Facing::E); 135 match r.rotate(Rotation::Left) { 136 Rover(_, _, facing) => assert_eq!(facing, Facing::N) 137 } 138 } 139 #[test] 140 fn spin_right() { 141 let r = Rover(1, 1, Facing::S); 142 match r.rotate(Rotation::Right) { 143 Rover(_, _, facing) => assert_eq!(facing, Facing::W) 144 } 145 } 146 147 #[test] 148 fn drive() { 149 let r = Rover(1, 1, Facing::S); 150 assert_eq!(driver::execute(&r, "ffrf"), 151 Rover(0, 3, Facing::W)); 152 } 153 }