Suggerimenti per giocare a golf in serie


14

Windows Batch (CMD) è probabilmente la lingua meno adatta per giocare a golf.

Evita i caratteri di nuova riga . Se stai cercando il codice più breve in byte, al contrario dei caratteri, ti consigliamo di eliminare tutti i ritorni a capo non necessari (caratteri di nuova riga = 2 byte). È possibile utilizzare l' &operazione per fare ciò, tagliando un byte per ciascun comando.

echo Hello&echo World.

Impostazione delle variabili . Quando si impostano le variabili utilizzando gli switch, il setparser ignorerà gli spazi.

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

Si noti che le stesse regole del parser non si applicano a tutti i comandi - ad esempio, per i loop richiedono spazi. Tranne tra set, string, or command(cioè ciò che è dentro le parentesi) e la parola do.

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

Espressioni matematiche semplici . Inoltre, nota l'espressione che ho usato per incrementare il set /acomando. Per semplici espressioni matematiche utilizzare += -= *= /=invece di (ad esempio) set /a a=%a%+1.

Raccolta del comando in uscita . Per ottenere l'output di un comando, a volte può essere utile l'output e la lettura da un file, dove altrimenti si sarebbe potuto usare un ciclo for per raccogliere l'output:

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

echo testinvia stdout a un file chiamato f, >favvia un nuovo comando &e ottieni il contenuto del file in una variabile set/pa=<f. Ovviamente questo non è sempre utile. Ma può essere quando tutto ciò che serve è una singola linea di output.

Uscita comando . Quando si sopprime l'output dei comandi, utilizzare @prima dei comandi, a meno che non sia necessario eliminare più di 9 comandi, nel qual caso, utilizzare @echo offall'inizio dello script. @echo offè lungo 9 byte e pertanto generalmente salverà più byte con script più lunghi.

I comandi spesso fanno molto di più di ciò che è ovvio : pensa a cosa stanno facendo i tuoi comandi. Per esempio; se è necessario impostare una variabile ed eseguire l'eco di un'altra variabile, anziché:

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

È possibile utilizzare il comando set con l' /popzione per l'output %a%per te.

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

Completamente golf ...

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

Un paio di esempi - Conta la somma di tutte le cifre - La congettura di Goldbach .

Tutti gli altri suggerimenti sono più che apprezzati: continuerò ad aggiornarlo se penso ad altro.


16
Si prega di inviare le parti di risposta come una risposta, non come parte della domanda.
Non che Charles, il

@Charles Sono abbastanza sicuro di come ho fatto questo è un formato accettabile per una "domanda suggerimenti". Altre persone possono aggiungere risposte con suggerimenti propri.
salato

Risposte:


4

contatori

Ogni volta che hai una variabile che fungerà da contatore a partire da 0potresti voler scrivere

set count=0
set/acount+=1

; tuttavia, è possibile eliminare le prime righe poiché ogni volta che set/aviene utilizzato con una variabile non impostata si presume che il suo valore sia0

set/acounter+=1

Blocchi di codice

Esistono diversi modi in cui è possibile radere alcuni byte quando è necessario utilizzare blocchi di codice.

Ogni volta che si apre un blocco di codice, non è necessario inserire un'interruzione di riga prima della prima riga di codice in quel blocco. Le parentesi di chiusura non devono necessariamente trovarsi su una linea propria.

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

può essere giocato a golf

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

Stampa senza seguire la nuova riga

Lo schema comune per questo è

echo|set/p=text

ma è possibile salvare 2 byte cambiando echoincd

cd|set/p=text

2
@ ankp-morpork Ehi, sono un po 'in ritardo. Ma voglio informarti che la ifdichiarazione può essere ulteriormente approfondita. Il migliore dovrebbe essere:if %a%==%b% (echo true)else echo false
stevefestl,

3

ampersands

Sebbene 's faccia sembrare il codice più breve, poiché usa meno righe, usa altrettanti caratteri come una nuova riga. Ciò significa che

echo a&echo b

è lungo quanto

echo a
echo b

