Skip to content

Instantly share code, notes, and snippets.

@richo
Last active August 29, 2015 14:25
Show Gist options
  • Save richo/9234ba67a1c03377fa53 to your computer and use it in GitHub Desktop.
Save richo/9234ba67a1c03377fa53 to your computer and use it in GitHub Desktop.
use std::io::Read;
enum Direction {
North,
South,
East,
West,
}
impl Direction {
fn parse<'a>(name: &'a str) -> Direction {
use Direction::*;
match name {
"NORTH" => North,
"SOUTH" => South,
"EAST" => East,
"WEST" => West,
e => panic!("Wtf direction is {}", e),
}
}
// TODO(richo) actually impl Display
fn to_string(&self) -> &'static str {
use Direction::*;
match self {
&North => "NORTH",
&South => "SOUTH",
&East => "EAST",
&West => "WEST",
}
}
fn turn_left(&self) -> Direction {
use Direction::*;
match self {
&North => West,
&South => East,
&East => North,
&West => South,
}
}
fn turn_right(&self) -> Direction {
use Direction::*;
match self {
&North => East,
&South => West,
&East => South,
&West => North,
}
}
}
struct State {
dir: Direction,
pos: (usize, usize),
}
impl State {
fn mov(&mut self) {
use Direction::*;
let (dx, dy) = match self.dir {
North => (0, 1),
South => (0, -1),
East => (1, 0),
West => (-1, 0),
};
let (x, y) = self.pos;
self.pos = (x + dx, y + dy);
}
fn left(&mut self) {
self.dir = self.dir.turn_left();
}
fn right(&mut self) {
self.dir = self.dir.turn_right();
}
fn report(&self) -> String {
let (x, y) = self.pos;
format!("{},{},{}", x, y, self.dir.to_string())
}
}
fn place<'a>(arg: &'a str) -> State {
let parts: Vec<_> = arg.split(",").collect();
let (x, y, f) = (parts[0], parts[1], parts[2]);
State {
dir: Direction::parse(f),
pos: (x.parse().unwrap(), y.parse().unwrap()),
}
}
fn main() {
let mut stdin = std::io::stdin();
let mut buf: String = String::new();
// First line has to be a place
let _ = stdin.read_line(&mut buf);
let parts: Vec<_> = buf.trim().split(" ").collect();
assert_eq!(parts[0], "PLACE");
let mut state = place(parts[1]);
loop {
let mut buf = String::new();
match stdin.read_line(&mut buf) {
Err(e) => panic!("{}", e.to_string()),
Ok(n) => {
if n == 0 {
return
}
}
}
let parts: Vec<_> = buf.trim().split(" ").collect();
match parts[0] {
"PLACE" => state = place(parts[1]),
"MOVE" => state.mov(),
"LEFT" => state.left(),
"RIGHT" => state.right(),
"REPORT" => println!("{}", state.report()),
other => panic!("Unexpected: {}", other),
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment