Cree el programa o función más corto que encuentre el factorial de un entero no negativo.
El factorial, representado con !
se define como tal
En inglés simple, el factorial de 0 es 1 y el factorial de n, donde n es mayor que 0 es n veces el factorial de uno menor que n.
Su código debe realizar entradas y salidas utilizando métodos estándar.
Requisitos:
- No utiliza ninguna biblioteca incorporada que pueda calcular el factorial (esto incluye cualquier forma de
eval
) - Puede calcular factoriales para números hasta 125
- Puede calcular el factorial para el número 0 (igual a 1)
- Completa en menos de un minuto para números hasta 125
La presentación más corta gana, en caso de empate gana la respuesta con más votos en el momento.
code-golf
arithmetic
factorial
Kevin Brown
fuente
fuente
Respuestas:
Golfscript - 12 caracteres
Comenzando con Golfscript - Factorial paso a paso
Aquí hay algo para las personas que están tratando de aprender golfscript. El requisito previo es una comprensión básica de golfscript y la capacidad de leer la documentación de golfscript.
Por eso queremos probar nuestra nueva herramienta golfscript . Siempre es bueno comenzar con algo simple, así que comenzamos con factorial. Aquí hay un intento inicial, basado en un pseudocódigo imperativo simple:
El espacio en blanco se usa muy raramente en golfscript. El truco más fácil para deshacerse del espacio en blanco es usar diferentes nombres de variables. Cada token se puede usar como una variable (ver la página de sintaxis ). Fichas útiles para utilizar como variables son caracteres especiales como
|
,&
,?
- por lo general no cualquier cosa usada en otras partes del código. Estos siempre se analizan como tokens de un solo personaje. En contraste, las variables comon
requerirán un espacio para insertar un número en la pila después. Los números son esencialmente variables preinicializadas.Como siempre, habrá declaraciones que podemos cambiar, sin afectar el resultado final. En golfscript, todo lo que se evalúa como verdadera, excepto
0
,[]
,""
, y{}
(ver esta ). Aquí, podemos cambiar la condición de salida de bucle a simplemente{n}
(bucleamos un tiempo adicional y terminamos cuando n = 0).Al igual que con el golf en cualquier idioma, es útil conocer las funciones disponibles. Afortunadamente, la lista es muy corta para golfscript. Podemos cambiar
1-
a(
para salvar a otro personaje. En la actualidad, el código se ve así: (podríamos usarlo en1
lugar de|
aquí si quisiéramos, lo que dejaría la inicialización).Es importante usar bien la pila para obtener las soluciones más cortas (práctica práctica). En general, si los valores solo se usan en un pequeño segmento de código, puede que no sea necesario almacenarlos en variables. Al eliminar la variable de producto en ejecución y simplemente usar la pila, podemos guardar una gran cantidad de caracteres.
Aquí hay algo más en lo que pensar. Estamos eliminando la variable
n
de la pila al final del cuerpo del bucle, pero luego la empujamos inmediatamente después. De hecho, antes de que comience el ciclo, también lo eliminamos de la pila. En su lugar, deberíamos dejarlo en la pila, y podemos mantener en blanco la condición del bucle.Quizás incluso podamos eliminar la variable por completo. Para hacer esto, necesitaremos mantener la variable en la pila en todo momento. Esto significa que necesitamos dos copias de la variable en la pila al final de la verificación de condición para que no la perdamos después de la verificación. Lo que significa que tendremos un redundante
0
en la pila después de que finalice el ciclo, pero eso es fácil de solucionar.¡Esto nos lleva a nuestra
while
solución de bucle óptima !Ahora todavía queremos hacer esto más corto. El objetivo obvio debería ser la palabra
while
. Mirando la documentación, hay dos alternativas viables: desplegar y hacer . Cuando tenga la opción de elegir diferentes rutas, intente sopesar los beneficios de ambas. Desplegar es 'casi un bucle while', por lo que, como estimación, reduciremos el carácterwhile
de 5 en 4/
. En cuanto ado
, cortamoswhile
en 3 caracteres y fusionamos los dos bloques, lo que podría salvar a otro personaje o dos.En realidad, hay un gran inconveniente al usar un
do
bucle. Dado que la verificación de la condición se realiza después de que el cuerpo se ejecuta una vez, el valor de0
será incorrecto, por lo que es posible que necesitemos una instrucción if. Te diré ahora que el despliegue es más corto (do
al final se proporcionan algunas soluciones ). Siga adelante y pruébelo, el código que ya tenemos requiere cambios mínimos.¡Excelente! Nuestra solución ahora es súper corta y hemos terminado aquí, ¿verdad? No. Esto tiene 17 caracteres y J tiene 12 caracteres. ¡Nunca admitas la derrota!
Ahora estás pensando con ... recursividad
Usar recursividad significa que debemos usar una estructura de ramificación. Desafortunadamente, pero como el factorial se puede expresar de manera tan breve y recursiva, parece una alternativa viable a la iteración.
Bueno, eso fue fácil: si hubiéramos intentado la recursividad antes, ¡tal vez ni siquiera hubiéramos visto usar un
while
bucle! Aún así, solo tenemos 16 caracteres.Matrices
Las matrices generalmente se crean de dos maneras: usando los caracteres
[
y]
, o con la,
función. Si se ejecuta con un número entero en la parte superior de la pila,,
devuelve una matriz de esa longitud con arr [i] = i.Para iterar sobre matrices, tenemos tres opciones:
{block}/
: empujar, bloquear, empujar, bloquear, ...{block}%
: [push, block, push, block, ...] (esto tiene algunos matices, por ejemplo, los valores intermedios se eliminan de la pila antes de cada inserción){block}*
: empujar, empujar, bloquear, empujar, bloquear, ...La documentación de golfscript tiene un ejemplo de uso
{+}*
para sumar el contenido de una matriz. Esto sugiere que podemos usar{*}*
para obtener el producto de una matriz.Desafortunadamente, no es tan simple. Todos los elementos están separados por uno (en
[0 1 2]
lugar de[1 2 3]
). Podemos usar{)}%
para rectificar este problema.Pues no del todo. Esto no maneja cero correctamente. Podemos calcular (n + 1)! / (N + 1) para rectificar esto, aunque esto cuesta demasiado.
También podemos tratar de manejar n = 0 en el mismo depósito que n = 1. Esto es realmente extremadamente corto de hacer, prueba y trabaja lo más corto que puedas.
Si queremos tener el incremento y la multiplicación en el mismo bloque, debemos iterar sobre cada elemento de la matriz. Como no estamos construyendo una matriz, esto significa que deberíamos estar usando
{)*}/
, lo que nos lleva a la implementación de factorial más corta de golfscript. Con 12 caracteres de largo, esto está relacionado con J!Soluciones de bonificación
Comenzando con una
if
solución sencilla para undo
bucle:Podemos exprimir un par extra de esto. Un poco complicado, por lo que tendrás que convencerte de que estos funcionan. Asegúrate de entender todo esto.
Una mejor alternativa es calcular (n + 1)! / (N + 1), lo que elimina la necesidad de una
if
estructura.Pero la
do
solución más corta aquí toma algunos caracteres para asignar 0 a 1, y todo lo demás para sí mismo, por lo que no necesitamos ninguna ramificación. Este tipo de optimización es extremadamente fácil de perder.Para cualquier persona interesada, aquí se proporcionan algunas soluciones recursivas alternativas con la misma longitud que la anterior:
* nota: en realidad no he probado muchas de las piezas de código en esta publicación, así que siéntase libre de informar si hay errores.
fuente
Haskell, 17
fuente
[1..0] ==> []
yproduct [] ==> 1
f 0=1;f n=n*f$n-1
tiene 17 caracteres.product
y, digamos,(*)
o(-)
"pueden calcular el factorial", y todos se definen a través del Preludio. ¿Por qué uno sería genial y no el otro?Python - 27
Así de simple:
fuente
0**x
.math.factorial
? No es un incorporado, ¿verdad?0**x
?APL (4)
Funciona como una función anónima:
Si quieres darle un nombre, 6 caracteres:
fuente
⍳
un vector índice,⍳5
es decir, es1 2 3 4 5
.×
es (obviamente) multiplicar,/
es reducir, y∘
es la composición de la función. Entonces,×/∘⍳
es una función que toma un argumentox
y da el producto de los números[1..x]
.J (12)
Una definición estándar en J:
¡Menos de 1 segundo por 125!
P.ej:
fuente
([:*/1+i.)
para 10 puntos, o incluso 8, ya que los paréntesis solo son necesarios para llamar a la función, no para la definición.f 125x
¿qué hace elx
? ¿Es un tipo especial de número?Golfscript - 13 caracteres (SYM)
define la función
!
versión alternativa de 13 caracteres
la versión completa del programa es de 10 caracteres
Las cajas de prueba toman menos de 1/10 de segundo:
entrada:
salida
entrada
salida
fuente
Perl 6: 13 caracteres
[*]
es igual que Haskellproduct
, y1..$_
es un conteo desde 1 hasta$_
, el argumento.fuente
[*]
(mensaje de error "Dos términos seguidos").Matlab, 15
Casos de prueba
fuente
Python, 28 bytes
(basado en la solución de Alexandru)
fuente
MATL , 2 bytes
Explicado:
Pruébalo en línea!
fuente
Ruby - 21 caracteres
Prueba
fuente
Java, 85 caracteres
fuente
import java.math.*;
(entonces, +19 bytes).PostScript, 26 caracteres
Ejemplo:
La función en sí solo toma 21 caracteres; el resto es vincularlo a una variable. Para guardar un byte, también se puede vincular a un dígito, así:
fuente
1.#INF
. (Utilicé GNU Ghostscript 9.0.7 compilado para Windows x64.)JavaScript, 25
CoffeeScript, 19
Devuelve
true
en el caso de n = 0, pero JavaScript lo obligará a escribir de todos modos.fuente
return
declaración en la función de JavaScript?return
! ¿Pero por qué no?function f(n)n?n*f(--n):1
f=n=>!n||n*f(n-1)
Toma eso, CoffeeScript!Ruby -
3029 caracteresPrueba
fuente
end
directamente después:*
sin una nueva línea o punto y coma.(1..10).inject :*
# => 3628800f(0)
?f=->n{(1..n).inject 1,:*}
. Llámalo conf[n]
.F #: 26 caracteres
No hay una función de producto incorporada en F #, pero puede hacer una con un pliegue
fuente
C #, 20 o 39 caracteres según su punto de vista
Como método de instancia tradicional (39 caracteres; probado aquí ):
Como una expresión lambda (20 caracteres, pero ver descargo de responsabilidad; probado aquí ):
Tenemos que usar
double
porque 125! == 1.88 * 10 209 , que es mucho más alto queulong.MaxValue
.Descargo de responsabilidad sobre el recuento de caracteres de la versión lambda:
Si recurres en un C # lambda, obviamente tienes que almacenar el lambda en una variable con nombre para que pueda llamarse a sí mismo. Pero a diferencia de (p. Ej.) JavaScript, una lambda autorreferenciada debe haberse declarado e inicializado en una línea anterior. No puede llamar a la función en la misma declaración en la que declara y / o inicializa la variable.
En otras palabras, esto no funciona :
Pero esto hace :
No hay una buena razón para esta restricción, ya
f
que nunca se puede desasignar en el momento en que se ejecuta. La necesidad de laFunc<int,double> f=null;
línea es una peculiaridad de C #. Si eso hace justo ignorarlo en el recuento de caracteres depende del lector.CoffeeScript,
2119 caracteres de verdadProbado aquí: http://jsfiddle.net/0xjdm971/
fuente
Brachylog ,
76 bytesAl hacer un rango y multiplicarlo
-1 tanques de bytes a ovs que tienen la idea de usar la función max ()
Explicación
Pruébalo en línea!
Brachylog ,
109 bytesrecursividad
Explicación
Pruébalo en línea!
fuente
;
lugar de,
permite solo una entrada numérica regular. -1byte de todos modosC (39 caracteres)
fuente
double f(n){return!n?1:n*f(n-1);}
- 33 caracteres.f(125)
se desbordaráD: 45 caracteres
Más legible:
Una versión más fresca (aunque más larga) es la plantilla que lo hace todo en tiempo de compilación ( 64 caracteres ):
Más legible:
Sin embargo, las plantillas homónimas son bastante detalladas, por lo que realmente no puede usarlas muy bien en el código de golf. D ya es lo suficientemente detallado en términos de recuento de caracteres para ser bastante pobre para el golf de código (aunque en realidad funciona muy bien para reducir el tamaño general del programa para programas más grandes). Sin embargo, es mi lenguaje favorito, así que me imagino que también podría intentar ver qué tan bien puedo lograrlo en el golf de código, incluso si los gustos de GolfScript están obligados a crearlo.
fuente
PowerShell - 36
Ingenuo:
Prueba:
fuente
Scala, 39 caracteres
La mayoría de los caracteres se aseguran de que
BigInt
se usen s para cumplir con el requisito de valores de hasta 125.fuente
(x:Int)=>(BigInt(1)to x).product
def f(x:Int)=(BigInt(1)to x).product
def f(x:BigInt)=(x.to(1,-1)).product
def f(x:BigInt)=(-x to-1).product.abs
Javascript, ES6 17
ES6:
fuente
PowerShell, 42 bytes
(guardado 2 caracteres usando filtro en lugar de función )
Salida:
fuente
filter f($x){if($x){$x*(f($x-1))}else{1}}
. Y se puede reducir aún más a 36 caracteres si se llama a través de una tubería, ya que es un filtro (por ejemplo125|f
):filter f{if($_){$_*($_-1|f)}else{1}}
Raqueta (esquema)
403529 bytesCalcula 0! ser 1, y calcula 125! en 0 segundos según el temporizador. Enfoque recursivo regular
Nueva versión para vencer el lisp común: multiplica todos los elementos de una lista (igual que esa solución de Haskell)
Versión más nueva para vencer a la otra solución de esquema y matemática a la otra solución de raqueta usando foldl en lugar de aplicar y usando rango en lugar de buildlist
fuente
Mornington Crescent ,
18271698 caracteresHoy tuve ganas de aprender un nuevo idioma, y esto es en lo que llegué ... (¿Por qué me hago esto a mí mismo?) Esta entrada no ganará ningún premio, pero supera las 0 respuestas hasta ahora usando el ¡mismo lenguaje!
Pruébalo en línea!
Cualquiera que haya viajado por Londres lo entenderá al instante, por supuesto, así que estoy seguro de que no necesito dar una explicación completa.
La mayor parte del trabajo al principio está en manejar el caso 0. Después de inicializar el producto en 1, puedo usarlo para calcular max (input, 1) para obtener la nueva entrada, ¡aprovechando el hecho de que 0! = 1! Entonces el ciclo principal puede comenzar.
(EDITAR: Se han guardado un montón de viajes quitando el 1 de "Heathrow Terminals 1, 2, 3" en lugar de generarlo dividiendo 7 (Sisters) por sí mismo. También utilizo un método más barato para generar el -1 en el siguiente paso.)
Disminuir es costoso en Mornington Crescent (aunque menos costoso que el Tubo en sí). Para hacer las cosas más eficientes, genero un -1 tomando el NOT de un 0 analizado y lo guardo en Hammersmith durante gran parte del ciclo.
Puse un trabajo significativo en esto, pero dado que este es mi primer intento de jugar golf en Mornington Crescent (de hecho, mi primer intento en cualquier idioma), espero haber perdido algunas optimizaciones aquí y allá. Si está interesado en programar en este idioma usted mismo (¿y por qué no lo estaría?), ¡ Esoteric IDE , con su modo de depuración y ventana de visualización, es imprescindible!
fuente
Befunge - 2x20 = 40 caracteres
Esta es una función porque es un bloque de código independiente que no utiliza el entorno envolvente. Debe colocar el argumento en la parte superior de la pila y luego ingresar desde la parte superior izquierda hacia la derecha, la función saldrá desde la parte inferior derecha hacia la derecha con el resultado en la parte superior de la pila.
Por ejemplo, para calcular el factorial de 125
Prueba 0
fuente
&:!#@_>:# 1# -# :# _$>\# :#* _$.@
(donde y debería ser reemplazado por la entrada). Son 32 caracteres / bytesJ - 6 caracteres
¿Esto cuenta? Sé que es muy similar al ejemplo J anterior, pero es un poco más corto :)
Soy un principiante con J, pero hasta ahora es muy divertido.
fuente
En C (23 caracteres)
Esto abusa de la "característica" GCC que hace que la última asignación cuente como una devolución si no se especifica ninguna devolución.
En C propia, 28 caracteres
fuente
0 == ({printf("Hello, world!"); 0;});
Kona (
116)K funciona de derecha a izquierda (en su mayor parte), por lo que enumeramos
x
(hacemos una lista / matriz de números de0
ax-1
), le agregamos1
(los rangos de lista0
ax
), luego multiplicamos todos los números. Si no fuera un requisito para calcular125!
, podría ahorrar 1 byte más eliminando al.
lado del1
. En cualquier caso, 125! se calcula en meros milisegundos:fuente
*/1.+!
: 6 bytes.