Niestandardowy konwerter liczbowy

30

Potęgi, które chcą być w stanie szybko przekonwertować dowolną liczbę, którą mają, na własną bazę liczbową, przy użyciu dowolnego formatu, jaki chcą.

Wkład

Twój program musi zaakceptować 3 parametry.

  1. Numer: numer ciągu do konwersji
  2. InputFormat: ciąg podstawowy, w którym aktualnie znajduje się liczba
  3. OutputFormat: ciąg podstawowy, na który ma zostać przekonwertowana liczba.

Wydajność

Twój program musi przekonwertować Numberze starej bazy numerów InputFormatna nową bazę numerówOutputFormat

Przykłady

("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"

Dodatkowy

Nowy test 77 podstawy nie jest wymagany, jeśli działa

  1. jeśli jesteś w języku, w którym musisz najpierw przekonwertować numer i jesteś zamknięty w 32Bit, możesz go pominąć.
  2. ponieważ jest to dodatkowy test.

Wszystkie przykłady zostały wygenerowane przez PHP 7.2 z rozszerzeniem bcmath przy użyciu następującego kodu (vars min, ale sformatowany kod). prawdopodobnie będzie krótsza droga, to jest właśnie sposób, w jaki wymyśliłem system, z którym musiałem to zrobić, fajnie byłoby sprawdzić, czy ktoś mógłby wymyślić krótszą wersję.

PHP 7.2 (bcmath - rozszerzenie) 614 bajtów

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

Wypróbuj online

Punktacja

To jest kod golfowy; najkrótszy kod wygrywa. Obowiązują standardowe luki.

Martin Barker
źródło
5
@WindmillCookies Według dowolnych znaków w ciągach formatujących.
Adám
6
Ładne pierwsze pytanie! :-)
Giuseppe,
2
Blisko spokrewnione .
AdmBorkBork
2
Warto dodać przypadek testowy dla „unikalnej” bazy - np ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (lub cokolwiek to właściwie powinno być, jeśli jest to nieprawidłowe)
pozew Fund Moniki z
2
Sugerowałbym przypadek testowy z ponad 36 znakami w formatach, aby złapać każdego, kto korzysta z wbudowanych, które przechodzą tylko do bazy 36
Jo King,

Odpowiedzi:

13

MATL , 2 bajty

Za

Wypróbuj online!
Wszystkie przypadki testowe.

Dla pana Za !

sundar - Przywróć Monikę
źródło
....................... wiesz, widziałem, że Zakonwersja bazowa, ale dokumenty na matl. nigdy nie było jasne, że akceptuje postacie bazy, więc nie spróbowałem. Rozpruć mnie!
Giuseppe,
@Giuseppe Haha, zapamiętałem to tylko dlatego, że wydawało się, że jest to polecenie, które jest gotowe do użycia (ab) w jakimś sprytnym hacku lub dwóch. Ironiczne jest to, że moje pierwsze użycie jest proste. :)
sundar - Przywróć Monikę
1
Moją pierwszą myślą, gdy zobaczyłem „Za”, był „Lord, Harry Dresden”. +1.
Pozew Fund Moniki w dniu
8

R , 124 bajty

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

Wypróbuj online!

Ugh, to było doozy. Używam typowych lewych sztuczek konwersji dla R, ale manipulacje ciągami w R są nadal nieuporządkowane!

Giuseppe
źródło
Niestety, to nie zadziała przy n = "0" ... powinieneś dodać 2 bajty, log(N+1,T)ale czasami powodując zera wiodące, np. Podczas konwersji 31 ​​z bazy 10 na bazę 2 :(
digEmAll 19.08.18
Aby uniknąć „problemu zerowego” w logarytmie bez zer wiodących, nie widzę wielu innych rozwiązań ... możesz log(N+!N,T)oczywiście użyć !oryginalnego znaczenia
digEmAll
@digEmWszystkie komentarze OP są wciąż niejasne, ale wygląda na to, że zero nie musi być obsługiwane.
Giuseppe,
No cóż ... więc w porządku :)
digEmAll
7

APL (Dyalog Unicode) , 22 bajty

Anonimowy przyrostek lambda. Przyjmuje InputFormatjako lewy argument i OutputFormatjako prawy argument i monituje o Numberpodanie ze standardowego wejścia. Przyjmuje się ⎕IO( I ndex O rigin) 0, co jest domyślne w wielu systemach.

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

