-
Notifications
You must be signed in to change notification settings - Fork 14
/
Collatz.java
121 lines (104 loc) · 3.55 KB
/
Collatz.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import java.math.BigInteger;
import java.util.concurrent.TimeUnit;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//@include
// Performs basic unit of work
class MyRunnable implements Runnable {
public int lower;
public int upper;
MyRunnable(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
@Override
public void run() {
for (int i = lower; i <= upper; ++i) {
Collatz.CollatzCheck(i, new HashSet<BigInteger>());
}
System.out.println("(" + lower + "," + upper + ")" );
}
}
//@exclude
// @include
public class Collatz {
// Checks an individual number
public static boolean CollatzCheck(BigInteger x, Set<BigInteger> visited) {
if (x.equals(BigInteger.ONE)) {
return true;
} else if (visited.contains(x)) {
return false;
}
visited.add(x);
if (x.getLowestSetBit() == 1) { // odd number
return CollatzCheck(
(new BigInteger("3")).multiply(x).add(BigInteger.ONE), visited);
} else { // even number
return CollatzCheck(x.shiftRight(1), visited); // divide by 2
}
}
public static boolean CollatzCheck(int x, Set<BigInteger> visited) {
BigInteger b = new BigInteger(new Integer(x).toString());
return CollatzCheck(b, visited);
}
// @exclude
static int N = 10000000;
static int RANGESIZE = 1000000;
static int NTHREADS = 4;
static void parseArgs(String [] args) {
if (args.length >= 1) {
N = Integer.parseInt(args[0]);
}
if (args.length >= 2) {
RANGESIZE = Integer.parseInt(args[1]);
}
if (args.length >= 3) {
NTHREADS = Integer.parseInt(args[2]);
}
}
public static void maintest(String [] args ) {
System.out.println("CollatzCheck(1): " + CollatzCheck(new BigInteger("1"),
new HashSet<BigInteger>()));
System.out.println("CollatzCheck(3): " + CollatzCheck(new BigInteger("3"),
new HashSet<BigInteger>()));
System.out.println("CollatzCheck(8): " + CollatzCheck(new BigInteger("8"),
new HashSet<BigInteger>()));
parseArgs(args);
}
//@include
public static ExecutorService execute() {
// Uses the Executor framework for task assignment and load balancing
List<Thread> threads = new ArrayList<Thread>();
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for (int i = 0 ; i < (N / RANGESIZE); ++i) {
Runnable worker = new MyRunnable(i * RANGESIZE + 1,
(i + 1) * RANGESIZE);
executor.execute(worker);
}
executor.shutdown();
return executor;
}
//@exclude
public static void main(String [] args) {
long lDateTime = new Date().getTime();
parseArgs(args);
ExecutorService executor = execute();
// while (!executor.isTerminated() ) {
// }
try {
while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {}
} catch (Exception e) { e.printStackTrace(); }
System.out.println("Finished all threads");
long fDateTime = new Date().getTime();
System.out.println("time in milliseconds for checking to " + N + " is " +
(fDateTime - lDateTime ) +
" (" + N/(fDateTime - lDateTime ) + " per ms)" );
}
//@include
}
//@exclude