module Y =
let permutation xxs =
let rec ins (acc : _ list list) (x : _) (hh : _ list) (xs : _ list) =
match xs with
| [] -> (hh @ [x]) :: acc
| h :: t -> ins ((hh @ (x :: xs)) :: acc) x (h :: hh) t
let rec loop (acc : _ list list) xs =
match xs with
| x :: t ->
let acc = List.collect (fun a -> ins [] x [] a) acc
loop acc t
| _ -> acc
loop [[]] xxs
let not_ontop x (arr : _[]) = arr.[Array.length arr - 1] <> x
let not_onbottom x (arr : _[]) = arr.[0] <> x
let level x (arr : _[]) = Array.findIndex ((=)x) arr
let not_near a b
(arr
: _
[]) = abs (level a arr
- level b arr
) <> 1 let higher_than a b (arr : _[]) = level a arr < level b arr
let solver rules mens =
for house' in permutation mens do
let house = List.toArray house'
if List.forall (fun rule -> rule house) rules
then printfn "%A" house
open Y
type Someone = | Baker | Cooper | Fletcher | Miller | Smith
[<EntryPoint>]
let main argv =
let mens = [ Baker; Cooper; Fletcher; Miller; Smith ]
let rules = [ Baker |> not_ontop
Cooper |> not_onbottom
Fletcher |> not_ontop
Fletcher |> not_onbottom
Miller |> higher_than Cooper
Smith |> not_near Fletcher
Fletcher |> not_near Cooper
]
Y.solver rules mens
0