From a1075277bedfd1eb53f5fffca5e564a9e840c234 Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Sat, 12 Nov 2022 19:06:52 +0100 Subject: [PATCH 1/9] Add a new implementation in rust --- .gitignore | 1 + rust-calc/Cargo.lock | 7 ++++ rust-calc/Cargo.toml | 8 +++++ rust-calc/src/main.rs | 81 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 .gitignore create mode 100644 rust-calc/Cargo.lock create mode 100644 rust-calc/Cargo.toml create mode 100644 rust-calc/src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ba796d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +rust-calc/target diff --git a/rust-calc/Cargo.lock b/rust-calc/Cargo.lock new file mode 100644 index 0000000..27e0258 --- /dev/null +++ b/rust-calc/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust-calc" +version = "0.1.0" diff --git a/rust-calc/Cargo.toml b/rust-calc/Cargo.toml new file mode 100644 index 0000000..4ef3c83 --- /dev/null +++ b/rust-calc/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust-calc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs new file mode 100644 index 0000000..e12e34f --- /dev/null +++ b/rust-calc/src/main.rs @@ -0,0 +1,81 @@ +use std::process; + +#[derive(Debug)] +enum Symbol { + Minus, + Plus, + Multiply, + Divide, +} + +struct TmpNum { + s: String, +} +impl TmpNum { + pub fn new() -> Self { + Self { s: String::new() } + } + fn push(&mut self, c: char) { + self.s.push(c); + } + fn get(&mut self) -> f32 { + let n = self.s.parse::().ok().expect("number is malformed"); + self.s = String::new(); + + n + } +} + +fn parse(pattern: String) -> (Vec, Vec) { + let mut symbols = Vec::new(); + let mut numbers = Vec::new(); + + let mut number = TmpNum::new(); + + for c in pattern.chars() { + let s: Option = match c { + '-' => Some(Symbol::Minus), + '+' => Some(Symbol::Plus), + '*' => Some(Symbol::Multiply), + '/' => Some(Symbol::Divide), + + _ => None, + }; + + match s { + Some(s) => { + symbols.push(s); + numbers.push(number.get()); + } + None => { + number.push(c); + } + } + } + + numbers.push(number.get()); + + (symbols, numbers) +} + +fn main() { + let pattern = match std::env::args().nth(1) { + None => { + println!("Input must be provided"); + process::exit(1) + } + Some(s) => s, + }; + + let (symbols, numbers) = parse(pattern); + + println!("{:?}", symbols); + println!("{:?}", numbers); + + let mut counter = 0; + let mut n1 = numbers.get(0).expect("expect at least the first value"); + while counter < symbols.len() { + let mut n2 = numbers.get(counter+1).expect("expect at least a second value"); + counter +=1; + } +} -- 2.40.1 From 8d36c71340cf71aa3f3ee9a147a492387daf4437 Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Sun, 13 Nov 2022 16:07:40 +0100 Subject: [PATCH 2/9] operational --- rust-calc/src/main.rs | 105 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 8 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index e12e34f..fd0ab86 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -1,4 +1,7 @@ -use std::process; +use std::{ + ops::{AddAssign, DivAssign, MulAssign, SubAssign}, + process, +}; #[derive(Debug)] enum Symbol { @@ -7,6 +10,16 @@ enum Symbol { Multiply, Divide, } +impl Symbol { + fn priority(&self) -> bool { + match self { + Symbol::Multiply => true, + Symbol::Divide => true, + + _ => false, + } + } +} struct TmpNum { s: String, @@ -58,6 +71,81 @@ fn parse(pattern: String) -> (Vec, Vec) { (symbols, numbers) } +fn calcul(symbols: Vec, numbers: Vec) -> f32 { + let mut counter = 0; + let mut n1 = *numbers.get(0).expect("expect at least the first value"); + while counter < symbols.len() { + let s = symbols + .get(counter) + .expect("expect at least a symbol value"); + let n2 = *numbers + .get(counter + 1) + .expect("expect at least a second value"); + + if s.priority() { + match s { + Symbol::Multiply => { + n1.mul_assign(n2); + } + Symbol::Divide => { + n1.div_assign(n2); + } + _ => {} + }; + } else { + let next_s = symbols.get(counter + 1); + match next_s { + Some(ss) => { + if ss.priority() { + let mut counter_2 = counter + 1; + let mut nn1 = *numbers + .get(counter_2) + .expect("during the priority, we expect at least the first value"); + while counter_2 < symbols.len() { + let nn2 = *numbers + .get(counter_2) + .expect("during the priority, we expect at least the second value"); + + if ss.priority() { + match ss { + Symbol::Multiply => { + nn1.mul_assign(nn2); + } + Symbol::Divide => { + nn1.div_assign(nn2); + } + _ => {} + } + } else { + counter = counter_2; + n1 = nn1; + break; + } + + counter_2 += 1; + } + } + } + None => {} + } + + match s { + Symbol::Minus => { + n1.sub_assign(n2); + } + Symbol::Plus => { + n1.add_assign(n2); + } + _ => {} + } + } + + counter += 1; + } + + n1 +} + fn main() { let pattern = match std::env::args().nth(1) { None => { @@ -69,13 +157,14 @@ fn main() { let (symbols, numbers) = parse(pattern); - println!("{:?}", symbols); - println!("{:?}", numbers); + // println!("{:?}", symbols); + // println!("{:?}", numbers); - let mut counter = 0; - let mut n1 = numbers.get(0).expect("expect at least the first value"); - while counter < symbols.len() { - let mut n2 = numbers.get(counter+1).expect("expect at least a second value"); - counter +=1; + if symbols.len() < 1 || symbols.len() + 1 != numbers.len() { + println!("The input is malformed"); + process::exit(2); } + + let res = calcul(symbols, numbers); + println!("{res}"); } -- 2.40.1 From fc31bfc38f5729840d54fb29708ff7127bdbea5b Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Sun, 13 Nov 2022 16:25:24 +0100 Subject: [PATCH 3/9] bracket WIP but fixed issue with signed value --- rust-calc/src/main.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index fd0ab86..fa31432 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -9,6 +9,9 @@ enum Symbol { Plus, Multiply, Divide, + + OpenBracket, + CloseBracket, } impl Symbol { fn priority(&self) -> bool { @@ -16,6 +19,17 @@ impl Symbol { Symbol::Multiply => true, Symbol::Divide => true, + Symbol::OpenBracket => true, + Symbol::CloseBracket => true, + + _ => false, + } + } + fn bracket(&self) -> bool { + match self { + Symbol::OpenBracket => true, + Symbol::CloseBracket => true, + _ => false, } } @@ -31,15 +45,16 @@ impl TmpNum { fn push(&mut self, c: char) { self.s.push(c); } - fn get(&mut self) -> f32 { - let n = self.s.parse::().ok().expect("number is malformed"); + fn get(&mut self) -> f64 { + println!("{}", self.s); + let n = self.s.parse::().ok().expect("number is malformed"); self.s = String::new(); n } } -fn parse(pattern: String) -> (Vec, Vec) { +fn parse(pattern: String) -> (Vec, Vec) { let mut symbols = Vec::new(); let mut numbers = Vec::new(); @@ -52,13 +67,20 @@ fn parse(pattern: String) -> (Vec, Vec) { '*' => Some(Symbol::Multiply), '/' => Some(Symbol::Divide), + '(' => Some(Symbol::OpenBracket), + ')' => Some(Symbol::CloseBracket), + _ => None, }; match s { Some(s) => { - symbols.push(s); - numbers.push(number.get()); + if number.s.len() == 0 { + number.push(c); + } else { + symbols.push(s); + numbers.push(number.get()); + } } None => { number.push(c); @@ -71,7 +93,7 @@ fn parse(pattern: String) -> (Vec, Vec) { (symbols, numbers) } -fn calcul(symbols: Vec, numbers: Vec) -> f32 { +fn calcul(symbols: Vec, numbers: Vec) -> f64 { let mut counter = 0; let mut n1 = *numbers.get(0).expect("expect at least the first value"); while counter < symbols.len() { -- 2.40.1 From 327917e29a2003200550ff6795c3a3d74916753d Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Sun, 13 Nov 2022 17:51:35 +0100 Subject: [PATCH 4/9] Brackets are fuly operational --- rust-calc/src/main.rs | 83 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index fa31432..1549ee2 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -3,7 +3,7 @@ use std::{ process, }; -#[derive(Debug)] +#[derive(Clone, Debug)] enum Symbol { Minus, Plus, @@ -19,9 +19,6 @@ impl Symbol { Symbol::Multiply => true, Symbol::Divide => true, - Symbol::OpenBracket => true, - Symbol::CloseBracket => true, - _ => false, } } @@ -30,6 +27,20 @@ impl Symbol { Symbol::OpenBracket => true, Symbol::CloseBracket => true, + _ => false, + } + } + fn open_bracket(&self) -> bool { + match self { + Symbol::OpenBracket => true, + + _ => false, + } + } + fn close_bracket(&self) -> bool { + match self { + Symbol::CloseBracket => true, + _ => false, } } @@ -46,12 +57,14 @@ impl TmpNum { self.s.push(c); } fn get(&mut self) -> f64 { - println!("{}", self.s); let n = self.s.parse::().ok().expect("number is malformed"); self.s = String::new(); n } + fn len(&self) -> usize { + self.s.len() + } } fn parse(pattern: String) -> (Vec, Vec) { @@ -60,7 +73,9 @@ fn parse(pattern: String) -> (Vec, Vec) { let mut number = TmpNum::new(); - for c in pattern.chars() { + let mut i = 0; + while i < pattern.len() { + let c = pattern.chars().nth(i).expect("some char"); let s: Option = match c { '-' => Some(Symbol::Minus), '+' => Some(Symbol::Plus), @@ -75,25 +90,67 @@ fn parse(pattern: String) -> (Vec, Vec) { match s { Some(s) => { - if number.s.len() == 0 { - number.push(c); + if s.bracket() { + let mut nb_bracket = 1; + let mut i2 = i + 1; + while i2 < pattern.len() { + let c2 = pattern.chars().nth(i2).expect("some char"); + let s2: Option = match c2 { + '(' => Some(Symbol::OpenBracket), + ')' => Some(Symbol::CloseBracket), + + _ => None, + }; + match s2 { + Some(s2) => { + if s2.bracket() { + if s2.open_bracket() { + nb_bracket += 1; + } else if s2.close_bracket() { + nb_bracket -= 1; + if nb_bracket == 0 { + let new_pattern = pattern + .get(i..i2) + .expect("expect the sub string") + .to_string(); + let (tmp_symbols, tmp_numbers) = parse(new_pattern); + let tmp_result = + calculation(&tmp_symbols, &tmp_numbers); + numbers.push(tmp_result); + i = i2; + } + } + } + } + None => {} + } + i2 += 1; + } } else { - symbols.push(s); - numbers.push(number.get()); + if number.s.len() == 0 { + number.push(c); + } else { + symbols.push(s); + numbers.push(number.get()); + } } } None => { number.push(c); } } + + i += 1; } - numbers.push(number.get()); + if number.len() != 0 { + numbers.push(number.get()); + } (symbols, numbers) } -fn calcul(symbols: Vec, numbers: Vec) -> f64 { +fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { let mut counter = 0; let mut n1 = *numbers.get(0).expect("expect at least the first value"); while counter < symbols.len() { @@ -187,6 +244,6 @@ fn main() { process::exit(2); } - let res = calcul(symbols, numbers); + let res = calculation(&symbols, &numbers); println!("{res}"); } -- 2.40.1 From fbe8e2c1c193ea6857c6fdd5a5dd653441812956 Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Mon, 14 Nov 2022 16:22:35 +0100 Subject: [PATCH 5/9] Add comment --- rust-calc/src/main.rs | 78 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index 1549ee2..141c593 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -3,6 +3,7 @@ use std::{ process, }; +// Provide a conformable way to work with symbols #[derive(Clone, Debug)] enum Symbol { Minus, @@ -14,6 +15,7 @@ enum Symbol { CloseBracket, } impl Symbol { + // Checks if the given symbol has priority or not fn priority(&self) -> bool { match self { Symbol::Multiply => true, @@ -22,6 +24,7 @@ impl Symbol { _ => false, } } + // Check if it brackets (open or close) fn bracket(&self) -> bool { match self { Symbol::OpenBracket => true, @@ -30,6 +33,7 @@ impl Symbol { _ => false, } } + // Check if it's an open bracket fn open_bracket(&self) -> bool { match self { Symbol::OpenBracket => true, @@ -37,6 +41,7 @@ impl Symbol { _ => false, } } + // Check if it's an close bracket fn close_bracket(&self) -> bool { match self { Symbol::CloseBracket => true, @@ -46,40 +51,50 @@ impl Symbol { } } +// Provides a object to hold the number being parsed from the string struct TmpNum { s: String, } impl TmpNum { + // Simple constructor pub fn new() -> Self { Self { s: String::new() } } + // Add a new char to the list of chars used to describe the number in a base 10 fashion fn push(&mut self, c: char) { self.s.push(c); } + // Returns the float number from the parsed input fn get(&mut self) -> f64 { + println!("XXX {}", self.s); let n = self.s.parse::().ok().expect("number is malformed"); self.s = String::new(); n } + // Returns the length of the current save number as chars. fn len(&self) -> usize { self.s.len() } } +// Takes as argument a string representing the wanted calculation and return a list of symbols and values. fn parse(pattern: String) -> (Vec, Vec) { let mut symbols = Vec::new(); let mut numbers = Vec::new(); let mut number = TmpNum::new(); + // Iteration of the chars let mut i = 0; while i < pattern.len() { let c = pattern.chars().nth(i).expect("some char"); + // Check if the given char is a recognized symbol let s: Option = match c { '-' => Some(Symbol::Minus), '+' => Some(Symbol::Plus), '*' => Some(Symbol::Multiply), + 'x' => Some(Symbol::Multiply), // This is the second way to express multiplication '/' => Some(Symbol::Divide), '(' => Some(Symbol::OpenBracket), @@ -89,12 +104,18 @@ fn parse(pattern: String) -> (Vec, Vec) { }; match s { + // If the char is a recognized symbol Some(s) => { + // If the char is a bracket if s.bracket() { + // Keep track of the number of brackets let mut nb_bracket = 1; + // Keep track of the new position into the list let mut i2 = i + 1; + // Loop the rest of the input while i2 < pattern.len() { let c2 = pattern.chars().nth(i2).expect("some char"); + // Recognize the brackets from the rest of the input let s2: Option = match c2 { '(' => Some(Symbol::OpenBracket), ')' => Some(Symbol::CloseBracket), @@ -102,33 +123,44 @@ fn parse(pattern: String) -> (Vec, Vec) { _ => None, }; match s2 { + // If brackets Some(s2) => { - if s2.bracket() { - if s2.open_bracket() { - nb_bracket += 1; - } else if s2.close_bracket() { - nb_bracket -= 1; - if nb_bracket == 0 { - let new_pattern = pattern - .get(i..i2) - .expect("expect the sub string") - .to_string(); - let (tmp_symbols, tmp_numbers) = parse(new_pattern); - let tmp_result = - calculation(&tmp_symbols, &tmp_numbers); - numbers.push(tmp_result); - i = i2; - } + // If open add the increment + if s2.open_bracket() { + nb_bracket += 1; + // If close decrease the counter and check if it gets to zero + } else if s2.close_bracket() { + nb_bracket -= 1; + if nb_bracket == 0 { + // Save the content of the brackets + let new_pattern = pattern + .get(i..i2) + .expect("expect the sub string") + .to_string(); + // Send it to the parse function + let (tmp_symbols, tmp_numbers) = parse(new_pattern); + // Do the calculation + let tmp_result = calculation(&tmp_symbols, &tmp_numbers); + // Add the calculated value to the list of numbers + numbers.push(tmp_result); + // Change the position in the list + i = i2; } } } + // Not a bracket, do nothing None => {} } + // Add counter at the end of the loop i2 += 1; } + // If not a bracket but symbol } else { + // If the length of number is zero, add to the current char to number + // It's in the case of signed numbers if number.s.len() == 0 { number.push(c); + // Otherwise add the number and the symbol } else { symbols.push(s); numbers.push(number.get()); @@ -136,23 +168,30 @@ fn parse(pattern: String) -> (Vec, Vec) { } } None => { + // It's not a recognized symbol so it must be part of a number number.push(c); } } + // Increment the list position i += 1; } + // At the end the last number need to be added too. if number.len() != 0 { numbers.push(number.get()); } + // Return the values (symbols, numbers) } +// Run the calculation based on the 2 different lists of symbols and numbers fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { let mut counter = 0; let mut n1 = *numbers.get(0).expect("expect at least the first value"); + + // Iterate the list of symbols while counter < symbols.len() { let s = symbols .get(counter) @@ -161,6 +200,7 @@ fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { .get(counter + 1) .expect("expect at least a second value"); + // If the symbol has priority then simply do the calculation and update n1 if s.priority() { match s { Symbol::Multiply => { @@ -172,9 +212,11 @@ fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { _ => {} }; } else { + // Check the next symbol let next_s = symbols.get(counter + 1); match next_s { Some(ss) => { + // If the next has priority start to check until where the priority calculation goes if ss.priority() { let mut counter_2 = counter + 1; let mut nn1 = *numbers @@ -195,12 +237,15 @@ fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { } _ => {} } + // End of the priority. + // Change the position in the list, save the new value as n1 and stop the priority loop } else { counter = counter_2; n1 = nn1; break; } + // Increment the position in the list counter_2 += 1; } } @@ -208,6 +253,7 @@ fn calculation(symbols: &Vec, numbers: &Vec) -> f64 { None => {} } + // Run the non prioritized calculation match s { Symbol::Minus => { n1.sub_assign(n2); -- 2.40.1 From a033d3b647db810564fb7b2addf2e5716c588085 Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Mon, 14 Nov 2022 16:42:12 +0100 Subject: [PATCH 6/9] Add support for automatic bracket simbol in progress --- rust-calc/src/main.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index 141c593..046e786 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -145,6 +145,30 @@ fn parse(pattern: String) -> (Vec, Vec) { numbers.push(tmp_result); // Change the position in the list i = i2; + + // Check the symbol after the closing bracket + let c3 = pattern.chars().nth(i2 + 1).expect("some char"); + if !c3.is_numeric() { + let s2 = match c3 { + '-' => Some(Symbol::Minus), + '+' => Some(Symbol::Plus), + '*' => Some(Symbol::Multiply), + '/' => Some(Symbol::Divide), + + _ => None, + }; + match s2 { + Some(s2) => { + symbols.push(s2); + i += 1; + } + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // This will be used in case of bracket directly followed by number. + None => { + symbols.push(Symbol::Multiply); + } + } + } } } } @@ -286,7 +310,12 @@ fn main() { // println!("{:?}", numbers); if symbols.len() < 1 || symbols.len() + 1 != numbers.len() { - println!("The input is malformed"); + println!( + "The input is malformed {} {} {}", + symbols.len() < 1, + symbols.len() + 1 != numbers.len(), + symbols.len() + ); process::exit(2); } -- 2.40.1 From 378102901965085f79ee661447cfabf873bcf293 Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Tue, 22 Nov 2022 21:44:55 +0100 Subject: [PATCH 7/9] Add test, fixes#5 --- rust-calc/src/main.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index 046e786..5ed6b4e 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -322,3 +322,31 @@ fn main() { let res = calculation(&symbols, &numbers); println!("{res}"); } + +#[cfg(test)] +mod tests { + use crate::{calculation, parse}; + + #[test] + fn basics() { + let (s, n) = parse("2+2".to_string()); + assert_eq!(calculation(&s, &n), 4.0); + let (s, n) = parse("4-9".to_string()); + assert_eq!(calculation(&s, &n), -5.0); + let (s, n) = parse("7*3".to_string()); + assert_eq!(calculation(&s, &n), 21.0); + let (s, n) = parse("9/3".to_string()); + assert_eq!(calculation(&s, &n), 3.0); + + let (s, n) = parse("15*20".to_string()); + assert_ne!(calculation(&s, &n), 0.0); + } + + #[test] + fn signs_2() { + let (s, n) = parse("2+2*4".to_string()); + assert_eq!(calculation(&s, &n), 10.0); + let (s, n) = parse("30/4-9".to_string()); + assert_eq!(calculation(&s, &n), -1.5); + } +} -- 2.40.1 From 908726e3c6921a938373641a370c1769ea645cff Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Fri, 9 Dec 2022 15:18:30 +0100 Subject: [PATCH 8/9] Fixes priority issue --- rust-calc/src/main.rs | 44 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index fd0ab86..ec3be19 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -71,14 +71,15 @@ fn parse(pattern: String) -> (Vec, Vec) { (symbols, numbers) } -fn calcul(symbols: Vec, numbers: Vec) -> f32 { +fn calculation(symbols: Vec, numbers: Vec) -> f32 { let mut counter = 0; let mut n1 = *numbers.get(0).expect("expect at least the first value"); + while counter < symbols.len() { let s = symbols .get(counter) .expect("expect at least a symbol value"); - let n2 = *numbers + let mut n2 = *numbers .get(counter + 1) .expect("expect at least a second value"); @@ -103,10 +104,11 @@ fn calcul(symbols: Vec, numbers: Vec) -> f32 { .expect("during the priority, we expect at least the first value"); while counter_2 < symbols.len() { let nn2 = *numbers - .get(counter_2) + .get(counter_2 + 1) .expect("during the priority, we expect at least the second value"); if ss.priority() { + println!("next is prio: {:?}\n{nn1} and {nn2}", ss); match ss { Symbol::Multiply => { nn1.mul_assign(nn2); @@ -118,11 +120,13 @@ fn calcul(symbols: Vec, numbers: Vec) -> f32 { } } else { counter = counter_2; - n1 = nn1; + n2 = nn1; break; } + n2 = nn1; counter_2 += 1; + counter = counter_2; } } } @@ -165,6 +169,36 @@ fn main() { process::exit(2); } - let res = calcul(symbols, numbers); + let res = calculation(symbols, numbers); println!("{res}"); } + +#[cfg(test)] +mod tests { + use crate::{calculation, parse}; + + #[test] + fn basics() { + let (s, n) = parse("2+2".to_string()); + assert_eq!(calculation(s, n), 4.0); + let (s, n) = parse("4-9".to_string()); + assert_eq!(calculation(s, n), -5.0); + let (s, n) = parse("7*3".to_string()); + assert_eq!(calculation(s, n), 21.0); + let (s, n) = parse("9/3".to_string()); + assert_eq!(calculation(s, n), 3.0); + + let (s, n) = parse("15*20".to_string()); + assert_ne!(calculation(s, n), 0.0); + } + + #[test] + fn signs_2() { + let (s, n) = parse("2*4+4".to_string()); + assert_eq!(calculation(s, n), 12.0); + let (s, n) = parse("2+2*4".to_string()); + assert_eq!(calculation(s, n), 10.0); + let (s, n) = parse("30/4-9".to_string()); + assert_eq!(calculation(s, n), -1.5); + } +} -- 2.40.1 From 86f08875a8a00384cbbcb333ae10531fe6dfcccf Mon Sep 17 00:00:00 2001 From: Alexandre Stein Date: Fri, 9 Dec 2022 15:52:01 +0100 Subject: [PATCH 9/9] One bracket is working Signed-off-by: Alexandre Stein --- rust-calc/src/main.rs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/rust-calc/src/main.rs b/rust-calc/src/main.rs index cb078aa..e1d5031 100644 --- a/rust-calc/src/main.rs +++ b/rust-calc/src/main.rs @@ -66,7 +66,6 @@ impl TmpNum { } // Returns the float number from the parsed input fn get(&mut self) -> f64 { - println!("XXX {}", self.s); let n = self.s.parse::().ok().expect("number is malformed"); self.s = String::new(); @@ -147,7 +146,10 @@ fn parse(pattern: String) -> (Vec, Vec) { i = i2; // Check the symbol after the closing bracket - let c3 = pattern.chars().nth(i2 + 1).expect("some char"); + let c3 = match pattern.chars().nth(i2 + 1){ + Some(c) => c, + None => break, + }; if !c3.is_numeric() { let s2 = match c3 { '-' => Some(Symbol::Minus), @@ -322,7 +324,6 @@ fn main() { process::exit(2); } - let res = calculation(symbols, numbers); println!("{res}"); } @@ -356,4 +357,24 @@ mod tests { let (s, n) = parse("30/4-9".to_string()); assert_eq!(calculation(s, n), -1.5); } + + #[test] + fn negative_number() { + let (s, n) = parse("-2*4+4".to_string()); + assert_eq!(calculation(s, n), -4.0); + let (s, n) = parse("-2+2*4".to_string()); + assert_eq!(calculation(s, n), 6.0); + } + + #[test] + fn with_1_bracket_set() { + let (s, n) = parse("2*(4+4)*2".to_string()); + assert_eq!(calculation(s, n), 32.0); + let (s, n) = parse("2*(4+4)".to_string()); + assert_eq!(calculation(s, n), 16.0); + let (s, n) = parse("-2*(4+4)".to_string()); + assert_eq!(calculation(s, n), -16.0); + let (s, n) = parse("(4+4)*2".to_string()); + assert_eq!(calculation(s, n), 16.0); + } } -- 2.40.1