É uma tartaruga nobre?

28

Como todos sabemos, são tartarugas até o fim . Mas também é primo?

Um número é considerado "primo da tartaruga" se atender às seguintes condições:

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.

Por exemplo, 239é um "prime de tartaruga", pois pode ser reduzido para 23um 2ou outro 3, ambos os quais são primos. Também pode ser reduzido para 29então 2. 151não é um primo de tartaruga, pois se reduz a 15(não primo), 51(não primo) ou 11. 11é primo, mas só pode reduzir para 1, o que não é.

Dado um número inteiro positivo, determine se é um "primo da tartaruga". Sua saída pode ser de qualquer forma, desde que ela seja igual para qualquer valor de verdade ou falsey.

Casos de teste:

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

Pontuação

Isso é , então a resposta mais curta em cada idioma vence!

Lord Farquaad
fonte
5
Relacionado
Magic Octopus Urn
@MagicOctopusUrn WOW
Keyu Gan
8
Realmente relacionados
FryAmTheEggman
3
Podemos considerar a entrada como uma lista de dígitos?
13136 totallyhuman
1
Suas condições dizem que todos os números primos de um dígito não são números primos de tartaruga. A condição 2 falha: não é possível remover um dígito e ainda deixar um número primo, pois a remoção do único dígito não deixa nada.
hvd

Respostas:

6

Gelatina , 16 bytes

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

Experimente online!

Como funciona

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).
Dennis
fonte
Geléia mais mágica! Cara, esse material fica em todos os lugares ...
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]

Experimente online!

Explicação

Primeiro montamos um teste de primalidade

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

Isso usa o Teorema de Wilson para determinar a primalidade de uma entrada.

Em seguida, declaramos um caso base, que afirmará que a cadeia vazia é verdadeira.

f[]=1>0

Agora vamos definir a função real

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

Nós usamos um guarda padrão para vincular zip[0..]xa y, porque precisamos usá-lo duas vezes mais tarde. Em seguida, afirmamos que a resposta é

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

[[snd b|b<-y,b/=a]|a<-y]são todos os números que são um dígito removido da nossa entrada. Portanto, estamos afirmando que pelo menos um desses números é verdadeiro f. A fim de garantir que os números compostos sejam falsos, adicionamos prime$read x. Se o número não for primo, a lista ficará vazia e a anylista vazia será falsa.

