From: alex Date: Thu, 7 Dec 2023 10:39:15 +0000 (+0100) Subject: Day07 - part 1 X-Git-Url: https://aoc.elinar.fr/?a=commitdiff_plain;h=5615d1c8a343a73ff9c92ccb4e6ad8753d900ed1;p=aoc_2023 Day07 - part 1 --- diff --git a/src/day07.rs b/src/day07.rs new file mode 100644 index 0000000..9e456d1 --- /dev/null +++ b/src/day07.rs @@ -0,0 +1,165 @@ +use std::io::Read; +use std::error::Error; +use std::fs::File; + +use std::collections::HashMap; +use std::cmp::Ordering; + +pub fn run(input_file: &str) -> Result<(), Box> { + let mut f = File::open(input_file)?; + let mut input = String::new(); + f.read_to_string(&mut input)?; + + let res = run_part1(&input)?; + println!("{res}"); + + let res = run_part2(&input)?; + println!("{res}"); + + Ok(()) +} + +static CARDS: &str = "123456789TJQKA"; + +#[derive(Debug, PartialEq, PartialOrd)] +enum HandType { + HighCard, + OnePair, + TwoPair, + ThreeOfAKind, + FullHouse, + FourOfAKind, + FiveOfAKind, +} + +#[derive(Debug, PartialEq)] +struct Hand { + cards: [char ; 5], + bid: u32, + hand_type: HandType, +} + +// TODO implémenter l'ordre +impl Hand { + pub fn new(cards: &str, bid: u32) -> Self { + let mut hand_cards: [ char ; 5 ] = [ '\0' ; 5]; + cards.chars().enumerate() + .for_each(|(i,c)| hand_cards[i] = c); + Self { + cards: hand_cards, + bid, + hand_type: Self::find_type(hand_cards), + } + + } + + pub fn find_type(cards: [char; 5]) -> HandType { + let mut map = CARDS.chars() + .map(|c| (c, 0_u32)) + .collect::>(); + cards.into_iter() + .for_each(|c| { map.insert(c, map.get(&c).unwrap() + 1); }); + + // on ne conserve que le type de cartes de la main et leur nombre + // d'occurrence + let occurrence = map.into_iter() + .filter(|(_,v)| v > &0) + .map(|(_,v)| v) + .collect::>(); + + match occurrence.len() { + 5 => HandType::HighCard, + 4 => HandType::OnePair, + 3 => { + // TwoPair or ThreeOfAKind + if occurrence.contains(&3) { + return HandType::ThreeOfAKind; + } + HandType::TwoPair + }, + 2 => { + // FullHouse or FourOfAKind + if occurrence.contains(&4) { + return HandType::FourOfAKind; + } + HandType::FullHouse + }, + 1 => HandType::FiveOfAKind, + _ => unreachable!(), + } + } +} + +impl PartialOrd for Hand { + fn partial_cmp(&self, other: &Self) -> Option { + if self.hand_type == other.hand_type { + // comparer les cartes + // pour cela on compare les index dans la liste des cartes CARDS + let mut i = 0; + while self.cards[i] == other.cards[i] { + i += 1; + } + let self_pos = CARDS.chars().position(|c| c == self.cards[i]).unwrap(); + let other_pos = CARDS.chars().position(|c| c == other.cards[i]).unwrap(); + return Some(self_pos.cmp(&other_pos)); + } + self.hand_type.partial_cmp(&other.hand_type) + } +} + +fn run_part1(input: &str) -> Result> { + println!("Running day07 - part 1"); + + let mut hands: Vec = Vec::new(); + + input.lines() + .filter(|l| !l.is_empty()) + .for_each(|l| { + let (cards, bid) = l.split_once(' ').unwrap(); + hands.push(Hand::new(cards, bid.parse().unwrap())); + }); + + hands.sort_by(|a, b| { + a.partial_cmp(&b).unwrap() + }); + + let res = hands.iter().enumerate() + .map(|(i, h)| { + let i: u32 = i as u32; + h.bid * (i + 1) + }) + .sum(); + + Ok(res) +} + +fn run_part2(input: &str) -> Result> { + println!("Running day07 - part 2"); + let res = 0; + Ok(res) +} + +#[cfg(test)] +mod tests { + use super::*; + + static TEXT_INPUT: &str = "\ +32T3K 765 +T55J5 684 +KK677 28 +KTJJT 220 +QQQJA 483 +"; + + #[test] + fn day07_part1() { + let res = run_part1(TEXT_INPUT); + assert_eq!(6440, res.unwrap()); + } + + #[test] + fn day07_part2() { + let res = run_part2(TEXT_INPUT); + assert_eq!(0, res.unwrap()); + } +} diff --git a/src/main.rs b/src/main.rs index ae0262c..d4ac3b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ pub mod day03; pub mod day04; pub mod day05; pub mod day06; +pub mod day07; fn main() { let args: Vec = env::args().collect(); @@ -33,6 +34,7 @@ fn run(day: &str, input_file: &str) -> Result<(), Box> { "day04" => day04::run(input_file)?, "day05" => day05::run(input_file)?, "day06" => day06::run(input_file)?, + "day07" => day07::run(input_file)?, _ => return Err(format!("unknown day \"{day}\"").into()), } Ok(())