diff --git a/src/main.rs b/src/main.rs index 368ef3d..247ba53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,24 @@ use rug::Float; mod nodes; +pub fn parse_and_calc(s: &str) -> Float { + nodes::Nodes::from_str(s).unwrap().evaluate() +} + +pub fn get_significant_digits(n: &Float) -> usize { + let raw_string = format!("{n}"); + + let mut significant_digits = raw_string.len() - 1; + for (i, _) in raw_string.char_indices() { + if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..'9')) { + significant_digits = i; + break; + } + } + + significant_digits +} + fn main() { let input = match env::args().skip(1).reduce(|x, a| a + &x) { Some(s) => s, @@ -20,59 +38,5 @@ fn main() { let result = parse_and_calc(&input); - println!("{result:.0$}", get_significant_digits(&result)); -} - -pub fn parse_and_calc(s: &str) -> Float { - nodes::Nodes::from_str(s).unwrap().evaluate() -} - -pub fn get_significant_digits(n: &Float) -> usize { - let raw_string = format!("{n}"); - - let mut significant_digits = raw_string.len() - 1; - let mut consecutive_zeros = 0; - let mut consecutive_nines = 0; - for (i, c) in raw_string.char_indices() { - if c == '0' { - consecutive_zeros += 1; - } else { - consecutive_zeros = 0; - } - - if c == '9' { - consecutive_nines += 1; - } else { - consecutive_nines = 0; - } - - if consecutive_zeros >= 10 { - significant_digits = i - consecutive_zeros; - break; - } else if consecutive_nines >= 10 { - significant_digits = i - consecutive_nines; - break; - } - - if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..='9')) { - significant_digits = i; - break; - } - } - - significant_digits -} - -#[test] -fn test_get_significant_digits() { - let many_zeros = parse_and_calc("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4"); - assert_eq!(many_zeros.to_f64(), 117.48139); - let many_nines = parse_and_calc("12.0096 + 15.9994 * 2"); - assert_eq!(many_nines.to_f64(), 44.0084); - let zero_nine_zero = parse_and_calc("2+12321(5+123)"); - assert_eq!(zero_nine_zero.to_f64(), 1577090.0); - - assert_eq!(get_significant_digits(&many_zeros), 8); - assert_eq!(get_significant_digits(&many_nines), 6); - assert_eq!(get_significant_digits(&zero_nine_zero), 6); + println!("{result:.0$}", get_significant_digits(&result).clamp(0, 6)); } diff --git a/src/nodes/from_str.rs b/src/nodes/from_str.rs index 94a4af4..a28b15a 100644 --- a/src/nodes/from_str.rs +++ b/src/nodes/from_str.rs @@ -111,6 +111,10 @@ impl FromStr for Nodes { } ParsingState::ReadingNumber(start_index) => { if !is_number_char(c) { + if matches!(nodes.last(), Some(Node::ParenthesisEnd)) { + nodes.push(Node::Operator(Default::default())); + } + nodes.push(Node::Number( Float::parse(&filtered_string[start_index..i]) .map_err(|e| { @@ -134,9 +138,6 @@ impl FromStr for Nodes { } else if c.is_alphabetic() { state = ParsingState::ReadingFunctionName(i); } else if c == '(' { - if matches!(nodes.last(), Some(Node::Number(_) | Node::ParenthesisEnd)) { - nodes.push(Node::Operator(Default::default())); - } nodes.push(Node::ParenthesisStart); } else if c == ')' { nodes.push(Node::ParenthesisEnd); diff --git a/src/nodes/tests.rs b/src/nodes/tests.rs index 405efe5..ae50576 100644 --- a/src/nodes/tests.rs +++ b/src/nodes/tests.rs @@ -11,11 +11,6 @@ fn implicit_mult() { Nodes::from_str("10 sin(10)").unwrap().evaluate().to_f64(), -5.440211108893698 ); - - assert_eq!( - Nodes::from_str("(10)(10)").unwrap().evaluate().to_f64(), - 100., - ) } #[test]