| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      1 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      2 | % !TEX program = xelatex
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      3 | \documentclass{article}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      4 | \usepackage{../styles/style}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      5 | \usepackage{disclaimer}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      6 | \usepackage{../styles/langs}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      7 | \usepackage{graphicx}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      8 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |      9 | \begin{document}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     10 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     11 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     12 | %% should ask to lower case the words.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     13 | 
 | 
| 456 |     14 | \section*{Resit: Evil Wordle Game (Scala, 7 Marks)}
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     15 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     16 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     17 | \noindent
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     18 | You are asked to implement a Scala program for making the popular Wordle game as difficult
 | 
| 456 |     19 | as possible. The deadline for your submission is on 24th January at 23:00. There will be no
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     20 | automated tests for the resit, but there are plenty of testcases in the template and the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     21 | task description. \bigskip
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     22 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     23 | \IMPORTANTNONE{}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     24 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     25 | \noindent
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     26 | Also note that the running time of each part will be restricted to a
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     27 | maximum of 30 seconds on my laptop.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     28 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     29 | \DISCLAIMER{}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     30 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     31 | \subsection*{Hints}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     32 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     33 | \noindent
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     34 | Useful data functions: \texttt{Source.fromURL},
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     35 | \texttt{Source.fromFile} for obtaining a webpage and reading a file,
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     36 | \texttt{.getOrElse(..,..)} allows to query a Map, but also gives a
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     37 | default value if the Map is not defined, a Map can be `updated' by
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     38 | using \texttt{+}, \texttt{.contains} and \texttt{.filter} can test whether
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     39 | an element is included in a list, and respectively filter out elements in a list,
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     40 | \texttt{.sortBy(\_.\_2)} sorts a list of pairs according to the second
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     41 | elements in the pairs---the sorting is done from smallest to highest,
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     42 | \texttt{.groupBy} orders lists according to same elements
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     43 | .
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     44 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     45 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     46 | \newpage
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     47 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     48 | 
 | 
| 456 |     49 | \subsection*{Resit (7 Marks, file wordle.scala)}
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     50 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     51 | You probably know the game of Wordle\footnote{\url{https://en.wikipedia.org/wiki/Wordle}}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     52 | where you are supposed to guess a five-letter word. The feedback for guesses can help
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     53 | with the next guess (green letters are correct, orange letters are present, but in the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     54 | wrong place). For example:
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     55 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     56 | \begin{center}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     57 | \includegraphics[scale=0.2]{../pics/w.jpeg}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     58 | \end{center}  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     59 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     60 | \noindent
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     61 | The idea of the program to be implemented here is to make the Wordle game as evil as possible
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     62 | by finding words that are the most difficult to guess. A word list of five-letter words is available
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     63 | from 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     64 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     65 | \begin{center}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     66 | \begin{tabular}{ll}  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     67 |   \url{https://nms.kcl.ac.uk/christian.urban/wordle.txt} & (78 KByte)\\
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     68 | \end{tabular}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     69 | \end{center}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     70 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     71 | \noindent
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     72 | In your program you need to download this list and implement some
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     73 | functions that in the end select the most difficult words (given an
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     74 | input from the user).  If bandwidth is an issue for you, download the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     75 | file locally, but in the submitted version use \texttt{Source.fromURL}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     76 | instead of \texttt{Source.fromFile}.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     77 | 
 | 
| 456 |     78 | 
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     79 | \subsection*{Tasks}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     80 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     81 | \begin{itemize}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     82 | \item[(1)] Implement the function \pcode{get_wordle_list} which takes an
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     83 |   URL-string as argument and requests the corresponding file. The function should
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     84 |   return the word list appropriately broken up into lines.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     85 |   The result should be a list of strings (the lines in the file). In case
 | 
| 456 |     86 |   the url does not produce a file, return the empty list.
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     87 | 
 | 
| 456 |     88 |   In what follows we will use \texttt{secrets} to refer  to the list of words listed
 | 
|  |     89 |   in \texttt{wordle.txt}.  
 | 
|  |     90 |   
 | 
|  |     91 |   \mbox{}\hfill [0.5 Marks]
 | 
|  |     92 | 
 | 
|  |     93 | \item[(2)] Implement a polymorphic function \pcode{removeN}, which removes $n$ occurrences of an
 | 
|  |     94 |   element from a list (if this element is less than $n$ times present, then remove all occurrences).
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     95 |   For example
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     96 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |     97 | \begin{lstlisting}[numbers=none]
 | 
| 456 |     98 | removeN(List(1,2,3,2,1), 3, 2) => List(1, 2, 2, 1)
 | 
|  |     99 | removeN(List(1,2,3,2,1), 2, 1) => List(1, 3, 2, 1)
 | 
|  |    100 | removeN(List(1,2,3,2,1), 2, 2) => List(1, 3, 1)
 | 
|  |    101 | removeN(List(1,2,3,2,1), 1, 1) => List(2, 3, 2, 1)
 | 
|  |    102 | removeN(List(1,2,3,2,1), 1, 3) => List(2, 3, 2)
 | 
|  |    103 | removeN(List(1,2,3,2,1), 0, 2) => List(1, 2, 3, 2, 1)
 | 
|  |    104 | removeN(List("1","2","3","2","1"), "1", 1)
 | 
|  |    105 |                            => List("2","3","2","1")
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    106 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    107 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    108 | Make sure you only remove at most $n$ occurrences of the element from the list.
 | 
| 456 |    109 | This function should work for lists of integers but also lists of chars, strings etc.\\
 | 
|  |    110 |   \mbox{}\hfill [0.5 Marks]
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    111 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    112 | \item[(3)] Implement a function \pcode{score} that calculates the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    113 |   feedback for a word against a secret word using the rules of the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    114 |   Wordle game. The output of \pcode{score} should be a list of 5
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    115 |   elements of type \pcode{Tip} representing three outcomes: a letter
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    116 |   in the correct position, a letter that is present, but not in the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    117 |   correct position and a letter that is absent. For example given the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    118 |   secret word "chess" the score for the word "caves" is
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    119 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    120 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    121 | List(Correct, Absent, Absent, Present, Correct)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    122 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    123 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    124 |   You have to be careful with multiple occurrences of letters. For example
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    125 |   the secret "chess" with the guess "swiss" should produce
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    126 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    127 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    128 | List(Absent, Absent, Absent, Correct, Correct)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    129 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    130 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    131 | even though the first 's' in "swiss" is present in the secret word, the 's' are already
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    132 | `used up' by the two letters that are correct. To implement this you need to
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    133 | implement first a function \pcode{pool} which calculates all the letters in
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    134 | a secret that are not correct in a word. For example
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    135 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    136 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    137 |   pool("chess", "caves")  => List(h, e, s)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    138 |   pool("chess", "swiss")  => List(c, h, e)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    139 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    140 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    141 |   Now the helper function \pcode{aux} can analyse the arguments secret and word recursively letter-by-letter and
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    142 |   decide: if the letters are the same, then return \pcode{Correct} for the corresponding position.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    143 |   If they are not the same, but the letter is in the pool, then return \pcode{Present} and also remove
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    144 |   this letter from the pool in the next recursive call of \pcode{aux}. Otherwise return \pcode{Absent} for the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    145 |   corresponding position. The function \pcode{score} is a wrapper for the function \pcode{aux}
 | 
