# HG changeset patch # User Christian Urban # Date 1544798514 0 # Node ID 975d34506e88147930f342a55fd93ad853fb4d6a # Parent a359976a6f3e68ef0c3f89d389b36cd73dab8c93 added marking diff -r a359976a6f3e -r 975d34506e88 TAs --- a/TAs Mon Dec 10 02:23:30 2018 +0000 +++ b/TAs Fri Dec 14 14:41:54 2018 +0000 @@ -40,6 +40,21 @@ 233 submissions +CW8, Part 1 + late (232) +159 => 6 149 +39 => 5 44 +10 => 4 10 +4 => 3 4 +7 => 2 8 +2 => 1 1 +11 => 0 16 +-------- +232 submissions + + + + ======================= Ninos Lahdo used var instead of val, but in useless places Name: Ninos Lahdo diff -r a359976a6f3e -r 975d34506e88 cws/cw04.pdf Binary file cws/cw04.pdf has changed diff -r a359976a6f3e -r 975d34506e88 cws/cw04.tex --- a/cws/cw04.tex Mon Dec 10 02:23:30 2018 +0000 +++ b/cws/cw04.tex Fri Dec 14 14:41:54 2018 +0000 @@ -126,11 +126,11 @@ Since some tasks are time sensitive, you can check the reference implementation as follows: if you want to know, for example, how long it takes to match strings of $a$'s using the regular expression $(a^*)^*\cdot b$ -you can querry as follows: +you can query as follows: -\begin{lstlisting}[language={},xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] +\begin{lstlisting}[xleftmargin=1mm,numbers=none,basicstyle=\ttfamily\small] $ scala -cp re.jar scala> import CW9a._ scala> for (i <- 0 to 5000000 by 500000) { @@ -231,7 +231,7 @@ \item[(2)] Implement a function, called \textit{der}, by recursion over regular expressions. It takes a character and a regular expression - as arguments and calculates the derivative regular expression according + as arguments and calculates the derivative of a xregular expression according to the rules: \begin{center} @@ -308,11 +308,11 @@ simplifies to just $r_1$. \textbf{Hint:} Regular expressions can be seen as trees and there are several methods for traversing - trees. One of them corresponds to the inside-out traversal, which is - sometimes also called post-order traversal: you traverse inside the + trees. One of them corresponds to the inside-out traversal, which is also + sometimes called post-order tra\-versal: you traverse inside the tree and on the way up you apply simplification rules. - Furthermore, - remember numerical expressions from school times: there you had expressions + \textbf{Another Hint:} + Remember numerical expressions from school times---there you had expressions like $u + \ldots + (1 \cdot x) - \ldots (z + (y \cdot 0)) \ldots$ and simplification rules that looked very similar to rules above. You would simplify such numerical expressions by replacing @@ -378,7 +378,7 @@ \] \noindent correctly to just \texttt{ONE}, where \texttt{SEQ} is nested - 50 or more times.\\ + 50 or more times?\\ \mbox{}\hfill[1 Mark] \end{itemize} diff -r a359976a6f3e -r 975d34506e88 marking4/mk --- a/marking4/mk Mon Dec 10 02:23:30 2018 +0000 +++ b/marking4/mk Fri Dec 14 14:41:54 2018 +0000 @@ -3,25 +3,27 @@ trap "exit" INT -files=${1:-assignment20178-*} +files=${1:-assignment20179-*} for sd in $files; do cd $sd echo $sd touch . - cp ../../../marking3/re_test.sh . - cp ../../../marking3/re1a_test.scala . - cp ../../../marking3/re1b_test.scala . - cp ../../../marking3/re1c_test.scala . - cp ../../../marking3/re1d_test.scala . - cp ../../../marking3/re1e_test.scala . + cp ../../../marking4/re_test.sh . + cp ../../../marking4/re_test1.scala . + cp ../../../marking4/re_test2.scala . + cp ../../../marking4/re_test3.scala . + cp ../../../marking4/re_test4.scala . + cp ../../../marking4/re_test5.scala . + cp ../../../marking4/re_test6.scala . ./re_test.sh output rm re_test.sh - rm re1a_test.scala - rm re1b_test.scala - rm re1c_test.scala - rm re1d_test.scala - rm re1e_test.scala + rm re_test1.scala + rm re_test2.scala + rm re_test3.scala + rm re_test4.scala + rm re_test5.scala + rm re_test6.scala cd .. done diff -r a359976a6f3e -r 975d34506e88 marking4/re.scala --- a/marking4/re.scala Mon Dec 10 02:23:30 2018 +0000 +++ b/marking4/re.scala Fri Dec 14 14:41:54 2018 +0000 @@ -1,8 +1,9 @@ // Part 1 about Regular Expression Matching //========================================== -object CW8a { +//object CW9a { +// Regular Expressions abstract class Rexp case object ZERO extends Rexp case object ONE extends Rexp @@ -38,10 +39,11 @@ def ~ (r: String) = SEQ(s, r) } -// (1a) Complete the function nullable according to +// (1) Complete the function nullable according to // the definition given in the coursework; this // function checks whether a regular expression -// can match the empty string +// can match the empty string and Returns a boolean +// accordingly. def nullable (r: Rexp) : Boolean = r match { case ZERO => false @@ -52,10 +54,10 @@ case STAR(_) => true } -// (1b) Complete the function der according to +// (2) Complete the function der according to // the definition given in the coursework; this // function calculates the derivative of a -// regular expression w.r.t. a character +// regular expression w.r.t. a character. def der (c: Char, r: Rexp) : Rexp = r match { case ZERO => ZERO @@ -68,11 +70,12 @@ case STAR(r1) => SEQ(der(c, r1), STAR(r1)) } -// (1c) Complete the function der according to +// (3) Complete the simp function according to // the specification given in the coursework; this -// function simplifies a regular expression; -// however it does not simplify inside STAR-regular -// expressions +// function simplifies a regular expression from +// the inside out, like you would simplify arithmetic +// expressions; however it does not simplify inside +// STAR-regular expressions. def simp(r: Rexp) : Rexp = r match { case ALT(r1, r2) => (simp(r1), simp(r2)) match { @@ -90,11 +93,12 @@ case r => r } -// (1d) Complete the two functions below; the first + +// (4) Complete the two functions below; the first // calculates the derivative w.r.t. a string; the second // is the regular expression matcher taking a regular // expression and a string and checks whether the -// string matches the regular expression +// string matches the regular expression. def ders (s: List[Char], r: Rexp) : Rexp = s match { case Nil => r @@ -102,12 +106,13 @@ } // main matcher function -def matcher(r: Rexp, s: String): Boolean = nullable(ders(s.toList, r)) +def matcher(r: Rexp, s: String) = nullable(ders(s.toList, r)) -// (1e) Complete the size function for regular -// expressions according to the specification +// (5) Complete the size function for regular +// expressions according to the specification // given in the coursework. + def size(r: Rexp): Int = r match { case ZERO => 1 case ONE => 1 @@ -120,29 +125,31 @@ // some testing data -/* -matcher(("a" ~ "b") ~ "c", "abc") // => true -matcher(("a" ~ "b") ~ "c", "ab") // => false + +//matcher(("a" ~ "b") ~ "c", "abc") // => true +//matcher(("a" ~ "b") ~ "c", "ab") // => false // the supposedly 'evil' regular expression (a*)* b val EVIL = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) -matcher(EVIL, "a" * 1000 ++ "b") // => true -matcher(EVIL, "a" * 1000) // => false +//matcher(EVIL, "a" * 1000 ++ "b") // => true +//matcher(EVIL, "a" * 1000) // => false // size without simplifications -size(der('a', der('a', EVIL))) // => 28 -size(der('a', der('a', der('a', EVIL)))) // => 58 +//size(der('a', der('a', EVIL))) // => 28 +//size(der('a', der('a', der('a', EVIL)))) // => 58 // size with simplification -size(simp(der('a', der('a', EVIL)))) // => 8 -size(simp(der('a', der('a', der('a', EVIL))))) // => 8 +//size(simp(der('a', der('a', EVIL)))) // => 8 +//size(simp(der('a', der('a', der('a', EVIL))))) // => 8 -// Java needs around 30 seconds for matching 28 a's with EVIL. +// Python needs around 30 seconds for matching 28 a's with EVIL. +// Java 9 and later increase this to an "astonishing" 40000 a's in +// around 30 seconds. // // Lets see how long it takes to match strings with -// 0.5 Million a's...it should be in the range of some -// seconds. +// 5 Million a's...it should be in the range of a +// couple of seconds. def time_needed[T](i: Int, code: => T) = { val start = System.nanoTime() @@ -151,9 +158,19 @@ (end - start)/(i * 1.0e9) } -for (i <- 0 to 5000000 by 500000) { - println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL, "a" * i)))) -} -*/ +//for (i <- 0 to 5000000 by 500000) { +// println(i + " " + "%.5f".format(time_needed(2, matcher(EVIL, "a" * i))) + " secs.") +//} + +// another "power" test case +//simp(Iterator.iterate(ONE:Rexp)(r => SEQ(r, ONE | ONE)).drop(100).next) == ONE -} +// the Iterator produces the rexp +// +// SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE) +// +// where SEQ is nested 100 times. + + + +//} diff -r a359976a6f3e -r 975d34506e88 marking4/re1a_test.scala --- a/marking4/re1a_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -import CW8a._ - -assert(nullable(ZERO) == false) -assert(nullable(ONE) == true) -assert(nullable(CHAR('a')) == false) -assert(nullable(ZERO | ONE) == true) -assert(nullable(ZERO | CHAR('a')) == false) -assert(nullable(ONE ~ ONE) == true) -assert(nullable(ONE ~ CHAR('a')) == false) -assert(nullable(STAR(ZERO)) == true) - diff -r a359976a6f3e -r 975d34506e88 marking4/re1b_test.scala --- a/marking4/re1b_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ - -import CW8a._ - -assert(der('a', ZERO | ONE) == (ZERO | ZERO)) -assert(der('a', (CHAR('a') | ONE) ~ CHAR('a')) == ALT((ONE | ZERO) ~ CHAR('a'), ONE)) -assert(der('a', (CHAR('a') | CHAR('a')) ~ CHAR('a')) == (ONE | ONE) ~ CHAR('a')) -assert(der('a', STAR(CHAR('a'))) == (ONE ~ STAR(CHAR('a')))) -assert(der('b', STAR(CHAR('a'))) == (ZERO ~ STAR(CHAR('a')))) diff -r a359976a6f3e -r 975d34506e88 marking4/re1c_test.scala --- a/marking4/re1c_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ - -import CW8a._ - - -assert(simp(ZERO | ONE) == ONE) -assert(simp(STAR(ZERO | ONE)) == STAR(ZERO | ONE)) -assert(simp(ONE ~ (ONE ~ (ONE ~ CHAR('a')))) == CHAR('a')) -assert(simp(ONE ~ (ONE ~ (ONE ~ ZERO))) == ZERO) -assert(simp(ALT(ONE ~ (ONE ~ (ONE ~ ZERO)), CHAR('a'))) == CHAR('a')) -assert(simp(CHAR('a') | CHAR('a')) == CHAR('a')) -assert(simp(CHAR('a') ~ CHAR('a')) == CHAR('a') ~ CHAR('a')) -assert(simp(ONE | CHAR('a')) == (ONE | CHAR('a'))) -assert(simp(ALT((CHAR('a') | ZERO) ~ ONE, - ((ONE | CHAR('b')) | CHAR('c')) ~ (CHAR('d') ~ ZERO))) == CHAR('a')) -assert(simp((ZERO | ((ZERO | ZERO) | (ZERO | ZERO))) ~ ((ONE | ZERO) | ONE ) ~ (CHAR('a'))) == ZERO) -assert(simp(ALT(ONE | ONE, ONE | ONE)) == ONE) -assert(simp(ALT(ZERO | CHAR('a'), CHAR('a') | ZERO)) == CHAR('a')) -assert(simp(Iterator.iterate(ONE:Rexp)(r => SEQ(r, ONE | ONE)).drop(50).next) == ONE) - diff -r a359976a6f3e -r 975d34506e88 marking4/re1d_test.scala --- a/marking4/re1d_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ - -import CW8a._ - -val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) - -assert(ders(("a" * 5).toList, EVIL_urban) == SEQ(SEQ(STAR(CHAR('a')),STAR(STAR(CHAR('a')))),CHAR('b'))) -assert(ders(List('b'), EVIL_urban) == ONE) -assert(ders(List('b','b'), EVIL_urban) == ZERO) -assert(matcher(EVIL_urban, "a" * 5 ++ "b") == true) -assert(matcher(EVIL_urban, "a" * 500 ++ "b") == true) -assert(matcher(EVIL_urban, "a" * 500) == false) -assert(matcher(EVIL_urban, "b") == true) -assert(matcher(EVIL_urban, "bb") == false) -assert(matcher("abc", "abc") == true) -assert(matcher(("ab" | "a") ~ (ONE | "bc"), "abc") == true) -assert(matcher(ONE, "") == true) -assert(matcher(ZERO, "") == false) -assert(matcher(ONE | CHAR('a'), "") == true) -assert(matcher(ONE | CHAR('a'), "a") == true) diff -r a359976a6f3e -r 975d34506e88 marking4/re1e_test.scala --- a/marking4/re1e_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ - -import CW8a._ - -val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) - -assert(size(der('a', der('a', EVIL_urban))) == 28) -assert(size(der('a', der('a', der('a', EVIL_urban)))) == 58) - -assert(size(ders("aaaaaa".toList, EVIL_urban)) == 8) -assert(size(ders(("a" * 50).toList, EVIL_urban)) == 8) diff -r a359976a6f3e -r 975d34506e88 marking4/re_test.sh --- a/marking4/re_test.sh Mon Dec 10 02:23:30 2018 +0000 +++ b/marking4/re_test.sh Fri Dec 14 14:41:54 2018 +0000 @@ -9,24 +9,28 @@ echo "Below is the feedback and provisional marks for your submission" >> $out -echo "for assignment 8 Part 1. Please note all marks are provisional until" >> $out +echo "for assignment 9 Part 1. Please note all marks are provisional until" >> $out echo "ratified by the assessment board -- this is not an official" >> $out echo "results transcript." >> $out echo "" >> $out -# marks for CW8 part 1 +# marks for CW9 part 1 marks=$(( 0 )) # compilation tests function scala_compile { - (ulimit -t 360; JAVA_OPTS="-Xmx1g" scala "$1" 2> /dev/null 1> /dev/null) + (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc "$1" 2> /dev/null 1> /dev/null) } # functional tests function scala_assert { - (ulimit -t 360; JAVA_OPTS="-Xmx1g" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) + (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" "$2" -e "") # 2> /dev/null 1> /dev/null) +} + +function scala_assert_long { + (ulimit -t 60; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) } # purity test @@ -67,7 +71,7 @@ tsts1=$(( 1 )) fi - +### re1 test if [ $tsts1 -eq 0 ] then @@ -80,7 +84,7 @@ echo " nullable(ONE ~ CHAR('a')) == false" | tee -a $out echo " nullable(STAR(ZERO)) == true" | tee -a $out - if (scala_assert "re.scala" "re1a_test.scala") + if (scala_assert "re.scala" "re_test1.scala") then echo " --> success" | tee -a $out marks=$(( marks + 1 )) @@ -89,7 +93,7 @@ fi fi - +### re2 test if [ $tsts1 -eq 0 ] then @@ -98,8 +102,23 @@ echo " der('a', (CHAR('a') | CHAR('a')) ~ CHAR('a')) == (ONE | ONE) ~ CHAR('a')" | tee -a $out echo " der('a', STAR(CHAR('a'))) == (ONE ~ STAR(CHAR('a')))" | tee -a $out echo " der('b', STAR(CHAR('a'))) == (ZERO ~ STAR(CHAR('a')))" | tee -a $out - - if (scala_assert "re.scala" "re1b_test.scala") + echo "" | tee -a $out + echo " val r0 = \"a\" ~ \"b\" ~ \"c\"" | tee -a $out + echo " assert(der('a', r0) == (ONE ~ \"b\") ~ \"c\")" | tee -a $out + echo " assert(der('b', r0) == (ZERO ~ \"b\") ~ \"c\")" | tee -a $out + echo " assert(der('c', r0) == (ZERO ~ \"b\") ~ \"c\")" | tee -a $out + echo "" | tee -a $out + echo " val r1 = (ONE ~ \"b\") ~ \"c\"" | tee -a $out + echo " assert(der('a', r1) == ((ZERO ~ \"b\") | ZERO) ~ \"c\")" | tee -a $out + echo " assert(der('b', r1) == ((ZERO ~ \"b\") | ONE) ~ \"c\")" | tee -a $out + echo " assert(der('c', r1) == ((ZERO ~ \"b\") | ZERO) ~ \"c\")" | tee -a $out + echo "" | tee -a $out + echo " val r2 = ((ZERO ~ \"b\") | ONE) ~ \"c\"" | tee -a $out + echo " assert(der('a', r2) == ((((ZERO ~ \"b\") | ZERO) ~ \"c\") | ZERO))" | tee -a $out + echo " assert(der('b', r2) == ((((ZERO ~ \"b\") | ZERO) ~ \"c\") | ZERO))" | tee -a $out + echo " assert(der('c', r2) == ((((ZERO ~ \"b\") | ZERO) ~ \"c\") | ONE))" | tee -a $out + + if (scala_assert "re.scala" "re_test2.scala") then echo " --> success" | tee -a $out marks=$(( marks + 1 )) @@ -108,13 +127,15 @@ fi fi - +### re3 test if [ $tsts1 -eq 0 ] then echo " simp(ZERO | ONE) == ONE" | tee -a $out echo " simp(STAR(ZERO | ONE)) == STAR(ZERO | ONE)" | tee -a $out echo " simp(ONE ~ (ONE ~ (ONE ~ CHAR('a')))) == CHAR('a')" | tee -a $out + echo " simp(((ONE ~ ONE) ~ ONE) ~ CHAR('a')) == CHAR('a')" | tee -a $out + echo " simp(((ONE | ONE) ~ ONE) ~ CHAR('a')) == CHAR('a')" | tee -a $out echo " simp(ONE ~ (ONE ~ (ONE ~ ZERO))) == ZERO" | tee -a $out echo " simp(ALT(ONE ~ (ONE ~ (ONE ~ ZERO)), CHAR('a'))) == CHAR('a')" | tee -a $out echo " simp(CHAR('a') | CHAR('a')) == CHAR('a')" | tee -a $out @@ -125,21 +146,18 @@ echo " simp((ZERO | ((ZERO | ZERO) | (ZERO | ZERO))) ~ ((ONE | ZERO) | ONE ) ~ (CHAR('a'))) == ZERO" | tee -a $out echo " simp(ALT(ONE | ONE, ONE | ONE)) == ONE" | tee -a $out echo " simp(ALT(ZERO | CHAR('a'), CHAR('a') | ZERO)) == CHAR('a')" | tee -a $out - echo " simp(Iterator.iterate(ONE:Rexp)(r => SEQ(r, ONE | ONE)).drop(50).next) == ONE" | tee -a $out - echo " the Iterator produces the rexp" | tee -a $out - echo "" | tee -a $out - echo " SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)" | tee -a $out - echo "" | tee -a $out - echo " where SEQ is nested 50 times." | tee -a $out - if (scala_assert "re.scala" "re1c_test.scala") + echo " simp(ALT(ONE | CHAR('a'), CHAR('a') | ONE)) == ALT(ONE | CHAR('a'), CHAR('a') | ONE)" tee -a $out + + if (scala_assert "re.scala" "re_test3.scala") then echo " --> success" | tee -a $out - marks=$(( marks + 2 )) + marks=$(( marks + 1 )) else echo " --> test failed" | tee -a $out fi fi +### re4 test if [ $tsts1 -eq 0 ] then @@ -153,13 +171,14 @@ echo " matcher(EVIL, \"b\") == true" | tee -a $out echo " matcher(EVIL, \"bb\") == false" | tee -a $out echo " matcher(\"abc\", \"abc\") == true" | tee -a $out + echo " matcher(\"abc\", \"ab\") == true" | tee -a $out echo " matcher((\"ab\" | \"a\") ~ (ONE | \"bc\"), \"abc\") == true" | tee -a $out echo " matcher(ONE, \"\") == true" | tee -a $out echo " matcher(ZERO, \"\") == false" | tee -a $out echo " matcher(ONE | CHAR('a'), \"\") == true" | tee -a $out echo " matcher(ONE | CHAR('a'), \"a\") == true" | tee -a $out - if (scala_assert "re.scala" "re1d_test.scala") + if (scala_assert "re.scala" "re_test4.scala") then echo " --> success" | tee -a $out marks=$(( marks + 1 )) @@ -168,6 +187,8 @@ fi fi +### re5 test + if [ $tsts1 -eq 0 ] then @@ -177,7 +198,37 @@ echo " size(ders(\"aaaaaa\".toList, EVIL)) == 8" | tee -a $out echo " size(ders((\"a\" * 50).toList, EVIL)) == 8" | tee -a $out - if (scala_assert "re.scala" "re1e_test.scala") + if (scala_assert "re.scala" "re_test5.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + +### re6 'power' test + + + +if [ $tsts1 -eq 0 ] +then + echo " simp(Iterator.iterate(ONE:Rexp)(r => SEQ(r, ONE | ONE)).drop(50).next) == ONE" | tee -a $out + echo " ...the Iterator produces the rexp" | tee -a $out + echo "" | tee -a $out + echo " SEQ(SEQ(SEQ(..., ONE | ONE) , ONE | ONE), ONE | ONE)" | tee -a $out + echo "" | tee -a $out + echo " where SEQ is nested 50 times." | tee -a $out + echo "" | tee -a $out + echo " simp(Iterator.iterate(ONE:Rexp)(r => ALT(r, r)).drop(20).next) == ONE" | tee -a $out + echo " ... the Iterator produces a rexp of size 2097151" | tee -a $out + echo "" | tee -a $out + echo " val EVIL = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))" | tee -a $out + echo " matcher(EVIL, \"a\" * 1000000 ++ \"b\") == true" | tee -a $out + echo " matcher(EVIL, \"a\" * 1000000) == false" | tee -a $out + + + if (time scala_assert_long "re.scala" "re_test6.scala") then echo " --> success" | tee -a $out marks=$(( marks + 1 )) @@ -188,7 +239,7 @@ ## final marks -echo "Overall mark for CW 8, Part 1" | tee -a $out +echo "Overall mark for CW 9, Part 1" | tee -a $out echo "$marks" | tee -a $out diff -r a359976a6f3e -r 975d34506e88 marking4/re_test1.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test1.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,10 @@ + +assert(nullable(ZERO) == false) +assert(nullable(ONE) == true) +assert(nullable(CHAR('a')) == false) +assert(nullable(ZERO | ONE) == true) +assert(nullable(ZERO | CHAR('a')) == false) +assert(nullable(ONE ~ ONE) == true) +assert(nullable(ONE ~ CHAR('a')) == false) +assert(nullable(STAR(ZERO)) == true) + diff -r a359976a6f3e -r 975d34506e88 marking4/re_test2.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test2.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,24 @@ + +assert(der('a', ZERO | ONE) == (ZERO | ZERO)) +assert(der('a', (CHAR('a') | ONE) ~ CHAR('a')) == ALT((ONE | ZERO) ~ CHAR('a'), ONE)) +assert(der('a', (CHAR('a') | CHAR('a')) ~ CHAR('a')) == (ONE | ONE) ~ CHAR('a')) +assert(der('a', STAR(CHAR('a'))) == (ONE ~ STAR(CHAR('a')))) +assert(der('b', STAR(CHAR('a'))) == (ZERO ~ STAR(CHAR('a')))) + + +val r0_urban = "a" ~ "b" ~ "c" +assert(der('a', r0_urban) == (ONE ~ "b") ~ "c") +assert(der('b', r0_urban) == (ZERO ~ "b") ~ "c") +assert(der('c', r0_urban) == (ZERO ~ "b") ~ "c") + +val r1_urban = (ONE ~ "b") ~ "c" + +assert(der('a', r1_urban) == ((ZERO ~ "b") | ZERO) ~ "c") +assert(der('b', r1_urban) == ((ZERO ~ "b") | ONE) ~ "c") +assert(der('c', r1_urban) == ((ZERO ~ "b") | ZERO) ~ "c") + +val r2_urban = ((ZERO ~ "b") | ONE) ~ "c" + +assert(der('a', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | ZERO)) +assert(der('b', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | ZERO)) +assert(der('c', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | ONE)) diff -r a359976a6f3e -r 975d34506e88 marking4/re_test3.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test3.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,21 @@ + + + +assert(simp(ZERO | ONE) == ONE) +assert(simp(STAR(ZERO | ONE)) == STAR(ZERO | ONE)) +assert(simp(ONE ~ (ONE ~ (ONE ~ CHAR('a')))) == CHAR('a')) +assert(simp(((ONE ~ ONE) ~ ONE) ~ CHAR('a')) == CHAR('a')) +assert(simp(((ONE | ONE) ~ ONE) ~ CHAR('a')) == CHAR('a')) +assert(simp(ONE ~ (ONE ~ (ONE ~ ZERO))) == ZERO) +assert(simp(ALT(ONE ~ (ONE ~ (ONE ~ ZERO)), CHAR('a'))) == CHAR('a')) +assert(simp(CHAR('a') | CHAR('a')) == CHAR('a')) +assert(simp(CHAR('a') ~ CHAR('a')) == CHAR('a') ~ CHAR('a')) +assert(simp(ONE | CHAR('a')) == (ONE | CHAR('a'))) +assert(simp(ALT((CHAR('a') | ZERO) ~ ONE, + ((ONE | CHAR('b')) | CHAR('c')) ~ (CHAR('d') ~ ZERO))) == CHAR('a')) +assert(simp((ZERO | ((ZERO | ZERO) | (ZERO | ZERO))) ~ ((ONE | ZERO) | ONE ) ~ (CHAR('a'))) == ZERO) +assert(simp(ALT(ONE | ONE, ONE | ONE)) == ONE) +assert(simp(ALT(ZERO | CHAR('a'), CHAR('a') | ZERO)) == CHAR('a')) +assert(simp(ALT(ONE | CHAR('a'), CHAR('a') | ONE)) == ALT(ONE | CHAR('a'), CHAR('a') | ONE)) + + diff -r a359976a6f3e -r 975d34506e88 marking4/re_test4.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test4.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,19 @@ + + +val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) + +assert(ders(("a" * 5).toList, EVIL_urban) == SEQ(SEQ(STAR(CHAR('a')),STAR(STAR(CHAR('a')))),CHAR('b'))) +assert(ders(List('b'), EVIL_urban) == ONE) +assert(ders(List('b','b'), EVIL_urban) == ZERO) +assert(matcher(EVIL_urban, "a" * 5 ++ "b") == true) +assert(matcher(EVIL_urban, "a" * 50 ++ "b") == true) +assert(matcher(EVIL_urban, "a" * 50) == false) +assert(matcher(EVIL_urban, "b") == true) +assert(matcher(EVIL_urban, "bb") == false) +assert(matcher("abc", "abc") == true) +assert(matcher("abc", "ab") == false) +assert(matcher(("ab" | "a") ~ (ONE | "bc"), "abc") == true) +assert(matcher(ONE, "") == true) +assert(matcher(ZERO, "") == false) +assert(matcher(ONE | CHAR('a'), "") == true) +assert(matcher(ONE | CHAR('a'), "a") == true) diff -r a359976a6f3e -r 975d34506e88 marking4/re_test5.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test5.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,8 @@ + +val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) + +assert(size(der('a', der('a', EVIL_urban))) == 28) +assert(size(der('a', der('a', der('a', EVIL_urban)))) == 58) + +assert(size(ders("aaaaaa".toList, EVIL_urban)) == 8) +assert(size(ders(("a" * 50).toList, EVIL_urban)) == 8) diff -r a359976a6f3e -r 975d34506e88 marking4/re_test6.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marking4/re_test6.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,9 @@ + + +val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b')) + + +assert(simp(Iterator.iterate(ONE:Rexp)(r => SEQ(r, ONE | ONE)).drop(50).next) == ONE) +assert(simp(Iterator.iterate(ONE:Rexp)(r => ALT(r, r)).drop(20).next) == ONE) +assert(matcher(EVIL_urban, "a" * 1000000) == false) +assert(matcher(EVIL_urban, "a" * 1000000 ++ "b") == true) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight1.scala --- a/testing3-bak/knight1.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ - -// Part 1 about finding and counting Knight's tours -//================================================== - -object CW7a extends App{ - -type Pos = (Int, Int) // a position on a chessboard -type Path = List[Pos] // a path...a list of positions - -//(1a) Complete the function that tests whether the position -// is inside the board and not yet element in the path. - -//def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = ... - -def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = { - -// if ((x._10 || x._2>0)) false else !path.contains(x) - - if (x._1 < 0 || x._2 < 0) false - else if (x._1 < dim && x._2 < dim && !path.contains(x)) true - else false - - -} - - - -def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = { - - val allPossibleMoves = List((x._1+1, x._2+2), (x._1+2, x._2+1), (x._1+2, x._2-1), (x._1+1, x._2-2), (x._1-1, x._2-2), (x._1-2, x._2-1), (x._1-2, x._2+1), (x._1-1, x._2+2)); - - //val finalList = allPossibleMoves.filter((a=>a._1= 0 && a._2 >= 0)); - - val finalList = for(pos<-allPossibleMoves if(is_legal(dim,path)(pos))) yield pos; - - // println("Space in board: " + dim*dim + " for dim: " + dim) - - - finalList.toList; - - -} - -println(legal_moves(8, Nil, (2,2))) -println(legal_moves(8, Nil, (7,7))) -println(legal_moves(8, List((4,1), (1,0)), (2,2))) -println(legal_moves(8, List((6,6)), (7,7))) -println(legal_moves(1, Nil, (0,0))) -println(legal_moves(2, Nil, (0,0))) -println(legal_moves(3, Nil, (0,0))) - -println("=================================================================================") -println("================================Comparision output===============================") -println("=================================================================================") - -println(legal_moves(8, Nil, (2,2)) == List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) -println(legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) -println(legal_moves(8, List((4,1), (1,0)), (2,2)) == List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) -println(legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) -println(legal_moves(1, Nil, (0,0)) == Nil) -println(legal_moves(2, Nil, (0,0)) == Nil) -println(legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))) - - -def count_tours(dim: Int, path: Path) : Int = { - - val allMovesFromCurrentPosition = legal_moves(dim, path, path.head); - - if (path.length == dim*dim) 1 else { - - if (allMovesFromCurrentPosition.size == 0 ) 0 else { - - allMovesFromCurrentPosition.map( element => count_tours(dim, element::path)).sum - - - } - - } - -} - - - -println ( count_tours(5, List((0,0))) ) - -def enum_tours(dim: Int, path: Path) : List[Path] = { - - val allMovesFromCurrentPosition = legal_moves(dim, path, path.head); - - if (path.length == dim*dim) List(path) else { - - allMovesFromCurrentPosition.map( element => enum_tours(dim, element::path)).flatten ; - - - } - } - println ( enum_tours(6, List((0,2))).size) -} - - - - - - - -//(1b) Complete the function that calculates for a position -// all legal onward moves that are not already in the path. -// The moves should be ordered in a "clockwise" manner. - -//def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = ... - - - - -//some test cases -// -//assert(legal_moves(8, Nil, (2,2)) == -// List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) -//assert(legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) -//assert(legal_moves(8, List((4,1), (1,0)), (2,2)) == -// List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) -//assert(legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) - - -//(1c) Complete the two recursive functions below. -// They exhaustively search for knight's tours starting from the -// given path. The first function counts all possible tours, -// and the second collects all tours in a list of paths. - -//def count_tours(dim: Int, path: Path) : Int = ... - - -//def enum_tours(dim: Int, path: Path) : List[Path] = ... diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight1_test.sh --- a/testing3-bak/knight1_test.sh Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -#!/bin/bash -set -e - -out=${1:-output} - -echo "" > $out - -echo "Below is the feedback for your submission of CW 7, Part 1 and 2." >> $out -echo "" >> $out - - -# compilation tests - -function scala_compile { - (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala "$1" 2>> $out 1>> $out) -} - -# functional tests - -function scala_assert_slow { - (ulimit -t 120; JAVA_OPTS="-Xmx1g" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) -} - -function scala_assert_thirty { - (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) -} - -function scala_assert_quick { - (ulimit -t 10; JAVA_OPTS="-Xmx1g" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) -} - -# purity test - -function scala_vars { - (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|mutable|new Array' "$1" 2> /dev/null 1> /dev/null) -} - - -# knights1: purity test - -echo "knight1.scala does not contain vars, returns etc?" >> $out - -if (scala_vars knight1.scala) -then - echo " --> fail: if you do not fix this, you will receive a mark of zero" >> $out - tsts0=$(( 1 )) -else - echo " --> success" >> $out - tsts0=$(( 0 )) -fi - - -# compilation test - -if [ $tsts0 -eq 0 ] -then - echo "knight1.scala runs?" >> $out - - if (scala_compile knight1.scala) - then - echo " --> success " >> $out - tsts1=$(( 0 )) - else - echo " --> scala did not run knight1.scala" >> $out - tsts1=$(( 1 )) - fi -else - tsts1=$(( 1 )) -fi - -### knight1a test - -if [ $tsts1 -eq 0 ] -then - echo "Takes 10 seconds or less to execute: " >> $out - echo " is_legal(8, Nil)(3, 4) == true " >> $out - echo " is_legal(8, List((4, 1), (1, 0)))(4, 1) == false " >> $out - echo " is_legal(2, Nil)(0, 0) == true" >> $out - - if (scala_assert_quick "knight1.scala" "knight1a_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - -### knight1b test - -if [ $tsts1 -eq 0 ] -then - echo "Takes 10 seconds or less to execute: " >> $out - echo " legal_moves(8, Nil, (2,2)) == List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))" >> $out - echo " legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))" >> $out - echo " legal_moves(8, List((4,1), (1,0)), (2,2)) == List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))" >> $out - echo " legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))" >> $out - echo " legal_moves(1, Nil, (0,0)) == Nil" >> $out - echo " legal_moves(2, Nil, (0,0)) == Nil" >> $out - echo " legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))" >> $out - - if (scala_assert_quick "knight1.scala" "knight1b_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - -### knight1c test - -if [ $tsts1 -eq 0 ] -then - echo " all_tours from every position on the board, in 2 minutes or less" >> $out - echo " dim = 1: 1" >> $out - echo " 2: 0,0,0,0" >> $out - echo " 3: 0,0,0,0,0,0,0,0,0" >> $out - echo " 4: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" >> $out - echo " 5: 304,0,56,0,304,0,56,0,56,0,56,0,64,0,56,0,56,0,56,0,304,0,56,0,304" >> $out - echo " enum_tours(5, List((0,2)) ) == 56 and all correct?" >> $out - - if (scala_assert_slow "knight1.scala" "knight1c_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - -# knights2: var test - -echo "knight2.scala does not contain vars, returns etc?" >> $out - -if (scala_vars knight2.scala) -then - echo " --> fail" >> $out - tsts0=$(( 1 )) -else - echo " --> success" >> $out - tsts0=$(( 0 )) -fi - - -# compilation test -if [ $tsts0 -eq 0 ] -then - echo "knight2.scala runs?" >> $out - - if (scala_compile knight2.scala) - then - echo " --> success" >> $out - tsts1=$(( 0 )) - else - echo " --> scala did not run knight2.scala" >> $out - tsts1=$(( 1 )) - fi -else - tsts1=$(( 1 )) -fi - -### knight2a test - -if [ $tsts1 -eq 0 ] -then - echo "Takes 10 seconds or less to execute: " >> $out - echo " Let f = (x:(Int, Int)) => if (x._1 > 3) Some(List(x)) else None " >> $out - echo " first(List((1,0),(2,0),(3,0),(4,0)), f) == Some(List((4,0)))" >> $out - echo " first(List((1,0),(2,0),(3,0)), f) == None" >> $out - - if (scala_assert_quick "knight2.scala" "knight2a_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - -### knight2b test - -if [ $tsts1 -eq 0 ] -then - echo "Takes 30 seconds or less to execute: " >> $out - echo " is first_tour(8, List((0, 0))) ok? " >> $out - echo " is first_tour(4, List((0, 0))) == None " >> $out - - if (scala_assert_thirty "knight2.scala" "knight2b_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight1a_test.scala --- a/testing3-bak/knight1a_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ - -assert(CW7a.is_legal(8, Nil)(3, 4) == true) -assert(CW7a.is_legal(8, List((4, 1), (1, 0)))(4, 1) == false) -assert(CW7a.is_legal(2, Nil)(0, 0) == true) - diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight1b_test.scala --- a/testing3-bak/knight1b_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ - -assert(CW7a.legal_moves(8, Nil, (2,2)) == - List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) -assert(CW7a.legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) -assert(CW7a.legal_moves(8, List((4,1), (1,0)), (2,2)) == - List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) -assert(CW7a.legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) -assert(CW7a.legal_moves(1, Nil, (0,0)) == List()) -assert(CW7a.legal_moves(2, Nil, (0,0)) == List()) -assert(CW7a.legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))) - diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight1c_test.scala --- a/testing3-bak/knight1c_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ - -import scala.concurrent._ -import scala.concurrent.duration._ -import ExecutionContext.Implicits.global -import scala.language.postfixOps - -type Pos = (Int, Int) // a position on a chessboard -type Path = List[Pos] // a path...a list of positions - -def count_all_tours_urban(dim: Int) = { - for (i <- (0 until dim).toList; - j <- (0 until dim).toList) yield CW7a.count_tours(dim, List((i, j))) -} - -def add_pair_urban(x: Pos)(y: Pos): Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves_urban(x: Pos): List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) - -def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = - moves_urban(x).filter(is_legal_urban(dim, path)) - -def correct_urban(dim: Int)(p: Path): Boolean = p match { - case Nil => true - case x::Nil => true - case x::y::p => if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false -} - - -lazy val f = Future { - assert(count_all_tours_urban(1) == List(1)) - assert(count_all_tours_urban(2) == List(0, 0, 0, 0)) - assert(count_all_tours_urban(3) == List(0, 0, 0, 0, 0, 0, 0, 0, 0)) - assert(count_all_tours_urban(4) == List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - assert(count_all_tours_urban(5) == List(304, 0, 56, 0, 304, 0, 56, 0, 56, 0, 56, 0, 64, 0, 56, 0, 56, 0, 56, 0, 304, 0, 56, 0, 304)) - - val ts = CW7a.enum_tours(5, List((0, 2))) - assert(ts.map(correct_urban(5)).forall(_ == true) == true) - assert(ts.length == 56) -} - -Await.result(f, 360 second) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight2.scala --- a/testing3-bak/knight2.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -// Part 2 about finding a single tour for a board -//================================================ - -object CW7b { - -type Pos = (Int, Int) // a position on a chessboard -type Path = List[Pos] // a path...a list of positions - -def print_board(dim: Int, path: Path) : Unit = { - println - for (i <- 0 until dim) { - for (j <- 0 until dim) { - print(f"${path.reverse.indexOf((i, j))}%3.0f ") - } - println - } -} - -def add_pair(x: Pos)(y: Pos) : Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves(x: Pos) : List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair(x)) - -def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = - moves(x).filter(is_legal(dim, path)) - - -def first(xs: List[Pos], f: Pos => Option[Path]) : Option[Path] = xs match { - case Nil => None - case x::xs => { - val result = f(x) - if (result.isDefined) result else first(xs, f) - } -} - -//first(List((1, 0),(2, 0),(3, 0),(4, 0)), (x => if (x._1 > 3) Some(List(x)) else None)) -//first(List((1, 0),(2, 0),(3, 0)), (x => if (x._1 > 3) Some(List(x)) else None)) - -def first_tour(dim: Int, path: Path) : Option[Path] = { - if (path.length == dim * dim) Some(path) - else - first(legal_moves(dim, path, path.head), (x: Pos) => first_tour(dim, x::path)) -} - -/* -val ts1 = first_tour(8, List((0, 0))).get - assert(correct_urban(8)(ts1) == true) - -val ts2 = first_tour(4, List((0, 0))) -assert(ts2 == None) - -print_board(8, first_tour(8, List((0, 0))).get) -*/ - -} - diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight2a_test.scala --- a/testing3-bak/knight2a_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ - -val f = (x:(Int, Int)) => if (x._1 > 3) Some(List(x)) else None - -assert(CW7b.first(List((1,0),(2,0),(3,0),(4,0)), f) == Some(List((4,0)))) -assert(CW7b.first(List((1,0),(2,0),(3,0)), f) == None) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight2b_test.scala --- a/testing3-bak/knight2b_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ - -import scala.concurrent._ -import scala.concurrent.duration._ -import ExecutionContext.Implicits.global -import scala.language.postfixOps - -type Pos = (Int, Int) // a position on a chessboard -type Path = List[Pos] // a path...a list of positions - -def add_pair_urban(x: Pos)(y: Pos): Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves_urban(x: Pos): List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) - -def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = - moves_urban(x).filter(is_legal_urban(dim, path)) - -def correct_urban(dim: Int)(p: Path): Boolean = p match { - case Nil => true - case x::Nil => true - case x::y::p => - if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false -} - - -lazy val f = Future { - - val ts1 = CW7b.first_tour(8, List((0, 0))).get - assert(correct_urban(8)(ts1) == true) - - val ts2 = CW7b.first_tour(4, List((0, 0))) - assert(ts2 == None) -} - -Await.result(f, 300 second) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight3.scala --- a/testing3-bak/knight3.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -// Part 3 about finding a single tour using the Warnsdorf Rule -//============================================================= - -//object CW8c { // for preparing the jar - -type Pos = (Int, Int) -type Path = List[Pos] - - -// for measuring time in the JAR -def time_needed[T](code: => T) : T = { - val start = System.nanoTime() - val result = code - val end = System.nanoTime() - println(f"Time needed: ${(end - start) / 1.0e9}%3.3f secs.") - result -} - - -def print_board(dim: Int, path: Path): Unit = { - println - for (i <- 0 until dim) { - for (j <- 0 until dim) { - print(f"${path.reverse.indexOf((i, j))}%4.0f ") - } - println - } -} - -def add_pair(x: Pos, y: Pos): Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal(dim: Int, path: Path, x: Pos): Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves(x: Pos): List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair(x, _)) - -def legal_moves(dim: Int, path: Path, x: Pos): List[Pos] = - moves(x).filter(is_legal(dim, path, _)) - -def ordered_moves(dim: Int, path: Path, x: Pos): List[Pos] = - legal_moves(dim, path, x).sortBy((x) => legal_moves(dim, path, x).length) - -import scala.annotation.tailrec - -@tailrec -def tour_on_mega_board_aux(dim: Int, paths: List[Path]): Option[Path] = paths match { - case Nil => None - case (path::rest) => - if (path.length == dim * dim) Some(path) - else tour_on_mega_board_aux(dim, ordered_moves(dim, path, path.head).map(_::path) ::: rest) -} - -def ttour_on_mega_board(dim: Int, path: Path): Option[Path] = - tour_on_mega_board_aux(dim, List(path)) - - -def tour_on_mega_board(dim: Int, path: Path) = - time_needed(ttour_on_mega_board(dim: Int, path: Path)) - -//} diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight3_test.sh --- a/testing3-bak/knight3_test.sh Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -#!/bin/bash -set -e - -out=${1:-output} - -echo "" > $out - -echo "Below is the feedback for your submission of CW 7, Part 3." >> $out -echo "" >> $out - -function scala_vars { - (egrep '\bvar\b|\breturn\b|ListBuffer|mutable' "$1" 2> /dev/null 1> /dev/null) -} - -# compilation tests - -function scala_compile { - (ulimit -t 30 ; JAVA_OPTS="-Xmx1g" scala "$1" 2>> $out 1>> $out) -} - -# functional tests - -# not sure yet what the right kind of stack should be - -function scala_assert { - (ulimit -t 20 ; JAVA_OPTS="-Xmx1g -Xss200m" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) -} - -# purity test - -function scala_vars { - (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|mutable|new Array' "$1" 2> /dev/null 1> /dev/null) -} - - -# knights3: purity test -# -echo "knight3.scala does not contain vars, returns etc?" >> $out - -if (scala_vars knight3.scala) -then - echo " --> fail: if you do not fix this, you will receive a mark of zero" >> $out - tsts0=$(( 1 )) -else - echo " --> success" >> $out - tsts0=$(( 0 )) -fi - - -# compilation test -if [ $tsts0 -eq 0 ] -then - echo "knight3.scala runs?" >> $out - - if (scala_compile knight3.scala) - then - echo " --> success" >> $out - tsts1=$(( 0 )) - else - echo " --> scala knight3.scala did not run successfully" >> $out - tsts1=$(( 1 )) - fi -else - tsts1=$(( 1 )) -fi - -# ordered move test - -if [ $tsts1 -eq 0 ] -then - echo "Takes 20 seconds or less to execute: " >> $out - echo " ordered_moves(8, List((3,4), (3,2)), (1, 3)) == List((0,1), (0,5), (2,1), (2,5))" >> $out - echo " ordered_moves(8, List((4,0)), (0,0)) == List((2,1), (1,2))" >> $out - echo " ordered_moves(8, List((0,4)), (0,0)) == List((1,2), (2,1))" >> $out - - if (scala_assert "knight3.scala" "knight3a_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - -# first-closed-tour test - -if [ $tsts1 -eq 0 ] -then - echo " first_closed_tour_heuristic(6, List((3, 3))) found and ok?" >> $out - - if (scala_assert "knight3.scala" "knight3b_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - - -if [ $tsts1 -eq 0 ] -then - echo "Takes 20 seconds or less to execute: " >> $out - echo " first_tour_heuristic(8, List((0,0))) found and ok?" >> $out - echo " first_tour_heuristic(40, List((0,0))) found and ok?" >> $out - - if (scala_assert "knight3.scala" "knight3c_test.scala") - then - echo " --> success" >> $out - else - echo " --> test failed" >> $out - fi -fi - - -## final marks -##echo "Overall mark for CW 7, Part 2" | tee -a $out -##echo "$marks" | tee -a $out diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight3a_test.scala --- a/testing3-bak/knight3a_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ - -import scala.concurrent._ -import scala.concurrent.duration._ -import ExecutionContext.Implicits.global -import scala.language.postfixOps - -lazy val f = Future { - -assert(CW7c.ordered_moves(8, List((3,4), (3,2)), (1, 3)) == List((0,1), (0,5), (2,1), (2,5))) -assert(CW7c.ordered_moves(8, List((4,0)), (0,0)) == List((2,1), (1,2))) -assert(CW7c.ordered_moves(8, List((0,4)), (0,0)) == List((1,2), (2,1))) - -} - -Await.result(f, 120 second) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight3b_test.scala --- a/testing3-bak/knight3b_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ - -//import scala.concurrent._ -//import scala.concurrent.duration._ -//import ExecutionContext.Implicits.global -//import scala.language.postfixOps - -type Pos = (Int, Int) -type Path = List[Pos] - -def add_pair_urban(x: Pos)(y: Pos): Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves_urban(x: Pos): List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) - -def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = - moves_urban(x).filter(is_legal_urban(dim, path)) - -def correct_urban(dim: Int)(p: Path): Boolean = p match { - case Nil => true - case x::Nil => true - case x::y::p => - if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false -} - -def correct_closed_urban(dim: Int)(p: Path) = - correct_urban(6)(p) && moves_urban(p.head).contains(p.last) - -//lazy val f = Future { - - val tsc = CW7c.first_closed_tour_heuristic(6, List((3, 3))).get - assert(correct_closed_urban(6)(tsc) == true) - -//} - -//Await.result(f, 300 second) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/knight3c_test.scala --- a/testing3-bak/knight3c_test.scala Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ - -//import scala.concurrent._ -//import scala.concurrent.duration._ -//import ExecutionContext.Implicits.global -//import scala.language.postfixOps - -type Pos = (Int, Int) -type Path = List[Pos] - -def add_pair_urban(x: Pos)(y: Pos): Pos = - (x._1 + y._1, x._2 + y._2) - -def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = - 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) - -def moves_urban(x: Pos): List[Pos] = - List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), - (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) - -def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = - moves_urban(x).filter(is_legal_urban(dim, path)) - -def correct_urban(dim: Int)(p: Path): Boolean = p match { - case Nil => true - case x::Nil => true - case x::y::p => - if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false -} - - -// !!!!!!! the futures need to be removed...otherwise funny results -//lazy val f1 = Future { - - val ts8 = CW7c.first_tour_heuristic(8, List((0,0))).get - assert(correct_urban(8)(ts8) == true) - -//} - -//Await.result(f1, 360 second) - - -//lazy val f2 = Future { - - val ts40 = CW7c.first_tour_heuristic(40, List((0,0))).get - assert(correct_urban(40)(ts40) == true) - -//} - -//Await.result(f2, 360 second) diff -r a359976a6f3e -r 975d34506e88 testing3-bak/mark --- a/testing3-bak/mark Mon Dec 10 02:23:30 2018 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -#!/bin/bash -###set -e - -trap "exit" INT - -./knight1_test.sh output1 -./knight3_test.sh output3 - diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight1.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight1.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,133 @@ + +// Part 1 about finding and counting Knight's tours +//================================================== + +object CW7a extends App{ + +type Pos = (Int, Int) // a position on a chessboard +type Path = List[Pos] // a path...a list of positions + +//(1a) Complete the function that tests whether the position +// is inside the board and not yet element in the path. + +//def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = ... + +def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = { + +// if ((x._10 || x._2>0)) false else !path.contains(x) + + if (x._1 < 0 || x._2 < 0) false + else if (x._1 < dim && x._2 < dim && !path.contains(x)) true + else false + + +} + + + +def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = { + + val allPossibleMoves = List((x._1+1, x._2+2), (x._1+2, x._2+1), (x._1+2, x._2-1), (x._1+1, x._2-2), (x._1-1, x._2-2), (x._1-2, x._2-1), (x._1-2, x._2+1), (x._1-1, x._2+2)); + + //val finalList = allPossibleMoves.filter((a=>a._1= 0 && a._2 >= 0)); + + val finalList = for(pos<-allPossibleMoves if(is_legal(dim,path)(pos))) yield pos; + + // println("Space in board: " + dim*dim + " for dim: " + dim) + + + finalList.toList; + + +} + +println(legal_moves(8, Nil, (2,2))) +println(legal_moves(8, Nil, (7,7))) +println(legal_moves(8, List((4,1), (1,0)), (2,2))) +println(legal_moves(8, List((6,6)), (7,7))) +println(legal_moves(1, Nil, (0,0))) +println(legal_moves(2, Nil, (0,0))) +println(legal_moves(3, Nil, (0,0))) + +println("=================================================================================") +println("================================Comparision output===============================") +println("=================================================================================") + +println(legal_moves(8, Nil, (2,2)) == List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) +println(legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) +println(legal_moves(8, List((4,1), (1,0)), (2,2)) == List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) +println(legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) +println(legal_moves(1, Nil, (0,0)) == Nil) +println(legal_moves(2, Nil, (0,0)) == Nil) +println(legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))) + + +def count_tours(dim: Int, path: Path) : Int = { + + val allMovesFromCurrentPosition = legal_moves(dim, path, path.head); + + if (path.length == dim*dim) 1 else { + + if (allMovesFromCurrentPosition.size == 0 ) 0 else { + + allMovesFromCurrentPosition.map( element => count_tours(dim, element::path)).sum + + + } + + } + +} + + + +println ( count_tours(5, List((0,0))) ) + +def enum_tours(dim: Int, path: Path) : List[Path] = { + + val allMovesFromCurrentPosition = legal_moves(dim, path, path.head); + + if (path.length == dim*dim) List(path) else { + + allMovesFromCurrentPosition.map( element => enum_tours(dim, element::path)).flatten ; + + + } + } + println ( enum_tours(6, List((0,2))).size) +} + + + + + + + +//(1b) Complete the function that calculates for a position +// all legal onward moves that are not already in the path. +// The moves should be ordered in a "clockwise" manner. + +//def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = ... + + + + +//some test cases +// +//assert(legal_moves(8, Nil, (2,2)) == +// List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) +//assert(legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) +//assert(legal_moves(8, List((4,1), (1,0)), (2,2)) == +// List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) +//assert(legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) + + +//(1c) Complete the two recursive functions below. +// They exhaustively search for knight's tours starting from the +// given path. The first function counts all possible tours, +// and the second collects all tours in a list of paths. + +//def count_tours(dim: Int, path: Path) : Int = ... + + +//def enum_tours(dim: Int, path: Path) : List[Path] = ... diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight1_test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight1_test.sh Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,206 @@ +#!/bin/bash + +# to make the script fail safely +set -euo pipefail + +out=${1:-output} + +echo "" > $out + +echo "Below is the feedback and provisional marks for your submission" >> $out +echo "for assignment 7 Part 1. Please note all marks are provisional until" >> $out +echo "ratified by the assessment board -- this is not an official" >> $out +echo "results transcript." >> $out +echo "" >> $out + +echo "Below is the feedback for your submission of CW 7, Part 1." >> $out +echo "" >> $out + + +# marks for CW7 part 1 +marks=$(( 0 )) + + +# compilation tests (used to be 30 secs) + +function scala_compile { + (ulimit -t 360; JAVA_OPTS="-Xmx1g" scala "$1" 2> /dev/null 1> /dev/null) +} + +# functional tests + +function scala_assert { + (ulimit -t 360; JAVA_OPTS="-Xmx1g" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) +} + +# purity test + +function scala_vars { + (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|mutable|new Array' "$1" 2> /dev/null 1> /dev/null) +} + + +# knights1: purity test + +echo "knight1.scala does not contain vars, returns, Arrays, ListBuffers etc?" | tee -a $out + +if (scala_vars knight1.scala) +then + echo " --> fail" | tee -a $out + tsts0=$(( 1 )) +else + echo " --> success" | tee -a $out + tsts0=$(( 0 )) +fi + + +# compilation test + +if [ $tsts0 -eq 0 ] +then + echo "knight1.scala runs?" | tee -a $out + + if (scala_compile knight1.scala) + then + echo " --> success " | tee -a $out + tsts1=$(( 0 )) + else + echo " --> scala did not run knight1.scala" | tee -a $out + tsts1=$(( 1 )) + fi +else + tsts1=$(( 1 )) +fi + +### knight1a test + +if [ $tsts1 -eq 0 ] +then + echo " is_legal(8, Nil)(3, 4) == true " | tee -a $out + echo " is_legal(8, List((4, 1), (1, 0)))(4, 1) == false " | tee -a $out + echo " is_legal(2, Nil)(0, 0) == true" | tee -a $out + + if (scala_assert "knight1.scala" "knight1a_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + +### knight1b test + +if [ $tsts1 -eq 0 ] +then + echo " legal_moves(8, Nil, (2,2)) == List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))" | tee -a $out + echo " legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))" | tee -a $out + echo " legal_moves(8, List((4,1), (1,0)), (2,2)) == List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))" | tee -a $out + echo " legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))" | tee -a $out + echo " legal_moves(1, Nil, (0,0)) == Nil" | tee -a $out + echo " legal_moves(2, Nil, (0,0)) == Nil" | tee -a $out + echo " legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))" | tee -a $out + + if (scala_assert "knight1.scala" "knight1b_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +### knight1c test + +if [ $tsts1 -eq 0 ] +then + echo " all_tours from every position on the board" | tee -a $out + echo " dim = 1: 1" | tee -a $out + echo " 2: 0,0,0,0" >> $out + echo " 3: 0,0,0,0,0,0,0,0,0" >> $out + echo " 4: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" | tee -a $out + echo " 5: 304,0,56,0,304,0,56,0,56,0,56,0,64,0,56,0,56,0,56,0,304,0,56,0,304" | tee -a $out + echo " enum_tours(5, List((0,2)) ) => 56 tours? and all correct?" | tee -a $out + + if (scala_assert "knight1.scala" "knight1c_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 2 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +# knights2: var test + +echo "knight2.scala does not contain vars, returns, Arrays, ListBuffers etc?" | tee -a $out + +if (scala_vars knight2.scala) +then + echo " --> fail" | tee -a $out + tsts0=$(( 1 )) +else + echo " --> success" | tee -a $out + tsts0=$(( 0 )) +fi + + +# compilation test +if [ $tsts0 -eq 0 ] +then + echo "knight2.scala runs?" | tee -a $out + + if (scala_compile knight2.scala) + then + echo " --> success" | tee -a $out + tsts1=$(( 0 )) + else + echo " --> scala did not run knight2.scala" | tee -a $out + tsts1=$(( 1 )) + fi +else + tsts1=$(( 1 )) +fi + +### knight2a test + +if [ $tsts1 -eq 0 ] +then + echo " val f = (x:(Int, Int)) => if (x._1 > 3) Some(List(x)) else None " | tee -a $out + echo " first(List((1,0),(2,0),(3,0),(4,0)), f) == Some(List((4,0)))" | tee -a $out + echo " first(List((1,0),(2,0),(3,0)), f) == None" | tee -a $out + + if (scala_assert "knight2.scala" "knight2a_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +### knight2b test + +if [ $tsts1 -eq 0 ] +then + echo " is first_tour(8, List((0, 0))) ok? " | tee -a $out + echo " is first_tour(4, List((0, 0))) == None " | tee -a $out + + if (scala_assert "knight2.scala" "knight2b_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 2 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +## final marks +echo "Overall mark for Part 1" | tee -a $out +echo "$marks" | tee -a $out + + diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight1a_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight1a_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,5 @@ + +assert(CW7a.is_legal(8, Nil)(3, 4) == true) +assert(CW7a.is_legal(8, List((4, 1), (1, 0)))(4, 1) == false) +assert(CW7a.is_legal(2, Nil)(0, 0) == true) + diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight1b_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight1b_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,11 @@ + +assert(CW7a.legal_moves(8, Nil, (2,2)) == + List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))) +assert(CW7a.legal_moves(8, Nil, (7,7)) == List((6,5), (5,6))) +assert(CW7a.legal_moves(8, List((4,1), (1,0)), (2,2)) == + List((3,4), (4,3), (3,0), (0,1), (0,3), (1,4))) +assert(CW7a.legal_moves(8, List((6,6)), (7,7)) == List((6,5), (5,6))) +assert(CW7a.legal_moves(1, Nil, (0,0)) == List()) +assert(CW7a.legal_moves(2, Nil, (0,0)) == List()) +assert(CW7a.legal_moves(3, Nil, (0,0)) == List((1,2), (2,1))) + diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight1c_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight1c_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,47 @@ + +import scala.concurrent._ +import scala.concurrent.duration._ +import ExecutionContext.Implicits.global +import scala.language.postfixOps + +type Pos = (Int, Int) // a position on a chessboard +type Path = List[Pos] // a path...a list of positions + +def count_all_tours_urban(dim: Int) = { + for (i <- (0 until dim).toList; + j <- (0 until dim).toList) yield CW7a.count_tours(dim, List((i, j))) +} + +def add_pair_urban(x: Pos)(y: Pos): Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves_urban(x: Pos): List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) + +def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = + moves_urban(x).filter(is_legal_urban(dim, path)) + +def correct_urban(dim: Int)(p: Path): Boolean = p match { + case Nil => true + case x::Nil => true + case x::y::p => if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false +} + + +lazy val f = Future { + assert(count_all_tours_urban(1) == List(1)) + assert(count_all_tours_urban(2) == List(0, 0, 0, 0)) + assert(count_all_tours_urban(3) == List(0, 0, 0, 0, 0, 0, 0, 0, 0)) + assert(count_all_tours_urban(4) == List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + assert(count_all_tours_urban(5) == List(304, 0, 56, 0, 304, 0, 56, 0, 56, 0, 56, 0, 64, 0, 56, 0, 56, 0, 56, 0, 304, 0, 56, 0, 304)) + + val ts = CW7a.enum_tours(5, List((0, 2))) + assert(ts.map(correct_urban(5)).forall(_ == true) == true) + assert(ts.length == 56) +} + +Await.result(f, 360 second) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight2.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight2.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,61 @@ +// Part 2 about finding a single tour for a board +//================================================ + +object CW7b { + +type Pos = (Int, Int) // a position on a chessboard +type Path = List[Pos] // a path...a list of positions + +def print_board(dim: Int, path: Path) : Unit = { + println + for (i <- 0 until dim) { + for (j <- 0 until dim) { + print(f"${path.reverse.indexOf((i, j))}%3.0f ") + } + println + } +} + +def add_pair(x: Pos)(y: Pos) : Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal(dim: Int, path: Path)(x: Pos) : Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves(x: Pos) : List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair(x)) + +def legal_moves(dim: Int, path: Path, x: Pos) : List[Pos] = + moves(x).filter(is_legal(dim, path)) + + +def first(xs: List[Pos], f: Pos => Option[Path]) : Option[Path] = xs match { + case Nil => None + case x::xs => { + val result = f(x) + if (result.isDefined) result else first(xs, f) + } +} + +//first(List((1, 0),(2, 0),(3, 0),(4, 0)), (x => if (x._1 > 3) Some(List(x)) else None)) +//first(List((1, 0),(2, 0),(3, 0)), (x => if (x._1 > 3) Some(List(x)) else None)) + +def first_tour(dim: Int, path: Path) : Option[Path] = { + if (path.length == dim * dim) Some(path) + else + first(legal_moves(dim, path, path.head), (x: Pos) => first_tour(dim, x::path)) +} + +/* +val ts1 = first_tour(8, List((0, 0))).get + assert(correct_urban(8)(ts1) == true) + +val ts2 = first_tour(4, List((0, 0))) +assert(ts2 == None) + +print_board(8, first_tour(8, List((0, 0))).get) +*/ + +} + diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight2a_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight2a_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,5 @@ + +val f = (x:(Int, Int)) => if (x._1 > 3) Some(List(x)) else None + +assert(CW7b.first(List((1,0),(2,0),(3,0),(4,0)), f) == Some(List((4,0)))) +assert(CW7b.first(List((1,0),(2,0),(3,0)), f) == None) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight2b_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight2b_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,40 @@ + +import scala.concurrent._ +import scala.concurrent.duration._ +import ExecutionContext.Implicits.global +import scala.language.postfixOps + +type Pos = (Int, Int) // a position on a chessboard +type Path = List[Pos] // a path...a list of positions + +def add_pair_urban(x: Pos)(y: Pos): Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves_urban(x: Pos): List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) + +def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = + moves_urban(x).filter(is_legal_urban(dim, path)) + +def correct_urban(dim: Int)(p: Path): Boolean = p match { + case Nil => true + case x::Nil => true + case x::y::p => + if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false +} + + +lazy val f = Future { + + val ts1 = CW7b.first_tour(8, List((0, 0))).get + assert(correct_urban(8)(ts1) == true) + + val ts2 = CW7b.first_tour(4, List((0, 0))) + assert(ts2 == None) +} + +Await.result(f, 300 second) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight3.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight3.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,63 @@ +// Part 3 about finding a single tour using the Warnsdorf Rule +//============================================================= + +//object CW8c { // for preparing the jar + +type Pos = (Int, Int) +type Path = List[Pos] + + +// for measuring time in the JAR +def time_needed[T](code: => T) : T = { + val start = System.nanoTime() + val result = code + val end = System.nanoTime() + println(f"Time needed: ${(end - start) / 1.0e9}%3.3f secs.") + result +} + + +def print_board(dim: Int, path: Path): Unit = { + println + for (i <- 0 until dim) { + for (j <- 0 until dim) { + print(f"${path.reverse.indexOf((i, j))}%4.0f ") + } + println + } +} + +def add_pair(x: Pos, y: Pos): Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal(dim: Int, path: Path, x: Pos): Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves(x: Pos): List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair(x, _)) + +def legal_moves(dim: Int, path: Path, x: Pos): List[Pos] = + moves(x).filter(is_legal(dim, path, _)) + +def ordered_moves(dim: Int, path: Path, x: Pos): List[Pos] = + legal_moves(dim, path, x).sortBy((x) => legal_moves(dim, path, x).length) + +import scala.annotation.tailrec + +@tailrec +def tour_on_mega_board_aux(dim: Int, paths: List[Path]): Option[Path] = paths match { + case Nil => None + case (path::rest) => + if (path.length == dim * dim) Some(path) + else tour_on_mega_board_aux(dim, ordered_moves(dim, path, path.head).map(_::path) ::: rest) +} + +def ttour_on_mega_board(dim: Int, path: Path): Option[Path] = + tour_on_mega_board_aux(dim, List(path)) + + +def tour_on_mega_board(dim: Int, path: Path) = + time_needed(ttour_on_mega_board(dim: Int, path: Path)) + +//} diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight3_test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight3_test.sh Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,124 @@ +#!/bin/bash + +# to make the script fail safely +set -euo pipefail + + +out=${1:-output} + +echo "" > $out + +echo "Below is the feedback and provisional marks for your submission" >> $out +echo "for assignment 7 Part 2. Please note all marks are provisional until" >> $out +echo "ratified by the assessment board -- this is not an official" >> $out +echo "results transcript." >> $out +echo "" >> $out + +# marks for CW7 part 2 +marks=$(( 0 )) + +# compilation tests + +function scala_compile { + (ulimit -t 360; JAVA_OPTS="-Xmx1g" scala "$1" 2> /dev/null 1> /dev/null) +} + +# functional tests + +function scala_assert { + (ulimit -t 360; JAVA_OPTS="-Xmx4g -Xss200m" scala -i "$1" "$2" -e "" 2> /dev/null 1> /dev/null) +} + + +# purity test + +function scala_vars { + (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|mutable|new Array' "$1" 2> /dev/null 1> /dev/null) +} + + +# knights3: purity test +# +echo "knight3.scala does not contain vars, returns, Arrays, ListBuffers etc?" | tee -a $out + + +if (scala_vars knight3.scala) +then + echo " --> test failed" | tee -a $out + tsts0=$(( 1 )) +else + echo " --> success" | tee -a $out + tsts0=$(( 0 )) +fi + + +# compilation test +if [ $tsts0 -eq 0 ] +then + echo "knight3.scala runs?" | tee -a $out + + if (scala_compile knight3.scala) + then + echo " --> success" | tee -a $out + tsts1=$(( 0 )) + else + echo " --> scala knight3.scala did not run successfully" | tee -a $out + tsts1=$(( 1 )) + fi +else + tsts1=$(( 1 )) +fi + +# ordered move test + +if [ $tsts1 -eq 0 ] +then + echo " ordered_moves(8, List((3,4), (3,2)), (1,3)) == List((0,1), (0,5), (2,1), (2,5))" | tee -a $out + echo " ordered_moves(8, List((4,0)), (0,0)) == List((2,1), (1,2))" | tee -a $out + echo " ordered_moves(8, List((0,4)), (0,0)) == List((1,2), (2,1))" | tee -a $out + + if (scala_assert "knight3.scala" "knight3a_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +# first-closed-tour test + +if [ $tsts1 -eq 0 ] +then + echo " first_closed_tour_heuristic(6, List((3,3))) found and correct?" | tee -a $out + + if (scala_assert "knight3.scala" "knight3b_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + + +if [ $tsts1 -eq 0 ] +then + echo " first_tour_heuristic(8, List((0,0))) found and correct?" | tee -a $out + echo " first_tour_heuristic(40, List((0,0))) found and correct?" | tee -a $out + + if (scala_assert "knight3.scala" "knight3c_test.scala") + then + echo " --> success" | tee -a $out + marks=$(( marks + 1 )) + else + echo " --> test failed" | tee -a $out + fi +fi + + +## final marks +echo "Overall mark for CW 7, Part 2" | tee -a $out +echo "$marks" | tee -a $out diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight3a_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight3a_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,15 @@ + +import scala.concurrent._ +import scala.concurrent.duration._ +import ExecutionContext.Implicits.global +import scala.language.postfixOps + +lazy val f = Future { + +assert(CW7c.ordered_moves(8, List((3,4), (3,2)), (1, 3)) == List((0,1), (0,5), (2,1), (2,5))) +assert(CW7c.ordered_moves(8, List((4,0)), (0,0)) == List((2,1), (1,2))) +assert(CW7c.ordered_moves(8, List((0,4)), (0,0)) == List((1,2), (2,1))) + +} + +Await.result(f, 120 second) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight3b_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight3b_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,40 @@ + +//import scala.concurrent._ +//import scala.concurrent.duration._ +//import ExecutionContext.Implicits.global +//import scala.language.postfixOps + +type Pos = (Int, Int) +type Path = List[Pos] + +def add_pair_urban(x: Pos)(y: Pos): Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves_urban(x: Pos): List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) + +def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = + moves_urban(x).filter(is_legal_urban(dim, path)) + +def correct_urban(dim: Int)(p: Path): Boolean = p match { + case Nil => true + case x::Nil => true + case x::y::p => + if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false +} + +def correct_closed_urban(dim: Int)(p: Path) = + correct_urban(6)(p) && moves_urban(p.head).contains(p.last) + +//lazy val f = Future { + + val tsc = CW7c.first_closed_tour_heuristic(6, List((3, 3))).get + assert(correct_closed_urban(6)(tsc) == true) + +//} + +//Await.result(f, 300 second) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/knight3c_test.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/knight3c_test.scala Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,49 @@ + +//import scala.concurrent._ +//import scala.concurrent.duration._ +//import ExecutionContext.Implicits.global +//import scala.language.postfixOps + +type Pos = (Int, Int) +type Path = List[Pos] + +def add_pair_urban(x: Pos)(y: Pos): Pos = + (x._1 + y._1, x._2 + y._2) + +def is_legal_urban(dim: Int, path: Path)(x: Pos): Boolean = + 0 <= x._1 && 0 <= x._2 && x._1 < dim && x._2 < dim && !path.contains(x) + +def moves_urban(x: Pos): List[Pos] = + List(( 1, 2),( 2, 1),( 2, -1),( 1, -2), + (-1, -2),(-2, -1),(-2, 1),(-1, 2)).map(add_pair_urban(x)) + +def legal_moves_urban(dim: Int, path: Path, x: Pos): List[Pos] = + moves_urban(x).filter(is_legal_urban(dim, path)) + +def correct_urban(dim: Int)(p: Path): Boolean = p match { + case Nil => true + case x::Nil => true + case x::y::p => + if (legal_moves_urban(dim, p, y).contains(x)) correct_urban(dim)(y::p) else false +} + + +// !!!!!!! the futures need to be removed...otherwise funny results +//lazy val f1 = Future { + + val ts8 = CW7c.first_tour_heuristic(8, List((0,0))).get + assert(correct_urban(8)(ts8) == true) + +//} + +//Await.result(f1, 360 second) + + +//lazy val f2 = Future { + + val ts40 = CW7c.first_tour_heuristic(40, List((0,0))).get + assert(correct_urban(40)(ts40) == true) + +//} + +//Await.result(f2, 360 second) diff -r a359976a6f3e -r 975d34506e88 testing3/testing3-bak/mark --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testing3/testing3-bak/mark Fri Dec 14 14:41:54 2018 +0000 @@ -0,0 +1,8 @@ +#!/bin/bash +###set -e + +trap "exit" INT + +./knight1_test.sh output1 +./knight3_test.sh output3 +