Вступление
В прошлом у нас было несколько проблем с базовым преобразованием, но не так много, предназначенных для работы с числами произвольной длины (то есть с числами, достаточно длинными, чтобы они переполняли целочисленный тип данных), и из них большинство считалось немного сложный. Мне любопытно, как можно добиться такого изменения базового кода.
Вызов
Напишите программу или функцию на выбранном вами языке, которая может преобразовать строку из одной базы в строку из другой базы. Входными данными должны быть число, которое нужно преобразовать (строка), от основания (число от 10 до 10), от основания до (от 10 до 10) и набор символов (строка). Выходными данными должно быть преобразованное число (строка).
Некоторые дополнительные детали и правила заключаются в следующем:
- Число для преобразования будет неотрицательным целым числом (так как
-
и.
может быть в наборе символов). Так тоже будет выходной. - Ведущие нули (первый символ в наборе символов) должны быть обрезаны. Если результат равен нулю, должна остаться одна нулевая цифра.
- Минимальный поддерживаемый базовый диапазон составляет от 2 до 95, состоящий из печатных символов ascii.
- Входные данные для числа, подлежащего преобразованию, набор символов и выходные данные должны иметь строковый тип данных. Основания должны иметь целочисленный тип данных base-10 (или целочисленные числа с плавающей точкой).
- Длина строки входного номера может быть очень большой. Трудно дать количественную оценку разумного минимума, но ожидайте, что он сможет обрабатывать не менее 1000 символов и завершить ввод 100 символов менее чем за 10 секунд на приличной машине (очень щедро для такой проблемы, но я не хочу скорость, чтобы быть в центре внимания).
- Вы не можете использовать встроенные функции изменения базы.
- Ввод набора символов может быть любым, а не только типичным 0-9a-z ... и т. Д.
- Предположим, что будет использоваться только действительный ввод. Не беспокойтесь об обработке ошибок.
Победитель будет определен по кратчайшему коду, который соответствует критериям. Они будут выбраны не позднее, чем через 7-10 дней, или если / когда будет достаточно заявок. В случае ничьей, код, который работает быстрее, будет победителем. Если достаточно близко по скорости / производительности, ответ, который пришел раньше, выигрывает.
Примеры
Вот несколько примеров ввода и вывода, которые ваш код должен уметь обрабатывать:
F("1010101", 2, 10, "0123456789")
> 85
F("0001010101", 2, 10, "0123456789")
> 85
F("85", 10, 2, "0123456789")
> 1010101
F("1010101", 10, 2, "0123456789")
> 11110110100110110101
F("bababab", 2, 10, "abcdefghij")
> if
F("10", 3, 2, "0123456789")
> 11
F("<('.'<)(v'.'v)(>'.'>)(^'.'^)", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> !!~~~~~~~!!!~!~~!!!!!!!!!~~!!~!!!!!!~~!~!~!!!~!~!~!!~~!!!~!~~!!~!!~~!~!!~~!!~!~!!!~~~~!!!!!!!!!!!!~!!~!~!~~~~!~~~~!~~~~~!~~!!~~~!~!~!!!~!~~
F("~~~~~~~~~~", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> ~
F("9876543210123456789", 10, 36, "0123456789abcdefghijklmnopqrstuvwxyz")
> 231ceddo6msr9
F("ALLYOURBASEAREBELONGTOUS", 62, 10, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
> 6173180047113843154028210391227718305282902
F("howmuchwoodcouldawoodchuckchuckifawoodchuckcouldchuckwood", 36, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> o3K9e(r_lgal0$;?w0[`<$n~</SUk(r#9W@."0&}_2?[n
F("1100111100011010101010101011001111011010101101001111101000000001010010100101111110000010001001111100000001011000000001001101110101", 2, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> this is much shorter
You cannot use built in change-of-base functions to convert the entire input string/number at once
? В частности, могу ли я использовать встроенную функцию для преобразования ввода в промежуточную базу? Могу ли я использовать встроенный для преобразования в целевую базу? Будет ли что-то подобноеconvert input with canonical form for given base; convert to base 10; convert to target base; convert back to specified character set with string replacement
?Ответы:
CJam, 34 байта
Формат ввода указан
input_N alphabet input_B output_B
в отдельной строке.Запустите все тестовые случаи.
объяснение
Это работает для того же количества байтов:
Разница лишь в том, что мы собираем строку вместо того, чтобы собирать все в стек и переворачивать ее.
источник
Python 2 ,
11511410610594 байтаПредложения по игре в гольф приветствуются. Попробуйте онлайн!
Изменить: -9 байт благодаря mbomb007. -2 байта благодаря FlipTack.
Ungolfed:
источник
while z:s=d[z%t]+s;z/=t
экономит 9 байт.z=0
иs=''
в объявление функции, чтобы сохранить байты.print
вместоreturn
это разрешено по умолчанию .Серьезно, 50 байтов
Шестнадцатеричный дамп:
Я горжусь этим, несмотря на его длину. Почему? Потому что он отлично работал со второй попытки. Я написал это и отладил буквально за 10 минут. Обычно отладка серьезной программы - это час работы.
Объяснение:
источник
C (функция) с библиотекой GMP , 260
Это оказалось дольше, чем я надеялся, но это все равно. Материал
mpz_*
действительно съедает много байтов. Я пытался#define M(x) mpz_##x
, но это дало чистый выигрыш в 10 байт.Функция
F()
является точкой входа. Он преобразует входную строку вmpz_t
последовательные умножения наfrom
-base и добавление индекса данной цифры в список цифр.Функция
O()
является рекурсивной функцией вывода. Каждая рекурсия divmodsmpz_t
поto
-BASE. Поскольку это приводит к выводу цифр в обратном порядке, рекурсия эффективно позволяет хранить цифры в стеке и выводить в правильном порядке.Тестовый водитель:
Добавлены новые строки и отступы для удобства чтения.
источник
JavaScript (ES6), 140 байт
В отличие от кода @ Mwr247 (который использует арифметику base-f для деления s на t каждый раз, собирая каждый остаток по мере его поступления), я использую арифметику base-t для умножения ответа на f каждый раз, добавляя каждую цифру s на ходу.
Ungolfed:
источник
Рубин,
11311210598979587 байтЯ как бы дважды опубликовал свой ответ на Python (как-то), так что вот ответ Ruby. Еще семь байтов благодаря manatwork , еще один байт благодаря Мартину Бюттнеру и еще 8 байтов благодаря cia_rana .
Ungolfed:
источник
s=d[z%t]+s;z/=t
вместоz,m=z.divmod t;s=d[m]+s
?APL, 10 байт
Это оператор APL. В APL
⍵
и⍺
используются для передачи значений, а⍵⍵
и⍺⍺
обычно используются для передачи функций. Я злоупотребляю этим здесь, чтобы иметь 3 аргумента.⍺⍺
левый аргумент,⍵⍵
«внутренний» правый аргумент, и⍵
является «внешним» правым аргументом.В принципе:
⍺(⍺⍺{...}⍵⍵)⍵
Тогда все, что нужно, это
⍳
найти позиции входной строки в таблице «from», а затем использовать[]
для индексации таблицы «to» с этими позициями.Пример:
источник
JavaScript (ES6), 175 байт
Я подумал, что прошло достаточно много времени, и я могу представить сделанный мной пример для создания примеров. Я могу попытаться сыграть немного лучше позже.
источник
Japt, 9 байт
Попытайся
источник