--- 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}
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%