Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
48a1da47fb |
|||
|
016e21ac5a |
|||
|
ca6af4d06f |
|||
|
6e14c4e967 |
|||
|
c8bc766e2a |
|||
|
909bcfef6d |
3 changed files with 58 additions and 18 deletions
74
src/main.rs
74
src/main.rs
|
|
@ -8,24 +8,6 @@ use rug::Float;
|
||||||
|
|
||||||
mod nodes;
|
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() {
|
fn main() {
|
||||||
let input = match env::args().skip(1).reduce(|x, a| a + &x) {
|
let input = match env::args().skip(1).reduce(|x, a| a + &x) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
|
|
@ -38,5 +20,59 @@ fn main() {
|
||||||
|
|
||||||
let result = parse_and_calc(&input);
|
let result = parse_and_calc(&input);
|
||||||
|
|
||||||
println!("{result:.0$}", get_significant_digits(&result).clamp(0, 6));
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,6 @@ impl FromStr for Nodes {
|
||||||
}
|
}
|
||||||
ParsingState::ReadingNumber(start_index) => {
|
ParsingState::ReadingNumber(start_index) => {
|
||||||
if !is_number_char(c) {
|
if !is_number_char(c) {
|
||||||
if matches!(nodes.last(), Some(Node::ParenthesisEnd)) {
|
|
||||||
nodes.push(Node::Operator(Default::default()));
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes.push(Node::Number(
|
nodes.push(Node::Number(
|
||||||
Float::parse(&filtered_string[start_index..i])
|
Float::parse(&filtered_string[start_index..i])
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
|
@ -138,6 +134,9 @@ impl FromStr for Nodes {
|
||||||
} else if c.is_alphabetic() {
|
} else if c.is_alphabetic() {
|
||||||
state = ParsingState::ReadingFunctionName(i);
|
state = ParsingState::ReadingFunctionName(i);
|
||||||
} else if c == '(' {
|
} else if c == '(' {
|
||||||
|
if matches!(nodes.last(), Some(Node::Number(_) | Node::ParenthesisEnd)) {
|
||||||
|
nodes.push(Node::Operator(Default::default()));
|
||||||
|
}
|
||||||
nodes.push(Node::ParenthesisStart);
|
nodes.push(Node::ParenthesisStart);
|
||||||
} else if c == ')' {
|
} else if c == ')' {
|
||||||
nodes.push(Node::ParenthesisEnd);
|
nodes.push(Node::ParenthesisEnd);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ fn implicit_mult() {
|
||||||
Nodes::from_str("10 sin(10)").unwrap().evaluate().to_f64(),
|
Nodes::from_str("10 sin(10)").unwrap().evaluate().to_f64(),
|
||||||
-5.440211108893698
|
-5.440211108893698
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Nodes::from_str("(10)(10)").unwrap().evaluate().to_f64(),
|
||||||
|
100.,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue