advent_of_code/2023/day7/rust/src/part_two.rs

139 lines
3.1 KiB
Rust

use std::fs::File;
use std::io::{self, prelude::*, BufReader};
use std::collections::HashMap;
use regex::Regex;
fn get_number(line: &str) -> u32 {
let re = Regex::new(r"\d+").unwrap();
let num: u32 = re.find(line).unwrap().as_str().parse().unwrap();
return num;
}
enum Hands{
HighCard=0,
OnePair,
TwoPair,
ThreeOfAKind,
FullHouse,
FourOfAKind,
FiveOfAKind,
}
fn get_hand(line: &str) -> Hands {
let mut cards = HashMap::new();
for ch in line.chars().clone()
{
cards.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);
}
let jays;
if cards.contains_key(&'J')
{
jays = cards.remove(&'J').unwrap();
}
else
{
jays = 0;
}
let mut my_vec = cards.into_values().collect::<Vec<_>>();
if my_vec.is_empty()
{
return Hands::FiveOfAKind;
}
my_vec.sort();
let max = my_vec[my_vec.len()-1]+jays;
if max == 5
{
return Hands::FiveOfAKind;
}
if max == 4
{
return Hands::FourOfAKind;
}
let next_max = my_vec[my_vec.len()-2];
if max == 3
{
if next_max == 2
{
return Hands::FullHouse;
}
return Hands::ThreeOfAKind;
}
if max == 2
{
if next_max == 2
{
return Hands::TwoPair;
}
return Hands::OnePair;
}
return Hands::HighCard;
}
fn hand2num(line: &str) -> u32
{
let num = line.chars().map( |m| match m {
'A' => 14,
'K' => 13,
'Q' => 12,
'J' => 1,
'T' => 10,
_ => m.to_digit(10).unwrap()
}).collect::<Vec<u32>>();
let mut sum = 0;
for i in 0..5
{
sum += num[i]*16_u32.pow((4-i).try_into().unwrap());
}
return sum;
}
fn get_ranking(num: u32, bid: u32, ranking: &mut [Vec<(u32, u32)>; 7], hand: usize)
{
let mut index = 0;
for i in &ranking[hand]
{
if i.0 > num { break;}
index += 1;
}
ranking[hand].insert(index, (num, bid));
}
fn process_line(line: String, ranking: &mut [Vec<(u32, u32)>; 7]) {
let parts = line.split(&[' ']).collect::<Vec<&str>>();
let bid = get_number(parts[1]);
let hand = get_hand(parts[0]);
let hand_num = hand2num(parts[0]);
get_ranking(hand_num, bid, ranking, hand as usize);
}
fn main() -> io::Result<()> {
let mut sum: u32 = 0;
let file = File::open("../input.txt")?;
let mut ranks: [Vec<(u32, u32)>; 7] = [vec![],vec![],vec![],vec![],vec![],vec![],vec![]];
let reader = BufReader::new(file);
for line in reader.lines() {
process_line(line?, &mut ranks);
}
let mut incrementer = 1;
println!("Listing Rankings");
for rank in &ranks {
for i in rank {
sum += incrementer*i.1;
incrementer += 1;
}
}
println!("{}", ranks[0].len());
println!("{}", ranks[1].len());
println!("{}", ranks[2].len());
println!("{}", ranks[3].len());
println!("{}", ranks[4].len());
println!("{}", ranks[5].len());
println!("{}", ranks[6].len());
println!("{}", sum);
Ok(())
}