257
|
1 |
% !TEX program = xelatex
|
6
|
2 |
\documentclass{article}
|
426
|
3 |
\usepackage{../styles/style}
|
|
4 |
\usepackage{../styles/langs}
|
218
|
5 |
\usepackage{disclaimer}
|
|
6 |
\usepackage{tikz}
|
|
7 |
\usepackage{pgf}
|
|
8 |
\usepackage{pgfplots}
|
|
9 |
\usepackage{stackengine}
|
|
10 |
%% \usepackage{accents}
|
|
11 |
\newcommand\barbelow[1]{\stackunder[1.2pt]{#1}{\raisebox{-4mm}{\boldmath$\uparrow$}}}
|
379
|
12 |
\usepackage{ulem}
|
6
|
13 |
|
|
14 |
\begin{document}
|
|
15 |
|
218
|
16 |
% BF IDE
|
|
17 |
% https://www.microsoft.com/en-us/p/brainf-ck/9nblgggzhvq5
|
|
18 |
|
396
|
19 |
\section*{Core Part 3 (Scala, 3 Marks)}
|
6
|
20 |
|
275
|
21 |
\mbox{}\hfill\textit{``[Google’s MapReduce] abstraction is inspired by the}\\
|
|
22 |
\mbox{}\hfill\textit{map and reduce primitives present in Lisp and many}\\
|
347
|
23 |
\mbox{}\hfill\textit{other functional languages.''}\smallskip\\
|
284
|
24 |
\mbox{}\hfill\textit{ --- Dean and Ghemawat, who designed this concept at Google}
|
347
|
25 |
\bigskip
|
275
|
26 |
|
411
|
27 |
\IMPORTANTNONE{}
|
62
|
28 |
|
|
29 |
\noindent
|
218
|
30 |
Also note that the running time of each part will be restricted to a
|
257
|
31 |
maximum of 30 seconds on my laptop.
|
218
|
32 |
|
|
33 |
\DISCLAIMER{}
|
86
|
34 |
|
221
|
35 |
\subsection*{Reference Implementation}
|
|
36 |
|
347
|
37 |
This Scala assignment comes with two reference implementations in
|
|
38 |
form of \texttt{jar}-files. This allows
|
|
39 |
you to run any test cases on your own computer. For example you can
|
471
|
40 |
call scala-cli on the command line with the option \texttt{--extra-jars
|
347
|
41 |
postfix.jar} and then query any function from the
|
|
42 |
\texttt{postfix.scala} file (similarly for file \texttt{postfix2.scala}). As
|
396
|
43 |
usual you have to prefix the calls with \texttt{C3a} and
|
|
44 |
\texttt{C3b}, respectively.
|
221
|
45 |
|
|
46 |
|
245
|
47 |
\begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small]
|
471
|
48 |
$ scala-cli --extra-jars postfix.jar
|
347
|
49 |
|
396
|
50 |
scala> C3a.syard(C3a.split("( 5 + 7 ) * 2"))
|
|
51 |
val res0: C3a.Toks = List(5, 7, +, 2, *)
|
221
|
52 |
\end{lstlisting}%$
|
|
53 |
|
6
|
54 |
|
367
|
55 |
\subsection*{Hints}
|
|
56 |
|
|
57 |
\noindent
|
396
|
58 |
\textbf{For Core Part 3:} useful operations for determining
|
367
|
59 |
whether a string is a number are \texttt{.forall} and \texttt{.isDigit}.
|
|
60 |
One way to calculate the the power operation is to use \texttt{.pow}
|
|
61 |
on \texttt{BigInt}s, like \texttt{BigInt(n).pow(m).toInt}.
|
|
62 |
\bigskip
|
|
63 |
|
|
64 |
|
396
|
65 |
\subsection*{Core Part (3 Marks, files postfix.scala, postfix2.scala)}
|
284
|
66 |
|
475
|
67 |
The \textit{Shunting Yard Algorithm} has been developed by Edsger Dijkstra,
|
284
|
68 |
an influential computer scientist who developed many well-known
|
|
69 |
algorithms. This algorithm transforms the usual infix notation of
|
|
70 |
arithmetic expressions into the postfix notation, sometimes also
|
475
|
71 |
called \textit{Reverse Polish Notation}.
|
284
|
72 |
|
|
73 |
Why on Earth do people use the postfix notation? It is much more
|
|
74 |
convenient to work with the usual infix notation for arithmetic
|
347
|
75 |
expressions. Most modern pocket calculators (as opposed to the ones used 20
|
284
|
76 |
years ago) understand infix notation. So why on Earth? \ldots{}Well,
|
|
77 |
many computers under the hood, even nowadays, use postfix notation
|
|
78 |
extensively. For example if you give to the Java compiler the
|
|
79 |
expression $1 + ((2 * 3) + (4 - 3))$, it will generate the Java Byte
|
|
80 |
code
|
|
81 |
|
|
82 |
\begin{lstlisting}[language=JVMIS,numbers=none]
|
|
83 |
ldc 1
|
|
84 |
ldc 2
|
|
85 |
ldc 3
|
|
86 |
imul
|
|
87 |
ldc 4
|
|
88 |
ldc 3
|
|
89 |
isub
|
|
90 |
iadd
|
|
91 |
iadd
|
|
92 |
\end{lstlisting}
|
|
93 |
|
|
94 |
\noindent
|
475
|
95 |
where the command \texttt{ldc} loads a number onto the stack, and \texttt{imul},
|
|
96 |
\texttt{isub} and \texttt{iadd} perform arithmetic operations on the stack. Clearly, this
|
|
97 |
is the arithmetic expression from above but in postfix notation.\bigskip
|
284
|
98 |
|
|
99 |
\noindent
|
|
100 |
The shunting yard algorithm processes an input token list using an
|
|
101 |
operator stack and an output list. The input consists of numbers,
|
|
102 |
operators ($+$, $-$, $*$, $/$) and parentheses, and for the purpose of
|
|
103 |
the assignment we assume the input is always a well-formed expression
|
|
104 |
in infix notation. The calculation in the shunting yard algorithm uses
|
|
105 |
information about the
|
|
106 |
precedences of the operators (given in the template file). The
|
|
107 |
algorithm processes the input token list as follows:
|
|
108 |
|
|
109 |
\begin{itemize}
|
|
110 |
\item If there is a number as input token, then this token is
|
|
111 |
transferred directly to the output list. Then the rest of the input is
|
|
112 |
processed.
|
|
113 |
\item If there is an operator as input token, then you need to check
|
|
114 |
what is on top of the operator stack. If there are operators with
|
|
115 |
a higher or equal precedence, these operators are first popped off
|
|
116 |
from the stack and moved to the output list. Then the operator from the input
|
|
117 |
is pushed onto the stack and the rest of the input is processed.
|
|
118 |
\item If the input is a left-parenthesis, you push it on to the stack
|
|
119 |
and continue processing the input.
|
|
120 |
\item If the input is a right-parenthesis, then you pop off all operators
|
|
121 |
from the stack to the output list until you reach the left-parenthesis.
|
|
122 |
Then you discharge the $($ and $)$ from the input and stack, and continue
|
|
123 |
processing the input list.
|
|
124 |
\item If the input is empty, then you move all remaining operators
|
|
125 |
from the stack to the output list.
|
475
|
126 |
\end{itemize}
|
|
127 |
|
|
128 |
\noindent
|
|
129 |
BTW, the rules above are written ``If\ldots'', but this is because English does not
|
|
130 |
include very sophisticated pattern matching. But clearly the rules above should be implemented
|
|
131 |
in Scala using pattern matching.
|
|
132 |
|
284
|
133 |
|
|
134 |
\subsubsection*{Tasks (file postfix.scala)}
|
|
135 |
|
|
136 |
\begin{itemize}
|
|
137 |
\item[(1)] Implement the shunting yard algorithm described above. The
|
|
138 |
function, called \texttt{syard}, takes a list of tokens as first
|
|
139 |
argument. The second and third arguments are the stack and output
|
|
140 |
list represented as Scala lists. The most convenient way to
|
|
141 |
implement this algorithm is to analyse what the input list, stack
|
|
142 |
and output list look like in each step using pattern-matching. The
|
|
143 |
algorithm transforms for example the input
|
|
144 |
|
|
145 |
\[
|
|
146 |
\texttt{List(3, +, 4, *, (, 2, -, 1, ))}
|
|
147 |
\]
|
|
148 |
|
|
149 |
into the postfix output
|
|
150 |
|
|
151 |
\[
|
|
152 |
\texttt{List(3, 4, 2, 1, -, *, +)}
|
|
153 |
\]
|
|
154 |
|
|
155 |
You can assume the input list is always a list representing
|
|
156 |
a well-formed infix arithmetic expression.\hfill[1 Mark]
|
|
157 |
|
|
158 |
\item[(2)] Implement a compute function that takes a postfix expression
|
|
159 |
as argument and evaluates it generating an integer as result. It uses a
|
|
160 |
stack to evaluate the postfix expression. The operators $+$, $-$, $*$
|
|
161 |
are as usual; $/$ is division on integers, for example $7 / 3 = 2$.
|
|
162 |
\hfill[1 Mark]
|
|
163 |
\end{itemize}
|
|
164 |
|
|
165 |
\subsubsection*{Task (file postfix2.scala)}
|
|
166 |
|
|
167 |
\begin{itemize}
|
347
|
168 |
\item[(3/4)] Extend the code in (1) and (2) to include the power
|
284
|
169 |
operator. This requires proper account of associativity of
|
|
170 |
the operators. The power operator is right-associative, whereas the
|
|
171 |
other operators are left-associative. Left-associative operators
|
|
172 |
are popped off if the precedence is bigger or equal, while
|
|
173 |
right-associative operators are only popped off if the precedence is
|
347
|
174 |
bigger.\hfill[1 Marks]
|
284
|
175 |
\end{itemize}
|
|
176 |
|
6
|
177 |
\end{document}
|
|
178 |
|
68
|
179 |
|
6
|
180 |
%%% Local Variables:
|
|
181 |
%%% mode: latex
|
|
182 |
%%% TeX-master: t
|
|
183 |
%%% End:
|