Este es otro desafío sobre los números de Fibonacci.
El objetivo es calcular el número 20'000'000 de Fibonacii lo más rápido posible. La salida decimal es aproximadamente 4 MiB grande; Empieza con:
28543982899108793710435526490684533031144309848579
La suma MD5 de la salida es
fa831ff5dd57a830792d8ded4c24c2cb
Tiene que enviar un programa que calcule el número mientras se ejecuta y coloca el resultado stdout
. El programa más rápido, medido en mi propia máquina, gana.
Aquí hay algunas reglas adicionales:
- Debe enviar el código fuente y un binario ejecutable en un Linux x64
- El código fuente debe ser más corto que 1 MiB, en caso de ensamblaje también es aceptable si solo el binario es tan pequeño.
- No debe incluir el número que se calculará en su binario, incluso de forma encubierta. El número debe calcularse en tiempo de ejecución.
- Mi computadora tiene dos núcleos; puedes usar paralelismo
Tomé una pequeña implementación de Internet que se ejecuta en aproximadamente 4.5 segundos. No debería ser muy difícil superar esto, suponiendo que tenga un buen algoritmo.
fastest-code
fibonacci
FUZxxl
fuente
fuente
phi = (1+sqrt(5))/2
Respuestas:
C con GMP, 3.6s
Dioses, pero GMP hace que el código sea feo. Con un truco al estilo Karatsuba, logré reducir a 2 multiplicaciones por paso de duplicación. Ahora que estoy leyendo la solución de FUZxxl, no soy el primero en tener la idea. Tengo un par de trucos más bajo la manga ... tal vez los pruebe más tarde.
Construido con
gcc -O3 m.c -o m -lgmp
.fuente
Sabio
Hmm, parece suponer que lo más rápido será un programa compilado. ¡No hay binario para ti!
En mi máquina, toma 0,10 segundos de CPU, 0,15 segundos de pared.
editar: cronometrado en la consola, en lugar del cuaderno
fuente
Haskell
Este es mi propio intento, aunque no escribí el algoritmo por mí mismo. Lo copié bastante de haskell.org y lo adapté para usarlo
Data.Vector
con su famosa fusión de secuencias:Esto toma alrededor de 4.5 segundos cuando se compila con GHC 7.0.3 y los siguientes indicadores:
fuente
enumFromStepN (s-1)
lugar deenumFromStepN s
VACA
¡Mugir! (Toma un tiempo. Bebe un poco de leche ...)
fuente
Mathematica, interpretada:
Cronometrado:
Y, por supuesto, no binario.
fuente
stdout
.-batchoutput
, solo imprime información de sincronización y no el número de Fibonacci.curl 'http://www.wolframalpha.com/input/?i=Fibonacci%5B2+10^6%5D' | grep 'Decimal approximation:' | sed ...
Se ejecuta en tiempo constante con respecto a la velocidad de su conexión a Internet. ;-)Ocaml, 0.856s en mi laptop
Requiere la biblioteca zarith. Usé Big_int pero es lento para perros en comparación con zarith. ¡Tomó 10 minutos con el mismo código! ¡La mayor parte del tiempo la pasé imprimiendo el maldito número (aproximadamente 9½ minutos)!
¡No puedo creer la diferencia que hizo la biblioteca!
fuente
Haskell
En mi sistema, esto funciona casi tan rápido como la respuesta de FUZxxl (~ 18 segundos en lugar de ~ 17 segundos).
fuente
C, algoritmo ingenuo
Tenía curiosidad, y no había usado gmp antes ... así que:
fib (1 millón) toma alrededor de 7 segundos ... por lo que este algoritmo no ganará la carrera.
fuente
Implementé el método de multiplicación matricial (de sicp, http://sicp.org.ua/sicp/Exercise1-19 ) en SBCL, pero tarda unos 30 segundos en terminar. Lo porté a C usando GMP, y devuelve el resultado correcto en aproximadamente 1.36 segundos en mi máquina. Es casi tan rápido como la respuesta de Boothby.
fuente
Java: 8 segundos para calcular, 18 segundos para escribir
fuente
Vamos
Es vergonzosamente lento. En mi computadora toma un poco menos de 3 minutos. Sin embargo, solo son 120 llamadas recursivas (después de agregar el caché). ¡Tenga en cuenta que esto puede usar mucha memoria (como 1.4 GiB)!
fuente
pseudocódigo (no sé qué están usando)
Le tomó a mi computadora 56 horas hacer esos dos términos. Mi computadora es un poco horrible. Tendré el número en un archivo de texto el 22 de octubre. 1.2 conciertos es un poco grande para compartir en mi conexión.
fuente