Поради щодо гри в гольф в Желлі


46

Jelly - це мовчазна , орієнтована на гольф мова програмування від нашого власного Денніса . Тут все частіше і частіше з'являються відповіді, перемагаючи інші гольф-мови, такі як Pyth та CJam, як за допомогою власної кодової сторінки, так і потужної ланцюгової системи для стислого вираження програм.

Давайте зіберемо кілька корисних порад для гри в гольф у Джеллі. (Як завжди, будь-яка порада на відповідь, будь ласка!)


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

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

3
Ось чудова порада: станьте учнем @ Денніса. Тоді ви справді будете гарні в гольф-желе.
Conor O'Brien

12
@Lynn Мені подобається, як ти кажеш наш власний Денніс. Наче ми всі одна велика родина: D.

Цей потік у випусках Jelly's GitHub про те, як насправді набрати символи кодової сторінки Jelly, ймовірно, варто порадити чи дві: github.com/DennisMitchell/jelly/isissue/6 У мене немає доступу до машини Windows, хоча я не знаю не впевнено пишуть ці шматочки.
Йордан

Відповіді:


25

Стиснення струни

Якщо ви шукаєте більш оптимізований / автоматичний струновий компресор, спробуйте цей .

Спробуйте в Інтернеті!

Схоже, стислий рядок виглядає так “...», де точки - це фрагмент даних, закодованих у базі-250. Алгоритм декомпресії трохи складний: фрагмент інтерпретується як ціле число "змішаної бази", з divmodвідривом різних частин цього цілого числа та побудовою з них рядка.

Я створив невеликий інтерфейс Python 3 для стиснення струн Jelly:

import dictionary
code_page = '''¡¢£¤¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¶°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƊƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż«»‘’“”'''

class Compress(list):
    def character(self, c):
        if c in '\n\x7f¶':
            o = 95
        elif ' ' <= c <= '~':
            o = ord(c)-32
        else:
            raise ValueError(c + " is neither printable ASCII nor a linefeed.")
        self += [lambda z: 3*z+0, lambda z: 96*z+o]; return self
    def string(self, s):
        for c in s: self.character(c)
        return self
    def dictionary(self, w):
        ts = bool(self)
        if w[:1] == ' ': w = w[1:]; ts = not ts
        dct = dictionary.short if len(w) < 6 else dictionary.long
        W, sc = (w, 0) if w in dct else (w[:1].swapcase() + w[1:], 1)
        if W not in dct: raise ValueError(w + " isn't in the dictionary.")
        f = ts or sc; j = (2 if sc else 1) if ts else 0; i = dct.index(W)
        self += [lambda z: 3*z+2, lambda z: 3*z+j] if f else [lambda z: 3*z+1]
        self += [lambda z: 2*z+int(len(w) < 6), lambda z: len(dct)*z+i]
        return self
    def go(self):
        compressed = []; z = 0
        for f in self[::-1]: z = f(z)
        while z:
            c = z % 250
            if c == 0: c = 250
            z = (z - c) // 250
            compressed.append(code_page[c - 1])
        return '“{0}»'.format(''.join(compressed[::-1]))

Використовуйте компресор наступним чином.

print(Compress()
      .dictionary('public')
      .dictionary(' static')
      .dictionary(' boolean')
      .string(' is')
      .dictionary('Power')
      .string('Of')
      .dictionary('Ten')
      .string('(')
      .dictionary('long')
      .dictionary(' input')
      .string(') {\n ')
      .dictionary(' return')
      .string('\n   ')
      .dictionary(' input')
      .string(' ==')
      .go())

Compress є конструктором струн:

  • .string(s) буде вставити необроблені символи ASCII для друку у рядок.

    (Кожен символ коштує приблизно 0,827 стислих байт.)

  • .dictionary(w)шукатиме рядок у вбудованих словниках Jelly. Ви можете почати рядок з одного пробілу, якщо ви хочете його. Якщо для цього потрібно відхилитися від нормальної поведінки додавання рядків або перевернути велику літери словника, воно додасть прапори відповідно.

    (Витрачає близько 1 997 байт для коротких слів, 2,433 байт для довгих слів; якщо є прапори, додайте 0,199 байт.)


15
Це корисно! Я трохи втомився стискати їх вручну ...
Dennis

1
@Dennis Чи можна це включити до самого Jelly, тому нам не доведеться копіювати його звідси кожного разу?
PurkkaKoodari

@ Pietu1998 Як атом чи щось інше?
Денніс

@Dennis Як скрипт утиліти у сховищі.
PurkkaKoodari

1
Напевно, вимагає чогось в желе.
CalculatorFeline

19

Це частина того, що стало навчальним посібником для Jelki wiki .

Ланцюги

(Це щось із подальших заходів щодо програмування Tacit .)

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


1. Ніладичні ланцюги

Це найпростіші з групи. Для оцінювання ланцюга, що починається з нілада, як α f g h, наприклад , оцінюйте монадичний ланцюг f g hу цьому ніладі α. (Caveats: якщо весь ланцюг порожній, замість нього повертається 0. Якщо α це не nilad, замініть його α=0замість.)

Наприклад, просто ½оцінюється на 4, що є 2.


