commit
707cd00662
8 changed files with 362 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
/target/ |
||||
|
**/*.rs.bk |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="CargoProjects"> |
||||
|
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" /> |
||||
|
</component> |
||||
|
<component name="ProjectRootManager"> |
||||
|
<output url="file://$PROJECT_DIR$/out" /> |
||||
|
</component> |
||||
|
<component name="RustProjectSettings"> |
||||
|
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" /> |
||||
|
</component> |
||||
|
</project> |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="ProjectModuleManager"> |
||||
|
<modules> |
||||
|
<module fileurl="file://$PROJECT_DIR$/trail.iml" filepath="$PROJECT_DIR$/trail.iml" /> |
||||
|
</modules> |
||||
|
</component> |
||||
|
</project> |
||||
@ -0,0 +1,6 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="VcsDirectoryMappings"> |
||||
|
<mapping directory="" vcs="Git" /> |
||||
|
</component> |
||||
|
</project> |
||||
@ -0,0 +1,4 @@ |
|||||
|
[[package]] |
||||
|
name = "trail" |
||||
|
version = "0.1.0" |
||||
|
|
||||
@ -0,0 +1,6 @@ |
|||||
|
[package] |
||||
|
name = "trail" |
||||
|
version = "0.1.0" |
||||
|
authors = ["Michael Preisach <michael@preisach.at>"] |
||||
|
|
||||
|
[dependencies] |
||||
@ -0,0 +1,309 @@ |
|||||
|
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); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module type="RUST_MODULE" version="4"> |
||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true"> |
||||
|
<exclude-output /> |
||||
|
<content url="file://$MODULE_DIR$"> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" /> |
||||
|
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" /> |
||||
|
<excludeFolder url="file://$MODULE_DIR$/target" /> |
||||
|
</content> |
||||
|
<orderEntry type="inheritedJdk" /> |
||||
|
<orderEntry type="sourceFolder" forTests="false" /> |
||||
|
</component> |
||||
|
</module> |
||||
Loading…
Reference in new issue