mars-rover-fe

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }