Konverter Basis Nomor Kustom

30

Kekuatan yang ingin dapat dengan cepat mengkonversi nomor apa pun yang mereka miliki menjadi basis nomor mereka sendiri menggunakan format apa pun yang mereka inginkan.

Memasukkan

Program Anda harus menerima 3 parameter.

  1. Nomor: Nomor string yang akan dikonversi
  2. InputFormat: string dasar nomor saat ini
  3. OutputFormat: string dasar yang nomornya akan dikonversi.

Keluaran

Program Anda harus mengonversi Numberdari basis angka lama InputFormatke basis angka baruOutputFormat

Contohnya

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

Tambahan

Tes base 77 baru tidak diperlukan alat peraga jika itu bekerja

  1. jika Anda menggunakan bahasa tempat Anda harus mengonversi ke nomor terlebih dahulu dan dikunci dalam 32Bit Anda dapat melewatinya.
  2. karena ini merupakan tes tambahan.

Semua contoh dihasilkan oleh PHP 7.2 dengan ekstensi bcmath menggunakan kode berikut (vars mnt tetapi kode diformat). mungkin akan ada cara yang lebih pendek ini hanya cara saya datang dengan sistem saya perlu melakukan ini dengan akan menyenangkan untuk melihat apakah ada yang bisa datang dengan versi yang lebih pendek.

PHP 7.2 (bcmath - ekstensi) 614 byte

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

Cobalah secara Online

Mencetak gol

Ini adalah kode golf; kode menang paling pendek. Celah standar berlaku.

Martin Barker
sumber
5
@WindmillCookies Oleh karakter apa pun yang ada dalam format string.
Adám
6
Pertanyaan pertama yang bagus! :-)
Giuseppe
2
Berhubungan erat .
AdmBorkBork
2
Mungkin patut menambahkan test case untuk basis "unik" - mis ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (atau apa pun yang seharusnya, jika itu salah)
Gugatan Dana Monica
2
Saya akan menyarankan test case dengan lebih dari 36 karakter dalam format, untuk menangkap siapa pun yang menggunakan built-in yang hanya naik ke base 36
Jo King

Jawaban:

13

MATL , 2 byte

Za

Cobalah online!
Semua uji kasus.

Untuk tuan Za !

sundar - Pasang kembali Monica
sumber
....................... Anda tahu, saya melihat bahwa Zamelakukan konversi basis tetapi dokumen pada matl.suever tidak jelas bahwa ia menerima karakter basis, jadi saya tidak mencobanya. RIP aku!
Giuseppe
@ Giuseppe Haha, saya mengingatnya hanya karena sepertinya itu adalah perintah yang matang untuk digunakan (ab) dalam beberapa atau dua hack cerdas. Ironisnya, penggunaan pertama saya adalah sebagai jawaban langsung. :)
sundar - Reinstate Monica
1
Pikiran pertama saya ketika saya melihat "Za" adalah "tuan, Harry Dresden". +1.
Dana Gugatan Monica
8

R , 124 byte

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

Cobalah online!

Ugh, ini doozy. Saya menggunakan trik konversi basis khas untuk R, tetapi manipulasi string dalam R masih berantakan!

Giuseppe
sumber
Sayangnya ini tidak akan bekerja dengan n = "0" ... Anda harus menambahkan 2 byte melakukan log(N+1,T)tetapi menyebabkan nol memimpin kadang-kadang misalnya ketika Anda mengkonversi 31 dari basis 10 ke basis 2 :(
digEmAll
Untuk menghindari "nol masalah" pada logaritma tanpa memimpin nol, saya tidak melihat banyak solusi lain ... Anda log(N+!N,T)tentu saja dapat menggunakan !dengan arti aslinya
digEmAll
@digEmAll komentar OP masih agak tidak jelas, tetapi tampaknya nol tidak perlu didukung.
Giuseppe
Oh well .. tidak apa-apa kalau begitu :)
digEmAll
7

APL (Dyalog Unicode) , 22 byte