così il tuo codice può rimanere leggibile senza sprecare caratteri.

Potrebbero esserci delle eccezioni perché alcuni editor di testo combinano avanzamento riga e ritorno a capo per ogni nuova riga.


L'ho incluso nel post originale perché una nuova riga conta due byte in ogni editor di testo che uso. Grazie per aver aggiunto questo chiarimento.
unclemeat

2
L'allineamento di ritorno del carraige di Window è di due caratteri e molti editor di testo lo contano come due, ma quando ho iniziato a rispondere alle domande sul golf uno dei commenti lasciati diceva che in PPCG i finali di riga vengono sempre conteggiati come un carattere.
Jerry Jeremiah,

2
Gli avanzamenti di riga in stile Unix funzioneranno perfettamente negli script CMD, almeno nelle versioni recenti di Windows.
user2428118

1
In realtà, CMD rimuove anche i caratteri CR prima di parsing: stackoverflow.com/questions/4094699/...
schnaader

3

Stampa direttamente il risultato di un calcolo numerico

Se la sfida richiede l'output di un numero che deve essere calcolato, è possibile utilizzare cmd/c set/aper emettere direttamente il risultato del calcolo invece di salvare il calcolo e riecheggiarlo. Esempio:

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

diventa

@cmd/cset/a%1+%2

Modifica: apparentemente non sono necessari spazi, risparmiando altri 2 byte.


2

Espansione ritardata

Invece di usare il long setLocal enableDelayedExpansionpuoi usare cmd /v on(o cmd/von) che avvierà un nuovo interprete con l'espansione variabile ritardata abilitata.

Devo ancora implementarlo, quindi non ho alcun esempio, ma potresti usarlo insieme allo /cswitch. Esempio:

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

Notare l'uso del carato prima della e commerciale. se è necessario utilizzare più e commerciali o altri caratteri speciali, potrebbe essere meglio racchiudere tutto /ctra virgolette:

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

Questo metodo ha anche il vantaggio di dover usare un solo @carattere per mascherare tutti gli input e può quindi essere usato, senza /von, come alternativa più breve a @echo off(o più @simboli).

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

Per script più lunghi, che non è possibile eseguire su una riga, è possibile effettuare le seguenti operazioni per salvare alcuni byte:

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

Oppure, non golfato:

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

Sostituire @echo off&setLocal enableDelayedExpansioncon quanto sopra.

Quando esegui per la prima volta il tuo script !!non si espande affatto, quindi ricevi un errore perché "!!"non è un comando. L'output dell'errore viene quindi reindirizzato a nul ( 2>nul). Quando questo primo 'comando' fallisce ( ||), chiama una nuova istanza di cmd, che chiama il file batch stesso (usando /v (on)per abilitare l'espansione ritardata e /qdisattivare l'eco). Quindi !!si espanderà a nulla, in quanto non vi è alcuna variabile chiamata <NULL>. Il resto dello script viene quindi eseguito. Dopodiché tornerà all'istanza originale di cmd e ( &&) esce con la /bcondizione di mantenere aperta la finestra (l'uscita è quindi non continua a scorrere lo script nel contesto della prima istanza cmd, con echo on e ritardata espansione off).


Per questo, l'esecuzione di file batch con cmd /q /v on /c <filename>dovrebbe contare solo come 2 byte perché sono due "flag" simili ai flag Perl come quelli -pIche contano solo come 2 byte extra.
Artyer,

1

Stringhe ripetitive

Imposta blocchi di codice ripetitivi nelle variabili, in cui il numero di byte utilizzati per impostare la variabile + il numero di byte per generare la variabile sono inferiori al numero di byte per chiamare direttamente il codice.

Per un esempio, vedi: Disegna le combinazioni che aggiungono fino a 100

