É 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.

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.


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.


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

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.


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());
}

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

Como acima, 1 não é primo.
— Wally

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.