Last active
December 7, 2023 09:28
-
-
Save object/b3d47284f695759575488ea306956c23 to your computer and use it in GitHub Desktop.
Advent of Code 2023, December 7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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