Теперь, когда я полностью зависим от Code Golf, возможно, пришло время попытаться освоить несколько языков для игры в гольф.
Учитывая, что я играю почти исключительно на JavaScript, Japt кажется логичным языком для начала. При следующей возможности я углублюсь в документацию, а пока, пожалуйста, опубликуйте любые советы, которые у вас есть для Japt, в ответах ниже.
Поскольку я новичок в японском языке и в целом в гольфе, если бы вы могли «переводить» ваши советы на JavaScript, где это возможно, это помогло бы мне разобраться с вещами.
Ответы:
Переход с JavaScript на Japt
Как вы, возможно, знаете, Japt - это просто сокращенная расширенная версия JavaScript. Я создал Japt, потому что устал от длинных имен свойств, таких как
String.fromCharCode(x)
иMath.floor(x)
, и от утомительного выполнения таких вещей, как создание диапазона. Вот тот минимум, который вам нужно знать при переходе с JavaScript на Japt:U
,V
,W
,X
,Y
, иZ
; полный массив хранится вN
. Результат последнего выражения печатается автоматически.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
для чисел).""
,0-9
,(
,+
,=
и т.д. - остаются теми же , когда transpiled (по большей части, во всяком случае).И это все, что вам нужно знать, чтобы написать базовый код Japt. Достижение максимальной мощности в гольф в Japt требует больше знаний, но это можно найти в других ответах.
Вот основной пример. Допустим, вы хотите взять строку символов ASCII и заменить каждый ее шестнадцатеричным символом. Вот как вы можете сделать это в JavaScript:
Теперь, чтобы преобразовать в Japt.
.split("")
в JS эквивалентноq""
в Japt, или даже короче, простоq
..join("")
также простоq
, разница в том, что объект является массивом, а не строкой..map(
естьm
,.charCodeAt(
естьc
и.toString(
естьs
. Так что наш код Japt может выглядеть так:В Japt, однако,
m
работает как со строками, так и с массивами, поэтому мы можем удалить обаq
s:Проверьте это онлайн! Как вы можете видеть в поле «JS-код», это напрямую переносится в:
Когда вы научитесь работать с Japt, вы будете все меньше и меньше фокусироваться на конвертации JavaScript и обратно и сможете писать код на Japt как на своем собственном языке. Вот объяснение, полностью исключающее часть JavaScript:
источник
Um_c s16
?¡Xc s16
:?Сжатие строковых массивов
Вступление
Если в вашем коде есть массив строк, самый очевидный способ сжать его - прогнать каждую строку по
Oc
отдельности. Для целей этого совета мы будем работать с массивом["lollipop","marshmallow","nougat","oreo"]
, который изначально весит 42 байта. Прохождение каждой строкиOc
дает нам:Это теперь 33 байта, достойная экономия.
Шаг 1
Но мы можем сделать лучше. Если мы присоединяем массив к строке, разделенной новой строкой, мы можем избавиться от скобок, запятых и лишних обратных символов и разделить их на новую строку, чтобы получить наш массив. Применение этого к нашему массиву примеров дает нам следующее:
Теперь до 26 байтов.
Шаг 2
Но мы можем сделать еще лучше! Мы могли бы использовать строчную букву для разделения строк вместо новой строки, которая может быть включена в сжатие.
z
не используется ни в одной из наших строк, поэтому давайте добавим это и посмотрим, как у нас получится.Ах, орешки - там нет улучшения; наш счетчик байтов увеличился на один! Там может быть еще одно письмо , вы могли бы использовать , но, в зависимости от ваших строк, не может быть достаточно мало , чтобы попробовать - в нашем примере есть 11:
b,c,d,f,j,k,q,v,x,y,z
. Попытка каждого была бы довольно утомительной, и вот тут-то и появился этот удобный инструмент ; передайте ему строки, разделенные новой строкой, и он попытается разграничить строки каждой буквой, не содержащейся ни в одной из них, и вывести:Выполнение нашего образца строк через это показывает, что
b
дает лучшие результаты:И вот, у вас это есть, у нас осталось всего 24 байта.
Шаг 3
Но мы можем сделать еще лучше! Если порядок строк в вашем массиве не имеет значения, возможно, существует другая перестановка в сочетании с другим разделителем, который может работать еще короче. Однако пробовать каждую возможность будет гораздо более утомительно. С нашими 4-мя строками можно попробовать 24 разных сочетания. С каждой из 11 возможных букв становится 264! Вот где этот инструмент вступает в игру. Опять же, введите в него строки, разделенные новой строкой, и он попробует каждую комбинацию каждой перестановки и каждой буквы-разделителя, выведя:
Пропуск наших примерных строк показывает, что
"nougat","oreo","lollipop","marshmallow"
при использованииb
в качестве разделителя можно получить наилучшие результаты, а конечное число байтов составляет всего 23:Бонусный совет: сжатие целочисленных массивов
Вы можете применить тот же принцип к массивам целых чисел, сначала преобразовав каждое из них в более высокое основание. Используя этот пример, 36-байтовый массив:
Мы можем уменьшить это до 29 байт, сначала преобразовав его в массив из 32 строк, а затем запустив его через первую программу сжатия:
Или всего 27 байт, используя вторую программу:
Возможно, вы сможете сохранить еще один байт или 2, переместив целочисленное преобразование в метод, который вы уже выполняете в массиве.
Примечания
q<letter>(<space>)
затрат·
. Хотя вы можете использовать один из ярлыков Unicode для возврата байта в зависимости от вашего разделителя (qÊ
такой же, какql<space>
, например).кредиты
источник
Сжатие строк
Japt (в настоящее время) использует библиотеку shoco для сжатия строк. Вы можете сжать произвольную строку, используя
Oc
, если она содержит серии строчных букв:Это выводит
HÁM, WŽld!
(ну,Ž
технически это непечатный символ). Вы можете распаковать это, обернув его в кавычки:Проверьте это онлайн!
Кроме того, вы можете использовать
Od
функцию для распаковки произвольной строки. Обычно это не полезно, но у него есть свои цели ...источник
HÁM, WŽld!
или это должно быть заключено в кавычки? Я предполагаю последнее.Сокращение чисел с помощью Char-кодов
В Japt вы можете использовать
#
символ, за которым следует символ, для создания кода. Это очень удобно при сокращении длинных чисел.Как упоминалось в @ETHproductions, это работает только для трехзначных прогонов в диапазоне 100-255, если вы не готовы перейти на UTF-8.
Примеры:
123
можно сократить до#{
101
можно сократить до#e
Вы даже можете связать их вместе:
123101
можно сократить до#{#e
Вы можете использовать
String.fromCharCode(123)
в JavaScript или123d
в Japt, чтобы найти соответствующий символ.String.fromCharCode(123)
возвращается{
источник
String.fromCharCode()
это один из тех (многих!) мерзких длинных методов JS, которые могут увеличить количество байтов. Предположительно, они будут считаться целыми числами? то есть, если мне нужно целое число123
в решении, я мог бы использовать,#{
чтобы сохранить байт.-Q
флаг в окно ввода, вы сможете лучше просмотреть тип вывода: кавычки вокруг строк , массивов и т. Д.String.fromCharCode(123)
работает в JavaScript, но вы можете сделать123d
в Japt, чтобы получить тот же результат ;-) Кроме того, это работает только для трехзначных прогонов в диапазоне100
-255
(если вы не хотите переключиться на UTF-8)Быстрый совет: пустой массив
[]
Japt имеет константу для пустого массива:
A
. Но, чтобы получить к нему доступ, вы должны добавить точку;
с запятой к вашей программе, чтобы использовать альтернативные константы Japt, иначеA
будет10
. Таким образом , используя;A
фактически предлагает 0 байт экономии более[]
, но будет сэкономить байты , если вам нужно , чтобы присвоить массив переменного (например,A=[]
).Однако, если (и только если) ваша программа не принимает никаких входных данных, вы можете получить доступ к пустому массиву с помощью всего 1 байта, используя
N
переменную, которая является массивом входных данных - без входных данных она будет пустой. Попробуйте это здесь .Это также имеет дополнительное преимущество, заключающееся в том, что вы можете использовать значения констант по умолчанию в вашей программе и, в некоторых случаях, все еще могут сэкономить ваши байты по сравнению с использованием,
;A
даже когда ваша программа принимает данные благодаря сочетаниям клавишs1
иs2
.источник
N
, хорошая идея.Оценка JavaScript
Japt позволяет вам выполнять сырой JavaScript, оборачивая его
$...$
.Например,
$alert("hello world")$
Это можно сократить, воспользовавшись автоматическим закрытием Japt
$
и)
.$alert("hello world")$
можно сократить до$alert("hello world"
Сжатие JavaScript
Вы также можете сжать JavaScript с помощью
Ox
.Если есть функция JavaScript, которую вы хотите использовать, скажем
screen.width
, вы можете сжать строку,"screen.width"
используяOc
, а затем вставить результат между Ox` ... `Обратите внимание, что вам не нужно закрывать кавычки в Japt, когда за ним ничего не следует.
источник
Ox
чтобы оценить строку. В противном случае вы бы просто вывели текст"screen.width"
. ПримерЗнай флаги
В соответствии с последним мета-консенсусом (декабрь 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
, а не «любая строчная функция алфавита».)источник
Юникод ярлыки
Есть много общих структур в Japt , которые просто не могут быть сохранены в одном ASCII полукоксе, такие как
qS
,p2
,mX{
,}
и т.д. Таким образом , чтобы обойти эту проблему , Japt имеет «ярлыки Unicode», которые являются символами в диапазоне\xA1
-\xDE
(¡
-Þ
) которые распространяются на эти общие структуры. Вы можете найти полный список этих документов в документации для переводчиков .Кроме того,
@
стоит заXYZ{
, и_
означаетZ{Z
, в функции помогают строить. Итак, давайте попробуем наш пример программы из другого ответа :Во-первых, мы можем заменить
X{X
на_
, что дает нам:Тогда мы можем заменить
m_
с®
экономией других байт:Или мы могли бы заменить
X{
с@
, что дает нам:Это позволяет нам использовать
¡
ярлык для сохранения двух байтов:Один из этих двух путей может быть сокращен на 1 байт больше, чем другой. Вы можете выяснить, какие?
источник
®c s16
за 6 байтов - выиграть ли мне печенье ?!®c sG
?csG
.Воспользуйтесь преимуществами предустановленных переменных
Переменные
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 двухбайтовых переменных, для которых будут заданы эти значения, и многое другое.источник
Используйте авто-функции
Скорее всего, вы уже знаете, что
@
и_
являются ярлыками дляXYZ{
иZ{Z
, соответственно (рассматриваются в сочетаниях клавиш Unicode ответе на ). Но иногда вы можете сделать функции еще короче.Предположим, у вас есть массив символов, и вы хотите отобразить каждый символ на его код. Вы можете сделать это с помощью одного из следующих:
Но есть и лучший способ. Если метод или оператор является первым элементом после другого метода или a
(
, он превращается в строку. Итак, эти две строки эквивалентны:Но как это помогает с нашими функциями? Ну, большинство методов, которые принимают функции, если дана строка, представляющая метод или оператор, будут интерпретировать его как функцию. Это означает, что вы также можете сделать это:
Я называю эти "авто-функции". Есть несколько разных сортов:
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!²
.Неявное присвоение переменной
Всякий раз, когда вы начинаете новую строку в Japt, результат предыдущей строки автоматически присваивается одной из входных переменных (
U
-Z
), где первая строка -U
втораяV
, и так далее.Давайте рассмотрим пример: скажем, вы хотите создать 2 массива для работы, один из которых содержит числа 1-10, а другой - их квадраты. Долгий путь сделать это будет так:
Однако, используя автоматическое присвоение переменных, это можно сократить до:
Мы сохранили 4 байта там. Но в этом случае мы можем сохранить еще один байт, потому что массив 1-10 назначен
U
иU
может быть опущен в определенных сценариях :предосторожность
С этим советом следует быть осторожным: вы не перезаписываете входные переменные, которые вам могут понадобиться позже в вашей программе. Этого можно избежать, оставив одну или несколько пустых строк в начале. В следующем примере 2 массива будут назначены переменным
V
&W
вместоU
&V
:источник
Знать Javascript
Так как любой код Japt работает как переносимый JS, хорошее понимание операторов JS и встроенных методов очень помогает в освоении фрагментов кода Japt.
Соответствующие советы JS
U
и затем оцениваетV.m
. (Наличие новой строки активирует неявное присваиваниеU
в первой строке.)0
более'0
).Соответствующие встроенные функции JS
Внимательно посмотрите, какие параметры передаются в аргументы функции.
Array.prototype.map
Array.a/b/m/x/y/í
,Number.o/õ
,String.m/y/í
Array.prototype.reduce
Array.r/å
,String.å
; дляå
4-й аргумент не передается.Array.prototype.some
Array.d
Array.prototype.every
Array.e
Для строковых методов полезно знать, как различается поведение при передаче строки или регулярного выражения с
g
флагом или без него .String.prototype.match
String.f/o
String.prototype.search
String.â
String.prototype.replace
String.e/k/r
e/r
передачи функций в качестве 2-го аргумента все в порядке, и понимание параметров функции настоятельно рекомендуется.источник
Используйте несколько строк при необходимости
Для большинства несложных задач вы можете выразить решение в одной строке 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
на следующую строку, чтобы код выглядел следующим образом:и перенесенный JS становится:
Вы можете ясно видеть, что это делает то же самое, что и однострочное решение, просто присваивая промежуточный результат обратно
U
.Рекурс с неявными аргументами
Функция рекурсии
ß
принимает всеUVWXYZ
как неявный параметр, если не указан.U
Очевидно, это основной вход, но вы можете использовать любой из,VWXYZ
чтобы отслеживать другие значения, которые вам нужны. Например, вы можете сделать что-то вроде следующего:В качестве альтернативы, если вам нужна только временная переменная, вы можете использовать встроенное присваивание, например
(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
.источник
Fun с авто-функциями
В качестве дополнения к общему совету ETH по автоматическим функциям , этот совет предоставит несколько конкретных примеров приемов сохранения байтов, которые вы можете достигнуть с их помощью, и я добавлю к ним больше, чем я думаю.
Получить наибольшее целое число в массиве.
Предположим, у нас есть массив,
[3,1,4,2]
присвоенный переменной,U
и мы собираемся извлечь из нее наибольшее число. Мы могли бы сделать это в 4 байта, отсортировав массив и затем вытолкнув последний элемент:Недостатком является то, что мы изменили исходный массив;
U
сейчас,[1,2,3]
что не всегда может быть желательным. К счастью, есть способ сделать это без изменения массива, который также на один байт короче:То, что мы сделали, - это уменьшение массива с помощью
w
метода, который при использовании целого числа возвращает большее из целого числа и аргумента метода (например,2w5
возвращает5
). Таким образом, приведенное выше является эквивалентомUrÈwY
илиUrXY{XwY}
. Обратите внимание, что этот совет не будет работать в случае, если все целые числа в массиве отрицательны.источник
Когда не использовать
í
í
полезная встроеннаяzip
функция, которая связывает (или соединяет ) два массива или строки и, необязательно, отображает каждую пару через функцию. Тем не менее, в настоящее время у него есть несколько незначительных проблем при использовании неравномерных массивов или строк:undefined
.Это может затруднить, скажем, сравнение двух неравных строк и взять символ с более высоким кодом из каждой пары. Даже если вы знаете, что
U
он будет длиннее, для решения этой простой задачи все равно требуется много байтов:Вместо этого вы можете взять входные данные в виде массива из двух строк, транспонировать массив с помощью
y
, а затем сопоставить каждую строку с правильным результатом:Преимущество этого заключается в том, чтобы всегда заполнять более короткую строку пробелами, превращая ее в кусок пирога, чтобы пройти через все две строки.
Реальные примеры: 1 , 2
источник
Генерация диапазона ASCII
Хотя у Japt (пока) нет встроенной функции для диапазона ASCII, вы можете сгенерировать массив символов всего за 5 байтов:
Попытайся
Как это устроено
95o
создает диапазон[0,95)
с каждым элементом, пропускаемым через авто-функцию,d
которая при использовании в числе возвращает символ в этой кодовой точке. Передайте число в качестве аргументаd
методу, в этом случаеH
константу Japt для 32, и оно будет добавлено к исходному числу перед преобразованием.Эквивалентное решение в JavaScript будет:
Случайные персонажи
Чтобы получить случайный символ в диапазоне ASCII, используйте
ö
вместо него, который возвращает случайное число из диапазона[0,X)
, гдеX
это число, на котором он запускается.Или, чтобы получить массив из нескольких случайных символов, передайте количество символов, которое вам нужно в качестве аргумента
ö
. Следующее вернет 10 символов:источник
Удалить ненужные структурные символы
К структурным гольцов, я имею в виду
{}
,()
,$
даже"
и`
. Обычно вы можете удалить эти символы, когда они появляются в конце программы (например,UmX{Xc +"; "} -> UmX{Xc +";
).Кроме того, вы можете удалить символы скобок или пробелы, когда они появляются в следующих местах:
;
(или конца программы);{
(и, соответственно,@
) или[
, или слева от]
или}
.Кроме того, запятые очень редко нужны для разделения аргументов. Если ты пишешь
AB
, например, Джапт знает, что вы имеете в видуA
иB
отдельно. Вам действительно нужна запятая только для разделения двух числовых литералов, таких какUs2,5
.Наконец, если есть
U
в начале программы или после того,{
или;
, с последующим вызовом метода (строчные буквами или связанным с ярлыком Unicode) или любым бинарным оператором исключая+
и-
(*
,&
,==
и т.д.), вы можете удалить ,U
чтобы сэкономить Байт и Japt вставит его для вас.источник
U
их можно опустить, даже если это не в начале программы.{
или;
. Есть ли другие, о которых вы знаете? (Прошло много времени с тех пор, как я закодировал эту функцию: P)Изменить последний элемент в массиве
Иногда вам может понадобиться изменить последний элемент в массиве, так что вот объяснение краткого способа сделать это. Мы будем работать с массивом,
[2,4,8,32]
назначенным для входной переменнойU
и делением последнего целого числа (32
) на 2.Очевидный способ добиться этого - это 9-байтовое решение ( демонстрация ):
hnx
устанавливает элемент по индексуn
наx
.gn
возвращает элемент по индексуn
.J
константа Джапта для-1
, которая, благодаря поддержке отрицательного индекса Japt, позволяет нам работать с последним элементом в массиве; удобно, когда вы не знаете размер массива./2
это просто деление на 2.Так указанных множеств элементов по индексу
-1
в массиве к элементу с индексом-1
в массиве , деленное на 2. Или в JavaScript:U[3]=U[3]/2
. Когда ты так пишешь, кажется, что это слишком долгий путь. К счастью, есть более короткий путь; мы могли бы извлечь последний элемент из массива, изменить его и отправить обратно в массив. Выполнение каждой из этих операций по отдельности заняло бы более 9 байтов, но мы можем сделать их все одновременно всего за 7 байтов, сэкономив 2 байта ( демонстрация )В переводе на JS это эквивалентно:
источник