Calendrier de l'avent de séquence de nombres premiers à six directions 2018 Édition Java

Cet article sera le "Calendrier de l'Avent Sick Prime Number Sequence 2018" Jour 2.

Pour plus de détails, reportez-vous à la page correspondante du calendrier de l'Avent. Si vous résumez le contenu du problème grossièrement, "Lorsqu'un entier positif N de 100 ou moins est donné, trouvez le Nième" nombre premier malade "et affichez-le séparé par des virgules. Fais le. " «Sick premier» fait référence à un nombre premier de 4 ou 9.

Puisqu'il s'agit d'un problème simple, je pense qu'il existe différentes solutions, mais pour le moment, s'il existe une API qui répond aux spécifications externes suivantes, il semble que la réponse au problème puisse être obtenue en les combinant.

  1. hasFourOrNine: Lorsqu'un entier naturel x est donné en argument, renvoie vrai si x contient 4 ou 9, sinon faux.
  2. ʻisPrime`: Quand un nombre naturel x est donné comme argument, renvoie vrai si x est un nombre premier, faux sinon.
  3. résoudre: Lorsqu'un entier naturel n de 100 ou moins est donné comme argument, renvoie une chaîne de caractères dans laquelle le nième" nombre premier shikusiku "est concaténé séparé par des virgules.

Maintenant, passons à l'implémentation, mais s'il s'agit d'une version légèrement plus ancienne de Java autour de Java 6 ou Java 7, elle aurait dû être écrite comme suit (bien qu'elle soit "légèrement ancienne", les systèmes Java sont généralement Ça dure longtemps, donc si c'est une version de cet âge, je pense qu'il y en a beaucoup qui fonctionnent encore ...)

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;
    }
}

L'exemple ci-dessus a une forte teinte de programmation procédurale, et l'apparence générale est portrait. Réécrivons-le comme 11 qui est la dernière version de Java à ce jour sans changer les spécifications externes (bien que je n'utilise aucune fonction de type Java 11 ...)

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);
    }
}

En faisant un usage intensif de l'API Stream et des expressions lambda, la longueur verticale a été raccourcie et le code horizontal global a été complété. Ce n'est pas une programmation fonctionnelle, mais cela introduit au moins une partie de ce paradigme.

La "lisibilité" est importante lors de la programmation, mais cela ne se sent pas comme une lisibilité à cette longueur ... Cependant, ce dernier est celui qui est amusant et confortable à écrire personnellement. La chaîne de méthodes devient une habitude (´ ・ ω ・ `)

Enfin, la solution au problème lorsque n = 100 est indiquée ci-dessous. Cependant, dans la spécification du problème, il était "séparé par des virgules", mais pour des raisons de lisibilité, il est indiqué ci-dessous par "séparé par des sauts de ligne". Notez s'il vous plaît.

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

Calendrier de l'avent de séquence de nombres premiers à six directions 2018 Édition Java
Calendrier de l'Avent japonais Édition Java de la colonne de nombres synthétiques
Cheking Prime number - Exemples de programmes de chaîne Java
java (nombre aléatoire)
[Java] Séquence d'échappement