Metadata
-
Date
-
Tagged
-
Part of series
- Advent of Code 2023 Day 1
- Advent of Code 2023 Day 2
- Advent of Code 2023 Day 3
- Advent of Code 2023 Day 4
- Advent of Code 2023 Day 5
- Advent of Code 2023 Day 6
- Advent of Code 2023 Day 7
- Advent of Code 2023 Day 8
- Advent of Code 2023 Day 9
- Advent of Code 2023 Day 10
- Advent of Code 2023 Day 11
- Advent of Code 2023 Day 12
- Advent of Code 2023 Day 13
- Advent of Code 2023 Day 14
- Advent of Code 2023 Day 15
- Advent of Code 2023 Day 16
- Advent of Code 2023 Day 17
- Advent of Code 2023 Day 18
- Advent of Code 2023 Day 19
- Advent of Code 2023 Day 20
- Advent of Code 2023 Day 21
- Advent of Code 2023 Day 22
- Advent of Code 2023 Day 23
- Advent of Code 2023 Day 25
-
Older post
-
Newer post
Advent of Code 2023 Day 7
Day 7: Camel Cards
https://adventofcode.com/2023/day/7
You arrive at Desert Island, an elf is there waiting to take you to your destination. A trip by camel!
The elf wants to play a game while travelling appropriately named camel cards.
It’s similar to poker, but a bit simpler, because that makes it easier to play while riding a camel.
You get a list of hands of cards. You need to order those hands based on the strength of each hand.
A hand consists of five cards.
The cards are all one of:
- A
- K
- Q
- J
- T
- 9
- 8
- 7
- 6
- 5
- 4
- 3
- 2
Each hand of 5 cards has a type of:
-
Five of a kind
All cards have the same label.
eg: AAAAA
-
Four of a kind
Four cards have the same label.
eg: AA8AA
-
Full House
Three cards have the same label, the two other cards have the same label.
eg: 23332
-
Three of a kind
Three cards have the same label.
eg: TTT98
-
Two pair
Two cards have the same label.
Two other cards also have the same label.eg: 23432
-
One pair
Two cards have the same label.
eg: A23A4
-
High card
All card labels are different.
eg: 23456
Each hand has a bid associated with it, it number.
If two hands have the same type, their order is determined by looking which hand has a stronger card first.
eg: hand1 is 33332
, and hand2 is 2AAAA
.
Both hands have the same type (four of a kind).
33332
is stronger because the first card is stronger.
If the first card is identical, the second card is compared, and so forth until one hand is stronger (two hands being completely identical never happens in the input).
Today’s input is a list of hands with their corresponding bids.
An example input looks like this:
Part 1
Order the hands in the input.
The weakest hand gets rank 1, the next one rank 2, and so on.
For each hand, multiply its rank by its bid to determine the hands winnings.
The question asks you determine the total winnings for all hands.
Option 1: lots of functions
Starting with some pseudo/skeleton-code again:
Helpers
I chose to represent the value of a single card as a number, ordered like the question specifies.
To score a single hand, I used a list of 2 sorted numbers:
- The amount of cards that appear the most often
- The amount of cards that appears the 2nd most often
Some examples:
[3, 2]
represents a hand with 3 cards of equal value, and 2 cards with a different identical value[3, 1]
represents a hand with 3 cards of equal value, and 1 card with a different value. (not represented is the last card that also has a different value)[5, 0]
represents a hand with 5 cards of equal value.[2, 2]
represents a hand with 2 pairs.
And finally, using those building blocks, a way to compare 2 hands and determine which one is stronger.
Code
Option 2: structures
I like to put data in neat structures. Rust structs are great.
Because the input is a string, I store references to that string in those structures.
Those need a lifetime, and that’s that 'a
stuff you see all over the place.
I’m not going deep into what that means in this post, but in a nutshell it means “this string is valid while this structure exists”.
By Implementing Ord
we tell Rust those structures can be ordered.
Code
Option 3: getting shifty
I didn’t implement this but you can also represent a hand as a single number.
4 bits represent each card. The starting bits represent the type of hand (from five of a kind to high card).
This would work by determining the value of each card, and shifting bits to represent that value onto a number. Then, shift a value representing the type of the hand onto the front of the same number.
Sorting those numbers would apply the sorting logic described where it sorts based on the type of hand first, and on the individual cards next.
Part 2
There is a second way to play this game.
The J
cards are now jokers, wildcards that can act like any other card.
You can use these jokers in a hand to make a stronger type of hand.
To balance this, the J
card is now the weakest card.
This causes a few adjustments to the code from part1.
Helpers
The function to determine the value of a single card:
The function to score a hand:
The function to compare 2 hands:
The result is nearly identical code to part one. It would be trivial to implement a boolean flag and combine these 2 version into one, but I had somewhere to go and copy-pasting was faster.