La tarea
Dado un número natural como entrada, su tarea es generar un valor verdadero o falso en función de si la entrada es un factorial de cualquier número natural. Puede suponer que el número de entrada siempre estará en el rango de números admitidos por su idioma, pero no debe abusar de los tipos de números nativos para trivializar el problema .
Se aplican lagunas estándar .
Entrada
Se le dará un número natural (de tipo Integer
o similar).
Puede tomar la entrada de la forma que desee, excepto suponiendo que esté en una variable predefinida. prompt
Se permite leer archivos, consolas, cuadros de diálogo ( ), cuadros de entrada, etc. ¡La entrada como argumento de función también está permitida!
Salida
Su programa debe generar un valor verdadero o falso basado en si el número de entrada es un factorial de cualquier número natural.
Asegúrese de que sus valores de verdad / falsey sean consistentes para todas las entradas, es decir, si está utilizando un par de 1 y 0 para denotar valores de verdad y falsey respectivamente, entonces su programa debe generar 1 para todas las entradas que deberían tener valores de verdad y 0 para todas las entradas que deberían tener valores falsey.
Puede tomar la salida de la forma que desee, excepto escribirla en una variable. Se permite escribir en archivos, consolas, pantallas, etc. ¡La función también return
está permitida!
¡Su programa no debe producir errores para ninguna entrada!
Casos de prueba
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!)
Criterio ganador
Este es el código de golf , por lo que gana el código más corto en bytes.
1
?Respuestas:
Brachylog , 1 byte
Pruébalo en línea!
Explicación
ḟ
es un incorporado que afirma la siguiente relación: su salida es el factorial de su entrada. Simplemente le damos una salida establecida y vemos si tiene éxito o no con una entrada variable.fuente
true.
es una declaración ytrue
no lo es)Jalea , 3 bytes
Pruébalo en línea!
1 para sí, 0 para no.
Cómo funciona
fuente
Jalea , 4 bytes
No es la respuesta más breve de Jelly, pero es bastante eficiente.
Pruébalo en línea!
Cómo funciona
fuente
ECMAScript Regex,
733+690+158119118(117🐌)bytesMi interés en la expresión regular se ha despertado con un vigor renovado después de más de 4 años y medio de inactividad. Como tal, fui en busca de conjuntos de números y funciones más naturales para que coincidan con expresiones regulares ECMAScript unarias, continué mejorando mi motor de expresiones regulares y comencé a repasar PCRE también.
Me fascina la extrañeza de construir funciones matemáticas en expresiones regulares ECMAScript. Los problemas deben abordarse desde una perspectiva completamente diferente, y hasta la llegada de una idea clave, se desconoce si tienen solución alguna. Obliga a echar una red mucho más amplia para encontrar qué propiedades matemáticas podrían utilizarse para resolver un problema particular.
La coincidencia de números factoriales fue un problema que ni siquiera consideré abordar en 2014, o si lo hice, solo momentáneamente, descartándolo como demasiado improbable. Pero el mes pasado, me di cuenta de que podía hacerse.
Al igual que con mis otras publicaciones de expresiones regulares de ECMA, daré una advertencia: recomiendo aprender a resolver problemas matemáticos unarios en expresiones regulares de ECMAScript. Ha sido un viaje fascinante para mí, y no quiero estropearlo para cualquiera que quiera probarlo ellos mismos, especialmente aquellos interesados en la teoría de números. Consulte esta publicación anterior para obtener una lista de problemas recomendados etiquetados consecutivamente con spoilers para resolver uno por uno.
Así que no sigas leyendo si no quieres que se te estropee un poco de magia regex unaria avanzada . Si desea intentar descubrir esta magia usted mismo, le recomiendo comenzar resolviendo algunos problemas en la expresión regular de ECMAScript como se describe en la publicación vinculada anteriormente.
Esta fue mi idea:
Después de estofarlo durante un tiempo y, mientras tanto, construir otras expresiones regulares, tomé la tarea de escribir la expresión regular factorial. Tomó varias horas, pero terminó funcionando bien. Como una ventaja adicional, el algoritmo podría devolver el factorial inverso como una coincidencia. No había forma de evitarlo, incluso; Por la naturaleza misma de cómo debe implementarse en ECMA, es necesario adivinar cuál es el factorial inverso antes de hacer cualquier otra cosa.
La desventaja es que este algoritmo generó una expresión regular muy larga ... pero me complació que terminara requiriendo una técnica utilizada en mi expresión regular de multiplicación de 651 bytes (la que terminó siendo obsoleta, porque un método diferente hizo un 50 byte regex). Esperaba que surgiera un problema que requiriera este truco: operar con dos números, que son ambas potencias de la misma base, en un bucle, al sumarlos sin ambigüedad y separarlos en cada iteración.
Pero debido a la dificultad y la longitud de este algoritmo, utilicé lookaheads moleculares (de la forma
(?*...)
) para implementarlo. Esa es una característica que no está en ECMAScript ni en ningún otro motor de expresiones regulares convencional, sino una que había implementado en mi motor . Sin ninguna captura dentro de una búsqueda molecular por adelantado, es funcionalmente equivalente a una búsqueda atómica, pero con las capturas puede ser muy potente. El motor retrocederá hacia adelante, y esto puede usarse para conjeturar un valor que recorre todas las posibilidades (para pruebas posteriores) sin consumir caracteres de la entrada. Usarlos puede hacer una implementación mucho más limpia. (La mirada retrospectiva de longitud variable es al menos igual en potencia a la búsqueda molecular adelantada, pero esta última tiende a hacer implementaciones más directas y elegantes).Por lo tanto, las longitudes de 733 y 690 bytes no representan en realidad encarnaciones de la solución compatibles con ECMAScript, de ahí el "+" después de ellas; seguramente es posible portar ese algoritmo a ECMAScript puro (lo que aumentaría un poco su longitud), pero no lo logré ... ¡porque pensé en un algoritmo mucho más simple y compacto! Uno que podría implementarse fácilmente sin miradas moleculares. También es significativamente más rápido.
Este nuevo, como el anterior, debe adivinar el factorial inverso, recorrer todas las posibilidades y probarlas para un partido. Divide N entre 2 para dejar espacio para el trabajo que necesita hacer, y luego siembra un ciclo en el que dividirá repetidamente la entrada por un divisor que comienza en 3 e incrementa cada vez. (Como tal, 1! Y 2! No pueden coincidir con el algoritmo principal, y deben tratarse por separado). El divisor se mantiene al agregarlo al cociente corriente; estos dos números se pueden separar inequívocamente porque, suponiendo M! == N, el cociente corriente continuará siendo divisible por M hasta que sea igual a M.
Así que me encanta que el problema se haya podido reducir a una complejidad aún menor que la expresión regular de Fibonacci optimizada para el golf , pero suspiro con decepción porque mi técnica de multiplexación de poderes de la misma base tendrá que esperar otro problema eso realmente lo requiere, porque este no. ¡Es la historia de que mi algoritmo de multiplicación de 651 bytes fue reemplazado por uno de 50 bytes, todo de nuevo!
Editar: pude soltar 1 byte (119 → 118) usando un truco encontrado por Grimy que puede acortar aún más la división en el caso de que el cociente sea mayor o igual que el divisor.
Sin más preámbulos, aquí está la expresión regular:
Versión verdadera / falsa (118 bytes):
^((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?$
Pruébalo en línea!
Devuelve factorial inverso o no coincidencia (124 bytes):
^(?=((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?$
Pruébalo en línea!
Devuelve factorial inverso o no coincidencia, en ECMAScript +
\K
(120 bytes):^((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?$
Y la versión libre con comentarios:
La historia completa de mis optimizaciones de golf de estas expresiones regulares está en github:
regex para hacer coincidir números factoriales: método de comparación de multiplicidad, con lookahead.txt molecular
regex para hacer coincidir números factoriales.txt (el que se muestra arriba)
((x*)x*)
((x*)+)
((x+)+)
\2
El motor .NET regex no emula este comportamiento en su modo ECMAScript y, por lo tanto, la regex de 117 bytes funciona:
Pruébalo en línea! (versión de desaceleración exponencial, con motor .NET regex + emulación ECMAScript)
fuente
JavaScript (ES6),
302928 bytesEspera un entero positivo. Devoluciones
-1
por falsedad y-2
por verdad.Nota : Esta función admite entradas bastante grandes (debe leer esto como: 'bastante grande para JS'). Debería funcionar de forma segura hasta 2 53 - 1 . Con seguridad comenzará en N = 121,645,100,408,831,992 , ¡esta entrada se redondeará a 19! = 121,645,100,408,832,000 debido a su codificación IEEE-754. No puede haber otros resultados positivos falsos antes 121.645.100.408.831.991 debido a errores de redondeo, pero no lo sé a ciencia cierta.
fuente
~
al final.Python 3 ,
3938 bytesUna función recursiva teniendo un número entero,
n
, devolviendo un valor booleano inversley que representa el resultado (Truthy:False
, Falsey:True
)Pruébalo en línea!
Se divide repetidamente
n
entrei
, con un valor inicial de1
, hasta que el resto sea menor o igual que1
luego, compruebe si ese resto es menor1
, solo los factoriales terminarán con un resto igual a1
, y<
es un byte más corto que==
.fuente
1
todos los factoriales, excepto los1
que devuelveTrue
.Java 8, 46 bytes
Esto se basa en la entrada de Roman Gräf de la que pude eliminar una docena de bytes. ¡Lo habría sugerido allí, pero todavía no tengo suficiente reputación para comentar! Mi código de corredor de prueba modificado:
fuente
Retina ,
5038 bytes12 bytes guardados gracias a @Neil al combinar acortar el ciclo y deshacerse del
;
Pruébalo en línea!
Salidas
1
para verdadero y0
para falso..+
coincide con el número entero1¶$&$*
reemplazándolo por1
seguido de una nueva línea y el partido convertido a unarioEl programa restante divide el número unario en la línea inferior al aumentar sucesivamente los enteros positivos, se mantiene un seguimiento en la línea superior, mientras que es posible hacerlo.
+`
bucle hasta que la cadena permanezca igual^(1+)¶(\1)+$
haga coincidir la línea superior con muchos1
sy un múltiplo de muchas1
s en la línea inferior y reemplácela con1$1¶$#2$*
la línea superior muchos1
s con otra1
, es decir, aumentar el número representado por la línea superior en 1, seguido de la nueva línea y el número de coincidencias de la línea superior en la línea inferior (es decir, conteo de coincidencias del segundo grupo de captura ) muchos1
s, es decir, dividiendo el número inferior por el número superiorUna vez que ya no sea posible hacerlo,
¶.$
dar el número de coincidencias de esta expresión regular, es decir. ¿existe un solitario1
en la línea de fondo, que solo sucede si el número es un factorialSi se permite no-crash / crash en lugar de valores de verdad / falsedad, entonces puedo obtener
3634 bytes.Esto sigue el mismo enfoque, pero combina las
$*
líneas tercera y cuarta. La tercera línea en adelante es parte del mismo bucle,{
es la abreviatura de+(
donde(
agrupa las líneas restantes en el bucle. Los factoriales terminan en el programa saliendo del bucle, mientras que los no factoriales se atascan en el bucle para siempre hasta que Retina lanza una excepción de desbordamiento causada por la última falla de reemplazo, por lo que la parte inferior está en unario en lugar de en decimal, y el primer reemplazo del bucle convierte la línea inferior de decimal a unario, por lo que explota rápidamente.fuente
1
como está implícito cuando$*
está al final del reemplazo.$*
con las otras dos líneas.05AB1E , 4 bytes
Pruébalo en línea!
Explicación
fuente
L
aparece su entrada? Además,Å!
le brinda una lista de factorial menor o igual que la entrada.D
aquí. Buena captura sobreÅ!
. Siempre me olvido de los comandos de lista. No guardará ningún byte, pero es más eficiente con seguridad.C ++,
10210092 BytesLoops a través de todos los valores de
0
an
y calcula los controles factoriales y luego, si es igual an
.Gracias Christoph! (guardado 8 bytes)
fuente
int a(int n){int i=n,j=0;for(;i;)j|=lround(exp(lgamma(i--+1)))==n;return j;}
.lround
ylgamma
ya son C ++ 11, así que simplemente podría#include<cmath>
. Tal vez puedas mejorar aún más mis sugerencias :)Haskell ,
4326 bytesPruébalo en línea!
fuente
f n=elem n$scanl1(*)[1..n]
Es ridículo ineficiente pero más corto.40430
sin demora notable.divMod
por[1..]
sucesivamente hasta llegar a un resto de cero con un cociente de 1 (factorial) o un resto distinto de cero (no factoriales), pero no parece ser el enfoque correcto. Lo que encontrar esta solución linda 46 caracteres, sin embargo:f|let x%n=mod n x==0&&(x+1)%div n x||n==1=(1%)
.Haskell , 38 bytes
Pruébalo en línea! Ejemplo de uso:
(2#) 24
. DevolucionesTrue
oFalse
.Esto es lo más corto que pude obtener sin dejar de ser muy eficiente. Incluso para números tan grandes como
El resultado se da de inmediato. La solución funciona dividiendo la entrada
n
porm = 2,3,4,5,...
hasta que el resultado sea uno on
no sea divisible entrem
.Para la solución más corta pero increíblemente ineficiente de 26 bytes que calcula las
n!
entradas que no son factoriales, mire aquí .fuente
MATL , 5 bytes
Pruébalo en línea!
Explicación
fuente
Fourier ,
4039 bytesPruébalo en FourIDE!
Básicamente multiplica el número N por una cantidad creciente hasta que N sea igual a (salida 1) o mayor que (salida 0) la entrada.
Explicación Pseudocódigo:
fuente
Japt ,
86 bytesPruébalo en línea!
Esto genera 0 para falso y 1 para verdadero.
Explicación
fuente
aU ¦J
ax¥U
(mapear cadaX
aX==U
y suma), a pesar de que no funcionará en TIO.2
causao
solo te darán[0,1]
. Aquí hay una solución con un ahorro de 1 byte.Perl 5, 31 bytes
La entrada se toma a través de STDIN, la salida se da a través del código de salida (1 para factorial, 0 para no factorial).
La entrada se divide por enteros sucesivos hasta que sea 1 o una fracción menor que uno, que se trunca en el resultado.
fuente
Perl 6 , 29 bytes
Pruébalo
Expandido:
fuente
{$_∈[\*] 1..$_}
. Otro enfoque interesante es2>*.polymod(1..*).sum
.setlX , 32 bytes
Crea una función llamada
f
donde usa su factorial potencial como parámetro.Funciona con un tamaño entero arbitrario, pero es bastante ineficiente.
(por cierto: esta es mi primera participación en un rompecabezas de programación)
fuente
C (gcc), 33 bytes
Tenga en cuenta que algunos autores definen "número natural" como un entero positivo . Por lo tanto, no me importa que
f(0)
cause una recursión infinita.fuente
R ,
2822 bytesPruébalo en línea!
fuente
C # (.NET Core) , 68 bytes
Pruébalo en línea!
No es la solución más corta, pero funciona con números realmente grandes. El enlace TIO incluye un ejemplo con
10000!
.Aquí hay una versión más corta que usa
int
que tiene un valor máximo de 2147483647 .C # (.NET Core) , 45 bytes
Pruébalo en línea!
¡Crédito a @KevinCruijssen por jugar 3 bytes en total en ambas respuestas!
fuente
&&
puede jugar al golf&
, y el seguimiento;
no tiene que contarse para las funciones lambda. Además, ¿no puedeulong k=2
estaruint k=2
en su respuesta de 50 bytes?&
frente&&
. Pensé que estaba teniendo un desbordamiento de pila, pero parece funcionar después de todo.ulong
es de 64 bits mientras queuint
es de 32. Parece que otros lo están usando,int
así que tal vez lo usaré para la versión corta. Con respecto al seguimiento;
, estas son funciones completas, no lambdas, ¿así que creo que necesito incluirlas?/
y%
entreulong
yuint
, pero noulong
yint
. No sabía eso :)double
usted comienza a ver redondeo en algún momento, por ejemplo, ¡24! y 120! fallar. Si bienSystem.Numerics.BigInteger
tiene la mayor precisión,int
es la respuesta más corta :)&&
operador de cortocircuito . Pero este es el código de golf;) Me alegra que te guste el10000!
ejemplo.C ++ (clang), 51 bytes
La recursión gana en lo que respecta al golf.
51 bytes, cero es verdadero:
int f(int n,int i=2){return n<2?!n:n%i|f(n/i,i+1);}
Esto sacrifica bastante velocidad por 1 byte de ahorro. Reemplace
|
con||
para hacerlo más rápido, debido a la evaluación de cortocircuito del OR lógico.Pruébalo en línea! (Versión lenta de 51 bytes) ¡
Pruébelo en línea! (Versión rápida de 52 bytes)
Versión lenta sin golf:
Versión rápida sin golf:
Hay muchas formas de reorganizar esto.
52 bytes, distinto de cero es cierto:
int f(int n,int i=2){return n<2?n:n%i?0:f(n/i,i+1);}
Pruébalo en línea!
52 bytes, cero es verdadero:
int f(int n,int i=2){return!n?1:n%i?n-1:f(n/i,i+1);}
Pruébalo en línea!
Antes de recurrir a la recursión, intenté hacer algunas versiones iterativas, y se acercaron.
54 bytes, distinto de cero es cierto:
int f(int n){for(int i=2;n>1;)n=n%i?0:n/i++;return n;}
Pruébalo en línea!
54 bytes, cero es verdadero (basado en el envío de Java 8 de Roman Gräf ):
int f(int n){int a=1,i=0;for(;a<n;a*=++i);return a-n;}
Pruébalo en línea!
Ahora, para el fondo del barril, versiones recursivas sin
n==0
manejo (considero que estos no son válidos, porque 0 es un número natural, y cualquier definición en la que no esté es para "números naturales" de uso muy limitado). En las versiones a continuación, la recursión infinita def(0)
cualquiera desencadena un defecto por desbordamiento de la pila, o con compiladores que lo optimizan para la iteración, bucles sin fin:48 bytes, cero es verdadero:
int f(int n,int i=2){return n%i?n-1:f(n/i,i+1);}
Pruébalo en línea!
48 bytes, cero es verdadero (basado en el envío de 33 bytes C (gcc) de Hagen von Eitzen ):
int f(int n,int e=0){return n%++e?n-1:f(n/e,e);}
Pruébalo en línea!
fuente
Mathematica, 20 bytes
otra versión para probar números grandes (ver comentarios)
prueba hasta 1000!
fuente
Range[#]
conRange@#
:)!Range@#!~FreeQ~#&
.Cubix , 24 bytes
Pruébalo en línea
Cubified
Comenzamos empujando
1
,I
nput,1
en la pila. Estos serán nuestro índice, nuestro objetivo y nuestro acumulador, respectivamente.Luego hacemos un bucle. En cada iteración, restamos el acumulador de la entrada. Si el resultado es 0, hemos terminado, así que empujamos
1
,O
utilizamos y salimos. Si es negativo, hemos ido demasiado lejos, así que empujamos0
,O
hablamos y salimos. De lo contrario, vemosfuente
Neim , 8 bytes
Explicación:
¡Intentalo!
Neim , 3 bytes (no competitivos)
No competitivos ya que el token contiene y el token factorial se agregaron después de que se realizó el desafío.
Explicación:
¡Intentalo!
fuente
> <> ,
2422 bytes-2 bytes gracias a @Aaron
Estoy probando un nuevo idioma (ya que mi licencia de Mathematica expiró ...)
Pruébelo en línea o en el área de juegos para peces
Asume que el número de entrada ya está en la pila y devuelve 0 o 1. Funciona multiplicando juntos los primeros n números hasta que deje de ser menor que la entrada, y luego imprima 1 si es igual a la entrada y 0 si no lo hace. t.
fuente
v>\n<^
en\\n/
; ver aquíAPL (Dyalog Unicode) , 5
67bytesGolfé un byte cambiando
×/
a!
gracias a Erik the OutgolferPruébalo en línea!
Explicación
fuente
N∊×\⍳N←⎕
¿Cómo toma esto un argumento? No veo porn
ningún lado. ¿Es esto algo específico de Dyalog?(⊢∊(×/⍳)) right_argument
como puedes ver en el enlace TIO. Y el se⊢
refiere al argumento correcto.⊢∊×\ä⍳
. La solución "correcta" (pero más larga) sería0=1|!⍣¯1
; "¿Es el factorial inverso un entero?"JavaScript (ES6), 71 bytes
Esto toma la entrada como argumento de función y
alert
s la salida. Salidas0
para falsey y1
para la verdad.Explicación
El programa consta de dos funciones,
f
yg
.f
es una función recursiva de computación factorial yg
es la función principal del programa.g
se supone que tiene un solo argumenton
. Define un argumento predeterminador
con un valor de 0 y otro argumento predeterminado con un valor de0
. Luego, itera sobre todos los números enteros de 0 an
y, en cada iteración, verifica si la funciónf
aplicada sobrei
(el índice actual) es igualn
, es decir, sin
es un factorial dei
. Si ese es el caso,r
el valor se establece en 1. Al final de la función,r
sealert
edita.Fragmento de prueba
( Nota: el fragmento sale
console.log()
como nadie le gusta a muchos de esos molestosalert()
) .fuente
QBIC ,
2119 bytesExplicación
Previamente
Explicación:
fuente
Java 8, 59 bytes
Código de prueba
fuente