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