Como encontrar números não muito primos


17

Seu desafio, se você optar por aceitá-lo, é codificar como golf uma função que retorna true ou false (ou alguma representação significativa similar de yes e no) se um número atender aos seguintes critérios:

  1. O inteiro em si é um número primo OU
  2. Qualquer um dos números inteiros vizinhos é primo

Por exemplo:
Uma entrada de 7retornaria True.
Uma entrada de 8também retornaria True.
Uma entrada de 15retornaria False. (Nem 14, 15 ou 16 são primos)

A entrada deve poder retornar corretamente para números entre 2 ^ 0 e 2 ^ 20, inclusive, portanto, não há necessidade de se preocupar com problemas de sinal ou estouros de número inteiro.


Estouros de número de 32 bits, não estouros de buffer, eu acho.
usuário desconhecido

Opa, significava "excesso de número inteiro". O cérebro entrou no piloto automático.
Mr. Llama

Respostas:


11

J, 17

*/<:$&q:(<:,],>:)

Retorna booleanos codificados como códigos de retorno do processo: zero para true, diferente de zero para false. Uso da amostra:

   */<:$&q:(<:,],>:) 7
0
   */<:$&q:(<:,],>:) 8
0
   */<:$&q:(<:,],>:) 15
3

*/0 p:<:,],>:é mais curto e uma função adequada (lambda) é([:*/0 p:<:,],>:)
randomra

9

Haskell, 47 caracteres

f n=any(\k->all((>0).mod k)[2..k-1])[n-1..n+1]

6

Python 85 80

def f(n):g=lambda n:all(n%i!=0for i in range(2,n));return g(n)or g(n-1)or g(n+1)

Primeira vez no Code Golf, provavelmente faltam alguns truques.


Você pode remover o []. todos ficarão felizes em trabalhar com uma expressão geradora. Se você não se importa que seu código seja feio, você também pode remover os espaços entre 0e for, e )e or.
stranac

@stranac Awesome. Muito obrigado.
Kris Harper

3
Fez algumas mudanças diretas, espero que ainda funcione:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
Nabb 14/01

@ Nabb Muito bom. Bem feito.
Kris Harper

5

Não é um candidato real na falta de código, por qualquer meio, mas ainda está enviando, pois a determinação da primidez pela expressão regular é distorcida de várias maneiras!

Python (2.x), 85 caracteres

import re
f=lambda n:any(not re.match(r"^1?$|^(11+?)\1+$","1"*x)for x in[n,n-1,n+1])

Você pode remover o loop for e construí-lo no regexp testando "1" * (n + 1), mas começando com ^ 1? 1? em vez de.
Howard

4

Ruby (55 ou 50 como lambda)

def f q;(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}};end

ou como lambda (use g[23]para chamá-lo)

g=->q{(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}}}

Cafés (53)

p=(q)->[q-1..q+1].some (n)->[2..n-1].every (d)->n%d>0

<pedantic> Deveria ser "proc" e não "lambda" </pedantic> ;-)
Maçaneta da porta

3

O Mathematica chato , 35 solução!

PrimeQ[n-1]||PrimeQ[n]||PrimeQ[n+1]

15
Pelo menos você pode jogar Or@@PrimeQ/@{n-1,n,n+1}.
Howard

Isto não é uma função.
Martin Ender

@ MartinBüttner: Não conheço o Mathematica, desculpe.
Ry-

