Skip to content

Commit 3c59597

Browse files
committedDec 12, 2014
Scala/ProjectEuler: Finish 1~50
1 parent 314df52 commit 3c59597

File tree

1 file changed

+216
-23
lines changed

1 file changed

+216
-23
lines changed
 

‎Scala/ProjectEuler/Puzzle_1_50.scala

+216-23
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ object Helper {
2121
}
2222
a
2323
}
24-
def isPrime(n : Int) = mPrimeBuffer(n) == 1
24+
def isPrime(n : Int) : Boolean = {
25+
if (n < kMaxPrimeValue) mPrimeBuffer(n) == 1
26+
else BigInt(n).isProbablePrime(20)
27+
}
2528
val primes : Stream[Int] = Stream.from(2) filter isPrime
2629

2730
def group[T](a : List[T]) : List[(T, Int)] = {
@@ -128,27 +131,55 @@ object Helper {
128131
}
129132
}
130133

131-
def intToArray(a : Array[Int], n : Int) : Int = {
134+
def longToArray(a : Array[Int], n : Long) : Int = {
132135
var len = 0
133136
var tn = n
134137
while (tn > 0) {
135-
a(len) = tn % 10
138+
a(len) = (tn % 10).toInt
136139
len += 1
137140
tn /= 10
138141
}
139142
reverse(a, 0, len)
140143
len
141144
}
142145

143-
def arrayToInt(a : Array[Int], begin : Int, end : Int, step : Int = 1) : Int = {
146+
def arrayToLong(a : Array[Int], begin : Int, end : Int, step : Int = 1) : Long = {
144147
var i = begin
145-
var sum = 0
148+
var sum = 0L
146149
while (i != end) {
147150
sum = sum * 10 + a(i)
148151
i += step
149152
}
150153
sum
151154
}
155+
156+
def permutation[T](a : Array[T], f : Array[T] => Unit) {
157+
def iterate(i : Int) {
158+
if (i == a.length) f(a)
159+
else {
160+
for (j <- (i until a.length)) {
161+
{ val t = a(i); a(i) = a(j); a(j) = t }
162+
iterate(i + 1);
163+
{ val t = a(i); a(i) = a(j); a(j) = t }
164+
}
165+
}
166+
}
167+
iterate(0)
168+
}
169+
170+
def combination[T](a : Array[T], n : Int, f : Array[T] => Unit) {
171+
val tempArray = a.clone
172+
def iterate(ia : Int, itemp : Int) {
173+
if (itemp == n) f(tempArray)
174+
else if (ia == a.length) {}
175+
else {
176+
tempArray(itemp) = a(ia)
177+
iterate(ia + 1, itemp + 1)
178+
iterate(ia + 1, itemp)
179+
}
180+
}
181+
iterate(0, 0)
182+
}
152183
}
153184

154185
object Test extends App {
@@ -420,22 +451,9 @@ object Test extends App {
420451
if (begin == end) 0
421452
else toInt(a, begin, end - 1) * 10 + a(end - 1)
422453
}
423-
def perm(a : Array[Int], f : Array[Int] => Unit) {
424-
def iterate(i : Int) {
425-
if (i == a.length) f(a)
426-
else {
427-
for (j <- (i until a.length)) {
428-
{ val t = a(i); a(i) = a(j); a(j) = t }
429-
iterate(i + 1);
430-
{ val t = a(i); a(i) = a(j); a(j) = t }
431-
}
432-
}
433-
}
434-
iterate(0)
435-
}
436454

437455
var result = Set[Int]()
438-
perm((1 to 9).toArray, a => {
456+
Helper.permutation[Int]((1 to 9).toArray, a => {
439457
val n = toInt(a, 0, 4)
440458
val n2 = toInt(a, 4, 5)
441459
val n3 = toInt(a, 5, 9)
@@ -494,7 +512,7 @@ object Test extends App {
494512
def valid(n : Int) : Boolean = {
495513
if (!Helper.isPrime(n)) false
496514
else {
497-
val len = Helper.intToArray(tempArray, n)
515+
val len = Helper.longToArray(tempArray, n)
498516
var off = 0
499517
while (off < len) {
500518
val tn = loopArrayToInt(tempArray, off, len)
@@ -521,20 +539,182 @@ object Test extends App {
521539
def valid(n : Int) : Boolean = {
522540
if (!Helper.isPrime(n)) return false
523541

524-
val len = Helper.intToArray(tempArray, n)
542+
val len = Helper.longToArray(tempArray, n)
525543
for (begin <- (0 until len)) {
526-
val tn = Helper.arrayToInt(tempArray, begin, len, 1)
544+
val tn = Helper.arrayToLong(tempArray, begin, len, 1).toInt
527545
if (!Helper.isPrime(tn)) return false
528546
}
529547
for (end <- (1 to len)) {
530-
val tn = Helper.arrayToInt(tempArray, 0, end, 1)
548+
val tn = Helper.arrayToLong(tempArray, 0, end, 1).toInt
531549
if (!Helper.isPrime(tn)) return false
532550
}
533551
true
534552
}
535553

536554
Helper.primes.dropWhile(_ < 10).filter(valid).take(11).sum
537555
}
556+
def puzzle_38() : Int = {
557+
def valid(s : String) : Boolean = {
558+
val set = mutable.BitSet(s.map(_ - '0') : _*)
559+
set.size == 9 && !set(0)
560+
}
561+
(9000 until 10000) map (n => n.toString + n * 2) filter valid map (_.toInt) max
562+
}
563+
def puzzle_39() : Int = {
564+
val m = mutable.Map[Int, Int]()
565+
for (
566+
c <- (2 until 500);
567+
b <- (2 until c - 1);
568+
aa = c * c - b * b;
569+
if aa < b * b;
570+
a = math.sqrt(aa).toInt;
571+
if a * a == aa;
572+
p = a + b + c if p < 1000
573+
) {
574+
m(p) = 1 + m.getOrElse(p, 0)
575+
}
576+
m.maxBy(_._2)._1
577+
}
578+
def puzzle_40() : Int = {
579+
def d(n : Int) : Char = {
580+
def getIndexAndLen(i : Int, len : Int = 1) : (Int, Int) = {
581+
val totalDigit = (math.pow(10, len) - math.pow(10, len - 1)).toInt * len
582+
if (i >= totalDigit) getIndexAndLen(i - totalDigit, len + 1) else (i, len)
583+
}
584+
val (i, len) = getIndexAndLen(n)
585+
val numIdx = i / len
586+
val digitIdx = i % len
587+
(math.pow(10, len - 1) + numIdx).toString()(digitIdx)
588+
}
589+
590+
(0 to 6) map (v => d(math.pow(10, v).toInt - 1) - '0') product
591+
}
592+
def puzzle_41() : Int = {
593+
var max = 0
594+
595+
import scala.util.control.Breaks
596+
val label = new Breaks
597+
label.breakable {
598+
for (end <- ('2' to '9').reverse) {
599+
Helper.permutation[Char](('1' to end).reverse.toArray, a => {
600+
val n = new String(a).toInt
601+
if (Helper.isPrime(n)) {
602+
max = n
603+
label.break
604+
}
605+
})
606+
}
607+
}
608+
609+
max
610+
}
611+
def puzzle_42() : Int = {
612+
val nums = Stream.from(1).map(v => v * (v + 1) / 2)
613+
def valid(word : String) : Boolean = {
614+
val n = word.map(_ - 'A' + 1).sum
615+
nums.dropWhile(_ < n).head == n
616+
}
617+
618+
val words = """\"(\w+)\"""".r.findAllMatchIn(scala.io.Source.fromFile("words.txt").mkString).map(_.group(1))
619+
words filter valid length
620+
}
621+
def puzzle_43() : Long = {
622+
def valid(a : Array[Int]) : Boolean = {
623+
def iterate(i : Int, primes : Stream[Int]) : Boolean = {
624+
if (i == 8) true
625+
else if (Helper.arrayToLong(a, i, i + 3) % primes.head == 0) iterate(i + 1, primes.tail)
626+
else false
627+
}
628+
iterate(1, Helper.primes)
629+
}
630+
631+
var nums = List[Long]()
632+
Helper.permutation[Int]((0 to 9).toArray, a => {
633+
if (valid(a)) nums = Helper.arrayToLong(a, 0, a.length, 1) :: nums
634+
})
635+
nums.sum
636+
}
637+
def puzzle_44() : Int = {
638+
def valid(r : Long) : Boolean = {
639+
val sqrtbbp4ac = math.sqrt(1 + 24 * r)
640+
((1 + sqrtbbp4ac) / 6).isValidInt
641+
}
642+
643+
val nums = Stream.range(1L, 2000L).map(v => v * (3 * v - 1) / 2)
644+
(for (
645+
d <- nums;
646+
j <- nums;
647+
k = d + j;
648+
if valid(k) && valid(j + k)
649+
) yield d).head.toInt
650+
}
651+
def puzzle_45() : Long = {
652+
def isTriangle(n : Long) : Boolean = {
653+
val sqrtbbp4ac = math.sqrt(1 + 8 * n)
654+
((-1 + sqrtbbp4ac) / 2).isValidInt
655+
}
656+
def isPentagonal(n : Long) : Boolean = {
657+
val sqrtbbp4ac = math.sqrt(1 + 24 * n)
658+
((1 + sqrtbbp4ac) / 6).isValidInt
659+
}
660+
Stream.from(144).map(v => v * (2 * v - 1)).filter(v => isTriangle(v) && isPentagonal(v)).head
661+
}
662+
def puzzle_46() : Int = {
663+
def isOddComposite(n : Int) : Boolean = {
664+
n % 2 == 1 && Helper.isPrime(n)
665+
}
666+
def diff(s1 : Stream[Int], s2 : Stream[Int]) : Stream[Int] = {
667+
if (s1.head == s2.head) diff(s1.tail, s2.tail)
668+
else if (s1.head < s2.head) s1.head #:: diff(s1.tail, s2)
669+
else diff(s1, s2.tail)
670+
}
671+
672+
val validNums = Helper.mergeStream[Int](Stream.from(1).map(v => v * v * 2), Helper.primes,
673+
(a, b) => a._1 + a._2 < b._1 + b._2).map(v => v._1 + v._2)
674+
diff(Stream.from(3).filter(v => v % 2 == 1 && !Helper.isPrime(v)), validNums).head
675+
}
676+
def puzzle_47() : Int = {
677+
val counts = Array.fill(140000)(0)
678+
for (
679+
p <- Helper.primes.takeWhile(_ < counts.length);
680+
i <- (p + p until counts.length by p)
681+
) {
682+
counts(i) += 1
683+
}
684+
685+
Stream.from(1).sliding(4).filter(l => l.forall(i => counts(i) == 4)).next()(0)
686+
}
687+
def puzzle_48() : String = {
688+
val s = ((1 to 1000) map (i => BigInt(i).pow(i)) sum).toString
689+
s.substring(s.length - 10)
690+
}
691+
def puzzle_49() : String = {
692+
val m = Helper.primes.dropWhile(_ < 1000).takeWhile(_ < 10000).toList.groupBy(v => v.toString.sorted)
693+
(for (
694+
(_, nums) <- m;
695+
a <- nums;
696+
b <- nums if a < b;
697+
c <- nums if b < c && b - a == c - b
698+
) yield a.toString + b + c).head
699+
}
700+
def puzzle_50() : Int = {
701+
val validPrimes = Helper.primes.takeWhile(_ < 50000)
702+
lazy val primeSums : Stream[Int] = 0 #:: primeSums.zip(validPrimes).map { case (i, j) => i + j }
703+
val sumTable = primeSums.toArray
704+
705+
def findWithLength(len : Int) : Int = {
706+
def iterate(i : Int) : Int = {
707+
if (i + len >= sumTable.length) 0
708+
else {
709+
val n = sumTable(i + len) - sumTable(i)
710+
if (n < 1000000 && Helper.isPrime(n)) n else iterate(i + 1)
711+
}
712+
}
713+
iterate(0)
714+
}
715+
716+
Stream.range(validPrimes.length, 22, -1).map(findWithLength).dropWhile(_ == 0).head
717+
}
538718

539719
Utils.timeit("1-15", 1) {
540720
assert(puzzle_1() == 233168)
@@ -578,6 +758,19 @@ object Test extends App {
578758
assert(puzzle_35() == 55)
579759
assert(puzzle_36() == 872187)
580760
assert(puzzle_37() == 748317)
761+
assert(puzzle_38() == 932718654)
762+
assert(puzzle_39() == 840)
763+
assert(puzzle_40() == 210)
764+
assert(puzzle_41() == 7652413)
765+
assert(puzzle_42() == 162)
766+
assert(puzzle_43() == 16695334890L)
767+
assert(puzzle_44() == 5482660)
768+
assert(puzzle_45() == 1533776805L)
769+
assert(puzzle_46() == 5777)
770+
assert(puzzle_47() == 134043)
771+
assert(puzzle_48() == "9110846700")
772+
assert(puzzle_49() == "296962999629")
773+
assert(puzzle_50() == 997651)
581774
}
582775

583776
println("pass!")

0 commit comments

Comments
 (0)