use anyhow::anyhow; use std::fs::File; use std::io::BufRead; use std::{io::BufReader, time::Instant}; type Ticket = [u8; 5]; const NUM_ENTRIES: usize = 10_000_000; fn ticket_from_str(s: &str) -> Result { let mut nums = s.split(" ").take(5).map(|s| s.parse::()).into_iter(); let num1 = nums.next(); let num2 = nums.next(); let num3 = nums.next(); let num4 = nums.next(); let num5 = nums.next(); if num1.is_none() || num2.is_none() || num3.is_none() || num4.is_none() || num5.is_none() { return Err(anyhow!("invalid lotto number")); } let r = [ num1.unwrap()?, num2.unwrap()?, num3.unwrap()?, num4.unwrap()?, num5.unwrap()?, ]; if r[0] < 1 || r[1] < 1 || r[2] < 1 || r[3] < 1 || r[4] < 1 || r[0] > 90 || r[1] > 90 || r[2] > 90 || r[3] > 90 || r[4] > 90 { return Err(anyhow!("lotto number out of bounds")); } Ok(r) } fn num_matches(t1: Ticket, t2: Ticket) -> usize { let mut result = 0; for n1 in t1 { for n2 in t2 { if n1 == n2 { result += 1; } } } result } fn main() -> Result<(), anyhow::Error> { let start = Instant::now(); println!("Parsing entries from stdin..."); let f = File::open("/mytmpfs/10m-v2.txt")?; let reader = BufReader::new(f); let mut entries = Vec::with_capacity(NUM_ENTRIES); for line in reader.lines() { match line { Ok(l) => match ticket_from_str(&l) { Ok(n) => entries.push(n), Err(_) => {} // noop }, Err(_) => break, } } let duration = start.elapsed(); println!( "{} entries parsed from stdin in {}ms", entries.len(), duration.as_millis() ); let winning = [68, 81, 40, 34, 85]; let start = Instant::now(); println!("Counting winners... (timer started)"); let mut winners: [usize; 6] = [0, 0, 0, 0, 0, 0]; for n in entries { let num_winning = num_matches(n, winning); winners[num_winning] += 1 } println!("Done counting winners (timer stopped)"); let duration = start.elapsed(); println!( "Winners: {:?}\nTime Elapsed: {}ms", winners.into_iter().skip(2).collect::>(), duration.subsec_millis(), ); Ok(()) }