È un numero primo di tartaruga?


28

Come tutti sappiamo, sono le tartarughe fino in fondo . Ma sono anche primi fino in fondo?

Un numero è considerato un "prime-tartaruga" se soddisfa le seguenti condizioni:

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.

Ad esempio, 239è un "primo-tartaruga", in quanto può essere ridotto a 23uno di questi 2o 3entrambi, entrambi primi. Inoltre può essere ridotto ad 29allora 2. 151non è un numero primo di tartaruga, in quanto riduce a 15(non primo), 51(non primo) o 11. 11è primo, ma può solo ridursi a 1, che non lo è.

Dato un numero intero positivo, determinare se si tratta di un "primo-tartaruga". Il tuo output può essere in qualsiasi forma purché fornisca lo stesso output per qualsiasi valore di verità o falsità.

Casi test:

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

punteggio

Questo è , quindi vince la risposta più breve in ogni lingua!



@MagicOctopusUrn WOW
Keyu Gan,


3
Possiamo prendere input come un elenco di cifre?
totalmente umano il

1
Le tue condizioni dicono che tutti i numeri primi a una cifra non sono numeri primi di tartaruga. Condizione 2 non riesce: non è possibile rimuovere una cifra e lasciare comunque un numero primo, poiché la rimozione dell'unica cifra non lascia nulla.
hvd,

Risposte:


6

Gelatina , 16 byte

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

Provalo online!

Come funziona

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

Più gelatina magica! Amico, questa roba arriva ovunque ...
caird coinheringaahing

7

Haskell , 104 102 99 98 97 95 91 byte

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]

Provalo online!

Spiegazione

Innanzitutto abbiamo impostato un test di primalità

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

Questo usa il Teorema di Wilson per determinare la primalità di un input.

Dichiariamo quindi un caso base, che affermerà che la stringa vuota è vera.

f[]=1>0

Ora definiamo la funzione effettiva

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

Usiamo una guardia modello da legano zip[0..]xa y, perché abbiamo bisogno di usare due volte in seguito. Quindi affermiamo che la risposta è

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

[[snd b|b<-y,b/=a]|a<-y]sono tutti i numeri che sono una cifra rimossa dal nostro input. Quindi stiamo affermando che almeno uno di questi numeri è vero f. Al fine di garantire che i numeri composti siano falsi, aggiungiamo prime$read x. Se il numero non è un numero primo, l'elenco diventa vuoto e quello anydi un elenco vuoto è falso.


1
−2 byte: any f[[or[f[
Anders Kaseorg,

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

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

Che valuta la funzione:

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

Soluzione ricorsiva. Accetta input come un elenco di cifre.

Ha 2 istruzioni logiche:

  1. xPrime è concatenato?

  2. È uno dei seguenti TRUE:

    1. La lunghezza è xdiversa da zero? Questa è la nostra condizione finale definitiva.

    2. È f TRUEper qualsiasi sottoinsieme di x?

La prima affermazione ci assicura di continuare a lavorare solo con numeri primi. Il secondo esegue l'effettiva ricorsione.

Due byte salvati grazie a @Giuseppe.

Ho dovuto ripristinare alcuni dei miei campi da golf a causa di un bug, in cui stavo provando per sbaglio una precedente definizione di funzione.

R, 98 byte, non concorrenti

Come ho detto nei commenti, ho creato un pacchetto . Dal momento che la sfida lo precede, questo non è competitivo, ma ho voluto mostrarlo un po '. Non è molto lontano, ma ci arriveremo.

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() è la prima funzione nel pacchetto e si occupa di concatenare le cifre in un numero.


Alcune di queste operazioni (ti sum(x*10^(((l<-sum(x|1))-1):0))guardano) sono tremendamente maleducate. Sto davvero pensando di creare un pacchetto golf per R.
JAD,

questa sarebbe stata la mia soluzione ma non sono riuscito a avvolgere la testa intorno al sapply... Inoltre penso che potresti voler fare f=pryr::f(...)o che dovresti usare fin sapply.
Giuseppe,

1
@Giuseppe Nomi di lettere singole per tutto: D Perché non chiamare il pacchetto go qualcosa del genere?
JAD,

1
@Giuseppe Creato l'inizio per un pacchetto: p Dai un'occhiata: github.com/JarkoDubbeldam/RG
JAD

1
@JarkoDubbeldam bellissima. Sono sicuro che le sfide future renderanno ovvie quali funzioni aggiuntive devono essere aggiunte. La manipolazione delle stringhe è grande: qualcosa per el(strsplit(x,''))risparmiare un sacco di byte.
BLT,

5

Gelatina , 19 byte

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

Provalo online!

Come funziona

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

Ricorsione senza custodia base ftw.


3

Gelatina , 27 26 byte

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

Un collegamento monadico che prende e restituisce numeri interi ( altrimenti 1per la tartaruga 0).

Provalo online!

Come?

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
È interessante vedere due risposte Jelly sostanzialmente diverse. Vediamo chi può ridurre il loro più piccolo.
Lord Farquaad,

2

Rubino , 72 57 + 8 = 80 65 byte

Usa la -rprimebandiera. -15 byte dall'istocratico!

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

Provalo online!


Puoi sostituirlo &&!!con just &, lancerà il risultato in un valore booleano. La tua chiamata ricorsiva può anche essere un po 'più breve usando i perlismi:!n.scan(/./){f[$`+$']&&break}}
histocrat

@histocrat Ah sì, ho dimenticato che in realtà non avevo bisogno di un corto circuito booleano per l'ultima parte a causa della condizione iniziale. Sai perché il n.scantrucco funziona così?
Value Ink

1
Sì, le due variabili globali lì sono impostate sulla stringa a sinistra e a destra della corrispondenza più recente, quindi concatenarle ti dà la stringa meno l'unico carattere. Dato che abbiamo bisogno di stato in ogni punto dell'iterazione, non possiamo fare nulla di simile .scan.find, ma possiamo uscire manualmente dal ciclo in caso di successo. Se ci rompiamo , scanritorna nil, altrimenti restituisce la stringa che è sempre vera.
istocratico,

2

Java, 220 byte

Provalo online!

golfed:

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

Ignora il mio commento precedente. Ma puoi giocare a questo: 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 byte )
Kevin Cruijssen il

