Поради для гольфу в Japt


18

Тепер, коли я сильно пристрастився до Code Golf, напевно, саме час я спробую підібрати кілька мов для гри в гольф.

З огляду на те, що я граю майже виключно в JavaScript, Japt здається логічною мовою для початку. Я буду занурюватися в документацію при наступній нагоді, але тим часом, будь ласка, опублікуйте будь-які поради щодо Japt у відповідях нижче.

Оскільки я початківець з мов Japt та гольфу в цілому, якщо ви зможете "перекласти" свої поради на JavaScript, де це можливо, це допоможе мені допомогти мені впоратися з речами.


Хе, спасибі за повідомлення про це. Я стримувався з цим, бо хотів би переробити Japt в якийсь момент, але це не відбудеться найближчим часом, і, мабуть, не зіпсує багато порад все одно. Порада для себе: напишіть підручник: P
ETHproductions

Не забудьте відвідати кімнату чатів Japt :)
Олівер

Відповіді:


11

Перехід від JavaScript до Japt

Як ви можете знати, Japt - це просто скорочена, розширена версія JavaScript. Я створив Japt через те, що мені набридли довгі назви властивостей, як-от String.fromCharCode(x)і Math.floor(x), і втомлюваність робити такі речі, як створення діапазону. Ось мінімальний мінімум, який ви повинні знати, переходячи від JavaScript до Japt:

  • Japt є transpiled мову; Japt код transpiled на JavaScript , а потім запустити в JS. (Я думаю, ви могли б сказати, складений , але транслідований звучить більше хіпстером. Відмова: Я абсолютно нічого не знаю про те, щоб бути хіпстером)
  • Усі записи за замовчуванням є повноцінними програмами. Вхід неявно аналізується, і перші шість входів поміщаються в змінні U, V, W, X, Y, і Z; повний масив зберігається в N. Результат останнього виразу друкується автоматично.
  • Усі великі літери є змінними та залишаються однаковими, коли їх перекладають. Більшість мають попередньо задані значення, які ви можете знайти в розділі "Змінні" в документах Japt (у перекладача ).
  • Усі малі літери - це прототипи функцій або методів . Japt додає методи a- zà- ÿ) для чисел, рядків та масивів. Коли ви використовуєте один із цих літер, Japt заповнює .і (; Ucу Japt еквівалентно U.c(JavaScript, що може означати ceil, charCodeAt або concat, залежно від типу U. Ось звідки походить більшість сил Джапта; Ви можете знайти повний перелік цих методів у розділах "_____ функцій" документів Japt (у перекладача ).
  • Простір представляє )і )представляє )). Це тому, що коли я вперше сконструював Japt, я хотів зберегти якомога більше байтів, і саме так я вперше подумав це зробити. (Хоча Us w nце виглядає краще, ніж Us)w)n)ІМХО.)
  • Функція позначається як ABC{...}, де ABCможе бути будь-який рядок змінних. Функції працюють здебільшого, як і в JS, головна відмінність полягає в тому, що останній вираз автоматично повертається (замість того, щоб використовувати returnабо думати ES6 в дужках).
  • 'позначає один рядок char (тобто 'aтакий же, як "a"), і #приймає наступний char-код і стає цим числом ( #eє таким же, як 101).
  • Все, що знаходиться між знаками долара, $залишається однаковим під час процесу транспіляції. Ви можете використовувати це для реалізації forциклів, наприклад, оскільки у Japt таких немає, але я б запропонував використовувати інші методи (наприклад, mна рядках і масивах чи oна числах).
  • Більшість інших символів зазвичай використовується в JS - "", 0-9, (, +, =і т.д. - залишаються тими ж , коли transpiled (здебільшого, у всякому разі).

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


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

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Тепер перейти на Japt. .split("")в JS еквівалентний q""у Japt, або навіть коротше, просто q. .join("")також просто q, різниця полягає в тому, що об'єктом є масив замість рядка. .map(є m, .charCodeAt(є cі .toString(є s. Отже, наш Japt-код може виглядати так:

Uq mX{Xc0 s16} q 

У Japt, однак, mдобре працює і на рядках, як і в масивах, тому ми можемо видалити обидва qs:

UmX{Xc0 s16}

Перевірте це в Інтернеті! Як ви бачите у полі "Код JS", це безпосередньо перекладається на:

U.m(function(X){return X.c(0).s(16)})

Коли ви навчитесь працювати з Japt, ви станете все менше орієнтуватися на перетворення вперед і назад з JavaScript і зможете кодувати в Japt як свою власну мову. Ось пояснення, що повністю виключає частину JavaScript:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

Можливо, краще показати ще один крок: ярлики Unicode. У цьому випадку ми могли б зберегти 2B з ними. Крім того, ви можете додати, що ви можете залишити певні речі наприкінці. Це врятувало б ще один байт.
Лука

Відмінний праймер, спасибі, ETH. Я думаю, що там достатньо, щоб розпочати мене з кількох простих викликів.
Кудлатий

Поєднуючи це з тим, що я до цього часу я прочитав з README, чи не можу бути правильним, що приклад вище можна було би скоротити Um_c s16?
Кудлатий

Або, ще коротше ¡Xc s16:?
Кудлатий

1
@Shaggy Ви маєте рацію! Людина, ти це швидко зрозумів ;-) Я додам декілька основних порад щодо гольфу Japt (на зразок ярликів Unicode і подібних), мабуть, як і інші відповіді.
ETHproductions

