| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Sat, 29 Aug 2020 16:05:59 +0100 | |
| changeset 342 | 3779dd003077 | 
| parent 50 | 9891c9fac37e | 
| permissions | -rw-r--r-- | 
| 47 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 1 | // Part 1 about the 3n+1 conceture | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 2 | //================================= | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 3 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 4 | //(1) Complete the collatz function below. It should | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 5 | // recursively calculate the number of steps needed | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 6 | // until the collatz series reaches the number 1. | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 7 | // If needed you can use an auxilary function that | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 8 | // performs the recursion. The function should expect | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 9 | // arguments in the range of 1 to 1 Million. | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 10 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 11 | def collatz(n: Long): List[Long] = | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 12 | if (n == 1) List(1) else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 13 | if (n % 2 == 0) (n::collatz(n / 2)) else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 14 | (n::collatz(3 * n + 1)) | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 15 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 16 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 17 | // an alternative that calculates the steps directly | 
| 50 | 18 | def collatz1(n: Long): Long = | 
| 47 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 19 | if (n == 1) 1 else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 20 | if (n % 2 == 0) (1 + collatz1(n / 2)) else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 21 | (1 + collatz1(3 * n + 1)) | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 22 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 23 | import scala.annotation.tailrec | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 24 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 25 | @tailrec | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 26 | def collatz2(n: Long, acc: Long): Long = | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 27 | if (n == 1) acc else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 28 | if (n % 2 == 0) collatz2(n / 2, acc + 1) else | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 29 | collatz2(3 * n + 1, acc + 1) | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 30 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 31 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 32 | //(2) Complete the collatz bound function below. It should | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 33 | // calculuate how many steps are needed for each number | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 34 | // from 1 upto a bound and return the maximum number of | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 35 | // steps and the corresponding number that needs that many | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 36 | // steps. You should expect bounds in the range of 1 | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 37 | // upto 1 million. | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 38 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 39 | def collatz_max(bnd: Long): (Long, Long) = {
 | 
| 50 | 40 | (1L to bnd).view.map((i) => (collatz1(i), i)).maxBy(_._1) | 
| 47 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 41 | } | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 42 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 43 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 44 | // some testing harness | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 45 | //val bnds = List(10, 100, 1000, 10000, 100000, 1000000) | 
| 50 | 46 | val bnds = List(10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 2000000000) | 
| 47 | ||
| 48 | ||
| 47 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 49 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 50 | for (bnd <- bnds) {
 | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 51 | val (steps, max) = collatz_max(bnd) | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 52 |   println(s"In the range of 1 - ${bnd} the number ${max} needs the maximum steps of ${steps}")
 | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 53 | } | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 54 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 55 | |
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 56 | //val all = for (i <- (1 to 100000).toList) yield collatz1(i) | 
| 
70306f6c65b1
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 57 | //println(all.sorted.reverse.take(10)) |