2020-10-27 22:55:31 +01:00
|
|
|
/// A Robot *aka droid* is represented here.
|
|
|
|
/// Each robot must have a unique id.
|
|
|
|
pub struct Robot {
|
2020-10-28 17:32:36 +01:00
|
|
|
id: u32,
|
2020-10-27 22:55:31 +01:00
|
|
|
o: Orientation,
|
|
|
|
p: Position,
|
2020-10-28 17:30:45 +01:00
|
|
|
i: Vec<char>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Robot {
|
|
|
|
/// Create new `Robot` with given id, `Orientation`, `Position` and instructions.
|
2020-10-28 18:20:37 +01:00
|
|
|
fn new(id: u32, o: Orientation, p: Position, i: Vec<char>) -> Robot {
|
2020-10-28 17:30:45 +01:00
|
|
|
Robot { id, o, p, i }
|
|
|
|
}
|
|
|
|
/// Apply given instruction to a `Robot`.
|
2020-10-28 19:12:30 +01:00
|
|
|
fn execute_instruction(&mut self) {
|
2020-10-28 17:30:45 +01:00
|
|
|
match self.i.pop() {
|
|
|
|
Some(instruction) => match instruction {
|
2020-10-28 19:12:30 +01:00
|
|
|
'L' => match self.o {
|
2020-10-28 17:30:45 +01:00
|
|
|
Orientation::N => self.o = Orientation::W,
|
|
|
|
Orientation::E => self.o = Orientation::N,
|
|
|
|
Orientation::S => self.o = Orientation::E,
|
|
|
|
Orientation::W => self.o = Orientation::S,
|
2020-10-28 19:12:30 +01:00
|
|
|
},
|
|
|
|
'R' => match self.o {
|
2020-10-28 17:30:45 +01:00
|
|
|
Orientation::N => self.o = Orientation::E,
|
|
|
|
Orientation::E => self.o = Orientation::S,
|
|
|
|
Orientation::S => self.o = Orientation::W,
|
|
|
|
Orientation::W => self.o = Orientation::N,
|
2020-10-28 19:12:30 +01:00
|
|
|
},
|
|
|
|
'F' => match self.o {
|
2020-10-28 17:30:45 +01:00
|
|
|
Orientation::N => self.p.y += 1,
|
|
|
|
Orientation::E => self.p.x += 1,
|
|
|
|
Orientation::S => self.p.y -= 1,
|
|
|
|
Orientation::W => self.p.x -= 1,
|
2020-10-28 19:12:30 +01:00
|
|
|
},
|
|
|
|
_ => (),
|
2020-10-28 17:30:45 +01:00
|
|
|
},
|
2020-10-28 19:12:30 +01:00
|
|
|
None => (),
|
2020-10-28 17:30:45 +01:00
|
|
|
}
|
|
|
|
}
|
2020-10-27 22:55:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Enum to store all possible orientations.
|
|
|
|
enum Orientation {
|
|
|
|
N,
|
|
|
|
E,
|
|
|
|
S,
|
|
|
|
W,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Struct to store robot position.
|
2020-10-28 18:20:37 +01:00
|
|
|
#[derive(PartialEq, Eq, Hash)]
|
2020-10-27 22:55:31 +01:00
|
|
|
struct Position {
|
|
|
|
x: i32,
|
|
|
|
y: i32,
|
|
|
|
}
|
2020-10-28 17:30:45 +01:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_new_robot() {
|
|
|
|
let r: Robot = Robot::new(
|
|
|
|
0,
|
|
|
|
Orientation::N,
|
|
|
|
Position { x: 1, y: 2 },
|
|
|
|
vec!['L', 'L', 'F', 'R'],
|
|
|
|
);
|
|
|
|
assert_eq!(r.id, 0);
|
|
|
|
assert!(matches!(r.o, Orientation::N));
|
|
|
|
assert_eq!(r.p.x, 1);
|
|
|
|
assert_eq!(r.p.y, 2);
|
|
|
|
assert_eq!(r.i, vec!['L', 'L', 'F', 'R']);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_execute_instruction() {
|
|
|
|
let mut r: Robot = Robot::new(
|
|
|
|
0,
|
|
|
|
Orientation::N,
|
|
|
|
Position { x: 1, y: 2 },
|
2020-10-28 19:12:30 +01:00
|
|
|
vec!['R', 'F', 'L', 'F'],
|
2020-10-28 17:30:45 +01:00
|
|
|
);
|
2020-10-28 19:12:30 +01:00
|
|
|
let mut hash = std::collections::HashMap::new();
|
|
|
|
//hash.insert(&r.p, &r.id); // first insert while initializing.
|
|
|
|
hash.remove(&r.p); // remove before execute_instruction().
|
|
|
|
r.execute_instruction();
|
|
|
|
hash.insert(&r.p, &r.id); // second insert after moving.
|
2020-10-28 17:30:45 +01:00
|
|
|
assert_eq!(r.p.x, 1);
|
|
|
|
assert_eq!(r.p.y, 3);
|
2020-10-28 19:12:30 +01:00
|
|
|
r.execute_instruction();
|
|
|
|
r.execute_instruction();
|
|
|
|
assert_eq!(r.p.x, 0);
|
|
|
|
assert_eq!(r.p.y, 3);
|
2020-10-28 17:30:45 +01:00
|
|
|
}
|
|
|
|
}
|