Skip to content

Instantly share code, notes, and snippets.

@jwosty
Created November 24, 2017 19:22
Show Gist options
  • Save jwosty/58db69d36e1303180344ab1975965c72 to your computer and use it in GitHub Desktop.
Save jwosty/58db69d36e1303180344ab1975965c72 to your computer and use it in GitHub Desktop.
module SecretSanta
open System
//let initConsole () =
// let clrstr = String.replicate Console.BufferWidth " "
// for _ in 1 .. Console.WindowHeight do
// Console.WriteLine clrstr
//let clearConsole () =
//Console.SetCursorPosition (0, 0)
//initConsole ()
//Console.SetCursorPosition (0, 0)
module List =
let remove x list = list |> List.filter (fun y -> x <> y)
let rec removei i list =
list |> List.mapi (fun i' x -> i', x)
|> List.filter (fun (i', x) -> i' <> i)
|> List.map snd
let removeRandom (rand: Random) (list: 'a list) =
let i = rand.Next list.Length
list.[i], removei i list
let shuffle (rand: Random) (list: 'a list) =
let indices = [0 .. list.Length - 1]
list |> (indices |> List.mapFold (fun indices x ->
let i, indices = removeRandom rand indices
(i, x), indices))
|> fst
|> List.sortBy fst
|> List.map snd
let dealRecipients rand names =
let givers = names
let recipientGroups =
[for name in names do yield name; yield name]
|> List.shuffle rand
|> List.chunkBySize 2
let giversWithRecipients =
List.zip givers recipientGroups
giversWithRecipients
let hasCollision giversWithRecipients =
giversWithRecipients |> List.exists (fun (giver, recipients) ->
recipients |> List.contains giver)
let allPossibleNoCollisionCombos rand names =
Seq.initInfinite (fun _ -> dealRecipients rand names) |> Seq.cache
|> Seq.filter (not << hasCollision)
[<WebSharper.JavaScript>]
let rec makeGrammaticalList items =
match items with
| [] -> ""
| a::[] -> a
| a::b::[] -> sprintf "%s and %s" a b
| a::rest -> sprintf "%s, %s" a (makeGrammaticalList rest)
//[<EntryPoint>]
//let main argv =
//let scenario =
// ["Alan"; "Paula"; "Paul"; "Sarah"; "Peter"; "John"]
// |> allPossibleNoCollisionCombos (new Random())
// |> Seq.head
//while true do
// clearConsole ()
// printf "Enter your name: "
// let name = (Console.ReadLine ()).Trim ()
// match scenario |> List.tryFind (fun (giver, _) -> name.ToLower () = giver.ToLower ()) with
// | Some(_, recipients) ->
// printfn "Your giftees are %A." (makeGrammaticalList recipients)
// | None ->
// printfn "Name not recognized!"
// printfn "Press any key to clear this screen."
// Console.ReadKey () |> ignore
//0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment