第45回 Ruby/Rails勉強会@関西に行ってきた
演習問題をやってみた
正の整数 n の階乗 n! を求める方法を何通りでも考えてください
class Integer def ! case self when 0, 1 1 else self * (self-1).! end end end # とか class Integer def ! (1..self).inject(1, &:*) end end 0.! # => 1 1.! # => 1 2.! # => 2 3.! # => 6 4.! # => 24
inject の初期値を 1 にするのは、いつものように id:no6v に教えてもらった。
文字列 "零 一 二 三 四 五 六 七 八 九 十 十一 十二 十三 十四 十五" があります。これから次のような日本語の漢数字の読みを表すハッシュテーブルを作ってください。
"零 一 二 三 四 五 六 七 八 九 十 十一 十二 十三 十四 十五".split(/\s+/). each_with_index.inject(Hash.new){|h, a|h[a[1]]=a[0];h} # >> {0=>"零", 1=>"一", 2=>"二", 3=>"三", 4=>"四", 5=>"五", # >> 6=>"六", 7=>"七", 8=>"八", 9=>"九", 10=>"十", 11=>"十一", # >> 12=>"十二", 13=>"十三", 14=>"十四", 15=>"十五"}
シンボルの配列 syms があります。これを先頭だけ大文字化され、昇順にソートされた文字列の配列に変えてください。
syms = [:tokyo, :kyoto, :osaka, :kobe, :matze, :sendai] syms.map{|i|i.to_s.capitalize}.sort # => ["Kobe", "Kyoto", "Matze", "Osaka", "Sendai", "Tokyo"]
正の整数 n の二重階乗 n!! を求めるメソッドを書いてください。
class Integer def factorial2 step(1, -2).inject(1, &:*) end end (0..9).map(&:factorial2) # => [1, 1, 2, 3, 8, 15, 48, 105, 384, 945]
残念ながら !! という名前のメソッドは作れない。
n までの整数からすべての合成数を除いて素数だけを残すやりかたとして「エラトステネスのふるい」というアルゴリズムが有名です。このアルゴリズムをイテレータを使ってうまく実装してください。
require 'prime' class Integer def eratosthenes Prime::EratosthenesGenerator.new.inject([]) do |prime, i| return prime if i > self prime << i end end end 20.eratosthenes # => [2, 3, 5, 7, 11, 13, 17, 19]
冗談です。
class Integer def eratosthenes (2..Math.sqrt(self).to_i). inject((2..self).to_a) do |sieve, prime| sieve.reject{|i|i > prime && i % prime == 0} end end end 20.eratosthenes # => [2, 3, 5, 7, 11, 13, 17, 19]
次のメソッドは二項分布を生成します。これを改良してください。ちなみに二項分布は次のように試行回数 n と確率 p をパラメータとする確率分布です。ここでは二項係数 nCx を計算するのにパスカルの三角形を構成して使っています。
[あとで書く] かも