Ruby で解く AtCoder 第一回アルゴリズム実技検定 A 例外処理


はじめに

AtCoder Problems の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

今回のお題

AtCoder 第一回アルゴリズム実技検定 A - 2 倍チェック
Difficulty: ???

今回のテーマ、例外処理

基本に忠実であれば正規表現で解答しますが、Ruby をより深く理解するために例外処理で解答したいと思います。

Ruby 正規表現

3文字とも数字だったらのパターン

ruby1.rb
s = gets.chomp
puts (/[0-9]{3}/ === s ? s.to_i * 2 : 'error')

s = gets.chomp
puts (s.match(/[0-9]{3}/) ? s.to_i * 2 : 'error')

1文字でも英小文字だったらのパターン

ruby2.rb
s = gets.chomp
puts (/[a-z]/ === s ? 'error' : s.to_i * 2)

s = gets.chomp
puts (s.match(/[a-z]/) ? 'error' : s.to_i * 2)

1文字でも数字以外だったらのパターン

ruby3.rb
s = gets.chomp
puts (/[^0-9]/ === s ? 'error' : s.to_i * 2)

s = gets.chomp
puts (s.match(/[^0-9]/) ? 'error' : s.to_i * 2)

Ruby to_i (WA)

to_iを直接適用したパターン

ruby4.rb
s = 'abc'
puts s.to_i # => 0
s = '42A'
puts s.to_i # => 42

リファレンス整数とみなせない文字があればそこまでを変換対象とします。とありますので、ここまでです。

Ruby Rational (AC)

Rationalを適用したパターン

ruby5.rb
s = gets.chomp
begin
  Rational(s)
rescue
  puts 'error'
else
  puts s.to_i * 2
end

例外処理の制御構造は次の通りです。

rescue.rb
begin
  # 例外が発生する可能性のある処理
[rescue [error_type,..] [=> evar] [then]
  # 例外が発生した時の処理
[else
  # 例外が発生しなかった時の処理]
[ensure
  # 例外に関係なく実行される処理]
end

begin else ensure は省略可能です。

普段はあまり使用しないRationalですが、「1/3」のような有理数を扱うクラスです。
to_rですと先頭の数字を解釈しますが、Rationalですと上手く例外が発生するようです。

ruby6.rb
puts '0x8'.to_r     # => 0/1
puts Integer('0x8') # => 8
puts Float('0x8')   # => 8.0
puts Complex('0x8') # => ArgumentError
puts Complex('08i') # => 0+8i

Complexは複素数を扱うクラスで、0x8では例外が発生するのですがiを含む文字列はすり抜ける可能性があります。

標準出力する際にto_iを使用するのが心苦しいと申しますか、やはり普通に正規表現を使用するのがいいと思います。

まとめ

  • 第一回アルゴリズム実技検定 A を解いた
  • Ruby に詳しくなった
  • 素直に正規表現を使用しましょう

参照したサイト
AtCoderでRuby学習8【第一回アルゴリズム実技検定 2倍チェック 】正規表現
instance method String#to_i
class Rational
制御構造