Lambda infix Anonim. Dibawa InputFormatsebagai argumen kiri dan OutputFormatsebagai argumen kanan, dan meminta Numberdari stdin. Diasumsikan ⎕IO( I ndex O rigin) 0, yang merupakan default pada banyak sistem.

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

Cobalah online!

{... } "dfn"; adalah argumen kiri, argumen kanan
(mnemonik: ujung kiri dan kanan alfabet Yunani)

⍵[... ] indeks format output dengan yang berikut:

   meminta input

  ⍺⍳ɩ menemukan karakter-karakter tersebut dalam format input

  (... )⊥ evaluasilah dalam basis berikut:

   ≢⍺ panjang format input

   hasilkan itu (terpisah ¯1dari (≢⍺))

  (... )⊥⍣¯1 konversikan ke basis berikut:

  ≢⍺ panjang format output

Adm
sumber
7

Japt, 5 byte

Bersantai kembali ke golf setelah istirahat 2 minggu

nV sW

Cobalah


Penjelasan

           :Implicit input of U=Number, V=InputFormat & W=OutputFormat
 nV        :Convert U from base V to decimal
    sW     :Convert to base W string
Shaggy
sumber
7

C (gcc), 79 + 46 = 125 byte

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

Ini harus dikompilasi dengan

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

bendera. (Ya, ini sangat samar, itulah sebabnya saya menyimpan jawaban lama saya di bawah ini.) Ini mendefinisikan makro fyang menampilkan jawaban untuk STDOUT.

Cobalah online!

C (gcc), 133 131 byte

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

Cobalah online!

Ini mendefinisikan fungsi fyang menampilkan jawaban untuk 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
}
Gagang pintu
sumber
Anda dapat menyimpan 2 byte dengan menggunakan putcharalih-alih writedan sedikit mengubah loop decoding: Coba online!
ErikF
indexFungsi ini menyelamatkan saya satu byte juga dengan pendekatan saya, tidak tahu tentang itu;)
Felix Palmen
6

05AB1E , 5 byte

ÅβIÅв

Cobalah online!

Ini tidak berfungsi di versi lawas 05AB1E. Ini hanya berfungsi pada versi baru, penulisan ulang Elixir.

Bagaimana itu bekerja

ÅβIÅв - Program lengkap.
Åβ - Konversi dari basis kustom ke desimal.
  I - Tekan input ketiga.
   Åв - Konversi dari desimal ke basis kustom. 
Tuan Xcoder
sumber
Anda menyatakan ini hanya berfungsi di 05AB1E v2 (tidak yakin apakah itu nomor versi yang benar ..), tetapi Anda masih menyediakan tautan TIO. Apakah versi Elixir sudah ada di TIO ?! : S Atau itu berfungsi untuk sebagian besar kasus uji, tetapi ada beberapa kasus tepi di mana ia hanya berfungsi di versi baru?
Kevin Cruijssen
2
05AB1E v2 sekarang tersedia di TIO. 05AB1E (warisan) (cari di bar tio) adalah nama 05AB1E lama dan 05AB1E adalah nama yang baru. Saya tahu Anda sudah melihatnya di ruang obrolan, tetapi saya akan membiarkannya di sini sebagai referensi untuk pengguna lain.
Tn. Xcoder
5

MATL , 5 byte

