use std::env; use std::fs::File; use std::io::BufReader; use std::io::prelude::*; use std::collections::HashMap; struct Station { min: f64, max: f64, sum: f64, n: usize, } fn main() { let args: Vec = env::args().collect(); let filename = &args[1]; println!("{filename}"); let file = File::open(filename).unwrap(); let mut buffered_reader = BufReader::with_capacity(1024, file); let mut line = String::new(); let mut stations = HashMap::::new(); stations.reserve(10_000); let mut line_no: usize = 0; loop { line_no += 1; if line_no % 10_000_000 == 0 { println!("{}", line_no); } line.clear(); let n = buffered_reader.read_line(&mut line).unwrap(); if n == 0 { break; } // in a worst case, the last 6 chars in a line are taken up by the temp // ...name;-14.4\n // in a best case, the last 4 chars in a line are taken up by the temp // ...name;9.2\n for i in 5..7 { if line.chars().nth_back(i) == Some(';') { let temp: f64 = line[n - i..n - 1].parse().unwrap(); let name = String::from(&line[..n - i - 1]); if let Some(station) = stations.get_mut(&name) { station.min = station.min.min(temp); station.max = station.max.max(temp); station.sum += temp; station.n += 1; } else { stations.insert(name, Station { min: temp, max: temp, sum: temp, n: 1, }); } break; } } } let mut stations: Vec<_> = stations.iter().collect(); stations.sort_unstable_by(|(n1, _), (n2, _)| n1.cmp(n2)); for (name, station) in stations { println!("{};{:.1};{:.1};{:.1}", name, station.min, station.sum / station.n as f64, station.max ); } }