Özel Sayı Baz Çevirici


30

İstedikleri herhangi bir formatı kullanarak sahip oldukları herhangi bir sayıyı hızlı bir şekilde kendi sayı tabanlarına dönüştürmek isteyen güçler.

Giriş

Programınız 3 parametre kabul etmelidir.

  1. Sayı: Dönüştürülecek dize numarası
  2. InputFormat: Numaranın bulunduğu dizge
  3. OutputFormat: Sayının dönüştürüleceği temel dize.

Çıktı

Programınız Numbereski sayı tabanından InputFormatyeni sayı tabanına dönüştürülmeliOutputFormat

Örnekler

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

Ek

Yeni taban 77 testi, eğer çalışırsa

  1. Eğer bir numaraya dönüştürmek zorunda olduğunuz ve 32Bit içinde kilitli kaldığınız bir dilde bunu atlayabilirsiniz.
  2. ek bir test olduğu gibi.

Tüm örnekler PHP 7.2 tarafından aşağıdaki kodu kullanarak bcmath uzantılı olarak üretildi (dakika olarak değişir, ancak kod formatlandı). Muhtemelen daha kısa bir yol olacak. Bu, sadece bununla birlikte yapmam gereken sistem için geldiğim yolun, eğer daha kısa bir versiyonun gelip gelmeyeceğini görmek güzel olurdu.

PHP 7.2 (bcmath - uzantı) 614 bayt

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

Çevrimiçi Deneyin

puanlama

Bu kod golf; en kısa kod kazanır. Standart boşluklar uygulanır.


5
@WindmillCookies Biçim dizelerinde hangi karakter olursa olsun.
Adám

6
Güzel ilk soru! :-)
Giuseppe


2
Örneğin, "benzersiz" bir temel için bir test senaryosu eklemeye değer olabilir ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (ya da her ne olursa olsun, eğer doğru değilse,)
Fon Monica'nın Davası

2
Biçimlerde 36 karakterden fazla olan bir test durumu öneriyorum, yalnızca üsse
Jo King

Yanıtlar:


13

....................... biliyorsunuz, Zabunun temel dönüşüm yaptığını gördüm, ancak matl.suever'daki dokümanlar, tabanın karakterlerini kabul ettiği konusunda net değildi. bu yüzden denemedim. Öldüm!
Giuseppe

@Giuseppe Haha, bunu hatırladım, çünkü sadece bir ya da iki kesmek için (ab) kullanması için uygun bir komut gibi görünüyordu. İronik olarak kullanmamın açık bir yerleşik cevap olarak kullanılması. :)
sundar - Monica

1
"Za" yı gördüğümde ilk düşüncem "Lord, Harry Dresden" idi. +1.
Fon Monica'nın Davası

8

R , 124 bayt

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

Çevrimiçi deneyin!

Ugh, bu bir doozydi. R için tipik temel dönüşüm hilelerini kullanırım, ancak R'deki string manipülasyonları hala karışık!


Maalesef n = ile bu olmaz eser "0" ... Eğer 2 byte yapıyor eklemek gerekir log(N+1,T)Eğer :( 2 tabanında, 10 tabanında 31 dönüştürdüğünüzde ama bazen örneğin bir lider sıfır neden
digEmAll

Önde gelen sıfır olmadan logaritmadaki "sıfır sayısından" kaçınmak için, başka pek çok çözüm göremiyorum ... log(N+!N,T)elbette !orijinal anlamını kullanarak yapabilirdiniz
digEmAll

@digEmTüm OP'nin yorumları hala net değil, ancak sıfırın desteklenmesi gerekmiyor gibi görünüyor.
Giuseppe

Oh iyi .. o zaman sorun değil :)
digEmAll

7

APL (Dyalog Unicode) , 22 bayt

