「す」「る」をランダムに表示して、「するすす」の並びが出現したらかかった文字数表示して終了する

このRubyスクリプトの解説でも書いてみようかなと。

i = 1

文字数のカウント……ですが、コレいらなかったんですよね。なぜ不要なのかはあとで説明します。

suru = [‘す’, ‘る’]

文字選択候補の配列です。この中から文字を毎回選択していきます。

srss = []

結果格納用の配列です。文字列ではなくあえて配列。

result = ”

結果表示用の文字列です。要は人間様向けの格納場所。

loop do

ここから無限ループが始まります。そのままだと本当に無限に繰り返してしまうのでbreakで抜け出してます。他の言語だとwhile(true)とかで無限ループを作れますが、Rubyだとloopで一発です。

  c = suru.sample

配列suruから「文字」アイテムを1個ランダムに選択してcに格納しています。Rubyらしさを出したかった場所その1です。乱数を意識しなくてもランダムにアイテムを取り出せるのがいいなって。乱数を使うのが目的じゃない、やりたいのはランダムにアイテムを選びたいんだ、そういう感じです。

  srss.push(c)

先ほど選んだ文字を結果格納用の配列の末尾に追加します。

  result << c

同様に、結果表示用の文字列にも追加します。

  if srss.length >= 4 && srss[-4, 4].join == ‘するすす’

文字数が4文字以上になったら、するすす完成チェックをするところです。Rubyらしさを出したかった場所その2です。Rubyの場合、配列の添え字に負数を入れると、後ろからいくつ目という指定ができます。そして、2番目のパラメーターで長さを指定しています。つまりこれは、うしろから4番目を始点として4つ取り出す、つまりうしろ4つを取り出すという意味になります。そしてそれをjoinで連結して4文字の文字列を作成し、’するすす’と一致するかを見ています。

この添え字に負数を入れられるのが結構お気に入りです。これがやりたくて配列にしたといっても過言じゃないです。

    result << “\n” + ‘-‘ * 10
result << “#{i}文字目で完成しました。\n”
break

するすす完成時の処理です。結果表示用の文字列に何文字目で完成したかを追加し、breakで先ほどの無限ループから脱出しています。

  elsif i >= 128

念のため、128文字まで行っても完成しなかった場合に打ち切る処理を作ります。

    result << “\n” + ‘-‘ * 10
result << “#{i}文字目まで来ましたが完成しませんでした。\n”
break

完成時のときと同様に、何文字目までいったが完成しなかったことを結果表示用の文字列に追加し、breakで先ほどの無限ループから脱出しています。

  end

一連の条件分岐の終わりです。

  i += 1

文字数カウンタのインクリメント(1加算)です。

end

無限ループの終端です。

さて、先ほどiは不要だと言いました。なぜ不要なのかというと、srss.lengthで文字数が判明するからです。iをsrss.lengthで置き換えて、初期化とインクリメントを消せばよかったわけです。あとでみかえすと詰めが甘いというかなんというか。

短いスクリプトですが、Rubyらしさ主張を2カ所(loopもいれれば3カ所かな)いれてあるのがちょっとしたこだわりです。

見る人が見たらつっこみどころもあるかもですが、とりあえずこんな感じで。