Suggerimenti per il golf a Kotlin


22

Dato il recente annuncio di Google del supporto ufficiale di Kotlin per lo sviluppo di Android, ho pensato che sarebbe stato opportuno sondare la community per alcuni fantastici consigli sul golf per questo relativamente nuovo linguaggio JVM.

Kotlin include una combinazione unica di funzionalità tra i suoi fratelli JVM che lo rende potenzialmente attraente per il golf:

Quindi, come posso spremere gli ultimi byte dal mio programma Kotlin? Un consiglio per risposta, per favore.


2
Ci sarebbe interesse per un linguaggio di golf che accorcia alcuni dei nomi più lunghi di Kotlin, ma non aggiunge molti extra (almeno inizialmente)? Sto pensando di creare una lettera comune, di ridurre il numero di caratteri e di aggiungere stringhe di una sola lettera con solo 1 virgoletta?
jrtapsell,

* Funzioni comuni
jrtapsell,

Sembra che l'interesse per il golf di Kotlin non sia così alto :( data.stackexchange.com/codegolf/query/793250/top-kotlin-golfers
jrtapsell,

Ho intenzione di iniziare a presentare più soluzioni Kotlin! Dovrò controllare anche quel tuo progetto.
Tyler MacDonell,

Risposte:


4

Funzioni di estensione

Le funzioni di estensione possono davvero aiutare a ridurre i nomi dei metodi incorporati e le loro catene, un esempio potrebbe essere:

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

ma questo aiuta solo se:

A) La chiamata è abbastanza lunga per annullare la definizione

B) La chiamata viene ripetuta

Uso di lambda piuttosto che metodi

Lambdas può tornare senza usare la parola chiave return, salvando i byte

KotlinGolfer

Un progetto che ho iniziato qui che prende un bel codice Kotlin e fornisce automaticamente post con test e collegamenti TIO


4

Usa +invece ditoString

Come ci si potrebbe aspettare, Stringsovraccarica l' +operatore per la concatenazione di stringhe, in questo modo.

print("Hel" + "lo")

Tuttavia, controllare i documenti ci dice che accetta Any?, non solo String. Come dichiarato:

Restituisce una stringa ottenuta concatenando questa stringa con la rappresentazione di stringa dell'altro oggetto specificato.

In altre parole, String + anythingassicurati di chiamare .toString()sul lato destro prima di concatenare. Questo permette di accorciare it.toString()a ""+it, una massiccia 8 byte risparmio al meglio e 6 byte nella peggiore.


Usa foldinvece dijoinToString

In relazione a quanto sopra, se stai chiamando mape quindi joinToString, puoi accorciarlo utilizzando foldinvece.

list.map{it.repeat(3)}.joinToString("")
list.fold(""){a,v->a+v.repeat(3)}

TIL fold è una cosa carina
Quinn


1

Definizione di Int in parametri

Questo probabilmente avrà alcuni casi d'uso piuttosto specifici in cui potrebbe valerne la pena, ma in una domanda recente ho scoperto che avrei potuto salvare qualche byte definendo la mia variabile come parametri opzionali piuttosto che definirli nella funzione.

Esempio dalla mia risposta a questa domanda:

definizione della variabile nella funzione:

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

definire le variabili come parametri:

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

perché ha var a=la stessa lunghezza in a:Int=quanto sarà lo stesso numero di byte per definirli (questo è solo il caso per Int) tuttavia dato che ora ho solo 1 riga nella funzione posso rilasciare {}e anche rilasciare un singolo ;(l'altro è sostituito con a ,)

Quindi, se ci sono delle funzioni che richiedono la definizione di un Int, e sarebbe una linea 1 se non si definisce l'int nella funzione - quindi farlo come parametro salverà un paio di byte


0

La tofunzione infix

Esiste una funzione di infissione standard denominata toche crea Pairs di due valori. È comunemente usato con mapOf()per la definizione di Maps ma può potenzialmente essere molto più breve del Pair()costruttore.

Pair(foo,bar)   //constructor
foo to bar      //best case 
(foo)to(bar)
((foo)to(bar))  //worst case

0

Ristrutturazione in argomenti lambda

Di 'che vuoi accettare a Pair<*,*>in a lambda. Normalmente, gestirlo sarebbe fastidioso. Ad esempio, ecco un lambda che prende a Paire controlla se i due valori sono uguali:

{it.first==it.second}

Questo è prolisso e goffo. Fortunatamente, Kotlin ti consente di destrutturare qualsiasi tipo distruttibile (qualsiasi tipo che implementa componentN()metodi, come Pair, Tripleecc.) Come argomenti per un lambda. Quindi, possiamo riscriverlo nel modo seguente:

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

Sembra simile al modello che abbina una tupla in qualcosa come F #, ed è in molti casi. Ma un'ampia varietà di tipi in Kotlin supporta la destrutturazione ( MatchResultè utile).

Puoi prendere più argomenti, però. Supponiamo che la tua lambda abbia dovuto assumere un Pairvalore aggiuntivo. Dovresti semplicemente scrivere la firma lambda in questo modo:

(a,b),c->  // pair first
a,(b,c)->  // pair second
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.