2. Монадичні ланцюги

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

Яке початкове значення для цієї оцінки зліва направо?

  • Якщо наш ланцюг починається з ниладу α, а за ним слідують нуль або більше монад (подібних ½), пар діад-нилад (як +2) і пар нилад-діад (подібних 4*): ми починаємо з оцінки α, а потім розглядаємо решту ланцюга .

  • В іншому випадку ми почнемо з аргументу, переданого до цього ланцюга ω, і розглянемо весь ланцюг.

Як ми йдемо по ланцюгу?

Давайте назвемо Vпоточне значення - спочатку це значення, описане вище, але воно оновлюється, коли ми проходимо по ланцюгу - і позначимо

  • нілади з використанням цифр,
  • монади, що використовують малі літери,
  • діади з допомогою символів оператора +, ×, ÷.

Тоді такі схеми порівнюються, зверху вниз:

                                 ┌───────────┬─────────┐
                                 │ old chain │ new V   │
                                 ╞═══════════╪═════════╡
                                 │ + × 1 ... │ (V+ω)×1 │ *
                                 │ + f ...   │ V+f(ω)  │
                                 │ + 1 ...   │ V+1     │
                                 │ 1 + ...   │ 1+V     │
                                 │ + ...     │ V+ω     │
                                 │ f ...     │ f(V)    │
                                 └───────────┴─────────┘
      (* Only if `...` consists of monads, dyad-nilad pairs, and nilad-dyad pairs.)

Давайте спробуємо це на ланцюжку +²×.

  • +це не найд, тому ми починаємо з V = ω.
  • Потім відбиваємо , узгоджуючи другий візерунок, і отримуємо V = ω+ω².
  • Потім відбиваємо ×, узгоджуючи п'ятий візерунок, і отримуємо V = (ω+ω²)×ω.
  • Зараз ланцюг порожній, такий (ω+ω²)×ωі наш кінцевий результат.

3. Діадичні ланцюги

Вони в основному схожі на монастирські ланцюги, але цього разу є два аргументи, λ(лівий) і ρ(правий).

Яке початкове значення?

  • Якщо ланцюг починається з трьох діад на кшталт + × %, ми починаємо з λ+ρ, і розглянемо ланцюжок × % ...далі.

  • В іншому випадку ми почнемо з цього λі розглянемо весь ланцюжок.

Як ми йдемо по ланцюгу?

Цього разу шаблони є

                                 ┌───────────┬─────────┐
                                 │ old chain │ new V   │
                                 ╞═══════════╪═════════╡
                                 │ + × 1 ... │ (V+ρ)×1 │ *
                                 │ + × ...   │ V+(λ×ρ) │
                                 │ + 1 ...   │ V+1     │
                                 │ 1 + ...   │ 1+V     │
                                 │ + ...     │ V+ρ     │
                                 │ f ...     │ f(V)    │
                                 └───────────┴─────────┘
      (* Only if `...` consists of monads, dyad-nilad pairs, and nilad-dyad pairs.)

Давайте спробуємо це на ланцюжку +×÷½.

  • Ланцюг починається з трьох діад, тому ми починаємо з V = λ+ρ, і викидаємо +.
  • Потім відбиваємо ×÷, узгоджуючи другий візерунок, і отримуємо V = (λ+ρ)×(λ÷ρ).
  • Потім ми рубаємо ½, узгоджуючи шостий візерунок, і отримуємо V = sqrt((λ+ρ)×(λ÷ρ)).
  • Зараз ланцюг порожній, тому ми закінчили.

2
Тож це стає більше підручником з желе, ніж підказками для гольфу в ньому? ;)
Мартін Ендер

5
Я теж так думаю. Якщо мова дуже складна для розуміння, я думаю, що "як це все працює навіть ?!" - хороша порада ^^ я все-таки маю намір в кінцевому підсумку перейти до не очевидних хитрощів і способів збереження байтів. Якщо цього немає тут, я міг би перенести його на GitHub, або (якщо Деннісу це подобається), репо з желе.
Лінн

16

Цифрові значення зі спеціальним кожухом

Ось кілька особливих випадків для розбору чисел Jelly:

  • - оцінює до -1
  • . оцінює до 0.5
  • ȷоцінює 1000( ȷдля наукових позначень, наприклад 2ȷ6є 2000000)
  • ıоцінює до 1j( ıдля складних чисел, наприклад, 2ı3є 2+3j)

Варто також зазначити, що щось подібне є насправді 4+1j, а не 4.

Ви можете їх змішувати і співставляти, наприклад:

  • -.є -0.5і є-1000
  • є -1+1j, ı-є -1jі -ı-є-1-1j
  • є 500.0
  • є 0.5+1j, ı.є 0.5jі .ı.є0.5+0.5j
  • ȷıє 1000+1j, ıȷє 1000jі ȷıȷє1000+1000j

Зауважте, що ȷ-є 0.1, але це не економить жодних байт .1. Тоді також є наступне, що вже можна зробити у відповідній кількості байтів за допомогою вбудованої змінної для 10 ( ), але може бути корисним у рідкісному випадку, коли вбудований недоступний або для економії при необхідності використання ¤:

  • ȷ.є sqrt(10) ~ 3.162277, .ȷ.є sqrt(10)/2 ~ 1.5811і ȷ-.є1/sqrt(10) ~ 0.31162

