From 707cd006628707057df7b99e2decd3310616e958 Mon Sep 17 00:00:00 2001 From: Michael Preisach Date: Thu, 24 May 2018 15:49:32 +0200 Subject: [PATCH] level 2 working --- .gitignore | 2 + .idea/misc.xml | 12 ++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 + Cargo.lock | 4 + Cargo.toml | 6 + src/main.rs | 309 ++++++++++++++++++++++++++++++++++++++++++++++ trail.iml | 15 +++ 8 files changed, 362 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 trail.iml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eccd7b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target/ +**/*.rs.bk diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..70bebef --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5afe65c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6a11e1c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "trail" +version = "0.1.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..94cf0ef --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trail" +version = "0.1.0" +authors = ["Michael Preisach "] + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..bd5200d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,309 @@ +fn main() { + println!("Hello, world!"); +} + +pub const DEBUG : bool = true; + +pub struct Trail { + waypoints: Vec, + directions: Vec, +} + +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 = Vec::new(); + for s in split { + plan.push(String::from(s)); + } + let steps = match plan.remove(0).parse::() { + 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, steps: i32) -> i32 { + if steps == 0 { + 0 + } else { + let mut stepcount = 0; + let part = plan.remove(0); + let count = match plan.remove(0).parse::() { + 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); + } +} \ No newline at end of file diff --git a/trail.iml b/trail.iml new file mode 100644 index 0000000..7fe828a --- /dev/null +++ b/trail.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file