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 = 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 = 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) -> (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; }