AOJ 0141 Spiral Pattern (Ruby)
問題。
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0141&lang=ja
「ぐるぐる模様」を出力します。簡単そうでかなりむずかしかったので、印象に残っています。
6番目の「ぐるぐる模様」 ###### # # # ## # # # # # # # # ####
コード。
result = [] gets.to_i.times do n = gets.to_i field = Array.new(n) {" " * n} x, y = 0, n - 1 go = ->(dx, dy, l) { l.times do field[y][x] = "#" x += dx y += dy end } square = ->(l) { if l != 1 go.(0, -1, l - 1) go.(1, 0, l - 1) go.(0, 1, l - 1) if l != 3 go.(-1, 0, l - 3) if l != 4 if l > 4 go.(0, -1, 2) square.(l - 4) end return end end end field[y][x] = "#" } square.(n) result << field.map {|l| l + "\n"}.join end puts result.join("\n")
解説
- まず、キャンバス
field[][]
の左下に、開始位置 (x
,y
) をセットします。 go.(dx, dy, l)
は、(dx, dy) 方向に l ステップだけ描画して、(x, y) を進めます。- まず (x, y) に # を置いてから、ステップを進めるという順です。
square.(l)
は l 番目の「ぐるぐる模様」のいちばん外側一周を描き、(x, y) を進めます。- l > 4 の場合は、外周一周を描いたら、2ステップ上に進んで、square.(l - 4) を再帰的に呼びます。
- l <= 4 の場合はややこしくて、場合分けがたくさんあります。
square.(l)
は、冗長でも case ~ when 式で書けばもっとすっきりしましたね。
こんな感じか。
square = ->(l) { case l when 1 field[y][x] = "#" when 2 go.(0, -1, 1) go.(1, 0, 1) field[y][x] = "#" when 3 go.(0, -1, 2) go.(1, 0, 2) go.(0, 1, 2) field[y][x] = "#" when 4 go.(0, -1, 3) go.(1, 0, 3) go.(0, 1, 3) go.(-1, 0, 2) else go.(0, -1, l - 1) go.(1, 0, l - 1) go.(0, 1, l - 1) go.(-1, 0, l - 3) go.(0, -1, 2) square.(l - 4) end }
これだと平凡ですね。