La tâche
À partir d’un nombre naturel en entrée, votre tâche consiste à produire une valeur de vérité ou de falsey selon que l’entrée est une factorielle de tout nombre naturel. Vous pouvez supposer que le numéro saisi sera toujours compris dans la plage de numéros prise en charge par votre langue, mais vous ne devez pas abuser des types de numéros natifs pour banaliser le problème .
Des échappatoires standard s'appliquent.
Contribution
Vous recevrez un nombre naturel (de type Integer
ou similaire).
Vous pouvez prendre les entrées de la manière que vous voulez, sauf en supposant que ce soit dans une variable prédéfinie. La lecture depuis un fichier, une console, une boîte de dialogue ( prompt
), une zone de saisie, etc. est autorisée. L'entrée comme argument de fonction est également autorisée!
Sortie
Votre programme doit générer une valeur de vérité ou de falsey selon que le nombre entré est une factorielle d'un nombre naturel.
Assurez-vous que vos valeurs de vérité / falsey sont cohérentes pour toutes les entrées, c.-à-d. Si vous utilisez une paire de 1 et 0 pour désigner respectivement les valeurs de vérité et de falsey, votre programme doit générer 1 pour toutes les entrées qui doivent avoir des valeurs de vérité et 0 pour toutes les entrées qui devraient avoir des valeurs de falsey.
Vous pouvez utiliser la sortie de n'importe quelle manière, sauf l'écrire dans une variable. L'écriture dans un fichier, une console, un écran, etc. est autorisée. La fonction return
est également autorisée!
Votre programme ne doit générer aucune erreur pour aucune entrée!
Cas de test
Input Output
1 Truthy (0! or 1!)
2 Truthy (2!)
3 Falsey
4 Falsey
5 Falsey
6 Truthy (3!)
7 Falsey
8 Falsey
24 Truthy (4!)
120 Truthy (5!)
Critère gagnant
C'est du code-golf , donc le code le plus court en octets gagne!
1
?Réponses:
Brachylog , 1 octet
Essayez-le en ligne!
Explication
ḟ
est une fonction intégrée qui affirme la relation suivante: sa sortie est la factorielle de son entrée. Nous lui donnons simplement une sortie définie et voyons si elle réussit ou non avec une entrée variable.la source
true.
c'est une déclaration et qu'elletrue
ne l'est pas)Gelée , 3 octets
Essayez-le en ligne!
1 pour oui, 0 pour non.
Comment ça marche
la source
Gelée , 4 octets
Pas la réponse la plus courte, mais c'est plutôt efficace.
Essayez-le en ligne!
Comment ça marche
la source
ECMAScript Regex,
733+690+158119118(117🐌)octetsMon intérêt pour regex a été suscité avec une vigueur renouvelée après plus de quatre ans et demi d'inactivité. En tant que tel, je suis allé à la recherche d'ensembles de nombres et de fonctions plus naturels à assortir à des expressions rationnelles unaires ECMAScript, j'ai repris l'amélioration de mon moteur d'expression régulière et ai commencé à mettre à jour PCRE.
Je suis fasciné par l'aliénation de la construction de fonctions mathématiques dans les expressions rationnelles ECMAScript. Les problèmes doivent être abordés sous un angle totalement différent et, jusqu'à l'arrivée d'une idée clé, on ne sait pas s'ils sont résolus. Cela oblige à utiliser un réseau beaucoup plus large pour déterminer quelles propriétés mathématiques pourraient être utilisées pour résoudre un problème particulier.
La correspondance des nombres factoriels était un problème que je n'avais même pas envisagé de résoudre en 2014 - ou, le cas échéant, momentanément, le rejetant comme étant trop improbable pour être possible. Mais le mois dernier, j'ai réalisé que cela pourrait être fait.
Comme pour mes autres posts sur les expressions rationnelles ECMA, je tiens à vous avertir: je vous recommande vivement d'apprendre à résoudre des problèmes mathématiques unaires dans ECMAScript regex. Ce voyage a été fascinant pour moi et je ne veux pas le gâter pour ceux qui voudraient éventuellement l'essayer eux-mêmes, en particulier ceux qui s'intéressent à la théorie des nombres. Voir ce message précédent pour une liste de problèmes recommandés consécutivement étiquetés spoiler à résoudre un par un.
Donc , ne lisez pas plus loin si vous ne voulez pas que la magie avancée des regex unaires soit gâtée . Si vous voulez vraiment essayer de découvrir cette magie vous-même, je vous recommande vivement de commencer par résoudre certains problèmes de la regex ECMAScript, comme indiqué dans l'article ci-dessus.
C'était mon idée:
Après avoir cuit dessus pendant un certain temps et construit entre-temps d'autres expressions rationnelles, je me suis lancé dans la tâche d'écrire l'expression rationnelle factorielle. Cela a pris plusieurs heures, mais a fini par bien fonctionner. En prime, l'algorithme pourrait renvoyer la factorielle inverse sous forme de correspondance. Il n'y avait pas moyen de l'éviter, même; De par la nature même de la manière dont il doit être mis en œuvre dans ECMA, il est nécessaire de deviner ce qu'est la factorielle inverse avant de faire autre chose.
L’inconvénient est que cet algorithme créait une très longue expression régulière ... regex octet). J'espérais qu'un problème nécessitant cette astuce se présenterait: Opérer sur deux nombres, qui sont tous deux des puissances de la même base, en boucle, en les additionnant sans ambiguïté et en les séparant à chaque itération.
Mais à cause de la difficulté et de la longueur de cet algorithme, j'ai utilisé des propriétés d'anticipation moléculaires (de la forme
(?*...)
) pour le mettre en œuvre. Il s’agit d’une fonctionnalité qui ne figure pas dans ECMAScript ni dans aucun autre moteur regex traditionnel, mais que j’ai implémentée dans mon moteur . Sans capture à l'intérieur d'un look moléculaire moléculaire, son fonctionnement est équivalent à un look atomique, mais avec des captures, il peut être très puissant. Le moteur fera un retour en arrière dans la vue anticipée, ce qui peut être utilisé pour conjecturer une valeur qui parcourt toutes les possibilités (pour des tests ultérieurs) sans consommer les caractères de l'entrée. Leur utilisation peut permettre une implémentation beaucoup plus propre. (La recherche de longueur variable est à tout le moins égale en puissance à la présentation moléculaire, mais cette dernière a tendance à donner lieu à des implémentations plus simples et élégantes.)Ainsi, les longueurs de 733 et 690 octets ne représentent pas réellement des incarnations de la solution compatibles avec ECMAScript - d'où le "+" après celles-ci; il est sûrement possible de porter cet algorithme en ECMAScript pur (ce qui augmenterait sa longueur un peu), mais je ne l'ai pas compris… parce que j'ai pensé à un algorithme beaucoup plus simple et plus compact! Une solution qui pourrait facilement être mise en œuvre sans avoir une apparence moléculaire. C'est aussi beaucoup plus rapide.
Ce nouveau, comme le précédent, doit deviner la factorielle inverse, en passant en revue toutes les possibilités et en les testant pour une correspondance. Il divise N par 2 pour faire de la place pour le travail à effectuer, puis amorce une boucle dans laquelle il divise à plusieurs reprises l'entrée par un diviseur qui commence à 3 et s'incrémente à chaque fois. (En tant que tel, 1! Et 2! Ne peuvent pas être comparés par l'algorithme principal et doivent être traités séparément.) Le diviseur est conservé en l'ajoutant au quotient en cours d'exécution; ces deux nombres peuvent être séparés sans ambiguïté car, en supposant que M! == N, le quotient courant continuera d'être divisible par M jusqu'à ce qu'il soit égal à M.
J'adore donc que le problème ait pu être réduit à un niveau de complexité encore inférieur à celui de mon regex de Fibonacci optimisé pour le golf , mais je soupire avec déception que ma technique de multiplexage des pouvoirs de la même base devra attendre un autre problème. cela l'exige réellement, parce que celui-ci n'en a pas. C'est l'histoire de mon algorithme de multiplication de 651 octets remplacé par un algorithme de 50 octets, encore et encore!
Edit: J'ai pu supprimer 1 octet (119 → 118) en utilisant une astuce trouvée par Grimy qui peut encore raccourcir la division dans le cas où le quotient est garanti supérieur ou égal au diviseur.
Sans plus tarder, voici la regex:
Version vraie / fausse (118 octets):
^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$|^xx?$
Essayez-le en ligne!
Renvoyer une factorielle inverse ou une absence de correspondance (124 octets):
^(?=((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\3$)\3|^xx?$
Essayez-le en ligne!
Renvoie une factorielle inverse ou une absence de correspondance, en ECMAScript +
\K
(120 octets):^((x*)x*)(?=\1$)(?=(xxx\2)+$)((?=\2\3*(x(?!\3)xx(x*)))\6(?=\5+$)(?=((x*)(?=\5(\8*$))x)\7*$)x\9(?=x\6\3+$))*\2\K\3$|^xx?$
Et la version libre avec commentaires:
L'historique complet de mes optimisations de golf de ces regex est sur github:
regex pour les nombres factoriels correspondants - méthode de comparaison de multiplicité, avec
regex moléculaire lookahead.txt pour les nombres factoriels correspondants.txt (celui présenté ci-dessus)
Notez que vousn = 3 ! 3 - 3 = 0
((x*)x*)
pouvez changer pour((x*)+)
((x+)+)
\2
Le moteur de regex .NET n'émule pas ce comportement en mode ECMAScript, et le regex de 117 octets fonctionne:
Essayez-le en ligne! (version à ralentissement exponentiel, avec moteur de régression .NET + émulation ECMAScript)
la source
JavaScript (ES6),
302928 octetsS'attend à un entier positif. Retours
-1
pour la fausseté et-2
pour la vérité.Remarque : cette fonction prend en charge les très grandes entrées (vous devez le lire comme suit: 'assez grand pour JS'). Il devrait fonctionner en toute sécurité jusqu'à 2 53 - 1 . Il échouera à coup sûr à partir de N = 121 645 100 , 408 831 992 , cette entrée étant arrondie à 19! = 121 645 100 408 832 000 en raison de son codage IEEE-754. Il se peut que d’autres résultats faux positifs aient été obtenus avant 121 645 100 408 831 991 à cause d’erreurs d’arrondi, mais je ne le sais pas avec certitude.
la source
~
à la fin.Python 3 ,
3938 octetsUne fonction récursive en prenant un entier
n
, retournant une valeur booléenne inversley représentant le résultat (truthy:False
, Falsey:True
)Essayez-le en ligne!
Divise de manière répétée
n
pari
, avec une valeur initiale de1
, jusqu'à ce que le reste soit inférieur ou égal à1
alors teste si ce reste est inférieur à1
, seules les factorielles se termineront par un reste égal à1
et<
sera un octet plus court que==
.la source
1
pour toutes les factorielles sauf1
pour lesquelles il retourneTrue
.Java 8, 46 octets
Ceci est basé sur l'entrée de Roman Gräf que j'ai pu supprimer d'une douzaine d'octets. Je l'aurais suggéré mais je n'ai pas encore assez de réputation pour commenter! Mon code de testeur modifié:
la source
Retina ,
5038 octets12 octets économisés grâce à @Neil en combinant raccourcissement de la boucle et suppression du
;
Essayez-le en ligne!
Sorties
1
pour true et0
pour faux..+
correspond au nombre entier1¶$&$*
en le remplaçant par1
suivi d'un saut de ligne et le match converti en unaireLe programme restant divise le nombre unaire de la ligne du bas en augmentant successivement les entiers positifs, suivi dans la ligne du haut, alors qu'il est possible de le faire.
+`
boucle jusqu'à ce que la chaîne reste identique^(1+)¶(\1)+$
correspondre à la ligne supérieure de nombreux1
s et un multiple de nombreux1
s sur la ligne du bas et le remplacer par1$1¶$#2$*
la ligne du haut est1
remplacée par une autre1
, c’est-à-dire que le nombre représenté par la ligne du haut est augmenté de 1, suivi de la nouvelle ligne et du nombre de correspondances de la ligne du haut dans la ligne du bas (c.-à-d. le nombre de correspondances du deuxième groupe de capture ) beaucoup de1
s, c'est-à-dire en divisant le nombre du bas par le nombre du hautUne fois qu'il n'est plus possible de le faire,
¶.$
donne le nombre de correspondances de cette regex, ie. existe-t-il un seul1
sur la ligne du bas, ce qui ne se produit que si le nombre est un facteurSi aucun crash / crash est autorisé à la place des valeurs véracité / faux, je peux alors obtenir
3634 octets.Cela va dans le même sens, mais combine
$*
les troisième et quatrième lignes. La troisième ligne est en avant d' une partie de la même boucle,{
est une abréviation pour le+(
cas des(
groupes les lignes restantes dans la boucle. Les factorielles se terminent lorsque le programme commence à sortir de la boucle, tandis que les non-factorielles restent bloquées dans la boucle jusqu'à ce que Retina lève une exception OverflowException causée par l'échec du dernier remplacement, le fond étant donc unaire au lieu de décimal et le premier remplacement de la boucle. convertit la ligne de fond de décimale à unaire, de sorte qu'elle explose rapidement.la source
1
car cela est impliqué quand$*
est à la fin du remplacement.$*
avec les deux autres lignes.05AB1E , 4 octets
Essayez-le en ligne!
Explication
la source
L
apparaît son entrée? En outre,Å!
vous donne une liste de factorielle inférieure ou égale à l'entrée.D
ici. Bonne prise à propos deÅ!
. J'oublie toujours les listes de commandes. Cela ne sauvera pas les octets, mais c’est certainement plus efficace.C ++,
10210092 octetsParcourt toutes les valeurs de
0
àn
et calcule la factorielle, puis vérifie si elle est égale àn
.Merci Christoph! (enregistré 8 octets)
la source
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}
.lround
etlgamma
sont déjà C ++ 11 donc pourrait simplement#include<cmath>
. Peut-être pourrez-vous encore améliorer mes suggestions :)Haskell ,
43 à26 octetsEssayez-le en ligne!
la source
f n=elem n$scanl1(*)[1..n]
est ridicule inefficace mais plus court.40430
sans délai sur ma machine .divMod
en[1..]
atteignant successivement le zéro restant avec un quotient de 1 (factoriel) ou un reste non nul (non factoriel), mais cela ne semble pas être la bonne approche. J'ai trouvé ce mignon solution 46 caractères, bien que:f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%)
.Haskell , 38 octets
Essayez-le en ligne! Exemple d' utilisation:
(2#) 24
. RetoursTrue
ouFalse
.C'est le plus court que j'ai pu obtenir tout en restant très efficace. Même pour des nombres aussi grands que
le résultat est immédiatement donné. La solution fonctionne en divisant l'entrée
n
parm = 2,3,4,5,...
jusqu'à ce que le résultat soit égal à un ou qu'iln
ne soit pas divisible parm
.Pour la solution à 26 octets, plus courte mais incroyablement inefficace, qui calcule les
n!
entrées non factorielles, regardez ici .la source
MATL , 5 octets
Essayez-le en ligne!
Explication
la source
Fourier ,
4039 octetsEssayez-le sur FourIDE!
En gros, multiplie le nombre N par un nombre croissant jusqu'à ce que N soit égal à (sortie 1) ou supérieur à (sortie 0) l'entrée.
Explication Pseudocode:
la source
Japt ,
8 à6 octetsEssayez-le en ligne!
Cette sortie 0 pour faux et 1 pour vrai.
Explication
la source
aU ¦J
enx¥U
(mapper chaqueX
surX==U
et résumer), bien que cela ne fonctionne pas sur TIO.2
becuaseo
ne vous donnera que[0,1]
. Voici un correctif avec une sauvegarde de 1 octet.Perl 5, 31 octets
L'entrée est prise via STDIN, la sortie est donnée par le code de sortie (1 pour factoriel, 0 pour non factoriel).
L'entrée est divisée par des entiers successifs jusqu'à ce que soit 1, soit une fraction inférieure à un, qui est tronquée dans le résultat.
la source
Perl 6 , 29 octets
Essaye-le
Étendu:
la source
{$_∈[\*] 1..$_}
. Une autre approche intéressante est2>*.polymod(1..*).sum
.setlX , 32 octets
Crée une fonction appelée
f
où vous utilisez votre factorielle potentielle comme paramètre.Cela fonctionne avec une taille entière arbitraire, mais c'est assez inefficace.
(au fait: c'est ma première participation à un puzzle de programmation)
la source
C (gcc), 33 octets
Notez que certains auteurs définissent "nombre naturel" comme un entier positif . Par conséquent, je me moque que cela
f(0)
provoque une récursion infinie.la source
R ,
2822 octetsEssayez-le en ligne!
la source
C # (.NET Core) , 68 octets
Essayez-le en ligne!
Pas la solution la plus courte, mais fonctionne avec de très gros nombres. Le lien TIO comprend un exemple avec
10000!
.Voici une version plus courte qui utilise
int
qui a une valeur maximale de 2147483647 .C # (.NET Core) , 45 octets
Essayez-le en ligne!
Nous remercions @KevinCruijssen pour avoir joué au golf 3 octets au total grâce aux deux réponses!
la source
&&
peut être joué au golf&
, et la fuite;
ne doit pas être comptée pour les fonctions lambda. De plus, le message ne peut-il pasulong k=2
figureruint k=2
dans votre réponse sur 50 octets?&
contre&&
. Je pensais avoir un débordement de pile, mais cela semble fonctionner après tout.ulong
est 64 bits tandis queuint
est 32. Il semble que les autres utilisent,int
alors je vais peut-être l'utiliser pour la version courte. En ce qui concerne la fin;
, ce sont des fonctions complètes, pas des lambdas, donc je pense avoir besoin de les inclure?/
et%
entreulong
etuint
, mais pasulong
etint
. Je ne savais pas que :)double
vous commencez à voir arrondir à un moment donné - par exemple, 24! et 120! échouer. Alors queSystem.Numerics.BigInteger
le plus de précision,int
est la réponse la plus courte :)&&
opérateur de court-circuit . Mais c'est du code golf;) Content que l'10000!
exemple vous plaise !C ++ (clang), 51 octets
La récursion l'emporte au golf.
51 octets, zéro est vrai:
int f(int n,int i=2){return n<2?!n:n%i|f(n/i,i+1);}
Cela sacrifie beaucoup de vitesse pour 1 octet d'économie. Remplacez le
|
avec par||
pour le rendre rapide, en raison de l'évaluation du OU logique par court-circuit.Essayez-le en ligne! (Version lente de 51 octets)
Essayez-le en ligne! (Version rapide de 52 octets)
Version lente non-golfée:
Version rapide non-golfée:
Il y a plusieurs façons de réorganiser cela.
52 octets, non nul est vrai:
int f(int n,int i=2){return n<2?n:n%i?0:f(n/i,i+1);}
Essayez-le en ligne!
52 octets, zéro est vrai:
int f(int n,int i=2){return!n?1:n%i?n-1:f(n/i,i+1);}
Essayez-le en ligne!
Avant de recourir à la récursivité, j'ai essayé de créer des versions itératives, qui se sont rapprochées.
54 octets, non nul est vrai:
int f(int n){for(int i=2;n>1;)n=n%i?0:n/i++;return n;}
Essayez-le en ligne!
54 octets, zéro est vrai (d'après la soumission de Roman 8 par Roman Gräf ):
int f(int n){int a=1,i=0;for(;a<n;a*=++i);return a-n;}
Essayez-le en ligne!
Maintenant, pour le fond du baril, des versions récursives sans
n==0
manipulation (je les considère comme non valides, car 0 est un nombre naturel, et toute définition dans laquelle elle ne correspond pas à des "nombres naturels" d'utilisation très limitée). Dans les versions ci-dessous, la récursion infinie de l'unef(0)
ou de l' autre déclenche une erreur de segmentation due au débordement de la pile, ou des compilateurs qui l'optimisent en itération, boucle en boucle:48 octets, zéro est vrai:
int f(int n,int i=2){return n%i?n-1:f(n/i,i+1);}
Essayez-le en ligne!
48 octets, zéro est vrai (d'après la soumission de 33 octets C (gcc) de Hagen von Eitzen ):
int f(int n,int e=0){return n%++e?n-1:f(n/e,e);}
Essayez-le en ligne!
la source
Mathematica, 20 octets
autre version pour tester les gros nombres (voir commentaires)
teste jusqu'à 1000!
la source
Range[#]
parRange@#
:)!Range@#!~FreeQ~#&
.Cubix , 24 octets
Essayez-le en ligne
Cubifié
Nous commençons par pousser
1
,I
nput,1
sur la pile. Ce seront notre index, notre cible et notre accumulateur, respectivement.Nous faisons alors une boucle. A chaque itération, on soustrait l'accumulateur de l'entrée. Si le résultat est 0, nous avons terminé, alors nous poussons
1
,O
utput et quittons. Si c'est négatif, nous sommes allés trop loin, alors nous poussons0
,O
utputons, et sortons. Sinon, on voitla source
Neim , 8 octets
Explication:
Essayez le!
Neim , 3 octets (non concurrents)
Les jetons Contenus et Factionnaires non compétitifs ont été ajoutés après le lancement du défi.
Explication:
Essayez le!
la source
> <> ,
2422 octets-2 octets grâce à @Aaron
J'essaie une nouvelle langue (depuis l'expiration de ma licence Mathematica…)
Essayez-le en ligne ou au terrain de jeu du poisson
Suppose que le numéro d'entrée est déjà sur la pile et renvoie 0 ou 1. Cela fonctionne en multipliant ensemble les n premiers nombres jusqu'à ce que celui-ci cesse d'être inférieur à l'entrée, puis en imprimant 1 s'il est égal à l'entrée et 0 s'il ne le fait pas. t.
la source
v>\n<^
en\\n/
; voir iciAPL (Dyalog Unicode) , 5
67octetsGolfé un octet en changeant
×/
pour!
grâce à Erik the OutgolferEssayez-le en ligne!
Explication
la source
N∊×\⍳N←⎕
Comment cela prend-il un argument? Je ne voisn
nulle part. Est-ce une chose spécifique à Dyalog?(⊢∊(×/⍳)) right_argument
comme vous pouvez le voir sur le lien TIO. Et le⊢
fait référence au bon argument.⊢∊×\ä⍳
. La solution "correcte" (mais plus longue) serait0=1|!⍣¯1
: "La factorielle inverse est-elle un entier?"JavaScript (ES6), 71 octets
Cela prend en entrée comme argument de fonction et en
alert
sortie. Sorties0
pour Falsey et1
pour la vérité.Explication
Le programme comprend deux fonctions
f
etg
.f
est une fonction récursive de calcul factoriel etg
constitue la fonction principale du programme.g
suppose d'avoir un seul argumentn
. Il définit un argument par défautr
avec une valeur de 0 et un autre argument par défaut avec une valeur de0
. Il effectue ensuite une itération sur tous les entiers de 0 àn
et vérifie, à chaque itération, si la fonctionf
appliquée suri
(l'indice actuel) est égalen
, c'est-à-dire s'iln
s'agit d'une factorielle dei
. Si tel est le cas,r
la valeur de s est définie sur 1. À la fin de la fonction,r
estalert
éd.Test Snippet
( Remarque: les extraits de code n'utilisent
console.log()
comme autant de personnes que trop de ces satanésalert()
s. )la source
QBIC ,
2119 octetsExplication
Précédemment
Explication:
la source
Java 8, 59 octets
Testcode
la source