8

Стиснення рядкових масивів

ОНОВЛЕННЯ: Інструменти, представлені в цій підказці, з тих пір будуть переписані, вдосконалені та інтегровані в мій перекладач Japt . Для найкращих результатів рекомендується використовувати цей компресор над будь-яким із зв'язаних нижче. Я перегляну цю пораду, коли у мене з’явиться ще час, і перепишу її новим компресором на увазі.

Вступ

Якщо у вашому коді є масив рядків, найбільш очевидним способом його стиснення було б запуск кожної рядкиOc окремо. Для цілей цієї поради ми будемо працювати з масивом ["lollipop","marshmallow","nougat","oreo"], який спочатку важить 42 байти. Запуск кожного рядка через Ocнас дає:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Це зараз 33 байти, гідна економія.


Крок 1

Але ми можемо зробити краще. Якщо ми приєднаємо масив до рядка, розділеного новою лінією, ми можемо позбутися дужок, коми та сторонніх задників і розділитись на новий рядок, щоб отримати наш масив. Застосовуючи це до нашого прикладу масиву, ми отримуємо наступне:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Зараз до 26 байт.


Крок 2

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

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ах, горіхи - поліпшення там немає; наш байт збільшився на один! Там може бути ще один лист , ви могли б використовувати , але, в залежності від ваших рядків, не може бути достатньо мало , щоб спробувати - в нашому прикладі є 11: b,c,d,f,j,k,q,v,x,y,z. Спроба кожного з них була б досить стомлюючою, і саме тут є цей зручний інструмент ; подайте його своїми рядками, розділеними новим рядком, і він спробує розмежувати рядки кожною літерою, яка не міститься в жодній з них, і вивести:

  • найкоротший стислий рядок,
  • роздільник, який він використовує, і
  • його довжина.

Запуск наших зразків рядків через нього показує, що bдає найкращі результати:

`lo¥ipáæqrÚaowbÍÞo`qb

І там у вас це є, ми знизилися до всього 24 байт.


Крок 3

Але , ми можемо зробити ще краще! Якщо порядок рядків у вашому масиві не має значення, можливо, є інша перестановка в поєднанні з іншим роздільником, який може вийти ще коротше. Спроба кожної можливості стане набагато більш втомливою. З нашими 4-ма рядками, можна спробувати 24 різні перестановки. З кожною з 11 можливих літер, яка стає 264! Ось де цей інструмент вступає в гру. Знову ж таки, подайте йому свої рядки, що розділяються з нового рядка, і він буде випробовувати кожну комбінацію кожної перестановки та кожного відмітного листа, виводячи:

  • порядок рядків у найкоротшому стисненому рядку,
  • стислий рядок,
  • роздільник, який він використовує, і,
  • його довжина.