Anonim infix lambda. Alır InputFormatsol argüman olarak ve OutputFormatsağ argüman olarak ve sorulmasına NumberStdin'den. Devraldı ⎕IO( Ben nDex Ç rigin) olmak 0üzere birçok sistem üzerine varsayılan olan.

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

Çevrimiçi deneyin!

{} "Dfn"; sol argüman, sağ argüman
(hatırlatıcı: Yunan alfabesinin sol ve sağ uçları)

⍵[] Çıkış formatını aşağıdaki gibi indeksleyin:

   giriş istemi

  ⍺⍳ɩ giriş formatında bu karakterlerin ndices

  ()⊥ Aşağıdaki temelde olduğunu değerlendirin:

   ≢⍺ giriş biçiminin uzunluğu

   verim ki (ayırır ¯1gelen (≢⍺))

  ()⊥⍣¯1 Aşağıdaki tabana dönüştürün:

  ≢⍺ çıkış formatının uzunluğu


7

Japt, 5 bayt

2 haftalık moladan sonra tekrar golfe girme

nV sW

Dene


açıklama

           :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 bayt

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

Bu derlenmeli

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

bayrağı. (Evet, bu inanılmaz derecede kabataslak, bu yüzden eski cevabımı aşağıda tutuyorum.) Bu f, cevabı STDOUT'a veren bir makroyu tanımlar .

Çevrimiçi deneyin!

C (gcc), 133 131 bayt

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

Çevrimiçi deneyin!

Bu f, cevabı STDOUT'a veren bir fonksiyon tanımlar .

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
}

Kod çözme döngüsünü putcharyerine kullanarak writeve değiştirerek 2 bayttan tasarruf edebilirsiniz : Çevrimiçi deneyin!
ErikF

Bu indexişlev benim yaklaşımımla da beni bir bayt kurtardı,
Felix Palmen

6

05AB1E , 5 bayt

ÅβIÅв

Çevrimiçi deneyin!

Bu mu değil 05AB1E mirası sürümünde çalışmaz. Sadece yeni sürümde çalışır, Elixir yeniden yazar.

Nasıl çalışır

ÅβIÅв - Tam program.
Åβ - Özel tabandan ondalık basamağa dönüştür.
  I - Üçüncü girişi itin.
   Åв - Ondalık sayıdan özel tabana dönüştürme. 

Yalnızca 05AB1E v2'de çalıştığını belirtirsiniz (doğru sürüm numarası olup olmadığından emin değildir ..), ancak yine de bir TIO bağlantısı sağladınız. Elixir sürümü zaten TIO'da mı? : S Veya çoğu sınama durumu için işe yarar, ancak yalnızca yeni sürümde çalıştığı bazı son durumlar var mı?
Kevin Cruijssen

2
05AB1E v2 artık TIO'da mevcut. 05AB1E (eski) (tio çubuğunda arayın) eski 05AB1E'nin adı ve 05AB1E yeni olanın adıdır. Bunu zaten sohbet odasında gördüğünüzü biliyorum, ama burada diğer kullanıcılar için referans olarak bırakacağım.
Bay Xcoder

5

MATL , 5 bayt

