You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

309 lines
9.0 KiB

fn main() {
println!("Hello, world!");
}
pub const DEBUG : bool = true;
pub struct Trail {
waypoints: Vec<Point>,
directions: Vec<Direction>,
}
impl Trail {
pub fn new() -> Trail {
Trail {
waypoints: Vec::new(),
directions: Vec::new(),
}
}
pub fn start(&mut self, way: String) -> DistArea {
if !way.is_empty() {
let mut da = DistArea{dist: 0, area: 0, size: 0};
let split = way.split_whitespace();
let mut plan : Vec<String> = Vec::new();
for s in split {
plan.push(String::from(s));
}
let steps = match plan.remove(0).parse::<i32>() {
Err(_) => 0,
Ok(i) => i,
};
self.directions.push(Direction::North);
self.waypoints.push(Point{x: 0, y: 0});
da.dist = self.walk(plan, steps);
let mut min = Point{x: 0, y: 0};
let mut max = Point{x: 0, y: 0};
for i in &self.waypoints {
if i.x < min.x {
min.x = i.x;
}
if i.y < min.y {
min.y = i.y;
}
if i.x > max.x {
max.x = i.x;
}
if i.y > max.y {
max.y = i.y;
}
}
da.area = (max.x - min.x) * (max.y - min.y);
da
} else {
DistArea{dist:0, area:0, size:0}
}
}
fn walk(&mut self, mut plan: Vec<String>, steps: i32) -> i32 {
if steps == 0 {
0
} else {
let mut stepcount = 0;
let part = plan.remove(0);
let count = match plan.remove(0).parse::<i32>() {
Err(_) => 0,
Ok(i) => i,
};
let mut dir = self.directions.last().unwrap().clone();
let mut pos = self.waypoints.last().unwrap().clone();
for _i in 0 .. count {
for c in part.chars() {
match c {
'F' => {
pos.add(dir, 1);
if DEBUG {
println!("F, pos: x={} y={}, dir: {:?}", pos.x, pos.y, dir);
}
stepcount += 1;
},
'L' => {
dir = Direction::turn_left(dir);
if DEBUG {
print!("L");
}
},
'R' => {
dir = Direction::turn_right(dir);
if DEBUG {
print!("R");
}
},
_ => (),
}
self.directions.push(dir);
self.waypoints.push(pos);
}
}
stepcount += self.walk(plan, steps - 1);
stepcount
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum Direction {
North,
East,
South,
West,
}
impl Direction {
pub fn turn_right(dir: Direction) -> Direction {
match dir {
Direction::North => Direction::East,
Direction::East => Direction::South,
Direction::South => Direction::West,
Direction::West => Direction::North,
}
}
pub fn turn_left(dir: Direction) -> Direction {
match dir {
Direction::North => Direction::West,
Direction::East => Direction::North,
Direction::South => Direction::East,
Direction::West => Direction::South,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct Point {
x: i32,
y: i32,
}
impl Point {
pub fn add(&mut self, dir: Direction, len: i32) {
match dir {
Direction::North => self.y += len,
Direction::East => self.x += len,
Direction::South => self.y -= len,
Direction::West => self.x -= len,
};
}
}
#[derive(Copy, Clone, Debug)]
pub struct DistArea {
pub dist: i32,
pub area: i32,
pub size: i32,
}
impl PartialEq for DistArea {
fn eq(&self, other: &DistArea) -> bool {
let mut res = self.dist == other.dist;
res &= self.area == other.area;
res &= self.size == other.size;
res
}
}
impl Eq for DistArea {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn level1_1() {
let input = String::from("1 FFFR 4");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.dist, 12);
}
#[test]
fn level1_2() {
let input = String::from("9 F 6 R 1 F 4 RFF 2 LFF 1 LFFFR 1 F 2 R 1 F 5");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.dist, 26);
}
#[test]
fn level1_3() {
let input = String::from("14 L 1 FR 1 FFFFFL 1 FFFFL 1 F 12 L 1 F 12 L 1 F 12 L 1 FFFFL 1 FFFFFFFFR 1 FFFR 1 FFFL 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.dist, 64);
}
#[test]
fn level1_4() {
let input = String::from("32 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFLFFF 3 R 1 FFFFFF 3 L 1 FFFRFLFLFRFF 2 R 1 FFFRFLFLFRFF 3 R 1 FFFFFF 1 L 1 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFFLFLFRFF 2 L 1 FFLFRFRFFLFLFRFF 3 R 1 FFRFLFLFFRFRFLFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1 FFFFFF 3 R 1 FFFRFLFLFRFF 5 R 1 FFLFRFRFLFFF 1 L 1 FFLFRFRFFLFLFRFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.dist, 344);
}
#[test]
fn level1_5() {
let input = String::from("10 FFLFRFRFFLFLFRFF 5 L 1 FFFRFLFLFRFF 4 L 1 FFLFRFRFFLFLFRFF 8 L 1 FFLFRFRFFLFLFRFF 4 L 1 FFFFFF 3 R 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.dist, 220);
}
#[test]
fn level2_1() {
let input = String::from("1 FFFR 4");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.area, 9);
}
#[test]
fn level2_2() {
let input = String::from("9 F 6 R 1 F 4 RFF 2 LFF 1 LFFFR 1 F 2 R 1 F 5");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.area, 30);
}
#[test]
fn level2_3() {
let input = String::from("14 L 1 FR 1 FFFFFL 1 FFFFL 1 F 12 L 1 F 12 L 1 F 12 L 1 FFFFL 1 FFFFFFFFR 1 FFFR 1 FFFL 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.area, 144);
}
#[test]
fn level2_4() {
let input = String::from("32 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFLFFF 3 R 1 FFFFFF 3 L 1 FFFRFLFLFRFF 2 R 1 FFFRFLFLFRFF 3 R 1 FFFFFF 1 L 1 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFFLFLFRFF 2 L 1 FFLFRFRFFLFLFRFF 3 R 1 FFRFLFLFFRFRFLFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1 FFFFFF 3 R 1 FFFRFLFLFRFF 5 R 1 FFLFRFRFLFFF 1 L 1 FFLFRFRFFLFLFRFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.area, 3552);
}
#[test]
fn level2_5() {
let input = String::from("10 FFLFRFRFFLFLFRFF 5 L 1 FFFRFLFLFRFF 4 L 1 FFLFRFRFFLFLFRFF 8 L 1 FFLFRFRFFLFLFRFF 4 L 1 FFFFFF 3 R 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.area, 1300);
}
#[test]
fn level3_1() {
let input = String::from("1 FFFR 4");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.size, 12);
}
#[test]
fn level3_2() {
let input = String::from("9 F 6 R 1 F 4 RFF 2 LFF 1 LFFFR 1 F 2 R 1 F 5");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.size, 12);
}
#[test]
fn level3_3() {
let input = String::from("14 L 1 FR 1 FFFFFL 1 FFFFL 1 F 12 L 1 F 12 L 1 F 12 L 1 FFFFL 1 FFFFFFFFR 1 FFFR 1 FFFL 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.size, 12);
}
#[test]
fn level3_4() {
let input = String::from("32 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFLFFF 3 R 1 FFFFFF 3 L 1 FFFRFLFLFRFF 2 R 1 FFFRFLFLFRFF 3 R 1 FFFFFF 1 L 1 FFRFLFLFFRFRFLFF 3 R 1 FFLFRFRFFLFLFRFF 2 L 1 FFLFRFRFFLFLFRFF 3 R 1 FFRFLFLFFRFRFLFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1 FFFFFF 3 R 1 FFFRFLFLFRFF 5 R 1 FFLFRFRFLFFF 1 L 1 FFLFRFRFFLFLFRFF 2 R 1 FFRFLFLFFRFRFLFF 2 L 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.size, 12);
}
#[test]
fn level3_5() {
let input = String::from("10 FFLFRFRFFLFLFRFF 5 L 1 FFFRFLFLFRFF 4 L 1 FFLFRFRFFLFLFRFF 8 L 1 FFLFRFRFFLFLFRFF 4 L 1 FFFFFF 3 R 1");
let mut trail = Trail::new();
let mut res = trail.start(input);
assert_eq!(res.size, 12);
}
}