Запуск наших зразків рядків через це показує , що "nougat","oreo","lollipop","marshmallow"з , bяк роздільник дає кращі результати, з остаточним підрахунком байт з усього 23:

`ÍÞo½o¥ipáæqrÚaow`qb


Порада про бонус: Стиснення масиву цілих чисел

Ви можете застосувати той же принцип до масивів цілих чисел, попередньо перетворивши кожне у вищу базу. Використовуючи цей зразок, 36-байтний масив:

[588181,156859,595676,475330,680474]

Ми можемо зменшити це до 29 байт, спершу перетворивши його в масив базових 32 рядків, а потім запустивши його через першу програму стиснення:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Або ж 27 байт за допомогою другої програми:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

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


Примітки

  1. Не забувайте враховувати q<letter>(<space>)витрати на 1 або 2 зайвих байта ·. Хоча, можливо, ви зможете скористатися одним із ярликів Unicode, щоб повернути байт назад, залежно від вашого роздільника ( такий же, як ql<space>, наприклад,).
  2. Слово обережності при використанні останнього інструменту: чим більше рядків у вас буде, тим більше буде перестановок і повільніше буде працювати програма, доки вона врешті не вискочить. Як детально описано вище, з 4-х зразкових рядків та 11 можливих букв, які можна спробувати, є 264 можливі комбінації, збільшити кількість рядків лише на 1 з тими ж 11 літерами, і ми вже маємо 1320 комбінацій для спробу. (Ви можете використовувати цей інструмент для підрахунку кількості комбінацій, якщо хочете).

Кредити

  • Олівер за натхнення створити інструменти, знайдені в цій підказці.
  • ETHпродукції для коректури.

6

Стискаючі струни

Japt (в даний час) використовує бібліотеку shoco для стискання рядків. Ви можете стиснути довільну рядок, використовуючи Oc, якщо вона містить пробіри малих літер:

Oc"Hello, World!"

Це виводить HÁM, WŽld! (ну Žтехнічно це недрукований персонаж). Ви можете розпаковувати це, загорнувши його у задній план:

`HÁM, WŽld!`

Перевірте це в Інтернеті!

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


Отже, якби я відповідав на "Привіт, світ!" Проблема, я б просто використовував HÁM, WŽld!або потрібно було б укласти її в беккетки? Я здогадуюсь останнього.
Кудлатий

2
@Shaggy Коли ви відповідаєте на запитання, вам потрібно буде включити весь код, так що це буде "HÁM, WŽld! у цьому випадку
Martijn Vissers

6

Скорочення чисел із Char-кодами

У Japt можна використовувати # символом, а за ним символом для створення чар-коду. Це стане в нагоді при скороченні довших чисел.

Як згадувалося @ETHproductions, це працює лише на трицифрових пробігах у діапазоні 100-255, якщо ви не бажаєте перейти на UTF-8.

Приклади:

123 можна скоротити до #{

101 можна скоротити до #e

Ви можете навіть пов’язати їх разом:

123101 можна скоротити до #{#e

Ви можете використовувати String.fromCharCode(123)в JavaScript або123d Japt, щоб знайти відповідний символ.

String.fromCharCode(123) повертає {


Дякую, @obarakon, чудова порада, щоб м'яч прокатувався; String.fromCharCode()- це один із тих (безліч!) неприємно довгих методів JS, який може бачити ваш байт. Імовірно, вони вважатимуться цілими числами? тобто, якщо мені потрібне ціле число 123в рішенні, я можу використовувати #{для збереження байт.
Кудлатий

1
Так, це цілі числа. Якщо ви додасте -Qпрапор у вікно введення, ви зможете краще переглянути тип виводу: лапки навколо рядків , масивів тощо.
Олівер

1
Ви повинні згадати, що це String.fromCharCode(123)працює в JavaScript, але ви можете зробити 123dв Japt, щоб отримати той же результат ;-) Також це працює лише на трицифрових пробігах у діапазоні 100- 255(якщо ви не готові перейти на UTF-8)
ETHproductions

