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