Ok(())
}
-static CARDS: &str = "J123456789TQKA";
+static CARDS: &str = "123456789TJQKA";
+static CARDS_JOKERS: &str = "J123456789TQKA";
#[derive(Debug, PartialEq, PartialOrd)]
enum HandType {
cards: [char ; 5],
bid: u32,
hand_type: HandType,
+ with_jokers: bool,
}
impl Hand {
- pub fn new(cards: &str, bid: u32) -> Self {
+ pub fn new(cards: &str, bid: u32, with_jokers: bool) -> 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),
+ hand_type: Self::find_type(hand_cards, with_jokers),
+ with_jokers,
}
-
}
- pub fn find_type(cards: [char; 5]) -> HandType {
+ pub fn find_type(cards: [char; 5], with_jokers: bool) -> HandType {
let mut map: HashMap<_, u32> = CARDS.chars()
.map(|c| (c, 0_u32))
.collect();
// on ne conserve que le type de cartes de la main et leur nombre
// d'occurrence
- // attention: si 5 jokers, on les garde
- let mut occurrence = map.into_iter()
+ if with_jokers {
+ // on ne conserve que les cartes qui ne sont pas des jokers
+ // attention: si 5 jokers, on les garde
+ map = map.into_iter()
.filter(|(k,v)| (v > &0 && k != &'J') || (k == &'J' && v == &5))
+ .collect();
+ } else {
+ map = map.into_iter()
+ .filter(|(k,v)| v > &0)
+ .collect();
+ }
+
+ let mut occurrence = map.into_iter()
.map(|(_,v)| v)
.collect::<Vec<_>>();
- // trie des occurences par ordre décroissant
- occurrence.sort_by(|a, b| b.cmp(&a));
- // les J sont associées aux cartes ayant le plus d'occurrence
- // sauf si toutes les cartes sont des J
- if occurrence[0] < 5 {
- occurrence[0] += jokers;
+ if with_jokers {
+ // trie des occurences par ordre décroissant
+ occurrence.sort_by(|a, b| b.cmp(&a));
+
+ // les J sont associées aux cartes ayant le plus d'occurrence
+ // sauf si toutes les cartes sont des J
+ if occurrence[0] < 5 {
+ occurrence[0] += jokers;
+ }
}
match occurrence.len() {
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();
+ let cards = match self.with_jokers && other.with_jokers {
+ true => CARDS_JOKERS,
+ false => CARDS,
+ };
+ 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");
-
+fn solve(input: &str, with_jokers: bool) -> u32 {
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.push(Hand::new(cards, bid.parse().unwrap(), with_jokers));
});
hands.sort_by(|a, b| {
})
.sum();
+ res
+}
+
+fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running day07 - part 1");
+ let res = solve(input, false);
Ok(res)
}
fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
println!("Running day07 - part 2");
- run_part1(input)
+ let res = solve(input, true);
+ Ok(res)
}
#[cfg(test)]