type Op = And = 0 | Or = 1 | Xor = 2 | Not = 3 | V1 = 4 | V2 = 5 | V3 = 6 | V4 = 7
| prg -> prg |> List.rev |> List.iter (printf "%A ")
let numberOfFunctions = (8.0 / 7.0) * ((8.0 ** float maxLength) - 1.0)
let mutable totalProcessed = 0L
let rec search func size stackDepth =
totalProcessed <- totalProcessed + 1L
if stackDepth = 1 && maxLength < 5 then printCode func; printfn ""
let remaining = maxLength - size
| x::y::xs when y >= Op.V1 && x > y ->
search (Op.And::func) (size + 1) (stackDepth - 1)
search (Op.Or::func) (size + 1) (stackDepth - 1)
search (Op.Xor::func) (size + 1) (stackDepth - 1)
if stackDepth <= remaining && stackDepth > 0 then
search (Op.Not::func) (size+1) stackDepth
if stackDepth < remaining then
search (Op.V1::func) (size + 1) (stackDepth + 1)
search (Op.V2::func) (size + 1) (stackDepth + 1)
search (Op.V3::func) (size + 1) (stackDepth + 1)
search (Op.V4::func) (size + 1) (stackDepth + 1)
printfn "Number of programs: %A" numberOfFunctions
printfn "Programs processed: %A" totalProcessed
printfn "%.2f%% of programs skipped" (100.0 - (float totalProcessed / numberOfFunctions) * 100.0)