use std::collections::HashMap; use std::fs::File; use std::io; use std::io::{BufRead, BufReader}; fn main() -> io::Result<()> { let file = File::open("input.txt")?; let reader = BufReader::new(file); let result = reader.lines() .map(|line| parse(line.unwrap())) .map(|line| get_win_amounts(line.0, line.1)) .map(|wins| calculate_points(wins)) .fold(0, |a, b| a + b); println!("First: {}", result); let file = File::open("input.txt")?; let reader = BufReader::new(file); let cards: Vec<(Vec, Vec)> = reader.lines() .map(|line| parse(line.unwrap())) .collect(); let mut map: HashMap = HashMap::new(); for i in 0..cards.len() { map.insert(i, 1); } for card_number in 0..cards.len() { let numbers = cards[card_number].to_owned(); let wins = get_win_amounts(numbers.0, numbers.1); let count = map[&card_number]; for i in 1..wins + 1 { map.entry(card_number + i as usize).and_modify(|value| *value += count); } } let result = map.iter() .map(|entry| entry.1) .fold(0, |a, b| a + b); println!("Second: {}", result); Ok(()) } fn calculate_points(wins: u32) -> u32 { if wins == 0 { return 0; } 2u32.pow(wins - 1) } fn get_win_amounts(winning_numbers: Vec, my_numbers: Vec) -> u32 { my_numbers.iter().filter(|number| winning_numbers.contains(number)).count() as u32 } fn parse(line: String) -> (Vec, Vec) { let relevant = line.split(':').nth(1).unwrap(); let mut parts = relevant.split('|'); let winning = parts.next().unwrap().trim(); let mine = parts.next().unwrap().trim(); (parse_numbers(winning), parse_numbers(mine)) } fn parse_numbers(numbers: &str) -> Vec { numbers.split_whitespace().map(|number| { number.parse::().unwrap() }).collect() } #[cfg(test)] mod tests { #[test] fn check_find_numbers() {} }