parse_matrix_line := input -> { vals := input.str_split(" ") vals_len := vals.len // reverse vals // vals_rev := {() -> &vals.pop}.as_list nums := vals.filter_map(v -> v.parse_float).as_list if nums.len.eq(vals_len) if nums.len.signum.eq(1) (nums) else () else () } read_matrix_line := width -> { ().read_line.try((line) -> line.trim, () -> "").parse_matrix_line.try( (line) -> { line := [List] line w := width.deref if w.eq(0) { width = line.len } else { loop { if line.len.subtract(w).signum.eq(-1) { &line.push(0.0) } else (()) } } (line) } () -> () ) } read_matrix := () -> { width := 0 if false &width.read_matrix_line { () -> &width.read_matrix_line }.as_list } matrix_get := (matrix, (line, col)) -> { matrix.get(line).try( () -> () (line) -> line.get(col) ) } leftpad := (str, l) -> { str := (str).concat d := l.subtract(str.len) loop { if d.signum.eq(1) { &str = (" ", str).concat &d = d.subtract(1) } else (()) } str } matrix_print := matrix -> { height := matrix.len width := 0 val_len := 0 matrix.for_each(line -> { l := line.len if width.subtract(l).signum.eq(-1) &width = l line.for_each(val -> { l := (val).concat.len if val_len.subtract(l).eq(-1) &val_len = l }) }) &val_len = val_len.sum(1) (height, "x", width, "-matrix").concat.println matrix.for_each(line -> { "(".print line.for_each(val -> val.leftpad(val_len).print) " )".println }) } fget := v -> v.get.try( () -> { ("called fget but get returned (): ", v).concat.panic } (v) -> v ) matrix_height := a -> a.len matrix_width := a -> a.get(0).try( () -> 0 (v) -> v.len ) multiply_matrix := (a, b) -> { if a.matrix_width.eq(b.matrix_height) { a.map(line -> { {() -> (())} // an infinite iterator repeatedly returning () .enumerate // an infinite iterator returning (i, ()) .take(b.matrix_width) // an iterator returning (i, ()), i < b.matrix_width .map((x, ()) -> line .enumerate .map((y, val) -> val.product(b.fget(y).fget(x))) .sum ) // an iterator returning floats .as_list // becomes a row in the output matrix }).as_list } else { "cannot multiply A and B because A's width isn't B's height." } } "Enter matrix A".println a := ().read_matrix "Enter matrix B".println b := ().read_matrix "A = ".print a.matrix_print "B = ".print b.matrix_print "A * B = ".print a.multiply_matrix(b).try( m -> m.matrix_print e -> e.println )