Est-ce une tortue?


28

Comme nous le savons tous, ce sont des tortues tout le long . Mais est-ce aussi l'amorçage vers le bas?

Un nombre est considéré comme un "premier tortue" s'il remplit les conditions suivantes:

1) It is prime.
2) It is possible to remove a single digit leaving a prime number.
3) Step 2 can be repeated until left with a single digit prime.

Par exemple, 239est un "tortue-prime", car il peut être réduit à 23alors l'un 2ou l' autre 3, les deux étant premiers. Il peut également être réduit jusque- 292. 151n'est pas un nombre premier de tortue, car il se réduit à 15(pas premier), 51(pas premier), ou11 . 11est premier, mais ne peut que se réduire à 1, ce qui n'est pas le cas.

Etant donné un entier positif, déterminez s'il s'agit d'un "premier tortue". Votre sortie peut être sous n'importe quelle forme tant qu'elle donne la même sortie pour toute valeur véridique ou falsey.

Cas de test:

input -> output
1     -> false
2     -> true
17    -> true
19    -> false
239   -> true
389   -> false

Notation

C'est le , donc la réponse la plus courte dans chaque langue gagne!



@MagicOctopusUrn WOW
Keyu Gan


3
Pouvons-nous prendre la saisie comme une liste de chiffres?
totalement juif

1
Vos conditions indiquent que tous les nombres premiers à un chiffre ne sont pas des nombres premiers de tortue. La condition 2 échoue: il n'est pas possible de supprimer un chiffre tout en laissant un nombre premier, car la suppression du seul chiffre ne laisse rien.
hvd

Réponses:


6

Gelée , 16 octets

DŒPḊṖLÐṀḌ߀¬Ȧ<ÆP

Essayez-le en ligne!

Comment ça marche

DŒPḊṖLÐṀḌ߀¬Ȧ<ÆP  Main link. Argument: n