2
Usando a versão de Howard, Or@@PrimeQ@{#-1,#,#+1}&(a barra em seu código não é necessária)
Martin Ender

3

C, 112 82 72 caracteres

Após o comentário de Ilmari Karonen, salvou 30 caracteres removendo maine agora Pretorna verdadeiro / falso. Também substituiu o loop pela recursão e mais alguns ajustes.

p(n,q){return++q==n||n%q&&p(n,q);}P(n){return p(-~n,1)|p(n,1)|p(~-n,1);}

Versão original:

p(n,q,r){for(r=0,q=2;q<n;)r|=!(n%q++);return!r;}
main(int n,int**m){putchar(48|p(n=atoi(*++m))|p(n-1)|p(n+1));}

Você pode salvar 2 caracteres com main(n,m)int**m;.
Ilmari Karonen

... e além disso, o desafio diz "código-golf uma função ".
Ilmari Karonen

3

Mathematica, 24 bytes

Não sei por que esse post antigo apareceu na minha lista hoje, mas percebi que o Mathematica é competitivo aqui.

Or@@PrimeQ/@{#-1,#,#+1}&

Função sem nome, usando um argumento inteiro e retornando Trueou False. Implementação direta.


PrimeQthreads sobre listas, então Or@@PrimeQ@{#-1,#,#+1}&(ou Or@@PrimeQ[#+{-1,0,1}]&) também funciona, para -1 byte. (Embora, eu acho que eu não sei se PrimeQde rosca sobre listas em 2012.)
Misha Lavrov

3

Stax , 6 bytes

Ç▀<╝ºΩ

Execute e depure

Explicação (sem embalagem):

;v:Pv<! Full program, implicit input  Example: 7
;v      Copy input and decrement               7 6
  :P    Next prime                             7 7
    v   Decrement                              7 6
     <! Check if input is >= result            1

2

JavaScript (71 73 80 )

n=prompt(r=0);for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;alert(r)

Demonstração: http://jsfiddle.net/ydsxJ/3/

Editar 1: mude for(i=2;i<j;i++)para for(i=1;++i<j;)(obrigado @minitech). Converter ifdeclaração em ternário. Movido r|=pe p=1para o exterior forpara eliminar chaves internas. Salvou 7 caracteres.

Edição 2: Combinar p=1e j++<=nparap=j++<=n , senão 2 chars (graças @ugoren).


Você pode usar em for(i=1;++i<j;)vez de for(i=2;i<j;i++)salvar mais 1 caractere.
Ry-

11
@ Minitech: !j%inão funcionará por causa da precedência. Uma alternativa de trabalho é j%i<1.
Nabb

@Nabb: Uau, você está certo. Isso é bobagem.
Ry-

Que tal p=j++<=n? Se o Javascript é como C aqui, deve funcionar.
ugoren

@ugoren: Parece que funcionou, obrigado!
Mckamokb

2

Regex (ECMAScript), 20 bytes

^x?x?(?!(x+)(x\1)+$)

Experimente online!

A versão acima não lida corretamente com zero, mas isso exige apenas 1 byte extra:

^x?x?(?!(x+)(x\1)+$)x

Como um bônus adicional, aqui está uma versão que fornece uma correspondência de retorno de 1um a menos que um primo, 2para um primo e 3um mais que um primo:

^x?x??(?!(x+)(x\1)+$)x

Experimente online!


A gama a pergunta fala sobre ele é "entre 2 ^ 0 e 2 ^ 20" para 1..2 ^ 20 então 0 não existe ...
RosLuP

@RosLuP É exatamente por isso que minha resposta principal é 20 bytes e não lida com 0 corretamente. Acho que vale a pena ir além das especificações precisas da pergunta e fornecer respostas mais robustas, além da resposta que corresponda minimamente às especificações da pergunta.
Deadcode

Às vezes eu faço o mesmo (escrevo teste 'desnecessário'), mas isso parece ir contra a maneira de pensar do codegolf, e as pessoas que escrevem não são consideradas "sérias" ...
RosLuP 03/02/19

11
@RosLuP Mas qual é o mal, desde que eu dê a resposta mínima como minha resposta principal? E você pode dar exemplos de pessoas que realmente pensam dessa maneira? Eu poderia entender se desse a minha única resposta como robusta, mas não estou fazendo isso.
Deadcode

1

C #, 96

Retorna -1,0,1 para true, qualquer outra coisa é falsa.

Qualquer sugestão para torná-lo mais curto seria maravilhosa!

int p(int q){var r=q-1;for(var i=2;i<r&r<q+2;i++){if(i==r-1)break;if(r%i==0)r+=i=1;}return r-q;}

Forma expandida:

int p(int q){
    var r=q-1;
    for(var i=2;i<r&r<q+2;i++){
        if(i==r-1)break;
        if(r%i==0)r+=i=1;
    }
    return r-q;     
}

Não tenho muita certeza, mas acho que você pode remover oe if(i==r-1)break;mudar o meio do forloop de i<rpara i<r-1. Seria trazer para baixo a 82.
Ciaran_McCarthy

1

GolfScript: 26

)0\{.:i,{i\%!},,2=@|\(}3*;

Explicação: O bloco mais interno {.:i,{i\%!},,2=@|\(}determina se a parte superior da pilha está pronta, verificando se existem exatamente 2 fatores a menos que a parte superior da pilha. Em seguida, ele é disjuntado com o segundo item da pilha, que mantém o estado de se um primo foi visto ainda. Por fim, diminui o número no topo da pilha.

Comece incrementando a entrada, inicializando o estado de primeira vista e repita o bloco 3 vezes. Como isso diminuirá duas vezes, mas começamos incrementando, isso cobrirá n+1e n-1.


1

C #, 87 97 caracteres

bool p(int q){return new[]{q-1,q,q+1}.Any(x=>Enumerable.Range(2,Math.Abs(x-2)).All(y=>x%y!=0));}

Eu não acho que isso funciona com 1 ou 2 como entrada
Ben Reich

@BenReich Não foi. Eu tive que adicionar dez caracteres para corrigi-lo :(
Steve Clanton

1

CJam, 12 bytes

Como o CJam é muito mais jovem que esse desafio, essa resposta não é elegível para a marca de seleção verde (que deve ser atualizada para a resposta da randomra de qualquer maneira). No entanto, jogar golfe foi realmente divertido - comecei com 17 bytes e depois mudei minha abordagem completamente três vezes, economizando um ou dois bytes de cada vez.

{(3,f+:mp:|}

Este é um bloco, o equivalente mais próximo a uma função no CJam, que espera a entrada na pilha e deixa 1 (verdade) ou 0 (falsidade) na pilha.

Teste aqui.

Aqui está como funciona:

(3,f+:mp:|
(          "Decrement the input N.";
 3,        "Push an array [0 1 2].";
   f+      "Add each of those to N-1, to get [N-1 N N+1].";
     :mp   "Test each each element for primality, yielding 0 or 1.";
        :| "Fold bitwise OR onto the list, which gives 1 if any of them was 1.";

1

F #, 68 bytes (não concorrente)

let p n=Seq.forall(fun x->n%x>0){2..n-1}
let m n=p(n-1)||p n||p(n+1)

Experimente online!

É por isso que eu amo código de golfe. Ainda sou muito verde com o F #, mas aprendo muito sobre como a linguagem funciona e o que ela pode fazer com esses tipos de desafios.


Por que não é competitivo?
Nit

11
Porque não tenho certeza se estou usando algo no F # hoje que não existia quando a pergunta foi feita em 2012. Admito que é pedante - até paranóico. Mas eu escrevo software farmacêutico para viver. A paranóia é saudável. ;)
Ciaran_McCarthy

11
Veja a tabela de versões do F # na Wikipedia . Dependendo da versão necessária, pode ser mais antiga que a pergunta.



1

Java 8, 83 bytes

n->n==1|p(n-1)+p(n)+p(n+1)>0int p(int n){for(int i=2;i<n;n=n%i++<1?0:n);return--n;}

Retorna true/ falsecomo valores de verdade / falsey.

Experimente online.

Explicação: "

n->                    // Method with integer parameter and boolean return-type
  n==1                 //  Return whether the input is 1 (edge-case)
  |p(n-1)+p(n)+p(n+1)>0//  Or if the sum of `n-1`, `n`, and `n+1` in method `p(n)` is not 0

int p(int n){          // Separated method with integer as both parameter and return-type
  for(int i=2;i<n;     //  Loop `i` in the range [2, `n`)
    n=n%i++<1?         //   If `n` is divisible by `i`
       0               //    Change `n` to 0
      :                //   Else:
       n);             //    Leave `n` as is
                       //  (After the loop `n` is either 0, 1, or unchanged,
                       //   if it's unchanged it's a prime, otherwise not)
  return--n;}          //  Return `n` minus 1

Portanto int p(int n), resultará em -1for n=0e non-primos, e resultará em n-1for n=1ou primos. Como p(0)+p(1)+p(2)se tornará -1+0+1 = 0e retornaria falso (mesmo que 2seja primo), esse n=1é um caso extremo usando essa abordagem.


Um único loop sem método separado teria 85 bytes :

n->{int f=0,j=2,i,t;for(;j-->-1;f=t>1?1:f)for(t=n+j,i=2;i<t;t=t%i++<1?0:t);return f;}

Retorna 1/ 0como valores de verdade / falsey.

Experimente online.

Explicação:

n->{              // Method with integer as both parameter and return-type
  int f=0,        //  Result-integer, starting at 0 (false)
      j=2,i,      //  Index integers
      t;          //  Temp integer
  for(;j-->-1;    //  Loop `j` downwards in range (2, -1]
      f=          //    After every iteration: Change `f` to:
        t>1?      //     If `t` is larger than 1 (`t` is a prime):
         1        //      Change `f` to 1 (true)
        :         //     Else:
         f)       //      Leave `f` the same
    for(t=n+j,    //   Set `t` to `n+j`
        i=2;i<t;  //   Inner loop `i` in the range [2, t)
      t=t%i++<1?  //    If `t` is divisible by `i`:
         0        //     Change `t` to 0
        :         //    Else:
         t);      //     Leave `t` the same
                  //   (If `t` is still the same after this inner loop, it's a prime;
                  //   if it's 0 or 1 instead, it's not a prime)
  return f;}      //  Return the result-integer (either 1/0 for true/false respectively)


0

R, 68 caracteres

f=function(n){library(gmp);i=isprime;ifelse(i(n-1)|i(n)|i(n+1),1,0)}

Uso (1 para VERDADEIRO, 0 para FALSO):

f(7)
[1] 1
f(8)
[1] 1
f(15)
[1] 0

11
Eu realmente não sei como R funciona, mas você poderia simplesmente fazer em i(n-1)|i(n)|i(n+1)vez de ifelse(i(n-1)|i(n)|i(n+1),1,0)?
Ry-

Você está certo: g = função (n) {biblioteca (gmp); i = isprime; i (n-1) | i (n) | i (n + 1)} - até 56 caracteres! ;-)
Paolo

0

C ++

k=3;cin>>i;i--;
while(k)
{l[k]=0;
  for(j=2;j<i;j++)
   if(!(i%j))
     l[k]++;
  k--;
  i++;
}
if(!l[1]|!l[2]|!l[3])
     cout<<"1";
else cout<<"0";

Bem-vindo ao CodeGold.SE. Se você olhar para as outras respostas, notará um formato comum usado para respostas a perguntas [code-golf]. Você também pode aplicá-lo às suas respostas.
dmckee

0

Q, 43 caracteres 36

{any min each a mod 2_'til each a:x+-1 0 1}
{any(min')a mod 2_'(til')a:x+-1 0 1}

0

J, 16 caracteres

   (_2&<@-4 p:]-2:)

   (_2&<@-4 p:]-2:) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1

0

Python, 69 67 caracteres

any(all(i%j for j in range(2,i))for i in range(input()-1,8**7)[:3])

8**7 > 2**20 enquanto é um pouco mais curto para escrever



0

C ++ 97

ugoren parece ter me derrotado na solução inteligente. Portanto, ele é uma versão abreviada do loop três vezes:

P(int k){int j=1;for(int i=2;i<k;){j=k%i++&&j;}return j;}
a(int b){return P(b)|P(b+1)|P(b-1);}

0

Quarto (gforth) , 104 bytes

: p dup 1 > if 1 over 2 ?do over i mod 0> * loop else 0 then nip ;
: f dup 1- p over 1+ p rot p + + 0< ;

Experimente online!

Explicação

Cheque principal (p)

dup 1 > if          \ if number to check if greater than 1
   1 over 2 ?do     \ place a 1 on the stack to act as a boolean and loop from 2 to n
      over i  mod   \ take the modulo of n and i
      0> *          \ check if greater than 0 (not a divisor) and multiply result by boolean
   loop             \ end the loop, result will be -1 if no divisor was found (prime)
else                \ if n is less than 2
   0                \ put 0 on the stack (not prime)
then                \ end the loop
nip                 \ drop n from the stack

Função principal (f)

dup 1- p             \ get n-1 and check if prime
over 1+ p            \ get n+1 and check if prime
rot p                \ rotate stack to put n on top and check if prime
+ + 0<               \ add the three results and check if less than 0 (at least 1 was prime)


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.