RosettaCodeData/Task/Matrix-multiplication/Ceylon/matrix-multiplication.ceylon

66 lines
1.6 KiB
Ceylon

alias Matrix => Integer[][];
void printMatrix(Matrix m) {
value strings = m.collect((row) => row.collect(Integer.string));
value maxLength = max(expand(strings).map(String.size)) else 0;
value padded = strings.collect((row) => row.collect((s) => s.padLeading(maxLength)));
for (row in padded) {
print("[``", ".join(row)``]");
}
}
Matrix? multiplyMatrices(Matrix a, Matrix b) {
function rectangular(Matrix m) =>
if (exists firstRow = m.first)
then m.every((row) => row.size == firstRow.size)
else false;
function rowCount(Matrix m) => m.size;
function columnCount(Matrix m) => m[0]?.size else 0;
if (!rectangular(a) || !rectangular(b) || columnCount(a) != rowCount(b)) {
return null;
}
function getNumber(Matrix m, Integer x, Integer y) {
assert (exists number = m[y]?.get(x));
return number;
}
function getRow(Matrix m, Integer rowIndex) {
assert (exists row = m[rowIndex]);
return row;
}
function getColumn(Matrix m, Integer columnIndex) => {
for (y in 0:rowCount(m))
getNumber(m, columnIndex, y)
};
return [
for (y in 0:rowCount(a)) [
for (x in 0:columnCount(b))
sum { 0, for ([a1, b1] in zipPairs(getRow(a, y), getColumn(b, x))) a1 * b1 }
]
];
}
shared void run() {
value m = [[1, 2, 3], [4, 5, 6]];
printMatrix(m);
print("---------");
print("multiplied by");
value m2 = [[7, 8], [9, 10], [11, 12]];
printMatrix(m2);
print("---------");
print("equals:");
value result = multiplyMatrices(m, m2);
if (exists result) {
printMatrix(result);
}
else {
print("something went wrong!");
}
}