Sundar menemukan builtin nyata untuk melakukan ini! Pilih jawaban itu alih-alih jawaban bodoh saya :-(

ZAwYA

Cobalah 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
sumber
4

Arang , 5 byte

⍘⍘SSS

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

  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

The BaseStringfungsi secara otomatis mengkonversi antara jumlah dan tali tergantung pada jenis parameter pertama.

Neil
sumber
3

Python 2 , 132 129 122 121 byte

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

Cobalah online!

Fungsi anonim (terima kasih, Erik the Outgolfer !) Yang mengubah angka asli menjadi integer basis 10, kemudian meneruskan integer dan string basis baru ke fungsi g (), yang secara rekursif mengkonversi ke basis baru. Sekarang melewati panjang OutputFormat sebagai parameter ke g ().

Diperbarui g () untuk bytecount yang lebih rendah. (terima kasih, Dennis !)

Indeks diganti () dengan find (). (terima kasih, Tuan Xcoder !)

Penjelasan Tidak Dikunci:

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
Triggernometri
sumber
1
Anda tidak perlu f=, fungsi anonim diizinkan secara default.
Erik the Outgolfer
@Erik the Outgolfer Apakah itu diizinkan ketika fungsi anonim memanggil fungsi lain, tho?
Triggernometri
Selama Anda memasukkan hal-hal lain dalam bytecount Anda, ya, Anda diizinkan untuk mendefinisikan variabel dan mengimpor modul.
Erik the Outgolfer
1
Fungsi pembantu bisa menjadi g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis
1
Dan yang utama bisa menjadi lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
Tn. Xcoder
2

Jelly , 11 byte

iⱮ’ḅL{ṃ⁵ṙ1¤

Cobalah online!

Urutan argumen: InputFormat, Nomor, OutputFormat. Pastikan untuk mengutip argumen dengan melarikan diri!

Erik the Outgolfer
sumber
Saya tidak yakin saya secara eksplisit menyatakan urutan params ...
Martin Barker
@ MartinBarker Params diambil dalam urutan 2, 1, 3 di sini. Saya tidak bisa melihat persyaratan untuk urutan tertentu dalam tantangan, dan itu akan patah semangat.
Erik the Outgolfer
3
@MartinBarker Pro Tip: Bersikap fleksibel dengan hal-hal seperti itu. Saya menemukan urutan input menjadi sama sekali tidak relevan ketika menyelesaikan suatu tugas, jadi saya sarankan agar Anda mengizinkan pemesanan parameter yang dipilih secara sewenang-wenang
Tn. Xcoder
Aku akan membiarkannya tetap saja hanya mencoba mengujinya sekarang.
Martin Barker
2

Pyth, 21 byte

s@LeQjimx@Q1dhQl@Q1le

Suite uji

Penjelasan:
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
sumber
2

Haskell , 119 byte

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

Cobalah online!

ბიმო
sumber
2

Perl 6 , 100 97 byte

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

Cobalah online!

Blok kode anonim yang mengambil 3 string dalam urutan, input, format input dan format output, kemudian mengembalikan sebuah string

Penjelasan:

{  # 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
sumber
2

VBA, 182 byte

Subrutin yang dideklarasikan yang mengambil input n, dalam bahasa ydan memproyeksikannya ke dalam bahasa 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
sumber
2

JavaScript (ES6), 90 86 byte

Mengambil input sebagai (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

Cobalah online!

Arnauld
sumber
Maaf, ini tidak valid karena Anda mengubah format input string ke array yang bukan sesuatu yang dapat dilakukan melalui input CLI. dan harus diprogram, Anda perlu membagi string ke dalam array untuk param pertama agar ini valid.
Martin Barker
@ MartinBarker Aturan mana yang Anda maksud? Diperbarui untuk mengambil 3 string.
Arnauld
Semua 3 dari parameter input mengatakan "string" sebagai C ++ string dapat langsung dibaca dan digunakan sebagai array dengan javascript itu tidak bisa.
Martin Barker
1

C (gcc) , 130 129 byte

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

Cobalah online!

-1 byte indexsebagai gantinya strchr.

Ini adalah pendekatan berulang sederhana, menggunakan kembali beberapa variabel (dan dengan demikian menyalahgunakan sizeof(int) == sizeof(char *)pada TIO) untuk menyimpan byte.

Memasukkan:

  • i nomor input
  • s karakter basis sumber
  • t karakter basis target

Keluaran:

  • r nomor hasil (penunjuk ke buffer)

Penjelasan:

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
sumber
Sarankan bcopy(r,r+1,++i)alih-alihmemmove(r+1,r,++i)
ceilingcat
1

Python 2 , 97 95 byte

Terima kasih kepada Chas Brown untuk -2 byte.

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

Cobalah online!

ovs
sumber
1

Java 10, 131 byte

Seorang lambda mengambil parameter dalam urutan sebagai string dan mengembalikan string.

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

Cobalah secara Online

Tidak disatukan

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