コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 040 A – 赤赤赤赤青

■はじめに

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

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

■問題

●出典

AtCoder Beginner Contest 040のA問題
https://atcoder.jp/contests/abc040/tasks/abc040_a

●問題文

n 個のブロックが一列に並んでいます。前から数えて x 個目のブロックだけが青色で、残りはすべて赤色です。

高橋君は、隣り合うブロックを交換する操作を何度か行って、青いブロックが列の端 (前から 1 番目かもしくは n 番目) に来るようにしようとしています。

最小で何回の操作が必要かを求めてください。

●制約

  • 1≦n≦100
  • 1≦x≦n

●入力

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

n x

●出力

必要な最小の操作回数を表す整数を 1 行に出力せよ。

■回答

●愚直に書く

まずは、先頭に持って行くのか末尾に持って行くのかを判断したい。
n-xxを比較して、xのが小さければ先頭に持って行くほうが早く、n-xのが小さければ末尾に持って行くのが早い。
n-xxのうち小さい方の数字から1を引いた数が、求めたい値、のはず…!

n, x = gets.split.map(&:to_i)
puts [n - x, x].min - 1

あれ、通らない…。

あ〜〜〜、先頭に持って行く場合と末尾に持って行く場合でちょっと計算が変わるのか。

n, x = gets.split.map(&:to_i)
puts [n + 1 - x, x].min - 1

通った!
でもなんか無理やり感があるな…。

●メソッド化して書く

→今日は割愛

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

マイナス1をminする前に持って行っても良いのでは?

n, x = gets.split.map(&:to_i)
puts [n - x, x - 1].min

通った!

●他の方の回答例

だいたい、上でリファクタリングしたのと同じ考え方だった。

●出てきたメソッド等

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

■振り返りなど

一回ミスったけどすぐ気づけて良かった。