149 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| 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(['J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', '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];
 | |
| 
 | |
| 	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_by(|(ha, _), (hb, _)| hand_compare(*ha, *hb));
 | |
| 
 | |
| 	println!("and now, the sorted:");
 | |
| 	for (hand, value) in hands.iter() {
 | |
| 		let ran = match rank(*hand) {
 | |
| 			6 => "five of a kind",
 | |
| 			5 => "four of a kind",
 | |
| 			4 => "full house",
 | |
| 			3 => "three of a kind",
 | |
| 			2 => "two pair",
 | |
| 			1 => "one pair",
 | |
| 			0 => "card high",
 | |
| 			_ => "mystery to us all"
 | |
| 		};
 | |
| 		println!("{:?}, which is a {}, for {}", hand, ran, value);
 | |
| 	}
 | |
| 
 | |
| 	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));
 | |
| 	}
 | |
| 
 | |
| 	return (m, value.parse().unwrap());	
 | |
| }
 | |
| 
 | |
| 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[1..] {
 | |
| 
 | |
| 		match number {
 | |
| 			5 => fives += 1,
 | |
| 			4 => fours += 1,
 | |
| 			3 => threes += 1,
 | |
| 			2 => twos += 1,
 | |
| 			1 => _ones += 1,
 | |
| 			_ => ()
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (fives > 0) || 
 | |
| 		((fours == 1) && (a[0] == 1)) ||
 | |
| 		((threes == 1) && (a[0] == 2)) ||
 | |
| 		((twos == 1) && (a[0] == 3)) ||
 | |
| 		(a[0] == 4) || 
 | |
| 		(a[0] == 5) {
 | |
| 		return 6;
 | |
| 	}
 | |
| 	if (fours > 0) ||
 | |
| 		((threes == 1) && (a[0] == 1)) ||
 | |
| 		((twos == 1) && (a[0] == 2)) ||
 | |
| 		(a[0] == 3) ||
 | |
| 		(a[0] == 4) {
 | |
| 		return 5;
 | |
| 	}
 | |
| 	if (threes == 1 && twos == 1) ||
 | |
| 		((twos == 2) && (a[0] == 1)) {
 | |
| 		return 4;
 | |
| 	}
 | |
| 	if (threes == 1) ||
 | |
| 		((twos == 1) && (a[0] == 1)) ||
 | |
| 		(a[0] == 2) {
 | |
| 		return 3;
 | |
| 	}
 | |
| 	if twos == 2 {
 | |
| 		return 2;
 | |
| 	}
 | |
| 	if (twos == 1) ||
 | |
| 		(a[0] == 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;
 | |
| } |