배치 골프를위한 팁


14

CMD (Windows Batch)는 코드 골프에 가장 적합한 언어 일 것입니다.

개행 문자를 피하십시오 . 문자와 달리 가장 짧은 코드를 바이트 단위로 찾으려면 불필요한 캐리지 리턴 (줄 바꿈 문자 = 2 바이트)을 모두 제거해야합니다. 이 &작업을 수행하여 각 명령에 대해 1 바이트를 트리밍 할 수 있습니다 .

echo Hello&echo World.

변수 설정 . 스위치를 사용하여 변수를 설정하면 set파서는 공백을 무시합니다.

set /a a+=1
set /p b="User Input: "
:: Will be handled the same as..
set/aa+=1
set/pb="User Input: "

예를 들어 for 루프에는 공백이 필요한 동일한 구문 분석기 규칙이 모든 명령에 적용되지는 않습니다. set, string, or command(즉, 괄호 안에있는 것)과 단어 사이는 제외합니다 do.

for /f %%a in (file.txt)do ...

간단한 수학적 표현 . 또한 set /a명령 에서 증분에 사용한 표현식을 확인하십시오 . 간단한 수학 표현식의 경우 += -= *= /=(예를 들어) 대신 사용하십시오 set /a a=%a%+1.

명령 출력 수집 . 명령의 출력을 얻으려면 때로는 파일을 출력하고 파일에서 읽는 것이 유용 할 수 있습니다. 그렇지 않으면 for 루프를 사용하여 출력을 수집했을 수 있습니다.

for /f %%a in ('echo test') do set a=%%a
:: Can be shortened to
echo test>f&set/pa=<f

echo teststdout을 f라는 파일로 보내고 >f새 명령을 시작한 &다음 파일의 내용을 변수로 가져옵니다 set/pa=<f. 분명히 이것이 항상 유용한 것은 아닙니다. 그러나 필요한 것은 한 줄의 출력 일 때도 가능합니다.

명령 출력 . 명령 출력 @을 억제 할 때는 9 개 이상의 명령 을 억제해야하는 경우가 아니면 명령 시작 전에 사용 하십시오 .이 경우 @echo off스크립트 시작시 사용 하십시오. @echo off는 9 바이트 길이이므로 일반적으로 더 긴 스크립트로 더 많은 바이트를 저장합니다.

명령은 종종 명백한 것 이상 을 수행합니다. 명령이 수행하는 작업에 대해 생각하십시오. 예를 들어; 변수를 설정하고 다른 변수를 에코해야하는 경우 :

set a=OUTPUT
echo %a%
echo test>f
set /p b=<f

/p스위치 와 함께 set 명령을 사용하여 출력 %a%할 수 있습니다.

set a=OUTPUT
echo test>f
set /p b=%a%<f

완전 골프 ...

set a=OUTPUT&echo test>f&set/pb=%a%<f

expamples의 몇 - 모든 숫자의 합계를 계산 - 골드 바흐의 추측 .

다른 팁은 고맙게 생각합니다. 다른 것을 생각하면 계속 업데이트하겠습니다.


16
이 부분의 답변 부분을 질문의 일부가 아닌 답변으로 게시하십시오.
— 찰스

@Charles 나는 이것이 어떻게했는지에 대해 '팁 질문'에 적합한 형식이라고 확신합니다. 다른 사람들은 자신의 팁으로 답변을 추가 할 수 있습니다.
— unclemeat

답변:


4

카운터

당신이 변수가 될 때마다 그에서 시작하는 카운터 역할을합니다 0당신이 쓰기에 할 수 있습니다

set count=0
set/acount+=1

; 그러나 set/a설정되지 않은 변수와 함께 사용될 때마다 그 값은 다음과 같이 가정 되기 때문에 첫 번째 줄을 제거 할 수 있습니다0

set/acounter+=1

코드 블록

코드 블록을 사용해야 할 때 몇 바이트를 줄일 수있는 여러 가지 방법이 있습니다.

코드 블록을 열 때마다 해당 블록의 첫 번째 코드 줄 앞에 줄 바꿈을 삽입하지 않아도됩니다. 닫는 괄호는 자체 줄에있을 필요는 없습니다.

If %a%==%b% (
     echo true
) else (
    echo false
)

골프를 칠 수있다

If %a%==%b% (echo true)else (echo false)

줄 바꿈없이 인쇄

이것에 대한 일반적인 패턴은

echo|set/p=text

하지만, 당신은 2 바이트가 변경 절약 할 수 있습니다 echo에cd

cd|set/p=text

2
@ ankp-morpork 안녕하세요, 조금 늦었습니다. 그러나 나는 그 if진술이 더 골프화 될 수 있음 을 알려 드리고자합니다 . 가장 좋은 것은 :if %a%==%b% (echo true)else echo false
— stevefestl

3

앰퍼샌드

&는 코드를 더 짧게 보이게하지만 줄이 적을수록 줄 바꿈만큼 많은 문자를 사용합니다. 이것은

echo a&echo b

만큼

echo a
echo b

따라서 문자를 낭비하지 않고도 코드를 읽을 수 있습니다.

일부 텍스트 편집기는 줄 바꿈과 캐리지 리턴을 새 줄마다 결합하기 때문에 예외가있을 수 있습니다.


사용하는 모든 텍스트 편집기에서 줄 바꿈이 2 바이트로 계산되므로 원본 게시물에 이것을 포함 시켰습니다. 이 설명을 추가해 주셔서 감사합니다.
— unclemeat

2
Window의 carraige 리턴 줄 바꿈은 두 문자이며 많은 텍스트 편집기는 두 문자로 계산하지만 골프 질문에 대답하기 시작했을 때 왼쪽 의견 중 하나는 PPCG 줄 끝이 항상 하나의 문자로 계산된다고 말했습니다.
— Jerry Jeremiah

2
유닉스 스타일의 줄 바꿈은 적어도 최신 버전의 Windows에서는 CMD 스크립트에서 잘 작동합니다.
— user2428118

1
사실, CMD는 심지어 구문 분석하기 전에 CR 문자를 제거합니다 stackoverflow.com/questions/4094699/...
— schnaader

3

숫자 계산 결과를 직접 인쇄

챌린지에서 계산해야하는 숫자를 출력해야하는 경우 다음을 사용할 수 있습니다. cmd/c set/a 을 저장 한 다음 에코하는 대신 계산 결과를 직접 출력하는 데 . 예:

@set/a a=%1+%2
@echo %a%

된다

@cmd/cset/a%1+%2

편집 : 분명히 공백이 필요하지 않으므로 2 바이트가 더 절약됩니다.


2

지연 확장

오래 사용하는 대신 setLocal enableDelayedExpansion사용할 수 있습니다 cmd /v on(또는cmd/von 지연 변수 확장 활성화와 새로운 인터프리터를 시작하는을).

아직 구현하지 않았으므로 예제가 없지만 /c스위치 와 함께 사용할 수 있습니다 . 예:

@cmd/von/cset test=test^&echo !test!

앰퍼샌드 전에 캐럿을 사용하십시오. 여러 앰퍼샌드 또는 다른 특수 문자를 사용해야하는 경우에는 /c스위치 뒤의 모든 것을 따옴표로 묶는 것이 좋습니다 .

@cmd/von/c"set test=test&set test1=test1&echo !test! !test1!"

이 방법은 또한 하나의 @문자 만 사용 하여 모든 입력 을 마스킹 해야하는 이점이 있으므로 (또는 여러 기호)에 /von대한 더 짧은 대안으로 없이 사용할 수 있습니다 .@echo off@

9 자 : @echo off
6 자 :@cmd/c

한 줄로 할 수없는 더 긴 스크립트의 경우 다음을 수행하여 일부 바이트를 저장할 수 있습니다.

@!! 2>nul||cmd/q/v/c%0&&exit/b

또는 골퍼하지 않은 경우 :

@!! 2>nul || cmd /q /v on /c %0 && exit/b

@echo off&setLocal enableDelayedExpansion위의 내용으로 교체하십시오 .

처음 실행할 때 스크립트 !!가 전혀 확장 "!!"되지 않으므로 명령이 아니기 때문에 오류가 발생 합니다. 그런 다음 오류 출력이 nul ( 2>nul) 로 파이프됩니다 . 이 첫 번째 'command'가 실패하면 ( ||), 배치 파일 자체를 호출하는 cmd의 새 인스턴스를 호출합니다 ( /v (on)확장 지연을 활성화하고 /q에코를 끄는 데 사용). 그러면 !!이라는 변수가 없으므로 아무것도 확장되지 않습니다 <NULL>. 그런 다음 나머지 스크립트가 실행됩니다. 그런 다음 cmd의 원래 인스턴스로 돌아가고 ( &&) /b창을 열어 두는 조건으로 종료합니다 (종료하면 첫 번째 cmd 인스턴스의 컨텍스트에서 echo를 사용하여 스크립트를 계속 실행하지 않습니다) 켜고 지연 확장 지연).


이를 위해 배치 파일을 실행하는 cmd /q /v on /c <filename>것은 2 바이트로만 계산해야 -pI합니다. 이는 2 개의 여분 바이트로만 계산되는 Perl 플래그와 비슷한 "플래그"와 유사하기 때문 입니다.
— Artyer

1

반복적 인 문자열

변수에 반복 코드 블록을 설정하십시오. 변수를 설정하는 데 사용 된 바이트 수 + 변수를 출력하는 바이트 수가 코드를 직접 호출하는 바이트 수보다 적습니다.

예를 들어, 최대 100을 더하는 조합 그리기를 참조하십시오.

를 포함하는 변수 ( "s"와 같은 하나의 문자로 이름이 지정된)를 만들면 set 명령 사용 당 1 바이트를 저장 set<space>합니다. set 명령을 12 번 이상 사용하는 경우에만 값을 생성합니다. 문자열 끝에 문자가 set s=set있습니다.

set s=set 
%s%a=1
%s%b=2
%s%c=3
%s%d=4
%s%e=5
%s%f=6
%s%g=7
%s%h=8
%s%i=9
%s%j=10
%s%k=11
%s%l=12
%s%m=13

