トップページ > プログラム > 2015年01月11日 > q/YrvBDO

書き込み順位&時間帯一覧

11 位/190 ID中時間01234567891011121314151617181920212223Total
書き込み数0110000010000000001001005



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
関数型プログラミング言語Haskell Part27_©2ch.net
推薦図書/必読書のためのスレッド 75 [転載禁止]©2ch.net

書き込みレス一覧

関数型プログラミング言語Haskell Part27_©2ch.net
15 :デフォルトの名無しさん[sage]:2015/01/11(日) 01:53:57.06 ID:q/YrvBDO
下記の問題について自分なりにプログラムしてみましたが、
問題の性質を静的に(宣言的に)表しているとは言い難いような気がします。
その性質自体がいくぶん動的な体をしているので仕方ないかも知れませんが。
皆さんなら、どのようにプログラムするでしょうか。

[問題]
型aの値には「大きさ」という属性があり、それは関数 (HaveSize a) => size :: a -> Int で得られる。
ただし戻り値は正の整数で、また、size x = size y となる x, y ∈a も存在する。

問題は、型 [a] の値と大きさ n(非負正数)のコンテナがあるとき、
[a] の要素を左から順にコンテナに溢れ出ないように詰め込んでいった場合に
どれだけの部分リストが詰め込めるかを調べる関数 saturate を作ること。

[例]
map size [a, b, c, d, e] = [2, 1, 3, 2, 3] とする。
コンテナの大きさが 7 なら、[a,b,c] がコンテナに詰め込める。
なぜなら [a, b, c] の大きさの合計が 2+1+3=6 で、
更に d を詰めようとすれば 6+2=8 になりコンテナの大きさを超えるからである。
コンテナの大きさが 6 の場合も同じく [a, b, c] まで詰め込める。
コンテナの大きさが 1 以下なら詰め込める部分リストは空リスト [] である。

[私の解答例]
saturate :: (HaveSize a) => Int -> [a] -> (Int, [a])
saturste _ [] = (0, [])
saturate n (x:xs)
  | n < s = (0, [])
  | otherwise = (s, x) +: saturate (n - s) xs
 where s = size x

infixr 5 +:
(+:) :: (Int, a) -> (Int, [a]) -> (Int, [a])
(m, x) +: (n, xs) = (m + n, x: xs)
関数型プログラミング言語Haskell Part27_©2ch.net
16 :デフォルトの名無しさん[sage]:2015/01/11(日) 02:13:40.35 ID:q/YrvBDO
>>15
ちなみに、関数 saturate の型について細かいことは問いません。

最低限、引数としてリスト [a] とコンテナのサイズがあり、
戻り値として実際に詰め込めた部分リスト [a] があればいいです。
他の引数があっても、制約を課してもいいです。

解答例のように部分リストの大きさも同時に分かれば尚いいですが、
それは後から sum . map size でも得られるので無くてもかまいません。


ちなみに、ちなみに、私の自分の解答に対する不満というのは、
問題の中に特に再帰的な性質が陽に現れている訳ではないのに、
関数の中で再帰を陽に使っていることです。

これは、たとえば部分が全体の縮小版になっているという
本質的に再帰的な性質を持つ階乗の計算をする関数を
再帰を陽に使って表すのとは訳が違う、ような気がなんとなくします。
関数型プログラミング言語Haskell Part27_©2ch.net
17 :デフォルトの名無しさん[sage]:2015/01/11(日) 08:16:23.15 ID:q/YrvBDO
>>16
もしかして、再帰は再帰でも、分割統治の出番ですか?
推薦図書/必読書のためのスレッド 75 [転載禁止]©2ch.net
283 :デフォルトの名無しさん[sage]:2015/01/11(日) 18:58:47.85 ID:q/YrvBDO
31バイトでつくるアセンブラプログラミング ~アセンブラ短歌の世界~

これとどっちがアホっぽいかな
関数型プログラミング言語Haskell Part27_©2ch.net
26 :デフォルトの名無しさん[sage]:2015/01/11(日) 21:33:43.65 ID:q/YrvBDO
>>19 >>20 >>22
自分のも含めてですが、どれも数ヶ月後にコードを読み返したとき、
何をやっているのか「すぐに分かる」ようなものではなさそうです。
>>20 の後者のは比較的に問題の仕様を思い出しやすいと思いましたが。
アドバイスをいただいておきながら生意気言ってすみません。
でも参考にさせていただきます。


結果リストの各要素の大きさの合計も同時に得るに誰も挑戦しなかったのは、
それによってコードが一気に複雑になるからですね。
やはり、両者は別の問題を解く計算として分けた方が良さそうですね。


ベンチについてですが、すいません、今回は処理速度はたいして気にしていません。
初めにはっきり言っておくべきでした。
コンテナのサイズもせいぜい50くらいです。
求めていたのは、問題の仕様をいかに宣言的にコード化するかでした。

それに、素直にやれば計算量オーダーは O(n) のはずなので、
各例とも極端な差は出ないのではないでしょうか。


ともかく、ありがとうございました。
参考にさせていただき、自分のコードを見直します。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。