Decomposizione in numeri primi


14

Dato un numero intero n, restituisce il numero di modi in cui n può essere scritto come un elenco di numeri primi. Ad esempio, 2323può essere scritto come (2,3,23), (23,23)oppure (2,3,2,3)oppure (23,2,3), in modo da produrre 4. Se non può essere scritto in questo modo, è necessario eseguire l'output 0.

Un numero primo come 019o 00000037è un numero primo valido per questo problema.

Casi test:

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)

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

Modifica: ora so perché dovrei usare la sandbox la prossima volta


Risposte:


7

Haskell , 96 89 byte

5 byte salvati grazie al test di primalità di 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]

Provalo online!

Spiegazione

La prima cosa che viene fatta è creare una funzione di test principale usando il teorema di Wilson usando la definizione di prime.

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

Quindi iniziare a definire f. La prima cosa che ho pensato quando ho visto questo problema era usare la programmazione dinamica. Tuttavia, la programmazione dinamica costa byte, quindi utilizza un algoritmo di "programmazione psuedo-dinamica". Mentre nella programmazione dinamica si memorizza in memoria un grafico Aciclico diretto, qui si usa solo la ricorsione e si ricalcola ogni nodo ogni volta che ne abbiamo bisogno. Perde continuamente i vantaggi della programmazione dinamica, ma questo è quindi chi se ne frega. (comunque meglio della ricerca della forza bruta)

L'algoritmo è il seguente, costruiamo un grafico aciclico diretto, L , in cui ciascun nodo rappresenta una sottostringa del numero. In particolare L i rappresenta le ultime cifre i del nostro input (chiamiamolo n ).

Definiamo L 0 per avere un valore di 1 e ogni altro valore in L per avere la somma di ogni L j tale che j <i e la sottostringa di n da i a j siano primi.

O in una formula:

Formula

Abbiamo poi tornare al valore al grande grande indice di L . ( L k dove k è il numero di cifre di n )


6

Gelatina , 8 byte

ŒṖḌÆPẠ€S

Provalo online!

-1 byte grazie a Leaky Nun
-1 byte grazie a Dennis

Spiegazione

ŒṖḌÆ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

Ho notato che 05AB1E non può farlo facilmente. Le partizioni sembrano un ottimo comando.
Magic Octopus Urn

5

Brachylog , 10 byte

ṫ{~cịᵐṗᵐ}ᶜ

Provalo online!

Innanzitutto converte l'input in una stringa. {…}ᶜConta il numero di uscite possibili per .

All'interno {…}dell'output di viene inviato ~c. L'output di questo predicato soddisfa che, quando concatenato, è uguale all'input. Questo viene inserito ịᵐ, il che specifica che il suo output è l'input con ogni stringa convertita in un numero intero. ṗᵐspecifica che il suo input è costituito da numeri primi


1
Non è necessario per convertire in stringa e viceversa, quei 7 byte sono sufficienti: {~cṗᵐ}ᶜ. Questo è veramente lento perché ~csugli interi funziona con l'aritmetica dei vincoli, ma in teoria funziona.
Fatalizza il

@Fatalizza Penso che non riesca a tenere conto degli zeri
iniziali

4

Pyth , 13 byte

lf.AmP_sdT./`

Suite di test.


Non conosco Pyth così bene ma invece di filtrare e poi prendere la lunghezza, potresti fare for_each invece di filter e quindi sommare?
HyperNeutrino

@HyperNeutrino fa differenza?
Leaky Nun,

Non sono sicuro, non ho ancora testato. Lo fa per Jelly (probabilmente a causa del filtro a due byte rapido) ma non ne sono sicuro.
HyperNeutrino

Il filtro @HyperNeutrino è un byte qui ...
Leaky Nun,


2

Python 2 , 161 byte

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

Provalo online!

La funzione gcrea le partizioni in modo ricorsivo (accetta una stringa come input ma genera un elenco di elenchi di ints). Gran parte del codice rimanente è solo per implementare "è dun numero primo?".



1

Pulito , 199 141 131 byte

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]

Provalo online!



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.