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
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);
|
|
}
|
|
}
|