È un numero primo? senza matematica [chiuso]


14

Scrivi un programma o una funzione in qualsiasi lingua che indichi se l'ingresso è un numero primo.

  • L'input è una stringa che rappresenta un numero naturale in base-10.
  • L'output è una delle due stringhe "Prime" o "Not !!" che identifica correttamente l'input.
  • Operatori aritmetici, operatori bit per bit, variabili e costanti numeriche, "elementi matematici" in generale, ecc ... non sono ammessi in nessun punto del programma. È necessario utilizzare le operazioni sulle stringhe per eseguire tutti i "calcoli" necessari.
  • È possibile confrontare le lunghezze delle stringhe (che sono numeri), ma in caso contrario, -10 al punteggio.
  • Il programma dovrebbe funzionare su qualsiasi input di lunghezza (con memoria e tempo sufficienti).
  • Vince il conteggio dei byte più basso (UTF-8).

Quali sono i limiti sul numero? Può essere negativo? Zero? Può contenere un punto decimale?
Giustino,

Se ha punti bonus, non è code-golf
Peter Taylor

Aggiunto "naturale" per specificare i limiti sull'input.
Wally,

Speravo di essere sorpreso da una folle manipolazione esplicita della stringa (stavo pensando personalmente di scrivere il codice per "decrementare" una stringa in modo da poter fare un ciclo - e sono stato diviso tra la divisione lunga della stringa e la sottrazione ripetuta della stringa ...), invece fu sorpreso da quel piccolo regex unario primo matcher! Forse dovrei porre di nuovo la domanda, impedendo a regex di vedere se ricevo cose ancora più meravigliose? Ma non credo che nulla sarà in grado di avvicinarsi alla brevità di quella regex.
Wally,

Per ottenere "cose ​​più meravigliose" forse potresti provare a renderlo un concorso di popolarità . Tuttavia, la modifica della stessa domanda è generalmente disapprovata. E non sono sicuro che dovresti fare una nuova domanda o cambiare qualcosa solo perché qualcuno ha inventato qualcosa a cui non hai pensato - penso che succeda abbastanza spesso qui. Inoltre, la flessione delle regole fa parte dello sport :)
daniero,

Risposte:


7

Rubino, 64-10 = 54

