与えた条件を満たす候補
Posted feedbacks - OCaml
イマイチ。
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 34 35 36 37 38 | #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 all_comb = function
| 0 -> [[]]
| n -> doList { let! rest = all_comb (n-1)
let! result = [(true::rest);(false::rest)]
return result }
let num_args cmds =
List.filter ((<>) "not") cmds
|> List.length
|> (+) 1
let rec satisfy (cmds:string list) (bools:bool list) =
match cmds,bools with
| [],b::[] -> b
| "not"::[],b::[] -> not b
| "not"::cs,b::bs -> satisfy cs ((not b)::bs)
| "and"::"not"::cs,b::b'::bs -> satisfy cs ((b && (not b'))::bs)
| "or"::"not"::cs,b::b'::bs -> satisfy cs ((b || (not b'))::bs)
| "and"::cs,b::b'::bs -> satisfy cs ((b && b')::bs)
| "or"::cs,b::b'::bs -> satisfy cs ((b || b')::bs)
let get_combs cmds =
doList { let! cont = all_comb (num_args cmds)
do! guard (satisfy cmds cont)
return cont }
do get_combs ["and";"or";"not";"and"]
|> (print_any >> print_newline)
|
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)
|





にしお
#3399()
Rating0/0=0.00
元ネタの 充足可能性問題 - Wikipedia は、 同じリテラル(x1とかnot x2とか)が複数回出てくることを想定しているので、 今回の問題のようにそれぞれ別の変数でだと乗法標準形 - Wikipediaにした場合に、答えが…と色々悩みどころでした。
[ reply ]