Skip to content
Snippets Groups Projects
Verified Commit 831fd071 authored by Falk Rehse's avatar Falk Rehse
Browse files

Day 7

parent e3cf24c2
Branches
No related tags found
No related merge requests found
#[derive(Debug, Eq, Hash, PartialEq, Copy, Clone)]
pub enum Card {
CardA,
CardK,
CardQ,
CardJ,
CardT,
Card9,
Card8,
Card7,
Card6,
Card5,
Card4,
Card3,
Card2,
}
impl Card {
pub fn from_char(c: char) -> Card {
match c {
'A' => Card::CardA,
'K' => Card::CardK,
'Q' => Card::CardQ,
'J' => Card::CardJ,
'T' => Card::CardT,
'9' => Card::Card9,
'8' => Card::Card8,
'7' => Card::Card7,
'6' => Card::Card6,
'5' => Card::Card5,
'4' => Card::Card4,
'3' => Card::Card3,
'2' => Card::Card2,
_ => panic!(),
}
}
pub fn to_value(self) -> u32 {
match self {
Card::CardA => 13,
Card::CardK => 12,
Card::CardQ => 11,
Card::CardJ => 10,
Card::CardT => 9,
Card::Card9 => 8,
Card::Card8 => 7,
Card::Card7 => 6,
Card::Card6 => 5,
Card::Card5 => 4,
Card::Card4 => 3,
Card::Card3 => 2,
Card::Card2 => 1,
}
}
}
use std::collections::HashMap;
use super::card::Card;
#[derive(Debug)]
pub struct Hand {
pub kind: HandType,
pub cards: Vec<Card>,
}
#[derive(Debug, Copy, Clone)]
pub enum HandType {
FiveOfAKind,
FourOfAKind,
FullHouse,
ThreeOfAKind,
TwoPair,
OnePair,
HighCard,
}
impl Hand {
pub fn from_str(input: &str) -> Hand {
let cards = input.chars().map(|c| Card::from_char(c)).collect();
Hand {
kind: HandType::from_cards(&cards),
cards,
}
}
}
impl HandType {
pub fn from_cards(cards: &Vec<Card>) -> HandType {
let mut map: HashMap<Card, u32> = HashMap::new();
for card in cards {
let count = map.get(&card).copied().unwrap_or(0);
map.insert(*card, count + 1);
}
let mut card_counts = map
.iter()
.map(|(card, amount)| *amount)
.collect::<Vec<u32>>();
card_counts.sort_unstable();
card_counts.reverse();
let max = card_counts[0];
let second = card_counts.get(1).unwrap_or(&0);
match (max, second) {
(5, _) => HandType::FiveOfAKind,
(4, _) => HandType::FourOfAKind,
(3, 2) => HandType::FullHouse,
(3, _) => HandType::ThreeOfAKind,
(2, 2) => HandType::TwoPair,
(2, _) => HandType::OnePair,
_ => HandType::HighCard,
}
}
pub fn to_value(self) -> u32 {
match self {
HandType::FiveOfAKind => 7,
HandType::FourOfAKind => 6,
HandType::FullHouse => 5,
HandType::ThreeOfAKind => 4,
HandType::TwoPair => 3,
HandType::OnePair => 2,
HandType::HighCard => 1,
}
}
}
use std::cmp::Ordering;
use crate::util::*;
mod card;
mod hand;
use hand::Hand;
pub fn solve_from_str(input: &str) -> u32 {
let mut set: Vec<(Hand, u32)> = input
.lines()
.map(|line| {
let mut data = line.split(" ");
let hand = data.next().unwrap();
let bid = data.next().unwrap();
(Hand::from_str(hand), regex_positive_number(bid))
})
.collect();
set.sort_unstable_by(|a, b| {
if a.0.kind.to_value() != b.0.kind.to_value() {
return a.0.kind.to_value().cmp(&b.0.kind.to_value());
}
for (i, card) in a.0.cards.iter().enumerate() {
if b.0.cards[i].to_value() != card.to_value() {
return card.to_value().cmp(&b.0.cards[i].to_value());
}
}
Ordering::Equal
});
set.iter()
.enumerate()
.map(|(i, (hand, bid))| (i as u32 + 1) * bid)
.sum()
}
#[derive(Debug, Eq, Hash, PartialEq, Copy, Clone)]
pub enum Card {
CardA,
CardK,
CardQ,
CardJ,
CardT,
Card9,
Card8,
Card7,
Card6,
Card5,
Card4,
Card3,
Card2,
}
impl Card {
pub fn from_char(c: char) -> Card {
match c {
'A' => Card::CardA,
'K' => Card::CardK,
'Q' => Card::CardQ,
'J' => Card::CardJ,
'T' => Card::CardT,
'9' => Card::Card9,
'8' => Card::Card8,
'7' => Card::Card7,
'6' => Card::Card6,
'5' => Card::Card5,
'4' => Card::Card4,
'3' => Card::Card3,
'2' => Card::Card2,
_ => panic!(),
}
}
pub fn to_value(self) -> u32 {
match self {
Card::CardA => 13,
Card::CardK => 12,
Card::CardQ => 11,
Card::CardT => 9,
Card::Card9 => 8,
Card::Card8 => 7,
Card::Card7 => 6,
Card::Card6 => 5,
Card::Card5 => 4,
Card::Card4 => 3,
Card::Card3 => 2,
Card::Card2 => 1,
Card::CardJ => 0,
}
}
}
use std::collections::HashMap;
use super::card::Card;
#[derive(Debug)]
pub struct Hand {
pub kind: HandType,
pub cards: Vec<Card>,
}
#[derive(Debug, Copy, Clone)]
pub enum HandType {
FiveOfAKind,
FourOfAKind,
FullHouse,
ThreeOfAKind,
TwoPair,
OnePair,
HighCard,
}
impl Hand {
pub fn from_str(input: &str) -> Hand {
let cards = input.chars().map(|c| Card::from_char(c)).collect();
Hand {
kind: HandType::from_cards(&cards),
cards,
}
}
}
impl HandType {
pub fn from_cards(cards: &Vec<Card>) -> HandType {
let mut map: HashMap<Card, u32> = HashMap::new();
let mut joker_count = 0u32;
for card in cards {
if *card == Card::CardJ {
joker_count += 1;
} else {
let count = map.get(&card).copied().unwrap_or(0);
map.insert(*card, count + 1);
}
}
let mut card_counts = map
.iter()
.map(|(card, amount)| *amount)
.collect::<Vec<u32>>();
card_counts.sort_unstable();
card_counts.reverse();
let max = card_counts.get(0).unwrap_or(&0) + joker_count;
let second = card_counts.get(1).unwrap_or(&0);
match (max, second) {
(5, _) => HandType::FiveOfAKind,
(4, _) => HandType::FourOfAKind,
(3, 2) => HandType::FullHouse,
(3, _) => HandType::ThreeOfAKind,
(2, 2) => HandType::TwoPair,
(2, _) => HandType::OnePair,
_ => HandType::HighCard,
}
}
pub fn to_value(self) -> u32 {
match self {
HandType::FiveOfAKind => 7,
HandType::FourOfAKind => 6,
HandType::FullHouse => 5,
HandType::ThreeOfAKind => 4,
HandType::TwoPair => 3,
HandType::OnePair => 2,
HandType::HighCard => 1,
}
}
}
use std::cmp::Ordering;
use crate::util::*;
mod card;
mod hand;
use hand::Hand;
pub fn solve_from_str(input: &str) -> u32 {
let mut set: Vec<(Hand, u32)> = input
.lines()
.map(|line| {
let mut data = line.split(" ");
let hand = data.next().unwrap();
let bid = data.next().unwrap();
(Hand::from_str(hand), regex_positive_number(bid))
})
.collect();
set.sort_unstable_by(|a, b| {
if a.0.kind.to_value() != b.0.kind.to_value() {
return a.0.kind.to_value().cmp(&b.0.kind.to_value());
}
for (i, card) in a.0.cards.iter().enumerate() {
if b.0.cards[i].to_value() != card.to_value() {
return card.to_value().cmp(&b.0.cards[i].to_value());
}
}
Ordering::Equal
});
set.iter()
.enumerate()
.map(|(i, (hand, bid))| (i as u32 + 1) * bid)
.sum()
}
......@@ -10,6 +10,8 @@ mod day_5_1;
mod day_5_2;
mod day_6_1;
mod day_6_2;
mod day_7_1;
mod day_7_2;
mod util;
......@@ -18,7 +20,7 @@ use std::fs;
fn main() {
let input = fs::read_to_string("input").expect("Could not read input!");
let solution = day_6_2::solve_from_str(input.as_str());
let solution = day_7_2::solve_from_str(input.trim_end());
println!("Solution: {}", solution);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment