概要
ABC317(ゲームフリーク Programming Contest 2023)のF問題で多次元配列が必要な問題が出題されました。特に工夫せずにやると7次元配列が必要です。
Crystal言語で配列の作り方はRubyと基本は同じです。2~3次元だとその場で書いてしまいますが、4次元を超えてくると辛いのでmacroを制作したので紹介します。
基本
Crystalの普通の1次元配列は
ar = Array(Int64).new(n, 0i64)
が基本です。ただ、型推論が効くので、
ar = Array.new(n, 0i64)
のように型を省略しても良いです
2次元の場合は、
ar = Array.new(n1) {Array.new(n2, 0) }
または、
ar = Array.new(n1) {Array.new(n2) { 0 } }
です。2つ目の配列をブロックにせずに
# これは間違いです!
ar = Array.new(n1, Array.new(n2, 0) )
と書いてしまうと、大変なバグになるのはRubyと同じです。
参考:
https://qiita.com/konchan_exbaka/items/46fde0869d3d5ec7d365
以上を踏まえると3次元は
ar = Array.new(n1) {Array.new(n2) { Array.new(n3) {0} } }
という感じです。4次元以上は明らかですね
多次元配列作成macro
Crystalにはmacroという仕組みがあり、コンパイル前にコードを展開してくれる方法があります。
これがかなり高機能で、ifやforなど基本的なプログラミングができます。そこで、多次元配列を生成するmacroを作ってみました。
macro make_array(initial, *a)
{% for i in 0...a.size %}
Array.new({{a[i]}}) {
{% end %}
{{initial}}
{% for i in 0...a.size %}
}
{% end %}
end
使い方は
ar = make_array(初期値, 1つ目の次元の大きさ, 2つ目の次元の大きさ, ...)
という感じです。型は初期値の型で決まるので注意してください。
例えば
ar = make_array(0, 2, 3, 4)
とすると、型は1つ目の0のInt32で初期値が0で2×3×4の3次元配列が作れます
まとめ
4次元以上の配列を作ることは滅多にないですが、たまに作るときに役立つと思います。何かの役に立てば幸いです。