Tarefa
Escreva uma função que aceite dois números inteiros a,b
que representam o número inteiro gaussiano z = a+ib
(número complexo). O programa deve retornar verdadeiro ou falso, dependendo de a+ib
ser um primo gaussiano ou não .
Definição:
a + bi
é um primo gaussiano se, e somente se, atender a uma das seguintes condições:
a
eb
são ambos diferentes de zero ea^2 + b^2
é primoa
é zero,|b|
é primo e|b| = 3 (mod 4)
b
é zero,|a|
é primo e|a| = 3 (mod 4)
Detalhes
Você deve escrever apenas uma função. Se o seu idioma não tiver funções, você pode assumir que os números inteiros estão armazenados em duas variáveis e imprimir o resultado ou gravá-lo em um arquivo.
Você não pode usar funções internas do seu idioma como isprime
ou prime_list
ou nthprime
ou factor
. O menor número de bytes vence. O programa deve trabalhar para a,b
onde a^2+b^2
está um número inteiro de 32 bits (assinado) e deve terminar em não mais do que 30 segundos.
Lista principal
Os pontos representam números primos no plano gaussiano ( x
= real, y
= eixo imaginário):
Alguns números primos maiores:
(9940, 43833)
(4190, 42741)
(9557, 41412)
(1437, 44090)
fonte
factor
no Bashmf
emF
no CJam, ...)Respostas:
Haskell - 77/
108107 Caracteresuso: nas duas soluções, digitar a% b retornará se a + bi é um primo gaussiano.
o mais baixo que consegui, mas sem criatividade ou desempenho (77 caracteres)
essa solução apenas fornece todos os números abaixo de n para verificar se é primo.
versão não destruída:
a próxima solução possui um recurso extra - memorização. depois de verificar se algum número inteiro n é primo, não será necessário recalcular a "primeiridade" de todos os números menores ou iguais a n, pois ele será armazenado no computador.
(107 caracteres. Os comentários são para esclarecer)
versão não destruída:
isso usa a peneira de Eratóstenes para calcular uma lista infinita de todos os números primos (chamados l para lista no código). (listas infinitas são um truque bem conhecido de haskell).
como é possível ter uma lista infinita? no início do programa, a lista não é avaliada e, em vez de armazenar os elementos da lista, o computador armazena a maneira de calculá-los. mas quando o programa acessa a lista, ele se avalia parcialmente até a solicitação. portanto, se o programa solicitar o quarto item da lista, o computador calculará todos os números primos até o quarto que ainda não foram avaliados, os armazenará e o restante permanecerá sem avaliação, armazenado como a maneira de computá-los uma vez necessário.
observe que tudo isso é dado livremente pela natureza preguiçosa da linguagem Haskell, nada disso é aparente no próprio código.
as duas versões do programa estão sobrecarregadas, para que possam manipular dados de tamanho arbitrário.
fonte
C,
149118 caracteresVersão editada (118 caracteres):
Esta é uma função única:
Dobra o teste de primalidade inteira em uma expressão
n/d/d|n<2
oculta no cálculo do valor de retorno. Esse código também utilizaa*b
como substitutoa&&b
(em outras palavrasa!=0 && b!=0
) e outros truques envolvendo precedência de operador e divisão de número inteiro. Por exemplo,n/d/d
é uma maneira mais curta de dizern/d/d>=1
, que é uma maneira segura de estourarn>=d*d
ou dizerd*d<=n
ou na sua essênciad<=sqrt(n)
.Versão original (149 caracteres):
Funções:
Q ( n ) retorna 0 (falso) se n for primo ou 1 (verdadeiro) se n for não primo. É uma função auxiliar para G ( a , b ).
G ( a , b ) retorna 1 (verdadeiro) se a + bi for um primo gaussiano ou 0 (falso) caso contrário.
Saída de amostra (aumentada em 200%) para | a |, | b | ≤ 128:
fonte
d++
não aconteça como parte da condição; caso contrário, ela estraga a lógica a seguir. Além disso, mover od=2
interior dofor
loop na verdade aumenta a contagem de caracteres, em vez de diminuí-la, porqued
ainda precisa ser declarado comoint
anterior aofor
loop. Estou esquecendo de algo?G(a,b){int s=abs(a)+abs(b),n=a*b?a*a+b*b:s,d=2;for(;n/d/d&&n%d;d++);return n>1>n/d/d&&s%4/3|a*b;}
sai para apenas 97 caracteres.APL (Dyalog Unicode) ,
36474849474328 bytesPega uma matriz de dois números inteiros
a b
e retorna o valor booleano da instruçãoa+bi is a Gaussian integer
.Edit: +11 bytes, porque eu não entendi a definição de um primo gaussiano. +1 byte de corrigir a resposta novamente. +1 byte de uma terceira correção de bug. -2 bytes devido ao uso de um trem em vez de um dfn. -4 bytes graças ao ngn devido ao uso de um protetor em
condition: if_true ⋄ if_false
vez deif_true⊣⍣condition⊢if_false
. -15 bytes graças ao ngn devido a encontrar uma maneira completamente diferente de escrever a condição if-else como um trem completo.Experimente online!
Explicação
fonte
Haskell - 121 caracteres (novas linhas incluídas)
Aqui está uma solução Haskell relativamente simples que não usa nenhum módulo externo e tem o máximo de eficiência possível.
Invoque como
ghci ./gprimes.hs
e, em seguida, você pode usá-lo no shell interativo. Nota: números negativos são complicados e devem ser colocados entre parênteses. Ou seja,fonte
Python -
121120 caracteresp
verifica seabs(x)
é primo repetindo todos os números de 2 aabs(x)**.5
(que ésqrt(abs(x))
). Fá-lo cedendox % s
para cada ums
.all
depois verifica se todos os valores obtidos são diferentes de zero e para de gerar valores quando encontrar um divisor dex
. Emf
,f(b,a)
substitui o argumentob==0
inspirado na resposta de Haskell de @killmous .-1 char e correção de bug de @PeterTaylor
fonte
s<abs(x)**.5
coms*s<abs(x)
uma poupança de 2. Embora realmente você deve estar verificando<=
, por isso é provavelmente de buggy no presente.f(0,15)
rendimentosTypeError: unsupported operand type(s) for &: 'bool' and 'generator'
com meu intérprete. :(f(0,15)
dáFalse
para mim, tanto em 2.7.6 e 3.4.1 (no OS X). Em qual versão você está?Python 2.7 ,
341301253 bytes, otimizado para velocidadeExperimente online!
Obrigado: 40 +48 - golfe inteiro para Jo King
fonte
f
lambda também é desnecessário, juntamente com alist
chamada. 257 bytes sem esses, mais alguma remoção de espaço em branco. Isso talvez não seja tão eficiente mais emboraPerl -
110107105 caracteresEspero ter seguido a definição vinculada corretamente ...
Ungolfed:
Explicação, porque alguém perguntou: Eu li os argumentos (
@_
) e colocar seus valores absolutos em$a
,$b
não porque a função não necessita de seu sinal. Cada um dos critérios requer o teste da primalidade de um número, mas esse número depende se$a
ou$b
não zero, o que tentei expressar da maneira mais curta possível e colocar$n
. Finalmente, verifico se$n
é primo contando quantos números entre 2 e ele próprio o dividimos sem deixar resto (essa é agrep...<2
parte) e depois verifico se um dos números é zero, o outro é igual a 3 módulo 4. A função é O valor de retorno é por padrão o valor de sua última linha e essas condições retornam algum valor verdadeiro se todas as condições forem atendidas.fonte
$a%4>2
vez de$a%4==3
.golflua
147141A contagem acima negligencia as novas linhas que adicionei para ver as diferentes funções. Apesar da insistência em não fazê-lo, a força bruta resolve os primos nos casos.
Retorna 1 se verdadeiro e 0 se não.
Uma versão não-gasta de Lua,
fonte
tonumber(io.read())
como um argumento parag
, no fim, e mais 2, removendo as novas linhasa
onde|a| <= |z|
ifa | z
(sea
dividez
).APL (NARS), 99 caracteres, 198 bytes
teste:
fonte
Encantos Rúnicos , 41 bytes
Experimente online!
Acabou sendo muito mais fácil do que eu pensava e não havia muito espaço para a golfificação. O programa original que bloqueei foi:
Eu brinquei com a tentativa de comparar as duas entradas ao mesmo tempo (que salvou todos os 1 byte), mas quando isso cai na seção "uma delas é zero", não havia uma boa maneira de descobrir qual item era diferente de zero para executar a última verificação, muito menos uma maneira de fazê-lo sem gastar pelo menos 1 byte (sem economia geral).
fonte
Mathematica, 149 caracteres
O código não usa nenhum recurso padrão de número primo do mathematica; em vez disso, conta o número de números inteiros na lista {n / 1, n / 2, ..., n / n}; se o número for 1 ou 2, então n é primo. Uma forma elaborada da função:
Gráfico de bônus de todos os Primes Gaussianos de -20 a 20:
fonte
Ruby
-rprime
,656080 bytesNão percebeu a regra "não é possível usar isPrime" ...
Experimente online!
fonte
Python -
117 122121fonte
==3
com>2