@ETHproductions Гарний дзвінок, оновлено!
Олівер

5

Коротка порада: Порожній масив []

Japt має константу для порожнього масиву: A. Але, щоб отримати доступ до нього, ви повинні додати крапку ;з комою до вашої програми, щоб використовувати альтернативні константи Japt, інакше Aбуде 10. Таким чином , використовуючи ;Aфактично пропонує 0 байт економії більш [], але буде заощадити байти , якщо вам потрібно , щоб привласнити масив змінного (наприклад,A=[] ).

Однак, якщо (і лише якщо) ваша програма не приймає жодного вводу, ви можете отримати доступ до порожнього масиву лише з 1 байтом, використовуючи Nзмінну, яка є масивом входів - без входів вона буде порожньою. Спробуйте це тут .

Це також має додаткову перевагу, що дозволяє використовувати постійні значення за замовчуванням у вашій програмі, а в деяких випадках все ще може заощадити ваші байти, використовуючи, ;Aнавіть коли ваша програма приймає дані завдяки ярликам для s1і s2.


2
Нічого собі, я не думав використовувати N, приємна ідея.
ETHproductions

2
Гарний, @Shaggy!
Олівер

4

Оцінка JavaScript

Japt дозволяє виконувати необроблений JavaScript, обертаючи його навколо $...$ .

Наприклад, $alert("hello world")$

Це можна скоротити, скориставшись автоматичним закриттям Japt $і ).

$alert("hello world")$ можна скоротити до $alert("hello world"

Стиснення JavaScript

Ви також можете стискати JavaScript, використовуючи Ox.

Якщо є функція JavaScript, яку ви хочете використовувати, скажімо screen.width, ви можете стиснути рядок "screen.width"за допомогоюOc , потім вставляючи результат між Ox` ... `

Зауважте, що вам не потрібно закривати цитати в Japt, коли за ним не дотримується нічого іншого.


@Shaggy Вам потрібно Oxоцінити рядок. В іншому випадку ви просто виведете текст "screen.width". Приклад
Олівер

4

Знай прапори

Згідно до останнього мета-консенсусу (грудень 2017 року) , прапори командного рядка більше не зараховуються до байтів. Це справді чудова новина для Japt, оскільки у неї є багато прапорів для додаткової обробки на вході / виході.

Усі доступні прапори в Japt описані нижче, в порядку оцінки . Прапори однієї групи ексклюзивні один одному. Зверніть увагу , що прапори в різних групах можуть бути використані в комбінації, в результаті чого - щось на зразок цього :)

mdefæ

Вся програма відображається на першому аргументі (U ).

Якщо є більше аргументів, вони передаються як є (тобто не відображаються попарно). В іншому випадку другий аргумент - це індекс, а третій - весь масив, так само, як U.m. Якщо Uчисло, воно перетворюється на діапазон; якщо рядок, він перетворюється на масив символів, і результати об'єднуються разом.

  • -m: Застосовує сказане та більше нічого.
  • -d: Повертається, trueякщо якийсь результат є простийfalse інакше.
  • -e: Повертається, trueякщо всі результати непрості,false інакше.
  • -f: Повертає масив елементів U , результати яких є truthy.
  • : Застосовує -fта повертає свій перший елемент.

gh

Бере елемент у вказаному індексі.

  • -g: Бере перший елемент (індекс 0).
  • -gX: Бере елемент в індексі X (може бути будь-яке додатне ціле число).
  • -h: Бере останній елемент.

Перетворити результат на булевий.

  • -!: Не застосовувати булеву не.
  • : Наносити булеву не двічі (повертає правдивість).

N

Перетворіть результат у число. Використовується одинарний плюс.

PRSQ

