3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

闘魂プログラミング: Rubyで楽しむAtCoder Beginners Selection

Last updated at Posted at 2025-04-04

2025-02-10_07-46-21_436.jpg

(これまでいただいたQiitanたちと他のお人形さんたちもいっしょに記念撮影)

はじめに

プログラミングのスキルを向上させるために、私は現在、AtCoderのABC問題に挑戦しています。AtCoderは、アルゴリズムやデータ構造を中心にした問題解決能力を磨く場であり、自分との闘いでもあります。挑戦を通じてアントニオ猪木さんがおっしゃった「闘魂とは己に打ち克つこと、そして闘いを通じて己の魂を磨いていくこと」を体現する一つの活動と捉えています。

AtCoderとは

AtCoderは、日本発のオンラインプログラミングコンテストプラットフォームで、競技プログラミングの学習や実力を試す場として多くのエンジニアや学生に利用されています。プラットフォーム上では、さまざまなレベルの問題が提供されており、初心者から上級者まで幅広く挑戦することができます。

AtCoderの主な特徴として、以下の点が挙げられます:

  • 定期的なコンテスト: 毎週開催される「AtCoder Beginner Contest (ABC)」や「AtCoder Regular Contest (ARC)」を通じて、問題解決能力を継続的に向上させることができます
  • 多彩な問題: アルゴリズム、データ構造、数学、最適化など、幅広い分野の問題が揃っています
  • ランキングとレーティング: 参加者の成績に応じてレーティングが変動し、自分の成長を数値として確認することが可能です

特にABCは、初心者向けの問題が中心でありながら、後半の問題はやりごたえのあるものも多く、プログラミングスキルを基礎から応用まで段階的に磨けるのが魅力です。AtCoderは単なる練習の場ではなく、自己成長や目標達成のための重要なステップとして、国内外のエンジニアから高く評価されています。

AtCoder Beginner Contest (ABC)

AtCoder Beginner Contest (ABC)についての個人の見解です。
順にレベルが上がります。

どのプログラミング言語でも共通にある「順次、分岐、繰り返し」で問題のレベルを解説してみます。

A問題

順次、分岐で解けます。

B問題

順次、分岐に加えて繰り返しを使います。

C問題

順次、分岐、三重程度の多重繰り返しを使います。


コンテストによりその傾向は異なります。
D問題以降は競技プログラミングの訓練が必要です。訓練無しに解ける人は才能があります。うらやましい限りです。

何を「一般的」と定義するのかは諸説あると思いますが、数学的センスを必要とはしない「一般的な」プログラミングはC問題くらいまでできればなんとかなります。何の自慢にもなりませんが、私はそれで20年以上飯を喰ってきました。そして自分でも気づいている通り、それは何の自慢にもなりませんし、htmlのタグを手打ちするのが当たり前だった牧歌的な時代をだらっとすごしてきた人間の感傷かもしれません。若い人には高みを目指して欲しいと思っています。そしてそんな私を生温かい目で鑑賞していただければ幸いです。ポエムです。

ここで述べたのはあくまでも個人の見解です。


AtCoder Beginners Selection

今回は、AtCoder Beginners Selectionに挑戦します。

以前、Elixirで解いた記事があります。

PracticeA - Welcome to AtCoder

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

# 整数の入力
a = gets.chomp.to_i
# スペース区切りの整数の入力
b,c = gets.chomp.split(" ").map(&:to_i)
# 文字列の入力
s = gets.chomp
# 出力
puts("#{a+b+c} #{s}")

ABC086A - Product

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

a, b = gets.chomp.split(" ").map(&:to_i)
x = a * b

if x.odd?
  puts 'Odd'
else
  puts 'Even'
end

ABC081A - Placing Marbles

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

s = gets.chomp
a = s.split("")
filtered = a.filter { |item| item == '1' }
puts filtered.size

ABC081B - Shift only

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

gets
a = gets.chomp.split(" ").map(&:to_i)

count = (10**9).times do |i|
  if a.all? { |item| item.even? }
    a = a.map { |item| item / 2 }
  else
    break i
  end
end

puts count

ABC087B - Coins

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

a = gets.chomp.to_i
b = gets.chomp.to_i
c = gets.chomp.to_i
x = gets.chomp.to_i

count = 0

(0..a).each do |i|
  (0..b).each do |j|
    (0..c).each do |k|
      if (i * 500 + j * 100 + k * 50) == x
        count = count + 1
      end
    end
  end
