--- /dev/null
+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<dyn Error>> {
+ 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::<HashMap<_,_>>();
+ 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::<Vec<_>>();
+
+ 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<Ordering> {
+ 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<u32, Box<dyn Error>> {
+ println!("Running day07 - part 1");
+
+ let mut hands: Vec<Hand> = 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<u32, Box<dyn Error>> {
+ 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());
+ }
+}