25 lectures. Make sure the files you submit can be processed by just |
25 lectures. Make sure the files you submit can be processed by just |
26 calling \texttt{scala <<filename.scala>>}.\bigskip |
26 calling \texttt{scala <<filename.scala>>}.\bigskip |
27 |
27 |
28 \noindent |
28 \noindent |
29 \textbf{Important:} Do not use any mutable data structures in your |
29 \textbf{Important:} Do not use any mutable data structures in your |
30 submissions! They are not needed. This excludes the use of |
30 submissions! They are not needed. This means you cannot use |
31 \texttt{ListBuffer}s, for example. Do not use \texttt{return} in your |
31 \texttt{ListBuffer}s, for example. Do not use \texttt{return} in your |
32 code! It has a different meaning in Scala, than in Java. |
32 code! It has a different meaning in Scala, than in Java. |
33 Do not use \texttt{var}! This declares a mutable variable. Feel free to |
33 Do not use \texttt{var}! This declares a mutable variable. Feel free to |
34 copy any code you need from files \texttt{knight1.scala}, |
34 copy any code you need from files \texttt{knight1.scala}, |
35 \texttt{knight2.scala} and \texttt{knight3.scala}. Make sure the |
35 \texttt{knight2.scala} and \texttt{knight3.scala}. Make sure the |
36 functions you submit are defined on the ``top-level'' of Scala, not |
36 functions you submit are defined on the ``top-level'' of Scala, not |
37 inside a class or object. Also note that the running time of |
37 inside a class or object. Also note that the running time of |
38 each part will be restricted to a maximum of 360 seconds. |
38 each part will be restricted to a maximum of 360 seconds on my |
|
39 laptop. |
39 |
40 |
40 |
41 |
41 \subsection*{Disclaimer} |
42 \subsection*{Disclaimer} |
42 |
43 |
43 It should be understood that the work you submit represents |
44 It should be understood that the work you submit represents |
46 uploaded to KEATS, which you can freely use.\medskip |
47 uploaded to KEATS, which you can freely use.\medskip |
47 |
48 |
48 \subsection*{Background} |
49 \subsection*{Background} |
49 |
50 |
50 The \textit{Knight's Tour Problem} is about finding a tour such that |
51 The \textit{Knight's Tour Problem} is about finding a tour such that |
51 the knight visits every field on an $n\times n$ chessboard once. Such |
52 the knight visits every field on an $n\times n$ chessboard once. For |
52 a tour is called \emph{open} tour. For example on a $5\times 5$ |
53 example on a $5\times 5$ chessboard, a knight's tour is: |
53 chessboard, an open knight's tour is: |
|
54 |
54 |
55 |
55 |
56 \chessboard[maxfield=d4, |
56 \chessboard[maxfield=d4, |
57 pgfstyle= {[base,at={\pgfpoint{0pt}{-0.5ex}}]text}, |
57 pgfstyle= {[base,at={\pgfpoint{0pt}{-0.5ex}}]text}, |
58 text = \small 24, markfield=Z4, |
58 text = \small 24, markfield=Z4, |
88 $2\times 2$, $3\times 3$ and $4\times 4$ chessboards, but for every |
88 $2\times 2$, $3\times 3$ and $4\times 4$ chessboards, but for every |
89 bigger board there is. |
89 bigger board there is. |
90 |
90 |
91 A knight's tour is called \emph{closed}, if the last step in the tour |
91 A knight's tour is called \emph{closed}, if the last step in the tour |
92 is within a knight's move to the beginning of the tour. So the above |
92 is within a knight's move to the beginning of the tour. So the above |
93 knight's tour is \underline{not} closed (it is open) because the last |
93 knight's tour is \underline{not} closed because the last |
94 step on field $(0, 4)$ is not within the reach of the first step on |
94 step on field $(0, 4)$ is not within the reach of the first step on |
95 $(4, 4)$. It turns out there is no closed knight's tour on a $5\times |
95 $(4, 4)$. It turns out there is no closed knight's tour on a $5\times |
96 5$ board. But there are on a $6\times 6$ board and on bigger ones, for |
96 5$ board. But there are on a $6\times 6$ board and on bigger ones, for |
97 example |
97 example |
98 |
98 |
197 |
197 |
198 |
198 |
199 \subsubsection*{Tasks (file knight1.scala)} |
199 \subsubsection*{Tasks (file knight1.scala)} |
200 |
200 |
201 \begin{itemize} |
201 \begin{itemize} |
202 \item[(1a)] Implement an is-legal-move function that takes a |
202 \item[(1a)] Implement an \texttt{is-legal-move} function that takes a |
203 dimension, a path and a position as argument and tests whether the |
203 dimension, a path and a position as argument and tests whether the |
204 position is inside the board and not yet element in the |
204 position is inside the board and not yet element in the |
205 path. \hfill[1 Mark] |
205 path. \hfill[1 Mark] |
206 |
206 |
207 \item[(1b)] Implement a legal-moves function that calculates for a |
207 \item[(1b)] Implement a \texttt{legal-moves} function that calculates for a |
208 position all legal onward moves. If the onward moves are |
208 position all legal onward moves. If the onward moves are |
209 placed on a circle, you should produce them starting from |
209 placed on a circle, you should produce them starting from |
210 ``12-oclock'' following in clockwise order. For example on an |
210 ``12-oclock'' following in clockwise order. For example on an |
211 $8\times 8$ board for a knight on position $(2, 2)$ and otherwise |
211 $8\times 8$ board for a knight on position $(2, 2)$ and otherwise |
212 empty board, the legal-moves function should produce the onward |
212 empty board, the legal-moves function should produce the onward |
225 \end{center} |
225 \end{center} |
226 \mbox{}\hfill[1 Mark] |
226 \mbox{}\hfill[1 Mark] |
227 |
227 |
228 \item[(1c)] Implement two recursive functions (count-tours and |
228 \item[(1c)] Implement two recursive functions (count-tours and |
229 enum-tours). They each take a dimension and a path as |
229 enum-tours). They each take a dimension and a path as |
230 arguments. They exhaustively search for {\bf open} tours starting |
230 arguments. They exhaustively search for tours starting |
231 from the given path. The first function counts all possible open |
231 from the given path. The first function counts all possible |
232 tours (there can be none for certain board sizes) and the second |
232 tours (there can be none for certain board sizes) and the second |
233 collects all open tours in a list of paths.\hfill[2 Marks] |
233 collects all tours in a list of paths.\hfill[2 Marks] |
234 \end{itemize} |
234 \end{itemize} |
235 |
235 |
236 \noindent \textbf{Test data:} For the marking, the functions in (1c) |
236 \noindent \textbf{Test data:} For the marking, the functions in (1c) |
237 will be called with board sizes up to $5 \times 5$. If you search |
237 will be called with board sizes up to $5 \times 5$. If you search |
238 for open tours on a $5 \times 5$ board starting only from field $(0, 0)$, |
238 for tours on a $5 \times 5$ board starting only from field $(0, 0)$, |
239 there are 304 of tours. If you try out every field of a $5 \times |
239 there are 304 of tours. If you try out every field of a $5 \times |
240 5$-board as a starting field and add up all open tours, you obtain |
240 5$-board as a starting field and add up all tours, you obtain |
241 1728. A $6\times 6$ board is already too large to be searched |
241 1728. A $6\times 6$ board is already too large to be searched |
242 exhaustively.\footnote{For your interest, the number of open tours on |
242 exhaustively.\footnote{For your interest, the number of tours on |
243 $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320, |
243 $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320, |
244 19591828170979904, respectively.} |
244 19591828170979904, respectively.} |
245 |
245 |
246 \subsubsection*{Tasks (file knight2.scala)} |
246 \subsubsection*{Tasks (file knight2.scala)} |
247 |
247 |
269 point however you should take into account when implementing |
269 point however you should take into account when implementing |
270 \textit{first}: you will need to calculate what the result of $f(x)$ |
270 \textit{first}: you will need to calculate what the result of $f(x)$ |
271 is; your code should do this only \textbf{once}!\\\mbox{}\hfill[1 Mark] |
271 is; your code should do this only \textbf{once}!\\\mbox{}\hfill[1 Mark] |
272 |
272 |
273 \item[(2b)] Implement a first-tour function that uses the |
273 \item[(2b)] Implement a first-tour function that uses the |
274 first-function from (2a), and searches recursively for an open tour. |
274 first-function from (2a), and searches recursively for a tour. |
275 As there might not be such a tour at all, the first-tour function |
275 As there might not be such a tour at all, the first-tour function |
276 needs to return an \texttt{Option[Path]}.\\\mbox{}\hfill[2 Marks] |
276 needs to return an \texttt{Option[Path]}.\\\mbox{}\hfill[2 Marks] |
277 \end{itemize} |
277 \end{itemize} |
278 |
278 |
279 \noindent |
279 \noindent |
281 sizes of up to $8 \times 8$. |
281 sizes of up to $8 \times 8$. |
282 |
282 |
283 |
283 |
284 \subsection*{Part 2 (3 Marks)} |
284 \subsection*{Part 2 (3 Marks)} |
285 |
285 |
286 As you should have seen in Part 1, a naive search for open tours |
286 As you should have seen in Part 1, a naive search for tours |
287 beyond $8 \times 8$ boards and also searching for closed tours |
287 beyond $8 \times 8$ boards and also searching for closed tours |
288 takes too much time. There is a heuristic (called Warnsdorf's rule) |
288 takes too much time. There is a heuristic, called Warnsdorf's rule |
289 that can speed up finding a tour. This heuristic states that a knight |
289 that can speed up finding a tour. This heuristic states that a knight |
290 is moved so that it always proceeds to the field from which the |
290 is moved so that it always proceeds to the field from which the |
291 knight will have the \underline{fewest} onward moves. For example for |
291 knight will have the \underline{fewest} onward moves. For example for |
292 a knight on field $(1, 3)$, the field $(0, 1)$ has the fewest possible |
292 a knight on field $(1, 3)$, the field $(0, 1)$ has the fewest possible |
293 onward moves, namely 2. |
293 onward moves, namely 2. |
329 the ordered-moves function from (3a). It is more likely to find |
329 the ordered-moves function from (3a). It is more likely to find |
330 a solution when started in the middle of the board (that is |
330 a solution when started in the middle of the board (that is |
331 position $(dimension / 2, dimension / 2)$). \hfill[1 Mark] |
331 position $(dimension / 2, dimension / 2)$). \hfill[1 Mark] |
332 |
332 |
333 \item[(3c)] Implement a first-tour-heuristic function for boards up to $50\times 50$. |
333 \item[(3c)] Implement a first-tour-heuristic function for boards up to $50\times 50$. |
334 It is the same function as in (3b) but searches for \textbf{open} tours. You have |
334 It is the same function as in (3b) but searches for tours. You have |
335 to be careful to write a tail-recursive version of the first-tour-heuristic |
335 to be careful to write a tail-recursive version of the first-tour-heuristic |
336 function otherwise you will get problems with stack-overflows. \hfill[1 Mark] |
336 function otherwise you will get problems with stack-overflows. \hfill[1 Mark] |
337 \end{itemize} |
337 \end{itemize} |
338 |
338 |
339 \end{document} |
339 \end{document} |