Suggerimenti per il golf a Tcl


15

Quali consigli generali hai per giocare a golf a Tcl? Sto cercando idee che possano essere applicate ai problemi del codice golf in generale che siano almeno in qualche modo specifiche per Tcl (es. "Rimuovere i commenti" non è una risposta). Si prega di inviare un suggerimento per risposta.

Risposte:


7

Usa lmapinvece foreach. Ciò richiede Tcl 8.6.

La sintassi è la stessa, ma lmaprestituisce un elenco con il risultato di ciascun ciclo.


4

Sulla mia risposta /codegolf//a/107557/29325 posso dimostrare:

  1. Di solito set j 0;while \$j<$n;{...;incr j}è più breve dell'equivalentefor {set j 0} {$j<$n} {incr j} {...}

  2. Quando la variabile di ciclo inizia da 1, possiamo fare l'incremento come parte della whilecondizione di test, evitando di scrivere prima set i 1inutilmente: while {[incr i]<=$n} {...}invece diset i 1;while \$i<=$n;{...;incr i}

ATTENZIONE : si può fare solo 2. nel caso di un anello esterno! Non ho potuto applicarlo alla mia jvariabile in quanto deve essere ripristinato a 1 all'esterno del proprio loop interno! E incr jacquisirebbe il valore impostato sull'ultimo passaggio del ciclo interno, invece di afferrare una variabile indefinitaj per assumerla 0e incrementarla 1!


4

A volte vale la pena usare time {script} ndov'è nil numero di iterazioni invece di un normale whileo forloop. Sebbene lo timescopo non sia il looping, l'effetto ottenuto è lo stesso.

Di recente ho apportato modifiche alle mie risposte seguendo questa direzione.

AGGIORNAMENTO: ho appena scoperto una trappola facile da cadere: non puoi sostituire a foro a whilecon un timeblocco, se contiene a breako a continue.


3

Usa la shell interattiva. Ciò consente di abbreviare i nomi dei comandi purché solo 1 comando inizi con le lettere rimanenti.

Esempio:

  • gets -> ge
  • lassign -> las
  • expr -> exp
  • puts -> pu

E le soluzioni interattive sono gratuite: P

Contesto :

Quando tclshviene eseguito con un terminale come dispositivo di input, imposta la variabile tcl_interactivesu 1. Ciò causa unknown(procedura predefinita che verrà chiamata se non è possibile trovare un comando) per cercare comandi che iniziano con quel nome.

Unico inconveniente: stamperà il risultato di ogni riga, utilizzare al ;posto delle nuove righe.
Ohh, e potrebbe invocare comandi esterni come w, che è una buona abbreviazione di while.


3

Sottocomandi e opzioni possono (di solito) essere abbreviati. Questo può salvare un bel po ', ma devi testare perché non tutto può essere abbreviato in questo modo ( regsuble opzioni non possono, ad esempio).

È quindi possibile utilizzare questo con la magia di namespacefare alcune cose veramente cattive. Considera questo:

namespace exp *;namespace en cr -c ?

Dopodiché, ?ora è un comando magico che ti consente di abbreviare qualsiasi comando Tcl globale, e tutto senza la cattiva incertezza di scherzare unknown.


2

Sto usando Tcl 8.0.5, ma credo che quanto segue sia applicabile a tutte le versioni recenti.

  1. Usa renameper rinominare rename:

    rename rename &
    

    La &può essere qualsiasi identificatore; &mi ricorda solo "riferimenti" in C.

  2. Usa il rinominato renameper rinominare set:

    & set =
    

    Ancora una volta, =può essere qualsiasi identificatore; =è solo intuitivo per me.

  3. Ora, rinomina altri comandi che vale la pena rinominare, ad es

    & regsub R
    & string S
    & while W
    

    Vale la pena rinominare un comando se, data la sua lunghezza n , e le occorrenze k , k (n-1) - (n + 4)> 0 . Risolvendo per k , la formula diventa k > (n+4)/(n-1). Ecco una tabella di riferimento che semplifica:

    length of       minimum         example(s)
    command         occurrences
    ------------------------------------------------
    2               6               if (consider renaming to "?")
    3               4               for, set (consider renaming to "=")
    4               3               eval, expr, incr (consider renaming to "+"), info, join, proc, puts, scan
    5               3               break, catch, lsort, split, subst, trace, unset, while
    6               3               format, lindex, lrange, regexp, regsub, rename, return, string, switch
    7               2               foreach, lappend, linsert, llength, lsearch, unknown
    .               2               lreplace
    .               2               continue
    .               2               
    
  4. Successivamente, compatti sottocomandi di uso frequente come

    = I index
    = L length
    

    così puoi fare cose come

    S $I $x 7
    S $L $x
    
  5. Qualche miscellanea ovvia:

    1. lappend può impostare il primo elemento di un elenco se non esiste ancora (non è necessario inizializzare).
    2. È possibile impostare array senza utilizzare array, ad es set doesNotExist(7) 43 .
    3. Puoi usare stringhe ( "a b c") invece di [list a b c].
    4. È possibile interpolare in stringhe in questo modo: foo${a}bar.
    5. Puoi usare two\ wordspiuttosto che "two words". (Ricorda in generale che per le stringhe contigue senza spazi, le doppie virgolette possono essere omesse!)
    6. Puoi quasi sempre riscrivere fors come whiles per salvare un carattere o due, dal momento che whilepuò controllare e incrementare simultaneamente mentre forusa blocchi separati.
  6. Per i programmi più grandi, ecco un trucco che ho pensato ma che non ho ancora applicato:

    proc unknown {c args} {eval [info commands $c*] $args}
    

    Questo emula le abbreviazioni dei comandi interattivi! Costa 54 caratteri, ma ora puoi usare jper join, spper split, stper string, wper whilee così via.


1
Se si desidera emulare abbreviazioni interattive, utilizzareinfo script {};set tcl_interactive 1
Johannes Kuhn l'

Figo, grazie! Ti ho accreditato qui . Ci sono stati alcuni problemi con quella tecnica, tuttavia, che non ho riscontrato con il unknownpercorso: vedi qui e qui .
Andrew Cheong,

La domanda richiede suggerimenti che sono in qualche modo specifici di Tcl. L'operatore ternario è incluso nei suggerimenti per tutte le lingue .
Peter Taylor,

@PeterTaylor - Grazie, ho rimosso quel suggerimento.
Andrew Cheong,

2

altrimenti è facoltativo

Come si dice nella pagina di manuale , elseè implicito nei ifcostrutti di blocco. Quindi cos'è

if ... {} else {}

può diventare

if ... {} {}

come puoi vedere in alcune delle mie risposte.


1

Potrebbe essere che dovrebbe essere integrato in un'altra risposta, ma qui va:

Quando a procha un solo parametro, può essere scritto come

proc p a {DO THINGS}

invece di

proc p {a} {DO THINGS}

Lo stesso vale per due parametri procusando una barra rovesciata; può essere scritto come

proc p a\ b {DO THINGS}

invece di

proc p {a b} {DO THINGS}

Per un numero più elevato di parametri, {}rendere il codice più breve.


1

A volte vale la pena sostituire le due setistruzioni per concatenare le stringhe con una sola lappendistruzione. Su una costruzione come, si può sostituire

set s ""

loop {
    # ...
    set s $s\X
}

di

loop {
    # ...
    append s X
}

Il appendcomando ha unincr comportamento simile, che inizializza una variabile non ancora definita.

Fare attenzione a non errore appenddalappend


1

Se stai gestendo un elenco con un'operazione che sinteticamente si interseca tra ciascun elemento, a volte puoi joinelementi per eseguire un'operazione specifica, invece di attraversarla.

Su /codegolf//a/127042/29325 c'è un esempio:

puts \n[expr [join [split [read stdin]] +]]

Si read stdin23 214 52quindi diviso darà la lista {23 214 52}. Dopo, [join {23 214 52} +]restituirà la stringa 23+214+52. Finalmente expr 23+214+52fa il lavoro di sommatoria


In questo caso, puoi omettere il split.
Johannes Kuhn,

@JohannesKuhn: grazie. Fatto.
sergiol,

1

Se hai codici di grandi dimensioni, è possibile evitare l' exprutilizzo multiplo namespace pat tcl::mathopall'inizio. Fornisce un'operazione di sintassi prefisso come una normale funzione Tcl. Per esempio:

namespace pat tcl::mathop
set sum [+ 1 2 3]
set prod [* {*}{1 2 3 4}]
puts $sum\ $prod

Vedi la pagina ufficiale di mathop doc


0

Quando sono presenti più variabili che si trovano setsu righe successive, è possibile utilizzare una lassignanziché diverseset istruzioni per ottenere lo stesso effetto.

Un esempio è la mia risposta /codegolf//a/105789/29325

Per decidere, è sufficiente ponderare il numero di variabili (assumendo variabili di 1 lettera, come previsto durante il golf):

  • <5, setè più golfista

  • = 5 sete lassigngenera lo stesso conteggio byte

  • > 5, lassignè più golfista

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.