--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cws/main_cw01.tex Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,237 @@
+% !TEX program = xelatex
+\documentclass{article}
+\usepackage{../style}
+\usepackage{disclaimer}
+\usepackage{../langs}
+
+
+
+\begin{document}
+
+\section*{Core Part 6 (Scala, 7 Marks)}
+
+\IMPORTANT{This part is about Scala. It is due on \cwSIXa{} at 5pm and worth 7\%.}
+
+\noindent
+Also note that the running time of each part will be restricted to a
+maximum of 30 seconds on my laptop.
+
+\DISCLAIMER{}
+
+\subsection*{Reference Implementation}
+
+Like the C++ assignments, the Scala assignments will work like this: you
+push your files to GitHub and receive (after sometimes a long delay) some
+automated feedback. In the end we take a snapshot of the submitted files and
+apply an automated marking script to them.\medskip
+
+\noindent
+In addition, the Scala coursework comes with a reference implementation
+in form of \texttt{jar}-files. This allows you to run any test cases
+on your own computer. For example you can call Scala on the command
+line with the option \texttt{-cp drumb.jar} and then query any
+function from the template file. Say you want to find out what
+the function \code{get_january_data}
+produces: for this you just need to prefix them with the object name
+\texttt{CW6b} and call them with some arguments:
+
+\begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
+$ scala -cp drumb.jar
+
+scala> CW6b.get_january_data("FB", 2014)
+val res2: List[String] = List(2014-01-02,54.709999,....)
+\end{lstlisting}%$
+
+\subsection*{Hints}
+
+\noindent
+\textbf{For the Core Part:} useful string functions:
+\texttt{.startsWith(...)} for checking whether a string has a given
+prefix, \texttt{\_ ++ \_} for concatenating two strings; useful option
+functions: \texttt{.flatten} flattens a list of options such that it
+filters way all \texttt{None}'s, \texttt{Try(...).getOrElse ...} runs
+some code that might raise an exception---if yes, then a default value
+can be given; useful list functions: \texttt{.head} for obtaining the
+first element in a non-empty list, \texttt{.length} for the length of
+a list; \texttt{.filter(...)} for filtering out elements in a list;
+\texttt{.getLines.toList} for obtaining a list of lines from a file;
+\texttt{.split(",").toList} for splitting strings according to a
+comma.\bigskip
+
+\noindent
+\textbf{Note!} Fortunately Scala supports operator overloading. But
+make sure you understand the difference between \texttt{100 / 3} and
+\texttt{100.0 / 3}!
+
+\newpage
+\subsection*{Core Part (7 Marks, file drumb.scala)}
+
+A purely fictional character named Mr T.~Drumb inherited in 1978
+approximately 200 Million Dollar from his father. Mr Drumb prides
+himself to be a brilliant business man because nowadays it is
+estimated he is 3 Billion Dollar worth (one is not sure, of course,
+because Mr Drumb refuses to make his tax records public).
+
+Since the question about Mr Drumb's business acumen remains open,
+let's do a quick back-of-the-envelope calculation in Scala whether his
+claim has any merit. Let's suppose we are given \$100 in 1978 and we
+follow a really dumb investment strategy, namely:
+
+\begin{itemize}
+\item We blindly choose a portfolio of stocks, say some Blue-Chip stocks
+ or some Real Estate stocks.
+\item If some of the stocks in our portfolio are traded in January of
+ a year, we invest our money in equal amounts in each of these
+ stocks. For example if we have \$100 and there are four stocks that
+ are traded in our portfolio, we buy \$25 worth of stocks
+ from each. (Be careful to also test cases where you trade with 3 stocks.)
+\item Next year in January, we look at how our stocks did, liquidate
+ everything, and re-invest our (hopefully) increased money in again
+ the stocks from our portfolio (there might be more stocks available,
+ if companies from our portfolio got listed in that year, or less if
+ some companies went bust or were de-listed).
+\item We do this for 41 years until January 2019 and check what would
+ have become out of our \$100.
+\end{itemize}
+
+\noindent
+Until Yahoo was bought by Altaba a few years ago, historical stock market
+data for such back-of-the-envelope calculations was freely available
+online. Unfortunately nowadays this kind of data is more difficult to
+obtain, unless you are prepared to pay extortionate prices or be
+severely rate-limited. Therefore this part comes with a number
+of files containing CSV-lists with the historical stock prices for the
+companies in our portfolios. Use these files for the following
+tasks.\bigskip
+
+\newpage
+\noindent
+\textbf{Tasks}
+
+\begin{itemize}
+\item[(1)] Write a function \texttt{get\_january\_data} that takes a
+ stock symbol and a year as arguments. The function reads the
+ corresponding CSV-file and returns the list of strings that start
+ with the given year (each line in the CSV-list is of the form
+ \texttt{someyear-01-someday,someprice}).\hfill[1 Mark]
+
+\item[(2)] Write a function \texttt{get\_first\_price} that takes
+ again a stock symbol and a year as arguments. It should return the
+ first January price for the stock symbol in the given year. For this
+ it uses the list of strings generated by
+ \texttt{get\_january\_data}. A problem is that normally a stock
+ exchange is not open on 1st of January, but depending on the day of
+ the week on a later day (maybe 3rd or 4th). The easiest way to solve
+ this problem is to obtain the whole January data for a stock symbol
+ and then select the earliest, or first, entry in this list. The
+ stock price of this entry should be converted into a double. Such a
+ price might not exist, in case the company does not exist in the given
+ year. For example, if you query for Google in January of 1980, then
+ clearly Google did not exist yet. Therefore you are asked to
+ return a trade price with type \texttt{Option[Double]}\ldots\texttt{None}
+ will be the value for when no price exists; \texttt{Some} if there is a
+ price.\hfill[1 Mark]
+
+\item[(3)] Write a function \texttt{get\_prices} that takes a
+ portfolio (a list of stock symbols), a years range and gets all the
+ first trading prices for each year in the range. You should organise
+ this as a list of lists of \texttt{Option[Double]}'s. The inner
+ lists are for all stock symbols from the portfolio and the outer
+ list for the years. For example for Google and Apple in years 2010
+ (first line), 2011 (second line) and 2012 (third line) you obtain:
+
+\begin{verbatim}
+ List(List(Some(312.204773), Some(26.782711)),
+ List(Some(301.0466), Some(41.244694)),
+ List(Some(331.462585), Some(51.464207))))
+\end{verbatim}\hfill[1 Mark]
+
+
+%\end{itemize}
+
+%\subsection*{Advanced Part 3 (4 Marks, continue in file drumb.scala)}
+%
+%\noindent
+%\textbf{Tasks}
+
+%\begin{itemize}
+
+\item[(4)] Write a function that calculates the \emph{change factor} (delta)
+ for how a stock price has changed from one year to the next. This is
+ only well-defined, if the corresponding company has been traded in both
+ years. In this case you can calculate
+
+ \[
+ \frac{price_{new} - price_{old}}{price_{old}}
+ \]
+
+ If the change factor is defined, you should return it
+ as \texttt{Some(change\_factor)}; if not, you should return
+ \texttt{None}.\mbox{}\hfill\mbox{[1 Mark]}
+
+\item[(5)] Write a function that calculates all change factors
+ (deltas) for the prices we obtained in Task (2). For the running
+ example of Google and Apple for the years 2010 to 2012 you should
+ obtain 4 change factors:
+
+\begin{verbatim}
+ List(List(Some(-0.03573991804411003), Some(0.539974575389325)),
+ List(Some(0.10103414222249969), Some(0.24777764141006836)))
+\end{verbatim}
+
+ That means Google did a bit badly in 2010, while Apple did very well.
+ Both did OK in 2011. Make sure you handle the cases where a company is
+ not listed in a year. In such cases the change factor should be \texttt{None}
+ (recall Task~(4)).
+ \mbox{}\hfill\mbox{[1 Mark]}
+
+\item[(6)] Write a function that calculates the ``yield'', or
+ balance, for one year for our portfolio. This function takes the
+ change factors, the starting balance and the year as arguments. If
+ no company from our portfolio existed in that year, the balance is
+ unchanged. Otherwise we invest in each existing company an equal
+ amount of our balance. Using the change factors computed under Task
+ (2), calculate the new balance. Say we had \$100 in 2010, we would have
+ received in our running example involving Google and Apple:
+
+ \begin{verbatim}
+ $50 * -0.03573991804411003 + $50 * 0.539974575389325
+ = $25.21173286726075
+ \end{verbatim}
+
+ as profit for that year, and our new balance for 2011 is \$125 when
+ converted to a \texttt{Long}.\mbox{}\hfill\mbox{[1 Mark]}
+
+\item[(7)] Write a function that calculates the overall balance
+ for a range of years where each year the yearly profit is compounded to
+ the new balances and then re-invested into our portfolio.
+ For this use the function and results generated under (6).\\
+ \mbox{}\hfill\mbox{[1 Mark]}
+\end{itemize}\medskip
+
+
+
+\noindent
+\textbf{Test Data:} File \texttt{drumb.scala} contains two portfolios
+collected from the S\&P 500, one for blue-chip companies, including
+Facebook, Amazon and Baidu; and another for listed real-estate
+companies, whose names I have never heard of. Following the dumb
+investment strategy from 1978 until 2019 would have turned a starting
+balance of \$100 into roughly \$39,162 for real estate and a whopping
+\$462,199 for blue chips. Note when comparing these results with your
+own calculations: there might be some small rounding errors, which
+when compounded lead to moderately different values.\bigskip
+
+
+\noindent
+\textbf{Moral:} Reflecting on our assumptions, we are over-estimating
+our yield in many ways: first, who can know in 1978 about what will
+turn out to be a blue chip company. Also, since the portfolios are
+chosen from the current S\&P 500, they do not include the myriad
+of companies that went bust or were de-listed over the years.
+So where does this leave our fictional character Mr T.~Drumb? Well, given
+his inheritance, a really dumb investment strategy would have done
+equally well, if not much better.\medskip
+
+\end{document}
+
--- a/cws/pcw01.tex Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-% !TEX program = xelatex
-\documentclass{article}
-\usepackage{../style}
-\usepackage{disclaimer}
-\usepackage{../langs}
-
-
-
-\begin{document}
-
-\section*{Core Part 6 (Scala, 7 Marks)}
-
-\IMPORTANT{This part is about Scala. It is due on \cwSIXa{} at 4pm and worth 7\%.}
-
-\noindent
-Also note that the running time of each part will be restricted to a
-maximum of 30 seconds on my laptop.
-
-\DISCLAIMER{}
-
-\subsection*{Reference Implementation}
-
-Like the C++ assignments, the Scala assignments will work like this: you
-push your files to GitHub and receive (after sometimes a long delay) some
-automated feedback. In the end we take a snapshot of the submitted files and
-apply an automated marking script to them.\medskip
-
-\noindent
-In addition, the Scala coursework comes with a reference implementation
-in form of \texttt{jar}-files. This allows you to run any test cases
-on your own computer. For example you can call Scala on the command
-line with the option \texttt{-cp drumb.jar} and then query any
-function from the template file. Say you want to find out what
-the functions ???
-produce: for this you just need to prefix them with the object name
-\texttt{CW6b}.
-If you want to find out what these functions produce for the argument
-\texttt{6}, you would type something like:
-
-\begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
-$ scala -cp collatz.jar
-
-scala> CW6a.collatz(6)
-...
-scala> CW6a.collatz_max(6)
-...
-\end{lstlisting}%$
-
-\subsection*{Hints}
-
-\noindent
-\textbf{For Core Part:} useful string functions:
-\texttt{.startsWith(...)} for checking whether a string has a given
-prefix, \texttt{\_ ++ \_} for concatenating two strings; useful option
-functions: \texttt{.flatten} flattens a list of options such that it
-filters way all \texttt{None}'s, \texttt{Try(...).getOrElse ...} runs
-some code that might raise an exception---if yes, then a default value
-can be given; useful list functions: \texttt{.head} for obtaining the
-first element in a non-empty list, \texttt{.length} for the length of
-a list; \texttt{.filter(...)} for filtering out elements in a list;
-\texttt{.getLines.toList} for obtaining a list of lines from a file;
-\texttt{.split(",").toList} for splitting strings according to a
-comma.\bigskip
-
-\noindent
-\textbf{Note!} Fortunately Scala supports operator overloading. But
-make sure you understand the difference between \texttt{100 / 3} and
-\texttt{100.0 / 3}!
-
-\newpage
-\subsection*{Core Part (7 Marks, file drumb.scala)}
-
-A purely fictional character named Mr T.~Drumb inherited in 1978
-approximately 200 Million Dollar from his father. Mr Drumb prides
-himself to be a brilliant business man because nowadays it is
-estimated he is 3 Billion Dollar worth (one is not sure, of course,
-because Mr Drumb refuses to make his tax records public).
-
-Since the question about Mr Drumb's business acumen remains open,
-let's do a quick back-of-the-envelope calculation in Scala whether his
-claim has any merit. Let's suppose we are given \$100 in 1978 and we
-follow a really dumb investment strategy, namely:
-
-\begin{itemize}
-\item We blindly choose a portfolio of stocks, say some Blue-Chip stocks
- or some Real Estate stocks.
-\item If some of the stocks in our portfolio are traded in January of
- a year, we invest our money in equal amounts in each of these
- stocks. For example if we have \$100 and there are four stocks that
- are traded in our portfolio, we buy \$25 worth of stocks
- from each. (Be careful to also test cases where you trade with 3 stocks.)
-\item Next year in January, we look at how our stocks did, liquidate
- everything, and re-invest our (hopefully) increased money in again
- the stocks from our portfolio (there might be more stocks available,
- if companies from our portfolio got listed in that year, or less if
- some companies went bust or were de-listed).
-\item We do this for 41 years until January 2019 and check what would
- have become out of our \$100.
-\end{itemize}
-
-\noindent
-Until Yahoo was bought by Altaba a few years ago, historical stock market
-data for such back-of-the-envelope calculations was freely available
-online. Unfortunately nowadays this kind of data is more difficult to
-obtain, unless you are prepared to pay extortionate prices or be
-severely rate-limited. Therefore this part comes with a number
-of files containing CSV-lists with the historical stock prices for the
-companies in our portfolios. Use these files for the following
-tasks.\bigskip
-
-\newpage
-\noindent
-\textbf{Tasks}
-
-\begin{itemize}
-\item[(1)] Write a function \texttt{get\_january\_data} that takes a
- stock symbol and a year as arguments. The function reads the
- corresponding CSV-file and returns the list of strings that start
- with the given year (each line in the CSV-list is of the form
- \texttt{someyear-01-someday,someprice}).\hfill[1 Mark]
-
-\item[(2)] Write a function \texttt{get\_first\_price} that takes
- again a stock symbol and a year as arguments. It should return the
- first January price for the stock symbol in the given year. For this
- it uses the list of strings generated by
- \texttt{get\_january\_data}. A problem is that normally a stock
- exchange is not open on 1st of January, but depending on the day of
- the week on a later day (maybe 3rd or 4th). The easiest way to solve
- this problem is to obtain the whole January data for a stock symbol
- and then select the earliest, or first, entry in this list. The
- stock price of this entry should be converted into a double. Such a
- price might not exist, in case the company does not exist in the given
- year. For example, if you query for Google in January of 1980, then
- clearly Google did not exist yet. Therefore you are asked to
- return a trade price with type \texttt{Option[Double]}\ldots\texttt{None}
- will be the value for when no price exists; \texttt{Some} if there is a
- price.\hfill[1 Mark]
-
-\item[(3)] Write a function \texttt{get\_prices} that takes a
- portfolio (a list of stock symbols), a years range and gets all the
- first trading prices for each year in the range. You should organise
- this as a list of lists of \texttt{Option[Double]}'s. The inner
- lists are for all stock symbols from the portfolio and the outer
- list for the years. For example for Google and Apple in years 2010
- (first line), 2011 (second line) and 2012 (third line) you obtain:
-
-\begin{verbatim}
- List(List(Some(312.204773), Some(26.782711)),
- List(Some(301.0466), Some(41.244694)),
- List(Some(331.462585), Some(51.464207))))
-\end{verbatim}\hfill[1 Mark]
-
-
-%\end{itemize}
-
-%\subsection*{Advanced Part 3 (4 Marks, continue in file drumb.scala)}
-%
-%\noindent
-%\textbf{Tasks}
-
-%\begin{itemize}
-
-\item[(4)] Write a function that calculates the \emph{change factor} (delta)
- for how a stock price has changed from one year to the next. This is
- only well-defined, if the corresponding company has been traded in both
- years. In this case you can calculate
-
- \[
- \frac{price_{new} - price_{old}}{price_{old}}
- \]
-
- If the change factor is defined, you should return it
- as \texttt{Some(change\_factor)}; if not, you should return
- \texttt{None}.\mbox{}\hfill\mbox{[1 Mark]}
-
-\item[(5)] Write a function that calculates all change factors
- (deltas) for the prices we obtained in Task (2). For the running
- example of Google and Apple for the years 2010 to 2012 you should
- obtain 4 change factors:
-
-\begin{verbatim}
- List(List(Some(-0.03573991804411003), Some(0.539974575389325)),
- List(Some(0.10103414222249969), Some(0.24777764141006836)))
-\end{verbatim}
-
- That means Google did a bit badly in 2010, while Apple did very well.
- Both did OK in 2011. Make sure you handle the cases where a company is
- not listed in a year. In such cases the change factor should be \texttt{None}
- (recall Task~(4)).
- \mbox{}\hfill\mbox{[1 Mark]}
-
-\item[(6)] Write a function that calculates the ``yield'', or
- balance, for one year for our portfolio. This function takes the
- change factors, the starting balance and the year as arguments. If
- no company from our portfolio existed in that year, the balance is
- unchanged. Otherwise we invest in each existing company an equal
- amount of our balance. Using the change factors computed under Task
- (2), calculate the new balance. Say we had \$100 in 2010, we would have
- received in our running example involving Google and Apple:
-
- \begin{verbatim}
- $50 * -0.03573991804411003 + $50 * 0.539974575389325
- = $25.21173286726075
- \end{verbatim}
-
- as profit for that year, and our new balance for 2011 is \$125 when
- converted to a \texttt{Long}.\mbox{}\hfill\mbox{[1 Mark]}
-
-\item[(7)] Write a function that calculates the overall balance
- for a range of years where each year the yearly profit is compounded to
- the new balances and then re-invested into our portfolio.
- For this use the function and results generated under (6).\\
- \mbox{}\hfill\mbox{[1 Mark]}
-\end{itemize}\medskip
-
-
-
-\noindent
-\textbf{Test Data:} File \texttt{drumb.scala} contains two portfolios
-collected from the S\&P 500, one for blue-chip companies, including
-Facebook, Amazon and Baidu; and another for listed real-estate
-companies, whose names I have never heard of. Following the dumb
-investment strategy from 1978 until 2019 would have turned a starting
-balance of \$100 into roughly \$39,162 for real estate and a whopping
-\$462,199 for blue chips. Note when comparing these results with your
-own calculations: there might be some small rounding errors, which
-when compounded lead to moderately different values.\bigskip
-
-
-\noindent
-\textbf{Moral:} Reflecting on our assumptions, we are over-estimating
-our yield in many ways: first, who can know in 1978 about what will
-turn out to be a blue chip company. Also, since the portfolios are
-chosen from the current S\&P 500, they do not include the myriad
-of companies that went bust or were de-listed over the years.
-So where does this leave our fictional character Mr T.~Drumb? Well, given
-his inheritance, a really dumb investment strategy would have done
-equally well, if not much better.\medskip
-
-\end{document}
-
Binary file cws/pre_cw01.pdf has changed
--- a/cws/pre_cw01.tex Sat Oct 31 16:23:12 2020 +0000
+++ b/cws/pre_cw01.tex Sat Oct 31 16:47:46 2020 +0000
@@ -53,7 +53,7 @@
\subsection*{Hints}
\noindent
-\textbf{For Preliminary Part:} useful math operators: \texttt{\%} for modulo, \texttt{\&} for bit-wise and; useful
+\textbf{For the Preliminary Part:} useful math operators: \texttt{\%} for modulo, \texttt{\&} for bit-wise and; useful
functions: \mbox{\texttt{(1\,to\,10)}} for ranges, \texttt{.toInt},
\texttt{.toList} for conversions, you can use \texttt{List(...).max} for the
maximum of a list, \texttt{List(...).indexOf(...)} for the first index of
Binary file pre_solition1/collatz.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_solition1/collatz.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,50 @@
+// Basic Part about the 3n+1 conjecture
+//==================================
+
+// generate jar with
+// > scala -d collatz.jar collatz.scala
+
+object CW6a { // for purposes of generating a jar
+
+def collatz(n: Long): Long =
+ if (n == 1) 0 else
+ if (n % 2 == 0) 1 + collatz(n / 2) else
+ 1 + collatz(3 * n + 1)
+
+
+def collatz_max(bnd: Long): (Long, Long) = {
+ val all = for (i <- (1L to bnd)) yield (collatz(i), i)
+ all.maxBy(_._1)
+}
+
+//collatz_max(1000000)
+//collatz_max(10000000)
+//collatz_max(100000000)
+
+/* some test cases
+val bnds = List(10, 100, 1000, 10000, 100000, 1000000)
+
+for (bnd <- bnds) {
+ val (steps, max) = collatz_max(bnd)
+ println(s"In the range of 1 - ${bnd} the number ${max} needs the maximum steps of ${steps}")
+}
+
+*/
+
+def is_pow(n: Long) : Boolean = (n & (n - 1)) == 0
+
+def is_hard(n: Long) : Boolean = is_pow(3 * n + 1)
+
+def last_odd(n: Long) : Long =
+ if (is_hard(n)) n else
+ if (n % 2 == 0) last_odd(n / 2) else
+ last_odd(3 * n + 1)
+
+
+//for (i <- 130 to 10000) println(s"$i: ${last_odd(i)}")
+for (i <- 1 to 100) println(s"$i: ${collatz(i)}")
+
+}
+
+
+
Binary file pre_templates1/collatz.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_templates1/collatz.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,43 @@
+// Preliminary Part about the 3n+1 conjecture
+//============================================
+
+object CW6a {
+
+//(1) Complete the collatz function below. It should
+// recursively calculate the number of steps needed
+// until the collatz series reaches the number 1.
+// If needed, you can use an auxiliary function that
+// performs the recursion. The function should expect
+// arguments in the range of 1 to 1 Million.
+
+def collatz(n: Long) : Long = ???
+
+
+//(2) Complete the collatz_max function below. It should
+// calculate how many steps are needed for each number
+// from 1 up to a bound and then calculate the maximum number of
+// steps and the corresponding number that needs that many
+// steps. Again, you should expect bounds in the range of 1
+// up to 1 Million. The first component of the pair is
+// the maximum number of steps and the second is the
+// corresponding number.
+
+def collatz_max(bnd: Long) : (Long, Long) = ???
+
+//(3) Implement a function that calculates the last_odd
+// number in a collatz series. For this implement an
+// is_pow_of_two function which tests whether a number
+// is a power of two. The function is_hard calculates
+// whether 3n + 1 is a power of two. Again you can
+// assume the input ranges between 1 and 1 Million,
+// and also assume that the input of last_odd will not
+// be a power of 2.
+
+def is_pow_of_two(n: Long) : Boolean = ???
+
+def is_hard(n: Long) : Boolean = ???
+
+def last_odd(n: Long) : Long = ???
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_testing1/collatz.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,37 @@
+object CW6a {
+
+//(1) Complete the collatz function below. It should
+// recursively calculate the number of steps needed
+// until the collatz series reaches the number 1.
+// If needed, you can use an auxiliary function that
+// performs the recursion. The function should expect
+// arguments in the range of 1 to 1 Million.
+def stepsCounter(n: Long, s: Long) : Long = n match{
+ case 1 => s
+ case n if(n%2==0) => stepsCounter(n/2,s+1)
+ case _ => stepsCounter(3*n+1, s+1)
+}
+
+def collatz(n: Long) : Long = n match {
+ case n if(n>0) => stepsCounter(n,0)
+ case n if(n<=0) => stepsCounter(1,0)
+}
+
+
+
+//(2) Complete the collatz_max function below. It should
+// calculate how many steps are needed for each number
+// from 1 up to a bound and then calculate the maximum number of
+// steps and the corresponding number that needs that many
+// steps. Again, you should expect bounds in the range of 1
+// up to 1 Million. The first component of the pair is
+// the maximum number of steps and the second is the
+// corresponding number.
+
+def collatz_max(bnd: Long) : (Long, Long) = {
+ val allCollatz = for(i<-1L until bnd) yield collatz(i)
+ val pair = (allCollatz.max, (allCollatz.indexOf(allCollatz.max) +1).toLong)
+ pair
+}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_testing1/collatz_test.sh Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+# to make the script fail safely
+set -euo pipefail
+
+
+out=${1:-output}
+
+echo -e "" > $out
+
+echo -e "Below is the feedback for your submission collatz.scala" >> $out
+echo -e "" >> $out
+
+
+# compilation tests
+
+function scala_compile {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala "$1" 2>> $out 1>> $out)
+}
+
+# functional tests
+
+function scala_assert {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
+}
+
+# purity test
+
+function scala_vars {
+ (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|collection.mutable|util.control|new Array' "$1" 2> /dev/null 1> /dev/null)
+}
+
+
+# var, .par return, ListBuffer test
+#
+echo -e "collatz.scala does not contain vars, returns etc?" >> $out
+
+if (scala_vars collatz.scala)
+then
+ echo -e " --> FAIL (make triple-sure your program conforms to the required format)\n" >> $out
+ tsts0=$(( 0 ))
+else
+ echo -e " --> success" >> $out
+ tsts0=$(( 0 ))
+fi
+
+### compilation test
+
+
+if [ $tsts0 -eq 0 ]
+then
+ echo -e "collatz.scala runs?" >> $out
+
+ if (scala_compile collatz.scala)
+ then
+ echo -e " --> success" >> $out
+ tsts=$(( 0 ))
+ else
+ echo -e " --> SCALA DID NOT RUN COLLATZ.SCALA\n" >> $out
+ tsts=$(( 1 ))
+ fi
+else
+ tsts=$(( 1 ))
+fi
+
+### collatz tests
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "collatz.scala tests:" >> $out
+ echo -e " collatz(1) == 0" >> $out
+ echo -e " collatz(6) == 8" >> $out
+ echo -e " collatz(9) == 19" >> $out
+
+ if (scala_assert "collatz.scala" "collatz_test1.scala")
+ then
+ echo -e " --> success" >> $out
+ else
+ echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
+ fi
+fi
+
+### collatz-max tests
+
+if [ $tsts -eq 0 ]
+then
+ echo -e " collatz_max(10) == (19, 9)" >> $out
+ echo -e " collatz_max(100) == (118, 97)" >> $out
+ echo -e " collatz_max(1000) == (178, 871)" >> $out
+ echo -e " collatz_max(10000) == (261, 6171)" >> $out
+ echo -e " collatz_max(100000) == (350, 77031)" >> $out
+ echo -e " collatz_max(1000000) == (524, 837799)" >> $out
+
+ if (scala_assert "collatz.scala" "collatz_test2.scala")
+ then
+ echo -e " --> success" >> $out
+ else
+ echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
+ fi
+fi
+
+
+### last-odd tests
+
+if [ $tsts -eq 0 ]
+then
+ echo -e " last_odd(113) == 85" >> $out
+ echo -e " last_odd(84) == 21" >> $out
+ echo -e " last_odd(605) == 341" >> $out
+
+ if (scala_assert "collatz.scala" "collatz_test3.scala")
+ then
+ echo -e " --> success" >> $out
+ else
+ echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
+ fi
+fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_testing1/collatz_test1.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,8 @@
+
+import CW6a._
+
+assert(collatz(1) == 0)
+assert(collatz(6) == 8)
+assert(collatz(9) == 19)
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_testing1/collatz_test2.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,8 @@
+import CW6a._
+
+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))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pre_testing1/collatz_test3.scala Sat Oct 31 16:47:46 2020 +0000
@@ -0,0 +1,4 @@
+
+assert(CW6a.last_odd(113) == 85)
+assert(CW6a.last_odd(84) == 21)
+assert(CW6a.last_odd(605) == 341)
Binary file solutions1/collatz.jar has changed
--- a/solutions1/collatz.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Basic Part about the 3n+1 conjecture
-//==================================
-
-// generate jar with
-// > scala -d collatz.jar collatz.scala
-
-object CW6a { // for purposes of generating a jar
-
-def collatz(n: Long): Long =
- if (n == 1) 0 else
- if (n % 2 == 0) 1 + collatz(n / 2) else
- 1 + collatz(3 * n + 1)
-
-
-def collatz_max(bnd: Long): (Long, Long) = {
- val all = for (i <- (1L to bnd)) yield (collatz(i), i)
- all.maxBy(_._1)
-}
-
-//collatz_max(1000000)
-//collatz_max(10000000)
-//collatz_max(100000000)
-
-/* some test cases
-val bnds = List(10, 100, 1000, 10000, 100000, 1000000)
-
-for (bnd <- bnds) {
- val (steps, max) = collatz_max(bnd)
- println(s"In the range of 1 - ${bnd} the number ${max} needs the maximum steps of ${steps}")
-}
-
-*/
-
-def is_pow(n: Long) : Boolean = (n & (n - 1)) == 0
-
-def is_hard(n: Long) : Boolean = is_pow(3 * n + 1)
-
-def last_odd(n: Long) : Long =
- if (is_hard(n)) n else
- if (n % 2 == 0) last_odd(n / 2) else
- last_odd(3 * n + 1)
-
-
-//for (i <- 130 to 10000) println(s"$i: ${last_odd(i)}")
-for (i <- 1 to 100) println(s"$i: ${collatz(i)}")
-
-}
-
-
-
Binary file templates1/collatz.jar has changed
--- a/templates1/collatz.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-// Preliminary Part about the 3n+1 conjecture
-//============================================
-
-object CW6a {
-
-//(1) Complete the collatz function below. It should
-// recursively calculate the number of steps needed
-// until the collatz series reaches the number 1.
-// If needed, you can use an auxiliary function that
-// performs the recursion. The function should expect
-// arguments in the range of 1 to 1 Million.
-
-def collatz(n: Long) : Long = ???
-
-
-//(2) Complete the collatz_max function below. It should
-// calculate how many steps are needed for each number
-// from 1 up to a bound and then calculate the maximum number of
-// steps and the corresponding number that needs that many
-// steps. Again, you should expect bounds in the range of 1
-// up to 1 Million. The first component of the pair is
-// the maximum number of steps and the second is the
-// corresponding number.
-
-def collatz_max(bnd: Long) : (Long, Long) = ???
-
-//(3) Implement a function that calculates the last_odd
-// number in a collatz series. For this implement an
-// is_pow_of_two function which tests whether a number
-// is a power of two. The function is_hard calculates
-// whether 3n + 1 is a power of two. Again you can
-// assume the input ranges between 1 and 1 Million,
-// and also assume that the input of last_odd will not
-// be a power of 2.
-
-def is_pow_of_two(n: Long) : Boolean = ???
-
-def is_hard(n: Long) : Boolean = ???
-
-def last_odd(n: Long) : Long = ???
-
-}
-
--- a/testing1/collatz.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-object CW6a {
-
-//(1) Complete the collatz function below. It should
-// recursively calculate the number of steps needed
-// until the collatz series reaches the number 1.
-// If needed, you can use an auxiliary function that
-// performs the recursion. The function should expect
-// arguments in the range of 1 to 1 Million.
-def stepsCounter(n: Long, s: Long) : Long = n match{
- case 1 => s
- case n if(n%2==0) => stepsCounter(n/2,s+1)
- case _ => stepsCounter(3*n+1, s+1)
-}
-
-def collatz(n: Long) : Long = n match {
- case n if(n>0) => stepsCounter(n,0)
- case n if(n<=0) => stepsCounter(1,0)
-}
-
-
-
-//(2) Complete the collatz_max function below. It should
-// calculate how many steps are needed for each number
-// from 1 up to a bound and then calculate the maximum number of
-// steps and the corresponding number that needs that many
-// steps. Again, you should expect bounds in the range of 1
-// up to 1 Million. The first component of the pair is
-// the maximum number of steps and the second is the
-// corresponding number.
-
-def collatz_max(bnd: Long) : (Long, Long) = {
- val allCollatz = for(i<-1L until bnd) yield collatz(i)
- val pair = (allCollatz.max, (allCollatz.indexOf(allCollatz.max) +1).toLong)
- pair
-}
-
-}
--- a/testing1/collatz_test.sh Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-#!/bin/bash
-
-# to make the script fail safely
-set -euo pipefail
-
-
-out=${1:-output}
-
-echo -e "" > $out
-
-echo -e "Below is the feedback for your submission collatz.scala" >> $out
-echo -e "" >> $out
-
-
-# compilation tests
-
-function scala_compile {
- (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala "$1" 2>> $out 1>> $out)
-}
-
-# functional tests
-
-function scala_assert {
- (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala -i "$1" -- "$2" -e "" 2> /dev/null 1> /dev/null)
-}
-
-# purity test
-
-function scala_vars {
- (egrep '\bvar\b|\breturn\b|\.par|ListBuffer|collection.mutable|util.control|new Array' "$1" 2> /dev/null 1> /dev/null)
-}
-
-
-# var, .par return, ListBuffer test
-#
-echo -e "collatz.scala does not contain vars, returns etc?" >> $out
-
-if (scala_vars collatz.scala)
-then
- echo -e " --> FAIL (make triple-sure your program conforms to the required format)\n" >> $out
- tsts0=$(( 0 ))
-else
- echo -e " --> success" >> $out
- tsts0=$(( 0 ))
-fi
-
-### compilation test
-
-
-if [ $tsts0 -eq 0 ]
-then
- echo -e "collatz.scala runs?" >> $out
-
- if (scala_compile collatz.scala)
- then
- echo -e " --> success" >> $out
- tsts=$(( 0 ))
- else
- echo -e " --> SCALA DID NOT RUN COLLATZ.SCALA\n" >> $out
- tsts=$(( 1 ))
- fi
-else
- tsts=$(( 1 ))
-fi
-
-### collatz tests
-
-if [ $tsts -eq 0 ]
-then
- echo -e "collatz.scala tests:" >> $out
- echo -e " collatz(1) == 0" >> $out
- echo -e " collatz(6) == 8" >> $out
- echo -e " collatz(9) == 19" >> $out
-
- if (scala_assert "collatz.scala" "collatz_test1.scala")
- then
- echo -e " --> success" >> $out
- else
- echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
- fi
-fi
-
-### collatz-max tests
-
-if [ $tsts -eq 0 ]
-then
- echo -e " collatz_max(10) == (19, 9)" >> $out
- echo -e " collatz_max(100) == (118, 97)" >> $out
- echo -e " collatz_max(1000) == (178, 871)" >> $out
- echo -e " collatz_max(10000) == (261, 6171)" >> $out
- echo -e " collatz_max(100000) == (350, 77031)" >> $out
- echo -e " collatz_max(1000000) == (524, 837799)" >> $out
-
- if (scala_assert "collatz.scala" "collatz_test2.scala")
- then
- echo -e " --> success" >> $out
- else
- echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
- fi
-fi
-
-
-### last-odd tests
-
-if [ $tsts -eq 0 ]
-then
- echo -e " last_odd(113) == 85" >> $out
- echo -e " last_odd(84) == 21" >> $out
- echo -e " last_odd(605) == 341" >> $out
-
- if (scala_assert "collatz.scala" "collatz_test3.scala")
- then
- echo -e " --> success" >> $out
- else
- echo -e " --> ONE OF THE TESTS FAILED\n" >> $out
- fi
-fi
--- a/testing1/collatz_test1.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-
-import CW6a._
-
-assert(collatz(1) == 0)
-assert(collatz(6) == 8)
-assert(collatz(9) == 19)
-
-
--- a/testing1/collatz_test2.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-import CW6a._
-
-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))
--- a/testing1/collatz_test3.scala Sat Oct 31 16:23:12 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-
-assert(CW6a.last_odd(113) == 85)
-assert(CW6a.last_odd(84) == 21)
-assert(CW6a.last_odd(605) == 341)