-
Notifications
You must be signed in to change notification settings - Fork 0
/
Euler7.scala
191 lines (160 loc) · 4.78 KB
/
Euler7.scala
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// https://projecteuler.net/problem=7
import scala.collection.mutable.ListBuffer
object Euler7 {
// timer function at the top of every solution: http://biercoff.com/easily-measuring-code-execution-time-in-scala/
def time[R](block: => R): R = {
val t0 = System.nanoTime()
val result = block
val t1 = System.nanoTime()
println("Elapsed time: " + ((t1 - t0) / 1000000.0) + "ms")
result
}
def allPrimesToNBig(n: BigInt): ListBuffer[BigInt] = {
// All prime numbers to a given BigInt
var allPrimes: ListBuffer[BigInt] = ListBuffer(2L)
// Except 2, only odds can be prime, so just prepend 2 to final answer, save 50% already
var initRange: List[BigInt] = List.range(3, n, 2)
while(initRange.length >= 1) {
val firstNumLeft = initRange.head
allPrimes = allPrimes += firstNumLeft
initRange = initRange.filterNot(initRange => initRange % firstNumLeft == 0)
}
allPrimes
}
def allPrimesToN(n: Int): ListBuffer[Int] = {
// All prime numbers to a given Int
// Ended up not really using this, but keeping it for record of thought process.
var allPrimes: ListBuffer[Int] = ListBuffer(2)
// Except 2, only odds can be prime, so just prepend 2 to final answer, save 50% already
var initRange: List[Int] = List.range(3, n, 2)
while(initRange.length >= 1) {
val firstNumLeft = initRange.head
allPrimes = allPrimes += firstNumLeft
initRange = initRange.filterNot(initRange => initRange % firstNumLeft == 0)
}
allPrimes
}
def allPrimesToN_v1(n: Int): ListBuffer[Int] = {
// All prime numbers to a given Int
// Ended up not really using this, but keeping it for record of thought process.
val allPrimes: ListBuffer[Int] = ListBuffer(2)
// Except 2, only odds can be prime, so just prepend 2 to final answer, save 50% already
var initRange: List[Int] = List.range(3, n, 2)
while(initRange.length >= 1) {
val firstNumLeft = initRange.head
allPrimes.append(firstNumLeft)
initRange = initRange.filterNot(initRange => initRange % firstNumLeft == 0)
}
allPrimes
}
def isXPrime(x: Int): Boolean = {
if (List(2,3).contains(x)) {
true
}
else if (x % 2 == 0) {
false
}
// Loop from 3 to sqrt(x) on odd numbers.
else {
val endVal: Int = math.ceil(math.sqrt(x)).toInt
var i: Int = 3
var prime: Boolean = true
while (prime == true & i <= endVal) {
if (x % i == 0) {
prime = false
}
i = i + 2
}
prime
}
}
def xthPrime(x: Int): Int = {
if (x == 1) {
2
}
var counter: Int = 1
var i: Int = 3
while (counter < x) {
if (isXPrime(i)) {
counter = counter + 1
}
if (counter < x) {
i = i + 2
}
}
i
}
def isXPrimeV1(x: Int): Boolean = {
if (List(2,3,5).contains(x)) {
true
}
else if (x % 2 == 0) {
false // no even number is a prime
}
else if (x % 6 == 3) {
false // all primes after 3 are in form x % 6 == 1 or 5
}
// Loop from 3 to sqrt(x) on odd numbers.
else {
val endVal: Int = math.ceil(math.sqrt(x)).toInt
var i: Int = 3
var prime: Boolean = true
while (prime == true & i <= endVal) {
if (x % i == 0) {
prime = false
}
i = i + 2
}
prime
}
}
def xthPrimeV1(x: Int): Int = {
if (x == 1) {
2
}
if (x == 2) {
3
}
var counter: Int = 2
var solution: Int = 3
var i: Int = 6
// skip by 6, check (i-1) and (i+1)
// a little help from https://www.xarg.org/puzzle/project-euler/problem-7/ pointing out 6k + 1 property
while (counter < x) {
if (isXPrimeV1(i - 1)) {
counter = counter + 1
if (counter == x) {
solution = i - 1
}
}
if (isXPrimeV1(i + 1) & counter < x) {
counter = counter + 1
if (counter == x) {
solution = i - 1
}
}
if (counter < x) {
i = i + 6
}
}
solution
}
def main(args: Array[String]): Unit = {
println("Solution 1: Use all primes to N function, manually iterate until length is 10,001. Then take last element")
time {println(allPrimesToNBig(104750L).last)}
// Elapsed time: 11649.774778ms
// But about 5 minutes to manually find a correct N to iterate to.
println("Solution 2: Use Int fuction since solution comfortably fits in Int data type.")
time {println(allPrimesToN(104750).last)}
// Elapsed time: 963.597641ms
println("Solution 3: Use Int function. Optimization on ListBuffer append method.")
time {println(allPrimesToN_v1(104750).last)}
// Elapsed time: 976.79323ms
println("Solution 4: Now iterate through a stream of odd integers, optimally check if each one is prime, and stop exactly on 10,001st.")
time{println(xthPrime(10001))}
// Elapsed time: 22.830978ms
println("Solution 5: Now iterate by 6, check +- 1 for prime. Slightly faster isXPrime func as well. Stop exactly on 10,001st.")
time{println(xthPrimeV1(10001))}
// Elapsed time: 21.675763ms
}
}