Pythonの課題をRubyで

授業の課題で,Pythonで以下のようなプログラムを組んできなさいというのがあったので,5分弱で終わらせました.

  • 整数値を入力する
  • 負の数は無視する
  • 0が入力されたら終了
  • 最後に合計と数字の個数,平均を求める


以下がソースコードです.

s = 0
i = 0
while 1:
  n = int(raw_input("input positive number:"))
  if n > 0:
    s += n
    i += 1
  if n == 0:
    break

print "sum:",s
print "number of numbers:",i
print "average:",float(s)/float(i)

=>
$ python savg.py 
input positive number:1
input positive number:2
input positive number:3
input positive number:-1
input positive number:0
sum: 6
number of numbers: 3
average: 2.0

raw_inputって結構素敵ですね.endが要らないから行数も自ずと短くなる.どーせRubyでもtabぐらい打つから,tab云々は置いておきましょう.


で,ココからが本題.折角なので,Rubyで面白可笑しく同じ事をしてみました.

関数を使って

関数を定義し,再帰的に処理する事で繰り返しを実現します.

def inpnum(nums)
  print "input positive number:"
  n = gets.to_i
  nums.push(n) if n > 0
  return if n == 0
  inpnum(nums)
end

nums = []
s = 0
inpnum(nums)
nums.each{ | e | s += e.to_i}
puts "sum:#{s}"
puts "number of numbers:#{nums.length}"
puts "avg:#{s.to_f/nums.length.to_f}"

結果は省略します.参照渡しなので返り値とかは必要でないので,コードもスッキリしています.

クロージャを使って

クロージャを使用して,繰り返し処理をします.

inpnum = lambda{|nums|
  print "input positive number:"
  n = gets.to_i
  nums.push(n) if n > 0
  return nums if n == 0
  inpnum.call(nums)
}

s = 0
nums = inpnum.call(Array.new)
nums.each{ | e | s += e.to_i}
puts "sum:#{s}"
puts "number of numbers:#{nums.length}"
puts "avg:#{s.to_f/nums.length.to_f}"

こちらも,結果は省略します.クロージャですので,参照渡しとかは無く,ちゃんと返り値を設定してあげなければなりません.ただ

inpnum.call(nums)

としただけではnumsの値が変わらない,ってのが,クロージャの良い所ですね.あぁ,やっとクロージャが普通に使えるようになってきたぞ.


ソースコードの長さは多少Rubyの方が長かったけど(もちろん,一番簡単な方法でやったヤツと比較して),やっぱりボクはRubyの方が好きだなぁ.


んじゃまぁ今日はコレぐらいで.