É um primo? sem matemática [fechado]

14

Escreva um programa ou função em qualquer idioma que diga se a entrada é um número primo.

  • A entrada é uma sequência que representa um número natural na base 10.
  • A saída é uma das duas strings "Prime" ou "Not !!" que identifica corretamente a entrada.
  • Operadores aritméticos, operadores bit a bit, variáveis ​​e constantes numéricas, "coisas matemáticas" em geral, etc ... não são permitidos em nenhum lugar do seu programa. Você deve usar operações de string para fazer todos os "cálculos" necessários.
  • Você pode comparar comprimentos de string (que são números) - mas -10 à sua pontuação, se não o fizer.
  • Seu programa deve funcionar com qualquer entrada de comprimento (com tempo e memória suficientes).
  • A menor contagem de bytes (UTF-8) vence.
Wally
fonte
Quais são os limites do número? Pode ser negativo? Zero? Ele pode conter um ponto decimal?
23414 Justin
Se ele tem pontos de bônus, não é código-golf
Peter Taylor
Adicionado "natural" para especificar limites na entrada.
Wally
Eu estava esperando ficar surpreso com alguma manipulação explícita e louca de strings (eu estava pensando pessoalmente em escrever código para "diminuir" uma string para poder fazer um loop - e fiquei dividida entre a divisão longa da string e a subtração repetida ...), em vez disso, eu ficou surpreso com aquele pequeno e legal ex-jogador unitário! Talvez eu precise fazer a pergunta novamente, desabilitando o regex para ver se eu recebo coisas ainda mais maravilhosas? Mas acho que nada será capaz de se aproximar da brevidade desse regex.
Wally
Para obter "coisas mais maravilhosas", talvez você possa tentar torná-lo um concurso de popularidade . Mudar a questão em si é geralmente desaprovado. E não tenho certeza de que você deva fazer uma nova pergunta ou mudar alguma coisa, apenas porque alguém apresentou algo em que você não pensou - acho que isso acontece com frequência aqui. Além disso, a regra de flexão é parte do esporte :)
daniero

Respostas:

7

Ruby, 64 - 10 = 54

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

Isso itera da string '1' (mais uma nova linha) para a string de entrada, usando o método de iteração de string incorporado do Ruby, que se parece muito com a adição de 1, mas que tecnicamente não cria uma variável numérica de alto nível a qualquer momento . Ele usa o fato de que haverá n iterações para uma entrada de n para criar uma cadeia de comprimento n e, em seguida, usa uma expressão regular para determinar se essa cadeia pode ser agrupada em substrings idênticos.

histocrata
fonte
O "1" no "mapa {? 1}" é um Fixnum? - em caso afirmativo, pode ser necessário alterá-lo para "map ('1')? Não consigo encontrar nenhuma documentação sobre a expressão? 1, exceto algumas dicas de que nas versões anteriores do Ruby ele retornava códigos ASCII e agora retorna uma string .
Wally
? 1 é o mesmo que '1', é uma literal de cadeia de 1 caractere. Eu poderia substituir todas as instâncias de 1, mas a primeira por qualquer outro caractere.
Histocrat
Ok - eu simplesmente não conseguia encontrar essa construção bem descrita em lugar nenhum!
Wally
Eu escolho isso como "o vencedor", uma vez que evita um pingo de matemática.
Wally
3
Nenhuma dica de chapéu para Abigail? Por vergonha. Este é AFAICT uma porta em frente dos 1998 perl solução: catonmat.net/blog/perl-regex-that-matches-prime-numbers
skibrianski
16

Ruby: 52 - 10 = 42

Usando uma variação desse famoso regex de correspondência principal.

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

Só para ficar claro: ?_*gets.to_ié uma operação de cadeia que anexa "_"a si mesma n vezes, onde n é o número de entrada. A meu ver, não são comparados comprimentos de cadeia, o que deve satisfazer o critério de bônus de 10 caracteres.

daniero
fonte
1
Eu não estou tão familiarizado com Ruby, então me corrija se estiver errado, mas o "to_i" não converte a string em um número inteiro? Não que eu não ame o brilhante verificador principal em unário ...
Wally
1
@Wally Eu não acho que "converter" não é a palavra certa, mas o método retorna um int, sim. Ainda assim, não uso nenhum dos itens a seguir Arithmetic operators, bit-wise operators, numeric variables and constantse você não pode realmente classificar a chamada de método como "math-stuff" in general..?
Daniero 15/02
@daniero Parece razoável - talvez bem no limite das especificações.
Wally
3

Perl 52-10 = 42

Implementação

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

Demo

$ 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
Abhijit
fonte
4
Eu não sou realmente um primo.
Elixenide
Usa um índice numérico da matriz - portanto, na borda da especificação.
Wally
Utilizar pop, em vez de $ARGV[0], excepto 4 caracteres, remover numérica índice de matriz
turba
1

ECMAScript 6, 159 - 10 = 149

Soa como uma tarefa para regex. E / S com prompt/ alertcomo de costume.

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

O loop while diminui o número decimal em um a cada iteração puramente por regex. O regex final corresponde a uma sequência que consiste em um número composto de x, correspondendo primeiro um fator e, em seguida, outro, repetindo o primeiro fator um para o restante da sequência.

FireFly
fonte
Eu gosto da função de decremento de string - clara 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]

Cria uma função chamada N que imprime o resultado desejado. A versão não compactada fica assim. Eu fiz um hand minify para limpar algumas variáveis ​​e, em seguida, executei o uglify e depois o hand minify novamente.

// 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!!");
}

Testei usando este trecho:

for(var X=0;X<10;X++) {
  console.log('checking: ' + X);
  N(X.toString());
}
Sugendran
fonte
1
Não sei se vejo como isso funciona, mas vejo uma variável numérica (i) e um operador aritmético (i ++).
Wally
Ah, não percebi que eu não poderia fazer um loop for assim .. reescrevê-lo esta noite.
Sugendran 19/02
Basicamente, estou produzindo uma matriz de seqüências cujos comprimentos são primos. Portanto, quando recebo uma entrada, continuo adicionando caracteres a uma sequência até o valor do comprimento corresponder à entrada. Então pego essa sequência e vejo se posso dividi-la uniformemente por qualquer um dos primos conhecidos. Se não posso, deve ser um primo. E por divisão, quero dizer, pego a string principal conhecida e continuo adicionando a ela mesma que o comprimento da string seja igual ou maior que a string em questão.
Sugendran
Eu atualizei o código, ele realmente reduz o número de caracteres ligeiramente :)
Sugendran
Legal. Parece a mesma idéia que o regex, mas mais eficiente e mostra explicitamente a lógica real.
Wally
0

Festança 66 - 10 = 56

Implementação

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

Demo

$ 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
Abhijit
fonte
Como acima, 1 não é primo.
Wally
0

Python 3, 109-10 = 89

print(['Not','Prime'][(lambda i:not any(' '*i==(' '*u)*v for u in range(i)for v in range(i)))(int(input()])

Não comparando comprimentos de string, mas inclusão de string. Postagem cruzada de duplicado Determine se um número é primo sem usar aritmética

Evpok
fonte