Forum Discussion
LBROWN7
Oct 12, 2023Brass Contributor
Excel LAMBDA RPN Programming Challenge
Hi All: There is a website called rosettacode.org (currently offline) that is an archive of the same problem solved in large number of computer-languages( approximately 96 – listed below) . E...
LBROWN7
Oct 12, 2023Brass Contributor
Below is my solution to the RPN Programming problem.
It works in Sheets. But returns a CALC error in Excel.
I suspect my problem is with the SCAN function in Excel which differs from what I expect/understand.
=LAMBDA(rpn_string,
LET(
_100, "RPN Calculator: https://www.rosettacode.org/wiki/Parsing/RPN_calculator_algorithm",
SPLIT2_L, LAMBDA(string, delimiters,
LET(
_0, "SPLIT",
_00, "Equivalent of Google Sheets Split funciton",
_10, "with 'split by each' set to true ",
_20, "see Google Sheets SPLIT documentation",
_30, "",
chars, MAKEARRAY(1, LEN(string), LAMBDA(ROW, COL, MID(string, COL, 1))),
result, REDUCE(
"",
chars,
LAMBDA(acc, cv,
LET(
acclen, ROWS(acc),
isdelim, LAMBDA(v, ISNUMBER(FIND(v, delimiters))),
concat2lastrow, LAMBDA(update,
MAKEARRAY(
acclen,
1,
LAMBDA(row, col, INDEX(acc, row, col) & IF(row = acclen, update, ""))
)
),
addblankrow, LAMBDA(IF(INDEX(acc, acclen, 1) = "", acc, VSTACK(acc, ""))),
new_acc, IF(isdelim(cv), addblankrow(), concat2lastrow(cv)),
new_acc
)
)
),
MAP(TOROW(result), LAMBDA(v, IF(ISNUMBER(v + 0), (v + 0), v)))
)
),
Lpad_L, LAMBDA(str, out_len, IF(LEN(str) < out_len, REPT(" ", out_len - LEN(str)), "") & str),
expr_L, LAMBDA(op, x, y, CHOOSE(FIND(op, "+-*/^"), y + x, y - x, y * x, y / x, y ^ x)),
tokens_v, SPLIT2_L(rpn_string, " "),
parse_rpm_m, SCAN(
"",
tokens_v,
LAMBDA(acc_v, c,
IF(
ISNUMBER(c),
(IF(acc_v = "", HSTACK(c), VSTACK(acc_v, c))),
LET(
stack_rows, ROWS(acc_v),
expression, expr_L(c, INDEX(acc_v, stack_rows), INDEX(acc_v, stack_rows - 1)),
IF(
stack_rows - 2 = 0,
expression,
VSTACK(
MAKEARRAY(stack_rows - 2, 1, LAMBDA(r, c, INDEX(acc_v, r, c))),
expression
)
)
)
)
)
),
result_1, TRANSPOSE(parse_rpm_m),
result_2, MAP(
SEQUENCE(COLUMNS(tokens_v)),
LAMBDA(i, HSTACK(" [ " & Lpad_L(i, 2) & " ] " & INDEX(tokens_v, i), INDEX(result_1, i)))
),
result_3, VSTACK(
{"POSTFIX EVALUATOR "},
HSTACK("POSTFIX" & ":", TRIM(rpn_string)),
HSTACK("RESULT" & ":", TRIM(INDEX(result_1, ROWS(result_1)))),
{" ", " "},
{"STEPS", "STACK "},
result_2
),
result_4, MAP(result_3, LAMBDA(c, IF(ISERROR(c), "", c))),
result_4
)
)("3 4 2 * 1 5 - 2 3 ^ ^ / +")
Below is the output
POSTFIX EVALUATOR | |||||
POSTFIX: | 3 4 2 * 1 5 - 2 3 ^ ^ / + | ||||
RESULT: | 3.00012207 | ||||
STEPS | STACK | ||||
[ 1 ] 3 | 3 | ||||
[ 2 ] 4 | 3 | 4 | |||
[ 3 ] 2 | 3 | 4 | 2 | ||
[ 4 ] * | 3 | 8 | |||
[ 5 ] 1 | 3 | 8 | 1 | ||
[ 6 ] 5 | 3 | 8 | 1 | 5 | |
[ 7 ] - | 3 | 8 | -4 | ||
[ 8 ] 2 | 3 | 8 | -4 | 2 | |
[ 9 ] 3 | 3 | 8 | -4 | 2 | 3 |
[ 10 ] ^ | 3 | 8 | -4 | 8 | |
[ 11 ] ^ | 3 | 8 | 65536 | ||
[ 12 ] / | 3 | 0.0001220703125 | |||
[ 13 ] + | 3.00012207 | ||||
- SergeiBaklanOct 13, 2023MVP
Or
rpn = LAMBDA(str, LET( arr, TEXTSPLIT(str, " "), operand, LAMBDA(op, pair, LET( a, --INDEX(pair, 1, 1), b, --INDEX(pair, 1, 2), SWITCH( op, "*", a*b, "-", a-b, "^", a^b, "/", a/b, "+", a+b ) ) ), operation, LAMBDA(a,v, IF( ISNUMBER(--v), HSTACK(a, v), HSTACK(DROP(a,,-2), operand(v, (TAKE(a,,-2))) ) ) ), REDUCE( "Result:", arr, operation) ))
- SergeiBaklanOct 13, 2023MVP
As variant
rpn = LAMBDA(str, LET( arr, TEXTSPLIT(str, " "), mpl, LAMBDA(pair, INDEX(pair,1,1)*INDEX(pair,1,2) ), sbs, LAMBDA(pair, INDEX(pair,1,1)-INDEX(pair,1,2) ), pow, LAMBDA(pair, INDEX(pair,1,1)^INDEX(pair,1,2) ), div, LAMBDA(pair, INDEX(pair,1,1)/INDEX(pair,1,2) ), pls, LAMBDA(pair, INDEX(pair,1,1)+INDEX(pair,1,2) ), DROP( REDUCE(0, arr, LAMBDA(a,v, IF( ISNUMBER(--v), HSTACK(a,v), IF( v="*", HSTACK( DROP(a,,-2), mpl( TAKE(a,,-2) )), IF( v="-", HSTACK( DROP(a,,-2), sbs( TAKE(a,,-2) )), IF( v="^", HSTACK( DROP(a,,-2), pow( TAKE(a,,-2) )), IF( v="/", HSTACK( DROP(a,,-2), div( TAKE(a,,-2) )), IF( v="+", HSTACK( DROP(a,,-2), pls( TAKE(a,,-2) )), )))))) ) ), ,1 ) ))