D                 Decimal; convert n to base 10.
 ŒP               Powerset; get all sub-arrays of n's decimal digits.
   Ḋ              Dequeue; remove the first sub-array (empty array).
    Ṗ             Pop; remove the last sub-array (all of n's digits).
     LÐṀ          Maximal by length; keep those of the remaining subarrays that
                  have maximal length. This keep exactly those sub-arrays that have
                  one (and only one) digit removed. If n < 10, this yields an empty
                  array. Without Ḋ, it would yield [[]] instead.
        Ḍ         Undecimal; turn the generated digit arrays into integers.
         ߀       Recursively map the main link over the generated integers.
           ¬      Negate; map 1 to 0 and 0 to 1.
            Ȧ     Any and all; yield 0 if the array is empty (n < 10) or any of the
                  recursive calls returned 1 (mapped to 0). If all calls returned
                  0, this will yield 1.
              ÆP  Test n for primality, yielding 1 for primes, 0 otherwise.
             <    Test if the result to the left is less than the result to the
                  right. This is possible only if the left result is 0 (n < 10 or
                  removing a digit results in a turtle prime) and the right result
                  is 1 (n itself is prime).

Plus de gelée magique! Mec, ces trucs sont partout ...
caird coinheringaahing

7

Haskell , 104 102 99 98 97 95 91 octets

p x=product[2..x-1]^2`mod`x>0
f[]=1>0
f x|y<-zip[0..]x=or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

Essayez-le en ligne!

Explication

Nous avons d'abord mis en place un test de primalité

p x=product[2..x-1]^2`mod`x>0

Cela utilise le théorème de Wilson pour déterminer la primauté d'une entrée.

Nous déclarons ensuite un cas de base, qui affirmera que la chaîne vide est véridique.

f[]=1>0

Maintenant, nous définissons la fonction réelle

f x|y<-zip[0..]x=or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

Nous utilisons un agent de modèle pour se lier zip[0..]xà y, parce que nous devons l' utiliser deux fois plus tard. Nous affirmons ensuite que la réponse est

or[f[snd b|b<-y,b/=a]|a<-y,p$read x]

[[snd b|b<-y,b/=a]|a<-y]est tous les nombres qui sont un chiffre supprimé de notre entrée. Nous affirmons donc qu'au moins un de ces chiffres est vrai f. Afin de garantir que les nombres composites sont faux, nous ajoutons prime$read x. Si le nombre n'est pas premier, la liste devient vide et la anyliste vide est fausse.


1
−2 octets: any f[[or[f[
Anders Kaseorg

1
−4 octets: [b|(i,b)<-y,i/=a]|(a,_)<-y[snd b|b<-y,b/=a]|a<-y
Anders Kaseorg

6

R, 124 122 120 113 95 93 106 105 octets

 g=pryr::f(`if`(gmp::isprime(sum(x*10^((l<-sum(x|1)-1):0))),any(!l,sapply(0:l+1,function(z)g(x[-z]))),!1))

Qui évalue à la fonction:

function (x) 
if (gmp::isprime(sum(x * 10^((l <- sum(x | 1) - 1):0)))) any(!l, 
    sapply(0:l + 1, function(z) g(x[-z]))) else !1

Solution récursive. Prend la saisie sous forme de liste de chiffres.

Dispose de 2 déclarations logiques:

  1. Le xpremier est -il concaténé?

  2. L'un des éléments suivants TRUE:

    1. La longueur est-elle xdifférente de zéro? Il s'agit de notre dernière condition de résiliation.

    2. Est-ce f TRUEpour un sous-ensemble de x?

La première déclaration garantit que nous continuons à travailler avec des nombres premiers uniquement. Le second fait la récursivité réelle.

Enregistré deux octets grâce à @Giuseppe.

J'ai dû annuler certains de mes golfs à cause d'un bug, où je testais par accident une définition de fonction précédente.

R, 98 octets, non concurrent

Comme je l'ai mentionné dans les commentaires, j'ai fait un package . Étant donné que le défi est antérieur à cela, ce n'est pas une compétition, mais je voulais le présenter un peu. Ce n'est pas grand-chose pour l'instant, mais nous y arriverons.

g=pryr::f(`if`(gmp::isprime(RG::C(x)),any(!(l<-sum(x|1)-1),sapply(0:l+1,function(z)g(x[-z]))),!1))

C() est la première fonction du package et prend en charge la concaténation des chiffres en numérique.


Certaines de ces opérations (vous regardant sum(x*10^(((l<-sum(x|1))-1):0))) sont tellement verbeuses. J'envisage vraiment de créer un forfait golf pour R.
JAD

cela aurait été ma solution mais je ne pouvais pas envelopper ma tête autour du sapply... Je pense aussi que vous voudrez peut-être le faire f=pryr::f(...)ou bien vous devrez l'utiliser fdans le sapply.
Giuseppe

1
@Giuseppe Noms d'une seule lettre pour tout: D Pourquoi ne pas appeler le colis gou quelque chose?
JAD

1
@Giuseppe Créé le début d'un package: p Jetez un œil: github.com/JarkoDubbeldam/RG
JAD

1
@JarkoDubbeldam beautiful. Je suis sûr que les défis futurs rendront évidentes les fonctions supplémentaires à ajouter. La manipulation des chaînes est grande: quelque chose pour el(strsplit(x,''))économiserait une tonne d'octets.
BLT

5

Gelée , 19 octets

DJḟЀ`ịDḌḟ0߀¬Ȧ¬aÆP

Essayez-le en ligne!

Comment ça marche

DJḟЀ`ịDḌḟ0߀¬Ȧ¬aÆP                input:239

D                    decimal         [2,3,9]
 J                   range@length    [1,2,3]
  ḟЀ`               filter out each [[2,3],[1,3],[1,2]]
      ịD             index&decimal   [[3,9],[2,9],[2,3]]
        Ḍ            undecimal       [39,29,23]
         ḟ0          filter out 0    [39,29,23]
           ߀        this@each       [1,1,1]
             ¬       logical not     [0,0,0]
              Ȧ      any and all     0
               ¬     logical not     1
                aÆP  and&is_prime    1

Récursion sans ftw de cas de base.


3

Gelée , 27 26 octets

DµœcL’$Ḍµ€FÆPÐf
×⁵WÇÐĿFṪ<8

Un lien monadique prenant et retournant des entiers ( 1pour tortue 0sinon).

Essayez-le en ligne!

Comment?

DµœcL’$Ḍµ€FÆPÐf  Link 1: primes by digit removal: list of numbers  e.g. [19790]
D                cast to decimal list (vectorises)                      [[1,9,7,9,0]]
 µ      µ€       monadic chain for €ach:
      $            last two links as a monad:
    L                length                                             5
     ’               decrement                                          4
  œc             combinations without replacement                       [[1,9,7,9],[1,9,7,0],[1,9,9,0],[1,7,9,0],[9,7,9,0]]
       Ḍ         cast from decimal list (vectorises)                    [1979,1970,1990,1790,9790]
          F      flatten (from a list of lists form the for €ach to a single list)
             Ðf  filter keep if:
           ÆP      is prime?

×⁵WÇÐĿFṪ<8  Main Link: number, n             e.g. 1979
 ⁵          literal 10
×           multiply                              19790
              (this is so the first number is tested as prime too)
  W         wrap in a list                        [19790]
    ÐĿ      loop, collecting results (including the input×10) while change still occurs:
   Ç          call the last (1) link as a monad   [[19790],[1979],[197,199,179],[19,17,97,19,19,17,19,79],[7,7,7,7],[]]
      F     flatten                               [19790,1979,197,199,179,19,17,97,19,19,17,19,79,7,7,7,7]
       Ṫ    tail                                  7
        <8  less than 8?                          1
              (if a single digit prime was reached this will be 1
               otherwise it will be 0
               e.g. an input of 4 yields 40 at the end which is not <8)

1
C'est intéressant de voir deux réponses Jelly sensiblement différentes. Voyons qui peut réduire le leur plus petit.
Lord Farquaad du

2

Rubis , 72 57 + 8 = 80 65 octets

Utilise le -rprimedrapeau. -15 octets d'histocrate!

f=->n{n==''||n.to_i.prime?&!n.scan(/./){f[$`+$']&&break}}

Essayez-le en ligne!


Vous pouvez remplacer &&!!par juste &, il convertira le résultat en booléen. Votre appel récursif peut également être un peu plus court en utilisant des perlismes:!n.scan(/./){f[$`+$']&&break}}
histocrat

@histocrat Ah oui, j'ai oublié que je n'avais pas vraiment besoin de court-circuitage booléen pour cette dernière partie à cause de la condition initiale. Savez-vous pourquoi l' n.scanastuce fonctionne comme elle le fait?
Value Ink

1
Oui, les deux variables globales sont définies sur la chaîne à gauche et à droite de la correspondance la plus récente, donc les concaténer vous donne la chaîne moins le seul caractère. Comme nous avons besoin d'un état à chaque point de l'itération, nous ne pouvons rien faire de tel .scan.find, mais nous pouvons sortir manuellement de la boucle en cas de succès. Si nous cassons, scanrenvoie nil, sinon il retourne la chaîne qui est toujours véridique.
histocrate

2

Java, 220 octets

Essayez-le en ligne!

Golfé:

boolean t(String n){int l=n.length();if(f(x->{for(int i=2;i<x;)if(x%i++==0)return 1<0;return x>1;},new Integer(n)))if(l<2)return 1>0;else for(int i=0;i<l;)if(t(n.substring(0,i)+n.substring(++i,l)))return 1>0;return 1<0;}

Non golfé:

  boolean t(String n) {
    int l = n.length();
    if (f(x -> {
      for (int i = 2; i < x;) {
        if (x % i++ == 0) {
          return 1 < 0;
        }
      }
      return x > 1;
    } , new Integer(n))) {
      if (l < 2) {
        return 1 > 0;
      }
      else {
        for (int i = 0; i < l;) {
          if (t(n.substring(0, i) + n.substring(++i, l))) {
            return 1 > 0;
          }
        }
      }
    }
    return 1 < 0;
  }

Ignorez mon commentaire précédent. Mais vous pouvez le boolean t(String n){int l=n.length(),x=new Integer(n),i;for(i=2;i<x;x=x%i++<1?0:x);if(x>1)if(l<2)return 1>0;else for(i=0;i<l;)if(t(n.substring(0,i)+n.substring(++i,l)))return 1>0;return 1<0;}
jouer

Vous pouvez enregistrer quelques octets en renvoyant 1 et 0 au lieu de vrai et faux.
Nevay

@Nevay Cela fonctionnerait en C ++, mais pas en Java. Les entiers ne peuvent pas être implicitement convertis en booléens.

1
Pas sûr mais d'où fvient-il?
Roman Gräf

La question indique que toute valeur peut être utilisée pour vrai / faux; le seul endroit où vous avez besoin d'un résultat booléen de la méthode est dans la dernière condition if (où vous pouvez ajouter >0pour convertir l'int entier en booléen) qui devrait économiser 2 * 2 + 1 * 4 = 8 octets dans la version de Kevin Cruijssen.
Nevay

1

05AB1E , 28 27 octets

Solution itérative.

¸[D0èg2‹#εæ¨D€gZQÏDpÏ}˜]p1å

Essayez-le en ligne!

Explication

¸                              # wrap input in a list
 [                             # start a loop
  D0èg2‹#                      # if the length of the first element is less than 2, break
         ε                     # apply to each element in the list
          æ                    # compute powerset
           ¨                   # remove last element (the full number)
            D€gZQÏ             # keep only the elements whose length is the max length
                  DpÏ          # keep only primes
                     }         # end apply
                      ˜        # flatten list
                       ]       # end loop
                        p1å    # is any element in the resulting list prime

1

Python 2 , 132 124 119 119 octets

-8 Merci à @WheatWizard

-5 Merci à @LeakyNun

p=lambda i:i>1and all(i%v for v in range(2,i))
f=lambda n:n<'0'or any(f(n[:i]+n[i+1:])for i in range(len(n)))*p(int(n))

Essayez-le en ligne!

Je ne peux penser à rien pour l'affiner sans un vérificateur principal intégré. Prend le nombre sous forme de chaîne (j'ai supposé cela étant donné que l'OP autorisait une liste de chiffres, mais sinon 14 octets pour un autre lambda), et calcule récursivement la tortuosité de chaque numéro "torturé".



Je pense que f=lambda n,i=0:n==''or p(int(n))and i<len(n)and(f(n[:i]+n[i+1:])or f(n,i+1))sauve un octet. Quelqu'un avec de meilleures compétences de golf en Python pourrait probablement raccourcir cela.
Neil

@Neil, il enregistre un octet, mais le libellé "la même sortie pour toute valeur véridique ou falsey" m'empêche de le prendre, car l'entrée 1 renvoie 0 au lieu de False comme les autres cas (en raison du contrôle de primalité -8) . Si l'OP autorise des sorties différentes (bien que également), je le changerais.
Arnold Palmer

1
Désolé, ma suggestion précédente n'est pas valide. 119 octets
Leaky Nun

1

C #, 355 octets

namespace System{using B=Numerics.BigInteger;class A{static void Main(){Console.WriteLine(D(Console.ReadLine()));}static bool P(B x){if(x<2)return 1<0;B r=1;for(int i=1;i<=x-1;i++)r*=i;return(r+1)%x==0;}static bool D(string x){if(x.Length==0)return 1>0;bool b;if(b=P(B.Parse(x))){var n=1<0;for(int i=0;i<x.Length;i++)n|=D(x.Remove(i,1));b&=n;}return b;}}}

Essayez-le en ligne!

Mon premier golf de code, donc j'espère que je l'ai bien fait. Je ne pouvais pas penser à un moyen de le rendre encore plus petit (à part utiliser int au lieu de BigInteger, mais je l'ai fait pour que cela fonctionne pour tous les cas de test fournis). Quoi qu'il en soit, voici le même format correctement:

namespace System
{
    using B = Numerics.BigInteger;
    class A
    {
        static void Main()
        {
            Console.WriteLine(D(Console.ReadLine()));
        }

        static bool P(B x)
        {
            if (x < 2)
                return 1<0;
            B r = 1;
            for (int i = 1; i <= x - 1; i++)
                r *= i;
            return (r + 1) % x == 0;
        }

        static bool D(string x)
        {
            if (x.Length == 0)
                return 1>0;
            bool b;
            if (b = P(B.Parse(x)))
            {
                var n = 1<0;
                for (int i = 0; i < x.Length; i++)
                    n |= D(x.Remove(i, 1));
                b &= n;
            }
            return b;
        }
    }
}


0

PHP , 164 octets

function t($n){for($i=1;++$i<$n;)if($n%$i<1)return 0;if($n<10)return $n>1;foreach($r=str_split($n)as$k=>$v){$q=$r;array_splice($q,$k,1);$z|=t(join($q));}return $z;}

Essayez-le en ligne!

Commence par tester la primauté du nombre, puis passe en revue les chiffres sous forme de tableau, en ressortant chacun et en réunissant les autres et en les alimentant de manière récursive à travers la fonction. Chaque lien vers le bas effectue un OU logique avec les chemins inférieurs, ne retournant que trues'il existe au moins un chemin de tous les nombres premiers.


0

Javascript 167 octets

n=>{a=[];for(i=1;i++<=n;)a.every(x=>i%x)?a.push(i):0;b=k=>(s=''+k,a.indexOf(k)>-1&&(k<10||[...s].some((x,i)=>(r=[...s],r.splice(i,1),b(~~(r.join('')))))));return b(n)}

Explication

n=>{
    a=[];                             // create array to store primes in
    for(i=1;i++<=n;)                  // iterate from 2 to n
        a.every(x=>i%x)?a.push(i):0;  // if i % x is truthy for all x in a,
                                      // then i is prime
    b=k=>(                            // function to test is k is turtle prime
        s=''+k,                       // convert k to a string
        a.indexOf(k)>-1 && (          // if k is prime and
            k<10 ||                   // k is a single digit or
            [...s].some((x,i)=>(      // iterate over the digits of k
                                      // and check to see if, by removing each
                                      // any of the resulting numbers is turtle prime
                                      // ... is spread operator
                                      // [...s] converts string s to an array of characters 
                r=[...s],             // convert s to an array again,
                                      // importantly, this cannot be the same array
                                      // we created above, as we need to
                r.splice(i,1),        // splice out the ith element of the array
                b(~~(r.join('')))     // join the array to a string, convert to int,
                                      // and check if this number is turtle prime
                                      // ~ is bitwise negate, implicitly converts to int first before negating
                                      // ~~ negates the negation, getting us the int
            ))
        )
    );
    return b(n)
}

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.