13

Оптимізований струновий компресор

Спробуйте в Інтернеті!

У публікації Лінн розповідається про те, які саме стискаються струни, а також компресор, який буде створювати ці стислі рядки. Тим НЕ менше, в той час як майструвати навколо з програмою в желе, я знайшов , що це втомлює , щоб об'єднати .dictionaryі .stringразом з правильними місцями розміщення просторів і так далі , і так далі, для того , щоб досягти мінімально можливої рядки.

Тому я вирішив створити розширення до сценарію Lynn, яке б зайняло введення користувача, і знайти найкоротший спосіб його стиснення, без того, щоб користувачеві потрібно було робити якусь роботу. Сценарій досить довгий, і тому я додав посилання TIO, а не сам код.

Спосіб роботи програми полягає в стисненні за допомогою трьох різних методів і визначення найкоротшого:

  1. Спосіб 1 просто кодує кожен байт вхідного сигналу за один раз, що, як правило, дає найдовший результат порівняно з іншими. Навіть коли вхід дуже короткий, він все ще вдається створити досить довгі альтернативи. Наприклад, найкоротший шлях, який testможна стиснути “¡ḌY», тоді як цей метод повертається “¡⁷ƑKʂ»(на 2 байти довше). Як правило, це працює лише в тому випадку, якщо рядок довжиною менше 4 символів

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

    Знаки пунктуації включають пробіли, де використовується метод № 3, але спочатку та оцінка методу 2: порівняємо один і два способи стискання рядка Hello, World!(містить слова, пунктуацію та пробіли, так ідеально). Стиснення символів за символом призводить до завершального рядка “ŒCdẉa÷¹ṂȤƓ(Ẋ)»(15 байт), який, як виявляється, довший, ніж простіший спосіб вивести Hello, World !: “Hello, World!. Тепер розглянемо метод другий. Це створює стислий рядок, “Ọƥ⁷Ƭė3⁶»який важить в 9 байт, що значно покращиться порівняно зі старим. Однак найкоротший привіт, світ! Програма в Jelly становить 8 байт , тому щось можна вдосконалити

  3. Тут представлений метод 3, що робить його ще коротшим. Як і очікувалося, результат для Hello, World - це, звичайно, “3ḅaė;œ»найкоротша можлива програма. Отже, що робить метод 3, що метод 2 не робить? Спосіб 3 поєднує одиночні простори у провідні простори, для яких декомпресор Jelly має прапор. У коді як для компресора, так і для декомпресора ви можете побачити такий код if flag_space: word = ' ' + word, який показує, що провідні пробіли підтримуються а) і підтримуються в байтах. Тому роздільник рядків з методу два адаптований так, що проміжки самі по собі об'єднуються в рядок безпосередньо після, щоб створити провідні рядки. Це означає, що Hello, World!розбирається як ["Hello", ",", " World", "!"], що при стисненні становить лише 6 байт (8, включаючи роздільники). Це майже завжди найкоротший метод стиснення, виключаючи додане я "розширення",

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

  • Програма перевіряє правильність кожної стислий версії чи ні, використовуючи декомпресор Денніса sss, який використовує Jelly (перейдіть прямо до джерела)
  • Ви можете побачити всі різні стислі рядки, зробивши перший аргумент командного рядка --debug, який замість того, щоб просто показувати найкоротший стислий рядок, показує всі 3 разом із копією "Це найкоротший"
  • Програма обробляє "не слова"

Не-слова

Я почав працювати над компресором Лінна після того, як побачив це повідомлення, зламав його і засмутився тим, що я не зміг знайти найкоротший спосіб його стиснення (це 29 або 32 байти для запису). Однак під час тестування моїх вдосконалень я виявив, що таких слів, як немає, knownsє в словнику Jelly. Тому я вирішив знайти спосіб стиснути ці "не слова" в найкоротшій можливій формі Jelly.

Я створив функцію ( trim), яка розбиває рядок як точку, де принаймні однією з частин рядка є слова. Наприклад, knownsбуло б розділено на програму, ["known", "s"]і програма додати перше слово через словник add ( .dictionary) та другу частину слова за допомогою .stringвиклику. Але це все ще залишає два крайні випадки: рядки, у яких немає слів (наприклад ajdl), і не слова, які мають слова в кінці, наприклад abctest, які не розбиваються на trimфункцію.

Оскільки немає способу знайти слова в рядку, в якому немає слів, найпростіший і найкоротший спосіб впоратися з ними - додавання їх у символі за допомогою .stringвиклику. Так ajdlби додали .string('ajdl'). В той час як не-слова, які закінчуються розпізнаними словами, по суті реалізує тример, але зворотно, а застосовуючи .dictionaryі .stringнавпаки, до тримеру вперед.

Як виявляється, обрізка струни, починаючи з початку або до кінця, звичайно, коротша, ніж додавання кожного символу до компресора, як продемонстровано вхідним abctest this stringсигналом, який видає вихід налагодження

Original        : abctest this string

