Советы по игре в гольф в партии


14

Windows Batch (CMD), вероятно, является наименее подходящим языком для игры в гольф кода.

Избегайте новых символов . Если вы ищете самый короткий код в байтах, в отличие от символов, вам нужно избавиться от всех ненужных возвратов каретки (символы новой строки = 2 байта). Для этого вы можете использовать &операцию, обрезая один байт для каждой команды.

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: "

Обратите внимание, что одни и те же правила синтаксического анализа не применяются ко всем командам - ​​например, для циклов требуются пробелы. За исключением между 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 testотправьте стандартный вывод в файл с именем f, >fзапустите новую команду &и получите содержимое файла в переменной set/pa=<f. Очевидно, это не всегда полезно. Но это может быть, когда все, что вам нужно, это одна строка вывода.

Вывод команды . При подавлении вывода команды используйте @перед командами, если вам не нужно подавить более 9 команд, в этом случае используйте @echo offв начале вашего сценария. @echo offимеет длину 9 байт и, следовательно, обычно сохраняет больше байтов при использовании более длинных сценариев.

Команды часто делают больше, чем просто то, что очевидно - подумайте о том, что делают ваши команды. Например; если вам нужно установить переменную и отобразить другую переменную вместо:

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

Вы можете использовать команду set с /pпереключателем для вывода %a%за вас.

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

Полностью в гольф ...

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

Несколько примеров - подсчитать сумму всех цифр - гипотеза Гольдбаха .

Любые другие советы более чем приветствуются - я буду продолжать обновлять это, если я думаю о чем-либо еще.


16
Пожалуйста, разместите ответные части этого как ответ, а не как часть вопроса.
Не то чтобы Чарльз

@ Чарльз Я вполне уверен, что я сделал это приемлемый формат для «вопроса о совете». Другие люди могут добавлять ответы с собственными советами.
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

так что ваш код может оставаться читаемым без потери символов.

Могут быть исключения, потому что некоторые текстовые редакторы объединяют перевод строки и возврат каретки для каждой новой строки.


Я включил это в исходное сообщение, потому что в каждом текстовом редакторе, который я использую, новая строка считается за два байта. Спасибо за добавление этого разъяснения.
unclemeat

2
Перевод строки в окне возврата carraige - это два символа, и многие текстовые редакторы будут считать его двумя, но когда я впервые начал отвечать на вопросы по гольфу, в одном из оставленных комментариев говорилось, что в PPCG окончания строк всегда считаются одним символом.
Джерри Иеремия

2
Перевод строки в стиле Unix будет отлично работать в сценариях CMD, по крайней мере, в последних версиях Windows.
user2428118

1
Фактически, CMD даже удаляет символы CR перед синтаксическим
анализом

3

Напечатайте результат численного расчета напрямую

Если для выполнения задачи требуется, чтобы вы вывели число, которое необходимо вычислить, вы можете использовать его cmd/c set/aдля непосредственного вывода результата вычисления, вместо того чтобы сохранить вычисление и затем повторить его. Пример:

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

становится

@cmd/cset/a%1+%2

Изменить: Видимо, пробелы не нужны вообще, сохраняя еще 2 байта.


2

Задержка расширения

Вместо использования longy 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). Когда эта первая «команда» завершается с ошибкой ( ||), она вызывает новый экземпляр cmd, который вызывает сам пакетный файл (используется /v (on)для включения отложенного расширения и /qотключения эха). Тогда !!будет расширяться до нуля, так как нет переменной с именем <NULL>. Затем выполняется остальная часть вашего сценария. После чего он вернется к исходному экземпляру cmd и &&выйдет ( ) с /bусловием, чтобы окно оставалось открытым (выход таков, что он не продолжает проходить через ваш скрипт в контексте первого экземпляра cmd с echo включено и задержано расширение отключено).


Для этого при запуске пакетных файлов с параметром 2 cmd /q /v on /c <filename>следует учитывать только 2 байта, поскольку они представляют собой два «флага», аналогичных флагам Perl, например, -pIкоторые учитываются только как 2 дополнительных байта.
Artyer

1

Повторяющиеся строки

Установите повторяющиеся блоки кода в переменных, где количество байтов, используемых для установки переменной + количество байтов для вывода переменной, меньше, чем число байтов для прямого вызова кода.

Для примера см .: Нарисуйте комбинации, которые составляют до 100

Вы сохраняете 1 байт на использование команды set, если создаете переменную (названную одним символом, например, "s"), которая содержит 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высказываниях

Это традиционное так называемое «безопасное» ifсравнение.

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

Чтобы сократить это утверждение, сделайте следующее, если ввод может быть только буквенно-цифровым / пустым :

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

Сохранение всего 2 байта.


Проблемы, требующие выхода

Если вопрос говорит что-то вроде:

Выводит как минимум 1 видимый символ.

тогда вы можете просто сделать это:

cd

cdПоказывает текущий каталог STDOUT.


GOTOмаркировка

Вот несколько методов gotoдобавления метки, упорядоченные в порядке убывания байтов.

goto :l
goto l
goto:l

Вышеуказанный метод сохраняет 1 байт.


1
В качестве альтернативы вы можете сделать то, goto:lчто сохраняет тот же 1 байт и имеет дополнительный бонус - сохранить вашу толстую кишку нетронутой
Матеус

@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 имеет специальное значение в соответствии с некоторыми входными данными.

С уважением,
Гейб


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

Спасибо за чтение этого довольно длинного ответа, и я надеюсь, что это поможет вам. С уважением,
Гейб


Публикация нескольких ответов на вопросы с советами - это не плохо.
Эрик Outgolfer
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.