author | Christian Urban <urbanc@in.tum.de> |
Thu, 06 Dec 2018 22:51:46 +0000 | |
changeset 237 | db4d2fcd8063 |
parent 218 | 22705d22c105 |
child 265 | 59779ce322a6 |
permissions | -rw-r--r-- |
6 | 1 |
\documentclass{article} |
62 | 2 |
\usepackage{../style} |
78 | 3 |
\usepackage{../langs} |
6 | 4 |
|
5 |
\begin{document} |
|
6 |
||
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
7 |
\section*{Replacement Coursework 1 (Roman Numerals)} |
6 | 8 |
|
100 | 9 |
This coursework is worth 10\%. It is about translating roman numerals |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
10 |
into integers and also about validating roman numerals. The coursework |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
11 |
is due on 2 February at 5pm. Make sure the files you submit can be |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
12 |
processed by just calling \texttt{scala <<filename.scala>>}.\bigskip |
62 | 13 |
|
14 |
\noindent |
|
15 |
\textbf{Important:} Do not use any mutable data structures in your |
|
110 | 16 |
submission! They are not needed. This menas you cannot use |
62 | 17 |
\texttt{ListBuffer}s, for example. Do not use \texttt{return} in your |
68 | 18 |
code! It has a different meaning in Scala, than in Java. Do not use |
19 |
\texttt{var}! This declares a mutable variable. Make sure the |
|
62 | 20 |
functions you submit are defined on the ``top-level'' of Scala, not |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
21 |
inside a class or object. Also note that the running time will be |
110 | 22 |
restricted to a maximum of 360 seconds on my laptop. |
86 | 23 |
|
6 | 24 |
|
100 | 25 |
\subsection*{Disclaimer} |
6 | 26 |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
27 |
It should be understood that the work you submit represents your own |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
28 |
effort! You have not copied from anyone else. An exception is the |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
29 |
Scala code I showed during the lectures or uploaded to KEATS, which |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
30 |
you can freely use.\bigskip |
6 | 31 |
|
32 |
||
100 | 33 |
\subsection*{Part 1 (Translation)} |
6 | 34 |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
35 |
\noindent |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
36 |
Roman numerals are strings consisting of the letters $I$, $V$, $X$, |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
37 |
$L$, $C$, $D$, and $M$. Such strings should be transformed into an |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
38 |
internal representation using the datatypes \texttt{RomanDigit} and |
109 | 39 |
\texttt{RomanNumeral} (defined in \texttt{roman.scala}), and then from |
40 |
this internal representation converted into Integers. |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
41 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
42 |
\begin{itemize} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
43 |
\item[(1)] First write a polymorphic function that recursively |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
44 |
transforms a list of options into an option of a list. For example, |
109 | 45 |
if you have the lists on the left-hand side, they should be transformed into |
110 | 46 |
the options on the right-hand side: |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
47 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
48 |
\begin{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
49 |
\begin{tabular}{lcl} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
50 |
\texttt{List(Some(1), Some(2), Some(3))} & $\Rightarrow$ & |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
51 |
\texttt{Some(List(1, 2, 3))} \\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
52 |
\texttt{List(Some(1), None, Some(3))} & $\Rightarrow$ & |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
53 |
\texttt{None} \\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
54 |
\texttt{List()} & $\Rightarrow$ & \texttt{Some(List())} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
55 |
\end{tabular} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
56 |
\end{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
57 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
58 |
This means the function should produce \texttt{None} as soon |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
59 |
as a \texttt{None} is inside the list. Otherwise it produces |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
60 |
a list of all \texttt{Some}s. In case the list is empty, it |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
61 |
produces \texttt{Some} of the empty list. \hfill[1 Mark] |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
62 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
63 |
|
109 | 64 |
\item[(2)] Write first a function that converts the characters $I$, $V$, |
65 |
$X$, $L$, $C$, $D$, and $M$ into an option of a \texttt{RomanDigit}. |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
66 |
If it is one of the roman digits, it should produce \texttt{Some}; |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
67 |
otherwise \texttt{None}. |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
68 |
|
109 | 69 |
Next write a function that converts a string into a |
70 |
\texttt{RomanNumeral}. Again, this function should return an |
|
71 |
\texttt{Option}: If the string consists of $I$, $V$, $X$, $L$, $C$, |
|
72 |
$D$, and $M$ only, then it produces \texttt{Some}; otherwise if |
|
73 |
there is any other character in the string, it should produce |
|
74 |
\texttt{None}. The empty string is just the empty |
|
75 |
\texttt{RomanNumeral}, that is the empty list of |
|
76 |
\texttt{RomanDigit}'s. You should use the function under Task (1) |
|
77 |
to produce the result. \hfill[2 Marks] |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
78 |
|
109 | 79 |
\item[(3)] Write a recursive function \texttt{RomanNumral2Int} that |
80 |
converts a \texttt{RomanNumeral} into an integer. You can assume the |
|
81 |
generated integer will be between 0 and 3999. The argument of the |
|
82 |
function is a list of roman digits. It should look how this list |
|
83 |
starts and then calculate what the corresponding integer is for this |
|
84 |
``start'' and add it with the integer for the rest of the list. That |
|
85 |
means if the argument is of the form shown on the left-hand side, it |
|
86 |
should do the calculation on the right-hand side. |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
87 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
88 |
\begin{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
89 |
\begin{tabular}{lcl} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
90 |
$M::r$ & $\Rightarrow$ & $1000 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
91 |
$C::M::r$ & $\Rightarrow$ & $900 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
92 |
$D::r$ & $\Rightarrow$ & $500 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
93 |
$C::D::r$ & $\Rightarrow$ & $400 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
94 |
$C::r$ & $\Rightarrow$ & $100 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
95 |
$X::C::r$ & $\Rightarrow$ & $90 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
96 |
$L::r$ & $\Rightarrow$ & $50 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
97 |
$X::L::r$ & $\Rightarrow$ & $40 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
98 |
$X::r$ & $\Rightarrow$ & $10 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
99 |
$I::X::r$ & $\Rightarrow$ & $9 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
100 |
$V::r$ & $\Rightarrow$ & $5 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
101 |
$I::V::r$ & $\Rightarrow$ & $4 + \text{roman numeral of rest}\; r$\\ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
102 |
$I::r$ & $\Rightarrow$ & $1 + \text{roman numeral of rest}\; r$ |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
103 |
\end{tabular} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
104 |
\end{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
105 |
|
109 | 106 |
The empty list will be converted to integer $0$.\hfill[1 Mark] |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
107 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
108 |
\item[(4)] Write a function that takes a string and if possible |
109 | 109 |
converts it into the internal representation. If successful, it then |
110 |
calculates the integer (an option of an integer) according to the |
|
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
111 |
function in (3). If this is not possible, then return |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
112 |
\texttt{None}.\hfill[1 Mark] |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
113 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
114 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
115 |
\item[(5)] The file \texttt{roman.txt} contains a list of roman numerals. |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
116 |
Read in these numerals, convert them into integers and then add them all |
109 | 117 |
up. The Scala function for reading a file is |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
118 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
119 |
\begin{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
120 |
\texttt{Source.fromFile("filename")("ISO-8859-9")} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
121 |
\end{center} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
122 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
123 |
Make sure you process the strings correctly by ignoring whitespaces |
109 | 124 |
where needed.\\ \mbox{}\hfill[1 Mark] |
105
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
125 |
\end{itemize} |
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
126 |
|
67ce930b5935
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
100
diff
changeset
|
127 |
|
100 | 128 |
\subsection*{Part 2 (Validation)} |
78 | 129 |
|
109 | 130 |
As you can see the function under Task (3) can produce some unexpected |
131 |
results. For example for $XXCIII$ it produces 103. The reason for this |
|
132 |
unexpected result is that $XXCIII$ is actually not a valid roman |
|
133 |
number, neither is $IIII$ for 4 nor $MIM$ for 1999. Although actual |
|
134 |
Romans were not so fussy about this,\footnote{They happily used |
|
135 |
numbers like $XIIX$ or $IIXX$ for 18.} but modern times declared |
|
136 |
that there are precise rules for what a valid roman number is, namely: |
|
137 |
||
138 |
\begin{itemize} |
|
139 |
\item Repeatable roman digits are $I$, $X$, $C$ and $M$. The other ones |
|
140 |
are non-repeatable. Repeatable digits can be repeated upto 3 times in a |
|
141 |
number (for example $MMM$ is OK); non-repeatable digits cannot be |
|
142 |
repeated at all (for example $VV$ is excluded). |
|
143 |
||
111 | 144 |
\item If a smaller digits precedes a bigger digit, then $I$ can precede $V$ and $X$; $X$ can preced |
109 | 145 |
$L$ and $C$; and $C$ can preced $D$ and $M$. No other combination is permitted in this case. |
146 |
||
147 |
\item If a smaller digit precedes a bigger digit (for example $IV$), then the smaller number |
|
148 |
must be either the first digit in the number, or follow a digit which is at least 10 times its value. |
|
149 |
So $VIV$ is excluded, because $I$ follows $V$ and $I * 10$ is bigger than $V$; but $XIV$ is |
|
150 |
allowed, because $I$ follows $X$ and $I * 10$ is equal to $X$. |
|
151 |
||
152 |
\item Let us say two digits are called a \emph{compound} roman digit |
|
153 |
when a smaller digit precedes a bigger digit (so $IV$, $XL$, $CM$ |
|
154 |
for example). If a compound digit is followed by another digit, then |
|
155 |
this digit must be smaller than the first digit in the compound |
|
156 |
digit. For example $IXI$ is excluded, but $XLI$ is not. |
|
157 |
||
158 |
\item The empty roman numeral is valid. |
|
159 |
\end{itemize} |
|
160 |
||
161 |
\noindent |
|
162 |
The tasks in this part are as follows: |
|
163 |
||
164 |
\begin{itemize} |
|
165 |
\item[(6)] Implement a recursive function \texttt{isValidNumeral} that |
|
166 |
takes a \texttt{RomanNumeral} as argument and produces true if \textbf{all} |
|
167 |
the rules above are satisfied, and otherwise false. |
|
168 |
||
169 |
Hint: It might be more convenient to test when the rules fail and then return false; |
|
170 |
return true in all other cases. |
|
171 |
\mbox{}\hfill[2 Marks] |
|
172 |
||
173 |
\item[(7)] Write a recursive function that converts an Integer into a \texttt{RomanNumeral}. |
|
174 |
You can assume the function will only be called for integers between 0 and 3999.\mbox{}\hfill[1 Mark] |
|
175 |
||
176 |
\item[(8)] Write a function that reads a text file (for example \texttt{roman2.txt}) |
|
177 |
containing valid and invalid roman numerals. Convert all valid roman numerals into |
|
178 |
integers, add them up and produce the result as a \texttt{RomanNumeral} (using the function |
|
179 |
from (7)). \hfill[1 Mark] |
|
180 |
\end{itemize} |
|
181 |
||
6 | 182 |
|
183 |
\end{document} |
|
184 |
||
68 | 185 |
|
6 | 186 |
%%% Local Variables: |
187 |
%%% mode: latex |
|
188 |
%%% TeX-master: t |
|
189 |
%%% End: |