Optimised       : “¡J+v(p⁸ụƘ$,»
Seperate spaces : “Ç⁴ṭḍµḄ7oeṂdḷp»
No trimmer      : “¤ɦ?Ɓ¢#fḲOạ⁾¶ɼȥƬ»
All characters  : “µẓþ"Y7_ḣṗḢ))9Þ⁴⁺Ẉ²)ɱ»
Non-compressed  : “abctest this string
Shortest        : “¡J+v(p⁸ụƘ$,»
=====

Різниця між оптимальним виходом (для якого використовується тример) та тим, що не є, є колосальним (для Jelly) 4 байтами. Нарешті, бувають випадки, коли сам рядок коротший за будь-яку стиснуту версію, про яку зараз було враховано.

Звичайно, велика заслуга в цьому припадає на Лінн за створення оригінального компресора


Якщо це буде видалено зараз, коли у нас є codegolf.stackexchange.com/a/151721/39328 ?
lirtosiast

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

10

Ви можете використовувати індексний сценарій від трьох до дев'яти ( ³⁴⁵⁶⁷⁸⁹) для гольфу деяких зазвичай використовуваних значень, але це залежить від кількості аргументів командного рядка, а у випадку посилань - від аргументів посилань.

  • ³ повертає 100 і працює лише за відсутності вводу.
  • повертає 16 і працює лише у тому випадку, якщо є щонайбільше один вхід.
  • повертає 10 і працює лише за наявності найбільших двох входів.
  • повертає пробіл, якщо є щонайбільше три входи.
  • повертає новий рядок, якщо є щонайбільше чотири входи.

Якщо вхід є п'ять, то вам не пощастило.

Нещодавно нова версія мови знизила значення ³до 100 і ввела кілька нових атомів, які повертають значення або (для посилань) їх аргументи.

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

Якщо ви перебуваєте в посиланні і маєте аргументи з обох сторін, але вам не пощастило.


1
Насправді невикористані входи заповнюються за замовчуванням! Така зручність!
CalculatorFeline

9

Зловживайте рядковими помилками

Кредити йдуть до Аднана, щоб скористатися цим першим у Написати програму для еластичності рядків .

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

Наприклад

“abcd”Ḥ

зараз не повинен робити нічого корисного, але оскільки (unhalve) реалізований як

lambda z: z * 2

і арифметичні атоми векторизуються на глибині 0 (тобто вони діють на числа або символи), наведений вище код Jelly дає

['aa', 'bb', 'cc', 'dd']

Будьте уважні, що це створює фактичні рядки Python (тип Jelly, як передбачається, не має), тому це не буде корисним у будь-яких ситуаціях.

Так само +/може бути корисно об'єднати рядки з однаковими застереженнями.


Отже, якщо в майбутньому, коли буде додана арифметика символів, ви додасте до цих атомів перевантаження типів для рядків та інших нечислових типів?
милі

1
Більш-менш. Я планую створити числовий тип, який є внутрішньо числом, але має прапор символів. Цей прапор впливав би лише на друк; символи можуть використовуватися замість цілих чисел скрізь.
Денніс

1
Sніколи не може бути корисним для об'єднання рядків, вони намагатимуться додати 0їх.
Ерік Аутгольфер

@EriktheOutgolfer Правий, прискіпливий базовий випадок. +/працює, хоча.
Денніс

@Dennis Так, я зараз дуже сильно виграв виклик +/.
Ерік Аутгольфер

8

Оптимальний струновий компресор

Нещодавно я попросив Еріка Outgolfer додати оптимізований струновий компресор на сторінку посилань на JHT , але вони сказали це

Вибачте, але цей компресор, здається, не виконаний повністю,
він каже, що “ugtestslug”це найкоротший термін ugtestslug, а “#ṀȮụḄPƇ»також виконує цю роботу

Тому я вирішив реалізувати оптимальний струмовий компресор.

Простий підхід, але гарантує знайти найменше можливе значення (а значить, і кількість байтів)

Отримати вхід з stdin, вивести на stdout. Так само, як оригінальний компресор, або (буквальний символ нового рядка) можна ввести як новий рядок.

Якщо спробувати запустити його з великою кількістю розділових знаків (наприклад, введення ¶-----¶), виведеться нестиснений рядок.

Звичайно, велика заслуга в цьому припадає на Лінн за створення оригінального компресора .


7

Це частина того, що стало навчальним посібником для Jelki wiki .

Мовчазне програмування

Jelly - це мовчазна мова програмування. Це означає, що ви визначаєте посилання (функції), складаючи наявні посилання у ланцюг , не чітко розмовляючи про залучені аргументи. Який спосіб аргументів "протікає" через цю композицію визначається шаблоном, в якому розташовані посилання. Приклад цього буде наведено незабаром, але спочатку нам потрібно ввести деякі поняття.

Арность ланки є дуже важливим поняттям. Усі атоми - вбудовані, як +і ½- мають фіксовані арности. Посилання сортуються за трьома категоріями, залежно від їхньої глибини:

  • Нілади не беруть ніяких аргументів (arity 0); крім деяких команд вводу / виводу та стаціонарних команд, вони в основному представляють постійні значення. Наприклад, буквальне 3- це нілад.

  • Монади беруть один аргумент (сутність 1). (Тут немає зв’язку з функціональними монадами програмування .) Наприклад, ½(квадратний корінь) - це монада.

  • Діади приймають два аргументи (арту 2): аргумент зліва і справа. Наприклад, +є діада.

(Використовуючи прикметники, ми говоримо, що посилання є ніладичною , монадичною чи діадичною .)

То яка ж сукупність посилань, які ми визначаємо при написанні програми? За замовчуванням вони різноманітні - тобто, абонент повинен вказати, скільки аргументів використовувати, а у випадку основного посилання залежить від того, скільки аргументів передано програмою.

Як приклад - ланцюг +(додавання) та ½(квадратний корінь). Оскільки відповідні артерії елементів цього ланцюга дорівнюють 2 і 1, ми називаємо це 2,1-ланцюгом . У перекладача є специфічні правила для розбиття ланцюгів, виходячи зі своїх артерій: ці правила диктують, що, враховуючи вхід n, це нове посилання обчислює n + sqrt(n). (Ви можете прочитати як "... плюс його квадратний корінь." )

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


Чи є тріади?
Conor O'Brien

Ні! Мені цікаво бачити, як Денніс буде реалізовувати, скажімо, заміну рядків, що за своєю суттю тріадично ( replace(str, old, new)).
Лінн

Я не знаю Джеллі, але я знаю трохи Дж. Можливо, це може бути, скажімо string (operator) (list), де (list)бінарний список old, new. Це мало б сенс, желе має вбудований pairоператор. За цією схемою, однак, це буде два байти для оператора.
Conor O'Brien

5
Зачекайте ... ½квадратний корінь? Чому ні ½, гм ... половина? Чому б не для квадратного кореня? :(
Cyoce

@Cyoce тому H, що вже наполовину, очевидно: P
Ven

6

Це частина того, що стало навчальним посібником для Jelki wiki .

Структура програми

Кожен рядок програми Jelly - це визначення посилання . Посилання - це в основному функції. Нижній рядок означає " main": це посилання оцінюється за допомогою аргументів, переданих у командному рядку.

Тоді всі посилання, окрім останнього, є визначеннями функцій: ви можете посилатися на них за допомогою акторів . Наприклад, çє "посилання над цією, як бінарний оператор (діада)" . Розглянемо цей приклад програми , яка обчислює квадрат суми своїх аргументів:

+
ç²

Це на зразок псевдокоду:

define f:
    the built-in link +
define main:
    apply the dyad f
    square the result

6

Це частина того, що стало навчальним посібником для Jelki wiki .

Багатоланцюгові ланки

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

Розглянемо цю програму:

C+H

Це доповнення плюс половина . Він приймає вхідне значення nі обчислює (1-n)+(n/2). Я не надто захоплююче, я знаю. Але структура насправді така:

                                                    структура 1

Посилання, яке ми написали, саме по собі є насправді ланцюгом, що містить єдиний ланцюг.

Припустимо, що ми хочемо (1-n)+(1-n)(n/2)замість цього обчислити . Діадичний ланцюг спрацював: за правилами ланцюга він обчислює λ+(λ×ρ), що схоже на те, що нам потрібно. Однак просто замінити +на нашу програму не обійдеться: C+×Hце 1,2,2,1-ланцюг - доповнення, потім додавання (аргумент), а потім помноження на половину - обчислення ((1-n)+n)×(n/2).

Ми хочемо , щоб желе для лікування , як єдине ціле, і зробити 1,2,1-ланцюг суб-ланцюгів C, і H. Багатоланцюгові посилання дозволяємо робити саме це! Для їх побудови ми використовуємо ланцюгові роздільники øµð : на зображенні вище вони ввели новий синій прямокутник, розміром 0, 1 і 2 відповідно. У нашому випадку ми можемо згрупувати ланцюги так, як хочемо, написавши Cð+×µH:

                            введіть тут опис зображення

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


Як ви зробили ці діаграми з цікавості?
Conor O'Brien

4
Я намалював їх від руки в Paint.NET :)
Лінн

4
Оце Так! Вражає! Це було б круто для жорстких програм Jelly, як інструмент, який робить це. (Akin to HexagonyColorer або як його ще називають)
Conor O'Brien

5

Якщо TMTOWTDI, виберіть той, який відповідає вашому ланцюжку.

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

Наприклад, прямим способом взяття суми всіх масивів у двовимірному масиві є

S€

яка відображає атом суми над усіма елементами масиву.

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

*

який відображає кожен x двовимірного масиву на x x . Наприклад, для A = [[1, 2], [3, 1], [2, 3]] виклик ланцюга дасть вихід [[1, 4], [27, 1], [4, 27]] .

Тепер ми хочемо взяти суму кожної пари. На жаль,

*S€

не працює, оскільки *більше не діє як гачок (використовуючи A як правильний аргумент), але є вилкою , тобто перший раз S€застосовується до A , а результат - правильний аргумент *.

Виправити це досить просто:

*¹S€
*⁸S€

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

Однак є спосіб зберегти байт! На вершині ḅ1(конвертувати з унарного в ціле число) також обчислюється сума кожного масиву в A A , але, на відміну від цього S€, є діадичним посиланням.

Ланцюжок

*ḅ1

повертає [5, 28, 31] (за бажанням); оскільки є діадичним, *гачки замість вилки


"На вершині ḅ1"?
CalculatorFeline

На вершині J термінологія. У Jelly це тип ланцюга, який працює безпосередньо на останньому поверненому значенні, тому він виконується поверх попередньої ланки ланцюга.
Денніс

Ще одна причина ніколи не намагатися вивчити цю мову ...: P
CalculatorFeline

1
Я почував так само і щодо J / APL, але через деякий час це відчувається так само природно, як і будь-яка інша мова.
Денніс

4

Стиснення цілого числа

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

Тепер, коли Jelly має свою кодову сторінку як постійну, алгоритм стиснення цілих чисел найпростіше виражається в самому Jelly:

ḃ250ịØJ”“;;”’ṄV

Спробуйте в Інтернеті!

(Вищенаведена програма також містить чек, щоб показати значення, на яке розкладається ціле число.)

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


4

Використовуйте зовнішні продукти для створення корисних цілих матриць

Ось історія, яку я створив у цій публікації з трохи приємнішим форматуванням HTML-таблиці.

Зовнішній продукт швидко þможе бути приєднаний до діад і викликає діад на кожну пару елементів у його лівій та правій аргументах. Це стенограма для €Ð€. Наприклад, якби у нас був код, [1,2]+€Ð€[0,10]ми могли би його скоротити, [1,2]+þ[0,10] і вони отримали б обоє [[1,2],[11,12]]. Я буду називати діаду з þзастосованим (наприклад, ) діадемою зовнішнього продукту.

Коли ціле число є одним з аргументів зовнішньої діадії продукту, Jelly спочатку приймає діапазон цього числа, а потім використовує результат як аргумент. Знаючи це, наведений приклад можна додатково скоротити до 2+þ[0,10]. Це справедливо як для лівого, так і для правого аргументів зовнішньої діади продукту.

Деякі діаграми зовнішнього продукту, коли діють одночасно на ціле число, дають певні цілі матриці, які можуть бути корисними для гри в гольф (особливо мистецькі виклики ASCII), але в іншому випадку знадобиться багато байт. Наприклад, при застосуванні до цілого числа nвиходить n×nматриця ідентичності. Спробуйте в Інтернеті!

Нижче наводиться таблиця діад і тип матриць, які вони отримують, перетворюючись на зовнішні діади добутку та діючи монадично на ціле число. Діади, перелічені в одному рядку, дають ті самі матриці. Є діади я не включені в таблиці , як &, |, %, w, і що також виробляє ціле число матриць , але їх модель не так просто , і, ймовірно , буде корисно в меншій кількості ситуацій. Спробуйте в Інтернеті!

+ ------------------------------------------------- ---- +
| Діад | Отримана матриця | Приклад |
+ ------------------------------------------------- ---- +
| = ⁼ | | 1 0 0 |
| ċ | Матриця особи | 0 1 0 |
| | | 0 0 1 |
+ ------------------------------------------------- ---- +
| | Елементи вище діагоналі дорівнюють 1, | 0 1 1 |
| <| всі інші елементи дорівнюють 0 | 0 0 1 |
| | | 0 0 0 |
+ ------------------------------------------------- ---- +
| | Елементи нижче діагоналі дорівнюють 1, | 0 0 0 |
| > | всі інші елементи дорівнюють 0 | 1 0 0 |
| | | 1 1 0 |
+ ------------------------------------------------- ---- +
| | Діагональні елементи дорівнюють 0, | 0 1 1 |
| n ⁻ | елементи діагоналі - 1 | 1 0 1 |
| | | 1 1 0 |
+ ------------------------------------------------- ---- +
| a ȧ | | 1 1 1 |
| ṛ ị | Індекс рядків кожного елемента | 2 2 2 |
| | | 3 3 3 |
+ ------------------------------------------------- ---- +
| o ḷ | | 1 2 3 |
| ȯ | Індекс стовпців кожного елемента | 1 2 3 |
| | | 1 2 3 |
+ ------------------------------------------------- ---- +
| | Головна діагональ - 0, верхня | 0 1 2 |
| _ | діагоналі дорівнюють 1, 2 ..., нижній | -1 0 1 |
| | діагоналі -1, -2 ... | -2 -1 0 |
+ ------------------------------------------------- ---- +
| | Головна діагональ - 0, нижня | 0 -1 -2 |
| _ @ | діагоналі дорівнюють 1, 2 ..., верхня | 1 0 -1 |
| | діагоналі -1, -2 ... | 2 1 0 |
+ ------------------------------------------------- ---- +
| | Головна діагональ - 0, верхня | 0 1 2 |
| ạ | а нижні діагоналі дорівнюють 1, | 1 0 1 |
| | 2, 3 ... | 2 1 0 |
+ ------------------------------------------------- ---- +
| | | 2 3 4 |
| + | Індекс рядків плюс індекс стовпців | 3 4 5 |
| | | 4 5 6 |
+ ------------------------------------------------- ---- +
| | Мінімум рядка | 1 1 1 |
| «| та індекси стовпців | 1 2 2 |
| | | 1 2 3 |
+ ------------------------------------------------- ---- +
| | Максимум рядка | 1 2 3 |
| »| та індекси стовпців | 2 2 3 |
| | | 3 3 3 |
+ ------------------------------------------------- ---- +

2

Перерахуйте команди та літерали

Якщо ви спробуєте використати багато невекторизуючих команд списку в літералі n чи списку літералів z , команда list спочатку перетвориться на якийсь список, а потім виконає команду в цьому списку.

Ці команди, як видається, використовують дзвінки до iterableфункції в jelly.py .

def iterable(argument, make_copy = False, make_digits = False, make_range = False):
    the_type = type(argument)
    if the_type == list:
        return copy.deepcopy(argument) if make_copy else argument
    if the_type != str and make_digits:
        return to_base(argument, 10)
    if the_type != str and make_range:
        return list(range(1, int(argument) + 1))
    return [argument]

Ось деякі неповні списки того, що будуть виконувати ці команди списку.

Обгортання списку

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

-------------------------------------------------------------------------------
| Command | Description     | Process                       | Effect          |
-------------------------------------------------------------------------------
| F       | Flattens a list | 4953F -> [4953]F -> [4953]    | Same as W       |
-------------------------------------------------------------------------------
| G       | Format a list   | 4953G -> [4953]G -> [4953]    | Same as W       |
|         | as a grid       |                               |                 |
-------------------------------------------------------------------------------
| I       | Increments      | 4953I -> [4953]I -> <nothing> | Empty list      |
-------------------------------------------------------------------------------
| S       | Sums a list     | 4953S -> [4953]S -> 4953      | Same as ¹       |
-------------------------------------------------------------------------------
| Ṭ       | Boolean array,  | 4Ṭ -> [4]Ṭ -> [0, 0, 0, 1]    | n-1 zeroes,     |
|         | 1s at indices   |                               | 1 at end        |
-------------------------------------------------------------------------------
| Ụ       | Sort indices by | 4Ụ -> [4]Ụ -> [1]             | Yields [1]      |
|         | by their values |                               |                 |
-------------------------------------------------------------------------------
| Ė       | Enumerate list  | 4Ė -> [4]Ė -> [[1, 4]]        | Yields [[1, n]] |
-------------------------------------------------------------------------------
| Ġ       | Group indices   | 4Ġ -> [4]Ġ -> [[1]]           | Yields [[1]]    |
|         | by values       |                               |                 |
-------------------------------------------------------------------------------
| Œr      | Run-length      | 4Œr -> [4]Œr -> [[4, 1]]      | Yields [[n, 1]] |
|         | encode a list   |                               |                 |
-------------------------------------------------------------------------------

Перетворити на базу 10

Тут функції викликають iterableперетворення числа до списку його цифр D, а потім запуск цих цифр.

-------------------------------------------------------------------------
| Command | Description     | Process                      | Effect     |
-------------------------------------------------------------------------
| Q       | Unique elements | 299Q -> [2, 9, 9]Q -> [2, 9] | Unique     |
|         | ordered by      |                              | digits     |
|         | appearance      |                              | of n       |
-------------------------------------------------------------------------
| Ṛ       | Non-vectorized  | 4953Ṣ -> [4, 9, 5, 3]Ṛ       | Reverses D |
|         | reverse         | -> [3, 5, 4, 9]              |            |
-------------------------------------------------------------------------
| Ṣ       | Sort a list     | 4953Ṣ -> [4, 9, 5, 3]Ṣ       | Sorts D    |
|         |                 | -> [3, 4, 5, 9]              |            |
-------------------------------------------------------------------------

Перетворити на список із діапазоном

Тут функції перетворюють число в діапазон R = [1 ... n], а потім виконують цей діапазон.

-----------------------------------------------------------------------------------------
| Command | Description       | Process                             | Effect            |
-----------------------------------------------------------------------------------------
| X       | Random element    | 4R -> [1 ... 4]X -> 2               | Random element    |
|         |                   |                                     |  of R             |
|         |                   |                                     |                   |
-----------------------------------------------------------------------------------------
| Ḋ       | Dequeue from list | 4R -> [1 ... 4]Ḋ -> [2, 3, 4]       | Range [2 ... n]   |
-----------------------------------------------------------------------------------------
| Ṗ       | Pop from list     | 4Ṗ -> [1 ... 4]Ṗ -> [1, 2, 3]       | Range [1 ... n-1] |
-----------------------------------------------------------------------------------------
| Ẇ       | Sublists of list  | 4Ẇ -> [1 ... 4]Ẇ                    | All sublists of R |
|         |                   | -> [[1], [2], [3], [4], [1, 2],     |                   |
|         |                   |     [2, 3], [3, 4], [1, 2, 3],      |                   |
|         |                   |     [2, 3, 4], [1, 2, 3, 4]]        |                   |
-----------------------------------------------------------------------------------------
| Ẋ       | Shuffle list      | 4Ẋ -> [1 ... 4]Ẋ -> [2, 1, 3, 4]    | Shuffles R        |
-----------------------------------------------------------------------------------------
| Œ!      | All permutations  | 3Œ! -> [1, 2, 3]Œ!                  | All permutations  |
|         | of a list         | -> [[1, 2, 3], [1, 3, 2],           | of R              |
|         |                   |     [2, 1, 3], [2, 3, 1],           |                   |
|         |                   |     [3, 1, 2], [3, 2, 1]]           |                   |
-----------------------------------------------------------------------------------------
| ŒḄ      | Non-vectorized    | 4ŒḄ -> [1 ... 4]ŒḄ                  | Bounces R         |
|         | bounce,           | -> [1, 2, 3, 4, 3, 2, 1]            |                   |
|         | z[:-1] + z[::-1]  |                                     |                   |
-----------------------------------------------------------------------------------------
| Œc      | Unordered pairs   | 4Œc -> [1 ... 4]Œc                  | Unordered pairs   |
|         | of a list         | -> [[1, 2], [1, 3], [1, 4], [2, 3], | of R              |
|         |                   |     [2, 4], [3, 4]]                 |                   |
-----------------------------------------------------------------------------------------
| Œċ      | Unordered pairs   | 4Œċ -> [1 ... 4]Œċ                  | Unordered pairs   |
|         | with replacement  | -> [[1, 1], [1, 2], [1, 3], [1, 4], | with replacement  |
|         | of a list         |     [2, 2], [2, 3], [2, 4], [3, 3], | of R              |
|         |                   |     [3, 4], [4, 4]]                 |                   |
-----------------------------------------------------------------------------------------
| ŒP      | Powerset of       | 3ŒP -> [1 ... 3]                    | Powerset of R     |
|         | a list            | -> ['', [1], [2], [3], [1, 2],      |                   |
|         |                   |     [1, 3], [2, 3], [1, 2, 3]]      |                   |
-----------------------------------------------------------------------------------------
| Œp      | Cartesian         | 4,2Œp -> [[1 ... 4], [1 ... 2]]Œp   | Cartesian product |
|         | product of z's    | -> [[1, 1], [1, 2], [2, 1], [2, 2], | of [1 ... z[i]]   |
|         | items             |     [3, 1], [3, 2], [4, 1], [4, 2]] | for i in z        |
-----------------------------------------------------------------------------------------

Це не зовсім точно. Так, Dequeue і декартовій твір це зробити, але сума обгортання замість створення діапазону, сортування і зворотного перетворення в підставі 10 першого.
Денніс

2

Іноді варто читати зі стандартного вводу, коли рівно два входи

Jelly оптимізовано для отримання даних з аргументів командного рядка. Однак він також оптимізований для написання монад, а не діад; з діадами існує стільки можливих значень для кожного вбудованого, що вам часто потрібно витрачати символів, щоб роз'єднатись, тоді як з монадами, як правило, існує багато способів сказати те саме.

Таким чином , якщо ви використовуєте один з двох входів тільки один раз, і проблема така , що вона не може бути легко неявно читати (тобто вам необхідно або зробити явним, або ж провести символ на }, @чи щось таке) , розгляньте читання його зі стандартного введення, Ɠа не розміщення його в командному рядку; що дозволяє точно розмістити вхід право там, де вам це потрібно, розміщуючи ваш Ɠ, гарантуючи при цьому, що будь-який інший неявний вклад буде взято з вашого іншого вводу. Це коштує байт і економить байт, і залежно від проблеми, цілком може заощадити другий байт, надавши більше можливостей для впорядкування коду.


