Numeri magnanimi


24

Dato un numero intero positivo come input determinare se si tratta di un numero magnanimo.

Un numero magnanimo è un numero tale che qualsiasi inserimento di un +segno tra due cifre qualsiasi nella base 10 determina un'espressione di un numero primo.

Ad esempio 40427 è magnanimo perché

4+0427  = 431  is prime
40+427  = 467  is prime
404+27  = 431  is prime
4042+7  = 4049 is prime

Produzione

Dovresti generare due valori distinti, uno quando l'ingresso è magnanimo e uno quando non lo è.

punteggio

L'obiettivo di questo concorso sarà quello di rendere le dimensioni del codice sorgente scritto per risolvere questo compito, espresso in byte, il più piccolo possibile.

Casi test

1       -> True
2       -> True
4       -> True
10      -> False
98      -> True
101     -> True
109     -> False
819     -> False
4063    -> True
40427   -> True
2000221 -> True

OEIS 253996


Sono solo confuso dalla definizione della sfida in cui 1 e 2 sono anche input validi. Per non parlare del fatto che 1con un segno più inserito tra due caratteri qualsiasi (nessun inserimento) può solo derivare 1, che di per sé non è primo.
Magic Octopus Urn,

4
@MagicOctopusUrn Il plus deve essere inserito tra due cifre, quindi poiché 1e 2non hanno due cifre, l'insieme di espressioni è vuoto. Tutti i membri dell'insieme vuoto sono primi. Inoltre nessuno di loro lo è, ma questo è a parte il punto. È un po 'confuso, te lo darò ma penso che abbia più senso delle alternative.
Mago del grano

Risposte:


8

05AB1E , 10 byte

Codice

η¨¹.s¨R+pP

Utilizza la codifica 05AB1E . Provalo online! oppure Verifica tutti i casi di test!

Spiegazione

η¨             # Take the prefixes of the input and remove the last element
  ¹.s¨         # Take the suffixes of the input and remove the last element
      R        # Reverse the array of suffixes
       +       # Vectorized addition
        p      # Check if each element is prime
         P     # Product of the array

Come funziona per 1 - 9. Il prodotto di un set vuoto è 1? Perché?
Magic Octopus Urn,

@MagicOctopusUrn Il prodotto vuoto è sempre uguale a 1.
Adnan,

@MagicOctopusUrn Prendere il prodotto sta fondamentalmente iniziando 1e moltiplicandolo per ogni articolo del set, quindi ...
ETHproductions

1
Ah, matematicamente ha senso. Indovinate proprio come come sumil []è equivalente 0, utilizzando la proprietà di induzione in sede di attuazione era abbastanza intelligente.
Magic Octopus Urn,

@jontro Sì, in UTF-8 , sono 14 byte. Tuttavia, 05AB1E utilizza la tabella codici 05AB1E , dove sono 10 byte.
Adnan,

7

C (gcc) , 8384 85 83 84 86 75 111 byte

Tutte le ottimizzazioni sono state disattivate e solo su GCC a 32 bit.

-1 byte grazie a @ceilingcat

+ alcuni byte per 1caso.

+ alcuni byte per funzioni riutilizzabili.

i,j,r,s;f(a){for(i=10,r=1;a/i;i*=10)for(s=a%i+a/i,r*=s-1,j=2;j<s;)r*=s%j++>0;a=!r;}

Accetta l'input come numero intero. Restituisce 1 per casi falsi, 0 per casi veri.

Provalo online!

Vedi la mia altra risposta per il codice Mathematica (55 byte).


Dovrebbero essere due risposte separate. Inoltre, la soluzione di Mathematica fornisce risultati non corretti per 1, 98e 4063.
ngenisis,

6

Retina , 38 byte

\B
$`$*_$'$*_
S`\d
G`^_$|^(__+)\1+$
^$

Provalo online!

Stampa 1per numeri magnanimi e 0non.

Spiegazione

\B
$`$*_$'$*_

Iniziamo abbinando ciascuna posizione tra due cifre (posizioni che non sono limiti di parola) e inserendo sia il prefisso che il suffisso di quella corrispondenza in unario, usando _come cifra unaria. Quindi, invece di inserire +s, inseriamo direttamente il risultato unario della somma.

S`\d

Ora dividiamo la stringa attorno alle cifre, in modo che ogni somma vada sulla propria linea e ci liberiamo di quelle cifre (ci sarà anche una linea vuota iniziale e finale, ma non è importante).

G`^_$|^(__+)\1+$

Questa è la regex standard per abbinare i numeri non primi in unario. L'uso di una Gfase rep qui significa che manteniamo semplicemente tutte le linee che contengono non-primi positivi (scartando le linee vuote).

^$

Infine controlliamo se la stringa è vuota. Se l'input è stato magnanimo, la fase precedente avrà scartato tutte le righe (perché erano tutte prime) e questo ci dà 1. Altrimenti, se una qualsiasi linea non era un numero primo, rimarrà nella stringa e il regex fallirà, dando 0.


4

Python 2 , 82 79 78 byte

f=lambda n,d=10:n<d or d/n<all((n/d+n%d)%k*f(n,10*d)for k in range(2,n/d+n%d))

Questo è lento e può solo affrontare i casi di test con memoization.

Provalo online!

Versione alternativa, 79 byte

f=lambda n,d=10:n<d or f(n,10*d)>d/n<all((n/d+n%d)%k for k in range(2,n/d+n%d))

Spedito al costo di un byte.

Provalo online!



3

Java 8, 175 171 94 88 byte

n->{long d=10,r=0,i,t;for(;d<=n;d*=10,r|=t-i)for(t=n/d+n%d,i=1;t%++i%t>0;);return r==0;}

-77 grazie a @PeterTaylor usando un'aritmetica (invece di String con .substring) e sbarazzandosi del metodo separato per verificare se il numero intero è un numero primo.
-6 byte usando metodo di verifica primaria di @SaraJ , quindi assicurati di votarla!

Provalo qui.

Spiegazione:

n->{                  // Method with long as both parameter and return-type
  long d=10,r=0,i,t;  //  Some temp longs
  for(;d<=n           //  Loop as long as `d` is below or equal to input `n`
                      //  (inclusive instead of exclusive due to special case 10)
      ;               //    After every iteration:
       d*=10,         //     Multiple `d` by 10
       r|=t-i)        //     and Bitwise-OR `r` with `t-i`
    for(t=n/d+n%d,    //   Set `t` to `n` integer-divided by `d` plus `n` modulo-`d`
        i=1;          //   Set `i` to 1
        t%++i%t>0;);  //   Inner oop as long as `t` modulo `i+1` modulo `t` is not 0 yet
                      //   (after we've first increased `i` by 1 with `++i`)
                      //   (if `t` equals `i` afterwards, it means `t` is a prime)
  return r==0;}       //  Return if `r` is still 0

1
Penso che ci siano almeno due modi per accorciarlo: in primo luogo, sostituire il loop pcon la ricorsione; in secondo luogo, si accumulano i risultati tali che la funzione principale richiede solo una returndichiarazione rendendo il valore sentinella da pessere -1e utilizzare &per verificare che tutti i valori restituiti sono -1.
Peter Taylor,

1
In realtà, quello grande è: non usare le stringhe.
Peter Taylor,

n->{for(long d=10,m=1;d<n;d*=10)m|=p(n/d+n%d,2)-2;return m>0;}long p(long n,int i){return i<n?p(n%i<1?1:n,i+1):n;}
Peter Taylor,

@PeterTaylor Grazie per i suggerimenti! Per quanto riguarda la funzione suggerita alla fine, sei sicuro che sia corretta? Attualmente sto dando risultati errati , a meno che non stia facendo qualcosa di sbagliato.
Kevin Cruijssen,

1
Ok, d<=nda gestire 10. Lo overflow dello stack non è un problema (la specifica non fornisce un intervallo di input che deve essere gestito), ma può essere risolto e si possono ottenere più risparmi ritornando a un loop e inline .
Peter Taylor,

2

Pyth , 14 byte

.AmP_ssMcQ]dtU

Provalo online! Verrà visualizzato Truese il numero è magnanimo,False altrimenti. Prende il numero come una stringa.

spiegazioni

.AmP_ssMcQ]dtU

              Q    # Implicit input Q
            tU     # Generate the range [1, 2, ..., len(Q)-1]
  m                # For each index d in the above range...
        cQ]d       # Split Q at index d
      sM           # Convert the two parts to integers
     s             # Sum
   P_              # Check it is a prime
.A                 # ...end for. Check all elements are True

2

Python 2 , 104 102 98 96 103 byte

  • Grazie a @Wheat Wizard per 2 byte: fatto i completamente anonimo poiché viene chiamato una sola volta.
  • Grazie a @Hyperneutrino per 4 byte: un modo più intelligente di ottenere i numeri dal numero principale invece di tagliare
  • @Hyperneutrino ha salvato altri 2 byte: x-1in appenax per il controllo del controllo principale.
  • Risolto il problema per caso x=10, aggiungendo così 7 byte, grazie a @Dennis e alla procedura guidata @Wheat per averlo individuato: la mia versione precedente considerava 1 un numero primo
lambda x:all((lambda x:x>1and all(x%j for j in range(2,x)))(x/10**j+x%10**j)for j in range(1,len(`x`)))

Provalo online!



Bene, grazie @HyperNeutrino
officialaimm,

1
96 byte : non è necessario x-1alla fine dell'intervallo; la gamma è esclusiva a destra.
HyperNeutrino,

1
Questo fallisce per 10 (nuovo test case).
Dennis,

1
Questo fallisce per 10. Credo anche che 10 sia l' unico numero per cui fallisce.
Mago del grano

2

Japt , 24 16 byte

Questa è stata praticamente una collaborazione tra @Shaggy, @ETHproduction e me stesso.

¬£[YîU UtY]xÃÅej

Provalo online!

Accetta l'input come stringa.


Gah! Quasi identico alla soluzione alternativa a cui stavo lavorando! Ecco i 22 byte che ho avuto finora. EDIT: ottenuto fino a 20 byte combinando cose da entrambi.
Shaggy,

@Shaggy Abbastanza divertente, sto lavorando alla mia modifica in questo momento ... È incredibilmente simile alla tua: ethproductions.github.io/japt/…
Oliver,

Suggerimento: xconverte automaticamente gli elementi dell'array in numeri ;-)
ETHproductions

Sì, è qui che andrei anche io, @ETHproductions: 16 byte .
Shaggy,

Inoltre, XîUè geniale. Penso che U¯X
funzioni

2

Pip , 25 24 byte

$&0N_%,_=1M$+(a^@_)M1,#a

Provalo online!

Spiegazione

aè il primo argomento della riga di comando. 1,#agenera un intervallo contenente numeri 1attraverso len(a)-1. A questo, mappiamo una funzione lambda:

$+(a^@_)
   a^@_   Split a at this index
$+(    )  Fold the resulting 2-element list on +

Successivamente, mappiamo un'altra funzione lambda 0N_%,_=1, che verifica la primalità. L'ho preso da questa risposta ; puoi leggere la spiegazione lì. Infine, pieghiamo l'elenco su AND logico ( $&). Il risultato è 1se tutte le somme fossero prime, in 0caso contrario.

Esempio, con input di 4063:

                    1,#a   [1; 2; 3]
           $+(a^@_)M       [67; 103; 409]
  0N_%,_=1M                [1; 1; 1]
$&                         1

2

CJam , 22 byte

