Sum the valid readings
A river gauge sends one reading per line over a flaky radio link, so some lines arrive garbled: 12x, --, a blank line, or a number too large for a 64-bit integer. Read all lines until input ends. A line is valid when, after trimming spaces, it parses as an i64; every other line is invalid. Print one line sum=<S> valid=<V> invalid=<I> with the sum of the valid readings and the two counts. The program must never panic on bad input.
Input
Zero or more lines until end of input. There may be no lines at all.
Output
One line: sum=<S> valid=<V> invalid=<I>.
Example 1
Input
12 -4 12x 30
Output
sum=38 valid=3 invalid=2
12, -4 and 30 are valid (sum 38); 12x and the blank line are not.
Example 2
Input
9223372036854775807 -1 9223372036854775808
Output
sum=9223372036854775806 valid=2 invalid=1
The last line is one more than the largest i64, so parsing fails and it counts as invalid instead of crashing the program.
Constraints
- 0 <= number of lines <= 10000
- The sum of the valid readings fits in an i64
Hints
Hint 1 of 3
line.trim().parse::<i64>() gives a Result: Ok(value) for a number, Err(_) for anything else, including an empty string.
Hint 2 of 3
Match on the Result and update sum and valid in the Ok arm, invalid in the Err arm; never call unwrap() here.
Hint 3 of 3
The for line in stdin.lock().lines() loop simply runs zero times on empty input, so the counters start at zero and the final println! handles that case by itself.
Solution
Show a reference solution and explanation
use std::io::{self, BufRead};
fn main() {
let stdin = io::stdin();
let mut sum: i64 = 0;
let mut valid = 0;
let mut invalid = 0;
for line in stdin.lock().lines() {
let line = line.unwrap();
match line.trim().parse::<i64>() {
Ok(value) => {
sum += value;
valid += 1;
}
Err(_) => invalid += 1,
}
}
println!("sum={} valid={} invalid={}", sum, valid, invalid);
}
Why it works
parse returns Result<i64, ParseIntError> precisely so that bad text is a value you can inspect rather than a crash. Matching on it turns the two outcomes into the two counters; unwrap() would be the wrong tool because a garbled line is expected, not exceptional. Trimming first matters: lines() strips the newline but not other spaces, and " 8 " should count as 8. Overflowing text such as 9223372036854775808 is rejected by parse with a PosOverflow error kind, so the same Err arm covers it without any special case. sum is an i64 because readings can be negative and large.