Спеціальний перетворювач базових номерів


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"

Додатковий

Новий тест базової 77 не потребує реквізиту, якщо він працює

  1. якщо ваш на мові, де ви повинні спочатку перетворити на число і заблокований протягом 32Bit, ви можете пропустити його.
  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
Можливо, варто додати тестовий випадок для "унікальної" бази - наприклад ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (або все, що насправді має бути, якщо це невірно)
Позов Моніки

2
Я б запропонував тестовий випадок з більш ніж 36 символами у форматах, щоб зловити всіх, хто використовує вбудовані модулі, які піднімаються лише до бази 36
Джо Кінг

Відповіді:


13

....................... Ви знаєте, я бачив, що Zaце робило перетворення бази, але в документах на matl.suever не було зрозуміло, що він приймає символи бази, тому я не пробував цього. РИПУЙ мені!
Джузеппе

@Giuseppe Haha, я запам'ятав це лише тому, що здавалося, що команда, яка дозріла для (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 все ще безлад!


На жаль, це не працюватиме з n = "0" ... вам слід додати 2 байти, log(N+1,T)але іноді викликаючи провідний нуль, наприклад, коли ви конвертуєте 31 з бази 10 в базу 2 :(
digEmAll

Щоб уникнути "нульової проблеми" логарифму без провідних нулів, я не бачу багато інших рішень ... ви, log(N+!N,T)звичайно, могли б скористатися !з оригінальним значенням
digEmAll

@digEmВсі коментарі ОП все ще дещо незрозумілі, але, схоже, нуль не потрібно підтримувати.
Джузеппе

Ну добре .. тоді добре :)
digEmAll

7

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

Анонімна інфіксація лямбда. Приймає InputFormatяк лівий аргумент і OutputFormatяк правий аргумент, і вимагає Numberвід stdin. Передбачає, що ⎕IO( I ndex O rigin) бути 0, що є типовим для багатьох систем.

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

Спробуйте в Інтернеті!

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

⍵[] Індексуйте вихідний формат наступним чином:

   запит на введення

  ⍺⍳dдокументи цих символів у форматі введення

  ()⊥ Оцінюють як наступну базу:

   ≢⍺ довжина формату введення

   урожай, який (відокремлюється ¯1від (≢⍺))

  ()⊥⍣¯1 Перетворити на таку базу:

  ≢⍺ довжина вихідного формату


7

Japt, 5 байт

Полегшення повернення в гольф після перерви на 2 тижні

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Åв - Повна програма.
Åβ - Перетворення з власної бази в десяткову.
  Я - Натисніть третій вхід.
   Åв - Перетворити з десяткової на власну базу. 

Ви заявляєте, що він працює лише у 05AB1E v2 (не впевнений, чи це правильний номер версії ..), але ви все-таки надали TIO-посилання. Версія Elixir вже є на TIO ?! : S Або це працює для більшості тестових випадків, але є деякі крайні випадки, коли він працює лише в новій версії?
Кевін Кройсейсен

2
05AB1E v2 тепер доступний у TIO. 05AB1E (спадщина) (пошук у рядку tio) - це ім'я старого 05AB1E, а 05AB1E - назва нового. Я знаю, що ви вже бачили це в чаті, але я залишу це тут як орієнтир для інших користувачів.
Містер Xcoder

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.

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 () для нижчого рахунку. (спасибі, Деннісе !)

Замінено індекс () на find (). (спасибі, пане Xcoder !)

Пояснення без вогню:

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

1
Вам не потрібно f=, анонімні функції дозволені за замовчуванням.
Erik the Outgolfer

@Erik the 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. Обов’язково цитуйте аргументи при правильному втечі!


Хрм не впевнений, що я чітко заявив про порядок парам ...
Мартін Баркер,

@MartinBarker Параметри взяті в порядку 2, 1, 3 тут. Я не бачу вимоги до конкретного замовлення у виклику, і це не відмовиться.
Ерік Аутгольфер

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


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

Спробуйте в Інтернеті!


На жаль, це не вірно, оскільки ви змінюєте вхідний формат рядка на масив, який не можна зробити через вхід 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)
roofcat


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;}

Спробуйте в Інтернеті

Безумовно

(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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.