Day seven

On day 7 we try and implement a simplified poker analyzer.

Parsing

The parser for this day isn't that complicated. It has been implemented as the following:

    let hands: Vec<(&str, &str)> = file.lines().map(|l| l.split_once(" ").expect("Couldn't split line!")).collect();
    let mut games: Vec<Hand> = Vec::new();

At first, we get all the lines and use .map() to apply some logic to every line. We split the lines at the space once, which separated the cards and the bids. This gives us a tuple, and by collecting this we end up with a vec of tuples.

Now we need to create cards. All the cards are made up of characters, but we can't sort them easily. Because of this we've created a cards enum with an implementation that enables us to sort the cards.

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum Card {
    Joker,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace,
}

impl Card {
    fn from_char(card: char, joker: bool) -> Self {
        match card {
            '2' => Self::Two,
            '3' => Self::Three,
            '4' => Self::Four,
            '5' => Self::Five,
            '6' => Self::Six,
            '7' => Self::Seven,
            '8' => Self::Eight,
            '9' => Self::Nine,
            'T' => Self::Ten,
            'J' => if joker { Self::Joker } else { Self::Jack },
            'Q' => Self::Queen,
            'K' => Self::King,
            'A' => Self::Ace,
            _ => panic!("That shouldn't be possible!")
        }
    }
}

This matches all the characters and assigns the correct cards to it. It aso contains a joker boolean, which we'll use in part two.

To get all the data in a better format, we created a Hand struct with the cards, score and the bid. The score will help us determining the hand rank soon.

#[derive(Debug)]
struct Hand {
    cards: Vec<Card>,
    score: [i64; 2],
    bid: i64,
}

We parse all the data in the following function:

    for (cards, bid) in hands {
        let bid: i64 = bid.parse().expect("Couldn't parse bid!");
        let cards: Vec<Card> = cards.chars().map(|c| Card::from_char(c, joker)).collect();
        
        games.push(Hand {
            cards,
            score: [0, 0],
            bid,
        });
    }
    
    games
}

For every hand, we parse the bid to an i64, all the cards get split into .chars() and gets parsed into a Card type. After this, we push the Hand struct to the games vec. We set the score to 0 to modify later.

Part one

In part one, we just need to build a simple poker parser.