2011年10月10日

[ruby-list:48457] Re: 1.8.7と1.9.2の挙動の違いについて

> で、蛇足の本題?ですが
>
> > のようにscanとjoinが必要な理由を初心者に説明するのはきついです。
> > これだと、自信を持って「Rubyの方がいいよ」とは言いづらいです。
>
> の所です。
> 「期待値 10」と言うことは、これらの例題は
> 1234 → 1+2+3+4 =10

> を再帰を使って解く という事を(PHPと比較して?)示す
> というのを意図されているのかと拝察します。
>
> それって相手の土俵に乗ってる様な気がします。
> たしか ruby は再帰はあまり得意ではなかった(最適化の点で)
> とも思いますし。
> 「1234 → 10 を解く」
> にまで戻って、NARUSEさんが示された inject を使うとかするとか、
> それがハイレベルすぎるようだと避けるにしても、
>   PHPのアルゴリズムをrubyに置き換える
> のではなく、
>   ruby ならこう(簡単に)書けるよ、
> ということを示されるのが良いのではないでしょうか。

ええと、この件については、別の枝で岩月さんが示されてる通り、
n.to_s[a, b] か n.to_s[c .. d] を使うのが良いように思います。
以上で本題終了で、

以下、蛇足を書いてたらどんどん長くなったのですが、蛇足事項。

組み込みプログラミングとか、Windows版rubyでも(前は?)そんな話があったと
思いますが、スタックが小さい環境ですぐ溢れるとか、この計算の例なら
10**100まで対応できるようにしなければならない、とかでない限り、再帰を
避ける理由はないように思います。Schemeなら正しく書いた再帰は非常に
効率的ですが、それと比べた場合、rubyとPHPは再帰に関してはたぶん
50歩100歩ではないかと思います。(そんなにPHPを知らないので間違ってる
かもしれません)

文が長くなっても「期待値」という言葉には、「たくさん試行した
として平均してありそうな値」という意味があるので、こういう場合は、
「期待される値」と言ったほうが良いでしょう。

私ならこう書く、という話になりますが、とりあえず下の桁から足すような形に
展開してもいいならこんな感じに、

def calc(prm)
if prm < 10 then
prm
else
prm % 10 + calc(prm / 10)
end
end

どうしても上の桁からならこうでしょうか

def calc(prm)
if prm < 10 then
prm
else
prm.to_s[0, 1].to_i + calc(prm.to_s[1 .. -1].to_i)
end
end

もちろんこんな解もありますが、
prm.to_s.each_char.map {|c| c.to_i }.inject(:+)

それからprintfに渡す式をリテラル式以外にするのはやめましょう。
printfの第一引数は、フォーマットを指定する文字列ですから、うっかり
% が入っている文字列を渡すと変なことになります。
改行がいらなければprintを、また、わざわざ + "\n" と書くぐらいなら
putsを使いましょう。
デバッグとか簡単な確認だけなら p でも。p なら to_s もいらなくなります。

prmという引数名も、パラメータ、かと思いますが、よくありません。
argなら、慣用的によく使われているという理由で使う理由がありますが、
prmはそういうこともないし、「パラメータ」だけではその中身の意味を、
ほとんどあらわしてないからです。
一文字変数はよくない、などと言われますが、数を意味する n 、文字列を
意味する s などは立派に意味があり、このくらいの短いまとまった部分で
あれば、むしろ使うほうが良い、と私は考えます。

こんな解も。ちょっとパズルし過ぎかな。

def calc s
calc_ s.each_char.to_a
end

def calc_ arr
if arr.empty? then
0
else
n = arr.shift.to_i
n + calc_(arr)
end
end


投稿者 xml-rpc : 2011年10月10日 12:29
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/106843
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。