Конвертер пользовательских номеров

30

Силы, которые хотят иметь возможность быстро конвертировать любое число, которое у них есть, в свою собственную базу номеров, используя любой формат, который они хотят.

вход

Ваша программа должна принимать 3 параметра.

  1. Номер: номер строки для преобразования
  2. InputFormat: базовая строка, в которой находится номер
  3. OutputFormat: базовая строка, в которую нужно преобразовать число.

Выход

Ваша программа должна преобразовать Numberиз старой базы InputFormatв новую.OutputFormat

Примеры

("1","0123456789","9876543210") = "8"
("985724","9876543210","0123456789ABCDEF") = "37C3"
("FF","0123456789ABCDEF","0123456789") = "255"
("FF","0123456789ABCDEF","01234567") = "377"
("18457184548971248772157", "0123456789","Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9Kk,Ll.Mm[Nn]Oo@Pp#Qq}Rr{Ss-Tt+Uu=Vv_Ww!Xx%Yy*Zz") = ",sekYFg_fdXb"

дополнительный

Новый тест Base 77 не требуется реквизит, если он работает, хотя

  1. если вы говорите на языке, где вы должны сначала преобразовать число в число и заблокированы в пределах 32 бит, вы можете пропустить его.
  2. как это дополнительный тест.

Все примеры были сгенерированы PHP 7.2 с расширением bcmath с использованием следующего кода (vars mins, но отформатированный код). вероятно, будет более короткий путь, и именно так я и придумал для системы, с которой мне нужно было это сделать, было бы неплохо, если бы кто-нибудь смог придумать более короткую версию.

PHP 7.2 (bcmath - расширение) 614 байт

<?php
function f($a, $b, $c)
{
    $d= str_split($b,1);
    $e= str_split($c,1);
    $f= str_split($a,1);
    $g=strlen($b);
    $h=strlen($c);
    $k=strlen($a);
    $r='';
    if ($c== '0123456789')
    {
        $r=0;
        for ($i = 1;$i <= $k; $i++)
            $retval = bcadd($retval, bcmul(array_search($f[$i-1], $d),bcpow($g,$k-$i)));
        return $r;
    }
    if ($b!= '0123456789')
        $l=f($a, $b, '0123456789');
    else
        $l= $a;
    if ($l<strlen($c))
        return $e[$l];
    while($l!= '0')
    {
        $r= $e[bcmod($l,$h)].$r;
        $l= bcdiv($l,$h,0);
    }
    return $r;
}

Попробуйте онлайн

счет

Это код гольф; самый короткий код выигрывает. Применяются стандартные лазейки.

Мартин Баркер
источник
5
@WindmillCookies Какими бы ни были символы в строках формата.
Адам
6
Хороший первый вопрос! :-)
Джузеппе
2
Тесно связана .
AdmBorkBork
2
Возможно, стоит добавить контрольный пример для «уникальной» базы - например ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (или что бы это ни было на самом деле, если это неверно)
Фонд Моника Иск
2
Я бы предложил тестовый пример с более чем 36 символами в форматах, чтобы поймать любого, кто использует встроенные модули, которые подходят только к базе 36
Джо Кинг,

Ответы:

13

MATL , 2 байта

Za

Попробуйте онлайн!
Все тестовые случаи.

За За господин !

sundar - Восстановить Монику
источник
....................... вы знаете, я видел, что это Zaсделал базовое преобразование, но документы на matl.suever не было ясно, что он принимает символы базы, поэтому я не пробовал это. Разорви меня!
Джузеппе
@ Giuseppe Ха-ха, я вспомнил это только потому, что казалось, что команда созрела для (ab) использования в каком-то умном взломе или двух. Странно, что мое первое использование это как прямой встроенный ответ. :)
sundar - Восстановить Монику
1
Моей первой мыслью, когда я увидел «За», было «господин, Гарри Дрезден». +1.
Фонд Моника иск
8

R , 124 байта

function(n,s,t,T=L(t),N=(match(!n,!s)-1)%*%L(s)^(L(n):1-1))intToUtf8((!t)[N%/%T^rev(0:log(N,T))%%T+1])
"!"=utf8ToInt
L=nchar

Попробуйте онлайн!

Тьфу, это было глупо. Я использую типичные базовые приемы преобразования для R, но манипуляции со строками в R все еще грязные!