Перетворити в якийсь рядок.

  • -P: Приєднайтесь до масиву с "".
  • -R: Приєднайтесь до масиву с "\n".
  • -S: Приєднайтесь до масиву с " ".
  • -Q: Застосувати JSON.stringify(може бути будь-який об’єкт, не тільки масив). Приклад .

x

Застосовує функцію xдо виходу. (Це буквально x, не "жодна функція малої літери алфавіту".)

  • Масив: Сума.
  • Рядок: Обріжте з обох кінців.
  • Номер: Круглий до цілого числа.

2
Зауважте, що використання прапорів не рахується як подання Japt, але воно вважається поданням мови Japt-with-specific-flags.
Ніт

3

Ярлики Unicode

У Japt існує багато загальних структур, які просто не можуть бути збережені в одному діаграмі ASCII, наприклад qS  , p2 , mX{, і т.д. Таким чином , щоб обійти цю проблему , Japt має «ярлики Unicode», які є символами в діапазоні \xA1- \xDE( ¡- Þ), які розширюються на ці загальні структури. Повний перелік їх можна знайти в документах перекладача .

Крім того, @розшифровується XYZ{та _розширюється Z{Z, щоб допомогти зібрати функції. Тож давайте гольф нашої прикладної програми з іншої відповіді :

UmX{Xc0 s16}

Під - перше, ми можемо замінити X{Xз _, що дає нам:

Um_c0 s16}

Тоді ми можемо замінити m_з ®економією інших байт:

U®c0 s16}

Або ми могли б замінити X{з @, що дає нам:

Um@Xc0 s16}

Потім це дозволяє використовувати ¡ярлик для збереження двох байтів:

¡Xc0 s16}

Один з цих двох шляхів можна скоротити на 1 байт більше, ніж інший. Ви можете розібратися, які?


1
®c s16на 6 байт - я виграю печиво ?!
Кудлатий

@Shaggy Ви можете зберегти ще 1 байт, якщо виглядаєте досить важко ...;)
ETHproductions

Було б ®c sG?
Кудлатий

1
Так! Я думаю, що це так низько, як ви можете піти. Молодці! :-)
ETHproductions

2
Дивовижно оглядаючись на них, спостерігаючи прогресування Джапта за кілька коротких місяців. Цього зараз можна досягти csG.
Кудлатий

3

Скористайтеся передустановленими змінними

Змінні A- Sзаздалегідь задані загальні значення, для представлення яких у Japt потрібно більше одного байта:

  • A- Gє 10- 16.
  • Hє 32, Iє 64, Jє -1, Lє 100.
  • Kвизначається як new Date(), яким можна маніпулювати різними способами.
  • Mі Oє об'єктами з різними корисними функціями. Ви можете дізнатися більше в документах.
  • Pє порожній рядок, Qце лапка, Rце нові рядки та Sє пробіл.
  • Tвстановлено на 0, тому ви можете використовувати його як акумулятор при необхідності.

Якщо перший символ у програмі - крапка з комою ; , A-Lскиньте наступне:

  • A- порожній масив [].
  • B є "ABCDEFGHIJKLMNOPQRSTUVWXYZ" .
  • C є "abcdefghijklmnopqrstuvwxyz" .
  • D є "QWERTYUIOP\nASDFGHJKL\nZXCVBNM" .
  • Eє "[a-z]", іF є "[A-Za-z]"(корисно до того, як я додав їх як функції регулярного виведення)
  • Gє 36, Hє 65і Iє91 (корисно для алфавітних діапазонів).
  • J - одна кома; L, єдиний період.

В даний час тільки A, B, Cі Dз цього списку дійсно корисні. Я планую додати кращу систему, яка дозволяє до 256 двобайтових змінних, які будуть встановлені на ці значення та ще багато іншого.


3

Використовуйте автоматичні функції

