17 hlabelformat=\arabic{ranklabel}, |
17 hlabelformat=\arabic{ranklabel}, |
18 vlabelformat=\arabic{filelabel}} |
18 vlabelformat=\arabic{filelabel}} |
19 |
19 |
20 \mbox{}\\[-18mm]\mbox{} |
20 \mbox{}\\[-18mm]\mbox{} |
21 |
21 |
22 \section*{Preliminary and Main Part 4 (Scala, 4 + 6 Marks)} |
22 \section*{Main Part 4 (Scala, 9 Marks)} |
23 |
23 |
24 \mbox{}\hfill\textit{``The problem with object-oriented languages is they’ve got all this implicit,}\\ |
24 \mbox{}\hfill\textit{``The problem with object-oriented languages is they’ve got all this implicit,}\\ |
25 \mbox{}\hfill\textit{environment that they carry around with them. You wanted a banana but}\\ |
25 \mbox{}\hfill\textit{environment that they carry around with them. You wanted a banana but}\\ |
26 \mbox{}\hfill\textit{what you got was a gorilla holding the banana and the entire jungle.''}\smallskip\\ |
26 \mbox{}\hfill\textit{what you got was a gorilla holding the banana and the entire jungle.''}\smallskip\\ |
27 \mbox{}\hfill\textit{ --- Joe Armstrong (creator of the Erlang programming language)}\medskip\bigskip |
27 \mbox{}\hfill\textit{ --- Joe Armstrong (creator of the Erlang programming language)}\medskip\bigskip |
28 |
28 |
29 \noindent |
29 \noindent |
30 This part is about searching and backtracking. You are asked to |
30 This part is about searching and backtracking. You are asked to |
31 implement Scala programs that solve various versions of the |
31 implement Scala programs that solve various versions of the |
32 \textit{Knight's Tour Problem} on a chessboard. The preliminary part (4\%) is |
32 \textit{Knight's Tour Problem} on a chessboard. |
33 due on \sout{\cwNINE{}} \textcolor{red}{16 December} at 5pm; the core part (6\%) is due on \cwNINEa{} at 5pm. |
33 % The preliminary part (4\%) is due on \sout{\cwNINE{}} |
34 Any 1\% you achieve in the preliminary part counts as your ``weekly engagement''. |
34 % \textcolor{red}{16 December} at 5pm; the core part (6\%) |
|
35 % is due on \cwNINEa{} at 5pm. Any 1\% you achieve in the |
|
36 % preliminary part counts as your ``weekly engagement''. |
35 \bigskip |
37 \bigskip |
36 %Note the core, more advanced, part might include material you have not |
38 |
|
39 % Note the core, more advanced, part might include material you have not |
37 %yet seen in the first three lectures. \bigskip |
40 %yet seen in the first three lectures. \bigskip |
38 |
41 |
39 \IMPORTANTNONE{} |
42 \IMPORTANTNONE{} |
40 |
43 |
41 \noindent |
44 \noindent |
162 setpieces={Ng7, Nb2}, |
165 setpieces={Ng7, Nb2}, |
163 boardfontsize=12pt,labelfontsize=9pt]} |
166 boardfontsize=12pt,labelfontsize=9pt]} |
164 |
167 |
165 \subsection*{Reference Implementation} |
168 \subsection*{Reference Implementation} |
166 |
169 |
167 \mbox{}\alert{}\textcolor{red}{You need to download \texttt{knight1.jar} from KEATS. The one |
170 %\mbox{}\alert{}\textcolor{red}{You need to download \texttt{knight1.jar} from K%EATS. The one |
168 supplied with github does not contain the correct code. See Scala coursework |
171 %supplied with github does not contain the correct code. See Scala coursework |
169 section on KEATS.}\medskip |
172 %section on KEATS.}\medskip |
170 |
173 |
171 \noindent |
174 \noindent |
172 This Scala part comes with three reference implementations in form of |
175 This Scala part comes with three reference implementations in form of |
173 \texttt{jar}-files. This allows you to run any test cases on your own |
176 \texttt{jar}-files. This allows you to run any test cases on your own |
174 computer. For example you can call Scala on the command line with the |
177 computer. For example you can call Scala on the command line with the |
175 option \texttt{-cp knight1.jar} and then query any function from the |
178 option \texttt{-cp knight1.jar} and then query any function from the |
176 \texttt{knight1.scala} template file. As usual you have to |
179 \texttt{knight1.scala} template file. As usual you have to |
177 prefix the calls with \texttt{CW9a}, \texttt{CW9b} and \texttt{CW9c}. |
180 prefix the calls with \texttt{M4a}, \texttt{M4b} and \texttt{M4c}. |
178 Since some of the calls are time sensitive, I included some timing |
181 Since some of the calls are time sensitive, I included some timing |
179 information. For example |
182 information. For example |
180 |
183 |
181 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
184 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
182 $ scala -cp knight1.jar |
185 $ scala -cp knight1.jar |
183 scala> CW9a.enum_tours(5, List((0, 0))).length |
186 scala> M4a.enum_tours(5, List((0, 0))).length |
184 Time needed: 1.722 secs. |
187 Time needed: 1.722 secs. |
185 res0: Int = 304 |
188 res0: Int = 304 |
186 |
189 |
187 scala> CW9a.print_board(8, CW9a.first_tour(8, List((0, 0))).get) |
190 scala> M4a.print_board(8, M4a.first_tour(8, List((0, 0))).get) |
188 Time needed: 15.411 secs. |
191 Time needed: 15.411 secs. |
189 |
192 |
190 51 46 55 44 53 4 21 12 |
193 51 46 55 44 53 4 21 12 |
191 56 43 52 3 22 13 24 5 |
194 56 43 52 3 22 13 24 5 |
192 47 50 45 54 25 20 11 14 |
195 47 50 45 54 25 20 11 14 |
199 |
202 |
200 |
203 |
201 \subsection*{Hints} |
204 \subsection*{Hints} |
202 |
205 |
203 \noindent |
206 \noindent |
204 \textbf{Preliminary Part} useful list functions: \texttt{.contains(..)} checks |
207 Useful list functions: \texttt{.contains(..)} checks |
205 whether an element is in a list, \texttt{.flatten} turns a list of |
208 whether an element is in a list, \texttt{.flatten} turns a list of |
206 lists into just a list, \texttt{\_::\_} puts an element on the head of |
209 lists into just a list, \texttt{\_::\_} puts an element on the head of |
207 the list, \texttt{.head} gives you the first element of a list (make |
210 the list, \texttt{.head} gives you the first element of a list (make |
208 sure the list is not \texttt{Nil}); a useful option function: |
211 sure the list is not \texttt{Nil}); a useful option function: |
209 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)}; |
212 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)}; |
210 anonymous functions can be constructed using \texttt{(x:Int) => ...}, |
213 anonymous functions can be constructed using \texttt{(x:Int) => ...}, |
211 this function takes an \texttt{Int} as an argument.\medskip |
214 this function takes an \texttt{Int} as an argument; |
212 |
215 a useful list function: \texttt{.sortBy} sorts a list |
213 |
|
214 \noindent |
|
215 \textbf{Main Part} a useful list function: \texttt{.sortBy} sorts a list |
|
216 according to a component given by the function; a function can be |
216 according to a component given by the function; a function can be |
217 tested to be tail-recursive by annotation \texttt{@tailrec}, which is |
217 tested to be tail-recursive by annotation \texttt{@tailrec}, which is |
218 made available by importing \texttt{scala.annotation.tailrec}.\medskip |
218 made available by importing \texttt{scala.annotation.tailrec}.\medskip |
219 |
219 |
220 |
220 |
221 |
221 |
222 |
222 |
223 \subsection*{Preliminary Part (4 Marks)} |
223 \subsection*{Tasks} |
224 |
224 |
225 You are asked to implement the knight's tour problem such that the |
225 You are asked to implement the knight's tour problem such that the |
226 dimension of the board can be changed. Therefore most functions will |
226 dimension of the board can be changed. Therefore most functions will |
227 take the dimension of the board as an argument. The fun with this |
227 take the dimension of the board as an argument. The fun with this |
228 problem is that even for small chessboard dimensions it has already an |
228 problem is that even for small chessboard dimensions it has already an |
252 \emph{tour} if the length of the path is $n \times n$, each element |
252 \emph{tour} if the length of the path is $n \times n$, each element |
253 occurs only once in the path, and each move follows the rules of how a |
253 occurs only once in the path, and each move follows the rules of how a |
254 knight moves (see above for the rules). |
254 knight moves (see above for the rules). |
255 |
255 |
256 |
256 |
257 \subsubsection*{Tasks (file knight1.scala)} |
257 \subsubsection*{Task 1 (file knight1.scala)} |
258 |
258 |
259 |
259 |
260 |
260 |
261 \begin{itemize} |
261 \begin{itemize} |
262 \item[(1)] Implement an \texttt{is\_legal} function that takes a |
262 \item[(1)] Implement an \texttt{is\_legal} function that takes a |
292 tours (there can be none for certain board sizes) and the second |
292 tours (there can be none for certain board sizes) and the second |
293 collects all tours in a list of paths. These functions will be |
293 collects all tours in a list of paths. These functions will be |
294 called with a path containing a single position---the starting field. |
294 called with a path containing a single position---the starting field. |
295 They are expected to extend this path so as to find all tours starting |
295 They are expected to extend this path so as to find all tours starting |
296 from the given position.\\ |
296 from the given position.\\ |
297 \mbox{}\hfill[2 Marks] |
297 \mbox{}\hfill[1 Mark] |
298 \end{itemize} |
298 \end{itemize} |
299 |
299 |
300 \noindent \textbf{Test data:} For the marking, the functions in (3) |
300 \noindent \textbf{Test data:} For the marking, the functions in (3) |
301 will be called with board sizes up to $5 \times 5$. If you search |
301 will be called with board sizes up to $5 \times 5$. If you search |
302 for tours on a $5 \times 5$ board starting only from field $(0, 0)$, |
302 for tours on a $5 \times 5$ board starting only from field $(0, 0)$, |
303 there are 304 of tours. If you try out every field of a $5 \times |
303 there are 304 of tours. If you try out every field of a $5 \times |
304 5$-board as a starting field and add up all tours, you obtain |
304 5$-board as a starting field and add up all tours, you obtain |
305 1728. A $6\times 6$ board is already too large to be searched |
305 1728. A $6\times 6$ board is already too large to be searched |
306 exhaustively.\footnote{For your interest, the number of tours on |
306 exhaustively.\footnote{For your interest, the number of tours on |
307 $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320, |
307 $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320, |
308 19591828170979904, respectively.}\smallskip |
308 19591828170979904, respectively.}\smallskip |
309 |
|
310 |
|
311 \subsection*{Core Part (6 Marks)} |
|
312 |
|
313 |
|
314 \subsubsection*{Tasks (file knight1.scala cont.)} |
|
315 |
|
316 \mbox{}\alert{}\textcolor{red}{You need to copy your \texttt{knight1.scala} |
|
317 from the preliminary part to the main part and then solve Tasks 4 and 5 |
|
318 inside the copied file. Do not forget to ``git add'' the file for |
|
319 pushing the results to the directory \texttt{main4}.}\medskip |
|
320 |
|
321 |
309 |
322 \begin{itemize} |
310 \begin{itemize} |
323 \item[(4)] Implement a \texttt{first}-function. This function takes a list of |
311 \item[(4)] Implement a \texttt{first}-function. This function takes a list of |
324 positions and a function $f$ as arguments; $f$ is the name we give to |
312 positions and a function $f$ as arguments; $f$ is the name we give to |
325 this argument). The function $f$ takes a position as argument and |
313 this argument). The function $f$ takes a position as argument and |
351 |
339 |
352 \item[(5)] Implement a \texttt{first\_tour} function that uses the |
340 \item[(5)] Implement a \texttt{first\_tour} function that uses the |
353 \texttt{first}-function from (4), and searches recursively for single tour. |
341 \texttt{first}-function from (4), and searches recursively for single tour. |
354 As there might not be such a tour at all, the \texttt{first\_tour} function |
342 As there might not be such a tour at all, the \texttt{first\_tour} function |
355 needs to return a value of type |
343 needs to return a value of type |
356 \texttt{Option[Path]}.\\\mbox{}\hfill[1 Mark] |
344 \texttt{Option[Path]}.\\\mbox{}\hfill[1 Mark] |
357 \end{itemize} |
345 \end{itemize} |
358 |
346 |
359 \noindent |
347 \noindent |
360 \textbf{Testing:} The \texttt{first\_tour} function will be called with board |
348 \textbf{Testing:} The \texttt{first\_tour} function will be called with board |
361 sizes of up to $8 \times 8$. |
349 sizes of up to $8 \times 8$. |
362 \bigskip |
350 \bigskip |
363 |
351 |
364 %%\newpage |
352 %%\newpage |
|
353 \subsubsection*{Task 2 (file knight2.scala)} |
365 |
354 |
366 \noindent |
355 \noindent |
367 As you should have seen in the earlier parts, a naive search for tours beyond |
356 As you should have seen in the earlier parts, a naive search for tours beyond |
368 $8 \times 8$ boards and also searching for closed tours even on small |
357 $8 \times 8$ boards and also searching for closed tours even on small |
369 boards takes too much time. There is a heuristics, called \emph{Warnsdorf's |
358 boards takes too much time. There is a heuristics, called \emph{Warnsdorf's |
393 |
382 |
394 \noindent |
383 \noindent |
395 Whenever there are ties, the corresponding onward moves can be in any |
384 Whenever there are ties, the corresponding onward moves can be in any |
396 order. When calculating the number of onward moves for each field, we |
385 order. When calculating the number of onward moves for each field, we |
397 do not count moves that revisit any field already visited. |
386 do not count moves that revisit any field already visited. |
398 |
|
399 \subsubsection*{Tasks (file knight2.scala)} |
|
400 |
387 |
401 \begin{itemize} |
388 \begin{itemize} |
402 \item[(6)] Write a function \texttt{ordered\_moves} that calculates a list of |
389 \item[(6)] Write a function \texttt{ordered\_moves} that calculates a list of |
403 onward moves like in (2) but orders them according to |
390 onward moves like in (2) but orders them according to |
404 Warnsdorf’s Rule. That means moves with the fewest legal onward moves |
391 Warnsdorf’s Rule. That means moves with the fewest legal onward moves |
421 %tail-recursive function of the \texttt{first\_tour\_heuristics} function |
408 %tail-recursive function of the \texttt{first\_tour\_heuristics} function |
422 %otherwise you will get problems with stack-overflows.\\ |
409 %otherwise you will get problems with stack-overflows.\\ |
423 \mbox{}\hfill[1 Mark] |
410 \mbox{}\hfill[1 Mark] |
424 \end{itemize} |
411 \end{itemize} |
425 |
412 |
426 \subsubsection*{Task (file knight3.scala)} |
413 \subsubsection*{Task 3 (file knight3.scala)} |
427 \begin{itemize} |
414 \begin{itemize} |
428 \item[(9)] Implement a function \texttt{tour\_on\_mega\_board} which is |
415 \item[(9)] Implement a function \texttt{tour\_on\_mega\_board} which is |
429 the same function as in (8), \textbf{but} should be able to |
416 the same function as in (8), \textbf{but} should be able to |
430 deal with boards up to |
417 deal with boards up to |
431 $70\times 70$ \textbf{within 30 seconds} (on my laptop). This will be tested |
418 $70\times 70$ \textbf{within 30 seconds} (on my laptop). This will be tested |
441 on my laptop: |
428 on my laptop: |
442 |
429 |
443 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
430 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
444 $ scala -cp knight3.jar |
431 $ scala -cp knight3.jar |
445 |
432 |
446 scala> CW9c.tour_on_mega_board(70, List((0, 0))) |
433 scala> M4c.tour_on_mega_board(70, List((0, 0))) |
447 Time needed: 9.484 secs. |
434 Time needed: 9.484 secs. |
448 ...<<long_list>>... |
435 ...<<long_list>>... |
449 \end{lstlisting}%$ |
436 \end{lstlisting}%$ |
450 |
437 |
451 \mbox{}\hfill[1 Mark] |
438 \mbox{}\hfill[1 Mark] |