O Windows Batch (CMD) é provavelmente o idioma menos adequado para o golfe com código.
Evite caracteres de nova linha . Se você estiver procurando pelo código mais curto em bytes, em vez de caracteres, desejará se livrar de todos os retornos de carro desnecessários (caracteres de nova linha = 2 bytes). Você pode usar a &
operação para fazer isso, aparando um byte para cada comando.
echo Hello&echo World.
Definindo variáveis . Ao definir variáveis usando opções, o set
analisador ignorará os espaços.
set /a a+=1
set /p b="User Input: "
:: Will be handled the same as..
set/aa+=1
set/pb="User Input: "
Observe que as mesmas regras do analisador não se aplicam a todos os comandos - como um exemplo, pois os loops requerem espaços. Exceto entre set, string, or command
(ou seja, o que está dentro dos colchetes) e a palavra do
.
for /f %%a in (file.txt)do ...
Expressões matemáticas simples . Além disso, observe a expressão que eu usei para incrementar no set /a
comando. Para expressões matemáticas simples, use em += -= *= /=
vez de (por exemplo) set /a a=%a%+1
.
Reunindo saída de comando . Para obter a saída de um comando, às vezes pode ser útil enviar e ler um arquivo, onde você poderia ter usado um loop for para reunir a saída:
for /f %%a in ('echo test') do set a=%%a
:: Can be shortened to
echo test>f&set/pa=<f
echo test
envie stdout para um arquivo chamado f, >f
inicie um novo comando &
e obtenha o conteúdo do arquivo em uma variável set/pa=<f
. Obviamente, isso nem sempre é útil. Mas pode ser quando tudo que você precisa é de uma única linha de saída.
Saída de comando . Ao suprimir a saída do comando, use @
antes dos comandos, a menos que você precise suprimir mais de 9 comandos; nesse caso, use @echo off
no início do seu script. @echo off
tem 9 bytes de comprimento e, portanto, geralmente salva mais bytes com scripts mais longos.
Os comandos geralmente fazem mais do que apenas o óbvio - pense no que seus comandos estão fazendo. Por exemplo; se você precisar definir uma variável e repetir outra variável, em vez de:
set a=OUTPUT
echo %a%
echo test>f
set /p b=<f
Você pode usar o comando set com a /p
opção de saída %a%
para você.
set a=OUTPUT
echo test>f
set /p b=%a%<f
Completamente jogado ...
set a=OUTPUT&echo test>f&set/pb=%a%<f
Um par de exemplos - Contagem da soma de todos os dígitos - conjectura de Goldbach .
Quaisquer outras dicas são mais do que apreciadas - continuarei atualizando isso se pensar em outra coisa.
Respostas:
Contadores
Sempre que você tiver uma variável que atuará como um contador a partir de
0
você, poderá escrever; no entanto, você pode eliminar as primeiras linhas porque sempre que
set/a
é usado com uma variável não definida, seu valor é assumido como0
Blocos de código
Existem várias maneiras de economizar alguns bytes quando precisar usar blocos de código.
Sempre que você abre um bloco de código, não é necessário inserir uma quebra de linha antes da primeira linha de código nesse bloco. Os parênteses de fechamento também não precisam estar em uma linha própria.
pode ser jogado golfe para
Imprimindo sem rastrear nova linha
O padrão comum para isso é
mas você pode salvar 2 bytes mudando
echo
paracd
fonte
if
declaração pode ser mais aprofundada. O melhor deve ser:if %a%==%b% (echo true)else echo false
E comercial
Embora & faça com que o código pareça mais curto, ele usa menos linhas, mas usa tantos caracteres quanto uma nova linha. Isso significa que
é contanto que
para que seu código fique legível sem desperdiçar caracteres.
Pode haver exceções, porque alguns editores de texto combinam o avanço de linha e o retorno de carridge para cada nova linha.
fonte
Imprimir diretamente o resultado de um cálculo numérico
Se o desafio exigir que você forneça um número que precise ser calculado, use-o
cmd/c set/a
para enviar diretamente o resultado do cálculo, em vez de salvar o cálculo e repeti-lo. Exemplo:torna-se
Editar: Aparentemente, nenhum espaço é necessário, economizando mais 2 bytes.
fonte
Expansão atrasada
Em vez de usar o longo,
setLocal enableDelayedExpansion
você pode usarcmd /v on
(oucmd/von
) o que iniciará um novo intérprete com a expansão variável atrasada ativada.Ainda tenho que implementar isso para não ter exemplos, mas você pode usá-lo em conjunto com o
/c
switch. Exemplo:Observe o uso do quilate antes do e comercial. se você precisar usar vários "e" comercial ou qualquer outro caractere especial, é melhor incluir tudo depois da
/c
mudança entre aspas:Esse método também tem a vantagem de ter que usar apenas um
@
caractere para mascarar todas as entradas e, portanto, pode ser usado, sem/von
, como uma alternativa mais curta a@echo off
(ou vários@
símbolos).9 caracteres:
@echo off
6 caracteres:
@cmd/c
Para scripts mais longos, que você não pode executar em uma linha, faça o seguinte para salvar alguns bytes:
Ou ungolfed:
Substitua
@echo off&setLocal enableDelayedExpansion
pelo acima.Quando você executa o script pela primeira vez,
!!
ele não será expandido, então você recebe um erro porque"!!"
não é um comando. A saída de erro é então canalizada para nul (2>nul
). Quando esse primeiro 'comando' falha (||
), ele chama uma nova instância do cmd, que chama o próprio arquivo em lotes (usando/v (on)
para ativar a expansão atrasada e/q
desativar o eco). Em seguida!!
, expandirá para nada, pois não há variável chamada<NULL>
. O restante do seu script é executado. Depois disso, ele retornará à instância original do cmd e (&&
) sairá com a/b
condição de manter a janela aberta (a saída é para que ele não continue a executar seu script no contexto da primeira instância do cmd, com echo expansão atrasada).fonte
cmd /q /v on /c <filename>
deve contar apenas como 2 bytes, porque são dois "sinalizadores" semelhantes aos sinalizadores Perl, como os-pI
que contariam apenas como 2 bytes extras.Sequências repetitivas
Defina blocos de código repetitivo em variáveis, em que o número de bytes usados para definir a variável + o número de bytes para gerar a variável são menores que o número de bytes para chamar apenas o código diretamente.
Por exemplo, consulte: Desenhe as combinações que somam até 100
Você salva 1 byte por uso do comando set, se criar uma variável (nomeada com um caractere, como "s") que contenha
set<space>
. Isso gera valor apenas se você usar o comando set mais de 12 vezes. (Observe que há um caractere no final da stringset s=set
).O acima é 1 byte menor que ..
Provavelmente, este é um exemplo muito ruim - mas é claro.
fonte
Início de uma string
A notação
%var:~start,end%
extrai uma substring da variávelvar
. No entanto, sestart
for0
, você pode omiti-lo completamente. Já sabemos que você pode omitir,end
se quiser o restante da string, o que faz com que seja%var:~%
um sinônimo quase inútil%var%
, exceto que ele retorna~
quando%var%
está vazio. (Talvez você possa usá-lo em um testeif %var:~%==~
:?)fonte
Encurtando
IF EQU
declaraçõesUsar em
==
vez deequ
salva 3 bytes.Encurtar citações em
IF
declaraçõesEssa é uma comparsão tradicional chamada "mais segura"
if
.Para encurtar esta declaração, faça o seguinte quando a entrada puder ser apenas alfanumérica / vazia :
Salvando um total de 2 bytes.
Desafios que exigem resultados
Se a pergunta disser algo como:
então você poderia fazer isso:
O
cd
mostra o diretório atual paraSTDOUT
.GOTO
um rótuloAqui estão alguns métodos para
goto
inserir um rótulo, ordenados em ordem decrescente de bytes.O método acima salva 1 byte.
fonte
goto:l
o que economiza o mesmo 1 byte e tem a vantagem adicional de manter seu cólon intactoOmitindo espaço entre comando e parâmetros com barras
Desculpe pelo título pouco informativo. O que estou tentando entender é que, para alguns (não todos) comandos do Windows, você pode omitir o espaço entre o nome do comando / programa e o parâmetro, desde que esse parâmetro comece com uma barra. Por exemplo:
torna-se
-1 Byte!
Saída da tubulação em vez de usar ERRORLEVEL
Usar ERRORLEVEL para determinar se um comando foi executado corretamente não é o método mais curto ou mais elegante. Em vez disso, você pode canalizar a saída. Isso funciona da seguinte maneira (lembre-se de que qualquer comando após o
&&
operador é executado apenas se o comando for&&
executado sem erros. Qualquer comando após o||
operador, por outro lado, será executado apenas se o comando antes NÃO for executado corretamente. Meu exemplo é :Isso pode ser substituído por:
-26 Bytes, uau! Observe que isso não funciona com comandos como
choice
, onde ERRORLEVEL possui um valor especial de acordo com alguma entrada.Atenciosamente,
Gabe
fonte
Usando parênteses efetivamente
Oi de novo,
Desculpe postar uma segunda resposta, mas achei que essa merecia. Percebi que as pessoas costumam usar um dos métodos a seguir para exibir a saída do comando sem exibir a
C:\Windows\System32>echo foo
linha traquina antes de cada comando.O primeiro método (usando
echo off
):O segundo método:
No entanto, nenhum desses métodos é tão curto quanto o seguinte:
Muito útil, certo? Em outra nota, isso pode ser usado para canalizar várias linhas de saída para um arquivo ou dispositivo facilmente. Por exemplo, este código longo:
torna-se significativamente mais curto:
Obrigado por ler esta resposta bastante longa, e espero que isso ajude você. Atenciosamente,
Gabe
fonte