Foro de elhacker.net

Programación => Scripting => Mensaje iniciado por: leogtz en 10 Abril 2009, 04:37 am



Título: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 10 Abril 2009, 04:37 am
Hola a todos.

Hace tiempo que tenía ganas de hacer esto en Batch.

Para los que no sepan que es la sucesión Fibonacci:
Citar
En matemáticas, la sucesión de Fibonacci es la siguiente sucesión infinita de números naturales:
(http://upload.wikimedia.org/math/6/0/7/6074d351583993b9a16dd2d9abf2bc5b.png)
El primer elemento es 0, el segundo es 1 y cada elemento restante es la suma de los dos anteriores. A cada elemento de esta sucesión se le llama número de Fibonacci. Esta sucesión fue descrita en Europa por Leonardo de Pisa, matemático italiano del siglo XIII también conocido como Fibonacci. Tiene numerosas aplicaciones en ciencias de la computación, matemáticas y teoría de juegos.
De Wikipedia.
Código
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. :code
  4. set /p "numero=Numero : "
  5. if not defined numero (goto:code)
  6. if %numero% lss 1 (
  7. echo.Error, numero negativo.
  8. set /p ,=Pulse Enter para volver.
  9. goto:code
  10. )
  11. for /l %%_ in (1,1,%numero%) do (set "variable%%_=0")
  12. set /a "variable1=1"
  13. set /a "variable2=2"
  14. set /a contador=0
  15. set /a "token_uno=1"
  16. set /a "token_dos=2"
  17. set /a "aumento_de_variable=3"
  18. :bucle
  19. if %contador% equ %numero% (goto:end)
  20. set /a "variable%aumento_de_variable%=!variable% style="color: #448888;">token_uno%! + !variable% style="color: #448888;">token_dos%!"
  21. set /a "token_uno+=1"
  22. set /a "token_dos+=1"
  23. set /a "aumento_de_variable+=1"
  24. set /a "contador+=1"
  25. goto:bucle
  26. :end
  27. for /l %%_ in (1,1,%numero%) do (
  28. echo !variable% style="color: #448888;">%_!
  29. )
  30. set /p =Teclee ENTER para salir.
  31. exit /b 0
Salida :
Código:
Numero : 9
1
2
3
5
8
13
21
34
55
Teclee ENTER para salir.
Código:
C:\>code
Numero : 5
1
2
3
5
8
Teclee ENTER para salir.
Código:
C:\>code
Numero : 25
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
Teclee ENTER para salir.

Saludos.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Littlehorse en 10 Abril 2009, 04:48 am
Por que del 46 en adelante dan numeros negativos?


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 10 Abril 2009, 04:56 am
Ahora no recuerdo cual es el limite en batch para almacenar.

Pero tampoco no pidas tanto, el termino 46 en la sucesión de fibonacci es demasiado, mira cuanto duró un codigo en C en calcular el 46, con recursión, es más, no pudó calcularlo, por ser un numero demasiado grande:

Código:
C:\>timethis fibonacci 46

TimeThis :  Command Line :  fibonacci 46
TimeThis :    Start Time :  Thu Apr 09 20:50:06 2009

1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 12
1393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 390881
69 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 -1323752223
TimeThis :  Command Line :  fibonacci 46
TimeThis :    Start Time :  Thu Apr 09 20:50:06 2009
TimeThis :      End Time :  Thu Apr 09 20:52:20 2009
TimeThis :  Elapsed Time :  00:02:14.500

C:\>

Mi codigo en Batch :
Código:
C:\>timethis code.bat

TimeThis :  Command Line :  code.bat
TimeThis :    Start Time :  Thu Apr 09 20:54:19 2009

Numero : 46
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
2178309
3524578
5702887
9227465
14930352
24157817
39088169
63245986
102334155
165580141
267914296
433494437
701408733
1134903170
1836311903
-1323752223
Teclee ENTER para salir.

TimeThis :  Command Line :  code.bat
TimeThis :    Start Time :  Thu Apr 09 20:54:19 2009
TimeThis :      End Time :  Thu Apr 09 20:54:21 2009
TimeThis :  Elapsed Time :  00:00:01.390

C:\>

Claro que no nos vamos a poner a comparar, solo es para hacer notar que el termino 46 en la sucesión de Fibonacci es muy grande.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Littlehorse en 10 Abril 2009, 05:08 am
Mira. (Banca que ahi edito)

(http://i44.tinypic.com/9abioi.jpg)


Yo tampoco me acuerdo cuanto es el limite en batch para almacenar, pero probablemente ese sea el problema, pero vamos en C ya que aparezca el numero negativo es porque lo codeaste sin ganas  ;D


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 10 Abril 2009, 05:21 am
Mira. (Banca que ahi edito)

(http://i44.tinypic.com/9abioi.jpg)


Yo tampoco me acuerdo cuanto es el limite en batch para almacenar, pero probablemente ese sea el problema, pero vamos en C ya que aparezca el numero negativo es porque lo codeaste sin ganas  ;D

Jaja, tal ves, es que lo hice con int´s, si lo hubiera hecho con long´s.  :P

Gracias por probar el codigo.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Littlehorse en 10 Abril 2009, 05:24 am
De nada! Che ese TimeThis lo hiciste vos?


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 10 Abril 2009, 05:26 am
No, pertenece a el Windows 2000 Resource Kit Tool.
Código:
http://www.microsoft.com/downloads/details.aspx?familyid=913795CD-7026-4143-AE85-1F5E096F9BE0&displaylang=en


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Littlehorse en 10 Abril 2009, 05:30 am
Thx!


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: 0x0309 en 10 Abril 2009, 20:14 pm
Hey Leo, considerando que solo debes ir sumando los dos números anteriores, podrías crear una función que trate las dos variables como texto, y vaya sumando cada carácter, así te evitas la aparación de números negativos, y podrías alcanzar números muy grandes, considerando que el tamaño máximo de una línea de órdenes es como 4000 u 8000 aprox.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 10 Abril 2009, 20:22 pm
Gracias, 0x0309

Un amigo me dijó que no necesitaba tantas variables, que si mucho con 4 se podía hacer, pero ya le expliqué que lo había en Batch y dijó :
"Ah, ok"

Pensó que la hicé en C  :D

Por cierto, recuerdas cual era el limite para almacenar?, hace muchisimo vi que lo posteaste pero lo olvidé.

Saludos.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: 0x0309 en 14 Abril 2009, 09:39 am
Leo, el límite para cmd.exe es 32 bits de amplitud o ancho. Así:

11111111111111111111111111111111
notación binaria: 32 bits o flags.

es en notación decimal: 4294967295

Ahora, el rango abarca números negativos y positivos, por lo que queda así:

-2147483648 a 2147483647

Hice una función que suma números en formato cadena de caracteres, para que así la sucesión no quede negativa.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: 0x0309 en 14 Abril 2009, 09:50 am
aqui una versión con la funcion suma:

Código:
@echo off




setlocal

:fibonacci
set n1=0
set n2=1

echo.%n1%
echo.%n2%

:hola

call :suma %n1% %n2%
set n1=%n2%
set n2=%suma%

echo.%suma%

goto hola

endlocal
goto :eof

::suma dos numeros positivos.
::Recibe dos numeros en formato de cadena de caracteres.
::util para sumar numeros mayores a 2147483647 (limite positivo. el rango de 32 bits en cmd solo permite numeros entre -2147483648 y 2147483647 )
::En windows nt y 2000 las cadenas de variables tiene un largo de maximo de 2047 caracteres, y en xp y superior: 8191.
::programado a la rapida por 0x0309
:suma
setlocal enableextensions enabledelayedexpansion
set primerNumero=%~1
set segundoNumero=%~2
call :len %primerNumero%
set /a lenPrimerNumero=%tam%
call :len %segundoNumero%
set /a lenSegundoNumero=%tam%
if %lenPrimerNumero% gtr %lenSegundoNumero% (
set mayor=primerNumero
set /a len=%lenPrimerNumero%-1
set menor=segundoNumero
) else (
set /a len=%lenSegundoNumero%-1
set mayor=segundoNumero
set menor=primerNumero
)
set /a diferencia=!len%mayor%!-!len%menor%!
set "loQueFalta="
for /l %%a in (1,1,%diferencia%) do (set loQueFalta=!loQueFalta!0)
set %menor%=%loQueFalta%!%menor%!
set /a reserva=0
set "suma="
:ciclo
for /F %%a in ("primerNumero:~!len!,1") do set digitoUno=!%%a!
for /F %%a in ("segundoNumero:~!len!,1") do set digitoDos=!%%a!
set /a sumaDigitos=!digitoUno!+!digitoDos!+!reserva!
set /a digitoResultante=!sumaDigitos!%%10
set /a reserva=!sumaDigitos!-!digitoResultante!
set /a reserva /=10
set suma=!digitoResultante!!suma!
set /a len -=1
if !len! geq 0 goto ciclo
if !reserva! gtr 0 (set suma=!reserva!!suma!)
(
endlocal
set suma=%suma%
)
goto :eof

:len
setlocal
set /a contl=0
set wordl=%~1
:loopl
if not defined wordl (goto endl)
set wordl=%wordl:~1%
set /a contl +=1
goto loopl
:endl
endlocal & set /a tam=%contl%
goto :eof


lista generada:
Código:
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765
10946
17711
28657
46368
75025
121393
196418
317811
514229
832040
1346269
2178309
3524578
5702887
9227465
14930352
24157817
39088169
63245986
102334155
165580141
267914296
433494437
701408733
1134903170
1836311903
2971215073
4807526976
7778742049
12586269025
20365011074
32951280099
53316291173
86267571272
139583862445
225851433717
365435296162
591286729879
956722026041
1548008755920
2504730781961
4052739537881
6557470319842
10610209857723
17167680177565
27777890035288
44945570212853
72723460248141
117669030460994
190392490709135
308061521170129
498454011879264
806515533049393
1304969544928657
2111485077978050
3416454622906707
5527939700884757
8944394323791464
14472334024676221
23416728348467685
37889062373143906
61305790721611591
99194853094755497
160500643816367088
259695496911122585
420196140727489673
679891637638612258
1100087778366101931
1779979416004714189
2880067194370816120
4660046610375530309
7540113804746346429
12200160415121876738
19740274219868223167
31940434634990099905
51680708854858323072
83621143489848422977
135301852344706746049
218922995834555169026
354224848179261915075
573147844013817084101
927372692193078999176
1500520536206896083277
2427893228399975082453
3928413764606871165730
6356306993006846248183
10284720757613717413913
16641027750620563662096
26925748508234281076009
43566776258854844738105
70492524767089125814114
114059301025943970552219
184551825793033096366333
298611126818977066918552
483162952612010163284885
781774079430987230203437
1264937032042997393488322
2046711111473984623691759
3311648143516982017180081
5358359254990966640871840
8670007398507948658051921
14028366653498915298923761
22698374052006863956975682
36726740705505779255899443
59425114757512643212875125
96151855463018422468774568
155576970220531065681649693
251728825683549488150424261
407305795904080553832073954
659034621587630041982498215
1066340417491710595814572169
1725375039079340637797070384
2791715456571051233611642553
4517090495650391871408712937
7308805952221443105020355490
11825896447871834976429068427
19134702400093278081449423917
30960598847965113057878492344
50095301248058391139327916261
81055900096023504197206408605
131151201344081895336534324866
212207101440105399533740733471
343358302784187294870275058337
555565404224292694404015791808
898923707008479989274290850145
1454489111232772683678306641953
2353412818241252672952597492098
3807901929474025356630904134051
6161314747715278029583501626149
9969216677189303386214405760200
16130531424904581415797907386349
...



Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 14 Abril 2009, 19:39 pm
Simplemente excelente, 0x0309.

Saludos.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Martin-Ph03n1X en 14 Abril 2009, 20:36 pm
jajaja no entendi pero en un ratito se genero un codigo ALTO 39043184998122354968635474677330498542864661988399598709411830703425204209650825
540787157763668286722
63173200356011969809443437297358849022080673265589795452673441480303628721313666
802004216758598573763
10221638535413432477807891197468934756494533525398939416208527218372883293096449
2342791374522266860485
16538958571014629458752234927204819658702600851957918961475871366403246165227815
9144795591280865434248
26760597106428061936560126124673754415197134377356858377684398584776129458324265
1487586965803132294733
43299555677442691395312361051878574073899735229314777339160269951179375623552081
0632382557083997728981
70060152783870753331872487176552328489096869606671635716844668535955505081876346
2119969522887130023714
11335970846131344472718484822843090256299660483598641305600493848713488070542842
72752352079971127752695
18341986124518419805905733540498323105209347444265804877284960702309038578730477
34872321602858257776409
29677956970649764278624218363341413361509007927864446182885454551022526649273320
07624673682829385529104
48019943095168184084529951903839736466718355372130251060170415253331565228003797
42496995285687643305513


Título: Re: Sucesión Fibonacci [Batch] {Actualizado}
Publicado por: leogtz en 15 Junio 2009, 05:26 am
Más optimizado, menos variables.
Código
  1. @echo off
  2. :: Leo Gutierrez R.
  3. setlocal enabledelayedexpansion
  4. set /a "y=1"
  5. :code
  6. set /p "numero=Terminos : "
  7. if not defined numero (goto:code)
  8. for /l %%_ in (1,1,%numero%) do (call:fibonacci)
  9. set /p =
  10. goto:eof
  11. :fibonacci
  12. set /a "y+=x"
  13. set /a "x=y-x"
  14. set /p "=!y! "<nul
  15. goto:eof


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: Darioxhcx en 15 Junio 2009, 08:38 am
tengo una duda..
no tiene que ver con el codigo.. lo vi y me gusta y esta bueno...
pero la duda que tengo es si dependiendo el sistema
x ejemplo sea
32 o 64 bits... te permitira trabajar con cifras mas grandes
como pasa con php

un sistema de 64 permite mas que uno de 32
alguien probo algo en 32 y 64 ?

puede ser que cambien en cuanto a eso
o no ?

un saludo


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: askrator en 15 Junio 2009, 13:23 pm
Mas corto aun:

Termino n = 1/raiz(5) * [(1+raiz(5)/2)^n-(1-raiz(5)/2)^n]

PD:

La raiz es cuadrada.

Saludos.


Título: Re: Sucesión Fibonacci [Batch]
Publicado por: leogtz en 15 Junio 2009, 17:26 pm
Mas corto aun:

Termino n = 1/raiz(5) * [(1+raiz(5)/2)^n-(1-raiz(5)/2)^n]

PD:

La raiz es cuadrada.

Saludos.

Bien, pero lamentablemente no poseemos soporte para numeros decimales.