自然数の分割
Posted feedbacks - OCaml
#4344 の移植。 エラー処理はあまり意味が無いので省いた。 あと、sort とかいらなかったので、これも削除。 (当初は、完全に末尾再帰にしようと思っていて、その時点では順番が崩れるだろうという予想だったんですが……)
rev_map や rev_append でリストの方向がころころ変わってる辺りが 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 | let rec split_num' base n m acc =
match n, m with
| _, 0 -> [[n]]
| n, _ when n < 0 -> acc
| n, m ->
let base' = base - n in
let sub = split_num' base' base' (pred m) [] in
let acc' = List.rev_map (fun xs -> n::xs) sub in
split_num' base (pred n) m (List.rev_append acc' acc)
let split_num n m =
let nums = split_num' n n (pred m) [] in
let lines =
List.rev_map begin fun lst ->
String.concat ", " (List.map string_of_int lst)
end nums
in
String.concat "\n" lines
let main () =
match Sys.argv with
| [|_; n; m|] ->
print_endline (split_num (int_of_string n) (int_of_string m))
| _ ->
print_endline "usage: command m n"
let () = if not !Sys.interactive then main ()
|
ざっくり書きました。upto みたいなのは標準ライブラリにあるのかな。 それから cons を関数として使おうとして (::) と書いてみたのですが、構文エラーになってしまいました。はて。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | open List
let upto x =
let rec upto' y =
if x=y then
[y]
else
y :: upto' (y+1)
in upto' 0
let cons x y = x::y
let rec bunkatu n m =
if m <= 1 then
[[n]]
else
let cand = map (fun x -> (x,n-x)) (upto n) in
concat (map (fun (a,b) -> map (cons a) (bunkatu b (m-1))) cand)
|




herumi
#4099()
Rating1/1=1.00
[ reply ]