Wypróbuj online!

{} „Dfn”; jest lewym argumentem, prawym argumentem
(mnemoniczny: lewy i prawy koniec alfabetu greckiego)

⍵[] Indeksuj format wyjściowy w następujący sposób:

   monit o wprowadzenie

  ⍺⍳Pliki tych znaków w formacie wejściowym

  ()⊥ Oceniamy jako będące w następującej bazie:

   ≢⍺ długość formatu wejściowego

   dochód, (wydzielane ¯1z (≢⍺))

  ()⊥⍣¯1 Przekonwertuj na następującą bazę:

  ≢⍺ długość formatu wyjściowego

Adám
źródło
7

Japt, 5 bajtów

Z powrotem w golfa po 2 tygodniowej przerwie

nV sW

Spróbuj


Wyjaśnienie

           :Implicit input of U=Number, V=InputFormat & W=OutputFormat
 nV        :Convert U from base V to decimal
    sW     :Convert to base W string
Kudłaty
źródło
7

C (gcc), 79 + 46 = 125 bajtów

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

Musi to zostać skompilowane z

-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)

flaga. (Tak, jest to niezwykle szkicowe, dlatego poniżej trzymam moją starą odpowiedź.) To definiuje makro, fktóre wysyła odpowiedź do STDOUT.

Wypróbuj online!

C (gcc), 133 131 bajtów

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

Wypróbuj online!

Definiuje funkcję, fktóra wysyła odpowiedź do 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
}
Klamka
źródło
Możesz zapisać 2 bajty, używając putcharzamiast writei nieznacznie zmieniając pętlę dekodującą: Wypróbuj online!
ErikF,
Ta indexfunkcja uratowała mi również jeden bajt przy moim podejściu, nie wiedziałam o tym;)
Felix Palmen
6

05AB1E , 5 bajtów

ÅβIÅв

Wypróbuj online!

To nie działa w starszej wersji 05AB1E. Działa tylko w nowej wersji, przepisz Elixir.

Jak to działa

ÅβIÅв - Pełny program.
Åβ - Konwertuj z bazy niestandardowej na dziesiętną.
  I - Naciśnij trzecie wejście.
   Åв - Konwertuj z bazy dziesiętnej na niestandardową. 
Pan Xcoder
źródło
Podajesz, że działa tylko w 05AB1E v2 (nie jestem pewien, czy to prawidłowy numer wersji ..), ale nadal udostępniasz łącze TIO. Czy wersja Elixir jest już dostępna w TIO ?! : S Lub działa w większości przypadków testowych, ale są pewne przypadki brzegowe, w których działa tylko w nowej wersji?
Kevin Cruijssen
2
05AB1E v2 jest teraz dostępny w TIO. 05AB1E (starsza wersja) (wyszukaj w pasku tio) to nazwa starego 05AB1E, a 05AB1E to nazwa nowego. Wiem, że już to widziałeś na czacie, ale zostawię to tutaj jako odniesienie dla innych użytkowników.
Pan Xcoder,
5

MATL , 5 bajtów

sundar znalazł wbudowane narzędzie, aby to zrobić! Idź upvot tę odpowiedź zamiast mojej głupiej :-(

ZAwYA

Wypróbuj online!

          % 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
źródło
4

Węgiel drzewny , 5 bajtów

⍘⍘SSS

Wypróbuj online!Link jest do pełnej wersji kodu. Wyjaśnienie:

  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

BaseStringFunkcja automatycznie konwertuje między liczbą i łańcucha w zależności od typu pierwszego parametru.

Neil
źródło
3

Python 2 , 132 129 122 121 bajtów

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)]

Wypróbuj online!

Funkcja anonimowa (dzięki, Erik the Outgolfer !), Która konwertuje pierwotną liczbę na liczbę całkowitą podstawową 10, a następnie przekazuje liczbę całkowitą i nowy ciąg bazowy do funkcji g (), która rekurencyjnie przekształca się w nową bazę. Teraz przekazuje długość OutputFormat jako parametr do g ().

Zaktualizowano g () dla niższej liczby bajtów. (dzięki, Dennis !)

Zamieniono index () na find (). (dzięki, panie Xcoder !)

