Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Binary_Death

#381
Código optimizado ;)
#382
Aquí dos funciones nuevas relacionadas con la suma y la resta. Las otras eran para decimales, estas son para saltarse el límite de 32 bits de precisión que tiene la cmd al operar.

Después, cuando haga funciones para división y multiplicación decimal y corrija todos los bugs de estas funciones, lo unificaré todo en una sola clase para poder trabajar en batch con cualquier número real, con todos los dígitos decimales que uno quiera.

Aquí vienen las funciones:


:_addx
setlocal enabledelayedexpansion
set "f_s=_%~1" & set "s_s=_%~2" & set "add_str="
set/a cnt=1,car=0
:__loop.a
set "n_1=!f_s:~-%cnt%,1!"
set "n_2=!s_s:~-%cnt%,1!"
if "%n_1%%n_2%" EQU "__" goto :_endadd
if "%n_1%" EQU "_" set/a n_1=0
if "%n_2%" EQU "_" set/a n_2=0
set/a add=%n_1%+%n_2%+%car%,car=0,cnt+=1
if %add% GEQ 10 (
set/a car=1
if "!f_s:~-%cnt%,1!!s_s:~-%cnt%,1!" NEQ "__" (
set "add=%add:~-1%"
))
set "add_str=%add%%add_str%"
goto :__loop.a
:_endadd
call :_filset "%add_str%" "add_str"
endlocal & set "%~3=%add_str%" & exit /b

:_subx
setlocal enabledelayedexpansion
if "%~1" EQU "%~2" set "sub_str=0" & goto :_endsub
call :_filset "%~1" "t_1" & call :_filset "%~2" "t_2"
call :_hst "%t_1%" "%t_2%"
if "%hst%" EQU "%t_2%" set "min=_%~2" & set "sbs=_%~1" & set "s_g=-"
if "%hst%" EQU "%t_1%" set "min=_%~1" & set "sbs=_%~2"
set "sub_str=" & set/a cnt=1,c_s=0,car=0
:__loop.b
set "n_1=!min:~-%cnt%,1!"
set "n_2=!sbs:~-%cnt%,1!"
if "%n_1%%n_2%" EQU "__" goto :_endsub
if "%n_2%" EQU "_" set/a n_2=0
if "%car%" EQU "1" set/a n_2+=1,car=0
if %n_1% LSS %n_2% set/a c_s=10,car=1
set/a sub=%n_1%-%n_2%+%c_s%
set "sub_str=%sub%%sub_str%"
set/a cnt+=1,c_s=0
goto :__loop.b
:_endsub
call :_filset "%sub_str%" "sub_str"
endlocal & set "%~3=%s_g%%sub_str%" & exit /b

:_filset
for /f "tokens=* delims=0" %%_ in ("%~1") do set "%~2=%%_"
if not defined %~2 set/a "%~2=0"
exit /b

:_hst
setlocal enabledelayedexpansion
call :_strlen "%~1" & set/a n[0]=!errorlevel!
call :_strlen "%~2" & set/a n[1]=!errorlevel!
if %n[0]% EQU %n[1]% set "s_0=%~1" & set "s_1=%~2" & goto :_endhst
set/a hst=0,nhst=1
if %n[1]% GTR !n[%hst%]! set/a hst=1,nhst=0
set/a l_0=!n[%hst%]!-!n[%nhst%]!
shift/0 & call set "s_0=%%~%hst%" & call set "s_1=%%~%nhst%"
for /l %%_ in (1,1,%l_0%) do call set "s_1=0!s_1!"
:_endhst
for /f %%_ in ('"(echo:%s_0%&echo:%s_1%)|sort"') do set "hst=%%_"
endlocal & set "hst=%hst%" & exit /b

:_strlen
setlocal
set/a cnt=0
for /f "tokens=* eol=" %%_ in (
'"cmd /u /c echo:%~1|more"'
) do set/a cnt+=1
endlocal & exit /b %cnt%


La sintaxis es:


call :_addx "sum1" "sum2" "variable_almacén"
call :_subx "min" "sbs" "variable_almacén"


Un saludo, y por favor, cualquier bug que encuentren díganmenlo, que así me ayudarán a mejorar la clase final ;)

PD: Devuelve también, en el caso de la resta, resultados negativos si el substraendo es mayor que el minuendo ;)

EDIT: Bug fixeado.

Un pequeño ejemplo de su uso:


@Echo Off
more/c<nul
echo:  125504500255796221456988250471037
echo:-        47662554011498822047690014
echo:-------------------------------------
call :_subx "125504500255796221456988250471037" "47662554011498822047690014" "rslt"
echo:  %rslt%
pause>nul & exit


Como podéis ver, estos números son imposibles de operar en batch, pero usando esta función es posible.

Con decimales y con capacidad para manejar números astronómicos, creo que ya no hay excusas para no hacer programas de matemáticas en batch.
#383
No hay de qué ;)

Puedes leerte esto para que te aclare dudas sobre setlocal: http://ss64.com/nt/delayedexpansion.html

¡Un saludo!
#384
Scripting / Re: [Reto Batch] Letras aleatorias
23 Julio 2012, 09:00 AM
Sí, por supuesto que todo depende del nivel al que se llegue. Ahí no hay nada que decir  :P