r:L,({)_L<i\L>i+mp!},!

Provalo online!

Stampa numero intero positivo per verità, zero per falsa.

-1 grazie a un trucco intelligente di Peter Taylor .
-3 grazie ad un altro suggerimento di Peter Taylor.


0&!è più corto di1+:*
Peter Taylor il

@PeterTaylor Ooh che è intelligente ... hai abusato del fatto che !restituisce un valore booleano e hai usato l'intersezione set con il valore falsy in 0modo che tu possa fare 0&!in 3 invece di 1&!!...
Erik the Outgolfer

È possibile salvare altri 3 byte assegnando l'input a una variabile, il che semplifica le manipolazioni dello stack e utilizzando l' ,operatore di filtro anziché f.
Peter Taylor,

PS Non vedo alcun abuso nell'uso !per convertire in un valore booleano: era standard in GolfScript ed è standard in CJam. E 1&!!sarebbe errato: 0&!è il test ovvio perché il requisito è forall, non esiste.
Peter Taylor,

@PeterTaylor Non intendevo questo: P
Erik the Outgolfer,

2

Japt , 23 byte

Accetta l'input come stringa.

Dang it; battuto fino al pugno su un'alternativa molto più breve a cui stavo lavorando.

£i+Ýe@OxXr"%+0+"'+)j

Provalo


@ETHproductions, no, avevi ragione; la versione originale era sbagliata; controllando solo numeri primi magnanimi . ¬£i+YÄÃe@OxX j
Shaggy,

Sapevo di non aver perso la testa; P
ETHproductions

1
Errore 4063(dovrebbe essere vero, è falso). Il trucco qui è che JS pensa che un vantaggio 0significhi che vuoi ottale ...
ETHproductions

Hmmm ... OK, penso di avere un'alternativa - ci vorranno alcuni minuti per testarlo e giocarlo.
Shaggy,

Penso che questo fallirà ora in alcuni casi che contengono due 0 seguiti da altre due cifre ... ( 40043, ad esempio) Basta aggiungere un +dopo il 0per risolvere questo problema.
ETHproductions

2

Mathematica, 75 byte

