aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/src/day7/solve.gleam
diff options
context:
space:
mode:
authorJ.J <thechairman@thechairman.info>2023-12-07 08:55:02 -0500
committerJ.J <thechairman@thechairman.info>2023-12-07 08:55:02 -0500
commit4c74fb990efa1a039440de1408581180181b6619 (patch)
tree143795cfcccbb12f6d777aacff2ff2340013f063 /aoc2023/src/day7/solve.gleam
parent54d51b1ea90e7367fec566b5c0d04075e651f1bd (diff)
downloadgleam_aoc-4c74fb990efa1a039440de1408581180181b6619.tar.gz
gleam_aoc-4c74fb990efa1a039440de1408581180181b6619.zip
day 7 refactor
Diffstat (limited to 'aoc2023/src/day7/solve.gleam')
-rw-r--r--aoc2023/src/day7/solve.gleam102
1 files changed, 47 insertions, 55 deletions
diff --git a/aoc2023/src/day7/solve.gleam b/aoc2023/src/day7/solve.gleam
index 7c76fc1..f1f83e9 100644
--- a/aoc2023/src/day7/solve.gleam
+++ b/aoc2023/src/day7/solve.gleam
@@ -26,6 +26,37 @@ type HandType {
// Common functions --------------------------------------------------------------------------------
+fn parse_hand(str: String) -> Hand {
+ let [cards, wager] = string.split(str, " ")
+ let cards =
+ string.to_graphemes(cards)
+ |> list.map(card_rank)
+ let assert Ok(wager) = int.parse(wager)
+
+ Hand(cards, wager)
+}
+
+fn classify_hand(hand: Hand) -> HandType {
+ case list.length(list.unique(hand.cards)), card_counts(hand) {
+ 1, _ -> FiveOfAKind
+ 2, [1, 4] -> FourOfAKind
+ 2, [2, 3] -> FullHouse
+ 3, [1, 1, 3] -> ThreeOfAKind
+ 3, [1, 2, 2] -> TwoPair
+ 4, _ -> OnePair
+ 5, _ -> HighCard
+ _, _ -> Unknown
+ }
+}
+
+fn card_counts(hand: Hand) {
+ hand.cards
+ |> list.sort(int.compare)
+ |> list.chunk(function.identity)
+ |> list.map(list.length)
+ |> list.sort(int.compare)
+}
+
fn hand_rank(hand_rank: HandType) -> Int {
case hand_rank {
HighCard -> 1
@@ -51,56 +82,25 @@ fn card_rank(card: String) -> Int {
}
}
-fn parse_hand(str: String) -> Hand {
- let [cards, wager] = string.split(str, " ")
- let cards =
- string.to_graphemes(cards)
- |> list.map(card_rank)
- let assert Ok(wager) = int.parse(wager)
-
- Hand(cards, wager)
-}
-
-fn card_counts(hand: Hand) {
- hand.cards
- |> list.sort(int.compare)
- |> list.chunk(function.identity)
- |> list.map(list.length)
- |> list.sort(int.compare)
-}
-
-fn classify_hand(hand: Hand) -> HandType {
- case list.length(list.unique(hand.cards)), card_counts(hand) {
- 1, _ -> FiveOfAKind
- 2, [1, 4] -> FourOfAKind
- 2, [2, 3] -> FullHouse
- 3, [1, 1, 3] -> ThreeOfAKind
- 3, [1, 2, 2] -> TwoPair
- 4, _ -> OnePair
- 5, _ -> HighCard
- _, _ -> Unknown
- }
-}
-
// Part 1 ------------------------------------------------------------------------------------------
pub fn part1(input: String) {
input
|> string.split("\n")
|> list.map(parse_hand)
- |> list.sort(compare_hands)
+ |> list.sort(compare_without_wilds)
|> list.index_map(fn(i, h) { { i + 1 } * h.wager })
|> int.sum
|> string.inspect
}
-fn compare_hands(hand1: Hand, hand2: Hand) -> Order {
- case
- int.compare(
- hand_rank(classify_hand(hand1)),
- hand_rank(classify_hand(hand2)),
- )
- {
+fn compare_without_wilds(hand1: Hand, hand2: Hand) {
+ use hand <- compare_hands(hand1, hand2)
+ function.compose(classify_hand, hand_rank)(hand)
+}
+
+fn compare_hands(hand1: Hand, hand2: Hand, using: fn(Hand) -> Int) -> Order {
+ case int.compare(using(hand1), using(hand2)) {
Eq -> compare_top_card(hand1.cards, hand2.cards)
other -> other
}
@@ -144,28 +144,20 @@ fn find_best_joker_substitution(hand: Hand) {
},
)
let subbed_hand = Hand(..hand, cards: subbed_cards)
- case compare_hands(acc, subbed_hand) {
+ case
+ compare_hands(acc, subbed_hand, function.compose(classify_hand, hand_rank))
+ {
Lt -> subbed_hand
_ -> acc
}
}
fn compare_hands_considering_jokers(hand1: Hand, hand2: Hand) -> Order {
- case
- int.compare(
- hand1
- |> find_best_joker_substitution
- |> classify_hand
- |> hand_rank,
- hand2
- |> find_best_joker_substitution
- |> classify_hand
- |> hand_rank,
- )
- {
- Eq -> compare_top_card(hand1.cards, hand2.cards)
- other -> other
- }
+ use hand <- compare_hands(hand1, hand2)
+ hand
+ |> find_best_joker_substitution
+ |> classify_hand
+ |> hand_rank
}
pub fn main() {