Lo que ocurre es eso, que si tomamos un 5/10 como algo de nivel medio, todos los 5/10 tienen que ser de nivel medio. Si lo tomamos como nivel básico, pues todos tienen que estar acorde a ese nivel.

También ocurre que cada usuario valora la dificultad de una manera según su nivel, y por eso hay discordancias y desproporciones en los niveles de dificultad. Si todos los códigos los valorara una sola persona (tú, en este caso), eso desaparecería.

Es una sugerencia, pero si crees que ya están bien pues nada que decir ;)
#385
Llamas a la función así:


call :_calc add|sub "operación" "variable"


Donde variable será donde se guarde el resultado.
Luego, al hacer:


echo. %variable%


Se te imprimirá en pantalla el resultado.

Por supuesto puedes hacer esto:


@echo off
echo ingrese primer numero
set  /p "a="
echo ingrese segundo numero
set /p "b="
call :_calc sub "%a%-%b%" "adt"
echo. Resultado de la resta: %adt%
pause > nul
exit


#386
Aquí dejo una función que es capaz de sumar y restar infinitos términos con tantos decimales como permita la cmd, usando sólo batch.

Dedicada a AgnesBlack, que tenía una duda con esto se ve.


@Echo Off
more/c<nul
call :_calc sub "12.72-8.189605-1.0025" "adt"
call :_calc add "%adt%+521.27+5" "adt"
echo: 12.72 - 8.189605 - 1.0025 + 521.27 + 5 = %adt%
pause 1>nul
exit
:_calc
setlocal enabledelayedexpansion
if "%~1" EQU "add" set "sym=+"
if "%~1" EQU "sub" set "sym=-"
set "add_str=%~2"
set "add_str=!add_str:%sym%= !"
set/a hst=0,cnt=0,add=0
for %%_ in (%add_str%) do (
set/a dec[!cnt!]=0
for /f "tokens=2 delims=." %%. in ("%%_") do (
call :_strlen "%%."
set/a dec[!cnt!]=!errorlevel!
if !errorlevel! GTR !hst! set/a hst=!errorlevel!
)
set/a cnt+=1
)
set/a cnt=0
if "%sym%" EQU "-" for %%_ in (%add_str:.=%) do (
set/a pow=%hst%-%dec[0]%,n_b=%%_
for /l %%. in (1,1,!pow!) do set "n_b=!n_b!0"
set/a add+=!n_b!*2
goto :__op
)
:__op
for %%_ in (%add_str:.=%) do (
call set/a pow=%hst%-%%dec[!cnt!]%%,n_b=%%_
for /l %%. in (1,1,!pow!) do set "n_b=!n_b!0"
set/a add%sym%=!n_b!,cnt+=1
)
set "res=!add:~0,-%hst%!.!add:~-%hst%!"
if %hst% EQU 0 set "res=%res:~1%"
endlocal & set "%~3=%res%" & exit /b
:_strlen
setlocal
set/a cnt=0
for /f "tokens=* eol=" %%_ in (
'"cmd /u /c echo:%~1|more"'
) do set/a cnt+=1
endlocal & exit /b %cnt%


¡Un saludo!
#387
De nada, me alegra haberte ayudado.

Saludos y suerte ;)
#388
Si todavía no controlas mucho batch tal vez sería conveniente que empezaras por un reto un poco más sencillo  :P

Si te dispones a hacerlo, seguro que si lo haces primero en C te será más fácil luego pasarlo a batch, por experiencia propia.

Saludos y ánimo.
#389
Batch no acepta números decimales de per se. Si quieres trabajar con ellos, tendrás que hacerte tú mismo las funciones adecuadas o usar algunas hechas por otro usuario.

También puedes usar una función que hice hace un tiempo que necesitaba hacer cuentas decimales:

Código (dos) [Seleccionar]

:calc
(Echo.%~2=%~1&&Echo.Wscript.StdOut.Write %~2) 1>%temp%\calc.vbs
for /f %%A in ('cscript //nologo %temp%\calc.vbs') do (set "%~2=%%A")
GoTo:EoF


Se usa, por ejemplo, así:

Código (dos) [Seleccionar]

@echo off
call:calc "5.1+5.1" "rslt"
Echo.%rslt%
pause 1>nul&exit/b
:calc
(Echo.%~2=%~1&&Echo.Wscript.StdOut.Write %~2) 1>%temp%\calc.vbs
for /f %%A in ('cscript //nologo %temp%\calc.vbs') do (set "%~2=%%A")
GoTo:EoF


Guarda este último código y ejecútalo, y verás que devuelve 10.2

Claro que, usa VBS.

Un saludo.

PD: Y sí, no hay más forma de sacar el cociente. El operador división es /, y el operador módulo es %.

#390
Scripting / [Reto Batch]Algoritmo Quicksort
22 Julio 2012, 20:31 PM
Reto Nº 18

Nombre:           Algoritmo Quicksort (Binary_Death)
Dificultad:        6/10
Objetivo:         Desarrollar una función de ordenamiento de números basada               en el algoritmo quicksort.

Indicaciones:   El algoritmo se puede ver aquí: http://es.wikipedia.org/wiki/Quicksort

La llamada a la función ha de ser como sigue: call :_qsort "a b c d e f g h i..."
Donde las letras son números cualquiera.