How to resolve the algorithm Set puzzle step by step in the F# programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Set puzzle step by step in the F# programming language

Table of Contents

Problem Statement

Set Puzzles are created with a deck of cards from the Set Game™. The object of the puzzle is to find sets of 3 cards in a rectangle of cards that have been dealt face up. There are 81 cards in a deck. Each card contains a unique variation of the following four features: color, symbol, number and shading. Three cards form a set if each feature is either the same on each card, or is different on each card. For instance: all 3 cards are red, all 3 cards have a different symbol, all 3 cards have a different number of symbols, all 3 cards are striped. There are two degrees of difficulty: basic and advanced. The basic mode deals 9 cards, that contain exactly 4 sets; the advanced mode deals 12 cards that contain exactly 6 sets. When creating sets you may use the same card more than once.

Write code that deals the cards (9 or 12, depending on selected mode) from a shuffled deck in which the total number of sets that could be found is 4 (or 6, respectively); and print the contents of the cards and the sets. For instance: DEALT 9 CARDS:

CONTAINING 4 SETS:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Set puzzle step by step in the F# programming language

Source code in the fsharp programming language

open System

type Number = One | Two | Three
type Color = Red | Green | Purple
type Fill = Solid | Open | Striped
type Symbol = Oval | Squiggle | Diamond

type Card = { Number: Number; Color: Color; Fill: Fill; Symbol: Symbol }

// A 'Set' is 3 cards in which each individual feature is either all the SAME on each card, OR all DIFFERENT on each card.
let SetSize = 3

type CardsGenerator() =
    let _rand = Random()    

    let shuffleInPlace data =
        Array.sortInPlaceBy (fun _ -> (_rand.Next(0, Array.length data))) data

    let createCards() =
        [| for n in [One; Two; Three] do
                for c in [Red; Green; Purple] do
                    for f in [Solid; Open; Striped] do
                        for s in [Oval; Squiggle; Diamond] do
                            yield { Number = n; Color = c; Fill = f; Symbol = s } |]

    let _cards = createCards()

    member x.GetHand cardCount =        
        shuffleInPlace _cards
        Seq.take cardCount _cards |> Seq.toList

// Find all the combinations of n elements
let rec combinations n items = 
    match n, items with
    | 0, _  -> [[]]
    | _, [] -> []
    | k, (x::xs) -> List.map ((@) [x]) (combinations (k-1) xs) @ combinations k xs

let validCardSet (cards: Card list) =
    // Valid feature if all features are the same or different
    let validFeature = function
        | [a; b; c] -> (a = b && b = c) || (a <> b && a <> c && b <> c)
        | _ -> false

    // Build and validate the feature lists
    let isValid = cards |> List.fold (fun (ns, cs, fs, ss) c ->                                
                               (c.Number::ns, c.Color::cs, c.Fill::fs, c.Symbol::ss)) ([], [], [], [])
                        |> fun (ns, cs, fs, ss) ->
                               (validFeature ns) && (validFeature cs) && (validFeature fs) && (validFeature ss)

    if isValid then Some cards else None

let findSolution cardCount setCount =
    let cardsGen = CardsGenerator()

    let rec search () =
        let hand = cardsGen.GetHand cardCount
        let foundSets = combinations SetSize hand |> List.choose validCardSet
        
        if foundSets.Length = setCount then (hand, foundSets) else search()

    search()

let displaySolution (hand: Card list, sets: Card list list) =
    let printCardDetails (c: Card) =
        printfn "    %A %A %A %A" c.Number c.Color c.Symbol c.Fill

    printfn "Dealt %d cards:" hand.Length
    List.iter printCardDetails hand
    printf "\n"

    printfn "Found %d sets:" sets.Length
    sets |> List.iter (fun cards -> List.iter printCardDetails cards; printf "\n" )

let playGame() =
    let solve cardCount setCount =
        displaySolution (findSolution cardCount setCount)

    solve 9 4
    solve 12 6

playGame()


  

You may also check:How to resolve the algorithm Price fraction step by step in the Quackery programming language
You may also check:How to resolve the algorithm Associative array/Iteration step by step in the Lingo programming language
You may also check:How to resolve the algorithm Memory allocation step by step in the AutoHotkey programming language
You may also check:How to resolve the algorithm Pseudo-random numbers/Combined recursive generator MRG32k3a step by step in the Julia programming language
You may also check:How to resolve the algorithm Mutex step by step in the Tcl programming language