Do day 7 challenge

This commit is contained in:
Cassandra de la Cruz-Munoz 2023-12-07 21:42:34 +01:00
parent da12b07502
commit 8c7567b21b
2 changed files with 399 additions and 0 deletions

196
src/07part1.rs Normal file
View File

@ -0,0 +1,196 @@
use std::{fs, cmp::Ordering};
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
enum Card {
None = 0,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Jack = 11,
Queen = 12,
King = 13,
Ace = 14
}
impl Copy for Card {}
impl Clone for Card {
fn clone(&self) -> Self {
*self
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
enum HandType {
FiveOfAKind = 6,
FourOfAKind = 5,
FullHouse = 4,
ThreeOfAKind = 3,
TwoPair = 2,
OnePair = 1,
HighCard = 0,
}
#[derive(Eq, Debug)]
struct Hand {
bet: u128,
hand_type: HandType,
cards: Vec<Card>,
}
impl Ord for Hand {
fn cmp(&self, other: &Self) -> Ordering {
if self.hand_type.ne(&other.hand_type) {
return self.hand_type.cmp(&other.hand_type);
}
if self.cards[0].ne(&other.cards[0]) {
return self.cards[0].cmp(&other.cards[0]);
}
if self.cards[1].ne(&other.cards[1]) {
return self.cards[1].cmp(&other.cards[1]);
}
if self.cards[2].ne(&other.cards[2]) {
return self.cards[2].cmp(&other.cards[2]);
}
if self.cards[3].ne(&other.cards[3]) {
return self.cards[3].cmp(&other.cards[3]);
}
return self.cards[4].cmp(&other.cards[4]);
}
}
impl PartialOrd for Hand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Hand {
fn eq(&self, other: &Self) -> bool {
self.cards == other.cards
}
}
fn main() {
let file_path = "input/07input.txt";
let contents = fs::read_to_string(file_path).expect("should read file");
let mut lines = contents.lines();
let mut hands: Vec<Hand> = Vec::new();
loop {
let line = lines.next();
if line.is_none() {
break;
}
let mut line_parts = line.unwrap().split_whitespace();
let hand_cards: Vec<Card> = line_parts.next().unwrap().chars().map(|x| match x{
'2' => Card::Two,
'3' => Card::Three,
'4' => Card::Four,
'5' => Card::Five,
'6' => Card::Six,
'7' => Card::Seven,
'8' => Card::Eight,
'9' => Card::Nine,
'T' => Card::Ten,
'J' => Card::Jack,
'Q' => Card::Queen,
'K' => Card::King,
'A' => Card::Ace,
_ => Card::None,
}).collect();
let bet = line_parts.next().unwrap().parse::<u128>().ok().unwrap();
let hand = hand_from_cards(bet, hand_cards);
let loc_val: usize;
match hands.binary_search_by(|probe| probe.cmp(&hand)) {
Ok(v) => loc_val = v,
Err(v) => loc_val = v,
}
hands.insert(loc_val, hand);
}
let mut total_winnings: u128 = 0;
for i in 0..hands.len() {
total_winnings += hands[i].bet * (i + 1).to_string().parse::<u128>().ok().unwrap();
}
println!("{}", total_winnings);
}
fn hand_from_cards(bet: u128, cards: Vec<Card>) -> Hand {
let hand_type: HandType;
if cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4] { // AAAAA
hand_type = HandType::FiveOfAKind;
} else if
(cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[3]) || // AAAAB
(cards[0] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4]) || // ABAAA
(cards[0] == cards[1] && cards[1] == cards[3] && cards[3] == cards[4]) || // AABAA
(cards[0] == cards[1] && cards[1] == cards[2] && cards[2] == cards[4]) || // AAABA
(cards[1] == cards[2] && cards[2] == cards[3] && cards[3] == cards[4]) // BAAAA
{
hand_type = HandType::FourOfAKind;
} else if
(cards[0] == cards[1] && cards[1] == cards[2] && cards[3] == cards[4]) || // AAABB
(cards[0] == cards[1] && cards[1] == cards[3] && cards[2] == cards[4]) || // AABAB
(cards[0] == cards[1] && cards[1] == cards[4] && cards[2] == cards[3]) || // AABBA
(cards[0] == cards[2] && cards[2] == cards[3] && cards[1] == cards[4]) || // ABAAB
(cards[0] == cards[2] && cards[2] == cards[4] && cards[1] == cards[3]) || // ABABA
(cards[0] == cards[3] && cards[3] == cards[4] && cards[1] == cards[2]) || // ABBAA
(cards[1] == cards[2] && cards[2] == cards[3] && cards[0] == cards[4]) || // BAAAB
(cards[1] == cards[2] && cards[2] == cards[4] && cards[0] == cards[3]) || // BAABA
(cards[1] == cards[3] && cards[3] == cards[4] && cards[0] == cards[2]) || // BABAA
(cards[2] == cards[3] && cards[3] == cards[4] && cards[0] == cards[1]) // BBAAA
{
hand_type = HandType::FullHouse;
} else if
(cards[0] == cards[1] && cards[1] == cards[2]) || // AAABC
(cards[0] == cards[1] && cards[1] == cards[3]) || // AABAC
(cards[0] == cards[1] && cards[1] == cards[4]) || // AABCA
(cards[0] == cards[2] && cards[2] == cards[3]) || // ABAAC
(cards[0] == cards[2] && cards[2] == cards[4]) || // ABACA
(cards[0] == cards[3] && cards[3] == cards[4]) || // ABCAA
(cards[1] == cards[2] && cards[2] == cards[3]) || // BAAAC
(cards[1] == cards[2] && cards[2] == cards[4]) || // BAACA
(cards[1] == cards[3] && cards[3] == cards[4]) || // BACAA
(cards[2] == cards[3] && cards[3] == cards[4]) // BCAAA
{
hand_type = HandType::ThreeOfAKind;
} else if
(cards[0] == cards[1] && cards[2] == cards[3]) || // AABBC
(cards[0] == cards[1] && cards[2] == cards[4]) || // AABCB
(cards[0] == cards[1] && cards[3] == cards[4]) || // AACBB
(cards[0] == cards[2] && cards[1] == cards[3]) || // ABABC
(cards[0] == cards[2] && cards[1] == cards[4]) || // ABACB
(cards[0] == cards[2] && cards[3] == cards[4]) || // ACABB
(cards[0] == cards[3] && cards[1] == cards[2]) || // ABBAC
(cards[0] == cards[3] && cards[1] == cards[4]) || // ABCAB
(cards[0] == cards[3] && cards[2] == cards[4]) || // ACBAB
(cards[0] == cards[4] && cards[1] == cards[2]) || // ABBCA
(cards[0] == cards[4] && cards[1] == cards[3]) || // ABCBA
(cards[0] == cards[4] && cards[2] == cards[3]) || // ACBBA
(cards[1] == cards[2] && cards[3] == cards[4]) || // CAABB
(cards[1] == cards[3] && cards[2] == cards[4]) || // CABAB
(cards[1] == cards[4] && cards[2] == cards[3]) // CABBA
{
hand_type = HandType::TwoPair;
} else if
cards[0] == cards[1] || // AABCD
cards[0] == cards[2] || // ABACD
cards[0] == cards[3] || // ABCAD
cards[0] == cards[4] || // ABCDA
cards[1] == cards[2] || // BAACD
cards[1] == cards[3] || // BACAD
cards[1] == cards[4] || // BACDA
cards[2] == cards[3] || // BCAAD
cards[2] == cards[4] || // BCADA
cards[3] == cards[4] // BCDAA
{
hand_type = HandType::OnePair;
} else { // ABCDE
hand_type = HandType::HighCard;
}
return Hand {bet, hand_type, cards};
}

