Tâche
Écrivez une fonction qui accepte deux entiers a,b
qui représentent l'entier gaussien z = a+ib
(nombre complexe). Le programme doit retourner vrai ou faux selon qu'il a+ib
s'agit d'un nombre premier gaussien ou non .
Définition:
a + bi
est un nombre premier gaussien si et seulement s'il remplit l'une des conditions suivantes:
a
etb
sont à la fois non nul eta^2 + b^2
est premiera
est zéro,|b|
est premier et|b| = 3 (mod 4)
b
est zéro,|a|
est premier et|a| = 3 (mod 4)
Détails
Vous ne devez écrire qu'une fonction. Si votre langue n'a pas de fonctions, vous pouvez supposer que les entiers sont stockés dans deux variables et imprimer le résultat ou l'écrire dans un fichier.
Vous ne pouvez pas utiliser les fonctions intégrées de votre langue comme isprime
ou prime_list
ou nthprime
ou factor
. Le plus petit nombre d'octets gagne. Le programme doit fonctionner pour a,b
où a^2+b^2
est un entier 32 bits (signé) et doit se terminer en pas plus de 30 secondes.
Liste principale
Les points représentent des nombres premiers sur le plan gaussien ( x
= réel, y
= axe imaginaire):
Quelques nombres premiers plus grands:
(9940, 43833)
(4190, 42741)
(9557, 41412)
(1437, 44090)
factor
dans Bash,mf
etmF
dans CJam, ...)Réponses:
Haskell -
77/108107 caractèresutilisation: dans les deux solutions, taper a% b retournera si a + bi est un nombre premier gaussien.
le plus bas que j'ai réussi, mais pas de créativité ni de performance (77 caractères)
cette solution passe simplement par tous les nombres en dessous de n pour vérifier s'il est premier.
version non golfée:
la solution suivante a une fonctionnalité supplémentaire - la mémorisation. une fois que vous avez vérifié si un entier n est premier, vous n'aurez pas besoin de recalculer la "primauté" de tous les nombres inférieurs ou égaux à n, car il sera stocké dans l'ordinateur.
(107 caractères. Les commentaires sont pour plus de clarté)
version non golfée:
ceci utilise le tamis d'Eratosthène pour calculer une liste infinie de tous les nombres premiers (appelés l pour liste dans le code). (les listes infinies sont une astuce bien connue de haskell).
comment est-il possible d'avoir une liste infinie? au début du programme, la liste n'est pas évaluée, et au lieu de stocker les éléments des listes, l'ordinateur stocke la façon de les calculer. mais lorsque le programme accède à la liste, il s'évalue partiellement jusqu'à la demande. donc, si le programme demandait le quatrième élément de la liste, l'ordinateur calculerait tous les nombres premiers jusqu'au quatrième qui ne sont pas déjà évalués, les stockerait et le reste resterait non évalué, stocké comme moyen de les calculer une fois nécessaire.
notez que tout cela est donné librement par la nature paresseuse du langage Haskell, rien de cela ne ressort du code lui-même.
les deux versions du programme sont surchargées, de sorte qu'elles peuvent gérer des données de taille arbitraire.
la source
C,
149118 caractèresVersion éditée (118 caractères):
Il s'agit d'une seule fonction:
Il replie le test de primalité entière en une expression
n/d/d|n<2
cachée dans le calcul de la valeur de retour. Ce code golfé utilise égalementa*b
comme substituta&&b
(en d'autres termesa!=0 && b!=0
) et d'autres astuces impliquant la priorité de l'opérateur et la division entière. Par exemple,n/d/d
c'est une façon plus courte de diren/d/d>=1
, qui est une manière sûre de déborder de diren>=d*d
oud*d<=n
ou essentiellementd<=sqrt(n)
.Version originale (149 caractères):
Les fonctions:
Q ( n ) renvoie 0 (faux) si n est premier, ou 1 (vrai) si n n'est pas premier. C'est une fonction d'aide pour G ( a , b ).
G ( a , b ) renvoie 1 (vrai) si a + bi est un nombre premier gaussien, ou 0 (faux) sinon.
Exemple de sortie (augmentée de 200%) pour | a |, | b | ≤ 128:
la source
d++
cela ne se produise pas dans le cadre de la condition, sinon cela gâche la logique suivante. De plus, déplacer l'd=2
intérieur de lafor
boucle augmente le nombre de caractères plutôt que de le diminuer, card
il doit toujours être déclaré commeint
avant lafor
boucle. Suis-je en train de manquer quelque chose?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;}
sort à seulement 97 caractères.APL (Dyalog Unicode) ,
36474849474328 octetsPrend un tableau de deux entiers
a b
et renvoie la valeur booléenne de l'instructiona+bi is a Gaussian integer
.Edit: +11 octets car j'ai mal compris la définition d'un nombre premier gaussien. +1 octet de correction à nouveau de la réponse. +1 octet d'une troisième correction de bogue. -2 octets dus à l'utilisation d'un train au lieu d'un dfn. -4 octets grâce à ngn en raison de l'utilisation d'un garde
condition: if_true ⋄ if_false
au lieu deif_true⊣⍣condition⊢if_false
. -15 octets grâce à ngn car il a trouvé une manière complètement différente d'écrire la condition if-else comme un train complet.Essayez-le en ligne!
Explication
la source
Haskell - 121 caractères (nouvelles lignes incluses)
Voici une solution Haskell relativement simple qui n'utilise aucun module externe et qui est autant utilisée que possible.
Appelez-le
ghci ./gprimes.hs
et vous pourrez ensuite l'utiliser dans le shell interactif. Remarque: les nombres négatifs sont capricieux et doivent être placés entre parenthèses. C'est à direla source
Python -
121120caractèresp
vérifie siabs(x)
est premier en itérant sur tous les nombres de 2 àabs(x)**.5
(ce qui estsqrt(abs(x))
). Il le fait en cédantx % s
pour chacuns
.all
vérifie ensuite si toutes les valeurs fournies sont non nulles et arrête de générer des valeurs une fois qu'il rencontre un diviseur dex
. Dansf
,f(b,a)
remplace le cas deb==0
, inspiré par la réponse de @killmous Haskell.-1 caractère et correction de bogue de bogue @PeterTaylor
la source
s<abs(x)**.5
pars*s<abs(x)
une économie de 2. Bien que vous devriez vraiment vérifier<=
, c'est probablement un buggy pour le moment.f(0,15)
cèdeTypeError: unsupported operand type(s) for &: 'bool' and 'generator'
avec mon interprète. :(f(0,15)
donneFalse
pour moi, à la fois sur 2.7.6 et 3.4.1 (sur OS X). Sur quelle version êtes-vous?Python 2.7 ,
341301253 octets, optimisé pour la vitesseEssayez-le en ligne!
Merci: 40 +48 - golf entier à Jo King
la source
f
lambda est également inutile, avec l'list
appel. 257 octets sans ceux-ci, plus une suppression des espaces blancs. Mais ce n'est peut-être plus aussi efficacePerl -
110107105 caractèresJ'espère avoir suivi correctement la définition liée ...
Non golfé:
Explication, parce que quelqu'un a demandé: je lis les arguments (
@_
) et de mettre leurs valeurs absolues en$a
,$b
parce que la fonction n'a pas besoin de leur signe. Chacun des critères nécessite de tester la primalité d'un nombre, mais ce nombre dépend de la valeur zéro$a
ou non$b
, que j'ai essayé d'exprimer de la manière la plus courte et de le mettre$n
. Enfin je vérifie si$n
est premier en comptant combien de nombres entre 2 et lui-même le divise sans reste (c'est lagrep...<2
partie), puis vérifie en outre que si l'un des nombres est nul alors l'autre est égal à 3 modulo 4. La fonction est la valeur de retour est par défaut la valeur de sa dernière ligne, et ces conditions renvoient une valeur vraie si toutes les conditions sont remplies.la source
$a%4>2
place de$a%4==3
.golflua
147141Le décompte ci-dessus néglige les nouvelles lignes que j'ai ajoutées pour voir les différentes fonctions. Malgré l'insistance à ne pas le faire, je résous par force brute les nombres premiers dans les cas.
Renvoie 1 si vrai et 0 sinon.
Une version Lua non golfée,
la source
tonumber(io.read())
comme argument àg
la fin, et 2 autres en supprimant les nouvelles lignesa
où|a| <= |z|
ifa | z
(sia
divisez
).APL (NARS), 99 caractères, 198 octets
tester:
la source
Enchantements runiques , 41 octets
Essayez-le en ligne!
J'ai fini par être beaucoup plus facile que je ne le pensais et il n'y avait pas beaucoup de place pour la golfification. Le programme original que j'ai bloqué était:
J'ai essayé de comparer les deux entrées en même temps (ce qui a sauvé tout d'un octet), mais lorsque cela tombe dans la section "l'une d'entre elles est nulle", il n'y avait pas de bon moyen de déterminer quel élément était non nul pour effectuer le dernier contrôle, et encore moins un moyen de le faire sans dépenser au moins 1 octet (pas d'économies globales).
la source
Mathematica, 149 caractères
Le code n'utilise aucune caractéristique de nombre premier standard de mathématique, au lieu de cela il compte le nombre d'entiers dans la liste {n / 1, n / 2, ..., n / n}; si le nombre est 1 ou 2, alors n est premier. Une forme élaborée de la fonction:
Intrigue bonus de tous les Primes gaussiennes de -20 à 20:
la source
Rubis
-rprime
,656080 octetsJe n'ai pas remarqué la règle "ne peut pas utiliser isPrime" ...
Essayez-le en ligne!
la source
Python -
117 122121la source
==3
par>2