위의 바이트는 1 바이트보다 짧습니다.

set a=1
set b=2
set c=3
set d=4
set e=5
set f=6
set g=7
set h=8
set i=9
set j=10
set k=11
set l=12
set m=13

이것은 아마도 좋지 않은 예일 것입니다.


1

문자열의 시작

표기법 %var:~start,end%은 변수의 하위 문자열을 추출합니다 var. 그러나 start이다 0당신은 완전히 생략 할 수 있습니다. 우리는 이미 당신은 생략 할 수 있다는 것을 알고 ,end당신이 만드는 문자열의 나머지하려는 경우 %var:~%에 거의 쓸모 동의어 %var%가 반환을 제외 ~하면 %var%빈입니다. (아마도 테스트에서 사용할 수 있습니다 : if %var:~%==~?)


나는 마지막 문장이 우리에게 이것을 인용하여 :) +1을 절약 할 것임을 상기시켜줍니다.
— stevefestl

1

단축 IF EQU진술

if %a% equ %b% do_something
if %a%==%b% do_something

사용 ==대신하여 equ 저장 3 바이트.


따옴표 단축 IF명세서

이것은 전통적인 소위 "safer"비교 if입니다.

if "%a%"=="%b%" do_something

이 문장을 줄이려면 입력이 영숫자 / 비어 있을 수있을 때 다음을 수행하십시오 .

if %a%.==%b%. do_something

총 2 바이트 저장


출력이 필요한 과제

질문에 다음과 같은 내용이 나오는 경우 :

하나 이상의 보이는 문자를 출력합니다.

그럼 당신은 이것을 할 수 있습니다 :

cd

는 cd현재 디렉토리를 보여줍니다 STDOUT.


GOTO라벨링

다음 goto은 바이트를 내림차순으로 정렬 한 레이블 을 작성 하는 몇 가지 방법입니다 .

goto :l
goto l
goto:l

위의 방법은 1 바이트를 저장 합니다.


1
또는 당신이 할 수있는 goto:l같은 1 바이트를 저장하는 하고 그대로 당신의 결장 유지의 추가 보너스가
— 마테우스 Avellar을

나는 당신의 의견에 따라 내용을 추가 한 : @MatheusAvellar
— stevefestl

1

슬래시로 명령과 매개 변수 사이의 공백 생략

정보가없는 제목에 대해 죄송합니다. 내가 얻으려고하는 것은 일부 (전부는 아님) Windows 명령의 경우 매개 변수가 슬래시로 시작하는 한 명령 / 프로그램 이름과 매개 변수 사이의 공백을 생략 할 수 있다는 것입니다. 예를 들면 다음과 같습니다.

for /f %%G in ...

된다

for/f %%G in ...

-1 바이트!

ERRORLEVEL을 사용하는 대신 배관 출력

ERRORLEVEL을 사용하여 명령이 올바르게 실행되었는지 확인하는 것이 가장 짧거나 가장 우아한 방법은 아닙니다. 대신 출력을 파이프 할 수 있습니다. 이것은 다음과 같이 작동합니다 (&& 오퍼레이터가 실행되기 전에 명령이 &&오류없이 실행 된 경우에만 운영자 . ||반면, 운영자 이후의 모든 명령 은 명령이 제대로 실행되지 않은 경우에만 실행됩니다). :

net session>nul
if %errorlevel%==0 (echo 1) else (echo 0)

이것은 다음으로 대체 될 수 있습니다.

net session>nul&&echo 1||echo 0

-26 바이트,와! 다음과 같은 명령에서는 작동하지 않습니다.choice ERRORLEVEL이 일부 입력에 따라 특별한 값을 갖는 곳 .

감사합니다,
Gabe


1

괄호를 효과적으로 사용하기

다시 안녕하세요

두 번째 답변을 게시하여 죄송하지만이 답변이 필요하다고 느꼈습니다. 사람들은 종종 C:\Windows\System32>echo foo각 명령 앞에 성가신 줄 을 표시하지 않고 다음 방법 중 하나를 사용하여 명령 출력을 표시합니다 .
첫 번째 방법 (사용 echo off) :

@echo off
echo foo
echo bar
echo foobar
echo barfoo

두 번째 방법 :

@echo foo
@echo bar
@echo foobar
@echo barfoo

그러나 이러한 방법 중 어느 것도 다음과 같이 짧지 않습니다.

@(echo foo
echo bar
echo foobar
echo barfoo)

아주 편리 하죠? 다른 말로, 이것은 여러 줄의 출력을 파일이나 장치에 쉽게 파이프하는 데 사용될 수 있습니다. 예를 들어이 긴 코드는 다음과 같습니다.

echo foo>file.txt
echo bar>file.txt
echo foobar>file.txt
echo barfoo>file.txt

상당히 짧아집니다 :

(echo foo
echo bar
echo foobar
echo barfoo)>file.txt

이 긴 답변을 읽어 주셔서 감사합니다. 이것이 도움이 되었기를 바랍니다. 감사합니다,
Gabe


팁 질문에 여러 답변을 게시 해도 나쁘지 않습니다.
— Outgolfer Erik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.