Поради щодо гольфу в Котліні


22

Зважаючи на нещодавнє оголошення Google про офіційну підтримку Котліна для розробки Android, я подумав, що може бути вчасно опитати громаду щодо деяких приголомшливих порад з гольфу щодо цієї відносно нової мови JVM.

Котлін включає унікальне поєднання можливостей серед своїх братів і сестер JVM, що робить його потенційно привабливим для гри в гольф:

Отже, як я видавлю останні кілька байтів із своєї програми «Котлін»? Будь ласка, одна порада на відповідь.


2
Чи буде інтерес до мови для гри в гольф, яка скорочує деякі довші назви Котліна, але не додає багато додаткових принаймні (принаймні спочатку)? Я думаю про те, щоб зробити загальну 1 букву, зробити короткий підрахунок рядків і додати рядки з однієї літери лише з 1 лапкою?
jrtapsell

* Загальні функції
jrtapsell

Здається, інтерес до гольф Котлін не такий високий :( data.stackexchange.com/codegolf/query/793250/top-kotlin-golfers
jrtapsell

Планую почати надсилати більше рішень Kotlin! Мені доведеться перевірити і твій проект.
Тайлер МакДонлл

Відповіді:


4

Функції розширення

Функції розширення дійсно можуть допомогти зменшити імена вбудованих методів та ланцюгів їх, прикладом може бути:

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

але це допомагає лише в тому випадку, якщо:

A) Виклик досить довгий, щоб скасувати визначення

В) Дзвінок повторюється

Використання лямбдів, а не методів

Лямбди можуть повертатися, не використовуючи ключове слово return, зберігаючи байти

KotlinGolfer

Проект я почав тут , який займає досить код Котлін і дає повідомлення з тестами і TIO посилання автоматично


4

Використовуйте +замістьtoString

Як можна було очікувати, Stringперевантажує +оператора для конкатенації рядків.

print("Hel" + "lo")

Однак перевірка документів говорить нам, що вона приймає Any?, а не просто String. Як зазначено:

Повертає рядок, отриманий шляхом об'єднання цієї рядки з представленням рядка даного іншого об'єкта.

Іншими словами, String + anythingобов'язково зателефонуйте .toString()в праву частину перед тим, як об'єднатися. Це дозволяє нам скоротити it.toString()до ""+itзначної економії 8 байт у кращому випадку та 6 байтів у гіршому випадку.


Використовуйте foldзамістьjoinToString

Зв'язане з вищезазначеним, якщо ви телефонуєте mapі потім joinToString, ви можете скоротити це, скориставшись foldнатомість.

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

TIL складка - річ, приємно
Квінн


1

Визначення Int у парамах

Можливо, це матиме досить специфічні випадки використання, коли це, можливо, того варто, але в недавньому питанні, в якому я займався гольфом, я виявив, що можу зберегти кілька байт, визначивши свою змінну як необов'язкові параметри, а не визначаючи їх у функції.

Приклад з моєї відповіді на це питання:

визначення змінної у функції:

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

визначення змінних як парами:

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

тому що var a=така ж довжина, як a:Int=і однакова кількість байтів, щоб визначити їх (це лише справа Int), однак, оскільки у мене зараз є лише 1 рядок у функції, я можу скинути {}і я також опустити один ;(інший замінено на a ,)

Отже, якщо є якісь функції, які потребують визначення Int, і це буде 1-лайнер, якщо ви не визначили int у функції - тоді виконання цього параметра буде збережено пару байтів


0

Функція toінфікування

Існує стандартна функція ІНФІКС імені , toщо створює PairS двох значень. Зазвичай він використовується mapOf()для визначення Maps, але потенційно він може бути набагато коротшим, ніж Pair()конструктор.

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

0

Руйнування в лямбда-аргументах

Скажіть, що ви бажаєте прийняти Pair<*,*>лямбда. Зазвичай поводження з цим було б дратівливим. Як приклад, ось лямбда, який приймає a Pairі перевіряє, чи є два значення рівними:

{it.first==it.second}

Це довговоле і незграбне. На щастя, Котлін дозволяє зруйнувати будь-який руйнівний тип (будь-який тип, який реалізує componentN()методи, наприклад Pair, Tripleтощо) як аргументи лямбда. Отже, ми можемо переписати це наступним чином:

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

Це схоже на візерунок, що відповідає кортежу в чомусь на зразок F #, і це у багатьох випадках. Але найрізноманітніші типи в Котліні підтримують руйнування ( MatchResultє корисним.)

Однак ви можете брати більше аргументів. Скажіть, ваша лямбда повинна була взяти Pairдодаткове значення. Ви просто напишете лямбдаський підпис так:

(a,b),c->  // pair first
a,(b,c)->  // pair second
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.