Advertisement
King0fGamesYami

Matrix

Sep 9th, 2014
453
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local a = {
  2.     len = function( self )
  3.         return self.length
  4.     end,
  5.     wid = function( self )
  6.         return self.width
  7.     end,
  8.     insert = function( self, x, y, value )
  9.         if not self[ x ] then
  10.             error( "x value out of bounds", 2 )
  11.         end
  12.         if not self[ x ][ y ] then
  13.             error( "y value out of bounds", 2 )
  14.         end
  15.         self[ x ][ y ] = value
  16.     end,
  17.     getValue = function( self, x, y )
  18.         return self[ x ] and self[ x ][ y ] or nil
  19.     end,
  20.     draw = function( self, a, b )
  21.         term.setCursorPos( a, b )
  22.         local maxNum = 0
  23.         local maxDec = 0
  24.         for x = 1, self:len() do
  25.             for y = 1, self:wid() do
  26.                 local v = tostring( self:getValue( x, y ) )
  27.                 if #v > maxNum then
  28.                     maxNum = #v
  29.                 end
  30.             end
  31.         end
  32.         maxNum = maxNum + 1
  33.         for x = 1, self:len() do
  34.             for y = 1, self:wid() do
  35.                 local value = self:getValue( x, y )
  36.                 term.write( value .. string.rep( " ", maxNum ) )
  37.             end
  38.             local _, b = term.getCursorPos()
  39.             term.setCursorPos( a, b + 1 )
  40.         end
  41.     end,
  42.     transpose = function( self )
  43.         local array = create( self:wid(), self:len() )
  44.         for pos = 1, self:len() do
  45.             for column = 1, array:len() do
  46.                 array:insert( column, pos, self:getValue( pos, column ) )
  47.             end
  48.         end
  49.         return array
  50.     end,
  51.     trace = function( self )
  52.         local v = 0
  53.         for x = 1, self:len() do
  54.             for y = 1, self:wid() do
  55.                 v = v + self:getValue( x, y )
  56.             end
  57.         end
  58.         return v
  59.     end,
  60. }
  61.  
  62. local mt = {
  63.     __metatable = { __type = "matrix" },
  64.     __index = a,
  65.     __add = function( lhs, rhs )
  66.         if type( rhs ) ~= "table" then
  67.             error( "attempt to add matrix and " .. type( rns ), 2 )
  68.         elseif getmetatable( rhs ).__type ~= "matrix" then
  69.             error( "attempt to add matrix and table", 2 )
  70.         elseif lhs:len() ~= rhs:len() or lhs:wid() ~= rhs:wid() then
  71.             error( "matrices' dimensions are not equal", 2 )
  72.         end
  73.         local array = create( lhs:len(), lhs:wid() )
  74.         for x, tbl in ipairs( lhs ) do
  75.             for y, value in ipairs( rhs ) do
  76.                 array:insert( x, y, rhs:getValue( x, y ) + lhs:getValue( x, y ) )
  77.             end
  78.         end
  79.         return array
  80.     end,
  81.     __sub = function( lhs, rhs )
  82.         if type( rhs ) ~= "table" and type( rhs ) ~= "number" then
  83.             error( "attempt to subtract matrix and " .. type( rhs ), 2 )
  84.         elseif getmetatable( rhs ).__type ~= "matrix" then
  85.             error( "attempt to subtract matrix and table", 2 )
  86.         elseif lhs:len() ~= rhs:len() or lhs:wid() ~= rhs:wid() then
  87.             error( "matrices' dimensions are not equal", 2 )
  88.         end
  89.         local array = create( lhs:len(), lhs:wid() )
  90.         for x, tbl in ipairs( lhs ) do
  91.             for y, value in ipairs( rhs ) do
  92.                 array:insert( x, y, rhs:getValue( x, y ) - lhs:getValue( x, y ) )
  93.             end
  94.         end
  95.         return array
  96.     end,
  97.     __mul = function( lhs, rhs )
  98.         if type( rhs ) ~= "table" and type( rhs ) ~= "number" then
  99.             error( "attempt to multiply matrix and " .. type( rns ), 2 )
  100.         elseif type( rhs ) == "table" and lhs:len() ~= rhs:wid() then
  101.             error( 'attempt to multiply ' .. lhs:len() .. "x" .. lys:wid() .. " matrix with " .. rhs:len() .. "x" .. rhs:wid() .. " matrix", 2 )
  102.         elseif type( rhs ) == "number" then
  103.             local array = create( lhs:len(), lhs:wid() )
  104.             for x = 1, lhs:len() do
  105.                 for y = 1, lhs:wid() do
  106.                     array:insert( x, y, lhs:getValue( x, y ) * rhs )
  107.                 end
  108.             end
  109.             return array
  110.         elseif getmetatable( rhs ).__type ~= "matrix" then
  111.             error( "attempt to multiply matrix and table", 2 )
  112.         end
  113.         local array = create( lhs:len(), rhs:wid() )
  114.         for pos = 1, lhs:len() do
  115.             for column = 1, rhs:len() do
  116.                 local value = 0
  117.                 for x = 1, lhs:wid() do
  118.                     value = value + lhs:getValue( pos, x ) * rhs:getValue( column, x )
  119.                 end
  120.                 array:insert( pos, column, value )
  121.             end
  122.         end
  123.         return array
  124.     end,
  125.     __eq = function( o1, o2 )
  126.         if o1:len() ~= o2:len() or o1:wid() ~= o2:wid() then
  127.             return false
  128.         end
  129.         for x = 1, o1:len() do
  130.             for y = 1, o1:wid() do
  131.                 if o1:getValue( x, y ) ~= o2:getValue( x, y ) then
  132.                     return false
  133.                 end
  134.             end
  135.         end
  136.         return true
  137.     end,
  138.     __lt = function( o1, o2 )
  139.         return o1:trace() < o2:trace()
  140.     end,
  141.     __le = function( o1, o2 )
  142.         return o1:trace() > o2:trace()
  143.     end,
  144.     __pow = function( lhs, rhs )
  145.         if type( rhs ) ~= "number" then
  146.             error( "attempt to perform arithmatic __pow on matrix and " .. type( rhs ), 2 )
  147.         end
  148.         local array = create( lhs:len(), lhs:wid() )
  149.         for x = 1, lhs:len() do
  150.             for y = 1, lhs:wid() do
  151.                 array:insert( x, y, lhs:getValue( x, y ) ^ rhs )
  152.             end
  153.         end
  154.         return array
  155.     end,
  156.     __div = function( lhs, rhs )
  157.         if type( rhs ) ~= "number" and type( rhs ) ~= "table" then
  158.             error( "Attempt to divide matrix by " .. type( rhs ), 2 )
  159.         elseif type( rhs ) == "table" and getmetatable( rhs ).__type == "matrix" then
  160.             error( "Attempt to divide matrix by matrix", 2 )
  161.         end
  162.         local array = create( lhs:len(), lhs:wid() )
  163.         for x = 1, lhs:len() do
  164.             for y = 1, lhs:wid() do
  165.                 array:insert( x, y, lhs:getValue( x, y ) / rhs )
  166.             end
  167.         end
  168.         return array
  169.     end,
  170.     __call = function()
  171.         error( "attempt to call matrix", 2 )
  172.     end,
  173. }
  174.  
  175. function create( length, width )
  176.     if length and width then
  177.         local array = { length = length, width = width }
  178.         for x = 1, length do
  179.             array[ x ] = {}
  180.             for y = 1, width do
  181.                 array[ x ][ y ] = 0
  182.             end
  183.         end
  184.         setmetatable( array, mt )
  185.         return array
  186.     end
  187.     length.length = #length
  188.     length.width = #length[ 1 ]
  189.     setmetatable( length, mt )
  190.     return length
  191. end
Advertisement
RAW Paste Data Copied
Advertisement