Si salva 1 byte per utilizzo del comando set, se si crea una variabile (denominata con un carattere, come "s") che contiene set<space>. Questo genera valore solo se si utilizza il comando set più di 12 volte. (Nota che c'è un carattere alla fine della stringa 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

Quanto sopra è 1 byte più corto di ..

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

Questo è probabilmente un esempio piuttosto scarso - ma ottiene il punto.


1

Inizio di una stringa

La notazione %var:~start,end%estrae una sottostringa della variabile var. Comunque se startè 0così puoi ometterlo del tutto. Sappiamo già che puoi omettere ,endse vuoi il resto della stringa, il che rende %var:~%un sinonimo quasi inutile %var%, tranne per il fatto che ritorna ~quando %var%è vuoto. (Forse potresti usarlo in un test if %var:~%==~:?)


Mi piace la tua ultima frase che ci ricorda che questo salverà alcune citazioni :) +1 per quello.
stevefestl,

1

IF EQUDichiarazioni di accorciamento

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

Usando ==invece di equ salva 3 byte.


Accorciamento delle citazioni nelle IFdichiarazioni

Questa è una tradizionale ifcomparazione cosiddetta "più sicura" .

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

Per abbreviare questa affermazione, procedere come segue quando l'input può essere solo alfanumerico / vuoto :

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

Salvataggio di un totale di 2 byte.


Sfide che richiedono risultati

Se la domanda dice qualcosa del tipo:

Emette almeno 1 carattere visibile.

allora potresti semplicemente fare questo:

cd

La cdmostra la directory corrente STDOUT.


GOTOing un'etichetta

Ecco alcuni metodi per gotocreare un'etichetta, ordinati in ordine decrescente di byte.

goto :l
goto l
goto:l

Il metodo sopra riportato consente di salvare 1 byte.


1
In alternativa, potresti fare ciò goto:lche salva lo stesso 1 byte e ha il vantaggio di mantenere intatti i tuoi due punti
Matheus Avellar

@MatheusAvellar: ho aggiunto il contenuto di conseguenza al tuo commento
stevefestl

1

Omettere lo spazio tra comando e parametri con barre

Mi dispiace per il titolo non informativo. Quello che sto cercando di ottenere è che per alcuni (non tutti) comandi di Windows, puoi omettere lo spazio tra il nome del comando / programma e il parametro, purché quel parametro inizi con una barra. Per esempio:

for /f %%G in ...

diventa

for/f %%G in ...

-1 byte!

Piping output invece di utilizzare ERRORLEVEL

L'uso di ERRORLEVEL per determinare se un comando è stato eseguito correttamente non è il metodo più breve o più elegante. Invece, è possibile reindirizzare l'output. Funziona come segue (ricorda che qualsiasi comando dopo l' &&operatore viene eseguito solo se il comando prima dell'esecuzione è stato &&eseguito senza errori. Qualsiasi comando dopo l' ||operatore, invece, verrà eseguito solo se il comando precedente non è stato eseguito correttamente. Il mio esempio è :

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

Questo potrebbe essere sostituito con:

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

-26 byte, wow! Si noti che questo non funziona con comandi come choice, in cui ERRORLEVEL ha un valore speciale secondo alcuni input.

Saluti,
Gabe


1

Usare le parentesi in modo efficace

Ciao di nuovo,

Mi dispiace pubblicare una seconda risposta, ma ho pensato che questa meritasse. Ho notato che le persone usano spesso uno dei seguenti metodi per visualizzare l'output del comando senza visualizzare quella fastidiosa C:\Windows\System32>echo fooriga prima di ogni comando.
Il primo metodo (usando echo off):

@echo off
echo foo
echo bar
echo foobar
echo barfoo

Il secondo metodo:

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

Tuttavia, nessuno di questi metodi è breve quanto il seguente:

@(echo foo
echo bar
echo foobar
echo barfoo)

Molto utile, vero? In un'altra nota, questo può essere usato per convogliare facilmente più linee di output in un file o dispositivo. Ad esempio, questo lungo codice:

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

diventa significativamente più breve:

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

Grazie per aver letto questa risposta piuttosto lunga, e spero che questo ti aiuti. Saluti,
Gabe


Pubblicare più risposte alle domande sui suggerimenti non è male.
Erik the Outgolfer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.