Ви, швидше за все, вже знаєте, що це @і _є ярлики для XYZ{і Z{Z, відповідно (охоплені ярликами Unicode ). Але іноді можна зробити функції ще коротшими.

Припустимо, у вас був масив символів, і ви хотіли зіставити кожного символу з його чар-кодом. Ви можете зробити це за допомогою будь-якого з цих:

mX{Xc} 
m_c} 

Але є кращий спосіб. Якщо метод або оператор є першим елементом після іншого методу або a (, він перетворюється на рядок. Отже, ці два рядки рівнозначні:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Але як це допомагає нашим функціям? Ну, більшість методів, які приймають функції, якщо їм дано рядок, що представляє метод або оператор, буде інтерпретувати його як функцію. Що означає, що ви також можете це зробити:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Я називаю ці "автоматичні функції". Існує кілька різних різновидів:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Сподіваємось, ви отримаєте ідею. Щоб обмінятись аргументами, просто встановіть префікс методу чи оператора !.


Чи варто тут зауважити, що використання автоматичних функцій також може забезпечити подальшу економію за рахунок використання ярликів? наприклад, m@2pXÃm!p2<space>m!².
Shaggy

Вуха! Я не думав використовувати рядок у карті, навіть не знав, що це можливо. Можливо, я в майбутньому заощаджую кілька байтів завдяки цьому.
RedClover

Привіт @Soaku, я якось пропустив те, що ти відповідав з Japt, тож дозвольте мені привітати вас із запізненням! Сподіваюсь, вам сподобалося використовувати його до цих пір. Якщо у вас є якісь питання, пропозиції або просто хочете поговорити, не соромтесь приєднатися до нас у чаті Japt (Github зазвичай працює також і для перших двох;))
ETHproductions

3

Неявне змінне призначення

Щоразу, коли ви починаєте новий рядок у Japt, результат попереднього рядка автоматично присвоюється одній із вхідних змінних ( U- Z), причому перший рядок є UдругимV і так далі.

Візьмемо приклад: скажімо, ви хотіли створити 2 масиви для роботи, один з числами 1-10, а другий, що містить їхні квадрати. Довгий шлях для цього був би таким:

U=Aõ V=Um² [do something with the arrays]

Однак, використовуючи автоматичне призначення змінних, це може бути скорочено до:

Aõ
Um²
[do something with the arrays]

Там ми зберегли 4 байти. Але в цьому випадку ми можемо зберегти ще один байт, оскільки масив 1-10 призначений Uі Uможе бути опущений у певних сценаріях :

Aõ
m²
[do something with the arrays]

Обережність

Одним із цих порад слід бути обережним - це те, що ви не перезаписуєте жодні вхідні змінні, які можуть знадобитися згодом у вашій програмі. Цього можна уникнути, залишивши на початку одного або декілька порожніх рядків. У наступному прикладі 2 масиви будуть призначені змінним V& W, а не U& V:


Aõ
Vm²
[do something with the arrays]

3

Знайте Javascript

Оскільки будь-який код Japt працює як трансліпільований JS, добре розуміння операторів JS та вбудованих методів дуже допомагає в гольф-кусках коду Japt.

Відповідні поради JS

[]Vm@...
...
  • Коротке замикання
  • Розщеплення з числами
    • Це можна узагальнити до будь-якого методу, який приймає рядки, але не числа. Число, передане там, неявно буде передано в рядок, часто зберігаючи байт (наприклад, 0над '0).

Відповідні вбудовані функції JS

Уважно подивіться, які параметри передаються для аргументів функції.

Для рядкових методів добре знати, як поведінка відрізняється між передачею рядка або регулярного вираження з gпрапором або без нього .

  • String.prototype.match
    • Споріднені методи Japt: String.f/o
  • String.prototype.search
    • Споріднений метод Japt: String.â
  • String.prototype.replace
    • Споріднені методи Japt: String.e/k/r
    • Тому що e/rпередача функцій як другого аргументу в порядку, і розуміння параметрів функції дуже рекомендується.

3

Використовуйте кілька рядків, коли це необхідно

Для більшості не надто важких проблем ви можете висловити рішення лише в одному рядку Japt як послідовність застосування вбудованих функцій. Але більш складні будуть вимагати використання циклічних конструкцій, рекурсії або повторного використання великих фрагментів коду. Ось тут надходить багатолінійне програмування.

Видаліть закривання паролів

Завдання : Давши масив чисел, з’єднайте кожен елемент із індексом у квадраті та відсортуйте його за сумою.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

Однорядкове рішення є íUm@Yp2})ñx, але })коштує два байти (а однобайтового ярлика немає). Ви можете видалити }), просто перемістивши трейлінг ñxдо наступного рядка, щоб код виглядав так:

