Rubyチュートリアル8章まで

takashi42332007-05-03

7章は配列とイテレータについての説明.

.times
.each
.sort
.join

やら結構便利なメソッドが多いと思う.

私的解答

好きな数だけ単語の入力をしてもらい(1行に1単語、最後はEnterだけの空行)、アルファベット順に並べ変えて出力するようなプログラムを書いてみましょう?

word = "Please Input your favorite word \n if you finished , you would only type Enter>>"
words = []

while word != "\n"
  puts word
  word = gets 
  words <<  word
end

#文字もソート出来るという事実
words =  words.sort

words.each do |word|
  puts word
end

以前、メソッドの章で書いた目次を表示するプログラムを修正してみましょう。その際、プログラムの最初で目次の情報(つまり、章の名前やページ番号など)をすべてひとつの配列にしまいます。その後、その配列から情報を取り出して美しくフォーマットされた目次を出力します。


ここにきて,前回パスしたものを利用しないとダメになったので,
再度おとなしく考えてみた所,思ったより難しくはなかった.

lineWidth = 40
puts "Practice Chapter5"
puts "Chapter1:Number".ljust(lineWidth/2) + "P1".rjust(lineWidth/2)
puts "Chapter2:Char".ljust(lineWidth/2) + "P72".rjust(lineWidth/2)
puts "Chapter3:Variable".ljust(lineWidth/2) + "P118".rjust(lineWidth/2)



puts "Practice Chapter7"
str = [["Chapter1:Number","P1"],["Chapter2:Char","P72"],["Chapter3:Variable","P118"]]

str.each do |string|
  puts string[0].ljust(lineWidth/2) + string[1].rjust(lineWidth/2)
end

8章はメソッドについて.
メソッドの引数をスペースだけで記述するというのが
少し違和感を受ける.が括弧でくくってもいいらしぃ.

上のenglishNumberを拡張してみましょう。最初にthousand(千の桁)を導入してください。上のプログラムでは 'ten hundred'となっているところを'one thousand'を返すように、あるいは、'one hundred hundred'の代わりに'ten thousand'を返すようにします。

 def englishNumber number
  if number < 0  #  負の数は不可です。
    return '負でない数を入力してください.'
  end
  if number == 0
    return 'zero'
  end

  numString = ''  #  これが最終的に返す文字列です。

  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']

  left  = number

  write = left/1000          #  千の桁以上の桁をwriteに入れます。
  left  = left - write*1000  #  下3桁をleftに残します。

  if write > 0
    thousands = englishNumber write
    numString = numString + thousands + ' thousand'
     if left > 0
      numString = numString + ' '
    end
  end



  write = left/100          #  百の桁以上の桁をwriteに入れます。
  left  = left - write*100  #  下2桁をleftに残します。

  if write > 0
    hundreds  = englishNumber write
    numString = numString + hundreds + ' hundred'
     if left > 0
      numString = numString + ' '
    end
  end

  write = left/10          #  今度は十の桁です。
  left  = left - write*10  #  そして十の桁をひきます。

  if write > 0
    if ((write == 1) and (left > 0))
      numString = numString + teenagers[left-1]
      left = 0
    else
      numString = numString + tensPlace[write-1]
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left  #  ここで、一の桁を書き出します。
  left  = 0     #  この桁を引きます。(0になります。)

  if write > 0
    numString = numString + onesPlace[write-1]
  end
  numString
end

puts englishNumber(  0)
puts englishNumber(1000000)

englishNumberにさらに改良を加えましょう。 milion(百万)を加えます。その結果、'one thousand thousand'の代わりに 'one million'が得られるようにします。その後、billion(十億)とかtrillion(兆)とかを追加していってみましょう。どこまでいけるでしょうか?