Niegolfowane Objaśnienie:

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
Triggernometria
źródło
1
Nie potrzebujesz f=, anonimowe funkcje są domyślnie dozwolone.
Erik the Outgolfer,
@Erik the Outgolfer Czy jest to dozwolone, gdy anonimowa funkcja wywołuje inną funkcję?
Triggernometry
Tak długo, jak włączysz inne rzeczy do swojego bajtu, tak, możesz definiować zmienne i importować moduły.
Erik the Outgolfer,
1
Funkcja pomocnika może się stać g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis
1
I główny może się stać lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
Pan Xcoder,
2

Galaretka , 11 bajtów

iⱮ’ḅL{ṃ⁵ṙ1¤

Wypróbuj online!

Kolejność argumentów: InputFormat, Number, OutputFormat. Pamiętaj, aby zacytować argumenty z odpowiednią ucieczką!

Erik the Outgolfer
źródło
Hrm nie jestem pewien, czy wyraźnie podałem kolejność params ...
Martin Barker,
@MartinBarker Parametry są podejmowane w kolejności 2, 1, 3 tutaj. Nie widzę zapotrzebowania na określoną kolejność w wyzwaniu i byłoby to zniechęcone.
Erik the Outgolfer
3
@MartinBarker Pro Wskazówka: bądź elastyczny w takich sprawach. Uważam kolejność wejść do całkowicie nieistotne podczas rozwiązywania zadania, więc proponuję, aby umożliwić dowolnie wybrany kolejność parametrów
Mr. Xcoder
i tak pozwolę mu się trzymać, próbując go teraz przetestować.
Martin Barker,
2

Pyth, 21 bajtów

s@LeQjimx@Q1dhQl@Q1le

Zestaw testowy

Wyjaśnienie:
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
źródło
2

Haskell , 119 bajtów

n!f=init.((foldl((+).(l f*))0[i|c<-n,(i,d)<-zip[0..]f,d==c],0)#)
(0,d)#b=[b!!d]
(r,d)#b=r`divMod`l b#b++[b!!d]
l=length

Wypróbuj online!

ბიმო
źródło
2

Perl 6 , 100 97 bajtów

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

Wypróbuj online!

Anonimowy blok kodu, który przyjmuje 3 ciągi w kolejności, dane wejściowe, format wejściowy i format wyjściowy, a następnie zwraca ciąg

Wyjaśnienie:

{  # 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
}
Jo King
źródło
2

VBA, 182 bajty

Zadeklarowany podprogram, który pobiera dane wejściowe nw języku yi wyświetla je w języku 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
Taylor Scott
źródło
2

JavaScript (ES6), 90 86 bajtów

Pobiera dane wejściowe jako (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

Wypróbuj online!

Arnauld
źródło
Niestety nie jest to poprawne, ponieważ zmiana formatu wejściowego ciągu znaków na tablicę nie jest czymś, co można wykonać za pomocą wejścia CLI. i musi być zaprogramowany, musisz podzielić ciąg na tablicę, aby pierwszy parametr był ważny.
Martin Barker,
@MartinBarker Do jakiej reguły się odwołujesz? Zaktualizowany, aby mimo to przyjąć 3 ciągi.
Arnauld
Wszystkie 3 parametry wejściowe mówią „ciąg”, ponieważ C ++ ciąg może być bezpośrednio wczytywany i używany jako tablica z javascript.
Martin Barker,
1

C (gcc) , 130 129 bajtów

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

Wypróbuj online!

-1 bajt za pomocą indexzamiast strchr.

Jest to proste podejście iteracyjne, polegające na ponownym wykorzystaniu niektórych zmiennych (a tym samym nadużyciu sizeof(int) == sizeof(char *)w TIO) w celu zaoszczędzenia bajtów.

Wkład:

  • i numer wejściowy
  • s źródłowe postacie bazowe
  • t docelowe postacie podstawowe

Wydajność:

  • r numer wyniku (wskaźnik do bufora)

Wyjaśnienie:

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
}
Felix Palmen
źródło
Zaproponuj bcopy(r,r+1,++i)zamiastmemmove(r+1,r,++i)
ceilingcat
1

Python 2 , 97 95 bajtów

Dzięki Chas Brown za -2 bajty.

n,s,t=input()
k=0;w='';x=len(t)
for d in n:k=len(s)*k+s.find(d)
while k:w=t[k%x]+w;k/=x
print w

Wypróbuj online!

ovs
źródło
1

Java 10, 131 bajtów

Lambda przyjmująca parametry w kolejności jako łańcuchy i zwracająca łańcuch.

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

Wypróbuj online

Bez golfa

(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
źródło