:Life
set /a R=%random%%%50+1
echo %random% >> %R%.bat
set /a t=%time:~6,-3%
If %t% geq 10 (
set /a t=%t%-10
) else (
set /a t=%t%+10
)
:wait
If %time:~6,-3% neq %t% goto :Wait
:death
set /a K=%random%%%50+1
del /Q %K%.bat
:disease
set /a D=%random%%%150+1
If %D% EQU 150 del /Q *.bat (
goto Life
) else (
If %D% EQU 150 echo On Error Resume Next > temp.vbs
If %D% EQU 150 echo MsgBox "Disease Killed The Biome", vbInformation + vbSystemModal + vbOKOnly, "Life.exe" >> temp.vbs
If %D% EQU 150 cscript temp.vbs
If %D% EQU 150 del temp.vbs
goto Life
)
:EOF
So my issue is the timer engine. The counter itself contains 00–59 but the other is 0–59 so when the ticker hits a number and it has a value of 9 or less it'll skip them on the next passover because they don't have 09 (etc.), is there a way where I can set the code to other ticker to stay at 59 the whole time?
It would be easier to read, if you could format your code a little bit.
To solve your current problem, you could use the time to decimal trick.
set /a t=1%time:~6,-3%-100
Else you got problems with the times 08 and 09, because of the leading zero, it assumes it should be an octal value and fails.
And in the wait-loop you could use the same way
:wait
set /a now=1%time:~6,-3%-100
If %now% neq %t% goto :Wait
But to wait a time it is better to use the way,
ping localhost -n [sec]+1 > NUL
because the your way consumes the 100% cpu (one core).
Related
This question already has an answer here:
How to generate succesive dates? (add N days to date)
(1 answer)
Closed last month.
I have bat script for loop function
#echo off set /p a="Start Date(yyyymmdd):"%=% set /p b="Finish Date
(yyyymmdd):"%=%
echo %a% echo %b%
echo start loop
FOR /L %%c IN (%a%,1,%b%) DO ( echo %%c
set inputan=%%c
call test_loopong.bat %inputan%
)
I need to run according to the range of start and end date input.
But from the script above, for example the start date is 20221231 and the end date is 20230103
will loop all numbers from 20221231, 20221232, 20221233......20230103
Please someone can help me.
Thanks
#ECHO Off
SETLOCAL
set /p "startdate=Start Date(yyyymmdd):"
set /p "finishdate=Finish Date (yyyymmdd):"
echo %startdate%
echo %finishdate%
IF %finishdate% lss %startdate% ECHO Invalid DATE range&GOTO :eof
echo start loop
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
GOTO :EOF
:test_loopong.bat
ECHO IN test_loopong : %%1=%1 inputan=%inputan%
GOTO :eof
I changed the variable names so that they are maintainable, 'though I've no idea what inputan means.
Added invalid date-range check.
Note syntax of set /p
Forget for the moment what for...%%y... does.
I used a set /a since %%c must be numeric.
Use set "var1=value" for setting STRING values - this avoids problems caused by trailing spaces.
I converted test_loopong.bat to an internal subroutine (call :name) for demonstration purposes to avoid having to generate another file.
I'm having that subroutine simply display the value of the variable inputan and the parameter %1. %%c can be delivered as a parameter to the subroutine (be it internal or external) but your syntax would appear to omit the parameter because of the delayed expansion trap - %var% will be replaced by the value of var at the time the outer loop (for...%%c) is encountered.
Now the for...%%y jiggery-pokery.
The command set /a inputan=%%c % 100 would set inputan to %%c mod 100. There's no importance about the variable name - that one's about to be assigned a different value again in a couple of lines.
When used in a for /f, batch will execute the set/a command and echo the result to the metavariable %%y.
However, = and % are special characters and need to be "escaped" (interpreted without their special meaning). Th escape character for most specials is caret (^) but for % is % itself.
The result of the calculation is assigned to %%y and we can then test that %%y is lss 32 - Less than 32, and also it is gtr 0 - Greater than 0. Only then do we call test_loopong.bat. This eliminates most non-dates
If you don't want to skip the non-dates, then remove the for...%%y line and delete one of the ) lines.
--- further thoughts ----
Suppressing the days 32..99 & 00 really only does half the job. Much better if we suppress months 13..99 & 00. The revision then would be (presenting just the main loop, minus the frippery)
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%e IN ('set /a inputan^=%%c %% 10000') DO IF %%e lss 1232 IF %%e gtr 100 (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
)
Same principle, just dealing with months in place of days.
One slight problem with this method is that it's as slow as a wet week.
So - a different approach
SET /a yyyy=%startdate:~0,4%
SET /a mm1=1%startdate:~4,2%
SET /a dd1=1%startdate:~-2%
:loop2
SET /a inputan=%yyyy%0000+%mm1%00+dd1-10100
IF %inputan% gtr %finishdate% GOTO :eof
CALL :test_loopong.bat %inputan%
SET /a dd1+=1
IF %dd1% leq 131 GOTO loop2
SET /a dd1=101&SET /a mm1+=1
IF %mm1% leq 112 GOTO loop2
SET /a mm1=101
SET /a yyyy+=1
GOTO loop2
This sets yyyy to the year and mm1/dd1 to 100+(month/day). 100+ needs to be done since batch regards a numeric string that starts 0 as
octal hence August and September cause problems.
So - calculate inputan by tringing 4 0s to yyyy, adding 100*mm1 and dd1, then subtracting 10100 since mm1 is mm+100 and dd1 is dd+100.
If the resultant inputan is greater than the finish date, end the routine.
Test using inputan.
Next day - add 1 to dd1.
If the result is less than or equal to 131, we're fine.
Otherwise set dd1 to 101 and increment the month
Same recipe for mm1, limit is 112 and bump the year if required.
---- Further revision to deal with non-dates 31st Apr, Jun, Sep, Nov and Feb (include leap years) ---
#ECHO Off
SETLOCAL
set /p "startdate=Start Date(yyyymmdd):"
set /p "finishdate=Finish Date (yyyymmdd):"
echo %startdate%
echo %finishdate%
IF %finishdate% lss %startdate% ECHO Invalid DATE range&GOTO :eof
echo start loop
GOTO ver2
FOR /L %%c IN (%startdate%,1,%finishdate%) DO (
FOR /F %%e IN ('set /a inputan^=%%c %% 10000') DO IF %%e lss 1232 IF %%e gtr 100 (
FOR /F %%y IN ('set /a inputan^=%%c %% 100') DO IF %%y lss 32 IF %%y gtr 0 (
echo %%c
set /a inputan=%%c
call :test_loopong.bat %%c
)
)
)
GOTO :EOF
:ver2
SET /a yyyy=%startdate:~0,4%
SET /a mm1=1%startdate:~4,2%
SET /a dd1=1%startdate:~-2%
:loop2
SET /a inputan=%yyyy%0000+%mm1%00+dd1-10100
IF %inputan% gtr %finishdate% GOTO :eof
CALL :test_loopong.bat %inputan%
SET /a dd1+=1
SET /a inputan=yyyy %% 4
IF %mm1%==102 IF %dd1% gtr 129 (GOTO nextmonth) ELSE IF %inputan% neq 0 IF %dd1%==129 GOTO nextmonth
FOR %%e IN (104 106 109 111) DO IF %%e131==%mm1%%dd1% GOTO nextmonth
IF %dd1% leq 131 GOTO loop2
:nextmonth
SET /a dd1=101&SET /a mm1+=1
IF %mm1% leq 112 GOTO loop2
SET /a mm1=101
SET /a yyyy+=1
GOTO loop2
GOTO :eof
:test_loopong.bat
ECHO IN test_loopong : %%1=%1 inputan=%inputan%
GOTO :eof
This must be very basic but i can't seem to find a way to get this done
my batch script goes like this:
#echo off
echo Type In Desired Volume And Press Enter
echo.
echo 0 = 0 %%
echo 1 = 100 %%
echo 0.10 = 10 %%
echo 0.65 = 65 %%
echo.
set /p input=
echo %input% > "C:\SetVol\Source\Volume.txt
I want to make it more user friendly by letting the user input a number between 0 and 100 instead of, for example, 0.10 for 10% audio volume. But i still need to output the 0.10 to a textfile if the user enters 10.
Google appears to longer be my best friend and we cant seem to communicate on this.
If anybody could help me get starter that would be great.
A simple way is to convert the input number to the requested output format.
One step is to prefix the input with 0.
set /p input=[Enter volume in %%]:
set "output=0.%input%"
echo %input% > "C:\SetVol\Source\Volume.txt
But this would fails for one digit values like 2%, becomes 0.2 instead of 0.02.
This can be fixed with prefix each number with 00 and take the last three digits and add a dot between.
set /p input=[Enter volume in %%]:
set "temp=00%input%"
set "output=%temp:~-3,1%.%temp:~-2%"
echo %output% > "C:\SetVol\Source\Volume.txt
You can use choice in a loop to make a key based 'slider', and then modifiy the variable value to include a 0. prefix or be 1 using an if condition:
#Echo off
set "volume=50"
:Volume
cls
Echo( Current volume: %Volume%%% [I]ncrease [D]ecrease [C]ontinue
For /f "delims=" %%G in ('Choice /N /C:IDC')Do (
If "%%G"=="I" If not %Volume% GEQ 100 Set /A Volume+=1
If "%%G"=="D" If not %Volume% LEQ 0 Set /A Volume-=1
If not "%%G"=="C" Goto :Volume
)
IF %volume% Equ 100 ( Set "Volume=1" )Else If %volume% LSS 10 (
Set "Volume=0.0%Volume%"
) Else Set "Volume=0.%Volume%"
:#your script here
For NTFS systems, a variant that stores the last set volume in an alternate data stream and reasigns the last value on return:
#Echo off
set "volume=50"
For /f "Usebackq delims=" %%G in ("%~f0:Volume")Do Set "%%G"
:Volume
cls
Echo( Current volume: %Volume%%% [I]ncrease [D]ecrease [C]ontinue
For /f "delims=" %%G in ('Choice /N /C:IDC')Do (
If "%%G"=="I" If not %Volume% GEQ 100 Set /A Volume+=1
If "%%G"=="D" If not %Volume% LEQ 0 Set /A Volume-=1
If not "%%G"=="C" Goto :Volume
)
Set Volume >"%~f0:Volume"
IF %volume% Equ 100 ( Set "Volume=1" )Else If %volume% LSS 10 (
Set "Volume=0.0%Volume%"
) Else Set "Volume=0.%Volume%"
:#your script here
Note: by using this method of input, invalid input cannot be entered.
Figured out a way to use the choice input, if anyone has a more neat or different way to do this please let me know... 291 more lines to edit...
#echo off
echo Choose Audio Volume 0-100 %%
:choice
set /P c=
if /I "%c%" EQU "0" goto :0
if /I "%c%" EQU "1" goto :1
if /I "%c%" EQU "2" goto :2
goto :choice
:0
echo 0 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
:1
echo 0.01 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
:2
echo 0.02 > C:\users\%username%\desktop\numbertest.txt
echo You chose %c% %%
pause
exit
I am currently making a game that has a persuasion system in it. I had all the code for one of the systems set up, but then I set up 2 more, and it started give me an error that said '(number) was not expected at this time'. when I put in 2 for the second choice, and 3 for the 3rd choice.
The code is like this.
#echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
set name=Quantum
cls
color 0a
Echo King Redwood: So 2000?
pause >nul
echo.
call :colorText 09 "1. 2500"
echo.
call :colorText 0e "2. 3000"
echo.
call :colorText 0c "3. 4000"
echo.
echo 4. 2000
echo.
set /p "purs=Enter:"
if /i %purs% == 1 (
goto CheckB )
if /i %purs% == 2 (
goto CheckY )
if /i %purs% == 3 (
goto CheckR )
if /i %purs% == 4 (
goto Convo )
:CheckB
set bleu=%random:~-2,1%
if %bleu% GTR 10 (
goto CheckB )
if %bleu% LSS 0 (
goto CheckB )
set /a num = 3
set /a reward = 2500
goto Res
:CheckY
set Yel=%random:~-2,1%
if %Yel% GTR 10 (
goto CheckY )
if %Yel% LSS 0 (
goto CheckY )
set /a num = 5
set reward = 3000
goto Res
:CheckR
set red=%random:~-2,1%
if %red% GTR 10 (
goto CheckB )
if %red% LSS 0 (
goto CheckB )
set /a num = 7
set /a reward = 4000
goto Res
:Convo
set /a reward = 2000
Echo %name%: I think that is a reasonable price.
Echo King Redwood: Very well.
Echo King Redwood: We will now take you to make sure you are
echo ready.
pause >nul
:Res
if %bleu% GEQ %num% goto Succeed
if NOT %bleu% GEQ %num% goto Fail
:Succeed
Echo %name%: I think that the struggles for such a long trip will be more then that
Echo %name%: How about %reward%?
Echo King Redwod: OK %reward% will work.
pause >nul
goto end
:Fail
Echo %name%: I think that you can give me %reward%.
Echo %name%: You know, for the struggles that there will be along the way.
echo If 2000 isn't good enough for you, I'll just have someone else do it.
pause >nul
:end
exit
:colorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1i
First, make sure to close the FOR loop by putting a ) before :CheckB.
For the 'was not expected at this time' error, you're sometimes comparing an empty variable to something. For example, by following CheckY, you set Yel, then proceed to Res and check Bleu, which is empty because it hasn't been set. You're putting nothing next to the binary GEQ operator, and that's why it's complaining.
Tip: to debug, try inserting ECHO statements like this:
:Res
echo bleu=%bleu%,num=%num%
Another problem: when using SET, do not surround the = by spaces. SET /a will work with spaces around =, just because of the nature of /a, but plain SET will not. Well, it will append your variable name with a space and prepend your value with a space, which is not what you want.
Another tip: you can constrain what RANDOM returns through SET /a and the modulus operator, like this.
SET /a red=%random% %% 11
This will set red to a number between 0 and 10, so there is no need for the substrings and goto routines you're using after picking your random number.
Also, consider using EXIT /b to exit the batch file and not the whole CMD environment.
I have a batch file and within that batch file I need to run one of two commands depending on time of my server.
If the time is between 22:00:00 and 03:30:00 -- xcopy /Y a\1.txt c\1.txt
If the time is before or after this range -- -- xcopy /Y b\1.txt c\1.txt
This will use xcopy to switch a file back and forth depending on the time.
I know this is easy but my brain just won't work atm lol
Edit:
Went with 22:00 and 4:00... this is what I came up with but it doesn't seem like the best way...
set current_time=%time:~0,5%
if "%current_time%" lss "22:00" goto daycycle
if "%current_time%" gtr " 4:00" goto daycycle
echo Do this between 10pm and 4am
goto continue
:daycycle
echo Do this before 10pm and after 4am
:continue
#echo off
setlocal enableextensions disabledelayedexpansion
set "now=%time: =0%"
set "task=day"
if "%now%" lss "03:30:00,00" ( set "task=night" )
if "%now%" geq "22:00:00,00" ( set "task=night" )
call :task_%task%
endlocal
exit /b
:task_day
:: do daily task
goto :eof
:task_night
:: do nightly task
goto :eof
EDITED - The previous code should work under the conditions in the original question. But will fail in different time configurations. This should solve the usual problems
#echo off
setlocal enableextensions disabledelayedexpansion
call :getTime now
set "task=day"
if "%now%" lss "03:30:00,00" ( set "task=night" )
if "%now%" geq "22:00:00,00" ( set "task=night" )
call :task_%task%
echo %now%
endlocal
exit /b
:task_day
:: do daily task
goto :eof
:task_night
:: do nightly task
goto :eof
:: getTime
:: This routine returns the current (or passed as argument) time
:: in the form hh:mm:ss,cc in 24h format, with two digits in each
:: of the segments, 0 prefixed where needed.
:getTime returnVar [time]
setlocal enableextensions disabledelayedexpansion
:: Retrieve parameters if present. Else take current time
if "%~2"=="" ( set "t=%time%" ) else ( set "t=%~2" )
:: Test if time contains "correct" (usual) data. Else try something else
echo(%t%|findstr /i /r /x /c:"[0-9:,.apm -]*" >nul || (
set "t="
for /f "tokens=2" %%a in ('2^>nul robocopy "|" . /njh') do (
if not defined t set "t=%%a,00"
)
rem If we do not have a valid time string, leave
if not defined t exit /b
)
:: Check if 24h time adjust is needed
if not "%t:pm=%"=="%t%" (set "p=12" ) else (set "p=0")
:: Separate the elements of the time string
for /f "tokens=1-5 delims=:.,-PpAaMm " %%a in ("%t%") do (
set "h=%%a" & set "m=00%%b" & set "s=00%%c" & set "c=00%%d"
)
:: Adjust the hour part of the time string
set /a "h=100%h%+%p%"
:: Clean up and return the new time string
endlocal & if not "%~1"=="" set "%~1=%h:~-2%:%m:~-2%:%s:~-2%,%c:~-2%" & exit /b
Try this:
#echo off
set hour=%time:~0,2%
set min=%time:~3,2%
if %hour% GEQ 22 (
xcopy /Y a\1.txt c\1.txt
) ELSE (
if %hour% LEQ 3 (
if %hour% EQU 3 if %min% GTR 30 (
xcopy /Y b\1.txt c\1.txt
goto :END
)
xcopy /Y a\1.txt c\1.txt
) ELSE (
xcopy /Y b\1.txt c\1.txt
goto :END
)
)
:END
And I'm rather sure that will do what you want. Manual if statements for the win! Note it would be a lot easier if it was 22:00 to 4:00 or 3:00. I had to incorperate the :30 minute checker.
But yea, it might not work, so just check it before you put it up on your server.
Monacraft.
What should work:
#echo off
:loop
set hour=%time:~0,2%
set min=%time:~3,2%
cls
ECHO %hour%
ECHO %min%
ECHO This %I%
IF %hour% == 14 GOTO Test2
goto loop
:Test2
IF %min% == 58 GOTO YUP
IF %min% == 59 GOTO LATE
Goto loop
:YUP
SET I=0
GOTO loop
:LATE
SET I=NOPE
GOTO loop
I've been working on a little project using batch files and I've ran into a problem. As far as I'm aware there's no way to run a check to see if a certain variable is a prime number, if I'm wrong would anyone please inform me of how to do so, otherwise, can anyone think of a workaround I could use (like checking if a number is equal to a number on a list of prime numbers on a txt file or whatever).
Thanks ^^
(Also it's worth noting I'm not very knowledgeable with batch files so please excuse any idiocy I may present..)
If you have a text file of prime numbers, 1 per line (obviously up through some limit), then the solution is trivial - just use FINDSTR.
Assuming you have a NUMBER variable containing a number, then
>nul findstr /x %NUMBER% "primes.txt" && (
REM prime actions go here
echo %NUMBER% is prime
) || (
REM not prime actions go here
echo %NUMBER% is NOT prime
)
UPDATE
Here is a native batch script that can test any valid integer supported by batch (signed 32 bit ints) to see if it is prime. Performance is much better than I thought possible.
::testPrime Number
::
:: Computes whether Number is a prime or not.
:: The result is printed to stdout.
::
:: ERRORLEVEL is also set to indicate the result:
:: 0 = Prime
:: 1 = Not Prime
:: 2 = Error
::
:: Number = Any valid integral expression supported by SET /A
::
#echo off
if "%~1"=="test" (
setlocal enableDelayedExpansion
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=num %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr !num! exit 0
)
)
setlocal disableDelayedExpansion
2>nul set /a "num=%~1" || (
>&2 echo invalid number: %1
exit /b 2
)
if %num% leq 1 (
echo %num% is NOT prime
exit /b 1
)
if %num% leq 3 (
echo %num% is prime
exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
echo %num% is NOT prime
exit /b 1
)
(
cmd /c "%~f0" test
) && (
echo %num% is prime
exit /b 0
) || (
echo %num% is NOT prime
exit /b 1
)
exit /b
The test is actually split into 2 parts, the 2nd of which is actually run in a new CMD instance. The 2nd part actually appears at the top of the script. This is done for performance reasons. It is the only way I can break out of a FOR /L loop immediately without terminating the batch script.
You can integrate your code with the script easily enough. For example:
#echo off
::----------------------------------------------------
:: This 2nd part of :testPrime must be at top of script
::
if "%~1"=="test" (
setlocal enableDelayedExpansion
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=num %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr !num! exit 0
)
)
:: End of 2nd part of :testPrime
::-----------------------------------------------------
:: Your code goes here
:: I'll just call the test with some representative values
::
setlocal disableDelayedExpansion
for %%N in (
1 2 3 4 100001 100003 5000009 5000011 0x7fffffff-2 0x7fffffff
) do >nul call :testPrime %%N && (
rem prime number actions go here
echo %%N is prime!
) || (
rem non-prime number actions go here
echo Not prime (%%N^)
)
exit /b
::----------------------------------------------------
:: Here is the 1st part of :testPrime
::
:testPrime
2>nul set /a "num=%~1" || (
>&2 echo invalid number: %1
exit /b 2
)
if %num% leq 1 (
echo %num% is NOT prime
exit /b 1
)
if %num% leq 3 (
echo %num% is prime
exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
echo %num% is NOT prime
exit /b 1
)
(
cmd /c "%~f0" test
) && (
echo %num% is prime
exit /b 0
) || (
echo %num% is NOT prime
exit /b 1
)
exit /b
The output for the above looks like this:
Not prime (1)
2 is prime!
3 is prime!
Not prime (4)
Not prime (100001)
100003 is prime!
Not prime (5000009)
5000011 is prime!
Not prime (0x7fffffff-2)
0x7fffffff is prime!
Finally, just for yucks, I wrote a variation that lists the next prime >= or <= a given number.
::nextPrime [/less] Num
::
:: List the minimum prime number >= Num
::
:: The /L option lists the maximum prime number <= Num
::
:: The ERRORLEVEL is set to the found prime number
::
:: Num = Any valid integral expression supported by SET /A
::
#echo off
setlocal enableDelayedExpansion
if "%~1"=="test" (
for /l %%N in (3 2 0x7fffffff) do (
set /a "test1=%2 %% %%N, test2=%%N*%%N"
if !test1! equ 0 exit 1
if !test2! gtr %2 exit 0
)
)
if "%~1"=="prev" (
if !num! lss 2 exit 0
set /a "test=num%%2"
if !test! equ 0 set /a num-=1
for /l %%N in (!num! -2 2) do cmd /c "%~f0" test %%N && exit %%N
exit 0
)
if "%~1"=="next" (
if !num! lss 2 exit 2
set /a "test=!num!%%2"
if !test! equ 0 set /a num+=1
for /l %%N in (!num! 2 0x7fffffff) do cmd /c "%~f0" test %%N && exit %%N
exit 0
)
set "cmd=next"
if /i "%~1" equ "/L" (
set "cmd=prev"
shift /1
)
2>nul set /a "num=%~1" || exit /b 0
cmd /c "%~f0" %cmd% || echo !errorlevel!
And here is a demonstration of usage with output:
D:\test>nextPrime 10000000
10000019
D:\test>nextPrime /l 10000000
9999991
All of those scripts seem awfully (and unnecessarily) large to me.
An easier way to do this is using... I believe the term I'm looking for is either modulo or modulus expressions (I think modulo is the plural or modulus).
#echo off & setlocal enabledelayedexpansion
:a
cls
set /p num=Type a number to be checked:
cls
set num2=%num%-1
if %num% leq 2 goto yes
for /l %%i in (2,1,%num2%) do (
set rem=%num% %% %%i
if %rem% neq 0 goto no
)
:yes
echo %num% is a prime number.
pause
goto a
:no
echo %num% is not a prime number.
pause
goto a
Basically, it gets a user-defined variable and checks, when divided by a number, if the remainder (rem) is 0 or not.
This way is a little slow, but the shortest code. You can make it a bit shorter by putting another if statement before the for loop that checks if the number has a remainder when divided by two.
Hope it helps.
Another prime lister, this one does'nt use a file and can reach 64,000,000 if you have patience. Keeps a list of prime divisors in an environment variable. If i had a batch integer square root routine i could make it faster.
#echo off
::batch prime list up to 64M by Antoni Gual
:: does not use files!!
setlocal enabledelayedexpansion
set bitmap=
set n=Y
set /a test=3,npri=3
echo 1th prime is 2 & echo 2th prime is 3
:nextpri
set /a test+=2,index=0,div=3
if %test% LSS 8000 set bitmap=%bitmap%%n%
if %test% gtr 64000000 exit /b
:nextest
if "!bitmap:~%index%,1!"=="N" goto nextdiv
set /a resi=!test!%%!div!
if %resi% equ 0 set n=N& goto nextpri
:nextdiv
set /a index+=1, div+=2
set /a div2=div*div
if %div2% gtr %test% (
set n=Y
echo %npri%th prime is %test%
set /a npri+=1
goto nextpri)
goto nextest
The following script does not perform a primality test. Rather, it generates prime numbers up to a specific bound (the hard-coded 1000 in this particular case). You could generate the list once and then use it in your script(s):
#echo off
echo 2
echo 3
echo 2 > primenos.txt
echo 3 >> primenos.txt
set current=3
:numbercalc
set tim=3
set /a max=%current%/5
:try
set /a t=%current%/%tim%
set /a u=%t%*%tim%
if %u% EQU %current% goto noprime
set /a tim+=2
if %tim% GTR %max% goto endtry
goto try
:endtry
echo %current%
echo %current% >> primenos.txt
:noprime
set /a current+=2
if %current% GTR 1000 goto end
goto numbercalc
:end
pause
Taken from here...
Assuming you have a text file with prime numbers (each number in a single line) you could do it like this:
#echo off
if "%1"=="" (echo Syntax: %~nx0 number & exit /b 2)
for /F "tokens=*" %%p in (primes.txt) do (
if %%p EQU %1 (
echo %1 is prime!
exit /b 0
)
)
echo %1 is not prime!
exit /b 1
Example call: isprime.cmd 2 would give you 2 is prime!.
Here is what I made. It finds all prime numbers up to 214748 but it is accurate and fast and outputs the results to a file called "pn.txt" and the current number to "cn.txt" (this was to let me know what its limit was):
(#echo off)&((set n=3)&((set tn=%n%)&((set d=2)&((set d2=)&((set m=100)&((echo.prime-numbers>pn.txt)&((echo. >>pn.txt)&((echo.1>>pn.txt)&((echo.2>>pn.txt)&((echo.1)&((echo.2)&(goto a))))))))))))
:a
(echo.%n%cn.txt)&((set tn=%n%)&(set tn=%n:~-1%))
(if %tn%==2 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==4 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==6 ((set /a n=%n%+1)&((set d=2%d2%)&(gotoa))))&((if %tn%==8 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==0 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(goto b)))))
:b
((set /a tn=%d%*%d%)&(if /i %tn% equ %n% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))&((if /i %tn% gtr %n% ((set tn=%n%)&((set l=%d%)&((if /i %n% equ 10000 (set d2=0))&((if /i %n% equ 100000 set (d2=00))&((set d=2%d2%)&((set m=100%d2%)&(goto d)))))))&((set /a d=%d%+1)&(goto b))
:d
(title verifing %n% at %d%)&(set tn=%n%)
set /a tn=%tn%*%m%
set /a tn=%tn%/%d%
set tn=%tn:~-2%
(if /i %tn% equ 00%d2% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(((set /a tn=%n%-1)&(if %d%==%tn% ((echo.%n%)&((echo.%n%>pn.txt)&(((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&(if %d%==%l% ((echo.%n%)&((echo.%n%>pn.txt)&((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&((set /a d=%d%+1)&(goto d)))
#echo off
::PRIMES
set multiple2=1
set add=1
set counter=1
color f0
set /p range=Computer primes 0-?:
set /a limit=(range/2)+1
set ut=3
mkdir prime0-%range%
cd prime0-%range%
echo >>2
:opipe
echo >>%ut%
set /a ut=ut+2
if %ut% GEQ %range% goto next
goto opipe
:next
set /a multiple2=multiple2+2
if %multiple2% GEQ %limit% goto end
set /a add=add+2
set /a multiple=multiple2
:process
set /a multiple=multiple+add
del %multiple%
if %multiple% GEQ %range% goto next
goto process
:end
CD ..
echo 2 >>ALLprime0-%range%.txt
:offx
set /a counter=counter+2
if exist prime0-%range%\%counter% echo %counter% >>ALLprime0-%range%.txt
if %counter% GEQ %range% goto down
goto offx
:down
echo Computation Succesful
pause
exit
::RMDIR /S /Q prime0-%range%
Please excuse me for beating a dead horse. Here is a radically differnt approach to generating primes in pure batch that overperforms everything else I have found .
It's based in Keeping a list of multiples of previous found primes around the window we're checking. The numbers not found in the list are primes. For keeping the list I use environment variables of the form #composite=next_increment .It uses a single loop, much faster and degrading slower than the nested double loop used in other algorithms. Unforunately a FOR and an auxiliar subrputine are required to overcome the impossiblilty of having repeated keys in environment, as sometimes multiples of different primes clash.
BTW the idea comes from an exerciste in Knuth's TAOCP Vol 3 page 617.
:: prime table using rotating multiples stored in environment
#echo off
setlocal enabledelayedexpansion
mode con cols=90
set #25=-10
set /a num=7,inc1=4,cnt=0,inc2=0,num1=0, maxprime=10000
set lin= 0:
call:line 2 & call:line 3 & call:line 5
:nextnum
if defined #%num% (
for %%i in (!#%num%!) do (
if %%i lss 0 (set /a num1=%num%-%%i,"inc2=-%%i<<1") else (set /a num1=%num%+%%i,"inc2=-(%%i>>1)")
call :aux !num1! !inc2!
)
set #%num%=
) else (
call :line %num%
set /a num1= num * num
if %inc1% equ 4 (set/a "inc2=num<<2") else (set /a "inc2=-(num<<1)")
if !num1! leq %maxprime% set #!num1!=!inc2!
)
set /a num+=inc1, inc1=6-inc1
if %num% lss %maxprime% goto nextnum
echo %lin%
pause & goto:eof
:aux
if %1 leq %maxprime% set #%1=%2 !#%1!
goto:eof
:line formats output in 10 right aligned columns
set num2= %1
set lin=%lin%%num2:~-8%
set /a cnt+=1,res1=(cnt%%10)
if %res1% neq 0 goto:eof
echo %lin%
set cnt1= %cnt%
set lin=%cnt1:~-5%:
goto:eof
#echo off
:top
set /p number=number:
set /a check=1
:work
set /a check=%check%+1
set /a result=%number%/%check%
set /a abc=%result%+1
if %abc% LSS %check% goto end
SET /a modulo=%number% %% %check%
IF %modulo%==0 (goto factor
) ELSE (goto notfactor
)
:factor
echo %check%
set /a other= %number%/%check%
echo %other%
echo.
goto work
:notfactor
goto work
:end
echo If you see 2 numbers this its a prime otherwise its composit
echo.
echo i am too lazy to code it further and have already spend way too much time trying to make this
pause
cls
goto top
this will also tell the prime factors if any.