advent of code 2023 edition
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aoc_2023/day07/aoc.rs

123 lines
2.3 KiB

10 months ago
use std::iter::*;
use std::cmp::*;
use std::collections::HashMap;
use std::fs;
use std::env;
type Hand = [usize;5];
fn main() {
let card_value: HashMap<char, usize> = zip([ '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J','Q', 'K', 'A'], 0..13).collect();
println!("Hello, AoC day 7!");
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("wrong number of arguments!");
std::process::exit(1);
}
let file_path = &args[1];
// get time lineaswords and distance line as words
let binding = fs::read_to_string(file_path)
.expect("Should have been able to read the file");
let contents = binding.lines();
let mut hands: Vec<(Hand, u32)> = Vec::new();
for line in contents {
if !line.is_empty() {
hands.push(parse(line, &card_value));
}
}
hands.sort_unstable_by(|(ha, _), (hb, _)| hand_compare(*ha, *hb));
let mut sum = 0;
for (index, (_hand, bet)) in hands.iter().enumerate() {
let score = ((index as u32) + 1) * bet;
sum += score;
}
println!("total scores was: {}", sum);
}
fn parse(line: &str, dictionary: &HashMap<char, usize>) -> (Hand, u32) {
let (hand, value) = line.split_once(" ").expect("expected a line to have the format 'AAAAA ###'");
let mut m: [usize;5] = [0;5];
for (i, character) in hand.chars().enumerate() {
m[i] = *dictionary.get(&character).expect(&format!("expected a card in {}", line));
}
let val:u32 = value.parse().unwrap();
println!("{:?} for {}", m, val);
return (m, val);
}
fn rank(hand: Hand) -> u32 {
let mut a = [0; 13];
for letter in hand {
a[letter] += 1;
}
let mut fives = 0;
let mut fours = 0;
let mut threes = 0;
let mut twos = 0;
let mut _ones = 0;
for number in a {
match number {
5 => fives += 1,
4 => fours += 1,
3 => threes += 1,
2 => twos += 1,
1 => _ones += 1,
_ => ()
}
}
if fives > 0 {
return 6;
}
if fours > 0 {
return 5;
}
if threes == 1 && twos == 1 {
return 4;
}
if threes == 1 {
return 3;
}
if twos == 2 {
return 2;
}
if twos == 1 {
return 1;
}
return 0;
}
fn hand_compare(a: Hand, b: Hand) -> Ordering {
let bs_a = rank(a);
let bs_b = rank(b);
if bs_a > bs_b {
return Ordering::Greater;
} else if bs_a < bs_b {
return Ordering::Less;
}
if a > b {
return Ordering::Greater;
} else if a < b {
return Ordering::Less;
}
return Ordering::Equal;
}