end

puts count

ABC083B - Some Sums

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

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

array = (1..n).map do |i|
  s = i.to_s.split('').map(&:to_i).sum()
  if a <= s and s <= b
    i
  else
    0
  end
end

sum = array.sum()
puts sum

ABC088B - Card Game for Two

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

gets
a = gets.chomp.split(" ").map(&:to_i)
a = a.sort().reverse()

alice = 0
bob = 0

a.each_with_index do |a, i|
  if i.even?
    alice = alice + a
  else
    bob = bob + a
  end
end

puts alice - bob

ABC085B - Kagami Mochi

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

n = gets.chomp.to_i
array = []

(1..n).each do |i|
  array << gets.chomp.to_i
end

puts array.uniq.size

ABC085C - Otoshidama

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

n, y = gets.chomp.split(" ").map(&:to_i)

found = false

(0..n).each do |i|
  (0..(n - i)).each do |j|
    k = n - i - j
    #next if [i, j, k].any? { |item| item < 0 }
    sum = 10000 * i + 5000 * j + 1000 * k
    if sum == y
      puts "#{i} #{j} #{k}"
      found = true
      break
    end
  end

  break if found
end

if !found
  puts "-1 -1 -1"
end

ABC049C - 白昼夢

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

s = gets.chomp.reverse
words =  ['dream', 'dreamer', 'erase', 'eraser'].map(&:reverse)
found = false

(10**5).times do |i|
  break if s.length == 0
  found = false

  words.each do |word|
    if s.start_with?(word)
      s = s[(word.length)..-1]
      found = true
      break
    end
  end

  break if !found
end

if found
  puts 'YES'
else
  puts 'NO'
end

ABC086C - Traveling

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

def main
  n = gets.chomp.to_i
  array_of_arrays = []

  n.times do |i|
    array_of_arrays << gets.chomp.split(" ").map(&:to_i)
  end

  before_t = 0
  before_x = 0
  before_y = 0

  result = false

  array_of_arrays.each do |t, x, y|
    result = false
    d = (x - before_x).abs + (y - before_y).abs
    dt = (t - before_t).abs
    break if d > dt
    break if ((dt - d) % 2) == 1

    before_t = t
    before_x = x
    before_y = y
    result = true
  end

  if result
    puts 'Yes'
  else
    puts 'No'
  end
end

main()

ここまでが、 AtCoder Beginners Selection の問題です。

以下、適当に選んで解いた問題の解答をついでに載せておきます。

A - Doors in the Center

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

n = gets().chomp().to_i()

if n.even?
  left = (n - 2) / 2
  right = left
  puts "#{'-' * left}==#{'-' * right}"
else
  left = (n - 1) / 2
  right = left
  puts "#{'-' * left}=#{'-' * right}"
end

A - Thermometer

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

f = gets().chomp().to_f()

if f >= 38.0
  puts 1
elsif f >= 37.5
  puts 2
else
  puts 3
end

B - Full House 3

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

def main
  a = gets.chomp.split(' ').map(&:to_i)

  values = a.tally().values().sort().reverse()

  if values == [5, 2]
    puts 'Yes'
  elsif values == [4, 3]
    puts 'Yes'
  elsif values == [4, 2, 1]
    puts 'Yes'
  elsif values == [3, 3, 1]
    puts 'Yes'
  elsif values == [3, 2, 2]
    puts 'Yes'
  elsif values == [3, 2, 1, 1]
    puts 'Yes'
  else
    puts 'No'
  end
end

main()

B - Ticket Gate Log

問題文はリンク先をご参照ください。
それでは解答です。

私の解答

Ruby

def main
  a = gets.chomp.split('')
  count = 0


  1000.times do |i|
    if i > 1 && a[i - 1] == 'o' && a[i].nil?
      break
    end

    if i.even? && a[i] != 'i'
      count = count + 1
      a.insert(i, 'i')
    elsif i.odd? && a[i] != 'o'
      count = count + 1
      a.insert(i, 'o')
    end
  end

  puts count
end

main()

まとめ

本記事を書くことを通して得られた経験は、『闘魂とは己に打ち克つこと』という言葉の重みを再認識させてくれました。今後も未知の領域へ果敢に挑戦していきます。

あなたもお好きなプログラミング言語で、プログラミングという藝術活動を楽しんでください!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?