Wskazówki dotyczące gry w golfa w Kotlinie


22

Biorąc pod uwagę niedawne ogłoszenie przez Google oficjalnej pomocy technicznej dotyczącej rozwoju Androida przez Kotlin , pomyślałem, że nadejdzie czas, aby sondować społeczność w poszukiwaniu niesamowitych wskazówek golfowych dla tego stosunkowo nowego języka JVM.

Kotlin zawiera unikalne połączenie funkcji wśród rodzeństwa JVM, co czyni go potencjalnie atrakcyjnym dla golfistów:

Jak więc wycisnąć ostatnie bajty z mojego programu Kotlin? Poproszę jedną wskazówkę na odpowiedź.


2
Czy byłoby zainteresowanie językiem golfa, który skraca niektóre z dłuższych nazw Kotlin, ale nie dodaje wielu dodatków (przynajmniej na początku)? Zastanawiam się nad zrobieniem wspólnej 1 litery, skracaniem liczby znaków w łańcuchach i dodawaniem pojedynczych liter z tylko 1 znakiem cudzysłowu?
jrtapsell

* Funkcje wspólne
jrtapsell 18.09.17

Wydaje się, że zainteresowanie golfem Kotlin nie jest aż tak duże :( data.stackexchange.com/codegolf/query/793250/top-kotlin-golfers
jrtapsell

Planuję zacząć przesyłać więcej rozwiązań Kotlin! Będę musiał także sprawdzić ten twój projekt.
Tyler MacDonell,

Odpowiedzi:


4

Funkcje rozszerzeń

Funkcje rozszerzeń mogą naprawdę pomóc w zmniejszeniu nazw metod wbudowanych i ich łańcuchów, przykładem może być:

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

ale pomaga to tylko wtedy, gdy:

A) Połączenie jest wystarczająco długie, aby anulować definicję

B) Połączenie zostanie powtórzone

Zastosowanie lambdas zamiast metod

Lambda może powrócić bez użycia słowa kluczowego return, oszczędzając bajty

KotlinGolfer

Projekt, który rozpocząłem tutaj, który pobiera ładny kod Kotlin i automatycznie podaje posty z testami i linkami TIO


4

Użyj +zamiasttoString

Jak można się spodziewać, Stringprzeciąża +operatora do konkatenacji łańcuchów, podobnie jak to.

print("Hel" + "lo")

Jednak sprawdzenie dokumentów mówi nam, że akceptuje Any?, nie tylko String. Jak wspomniano:

Zwraca ciąg uzyskany przez połączenie tego ciągu z ciągiem reprezentującym dany inny obiekt.

Innymi słowy, String + anythingupewnij się, że zadzwoniłeś .toString()po prawej stronie przed połączeniem. To pozwala nam skrócić it.toString()do ""+itogromnych oszczędności 8 bajtów w najlepszym wypadku i 6 bajtów w najgorszym.


Użyj foldzamiastjoinToString

W związku z powyższym, jeśli dzwonisz, mapa następnie joinToStringmożesz to skrócić, używając foldzamiast tego.

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

Fałdowanie TIL jest fajne
Quinn


1

Definiowanie Int w params

Prawdopodobnie będzie to miało kilka specyficznych przypadków użycia, w których może być tego warte, ale w ostatnim pytaniu, w którym grałem w golfa, stwierdziłem, że mogę zaoszczędzić kilka bajtów, definiując moją zmienną jako parametry opcjonalne zamiast definiować je w funkcji.

Przykład z mojej odpowiedzi na to pytanie:

definiowanie zmiennej w funkcji:

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

definiowanie zmiennych jako params:

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

ponieważ var a=ma taką samą długość, ponieważ a:Int=zdefiniowanie ich będzie miało taką samą liczbę bajtów (tak jest tylko w przypadku Int), ale ponieważ teraz mam tylko 1 linię w funkcji, mogę ją upuścić {}i upuszczam też jeden ;(drugi to zastąpiony przez a ,)

Więc jeśli są jakieś funkcje, które wymagają zdefiniowania Int, i byłby 1 linijką, jeśli nie zdefiniowałeś int w funkcji - wtedy wykonanie tego jako parametru pozwoli zaoszczędzić kilka bajtów


0

Funkcja toinfix

Dostępna jest standardowa funkcja poprawki, toktóra tworzy Pairs dwóch wartości. Jest powszechnie używany mapOf()do definiowania Maps, ale potencjalnie może być znacznie krótszy niż Pair()konstruktor.

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

0

Destrukcja w argumentach lambda

Powiedz, że chcesz zaakceptować Pair<*,*>lambda. Zwykle radzenie sobie z tym byłoby denerwujące. Na przykład, oto lambda, która pobiera a Pairi sprawdza, czy dwie wartości są równe:

{it.first==it.second}

To jest rozwlekłe i niezdarne. Na szczęście, Kotlin pozwala destructure wszelkiego rodzaju destructable (dowolny typ, który implementuje componentN()metody, takie jak Pair, Tripleitd.) Jako argumenty lambda. Możemy to przepisać w następujący sposób:

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

Wygląda podobnie do wzorca pasującego krotkę w czymś takim jak F # iw wielu przypadkach jest. Ale szeroka gama typów w Kotlinie wspiera destrukcję ( MatchResultjest przydatna).

Możesz wziąć więcej argumentów. Powiedz, że twoja lambda musiała przyjąć Pairdodatkową wartość. Po prostu napiszesz podpis lambda w ten sposób:

(a,b),c->  // pair first
a,(b,c)->  // pair second
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.