Conseils pour jouer au golf à Kotlin

22

Compte tenu de l'annonce récente par Google de la prise en charge officielle de Kotlin pour le développement Android, j'ai pensé qu'il serait peut-être opportun d'interroger la communauté pour obtenir des conseils de golf impressionnants pour ce langage JVM relativement nouveau.

Kotlin comprend une combinaison unique de fonctionnalités parmi ses frères et sœurs JVM, ce qui le rend potentiellement attrayant pour le golf:

Alors, comment puis-je extraire les derniers octets de mon programme Kotlin? Un conseil par réponse, s'il vous plaît.

Tyler MacDonell
la source
2
Y aurait-il un intérêt pour une langue de golf qui raccourcit certains des noms plus longs de Kotlin, mais n'ajoute pas beaucoup d'extras (au moins initialement)? Je songe à créer une lettre commune, à raccourcir le nombre de caractères de chaîne et à ajouter des chaînes à une seule lettre avec un seul guillemet?
jrtapsell
* Fonctions communes
jrtapsell
Il semble que l'intérêt pour le golf à Kotlin ne soit pas si élevé :( data.stackexchange.com/codegolf/query/793250/top-kotlin-golfers
jrtapsell
Je prévois de commencer à soumettre plus de solutions Kotlin! Je devrai également vérifier ce projet.
Tyler MacDonell

Réponses:

4

Fonctions d'extension

Les fonctions d'extension peuvent vraiment aider à réduire les noms des méthodes intégrées et leurs chaînes, un exemple pourrait être:

fun String.c() = this.split("").groupingBy{it}.eachCount()

mais cela n'aide que si:

A) L'appel est suffisamment long pour annuler la définition

B) L'appel est répété

Utilisation de lambdas plutôt que de méthodes

Lambdas peut retourner sans utiliser le mot clé return, économisant des octets

KotlinGolfer

Un projet que j'ai commencé ici qui prend du joli code Kotlin et donne automatiquement des publications avec des tests et des liens TIO

jrtapsell
la source
4

Utiliser +au lieu detoString

Comme on pouvait s'y attendre, Stringsurcharge l' +opérateur pour la concaténation de chaînes, comme ceci.

print("Hel" + "lo")

Cependant, la vérification des documents nous indique qu'il accepte Any?, pas seulement String. Comme indiqué:

Renvoie une chaîne obtenue en concaténant cette chaîne avec la représentation sous forme de chaîne de l'autre objet donné.

En d'autres termes, String + anythingassurez-vous d'appeler .toString()sur le côté droit avant de concaténer. Cela nous permet de raccourcir it.toString()à ""+it, une économie massive de 8 octets au mieux et 6 octets au pire.


Utiliser foldau lieu dejoinToString

En relation avec ce qui précède, si vous appelez mappuis joinToString, vous pouvez raccourcir cela en utilisant à la foldplace.

list.map{it.repeat(3)}.joinToString("")
list.fold(""){a,v->a+v.repeat(3)}
escargot_
la source
TIL fold est une chose, sympa
Quinn
1

Définition des Int dans les paramètres

Cela aura probablement des cas d'utilisation assez spécifiques où cela peut valoir la peine, mais dans une question récente, j'ai joué au golf, j'ai trouvé que je pouvais économiser quelques octets en définissant ma variable en tant que paramètres facultatifs plutôt qu'en les définissant dans la fonction.

Exemple de ma réponse à cette question:

définition de variable dans la fonction:

fun String.j()={var b=count{'-'==it}/2;var a=count{'/'==it};listOf(count{'o'==it}-a,a-b,b)}

définir des variables comme paramètres:

fun String.j(b:Int=count{'-'==it}/2,a:Int=count{'/'==it})=listOf(count{'o'==it}-a,a-b,b)

car var a=est de la même longueur que a:Int=ce sera le même nombre d'octets pour les définir (ce n'est que le cas pour Int) mais comme je n'ai plus qu'une ligne dans la fonction, je peux supprimer la {}et je supprime également une seule ;(l'autre est remplacé par a ,)

Donc, s'il y a des fonctions qui nécessitent de définir un Int, et serait un liner si vous n'avez pas défini l'int dans la fonction - le faire en tant que paramètre économisera quelques octets

Quinn
la source
0

La tofonction infixe

Il existe une fonction d'infixe standard nommée toqui crée Pairs de deux valeurs. Il est couramment utilisé avec mapOf()pour définir Maps, mais il peut potentiellement être beaucoup plus court que le Pair()constructeur.

Pair(foo,bar)   //constructor
foo to bar      //best case 
(foo)to(bar)
((foo)to(bar))  //worst case
escargot_
la source
0

Déstructuration dans les arguments lambda

Dites que vous voulez accepter un Pair<*,*>dans un lambda. Normalement, gérer cela serait ennuyeux. À titre d'exemple, voici un lambda qui prend un Pairet vérifie si les deux valeurs sont égales:

{it.first==it.second}

C'est de longue haleine et maladroit. Heureusement, Kotlin vous permet de détruire tout type destructible (tout type qui implémente des componentN()méthodes, telles que Pair, Tripleetc.) comme arguments d'un lambda. Nous pouvons donc réécrire ceci de la manière suivante:

{(a,b)->a==b}

Il ressemble à un motif correspondant à un tuple dans quelque chose comme F #, et il l'est dans de nombreux cas. Mais une grande variété de types dans Kotlin prennent en charge la déstructuration ( MatchResultest utile.)

Vous pouvez cependant prendre plus d'arguments. Supposons que votre lambda doive prendre une Pairvaleur supplémentaire. Vous écririez simplement la signature lambda comme ceci:

(a,b),c->  // pair first
a,(b,c)->  // pair second
escargot_
la source