diff --git a/src/euler54/src/main.rs b/src/euler54/src/main.rs index 6bca5e7..2953938 100644 --- a/src/euler54/src/main.rs +++ b/src/euler54/src/main.rs @@ -1,12 +1,26 @@ -use std::collections::{HashMap, HashSet}; +#![allow(dead_code, unused_imports)] -#[allow(dead_code)] +use std::{ + cmp::max, + collections::{HashMap, HashSet}, +}; + +type Cards = [Card; 5]; +type Values = [Value; 5]; + +const ROYAL_FLUSH: [Value; 5] = [ + Value::Ten, + Value::Jack, + Value::Queen, + Value::King, + Value::Ace, +]; fn main() { println!("Hello, world!"); } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)] struct Card { value: Value, suit: Suit, @@ -22,7 +36,7 @@ impl Card { } } -#[derive(Debug, PartialEq, Hash, Eq, Clone)] +#[derive(Debug, PartialEq, Hash, Eq, Clone, PartialOrd, Ord)] enum Suit { Diamonds, Hearts, @@ -42,7 +56,7 @@ impl Suit { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)] enum Value { Two, Three, @@ -90,6 +104,7 @@ struct Game { player2: Hand, } +#[derive(PartialEq, PartialOrd)] enum Evaluation { High, OnePair, @@ -99,7 +114,7 @@ enum Evaluation { Flush, FullHouse, FourOfAKind, - StraightFlush, + StraightFlush(Card), RoyalFlush, } @@ -129,13 +144,13 @@ impl Hand { } trait Contains { - fn contains_value(&self, x: T) -> bool; + fn contains_value(&self, x: &T) -> bool; } -impl Contains for &[Card] { - fn contains_value(&self, x: Value) -> bool { +impl Contains for &Cards { + fn contains_value(&self, x: &Value) -> bool { for card in self.iter() { - if card.value == x { + if card.value == *x { return true; } } @@ -143,39 +158,54 @@ impl Contains for &[Card] { } } +trait CardTrait { + fn have_matching_suits(&self) -> bool; + fn contain_all_values_of(&self, values: &Values) -> bool; + fn get_highest_card(&self) -> Card; + fn have_consecutive_values(&self) -> bool; +} + +impl CardTrait for Cards { + fn have_matching_suits(&self) -> bool { + self[1..] + .iter() + .zip(self[..4].iter()) + .all(|(c1, c2)| c1.suit == c2.suit) + } + + fn contain_all_values_of(&self, values: &Values) -> bool { + values.iter().all(|v| self.contains_value(v)) + } + + fn get_highest_card(&self) -> Card { + self.iter() + .reduce(|accum, item| max(accum, item)) + .unwrap() + .clone() + } + + fn have_consecutive_values(&self) -> bool { + self[0].value + 1 + } +} + impl Evaluation { - fn from_cards(cards: &[Card]) -> Self { - todo!() - } - - fn is_royal_flush(cards: &[Card]) -> Option { - let values = [ - Value::Ten, - Value::Jack, - Value::Queen, - Value::King, - Value::Ace, - ]; - for value in values { - if !cards.contains_value(value) { - return None; - } - } - if Self::have_matching_suits(cards) { - Some(cards[0].suit.clone()) + fn from_cards(cards: &Cards) -> Self { + if Self::is_royal_flush(cards) { + Self::RoyalFlush + } else if Self::is_straight_flush(cards) { + Self::StraightFlush(cards.get_highest_card()) } else { - None + todo!() } } - fn have_matching_suits(cards: &[Card]) -> bool { - let first_suit = &cards[0].suit; - for card in cards { - if &card.suit != first_suit { - return false; - } - } - true + fn is_straight_flush(cards: &Cards) -> bool { + cards.have_matching_suits() && cards.have_consecutive_values() + } + + fn is_royal_flush(cards: &Cards) -> bool { + cards.have_matching_suits() && cards.contain_all_values_of(&ROYAL_FLUSH) } }