use std::io;
use std::io::BufRead;

struct Card {
    match_count: usize,
    copies: usize,
}

fn get_points(match_count: usize) -> usize {
    match match_count{
        0 => 0,
        _ => 2_usize.pow((match_count-1).try_into().unwrap()),
    }
}

fn main() {
    let mut lines_processed = 0;
    let mut cards: Vec<Card> = Vec::new();
    let mut total_points: usize = 0;


    let mut line = String::new();
    while io::stdin().lock().read_line(&mut line).unwrap() > 0 {
        println!("input {}", line.trim());
        let card_strings = line.trim().split_once(':').unwrap();
        //dbg!(card_strings);
        //let card_number: usize = card_strings.0[5..].trim().parse::<usize>().unwrap();
        let card_data_string  = card_strings.1.trim().split_once('|').unwrap();

        let winning_numbers: Vec<usize> = card_data_string.0
                                                          .split_whitespace()
                                                          .map(|s| s.parse().unwrap())
                                                          .collect();
        let my_numbers: Vec<usize> = card_data_string.1
                                                     .split_whitespace()
                                                     .map(|s| s.parse().unwrap())
                                                     .collect();
                                     
        let match_count: usize = my_numbers.iter()
                                           .filter(|x| winning_numbers.contains(x))
                                           .count().try_into().unwrap();
        
        total_points += get_points(match_count);
        cards.push(Card {
            match_count: match_count,
            copies: 1,
        });
        lines_processed += 1;
        line.clear();
    }

    println!("\n Ingested {} Lines", lines_processed);
    println!("===================================");


    for i in 1..cards.len() {
        let current_card_match_no = cards[i-1].match_count;
        let current_card_copies_no = cards[i-1].copies;
        //dbg!(current_card_match_no);
        for j in 1..=current_card_match_no {
            cards[(i-1)+j].copies += current_card_copies_no;
        }
    }

    let total_card_copies: usize = cards.iter().map(|x| x.copies).sum();

    println!("\n Processed {} Cards", cards.len());
    println!("===================================");
    println!("Total Points: \n{}", total_points);
    println!("Total Cards: \n{}", total_card_copies);
}
