author | Christian Urban <urbanc@in.tum.de> |
Thu, 17 Nov 2016 03:10:44 +0000 | |
changeset 55 | 6610c1dfa8a9 |
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)) |