Ist es eine Turtle Prime?


28

Wie wir alle wissen, ist es Schildkröten den ganzen Weg nach unten . Aber ist es auch ganz unten?

Eine Zahl wird als "Turtle-Prime" betrachtet, wenn sie die folgenden Bedingungen erfüllt:

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.

Zum Beispiel 239ist es eine "Schildkröten-Primzahl", da sie auf 23eine 2oder 3beide Primzahlen reduziert werden kann. Es kann auch auf 29dann reduziert werden 2. 151ist keine Schildkröten-Primzahl, da sie auf 15(keine Primzahl), 51(keine Primzahl) oder reduziert wird 11. 11ist prim, kann aber nur reduzieren 1, was nicht ist.

Bestimmen Sie bei einer positiven Ganzzahl, ob es sich um eine "Turtle-Prime" handelt. Ihre Ausgabe kann in beliebiger Form erfolgen, sofern sie für alle wahrheitsgemäßen oder falschen Werte dieselbe Ausgabe liefert.

Testfälle:

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

Wertung

Das ist , also gewinnt die kürzeste Antwort in jeder Sprache!



@MagicOctopusUrn WOW
Keyu Gan


3
Können wir Eingaben als Ziffernliste nehmen?
Totalhuman

1
Ihre Bedingungen besagen, dass alle einstelligen Primzahlen keine Schildkrötenprimzahlen sind. Bedingung 2 schlägt fehl: Es ist nicht möglich, eine Ziffer zu entfernen und dennoch eine Primzahl zu hinterlassen, da das Entfernen der einzigen Ziffer nichts übrig lässt.
HDV

Antworten:


6

Gelee , 16 Bytes

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

Probieren Sie es online!

Wie es funktioniert

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).

Noch mehr magisches Gelee! Mann, dieses Zeug wird überall ...
Caird Coinheringaahing

7

Haskell , 104 102 99 98 97 95 91 Bytes

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]

Probieren Sie es online!

Erläuterung

Zuerst haben wir einen Primalitätstest eingerichtet

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

Hierbei wird der Satz von Wilson verwendet , um die Primalität einer Eingabe zu bestimmen.

Wir deklarieren dann einen Basisfall, der besagt, dass die leere Zeichenkette wahr ist.

f[]=1>0

Nun definieren wir die eigentliche Funktion

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

Wir verwenden ein Muster Wache zu binden zip[0..]xan y, weil wir es später zweimal verwenden müssen. Wir behaupten dann, die Antwort sei

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

[[snd b|b<-y,b/=a]|a<-y]sind alle Zahlen, die eine Ziffer sind, die aus unserer Eingabe entfernt wurden. Wir behaupten also, dass mindestens eine dieser Zahlen der Wahrheit entspricht f. Um sicherzustellen, dass zusammengesetzte Zahlen falsch sind, fügen wir sie hinzu prime$read x. Wenn die Zahl keine Primzahl ist, wird die Liste leer und die anyeiner leeren Liste ist falsch.


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