And@@Table[PrimeQ@ToExpression@StringInsert[#,"+",n],{n,2,StringLength@#}]&

Functionche si aspetta a String. indica PrimeQ@ToExpression@StringInsert[#,"+",n]se l'inserimento di una lettera +dopo la nth dà un numero primo. Table[...,{n,2,StringLength@#}]fornisce l'elenco di questi valori come nintervalli dalla 2lunghezza della stringa. Prendiamo quindi Andciascuno degli elementi di tale elenco. Convenientemente, se StringLength@#<2, quindi Table[...]è l'elenco vuoto, per il qualeAnd@@{}==True


2

Mathematica, 55 50 45 49 50 54 62 byte

Sembra che dovrei pubblicarlo separatamente.

+6 byte per la lunghezza del codice rimisurata.

+5 byte grazie alla ngenisi.

And@@(qPrimeQ[#~Mod~q+⌊#/q⌋])@Rest@PowerRange@#&

Prende l'input come numero intero e restituisce regolare Truee False. Il mezzo è Unicode 0xF4A1, abbreviazione di Function[,]. La lunghezza del codice viene misurata sulla dimensione del file (UTF-8 senza DBA), commentare se non è corretto.

PowerRange[x]restituisce 1, 10, 100 ... non maggiore di x, che viene introdotto in Mathematica 10.


2

Inglese semplice 4.204 341 315 251 241 240 byte

(Ri) incorporato test di primalità nella libreria di Plain English, spostando 3.863 byte nella libreria di Plain English. Eliminati 26 byte di spazio bianco. 64 byte salvati abbreviando le variabili locali. 10 byte salvati abbreviando l'interfaccia. Secondo il suggerimento di RosLuP , è stato salvato 1 byte modificando la modalità di inizializzazione e incremento di m.

To decide if a n number is g:
Put 1 in a m number.
Loop.
Multiply the m by 10.
If the m is greater than the n, say yes.
Divide the n by the m giving a q quotient and a r remainder.
Add the q to the r.
If the r is not prime, say no.
Repeat.

Versione non modificata del codice finale:

To decide if a number is magnanimous:
  Put 1 in another number.
  Loop.
    Multiply the other number by 10.
    If the other number is greater than the number, say yes.
    Divide the number by the other number giving a quotient and a remainder.
    Add the quotient to the remainder.
    If the remainder is not prime, say no.
  Repeat.

Note: L'IDE inglese semplice è disponibile su github.com/Folds/english . L'IDE funziona su Windows. Si compila in codice x86 a 32 bit.

Il fork dinamico di Plain English dell'Ordine Osmosiano aveva già avuto test di primalità nella versione 4700, ma utilizzava un algoritmo molto inefficiente (da gennaio a giugno 2017). Le versioni 4001-4011 del fork dinamico del sito GitHub hanno omesso i test di primalità. La versione 4013 del fork dinamico del sito GitHub include test di primalità. Il codice per eseguire il test di primalità è stato sviluppato come parte delle precedenti revisioni di questa risposta.


1

Perl 6 , 58 byte

{?(10,10* *...^*>$_).map({$_ div$^a+$_%$^a}).all.is-prime}

Provalo online!

10, 10 * * ...^ * > $_ is the geometric sequence of multiples of ten, taken until one before the element that exceeds the input parameter $_. Then we just check that for each power of ten, the sum of the input parameter taken div and mod that power is prime.


1

Haskell, 114 110 bytes

p x=[x]==[i|i<-[2..x],x`mod`i<1]
i!x|i<1=0<1|0<1=p(uncurry(+)$divMod x$10^i)&&(i-1)!x
f x=(length(show x)-1)!x

Ungolfed with explanation:

-- Check if x is a prime number
p x = [x] == [i | i<-[2..x], x`mod`i < 1]
-- Checks all pairs of numbers a '+' can be put in between
i ! x | i<1 = 0<1                                -- Single-digit numbers are always truthy
      | 0<1 = p (uncurry (+) $ divMod x $ 10^i)  -- Does x split at i digits from right sum up to a prime?
           && (i-1) ! x                          -- If so, check next pair
-- Start (!) with the number of digits in x minus one
f x = (length (show x)-1) ! x

If you use p x=[x]==[i|i<-[2..x],x`mod`i<1] as your prime check you can save 2 bytes.
Wheat Wizard

You can also use divMod x$10^i instead of x`divMod`(10^i)
Wheat Wizard

@WheatWizard: I knew the prime test could still be improved somehow. ;) Thanks!
siracusa

1

Axiom, 88 bytes

f(n:PI):Boolean==(i:=10;repeat(q:=n quo i;q=0 or ~prime?(q+n rem i)=>break;i:=i*10);q=0)

test and results

(10) -> [[i,f(i)]  for i in [1,2,4,10,98,101,109,819,4063,40427,2000221,999999999999999999999999999999999999999999999]]
   (10)
   [[1,true], [2,true], [4,true], [10,false], [98,true], [101,true],
    [109,false], [819,false], [4063,true], [40427,true], [2000221,true],
    [999999999999999999999999999999999999999999999 ,false]]


1

Perl 6, 35 bytes

{m:ex/^(.+)(.+)$/.all.sum.is-prime}

Try it online!

Explanation:

{                                 }     # Anonymous code block that
 m:ex/^        $/                         # Match all
       (.+)(.+)                           # Splits of the input number
                 .all                     # Are all of them
                     .sum                   # When summed
                         .is-prime          # Prime?

0

Stacked , 51 byte

[tostr:#'1-~>splitat tr['+',' '#`#~prime]map 1,all]

Try it online!

Questa è una funzione Funziona convertendo il suo argomento in una stringa ( tostr), duplicandolo e ottenendo la sua lunghezza ( :#'), sottraendo 1 ( 1-), facendo un intervallo da 1 a quel numero ( ~>). Lo stack è simile a questo, per input 40427:

('40427' (1 2 3 4))

Eseguiamo vettorializzati splitat, portando il seguente array ad essere in cima allo stack:

(('4' '40' '404' '4042') ('0427' '427' '27' '7'))

Trasponendolo con tr, otteniamo:

(('4' '0427') ('40' '427') ('404' '27') ('4042' '7'))

Quindi, mappiamo la funzione ['+',' '## ~ prime] (withmap`). Questa funzione fa:

['+',' '#`#~prime]
 '+',                concatenate a plus sign (string)    `('4' '0427' '+')
     ' '#`           join by spaces                      `'4 0427 +'`
          #~         evaluate                            `431`
            prime    check primality                     `1`

Quindi, dopo la mappa, ci concateniamo 1. Questo perché allrestituisce undefun elenco vuoto.


0

JavaScript (ES6), 70 byte

P=(n,x=2)=>n%x?P(n,x+1):n==x
f=(n,i=10)=>i>n||P((n/i|0)+n%i)&f(n,i*10)

Fails on the last case in my browser due to a "too much recursion" error while calculating P(200023). Hopefully this doesn't invalidate it.


0

QBIC, 38 bytes

_L;|[a-1|q=q*µ!_sA,b|!+!_sA,b+1,a|!}?q

Explanation

_L |     Create a variable a and set it to the length of
  ;      the input string (A$)
[a-1|    FOR b = 1 to a-1
q=q*     multiply q by
 µ       -1 if prime, 0 if not, of
  !        a cast of 
   _s       a substring of
     A,       A$
     b        from index 1 to index b (only one index is given, so that is assumed to be the req. length from 1)
      |!   to number
 +         plus
 !         a cast of
  _s         a substring of
    A,         A$
    b+1        from index b+1
    ,a         for the length of a (does not error if it exceeds the end of the string)
      |!   to number
 }       NEXT 
 ?q      PRINT q, which is eitrher -1 or 1 for all-prime sums, or 0 otherwise

0

CJam (21 bytes)

r:R,({RiA@)#md+mp!},!

Online demo, online test suite

Dissection

r:R       e# Take a token of input and assign it to R
,(        e# Take the length of R minus one
{         e# Filter i = 0 to (length of R minus two)
  Ri      e#   Push R as an integer value
  A@)#    e#   Push 10 to the power of (i + 1)
  md      e#   divmod
  +mp!    e#   Add, primality test, negate result
},        e# The result of the filter is a list of splits which give a non-prime
!         e# Negate result, giving 0 for false and 1 for true


0

APL(NARS), chars 35, bytes 70

{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}

test:

  f←{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}
  f¨1 2 4 10 98 101 109 819 4063 40427 2000221
1 1 1 0 1 1 0 0 1 1 1 

This would be the translation in APL from Axiom post algo here...

{0≥k←¯1+≢⍕⍵:1⋄∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k}
 0≥k←¯1+≢⍕⍵:1⋄  assign to k the length as array of argument return 1 if that is <=0
 ∧/0π(m∣⍵)+⌊⍵÷m←10*⍳k
              m←10*⍳k  m is the array pow(10,1..k)
           ⌊⍵÷m       the array of quotient of argumet with m
          +           sum 
     (m∣⍵)            with array of remander
   0π                 build the binary array of "are prime each"
 ∧/                   and that array

0

PHP, 100 bytes

for(;++$k<strlen($a=$argn);$x+=$i==1)for($i=$n=substr($a,$k)+$b.=$a[$k-1];--$i&&$n%$i;);echo$x+2>$k;

prints 1 if input is magnanimous, empty output if not. Run as pipe with -nR or try it 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.