| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Sat, 07 Nov 2020 19:13:06 +0000 | |
| changeset 353 | 0913158ef452 | 
| 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))  |