| 456 |    146 |   calling \pcode{aux} with the appropriate arguments (recall what is calculated with \pcode{pool}).\mbox{}\hfill [2 Marks]
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    147 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    148 | \item[(4)] Implement a function \pcode{eval} that gives an integer value to each of the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    149 |   \pcode{Tip}s such that
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    150 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    151 |   \begin{center}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    152 |   \begin{tabular}{lcl}  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    153 |     \textit{eval (Correct)} & $\dn$ & $10$\\
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    154 |     \textit{eval (Present)} & $\dn$ & $1$\\
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    155 |     \textit{eval (Absent)} & $\dn$ & $0$
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    156 |   \end{tabular}                                   
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    157 |   \end{center}  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    158 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    159 |   The function \pcode{iscore} then takes an output of \pcode{score} and sums
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    160 |   up all corresponding values. For example for 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    161 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    162 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    163 |   iscore("chess", "caves")  => 21
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    164 |   iscore("chess", "swiss")  => 20
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    165 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    166 |   \mbox{}\hfill [0.5 Marks]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    167 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    168 | \item[(5)] The function \pcode{evil} takes a list of secrets (the list from Task 1)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    169 |   and a word as arguments, and calculates the list of words with the lowest
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    170 |   score (remember we want to make the Wordle game as difficult as possible---therefore
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    171 |   when the user gives us a word, we want to find the secrets that produce the lowest
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    172 |   score). For this implement a helper function \pcode{lowest} that goes through
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    173 |   the secrets one-by-one and calculates the score. The argument \pcode{current} is
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    174 |   the score of the ``currently'' found secrets. When the function \pcode{lowest}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    175 |   is called for the first time then this will be set to the maximum integer value
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    176 |   \pcode{Int.MaxValue}. The accumulator will be first empty. If a secret is found
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    177 |   with the same score as \pcode{current} then this word is added to the accumulator.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    178 |   If the secret has a lower score, then the accumulator will be discarded and this
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    179 |   secret will be the new accumulator. If the secret has a higher score, then it can be
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    180 |   ignored. For example \pcode{evil} (the wrapper for \pcode{lowest}) generates
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    181 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    182 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    183 | evil(secrets, "stent").length => 1907
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    184 | evil(secrets, "hexes").length => 2966
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    185 | evil(secrets, "horse").length => 1203
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    186 | evil(secrets, "hoise").length => 971
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    187 | evil(secrets, "house").length => 1228
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    188 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    189 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    190 | where \pcode{secrets} is the list generated under Task 1.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    191 | In all cases above the iscore of the resulting secrets is 0, but this does not need to be the case
 | 
