updated
authorChristian Urban <christian.urban@kcl.ac.uk>
Mon, 21 Jul 2025 16:38:07 +0100
changeset 494 253d1ccb65de
parent 493 244df77507c2
child 495 b47879225270
updated
core_marking1/collatz_test.sh
core_marking1/collatz_test1.scala
core_marking1/collatz_test2.scala
core_marking1/collatz_test3.scala
core_marking2/docdiff_test.sh
core_marking2/docdiff_test1.scala
core_marking2/docdiff_test2.scala
core_marking2/docdiff_test3.scala
core_marking2/docdiff_test4.scala
core_marking3/postfix_test.sh
core_marking3/postfix_test1.scala
core_marking3/postfix_test2.scala
core_marking3/postfix_test3.scala
core_marking3/postfix_test4.scala
cws/disclaimer.sty
cws/main_cw05.pdf
cws/main_cw05.tex
cws/resit2.tex
handouts/pep-ho.pdf
handouts/pep-ho.tex
main_marking3/re_test.sh
main_marking3/re_test0.scala
main_marking3/re_test1.scala
main_marking3/re_test2.scala
main_marking3/re_test3.scala
main_marking3/re_test3a.scala
main_marking3/re_test4.scala
main_marking3/re_test5.scala
main_marking3/re_test6.scala
main_marking3/re_test7.scala
main_marking4/mk_main4
main_marking5/bf_test.sh
main_marking5/bf_test1.scala
main_marking5/bf_test2.scala
main_marking5/bf_test3.scala
main_marking5/bf_test4.scala
main_marking5/bf_test4b.scala
main_marking5/bf_test4c.scala
main_marking5/bf_test5.scala
main_marking5/bf_test6.scala
main_marking5/bf_test7.scala
main_marking5/mk_main5
main_solution3/re.scala
main_solution5/bfc.scala
progs/lecture1.scala
progs/lecture2.scala
progs/lecture3.scala
progs/lecture4.scala
progs/lecture5.scala
progs/mandelbrot.sc
slides/slides01.pdf
slides/slides01.tex
slides/slides02.pdf
slides/slides02.tex
slides/slides03.pdf
slides/slides03.tex
slides/slides04.pdf
slides/slides04.tex
slides/slides05.pdf
slides/slides05.tex
--- a/core_marking1/collatz_test.sh	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking1/collatz_test.sh	Mon Jul 21 16:38:07 2025 +0100
@@ -22,17 +22,21 @@
 # marks for core part 1
 marks=$(( 0 ))
 
