Decomposição em números primos


14

Dado um número inteiro n, retorne o número de maneiras que n pode ser escrito como uma lista de números primos. Por exemplo, 2323pode ser escrito como (2,3,23), (23,23)ou (2,3,2,3)ou (23,2,3), para que você produza 4. Se não puder ser escrito dessa maneira, você deverá imprimir 0.

Um número primo como 019ou 00000037é um primo válido para esse problema.

Casos de teste:

5 -> 1
55 -> 1 
3593 -> 4 (359 and 3, or 3 and 593, or 3 and 59 and 3, or 3593)
3079 -> 2 (3 and 079, or 3079)
119 -> 0 
5730000037 -> 7 (5,7,3,000003,7, 5,7,3,0000037, 5,73,000003,7, 5,73,0000037, 5,73000003,7, 5,7,30000037, 5730000037)
0-> undefined (you do not have to handle this case)

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

Edit: agora eu sei por que devo usar a sandbox na próxima vez


Respostas:


7

Haskell , 96 89 bytes

5 bytes salvos graças ao teste de primalidade de H.PWiz

p x=[1|0<-mod x<$>[2..x]]==[1]
f[]=1
f b=sum[f$drop i b|i<-[1..length b],p$read$take i b]

Experimente online!

Explicação

A primeira coisa que se faz é criar uma função de teste primo usando o teorema de Wilson usando a definição de primo.

p x=[1|0<-mod x<$>[2..x]]==[1]

Então comece a definir f. A primeira coisa que pensei quando vi esse problema foi usar a programação dinâmica. No entanto, a programação dinâmica custa bytes, portanto, isso usa um algoritmo de "programação psuedo-dinâmica". Enquanto na programação dinâmica você armazenaria um gráfico Acyclic Directed na memória aqui, apenas usamos recursão e recalculamos cada nó sempre que necessário. Perde todos os benefícios de tempo da programação dinâmica, mas esse é o para quem se importa. (ainda melhor do que a pesquisa por força bruta)

O algoritmo é o seguinte: construímos um gráfico acíclico direcionado, L , em que cada nó representa uma substring do número. Em particular, L i representa os últimos dígitos i da nossa entrada (vamos chamá-la de n ).

Definimos L 0 para ter um valor de 1 e o outro valor em L para ter a soma de cada L j, de modo que j <i e a substring de n de i a j sejam primos.

Ou em uma fórmula:

Fórmula

Em seguida, retornar o valor na maior maior índice de L . ( L k onde k é o número de dígitos de n )


6

Geléia , 8 bytes

ŒṖḌÆPẠ€S

Experimente online!

-1 byte graças a Leaky Nun
-1 byte graças a Dennis

Explicação

ŒṖḌÆPẠ€S  Main Link
ŒṖ        List Partitions (automatically converts number to decimal digits)
  Ḍ       Convert back to integers (auto-vectorization)
   ÆP     Are they primes? (auto-vectorization)
     Ạ€   For each, are they all truthy (were the numbers all primes?); 1/0 for truthy/falsy
       S  Sum; gets number of truthy elements

Percebi que 05AB1E não pode fazer isso facilmente. Partições parece um ótimo comando.
Magic Octopus Urn

5

Brachylog , 10 bytes

ṫ{~cịᵐṗᵐ}ᶜ

Experimente online!

Primeiro converte a entrada em uma string.{…}ᶜConta o número de saídas possíveis para .

Dentro {…}da saída de é alimentado para ~c. A saída desse predicado satisfaz que, quando concatenada, é igual à entrada. Isso é alimentado ịᵐ, o que especifica que sua saída é a entrada com cada sequência convertida em um número inteiro. ṗᵐespecifica que sua entrada consiste em números primos


1
Você não precisa converter para string e para trás, esses 7 bytes são suficientes: {~cṗᵐ}ᶜ. Isso é realmente lento porque ~cem números inteiros trabalha com aritmética de restrição, mas em teoria funciona.
Fatalize

@Fatalize Eu acho que não conta para zeros à esquerda
H.PWiz

4

Pitão , 13 bytes

lf.AmP_sdT./`

Suíte de teste.


Eu não conheço Pyth tão bem, mas em vez de filtrar e, em seguida, tirar o comprimento, você poderia fazer for_each em vez de filtrar e somar?
HyperNeutrino

@HyperNeutrino isso faz alguma diferença?
gotejante Nun

Não tenho certeza, não testei. Isso vale para o Jelly (provavelmente por causa do filtro de dois bytes rápido), mas não tenho certeza.
HyperNeutrino

@HyperNeutrino filter is one byte here ...
Leaky Nun


2

Python 2 , 161 bytes

lambda n:sum(all(d>1and all(d%i>0for i in range(2,d))for d in v)for v in g(`n`))
g=lambda s:[[int(s[:i])]+t for i in range(1,len(s))for t in g(s[i:])]+[[int(s)]]

Experimente online!

A função gcria as partições recursivamente (recebe uma string como entrada, mas gera uma lista de listas de entradas). A maior parte do código restante é apenas para implementar 'is da prime?'.



1

Limpo , 199 141 131 bytes

import StdEnv
?n|n<2=0|and[gcd n i<2\\i<-[2..n-1]]=1=0
@n#s=toString n
#f=toInt o(%)s
= ?n+sum[@(f(0,i))\\i<-[0..n]| ?(f(i+1,n))>0]

Experimente online!



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.