@@ -21,7 +21,10 @@ object Helper {
21
21
}
22
22
a
23
23
}
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
+ }
25
28
val primes : Stream [Int ] = Stream .from(2 ) filter isPrime
26
29
27
30
def group [T ](a : List [T ]) : List [(T , Int )] = {
@@ -128,27 +131,55 @@ object Helper {
128
131
}
129
132
}
130
133
131
- def intToArray (a : Array [Int ], n : Int ) : Int = {
134
+ def longToArray (a : Array [Int ], n : Long ) : Int = {
132
135
var len = 0
133
136
var tn = n
134
137
while (tn > 0 ) {
135
- a(len) = tn % 10
138
+ a(len) = ( tn % 10 ).toInt
136
139
len += 1
137
140
tn /= 10
138
141
}
139
142
reverse(a, 0 , len)
140
143
len
141
144
}
142
145
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 = {
144
147
var i = begin
145
- var sum = 0
148
+ var sum = 0L
146
149
while (i != end) {
147
150
sum = sum * 10 + a(i)
148
151
i += step
149
152
}
150
153
sum
151
154
}
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
+ }
152
183
}
153
184
154
185
object Test extends App {
@@ -420,22 +451,9 @@ object Test extends App {
420
451
if (begin == end) 0
421
452
else toInt(a, begin, end - 1 ) * 10 + a(end - 1 )
422
453
}
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
- }
436
454
437
455
var result = Set [Int ]()
438
- perm ((1 to 9 ).toArray, a => {
456
+ Helper .permutation[ Int ] ((1 to 9 ).toArray, a => {
439
457
val n = toInt(a, 0 , 4 )
440
458
val n2 = toInt(a, 4 , 5 )
441
459
val n3 = toInt(a, 5 , 9 )
@@ -494,7 +512,7 @@ object Test extends App {
494
512
def valid (n : Int ) : Boolean = {
495
513
if (! Helper .isPrime(n)) false
496
514
else {
497
- val len = Helper .intToArray (tempArray, n)
515
+ val len = Helper .longToArray (tempArray, n)
498
516
var off = 0
499
517
while (off < len) {
500
518
val tn = loopArrayToInt(tempArray, off, len)
@@ -521,20 +539,182 @@ object Test extends App {
521
539
def valid (n : Int ) : Boolean = {
522
540
if (! Helper .isPrime(n)) return false
523
541
524
- val len = Helper .intToArray (tempArray, n)
542
+ val len = Helper .longToArray (tempArray, n)
525
543
for (begin <- (0 until len)) {
526
- val tn = Helper .arrayToInt (tempArray, begin, len, 1 )
544
+ val tn = Helper .arrayToLong (tempArray, begin, len, 1 ).toInt
527
545
if (! Helper .isPrime(tn)) return false
528
546
}
529
547
for (end <- (1 to len)) {
530
- val tn = Helper .arrayToInt (tempArray, 0 , end, 1 )
548
+ val tn = Helper .arrayToLong (tempArray, 0 , end, 1 ).toInt
531
549
if (! Helper .isPrime(tn)) return false
532
550
}
533
551
true
534
552
}
535
553
536
554
Helper .primes.dropWhile(_ < 10 ).filter(valid).take(11 ).sum
537
555
}
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
+ }
538
718
539
719
Utils .timeit(" 1-15" , 1 ) {
540
720
assert(puzzle_1() == 233168 )
@@ -578,6 +758,19 @@ object Test extends App {
578
758
assert(puzzle_35() == 55 )
579
759
assert(puzzle_36() == 872187 )
580
760
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 )
581
774
}
582
775
583
776
println(" pass!" )
0 commit comments