Giuseppe
источник
К сожалению, это не будет работать с n = "0" ... вы должны добавить 2 байта, log(N+1,T)но иногда приводите к
начальному
Чтобы избежать «нулевой проблемы» в логарифме без начальных нулей, я не вижу много других решений ... вы могли бы, log(N+!N,T)конечно, использовать !с оригинальным значением
digEmAll
@digEm Все комментарии ОП все еще немного неясны, но, похоже, ноль не должен поддерживаться.
Джузеппе
Ну да ладно .. тогда все нормально :)
digEmAll
7

APL (Dyalog Unicode) , 22 байта

Анонимный инфикс лямбда. Принимает в InputFormatкачестве левого аргумента и в OutputFormatкачестве правого аргумента и запрашивает Numberот стандартного ввода. Предполагается ⎕IO( я ndex O rigin) 0, что по умолчанию во многих системах.

{⍵[(≢⍵)⊥⍣¯1⊢(≢⍺)⊥⍺⍳⎕]}

Попробуйте онлайн!

{} "Дфн"; левый аргумент, правый аргумент
(мнемоника: левый и правый концы греческого алфавита)

⍵[] Индексировать выходной формат следующим образом:

   запрос на ввод

  ⍺⍳указатели этих символов в формате ввода

  ()⊥ Оценивать как находящуюся в следующей базе:

   ≢⍺ длина формата ввода

   дать это (отделяется ¯1от (≢⍺))

  ()⊥⍣¯1 Преобразовать в следующую базу:

  ≢⍺ длина выходного формата

Адам
источник
7

Japt, 5 байт

Возвращение в гольф после двухнедельного перерыва

nV sW

Попытайся


объяснение

           :Implicit input of U=Number, V=InputFormat & W=OutputFormat
 nV        :Convert U from base V to decimal
    sW     :Convert to base W string
мохнатый
источник
7

C (gcc), 79 + 46 = 125 байт

char*O;l,n;g(n){n/l&&g(n/l);write(1,O+n%l,1);}

Это должно быть скомпилировано с

-Df(s,i,o)=for(n=l=0;n=n*strlen(i)+index(i,s[l])-i,s[++l];);l=strlen(O=o);g(n)

флаг. (Да, это невероятно схематично, поэтому я держу свой старый ответ ниже.) Это определяет макрос, fкоторый выводит ответ на STDOUT.

Попробуйте онлайн!

C (gcc), 133 131 байт

char*O;l;g(n){n/l&&g(n/l);write(1,O+n%l,1);}f(s,i,o,n)char*s,*i,*o;{for(n=0,l=strlen(O=o);n=n*strlen(i)+index(i,*s)-i,*++s;);g(n);}

Попробуйте онлайн!

Это определяет функцию, fкоторая выводит ответ на STDOUT.

char*O;           // declare variable to store output charset
l;                // will be set to length of O
g(n){             // helper function to print the result
  n/l&&g(n/l);    // recursively calls itself if there are more digits
  write(1,        // output to stdout...
   O+n%l,1);      // the byte at (n mod output base) in O
}
f(s,i,o,n)        // main function
char*s,*i,*o;{    // declare string inputs
for(n=0,          // initialize n to 0
l=strlen(O=o);    // assign output charset so we don't have to pass it to g
n=n*strlen(i)     // repeatedly multiply n by input base...
+index(i,*s)-i,   // ... add the index of the digit in input charset...
*++s;);           // and move to the next digit until there's none left
g(n);             // call the helper function on the resulting integer
}
Дверная ручка
источник
Вы можете сэкономить 2 байта, используя putcharвместо writeи слегка меняя цикл декодирования: попробуйте онлайн!
ErikF
Эта indexфункция спасла мне и один байт благодаря моему подходу, я не знал об этом;)
Феликс Пальмен,
6

05AB1E , 5 байтов

ÅβIÅв

Попробуйте онлайн!

Это не работает в устаревшей версии 05AB1E. Это работает только на новой версии, переписать Elixir.

Как это работает

ÅβIÅв - Полная программа.
Åβ - конвертировать из пользовательской базы в десятичную.
  Я - толкнуть третий вход.
   Åв - конвертировать из десятичной в пользовательскую базу. 
Мистер Xcoder
источник
Вы заявляете, что он работает только в 05AB1E v2 (не уверен, что это правильный номер версии ..), но вы все равно предоставили ссылку TIO. Версия Elixir уже есть на TIO ?! : S Или это работает для большинства тестовых случаев, но есть некоторые крайние случаи, когда это работает только в новой версии?
Кевин Круйссен
2
05AB1E v2 теперь доступен на TIO. 05AB1E (legacy) (найдите его в тио-баре) - это имя старого 05AB1E, а 05AB1E - имя нового. Я знаю, что вы уже видели это в чате, но я оставлю это здесь как ссылку для других пользователей.
Мистер Кскодер
5