puts ('1
'..gets).map{?1}*''=~/^1?$|^(11+?)\1+$/?'Not!!': :Prime

Questo scorre dalla stringa '1' (più una nuova riga) alla stringa di input, usando il metodo di iterazione di stringa incorporato di Ruby che assomiglia moltissimo come l'aggiunta di 1, ma che tecnicamente non crea una variabile numerica di alto livello in nessun punto . Usa il fatto che ci saranno n iterazioni per un input di n per creare una stringa n-lunghezza, quindi usa un'espressione regolare per determinare se quella stringa può essere raggruppata in sottostringhe identiche.


L '"1" nella "mappa {? 1}" è un Fixnum? - in tal caso, potresti doverlo cambiare in "map ('1')? Non riesco a trovare alcuna documentazione sull'espressione? 1 tranne alcuni suggerimenti che nelle versioni precedenti di Ruby restituiva codici ASCII e ora restituisce una stringa .
Wally

? 1 è uguale a '1', è letterale di una stringa di 1 carattere. Potrei sostituire tutte le istanze di 1 ma la prima con qualsiasi altro personaggio.
istocrato,

Ok - non riuscivo a trovare quella costruzione ben descritta da nessuna parte!
Wally,

Ho scelto questo come "il vincitore" poiché fa di tutto per evitare anche un pizzico di matematica.
Wally,

3
Nessuna punta di cappello ad Abigail? Per vergogna. Questa è una porta diretta della soluzione perl del 1998: catonmat.net/blog/perl-regex-that-matches-prime-numbers
skibrianski

16

Rubino: 52-10 = 42

Usando una variante di quel famoso regex di corrispondenza dei primi.

puts ?_*gets.to_i=~/^(_|(__+?)\2+)$/?"Not!!":"Prime"

Giusto per essere chiari: ?_*gets.to_iè un'operazione stringa che si aggiunge "_"a se stessa n volte, dove n è il numero di input. A mio avviso, non viene confrontata la lunghezza delle stringhe, quindi ciò dovrebbe soddisfare il criterio del bonus di 10 caratteri.


1
Non ho familiarità con Ruby, quindi correggimi se sbaglio, ma "to_i" non converte la stringa in un numero intero? Non che io non ami il brillient prime checker in unario ...
Wally,

1
@Wally Non penso che "convertire" non sia la parola giusta, ma il metodo restituisce un int, sì. Tuttavia, non utilizzo nessuna delle seguenti Arithmetic operators, bit-wise operators, numeric variables and constants, e non puoi davvero classificare chiamando un metodo come "math-stuff" in general..?
daniero,

@daniero Sembra ragionevole, forse proprio al limite delle specifiche.
Wally,

3

Perl 52-10 = 42

Implementazione

print((('-'x$ARGV[0])=~/^.$|^(..+?)\1+$/)?Not:Prime)

dimostrazione

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && perl Prime.pl {} && echo"
1 Not
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not

4
1 non è proprio un numero primo.
elixenide,

Utilizza un indice numerico di array, quindi al limite delle specifiche.
Wally,

Usa popinvece di $ARGV[0], salva 4 caratteri, rimuovi indice numerico array
mob

1

ECMAScript 6, 159-10 = 149

Sembra un compito per regex. I / O con prompt/ alertcome al solito.

for(s=prompt(u=""); /[^0]/.test(s); )
  s=s.replace(/(.)(0*)$/,(_,d,t)=>u+="x"," 012345678"[d]+t.replace(/0/g,"9"))
alert(/^((xx+)\2+|x?)$/.test(u)?"Not!!":"Prime")

Il ciclo while decrementa il numero decimale di uno ogni iterazione puramente mediante regex. La regex finale corrisponde a una stringa composta da un numero composto di x, facendo corrispondere prima un fattore, quindi un altro ripetendo il primo fattore uno per il resto della stringa.


Mi piace la funzione di decremento delle stringhe: chiara e concisa.
Wally,

1

Javascript 266

function N(a){function b(a){return P.every(function(b){if(n=b,i=a.length,j=b.length,j>i) return;if(j==i) return 1;while(n.length<i)n+=b;return n.length!=i})}if(q=A,A!=a)for(;q.length.toString()!=a;)b(q)&&P.push(q),q+=A;console.log(b(q)?"Prime":"Not!!")}A="0",P=[A+A]

Crea una funzione chiamata N che stamperà il risultato desiderato. La versione non modificata è simile a questa. Ho fatto una minificazione a mano per ripulire alcune variabili e poi l'ho passato attraverso uglify e poi lo ho minimizzato a mano.

// A a string of "0" for using to generate long strings
// P is the store for all known primes
A="0", P=[A+A];
function N(val) {
  function _isPrime(str) {
    // go through all the known primes and return true
    // if we don't match on any of them
    return P.every(function(prime) {
      // prime is some known string whose length is a prime number
      tsr = prime, strlen = str.length, primelen = prime.length;
      // if the string we're checking has fewer chars than
      // this then it's not a prime
      if(strlen < primelen) return 0;
      // if the string we're checking has the same number of chars
      // as the the prime we're checking against then it is a prime
      if(primelen == strlen) return 1;
      // Keep incrementing our temporary string with the prime we're
      // checking. we'll break out of the loop once the temporary string
      // is greater than or equal to the string we're testing
      while(tsr.length < strlen) {
        tsr += prime;
      }
      return !(tsr.length == strlen)
    });
  }
  // start with a string of one unit
  nstr = A
  if(A!=val) {
    // keep incrementing the string so that we can compile a list
    // of known primes smaller than this value
    while(nstr.length.toString() !== val) {
      if(_isPrime(nstr)) {
        P.push(nstr);
      }
      nstr += A;
    }
  }
  console.log(_isPrime(nstr) ? "Prime" : "Not!!");
}

Testato usando questo snippet:

for(var X=0;X<10;X++) {
  console.log('checking: ' + X);
  N(X.toString());
}

1
Non sono sicuro di vedere come funziona, ma vedo una variabile numerica (i) e un operatore aritmetico (i ++).
Wally,

Oh, non avevo capito che non potevo fare un ciclo for in quel modo .. lo riscriverò stasera.
Sugendran,

Fondamentalmente sto producendo una serie di stringhe le cui lunghezze sono numeri primi. Quindi quando ricevo un input continuo ad aggiungere caratteri a una stringa fino a quando il valore di lunghezza per la stringa corrisponde all'input. Prendo quindi questa stringa e vedo se posso dividerla uniformemente per uno dei numeri primi conosciuti. Se non posso, allora deve essere un numero primo. E per divisione intendo che prendo la stringa principale nota e continuo ad aggiungerla a se stessa, la lunghezza della stringa è uguale o maggiore della stringa in questione.
Sugendran,

Ho aggiornato il codice, in realtà riduce leggermente il numero di caratteri :)
Sugendran,

Freddo. Sembra la stessa idea del regex, ma più efficiente e mostra esplicitamente la logica attuale.
Wally,

0

Bash 66 - 10 = 56

Implementazione

[[ -z `printf %$1s|grep -P "^(..+?)\1+$"` ]]&&echo Prime||echo Not

dimostrazione

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && ./Prime.sh {}"
1 Prime
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not

Come sopra, 1 non è un numero primo.
Wally,

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.