Day 7 complete.

This commit is contained in:
Drew Galbraith 2023-12-07 10:38:01 -08:00
parent 0d4261c666
commit 6be7d82bdb
3 changed files with 1197 additions and 0 deletions

1000
input/day07.txt Normal file

File diff suppressed because it is too large Load Diff

194
src/day7.rs Normal file
View File

@ -0,0 +1,194 @@
use std::cmp::Ordering;
use std::collections::HashMap;
use std::io;
use std::iter::zip;
fn get_rank(hand: &String) -> u32 {
let mut map: HashMap<char, u32> = HashMap::new();
for c in hand.chars() {
if map.contains_key(&c) {
*map.get_mut(&c).unwrap() += 1;
} else {
map.insert(c, 1);
}
}
// Five of a kind
for (_, v) in &map {
if *v == 5 {
return 7;
}
}
// Four of a kind
for (_, v) in &map {
if *v == 4 {
return 6;
}
}
// Full house & Three of a kind
for (_, v) in &map {
if *v == 3 {
for (_, v2) in &map {
if *v2 == 2 {
// Full House
return 5;
}
}
// Three of a kind
return 4;
}
}
// Pairs
let mut pair_cnt = 0;
for (_, v) in &map {
if *v == 2 {
pair_cnt += 1;
}
}
match pair_cnt {
2 => 3,
1 => 2,
_ => 1,
}
}
fn get_rank_wild(hand: &String) -> u32 {
let mut map: HashMap<char, u32> = HashMap::new();
for c in hand.chars() {
if map.contains_key(&c) {
*map.get_mut(&c).unwrap() += 1;
} else {
map.insert(c, 1);
}
}
let wild = match map.get(&'J') {
Some(v) => *v,
None => 0,
};
map.remove(&'J');
if wild == 5 {
return 7;
}
// Five of a kind
for (_, v) in &map {
if *v + wild == 5 {
return 7;
}
}
// Four of a kind
for (_, v) in &map {
if *v + wild == 4 {
return 6;
}
}
// Natural Full house & Three of a kind
for (_, v) in &map {
if *v == 3 {
for (_, v2) in &map {
if *v2 == 2 {
// Full House
return 5;
}
}
// Three of a kind
return 4;
}
}
// Pairs
let mut pair_cnt = 0;
for (_, v) in &map {
if *v == 2 {
pair_cnt += 1;
}
}
match pair_cnt {
2 => match wild {
1 => 5, // Full House
_ => 3, // Two Pair
},
1 => match wild {
1 => 4, // Three of a kind.
_ => 2, // One Pair.
},
_ => match wild {
2 => 4, // Three of a kind.
1 => 2, // Pair.
_ => 1, // High card.
},
}
}
fn cmp_card(first: &char, second: &char, jacks_wild: bool) -> Ordering {
let order = if jacks_wild {
"J23456789TQKA"
} else {
"23456789TJQKA"
};
order
.find(*first)
.unwrap()
.cmp(&order.find(*second).unwrap())
}
fn sort_hands_internal(first: &String, second: &String, jacks_wild: bool) -> Ordering {
if jacks_wild {
match get_rank_wild(&first).cmp(&get_rank_wild(&second)) {
Ordering::Less => return Ordering::Less,
Ordering::Greater => return Ordering::Greater,
_ => {}
}
} else {
match get_rank(&first).cmp(&get_rank(&second)) {
Ordering::Less => return Ordering::Less,
Ordering::Greater => return Ordering::Greater,
_ => {}
}
}
for (f, s) in zip(first.chars(), second.chars()) {
match cmp_card(&f, &s, jacks_wild) {
Ordering::Less => return Ordering::Less,
Ordering::Greater => return Ordering::Greater,
_ => {}
}
}
Ordering::Equal
}
fn sort_hands(first: &(String, u64), second: &(String, u64), jacks_wild: bool) -> Ordering {
sort_hands_internal(&first.0, &second.0, jacks_wild)
}
pub fn get_total_winnings(jacks_wild: bool) -> u64 {
let mut buffer = String::new();
let mut hands: Vec<(String, u64)> = Vec::new();
while io::stdin().read_line(&mut buffer).unwrap() > 0 {
let mut parts = buffer.trim().split(' ');
let hand = parts.next().unwrap();
let bidstr = parts.next().unwrap();
let bid: u64 = bidstr.parse().expect("Couldn't parse bid");
hands.push((hand.to_string(), bid));
buffer = String::new();
}
hands.sort_by(|a, b| sort_hands(a, b, jacks_wild));
let mut score = 0;
for i in 0..hands.len() {
score += (i as u64 + 1) * hands[i].1;
}
score
}

View File

@ -6,6 +6,7 @@ mod day3;
mod day4;
mod day5;
mod day6;
mod day7;
fn main() {
let args: Vec<String> = env::args().collect();
@ -26,6 +27,8 @@ fn main() {
"day5b" => println!("Min: {}", day5::get_lowest_location(true)),
"day6a" => println!("Product: {}", day6::get_winning_combos()),
"day6b" => println!("Product: {}", day6::get_single_winning_combo()),
"day7a" => println!("Score: {}", day7::get_total_winnings(false)),
"day7b" => println!("Score: {}", day7::get_total_winnings(true)),
_ => println!("Unrecognized day: {}", args[1]),
}
}