鍋あり谷あり

テーマを決めずに適当に書いています。

筑波の ruby の 23番

Ruby プログラミング 50題」
http://klis.tsukuba.ac.jp/klib/index.php?plugin=attach&refer=KISL%2Ftop&openfile=ruby.pdf
という素晴らしい資料を筑波大学が公開している。

で。

この 23番。

tango = ["knowledge", "information", "system" , "library", "metadata"]

while true
  print("単語を入力してください\n")
  print("終わる時は . (ピリオド) を入力してください\n")
  a = gets.chomp
  if a == "."
    break
  end

  j=0
  while j < tango.size
    if a == tango[j]
      print(a, "は辞書に登録されています\n")
      break
    end
    j=j+1
  end
  if j == tango.size
    print(a, "を登録します\n")
    tango.push(a)
  end
end
tango.each{|value|
  print(value, "\n")
}

j をループカウンタにした while ループが難しい。

  • 事前条件 : tango.size は 5。a は未登録の単語 "hoge" にしておこう。
  • while文 : j は 0。j<tango.size は true なので ループ内に入る。
  • a==tango[j] は "hoge"=="knowledge" という意味なので、false。
  • break しなかったので、j=j+1 が実行され、j の値が 1になる。
  • 中略
  • break しなかったので、j=j+1 が実行され、j の値が 5なる。
  • while文 : j は 5。j<tango.size は false なのでループ終了
  • if j==tango.size に到達。5==5 ということなので、true。
  • print(a, "を登録します\n") を実行
  • tango.push(a) を実行。tango.size が 6 になる。

ということなんだけど、箇条書きにしただけなので説明できてないような気もする。

while の中で一度も a == tango[j] が true にならなかった場合、j が tango.size と等しくなるまで増えていく。
ので、while を終えた時点で j と tango.size が等しくなる。
逆に。
while の中で a==tango[j] が true になった場合、その時点で終了するので、while ループを抜けた段階での j は tango.size より小さくなる。
表にしようか。

状況 while ループを抜けた段階での jの値
a==tango[j] が true になったので break した 0以上で、tango.size より小さい
a==tango[j] が 一度も true にならなかった tango.size に等しい
起こりえない状況 tango.size より大きい
こんな感じ。 起こりえない状況が条件に混入しても困らないので、 もとのソースで
  if j == tango.size
となっている if 文 の == となっている部分は、== でも >= でも構わないけど、<= だと困る。 ということなんだけど、こんな説明でいい?

蛇足

私は、 chomp も chop も書かないようにしている。どっちが何なのか覚えられないし、状況によって変な動作になるのでちょっとこわい。 strip の方がいいと思う。