È possibile salvare alcuni byte restituendo 1 e 0 anziché true e false.
Nevay,

@Nevay Funzionerebbe in C ++, ma non in Java. I numeri interi non possono essere implicitamente convertiti in booleani.

1
Non sei sicuro ma da dove fviene?
Roman Gräf,

La domanda afferma che qualsiasi valore può essere usato per vero / falso; l'unico posto in cui è necessario un risultato booleano del metodo è nell'ultima condizione if (dove è possibile aggiungere >0per convertire int in un valore booleano) che dovrebbe salvare 2 * 2 + 1 * 4 = 8 byte nella versione di Kevin Cruijssen.
Nevay,

1

05AB1E , 28 27 byte

Soluzione iterativa.

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

Provalo online!

Spiegazione

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

-8 Grazie a @WheatWizard

-5 Grazie a @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))

Provalo online!

Non riesco a pensare a nulla per affinare senza un controllo principale incorporato. Prende il numero come una stringa (supponevo che questo dato l'OP consentisse un elenco di cifre, ma in caso contrario +14 byte per un'altra lambda), e calcola ricorsivamente la torbidità di ogni numero "torturato".



Penso che 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))salva un byte. Qualcuno con migliori abilità nel golf di Python potrebbe probabilmente accorciarlo ulteriormente.
Neil,

@Neil, salva un byte, ma la dicitura "lo stesso output per qualsiasi valore di verità o falsità" mi impedisce di prenderlo, poiché l'immissione di 1 restituisce 0 anziché False come gli altri casi (a causa del controllo di primalità -8) . Se l'OP consente uscite diverse (anche se anche), allora lo cambierei.
Arnold Palmer,

1
Spiacenti, il mio suggerimento precedente non è valido. 119 byte
Leaky Nun,

1

C #, 355 byte

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

Provalo online!

Il mio primo codice golf, quindi spero di averlo fatto bene. Non riuscivo a pensare a un modo per renderlo ancora più piccolo (a parte usare int invece di BigInteger, ma l'ho fatto in modo che funzionasse per tutti i casi di test forniti). Comunque, ecco lo stesso formattato correttamente:

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 byte

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

Provalo online!

Inizia testando il numero per primalità, quindi scorre le cifre come una matrice, saltando fuori ciascuna e unendo il resto insieme e alimentandoli nuovamente ricorsivamente attraverso la funzione. Ogni collegamento verso il basso esegue un OR logico con i percorsi inferiori, ritornando solo truese esiste almeno un percorso di tutti i numeri primi.


0

Javascript 167 byte

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

Spiegazione

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.