From cd0f4a0867738e9cad403ef802807325c0347887 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Thu, 29 Oct 2020 14:34:04 +0100 Subject: [PATCH 01/12] Add shitty parser --- src/main.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main.rs b/src/main.rs index 13b6b44..13ad09e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,32 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result x, Err(_) => return Err("Could not convert token two from the first string to i32"), }; + loop { + // This line should be empty. + let empty_line = match lines.next() { + None => break, + Some(x) => x, + }; + if !empty_line.is_empty() { + return Err("This line should be empty !"); + } + let a = match lines.next() { + None => return Err("This line should be config !"), + Some(raw) => raw, + }; + if a.is_empty() { + return Err("The config line should be empty !"); + } + let b = match lines.next() { + None => return Err("This line should be instruction !"), + Some(raw) => raw, + }; + if b.is_empty() { + return Err("The instruction line should be empty !"); + } + println!("{}", a); + println!("{}", b); + } Ok(world::World { x, y }) } From 0dd5080d63adc89802ac3f14c76b79a5b8ef265a Mon Sep 17 00:00:00 2001 From: Martin HART Date: Thu, 29 Oct 2020 14:43:38 +0100 Subject: [PATCH 02/12] Change err msg --- src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 13ad09e..bc5afc2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -80,18 +80,18 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result return Err("This line should be config !"), + None => return Err("This line should be the config !"), Some(raw) => raw, }; if a.is_empty() { - return Err("The config line should be empty !"); + return Err("Thi line should not be empty !"); } let b = match lines.next() { - None => return Err("This line should be instruction !"), + None => return Err("This line should be the instruction !"), Some(raw) => raw, }; if b.is_empty() { - return Err("The instruction line should be empty !"); + return Err("Thi line should not be empty !"); } println!("{}", a); println!("{}", b); From 037df4227183797071d12295358a66f94070ae9f Mon Sep 17 00:00:00 2001 From: Martin HART Date: Thu, 29 Oct 2020 14:44:16 +0100 Subject: [PATCH 03/12] correct typo --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index bc5afc2..a29b6e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,7 +84,7 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result raw, }; if a.is_empty() { - return Err("Thi line should not be empty !"); + return Err("This line should not be empty !"); } let b = match lines.next() { None => return Err("This line should be the instruction !"), From a50ec5d79bb4a357dcc1cf759254ea94c1484424 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Thu, 29 Oct 2020 14:52:43 +0100 Subject: [PATCH 04/12] change var name --- src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index a29b6e1..c90b42f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,22 +79,22 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result return Err("This line should be the config !"), Some(raw) => raw, }; - if a.is_empty() { + if raw_setup.is_empty() { return Err("This line should not be empty !"); } - let b = match lines.next() { + let raw_inst = match lines.next() { None => return Err("This line should be the instruction !"), Some(raw) => raw, }; - if b.is_empty() { + if raw_inst.is_empty() { return Err("Thi line should not be empty !"); } - println!("{}", a); - println!("{}", b); + println!("{}", raw_setup); + println!("{}", raw_inst); } Ok(world::World { x, y }) } From 5c9aeabd033cd090e7810546a94fa2dc264788a8 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 11:56:24 +0100 Subject: [PATCH 05/12] parse token setup line --- src/main.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index c90b42f..d452135 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,8 +91,21 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result raw, }; if raw_inst.is_empty() { - return Err("Thi line should not be empty !"); + return Err("This line should not be empty !"); } + let mut setup = raw_setup.split_whitespace(); + let pos_x = match setup.next() { + None => return Err("Could not read the first token of the setup line !"), + Some(raw) => raw, + }; + let pos_y = match setup.next() { + None => return Err("Could not read the second token of the setup line !"), + Some(raw) => raw, + }; + let orientation = match setup.next() { + None => return Err("Could not read the third token of the setup line !"), + Some(raw) => raw, + }; println!("{}", raw_setup); println!("{}", raw_inst); } From f4a1eac5b738b698280ef0a80ced06d0c77f2d29 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 12:08:12 +0100 Subject: [PATCH 06/12] Convert values of the setup line --- src/main.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main.rs b/src/main.rs index d452135..b327483 100644 --- a/src/main.rs +++ b/src/main.rs @@ -93,6 +93,7 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result return Err("Could not read the first token of the setup line !"), @@ -106,6 +107,22 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result return Err("Could not read the third token of the setup line !"), Some(raw) => raw, }; + // Convert values of the setup line + let r_x = match pos_x.parse::() { + Err(_) => return Err("Could not convert the first token of the setup ligne to i32 !"), + Ok(raw) => raw, + }; + let r_y = match pos_y.parse::() { + Err(_) => return Err("Could not convert the second token of the setup ligne to i32 !"), + Ok(raw) => raw, + }; + let r_o = match orientation { + "N" => robot::Orientation::N, + "E" => robot::Orientation::E, + "S" => robot::Orientation::S, + "W" => robot::Orientation::W, + _ => return Err("The third token of the setup line do not match any orientations !"), + }; println!("{}", raw_setup); println!("{}", raw_inst); } From 6fa55b69244b63318c24578a568296b23432a671 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 13:23:17 +0100 Subject: [PATCH 07/12] Need to fix a lot of bugs... --- src/main.rs | 77 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index b327483..b511384 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,74 +46,89 @@ fn check_collisions( } /// Parse the config file, generate the world and robot pool. -fn parse_config(conf: String, pool: &mut Vec) -> Result { +fn parse_config(conf: String, pool: &mut Vec) -> Result { let mut lines = conf.lines(); // The first line of the config file should be the World. let raw_line: &str = match lines.next() { Some(raw) => raw, - None => return Err("Could not read the first line of the config file !"), + None => return Err("Could not read the first line of the config file !".to_string()), }; let mut tokens = raw_line.split_whitespace(); let token1 = match tokens.next() { Some(raw) => raw, - None => return Err("Could not read the first token of the first line !"), + None => return Err("Could not read the first token of the first line !".to_string()), }; let token2 = match tokens.next() { Some(raw) => raw, - None => return Err("Could not read the second token of the first line !"), + None => return Err("Could not read the second token of the first line !".to_string()), }; let x: i32 = match token1.parse::() { Ok(x) => x, - Err(_) => return Err("Could not convert token one from the first string to i32"), + Err(_) => { + return Err("Could not convert token one from the first string to i32".to_string()) + } }; let y: i32 = match token2.parse::() { Ok(x) => x, - Err(_) => return Err("Could not convert token two from the first string to i32"), + Err(_) => { + return Err("Could not convert token two from the first string to i32".to_string()) + } }; + let w = world::World { x, y }; + let mut r_id: u32 = 0; loop { + r_id += 1; // This line should be empty. let empty_line = match lines.next() { None => break, Some(x) => x, }; if !empty_line.is_empty() { - return Err("This line should be empty !"); + return Err("This line should be empty !".to_string()); } let raw_setup = match lines.next() { - None => return Err("This line should be the config !"), + None => return Err("This line should be the config !".to_string()), Some(raw) => raw, }; if raw_setup.is_empty() { - return Err("This line should not be empty !"); + return Err("This line should not be empty !".to_string()); } let raw_inst = match lines.next() { - None => return Err("This line should be the instruction !"), + None => return Err("This line should be the instruction !".to_string()), Some(raw) => raw, }; if raw_inst.is_empty() { - return Err("This line should not be empty !"); + return Err("This line should not be empty !".to_string()); } // Parse the setup line of the robot. let mut setup = raw_setup.split_whitespace(); let pos_x = match setup.next() { - None => return Err("Could not read the first token of the setup line !"), + None => return Err("Could not read the first token of the setup line !".to_string()), Some(raw) => raw, }; let pos_y = match setup.next() { - None => return Err("Could not read the second token of the setup line !"), + None => return Err("Could not read the second token of the setup line !".to_string()), Some(raw) => raw, }; let orientation = match setup.next() { - None => return Err("Could not read the third token of the setup line !"), + None => return Err("Could not read the third token of the setup line !".to_string()), Some(raw) => raw, }; // Convert values of the setup line let r_x = match pos_x.parse::() { - Err(_) => return Err("Could not convert the first token of the setup ligne to i32 !"), + Err(_) => { + return Err( + "Could not convert the first token of the setup ligne to i32 !".to_string(), + ) + } Ok(raw) => raw, }; let r_y = match pos_y.parse::() { - Err(_) => return Err("Could not convert the second token of the setup ligne to i32 !"), + Err(_) => { + return Err( + "Could not convert the second token of the setup ligne to i32 !".to_string(), + ) + } Ok(raw) => raw, }; let r_o = match orientation { @@ -121,12 +136,24 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result robot::Orientation::E, "S" => robot::Orientation::S, "W" => robot::Orientation::W, - _ => return Err("The third token of the setup line do not match any orientations !"), + _ => { + return Err( + "The third token of the setup line do not match any orientations !".to_string(), + ) + } }; - println!("{}", raw_setup); - println!("{}", raw_inst); + + // Convert instructions line. + let inst: Vec = raw_inst.chars().collect(); + let r = robot::Robot::new(r_id, r_o, robot::Position { x: r_x, y: r_y }, inst); + + // Load robot inside the pool. + match check_map(&r, &w) { + Ok(()) => pool.push(r), + Err(err) => return Err(err), + } } - Ok(world::World { x, y }) + Ok(w) } /// Retrieve the content of a file and return it as a string. @@ -154,6 +181,16 @@ fn main() -> Result<(), Box> { let mut robot_pool: Vec = Vec::new(); let world: world::World = parse_config(raw_conf, &mut robot_pool)?; + println!("World -> x: {}, y: {}", world.x, world.y); + println!("Number of robot -> {}", robot_pool.len()); + println!( + "robot_pool[0] -> id: {}, x: {}, y: {}", + robot_pool[0].id, robot_pool[0].p.x, robot_pool[0].p.y + ); + println!( + "robot_pool[1] -> id: {}, x: {}, y: {}", + robot_pool[1].id, robot_pool[1].p.x, robot_pool[1].p.y + ); Ok(()) } From 46d4f27e24bda956a71f219dc8f99c08bbf05796 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 15:15:11 +0100 Subject: [PATCH 08/12] Add instruction validator --- src/world.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/world.rs b/src/world.rs index 357b82d..43afa6e 100644 --- a/src/world.rs +++ b/src/world.rs @@ -3,3 +3,31 @@ pub struct World { pub x: i32, pub y: i32, } + +pub fn is_instruction(v: &Vec) -> bool { + for c in v { + match c { + 'F' => continue, + 'R' => continue, + 'L' => continue, + _ => return false, + } + } + true +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn is_instruction_test() { + let v = vec!['F', 'R', 'L', 'F']; + assert!(is_instruction(&v)); + } + #[test] + #[should_panic] + fn is_instruction_test_fail() { + let v = vec!['F', 'R', 'L', 'Z']; + assert!(is_instruction(&v)); + } +} From 5d4d3a29c7336cc9ea88ce36e2bee5ddfe811299 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 15:29:52 +0100 Subject: [PATCH 09/12] Change string conversion methods --- src/main.rs | 76 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index b511384..317e5c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,27 +51,43 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result raw, - None => return Err("Could not read the first line of the config file !".to_string()), + None => { + return Err(String::from( + "Could not read the first line of the config file !", + )) + } }; let mut tokens = raw_line.split_whitespace(); let token1 = match tokens.next() { Some(raw) => raw, - None => return Err("Could not read the first token of the first line !".to_string()), + None => { + return Err(String::from( + "Could not read the first token of the first line !", + )) + } }; let token2 = match tokens.next() { Some(raw) => raw, - None => return Err("Could not read the second token of the first line !".to_string()), + None => { + return Err(String::from( + "Could not read the second token of the first line !", + )) + } }; let x: i32 = match token1.parse::() { Ok(x) => x, Err(_) => { - return Err("Could not convert token one from the first string to i32".to_string()) + return Err(String::from( + "Could not convert token one from the first string to i32", + )) } }; let y: i32 = match token2.parse::() { Ok(x) => x, Err(_) => { - return Err("Could not convert token two from the first string to i32".to_string()) + return Err(String::from( + "Could not convert token two from the first string to i32", + )) } }; let w = world::World { x, y }; @@ -84,50 +100,62 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result x, }; if !empty_line.is_empty() { - return Err("This line should be empty !".to_string()); + return Err(String::from("This line should be empty !")); } let raw_setup = match lines.next() { - None => return Err("This line should be the config !".to_string()), + None => return Err(String::from("This line should be the config !")), Some(raw) => raw, }; if raw_setup.is_empty() { - return Err("This line should not be empty !".to_string()); + return Err(String::from("This line should not be empty !")); } let raw_inst = match lines.next() { - None => return Err("This line should be the instruction !".to_string()), + None => return Err(String::from("This line should be the instruction !")), Some(raw) => raw, }; if raw_inst.is_empty() { - return Err("This line should not be empty !".to_string()); + return Err(String::from("This line should not be empty !")); } // Parse the setup line of the robot. let mut setup = raw_setup.split_whitespace(); let pos_x = match setup.next() { - None => return Err("Could not read the first token of the setup line !".to_string()), + None => { + return Err(String::from( + "Could not read the first token of the setup line !", + )) + } Some(raw) => raw, }; let pos_y = match setup.next() { - None => return Err("Could not read the second token of the setup line !".to_string()), + None => { + return Err(String::from( + "Could not read the second token of the setup line !", + )) + } Some(raw) => raw, }; let orientation = match setup.next() { - None => return Err("Could not read the third token of the setup line !".to_string()), + None => { + return Err(String::from( + "Could not read the third token of the setup line !", + )) + } Some(raw) => raw, }; // Convert values of the setup line let r_x = match pos_x.parse::() { Err(_) => { - return Err( - "Could not convert the first token of the setup ligne to i32 !".to_string(), - ) + return Err(String::from( + "Could not convert the first token of the setup ligne to i32 !", + )) } Ok(raw) => raw, }; let r_y = match pos_y.parse::() { Err(_) => { - return Err( - "Could not convert the second token of the setup ligne to i32 !".to_string(), - ) + return Err(String::from( + "Could not convert the second token of the setup ligne to i32 !", + )) } Ok(raw) => raw, }; @@ -137,14 +165,18 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result robot::Orientation::S, "W" => robot::Orientation::W, _ => { - return Err( - "The third token of the setup line do not match any orientations !".to_string(), - ) + return Err(String::from( + "The third token of the setup line do not match any orientations !", + )) } }; // Convert instructions line. let inst: Vec = raw_inst.chars().collect(); + if !world::is_instructions(&inst) { + return Err(String::from("Invalid instructions !")); + } + let r = robot::Robot::new(r_id, r_o, robot::Position { x: r_x, y: r_y }, inst); // Load robot inside the pool. From 2fe77a0e2d97048f12baad9bf49879f7709a94b4 Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 16:06:22 +0100 Subject: [PATCH 10/12] fix typo --- src/world.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/world.rs b/src/world.rs index 43afa6e..927a82a 100644 --- a/src/world.rs +++ b/src/world.rs @@ -4,7 +4,7 @@ pub struct World { pub y: i32, } -pub fn is_instruction(v: &Vec) -> bool { +pub fn is_instructions(v: &Vec) -> bool { for c in v { match c { 'F' => continue, @@ -20,14 +20,14 @@ pub fn is_instruction(v: &Vec) -> bool { mod tests { use super::*; #[test] - fn is_instruction_test() { + fn is_instructions_test() { let v = vec!['F', 'R', 'L', 'F']; - assert!(is_instruction(&v)); + assert!(is_instructions(&v)); } #[test] #[should_panic] - fn is_instruction_test_fail() { + fn is_instructions_test_fail() { let v = vec!['F', 'R', 'L', 'Z']; - assert!(is_instruction(&v)); + assert!(is_instructions(&v)); } } From 843a26fa90a218eb7bf35f1da5cf5aa16141247c Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 16:11:13 +0100 Subject: [PATCH 11/12] Remove prinln!() debug test --- src/main.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index be2c6f6..097c868 100644 --- a/src/main.rs +++ b/src/main.rs @@ -185,6 +185,7 @@ fn parse_config(conf: String, pool: &mut Vec) -> Result return Err(err), } } + Ok(w) } @@ -213,16 +214,6 @@ fn main() -> Result<(), Box> { let mut robot_pool: Vec = Vec::new(); let world: world::World = parse_config(raw_conf, &mut robot_pool)?; - println!("World -> x: {}, y: {}", world.x, world.y); - println!("Number of robot -> {}", robot_pool.len()); - println!( - "robot_pool[0] -> id: {}, x: {}, y: {}", - robot_pool[0].id, robot_pool[0].p.x, robot_pool[0].p.y - ); - println!( - "robot_pool[1] -> id: {}, x: {}, y: {}", - robot_pool[1].id, robot_pool[1].p.x, robot_pool[1].p.y - ); Ok(()) } From bdf91b7777ae1e34fe17be9cca5bd93deeb9745b Mon Sep 17 00:00:00 2001 From: Martin HART Date: Fri, 30 Oct 2020 16:34:25 +0100 Subject: [PATCH 12/12] GnaGnaGna volo want that... --- src/robot.rs | 26 ++++++++++++++++++++++++++ src/world.rs | 28 ---------------------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/robot.rs b/src/robot.rs index a06e218..7ab8c5a 100644 --- a/src/robot.rs +++ b/src/robot.rs @@ -56,6 +56,19 @@ pub struct Position { pub y: i32, } +/// Check if instructions list is valid. +pub fn is_instructions(v: &Vec) -> bool { + for c in v { + match c { + 'F' => continue, + 'R' => continue, + 'L' => continue, + _ => return false, + } + } + true +} + #[cfg(test)] mod tests { use super::*; @@ -95,4 +108,17 @@ mod tests { assert_eq!(r.p.x, 0); assert_eq!(r.p.y, 3); } + + #[test] + fn is_instructions_test() { + let v = vec!['F', 'R', 'L', 'F']; + assert!(is_instructions(&v)); + } + + #[test] + #[should_panic] + fn is_instructions_test_fail() { + let v = vec!['F', 'R', 'L', 'Z']; + assert!(is_instructions(&v)); + } } diff --git a/src/world.rs b/src/world.rs index 927a82a..357b82d 100644 --- a/src/world.rs +++ b/src/world.rs @@ -3,31 +3,3 @@ pub struct World { pub x: i32, pub y: i32, } - -pub fn is_instructions(v: &Vec) -> bool { - for c in v { - match c { - 'F' => continue, - 'R' => continue, - 'L' => continue, - _ => return false, - } - } - true -} - -#[cfg(test)] -mod tests { - use super::*; - #[test] - fn is_instructions_test() { - let v = vec!['F', 'R', 'L', 'F']; - assert!(is_instructions(&v)); - } - #[test] - #[should_panic] - fn is_instructions_test_fail() { - let v = vec!['F', 'R', 'L', 'Z']; - assert!(is_instructions(&v)); - } -}