Советы по игре в гольф в Джапте


18

Теперь, когда я полностью зависим от Code Golf, возможно, пришло время попытаться освоить несколько языков для игры в гольф.

Учитывая, что я играю почти исключительно на JavaScript, Japt кажется логичным языком для начала. При следующей возможности я углублюсь в документацию, а пока, пожалуйста, опубликуйте любые советы, которые у вас есть для Japt, в ответах ниже.

Поскольку я новичок в японском языке и в целом в гольфе, если бы вы могли «переводить» ваши советы на JavaScript, где это возможно, это помогло бы мне разобраться с вещами.


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

Не забудьте посетить чат Japt :)
Оливер

Ответы:


11

Переход с JavaScript на Japt

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

  • Джапт - это трансплантированный язык; Код Japt переносится в 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).
  • 'обозначает одну символьную строку (то 'aесть совпадает с "a"), #принимает следующий код и становится этим числом ( #eсовпадает с 101).
  • Все, что находится между знаками доллара, $остается неизменным во время процесса переноса. Это можно использовать for, например, для реализации циклов, поскольку у Japt их нет, но я бы предложил использовать другие методы (например, mдля строк и массивов или oдля чисел).
  • Большинство других символов обычно используется в JS - "", 0-9, (, +, =и т.д. - остаются теми же , когда transpiled (по большей части, во всяком случае).

И это все, что вам нужно знать, чтобы написать базовый код Japt. Достижение максимальной мощности в гольф в 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

Может быть, лучше показать еще один шаг: ярлыки Юникода. В этом случае мы могли бы сохранить 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. Не забудьте учесть 1 или 2 дополнительных байтовых q<letter>(<space>)затрат ·. Хотя вы можете использовать один из ярлыков 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! в данном случае
Мартин Виссерс

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, результаты которых верны.
  • : Применяет -fи возвращает свой первый элемент.

gh

Принимает элемент по указанному индексу.

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

Преобразовать результат в логическое значение.

  • -!: Не применять логическое значение не.
  • : Применить логическое значение не дважды (возвращает правдивость).

N

Преобразовать результат в число. Одинарный плюс используется.

PRSQ

Конвертировать в какую-то строку.

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

x

Применяет функцию xк выходу. (Буквально x, а не «любая строчная функция алфавита».)

  • Array: Sum.
  • Строка: отделка с обоих концов.
  • Число: округлить до целого числа.

2
Обратите внимание, что использование флагов не считается отправкой Japt, а считается передачей языка Japt-with-specific-flags-language.
Нит

3

Юникод ярлыки

Есть много общих структур в 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!².
Лохматый

Ого! Я не думал об использовании строки в карте, даже не знал, что это возможно. Возможно, я сэкономлю несколько байтов благодаря этому в будущем.
RedClover

Эй @ Соаку, я почему-то пропустил, что ты отвечаешь с Джаптом, так что позволь мне поздороваться с тобой! Надеюсь, вам понравилось это до сих пор. Если у вас есть какие-либо вопросы, предложения или вы просто хотите поговорить, не стесняйтесь присоединиться к нам в чате 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@...
...

Соответствующие встроенные функции JS

Внимательно посмотрите, какие параметры передаются в аргументы функции.

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

  • String.prototype.match
    • Связанные методы Japt: String.f/o
  • String.prototype.search
    • Связанный метод Japt: String.â
  • String.prototype.replace
    • Связанные методы Japt: String.e/k/r
    • Для e/rпередачи функций в качестве 2-го аргумента все в порядке, и понимание параметров функции настоятельно рекомендуется.

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это один символ и Vвозвращает строку, или
    • $V($Uили [U]mV gвообще.
  • Тем не менее, отображение или циклы с ним довольно легко. Чтобы отобразить массив, используйте UmV. Чтобы найти первое целое число, которое удовлетворяет V, используйте Va.

2

Fun с авто-функциями

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


Получить наибольшее целое число в массиве.

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

Un o

Недостатком является то, что мы изменили исходный массив; Uсейчас, [1,2,3]что не всегда может быть желательным. К счастью, есть способ сделать это без изменения массива, который также на один байт короче:

Urw

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


1
Примечание: я планирую добавить функции для получения минимума и максимума массива, хотя, вероятно, только в версии 2.
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 , например, Джапт знает, что вы имеете в виду Aи Bотдельно. Вам действительно нужна запятая только для разделения двух числовых литералов, таких какUs2,5 .

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


Я обнаружил несколько других случаев, когда Uих можно опустить, даже если это не в начале программы.
Лохматый

@ Shaggy Да, конечно, это также работает после {или ;. Есть ли другие, о которых вы знаете? (Прошло много времени с тех пор, как я закодировал эту функцию: P)
ETHproductions

Не могу думать о них с макушки головы; Я проверю это снова, когда завтра вернусь к своему компьютеру.
Лохматый

1

Изменить последний элемент в массиве

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

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

UhJUgJ /2
  • hnxустанавливает элемент по индексу nнаx .
  • gn возвращает элемент по индексу n .
  • J константа Джапта для -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.