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.
123 lines
2.3 KiB
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;
|
||
|
}
|