import vector
def missing is public, readable = object{
method asString->String{"-"}
}
type Iterator = {
reset->Void
hasNext->Boolean
get->T
next->T}
type Vector = {
size->Number
isEmpty->Boolean
clear->Void
contains(_:T)->Boolean
addFirst(_:T)->Void
addLast(_:T)->Void
firstElement->T
lastElement->T
removeFirst->T
removeLast->T
removeValue(_:T)->T
indexOf(_:T)->Number
at(_:Number)->T
setValue(_:T)at(_:Number)->T
add(_:T)at(_:Number)->Void
removeFromIndex(_:Number)->T
iterator->Iterator
asString->String
forEachDo(_:Block)->Void
map(_:Block)->Vector
ensureCapacity(_:Number)->Void
capacity->Number
copyInto(_)->Void
indexOf(_:T)startingFrom(_:Number)->Number
setSize(_:Number)->Void
trimToSize->Void}
type Matrix = {
atRow(_:Number)Col(_:Number)->T
setValue(_:T)atRow(_:Number)Col(_:Number)->Void
addRowAt(_:Number)->Void
addColAt(_:Number)->Void
removeRowAt(_:Number)->Vector
removeColAt(_:Number)->Vector
columns->Number
rows->Number
asString->String}
method new->Matrix is public{MatrixClass.new(0, 0)}
method withRows(h:Number)columns(w:Number)->Matrix is public{
if((h >= 0) && (w >= 0)) then {MatrixClass.new(h, w)}
else{
print "Must have non-negative rows and columns"
new}
}
class MatrixClass.new(h:Number, w:Number) {
var height:Number is readable := h
var width:Number is readable:= w
var index:Vector is readable := vector.withSize(height)
for(1..height) do {i->
var theRow:Vector := vector.withSize(width)
index.addLast(theRow)
for(1..width) do {j-> theRow.addLast(missing)}
}
// Fetch element from matrix
// @pre 0 < row <= height, 0 < col <= width
// @post @return object at (row, col)
// @param row the row of the element
// @param col the column of the element
method atRow(row:Number)Col(col:Number)->Dynamic is public{
if((0 < row)&&(row <= height)&&(0 < col)&&(col <= width)) then{
index.at(row).at(col)}
else{
print "Invalid index"
missing}
}
// Change value at location (row, col)
// @pre 0 < row <= height, 0 < col <= width
// @post changes location (row, col) to value
// @param value the new object reference
// @param row the row of value to be changed
// @param col the column of value to be changed
method setValue(value)atRow(row:Number)Col(col:Number)->Void is public{
if((0 < row)&&(row <= height)&&(0 < col)&&(col <= width)) then{
index.at(row).setValue(value)at(col)}
else{print "Invalid index"}
}
// Add a new row, whose index will be r
// @pre 0 < r <= height + 1
// @post inserts row of null values to be row r
// @param r the index of the newly inseted row
method addRowAt(r:Number)->Void is public{
if((0 < r) && (r <= (height + 1))) then{
height := height + 1
var theRow:Vector := vector.withSize(width)
for(1..width) do {i->theRow.addLast(missing)}
index.add(theRow)at(r)}
else{print "Invalid row index"}
}
// Add a new column, whose index will be c
// @pre 0 < c <= width + 1
// @post inserts column of null values to be column c
// @param c the index of the newly inserted column
method addColAt(c:Number)->Void is public{
if((0 < c) && (c <= (width + 1))) then{
width := width + 1
for(1..height) do {i->
index.at(i).add(missing)at(c)}
}
else{print "Invalid column index"}
}
// Remove row whose index is r.
// The row is returned as a vector.
// @pre 0 < r <= height
// @post removes row r and returns it
// @param r the index of to-be-removed row
// @return vector of values once in row
method removeRowAt(r:Number)->Vector is public{
if((0 < r) && (r <= height)) then{
var result:Vector := index.at(r)
height := height - 1
index.removeFromIndex(r)
result}
else{
print "Invalid row index"
vector.withSize(width)}
}
// Remove column whose index is c
// @pre 0 < c <= width
// @post removes column c and returns it as vector
// @param c the index of column to-be-removed
// @return removes row r and returns it as a vector
method removeColAt(c:Number)->Vector is public{
if((0 < c) && (c <= width)) then{
var result:Vector := vector.withSize(height)
width := width - 1
for(1..height) do{i->
var theRow:Vector := index.at(i)
result.addLast(theRow.at(c))
theRow.removeFromIndex(c)}
result}
else{
print "Invalid column index"
vector.withSize(height)}
}
// @post @return number of columns in matrix
method columns->Number is public{width}
// @post @return number of rows in matrix
method rows->Number is public{height}
// @post @return string representation of matrix
method asString->String is public{
var str:String := "
for(1..width) do {j->
str := str ++ " "}
str := str ++ "\n"}
return str ++ ">"}
}