Conseils pour jouer au golf à Röda


12

Röda est un langage de script basé sur les flux créé par fergusq .

Quels conseils généraux avez-vous pour jouer au golf à Röda? Je cherche des idées qui peuvent être appliquées aux problèmes de code-golf et qui sont également au moins quelque peu spécifiques à Röda (par exemple, "supprimer les commentaires" n'est pas une réponse).

Veuillez poster un pourboire par réponse.


Essayez-vous d'obtenir des conseils pour me battre dans le golf? : P (je devrais probablement regarder les astuces pour la page Python)
HyperNeutrino

Wow, une question de PCG.SE qui est entrée dans les Hot Network Questions et qui n'est pas un puzzle / défi de programmation! :)
Pedro A

1
@HyperNeutrino Shhh .... :)
user41805

Réponses:


7

Utilisez des traits de soulignement

C'est probablement le conseil le plus important. Presque tous les programmes de golf Röda utilisent des traits de soulignement.

La syntaxe de soulignement est le sucre syntaxique pour les forboucles. Les lignes de code suivantes sont équivalentes:

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

Chaque trait de soulignement ajoute une nouvelle variable à une forboucle invisible autour de l'instruction. La boucle extrait une valeur du flux pour chaque variable / trait de soulignement, puis se répète, jusqu'à ce qu'il ne reste aucune valeur.

Les traits de soulignement peuvent être utilisés n'importe où dans les instructions:

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

Si vous devez faire référence à la même valeur de soulignement plus d'une fois ou utiliser les valeurs dans l'ordre inverse, vous pouvez mettre un nombre après le soulignement:

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

Certains points-virgules / nouvelles lignes sont facultatifs

Lors de l'écriture de code Röda, il est généralement recommandé d'utiliser des sauts de ligne ou des points-virgules pour séparer toutes les instructions. Cependant, lors du golf, il convient de savoir que tous les points-virgules ne sont pas vraiment requis.

Voici une liste incomplète des endroits où les points-virgules / nouvelles lignes sont facultatifs . La plupart d'entre eux ne sont pas applicables lorsque la déclaration suivante commence par un opérateur ( (, [, +, etc.).

  • Après les affectations
  • Après les appels de fonction, lorsqu'il y a au moins un argument (par exemple f x) ou lorsque des parenthèses sont utilisées (par exemple f())
  • Partout, si la ligne suivante / déclaration commencerait par |, ), ]ou}

Si l'instruction suivante commence par un opérateur, le point-virgule / nouvelle ligne est facultatif si

  • L'instruction est un appel de fonction et des parenthèses sont utilisées, par exemple {f(x)[y]}est la même que {f(x);[y]}. Cela ne fonctionne que dans le contexte de l'instruction, pas lorsque l'appel de fonction est une expression.
  • L'instruction est une affectation et des parenthèses sont utilisées, par exemple x=(y)[z]est identique à x=(y);[z](qui n'est pas identique à x=((y)[z])).

Et voici quelques endroits où les nouvelles lignes sont malheureusement nécessaires :

  • Après ++et --.
  • Après [...].

Il est souvent possible de sauvegarder des octets en réorganisant les affectations. Par exemple:

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

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

1

Utiliser des structures de contrôle de suffixe

Il n'est presque jamais optimal de ne pas utiliser de suffixe, comme vous pouvez le {...}remplacer do...end.

Quelques exemples:

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]

Pouvez-vous faire à la if[_ in y]place?
user41805

@KritixiLithos Non, car je veux que la condition soit OU, pas ET. Actuellement, il vérifie s'il y a au moins une valeur xqui est également dans y, mais votre condition vérifierait si toutes les valeurs dans xsont également dans y. (L'exemple a été copié à partir d'ici ).
fergusq

1

Utilisez le flux pour la saisie

Dans les cas où l'entrée est une liste d'éléments, il peut être avantageux d'extraire les valeurs du flux au lieu de les obtenir sous forme de tableau.

Dans la plupart des cas, les éléments du tableau sont itérés en les poussant vers le flux, puis en les itérant à l'aide d'une forboucle (ou d'un trait de soulignement). Comme les éléments sont de toute façon répétés à partir du flux, pourquoi ne pas définir qu'ils devraient être là depuis le début?

Par exemple, pour calculer la somme des carrés des nombres en entrée:

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

1

Les parenthèses sont facultatives dans le contexte de l'instruction. Cela s'applique même si l'argument commence par un opérateur. Par exemple, [a()|sqrt-_]est plus court que [a()|sqrt(-_)]. Les parenthèses après asont obligatoires, comme ac'est le cas dans le contexte de l'expression, pas dans le contexte de l'instruction.

Cependant, l' écriture [a()|sqrt(_+1)*2]est impossible, et les parenthèses supplémentaires sont nécessaires pour aider l'analyseur: [a()|sqrt((_+1)*2)]. Il est souvent possible de réécrire une telle expression afin qu'elle ne commence pas par une parenthèse:[a()|sqrt 2*(_+1)]


Est-il également possible de passer plusieurs paramètres aux fonctions sans nécessiter de parenthèses?
user41805

@KritixiLithos Oui. Par exemple. [a()|atan2 _,_]serait autorisé.
fergusq

1

Utiliser à la ,place des instructions ..in []/push

Connexes: utiliser ,au lieu deand

La pushfonction (ainsi que la printfonction) peut accepter n'importe quel nombre d'arguments et génère chacun d'eux sans délimiteur.

Cela signifie donc quelque chose comme ça

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

peut être raccourci en juste

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

économiser 1 octet.


1

[]/ push>print

N'utilisez jamais de printdéclarations. []les déclarations push sont toujours plus golfiques. La différence entre printet pushest que le premier produit une nouvelle ligne de fin tandis que la seconde ne le fait pas. Cependant, cela peut être contourné.

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

Utilisation de ``chaînes

Dans les ""chaînes, vous devrez échapper à certains personnages pour les utiliser. Par exemple, pour imprimer la barre oblique inverse, vous devez avoir une chaîne comme "\\". Il y a un octet supplémentaire pour échapper à la barre oblique inverse. Cependant, si vous utilisez ``, vous n'avez pas à échapper à ce caractère et pouvez enregistrer un octet.

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

Non seulement cela, vous pouvez encoder des variables et des expressions à l'intérieur des ``chaînes en utilisant $variableNameou ${expression}, une fonctionnalité non présente dans les ""chaînes.

Nous sortons la chaîne "a"concaténée avec la valeur de la variable bavec une nouvelle ligne de fin dans ces exemples.

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

1

Utiliser ,au lieu deand

Les conditions à Röda sont des flux et peuvent consister en plusieurs valeurs. Ces valeurs sont réduites à une valeur booléenne avec and.

Cela signifie que vous pouvez remplacer andpar ,dans des conditions pour envoyer plusieurs valeurs dans le flux:

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

L'état vide est vrai

Il est également possible d'avoir une condition qui ne contient aucune valeur, ce qui est vrai.

x while true
x while[]

1

Rédiger des listes de remplacement sous forme *"...;..."/";"

La replacefonction prend normalement une liste de chaînes comme arguments. Cependant, si la liste est très longue, il est avantageux de simplement stocker les paires d'expression régulière / remplacement dans une chaîne, puis de diviser la chaîne et d'utiliser l'opérateur étoile:

replace"a","b","c","d"
replace*"a;b;c;d"/";"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.