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  | 
  |