| 456 |    192 | in general.
 | 
|  |    193 | 
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    194 |   \mbox{}\hfill [1.5 Marks]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    195 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    196 | \item[(6)] The secrets generated in Task 5 are the ones with the lowest score
 | 
| 456 |    197 |   with respect to the word. You can think of these as the secrets that are furthest ``away'' from the
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    198 |   given word. This is already quite evil for a secret word---remember we can choose
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    199 |   a secret \emph{after} a user has given a first word. Now we want to make it
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    200 |   even more evil by choosing words that have the most obscure letters. For this we
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    201 |   calculate the frequency of how many times certain letters occur in our secrets
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    202 |   list (see Task 1). The \emph{frequency} of the letter $c$, say, is given by the formula
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    203 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    204 |   \begin{center}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    205 |   $\textit{freq(c)} \dn 1 - \frac{\textit{number of occurrences of c}}{\textit{number of all letters}}$  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    206 |   \end{center}  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    207 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    208 |   That means that letters that occur fewer times in our secrets have a higher frequency.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    209 |   For example the letter 'y' has the frequency 0.9680234350909651 while the much more
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    210 |   often occurring letter 'e' has only 0.897286463151403 (all calculations should be done
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    211 |   with Doubles).
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    212 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    213 |   The function \pcode{frequencies} should calculate the frequencies for all lower-case letters
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    214 |   by generating a Map from letters (\pcode{Char}) to Doubles (frequencies).\\ 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    215 |   \mbox{}\hfill [1 Mark]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    216 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    217 | \item[(7)] In this task we want to use the output of \pcode{evil}, rank each string in the
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    218 |   generated set and then filter out the strings that are ranked highest (the ones with the most obscure letters).
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    219 |   This list of strings often contains only a single word, but in general there might be more (see below).
 | 
| 456 |    220 |   First implement a function \pcode{rank} that takes a frequency map (from 6) and a string as arguments.
 | 
|  |    221 |   In the testcases, the frequency map is generated for all words in \texttt{secrets}, that is the
 | 
|  |    222 |   whole list in \texttt{wordle.txt}. The function  
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    223 |   generates a rank by summing up all frequencies of the letters in the string. For example
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    224 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    225 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    226 | rank(frequencies(secrets), "adobe") => 4.673604687018193
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    227 | rank(frequencies(secrets), "gaffe") => 4.745205057045945
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    228 | rank(frequencies(secrets), "fuzzy") => 4.898735738513722
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    229 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    230 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    231 |   Finally, implement a function \pcode{ranked_evil} that selects from the output of \pcode{evil}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    232 |   the string(s) which are highest ranked in evilness.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    233 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    234 |   
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    235 | \begin{lstlisting}[numbers=none]
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    236 | ranked_evil(secrets, "abbey") => List(whizz)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    237 | ranked_evil(secrets, "afear") => List(buzzy)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    238 | ranked_evil(secrets, "zincy") => List(jugum)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    239 | ranked_evil(secrets, "zippy") => List(chuff)
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    240 | \end{lstlisting}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    241 | 
 | 
| 456 |    242 | This means if the user types in "abbey" then the most evil word to choose as secret is ``whizz'' (according to
 | 
| 424 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    243 | our calculations). This word has a zero \pcode{iscore} and the most obscure letters.
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    244 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    245 | \mbox{}\hfill [1 Mark]  
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    246 | \end{itemize}
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    247 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    248 | \end{document} 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    249 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    250 | %%% Local Variables: 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    251 | %%% mode: latex
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    252 | %%% TeX-master: t
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    253 | %%% End: 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    254 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    255 | 
 | 
| 
Christian Urban <christian.urban@kcl.ac.uk> parents: diff
changeset |    256 | 
 |