Assistente de Trigo
fonte
1
−2 bytes: any f[[or[f[
Anders Kaseorg 17/17/17
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))

Que avalia a função:

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

Solução recursiva. Recebe a entrada como uma lista de dígitos.

Possui 2 declarações lógicas:

  1. É xprimo quando concatenado?

  2. É um dos seguintes TRUE:

    1. O comprimento é xdiferente de zero? Esta é a nossa condição final de rescisão.

    2. É f TRUEpara qualquer subconjunto de x?

A primeira declaração garante que continuemos trabalhando apenas com números primos. O segundo faz a recursão real.

Economizou dois bytes graças a @Giuseppe.

Eu tive que reverter alguns dos meus tacos por causa de um bug, onde estava testando com uma definição de função anterior por acidente.

R, 98 bytes, não concorrente

Como mencionei nos comentários, fiz um pacote . Como o desafio antecede isso, isso não é competitivo, mas eu queria mostrar um pouco. Não é muito até agora, mas vamos chegar lá.

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() é a primeira função no pacote e cuida da concatenação de dígitos em um numérico.

JAD
fonte
Algumas dessas operações (olhando para você sum(x*10^(((l<-sum(x|1))-1):0))) são muitíssimo ruins. Estou realmente pensando em criar um pacote de golfe para R.
JAD
essa teria sido a minha solução, mas eu não conseguia sapplyentender o ... Também acho que você pode querer fazer f=pryr::f(...)ou precisa usar fo sapply.
Giuseppe
1
@ Giuseppe Nomes de letras únicas para tudo: D Por que não chamar o pacote gou algo assim?
JAD
1
@ Giuseppe Criou o início de um pacote: p Dê uma olhada: github.com/JarkoDubbeldam/RG
JAD
1
@JarkoDubbeldam beautiful. Tenho certeza de que os desafios futuros tornarão óbvias quais funções adicionais precisam ser adicionadas. A manipulação de strings é grande: algo para el(strsplit(x,''))economizar uma tonelada de bytes.
BLT
5

Geléia , 19 bytes

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

Experimente online!

Como funciona

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

Recursão sem base ftw.

Freira Furada
fonte
3

Geléia , 27 26 bytes

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

Um link monádico que recebe e retorna números inteiros ( 1para tartarugas 0).

Experimente online!

Quão?

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)
Jonathan Allan
fonte
1
É interessante ver duas respostas Jelly substancialmente diferentes. Vamos ver quem pode reduzir o deles.
Lord Farquaad
2

Ruby , 72 57 + 8 = 80 65 bytes

Usa a -rprimebandeira. -15 bytes de histocrat!

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

Experimente online!

Value Ink
fonte
Você pode substituir &&!!por just &, ele converterá o resultado em um booleano. Sua chamada recursiva também pode ficar um pouco mais curta usando perlismos:!n.scan(/./){f[$`+$']&&break}}
histocrat
@histocrat Ah sim, esqueci que não precisava de um curto-circuito booleano para a última parte devido à condição inicial. Você sabe por que o n.scantruque funciona da maneira que funciona?
Value Ink
1
Sim, as duas variáveis ​​globais definidas na sequência de caracteres à esquerda e à direita da correspondência mais recente; portanto, concatená-las fornece a sequência de caracteres menos o caractere. Como precisamos declarar em cada ponto da iteração, não podemos fazer nada assim .scan.find, mas podemos interromper manualmente o ciclo do sucesso. Se quebrarmos, scanretorna nil, caso contrário, retorna a string que é sempre verdadeira.
histocrat 17/07/2017
2

Java, 220 bytes

Experimente online!

Golfe:

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

fonte
Ignore meu comentário anterior. Mas você pode golfe-lo para isto: 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
Você pode salvar alguns bytes retornando 1 e 0 em vez de verdadeiro e falso.
Nevay
@Nevay Isso funcionaria em C ++, mas não em Java. Inteiros não podem ser implicitamente convertidos em booleanos.
1
Não tenho certeza, mas de onde fvem?
Roman Gräf
A pergunta afirma que qualquer valor pode ser usado para verdadeiro / falso; o único local em que você precisa de um resultado booleano do método é a última condição if (onde você pode adicionar >0para converter o int em um booleano), que deve salvar 2 * 2 + 1 * 4 = 8 bytes na versão de Kevin Cruijssen.
Nevay
1

05AB1E , 28 27 bytes

Solução iterativa.

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

Experimente online!

Explicação

¸                              # 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
Emigna
fonte
1

Python 2 , 132 124 119 bytes

-8 Obrigado a @WheatWizard

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

Experimente online!

Não consigo pensar em nada para aperfeiçoá-lo sem um verificador principal embutido. Pega o número como uma string (presumi que, dado que o OP permitia uma lista de dígitos, mas, se não fosse, +14 bytes para outro lambda), e recursivamente calcula a turtleness de cada número "enrolado".

Arnold Palmer
fonte
Eu acho 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))salva um byte. Alguém com melhores habilidades de golfe em Python provavelmente poderia diminuir ainda mais isso.
Neil
@ Neil, ele salva um byte, mas a expressão "a mesma saída para qualquer valor de verdade ou falsey" me impede de aceitá-lo, pois a entrada 1 retorna 0 em vez de False como nos outros casos (devido à verificação de primalidade -8) . Se o OP permitir saídas diferentes (embora sinônimas), eu mudaria.
9609 Arnold Palmer
1
Desculpe, minha sugestão anterior é inválida. 119 bytes
Freira vazada
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;}}}

Experimente online!

Meu primeiro código de golfe, então espero ter feito tudo certo. Não consegui pensar em uma maneira de torná-lo ainda menor (exceto usar int em vez de BigInteger, mas fiz isso para que funcionasse em todos os casos de teste fornecidos). Enfim, aqui está o mesmo formatado corretamente:

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;
        }
    }
}
Grzegorz Puławski
fonte
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;}

Experimente online!

Começa testando o número de primalidade e, em seguida, percorre os dígitos como uma matriz, abrindo cada um e juntando o restante novamente e alimentando-os recursivamente através da função novamente. Cada link para baixo faz um OR lógico com os caminhos inferiores, retornando apenas truese existir pelo menos um caminho de todos os números primos.

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

Explicação

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

asgallant
fonte