Day 7 - Discoded/adventofcode GitHub Wiki

Day 7

In Camel Cards, you get a list of hands, and your goal is to order them based on the strength of each hand. A hand consists of five cards labeled one of A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, or 2. The relative strength of each card follows this order, where A is the highest and 2 is the lowest.

To play Camel Cards, you are given a list of hands and their corresponding bid (your puzzle input)

Find the rank of every hand in your set. What are the total winnings?

Putting the hands in order of strength

There are 7 types of cards from strongest to weakest:

  • Five of a kind
  • Four of a kind
  • Full house
  • Three of a kind
  • Two pair
  • One pair
  • High card

Types of Cards

Type Definition
Five of a kind Where all five cards have the same label
Four of a kind Where four cards have the same label and one card has a different label
Full house Where three cards have the same label, and the remaining two cards share a different label.
Three of a kind Where three cards have the same label, and the remaining two cards are each different from any other card in the hand
Two pair Where two cards share one label, two other cards share a second label, and the remaining card has a third label
One pair Where two cards share one label, and the other three cards have a different label from the pair and each other
High card Where all cards' labels are distinct

Problem Solving

Given 5 cards, we have to check each invidual card

Example hand: 32T3K

Compare:
    3 and 2 -> dif
    3 and T -> dif
    3 and 3 -> same
    3 and K -> dif
        2 and T -> dif
        2 and 3 -> dif
        2 and K -> dif
            T and 3 -> dif
            T and K -> dif
                3 and K -> dif
    Hand is One pair

We then have a pattern:

Let n be the number of cards and i be the ith card:
Check
i and i + 2, i and i + 3, ..., i and i + 5
i + 2 and i +3, ..., i + 2 and i + 5

$$ \text{We check a total of } \frac{n^2 + n}{2} \text{ times} $$

We first find the pairs in the hand:

def find_pair(the_hand: str):
    if the_hand == "":
        return []
    pairs = []
    card0 = the_hand[0]
    for card in the_hand[1:]:
        if(card == card0):
            pairs.append(card + card)
        
    return pairs + find_pair(the_hand[1:])

find_pair() will reuse the same card for pair so if there are 5 cards of the kind, it will produce 10 "pairs.

Same cards "Pairs" Type
1 0 High Card
2 1 One pair
1 and 1 2 Two pair
3 3 Three of a kind
3 and 2 4 Full House
4 6 Four of a kind
5 10 Five of a kind

Two pair and Full house are the only different types.

A two pair will have 2 sets of identical cards to one another but separate from each set. Example: 22334. Therefore a Two Pair will give us 2 "Pairs"

A full house hand will have 3 of the same cards and 2 that are the same with each other but different from the other 3. Example: 23332. Therefore a Full House will give us 4 "Pairs".

Let pairs be the list given from find_pair()

switch len(pairs):
    case 0: High card
    case 1: One Pair
    case 2: Two Pair
    case 3: Three of a kind
    case 4: Full house
    case 6: Four of a kind
    case 10: Five of a kind

We now know the type of card each hand is. We simply now need to order them. From strongest to weakest the cards are A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2, Assuming the hands are grouped by their type, i.e. All high cards are in an unordered list:

Comparing one high_card to another we have to take its first character, and compare them. If they're equal, we move to the next card in the hand.

We first have to assign values to the different cards. To do this I use a map where:

'2' = 0, 
'3' = 1, 
'4' = 2 
all the way to 'A' = 12
compare(hand_0, hand_1):
    for (int i = 0; i < 5; i++) {

        if (map(hand_0[i]) - map(hand_1[i])) != 0:

            return map(hand_0[i]) - map(hand_1[i])
        
    } 

After sorting each list, we know create a new list where we add each element of each list starting from the weakest to the strongest hand. high_cards | one pair | ... | five_of_a_kind |

Now we iterate through them:

Let ranked_list be the list of tuples where a tuple is (hand, bid)
and total_winnings a sum of each bid*rank

for i, hand in enumerate(ranked_list):

    total_winnings = total_winnings + hand[1]*(i+1)

Day 7 Part 2

To make things a little more interesting, the Elf introduces one additional rule. Now, J cards are jokers - wildcards that can act like whatever card would make the hand the strongest type possible.

To balance this, J cards are now the weakest individual cards, weaker even than 2. The other cards stay in the same order: A, K, Q, T, 9, 8, 7, 6, 5, 4, 3, 2, J.

Now that J's are wildcards, lets look at all the possible iterations of J

2 J:
JABCD High card
JAABC 
JAABB
JAAAB

2 J:
JJABC
JJAAB
JJAAA

3 J:
JJJAB
JJJAA

4 J:
JJJJA

5 J:
JJJJJ