2

Існує кілька неочевидних способів перевірити властивості аргументу за допомогою Ƒ. Нижче наведено декілька. Я залишив поза багато застосувань цього короткого (наприклад , ŒuƑ, ) , тому що вони вже найпростіші способи досягнення їхньої поведінки.

OƑ  Is number?
ỌƑ  Is character? (errors on negative numeric input)
ḂƑ  Between 0 and 2? 0<=x<2 (python). <2aAƑƊ or of course ⁼Ḃ$ in Jelly.
ḞƑ  Is integer?
UƑ  Like `ŒḂ`, but checks if all sublists of depth 1 are palindromes.
ṠƑ  Is one of -1, 0, 1? (e-r1¤$)

Не соромтесь редагувати це, щоб додати більше цікавих справ.


2

Ви можете спробувати онлайн-редактор Jelly Balls, призначений для легкої побудови коду на Jelly Language .

Особливості включають:

  • Палітра команд з усіма атомами та символами синтаксису, організованими за типом
  • Онлайн-аналізатор розпізнає в коді літерали та 2-байтові атоми
  • Спрощений інтерпретатор Jelly interpreter для запуску коду Jelly на веб-сторінці в JavaScript
  • Прямі посилання для передачі коду в TIO або інший сеанс Jelly Balls
  • Автоматичні підказки
  • Оптимізовано для мобільних пристроїв

Спробуйте: https://jellyballs.github.io

Кульки з желе

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

Кульки з желе

  • Звіт про код, що показує опис кожного кроку

Кульки з желе

  • Сторінка рецептів з прикладами желе

Кульки з желе

  • Інтерактивна сторінка коду з 256 символів желе

Кульки з желе



3
Я думаю, посилання на IDE, що дозволяє писати Jelly без користувальницької розкладки клавіатури, є досить корисною порадою. Багато початківців Jelly боролися з цим.
Денніс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.