03

Task

演習 6 上の例題をそのまま動かして確認しなさい。OK なら、次のことをやってみなさい。

演習 8 配列を使った面白いと思うプログラムを作りなさい。

Program, execution and description

前回同様に、 Vec は各演算子を再定義することで、後から数字を指定できるようになります。 今回作成した Vec class のコードについては最後に記載しました。

Vec a ~ d では、_ 変数を引数のように扱うことで、演習 a ~ d までの式をつくりました。 Vec x ~ w は各方向の単位 Vector を <=> 演算子で指定して、Vec a に全て足しました。

.map は、値 v と index の i から、新しい Vec object がつくられます。 その他、 .size.sort などよく使われそうな機能を作成しました。

以上から、 a ~ d のコード は以下のようになります。

_, x, y, z, w = (0..4).map do Vec.new end a = _ + x + y + z + w b = _.map(->v, i{v > 0 ? v + 1 : v}) c = _.map(->v, i{_[(i - _.size / 2).to_i % _.size]}) d = _.sort x <=> [1, 0, 0, 0] y <=> [0, 1, 0, 0] z <=> [0, 0, 1, 0] w <=> [0, 0, 0, 1] puts " _ \t\t\t| a \t\t\t| b \t\t\t| c \t\t\t| d" puts " :- \t\t\t| :- \t\t\t| :- \t\t\t| :- \t\t\t| :-" (-3..3).map do |i| _ <=> [0, 1, i, -i] puts " #{_} \t| #{a} \t| #{b} \t| #{c} \t| #{d}" end

About Task

実行結果は以下のようになりました。

_ a b c d
[0, 1, -3, 3] [1, 2, -2, 4] [0, 2, -3, 4] [-3, 3, 0, 1] [-3, 0, 1, 3]
[0, 1, -2, 2] [1, 2, -1, 3] [0, 2, -2, 3] [-2, 2, 0, 1] [-2, 0, 1, 2]
[0, 1, -1, 1] [1, 2, 0, 2] [0, 2, -1, 2] [-1, 1, 0, 1] [-1, 0, 1, 1]
[0, 1, 0, 0] [1, 2, 1, 1] [0, 2, 0, 0] [0, 0, 0, 1] [0, 0, 0, 1]
[0, 1, 1, -1] [1, 2, 2, 0] [0, 2, 2, -1] [1, -1, 0, 1] [-1, 0, 1, 1]
[0, 1, 2, -2] [1, 2, 3, -1] [0, 2, 3, -2] [2, -2, 0, 1] [-2, 0, 1, 2]
[0, 1, 3, -3] [1, 2, 4, -2] [0, 2, 4, -3] [3, -3, 0, 1] [-3, 0, 1, 3]

Consideration

内積や外積、normalize など、よく使う演算を *, /, ! として再定義しました。 外積については 4次元以降は非常に複雑だったので、使いそうな3次元のみ対応しました。

また、Matrix については、時間内にdebugが出来ませんでしたが、今後作成する予定です。 コードとテストの実行結果については以下のようになりました。

a, b = (0..1).map do Vec.new end puts " a \t\t| b \t\t| a·b \t\t| a×b \t\t\t| a/(a*a)" puts " :- \t\t| :- \t\t| :- \t\t| :- \t\t\t| :-" (0..2).map do |i| (0..2).map do |j| a <=> [i, j * 2, 3] b <=> [4, i * 5, j * 6] puts " #{a} \t| #{b} \t| #{a*b} \t\t| #{a/b}\t\t| #{!a}" end end
a b a·b a×b a/√(a*a)
[0, 0, 3] [4, 0, 0] 0 [0, 12, 0] [0.0, 0.0, 1.0]
[0, 2, 3] [4, 0, 6] 18 [12, 12, -8] [0.0, 0.5547001962252291, 0.8320502943378437]
[0, 4, 3] [4, 0, 12] 36 [48, 12, -16] [0.0, 0.8, 0.6]
[1, 0, 3] [4, 5, 0] 4 [-15, 12, 5] [0.31622776601683794, 0.0, 0.9486832980505138]
[1, 2, 3] [4, 5, 6] 32 [-3, 6, -3] [0.2672612419124244, 0.5345224838248488, 0.8017837257372732]
[1, 4, 3] [4, 5, 12] 60 [33, 0, -11] [0.19611613513818404, 0.7844645405527362, 0.5883484054145521]
[2, 0, 3] [4, 10, 0] 8 [-30, 12, 20] [0.5547001962252291, 0.0, 0.8320502943378437]
[2, 2, 3] [4, 10, 6] 46 [-18, 0, 12] [0.48507125007266594, 0.48507125007266594, 0.7276068751089989]
[2, 4, 3] [4, 10, 12] 84 [18, -12, 4] [0.3713906763541037, 0.7427813527082074, 0.5570860145311556]

utils

def isNum (target) target.is_a? Numeric end def isArr (target) target.instance_of?(Array) end def isVec (target) target.instance_of?(Vec) end

Vec

class Vec def initialize(init = [1, 0, 0], args = 0) @v = init @n = args @_ = ->(v = @v, n = @n){Vec.new(v, n)} end def to_a() isArr(@v) ? @v : @v[@n] end def to_s() to_a.to_s end def size() to_a.size end def sum() to_a.sum end def sort() @_[->n{to_a.sort}] end def map(_) @_[->n{to_a.map.with_index{|v, i| _[v, i]}}] end def +(_) map(isNum(_) ? ->v, i{v + _} : ->v, i{v + _[i]}) end def -(_) map(isNum(_) ? ->v, i{v - _} : ->v, i{v - _[i]}) end def *(_) isNum(_) ? map(->v, i{v * _}) : map(->v, i{v * _[i]}).sum end def /(_) isNum(_) ? map(->v, i{v / _}) : cross(_) end def [](_) v = to_a; v[_] end def <=>(_) @v = _ end def >>(_) _ << @n end def <<(n) @_[@v, n] end def +@() map(->v, i{+v}) end def -@() map(->v, i{-v}) end def !@() self / Math::sqrt(self * self) end def cross(_) @_[->n{ v = _.to_a; [ @v[1] * v[2] - @v[2] * v[1], @v[2] * v[0] - @v[0] * v[2], @v[0] * v[1] - @v[1] * v[0],] }] end end