Comunidad PHPeros
Otros => Los Retos PHPeros => Mensaje iniciado por: good en 25 de Agosto de 2011, 21:28:04 pm
-
hola! la idea es crear una función como por ejemplo factorial($n);, y que devuelva el factorial de n (n!)
A ver quien hace el procedimiento más rápido!! :D
El factorial de 3 es 1*2*3, el de 5 es 1*2*3*4*5... etc
NOTA EXTRA:
he pensado en limitar el número que se pase por input, la función solo procesa números del 0 al 15
-
Hola Good!
Suponiendo que estamos hablando de PHP (El tema lo has publicado en retos pero no especificas la categoría exactamente) voy a elaborar este código, hace tiempo que no programo, puede que esté algo oxidado pero lo voy a intentar.
miarchivo.php
<?php
function n($n){
$operacion = 1;
for($i=1; $i <= $n; $i++){
$operacion = $operacion*$i;
}
return $operacion;
}
echo n($_GET['n']);
?>
Si por ejemplo, vamos a miarchivo.php?num=5 hará la operación 1*2*3*4*5 cuyo resultado es 120. La verdad es que es un script sencillo pero como hace tiempo que no programo pues me ha costado un poco pensar el algoritmo jaja.
Un saludo,
Siquillote.
-
vale, pero no es lo suficientemente rápido, se puede optimizar!
-
vale, pero no es lo suficientemente rápido, se puede optimizar!
Hola Good,
La verdad no entiendo porque dices que no es lo suficientemente rápido... a mi ni me tarda milésimas. En cuanto a que dices que se puede optimizar yo creo que es "imposible". Se utilizan los métodos exactos y concisos, ni mas ni menos. Hombre, se podría simplificar quitando la función pero como tu pedías una función...
Un saludo,
Siquillote.
-
Hola Good,
La verdad no entiendo porque dices que no es lo suficientemente rápido... a mi ni me tarda milésimas. En cuanto a que dices que se puede optimizar yo creo que es "imposible". Se utilizan los métodos exactos y concisos, ni mas ni menos. Hombre, se podría simplificar quitando la función pero como tu pedías una función...
Un saludo,
Siquillote.
hay una manera de hacerlo más eficiente. Éste que has hecho funciona bien, sí, pero siempre tiene que realizar el cálculo completo, por ejemplo, si lo probaras así:
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
factorial (1000);
seguramente no sería tan rápido xD
-
Hola Good,
Verás, la cosa del reto (según a mi entender) es crear una función que elabore ese algoritmo no hacer que si a partir de X numero vaya mas rápido o lento o si llamas a la funcion 80 veces en tu script, ¿No crees?.
Un saludo,
Ángel.
-
Hola Good,
Verás, la cosa del reto (según a mi entender) es crear una función que elabore ese algoritmo no hacer que si a partir de X numero vaya mas rápido o lento o si llamas a la funcion 80 veces en tu script, ¿No crees?.
Un saludo,
Ángel.
el reto es buscar la solución más rápida y eficiente, es un problema en el que se tiene en cuenta la eficiencia (velocidad) del proceso para cualquier caso (llamar solo una vez a la función o llamarla tantas veces como sea necesario)
-
function factorial($numero){
for($i = $numero-1; $i > 0; $i--)
$numero *= $i;
return $numero;
}
-
el reto es buscar la solución más rápida y eficiente, es un problema en el que se tiene en cuenta la eficiencia (velocidad) del proceso para cualquier caso (llamar solo una vez a la función o llamarla tantas veces como sea necesario)
Hola Good,
Verás, no se si llegas a entenderme bien. A lo que yo voy es a decirte que por muy "eficaz" y rápida crees una función dará igual si la llamas 5000 veces. La función no sabe cuantas veces la está llamando por lo tanto no se puede hacer nada respecto a ello.
function factorial($numero){
for($i = $numero-1; $i > 0; $i--)
$numero *= $i;
return $numero;
}
Si, visto de esa forma si que es mas corto de elaborar. Bien visto así Physlet, enhorabuena.
Un saludo,
Siquillote.
-
Hola Good,
Verás, no se si llegas a entenderme bien. A lo que yo voy es a decirte que por muy "eficaz" y rápida crees una función dará igual si la llamas 5000 veces. La función no sabe cuantas veces la está llamando por lo tanto no se puede hacer nada respecto a ello.
Si, visto de esa forma si que es mas corto de elaborar. Bien visto así Physlet, enhorabuena.
Un saludo,
Siquillote.
sigue siendo "ineficiente" en cuestión de rapidez
-
Si, visto de esa forma si que es mas corto de elaborar. Bien visto así Physlet, enhorabuena.
Un saludo,
Siquillote.
La forma más eficiente –según creo– es usando recursividad. En breve lo subo.
-
La forma más eficiente –según creo– es usando recursividad. En breve lo subo.
He actualizado el enunciado
-
La más eficiente sin tu último requerimiento sería esta:
function factorial ($numero){
return $numero == 1 ? $numero : $numero * factorial($numero - 1);
}
-
La forma más eficiente –según creo– es usando recursividad. En breve lo subo.
Como no sabía a que te referías a recursividad he googleado un poco y me encontrado esto (http://www.desarrolloweb.com/articulos/funciones-recursivas-recursividad.html). Creo que esa podría ser la solución a este reto.
La más eficiente sin tu último requerimiento sería esta:
function factorial ($numero){
return $numero == 1 ? $numero : $numero * factorial($numero - 1);
}
EDIT: Physlet, he ido a comprobar la funcionalidad del algoritmo y no funciona.
Un saludo,
Siquillote
-
La más eficiente sin tu último requerimiento sería esta:
function factorial ($numero){
return $numero == 1 ? $numero : $numero * factorial($numero - 1);
}
esta solución tardaría lo mismo que la anterior, puedes optimizar este mismo código para que sea mucho más eficiente
-
esta solución tarda lo mismo que la anterior, puedes optimizar este mismo código para que sea mucho más eficiente
¿Es esta la solución (http://www.desarrolloweb.com/articulos/funciones-recursivas-recursividad.html) al reto?
-
porcierto, no hay que limitarse a lo que haya dentro de la función, podeis usar estructuras
-
¿Es esta la solución (http://www.desarrolloweb.com/articulos/funciones-recursivas-recursividad.html) al reto?
no, no es la solución más eficiente.
la idea si que es hacer una función recursiva, pero que sea eficiente
-
revisad el cambio del enunciado, los números para calcular su factorial ahora están entre 1 y 1000
-
revisad el cambio del enunciado, los números para calcular su factorial ahora están entre 1 y 1000
Hola Good,
Yo estoy por dejar el reto, aparte de que hace tiempo que no programo y tengo la practica atrofiada, no se que estás buscando. El código de Physlet debería ser lo bastante eficaz tal y como lo estás buscando así que a mi no se me ocurre nada.
Un saludo,
Siquillote.
-
function factorial($n){
return $n==1?1:$n*factorial($n-1);
}
Esto ya no se llama "optimización", se llama ahorro de espacio.
-
function factorial($n){
return $n==1?1:$n*factorial($n-1);
}
Esto ya no se llama "optimización", se llama ahorro de espacio.
eso no importa, lo que importa es la velocidad, no el número de lineas
-
eso no importa, lo que importa es la velocidad, no el número de lineas
Quiero conocer el método más "eficaz" del que hablas.
Y estoy usando la misma cantidad de líneas, el único cambio que hice fue acortar el nombre de la variable y quitar los espacios, de alguna u otra forma eso ocupa bytes, y hace que cargue más lento el archivo. Aunque obvio, con esta dimensión de archivo las diferencias son invisibles.
-
Quiero conocer el método más "eficaz" del que hablas.
Y estoy usando la misma cantidad de líneas, el único cambio que hice fue acortar el nombre de la variable y quitar los espacios, de alguna u otra forma eso ocupa bytes, y hace que cargue más lento el archivo. Aunque obvio, con esta dimensión de archivo las diferencias son invisibles.
pero pensadlo xD, porcierto, he cambiado el enunciado otra vez, la función estará hecha para leer valores del 1 al 15, porque php no puede calcular valores super largos directamente
-
teneis que usar estructuras
-
¿A qué tipo de estructuras te refieres?
function factorial($n){
return $n > 15 || $n < 1 ? false : ($n==1 ? 1 : $n*factorial($n-1));
}
$fact = factorial(5);
echo $fact ? $fact : 'Error';
-
¿A qué tipo de estructuras te refieres?
function factorial($n){
return $n > 15 || $n < 0 ? false : ($n==1 ? 1 : $n*factorial($n-1));
}
$fact = factorial(5);
echo $fact ? $fact : 'Error';
no, esa sigue siendo una de las soluciones lentas, he limitado el número por el hecho de que php no puede calcular factoriales enormes xD
porcierto, el script asume que es del 1 al 15, no hace falta que pongas eso de error, lo único que interesa es el Procedimiento
-
no, esa sigue siendo una de las soluciones lentas, he limitado el número por el hecho de que php no puede calcular factoriales enormes xD
porcierto, el script asume que es del 1 al 15, no hace falta que pongas eso de error, lo único que interesa es el Procedimiento
No, asume que era de 0 a 15. Editaste el que corregí. Ahora sí asume de 1 a 15.
Y pues, ando esperando.
-
No, asume que era de 0 a 15. Editaste el que corregí. Ahora sí asume de 1 a 15.
Y pues, ando esperando.
igualmente, el factorial de 0 es 1, bueno ahora cambio el enunciado en cuento a eso.
no, sigue siendo una solución poco eficiente
-
Vale, pero sigo esperando la solución eficiente.
-
Vale, pero sigo esperando la solución eficiente.
como quieras, pero te la mando por mensaje privado para que el tema quede abierto
-
Por favor, y gracias.
-
como quieras, pero te la mando por mensaje privado para que el tema quede abierto
A mi también me interesaría saberlo, estoy muerto de curiosidad jaja. Es verdad eso que dicen que cada día se aprende algo nuevo, si señor.
Un saludo,
Siquillote.
-
Quien se anime puede seguir pensando cómo hacerlo
-
Yo preferiría que me enviaras la solución, porque no se me ocurre otra manera de hacerlo que no hayan dicho ya.
-
Yo preferiría que me enviaras la solución, porque no se me ocurre otra manera de hacerlo que no hayan dicho ya.
ya está, enviado
-
Nada más que agregar, además de que no es un código extensible/portable/reutilizable.
-- Physlet --
0.0023460388183594 segundos
0.0024032592773438 segundos
0.0024604797363281 segundos
0.0023889541625977 segundos
0.0023889541625977 segundos
-- good --
0.0033044815063477 segundos
0.0031757354736328 segundos
0.0034189224243164 segundos
0.0033044815063477 segundos
0.0032901763916016 segundos
-
Nada más que agregar, además de que no es un código extensible/portable/reutilizable.
-- Physlet --
0.0023460388183594 segundos
0.0024032592773438 segundos
0.0024604797363281 segundos
0.0023889541625977 segundos
0.0023889541625977 segundos
-- good --
0.0033044815063477 segundos
0.0031757354736328 segundos
0.0034189224243164 segundos
0.0033044815063477 segundos
0.0032901763916016 segundos
a ver, si solo vas a llamar a la función una vez, espérate esto, es algo Obvio viendo los códigos. Pero si haces por ejemplo un millón de llamadas, el tiempo debería cambiar, ya que tu programa realiza el cálculo un millón de veces y el mío solo una
-
a ver, si solo vas a llamar a la función una vez, espérate esto, es algo Obvio viendo los códigos. Pero si haces por ejemplo un millón de llamadas, el tiempo debería cambiar, ya que tu programa realiza el cálculo un millón de veces y el mío solo una
Tu argumento no es válido compañero. Creo que eso era lo que discutías con Siq anteriormente.
Es totalmente INCORRECTO llamar más de 1 vez a una misma función, con los mismos parámetros y que dé el mismo resultado.
Y vuelvo y digo, tu código no es extensible.
Edito:
Ya entendíqué me intentas dar a entender, pero estás basándote en un límite y ese arreglo lo deberás ampliar cada vez que se cambie el límite, ya que en realidad el límite es 170 y deberás hacer un bucle para generar todas las posiciones del arreglo.
-
Tu argumento no es válido compañero. Creo que eso era lo que discutías con Siq anteriormente.
Es totalmente INCORRECTO llamar más de 1 vez a una misma función, con los mismos parámetros y que dé el mismo resultado.
Y vuelvo y digo, tu código no es extensible.
si supieras leer el código lo entenderías
la diferencia que hay es que de la manera dinámica solo calculas UNA VEZ los factoriales, en cambio, Tú los calculas continuamente, si calculas por ejemplo el factorial de 15, y después el de 14, lo estás haciendo de una manera poco eficiente.
Cuando, de la manera dinámica calculas el de 15, entonces habrá guardado ya TODOS los factoriales en una tabla y no será necesario VOLVERLOS A CALCULAR como hace tu solución.
-
pongo un límite porque es un PROBLEMA. Prueba a calcular 1000! a ver que pasa
-
Ya entendí a lo que te refieres. Gracias.
-
A menos que exista un modo matemático de solucionar este problema, no se me ocurre nada más rápido. Envíame la solución -si quieres- y la testearé en 1000 bucles :P
-
A menos que exista un modo matemático de solucionar este problema, no se me ocurre nada más rápido. Envíame la solución -si quieres- y la testearé en 1000 bucles :P
se puede irerar un máximo de 15 veces, 1000 bucles es mortal xDD
-
se puede irerar un máximo de 15 veces, 1000 bucles es mortal xDD
Me podrías enviar la solución, por favor? Me pica mucho la curiosidad... ya que dijiste que sólo sacas el factorial una vez, y es algo que se me hace extraño en un bucle.
Saludos
-
si quieres hacerlo iterando, haz solo un bucle para guardar los 15 factoriales, y los guardas en un array
factorial[1] = 1, factorial[5] = 120... etc
pero la opción recursiva para mi es más elegante xD
-
factorial ($a){
if ($a > 1)
return ($a * factorial ($a-1));
else
return 1;
}
Bucle de 100 veces:
Factorial de 1: 1
Factorial de 2: 2
Factorial de 3: 6
Factorial de 4: 24
Factorial de 5: 120
Factorial de 6: 720
Factorial de 7: 5040
Factorial de 8: 40320
Factorial de 9: 362880
Factorial de 10: 3628800
Factorial de 11: 39916800
Factorial de 12: 479001600
Factorial de 13: 6227020800
Factorial de 14: 87178291200
Factorial de 15: 1307674368000
Factorial de 16: 20922789888000
Factorial de 17: 355687428096000
Factorial de 18: 6402373705730000
Factorial de 19: 1.21645100409E+17
Factorial de 20: 2.43290200818E+18
Factorial de 21: 5.10909421717E+19
Factorial de 22: 1.12400072778E+21
Factorial de 23: 2.58520167389E+22
Factorial de 24: 6.20448401733E+23
Factorial de 25: 1.55112100433E+25
Factorial de 26: 4.03291461127E+26
Factorial de 27: 1.08888694504E+28
Factorial de 28: 3.04888344612E+29
Factorial de 29: 8.84176199374E+30
Factorial de 30: 2.65252859812E+32
Factorial de 31: 8.22283865418E+33
Factorial de 32: 2.63130836934E+35
Factorial de 33: 8.68331761881E+36
Factorial de 34: 2.9523279904E+38
Factorial de 35: 1.03331479664E+40
Factorial de 36: 3.7199332679E+41
Factorial de 37: 1.37637530912E+43
Factorial de 38: 5.23022617467E+44
Factorial de 39: 2.03978820812E+46
Factorial de 40: 8.15915283248E+47
Factorial de 41: 3.34525266132E+49
Factorial de 42: 1.40500611775E+51
Factorial de 43: 6.04152630634E+52
Factorial de 44: 2.65827157479E+54
Factorial de 45: 1.19622220865E+56
Factorial de 46: 5.50262215981E+57
Factorial de 47: 2.58623241511E+59
Factorial de 48: 1.24139155925E+61
Factorial de 49: 6.08281864034E+62
Factorial de 50: 3.04140932017E+64
Factorial de 51: 1.55111875329E+66
Factorial de 52: 8.06581751709E+67
Factorial de 53: 4.27488328406E+69
Factorial de 54: 2.30843697339E+71
Factorial de 55: 1.26964033537E+73
Factorial de 56: 7.10998587805E+74
Factorial de 57: 4.05269195049E+76
Factorial de 58: 2.35056133128E+78
Factorial de 59: 1.38683118546E+80
Factorial de 60: 8.32098711274E+81
Factorial de 61: 5.07580213877E+83
Factorial de 62: 3.14699732604E+85
Factorial de 63: 1.9826083154E+87
Factorial de 64: 1.26886932186E+89
Factorial de 65: 8.24765059208E+90
Factorial de 66: 5.44344939077E+92
Factorial de 67: 3.64711109182E+94
Factorial de 68: 2.48003554244E+96
Factorial de 69: 1.71122452428E+98
Factorial de 70: 1.197857167E+100
Factorial de 71: 8.50478588568E+101
Factorial de 72: 6.12344583769E+103
Factorial de 73: 4.47011546151E+105
Factorial de 74: 3.30788544152E+107
Factorial de 75: 2.48091408114E+109
Factorial de 76: 1.88549470167E+111
Factorial de 77: 1.45183092028E+113
Factorial de 78: 1.13242811782E+115
Factorial de 79: 8.94618213078E+116
Factorial de 80: 7.15694570463E+118
Factorial de 81: 5.79712602075E+120
Factorial de 82: 4.75364333701E+122
Factorial de 83: 3.94552396972E+124
Factorial de 84: 3.31424013457E+126
Factorial de 85: 2.81710411438E+128
Factorial de 86: 2.42270953837E+130
Factorial de 87: 2.10775729838E+132
Factorial de 88: 1.85482642257E+134
Factorial de 89: 1.65079551609E+136
Factorial de 90: 1.48571596448E+138
Factorial de 91: 1.35200152768E+140
Factorial de 92: 1.24384140546E+142
Factorial de 93: 1.15677250708E+144
Factorial de 94: 1.08736615666E+146
Factorial de 95: 1.03299784882E+148
Factorial de 96: 9.91677934871E+149
Factorial de 97: 9.61927596825E+151
Factorial de 98: 9.42689044888E+153
Factorial de 99: 9.33262154439E+155
Factorial de 100: 9.33262154439E+157
Tiempo (s): 0.0419449806213
Memoria (kB): 31.6796875
Es suficiente?
Fuente: http://www.cplusplus.com/doc/tutorial/functions2/ (solo la función)
Saludos
-
Se puede simplificar un poco más:
function factorial($n)
{
return ($n > 1) ? ($n * factorial($n-1)) : 1;
}
-
Se puede simplificar un poco más:
function factorial($n)
{
return ($n > 1) ? ($n * factorial($n-1)) : 1;
}
No, no se trata de simplificar. Se trata de hacerlo recursivo y que gaste menos recursos, ya que aunque esté simplificado no gasta más / menos que uno que está simplificado.
Saludos.
-
No, no se trata de simplificar. Se trata de hacerlo recursivo y que gaste menos recursos, ya que aunque esté simplificado no gasta más / menos que uno que está simplificado.
Saludos.
no, nmartin021, no mme vale xD.
optimízalo
-
no, nmartin021, no mme vale xD.
optimízalo
Me rindo, envíame la solución por MP, por favor. Gracias.
Saludos