MATL , 5 байтов

sundar нашел настоящий встроенный для этого! Пойди, проголосуй за этот ответ вместо моего тупого :-(

ZAwYA

Попробуйте онлайн!

          % implicit input N, the number, and S, the digits of the Source base
ZA        % base2dec, convert string N using S as digits into a base 10 integer
w         % swap stack elements, with implicit input T, the digits of the Target base
YA        % dec2base, reverse the ZA operation with digits coming from T instead.
Giuseppe
источник
4

Древесный уголь , 5 байт

⍘⍘SSS

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

  S     Input the "number"
   S    Input the input format
 ⍘      Convert to number using that format
    S   Input the output format
⍘       Convert to string using that format
        Implicitly print

BaseStringФункция автоматически преобразует числа и строки в зависимости от типа первого параметра.

Нил
источник
3

Python 2 , 132 129 122 121 байт

lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b)
g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)]

Попробуйте онлайн!

Анонимная функция (спасибо, Эрик, Outgolfer !), Которая преобразует исходное число в целое число 10, а затем передает целое число и новую базовую строку в функцию g (), которая рекурсивно преобразуется в новую базу. Теперь передается длина OutputFormat в качестве параметра для g ().

Обновлен g () для более низкого количества пользователей. (спасибо, Деннис !)

Заменил index () на find (). (спасибо, мистер Xcoder !)

Ungolfed Объяснение:

def f(n, a, b):
    # reverse the string to that the least significant place is leftmost
    # Ex: 985724 -> 427589
    n = n[::-1]
    # get the value of each place, which is its index in the InputFormat, times the base to the power of the place
    # Ex: 427589, 9876543210 -> 5*10^0, 7*10^1, 2*10^2, 4*10^3, 1*10^4, 0*10^5 -> [5,70,200,4000,10000,0]
    n = [a.find(j)*len(a)**i for i,j in enumerate(n)]
    # add all of the values together to bet the value in base 10
    # Ex: (5 + 70 + 200 + 4000 + 10000 + 0) = 14275
    n = sum(n)

    # call the convert to base function
    return g(n, b)

def g(n, c):
    # string slice, which will return an empty string if n:n+1 is not in range
    # an empty string is falsey
    if c[n:n+1]:
        return c[n:n+1]
    else:
        # get current least significant digit
        rem = c[n%len(c)]
        # get the rest of the integer
        div = n/len(c)

        # get the converted string for the rest of the integer, append the calculated least significant digit
        return g(div,c)+rem
Triggernometry
источник
1
Вам не нужно f=, анонимные функции разрешены по умолчанию.
Эрик Outgolfer
@Erik the Outgolfer Это разрешено, когда анонимная функция вызывает другую функцию?
Триггернометрия
Пока вы включаете другие вещи в свой счет, да, вы можете определять переменные и импортировать модули.
Эрик Outgolfer
1
Вспомогательная функция может стать g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Деннис
1
И главным может стать lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
г-н Xcoder
2

Желе , 11 байт