1
−4 Bytes: [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 Bytes

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

Was zur Funktion auswertet:

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

Rekursive Lösung. Übernimmt die Eingabe als Ziffernliste.

Hat 2 logische Aussagen:

  1. Ist xPrime verkettet?

  2. Ist eine der folgenden TRUE:

    1. Ist die Länge xungleich Null? Dies ist unsere endgültige Kündigungsbedingung.

    2. Gilt f TRUEfür irgendeine Teilmenge von x?

Die erste Anweisung stellt sicher, dass wir weiterhin nur mit Primzahlen arbeiten. Der zweite führt die eigentliche Rekursion durch.

Zwei Bytes dank @ Giuseppe gespeichert.

Ich musste einige meiner Golfplätze wegen eines Fehlers zurücksetzen, bei dem ich versehentlich mit einer früheren Funktionsdefinition getestet habe.

R, 98 Bytes, nicht konkurrierend

Wie ich in den Kommentaren erwähnt habe, habe ich ein Paket gemacht . Da die Herausforderung älter ist als diese, ist dies nicht konkurrierend, aber ich wollte es ein bisschen zur Schau stellen. Es ist noch nicht viel, aber wir werden es schaffen.

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() ist die erste Funktion im Paket und kümmert sich um die Verknüpfung von Ziffern zu einer Zahl.


Einige dieser Operationen (Sieh dich an sum(x*10^(((l<-sum(x|1))-1):0))) sind verdammt wortreich. Ich denke wirklich darüber nach, ein Golfpaket für zu erstellen R.
JAD

Dies wäre meine Lösung gewesen, aber ich konnte meinen Kopf nicht um die sapply... legen. Außerdem denke ich, dass Sie dies tun möchten f=pryr::f(...)oder dass Sie es fin der ... verwenden müssen sapply.
Giuseppe

1
@ Giuseppe Einzelne Buchstaben für alles: D Warum nicht das Paket anrufen goder so?
JAD

1
@ Giuseppe Erstellt den Start für ein Paket: p Schau mal: github.com/JarkoDubbeldam/RG
JAD

1
@ JarkoDubbeldam schön. Ich bin mir sicher, dass zukünftige Herausforderungen deutlich machen werden, welche zusätzlichen Funktionen hinzugefügt werden müssen. Die Manipulation von Strings ist groß: Etwas für el(strsplit(x,''))würde eine Menge Bytes sparen.
BLT

5

Jelly , 19 Bytes

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

Probieren Sie es online!

Wie es funktioniert

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

Rekursion ohne Basisfall ftw.


3

Jelly , 27 26 Bytes

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

Eine monadische Verknüpfung, die ganze Zahlen aufnimmt und zurückgibt ( ansonsten 1für Turtle 0).

Probieren Sie es online!

Wie?

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
Es ist interessant, zwei wesentlich unterschiedliche Jelly-Antworten zu sehen. Mal sehen, wer kann ihre verringern kleiner.
Lord Farquaad

2

Ruby , 72 57 + 8 = 80 65 Bytes

Verwendet die -rprimeFlagge. -15 Bytes vom Histokraten!

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

Probieren Sie es online!


Sie können es durch &&!!just ersetzen &. Es wird das Ergebnis in einen Booleschen Wert umgewandelt. Ihr rekursiver Aufruf kann mit Perlismen auch etwas kürzer werden:!n.scan(/./){f[$`+$']&&break}}
Histokrat

@histocrat Ah ja, ich habe vergessen, dass ich wegen der Anfangsbedingung für diesen letzten Teil keinen booleschen Kurzschluss brauchte. Wissen Sie, warum der n.scanTrick so funktioniert, wie er funktioniert?
Value Ink

1
Ja, die beiden globalen Variablen dort sind auf die Zeichenfolge links und rechts der letzten Übereinstimmung gesetzt. Wenn Sie sie also verketten, erhalten Sie die Zeichenfolge abzüglich des einen Zeichens. Da wir an jedem Punkt der Iteration einen Zustand benötigen, können wir nichts dergleichen tun .scan.find, aber wir können die Schleife bei Erfolg manuell verlassen. Wenn wir brechen, wird scanzurückgegeben nil, andernfalls wird die Zeichenfolge zurückgegeben, die immer wahr ist.
Histokrat

2

Java, 220 Bytes

Probieren Sie es online!

Golf gespielt:

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

Ungolfed:

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

Ignoriere meinen vorherigen Kommentar. Aber Sie können es zu diesem Golf spielen: 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;}( 191 Bytes )
Kevin Cruijssen

Sie können einige Bytes sparen, indem Sie 1 und 0 anstelle von true und false zurückgeben.
Nevay

@Nevay Das würde in C ++ funktionieren, aber nicht in Java. Ganzzahlen können nicht implizit in Boolesche Werte konvertiert werden.

1
Nicht sicher, aber woher kommt fdas?
Roman Gräf

Die Frage besagt, dass jeder Wert für wahr / falsch verwendet werden kann; Der einzige Ort, an dem Sie ein boolesches Ergebnis der Methode benötigen, ist die letzte if-Bedingung (in der Sie hinzufügen können >0, um das int in ein boolesches zu konvertieren), die in Kevin Cruijssens Version 2 * 2 + 1 * 4 = 8 Bytes speichern sollte.
Nevay

1

05AB1E , 28 27 Bytes

Iterative Lösung.

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

Probieren Sie es online!

Erläuterung

¸                              # 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 Bytes

-8 Danke an @WheatWizard

-5 Danke an @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))

Probieren Sie es online!

Ich kann mir nichts vorstellen, um es zu verbessern, ohne einen eingebauten Prime Checker. Nimmt die Zahl als Zeichenkette (ich nahm an, dass das OP eine Liste von Ziffern zulässt, aber wenn nicht, dann +14 Bytes für ein anderes Lambda) und berechnet rekursiv die Turtleness jeder "geschilderten" Zahl.



Ich denke, 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))spart ein Byte. Jemand mit besseren Python-Golffähigkeiten könnte dies wahrscheinlich weiter verkürzen.
Neil

@Neil, es speichert zwar ein Byte, aber die Formulierung "Gleiche Ausgabe für alle Wahrheiten oder falschen Werte" hindert mich daran, es zu verwenden, da die Eingabe von 1 wie in den anderen Fällen 0 anstelle von Falsch zurückgibt (aufgrund der Primalitätsprüfung -8). . Wenn das OP verschiedene (wenn auch auch) Ausgänge zulässt, dann würde ich es ändern.
Arnold Palmer

1
Entschuldigung, mein vorheriger Vorschlag ist ungültig. 119 Bytes
Undichte Nonne

1

C #, 355 Bytes

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

Probieren Sie es online!

Mein erster Code Golf, also hoffe ich, dass ich es gut gemacht habe. Ich konnte mir keine Möglichkeit vorstellen, es noch kleiner zu machen (außer int anstelle von BigInteger zu verwenden, aber ich habe es getan, damit es für alle bereitgestellten Testfälle funktioniert). Wie auch immer, hier ist das gleiche richtig formatiert:

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 Bytes

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

Probieren Sie es online!

Beginnt damit, die Zahl auf Primalität zu testen, durchläuft dann die Ziffern als Array, springt aus jeder heraus und fügt den Rest wieder zusammen und führt sie rekursiv durch die Funktion. Jede Verknüpfung nach unten führt ein logisches ODER mit den unteren Pfaden durch und kehrt nur zurück, truewenn mindestens ein Pfad aller Primzahlen vorhanden ist.


0

Javascript 167 Bytes

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

Erläuterung

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.