コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 079 A – Good Integer

INDEX

■はじめに

Rubyの基礎的な問題をたくさん解くことで基本的な考え方やメソッドの使い方を定着させたい。
基本的にはAtCoderというプログラミングコンテスト(競技プログラミング)の過去問を使う。(AtCoderは難易度が分かれており、難易度の低いA問題かB問題を解いていく)

(5/23時点の方針)
メソッドの切り分け方や値の受け渡しを練習するために、コード長の短さについては気にせずに書くことにする。

(2022/10/17時点の方針)
しばらくはB問題を小さい番号の方からやっていく。たまにA問題もやるかも。

■問題

●出典

AtCoder Beginner Contest 079のA問題
https://atcoder.jp/contests/abc079/tasks/abc079_a

●問題文

1118 のような、3 つ以上の同じ数字が連続して並んだ 4 桁の整数を 良い整数 とします。
4 桁の整数 N が与えられるので、N が 良い整数 かどうかを答えてください。

●制約

  • 1000≦N≦9999
  • 入力は整数からなる

●入力

入力は以下の形式で標準入力から与えられる。

N

●出力

N が 良い整数 ならば Yes を、そうでなければ No を出力せよ。

■回答

●愚直に書く

えーと、1つずつ配列に入れて、要素が重複してたらまとめるようなメソッドがあった気がするのでそれをやって、まとめた後の要素数が1か2であれば大丈夫か?
いや、それだと1122みたいな時もまとめた後の要素数が2になるからダメだな。。。

うーん、愚直に考えて、まず配列の要素をsortして、1番目と2番目と3番目が等しければYesってことで良いか…?

やってみよう。

n = gets.chomp.split("").map(&:to_i).sort
if n[0] == n[1] && n[0] == n[2]
  puts "Yes"
else
  puts "No"
end

通った!
もうちょっとスマートな方法はありそう…!

●メソッド化して書く

メソッドを作る練習のために、あえてそういう書き方をする。

今日は割愛。

●リファクタリング/別アプローチ

絶対もっとシンプルにできそう、、、

やたら試行錯誤してしまったが、sortしているので、「1番目と2番目と3番目が等しければ」ではなく1番目と3番目が等しければ」だけで今回の条件は満たせそう。

n = gets.chomp.split("").map(&:to_i).sort
if n[0] == n[2]
  puts "Yes"
else
  puts"No"
end

通った!

三項演算子にして、

n = gets.chomp.split("").map(&:to_i).sort
puts n[0] == n[2] ? "Yes" : "No"

通った!

●他の方の回答例

アッ、正規表現…!
そうか正規表現でできたのか〜。
ただ、回答例を見てもどういう書き方になっているかよく掴めていない…。

puts gets[/(.)\1\1/]?:Yes: :No

/(.)\1\1/、特に\1がわからなかったのでChatGPTさんに聞いた。

なるほど、/(.)\1\1/は同じ文字が3回連続ということか。

あと以下の回答もあって、これは力技だけどわかりやすい…!

puts gets=~/111|222|333|444|555|666|777|888|999|000/ ? "Yes" : "No"

●出てきたメソッド等

公式リファレンスを見る訓練。

■振り返りなど

正規表現を思いつけず悔しかった。
あと正規表現の理解が浅く、もうちょっと勉強せねばと思った。