はじめに
前回の記事から一年近くたっていますが、Numo::NArray
の学習を含めて、久々に取り組みたいと思います。
Numo::NArray
require.rb
require 'numo/narray'
include Numo
new.rb
@banmen = UInt32.zeros(h, w)
XXX.zeros
で、初期値0
h
行w
列の行列を生成します。
cast.rb
@uramen = NArray.cast(Array.new(h){ Array.new(w){ (1..9).to_a } })
NArray.cast
を使用するとRuby
の配列から行列を生成することができます。
ここでは、3次元の行列をイメージします。
初期状態では、1~9のすべての数値の可能性があります。
ここで、角に3
が設定されたとします。
すると行、列、ブロックの三つで3
を消すことができます。
初期の配置が決まるたびに、積まれたダイスが次々に落とされるイメージをコーディングします。
今回のソース
narray01.rb
require 'numo/narray'
include Numo
h = w = 9
@banmen = UInt32.zeros(h, w)
@uramen = NArray.cast(Array.new(h){ Array.new(w){ (1..9).to_a } })
def mask(h, w, num)
return if num == 0
h2 = (h / 3) * 3
w2 = (w / 3) * 3
maskarray = @uramen[h, w, 0..].eq(num)
@uramen[h, w, 0..] *= maskarray # 数値の設置用マスク
maskarray = @uramen[h, 0.., 0..].ne(num)
@uramen[h, 0.., 0..] *= maskarray # 行のマスク
maskarray = @uramen[0.., w, 0..].ne(num)
@uramen[0.., w, 0..] *= maskarray # 列のマスク
maskarray = @uramen[h2..h2+2, w2..w2+2, 0..].ne(num)
@uramen[h2..h2+2, w2..w2+2, 0..] *= maskarray # ブロックのマスク
end
h.times do |i|
a = gets.chomp.split('').map(&:to_i)
a.each_with_index do |x, j|
@banmen[i, j] = x
mask(i, j, x)
end
end
今回のポイントはマスク処理です。
maskarray.rb
require 'numo/narray'
include Numo
@uramen = NArray.cast([1, 2, 3, 4, 5, 6, 7, 8, 9])
maskarray = @uramen.eq(3)
p maskarray
# Numo::Bit#shape=[9]
# [0, 0, 1, 0, 0, 0, 0, 0, 0]
@uramen *= maskarray
p @uramen
# Numo::Int32#shape=[9]
# [0, 0, 3, 0, 0, 0, 0, 0, 0]
eq
で等しいとき、ne
で等しくないとき、0
と1
で構成された行列を生成し行列演算を行うことにより、不要な数値を0
に置換します。
まとめ
今回は、画像生成で力尽きました。