コンテンツへスキップ

【Ruby基礎】AtCoder Beginner Contest 004 B – 回転

  • by

INDEX

■はじめに

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

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

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

■問題

●出典

AtCoder Beginner Contest 004のB問題
https://atcoder.jp/contests/abc004/tasks/abc004_2

●問題文

高橋君は 4 x 4 マスの盤面を見つけました。
各マスには .ox のいずれかの文字が書かれています。
彼はこの盤面を回転させた後、どういった状態になるのか気になりました。
盤面を正面から見たときの状態が与えられるので、180 度回転させた後の盤面を出力してください。

●入力

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

c0,0 c0,1 c0,2 c0,3
c1,0 c1,1 c1,2 c1,3
c2,0 c2,1 c2,2 c2,3
c3,0 c3,1 c3,2 c3,3

1 行目から 4 行目にわたって、盤面の初期状態が半角スペース区切りで与えられる。

  • ci,j (0≦i,j≦3) は 盤面のマスを意味し、 .ox から構成される。

●出力

180 度回転させた後の盤面を入力と同じフォーマットで出力してください。
また、出力の末尾には改行を入れること。

■回答

●愚直に書く

1行ずつ標準入力をとって、

  • 1行目→4行目になって並び順は逆
  • 2行目→3行目になって並び順は逆
  • 3行目→2行目になって並び順は逆
  • 4行目→1行目になって並び順は逆

という処理を行えば良さそう。

c0 = gets.chomp.split
c1 = gets.chomp.split
c2 = gets.chomp.split
c3 = gets.chomp.split

a0 = c3.reverse
a1 = c2.reverse
a2 = c1.reverse
a3 = c0.reverse

puts a0.join(" ")
puts a1.join(" ")
puts a2.join(" ")
puts a3.join(" ")

通った!
とはいえすごい重複して書いているので、もう少し整理していきたい。

ひとまず、aの変数をやめてメソッドチェーンでつなぐ。

c0 = gets.chomp.split
c1 = gets.chomp.split
c2 = gets.chomp.split
c3 = gets.chomp.split

puts c3.reverse.join(" ")
puts c2.reverse.join(" ")
puts c1.reverse.join(" ")
puts c0.reverse.join(" ")

通った!
う〜んもう少し整理したいが…。

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

手探りで書いていたら結構短いコードでできた。

a = readlines
puts a.map{|n| n.delete("\n").reverse}.reverse

まずreadlinesで、行ごとの文字列が要素になった配列が取れる。
続いて、mapを使って要素ごと(=標準入力の行ごと)で処理するようにしてまずdeleteで改行タグの\nを取り除き、要素内の文字列をreverseする。
2個目のreverseは要素間のreverseということになり、これをすることで1行目と4行目、そして2行目と3行目が入れ替わり、求める状態になる。

●メソッド化して書く

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

def main
  a = read_lines
  puts rotate180(a)
end

def rotate180(a)
  a.map{|n| n.delete("\n").reverse}.reverse
end

def read_lines
  readlines
end

main

通った!

●他の方の回答例

最短コード、21byteってまじですか笑。

puts`dd`.chop.reverse

ddというのを使っている。たまに見るけど、unixのコマンドらしい。これで4行丸ごと180度回転できるのか。

●出てきたメソッド等

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

■振り返りなど

愚直な回答から別解もできて、良かった。