Advertisement
Guest User

Untitled

a guest
Oct 11th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 6.63 KB | None | 0 0
  1.  
  2. @ECHO OFF
  3. SETLOCAL EnableDelayedExpansion
  4.  
  5. :: Project Euler Problem 25
  6. :: What is the index of the first term in the Fibonacci sequence to contain
  7. :: 1000 digits?
  8.  
  9. :: There's probably a clever way to do this. Alas, I am not clever.
  10.  
  11. SET _Fib=1
  12. SET _Fib1=1
  13. SET _FibIndex=2
  14. SET _FibIs32bit=1
  15. SET _FibLen=
  16. SET _FibDec=
  17.  
  18. :FibLoop
  19. SET _FibPrev=%_Fib%
  20. IF !_FibIs32bit! EQU 1 (
  21.     SET /A _FibIndex+=1
  22.     SET /A _Fib=_Fib+_Fib1
  23. ) ELSE (
  24.     SET /A _FibIndex+=1
  25.     CALL :ExtAdd !_Fib! !_Fib1! _Fib
  26.     CALL :ExtDim !_Fib! _FibLen _FibDec
  27.     IF !_FibLen! GEQ 1000 GOTO EndLoop 
  28. )
  29. SET _Fib1=%_FibPrev%
  30. IF %_Fib% GTR 1000000000 SET _FibIs32bit=0
  31. GOTO FibLoop
  32.  
  33. :EndLoop
  34. ECHO:The index of the first 1000 digit term is %_FibIndex%
  35.  
  36. GOTO :EOF
  37.  
  38. :ExtAdd
  39.     SETLOCAL EnableDelayedExpansion
  40.     :: Used to add two arbitrary numbers together.
  41.     :: Requires - :ExtMatchPad, :ExtDim
  42.     :: Accepts three parameters:
  43.     :: %1, %2 - The numbers to be added together (passed by value)
  44.     :: %3 - The result (passed by reference)
  45.     ::
  46.     :: Example invocation:
  47.     :: CALL :ExtAdd %_Num1% %_Num2% _Result
  48.     :: |--> Sums _Num1 and _Num2 and saves result in _Result
  49.  
  50.     SET _Add1=%1
  51.     SET _Add2=%2
  52.     SET _AddResult=
  53.     SET _AddCarry=0
  54.     SET _IntLen=1
  55.    
  56.     :ExtAddNums
  57.     CALL :ExtDim %_Add1% _Add1Len _Add1Dec
  58.     CALL :ExtDim %_Add2% _Add2Len _Add2Dec
  59.     CALL :ExtMatchPad _Add1 _Add2 _AddLen _AddDec %_Add1Len% %_Add1Dec% %_Add2Len% %_Add2Dec%
  60.  
  61.     FOR /L %%G IN (%_AddLen%,-1,1) DO (
  62.         SET /A _AddPos=%%G-1
  63.         CALL SET _AddInt1=%%_Add1:~!_AddPos!,%_IntLen%%%
  64.         CALL SET _AddInt2=%%_Add2:~!_AddPos!,%_IntLen%%%
  65.         SET /A _AddByPos=_AddInt1+_AddInt2+_AddCarry
  66.         IF !_AddByPos! GEQ 10 (
  67.             SET _AddCarry=1
  68.             SET /A _AddByPos-=10
  69.         ) ELSE (
  70.             SET _AddCarry=0
  71.         )
  72.         SET _AddResult=!_AddByPos!!_AddResult!
  73.     )
  74.  
  75.     IF %_AddCarry% EQU 1 SET _AddResult=1%_AddResult%
  76.  
  77.     :ExtAddReturnResult
  78.     ENDLOCAL & SET %3=%_AddResult%
  79. GOTO :EOF
  80.  
  81. :ExtMatchPad
  82.     SETLOCAL EnableDelayedExpansion
  83.     :: Used to match length and decimal position of two number strings
  84.     :: Requires - :ExtPad, :ExtDim, :ExtMakeFloat
  85.     :: Accepts the following parameters (passed by reference):
  86.     :: %1, %2 - Two numbers to match
  87.     :: %3, %4 - Length and decimal position of padded numbers.
  88.     ::
  89.     :: Optionally accepts the following (passed by value)
  90.     :: %5, %6 - Length and decimal position of %1
  91.     :: %7, %8 - Length and decimal position of %2
  92.     ::
  93.     :: Example invocation:
  94.     :: CALL :ExtMatchPad _Num1 _Num2
  95.     :: |--> Makes _Num1 and _Num2 have the same length
  96.     ::      and decimal position
  97.     :: So, 1234.5 and 1.2345 become 1234.5000 and 0001.2345.
  98.  
  99.     SET _MatchPad1=!%1!
  100.     SET _MatchPad2=!%2!
  101.     SET _MatchPadL=
  102.     SET _MatchPadD=
  103.    
  104.     IF NOT [%8]==[] (
  105.         SET _MatchPadL2=%7
  106.         SET _MatchPadD2=%8
  107.     ) ELSE CALL :ExtDim %_MatchPad2% _MatchPadL2 _MatchPadD2
  108.    
  109.     IF NOT [%6]==[] (
  110.         SET _MatchPadL1=%5
  111.         SET _MatchPadD1=%6
  112.     ) ELSE CALL :ExtDim %_MatchPad1% _MatchPadL1 _MatchPadD1
  113.  
  114.     :: Add a decimal if one number has a decimal and the other doesn't.
  115.     IF %_MatchPadD1% GTR %_MatchPadL1% (
  116.         IF %_MatchPadD2% LEQ %_MatchPadL2% (
  117.             CALL :ExtMakeFloat _MatchPad1 _MatchPadL1
  118.         )
  119.     )
  120.     IF %_MatchPadD2% GTR %_MatchPadL2% (
  121.         IF %_MatchPadD1% LEQ %_MatchPadL1% (
  122.             CALL :ExtMakeFloat _MatchPad2 _MatchPadL2
  123.         )
  124.     )
  125.    
  126.     :: Pad number strings so they both line up.
  127.     IF %_MatchPadD1% GTR %_MatchPadD2% (
  128.         SET /A "_DPadLen=_MatchPadD1-_MatchPadD2"
  129.         CALL :ExtPad _MatchPad2 !_DPadLen! L _MatchPadL2 _MatchPadD2
  130.         SET _MatchPadD=!_MatchPadD1!
  131.     )
  132.     IF %_MatchPadD2% GTR %_MatchPadD1% (
  133.         SET /A "_DPadLen=_MatchPadD2-_MatchPadD1"
  134.         CALL :ExtPad _MatchPad1 !_DPadLen! L _MatchPadL1 _MatchPadD1
  135.         SET _MatchPadD=!_MatchPadD2!
  136.     )
  137.  
  138.     IF %_MatchPadL1% GTR %_MatchPadL2% (
  139.         SET /A _LPadLen=_MatchPadL1-_MatchPadL2
  140.         CALL :ExtPad _MatchPad2 !_LPadLen! R _MatchPadL2 _MatchPadD2
  141.         SET _MatchPadL=!_MatchPadL1!
  142.     )
  143.     IF %_MatchPadL2% GTR %_MatchPadL1% (
  144.         SET /A _LPadLen=_MatchPadL2-_MatchPadL1
  145.         CALL :ExtPad _MatchPad1 !_LPadLen! R _MatchPadL1 _MatchPadD1
  146.         SET _MatchPadL=!_MatchPadL2!
  147.     )
  148.    
  149.     IF NOT DEFINED _MatchPadL SET _MatchPadL=%_MatchPadL1%
  150.     IF NOT DEFINED _MatchPadD SET _MatchPadD=%_MatchPadD1%
  151.  
  152.     ENDLOCAL & SET %1=%_MatchPad1%& SET %2=%_MatchPad2%& SET %3=%_MatchPadL%& SET %4=%_MatchPadD%
  153. GOTO :EOF
  154.  
  155. :ExtMakeFloat
  156.     SETLOCAL EnableDelayedExpansion
  157.     :: Used to add a decimal point to a number string
  158.     :: Accepts the following parameters:
  159.     :: %1 - The variable that needs a decimal point
  160.     ::
  161.     :: Example invocation:
  162.     :: CALL :ExtMakeFloat _Num _Len
  163.     :: |--> Returns _Num with a . at the end (1234 -> 1234.)
  164.     :: |--> Automatically increments length by one.
  165.  
  166.     SET _FloatNum=!%1!
  167.     SET /A _FloatLength=%2
  168.  
  169.     :: Only do this if we really need to...
  170.     CALL :ExtDim %_FloatNum% _FloatLen _FloatDec
  171.     IF %_FloatDec% GTR %_FloatLen% (
  172.         SET _FloatNum=!_FloatNum!.
  173.         SET /A _FloatLength+=1
  174.     )
  175.    
  176.     ENDLOCAL & SET %1=%_FloatNum%& SET /A %2=%_FloatLength%
  177. GOTO :EOF
  178.  
  179. :ExtPad
  180.     SETLOCAL EnableDelayedExpansion
  181.     :: Used to pad a number to facilitate mathematical operations
  182.     :: Accepts the following parameters:
  183.     :: %1 - The variable that needs to be padded
  184.     :: %2 - The number of positions to pad
  185.     :: %3 - The direction the pad needs to be applied (L or R)
  186.     :: %4 - Length variable - Returned with padded length
  187.     :: %5 - Decimal variable - Returned with adjusted position
  188.     ::
  189.     :: Example invocation:
  190.     :: CALL :ExtPad _Num 5 L _Len _Dec
  191.     :: |--> Returns padded length and decimal position in _Len & _Dec.
  192.     :: |--> Returns padded number back in _Num
  193.  
  194.     SET _PadNum=!%1!
  195.     SET /A _PadLength=%4
  196.     SET /A _PadDecimal=%5
  197.     IF %3==L (
  198.         FOR /L %%G IN (1,1,%2) DO (
  199.             SET _PadNum=0!_PadNum!
  200.             SET /A _PadLength+=1
  201.             SET /A _PadDecimal+=1
  202.         )
  203.     )
  204.     IF %3==R (
  205.         FOR /L %%G IN (1,1,%2) DO (
  206.             SET _PadNum=!_PadNum!0
  207.             SET /A _PadLength+=1
  208.         )
  209.     )
  210.     ENDLOCAL & SET %1=%_PadNum%& SET /A %4=%_PadLength% & SET /A %5=%_PadDecimal%
  211. GOTO :EOF  
  212.  
  213. :ExtDim
  214.     SETLOCAL EnableDelayedExpansion
  215.     :: Used to get the string length and decimal position of a number.
  216.     :: Accepts three parameters:
  217.     :: %1 - The number that needs its size and precision
  218.     :: %2 - A variable in which the size is returned
  219.     :: %3 - A variable in which the position of the decimal is returned
  220.     :: Returns length and decimal position by reference.
  221.     ::
  222.     :: Example invocation:
  223.     :: CALL :ExtDim %_Num% _Len _Dec
  224.    
  225.     SET _DimLength=0
  226.     SET _DimDecimal=-1
  227.     SET _DimArg=%1
  228.    
  229.     FOR %%G IN (0,1,2,3,4,5,6,7,8,9,.) DO (
  230.         SET _DimArg=!_DimArg:%%G=%%G !
  231.     )
  232.    
  233.     FOR %%G IN (%_DimArg%) DO (
  234.         SET /A _DimLength+=1
  235.         IF "%%G"=="." (
  236.             SET _DimDecimal=!_DimLength!
  237.         )
  238.     )
  239.  
  240.     IF %_DimDecimal% EQU -1 SET /A "_DimDecimal=_DimLength+1"
  241.     ENDLOCAL & SET /A %2=%_DimLength% & SET /A %3=%_DimDecimal%
  242. GOTO :EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement