Skip to content

Commit

Permalink
Solve day 7
Browse files Browse the repository at this point in the history
  • Loading branch information
ricohageman committed Dec 7, 2023
1 parent 9a10d5c commit 86aad75
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 8 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.

| Day | Part 1 | Part 2 |
| :---: | :---: | :---: |
| [Day 1](./src/bin/01.rs) | `86.3µs` | `1.1ms` |
| [Day 2](./src/bin/02.rs) | `47.1µs` | `61.1µs` |
| [Day 3](./src/bin/03.rs) | `608.6µs` | `581.3µs` |
| [Day 4](./src/bin/04.rs) | `280.9µs` | `294.7µs` |
| [Day 5](./src/bin/05.rs) | `22.4µs` | `94.4µs` |
| [Day 6](./src/bin/06.rs) | `515.0ns` | `423.0ns` |

**Total: 3.18ms**
| [Day 1](./src/bin/01.rs) | `86.2µs` | `1.0ms` |
| [Day 2](./src/bin/02.rs) | `48.9µs` | `63.0µs` |
| [Day 3](./src/bin/03.rs) | `615.7µs` | `605.0µs` |
| [Day 4](./src/bin/04.rs) | `277.2µs` | `281.7µs` |
| [Day 5](./src/bin/05.rs) | `23.1µs` | `93.9µs` |
| [Day 6](./src/bin/06.rs) | `392.0ns` | `333.0ns` |
| [Day 7](./src/bin/07.rs) | `360.4µs` | `372.4µs` |

**Total: 3.83ms**
<!--- benchmarking table --->

---
Expand Down
5 changes: 5 additions & 0 deletions data/examples/07.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483
187 changes: 187 additions & 0 deletions src/bin/07.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
use itertools::Itertools;
advent_of_code::solution!(7);

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum HandStrength {
FiveOfAKind,
FourOfAKind,
FullHouse,
ThreeOfAKind,
TwoPair,
OnePair,
HighCard,
}

type Hand = [usize; 5];

impl From<&Hand> for HandStrength {
fn from(hand: &Hand) -> Self {
let occurrence_of_cards = hand.iter().counts();

match occurrence_of_cards.len() {
1 => HandStrength::FiveOfAKind,
2 => match occurrence_of_cards.values().next().unwrap() {
1 | 4 => HandStrength::FourOfAKind,
2 | 3 => HandStrength::FullHouse,
_ => panic!(),
},
3 => match occurrence_of_cards.values().max().unwrap() {
3 => HandStrength::ThreeOfAKind,
2 => HandStrength::TwoPair,
_ => panic!(),
},
4 => HandStrength::OnePair,
5 => HandStrength::HighCard,
_ => panic!(),
}
}
}

pub fn part_one(input: &str) -> Option<usize> {
let mut number_of_lines = 0;

Some(
input
.lines()
.filter_map(|line| line.split_once(' '))
.map(|(hand, bid)| (hand, bid.parse::<usize>().unwrap()))
.map(|(hand, bid)| {
let hand: Hand = hand
.chars()
.map(|char| match char {
'A' => 1,
'K' => 2,
'Q' => 3,
'J' => 4,
'T' => 5,
'9' => 6,
'8' => 7,
'7' => 8,
'6' => 9,
'5' => 10,
'4' => 11,
'3' => 12,
'2' => 13,
_ => panic!(),
})
.collect::<Vec<_>>()
.try_into()
.unwrap();

let strength = HandStrength::from(&hand);

number_of_lines += 1;

(hand, strength, bid)
})
.sorted_by_key(|(hand, strength, _)| (*strength, *hand))
.enumerate()
.map(|(index, (_, _, bid))| (number_of_lines - index) * bid)
.sum(),
)
}

pub fn part_two(input: &str) -> Option<usize> {
let mut number_of_lines = 0;

Some(
input
.lines()
.filter_map(|line| line.split_once(' '))
.map(|(hand, bid)| (hand, bid.parse::<usize>().unwrap()))
.map(|(hand, bid)| {
number_of_lines += 1;

let hand: Hand = hand
.chars()
.map(|char| match char {
'A' => 1,
'K' => 2,
'Q' => 3,
'T' => 4,
'9' => 5,
'8' => 6,
'7' => 7,
'6' => 8,
'5' => 9,
'4' => 10,
'3' => 11,
'2' => 12,
'J' => 13,
_ => panic!(),
})
.collect::<Vec<_>>()
.try_into()
.unwrap();

let number_of_jokers: usize = hand.iter().filter(|value| **value == 13).count();

let strength = match HandStrength::from(&hand) {
HandStrength::FiveOfAKind => match number_of_jokers {
0 => HandStrength::FiveOfAKind,
5 => HandStrength::FiveOfAKind,
_ => panic!(),
},
HandStrength::FourOfAKind => match number_of_jokers {
0 => HandStrength::FourOfAKind,
1 => HandStrength::FiveOfAKind,
4 => HandStrength::FiveOfAKind,
_ => panic!(),
},
HandStrength::FullHouse => match number_of_jokers {
0 => HandStrength::FullHouse,
2 => HandStrength::FiveOfAKind,
3 => HandStrength::FiveOfAKind,
_ => panic!(),
},
HandStrength::ThreeOfAKind => match number_of_jokers {
0 => HandStrength::ThreeOfAKind,
1 => HandStrength::FourOfAKind,
2 => HandStrength::FiveOfAKind,
3 => HandStrength::FourOfAKind,
_ => panic!(),
},
HandStrength::TwoPair => match number_of_jokers {
0 => HandStrength::TwoPair,
1 => HandStrength::FullHouse,
2 => HandStrength::FourOfAKind,
_ => panic!(),
},
HandStrength::OnePair => match number_of_jokers {
0 => HandStrength::OnePair,
1 => HandStrength::ThreeOfAKind,
2 => HandStrength::ThreeOfAKind,
_ => panic!(),
},
HandStrength::HighCard => match number_of_jokers {
0 => HandStrength::HighCard,
1 => HandStrength::OnePair,
_ => panic!(),
},
};

(hand, strength, bid)
})
.sorted_by_key(|(hand, strength, _)| (*strength, *hand))
.enumerate()
.map(|(index, (_, _, bid))| (number_of_lines - index) * bid)
.sum(),
)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(6440));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(5905));
}
}

0 comments on commit 86aad75

Please sign in to comment.