a = {
len = function( self )
return self.length
end,
wid = function( self )
return self.width
end,
insert = function( self, x, y, value )
if not self[ x ] then
error( "x value out of bounds", 2 )
end
if not self[ x ][ y ] then
error( "y value out of bounds", 2 )
end
self[ x ][ y ] = value
end,
getValue = function( self, x, y )
return self[ x ] and self[ x ][ y ] or nil
end,
}
mt = {
__type = "array",
__index = a,
__add = function( lhs, rhs )
if type( rhs ) ~= "table" then
error( "attempt to add array and " .. type( rns ), 2 )
elseif getmetatable( rhs ).__type ~= "array" then
error( "attempt to add array and table", 2 )
elseif lhs:len() ~= rhs:len() or lhs:wid() ~= rhs:wid() then
error( "arrays' dimensions are not equal", 2 )
end
local array = create( lhs:len(), lhs:wid() )
for x, tbl in ipairs( lhs ) do
for y, value in ipairs( rhs ) do
array:insert( x, y, rhs:getValue( x, y ) + lhs:getValue( x, y ) )
end
end
return array
end,
__sub = function( lhs, rhs )
if type( rhs ) ~= "table" and type( rhs ) ~= "number" then
error( "attempt to subtract array and " .. type( rhs ), 2 )
elseif getmetatable( rhs ).__type ~= "array" then
error( "attempt to subtract array and table", 2 )
elseif lhs:len() ~= rhs:len() or lhs:wid() ~= rhs:wid() then
error( "arrays’ dimensions are not equal", 2 )
end
local array = create( lhs:len(), lhs:wid() )
for x, tbl in ipairs( lhs ) do
for y, value in ipairs( rhs ) do
array:insert( x, y, rhs:getValue( x, y ) - lhs:getValue( x, y ) )
end
end
return array
end,
__mul = function( lhs, rhs )
if type( rhs ) ~= "table" and type( rhs ) ~= "number" then
error( "attempt to multiply array and " .. type( rns ), 2 )
elseif type( rhs ) == "table" and lhs:len() ~= rhs:wid() then
error( 'attempt to multiply ' .. lhs:len() .. ", " .. lys:wid() .. " array with " .. rhs:len() .. ", " .. rhs:wid() .. " array", 2 )
elseif type( rhs ) == "number" then
local array = create( lhs:len(), lhs:wid() )
for x = 1, lhs:len() do
for y = 1, lhs:wid() do
array:insert( x, y, lhs:getValue( x, y ) * rhs )
end
end
return array
elseif getmetatable( rhs ).__type ~= "array" then
error( "attempt to multiply array and table", 2 )
end
local array = create( lhs:len(), rhs:wid() )
for pos = 1, lhs:len() do
for column = 1, rhs:len() do
local value = 0
for x = 1, lhs:wid() do
value = value + lhs:getValue( pos, x ) * rhs:getValue( column, x )
end
array:insert( pos, column, value )
end
end
return array
end,
__div = function( lhs, rhs )
if type( rhs ) ~= "table" and type( rhs ) ~= "number" then
error( "attempt to divide array and " .. type( rhs ), 2 )
elseif type( rhs ) == "table" and getmetatable( rhs ).__type ~= "array" then
error( "attempt to divide array and table", 2 )
elseif type( rhs ) == "number" then
local array = create( lhs:len(), lhs:wid() )
for x = 1, lhs:len() do
for y = 1, lhs:wid() do
array:insert( x, y, lhs:getValue( x, y ) / rhs )
end
end
return array
end
--#what to do here...
end,
}
function create( length, width )
if length and width then
local array = { length = length, width = width }
for x = 1, length do
array[ x ] = {}
for y = 1, width do
array[ x ][ y ] = 0
end
end
setmetatable( array, mt )
return array
end
length.length = #length
length.width = #length[ 1 ]
setmetatable( length, mt )
return length
end