Skip to content

Instantly share code, notes, and snippets.

@object
Last active December 7, 2023 09:28
Show Gist options
  • Select an option

  • Save object/b3d47284f695759575488ea306956c23 to your computer and use it in GitHub Desktop.

Select an option

Save object/b3d47284f695759575488ea306956c23 to your computer and use it in GitHub Desktop.
Advent of Code 2023, December 7
#time "on"
open System
open System.IO
type HandType =
| FiveOfKind of int
| FourOfKind of int * int
| FullHouse of int * int
| ThreeOfKind of int * int * int
| TwoPair of int * int * int
| OnePair of int * int * int * int
| HighCard of int * int * int * int * int
let getCardRank enableJoker c =
match c with
| 'A' -> 14
| 'K' -> 13
| 'Q' -> 12
| 'J' -> if enableJoker then 0 else 11
| 'T' -> 10
| _ -> int c - int '0'
let getHandRank getHandType hand =
let handType =
match getHandType hand with
| FiveOfKind _ -> 6
| FourOfKind _ -> 5
| FullHouse _ -> 4
| ThreeOfKind _ -> 3
| TwoPair _ -> 2
| OnePair _ -> 1
| HighCard _ -> 0
handType, hand
let rec getHandType enableJoker (hand: int list) =
let cardRank = fst
let cardCount = snd
let cardCounts =
hand
|> List.distinct
|> List.map (fun x -> x, hand |> List.filter (fun y -> y = x) |> List.length)
|> List.sortBy (fun (rank, length) -> if rank = 0 then 0 else length * 20 + rank)
|> List.rev
let cardCounts =
if enableJoker && cardCounts |> List.exists (fun (rank, _) -> rank = 0) && cardCounts.Length > 1 then
let head = (cardRank cardCounts[0], cardCount cardCounts[0] + cardCount (cardCounts |> List.last))
head :: (cardCounts |> List.truncate (cardCounts.Length - 1) |> List.skip 1)
else
cardCounts
if cardCounts.Length = 1 then
FiveOfKind (cardRank cardCounts[0])
else if cardCounts.Length = 2 then
if cardCount cardCounts[0] = 4 then
FourOfKind (cardRank cardCounts[0], cardRank cardCounts[1])
else
FullHouse (cardRank cardCounts[0], cardRank cardCounts[1])
else if cardCounts.Length = 3 then
if cardCount cardCounts[0] = 3 then
ThreeOfKind (cardRank cardCounts[0], cardRank cardCounts[1], cardRank cardCounts[2])
else
TwoPair (cardRank cardCounts[0], cardRank cardCounts[1], cardRank cardCounts[2])
else if cardCounts.Length = 4 then
OnePair (cardRank cardCounts[0], cardRank cardCounts[1], cardRank cardCounts[2], cardRank cardCounts[3])
else
HighCard (cardRank cardCounts[0], cardRank cardCounts[1], cardRank cardCounts[2], cardRank cardCounts[3], cardRank cardCounts[4])
let input =
File.ReadAllLines(__SOURCE_DIRECTORY__ + "/../data/input07.txt")
|> Seq.toList
let getResult enableJoker =
input
|> List.map (fun str -> str.Split ' ' |> fun x -> x[0] |> Seq.toList |> List.map (getCardRank enableJoker), x[1] |> Int32.Parse)
|> List.sortBy (fun (hand, bid) -> getHandRank (getHandType enableJoker) hand)
|> List.mapi (fun ndx (rank, bid) -> ndx+1, bid)
|> List.map (fun (ndx, bid) -> int64 ndx * int64 bid)
|> List.sum
// Part One
getResult false
// Part Two
getResult true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment