Comment detail
与えた条件を満たす候補 (Nested Flatten)nskj77さんのコードを参考に修正してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #light
type ListBuilder () =
member l.Bind (v,f) = List.concat (List.map f v)
member l.Return x = [x]
member l.Let(v,f) = f v
let guard c = if c then [()] else []
let doList = new ListBuilder()
let rec satisfy prev bs cmds =
match bs, cmds with
| b::[], _ -> prev b
| b::bs, cmd::cmds ->
match cmd with
| "not" -> satisfy prev ((not b)::bs) cmds
| "and" -> satisfy ((&&) (prev b)) bs cmds
| "or" -> satisfy ((||) (prev b)) bs cmds
let rec all_comb = function
| 0 -> [[]]
| n -> doList { let! rest = all_comb (n-1)
let! result = [(true::rest);(false::rest)]
return result }
let get_combs cmds =
let len = 1 + (List.length (List.filter ((<>) "not") cmds))
doList { let! bs = all_comb len
do! guard (satisfy (fun x -> x) bs cmds)
return bs }
do get_combs ["and";"or";"not";"and"]
|> (print_any >> print_newline)
|
さらにモナドを使わずに書き直してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #light
let rec satisfy prev bs cmds =
match bs, cmds with
| b::[], _ -> prev b
| b::bs, cmd::cmds ->
match cmd with
| "not" -> satisfy prev ((not b)::bs) cmds
| "and" -> satisfy ((&&) (prev b)) bs cmds
| "or" -> satisfy ((||) (prev b)) bs cmds
let rec all_comb = function
| 0 -> [[]]
| n -> [ for res in all_comb (n-1) ->> [true::res;false::res] ]
let get_combs cmds =
let len = 1 + (List.length (List.filter ((<>) "not") cmds))
[for bs in all_comb len when satisfy (fun x -> x) bs cmds -> bs]
do get_combs ["and";"or";"not";"and"]
|> (print_any >> print_newline)
|





iwk
#2109()
[
OCaml
]
Rating-1/1=-1.00
Rating-1/1=-1.00-0+
1 reply [ reply ]