21歳未経験からRailsエンジニアになるまで

21歳フリーターの僕がrailsエンジニアになるまでを自分なりに書いていくブログです。

AtCoderをRubyで解いてみた!!(前編)

来たるコーディングテストへの対策として何が一番いいのか色々試しております。

 

その中で日本語&他の人の回答も見れるという点からAtCoderというサイトにたどり着きました!!(こりゃいいぞ)

自分の回答と照らし合わせてより良いコードとも照らし合わすことができるのでこりゃ最高ってことで自分なりに解いて見直しをしてみました!!

 

atcoder.jp

それじゃあ行ってみよう!!

 

 

 

前提


 まずこちらの

AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~ - Qiita

の10問をRubyで自分なりに解きました。

こちらを別のタブで開き問題をみながら解いてみてください!

 

次にこちらの

AtCoder に登録したら解くべき精選過去問 10 問を Ruby で解いてみた - Qiita

を参考にリファクタリングしました!!

 

いやぁ、とても勉強になる。

Paizaなどはたとえ自分が合っていたとしても他の回答がみられないので僕みたいな経験がない身からするとやりずらかったです。

 

第1問


 

*自分*

a, b = gets.split.map(&:to_i)
puts (a * b).even? ? 'Even' : 'Odd' 

 *模範*

a, b = gets.strip.split.map(&:to_i)
puts (a * b).even? ? 'Even' : 'Odd' 

 *ポイント*

 if分は3項演算子でシンプルにすればコードが短く書ける。

条件演算子(?:) - 条件分岐 - Ruby入門

第2問


 

*自分*

s = gets.split("").map(&:to_i)
puts s.sum 

*模範*

puts gets.strip.split("").map(&:to_i).inject(:+) 

*ポイント*

・ sumメソッドはRubyバージョン2.4以降から利用できるメソッドみたい。

 どうやらAtCoderRubyバーションは2.3だから使えない。

・模範はinjectメソッドを使っているがこれからの事を考えて覚えておく必要性はない気がする。

・わざわざ変数に入れなくても

puts gets.split("").map(&:to_i).sum

としてもよかった。

第3問


 

*自分*

回答できませんでした。 

*模範*

 _n = gets.to_i
as = gets.strip.split.map(&:to_i)
cnt = 0
while as.all?(&:even?) do
      cnt = cnt.succ
      as = as.map { |a| a / 2 }
end

puts cnt

*ポイント*

・ 『全てが偶数である』という判別にall?という便利なメソッドがある。

・ Whileのループ技もしかっかり身につけたいところ

all? (Enumerable) - Rubyリファレンス

第4問


 

*自分*

 回答できませんでした。

*模範*

 a, b, c, x = 4.times.map { gets.to_i }
cnt = 0
(0..a).each do |i|
  (0..b).each do |j|
    (0..c).each do |k|
                      cnt += 1 if i * 500 + j * 100 + k * 50 == x
          end
     end
end

puts cntputs cnt

*ポイント*

 ・同形式の複数の標準入力はtimesメソッドで受け取る。(コードが簡潔)

・複数の変数の組み合わせはeachメソッドで入れ子の繰り返しを行う

・後置if文記法を使う(コードが簡潔)

第5問


 

*自分*

n, a, b = gets.split(" ").map(&:to_i)n, a, b = gets.split(" ").map(&:to_i)

result = []

(1..n).each do |m|

     result << m if m.to_s.split("").map(&:to_i).sum.between?(a, b)

end

puts result.sum

*模範*

n, a, b = gets.strip.split.map(&:to_i)

n,a,b = STDIN.gets.chomp.split(" ").map(&:to_i)
result = 0

(1..n).each do |i|
    j = i
    sum = 0
    while j > 0
       sum += j % 10
       j = j / 10
    end
    if sum >= a && sum <= b
        result += i
    end
end

puts result 

*ポイント*

・各桁の和を求めるには10で割った余りの合計を足していく方が主流だそうです。

・後置if文て結構便利なんだなってこんぐらいから痛感する。

betweenメソッドは初めて触れたが使い勝手がいい。

between? (Comparable) - Rubyリファレンス

 

感想


 

いざやってみるとプログラミングって難しいと改めて実感しますね。

しかし、論理立てて1つ1つ解いていくのはやはり楽しさの1つですね。

*1『チェリー本』で基礎は学習意しておりますが、その他での重要さはズバリ

『メソッド』だと感じました。

いくら配列や文字列の仕組みを理解できてもそこに変化を与えるメソッドを覚えないと意味がないと感じました。

コーディングテストに向けてさらに勉強あるのみですね。

後編は近々あげま〜す!!(自己満)

それじゃバイバイ!!

 

*1チェリー本