Skip to content

Instantly share code, notes, and snippets.

@SteveGilham
Last active September 29, 2020 18:26
Show Gist options
  • Save SteveGilham/23352205fc2ec9a801e4986f85c9d623 to your computer and use it in GitHub Desktop.
Save SteveGilham/23352205fc2ec9a801e4986f85c9d623 to your computer and use it in GitHub Desktop.
Puzzle solver
open System
open System.IO
let words = File.ReadAllLines(@".\brit-a-z.txt")
|> Array.filter (fun x -> x.IndexOf('\'') < 0)
let nines = words
|> Array.filter (fun x -> x.StartsWith("a"))
|> Array.filter (fun x -> x.Length = 9)
printfn "%d candidate words" nines.Length
let fives = words
|> Array.filter (fun x -> x.Length = 5)
printfn "%d candidate sub-words" fives.Length
let bag (x : String) = x |> Seq.cast<Char>
let takeChar (c : Char) (l : Char seq) =
let head = Seq.takeWhile (fun h -> h <> c) l
let tail = Seq.skipWhile (fun t -> t <> c) l
if Seq.isEmpty tail then None
else Some (Seq.concat [| head ; tail |> Seq.skip 1 |] )
let takeChars (l : Char seq) (c : Char seq) =
Seq.fold (fun l' c' -> Option.bind (takeChar c') l') (Some(l)) c
let solutions (t9 : Char seq) =
let l5 = fives
|> Array.filter (fun x -> let s = bag x
(takeChars t9 s) |> Option.isSome)
let matches = l5
|> Seq.map (fun x -> l5
|> Array.filter (fun y -> (x.Chars 2) = (y.Chars 0))
|> Array.filter (fun y -> let sy = bag y
let sx = bag x
let all = Seq.concat [| sy ; sx |] |> Seq.skip 1
(takeChars t9 all) |> Option.isSome)
|> Array.map (fun y -> (x, y)))
|> Seq.concat
matches |> Seq.toList
let suitable (t9 : string) =
match solutions (bag t9) with
| x :: [] -> Some (t9, x)
| _ -> None
printfn "%A" (suitable "supernova")
let sw1 = System.Diagnostics.Stopwatch.StartNew()
let total = nines
|> Seq.choose suitable
|> Seq.map (fun x -> printfn "%A" x
x)
|> Seq.length
printfn "%A" total
sw1.Stop()
printfn "%A" (sw1.Elapsed)
;;
//9
//00:00:10.3040735
//161
//00:02:09.9284476
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment