Quels conseils avez-vous pour jouer au golf à Lua? Je recherche des idées qui peuvent être appliquées aux problèmes de golf de code en général qui sont au moins quelque peu spécifiques à Lua (par exemple, "supprimer les commentaires" n'est pas une réponse). Veuillez poster un pourboire par réponse.
21
Réponses:
En plus de ceux déjà publiés, voici quelques astuces que j'ai rassemblées au fil du temps, sans ordre précis ...
Pour les appels de fonction qui n'ont qu'un seul paramètre délimité par un symbole (
"
pour les chaînes,{
pour les tables), le paramètre n'a pas besoin d'être entouré de parenthèses.Par exemple, au lieu de le faire
print("hello")
, vous pouvez simplement faire:print"hello"
Supprimez autant d'espaces que possible - cela est particulièrement facile à faire après un symbole qui ferme des chaînes (ou avant une ouverture), des appels de fonction, des tableaux ...
Au lieu de cela,
print(42) a=1
vous pouvez le faireprint(42)a=1
. Autre exemple:print(a and-1 or-2)
.Utilisez l'opérateur ternaire quand vous le pouvez! Au lieu de
if a>0 then print("hello") else print("goodbye") end
, préférezprint(a>0 and "hello" or "goodbye")
. Plus d'infos ici .(Cela peut effectivement faire encore mieux:
print(a>0 and"hello"or"goodbye")
)Utilisez le sucre syntaxique d'appel du côlon lorsque vous le pouvez: au lieu de
string.rep(str,12)
, faitesstr:rep(12)
. Cela fonctionne également sur les non-variables de cette façon (et uniquement de cette façon):("a"):rep(5)
Au lieu de faire
tonumber(str)
simplementstr+0
Pour les fonctions sans paramètres, au lieu de les définir de la manière habituelle (
function tick() blabla() end
), vous pouvez faireticks=loadstring"blabla()"
:, qui enregistre 1 ou plusieurs octets, selon le contenu. De plus, si vous définissez plusieurs fonctions, localisezloadstring
une variable à 1 caractère avant et vous économiserez beaucoup d'octets;). Crédits à Jim Bauwens pour cette astuce.Lua considère la chaîne vide (et
0
trop contrairement aux autres langues) comme vraie dans les tests conditionnels, donc, par exemple, au lieu de le fairewhile 1 do ... end
, économisez 1 octet en écrivantwhile''do ... end
la source
str+0
équivalent est~~str
, peut être utile pour sa prioritéJ'en ai déjà pensé un. Je ne sais pas si cela fonctionne dans d'autres langages, mais Lua est le seul que je connaisse qui vous permet de stocker des fonctions dans des variables. Donc si eg
string.sub
est utilisé plusieurs fois dans votre programme, utilisez egs=string.sub
.la source
s=("").sub
ous=a.sub
pour toute variablea
contenant une valeur de chaîne.C'est un langage assez verbeux pour le golf ... mais quelques conseils généraux qui me viennent à l'esprit sont:
if
...then
...else
...end
est un gaspillage majeur.for i=1,5 do
.#
opérateur est assez bon pour le golf (et en général).la source
Raccourcissez votre boucle infinie
Lorsque vous devez utiliser une boucle infinie, vous pouvez penser à utiliser un
while
, mais l'utilisation d'une étiquette à la place est plus courte de 2 octets:Utilisez le moins d'espace possible
Il y a une chose simple que vous pourriez (ab) utiliser pour supprimer encore plus d'espaces de votre code. Les spécifications de Lua sont claires sur le nom que vous donnez aux variables: elles doivent commencer par une lettre. Cela implique que, parfois, vous pouvez sauter des espaces entre les nombres et les fonctions / variables
La possibilité de supprimer l'espace dépend de la lettre qui suit le chiffre, voici la lettre qui ne vous permettra pas de faire ceci:
En l'utilisant et en prêtant attention à la façon dont vous appelez vos variables, vous pouvez libérer la plupart de vos codes source sans espace.
Reprenant un exemple déjà ici, et en utilisant ce conseil, voici un octet de plus que vous pouvez raser :).
Utilisez la bonne méthode de saisie
Si nous regardons le passe-partout et le coût pour chaque type principal d'entrée, voici ce que nous avons:
Chacune de cette méthode nous permet de prendre 1 entrée, la fonction étant celle qui a le coût le plus élevé (mais nous permet de prendre un tableau en entrée)
Nous pouvons maintenant voir que l'utilisation de l'argument de ligne de commande est la voie à suivre si vous voulez jouer au golf, mais sachez que cela peut être encore plus court
Les
...
sont un peu spéciaux dans lua, c'est une variable contenant le contenu décompressé dearg
, ou les paramètres décompressés dans le cas d'une fonction variadique.Lorsque vous devrez obtenir plusieurs entrées et utiliser chacune d'elles, il peut être utile de les enregistrer dans une variable. Voici quelques façons de sauvegarder 2 entrées dans des variables
et voici l'appel le plus court que vous auriez pu faire sans les variables:
À partir du moment où vous avez 3 arguments, ou lorsque vous utilisez 2 arguments, avec un utilisé deux fois, vous gagnez déjà des octets à cause de
a,b=...
! :)N'utilisez presque jamais si!
Il n'y a presque aucun cas où l'utilisation d'une instruction if / elseif / if coûtera moins cher qu'un ternaire. le passe-partout pour une telle déclaration est vraiment lourd:
Avec un exemple simple, vous économisez déjà 12 octets, quand vous devez faire des elseifs, cela devient de plus en plus important, alors soyez conscient de cela!
De plus, les ternaires à lua sont spéciaux , il y a des conditions dans leur fonctionnement, pour ceux qui sont intéressés, je l'expliquerai ci-dessous:
Les ternaires en lua sont de la forme
<condition> and <case true: have to be a true value> or <case false: can be anything>
Tout d'abord, voyons la table de vérité du
or
. Aor
peut être considéré comme une fonction: il renvoie toujours une valeur, voici la valeur qu'il renvoie:C'est ce qui nous permet de construire notre ternaire.
C'est
and
ce qui nous permet d'évaluer la condition, elle reviendra toujoursy
si la valeur estx and y
vraie.Le problème avec cela est qu'il échouera si nous voulons qu'un
nil
oufalse
soit retourné lorsque la condition estfalse
. Par exemple, ce qui suit renvoie toujours 5, bien que la condition soit vraie.Voici une évaluation étape par étape d'un ternaire pour expliquer comment cela fonctionne (il sera utile lorsque vous devrez les imbriquer :))
la source
J'ai également compilé plusieurs conseils. Je suis sûr que certains des miens chevaucheront ceux déjà mentionnés, mais je les inclurai de toute façon dans la veine de créer une réponse plus complète.
Attribuer des fonctions répétées aux variables
Lua vous permet d'assigner des fonctions aux variables. Même une variable de caractère. Cela signifie que si vous répétez la fonction
string.sub(x, y)
plus de deux fois, vous bénéficierez de son affectation à une variable.Sans attribuer à une variable (69 caractères):
Affectation à une variable (51 caractères):
Il y a des cas où vous pouvez aller encore plus loin. Lua permet à un POO de manipuler des chaînes, comme ceci:
str:sub(x, y)
oustr.sub(x, y)
Cela ouvre de nouvelles options pour notre code. Vous pouvez affecter une variable à la fonction par sa référence comme indiqué (46 caractères.)Utilisez le moyen le plus efficace pour analyser les chaînes
Vous pouvez vous retrouver à utiliser une
for
boucle etstring.sub
à itérer caractère par caractère dans Lua. Parfois, cela peut fonctionner le mieux, selon vos besoins, mais d'autres fois, string.gmatch fonctionnera en moins de caractères. Voici un exemple des deux:Et au golf, la différence est plus notable:
Restructurer les affectations pour optimiser les espaces blancs
Dans Lua, vous n'avez pas besoin de mettre un caractère espace entre des parenthèses fermées ou un guillemet de fin et le caractère suivant. Jusqu'à présent, j'ai trouvé deux cas où une restructuration dans cet esprit coupera les caractères.
Affectation de variables:
Si relevés:
Renvoie le moins de caractères possible
Si vous devez renvoyer une valeur vraie ou fausse, il semble que vous devez nécessairement utiliser au moins 5 caractères pour la valeur de retour. En réalité, les travaux suivants fonctionnent tout aussi bien:
la source
nil
et lafalse
valeur false dans Lua, tout le reste est vrai, pour que vos conseils sur le remplacementx==0
,x==""
etx==''
parx
est faux. Je le change actuellement ennil
:).Ce ne sont que des optimisations Lua (je pense):
Les chaînes sont automatiquement converties en nombres lorsque vous effectuez des opérations arithmétiques sur elles. Attention aux instructions conditionnelles, elles ne se convertissent pas automatiquement. C'est idéal pour prendre les entrées utilisateur sous forme de nombres tout en économisant de l'espace.
La commutation du contenu de deux variables ne nécessite pas de variable temporaire.
a,b=b,a
permutera les valeurs de a et b.De plus, pour prolonger ce qui a été dit ci-dessus, tout caractère alphanumérique peut toucher un caractère non alphanumérique. Il en
a,b=io.read():match"(.+)/(.+)"u,v=a,b
va de même pour un script parfait et fonctionnel, même en l'absence d'espace.la source
Combiner les affectations de variables locales
Au lieu de:
Utiliser l'affectation parallèle:
6 octets enregistrés pour chaque variable!
Déclarer des variables locales via des paramètres de fonction inutilisés
Au lieu de:
Utilisation
6 octets enregistrés (moins 1 à 2 octets pour chaque variable pouvant être dupliquée).
la source
local
est justifiée lors du golf, car il suffit d'utiliser un nom différent. Nous pourrions utiliser TOUS les noms jusqu'à 7 caractères ET tables avec des index de chaîne jusqu'à 7 combinaisons de caractères avant de toucher quelque chose qui pourrait bénéficier de l'utilisation des locauxFonctions variadiques
La principale fonction variadique qui vous dérangera est
print()
. Par exemple, lorsque vous l'utilisez,String.gsub()
il affichera la chaîne que vous avez modifiée ET le nombre degsub
déclenchements.Pour supprimer cette deuxième sortie, encapsulez votre
gsub
in parens pour la forcer à renvoyer une seule valeurla source
Savoir comment sortir
Il y a deux méthodes principales de sortie dans lua
Lorsque vous devez concaténer plusieurs fois, vous pouvez raccourcir cela en utilisant
io.write()
assigné à une variable d'une lettre au lieu de l'opérateur de concaténation standard..
Vous gagnez 2 octets à chaque appel tout en payant d'avance
Vous êtes même à la troisième concaténation et commencez à gagner des octets à la quatrième.
la source
print
et nonprintf
!Un tas de conseils sans ordre particulier:
string
est un nom assez long. Efficacement,('').char
c'est la même chose questring.char
. Des résultats encore meilleurs peuvent être obtenus si vous l'utilisez avec un point-virgule sur les variables:,a=...; print(a:sub(1, 5))
mais certainesstring
fonctions ne prennent pas de chaînes en entrée.tonumber
et+0
souvent ne gaspille que des octets.load'your function code here'
au lieu defunction()your function code here end
. Accédez aux arguments de la fonction en utilisant...
inside.a:gsub('.',load'my function')
semble être le moyen le plus court pour parcourir les caractères d'une chaînea:find('.',1,1)
(pour tester ce problème, essayez d'inclure%
à divers endroits dans votre entrée et consultez les résultats). D'innombrables idées ont éclaté à cause de Lua essayant d'analyser l'entrée comme modèle.nil
est de trois octets,_
est un (c'est juste un nom aléatoire qui n'existe probablement pas). De plus, tout chiffre fonctionnera comme une valeur véridique.x and i or o
. Ce n'est pas seulement un opérateur ternaire - c'est une expression logique complète. En fait, cela signifie ce qui suit: "six
c'est vrai, essayezi
. Si x ou i est faux, retournez o". Donc, si cei
n'est pas vrai, le résultat l'esto
. En outre, les deuxand
ouor
peuvent être supprimés parties (x and i
,x or o
).math.floor
:5.3//1==5.0
. Veuillez noter que le nombre résultant suit toujours le type d'entrée un (entier / flottant).la source