
【プログラミング学習】paiza・マップのナンバリング問題(後編)
お疲れ様です、上凪 羊です。
本日は予告通り、昨日の記事
の後編ということで、早速やっていきましょう。
おさらい
問題について等は上の記事を参照するということで、昨日は
D=1(右上方向へ対角線をどう書いていくか)
についてやっていました。
D=2は横、D=3は縦へのナンバリングということでループを二重で書いてcount += 1で数値を順々に書いていけばいいので割愛します。
ということで本日はD=4、左下方向への対角線を使ってマップをナンバリングしていくやり方についてです。
解答を導くために

再掲。このような形で座標(0,0)から順に数字を振っていきます。その方向が左下方向へ、となります。
d = 4(左下方向へのマッピング)・上端編
when 4
ans[0][0] = 1
count += 1
(1...w).each do |i|
(0..[i, h - 1].min).each do |j|
ans[j][i - j] = count
count += 1
end
end
ということで、昨日のD=1では右上へのマッピングということで(0,0)からスタートして左端の列(h, 0)が対角線のスタート地点となりました。
今回は左下方向へのマッピングにあたって、画像の例を見ると分かりやすいですが上端の行(0, w)がそれぞれ対角線のスタート地点と置けます。
まずは(1…w)の範囲をループさせます。
範囲の制限は、この場合は下への増加=hの増加が主になるということで、変数wであるiと、h - 1(一番最後の行のインデックス)のminを上限に。
ans[j][i - j]は昨日の左端編と対応します。
[j]が表すのは座標で言えばy座標、もともとの変数でいうとh、ということで左下へと対角線上をひとつひとつ置き換えていく際にはy座標の値は1ずつ増えていけばいいわけです。
対して[i - j]です。座標で言えばx座標。
変数wであるiから、jを引くことで左への移動をあらわします。
変数wが減少することが左への移動
変数hが増加することが下への移動
ということで、それらを組み合わせて左下へひとつずつ移動していくということになります。
d = 4(左下方向へのマッピング)・右端編
(1...h).each do |i|
(0...[h - i, w].min).each do |j|
ans[i + j][w - 1 - j] = count
count += 1
end
end
上端を右端までマッピングし終えたら、次に対角線のスタートとなるのは右端(h, 3)ですね(ここでは4行4列のマップを想定しています)。
ということで(1…h)の範囲のループになります。ループ内での範囲制限は先程と同じく、下への移動を主に考えて変数wと、h - iのminを上限に。
あとは、y座標については、昨日の内容と再び対応して、初期地点である右端かつ上端が既に書き換えられているため、基準地点をたさないといけないということで[i + j]になると。
x座標は[w - 1 - j]で、最後の列のインデックスであるw - 1から、左への移動ということで- jをしていきます。
終わりに
文章自体は引き続きとっ散らかったのですが、2日にわけて考えていったら、マップ問題への理解自体は強まった気がしてきました。
一点、処理の上で大事そうだと思ったポイントがありました
Hの増加→下への移動
Hの減少→上への移動
Wの増加→右への移動
Wの減少→左への移動
そして、上を組み合わせることで右上、右下、左上、左下への移動を実現させるという八方向の処理が可能になるということです。
おそらくマップ処理の肝だと思いますし、ようやく問題を解いてうんうん唸ったことでこの基本的な概念は入ってきた気がします。
乱筆になりましたが、マップ問題に取り組んだ学びみたいなものはなんとか書けたのかなと思います……。
これを踏まえて他のマップ問題も手を出してみて、理解をより強固にしていけるとよりよいですね。そこも目指して問題を解いていきましょう。
それでは、お読みくださりありがとうございます。