íUm@Yp2
ñx

і перекладений JS стає:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Ви можете чітко бачити, що це робить те саме, що і однолінійне рішення, просто присвоюючи проміжний результат назад U .

Повторіть з неявними аргументами

Функція рекурсії ßприймає все UVWXYZяк неявний параметр, якщо не вказано. UОчевидно, це основний вклад, але ви можете використовувати будь-який з, VWXYZщоб відслідковувати інші необхідні вам значення. Наприклад, ви можете зробити щось на зразок наступного:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

Крім того, якщо все, що вам потрібно, є тимчасовою змінною, ви можете використовувати вбудоване призначення, наприклад (T=...), так як змінна T(0) рідко використовується як є.

Використовуйте довгу функцію

З цього приводу я не думаю, що я можу придумати гарний приклад завдання, тому я посилаюся на єдине рішення, яке використовувала ця порада , та лише окреслити деякі загальні ідеї.

  • Щоб повторно використовувати функцію, потрібно зберегти її у змінній. Запуск лінії з функцією відкривачем {, @або _робить роботу. Крім того, ви можете також зробити щось на кшталт (T=@...})вбудовування призначення функції всередині більш складної лінії.
  • Насправді не тривіально викликати збережену функцію. Припустимо V, це функція, і ми хочемо зателефонувати V(U)в JS. VUне працює, оскільки це просто означає V,U. V(Uтеж не є; це V,(U). Навіть методи функціонування не дуже допомагають. Найкращий спосіб, який ми знайшли:
    • [U]xV (карта та сума), якщо результат число
    • UmVякщо Uце один char та Vповертає рядок, або
    • $V($Uабо [U]mV gвзагалі.
  • Однак зіставити карту або циклічно з нею досить просто. Для картографування масиву використовуйте UmV. Щоб знайти перше ціле число, яке задовольняє V, використовуйте Va.

2

Розваги за допомогою автоматичних функцій

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


Отримайте найбільше ціле число в масиві.

Припустимо, у нас масив [3,1,4,2]призначений змінній, Uі ми мусимо отримати найбільшу кількість з нього. Ми могли б зробити це в 4 байти, сортуючи масив, а потім вискочивши останній елемент:

Un o

Мінус у тому, що ми змінили вихідний масив; Uце зараз, [1,2,3]що може не завжди бути бажаним. На щастя, існує спосіб зробити це без зміни масиву, який також на один байт коротший:

Urw

Що ми там зробили, це скоротити масив за допомогою wметоду, який, використовуючи ціле число, повертає більше цілого числа та аргумент методу (наприклад, 2w5повертає 5). Отже, вищезгадане є еквівалентом UrÈwYабо UrXY{XwY}. Зауважте, що ця підказка не працюватиме у випадку, коли всі цілі масиви в масиві будуть від'ємними.


1
Бічна примітка: я планую додати функції, щоб отримати мінімум та максимум масиву, хоча, ймовірно, лише у v2.
ETHproductions

2

Коли не користуватисяí

íє корисною вбудованою парою (або zipсекціями) двох масивів або рядків і необов'язково відображає кожну пару через функцію. Однак наразі у нього є кілька незначних проблем, коли даються нерівні масиви або рядки:

  • Якщо перший масив містить більше елементів, ніж другий, неіснуючі елементи у другому будуть задані як undefined.
  • Якщо другий масив містить більше елементів, ніж перший, він зупинить обробку в кінці першого масиву.

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

UíUç hV @[XY]n o

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

Uy m_q n o

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

Приклади з реального життя: 1 , 2


2

Створіть діапазон ASCII

Оновлення: Japt тепер має константу для діапазону ASCII; альтернативне значення для E, доступне для ;. Додаткову інформацію про константи Джапта див. У цій підказці .

Поки Japt ще не має вбудованого діапазону ASCII, ви можете генерувати масив символів усього 5 байт:

95odH

Спробуй це


Як це працює

95oстворює діапазон, [0,95)коли кожен елемент передається через автоматичну функцію, d яка при використанні в номері повертає символ у цій кодовій точці. dВ цьому випадку передайте число як аргумент методуH константа Japt для 32, і вона буде додана до вихідного числа перед перетворенням.

Еквівалентним рішенням у JavaScript буде:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Випадкові персонажі

Для отримання випадкового символу в діапазоні ASCII використовуйте öнатомість, який повертає випадкове число з діапазону [0,X), де Xце число, на якому воно працює.

95ö dH

Або, щоб отримати масив з декількох випадкових символів, передайте кількість символів, яке вам потрібно в якості аргументу ö. Наступне поверне 10 символів:

95öA mdH

1

Видаліть непотрібні структурні елементи

До структурних гольців, я маю в виду {}, (), $навіть "і `. Зазвичай ви можете видаляти ці символи кожного разу, коли вони виникають в кінці програми (наприклад UmX{Xc +"; "} -> UmX{Xc +"; ).

Крім того, ви можете видаляти паролі або пробіли, коли вони з’являються в таких місцях:

  • Вгору проти крапки з комою ;(або в кінці програми);
  • Праворуч від {(і подовження @) або [, або зліва від ]або }.

Також коми дуже рідко потрібні для розділення аргументів. Якщо ви пишете AB, наприклад, Japt знає, що ви маєте на увазі Aі Bокремо. Вам дійсно потрібна кома для розділення двох числових літералів, таких якUs2,5 .

Нарешті, якщо є Uна початку програми або після того, {чи ;, з подальшим викликом методу (рядкові буквами або пов'язаним з ярликом Unicode) або будь-яким бінарним оператором виключаючи +і -( *, &, ==і т.д.), ви можете видалити , Uщоб заощадити байт і Japt вставлять його для вас.


Я знайшов кілька інших випадків, коли їх Uможна не помітити навіть тоді, коли це не на початку програми.
Кудлатий

@Shaggy О так, він також працює після {або ;. Чи є ще інші, про які ви знаєте? (Минуло час, коли я
зашифрував

Не можу придумати їх у верхній частині голови; Я перевірю це ще раз, коли завтра повернусь до свого комп’ютера.
Кудлатий

1

Змінення останнього елемента в масиві

Іноді вам може знадобитися змінити останній елемент у масиві, ось ось пояснення короткого способу цього зробити. Ми будемо працювати з масивом, [2,4,8,32]призначеним для вхідної змінної, Uі ділимо останнє ціле число (32 ) на 2.

Очевидним способом досягти цього було б це 9-байтне рішення ( Демо ):

UhJUgJ /2
  • hnxвстановлює елемент в індексі nдоx .
  • gn повертає елемент в індекс n .
  • J - константа Japt для -1 , яка завдяки підтримці Japt щодо негативного індексу дозволяє нам працювати з останнім елементом у масиві; зручно, коли ви не знаєте розмір масиву.
  • І /2це просто ділення на 2.

Отже, вище встановлює елемент в індексі -1 в масиві до елемента в індексі -1в масиві, розділеному на 2. Або в JavaScript : U[3]=U[3]/2. Коли ви пишете це так, здається, це занадто довгодушний спосіб робити це. На щастя, є більш короткий шлях; ми можемо випустити останній елемент із масиву, змінити його та відсунути назад до масиву. Виконуючи кожну з цих операцій окремо, потрібно більше 9 байт, але ми можемо робити їх відразу за всього 7 байт, 2 байти збереження ( демонстрація )

UpUo /2

У перекладі на JS це еквівалент:

U.push(U.pop()/2)&&U
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.