use anyhow::anyhow; use std::io::BufRead; use std::{ io::{stdin, 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> { println!("Parsing entries from stdin..."); let reader = BufReader::new(stdin()); 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, } } println!("{} entries parsed from stdin", entries.len()); 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, duration.subsec_millis() ); Ok(()) }