+
+# compilation tests
+
 # compilation tests
 
 function scala_compile {
-  (JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
+    (ulimit -t 30; scala-cli compile --server=false -color never -Xprint:parser "$1" 2> c$out 1> c$out)
 }
 
 # functional tests
 
 function scala_assert {
-  (JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+  (ulimit -t 30; scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
+
  
 # purity test
 function scala_vars {
--- a/core_marking1/collatz_test1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking1/collatz_test1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,8 +1,11 @@
 
+def urbanmain() = {
+  import C1._
 
-assert(C1.collatz(1) == 0)
-assert(C1.collatz(6) == 8)
-assert(C1.collatz(9) == 19)
-assert(C1.collatz(9000) == 47)
+  assert(C1.collatz(1) == 0)
+  assert(C1.collatz(6) == 8)
+  assert(C1.collatz(9) == 19)
+  assert(C1.collatz(9000) == 47)
 
+}
 
--- a/core_marking1/collatz_test2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking1/collatz_test2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,10 +1,12 @@
-import C1._
-
-assert(collatz_max(10) == (19, 9))
-assert(collatz_max(100) == (118, 97))
-assert(collatz_max(1000) == (178, 871))
-assert(collatz_max(10000) == (261, 6171))
-assert(collatz_max(100000) == (350, 77031))
-assert(collatz_max(1000000) == (524, 837799))
-assert(collatz_max(2) == (1, 2))
-assert(collatz_max(77000) == (339, 52527))
+def urbanmain() = {
+  import C1._
+ 
+  assert(collatz_max(10) == (19, 9))
+  assert(collatz_max(100) == (118, 97))
+  assert(collatz_max(1000) == (178, 871))
+  assert(collatz_max(10000) == (261, 6171))
+  assert(collatz_max(100000) == (350, 77031))
+  assert(collatz_max(1000000) == (524, 837799))
+  assert(collatz_max(2) == (1, 2))
+  assert(collatz_max(77000) == (339, 52527))
+}
--- a/core_marking1/collatz_test3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking1/collatz_test3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -3,10 +3,13 @@
 import ExecutionContext.Implicits.global
 import scala.language.postfixOps 
 
-lazy val f = Future {
-assert(C1.last_odd(113) == 85)
-assert(C1.last_odd(84) == 21)
-assert(C1.last_odd(605) == 341)
+def urbanmain() = {
+  
+  lazy val f = Future {
+    assert(C1.last_odd(113) == 85)
+    assert(C1.last_odd(84) == 21)
+    assert(C1.last_odd(605) == 341)
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
--- a/core_marking2/docdiff_test.sh	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking2/docdiff_test.sh	Mon Jul 21 16:38:07 2025 +0100
@@ -25,13 +25,13 @@
 # compilation tests
 
 function scala_compile {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
+    (ulimit -t 30; scala-cli compile --server=false -color never -Xprint:parser "$1" 2> c$out 1> c$out)
 }
 
 # functional tests
 
 function scala_assert {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+  (ulimit -t 30; scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
 # purity test
--- a/core_marking2/docdiff_test1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking2/docdiff_test1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,4 +1,7 @@
-import C2._
+
+def urbanmain() = {
+  import C2._
 
-assert(clean("ab a abc") == List("ab", "a", "abc"))
-assert(clean("ab*a abc1") == List("ab", "a", "abc1"))
+  assert(clean("ab a abc") == List("ab", "a", "abc"))
+  assert(clean("ab*a abc1") == List("ab", "a", "abc1"))
+}
--- a/core_marking2/docdiff_test2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking2/docdiff_test2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,10 +1,12 @@
 
-import C2._
+def urbanmain() = {
+  import C2._
 
-assert(occurrences(List("a", "b", "b", "c", "d")) == Map("a" -> 1, "b" -> 2, "c" -> 1, "d" -> 1))
+  assert(occurrences(List("a", "b", "b", "c", "d")) == Map("a" -> 1, "b" -> 2, "c" -> 1, "d" -> 1))
 
-assert(occurrences(List("d", "b", "d", "b", "d")) == Map("d" -> 3, "b" -> 2))
+  assert(occurrences(List("d", "b", "d", "b", "d")) == Map("d" -> 3, "b" -> 2))
 
-assert(occurrences(List("b", "b", "b", "b", "b")) == Map("b" -> 5))
+  assert(occurrences(List("b", "b", "b", "b", "b")) == Map("b" -> 5))
 
-assert(occurrences(Nil) == Map())
+  assert(occurrences(Nil) == Map())
+}
--- a/core_marking2/docdiff_test3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking2/docdiff_test3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,15 +1,17 @@
 
-import C2._
+def urbanmain() = {
+  import C2._
 
-val urban_list1 = List("a", "b", "b", "c", "d")
-val urban_list2 = List("d", "b", "d", "b", "d")
+  val urban_list1 = List("a", "b", "b", "c", "d")
+  val urban_list2 = List("d", "b", "d", "b", "d")
 
-assert(prod(urban_list1, urban_list2) == 7)
-assert(prod(urban_list1, urban_list1) == 7)
-assert(prod(urban_list2, urban_list2) == 13)
+  assert(prod(urban_list1, urban_list2) == 7)
+  assert(prod(urban_list1, urban_list1) == 7)
+  assert(prod(urban_list2, urban_list2) == 13)
 
 
-val urban_listA = List("a", "b", "b", "c", "d")
-val urban_listB = List("1", "2", "3", "4", "5")
+  val urban_listA = List("a", "b", "b", "c", "d")
+  val urban_listB = List("1", "2", "3", "4", "5")
 
-assert(prod(urban_listA, urban_listB) == 0)
+  assert(prod(urban_listA, urban_listB) == 0)
+}
--- a/core_marking2/docdiff_test4.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking2/docdiff_test4.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,9 +1,12 @@
 
-import C2._
+
+def urbanmain() = {
+  import C2._
 
-val urban_list1 = List("a", "b", "b", "c", "d")
-val urban_list2 = List("d", "b", "d", "b", "d")
+  val urban_list1 = List("a", "b", "b", "c", "d")
+  val urban_list2 = List("d", "b", "d", "b", "d")
 
-assert(overlap(urban_list1, urban_list2) == 0.5384615384615384)
-assert(overlap(urban_list1, urban_list1) == 1.0)
-assert(overlap(urban_list2, urban_list2) == 1.0)
+  assert(overlap(urban_list1, urban_list2) == 0.5384615384615384)
+  assert(overlap(urban_list1, urban_list1) == 1.0)
+  assert(overlap(urban_list2, urban_list2) == 1.0)
+}
--- a/core_marking3/postfix_test.sh	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking3/postfix_test.sh	Mon Jul 21 16:38:07 2025 +0100
@@ -20,17 +20,16 @@
 # marks for CW9 preliminary
 marks=$(( 0.0 ))
 
-
 # compilation tests
 
 function scala_compile {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
+    (ulimit -t 30; scala-cli compile --server=false -color never -Xprint:parser "$1" 2> c$out 1> c$out)
 }
 
 # functional tests
 
 function scala_assert {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+  (ulimit -t 30; scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
 # purity test
--- a/core_marking3/postfix_test1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking3/postfix_test1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,7 +1,10 @@
-import C3a._
 
 
-assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+"))
-assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+"))
-assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+"))
-assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/"))
+def urbanmain() = {
+  import C3a._
+
+  assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+"))
+  assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+"))
+  assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+"))
+  assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/"))
+}
--- a/core_marking3/postfix_test2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking3/postfix_test2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,8 +1,11 @@
-import C3a._
+
+def urbanmain() = {
+  import C3a._
 
-assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7)
-assert(compute(syard(split("10 + 12 * 33"))) == 406)
-assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24)
-assert(compute(syard(split("5 + 7 / 2"))) == 8)
-assert(compute(syard(split("5 * 7 / 2"))) == 17)
-assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15)
+  assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7)
+  assert(compute(syard(split("10 + 12 * 33"))) == 406)
+  assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24)
+  assert(compute(syard(split("5 + 7 / 2"))) == 8)
+  assert(compute(syard(split("5 * 7 / 2"))) == 17)
+  assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15)
+}
--- a/core_marking3/postfix_test3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking3/postfix_test3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,9 +1,11 @@
-import C3b._
+
+def urbanmain() = {
+  import C3b._
 
 
-assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+"))
-assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+"))
-assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+"))
-assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/"))
-assert(syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3")) == List("3", "4", "8", "*", "5", "1", "-", "2", "3", "^", "^", "/", "+"))
-
+  assert(syard(split("3 + 4 * ( 2 - 1 )")) == List("3", "4", "2", "1", "-", "*", "+"))
+  assert(syard(split("( ( ( 3 ) ) + ( ( 4 + ( 5 ) ) ) )")) == List("3", "4", "5", "+", "+"))
+  assert(syard(split("5 + 7 / 2")) == List("5", "7", "2", "/", "+"))
+  assert(syard(split("5 * 7 / 2")) == List("5", "7", "*", "2", "/"))
+  assert(syard(split("3 + 4 * 8 / ( 5 - 1 ) ^ 2 ^ 3")) == List("3", "4", "8", "*", "5", "1", "-", "2", "3", "^", "^", "/", "+"))
+}
--- a/core_marking3/postfix_test4.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/core_marking3/postfix_test4.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,13 +1,16 @@
-import C3b._
+
+def urbanmain() = {
+  import C3b._
 
 
-assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7)
-assert(compute(syard(split("10 + 12 * 33"))) == 406)
-assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24)
-assert(compute(syard(split("5 + 7 / 2"))) == 8)
-assert(compute(syard(split("5 * 7 / 2"))) == 17)
-assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15)
-assert(compute(syard(split("4 ^ 3 ^ 2"))) == 262144)
-assert(compute(syard(split("4 ^ ( 3 ^ 2 )"))) == 262144)
-assert(compute(syard(split("( 4 ^ 3 ) ^ 2"))) == 4096)
-assert(compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) == 65536)
+  assert(compute(syard(split("3 + 4 * ( 2 - 1 )"))) == 7)
+  assert(compute(syard(split("10 + 12 * 33"))) == 406)
+  assert(compute(syard(split("( 5 + 7 ) * 2"))) == 24)
+  assert(compute(syard(split("5 + 7 / 2"))) == 8)
+  assert(compute(syard(split("5 * 7 / 2"))) == 17)
+  assert(compute(syard(split("9 + 24 / ( 7 - 3 )"))) == 15)
+  assert(compute(syard(split("4 ^ 3 ^ 2"))) == 262144)
+  assert(compute(syard(split("4 ^ ( 3 ^ 2 )"))) == 262144)
+  assert(compute(syard(split("( 4 ^ 3 ) ^ 2"))) == 4096)
+  assert(compute(syard(split("( 3 + 1 ) ^ 2 ^ 3"))) == 65536)
+}
--- a/cws/disclaimer.sty	Sun Sep 15 12:57:59 2024 +0100
+++ b/cws/disclaimer.sty	Mon Jul 21 16:38:07 2025 +0100
@@ -98,7 +98,7 @@
 your \textbf{own} effort! You have implemented the code entirely
 on your own. You have not copied from anyone else.
 Do not be tempted to ask Copilot for help or
-do any other shenanigans like this! An exception is the Scala
+do any other AI-shenanigans like this! An exception is the Scala
 code I showed during the lectures or uploaded to KEATS,
 which you can freely use.\bigskip
 }
Binary file cws/main_cw05.pdf has changed
--- a/cws/main_cw05.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/cws/main_cw05.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -24,7 +24,7 @@
 
 \noindent
 This part is about a small (esoteric) programming language called
-brainf***. We will implement an interpreter and compiler for
+brainf***. The task is to implement an interpreter and compiler for
 this language.\bigskip
 
 %\IMPORTANT{This part is worth 10\% and you need to submit it on \cwTEN{} at 5pm.
@@ -113,7 +113,9 @@
 
 Some relatively sophisticated sample programs in brainf*** are given
 in the file \texttt{bf.scala}, including a brainf*** program for the
-Sierpinski triangle and the Mandelbrot set.  There seems to be even a
+Sierpinski triangle and the Mandelbrot set.\footnote{Of course somebody 
+tried LLMs for writing bf-programs. As expected, they did spectacularly 
+badly in this task. \hr{https://www.reddit.com/r/programming/comments/1m4rk3r/comment/n49qrnv/}}  There seems to be even a
 dedicated Windows IDE for bf programs, though I am not sure whether
 this is just an elaborate April fools' joke---judge yourself:
 
--- a/cws/resit2.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/cws/resit2.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -52,9 +52,9 @@
 
 \noindent
 You are asked to implement a Scala program for playing the Shogun
-board game.  The deadline for your submission is on 26th July at
+board game.  The deadline for your submission is on 31th July at
 16:00.  Make sure you use \texttt{scala-cli} and Scala version \textbf{3.XX}
-for the resit---the same version as during the lectures.  \medskip
+for the resit.  \medskip
 
 \IMPORTANTNONE{}
 
@@ -115,7 +115,7 @@
 above.  What sets Shogun apart from chess and checkers is that each
 piece has, what I call, a kind of \textit{energy}---which for pawns is
 a number between 1 and 4, and for kings between 1 and 2. The energy
-determines how far a piece has to move. In the physical version of
+determines how far a piece can move. In the physical version of
 Shogun, the pieces and the board have magnets that can change the
 energy of a piece from move to move---so a piece on one field can have
 energy 2 and on a different field the same piece might have energy
@@ -136,7 +136,7 @@
 
 \begin{itemize}
 \item The energy of a piece determines how far, that is how many
-  fields, a piece has to move (remember pawns have an energy between 1 --
+  fields, a piece can move (remember pawns have an energy between 1 --
   4, kings have an energy of only 1 -- 2). The energy of a piece might
   change when the piece moves to new field.
 \item Pieces can move in straight lines (up, down, left, right), or in
@@ -251,7 +251,7 @@
 
 Useful functions about pieces and boards are defined at the beginning
 of the template file. The function \texttt{.map} applies a function to
-each element of a list or set; \texttt{.flatMap} works like
+each element of a list or a set; \texttt{.flatMap} works like
 \texttt{map} followed by a \texttt{.flatten}---this is useful if a
 function returns a set of sets, which need to be ``unioned up''.  Sets
 can be partitioned according to a predicate with the function
@@ -317,8 +317,8 @@
 case object D extends Move    // down
 case object R extends Move    // right
 case object L extends Move    // left
-case object RU extends Move   // ...
-case object LU extends Move
+case object RU extends Move   // right-up
+case object LU extends Move   // ...
 case object RD extends Move
 case object LD extends Move
 case object UR extends Move
Binary file handouts/pep-ho.pdf has changed
--- a/handouts/pep-ho.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/handouts/pep-ho.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -186,24 +186,24 @@
 \noindent\alert
 For PEP, make sure you are using the version 3(!) of Scala. This is
 the version I am going to use in the lectures and in the coursework. This
-can be any version of Scala 3.X where $X=\{3,4\}$. Also the minor
+can be any version of Scala 3.X where $X=\{4,5\}$. Also the minor
 number does not matter. Note that this will be the second year I am
 using this newer version of Scala -- some hiccups can still happen. Apologies
 in advance!\bigskip
 
-\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
-  I will be using the \textbf{\texttt{scala-cli}} REPL for Scala 3, rather
-  than the ``plain'' Scala REPL. This is a batteries included version of
-  Scala 3 and is easier to use and to install. In fact
-  \texttt{scala-cli} is designated to replace
-  the ``plain'' Scala REPL in future versions of Scala.
-  So why not using it now?
-  It can be downloaded from:
-
-  \begin{center}
-  \url{https://scala-cli.virtuslab.org}
-  \end{center}
-\end{tcolorbox}\medskip
+%\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
+%  I will be using the \textbf{\texttt{scala-cli}} REPL for Scala 3, rather
+%  than the ``plain'' Scala REPL. This is a batteries included version of
+%  Scala 3 and is easier to use and to install. In fact
+%  \texttt{scala-cli} is designated to replace
+%  the ``plain'' Scala REPL in future versions of Scala.
+%  So why not using it now?
+%  It can be downloaded from:%
+%
+%  \begin{center}
+% \url{https://scala-cli.virtuslab.org}
+%  \end{center}
+%\end{tcolorbox}\medskip
 
 
 \noindent
@@ -251,7 +251,7 @@
   I have also bound the keys \keys{Ctrl} \keys{Ret} to the
   action ``Run-Selected-Text-In-Active-Terminal'' in order to quickly
   evaluate small code snippets in the Scala REPL. I use Codium's internal
-  terminal to run \texttt{scala-cli} version 1.0.5 which
+  terminal to run \texttt{scala} version 1.0.5 which
   uses Scala 3.3.1.\label{vscode}}
 \end{boxedminipage}
 \end{figure}
@@ -284,7 +284,7 @@
 \noindent
 But you should be careful if you use them for your coursework: they
 are meant to play around, not really for serious work. Therefore make
-sure \texttt{scala-cli} works on your own machine ASAP!
+sure \texttt{scala} works on your own machine ASAP!
 
 As one might expect, Scala can be used with the heavy-duty IDEs
 Eclipse and IntelliJ. For example IntelliJ includes plugins for
@@ -534,30 +534,30 @@
 
 \subsection*{The Very Basics}
 
-Let us get back to Scala and \texttt{scala-cli}: One advantage of
+Let us get back to Scala: One advantage of
 Scala over Java is that it includes an interpreter (a REPL, or
 \underline{R}ead-\underline{E}val-\underline{P}rint-\underline{L}oop)
 with which you can run and test small code snippets without the need
 of a compiler. This helps a lot with interactively developing
 programs. It is my preferred way of writing small Scala programs. Once
-you installed \texttt{scala-cli}, you can start the interpreter by typing on the
+you installed \texttt{scala}, you can start the interpreter by typing on the
 command line:
 
 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
-$ scala-cli
-Welcome to Scala 3.4.1 (21.0.2, Java OpenJDK 64-Bit Server VM).
-Type in expressions for evaluation. Or try :help.
+$ scala
+Welcome to Scala 3.5.1 (21.0.4, Java OpenJDK 64-Bit Server VM).
+Type in expressions for evaluation. Or try :help.  
 
 scala>
 \end{lstlisting}%$
 
 \noindent The precise response may vary depending on the version and
-platform where you installed \texttt{scala-cli}. Make sure however that
-\texttt{scala-cli} uses Scala version 3---you can find the version
+platform where you installed \texttt{scala}. Make sure however that
+\texttt{scala} uses version 3---you can find the version
 number in the welcome message. Also note that at the first time
-\texttt{scala-cli} runs, it might download various components, for
+\texttt{scala} runs, it might download various components, for
 example the Scala compiler, Scala runtimes etc. Once
-\texttt{scala-cli} is up and running, you can type at the prompt
+\texttt{scala} is up and running, you can type at the prompt
 expressions like \code{2 + 3}\;\keys{Ret} and the output will be
 
 \begin{lstlisting}[numbers=none,language={}]
@@ -595,7 +595,7 @@
 now, the latter kind of functions always has \code{Unit} as
 return type. It is just not printed by Scala.
 
-You can try more examples with the \texttt{scala-cli} REPL, but feel free to
+You can try more examples with the \texttt{scala} REPL, but feel free to
 first guess what the result is (not all answers by Scala are obvious):
 
 \begin{lstlisting}[numbers=none,language={}]
@@ -654,11 +654,11 @@
 %}
 
 \noindent save it in a file, say {\tt hello-world.scala}, and
-then use \texttt{scala-cli} (which compiles the
+then use \texttt{scala} (which compiles the
 scala file and runs it):
 
 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
-$ scala-cli hello-world.scala
+$ scala hello-world.scala
 hello world
 \end{lstlisting}
 
@@ -668,7 +668,7 @@
 Runtime. This can be done as follows:
 
 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
-$ scala-cli --power package --assembly hello-world.scala
+$ scala --power package --assembly hello-world.scala
 $ java -jar Hello.jar
 hello world
 \end{lstlisting}
--- a/main_marking3/re_test.sh	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test.sh	Mon Jul 21 16:38:07 2025 +0100
@@ -21,19 +21,20 @@
 # compilation tests
 
 function scala_compile {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
+    (ulimit -t 30; scala-cli compile --server=false -color never -Xprint:parser "$1" 2> c$out 1> c$out)
 }
 
 # functional tests
 
 function scala_assert {
-  (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+  (ulimit -t 30; scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
 function scala_assert_thirty {
-  (ulimit -t 40; JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)  
+  (ulimit -t 40; scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
+
 # purity test
 function scala_vars {
    (sed 's/immutable/ok/g' c$out > cb$out;
--- a/main_marking3/re_test0.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test0.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,6 +1,8 @@
-import M3._
+
+def urbanmain() = {
+  import M3._
 
-assert(ALTs.getClass == ALTs.getClass)
-assert(SEQs.getClass == SEQs.getClass)
+  assert(ALTs.getClass == ALTs.getClass)
+  assert(SEQs.getClass == SEQs.getClass)
+}
 
-
--- a/main_marking3/re_test1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,14 +1,17 @@
-import M3._
-
-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)
-assert(nullable(ALTs(List(ONE, CHAR('a'), ZERO))) == true)
-assert(nullable(SEQs(List(ONE, ALTs(List(ONE, CHAR('a'), ZERO)), STAR(ZERO)))) == true)
 
 
+def urbanmain() = {
+  import M3._
+
+  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)
+  assert(nullable(ALTs(List(ONE, CHAR('a'), ZERO))) == true)
+  assert(nullable(SEQs(List(ONE, ALTs(List(ONE, CHAR('a'), ZERO)), STAR(ZERO)))) == true)
+}
+
--- a/main_marking3/re_test2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,26 +1,30 @@
-import M3._
+
+def urbanmain() = {
+
+  import M3._
 
-assert(der('a', ZERO | ONE) == ALT(ZERO, ZERO))
-assert(der('a', (CHAR('a') | ONE) ~ CHAR('a')) == ALTs(List(SEQ(ALT(ONE, ZERO), CHAR('a')), SEQs(List(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'))))
+  assert(der('a', ZERO | ONE) == ALT(ZERO, ZERO))
+  assert(der('a', (CHAR('a') | ONE) ~ CHAR('a')) == ALTs(List(SEQ(ALT(ONE, ZERO), CHAR('a')), SEQs(List(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 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"
+  val r1_urban = (ONE ~ "b") ~ "c"
 
-assert(der('a', r1_urban) == ((ZERO ~ "b") | SEQs(List(ZERO))) ~ "c")
-assert(der('b', r1_urban) == ((ZERO ~ "b") | SEQs(List(ONE))) ~ "c")
-assert(der('c', r1_urban) == ((ZERO ~ "b") | SEQs(List(ZERO))) ~ "c")
+  assert(der('a', r1_urban) == ((ZERO ~ "b") | SEQs(List(ZERO))) ~ "c")
+  assert(der('b', r1_urban) == ((ZERO ~ "b") | SEQs(List(ONE))) ~ "c")
+  assert(der('c', r1_urban) == ((ZERO ~ "b") | SEQs(List(ZERO))) ~ "c")
+
+  val r2_urban = ((ZERO ~ "b") | ONE) ~ "c"
 
-val r2_urban = ((ZERO ~ "b") | ONE) ~ "c"
+  assert(der('a', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ZERO))))
+  assert(der('b', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ZERO))))
+  assert(der('c', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ONE))))
+}
 
-assert(der('a', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ZERO))))
-assert(der('b', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ZERO))))
-assert(der('c', r2_urban) == ((((ZERO ~ "b") | ZERO) ~ "c") | SEQs(List(ONE))))
-
--- a/main_marking3/re_test3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,22 +1,24 @@
-import M3._
+
+def urbanmain() = {
+  import M3._
 
 
-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,
+  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')))
-assert(simp(ALTs(Nil)) == ZERO)
-assert(simp(SEQs(List(CHAR('a')))) == 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')))
+  assert(simp(ALTs(Nil)) == ZERO)
+  assert(simp(SEQs(List(CHAR('a')))) == CHAR('a'))
+}
--- a/main_marking3/re_test3a.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test3a.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,10 +1,12 @@
-import M3._
 
+def urbanmain() = {
+  import M3._
 
-assert(flts(Nil) == Nil)
-assert(flts(ZERO::ZERO::Nil) == List(ZERO))
-assert(flts(ZERO::ONE::ZERO::ONE::Nil) == List(ZERO))
-assert(flts(ONE::ALTs(List(ONE))::ONE::Nil) == List(ALTs(List(ONE))))
-assert(flts(ONE::ALTs(List(ONE))::ONE::ALTs(List(ONE))::Nil) == List(ALTs(List(ONE)), ALTs(List(ONE))))
-assert(flts(List(CHAR('a'), ONE, ONE, CHAR('b')), Nil) == List(CHAR('a'), CHAR('b')))
-assert(flts(List(ONE ~ CHAR('a'), CHAR('b') ~ ONE), Nil) == List(ONE, CHAR('a'), CHAR('b'), ONE))
+  assert(flts(Nil) == Nil)
+  assert(flts(ZERO::ZERO::Nil) == List(ZERO))
+  assert(flts(ZERO::ONE::ZERO::ONE::Nil) == List(ZERO))
+  assert(flts(ONE::ALTs(List(ONE))::ONE::Nil) == List(ALTs(List(ONE))))
+  assert(flts(ONE::ALTs(List(ONE))::ONE::ALTs(List(ONE))::Nil) == List(ALTs(List(ONE)), ALTs(List(ONE))))
+  assert(flts(List(CHAR('a'), ONE, ONE, CHAR('b')), Nil) == List(CHAR('a'), CHAR('b')))
+  assert(flts(List(ONE ~ CHAR('a'), CHAR('b') ~ ONE), Nil) == List(ONE, CHAR('a'), CHAR('b'), ONE))
+}
--- a/main_marking3/re_test4.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test4.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,5 +1,8 @@
-import M3._
+
+def urbanmain() = {
 
-assert(denest(List(ONE, ZERO, ALTs(List(ONE, CHAR('a'))))) 
-   == List(ONE, ONE, CHAR('a')))
-assert(denest(List(ONE ~ ONE, ZERO, ZERO | ONE)) == List(ONE ~ ONE, ZERO, ONE))
+  import M3._
+
+  assert(denest(List(ONE, ZERO, ALTs(List(ONE, CHAR('a'))))) == List(ONE, ONE, CHAR('a')))
+  assert(denest(List(ONE ~ ONE, ZERO, ZERO | ONE)) == List(ONE ~ ONE, ZERO, ONE))
+}
--- a/main_marking3/re_test5.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test5.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,6 +1,9 @@
-import M3._
+
+def urbanmain() = {
+
+  import M3._
 
-assert(flts(List(CHAR('a'), ZERO, ONE), Nil) == List(ZERO))
-assert(flts(List(CHAR('a'), ONE, ONE, CHAR('b')), Nil) == List(CHAR('a'), CHAR('b')))
-assert(flts(List(ONE ~ CHAR('a'), CHAR('b') ~ ONE), Nil) == List(ONE, CHAR('a'), CHAR('b'), ONE))
-
+  assert(flts(List(CHAR('a'), ZERO, ONE), Nil) == List(ZERO))
+  assert(flts(List(CHAR('a'), ONE, ONE, CHAR('b')), Nil) == List(CHAR('a'), CHAR('b')))
+  assert(flts(List(ONE ~ CHAR('a'), CHAR('b') ~ ONE), Nil) == List(ONE, CHAR('a'), CHAR('b'), ONE))
+}
--- a/main_marking3/re_test6.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test6.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,10 +1,13 @@
-import M3._
+
+def urbanmain() = {
+  import M3._
 
-assert(SEQs_smart(Nil) == ONE)
-assert(SEQs_smart(List(ZERO)) == ZERO)
-assert(SEQs_smart(List(CHAR('a'))) == CHAR('a'))
-assert(SEQs_smart(List(ONE ~ ONE)) == ONE ~ ONE)
-assert(SEQs_smart(List(ONE, ONE)) == SEQs(List(ONE, ONE)))
-assert(ALTs_smart(Nil) == ZERO)
-assert(ALTs_smart(List(ONE ~ ONE)) == ONE ~ ONE)
-assert(ALTs_smart(List(ZERO, ZERO)) == ALTs(List(ZERO, ZERO)))
+  assert(SEQs_smart(Nil) == ONE)
+  assert(SEQs_smart(List(ZERO)) == ZERO)
+  assert(SEQs_smart(List(CHAR('a'))) == CHAR('a'))
+  assert(SEQs_smart(List(ONE ~ ONE)) == ONE ~ ONE)
+  assert(SEQs_smart(List(ONE, ONE)) == SEQs(List(ONE, ONE)))
+  assert(ALTs_smart(Nil) == ZERO)
+  assert(ALTs_smart(List(ONE ~ ONE)) == ONE ~ ONE)
+  assert(ALTs_smart(List(ZERO, ZERO)) == ALTs(List(ZERO, ZERO)))
+}
--- a/main_marking3/re_test7.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking3/re_test7.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,19 +1,22 @@
-import M3._
 
-val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
+def urbanmain() = {
+  import M3._
+
+  val EVIL_urban = SEQ(STAR(STAR(CHAR('a'))), CHAR('b'))
 
-assert(ders(("a" * 5).toList, EVIL_urban) == SEQs(List(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)
+  assert(ders(("a" * 5).toList, EVIL_urban) == SEQs(List(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)
+}
--- a/main_marking4/mk_main4	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking4/mk_main4	Mon Jul 21 16:38:07 2025 +0100
@@ -10,33 +10,21 @@
   cd $sd
   echo $sd
   touch .
-  cp ../../../../../main_marking4/knight_test.sh .
-  cp ../../../../../main_marking4/knight1_test1.scala .
-  cp ../../../../../main_marking4/knight1_test2.scala .
-  cp ../../../../../main_marking4/knight1_test3a.scala .
-  cp ../../../../../main_marking4/knight1_test3b.scala .
-  cp ../../../../../main_marking4/knight1_test3c.scala .
-  cp ../../../../../main_marking4/knight1_test4.scala .
-  cp ../../../../../main_marking4/knight1_test5.scala .
-  cp ../../../../../main_marking4/knight2_test6.scala .
-  cp ../../../../../main_marking4/knight2_test7.scala .
-  cp ../../../../../main_marking4/knight2_test8.scala .
-  cp ../../../../../main_marking4/knight3_test9.scala .
-  cp ../../../../../main_marking4/knight4_test10.scala .
-  ./knight_test.sh output
-  rm knight_test.sh
-  rm knight1_test1.scala
-  rm knight1_test2.scala
-  rm knight1_test3a.scala 
-  rm knight1_test3b.scala
-  rm knight1_test3c.scala
-  rm knight1_test4.scala
-  rm knight1_test5.scala
-  rm knight2_test6.scala
-  rm knight2_test7.scala
-  rm knight2_test8.scala
-  rm knight3_test9.scala
-  rm knight4_test10.scala
+  cp ../../../../main_marking4/shogun_test.sh .
+  cp ../../../../main_marking4/shogun_test1.scala .
+  cp ../../../../main_marking4/shogun_test2.scala .
+  cp ../../../../main_marking4/shogun_test3.scala .
+  cp ../../../../main_marking4/shogun_test4.scala .
+  cp ../../../../main_marking4/shogun_test5.scala .
+  cp ../../../../main_marking4/shogun_test6.scala .
+  ./shogun_test.sh output
+  rm shogun_test.sh
+  rm shogun_test1.scala
+  rm shogun_test2.scala
+  rm shogun_test3.scala 
+  rm shogun_test4.scala
+  rm shogun_test5.scala
+  rm shogun_test6.scala
   cd ..
   cd ..
 done
--- a/main_marking5/bf_test.sh	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test.sh	Mon Jul 21 16:38:07 2025 +0100
@@ -25,19 +25,20 @@
 # compilation tests
 
 function scala_compile {
-  (JAVA_OPTS="-Xmx1g" scala -Xprint:parser "$1" 2> c$out 1> c$out)
+    (timeout 35s scala-cli compile --server=false -color never -Xprint:parser "$1" 2> c$out 1> c$out)
 }
 
 # functional tests
 
 function scala_assert {
-  (JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+  (timeout 35s scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
 function scala_assert_thirty {
-  (JAVA_OPTS="-Xmx1g" scala -nc -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)  
+  (timeout 35s scala-cli --server=false -i "$1" "$2" -e "urbanmain()" 2> /dev/null 1> /dev/null)
 }
 
+
 # purity test
 function scala_vars {
    (sed 's/immutable/ok/g' c$out > cb$out;
--- a/main_marking5/bf_test1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,4 +1,8 @@
-import M5a._ 
+
+def urbanmain() = {
+  import M5a._ 
 
-assert(load_bff("benchmark.bf").length == 188)
-assert(load_bff("foobar.bf") == "")
+  assert(load_bff("benchmark.bf").length == 188)
+  assert(load_bff("foobar.bf") == "")
+
+}
--- a/main_marking5/bf_test2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,6 +1,10 @@
-import M5a._
+
+def urbanmain() = {
+
+  import M5a._
 
-assert(sread(Map(), 2) == 0)
-assert(sread(Map(2 -> 1), 2) == 1)
-assert(write(Map(), 1, 2) == Map(1 -> 2))
-assert(write(Map(1 -> 0), 1, 2) == Map(1 -> 2))
+  assert(sread(Map(), 2) == 0)
+  assert(sread(Map(2 -> 1), 2) == 1)
+  assert(write(Map(), 1, 2) == Map(1 -> 2))
+  assert(write(Map(1 -> 0), 1, 2) == Map(1 -> 2))
+}
--- a/main_marking5/bf_test3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,19 +1,22 @@
-import M5a._
+
+def urbanmain() = {
+  import M5a._
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
 
-lazy val f = Future {
-assert(jumpRight("[xxxxxx]xxx", 1, 0) == 8)
-assert(jumpRight("[xx[x]x]xxx", 1, 0) == 8)
-assert(jumpRight("[xx[x]x]xxx", 1, 0) == 8)  
-assert(jumpRight("[xx[xxx]xxx", 1, 0) == 11)
-assert(jumpRight("[x[][]x]xxx", 1, 0) == 8)
-assert(jumpLeft("[xxxxxx]xxx", 6, 0) == 1)
-assert(jumpLeft("[xxxxxx]xxx", 7, 0) == -1)
-assert(jumpLeft("[x[][]x]xxx", 6, 0) == 1)
+  lazy val f = Future {
+    assert(jumpRight("[xxxxxx]xxx", 1, 0) == 8)
+    assert(jumpRight("[xx[x]x]xxx", 1, 0) == 8)
+    assert(jumpRight("[xx[x]x]xxx", 1, 0) == 8)  
+    assert(jumpRight("[xx[xxx]xxx", 1, 0) == 11)
+    assert(jumpRight("[x[][]x]xxx", 1, 0) == 8)
+    assert(jumpLeft("[xxxxxx]xxx", 6, 0) == 1)
+    assert(jumpLeft("[xxxxxx]xxx", 7, 0) == -1)
+    assert(jumpLeft("[x[][]x]xxx", 6, 0) == 1)
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
--- a/main_marking5/bf_test4.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test4.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,28 +1,31 @@
-import M5a._
+
+def urbanmain() = {
+
+  import M5a._
 
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
 
-lazy val f = Future {
+  lazy val f = Future {
 
-assert(run("[-]", Map(0 -> 100)) == Map(0 -> 0))
-assert(run("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
-assert(run("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
+    assert(run("[-]", Map(0 -> 100)) == Map(0 -> 0))
+    assert(run("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
+    assert(run("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
 
 
-val hw_urban = """+++++[->++++++++++<]>--<+++[->>++++++++++
+    val hw_urban = """+++++[->++++++++++<]>--<+++[->>++++++++++
                   <<]>>++<<----------[+>.>.<+<]"""
-assert(run(hw_urban) == Map(0 -> 0, 1 -> 58, 2 -> 32))
+    assert(run(hw_urban) == Map(0 -> 0, 1 -> 58, 2 -> 32))
 
-val hw_urban1 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
+    val hw_urban1 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
                    +++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
 
-assert(run(hw_urban1) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
+    assert(run(hw_urban1) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
 
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
-
--- a/main_marking5/bf_test4b.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test4b.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,21 +1,23 @@
-import M5a._
 
+def urbanmain() = {
+
+  import M5a._
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
 
-lazy val f = Future {
-val urban_bench = 
-""">+[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
+  lazy val f = Future {
+    val urban_bench = 
+      """>+[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
    [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
    ++++++++[>++++++++++[>++++++++++[>++++++++++[>+
    +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++."""
 
-assert(run(urban_bench, Map()) == 
-  Map(0 -> 10, 5 -> 0, 1 -> 0, 6 -> 0, 2 -> 0, 7 -> 0, 3 -> 0, 4 -> 0))
+  assert(run(urban_bench, Map()) == Map(0 -> 10, 5 -> 0, 1 -> 0, 6 -> 0, 2 -> 0, 7 -> 0, 3 -> 0, 4 -> 0))
 
-}
+  }
 
-Await.result(f, 32 second)
+  Await.result(f, 32 second)
+}
--- a/main_marking5/bf_test4c.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test4c.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,6 +1,10 @@
-import M5a._
+
+def urbanmain() = {
+  import M5a._
 
-val urban_generate = 
-"""+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]"""
+  val urban_generate = 
+    """+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]"""
 
-assert(generate("ABC".toList) == urban_generate)
+  assert(generate("ABC".toList) == urban_generate)
+
+}
--- a/main_marking5/bf_test5.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test5.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,34 +1,34 @@
-import M5b._
 
+def urbanmain() = {
+  import M5b._
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
 
-lazy val f = Future {
-val hw_urban = """+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]"""
-assert(jtable(hw_urban) == Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6))
+  lazy val f = Future {
+    val hw_urban = """+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]"""
 
-val hw_urban1 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
+    assert(jtable(hw_urban) == Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6))
 
-assert(jtable(hw_urban1) == Map(14 -> 34, 33 -> 15, 45 -> 44, 48 -> 9, 43 -> 46, 8 -> 49))
+    val hw_urban1 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
 
-
+    assert(jtable(hw_urban1) == Map(14 -> 34, 33 -> 15, 45 -> 44, 48 -> 9, 43 -> 46, 8 -> 49))
 
-assert(run2("[-]", Map(0 -> 100)) == Map(0 -> 0))
-assert(run2("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
-assert(run2("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
-val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
+    assert(run2("[-]", Map(0 -> 100)) == Map(0 -> 0))
+    assert(run2("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
+    assert(run2("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
+    val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
                   <<]>>++<<----------[+>.>.<+<]"""
-assert(run2(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
+    assert(run2(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
 
-val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
+    val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
                    +++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
 
-assert(run2(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
+    assert(run2(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
 
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
-
--- a/main_marking5/bf_test6.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test6.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,33 +1,35 @@
-import M5b._
 
-import io.Source
-import scala.util._
+def urbanmain() = {
+  import M5b._
 
-def urban_load_bff(name: String) : String = 
-  Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
+  import io.Source
+  import scala.util._
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  def urban_load_bff(name: String) : String = 
+    Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
 
-lazy val f = Future {
-  assert(optimise(urban_load_bff("benchmark.bf")).length == 181)
-  assert(optimise(urban_load_bff("sierpinski.bf")).length == 110)
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
+
+  lazy val f = Future {
+    assert(optimise(urban_load_bff("benchmark.bf")).length == 181)
+    assert(optimise(urban_load_bff("sierpinski.bf")).length == 110)
 
-  assert(run3("[-]", Map(0 -> 100)) == Map(0 -> 0))
-  assert(run3("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
-  assert(run3("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
-  val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
+    assert(run3("[-]", Map(0 -> 100)) == Map(0 -> 0))
+    assert(run3("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
+    assert(run3("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
+    val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
                   <<]>>++<<----------[+>.>.<+<]"""
-  assert(run3(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
+    assert(run3(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
 
-  val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
+    val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
                    +++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
 
-  assert(run3(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
+    assert(run3(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
 
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
-
--- a/main_marking5/bf_test7.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/bf_test7.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,33 +1,36 @@
-import M5b._
+
+def urbanmain() = {
+
+  import M5b._
 
-import io.Source
-import scala.util._
+  import io.Source
+  import scala.util._
 
-def urban_load_bff(name: String) : String = 
-  Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
-
+  def urban_load_bff(name: String) : String = 
+    Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
 
 
-import scala.concurrent._
-import scala.concurrent.duration._
-import ExecutionContext.Implicits.global
-import scala.language.postfixOps 
+  import scala.concurrent._
+  import scala.concurrent.duration._
+  import ExecutionContext.Implicits.global
+  import scala.language.postfixOps 
 
-lazy val f = Future {
-assert(combine(optimise(urban_load_bff("benchmark.bf"))).length == 134)
-assert(combine(optimise(urban_load_bff("sierpinski.bf"))).length == 122)
+  lazy val f = Future {
+    assert(combine(optimise(urban_load_bff("benchmark.bf"))).length == 134)
+    assert(combine(optimise(urban_load_bff("sierpinski.bf"))).length == 122)
 
-assert(run4("[-]", Map(0 -> 100)) == Map(0 -> 0))
-assert(run4("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
-assert(run4("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
-val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
+    assert(run4("[-]", Map(0 -> 100)) == Map(0 -> 0))
+    assert(run4("[->+<]", Map(0 -> 10)) == Map(0 -> 0, 1 -> 10))
+    assert(run4("[>>+>>+<<<<-]", Map(0 -> 42)) == Map(0 -> 0, 2 -> 42, 4 -> 42))
+    val hw_urban2 = """+++++[->++++++++++<]>--<+++[->>++++++++++
                   <<]>>++<<----------[+>.>.<+<]"""
-assert(run4(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
+    assert(run4(hw_urban2) == Map(0 -> 0, 1 -> 58, 2 -> 32))
 
-val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
+    val hw_urban3 = """++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.
                    +++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."""
 
-assert(run4(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
+    assert(run4(hw_urban3) == Map(0 -> 0, 5 -> 33, 1 -> 0, 6 -> 10, 2 -> 72, 3 -> 100, 4 -> 87))
+  }
+
+  Await.result(f, 32 second)
 }
-
-Await.result(f, 32 second)
--- a/main_marking5/mk_main5	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_marking5/mk_main5	Mon Jul 21 16:38:07 2025 +0100
@@ -10,17 +10,17 @@
   cd $sd
   echo $sd
   touch .
-  cp ../../../../../main_marking5/bf_test.sh .
-  cp ../../../../../main_marking5/bf_test1.scala .
-  cp ../../../../../main_marking5/bf_test2.scala .
-  cp ../../../../../main_marking5/bf_test3.scala .
-  cp ../../../../../main_marking5/bf_test4.scala .
-  cp ../../../../../main_marking5/bf_test4b.scala .
-  cp ../../../../../main_marking5/bf_test4c.scala .
-  cp ../../../../../main_marking5/bf_test5.scala .
-  cp ../../../../../main_marking5/bf_test6.scala .
-  cp ../../../../../main_marking5/bf_test7.scala .
-  cp ../../../../../main_marking5/*.bf .
+  cp ../../../../main_marking5/bf_test.sh .
+  cp ../../../../main_marking5/bf_test1.scala .
+  cp ../../../../main_marking5/bf_test2.scala .
+  cp ../../../../main_marking5/bf_test3.scala .
+  cp ../../../../main_marking5/bf_test4.scala .
+  cp ../../../../main_marking5/bf_test4b.scala .
+  cp ../../../../main_marking5/bf_test4c.scala .
+  cp ../../../../main_marking5/bf_test5.scala .
+  cp ../../../../main_marking5/bf_test6.scala .
+  cp ../../../../main_marking5/bf_test7.scala .
+  cp ../../../../main_marking5/*.bf .
   ./bf_test.sh output
   rm bf_test.sh
   rm bf_test1.scala
--- a/main_solution3/re.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_solution3/re.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -142,6 +142,34 @@
 }
 
 
+def draw_rs(rs: List[Rexp], prefix: String) : String = {
+  val rsi = rs.iterator
+  rsi.map(r => draw_r(r, prefix, rsi.hasNext)).mkString
+}
+
+def draw_r(e: Rexp, prefix: String, more: Boolean) : String = {
+  val full_prefix = s"$prefix${if more then "├" else "└"}"
+  val childPrefix = s"$prefix${if more then "│" else " "} "
+  s"\n${full_prefix}" ++
+  (e match {
+    case ZERO => s"0"
+    case ONE => s"1"
+    case CHAR(c) => s"$c"
+    case ALTs(rs) => s"ALTs" ++ draw_rs(rs, childPrefix)
+    case SEQs(rs) => s"SEQs" ++ draw_rs(rs, childPrefix)
+    case STAR(r) => s"STAR" ++ draw_r(r, childPrefix, false)
+  })
+}
+
+def draw(e: Rexp) = 
+    draw_r(e, "", false)
+
+
+val re = STAR(STAR("aa" | "aaa"))
+
+for (n <- 1 to 100) {
+  println(s"$n: ${size(ders(("a" * n).toList, re))}")
+}
 
 // some testing data
 /*
--- a/main_solution5/bfc.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/main_solution5/bfc.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,5 +1,6 @@
-// Part 2 about a "Compiler" for the Brainf*** language
-//======================================================
+// Main Part 5 about a "Compiler" for the Brainf*** language
+//============================================================
+
 
 object M5b {
 
@@ -10,306 +11,324 @@
 // templates below.
 
 
-def time_needed[T](n: Int, code: => T) = {
+// DEBUGGING INFORMATION FOR COMPILERS!!!
+//
+// Compiler, even real ones, are fiendishly difficult to get
+// to produce correct code. One way to debug them is to run
+// example programs ``unoptimised''; and then optimised. Does
+// the optimised version still produce the same result?
+
+
+// for timing purposes
+def time_needed[T](n: Int, code: => T) ={
   val start = System.nanoTime()
   for (i <- 0 until n) code
   val end = System.nanoTime()
   (end - start)/(n * 1.0e9)
 }
 
+
 type Mem = Map[Int, Int]
 
-
 import io.Source
 import scala.util._
 
-def load_bff(name: String) : String = 
-  Try(Source.fromFile(name)("ISO-8859-1").mkString).getOrElse("")
-
-def sread(mem: Mem, mp: Int) : Int = 
-  mem.getOrElse(mp, 0)
-
-def write(mem: Mem, mp: Int, v: Int) : Mem =
-  mem.updated(mp, v)
+// ADD YOUR CODE BELOW
+//======================
 
-def jumpRight(prog: String, pc: Int, level: Int) : Int = {
-  if (prog.length <= pc) pc 
-  else (prog(pc), level) match {
-    case (']', 0) => pc + 1
-    case (']', l) => jumpRight(prog, pc + 1, l - 1)
-    case ('[', l) => jumpRight(prog, pc + 1, l + 1)
-    case (_, l) => jumpRight(prog, pc + 1, l)
-  }
-}
-
-def jumpLeft(prog: String, pc: Int, level: Int) : Int = {
-  if (pc < 0) pc 
-  else (prog(pc), level) match {
-    case ('[', 0) => pc + 1
-    case ('[', l) => jumpLeft(prog, pc - 1, l - 1)
-    case (']', l) => jumpLeft(prog, pc - 1, l + 1)
-    case (_, l) => jumpLeft(prog, pc - 1, l)
-  }
-}
+def compute(prog: String, pc: Int, mp: Int, mem: Mem) : Mem = 
 
-def compute(prog: String, pc: Int, mp: Int, mem: Mem) : Mem = {
-  if (0 <= pc && pc < prog.length) { 
-    val (new_pc, new_mp, new_mem) = prog(pc) match {
-      case '>' => (pc + 1, mp + 1, mem)
-      case '<' => (pc + 1, mp - 1, mem)
-      case '+' => (pc + 1, mp, write(mem, mp, sread(mem, mp) + 1))
-      case '-' => (pc + 1, mp, write(mem, mp, sread(mem, mp) - 1))
-      case '.' => { print(sread(mem, mp).toChar); (pc + 1, mp, mem) }
-      case '['  => if (sread(mem, mp) == 0) (jumpRight(prog, pc + 1, 0), mp, mem) else (pc + 1, mp, mem) 
-      case ']'  => if (sread(mem, mp) != 0) (jumpLeft(prog, pc - 1, 0), mp, mem) else (pc + 1, mp, mem) 
-      case _ => (pc + 1, mp, mem)
-    }		     
-    compute(prog, new_pc, new_mp, new_mem)	
-  }
-  else mem
-}
+    if(pc<0 || pc>= prog.length())
+        mem
+    else
+        prog.charAt(pc) match
+            case '>' => compute(prog, pc+1, mp+1, mem)
 
-def run(prog: String, m: Mem = Map()) = compute(prog, 0, 0, m)
-
-
-// The baseline to what we can compare our "compiler"
-// implemented below. It should require something like 
-// 60 seconds for the calculation on my laptop
-//
-//time_needed(1, run(load_bff("benchmark.bf")))
-
+            case '<' => compute(prog, pc+1, mp-1, mem)
 
+            case '+' => compute(prog, pc+1, mp, write(mem, mp, sread(mem, mp)+1))
 
-// DEBUGGING INFORMATION!!!
-//
-// Compiler, even real ones, are fiedishly difficult to get
-// to prduce correct code. The point is that for example for
-// the sierpinski program, they need to still generate code
-// that displays such a triangle. If yes, then one usually
-// can take comfort that all is well. If not, then something
-// went wrong during the optimisations.
+            case '-' => compute(prog, pc+1, mp, write(mem, mp, sread(mem, mp)-1))
 
-
-
-// (5) Write a function jtable that precomputes the "jump
-//     table" for a bf-program. This function takes a bf-program 
-//     as an argument and Returns a Map[Int, Int]. The 
-//     purpose of this map is to record the information
-//     that given on the position pc is a '[' or a ']',
-//     then to which pc-position do we need to jump next?
-// 
-//     For example for the program
-//    
-//       "+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]"
-//
-//     we obtain the map
-//
-//       Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6)
-//  
-//     This states that for the '[' on position 5, we need to
-//     jump to position 20, which is just after the corresponding ']'.
-//     Similarly, for the ']' on position 19, we need to jump to
-//     position 6, which is just after the '[' on position 5, and so
-//     on. The idea is to not calculate this information each time
-//     we hit a bracket, but just look up this information in the 
-//     jtable. You can use the jumpLeft and jumpRight functions
-//     from Part 1 for calculating the jtable.
-//
-//     Then adapt the compute and run functions from Part 1 in order 
-//     to take advantage of the information stored in the jtable. 
-//     This means whenever jumpLeft and jumpRight was called previously,
-//     you should look up the jump address in the jtable.
- 
+            case '.' => 
+                compute(prog, pc+1, mp, mem)
 
-def jtable(pg: String) : Map[Int, Int] = 
-    (0 until pg.length).collect { pc => pg(pc) match {
-      case '[' => (pc -> jumpRight(pg, pc + 1, 0))
-      case ']' => (pc -> jumpLeft(pg, pc - 1, 0))
-    }}.toMap
-
-
-// testcase
-// jtable("""+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]""")
-// =>  Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6)
-
+            case '[' => 
+                if(sread(mem, mp) == 0) 
+                    compute(prog, jumpRight(prog, pc+1, 0), mp, mem)
+                else 
+                    compute(prog, pc+1, mp, mem) 
 
-def compute2(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = {
-  if (0 <= pc && pc < pg.length) { 
-    val (new_pc, new_mp, new_mem) = pg(pc) match {
-      case '>' => (pc + 1, mp + 1, mem)
-      case '<' => (pc + 1, mp - 1, mem)
-      case '+' => (pc + 1, mp, write(mem, mp, sread(mem, mp) + 1))
-      case '-' => (pc + 1, mp, write(mem, mp, sread(mem, mp) - 1))
-      case '.' => { print(sread(mem, mp).toChar); (pc + 1, mp, mem) }
-      case '['  => if (sread(mem, mp) == 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case ']'  => if (sread(mem, mp) != 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case _ => (pc + 1, mp, mem)
-    }		     
-    compute2(pg, tb, new_pc, new_mp, new_mem)	
-  }
-  else mem
-}
+            case ']' => 
+                if(sread(mem, mp) == 0) 
+                    compute(prog, pc+1, mp, mem)
+                else 
+                    compute(prog, jumpLeft(prog, pc-1, 0), mp, mem) 
 
-
-def run2(pg: String, m: Mem = Map()) = 
-  compute2(pg, jtable(pg), 0, 0, m)
-
-//time_needed(1, run2(load_bff("benchmark.bf")))
+            case _ => compute(prog, pc + 1, mp, mem)
 
 
 
-// (6) Write a function optimise which deletes "dead code" (everything
-// that is not a bf-command) and also replaces substrings of the form
-// [-] by a new command 0. The idea is that the loop [-] just resets the
-// memory at the current location to 0. In the compute3 and run3 functions
-// below you implement this command by writing the number 0 to mem(mp), 
-// that is write(mem, mp, 0). 
-//
-// The easiest way to modify a string in this way is to use the regular
-// expression """[^<>+-.\[\]""", which recognises everything that is 
-// not a bf-command and replace it by the empty string. Similarly the
-// regular expression """\[-\]""" finds all occurences of [-] and 
-// by using the Scala method .replaceAll you can repplace it with the 
-// string "0" standing for the new bf-command.
+def run(prog: String, m: Mem = Map()) = 
+    compute(prog, 0, 0, m)
+
+
+// (6) 
+def jumpRight(prog: String, pc: Int, level: Int) : Int = 
+    if (pc<0 || pc>= prog.length() )
+        pc
+    else
+        prog(pc) match
+            case '[' => jumpRight(prog, pc+1, level+1)
+
+            case ']' => 
+                {
+                    if (level == 0)
+                        pc+1           
+                    else 
+                        jumpRight(prog, pc+1, level-1)
+
+                }
+
+            case _ => jumpRight(prog, pc+1, level)
+
 
-def optimise(s: String) : String = {
-  s.replaceAll("""[^<>+-.\[\]]""","")
-   .replaceAll("""\[-\]""", "0")
-}
+def jumpLeft(prog: String, pc: Int, level: Int) : Int = 
+    if (pc<0 || pc>= prog.length() )
+          pc
+    else
+        prog(pc) match
+            case '[' => 
+                {
+                    if (level == 0)
+                        pc+1 
+                    else 
+                        jumpLeft(prog, pc-1, level-1)
+
+                }
+
+            case ']' => jumpLeft(prog, pc-1, level+1)
+
+            case _ => jumpLeft(prog, pc-1, level)
+
+
+def jtable(pg: String) : Map[Int, Int] = 
+    val b1 = (0 until pg.length)
+      .filter(n => pg.substring(n, n+1) == "[")
+      .map(n => n -> jumpRight(pg, n + 1, 0)).toMap
+
+    val b2 = (0 until pg.length)
+       .filter(n => pg.substring(n, n+1) == "]")
+       .map(n => n -> jumpLeft(pg, n-1, 0)).toMap
+
+    b1++b2
 
 
-def compute3(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = {
-  if (0 <= pc && pc < pg.length) { 
-    val (new_pc, new_mp, new_mem) = pg(pc) match {
-      case '0' => (pc + 1, mp, write(mem, mp, 0))
-      case '>' => (pc + 1, mp + 1, mem)
-      case '<' => (pc + 1, mp - 1, mem)
-      case '+' => (pc + 1, mp, write(mem, mp, sread(mem, mp) + 1))
-      case '-' => (pc + 1, mp, write(mem, mp, sread(mem, mp) - 1))
-      case '.' => { print(sread(mem, mp).toChar); (pc + 1, mp, mem) }
-      case '['  => if (sread(mem, mp) == 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case ']'  => if (sread(mem, mp) != 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case _ => (pc + 1, mp, mem)
-    }		     
-    compute3(pg, tb, new_pc, new_mp, new_mem)	
-  }
-  else mem
-}
+// testcase
+//
+// jtable("""+++++[->++++++++++<]>--<+++[->>++++++++++<<]>>++<<----------[+>.>.<+<]""")
+// =>  Map(69 -> 61, 5 -> 20, 60 -> 70, 27 -> 44, 43 -> 28, 19 -> 6)
+
+def load_bff(name: String) : String =  
+    try 
+       Source.fromFile(name).mkString
+    catch
+        case e: Exception => ""
+
+def sread(mem: Mem, mp: Int) : Int = 
+    mem.getOrElse(mp,0)
+
+def write(mem: Mem, mp: Int, v: Int) : Mem = 
+    mem + (mp -> v)
+
+def compute2(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = 
+
+    if(pc<0 || pc>= pg.length())
+        mem
+    else
+        pg.charAt(pc) match
+            case '>' => compute2(pg,tb, pc+1, mp+1, mem)
 
-def run3(pg: String, m: Mem = Map()) = { 
-  val pg_opt = optimise(pg)
-  compute3(pg_opt, jtable(pg_opt), 0, 0, m)
-}
+            case '<' => compute2(pg,tb, pc+1, mp-1, mem)
+
+            case '+' => compute2(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)+1))
+
+            case '-' => compute2(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)-1))
+
+            case '.' => 
+                compute2(pg,tb, pc+1, mp, mem)
 
+            case '[' => 
+                if(sread(mem, mp) == 0) 
+                    compute2(pg, tb, tb(pc), mp, mem)
+                else 
+                    compute2(pg, tb, pc+1, mp, mem)
+
+            case ']' => 
+                if(sread(mem, mp) == 0) 
+                    compute2(pg, tb, pc+1, mp, mem)
+                else 
+                    compute2(pg, tb, tb(pc), mp, mem)  
+
+            case _ => compute2(pg,tb,pc + 1, mp, mem)
+
+def run2(pg: String, m: Mem = Map()) = 
+    compute2(pg, jtable(pg), 0, 0, m)
 
 // testcases
-
-//println(optimise(load_bff("collatz.bf")))
-//optimise(load_bff("benchmark.bf"))          // should have inserted 0's
-//optimise(load_bff("mandelbrot.bf")).length  // => 11203
- 
-//time_needed(1, run3(load_bff("benchmark.bf")))
-//time_needed(1, run3(load_bff("mandelbrot.bf")))
+// time_needed(1, run2(load_bff("benchmark.bf")))
+// time_needed(1, run2(load_bff("sierpinski.bf")))
 
 
 
-// (7)  Write a function combine which replaces sequences
-// of repated increment and decrement commands by appropriate
-// two-character commands. For example for sequences of +
-//
-//              orig bf-cmds  | replacement
-//            ------------------------------
-//              +             | +A 
-//              ++            | +B
-//              +++           | +C
-//                            |
-//              ...           |
-//                            | 
-//              +++....+++    | +Z
-//                (where length = 26)
-//
-//  Similar for the bf-command -, > and <. All other commands should
-//  be unaffected by this change.
-//
-//  Adapt the compute4 and run4 functions such that they can deal
-//  appropriately with such two-character commands.
+// (7) 
 
-def splice(cs: List[Char], acc: List[(Char, Int)]) : List[(Char, Int)] = (cs, acc) match {
-  case (Nil, acc) => acc  
-  case ('[' :: cs, acc) => splice(cs, ('[', 1) :: acc)
-  case (']' :: cs, acc) => splice(cs, (']', 1) :: acc)
-  case ('.' :: cs, acc) => splice(cs, ('.', 1) :: acc)
-  case ('0' :: cs, acc) => splice(cs, ('0', 1) :: acc)
-  case (c :: cs, Nil) => splice(cs, List((c, 1)))
-  case (c :: cs, (d, n) :: acc) => 
-    if (c == d && n < 26) splice(cs, (c, n + 1) :: acc)
-    else splice(cs, (c, 1) :: (d, n) :: acc)
-}
+def optimise(s: String) : String = 
+    val notCommand = """[^<>+\-.\[\]]""".r
+    val occurrence = """\[-\]""".r
 
-def spl(s: String) = splice(s.toList, Nil).reverse
-
-//spl(load_bff("benchmark.bf"))
-
-def combine(s: String) : String = {
-  (for ((c, n) <- spl(s)) yield c match {
-    case '>' => List('>', (n + '@').toChar)
-    case '<' => List('<', (n + '@').toChar)
-    case '+' => List('+', (n + '@').toChar)
-    case '-' => List('-', (n + '@').toChar)
-    case _ => List(c)
-  }).flatten.mkString
-}
+    val deleted = notCommand.replaceAllIn(s, "")
+    occurrence.replaceAllIn(deleted, "0")
 
 
-//combine(load_bff("benchmark.bf"))
+def compute3(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = 
+
+    if(pc<0 || pc>= pg.length())
+        mem
+    else
+        pg.charAt(pc) match
+            case '>' => compute3(pg,tb, pc+1, mp+1, mem)
+
+            case '<' => compute3(pg,tb, pc+1, mp-1, mem)
+
+            case '+' => compute3(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)+1))
+
+            case '-' => compute3(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)-1))
+
+            case '.' => 
+                compute3(pg,tb, pc+1, mp, mem)
 
-def compute4(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = {
-  if (0 <= pc && pc < pg.length) { 
-    val (new_pc, new_mp, new_mem) = pg(pc) match {
-      case '0' => (pc + 1, mp, write(mem, mp, 0))
-      case '>' => (pc + 2, mp + (pg(pc + 1) - '@'), mem)
-      case '<' => (pc + 2, mp - (pg(pc + 1) - '@'), mem)
-      case '+' => (pc + 2, mp, write(mem, mp, sread(mem, mp) + (pg(pc + 1) - '@')))
-      case '-' => (pc + 2, mp, write(mem, mp, sread(mem, mp) - (pg(pc + 1) - '@')))
-      case '.' => { print(sread(mem, mp).toChar); (pc + 1, mp, mem) }
-      case '['  => if (sread(mem, mp) == 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case ']'  => if (sread(mem, mp) != 0) (tb(pc), mp, mem) else (pc + 1, mp, mem) 
-      case _ => (pc + 1, mp, mem)
-    }		     
-    compute4(pg, tb, new_pc, new_mp, new_mem)	
-  }
-  else mem
-}
+            case '[' => 
+                if(sread(mem, mp) == 0) 
+                    compute3(pg, tb, tb(pc), mp, mem)
+                else 
+                    compute3(pg, tb, pc+1, mp, mem)
 
-def run4(pg: String, m: Mem = Map()) = { 
-  val pg_opt = combine(optimise(pg))
-  compute4(pg_opt, jtable(pg_opt), 0, 0, m)
-}
+            case ']' => 
+                if(sread(mem, mp) == 0) 
+                    compute3(pg, tb, pc+1, mp, mem)
+                else 
+                    compute3(pg, tb, tb(pc), mp, mem)  
+
+            case _ => compute3(pg,tb,pc + 1, mp, mem)
+
+def run3(pg: String, m: Mem = Map()) = 
+    val opt = optimise(pg)
+    compute3(opt, jtable(opt), 0, 0, m)
+
+
 
 // testcases
-//println(combine(optimise(load_bff("mandelbrot.bf").drop(123))))
-
-//combine(optimise(load_bff("benchmark.bf"))) // => """>A+B[<A+M>A-A]<A[[....."""
-
-//time_needed(1, run4(load_bff("benchmark.bf")))
-
-//time_needed(1, run(load_bff("sierpinski.bf"))) 
-//time_needed(1, run4(load_bff("sierpinski.bf"))) 
-
-//println(time_needed(1, run4(load_bff("mandelbrot.bf"))))
+//
+// optimise(load_bff("benchmark.bf"))          // should have inserted 0's
+// optimise(load_bff("mandelbrot.bf")).length  // => 11205
+// 
+// time_needed(1, run3(load_bff("benchmark.bf")))
 
 
 
+// (8)  
+// consider if the char does not exist\\
+
+def counterHelper(chars: List[Char], consec: Int, charToCount: Char): Int =
+    chars match 
+          case head :: tail if ((head == charToCount && head == tail.headOption.getOrElse(' ')) )=>
+            counterHelper(tail, consec + 1, charToCount)
+
+          case head :: tail if (head == charToCount && head != tail.headOption.getOrElse(' '))=>
+            consec+1
+
+          case head :: tail if (head != charToCount && head != tail.headOption.getOrElse(' '))=>
+            consec
+   
+
+def counter(input: String, charToCount: Char): Int = 
+    counterHelper(input.toList, 0, charToCount)
+
+def handleCharacter(orgin: String, newstr: String, sindex: Int, letterMap: Map[Int, Char], charToCount: Char): String = 
+    val num = counter(orgin.substring(sindex), charToCount)
+    val lett = letterMap.getOrElse(num, "")
+    combineHelper(orgin, newstr + charToCount + lett, sindex + num, letterMap)
+
+def combineHelper(orgin: String, newstr: String, sindex: Int, letterMap: Map[Int, Char] ): String = 
+    if (sindex >= orgin.length())
+      newstr
+    else 
+      val result = 
+        orgin.charAt(sindex) match 
+            case '>' => handleCharacter(orgin, newstr, sindex, letterMap, '>')
+            case '<' => handleCharacter(orgin, newstr, sindex, letterMap, '<')
+            case '+' => handleCharacter(orgin, newstr, sindex, letterMap, '+')
+            case '-' => handleCharacter(orgin, newstr, sindex, letterMap, '-')
+            case _ => combineHelper(orgin, newstr + orgin.charAt(sindex), sindex + 1, letterMap)
+
+      result
+
+def combine(s: String) : String = 
+    val letterMap = (1 to 26).zip('A' to 'Z').toMap
+    combineHelper(s,"",0, letterMap)
+
+// testcase
+// combine(load_bff("benchmark.bf"))
+
+def compute4(pg: String, tb: Map[Int, Int], pc: Int, mp: Int, mem: Mem) : Mem = 
+
+    if(pc<0 || pc>= pg.length())
+            mem
+    else
+        pg.charAt(pc) match
+            case '>' => compute4(pg,tb, pc+1, mp+1, mem)
+
+            case '<' => compute4(pg,tb, pc+1, mp-1, mem)
+
+            case '+' => compute4(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)+1))
+
+            case '-' => compute4(pg,tb, pc+1, mp, write(mem, mp, sread(mem, mp)-1))
+
+            case '.' => 
+                compute4(pg,tb, pc+1, mp, mem)
+
+            case '[' => 
+                if(sread(mem, mp) == 0) 
+                    compute4(pg, tb, tb(pc), mp, mem)
+                else 
+                    compute4(pg, tb, pc+1, mp, mem)
+
+            case ']' => 
+                if(sread(mem, mp) == 0) 
+                    compute4(pg, tb, pc+1, mp, mem)
+                else 
+                    compute4(pg, tb, tb(pc), mp, mem)  
+
+            case _ => compute4(pg,tb,pc + 1, mp, mem)
+
+// should call first optimise and then combine on the input string
+//
+def run4(pg: String, m: Mem = Map()) = 
+    val opt = optimise(pg)
+    val com= combine(opt)
+    compute4(com, jtable(com), 0, 0, m)
+    
+ 
+// testcases
+// combine(optimise(load_bff("benchmark.bf"))) // => """>A+B[<A+M>A-A]<A[[....."""
+
+// testcases (they should now run much faster)
+// time_needed(1, run4(load_bff("benchmark.bf")))
+// time_needed(1, run4(load_bff("sierpinski.bf"))) 
+// time_needed(1, run4(load_bff("mandelbrot.bf")))
 
 
 }
 
 
-@main def main() = {
-  import M5b._
-  println(time_needed(1, run(load_bff("mandelbrot.bf"))))
-  println(time_needed(1, run2(load_bff("mandelbrot.bf"))))
-  println(time_needed(1, run3(load_bff("mandelbrot.bf"))))
-  println(time_needed(1, run4(load_bff("mandelbrot.bf"))))
-}
-
--- a/progs/lecture1.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/lecture1.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,6 +1,9 @@
 // Scala Lecture 1
 //=================
 
+println("Hello World")
+
+
 // - List, Sets, Ints, Strings, ... 
 // - Value assignments (val vs var)
 // - How to define functions? (What is returned?)
@@ -11,6 +14,7 @@
 //
 
 
+
 // Value assignments
 // (their names should be lower case)
 //====================================
@@ -19,13 +23,11 @@
 val x = 42
 val y = 3 + 4 
 val z = x / y
-val x = 0
+val x = 17 
 println(z)
 
 
 // (you cannot reassign values: z = 9 will give an error)
-var z = 9
-z = 10
 
 
 
@@ -33,12 +35,21 @@
 // Collections
 //=============
 
-List(1,2,3,1)
-Set(1,2,3,1)
+val ls = List("1","2","3","1")
+
+val ls2 = ls ::: ls
+
+val s1 = Set(1,2,3,1)
 
 // picking an element in a list
 val lst = List(1, 2, 3, 1)
 
+val lst = List(1, 2, 3, 1)
+
+val lst1 = 0 :: lst
+
+println(lst)
+println(lst1)
 
 lst(0)
 lst(2)
@@ -55,7 +66,7 @@
 List(1, 2, 3) ::: List(4, 5, 6)
 
 // also
-List(1, 2, 3) ++ List(3, 6, 5)
+List(1, 2, 3) ::: List(3, 6, 5)
 Set(1, 2, 3) ++ Set(3, 6, 5)
 
 // ranges
@@ -172,7 +183,7 @@
 // you can make the type of a value explicit
 val name = "bob"
 
-val name : String = "bob"
+val name : Int = "bob"
 
 // type errors
 math.sqrt("64")
@@ -202,20 +213,6 @@
 // Function Definitions
 //======================
 
-
-def incr(x: Int) : Int = x + 1
-def double(x: Int) : Int = x + x
-def square(x: Int) : Int = x * x
-
-def str(x: Int) : String = x.toString
-
-
-incr(3)
-double(4)
-square(6)
-str(3)
-
-
 // The general scheme for a function: you have to give a 
 // type to each argument and a return type of the function
 //
@@ -223,27 +220,37 @@
 //     ....
 //  }
 
-
-// > LENGTH OF LIST EXAMPLE
-def len(xs: List[Int], acc: Int) : Int = {
-   if (xs == Nil) acc
-   else foo(xs.tail, acc + 1)
+def average(ls: List[Int]) : Int = {
+  println(s"$ls")
+  val s = ls.sum
+  val l = ls.length
+  if (l == 0) 0 
+  else s / l
 }
 
-def len(xs: List[Int]) : Int = foo(xs, 0)
+average(List(1,2,3,4,56))
+def incr(x: Int) : Int = x + 1
+def double(x: Int) : Int = x + x
+def square(x: Int) : Int = x * x
+
+def str(x: Int) : String = x.toString
+
+incr(3)
+double(4)
+square(6)
+str(3)
+
+
+
+
+def len(xs: List[Int]) : Int = {
+   if (xs == Nil) 0
+   else 1 + len(xs.tail)
+}
 
 len(List(1,2,3,4,1))
 
 
-def len(xs: List[Int]) : Int = {
-    if (xs == Nil) 0
-    else (1 + len(xs.tail))
-}    
-
-
-
-len(List(1,2,3,4,1))
-
 
 
 def len(xs: List[Int]) : Int = xs match {
@@ -322,9 +329,12 @@
 // For-Comprehensions (not For-Loops)
 //====================================
 
-val lst = (1 to 10).toList
-for (n <- lst) yield n * n 
+val lst = (1 to 10).toSet
+val result = for (n <- lst) yield {
+  n * n 
+}
 
+println(result)
 
 for (n <- lst) yield { 
   square(n) + double(n)
@@ -341,7 +351,7 @@
        m <- (1 to 10).toList) yield n * m
 
 println(mult_table.mkString(","))
-mult_table.sliding(10,10).toList
+mult_table.sliding(10,10).toList.mkString(",")
 
 
 .mkString("\n")
@@ -361,7 +371,6 @@
 val xs = for (n <- (1 to 3).toList; 
      m <- (1 to 3).toList) yield (n,m)
 
-xs.filter{case (m, n) => (n + m) % 2 == 0}    
 
 for (n <- (1 to 3).toList; 
      m <- (1 to 3).toList;
@@ -397,6 +406,7 @@
 
 val foo = for (n <- (1 to 10).toList) yield n * n
 
+println(for (n <- (1 to 10).toList)  print(n))
 
 // BTW: a roundabout way of printing out a list, say
 val lst = ('a' to 'm').toList
@@ -422,7 +432,12 @@
 def get_length(s: String) : (String, Int) = 
   (s, s.length) 
 
+def len(s: String) : Int = s.length
+
+
 val lst = List("zero", "one", "two", "three", "four", "ten")
+lst.sorted
+lst.sortBy(len(_))
 val strs = for (s <- lst) yield get_length(s)
 
 strs.sortBy(_._2)
@@ -476,7 +491,7 @@
 // But what the heck....lets try to count to 1 Mio in parallel
 // 
 // requires
-// scala-cli --extra-jars scala- parallel-collections_3-1.0.4.jar
+// scala --extra-jars scala- parallel-collections_3-1.0.4.jar
 
 import scala.collection.parallel.CollectionConverters._
 
@@ -562,21 +577,18 @@
 // Further Information
 //=====================
 
-// We are going to use Scala 3 and the scala-cli repl (easier to use)
-//
-//  https://scala-cli.virtuslab.org
-//
-//
-// The Scala homepage and general information is at
+// We are going to use Scala 3. The Scala homepage 
+// and general information is at
 //
 //  http://www.scala-lang.org
 //	http://docs.scala-lang.org
 //
 //
-// It should be fairly easy to install the scala-cli binary and
+// It should be fairly easy to install the scala binary and
 // run Scala on the commandline. People also use Scala with 
-// Vim and Jedit. I currently settled on Codium
+// Vim and Jedit. I currently settled on Codium / VSCode
 //
+//   https://vscodium.com
 //   https://code.visualstudio.com
 //
 // There are also plugins for Eclipse and IntelliJ - YMMV.
@@ -584,7 +596,6 @@
 // running Scala applications (but do not blame me if you lose 
 // all what you typed in):
 //
-//   https://scalafiddle.io 
 //   https://scastie.scala-lang.org
 //
 //
--- a/progs/lecture2.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/lecture2.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -30,14 +30,23 @@
 // Option[Boolean]: None, Some(true), Some(false)
 // Option[...]: None, Some(_)
 
+def div(x: Int, y: Int) : Int = 
+  x / y
+
 def safe_div(x: Int, y: Int) : Option[Int] = 
   if (y == 0) None else Some(x / y)
 
-safe_div(10 + 5, 0)  
+def foo_calculation(x: Int) = 
+  if (safe_div(x, x) == None) 24 else safe_div(x, x).get
+
+foo_calculation(3)
+foo_calculation(0)
+
+safe_div(10 + 5, 3)  
 
 List(1,2,3,4,5,6).indexOf(7)
-List[Int]().min
-List[Int](3,4,5).minOption
+List[Int](3,4,5).min
+List[Int]().minOption
 
 
 
@@ -49,7 +58,7 @@
 import scala.util._      // Try,...
 import io.Source         // fromURL
 
-val my_url = "https://nms.kcl.ac.uk/christian.urban2/"
+val my_url = "https://nms.kcl.ac.uk/christian.urban/"
 
 Source.fromURL(my_url)("ISO-8859-1").mkString
 Source.fromURL(my_url)("ISO-8859-1").getLines().toList
@@ -94,6 +103,11 @@
 
 val lst = List(None, Some(1), Some(2), None, Some(3))
 
+for (x <- lst) yield {
+  if (x == None) None
+  else Some(x.get + 1)
+}
+
 lst.flatten
 
 Some(1).get
@@ -173,10 +187,13 @@
 def inc(x: Int) : Int = x + 1
 val lst = (1 to 10).toList
 
-lst.filter(_ % 2 == 0)
+lst.filter(odd)
+lst.exists(even)
 lst.count(odd)
-lst.find(even)
-lst.exists(even)
+
+lst.filter(_ % 2 == 0)
+
+
 
 lst.find(_ < 4)
 lst.filter(_ < 4) 
@@ -191,8 +208,8 @@
 lst.filter(_ % 2 == 0)
 
 
-lst.sortWith((x, y) => x < y)
-lst.sortWith(_ > _)
+lst.sortWith((x, y) => x > y)
+lst.sortWith(_ < _)
 
 // but this only works when the arguments are clear, but 
 // not with multiple occurences
@@ -211,7 +228,7 @@
 ps.sortBy(x => x._1)
 ps.sortBy(_._2)
 
-ps.maxBy(_._1)
+ps.maxBy(x => x._2)
 ps.maxBy(_._2)
 
 
@@ -224,6 +241,10 @@
 val lst = (1 to 10).toList
 
 lst.map(square)
+lst.map(n => square(n))
+
+for (n <- lst) yield square(n)
+
 lst.map(x => (double(x), square(x)))
 
 // works also for strings
--- a/progs/lecture3.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/lecture3.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -10,6 +10,36 @@
 // - string interpolations
 // - Pattern-Matching
 
+def fact(n: BigInt) : BigInt = {
+  if (n == 0) 1 
+  else n * fact(n - 1)
+}
+
+def fib(n: BigInt) : BigInt = {
+  if (n == 0) 1
+  else if (n == 1) 1 
+  else fib(n - 1) + fib(n - 2)
+}
+
+
+
+
+
+def inc(n: Int) : Int = n + 1
+
+for (n <- List(1,2,3,4)) yield inc(n)
+
+List().map(inc)
+
+
+
+my_map(inc, List(1,2,3,4))
+
+
+
+
+
+
 // A Recursive Web Crawler / Email Harvester
 //===========================================
 //
@@ -79,6 +109,12 @@
 // EFFICIENT AND FAST, just explaining exhaustive
 // depth-first search
 
+//> using dep org.scala-lang.modules::scala-parallel-collections:1.0.4
+import scala.collection.parallel.CollectionConverters.*
+
+
+val s1 = "s\n"
+val s2 = """s\n"""
 
 val game0 = """.14.6.3..
               |62...4..9
@@ -286,6 +322,14 @@
 //       case patternN => expressionN
 //    }
 
+def my_map(f: Int => Int, xs: List[Int]) : List[Int] =  
+  xs match {
+    case Nil => Nil 
+    case hd::tl => f(hd) ::  my_map(f, tl)
+  }
+
+my_map(x => x * x, List(1,2,3,4))
+
 
 // recall
 def len(xs: List[Int]) : Int = {
@@ -350,6 +394,8 @@
 // more interesting patterns for lists - calculate the deltas between 
 // elements
 
+List(4,3,2,1) -> List(1,1,.. )
+
 def delta(xs: List[Int]) : List[Int] = xs match {
   case Nil => Nil
   case x::Nil => x::Nil
@@ -386,6 +432,13 @@
 val lf = Leaf(20)
 val tr = Node("foo", Leaf(10), Leaf(23))
 
+def sizet(t: Tree) : Int = t match {
+  case Leaf(_) => 1
+  case Node(_, left , right) => 1 + sizet(left) + sizet(right)
+}
+
+sizet(tr)
+
 val lst : List[Tree] = List(lf, tr)
 
 
--- a/progs/lecture4.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/lecture4.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,9 +1,84 @@
 // Scala Lecture 4
 //=================
 
-// pattern-matching
+//===================
+// polymorphic types
+// (algebraic) datatypes and pattern-matching
+// extensions and implicits
 // tail-recursion
-// polymorphic types
+
+
+
+// You do not want to write functions like contains, first, 
+// length and so on for every type of lists.
+
+def length_int_list(lst: List[Int]): Int = lst match {
+  case Nil => 0
+  case _::xs => 1 + length_int_list(xs)
+}
+
+length_int_list(List(1, 2, 3, 4))
+
+def length_string_list(lst: List[String]): Int = lst match {
+  case Nil => 0
+  case _::xs => 1 + length_string_list(xs)
+}
+
+length_string_list(List("1", "2", "3", "4"))
+
+
+// you can make the function parametric in type(s)
+
+def length[A](lst: List[A]): Int = lst match {
+  case Nil => 0
+  case x::xs => 1 + length(xs)
+}
+length(List("1", "2", "3", "4"))
+length(List(1, 2, 3, 4))
+
+
+length[String](List(1, 2, 3, 4))
+
+
+def map[A, B](lst: List[A], f: A => B): List[B] = lst match {
+  case Nil => Nil
+  case x::xs => f(x)::map(xs, f) 
+}
+
+map(List(1, 2, 3, 4), (x: Int) => x.toString)
+
+                                                                
+// Type inference is local in Scala
+
+def id[T](x: T) : T = x
+
+val x = id(322)          // Int
+val y = id("hey")        // String
+val z = id(Set(1,2,3,4)) // Set[Int]
+
+
+// The type variable concept in Scala can get 
+// really complicated.
+//
+// - variance (OO)
+// - bounds (subtyping)
+// - quantification
+
+// Java has issues with this too: Java allows
+// to write the following incorrect code, and
+// only recovers by raising an exception
+// at runtime.
+
+// Object[] arr = new Integer[10];
+// arr[0] = "Hello World";
+
+
+// Scala gives you a compile-time error, which
+// is much better.
+
+var arr = Array[Int]()
+arr(0) = "Hello World"
+
 
 
 
@@ -40,152 +115,20 @@
 len(List(1,2,3,4))
 
 
-List(1,2,3,4).map(x => x * x)
-
-def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = 
-  lst match {
-    case Nil => Nil
-    case foo::xs => f(foo) :: my_map_int(xs, f)
-  }
-
-def my_map_option(opt: Option[Int], f: Int => Int) : Option[Int] = 
-  opt match {
-    case None => None
-    case Some(x) => {
-      Some(f(x))
-    }
-  }
-
-my_map_option(None, x => x * x)
-my_map_option(Some(8), x => x * x)
-
-
-// you can also have cases combined
-def season(month: String) : String = month match {
-  case "March" | "April" | "May" => "It's spring"
-  case "June" | "July" | "August" => "It's summer"
-  case "September" | "October" | "November" => "It's autumn"
-  case "December" => "It's winter"
-  case "January" | "February" => "It's unfortunately winter"
-  case _ => "Wrong month"
-}
-
-// pattern-match on integers
+//=================
+// Trees (example of an Algebraic Datatype)
 
-def fib(n: Int) : Int = n match { 
-  case 0 | 1 => 1
-  case _ => fib(n - 1) + fib(n - 2)
-}
-
-fib(10)
-
-// pattern-match on results
-
-// Silly: fizz buzz
-def fizz_buzz(n: Int) : String = (n % 3, n % 5) match {
-  case (0, 0) => "fizz buzz"
-  case (0, _) => "fizz"
-  case (_, 0) => "buzz"
-  case _ => n.toString  
-}
-
-for (n <- 1 to 20) 
- println(fizz_buzz(n))
+abstract class Tree
+case class Leaf(x: Int) extends Tree
+case class Node(s: String, left: Tree, right: Tree) extends Tree 
 
-// guards in pattern-matching
+val lf = Leaf(20)
+val tr = Node("foo", Leaf(10), Leaf(23))
 
-def foo(xs: List[Int]) : String = xs match {
-  case Nil => s"this list is empty"
-  case x :: xs if x % 2 == 0 
-     => s"the first elemnt is even"
-  case x if len(x) ==
-     => s"this list has exactly two elements"   
-  case x :: y :: rest if x == y
-     => s"this has two elemnts that are the same"
-  case hd :: tl => s"this list is standard $hd::$tl"
-}
-
-foo(Nil)
-foo(List(1,2,3))
-foo(List(1,1))
-foo(List(1,1,2,3))
-foo(List(2,2,2,3))
-
+val lst : List[Tree] = List(lf, tr)
 
 
 
-abstract class Colour
-case object Red extends Colour 
-case object Green extends Colour 
-case object Blue extends Colour
-case object Yellow extends Colour
-
-
-def fav_colour(c: Colour) : Boolean = c match {
-  case Green => true
-  case Red => true
-  case _  => false 
-}
-
-fav_colour(Blue)
-
-
-// ... a tiny bit more useful: Roman Numerals
-
-sealed abstract class RomanDigit 
-case object I extends RomanDigit 
-case object V extends RomanDigit 
-case object X extends RomanDigit 
-case object L extends RomanDigit 
-case object C extends RomanDigit 
-case object D extends RomanDigit 
-case object M extends RomanDigit 
-
-type RomanNumeral = List[RomanDigit] 
-
-List(I, M,C,D,X,X,V,I,I, A)
-
-/*
-I    -> 1
-II   -> 2
-III  -> 3
-IV   -> 4
-V    -> 5
-VI   -> 6
-VII  -> 7
-VIII -> 8
-IX   -> 9
-X    -> 10
-*/
-
-def RomanNumeral2Int(rs: RomanNumeral): Int = rs match { 
-  case Nil => 0
-  case M::r    => 1000 + RomanNumeral2Int(r)  
-  case C::M::r => 900 + RomanNumeral2Int(r)
-  case D::r    => 500 + RomanNumeral2Int(r)
-  case C::D::r => 400 + RomanNumeral2Int(r)
-  case C::r    => 100 + RomanNumeral2Int(r)
-  case X::C::r => 90 + RomanNumeral2Int(r)
-  case L::r    => 50 + RomanNumeral2Int(r)
-  case X::L::r => 40 + RomanNumeral2Int(r)
-  case X::r    => 10 + RomanNumeral2Int(r)
-  case I::X::r => 9 + RomanNumeral2Int(r)
-  case V::r    => 5 + RomanNumeral2Int(r)
-  case I::V::r => 4 + RomanNumeral2Int(r)
-  case I::r    => 1 + RomanNumeral2Int(r)
-}
-
-RomanNumeral2Int(List(I,V))             // 4
-RomanNumeral2Int(List(I,I,I,I))         // 4 (invalid Roman number)
-RomanNumeral2Int(List(V,I))             // 6
-RomanNumeral2Int(List(I,X))             // 9
-RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) // 1979
-RomanNumeral2Int(List(M,M,X,V,I,I))     // 2017
-
-abstract class Tree
-case class Leaf(x: Int)
-case class Branch(tl: Tree, tr: Tree)
-
 
 abstract class Rexp
 case object ZERO extends Rexp                      // matches nothing
@@ -205,18 +148,8 @@
 }
 
 
-// Trees (example of an Algebraic Datatype)
 
 
-abstract class Tree
-case class Leaf(x: Int) extends Tree
-case class Node(s: String, left: Tree, right: Tree) extends Tree 
-
-val lf = Leaf(20)
-val tr = Node("foo", Leaf(10), Leaf(23))
-
-val lst : List[Tree] = List(lf, tr)
-
 
 
 // expressions (essentially trees)
@@ -327,7 +260,7 @@
   if (n == 0) acc else factT(n - 1, n * acc)
 
 
-factT(10, 1)
+factT(1000,1)
 println(factT(100000, 1))
 
 
@@ -357,81 +290,31 @@
 // nothing is perfect. 
 
 
-
-// Polymorphic Types
-//===================
-
-// You do not want to write functions like contains, first, 
-// length and so on for every type of lists.
-
-def length_int_list(lst: List[Int]): Int = lst match {
-  case Nil => 0
-  case _::xs => 1 + length_int_list(xs)
-}
-
-length_int_list(List(1, 2, 3, 4))
+// default arguments
 
-def length_string_list(lst: List[String]): Int = lst match {
-  case Nil => 0
-  case _::xs => 1 + length_string_list(xs)
-}
-
-length_string_list(List("1", "2", "3", "4"))
-
-
-// you can make the function parametric in type(s)
+def factT(n: BigInt, acc: BigInt = 1): BigInt =
+  if (n == 0) acc else factT(n - 1, n * acc)
 
-def length[A](lst: List[A]): Int = lst match {
-  case Nil => 0
-  case x::xs => 1 + length(xs)
-}
-length(List("1", "2", "3", "4"))
-length(List(1, 2, 3, 4))
-
-
-length[String](List(1, 2, 3, 4))
+factT(1_000_000)
 
 
-def map[A, B](lst: List[A], f: A => B): List[B] = lst match {
-  case Nil => Nil
-  case x::xs => f(x)::map(xs, f) 
+def length[A](xs: List[A]) : Int = xs match {
+  case Nil => 0
+  case _ :: tail => 1 + length(tail)
 }
 
-map(List(1, 2, 3, 4), (x: Int) => x.toString)
-
-
-// should be
-def first[A, B](xs: List[A], f: A => Option[B]) : Option[B] = ???
+length(List.fill(100000)(1))
 
-// Type inference is local in Scala
-
-def id[T](x: T) : T = x
+def lengthT[A](xs: List[A], acc : Int = 0) : Int = xs match {
+  case Nil => acc
+  case _ :: tail => lengthT(tail, 1 + acc)
+}
 
-val x = id(322)          // Int
-val y = id("hey")        // String
-val z = id(Set(1,2,3,4)) // Set[Int]
+lengthT(List.fill(100000)(1))
 
 
-// The type variable concept in Scala can get really complicated.
-//
-// - variance (OO)
-// - bounds (subtyping)
-// - quantification
-
-// Java has issues with this too: Java allows
-// to write the following incorrect code, and
-// only recovers by raising an exception
-// at runtime.
-
-// Object[] arr = new Integer[10];
-// arr[0] = "Hello World";
 
 
-// Scala gives you a compile-time error, which
-// is much better.
-
-var arr = Array[Int]()
-arr(0) = "Hello World"
 
 
 
@@ -467,26 +350,6 @@
 i"add ${3+2} ${3 * 3}" 
 
 
-// default arguments
-
-def length[A](xs: List[A]) : Int = xs match {
-  case Nil => 0
-  case _ :: tail => 1 + length(tail)
-}
-
-def lengthT[A](xs: List[A], acc : Int = 0) : Int = xs match {
-  case Nil => acc
-  case _ :: tail => lengthT(tail, 1 + acc)
-}
-
-lengthT(List.fill(100000)(1))
-
-
-def fact(n: BigInt, acc: BigInt = 1): BigInt =
-  if (n == 0) acc else fact(n - 1, n * acc)
-
-fact(10)
-
 
 
 // currying    (Haskell Curry)
@@ -672,7 +535,8 @@
       if (isDone(game)) searchT(rest, game::sols)
       else {
         val cs = candidates(game, emptyPosition(game))
-        searchT(cs.map(c => update(game, empty(game), c)) ::: rest, sols)
+        searchT(cs.map(c => update(game, empty(game), c)) 
+                  ::: rest, sols)
      }
    }
  }
@@ -730,24 +594,16 @@
 //     "HAL".increment
 //
 // you can avoid ugly fudges, like a MyString, by
-// using implicit conversions.
+// using an extension.
 
-print("\n")
-print("""\n""")
 
-implicit class MyString(s: String) {
+extension (s: String) {
   def increment = s.map(c => (c + 1).toChar) 
 }
 
 "HAL".increment
 
 
-// Abstract idea:
-// In that version implicit conversions were used to solve the 
-// late extension problem; namely, given a class C and a class T, 
-// how to have C extend T without touching or recompiling C. 
-// Conversions add a wrapper when a member of T is requested 
-// from an instance of C.
 
 
 
@@ -758,7 +614,7 @@
     Duration(time + unit.convert(o.time, o.unit), unit)
 }
 
-implicit class Int2Duration(that: Int) {
+extension (that: Int) {
   def seconds = Duration(that, SECONDS)
   def minutes = Duration(that, MINUTES)
 }
@@ -789,7 +645,6 @@
 
 // some convenience for typing in regular expressions
 import scala.language.implicitConversions    
-import scala.language.reflectiveCalls 
 
 def charlist2rexp(s: List[Char]): Rexp = s match {
   case Nil => ONE
@@ -797,28 +652,22 @@
   case c::s => SEQ(CHAR(c), charlist2rexp(s))
 }
 
-implicit def string2rexp(s: String): Rexp = 
-  charlist2rexp(s.toList)
+given Conversion[String, Rexp] = 
+   (s => charlist2rexp(s.toList))
 
 val r1 = STAR("ab")
 val r2 = STAR("hello") | STAR("world")
 
 
-implicit def RexpOps (r: Rexp) = new {
+extension (r: Rexp) {
   def | (s: Rexp) = ALT(r, s)
   def % = STAR(r)
   def ~ (s: Rexp) = SEQ(r, s)
 }
 
-implicit def stringOps (s: String) = new {
-  def | (r: Rexp) = ALT(s, r)
-  def | (r: String) = ALT(s, r)
-  def % = STAR(s)
-  def ~ (r: Rexp) = SEQ(s, r)
-  def ~ (r: String) = SEQ(s, r)
-}
+//example regular expressions
 
-//example regular expressions
+val rex = "ab".%
 
 
 val digit = ("0" | "1" | "2" | "3" | "4" | 
@@ -850,7 +699,7 @@
 import scala.language.implicitConversions   
 
 val i = Complex(0, 1)
-implicit def double2complex(re: Double) = Complex(re, 0)
+given Conversion[Double, Complex] = (re: Double) => Complex(re, 0)
 
 val inum1 = -2.0 + -1.5 * i
 val inum2 =  1.0 +  1.5 * i
--- a/progs/lecture5.scala	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/lecture5.scala	Mon Jul 21 16:38:07 2025 +0100
@@ -1,110 +1,12 @@
 // Scala Lecture 5
 //=================
 
-for (n <- (1 to 10).toList) yield {
-  val add = 10
-  n + add
-}
-
-println(add)
-
-List(1,2,3,4).sum
-
-// extension methods
-// implicit conversions
-// (Immutable) OOP
-
-// Cool Stuff in Scala
-//=====================
-
-
-// Extensions or How to Pimp your Library
-//======================================
-
-// For example adding your own methods to Strings:
-// Imagine you want to increment strings, like
-//
-//     "HAL".increment
-//
-// you can avoid ugly fudges, like a MyString, by
-// using extensions.
-
-extension (s: String) {
-  def increment = s.map(c => (c + 1).toChar)
-}
-
-"HAL".increment
-
-
-
-// a more relevant example
-
-import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES}
-
-case class Duration(time: Long, unit: TimeUnit) {
-  def +(o: Duration) = 
-    Duration(time + unit.convert(o.time, o.unit), unit)
-}
-
-extension (that: Int) {
-  def seconds = Duration(that, SECONDS)
-  def minutes = Duration(that, MINUTES)
-}
+def foo(n: Int) = ???
 
-2.minutes + 60.seconds
-5.seconds + 2.minutes   //Duration(125, SECONDS )
-
-
-// Implicit Conversions
-//=====================
-
-
-
-// Regular expressions - the power of DSLs in Scala
-//==================================================
-
-abstract class Rexp
-case object ZERO extends Rexp                     // nothing
-case object ONE extends Rexp                      // the empty string
-case class CHAR(c: Char) extends Rexp             // a character c
-case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2
-case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2  
-case class STAR(r: Rexp) extends Rexp             // star         r*
-
-val r = STAR(CHAR('a'))
-
-
-// some convenience for typing in regular expressions
-import scala.language.implicitConversions    
-import scala.language.reflectiveCalls 
+fop(10)
 
-def charlist2rexp(s: List[Char]): Rexp = s match {
-  case Nil => ONE
-  case c::Nil => CHAR(c)
-  case c::s => SEQ(CHAR(c), charlist2rexp(s))
-}
-
-given Conversion[String, Rexp] = (s => charlist2rexp(s.toList))
-
-extension (r: Rexp) {
-  def | (s: Rexp) = ALT(r, s)
-  def % = STAR(r)
-  def ~ (s: Rexp) = SEQ(r, s)
-}
-
-val r1 = CHAR('a') | CHAR('b') | CHAR('c')
-val r2 = CHAR('a') ~  CHAR('b')
-
-val r3 : Rexp = "hello world"
-      
-
-//example regular expressions
-val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-val sign = "+" | "-" | ""
-val number = sign ~ digit ~ digit.% 
-
-
-
+List.fill(1)(100)
+// (Immutable) OOP
 
 // Object Oriented Programming in Scala
 // =====================================
@@ -164,50 +66,6 @@
 }
 
 
-// In mandelbrot.scala I used complex (imaginary) numbers 
-// and implemented the usual arithmetic operations for complex 
-// numbers.
-
-case class Complex(re: Double, im: Double) { 
-  // represents the complex number re + im * i
-  def +(that: Complex) = Complex(this.re + that.re, this.im + that.im)
-  def -(that: Complex) = Complex(this.re - that.re, this.im - that.im)
-  def *(that: Complex) = Complex(this.re * that.re - this.im * that.im,
-                                 this.re * that.im + that.re * this.im)
-  def *(that: Double) = Complex(this.re * that, this.im * that)
-  def abs = Math.sqrt(this.re * this.re + this.im * this.im)
-}
-
-// usual way to reference methods
-//object.method(....)
-
-val test = Complex(1, 2) + (Complex (3, 4))
-
-
-import scala.language.postfixOps
-(List(5,4,3,2,1) sorted) reverse
-
-// this could have equally been written as
-val test = Complex(1, 2).+(Complex (3, 4))
-
-// this applies to all methods, but requires
-import scala.language.postfixOps
-
-List(5, 2, 3, 4).sorted
-List(5, 2, 3, 4) sorted
-
-
-// ...to allow the notation n + m * i
-import scala.language.implicitConversions   
-
-val i = Complex(0, 1)
-
-given Conversion[Double, Complex] = (re => Complex(re, 0))
-
-val inum1 = -2.0 + -1.5 * i
-val inum2 =  1.0 +  1.5 * i
-
-
 
 // All is public by default....so no public is needed.
 // You can have the usual restrictions about private 
@@ -489,7 +347,7 @@
 // up to a level
 
 def enuml(l: Int, s: String) : Set[Rexp] = l match {
-  case 0 => Set(ZERO, ONE) ++ s.map(CHAR).toSet
+  case 0 => Set(ZERO, ONE) ++ s.map(CHAR(_)).toSet
   case n =>  
     val rs = enuml(n - 1, s)
     rs ++
--- a/progs/mandelbrot.sc	Sun Sep 15 12:57:59 2024 +0100
+++ b/progs/mandelbrot.sc	Mon Jul 21 16:38:07 2025 +0100
@@ -3,11 +3,13 @@
 //
 //   see https://en.wikipedia.org/wiki/Mandelbrot_set
 //
-// You can run on the file one the commandline with
+// You can run the file on the commandline with
 //
 //   scala mandelbrot.sc
 //
+// Or inside the REPL with
 //
+//   scala --extra-jars scala-parallel-collections_3-1.0.4.jar
 //
 // !! UPDATE ON TIMING: On my faster Mac-M1 machine
 // !! the times for the first example are ca. 4 secs for
@@ -16,7 +18,6 @@
 
 // for parallel collections
 //> using dep org.scala-lang.modules::scala-parallel-collections:1.0.4
-import scala.language.implicitConversions.*
 import scala.collection.parallel.CollectionConverters.*
 
 // for graphics
@@ -177,7 +178,6 @@
                 exc2 - delta * n, 1000))} secs")
 
 
-
 // Larry Paulson's example
 val exl1 = -0.74364990 + 0.13188170 * i
 val exl2 = -0.74291189 + 0.13261971 * i
Binary file slides/slides01.pdf has changed
--- a/slides/slides01.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/slides/slides01.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -5,7 +5,7 @@
 \usepackage{../styles/langs}
 %\usepackage{../data}
 \usetikzlibrary{shapes} 
-
+\usepackage{ulem}
 \hfuzz=220pt  
 
 %\setmonofont[Scale=.88]{Consolas}
@@ -110,7 +110,7 @@
     %Office: & N\liningnums{7.07} (North Wing, Bush House)\bigskip\\
     Slides \& Code: & KEATS\bigskip\\
 
-    Office Hour: &  Fridays 13:00 -- 14:00\\
+    Office Hour: &  Thursdays 13:00 -- 14:00\\
     Location: & N7.07 (North Wing, Bush House)\bigskip\\
 
     Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
@@ -274,8 +274,8 @@
 
 \begin{minipage}{1.1\textwidth}
 \begin{itemize}
-\item contains a REPL $\Rightarrow$ but this year we use
-  \textcolor{red}{\texttt{scala-cli}}  
+\item contains a REPL $\Rightarrow$ this year we use
+  \sout{scala-cli} \textcolor{red}{\texttt{scala}}   
 \item I use VS Codium and a Scala extension (M'place)
 \begin{center}  
 \includegraphics[scale=0.10]{../pics/vscode.png}\\[-10mm]\mbox{}
@@ -312,29 +312,32 @@
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \begin{frame}[c, fragile]
-\frametitle{This year Scala 3/ \textbf{\texttt{scala-cli}}}
+\frametitle{Scala 3}
 
 \mbox{}\\
 
 \begin{minipage}{1.3\textwidth}
 \begin{center}
-\textbf{\texttt{scala-cli}}
-$\quad\Rightarrow$ {\small\url{https://scala-cli.virtuslab.org/}}\bigskip
+\textbf{\texttt{scala}}
+$\quad\Rightarrow$ {\small\url{https://www.scala-lang.org/download/}}\bigskip
 \end{center}
 
 Installation problems:
 \begin{itemize}
-\item Oscar Sjostedt (\texttt{\small{}oscar.sjostedt@kcl.ac.uk})
-\item Nicole Lehchevska (\texttt{\small{}nicole.lehchevska@kcl.ac.uk})\bigskip
+\item Flavio Melinte Citea (\texttt{\small{}flavio.melinte\_citea@kcl.ac.uk})  
+\item Zishan Rahman (\texttt{\small{}zishan.rahman@kcl.ac.uk})
+\item Opale Sjostedt (\texttt{\small{}opale.sjostedt@kcl.ac.uk})
+\item Oliver Iliffe (\texttt{\small{}oliver.iliffe@kcl.ac.uk})  
+  \bigskip
 \end{itemize}
 Github problems:
 \begin{itemize}
-\item Quan Tran (\texttt{\small{}anh.tran@kcl.ac.uk})\bigskip
+\item Zishan Rahman (\texttt{\small{}zishan.rahman@kcl.ac.uk})  
 \end{itemize}
-Discussion forum:
-\begin{itemize}  
-\item Ruben Ticehurst-James (\texttt{\small{}ruben.ticehurst-james@kcl.ac.uk})  
-\end{itemize}
+%Discussion forum:
+%\begin{itemize}  
+%\item Ruben Ticehurst-James (\texttt{\small{}ruben.ticehurst-james@kcl.ac.uk})  
+%\end{itemize}
 \end{minipage}
   
 \end{frame}
@@ -964,9 +967,9 @@
 \frametitle{Conclusion for Today}
 
 \begin{itemize}
-\item This year we will be using Scala 3 with the \texttt{scala-cli} REPL!\\ 
+\item This year we will be using Scala 3 with the \texttt{scala} REPL!\\ 
   \medskip
-\item {\bf\url{https://scala-cli.virtuslab.org/}}\bigskip
+\item {\bf\url{https://www.scala-lang.org/}}\bigskip
   
 \item Scala can be a rather \textbf{\alert{deep}} language\ldots i.e.~gives
   you a lot of rope to shoot yourself.\bigskip
Binary file slides/slides02.pdf has changed
--- a/slides/slides02.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/slides/slides02.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -48,7 +48,7 @@
     %Office: & N\liningnums{7.07} (North Wing, Bush House)\bigskip\\
     Slides \& Code: & KEATS\bigskip\\
 
-    Office Hour: &  Fridays 13:00 -- 14:00\\
+    Office Hour: &  Thursdays 13:00 -- 14:00\\
     Location: & N7.07 (North Wing, Bush House)\bigskip\\
 
     Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
@@ -67,6 +67,69 @@
 \end{frame}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}[c, fragile]
+\frametitle{Scala 3}
+
+\mbox{}\\
+
+\begin{minipage}{1.3\textwidth}
+\begin{center}
+\textbf{\texttt{scala}}
+$\quad\Rightarrow$ {\small\url{https://www.scala-lang.org/download/}}\bigskip
+\end{center}
+
+Installation problems:
+\begin{itemize}
+\item Flavio Melinte Citea (\texttt{\small{}flavio.melinte\_citea@kcl.ac.uk})  
+\item Zishan Rahman (\texttt{\small{}zishan.rahman@kcl.ac.uk})
+\item Opale Sjostedt (\texttt{\small{}opale.sjostedt@kcl.ac.uk})
+\item Oliver Iliffe (\texttt{\small{}oliver.iliffe@kcl.ac.uk})  
+  \bigskip
+\end{itemize}
+Github problems:
+\begin{itemize}
+\item Zishan Rahman (\texttt{\small{}zishan.rahman@kcl.ac.uk})  
+\end{itemize}
+%Discussion forum:
+%\begin{itemize}  
+%\item Ruben Ticehurst-James (\texttt{\small{}ruben.ticehurst-james@kcl.ac.uk})  
+%\end{itemize}
+\end{minipage}
+  
+\end{frame}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\begin{frame}[c, fragile]
+%%\frametitle{General Scheme of}  
+
+ \small
+\begin{lstlisting}[language=Scala,numbers=none]
+def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
+
+   ....
+
+}
+\end{lstlisting}
+
+  
+\end{frame}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\begin{frame}[c, fragile]
+
+\begin{lstlisting}[language=Scala,numbers=none]
+def average(xs: List[Int]) : Int = {
+  val s = xs.sum
+  val n = xs.length
+  s / n
+}
+\end{lstlisting}
+
+  
+\end{frame}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
 % \begin{frame}[t,fragile]
Binary file slides/slides03.pdf has changed
--- a/slides/slides03.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/slides/slides03.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -64,7 +64,7 @@
     %Office: & N\liningnums{7.07} (North Wing, Bush House)\bigskip\\
     Slides \& Code: & KEATS\bigskip\\
 
-    Office Hour: &  Fridays 13:00 -- 14:00\\
+    Office Hour: &  Thursdays 13:00 -- 14:00 (send email first)\\
     Location: & N7.07 (North Wing, Bush House)\bigskip\\
 
     Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
Binary file slides/slides04.pdf has changed
--- a/slides/slides04.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/slides/slides04.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -178,10 +178,10 @@
     %%Office: & N\liningnums{7.07} (North Wing, Bush House)\bigskip\\
     Slides \& Code: & KEATS\bigskip\\
 
-    Office Hour: &  Fridays 13:00 -- 14:00\\
+    Office Hour: &  Thursdays 13:00 -- 14:00 (send email first)\\
     Location: & N7.07 (North Wing, Bush House)\bigskip\\
 
-    Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
+    %Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
   \end{tabular}
   \end{center}
 
@@ -518,33 +518,33 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
-\begin{frame}[c,fragile]
-\small
-\textcolor{red}{MacOSX}\medskip
-
-\begin{minipage}{13cm}
-  \begin{itemize}
-  \item[0)] (if needed) \texttt{brew install java} \;\;or\;\; \texttt{brew reinstall java}
-  \item[1)] \texttt{curl -s "https://get.sdkman.io" | bash}
-  \item[2)] \texttt{sdk install scala 2.13.7}  
-  \end{itemize}
-\end{minipage}\bigskip
+%\begin{frame}[c,fragile]
+%\small
+%\textcolor{red}{MacOSX}\medskip
+%
+%\begin{minipage}{13cm}
+%  \begin{itemize}
+%  \item[0)] (if needed) \texttt{brew install java} \;\;or\;\; \texttt{brew reinstall java}
+%  \item[1)] \texttt{curl -s "https://get.sdkman.io" | bash}
+%  \item[2)] \texttt{sdk install scala 2.13.7}  
+%  \end{itemize}
+%\end{minipage}\bigskip
   
-\textcolor{red}{Windows / Linux Ubuntu}\medskip
+%\textcolor{red}{Windows / Linux Ubuntu}\medskip
 
-\begin{minipage}{13cm}
-  \begin{itemize}
-  \item[0)] (if needed) \texttt{sudo apt-get remove scala-library scala}
-  \item[1)] {\fontsize{8.5}{8.5}\selectfont\texttt{sudo wget https://downloads.lightbend.com/scala/2.13.7/scala-2.13.7.deb}}
-  \item[2)] \texttt{sudo dpkg -i scala-2.13.7.deb}  
-  \end{itemize}
-\end{minipage}\bigskip
+%\begin{minipage}{13cm}
+%  \begin{itemize}
+%  \item[0)] (if needed) \texttt{sudo apt-get remove scala-library scala}
+%  \item[1)] {\fontsize{8.5}{8.5}\selectfont\texttt{sudo wget https://downloads.lightbend.com/scala/2.13.7/scala-2.13.7.deb}}
+%  \item[2)] \texttt{sudo dpkg -i scala-2.13.7.deb}  
+%  \end{itemize}
+%\end{minipage}\bigskip
 
-\begin{minipage}{13cm}
-other Linux distros: \texttt{sudo apt-get scala}
-\end{minipage}
+%\begin{minipage}{13cm}
+%other Linux distros: \texttt{sudo apt-get scala}
+%\end{minipage}
 
-\end{frame}
+%\end{frame}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
Binary file slides/slides05.pdf has changed
--- a/slides/slides05.tex	Sun Sep 15 12:57:59 2024 +0100
+++ b/slides/slides05.tex	Mon Jul 21 16:38:07 2025 +0100
@@ -164,10 +164,10 @@
     %Office: & N\liningnums{7.07} (North Wing, Bush House)\bigskip\\
     Slides \& Code: & KEATS\bigskip\\
 
-    Office Hour: &  Fridays 13:00 -- 14:00\\
+    Office Hour: &  Thursdays 13:00 -- 14:00\\
     Location: & N7.07 (North Wing, Bush House)\bigskip\\
 
-    Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
+    %Pollev: & \texttt{\alert{https://pollev.com/cfltutoratki576}}\\  \\
   \end{tabular}
   \end{center}
 
@@ -208,7 +208,7 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\begin{frame}[c]
+\begin{frame}<1>[c]
   \frametitle{Main 3: Regexes}
   
 \begin{center}
@@ -337,54 +337,54 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
-\begin{frame}[c,fragile]
-\frametitle{Polyorphic Types} 
+% \begin{frame}[c,fragile]
+% \frametitle{Polyorphic Types} 
 
-%To be avoided:\bigskip\bigskip
-\small
+% %To be avoided:\bigskip\bigskip
+% \small
 
-\begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-6mm]
-def length_string_list(lst: List[String]): Int = 
- lst match {
-   case Nil => 0
-   case x::xs => 1 + length_string_list(xs)
- }
+% \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-6mm]
+% def length_string_list(lst: List[String]): Int = 
+%  lst match {
+%    case Nil => 0
+%    case x::xs => 1 + length_string_list(xs)
+%  }
 
  
-def length_int_list(lst: List[Int]): Int = 
- lst match {
-   case Nil => 0
-   case x::xs => 1 + length_int_list(xs)
- }
-\end{lstlisting}
+% def length_int_list(lst: List[Int]): Int = 
+%  lst match {
+%    case Nil => 0
+%    case x::xs => 1 + length_int_list(xs)
+%  }
+% \end{lstlisting}
 
-\end{frame}
+% \end{frame}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
-\begin{frame}[c,fragile]
-\frametitle{Polyorphic Types} 
+% \begin{frame}[c,fragile]
+% \frametitle{Polyorphic Types} 
 
-\small
+% \small
 
-\begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-6mm]
-def length[A](lst: List[A]): Int = lst match {
-  case Nil => 0
-  case x::xs => 1 + length(xs)
-}
+% \begin{lstlisting}[language=Scala, numbers=none, xleftmargin=-6mm]
+% def length[A](lst: List[A]): Int = lst match {
+%   case Nil => 0
+%   case x::xs => 1 + length(xs)
+% }
 
-length(List("1", "2", "3", "4"))
-length(List(1, 2, 3, 4))
+% length(List("1", "2", "3", "4"))
+% length(List(1, 2, 3, 4))
 
 
-def map[A, B](lst: List[A], f: A => B): List[B] = 
- lst match {
-   case Nil => Nil
-   case x::xs => f(x)::map(xs, f) 
- }
-\end{lstlisting}
-\end{frame}
+% def map[A, B](lst: List[A], f: A => B): List[B] = 
+%  lst match {
+%    case Nil => Nil
+%    case x::xs => f(x)::map(xs, f) 
+%  }
+% \end{lstlisting}
+% \end{frame}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
@@ -485,25 +485,31 @@
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%     
 
-\begin{frame}[c]
+\begin{frame}[t]
 \frametitle{Where to go on from here?}
 
 \begin{itemize}
-\item Martin Odersky (EPFL) developed now Scala 3\medskip
+\item Martin Odersky (EPFL) developed Scala\medskip
 
 \item I use Ammonite by Haoyi Li\medskip
   
 \item Elm (\url{http://elm-lang.org})\ldots web applications with style\medskip   
 
-\item Haskell, Ocaml, Standard ML, Scheme, \ldots 
+\item Haskell, Ocaml, Standard ML, Scheme, \ldots \bigskip\bigskip\bigskip
 \end{itemize}  
 
 \begin{textblock}{5}(12,9)
 \includegraphics[scale=0.15]{../pics/haojili.png} 
 \end{textblock}  
+
+\only<2->{C++, Scala, }
+\only<3->{PHP, Python, Perl, Bash}
+
 \end{frame}
 
 
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%