Suggerimenti per il golf a Röda


12

Röda è un linguaggio di scripting basato su stream creato da fergusq .

Quali consigli generali hai per giocare a golf a Röda? Sto cercando idee che possano essere applicate a problemi di code-golf e che siano almeno in qualche modo specifiche per Röda (ad esempio "rimuovere i commenti" non è una risposta).

Si prega di inviare un suggerimento per risposta.


Stai cercando consigli per battermi nel golf? : P (dovrei probabilmente dare un'occhiata ai suggerimenti per la pagina di Python)
HyperNeutrino,

Wow, una domanda di PCG.SE che è entrata nelle Domande sulla rete calda e non è un puzzle / sfida di programmazione! :)
Pedro A

1
@HyperNeutrino Shhh .... :)
user41805

Risposte:


7

Usa trattini bassi

Questo è probabilmente il consiglio più importante. Quasi tutti i programmi golf Röda utilizzano caratteri di sottolineatura.

La sintassi di sottolineatura è lo zucchero sintattico per i forloop. Le seguenti righe di codice sono equivalenti:

ls""|fileLength x for x|sort|pull
ls""|fileLength _|sort|pull

Ogni carattere di sottolineatura aggiunge una nuova variabile a un forciclo invisibile attorno all'istruzione. Il ciclo estrae un valore dallo stream per ogni variabile / carattere di sottolineatura e quindi si ripete, fino a quando non rimangono più valori.

I trattini bassi possono essere usati ovunque nelle dichiarazioni:

a[x:y+1]=[1]*(1+y-x) /* Sets range x..y (inclusive) */
seq x,y|a[_]=1       /* 6 bytes less */

Se è necessario fare riferimento allo stesso valore di sottolineatura più di una volta o utilizzare i valori in ordine inverso, è possibile inserire un numero dopo il trattino di sottolineatura:

a|[_^_1]  /* maps x to x^x */
a|[_2-_1] /* maps each pair (x,y) to y-x, eg. [1,2,4,8] -> [1, 4] */

3

Alcuni punti e virgola / nuove righe sono facoltativi

Quando si scrive il codice Röda, si consiglia generalmente di utilizzare nuove righe o punti e virgola per separare tutte le istruzioni. Tuttavia, quando si gioca a golf, vale la pena sapere che non tutti i punti e virgola sono realmente richiesti.

Ecco un elenco incompleto di luoghi in cui i punti e virgola / le nuove righe sono facoltativi . La maggior parte di loro non si applicano quando il seguente dichiarazione inizia con un operatore ( (, [, +, etc.).

  • Dopo incarichi
  • Dopo le chiamate di funzione, quando è presente almeno un argomento (ad es. f x) O quando vengono utilizzate le parentesi (ad es. f())
  • Ovunque, se la prossima linea di / affermazione sarebbe cominciare |, ), ]o}

Se la dichiarazione successiva inizia con un operatore, il punto e virgola / newline è facoltativo se

  • L'istruzione è una chiamata di funzione e vengono utilizzate le parentesi, ad esempio {f(x)[y]}è uguale a {f(x);[y]}. Funziona solo nel contesto dell'istruzione, non quando la chiamata di funzione è un'espressione.
  • L'istruzione è un incarico e vengono utilizzate le parentesi, ad esempio x=(y)[z]è uguale a x=(y);[z](che non è uguale a x=((y)[z])).

E qui ci sono alcuni luoghi in cui purtroppo le newline sono richieste :

  • Dopo ++e --.
  • Dopo [...].

Spesso è possibile salvare byte riorganizzando le assegnazioni. Per esempio:

a=0;b=""c=[""]
b=""c=[b]a=0

x=f()y=i;z=a[0]
x=f()z=a[0]y=i

1

Usa strutture di controllo suffisso

Non è quasi mai ottimale non usare le istruzioni suffisso, come si può usare {...}al posto di do...end.

Qualche esempio:

x|unless[not(_ in y)]do[0]else[1]done
x|[0]unless[not(_ in y)]else[1]

if[p<0]do c+=p;a-=p done
{c+=p;a-=p}if[p<0]

Puoi fare if[_ in y]invece?
user41805

@KritixiLithos No, perché voglio che la condizione sia OR, non AND. Attualmente controlla se c'è almeno un valore in xquello che è anche in y, ma la tua condizione controlla se ci sono anche tutti i valori xin y. (L'esempio è stato copiato da qui ).
fergusq,

1

Usa lo stream per l'input

Nei casi in cui l'input è un elenco di elementi, può essere utile estrarre i valori dallo stream anziché ottenerli come array.

Nella maggior parte dei casi, gli elementi dell'array vengono ripetuti spingendoli nel flusso e quindi ripetendolo utilizzando un forciclo (o un trattino basso). Dato che gli elementi vengono ripetuti dallo stream, perché non definire che dovrebbero essere presenti dall'inizio?

Ad esempio, per calcolare la somma dei quadrati dei numeri in input:

{|a|a|[_^2]|sum} /* Removing a redundant argument */
{[_^2]|sum}      /* saves 5 bytes */

1

Le parentesi sono opzionali nel contesto dell'istruzione. Questo vale anche se l'argomento inizia con un operatore. Ad esempio, [a()|sqrt-_]è più breve di [a()|sqrt(-_)]. Le parentesi dopo asono obbligatorie, come anel contesto dell'espressione, non nel contesto dell'istruzione.

Tuttavia, la scrittura [a()|sqrt(_+1)*2]non è possibile, e sono necessari parentesi in più per aiutare il parser: [a()|sqrt((_+1)*2)]. Spesso è possibile riscrivere tale espressione in modo che non inizi con una parentesi:[a()|sqrt 2*(_+1)]


È anche possibile passare più parametri alle funzioni senza richiedere parentesi?
user41805,

@KritixiLithos Sì. Per esempio. [a()|atan2 _,_]sarebbe permesso.
Fergusq,

1

Utilizzare ,invece di ..in []/ pushistruzioni

Correlati: utilizzare ,invece diand

La pushfunzione (così come la printfunzione) può accettare un numero qualsiasi di argomenti e genera ciascuno di essi senza delimitatore.

Quindi questo significa qualcosa del genere

["a"..b]        /*8 bytes (string "a" concatenated with variable b)*/

può essere abbreviato in giusto

["a",b]         /*7 bytes*/

risparmio di 1 byte.


1

[]/ push>print

Non usare mai le printdichiarazioni. []le dichiarazioni push sono sempre più golfistiche. La differenza tra printe pushè che il primo genera una nuova riga finale mentre il secondo no. Tuttavia, questo può essere eluso.

print"a"              /* 8 bytes */
["a                   /* 6 bytes; uses a literal newline */
"]

print"a",b            /* 10 bytes */
[`a$b                 /* 8 bytes; uses a literal newline and `` strings */
`]

1

Usando le ``stringhe

Nelle ""stringhe dovrai sfuggire a determinati personaggi per usarli. Ad esempio, per stampare la barra rovesciata, dovresti avere una stringa come "\\". C'è un byte aggiunto per sfuggire alla barra rovesciata. Tuttavia, se si utilizza ``, non è necessario uscire da questo carattere e è possibile salvare un byte.

print"\\"     /* 9 bytes */
print`\`      /* 8 bytes */

Non solo, puoi codificare variabili ed espressioni all'interno delle ``stringhe usando $variableNameo ${expression}, una funzione non presente nelle ""stringhe.

In questi esempi stiamo producendo la stringa "a"concatenata con il valore della variabile bcon una nuova riga finale.

["a",b,"      /* 11
"]               bytes   */
[`a$b         /* 8
`]               bytes; encodes b in the string using $b */

1

Usa ,invece diand

Le condizioni in Röda sono flussi e possono essere costituite da più valori. Questi valori sono ridotti a un valore booleano con and.

Ciò significa che è possibile sostituire andcon ,in condizioni per inviare più valori allo stream:

x if[a and b]
x if[a,b]

La condizione vuota è vera

È anche possibile avere una condizione che non contiene valori, il che è vero.

x while true
x while[]

1

Scrivi elenchi di sostituzione nel modulo *"...;..."/";"

La replacefunzione prende normalmente un elenco di stringhe come argomenti. Tuttavia, se l'elenco è molto lungo, è utile semplicemente memorizzare le coppie regex / sostituzione in una stringa e quindi dividere la stringa e utilizzare l'operatore stella:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
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.