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
Несколько примеров - подсчитать сумму всех цифр - гипотеза Гольдбаха .
Любые другие советы более чем приветствуются - я буду продолжать обновлять это, если я думаю о чем-либо еще.
Ответы:
Счетчики
Всякий раз, когда у вас есть переменная, которая будет действовать как счетчик, начиная с,
0
вы можете написать; однако вы можете исключить первые строки, потому что всякий раз, когда
set/a
используется неустановленная переменная, предполагается, что ее значение равно0
Кодовые блоки
Есть несколько способов уменьшить количество байт, когда вам приходится использовать блоки кода.
Всякий раз, когда вы открываете блок кода, вам не нужно вставлять разрыв строки перед первой строкой кода в этом блоке. Закрывающие скобки не обязательно должны быть в отдельной строке.
может быть в гольф
Печать без ведомой новой строки
Общий шаблон для этого
но, вы можете сохранить 2 байта изменения
echo
вcd
источник
if
заявление может быть дополнено. Лучшим должен быть:if %a%==%b% (echo true)else echo false
Амперсанды
Хотя & делает код более коротким, поскольку он использует меньше строк, он использует столько же символов, сколько и символ новой строки. Это означает, что
так долго, как
так что ваш код может оставаться читаемым без потери символов.
Могут быть исключения, потому что некоторые текстовые редакторы объединяют перевод строки и возврат каретки для каждой новой строки.
источник
Напечатайте результат численного расчета напрямую
Если для выполнения задачи требуется, чтобы вы вывели число, которое необходимо вычислить, вы можете использовать его
cmd/c set/a
для непосредственного вывода результата вычисления, вместо того чтобы сохранить вычисление и затем повторить его. Пример:становится
Изменить: Видимо, пробелы не нужны вообще, сохраняя еще 2 байта.
источник
Задержка расширения
Вместо использования longy
setLocal enableDelayedExpansion
вы можете использоватьcmd /v on
(илиcmd/von
), который запустит новый интерпретатор с включенным отложенным расширением переменной.Я еще не реализовал это, поэтому у меня нет примеров, но вы можете использовать это вместе с
/c
коммутатором. Пример:Обратите внимание на использование карата перед амперсандом. если вам нужно использовать несколько амперсандов или любые другие специальные символы, лучше заключить все
/c
в кавычки после переключателя:Этот метод также имеет преимущество, заключающееся в том, что для
@
маскировки всего ввода используется только один символ , и поэтому его можно использовать без/von
более короткой альтернативы@echo off
(или нескольких@
символов).9 символов:
@echo off
6 символов:
@cmd/c
Для более длинных скриптов, которые вы не можете сделать в одной строке, вы можете сделать следующее, чтобы сохранить несколько байтов:
Или, не одураченный
Заменить
@echo off&setLocal enableDelayedExpansion
на вышеуказанное.При первом запуске ваш скрипт
!!
вообще не будет расширяться, поэтому вы получите ошибку, потому что"!!"
это не команда. Вывод ошибки затем передается в nul (2>nul
). Когда эта первая «команда» завершается с ошибкой (||
), она вызывает новый экземпляр cmd, который вызывает сам пакетный файл (используется/v (on)
для включения отложенного расширения и/q
отключения эха). Тогда!!
будет расширяться до нуля, так как нет переменной с именем<NULL>
. Затем выполняется остальная часть вашего сценария. После чего он вернется к исходному экземпляру cmd и&&
выйдет ( ) с/b
условием, чтобы окно оставалось открытым (выход таков, что он не продолжает проходить через ваш скрипт в контексте первого экземпляра cmd с echo включено и задержано расширение отключено).источник
cmd /q /v on /c <filename>
следует учитывать только 2 байта, поскольку они представляют собой два «флага», аналогичных флагам Perl, например,-pI
которые учитываются только как 2 дополнительных байта.Повторяющиеся строки
Установите повторяющиеся блоки кода в переменных, где количество байтов, используемых для установки переменной + количество байтов для вывода переменной, меньше, чем число байтов для прямого вызова кода.
Для примера см .: Нарисуйте комбинации, которые составляют до 100
Вы сохраняете 1 байт на использование команды set, если создаете переменную (названную одним символом, например, "s"), которая содержит
set<space>
. Это только генерирует значение, если вы используете команду set более 12 раз. (Обратите внимание, что в конце строки есть символset s=set
).Выше 1 байт короче, чем ..
Вероятно, это довольно плохой пример - но он все понял.
источник
Начало строки
Обозначение
%var:~start,end%
извлекает подстроку переменнойvar
. Однако еслиstart
есть,0
то вы можете опустить его полностью. Мы уже знаем, что вы можете опустить,,end
если вы хотите остаток строки, что делает%var:~%
практически бесполезным синонимом, за%var%
исключением того, что он возвращает,~
когда%var%
пусто. (Возможно, вы могли бы использовать его в тестеif %var:~%==~
:?)источник
Сокращенные
IF EQU
заявленияИспользование
==
вместоequ
сохранения 3 байта.Сокращение цитат в
IF
высказыванияхЭто традиционное так называемое «безопасное»
if
сравнение.Чтобы сократить это утверждение, сделайте следующее, если ввод может быть только буквенно-цифровым / пустым :
Сохранение всего 2 байта.
Проблемы, требующие выхода
Если вопрос говорит что-то вроде:
тогда вы можете просто сделать это:
cd
Показывает текущий каталогSTDOUT
.GOTO
маркировкаВот несколько методов
goto
добавления метки, упорядоченные в порядке убывания байтов.Вышеуказанный метод сохраняет 1 байт.
источник
goto:l
что сохраняет тот же 1 байт и имеет дополнительный бонус - сохранить вашу толстую кишку нетронутойПропуск пространства между командой и параметрами с косой чертой
Извините за неинформативный заголовок. Я пытаюсь понять, что для некоторых (не всех) команд Windows вы можете пропустить пробел между именем команды / программы и параметром, если этот параметр начинается с косой черты. Например:
становится
-1 байт!
Вывод трубопровода вместо использования ERRORLEVEL
Использование ERRORLEVEL для определения правильности выполнения команды - не самый короткий и не самый элегантный метод. Вместо этого вы можете передавать данные по конвейеру. Это работает следующим образом (помните, что любая команда после
&&
оператора выполняется только в том случае, если команда перед&&
запуском без ошибок. С||
другой стороны, любая команда после оператора будет выполняться только в том случае, если команда до этого НЕ выполнялась должным образом. Мой пример :Это можно заменить на:
-26 байт, вау! Обратите внимание, что это не работает с такими командами, как
choice
, где ERRORLEVEL имеет специальное значение в соответствии с некоторыми входными данными.С уважением,
Гейб
источник
Эффективное использование скобок
Привет еще раз,
Извините, что опубликовал второй ответ, но я чувствовал, что этот заслужил это. Я заметил, что люди часто используют один из следующих методов для отображения вывода команды без отображения этой надоедливой
C:\Windows\System32>echo foo
строки перед каждой командой.Первый способ (с использованием
echo off
):Второй метод:
Однако ни один из этих методов не является таким коротким, как следующие:
Довольно удобно, правда? С другой стороны, это можно легко использовать для передачи нескольких строк вывода в файл или устройство. Например, этот длинный код:
становится значительно короче:
Спасибо за чтение этого довольно длинного ответа, и я надеюсь, что это поможет вам. С уважением,
Гейб
источник