Skip to content

Commit

Permalink
Day 7, Part 2
Browse files Browse the repository at this point in the history
Copy paste ftw :)
  • Loading branch information
michaeladler committed Dec 7, 2023
1 parent 02973a5 commit 647a77f
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The solutions were tested on different processors using [hyperfine](https://gith
| 4 | 368 µs | 679 µs |
| 5 | 1.4 s | 2.6 s |
| 6 | 273 µs | 472 µs |
| 7 | 4.4 ms | |

## 🙏 Acknowledgments and Resources

Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ days = {
'day04': [ 'src/day04/solve.c', 'src/day04/sort.c' ],
'day05': [ 'src/day05/solve.c' ],
'day06': [ 'src/day06/solve.c' ],
'day07': [ 'src/day07/solve.c', 'src/day07/hand.c' ],
'day07': [ 'src/day07/solve.c', 'src/day07/part1.c', 'src/day07/part2.c' ],
# XXX: marker
}

Expand Down
10 changes: 6 additions & 4 deletions puzzle/day07.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ Find the rank of every hand in your set. What are the total winnings?

Your puzzle answer was 253910319.

The first half of this puzzle is complete! It provides one gold star: *

--- Part Two ---

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.
Expand All @@ -85,9 +83,13 @@ With the new joker rule, the total winnings in this example are 5905.

Using the new joker rule, find the rank of every hand in your set. What are the new total winnings?

Answer:
Your puzzle answer was 254083736.

Both parts of this puzzle are complete! They provide two gold stars: **

At this point, you should return to your Advent calendar and try another puzzle.

Although it hasn't changed, you can still get your puzzle input.
If you still want to see it, you can get your puzzle input.

You can also [Shareon Twitter Mastodon] this puzzle.

13 changes: 8 additions & 5 deletions src/day07/hand.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* Author: Michael Adler
*
* Copyright: 2023 Michael Adler
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "aoc/types.h"
Expand All @@ -19,8 +27,3 @@ typedef enum {
FOUR_KIND,
FIVE_KIND
} hand_strength;

hand_strength Hand_compute_strength(Hand h);

// forward decl
void Hand_tim_sort(Hand *dst, const size_t size);
9 changes: 8 additions & 1 deletion src/day07/hand.c → src/day07/part1.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/*
* Author: Michael Adler
*
* Copyright: 2023 Michael Adler
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
Expand Down Expand Up @@ -70,7 +78,6 @@ hand_strength Hand_compute_strength(Hand h) {

// return GT if x > y
static inline int Hand_compare(Hand x, Hand y) {

hand_strength x_strength = Hand_compute_strength(x);
hand_strength y_strength = Hand_compute_strength(y);

Expand Down
15 changes: 15 additions & 0 deletions src/day07/part1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Author: Michael Adler
*
* Copyright: 2023 Michael Adler
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "hand.h"

hand_strength Hand_compute_strength(Hand h);

void Hand_tim_sort(Hand *dst, const size_t size);
85 changes: 85 additions & 0 deletions src/day07/part2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Author: Michael Adler
*
* Copyright: 2023 Michael Adler
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>

#include "aoc/macros.h"
#include "hand.h"
#include "part1.h"

#define LT -1
#define EQ 0
#define GT 1

// The higher the value the stronger the card.
// Strength range is [0, 12].
static inline int card_strength_part2(char c) {
// J -> 0, 2 -> 1, ..., 9 -> 8, rest is the same as in card_strength
switch (c) {
case 'T': return 9;
case 'J': return 0;
case 'Q': return 10;
case 'K': return 11;
case 'A': return 12;
default: assert(c >= '2' && c <= '9'); return c - '1';
}
}

static inline int break_tie_part2(Hand x, Hand y) {
for (int i = 0; i < CARDS_PER_HAND; i++) {
char lhs = x.cards[i], rhs = y.cards[i];
if (lhs != rhs) {
return card_strength_part2(lhs) < card_strength_part2(rhs) ? LT
: GT;
}
}
return EQ;
}

hand_strength Hand_compute_strength_part2(Hand h) {
// all possible values a Joker can take on
static char joker_values[] = {'A', 'K', 'Q', 'T', '9', '8',
'7', '6', '5', '4', '3', '2'};

int joker_idx[CARDS_PER_HAND];
int joker_count = 0;
for (int i = 0; i < CARDS_PER_HAND; i++) {
if (h.cards[i] == 'J') { joker_idx[joker_count++] = i; }
}
// for each joker, try possible values;
// note that it's always better to use the same value for a joker, so we
// don't have to bother trying different values for different jokers within
// the same hand
hand_strength max_strength = 0;
for (size_t i = 0; i < ARRAY_LENGTH(joker_values); i++) {
char value = joker_values[i];
// substitute joker within the hand
for (int j = 0; j < joker_count; j++) { h.cards[joker_idx[j]] = value; }
hand_strength strength = Hand_compute_strength(h);
if (strength > max_strength) { max_strength = strength; }
}
return max_strength;
}

// return GT if x > y
static inline int Hand_compare_part2(Hand x, Hand y) {
hand_strength x_strength = Hand_compute_strength_part2(x);
hand_strength y_strength = Hand_compute_strength_part2(y);

if (x_strength < y_strength) { return LT; }
if (x_strength > y_strength) { return GT; }
assert(x_strength == y_strength);
return break_tie_part2(x, y);
}

#define SORT_NAME Hand_part2
#define SORT_TYPE Hand
#define SORT_CMP(x, y) (Hand_compare_part2(x, y))
#include "sort.h"
15 changes: 15 additions & 0 deletions src/day07/part2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Author: Michael Adler
*
* Copyright: 2023 Michael Adler
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include "hand.h"

hand_strength Hand_compute_strength_part2(Hand h);

void Hand_part2_tim_sort(Hand *dst, const size_t size);
19 changes: 12 additions & 7 deletions src/day07/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
#include "solve.h"
#include "aoc/all.h"

#include "hand.h"

#define MAX_HANDS 1000
#include "part1.h"
#include "part2.h"

void solve(const char *buf, size_t buf_size, Solution *result) {
i64 part1 = 0, part2 = 0;
size_t pos = 0;

Hand hand[MAX_HANDS];
Hand hand[1000];
size_t hand_count = 0;

// parser
while (pos < buf_size) {
for (int i = 0; i < CARDS_PER_HAND; i++) {
hand[hand_count].cards[i] = buf[pos++];
Expand All @@ -29,15 +29,20 @@ void solve(const char *buf, size_t buf_size, Solution *result) {
pos++; // newline
}

// part 1
Hand_tim_sort(hand, hand_count); // weakest hand is first

for (size_t i = 0; i < hand_count; i++) {
log_debug("%.*s %d", 5, hand[i].cards, Hand_compute_strength(hand[i]));
// Each hand wins an amount equal to its bid multiplied by its rank
i64 rank = i + 1, bid = hand[i].bid;
part1 += rank * bid;
}

// part 2
Hand_part2_tim_sort(hand, hand_count);
for (size_t i = 0; i < hand_count; i++) {
i64 rank = i + 1, bid = hand[i].bid;
part2 += rank * bid;
}

aoc_itoa(part1, result->part1, 10);
aoc_itoa(part2, result->part2, 10);
}
Expand Down
4 changes: 2 additions & 2 deletions src/day07/solve_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ QQQJA 483\n";
Solution solution;
solve(buf, strlen(buf), &solution);
ASSERT_STR("6440", solution.part1);
ASSERT_STR("0", solution.part2);
ASSERT_STR("5905", solution.part2);
}

#ifdef HAVE_INPUTS
CTEST(day07, real) {
Solution solution;
solve_input("input/" DAY ".txt", &solution);
ASSERT_STR("253910319", solution.part1);
// ASSERT_STR("0", solution.part2);
ASSERT_STR("254083736", solution.part2);
}
#endif

Expand Down

0 comments on commit 647a77f

Please sign in to comment.