From 078b83dfa5cf3ac2f5de3984008743366aaa577e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 27 Oct 2023 19:19:42 +0200 Subject: [PATCH] add/change examples --- examples/02_Calc_Sum.mers | 13 +- examples/03_Basic_Calculator.mers | 23 ++- ...r.mers => 04_Greatest_Common_Divisor.mers} | 8 +- examples/05_Matrix_Multiplicator.mers | 168 ++++++++++++++++++ 4 files changed, 187 insertions(+), 25 deletions(-) rename examples/{05_Greatest_Common_Divisor.mers => 04_Greatest_Common_Divisor.mers} (80%) create mode 100644 examples/05_Matrix_Multiplicator.mers diff --git a/examples/02_Calc_Sum.mers b/examples/02_Calc_Sum.mers index c9ead8f..7a97260 100644 --- a/examples/02_Calc_Sum.mers +++ b/examples/02_Calc_Sum.mers @@ -1,13 +1,10 @@ total := 0.0 {() -> { ("Total: ", total, ". Type a number to change.").concat.println - ( - ().read_line.trim.parse_float, - ( - n -> &total = (total, n).sum, - // not a number, so return a 1-tuple to break from the loop - () -> (()) - ) - ).try + ().read_line.trim.parse_float.try(( + n -> &total = (total, n).sum, + // not a number, so return a 1-tuple to break from the loop + () -> (()) + )) }}.loop "Goodbye.".println diff --git a/examples/03_Basic_Calculator.mers b/examples/03_Basic_Calculator.mers index 5926b54..a2f60e2 100644 --- a/examples/03_Basic_Calculator.mers +++ b/examples/03_Basic_Calculator.mers @@ -8,23 +8,20 @@ current := 0.0 {() -> { ("[ ", current, " ]").concat.println input := ().read_line.trim - num := ( - (input, 1).substring.trim.parse_float, - ( - () -> 0.0, - val -> val - ) - ).try - mode := (input, 0, 1).substring - if (mode, "+").eq { + num := (input, 1).substring.trim.parse_float.try(( + () -> 0.0, + val -> val + )) + mode := input.substring(0, 1) + if mode.eq("+") { ¤t = (current, num).sum - } else if (mode, "-").eq { + } else if mode.eq("-") { ¤t = (current, (num, -1).product).sum - } else if (mode, "*").eq { + } else if mode.eq("*") { ¤t = (current, num).product - } else if (mode, "=").eq { + } else if mode.eq("=") { ¤t = num - } else if (input, "exit").eq { + } else if input.eq("exit") { (()) } }}.loop diff --git a/examples/05_Greatest_Common_Divisor.mers b/examples/04_Greatest_Common_Divisor.mers similarity index 80% rename from examples/05_Greatest_Common_Divisor.mers rename to examples/04_Greatest_Common_Divisor.mers index b65f8d5..4145abf 100644 --- a/examples/05_Greatest_Common_Divisor.mers +++ b/examples/04_Greatest_Common_Divisor.mers @@ -1,12 +1,12 @@ gcd := vals -> { () -> { (a, b) := vals - if (a, b).eq + if a.eq(b) (a) - else if ((a, b).diff.signum, 1).eq - &vals = (a, (a, b).diff) + else if a.diff(b).signum.eq(1) + &vals = (a, a.diff(b)) else - &vals = ((b, a).diff, b) + &vals = (b.diff(a), b) } }.loop diff --git a/examples/05_Matrix_Multiplicator.mers b/examples/05_Matrix_Multiplicator.mers new file mode 100644 index 0000000..e13a658 --- /dev/null +++ b/examples/05_Matrix_Multiplicator.mers @@ -0,0 +1,168 @@ +// if string is a + delim + b, returns (a, b), +// otherwise returns (). b can contain delim. +split_once := (s, delim) -> { + ( + (s, delim).index_of, + ( + index -> ( + (s, 0, index).substring, + (s, (index, delim.len).sum).substring + ) + () -> () + ) + ).try +} + +// repeats split_once until no delim is left and returns a list of strings +split_ := (s, delim, require_nonempty) -> { + out := (s).as_list + &out.pop + { + () -> s.split_once(delim).try(( + (s1, s2) -> { + &s = s2 + if s1.len.signum.eq(1) + &out.push(s1) + } + () -> { + if s.len.signum.eq(1) + &out.push(s) + (()) + } + )) + }.loop + out +} + +split := (s, delim) -> s.split_(delim, true) + +parse_matrix_line := input -> { + vals := input.split(" ") + vals_len := vals.len + // reverse vals + vals_rev := {() -> &vals.pop}.as_list + nums := {() -> &vals_rev.pop.try(( + () -> () + (v) -> v.parse_float.try(( + () -> () + v -> (v) + )) + ))}.as_list + if nums.len.eq(vals_len) + if nums.len.signum.eq(1) + (nums) + else () + else () +} + +read_matrix_line := width -> { + ().read_line.trim.parse_matrix_line.try(( + (line) -> { + w := width.deref + if w.eq(0) { + width = line.len + } else { + {() -> if line.len.diff(w).signum.eq(1) { + &line.push(0.0) + } else (())}.loop + } + (line) + } + () -> () + )) +} + +read_matrix := () -> { + width := 0 + { () -> &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 := str.len.diff(l) + {() -> if d.signum.eq(1) { + &str = (" ", str).concat + &d = 1.diff(d) + } else {(())}}.loop + str +} + +matrix_print := matrix -> { + height := matrix.len + width := 0 + val_len := 0 + matrix.for_each(line -> { + l := line.len + if l.diff(width).signum.eq(-1) + &width = l + line.for_each(val -> { + l := (val).concat.len + if l.diff(val_len).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 ():".println + v.println + 5.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 +))