Sundar bunu yapmak için gerçek yerleşik buldu! Benim aptal yerine bu cevabı yükselt :-(

ZAwYA

Çevrimiçi deneyin!

          % 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

Kömür , 5 bayt

⍘⍘SSS

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

  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

BaseStringFonksiyonu otomatik olarak ilk parametre tipine bağlı olarak sayı ve dize arasında dönüştürür.


3

Python 2 , 132 129 122 121 bayt

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

Çevrimiçi deneyin!

Orijinal sayıyı bir 10 tamsayıya dönüştüren adsız bir işlev (teşekkürler, Outgolfer Erik !), Daha sonra tamsayıyı ve yeni taban dizesini yinelemeli olarak yeni ana birimine dönüştüren g () işlevine geçirir. Şimdi OutputFormat'ın uzunluğunu g () parametresi olarak geçirir.

Daha düşük bir bytecount için g () güncellendi. (teşekkürler, Dennis !)

Index (), find () ile değiştirildi. (teşekkürler, Bay Xcoder !)

Ungolfed Açıklama:

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
İhtiyacınız yok f=, isimsiz fonksiyonlara varsayılan olarak izin verilir.
Outgolfer Erik

@ Outgolfer Adsız işlev başka bir işlev çağırdığında buna izin var mı, tho?
Triggernometry

Diğer öğeleri bytecount'unuza eklediğiniz sürece, evet, değişkenleri tanımlamanıza ve modülleri içe aktarmanıza izin verilir.
Outgolfer Erik

1
Yardımcı işlev olabilir g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis

1
Ve asıl olan olabilir lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
Bay Xcoder

2

Jöle , 11 bayt

iⱮ’ḅL{ṃ⁵ṙ1¤

Çevrimiçi deneyin!

Bağımsız değişken sırası: InputFormat, Number, OutputFormat. Argümanları uygun bir şekilde kaçmayı önerdiğinizden emin olun!


Hrm, açıkça paramların sırasını belirttiğimden emin değilim ...
Martin Barker

@MartinBarker Params burada 2, 1, 3 sırayla alınır. Mücadelede belirli bir düzen için bir gereksinim göremiyorum ve bu cesareti kırılacaktı.
Outgolfer Erik

3
@MartinBarker Pro Tip: Böyle şeylerle esnek olun. Bir görevi çözerken girdilerin sırasının tamamen alakasız olduğunu buluyorum, bu nedenle parametrelerin herhangi bir isteğe bağlı olarak seçilmesine izin vermenizi öneriyorum
Bay Xcoder

Şimdi denemeye çalışmasına rağmen yapışmasına izin verecektim.
Martin Barker,

2

Pyth, 21 bayt

s@LeQjimx@Q1dhQl@Q1le

Test odası

Açıklama:
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 bayt

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

Çevrimiçi deneyin!

Sıralı, giriş, giriş formatı ve çıkış biçiminde 3 dizeyi alan adsız kod bloğu, ardından bir dizge döndürür

Açıklama:

{  # 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 bayt

nDilde yve bu dile projeksiyonda girdi alan, beyan edilen bir alt yordam 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 bayt

Girişi olarak alır (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

Çevrimiçi deneyin!


Maalesef, bu, dizenin giriş biçimini, bir CLI girişi ile yapılabilecek bir şey olmayan bir diziye değiştirdiğiniz için geçerli değildir. ve bunun geçerli olması için ilk param için dizeyi diziye bölmeniz gerekir.
Martin Barker

@MartinBarker Hangi kuralı kastediyorsunuz? Yine de 3 string almak için güncellendi.
Arnauld

Girdi parametrelerinin 3'ü de C ++ olarak "string" yazıyor, dize doğrudan okunabiliyor ve javascript ile dizilemedi.
Martin Barker,

1

C (gcc) , 130 129 bayt

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

Çevrimiçi deneyin!

-1 bayt indexyerine kullanın strchr.

Bu, sizeof(int) == sizeof(char *)baytları kurtarmak için bazı değişkenleri (ve böylece TIO'yu kötüye kullanan ) yeniden kullanarak basit bir yinelemeli yaklaşımdır .

Giriş:

  • i Numara giriniz
  • s kaynak temel karakterleri
  • t hedef taban karakterleri

Çıktı:

  • r sonuç numarası (bir tampon için işaretçi)

Açıklama:

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
}

Öner bcopy(r,r+1,++i)yerinememmove(r+1,r,++i)
ceilingcat

1

Python 2 , 97 95 bayt

-2 bayt için Chas Brown'a teşekkürler.

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

Çevrimiçi deneyin!


1

Java 10, 131 bayt

Parametreleri dizge olarak alarak bir dize döndüren bir lambda.

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

Çevrimiçi Deneyin

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.