Six Prime Number Sequence Advent Calendar 2018 Java Edition

This article will be "Sikshiku Prime Number Sequence Advent Calendar 2018" Day 2.

For details, see the corresponding page of the Advent calendar. If you summarize the problem contents roughly, "When a positive integer N of 100 or less is given, find the Nth" sick prime number "and output it separated by commas. Do it. " "Sick prime number" refers to a prime number of 4 or 9.

Since it is a simple problem, I think there are various solutions, but for the time being, if there is an API that meets the following external specifications, it seems that the answer to the problem can be obtained by combining these.

  1. hasFourOrNine: When a natural number x is given as an argument, it returns true if x contains 4 or 9, otherwise false.
  2. ʻisPrime`: When a natural number x is given as an argument, it returns true if x is a prime number, false otherwise.
  3. solve: When a natural number n less than or equal to 100 is given as an argument, returns a character string in which the nth" squeaky prime number "is concatenated separated by commas.

Now, let's move on to implementation, but if it is a slightly older version of Java around Java 6 or Java 7, it should have been written as follows (although it is "somewhat old", Java systems are generally It lasts a long time, so if it's a version of this age, I think there are many that are still in operation ...)

Main1.java



public class Main1 {
    public static void main(String[] args) {
        int n = 100;
        System.out.println(solve(n));
    }
    
    public static String solve(int n) {
        StringBuilder answer = new StringBuilder();
        for (int x = 1; n > 0; x++) {
            if (isPrime(x) && hasFourOrNine(x)) {
                answer.append(x);
                if (--n > 0) {
                    answer.append(",");
                }
            }
        }
        return answer.toString();
    }
    
    public static boolean hasFourOrNine(int x) {
        while (x > 0) {
            int i = x % 10;
            if (i == 4 || i == 9) {
                return true;
            }
            x /= 10;
        }
        return false;
    }
    
    public static boolean isPrime(int x) {
        if (x < 2) {
            return false;
        }
        
        for (int i = 2; i <= Math.sqrt(x); i++) {
            if (x % i == 0) {
                return false;
            }
        }
        return true;
    }
}

The above example has a strong procedural programming tint, and the overall look is portrait. Let's rewrite it like 11 which is the latest version of Java as of today without changing the external specifications (although I do not use any Java 11-like functions ...)

Main2.java


import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main2 {
    public static void main(String[] args) {
        int n = 100;
        System.out.println(solve(n));
    }
    
    public static String solve(int n) {
        return IntStream.iterate(1, x -> x + 1)
                        .filter(Main2::isPrime)
                        .filter(Main2::hasFourOrNine)
                        .mapToObj(String::valueOf)
                        .limit(n)
                        .collect(Collectors.joining(","));
    }
    
    public static boolean hasFourOrNine(int x) {
        return IntStream.iterate(x, i -> i > 0, i -> i / 10)
                        .map(i -> i % 10)
                        .anyMatch(i -> i == 4 || i == 9);
    }
    
    public static boolean isPrime(int x) {
        return x >= 2 && IntStream.rangeClosed(2, (int)Math.sqrt(x)).allMatch(i -> x % i != 0);
    }
}

By making heavy use of the Stream API and lambda expressions, the vertical length has been shortened, and the overall horizontal code has been completed. It's not functional programming, but it introduces at least part of that paradigm.

"Readability" is important when programming, but it doesn't feel like readability at this length. However, the latter is the one that is fun and comfortable to write personally. Method chain becomes a habit (´ ・ ω ・ `)

Finally, the solution to the problem when n = 100 is shown below. However, in the specification of the problem, it was "comma separated", but for the sake of readability, it is shown below as "line feed separated". Please note.

19
29
41
43
47
59
79
89
97
109
139
149
179
191
193
197
199
229
239
241
269
293
347
349
359
379
389
397
401
409
419
421
431
433
439
443
449
457
461
463
467
479
487
491
499
509
541
547
569
593
599
619
641
643
647
659
691
709
719
739
743
769
797
809
829
839
859
907
911
919
929
937
941
947
953
967
971
977
983
991
997
1009
1019
1039
1049
1069
1091
1093
1097
1109
1129
1193
1229
1249
1259
1279
1289
1291
1297
1319

Recommended Posts

Six Prime Number Sequence Advent Calendar 2018 Java Edition
Japanese Advent Calendar Java Edition of Synthetic Sequences
Cheking Prime number --Java string program examples
java (random number)
[Java] Escape sequence