iⱮ’ḅL{ṃ⁵ṙ1¤

Попробуйте онлайн!

Порядок аргументов: InputFormat, Number, OutputFormat. Обязательно процитируйте аргументы с правильным побегом!

Эрик Outgolfer
источник
Хм, не уверен, что я четко указал порядок параметров ...
Мартин Баркер,
@MartinBarker Параметры здесь взяты в порядке 2, 1, 3. Я не вижу требования для конкретного заказа в конкурсе, и это не рекомендуется.
Эрик Outgolfer
3
@MartinBarker Pro Совет: будьте гибкими с такими вещами. Я считаю, что порядок входных данных совершенно не имеет значения при решении задачи, поэтому я предлагаю вам разрешить любое произвольно выбранное упорядочение параметров
г-н Xcoder
Я собирался позволить этому все равно остаться, просто пытаясь проверить это сейчас.
Мартин Баркер
2

Pyth, 21 байт

s@LeQjimx@Q1dhQl@Q1le

Тестирование

Объяснение:
s@LeQjimx@Q1dhQl@Q1le  | Code
s@LeQjimx@Q1dhQl@Q1leQ |  with implicit variables
       m               | Map the function
        x   d          |   index of d in
         @Q1           |    the second string in the input
             hQ        |  over the first string in the input
      i                | Convert the resulting list to int from base
               l@Q1    |  length of the second string in the input
     j                 | Convert the int into a list in base
                   leQ |  length of the last string in the input
 @LeQ                  | Turn each number in the list into the character from the numbers index in the last string in the input
s                      | Concatenate the strings in to one string
                       | Implicit print
hakr14
источник
2

Perl 6 , 100 97 байт

{$^c.comb[(":"~$^b.chars~[$^a.comb>>.&{index $b,$_}].perl).EVAL.polymod($c.chars xx*)].join.flip}

Попробуйте онлайн!

Блок анонимного кода, который принимает 3 строки в порядке ввода, ввода, ввода и вывода, а затем возвращает строку

Объяснение:

{  # Anonymous code block
  $^c.comb[  # Split the output format into characters
           (":"~$^b.chars~[$^a.comb>>.&{index $b,$_}].perl) # The radix syntax in a string e.g ":3[1,2,3]"
           .EVAL  # Eval'ed to produce the base 10 version
           .polymod($c.chars xx*)  # Converted to a list in the output base (reversed)
          ] # Convert the list into indexes of the output format
           .join  # Join the characters to a string
           .flip  # And unreversed
}
Джо Кинг
источник
2

VBA, 182 байта

Объявленная подпрограмма, которая принимает данные nна языке yи проецирует их на язык z.

Sub f(n,y,z)
l=Len(n)
For i=-l To-1
v=v+(InStr(1,y,Mid(n,-i,1))-1)*Len(y)^(l+i)
Next
l=Len(z)
While v
v=v-1
d=v Mod l+1
v=v\l
If d<0Then v=v+1:d=d-l
o=Mid(z,d+1,1)&o
Wend
n=o
End Sub
Тейлор Скотт
источник
2

JavaScript (ES6), 90 86 байт

Принимает вход как (input_format)(output_format)(number).

s=>d=>g=([c,...n],k=0)=>c?g(n,k*s.length+s.search(c)):k?g(n,k/(l=d.length)|0)+d[k%l]:n

Попробуйте онлайн!

Arnauld
источник
Извините, это недопустимо, так как вы изменили формат ввода строки на массив, который нельзя сделать с помощью ввода CLI. и должен быть запрограммирован, вам нужно разбить строку на массив, чтобы первый параметр был действительным.
Мартин Баркер
@MartinBarker На какое правило вы ссылаетесь? Обновлен, чтобы взять 3 строки в любом случае.
Арно
Все 3 входных параметра говорят «строка», так как в C ++ строка может быть непосредственно считана и использована как массив с javascript, которого не может быть.
Мартин Баркер
1

C (gcc) , 130 129 байтов

v;c(r,i,s,t)char*r,*i,*t;{for(r[1]=v=0;*i;v=v*strlen(s)+index(s,*i++)-s);for(s=strlen(t),i=1;*r=t[v%s],v/=s;memmove(r+1,r,++i));}

Попробуйте онлайн!

-1 байт, используя indexвместо strchr.

Это простой итеративный подход, повторное использование некоторых переменных (и, следовательно, злоупотребление sizeof(int) == sizeof(char *)TIO) для сохранения байтов.

Входные данные:

  • i входной номер
  • s исходные базовые символы
  • t целевые базовые символы

Выход:

  • r номер результата (указатель на буфер)

Объяснение:

v;                                        // value of number
c(r,i,s,t)char*r,*i,*t;{
    for(r[1]=v=0;                         // initialize value and second
                                          // character of output to 0
        *i;                               // loop while not at the end of
                                          // input string
         v=v*strlen(s)+index(s,*i++)-s);  // multiply value with source base
                                          // and add the value of the current
                                          // digit (position in the base string)
    for(s=strlen(t),i=1;                  // initialize s to the length of the
                                          // target base string, length of
                                          // result to 1
        *r=t[v%s],v/=s;                   // add character for current digit
                                          // (value modulo target base) and
                                          // divide value by target base until
                                          // 0 is reached
        memmove(r+1,r,++i));              // move result string one place to
                                          // the right
}
Феликс Палмен
источник
Предлагаю bcopy(r,r+1,++i)вместоmemmove(r+1,r,++i)
floorcat
1

Java 10, 131 байт

Лямбда, принимающая параметры по порядку в виде строк и возвращающая строку.

(i,f,o)->{int n=0,b=o.length();var r="";for(var c:i.split(r))n=n*f.length()+f.indexOf(c);for(;n>0;n/=b)r=o.charAt(n%b)+r;return r;}

Попробуйте онлайн

Ungolfed

(i, f, o) -> {
    int n = 0, b = o.length();
    var r = "";
    for (var c : i.split(r))
        n = n * f.length() + f.indexOf(c);
    for (; n > 0; n /= b)
        r = o.charAt(n % b) + r;
    return r;
}
Jakob
источник