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