def englishNumber number
  if number < 0  #  負の数は不可です。
    return '負でない数を入力してください.'
  end
  if number == 0
    return 'zero'
  end

  numString = ''  #  これが最終的に返す文字列です。

  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']



  left  = number
  digits = [1000000,1000,100]
  digits_words =  [" milion"," thousand"," hundred"]
  cnt = 0
  #.lengthは要素の数を返します.
  len = digits.length - 1
  for cnt in 0..len
    write = left / digits[cnt]
    left  = left - write * digits[cnt]
    if write > 0
      milions  = englishNumber write
      numString = numString + milions + digits_words[cnt]
      if left > 0
        numString = numString + ' '
      end
    end
  end


  write = left/10          #  今度は十の桁です。
  left  = left - write*10  #  そして十の桁をひきます。

  if write > 0
    if ((write == 1) and (left > 0))
      numString = numString + teenagers[left-1]
      left = 0
    else
      numString = numString + tensPlace[write-1]
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left  #  ここで、一の桁を書き出します。
  left  = 0     #  この桁を引きます。(0になります。)

  if write > 0
    numString = numString + onesPlace[write-1]
  end
  numString
end

puts englishNumber(  0)
puts englishNumber(100000101)
puts englishNumber(111111111)

milionやらbillionやらを,配列にしたので
trillionやらも処理ができる.

weddingNumberはどうでしょう? このプログラムはenglishNumber とほとんど同じように動作しますが、"and" という接続詞をやたらめったら挿入します。たとえば 'nineteen hundred and seventy and two' という具合に、結婚式の招待状のような感じで。もう少し例を挙げたいと思いましたが、私自身詳しくありません。結婚のコーディネータに訊いてみるのも良いでしょう。

WeddingNumberが何かが分からなかったので,プログラムの書きようがないという残念な結論.
何なんだろうね....

99本のビールが壁に..." englishNumberと以前作ったプログラムを使って、今度は正しい 方法でこの歌の詩を出力させなさい。その後は、9999から初めてコンピュータをこらしめましょう。 (ただ、あまり大きな数字を使うと、コンピュータといえども全部出力するのにかなりの時間を必要とします。10万本のボトルには、かなりの時間がかかります。もし、100万本のボトルなどとするとあなた自身がひどい目に会いますよ。

def englishNumber number
  if number < 0  #  負の数は不可です。
    return '負でない数を入力してください.'
  end
  if number == 0
    return 'zero'
  end

  numString = ''  #  これが最終的に返す文字列です。

  onesPlace = ['one',     'two',       'three',    'four',     'five',
               'six',     'seven',     'eight',    'nine']
  tensPlace = ['ten',     'twenty',    'thirty',   'forty',    'fifty',
               'sixty',   'seventy',   'eighty',   'ninety']
  teenagers = ['eleven',  'twelve',    'thirteen', 'fourteen', 'fifteen',
               'sixteen', 'seventeen', 'eighteen', 'nineteen']



  left  = number
  digits = [1000000,1000,100]
  digits_words =  [" milion"," thousand"," hundred"]
  cnt = 0
  #.lengthは要素の数を返します.
  len = digits.length - 1
  for cnt in 0..len
    write = left / digits[cnt]
    left  = left - write * digits[cnt]
    if write > 0
      milions  = englishNumber write
      numString = numString + milions + digits_words[cnt]
      if left > 0
        numString = numString + ' '
      end
    end
  end


  write = left/10          #  今度は十の桁です。
  left  = left - write*10  #  そして十の桁をひきます。

  if write > 0
    if ((write == 1) and (left > 0))
      numString = numString + teenagers[left-1]
      left = 0
    else
      numString = numString + tensPlace[write-1]
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left  #  ここで、一の桁を書き出します。
  left  = 0     #  この桁を引きます。(0になります。)

  if write > 0
    numString = numString + onesPlace[write-1]
  end
  numString
end

 englishNumber(  0)
puts englishNumber(100000101)
puts englishNumber(111111111)

def write beer_num
  while beer_num != 0
    num = englishNumber(beer_num)
    puts num + "Bottoles of beer on the wall"
    puts num + "Bottoles of beer on the wall"
    puts "take one down and pass it around"
    beer_num = beer_num - 1
    puts englishNumber(beer_num) + "Bottoles of beer on the wall"
  end
end


write 100

これで8章までおしまい.
作者,曰く,これで一応Rubyプログラマとして生きて行けるらいしぃ.
って事で,私も会食に行ってきます.