203
src/07part2.rs Normal file
View File

@ -0,0 +1,203 @@
use std::{fs, cmp::Ordering, collections::HashMap};
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
enum Card {
None = 0,
Joker = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Queen = 12,
King = 13,
Ace = 14
}
impl Copy for Card {}
impl Clone for Card {
fn clone(&self) -> Self {
*self
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
enum HandType {
FiveOfAKind = 6,
FourOfAKind = 5,
FullHouse = 4,
ThreeOfAKind = 3,
TwoPair = 2,
OnePair = 1,
HighCard = 0,
}
#[derive(Eq, Debug)]
struct Hand {
bet: u128,
hand_type: HandType,
cards: Vec<Card>,
}
impl Ord for Hand {
fn cmp(&self, other: &Self) -> Ordering {
if self.hand_type.ne(&other.hand_type) {
return self.hand_type.cmp(&other.hand_type);
}
if self.cards[0].ne(&other.cards[0]) {
return self.cards[0].cmp(&other.cards[0]);
}
if self.cards[1].ne(&other.cards[1]) {
return self.cards[1].cmp(&other.cards[1]);
}
if self.cards[2].ne(&other.cards[2]) {
return self.cards[2].cmp(&other.cards[2]);
}
if self.cards[3].ne(&other.cards[3]) {
return self.cards[3].cmp(&other.cards[3]);
}
return self.cards[4].cmp(&other.cards[4]);
}
}
impl PartialOrd for Hand {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for Hand {
fn eq(&self, other: &Self) -> bool {
self.cards == other.cards
}
}
fn main() {
let file_path = "input/07input.txt";
let contents = fs::read_to_string(file_path).expect("should read file");
let mut lines = contents.lines();
let mut hands: Vec<Hand> = Vec::new();
loop {
let line = lines.next();
if line.is_none() {
break;
}
let mut line_parts = line.unwrap().split_whitespace();
let hand_cards: Vec<Card> = line_parts.next().unwrap().chars().map(|x| match x{
'2' => Card::Two,
'3' => Card::Three,
'4' => Card::Four,
'5' => Card::Five,
'6' => Card::Six,
'7' => Card::Seven,
'8' => Card::Eight,
'9' => Card::Nine,
'T' => Card::Ten,
'J' => Card::Joker,
'Q' => Card::Queen,
'K' => Card::King,
'A' => Card::Ace,
_ => Card::None,
}).collect();
let bet = line_parts.next().unwrap().parse::<u128>().ok().unwrap();
let hand = hand_from_cards(bet, hand_cards);
let loc_val: usize;
match hands.binary_search_by(|probe| probe.cmp(&hand)) {
Ok(v) => loc_val = v,
Err(v) => loc_val = v,
}
hands.insert(loc_val, hand);
}
let mut total_winnings: u128 = 0;
for i in 0..hands.len() {
total_winnings += hands[i].bet * (i + 1).to_string().parse::<u128>().ok().unwrap();
}
println!("{}", total_winnings);
}
fn hand_from_cards(bet: u128, cards: Vec<Card>) -> Hand {
let hand_type: HandType;
let mut cards_map = HashMap::new();
for card in cards.iter() {
if cards_map.get(&card).is_none() {
cards_map.insert(card, 0);
}
cards_map.insert(&card, 1+cards_map.get(&card).unwrap());
}
let mut hand_cards: Vec<Card> = Vec::new();
let mut hand_card_counts = Vec::new();
for card in cards_map.keys() {
for _i in 0..cards_map[card] {
let mut matched = false;
for j in 0..hand_card_counts.len() {
if hand_card_counts[j] > cards_map[card] {
hand_card_counts.insert(j, cards_map[card]);
hand_cards.insert(j, *card.to_owned());
matched = true;
break;
}
}
if !matched && hand_card_counts.len() > 0 {
hand_card_counts.insert(hand_card_counts.len()-1, cards_map[card]);
hand_cards.insert(hand_card_counts.len()-1, *card.to_owned());
} else if !matched {
hand_card_counts.insert(0, cards_map[card]);
hand_cards.insert(0, *card.to_owned());
}
}
}
hand_cards.reverse();
if
(hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2] && hand_cards[2] == hand_cards[3] && hand_cards[3] == hand_cards[4]) || // AAAAA
(hand_cards[4] == Card::Joker && hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2] && hand_cards[2] == hand_cards[3]) || // AAAAJ
(hand_cards[3] == Card::Joker && hand_cards[4] == Card::Joker && hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2]) || // AAAJJ
(hand_cards[0] == Card::Joker && hand_cards[1] == Card::Joker && hand_cards[2] == Card::Joker && hand_cards[3] == hand_cards[4]) || // JJJAA
(hand_cards[2] == Card::Joker && hand_cards[3] == Card::Joker && hand_cards[0] == Card::Joker && hand_cards[1] == Card::Joker) // JJJJA
{
hand_type = HandType::FiveOfAKind;
} else if
(hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2] && hand_cards[2] == hand_cards[3]) || // AAAAB
(hand_cards[3] == Card::Joker && hand_cards[1] == hand_cards[2] && hand_cards[2] == hand_cards[0]) || // AAAJB
(hand_cards[4] == Card::Joker && hand_cards[1] == hand_cards[2] && hand_cards[2] == hand_cards[0]) || // AAABJ
(hand_cards[2] == Card::Joker && hand_cards[3] == Card::Joker && hand_cards[0] == hand_cards[1]) || // AAJJB
(hand_cards[0] == Card::Joker && hand_cards[1] == Card::Joker && hand_cards[2] == hand_cards[3]) || // JJAAB
(hand_cards[1] == Card::Joker && hand_cards[2] == Card::Joker && hand_cards[0] == Card::Joker) // JJJAB
{
hand_type = HandType::FourOfAKind;
} else if
(hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2] && hand_cards[3] == hand_cards[4]) || // AAABB
(hand_cards[0] == hand_cards[1] && hand_cards[2] == hand_cards[3] && hand_cards[4] == Card::Joker) // AABBJ
{
hand_type = HandType::FullHouse;
} else if
(hand_cards[0] == hand_cards[1] && hand_cards[1] == hand_cards[2]) || // AAABC
(hand_cards[0] == hand_cards[1] && hand_cards[2] == Card::Joker) || // AAJBC
(hand_cards[0] == hand_cards[1] && hand_cards[3] == Card::Joker) || // AABJC
(hand_cards[0] == hand_cards[1] && hand_cards[4] == Card::Joker) || // AABCJ
(hand_cards[0] == Card::Joker && hand_cards[1] == Card::Joker) // JJABC
{
hand_type = HandType::ThreeOfAKind;
} else if
hand_cards[0] == hand_cards[1] && hand_cards[2] == hand_cards[3] // AABBC
{
hand_type = HandType::TwoPair;
} else if
hand_cards[0] == hand_cards[1] || // AABCD
hand_cards[0] == Card::Joker || // JABCD
hand_cards[1] == Card::Joker || // AJBCD
hand_cards[2] == Card::Joker || // ABJCD
hand_cards[3] == Card::Joker || // ABCJD
hand_cards[4] == Card::Joker // ABCDJ
{
hand_type = HandType::OnePair;
} else { // ABCDE
hand_type = HandType::HighCard;
}
// println!("{:?} {:?}", hand_cards, hand_type);
return Hand {bet, hand_type, cards};
}