Это вдохновлено ответом 05AB1E от Magic Octupus Urn .
Имеется два аргумента, положительное целое число и строка / список символов:
- Переведите число в base-n, где n - длина строки.
- Для каждого символа замените каждое появление индекса этого символа в числе base-n этим символом.
- Распечатать или вернуть новую строку.
Примеры:
Input:
2740, ["|","_"]
2740 -> 101010110100 in base 2
-> Replace 0s with "|" and 1s with "_"
Output: _|_|_|__|_||
Input:
698911, ["c","h","a","o"]
698911 -> 2222220133 in base 4
-> Replace 0s with "c", 1s with "h", 2s with "a", and 3s with "o"
Output -> "aaaaaachoo"
Input:
1928149325670647244912100789213626616560861130859431492905908574660758972167966, [" ","\n","|","_","-"]
Output:
__ __
| |_| |
___| |___
- - - -
- - - - - - -
- - - - - - - -
_______________
Input: 3446503265645381015412, [':', '\n', '.', '_', '=', ' ', ')', '(', ',']
Output:
_===_
(.,.)
( : )
( : )
Правила:
- IO гибкий .
- Вы можете взять число в любой базе, если оно согласовано между входами
- Список символов должен быть индексирован 0, хотя 0 - первый символ, а n-1 - последний.
- Возможными символами могут быть любые печатные символы ASCII, а также пробелы, такие как символы табуляции и перевода строки.
- Данный список символов будет иметь длину в диапазоне
2-10
включительно. То есть самое маленькое основание является двоичным, а самое большое - десятичным (здесь не надоедливые буквы ) - Стандартные лазейки запрещены
- Не стесняйтесь отвечать, даже если ваш язык не выдерживает больших тестовых случаев.
Поскольку это код-гольф , выигрывает самый короткий код для каждого языка. ( Я знаю, что у всех языков игры в гольф есть встроенные встроенные байты ;)
code-golf
ascii-art
base-conversion
Джо Кинг
источник
источник
Ответы:
05AB1E ,
76 байтовПоскольку он был вдохновлен ответом 05AB1E, ответ, данный в 05AB1E, кажется подходящим. :)
-1 байт благодаря @Enigma , удалив foreach и сделав это неявно.
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
источник
gв¹sèJ
сохранить байт.¹sè
себе сейчас (я знал, что изменение на?
aJ
даст тот же результат в этом случае.)Java 8,
7250 байт-22 байта благодаря @ OlivierGrégoire , возвращая
IntStream
вместо печати напрямую.Попробуйте онлайн .
Объяснение:
источник
a->n->n.toString(a.length).chars().map(c->a[c-48])
(50 байт), поскольку "IO гибок"String f(char[]a,int n){return n>0?f(a,n/a.length)+a[n%a.length]:"";}
(69 байт) рекурсивный, для развлечения.Python 3 , 49 байт
Пока не могу комментировать, поэтому выкладываю ответ Python 2, адаптированный к Python 3.5.
источник
Japt, 2 байта
Может принимать второй вход в виде массива или строки. Сбой последних 2 тестовых случаев, так как числа превышают максимальное целое число JavaScript. Замените
s
на,ì
чтобы вместо него вывести массив символов.Попытайся
источник
Haskell ,
4039 байтПопробуйте онлайн!
Поскольку
Int
тип Хаскелла ограничен9223372036854775807
, это не подходит для больших чисел.-1 байт благодаря Лайкони .
Ungolfed
Попробуйте онлайн!
источник
cycle
вместоmod
!div n(length l)
сохраняет байт.MATL , 2 байта
Попробуйте онлайн!
Входные данные - это число и строка.
Сбой для превышения чисел
2^53
из-за точности с плавающей точкой.объяснение
Что
YA
знаете, встроенная (базовая конверсия с указанными целевыми символами).источник
JavaScript (ES6), 48 байт
Вводит синтаксис карри
(c)(n)
, где c - список символов, а n - целое число.Безопасно только для n <2 53 .
Попробуйте онлайн!
JavaScript (ES6), 99 байт
С поддержкой больших целых
Вводит в синтаксисе карри
(c)(a)
, где c - список символов, a - список десятичных цифр (в виде целых чисел).Попробуйте онлайн!
источник
32-разрядный машинный код x86 (32-разрядные целые числа): 17 байт.
(также см. другие версии ниже, включая 16 байтов для 32-битной или 64-битной версии с соглашением о вызовах DF = 1.)
Вызывающая сторона передает аргументы в регистрах, включая указатель на конец выходного буфера (как мой ответ C ; см. Его
_itoa
для обоснования и объяснения алгоритма.) Это делает внутренняя часть glibc , так что это не просто придумано для code-golf. Регистры передачи аргументов близки к x86-64 System V, за исключением того, что у нас есть аргумент в EAX вместо EDX.По возвращении EDI указывает на первый байт строки C с нулем в конце в выходном буфере. Обычный регистр возвращаемых значений - EAX / RAX, но на языке ассемблера вы можете использовать любое удобное для вызова соглашение о вызовах. (
xchg eax,edi
в конце добавил бы 1 байт).Вызывающий может вычислить явную длину, если он хочет, из
buffer_end - edi
. Но я не думаю, что мы можем оправдать исключение терминатора, если функция не возвращает оба указателя start + end или указатель + length. Это сэкономило бы 3 байта в этой версии, но я не думаю, что это оправдано.idiv
. Другие аргументы не являются неявными операндами.)dec edi
, поэтому должна быть в низком 4GiB)nasm -felf32 ascii-compress-base.asm -l /dev/stdout | cut -b -30,$((30+10))-
(Отредактировано вручную, чтобы уменьшить комментарии, нумерация строк странная.)Удивительно, что самая простая версия, в которой практически нет компромиссов между скоростью и размером, является наименьшей, но
std
/cld
стоит 2 байта, чтобы использоватьstosb
ее в порядке убывания и при этом следовать общему соглашению о вызовах DF = 0. (И STOS уменьшается после сохранения, оставляя указатель, указывающий один байт, слишком низким при выходе из цикла, что обходится нам лишними байтами для обхода.)Версии:
Я придумал 4 существенно разных уловки реализации (использование простой
mov
загрузки / сохранения (см. Выше), использованиеlea
/movsb
(аккуратно, но не оптимально), использованиеxchg
/xlatb
/stosb
/xchg
, и тот, который входит в цикл с хаком с перекрывающимися инструкциями. См. Код ниже) , Последнему нужен трейлинг0
в таблице поиска для копирования в качестве ограничителя выходной строки, поэтому я считаю это как +1 байт. В зависимости от 32/64-битного (1 байтinc
или нет) и от того, можем ли мы предположить, что вызывающая сторона устанавливает DF = 1 (stosb
нисходящий) или что-то еще, разные версии (привязаны) являются самыми короткими.DF = 1 для сохранения в порядке убывания делает выигрыш для xchg / stosb / xchg, но вызывающий часто этого не хочет; Это похоже на то, чтобы разгрузить вызывающего абонента трудным образом. (В отличие от пользовательских регистров передачи аргументов и возвращаемых значений, которые обычно не требуют от вызывающего asm дополнительной работы.) Но в 64-битном коде,
cld
/scasb
работает какinc rdi
, избегая усечения выходного указателя до 32-битного, поэтому иногда неудобно сохранять DF = 1 в 64-битных чистых функциях. , (Указатели на статический код / данные являются 32-разрядными в исполняемых файлах x86-64 без PIE в Linux и всегда в Linux x32 ABI, поэтому версия x86-64, использующая 32-разрядные указатели, может использоваться в некоторых случаях.) В любом случае, это взаимодействие делает интересным взглянуть на различные комбинации требований.nostring
) .stosb_edx_arg
илиskew
) ; или с входящим DF = dontcare, оставляя его установленным: 16 + 1Bstosb_decode_overlap
или 17Bstosb_edx_arg
stosb_decode_overlap
) , 18B (stosb_edx_arg
илиskew
)x86-64 с 64-битными указателями, другая обработка DF: 16B (DF = 1
skew
) , 17B (nostring
с DF = 1, используяscasb
вместоdec
). 18B (stosb_edx_arg
сохранение DF = 1 с 3 байтамиinc rdi
).Или если мы разрешаем возвращать указатель на 1 байт перед строкой, 15B (
stosb_edx_arg
безinc
конца в конце). Все готово к повторному вызову и расширению еще одной строки в буфере с другой базой / таблицей ... Но это имело бы больше смысла, если бы мы не хранили и завершение0
, и вы могли бы поместить тело функции в цикл, так что это действительно отдельная проблема.x86-64 с 32-разрядным выходным указателем, соглашение о вызовах DF = 0: улучшения по сравнению с 64-разрядным выходным указателем нет, но
nostring
теперь 18B ( ) связывается.skew
). Или установить DF = 1 и оставить его, 17B дляskew
с,std
но нетcld
. Или 17 + 1B дляstosb_decode_overlap
сinc edi
в конце вместоcld
/scasb
.С соглашением о вызовах DF = 1: 16 байтов (IA32 или x86-64)
Требует DF = 1 на входе, оставляет его установленным. Едва ли правдоподобно , по крайней мере, для каждой функции. Делает то же самое, что и вышеупомянутая версия, но с xchg для получения остатка в / из AL до / после XLATB (поиск таблицы с R / EBX в качестве базы) и STOSB (
*output-- = al
).При нормальном DF = 0 на входной / выходной конвенции, / / версия 18 байт для 32 и 64-битного кода, и является 64-битным (работает с выходным указателем 64-битной).
std
cld
scasb
Обратите внимание, что входные аргументы находятся в разных регистрах, включая RBX для таблицы (для
xlatb
). Также обратите внимание, что этот цикл начинается с сохранения AL и заканчивается последним еще не сохраненным символом (следовательно,mov
в конце). Таким образом, петля "перекошена" относительно других, отсюда и название.Подобная нескошенная версия выходит за рамки EDI / RDI, а затем исправляет ее.
Я попробовал альтернативную версию этого с
lea esi, [rbx+rdx]
/movsb
в качестве тела внутреннего цикла. (RSI сбрасывается при каждой итерации, но RDI уменьшается). Но он не может использовать xor-zero / stos для терминатора, поэтому он на 1 байт больше. (И это не 64-битная чистота для таблицы поиска без префикса REX на LEA.)LUT с явной длиной и разделителем 0: 16 + 1 байт (32-разрядный)
Эта версия устанавливает DF = 1 и оставляет это так. Я считаю дополнительный байт LUT, необходимый как часть общего количества байтов.
Крутой трюк здесь состоит в том, чтобы одни и те же байты декодировали двумя разными способами . Мы попадаем в середину цикла с остаток = основание и частное = входное число, и копировать терминатор 0 на место.
В первый раз через функцию первые 3 байта цикла потребляются как старшие байты disp32 для LEA. Этот LEA копирует базу (модуль) в EDX,
idiv
производит остаток для последующих итераций.2-й байт
idiv ebp
-FD
это код операции дляstd
инструкции, необходимой для работы этой функции. (Это было счастливое открытие. Я смотрел на этоdiv
ранее, что отличается отidiv
использования/r
битов в ModRM. 2-й байтdiv epb
декодирования какcmc
, что безвредно, но не полезно. Но сidiv ebp
помощью мы можем на самом деле удалитьstd
сверху функции.)Обратите внимание, что входные регистры снова отличаются: EBP для базы.
Этот трюк с перекрывающимся декодированием также можно использовать с
cmp eax, imm32
: для эффективного перехода вперед на 4 байта требуется всего 1 байт, только флаги засорения. (Это ужасно для производительности на процессорах, которые отмечают границы команд в кеше L1i, кстати).Но здесь мы используем 3 байта, чтобы скопировать регистр и перейти в цикл. Обычно это занимает 2 + 2 (mov + jmp) и позволяет нам перейти в цикл прямо перед STOS, а не перед XLATB. Но тогда нам понадобится отдельная ЗППП, и это будет не очень интересно.
Попробуйте онлайн! (с
_start
вызывающим абонентом, который используетsys_write
результат)Лучше всего для отладки запускать его
strace
или выводить в шестнадцатеричном формате, чтобы вы могли убедиться, что\0
в нужном месте есть терминатор и так далее. Но вы можете видеть, что это на самом деле работает, и производитьAAAAAACHOO
для ввода(На самом деле
xxAAAAAACHOO\0x\0\0...
, потому что мы выгружаем из буфера на 2 байта ранее до фиксированной длины. Таким образом, мы можем видеть, что функция записала байты, которые она должна, и не наступила ни на один байт, которого она не должна иметь. указатель начала, переданный функции, был вторым последнимx
символом, за которым следовали нули.)источник
Желе , 4 байта
Попробуйте онлайн!
ṃ
буквально встроенный для этого. Остальные три байта составляют индексирование Jelly на основе одного.источник
ṃ
« декомпрессию базы; преобразовать x в базовую длину (y), а затем индексировать в y. »? Это для очень исключительных случаев, когда база, которую вы хотите преобразовать, и длина строки / целого числа / списка равны? Когда я ищу его, я могу найти только три ответа, используя его: 1 ; 2 ; 3 . Что-то странное, встроенное в каждый день. : S“sspspdspdspfdspfdsp”
, но“çƥ÷£ḟ’ṃ“spdf”¤
вы сохраните шесть байтов. Это особенно полезно с базовыми 250 номерамиPython 2 ,
4948 байтов-1 байт благодаря Джо Кингу
Попробуйте онлайн!
Альтернативная версия (не подходит для больших чисел),
4543 байта-2 байта благодаря Джо Кингу
Попробуйте онлайн!
источник
Древесный уголь ,
31 байтаПопробуйте онлайн! Ссылка на подробную версию кода. Редактировать: Сохранено 2 байта благодаря @ ASCII-only. Предыдущая версия до добавления встроенной функции, 8 байт:
Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:
источник
θη
? Выглядит немного запутанно. Почему бы просто не удалить его полностью и не уйти⍘
?D 112 байт
Попробуйте онлайн!
Это порт ответа C ++ от HatsuPointerKun
Стиль вызова:
u(ulong(n), to!(char[])(b))
гдеn
и гдеb
левый и правый аргументыD конкретные вещи
К сожалению, нам нужно импортировать,
std.conv
чтобы делать любые преобразования типов сверх очень простых преобразований типов.Используя golfy системы шаблонов, и давая функцию необходимых типов (поэтому называть это не просто
u(n,b)
), мы можем сократить вхожденияchar[]
иulong
в1
байтах каждого, когда внутри й функций.D инициализирует наши типы для нас, поэтому
C t;
сокращенно дляC t=cast(char[])([])
to!C
преобразует целое числоn%l
в массив символов (используя кодовые точки) и~
выполняет конкатенациюforeach(ref c;t)
похоже наfor(... : ...)
цикл C ++ , но немного дольше.ref
похоже&
, он обрабатываетсяc
как скопированный по ссылке (т. е. мы можем изменитьt
). К счастью, D выводит типc
без какого-либо ключевого слова, обозначающего тип.источник
C ++,
150144 байта,uint64
ввод-6 байт благодаря Захари
Использование переменной для хранения размера увеличит количество пользователей на 1
Для вызова функции:
Сначала число, второе - строка (массив символов)
Тестовые случаи:
источник
#include
, вы можете изменить;;
на просто;
, и'0'
может быть просто48
for
циклом:for(;n;n/=b.size())t=std::to_string(n%b.size())+t;
b.size()
в этом цикле ничего не меняется.Веточка, 66 байт
Создан,
macro
который должен бытьimport
вставлен в шаблон.Ожидаемые значения:
Для первых аргументов (
n
):Для второго аргумента (
c
):Как использовать:
.twig
файл{% import 'file.twig' as uncompress %}
uncompress.d()
Ungolfed (нефункциональный):
Вы можете проверить этот код на: https://twigfiddle.com/54a0i9
источник
Pyth,
987 байтСохраненный байт благодаря hakr14 и еще одно спасибо Mr. Xcoder.
Попробуй здесь
объяснение
источник
m@Qd
на@LQ
vz
наE
.C89, ограниченный диапазон со знаком
int n
,6453 байтаchar **out
и измените его, вместо того, чтобы брать и возвращатьchar *
Принимает число как
int
, таблица поиска как массив + длина.Выход записывается в
char *outbuf
. Вызывающая сторона передает (по ссылке) указатель на конец буфера. Функция изменяет этот указатель так, чтобы он указывал на первый байт строки при возврате.Это действительно C89 и работает правильно даже при включенной оптимизации. то есть не зависит от
-O0
поведения gcc при падении с конца непустой функции или любого другого UB.Передача указателя в конец буфера является нормальной для оптимизированной функции int-> string, такой как встроенная
_itoa
функция glibc . Смотрите этот ответ для подробного объяснения разбиения целого числа на цифры с помощью цикла div / mod, как мы делаем здесь, в C, а также в x86-64 asm. Если основание является степенью 2, вы можете сдвинуть / замаскировать, чтобы сначала извлечь цифры MSD, но в противном случае единственный хороший вариант - сначала младшая цифра (с модулем).Попробуйте онлайн! , Безголовая версия:
В этой версии с явной длиной входными данными является a,
char table[]
который не нуждается в завершающем 0 байте, потому что мы никогда не рассматриваем его как строку. Это может бытьint table[]
для всех нас волнует. В C нет контейнеров, которые знают свою собственную длину, поэтому указатель + длина - это обычный способ передать массив с размером. Поэтому мы выбираем это вместо необходимостиstrlen
.Максимальный размер буфера приблизительно
sizeof(int)*CHAR_BIT + 1
, так что он маленький и постоянный во время компиляции. (Мы используем это много места с base = 2 и всеми битами, установленными на 1.) Например, 33 байта для 32-битных целых чисел, включая0
терминатор.C89, со знаком,
int
таблица как строка C неявной длины, 65 байтЭто то же самое, но входные данные являются строкой неявной длины, поэтому мы должны найти длину сами.
источник
Bash + основные утилиты , 49 байт
Попробуйте онлайн!
Комментарии / объяснение
Он принимает аргументы командной строки в качестве входных данных (число в базе 10, затем одну строку со списком символов) и выводит в стандартный вывод. Специальные символы , такие как пространство, символ новой строки, и т.д. , могут быть введены в восьмеричной записи (например,
\040
для пространства), или\n
для перевода строки,\t
на вкладке или любой другой управляющей последовательности , чтоecho -e
иtr
интерпретировать одинаково.Многие байты здесь предназначены для обработки специальных символов и больших тестовых случаев. Если мне нужно обрабатывать только не страшные символы, а цифры маленькие (например, первый тестовый пример), это сделают следующие 24 байта:
При этом используется расширение параметра
${#2}
для получения количества символов в строке, создается программа постоянного тока для выполнения базового преобразования, а затем отправляется преобразованное число черезtr
.Это не будет обрабатывать символы новой строки, пробелы или табуляции, поэтому, чтобы иметь дело с escape-последовательностями, не затрагивая основание, я делаю подсчет символов
wc -c
после интерпретации escape -кодовecho -en
. Это расширяет программу до 38 байт:К сожалению, у dc есть досадная «особенность», при которой, если он выводит большое число, он будет обтекать его последовательностью слеш + новая строка, поэтому в больших тестовых примерах этот дополнительный вывод получен. Чтобы удалить его, я передаю вывод dc,
tr -dc 0-9
чтобы удалить нечисловые символы. И вот мы здесь.источник
dc -e${#2}o$1p|tr 0-9 "$2"
воспринимать ввод буквально, а не в \ escaped-форме, чтобы он мог обрабатывать пробелы, ноtr
не имеет возможности, например, не рассматривать его-
как символ диапазона. Если на входе-
нет конца строки, он прерывается. Возможно, вы можете использоватьsed "y/0123456789/$2/"
. Нет, я думаю, нет, GNUsed
требует , чтобы оба аргументаy
были одинаковой длины, и кажется, что они задыхаются от перевода строки.APL (Dyalog Unicode) ,
14 1312 байтПопробуйте онлайн!
Инфиксная молчаливая функция; не может обработать самый большой тестовый пример из-за представления с плавающей запятой.
Благодаря @ Adám сэкономлено
12 байта!Для заголовков добавлено 13 байтов(Я забыл, что это не относится. )⎕IO←0
:: I ndex O rigin = 0 и⎕FR←1287
: F loat R epresentation = 128 бит.Как?
источник
Атташе , 17 байт
Попробуйте онлайн!
объяснение
источник
Холст , 7 байтов
Попробуй это здесь!
Прямая реализация:
Входной набор символов также может быть строкой, если он не содержит новой строки, потому что Canvas не имеет символа новой строки и автоматически преобразует его в 2D-объект.
источник
Stax ,
65 байтЗапустите и отладьте его
Объяснение:
источник
SOGL V0.12 , 10 байтов
Попробуй здесь!
Довольно долго, учитывая, что идея в значительной степени реализована на языке: здесь , ввод
выдает сжатую строку, используя этот метод.
источник
Рубин , 31 байт
Попробуйте онлайн!
источник
Stax , 2 байта
Запустите и отладьте его
:B
это инструкция в Stax, которая делает это. Обычно он работает с «строкой» * вместо массива «строк». В конце концов, это означает, что вывод представляет собой массив из односимвольных массивов. Но выход неявно выравнивается в любом случае.* У Stax нет строкового типа. Текст представлен целочисленными массивами кодовых точек.
источник
J , 12 байт
Как?
Попробуйте онлайн!
источник
Wolfram Language (Mathematica) , 49 байтов
Попробуйте онлайн!
источник
C (gcc) , 110 байтов
Попробуйте онлайн!
Описание:
источник
sprintf
. Моя версия C составляет 53 байта с выходным буфером, предоставленным вызывающей стороной. Вы можете сделать этоstrcpy
в конце, если хотите скопировать байты в начало буфера.CJam , 11 байт
Попробуйте онлайн! Принимает ввод как число, затем перевод строки, затем символы в ASCII-арт.
объяснение
источник
liq
в начале, и это сэкономит вам 3 байта!JavaScript, 39 байт
Решение Python для Port of Rod .
Попробуйте онлайн
источник
n
до 64 бит, верно? (В Python встроены целые числа произвольной точности, но числа JS, естественно, являютсяdouble
точными числами с плавающей точкой, которые можно преобразовать в целое число). Кажется, не работает для более крупных тестовых случаев в вопросе, например 1928149325670647244912100789213626616560861130859431492905908574660758972167966. Да, но вопрос позволяет получить ответы, подобные этому. И все же следует отметить.SimpleTemplate , 86 байт
Вау, это был огромный вызов!
Это было сделано из-за отсутствия прямого доступа к определенным индексам, когда индекс является переменной.
Ошибка также сделала его длиннее, требуя хранить значения внутри переменной.
Ожидаемые значения:
Первый аргумент (
argv.0
) может быть:Второй аргумент (
argv.1
) может быть:Как это работает?
Это работает так:
C
как массив, содержащий:C
"{@echoA."
"}"
join
функции)Это приводит, например,
C
содержащий"{@echoA.0}{@echoA.1}..."
C
Ungolfed:
Вы можете попробовать этот код на: https://ideone.com/NEKl2q
Оптимальный результат
Если бы не было ошибок, это был бы лучший результат, учитывая ограничения (77 байт):
источник