Day 7 #6
@@ -3,15 +3,6 @@ namespace AdventOfCode2023
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
|
||||
//type Hand =
|
||||
// | Five of byte
|
||||
// | Four of high: byte * low: byte
|
||||
// | FullHouse of three: byte * two: byte
|
||||
// | Three of three: byte * highOther: byte * lowOther: byte
|
||||
// | TwoPairs of highPair: byte * lowPair: byte * other: byte
|
||||
// | Pair of pair: byte * highOther: byte * midOther: byte * lowOther: byte
|
||||
// | High of high: byte * mid: byte * low: byte * lowest: byte * lowestest: byte
|
||||
|
||||
type Hand =
|
||||
| Five = 10
|
||||
| Four = 9
|
||||
@@ -42,7 +33,7 @@ module Day7 =
|
||||
elif c = 'A' then 14uy
|
||||
else failwithf "could not parse: %c" c
|
||||
|
||||
let inline private updateState (tallies : ResizeArray<_>) (newNum) =
|
||||
let inline private updateState (tallies : ResizeArray<_>) newNum =
|
||||
let mutable isAdded = false
|
||||
|
||||
for i = 0 to tallies.Count - 1 do
|
||||
@@ -53,7 +44,12 @@ module Day7 =
|
||||
if not isAdded then
|
||||
tallies.Add (newNum, 1)
|
||||
|
||||
let inline parseHand (adjustJoker : bool) (s : ReadOnlySpan<char>) : Hand * HandContents =
|
||||
let inline parseHand
|
||||
(tallyBuffer : ResizeArray<_>)
|
||||
(adjustJoker : bool)
|
||||
(s : ReadOnlySpan<char>)
|
||||
: Hand * HandContents
|
||||
=
|
||||
let contents =
|
||||
{
|
||||
First = toByte adjustJoker s.[0]
|
||||
@@ -63,29 +59,32 @@ module Day7 =
|
||||
Fifth = toByte adjustJoker s.[4]
|
||||
}
|
||||
|
||||
let tallies = ResizeArray 5
|
||||
tallies.Add (contents.First, 1)
|
||||
updateState tallies contents.Second
|
||||
updateState tallies contents.Third
|
||||
updateState tallies contents.Fourth
|
||||
updateState tallies contents.Fifth
|
||||
tallyBuffer.Clear ()
|
||||
tallyBuffer.Add (contents.First, 1)
|
||||
updateState tallyBuffer contents.Second
|
||||
updateState tallyBuffer contents.Third
|
||||
updateState tallyBuffer contents.Fourth
|
||||
updateState tallyBuffer contents.Fifth
|
||||
|
||||
let jokerCount, jokerPos =
|
||||
let mutable count = 0
|
||||
let mutable jokerPos = -1
|
||||
if not adjustJoker then
|
||||
0, -1
|
||||
else
|
||||
let mutable count = 0
|
||||
let mutable jokerPos = -1
|
||||
|
||||
for i = 0 to tallies.Count - 1 do
|
||||
let card, tally = tallies.[i]
|
||||
for i = 0 to tallyBuffer.Count - 1 do
|
||||
let card, tally = tallyBuffer.[i]
|
||||
|
||||
if card = 1uy then
|
||||
count <- tally
|
||||
jokerPos <- i
|
||||
if card = 1uy then
|
||||
count <- tally
|
||||
jokerPos <- i
|
||||
|
||||
count, jokerPos
|
||||
count, jokerPos
|
||||
|
||||
let hand =
|
||||
if jokerCount > 0 then
|
||||
match tallies.Count with
|
||||
match tallyBuffer.Count with
|
||||
| 1 ->
|
||||
// Five jokers
|
||||
Hand.Five
|
||||
@@ -97,39 +96,42 @@ module Day7 =
|
||||
if jokerCount >= 2 then
|
||||
// JJABB or JJJAB
|
||||
Hand.Four
|
||||
else
|
||||
else if
|
||||
// JAABB or JAAAB
|
||||
let tallies = tallies |> Seq.map snd |> Seq.toArray
|
||||
|
||||
if Array.contains 3 tallies then
|
||||
Hand.Four
|
||||
else
|
||||
jokerPos <> 0
|
||||
then
|
||||
if snd tallyBuffer.[0] = 2 then
|
||||
Hand.FullHouse
|
||||
else
|
||||
Hand.Four
|
||||
else if snd tallyBuffer.[1] = 2 then
|
||||
Hand.FullHouse
|
||||
else
|
||||
Hand.Four
|
||||
| 4 ->
|
||||
// Jokers plus three other card types, exactly one of which therefore is a two-of.
|
||||
Hand.Three
|
||||
| 5 ->
|
||||
// Five different cards, one of which is a joker.
|
||||
Hand.Pair
|
||||
| _ -> failwithf "bad tallies: %+A" tallies
|
||||
else
|
||||
|
||||
let tallies = tallies |> Seq.map snd |> Seq.toArray
|
||||
|
||||
if tallies |> Array.contains 5 then
|
||||
| _ -> failwith "bad tallyBuffer"
|
||||
elif tallyBuffer.Count = 1 then
|
||||
Hand.Five
|
||||
elif Array.contains 4 tallies then
|
||||
Hand.Four
|
||||
elif Array.contains 3 tallies then
|
||||
if Array.contains 2 tallies then
|
||||
elif tallyBuffer.Count = 2 then
|
||||
// AAAAB or AAABB
|
||||
if snd tallyBuffer.[0] = 3 || snd tallyBuffer.[0] = 2 then
|
||||
Hand.FullHouse
|
||||
else
|
||||
Hand.Three
|
||||
elif Array.contains 2 tallies then
|
||||
if tallies |> Array.filter (fun x -> x = 2) |> Array.length = 2 then
|
||||
Hand.TwoPairs
|
||||
else
|
||||
Hand.Pair
|
||||
Hand.Four
|
||||
elif tallyBuffer.Count = 3 then
|
||||
// AAABC or AABBC
|
||||
if snd tallyBuffer.[0] = 3 then Hand.Three
|
||||
elif snd tallyBuffer.[0] = 2 then Hand.TwoPairs
|
||||
elif snd tallyBuffer.[1] = 3 then Hand.Three
|
||||
elif snd tallyBuffer.[1] = 2 then Hand.TwoPairs
|
||||
else Hand.Three
|
||||
elif tallyBuffer.Count = 4 then
|
||||
Hand.Pair
|
||||
else
|
||||
Hand.High
|
||||
|
||||
@@ -138,12 +140,13 @@ module Day7 =
|
||||
let parse (adjustJoker : bool) (s : string) : ResizeArray<Hand * HandContents * int> =
|
||||
use mutable lines = StringSplitEnumerator.make '\n' s
|
||||
let result = ResizeArray ()
|
||||
let tallies = ResizeArray 5
|
||||
|
||||
while lines.MoveNext () do
|
||||
if not lines.Current.IsEmpty then
|
||||
use mutable line = StringSplitEnumerator.make' ' ' lines.Current
|
||||
line.MoveNext () |> ignore
|
||||
let hand, contents = parseHand adjustJoker line.Current
|
||||
let hand, contents = parseHand tallies adjustJoker line.Current
|
||||
line.MoveNext () |> ignore
|
||||
let bid = Int32.Parse line.Current
|
||||
|
||||
|
Reference in New Issue
Block a user