# HG changeset patch # User Christian Urban # Date 1548086670 0 # Node ID ba4d976ca88df19bf21bb180ec0c300ba4173268 # Parent 512292bb5e936c3fcd4ad24e0196e91ff0f45f0e updated diff -r 512292bb5e93 -r ba4d976ca88d cws/cw04.pdf Binary file cws/cw04.pdf has changed diff -r 512292bb5e93 -r ba4d976ca88d cws/cw04.tex --- a/cws/cw04.tex Thu Jan 17 00:53:24 2019 +0000 +++ b/cws/cw04.tex Mon Jan 21 16:04:30 2019 +0000 @@ -1,3 +1,4 @@ +% !TEX program = xelatex \documentclass{article} \usepackage{../style} \usepackage{../langs} @@ -103,7 +104,7 @@ expressions. The background is that ``out-of-the-box'' regular expression matching in mainstream languages like Java, JavaScript and Python can sometimes be excruciatingly slow. You are supposed to implement -an regular expression macther that is much, much faster. The advanced part is +an regular expression matcher that is much, much faster. The advanced part is about the shunting yard algorithm that transforms the usual infix notation of arithmetic expressions into the postfix notation, which is for example used in compilers.\bigskip @@ -112,7 +113,7 @@ \noindent Also note that the running time of each part will be restricted to a -maximum of 30 seconds on my laptop. +maximum of 30 seconds on my laptop. \DISCLAIMER{} diff -r 512292bb5e93 -r ba4d976ca88d cws/cw05.pdf Binary file cws/cw05.pdf has changed diff -r 512292bb5e93 -r ba4d976ca88d cws/disclaimer.sty --- a/cws/disclaimer.sty Thu Jan 17 00:53:24 2019 +0000 +++ b/cws/disclaimer.sty Mon Jan 21 16:04:30 2019 +0000 @@ -1,6 +1,6 @@ \newcommand{\IMPORTANT}{% \noindent -\textbf{Important:} +\textbf{Important} \begin{itemize} \item Make sure the files you submit can be processed by just calling\\ diff -r 512292bb5e93 -r ba4d976ca88d handouts/pep-ho.tex --- a/handouts/pep-ho.tex Thu Jan 17 00:53:24 2019 +0000 +++ b/handouts/pep-ho.tex Mon Jan 21 16:04:30 2019 +0000 @@ -27,6 +27,11 @@ % http://courses.cms.caltech.edu/cs134/cs134b/book.pdf % http://alexott.net/en/fp/books/ +%John Hughes’ simple words: +%A combinator is a function which builds program fragments +%from program fragments. + + \begin{document} \fnote{\copyright{} Christian Urban, King's College London, 2017, 2018} diff -r 512292bb5e93 -r ba4d976ca88d marking4/TESTCASE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/TESTCASE Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,1 @@ +println(simp(Iterator.iterate(ONE:Rexp)(r => ALT(r, r)).drop(40).next)) \ No newline at end of file diff -r 512292bb5e93 -r ba4d976ca88d marking4/mk-advanced --- a/marking4/mk-advanced Thu Jan 17 00:53:24 2019 +0000 +++ b/marking4/mk-advanced Mon Jan 21 16:04:30 2019 +0000 @@ -3,21 +3,21 @@ trap "exit" INT -files=${1:-assignment20178-*} +files=${1:-assignment20189-*} for sd in $files; do cd $sd echo $sd touch . - cp ../../../marking3/bf_test.sh . - cp ../../../marking3/bf1a_test.scala . - cp ../../../marking3/bf1b_test.scala . - cp ../../../marking3/bf1c_test.scala . - ./bf_test.sh output - rm bf_test.sh - rm bf1a_test.scala - rm bf1b_test.scala - rm bf1c_test.scala + cp ../../../marking4/postfix_test.sh . + cp ../../../marking4/postfix_test7.scala . + cp ../../../marking4/postfix_test8.scala . + cp ../../../marking4/postfix_test9.scala . + ./postfix_test.sh output + rm postfix_test.sh + rm postfix_test7.scala + rm postfix_test8.scala + rm postfix_test9.scala cd .. done diff -r 512292bb5e93 -r ba4d976ca88d marking4/output --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/output Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,46 @@ + +Below is the feedback and provisional marks for your submission +for assignment 9 Part 2. Please note all marks are provisional until +ratified by the assessment board -- this is not an official +results transcript. + +postfix.scala does not contain vars, returns, Arrays, ListBuffers etc? + --> success +postfix.scala runs? + --> success + syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "\*", "+") + syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+") + syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+") + syard(split("5 * 7 / 2")) == List("5", "7", "\*", "2", "/") + --> success + compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7 + compute(syard(split("10 + 12 * 33"))) == 406 + compute(syard(split("( 5 + 7 ) * 2"))) == 24 + compute(syard(split("5 + 7 / 2"))) == 8 + compute(syard(split("5 * 7 / 2"))) == 17 + compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15 + --> success +postfix2.scala does not contain vars, returns, Arrays, ListBuffers etc? + --> success +postfix2.scala runs? + --> success + syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "\*", "+") + syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+") + syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+") + syard(split("5 * 7 / 2")) == List("5", "7", "\*", "2", "/") + syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3")) == + List("3", "4", "8", "\*", "5", "1", "-", "2", "3", "^", "^", "/", "+") + + compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7 + compute(syard(split("10 + 12 * 33"))) == 406 + compute(syard(split("( 5 + 7 ) * 2"))) == 24 + compute(syard(split("5 + 7 / 2"))) == 8 + compute(syard(split("5 * 7 / 2"))) == 17 + compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15 + compute(syard(split("4 ^ 3 ^ 2"))) == 262144 + compute(syard(split("4 ^ ( 3 ^ 2 )"))) == 262144 + compute(syard(split("( 4 ^ 3 ) ^ 2"))) == 4096 + compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) == 65536 + --> success +Overall mark for CW 9, Part 2 +4 diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix.scala Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,103 @@ +// Shunting Yard Algorithm +// by Edsger Dijkstra +// ======================== + +//object CW9b { + +type Toks = List[String] + +// the operations in the simple version +val ops = List("+", "-", "*", "/") + +// the precedences of the operators +val precs = Map("+" -> 1, + "-" -> 1, + "*" -> 2, + "/" -> 2) + +// helper function for splitting strings into tokens +def split(s: String) : Toks = s.split(" ").toList + +// (6) Implement below the shunting yard algorithm. The most +// convenient way to this in Scala is to implement a recursive +// function and to heavily use pattern matching. The function syard +// takes some input tokens as first argument. The second and third +// arguments represent the stack and the output of the shunting yard +// algorithm. +// +// In the marking, you can assume the function is called only with +// an empty stack and an empty output list. You can also assume the +// input os only properly formatted (infix) arithmetic expressions +// (all parentheses will be well-nested, the input only contains +// operators and numbers). + +// You can implement any additional helper function you need. I found +// it helpful to implement two auxiliary functions for the pattern matching: +// + +def is_op(op: String) : Boolean = ops.contains(op) + +def prec(op1: String, op2: String) : Boolean = precs(op1) <= precs(op2) + + +def syard(toks: Toks, st: Toks = Nil, out: Toks = Nil) : Toks = (toks, st, out) match { + case (Nil, _, _) => out.reverse ::: st + case (num::in, st, out) if (num.forall(_.isDigit)) => + syard(in, st, num :: out) + case (op1::in, op2::st, out) if (is_op(op1) && is_op(op2) && prec(op1, op2)) => + syard(op1::in, st, op2 :: out) + case (op1::in, st, out) if (is_op(op1)) => syard(in, op1::st, out) + case ("("::in, st, out) => syard(in, "("::st, out) + case (")"::in, op2::st, out) => + if (op2 == "(") syard(in, st, out) else syard(")"::in, st, op2 :: out) + case (in, st, out) => { + println(s"in: ${in} st: ${st} out: ${out.reverse}") + Nil + } +} + + +// test cases +//syard(split("3 + 4 * ( 2 - 1 )")) // 3 4 2 1 - * + +//syard(split("10 + 12 * 33")) // 10 12 33 * + +//syard(split("( 5 + 7 ) * 2")) // 5 7 + 2 * +//syard(split("5 + 7 / 2")) // 5 7 2 / + +//syard(split("5 * 7 / 2")) // 5 7 * 2 / +//syard(split("9 + 24 / ( 7 - 3 )")) // 9 24 7 3 - / + + +//syard(split("3 + 4 + 5")) // 3 4 + 5 + +//syard(split("( ( 3 + 4 ) + 5 )")) // 3 4 + 5 + +//syard(split("( 3 + ( 4 + 5 ) )")) // 3 4 5 + + +//syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) // 3 4 5 + + + +// (7) Implement a compute function that evaluates an input list +// in postfix notation. This function takes a list of tokens +// and a stack as argumenta. The function should produce the +// result as an integer using the stack. You can assume +// this function will be only called with proper postfix +// expressions. + +def op_comp(s: String, n1: Int, n2: Int) = s match { + case "+" => n2 + n1 + case "-" => n2 - n1 + case "*" => n2 * n1 + case "/" => n2 / n1 +} + +def compute(toks: Toks, st: List[Int] = Nil) : Int = (toks, st) match { + case (Nil, st) => st.head + case (op::in, n1::n2::st) if (is_op(op)) => compute(in, op_comp(op, n1, n2)::st) + case (num::in, st) => compute(in, num.toInt::st) +} + +// test cases +// compute(syard(split("3 + 4 * ( 2 - 1 )"))) // 7 +// compute(syard(split("10 + 12 * 33"))) // 406 +// compute(syard(split("( 5 + 7 ) * 2"))) // 24 +// compute(syard(split("5 + 7 / 2"))) // 8 +// compute(syard(split("5 * 7 / 2"))) // 17 +// compute(syard(split("9 + 24 / ( 7 - 3 )"))) // 15 + +//} + + diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix2.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix2.scala Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,100 @@ +// Shunting Yard Algorithm +// including Associativity for Operators +// ===================================== + +//object CW9c { // just for generating a jar file + +// type of tokens +type Toks = List[String] + +// helper function for splitting strings into tokens +def split(s: String) : Toks = s.split(" ").toList + +// left- and right-associativity +abstract class Assoc +case object LA extends Assoc +case object RA extends Assoc + +// power is right-associative, +// everything else is left-associative +def assoc(s: String) : Assoc = s match { + case "^" => RA + case _ => LA +} + +// the precedences of the operators +val precs = Map("+" -> 1, + "-" -> 1, + "*" -> 2, + "/" -> 2, + "^" -> 4) + +// the operations in the basic version of the algorithm +val ops = List("+", "-", "*", "/", "^") + +// (8) Implement the extended version of the shunting yard algorithm. +// This version should properly account for the fact that the power +// operation is right-associative. Apart from the extension to include +// the power operation, you can make the same assumptions as in +// basic version. + +def is_op(op: String) : Boolean = ops.contains(op) + +def prec(op1: String, op2: String) : Boolean = assoc(op1) match { + case LA => precs(op1) <= precs(op2) + case RA => precs(op1) < precs(op2) +} + +def syard(toks: Toks, st: Toks = Nil, out: Toks = Nil) : Toks = (toks, st, out) match { + case (Nil, _, _) => out.reverse ::: st + case (num::in, st, out) if (num.forall(_.isDigit)) => + syard(in, st, num :: out) + case (op1::in, op2::st, out) if (is_op(op1) && is_op(op2) && prec(op1, op2)) => + syard(op1::in, st, op2 :: out) + case (op1::in, st, out) if (is_op(op1)) => syard(in, op1::st, out) + case ("("::in, st, out) => syard(in, "("::st, out) + case (")"::in, op2::st, out) => + if (op2 == "(") syard(in, st, out) else syard(")"::in, st, op2 :: out) + case (in, st, out) => { + println(s"in: ${in} st: ${st} out: ${out.reverse}") + Nil + } +} + +def op_comp(s: String, n1: Long, n2: Long) = s match { + case "+" => n2 + n1 + case "-" => n2 - n1 + case "*" => n2 * n1 + case "/" => n2 / n1 + case "^" => Math.pow(n2, n1).toLong +} + +def compute(toks: Toks, st: List[Long] = Nil) : Long = (toks, st) match { + case (Nil, st) => st.head + case (op::in, n1::n2::st) if (is_op(op)) => compute(in, op_comp(op, n1, n2)::st) + case (num::in, st) => compute(in, num.toInt::st) +} + + + + +//compute(syard(split("3 + 4 * ( 2 - 1 )"))) // 7 +//compute(syard(split("10 + 12 * 33"))) // 406 +//compute(syard(split("( 5 + 7 ) * 2"))) // 24 +//compute(syard(split("5 + 7 / 2"))) // 8 +//compute(syard(split("5 * 7 / 2"))) // 17 +//compute(syard(split("9 + 24 / ( 7 - 3 )"))) // 15 + +//compute(syard(split("4 ^ 3 ^ 2"))) // 262144 +//compute(syard(split("4 ^ ( 3 ^ 2 )"))) // 262144 +//compute(syard(split("( 4 ^ 3 ) ^ 2"))) // 4096 +//compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) // 65536 + +//syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3")) // 3 4 8 * 5 1 - 2 3 ^ ^ / + +//compute(syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3"))) // 3 + +//compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) // 65536 + + + +//} diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix_test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix_test.sh Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,179 @@ +#!/bin/bash +set -euo pipefail + + +out=${1:-output} + +echo -e "" > $out + + +echo "Below is the feedback and provisional marks for your submission" >> $out +echo "for assignment 9 Part 2. Please note all marks are provisional until" >> $out +echo "ratified by the assessment board -- this is not an official" >> $out +echo "results transcript." >> $out +echo "" >> $out + +# marks for CW9 part 2 +marks=$(( 0 )) + + +# compilation tests + +function scala_compile { + (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc "$1" 2>> $out 1>> $out) +} + +# functional tests + +function scala_assert { + (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) +} + +# purity test + +function scala_vars { + (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|mutable|new Array' "$1" 2> /dev/null 1> /dev/null) +} + + +# var, return, ListBuffer test +# +echo -e "postfix.scala does not contain vars, returns, Arrays, ListBuffers etc?" | tee -a $out + +if (scala_vars postfix.scala) +then + echo " --> test failed" | tee -a $out + tsts0=$(( 1 )) +else + echo " --> success" | tee -a $out + tsts0=$(( 0 )) +fi + +# compilation test +if [ $tsts0 -eq 0 ] +then + echo "postfix.scala runs?" | tee -a $out + + if (scala_compile re.scala) + then + echo " --> success" | tee -a $out + tsts1=$(( 0 )) + else + echo " --> scala postfix.scala did not run successfully" | tee -a $out + tsts1=$(( 1 )) + fi +else + tsts1=$(( 1 )) +fi + + +### postfix tests + +if [ $tsts1 -eq 0 ] +then + echo -e " syard(split(\"3 + 4 * ( 2 - 1 )\")) == List(\"3\", \"4\", \"2\", \"1\", \"-\", \"*\", \"+\")" | tee -a $out + echo -e " syard(split(\"( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )\")) == List(\"3\", \"4\", \"5\", \"+\", \"+\")" | tee -a $out + echo -e " syard(split(\"5 + 7 / 2\")) == List(\"5\", \"7\", \"2\", \"/\", \"+\")" | tee -a $out + echo -e " syard(split(\"5 * 7 / 2\")) == List(\"5\", \"7\", \"*\", \"2\", \"/\")" | tee -a $out + + if (scala_assert "postfix.scala" "postfix_test7.scala") + then + echo -e " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo -e " --> test failed" | tee -a $out + fi +fi + + + +if [ $tsts1 -eq 0 ] +then + echo -e " compute(syard(split(\"3 + 4 * ( 2 - 1 )\"))) == 7" | tee -a $out + echo -e " compute(syard(split(\"10 + 12 * 33\"))) == 406" | tee -a $out + echo -e " compute(syard(split(\"( 5 + 7 ) * 2\"))) == 24" | tee -a $out + echo -e " compute(syard(split(\"5 + 7 / 2\"))) == 8" | tee -a $out + echo -e " compute(syard(split(\"5 * 7 / 2\"))) == 17" | tee -a $out + echo -e " compute(syard(split(\"9 + 24 / ( 7 - 3 )\"))) == 15" | tee -a $out + + if (scala_assert "postfix.scala" "postfix_test8.scala") + then + echo -e " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + + +### postfix2 tests + +# var, return, ListBuffer test +# +# var, return, ListBuffer test +# +echo -e "postfix2.scala does not contain vars, returns, Arrays, ListBuffers etc?" | tee -a $out + +if (scala_vars postfix2.scala) +then + echo " --> test failed" | tee -a $out + tsts0=$(( 1 )) +else + echo " --> success" | tee -a $out + tsts0=$(( 0 )) +fi + + +# compilation test + +# compilation test +if [ $tsts0 -eq 0 ] +then + echo "postfix2.scala runs?" | tee -a $out + + if (scala_compile re.scala) + then + echo " --> success" | tee -a $out + tsts1=$(( 0 )) + else + echo " --> scala postfix2.scala did not run successfully" | tee -a $out + tsts1=$(( 1 )) + fi +else + tsts1=$(( 1 )) +fi + + +if [ $tsts1 -eq 0 ] +then + echo -e " syard(split(\"3 + 4 * ( 2 - 1 )\")) == List(\"3\", \"4\", \"2\", \"1\", \"-\", \"*\", \"+\")" | tee -a $out + echo -e " syard(split(\"( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )\")) == List(\"3\", \"4\", \"5\", \"+\", \"+\")" | tee -a $out + echo -e " syard(split(\"5 + 7 / 2\")) == List(\"5\", \"7\", \"2\", \"/\", \"+\")" | tee -a $out + echo -e " syard(split(\"5 * 7 / 2\")) == List(\"5\", \"7\", \"*\", \"2\", \"/\")" | tee -a $out + echo -e " syard(split(\"3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3\")) == " | tee -a $out + echo -e " List(\"3\", \"4\", \"8\", \"*\", \"5\", \"1\", \"-\", \"2\", \"3\", \"^\", \"^\", \"/\", \"+\")" | tee -a $out + echo -e " " | tee -a $out + echo -e " compute(syard(split(\"3 + 4 * ( 2 - 1 )\"))) == 7" | tee -a $out + echo -e " compute(syard(split(\"10 + 12 * 33\"))) == 406" | tee -a $out + echo -e " compute(syard(split(\"( 5 + 7 ) * 2\"))) == 24" | tee -a $out + echo -e " compute(syard(split(\"5 + 7 / 2\"))) == 8" | tee -a $out + echo -e " compute(syard(split(\"5 * 7 / 2\"))) == 17" | tee -a $out + echo -e " compute(syard(split(\"9 + 24 / ( 7 - 3 )\"))) == 15" | tee -a $out + echo -e " compute(syard(split(\"4 ^ 3 ^ 2\"))) == 262144" | tee -a $out + echo -e " compute(syard(split(\"4 ^ ( 3 ^ 2 )\"))) == 262144" | tee -a $out + echo -e " compute(syard(split(\"( 4 ^ 3 ) ^ 2\"))) == 4096" | tee -a $out + echo -e " compute(syard(split(\"( 3 + 1 ) ^ 2 ^ 3\"))) == 65536" | tee -a $out + + if (scala_assert "postfix2.scala" "postfix_test9.scala") + then + echo -e " --> success" | tee -a $out + marks=$(( marks + 2 )) + else + echo " --> test failed" | tee -a $out + fi +fi + +## final marks +echo "Overall mark for CW 9, Part 2" | tee -a $out +echo "$marks" | tee -a $out diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix_test7.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix_test7.scala Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,5 @@ + +assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+")) +assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+")) +assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+")) +assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/")) diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix_test8.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix_test8.scala Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,7 @@ + +assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7) +assert(compute(syard(split("10 + 12 * 33"))) == 406) +assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24) +assert(compute(syard(split("5 + 7 / 2"))) == 8) +assert(compute(syard(split("5 * 7 / 2"))) == 17) +assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15) diff -r 512292bb5e93 -r ba4d976ca88d marking4/postfix_test9.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/postfix_test9.scala Mon Jan 21 16:04:30 2019 +0000 @@ -0,0 +1,19 @@ + +assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+")) +assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+")) +assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+")) +assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/")) +assert(syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3")) == List("3", "4", "8", "*", "5", "1", "-", "2", "3", "^", "^", "/", "+")) + + + +assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7) +assert(compute(syard(split("10 + 12 * 33"))) == 406) +assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24) +assert(compute(syard(split("5 + 7 / 2"))) == 8) +assert(compute(syard(split("5 * 7 / 2"))) == 17) +assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15) +assert(compute(syard(split("4 ^ 3 ^ 2"))) == 262144) +assert(compute(syard(split("4 ^ ( 3 ^ 2 )"))) == 262144) +assert(compute(syard(split("( 4 ^ 3 ) ^ 2"))) == 4096) +assert(compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) == 65536)