Conversor de Base de Número Personalizado


30

Os poderes desejados poderão converter rapidamente qualquer número que eles possuírem em sua própria base de números, usando o formato que desejar.

Entrada

Seu programa deve aceitar 3 parâmetros.

  1. Number: o número da string a ser convertida
  2. InputFormat: a string base em que o número está atualmente
  3. OutputFormat: a cadeia de base na qual o número deve ser convertido.

Saída

Seu programa deve converter a Numberbase de números antiga InputFormatpara a nova base de númerosOutputFormat

Exemplos

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

Adicional

O novo teste da base 77 não é necessário, se ele funcionar

  1. se você estiver em um idioma no qual você precisa primeiro converter para um número e estiver bloqueado no 32Bit, poderá ignorá-lo.
  2. como é um teste adicional.

Todos os exemplos foram gerados pelo PHP 7.2 com a extensão bcmath usando o código a seguir (vars mins mas código formatado). provavelmente haverá uma maneira mais curta. Foi exatamente dessa maneira que eu criei para o sistema com o qual eu precisava fazer isso. Seria bom ver se alguém poderia ter uma versão mais curta.

PHP 7.2 (bcmath - extensão) 614 bytes

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

Experimente Online

Pontuação

Isso é código de golfe; o código mais curto vence. Aplicam-se brechas padrão.


5
@WindmillCookies Por qualquer caractere que esteja nas cadeias de caracteres de formato.
— Adám 16/08/19

6
Boa primeira pergunta! :-)
— Giuseppe


2
Pode valer a pena adicionar um caso de teste para uma base "única" - por exemplo ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (ou seja lá o que realmente deve ser, se isso é incorreto)
— Ação do Fundo Monica

2
Eu sugeriria um caso de teste com mais de 36 caracteres nos formatos, para capturar qualquer pessoa usando built-ins que só vão até a base 36
— Jo King

Respostas:


13

....................... você sabe, vi que a Zaconversão base, mas os documentos em matl.suever não estavam claros de que aceitavam os caracteres da base, então eu não tentei. RIP me!
— Giuseppe

@ Giuseppe Haha, eu me lembrei apenas porque parecia um comando pronto para (ab) usar em algum truque inteligente ou dois. Irônico que meu primeiro uso seja uma resposta direta. :)
— sundar - Restabelece Monica 16/08

1
Meu primeiro pensamento quando vi "Za" foi "senhor, Harry Dresden". +1.
— Fund Monica's Lawsuit

8

R , 124 bytes

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

Experimente online!

Ugh, isso foi doozy. Eu uso os truques típicos de conversão de base para R, mas as manipulações de string em R ainda são confusas!


Infelizmente isso não funcionará com n = "0" ... você deve adicionar 2 bytes fazendo log(N+1,T) , mas causando um zero à esquerda, por vezes, por exemplo, quando você converter 31 da base 10 a base 2 :(
— digEmAll

Para evitar o "problema zero" no logaritmo sem zeros à esquerda, não vejo muitas outras soluções ... é log(N+!N,T)claro que você poderia usar! com o significado original
— digEmAll

Todos os comentários do OP ainda são um pouco incertos, mas parece que o zero não precisa ser suportado.
— Giuseppe

Oh bem ... tudo bem então :) :)
— digEmAll

7

APL (Dyalog Unicode) , 22 bytes

Infix anônimo lambda. Toma InputFormatcomo argumento à esquerda e OutputFormatcomo argumento à direita e solicita a Numberpartir de stdin. Assume ⎕IO( I ndex O rigin) como sendo 0, o padrão em muitos sistemas.

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

Experimente online!

{... } "dfn"; ⍺é argumento à esquerda, ⍵é argumento à direita
 (mnemônico: extremidades esquerda e direita do alfabeto grego)

 ⍵[...]  Indexe o formato de saída com o seguinte:

  ⎕ solicitação de entrada

  ⍺⍳ ɩ índices desses caracteres no formato de entrada

  (...)⊥  Avalie como estando na seguinte base:

   ≢⍺ o comprimento do formato de entrada

  ⊢ rendimento que (separa ¯1de (≢⍺))

  (… )⊥⍣¯1 Converta para a seguinte base:

  ≢⍺ o comprimento do formato de saída


7

Japt, 5 bytes

Regressando ao golfe após um intervalo de 2 semanas

nV sW

Tente


Explicação

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

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

Isso deve ser compilado com o

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

bandeira. (Sim, isso é incrivelmente superficial, e é por isso que estou mantendo minha resposta antiga abaixo.) Isso define uma macro fque gera a resposta para STDOUT.

Experimente online!

C (gcc), 133 131 bytes

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

Experimente online!

Isso define uma função fque envia a resposta para 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
}

Você pode economizar 2 bytes usando em putcharvez de writee alterando um pouco o loop de decodificação: Experimente online!
— ErikF 17/08/19

Esta indexfunção salva-me um byte, bem como com a minha abordagem, não sabia sobre isso;)
— Felix Palmen

6

05AB1E , 5 bytes

ÅβIÅв

Experimente online!

Isso não funciona na versão herdada do 05AB1E. Funciona apenas na nova versão, reescrita do Elixir.

Como funciona

ÅβIÅв - Programa completo.
Åβ - Converte da base personalizada para decimal.
  I - Pressione a terceira entrada.
   Åв - Converte de decimal para base personalizada. 

Você afirma que só funciona no 05AB1E v2 (não tem certeza se esse é o número da versão correto ..), mas ainda forneceu um link TIO. A versão do Elixir já está no TIO ?! : S Ou funciona para a maioria dos casos de teste, mas há alguns casos extremos em que funciona apenas na nova versão?
— Kevin Cruijssen 17/08/1918

2
05AB1E v2 já está disponível no TIO. 05AB1E (legado) (procure na barra de tio) é o nome do antigo 05AB1E e 05AB1E é o nome do novo. Eu sei que você já viu isso na sala de bate-papo, no entanto, mas vou deixar aqui como uma referência para outros usuários.
— Xcoder

5

MATL , 5 bytes

sundar encontrou o real embutido para fazer isso! Voto acima dessa resposta em vez da minha idiota :-(

ZAwYA

Experimente 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.

4

Carvão , 5 bytes

⍘⍘SSS

Experimente online! Link é a versão detalhada do código. Explicação:

  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

A BaseStringfunção converte automaticamente entre número e string, dependendo do tipo do primeiro parâmetro.


3

Python 2 , 132 129 122 121 bytes

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

Experimente online!

Uma função anônima (obrigado, Erik o Outgolfer !), Que converte o número original em um número inteiro de base 10, depois passa o número inteiro e a nova string de base para a função g (), que converte recursivamente para a nova base. Agora passa o comprimento do OutputFormat como um parâmetro para g ().

Atualizado g () para um número de bytes mais baixo. (obrigado, Dennis !)

Índice substituído () por find (). (obrigado, Sr. Xcoder !)

Explicação 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

1
Você não precisa f=, funções anônimas são permitidas por padrão.
— Erik the Outgolfer

@Erik the Outgolfer Isso é permitido quando a função anônima chama outra função, tho?
— Triggernometry

Desde que você inclua os outros itens no seu número de bytes, sim, você poderá definir variáveis ​​e importar módulos.
— Erik the Outgolfer

1
A função auxiliar pode se tornar g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
— Dennis

1
E o principal pode se tornar lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
— Mr. Xcoder

2

Gelatina , 11 bytes

iⱮ’ḅL{ṃ⁵ṙ1¤

Experimente online!

Ordem dos argumentos: InputFormat, Number, OutputFormat. Certifique-se de citar os argumentos com escape apropriado!


Hrm não sei se dizia explicitamente a ordem dos parâmetros ...
— Martin Barker

@MartinBarker Os parâmetros são obtidos na ordem 2, 1, 3 aqui. Não vejo um requisito para uma ordem específica no desafio, e isso seria desencorajado.
— Erik the Outgolfer

3
@MartinBarker Pro Dica: Seja flexível com essas coisas. Acho que a ordem das entradas para ser completamente irrelevante quando resolver uma tarefa, então eu sugiro que você permitir que qualquer ordenação escolhido arbitrariamente dos parâmetros
— Mr. Xcoder

eu ia deixar assim mesmo, tentando testá-lo agora.
— Martin Barker

2

Pitão, 21 bytes

s@LeQjimx@Q1dhQl@Q1le

Suíte de teste

Explicação:
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 bytes

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

Experimente online!

Bloco de código anônimo que utiliza três cadeias de caracteres em ordem, entrada, formato de entrada e formato de saída e retorna uma string

Explicação:

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

Uma sub-rotina declarada que recebe entrada,, nno idioma ye os projeta no idioma 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 bytes

Toma entrada como (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

Experimente online!


Desculpe, isso não é válido, pois você altera o formato de entrada da sequência para uma matriz que não é algo que pode ser feito por meio de uma entrada da CLI. e precisa ser programado, você precisa dividir a string na matriz para que o primeiro parâmetro seja válido.
— Martin Barker

@MartinBarker A qual regra você está se referindo? Atualizado para levar três seqüências de qualquer maneira.
— Arnauld

Todos os três parâmetros de entrada dizem que "string", como C ++, uma string pode ser lida diretamente e usada como uma matriz com javascript.
— Martin Barker

1

C (gcc) , 130 129 bytes

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

Experimente online!

-1 byte usando em indexvez de strchr.

Essa é uma abordagem iterativa simples, reutilizando algumas variáveis ​​(e, dessa forma, abusando sizeof(int) == sizeof(char *) do TIO) para salvar bytes.

Entrada:

  • i número de entrada
  • s caracteres base de origem
  • t caracteres base de destino

Saída:

  • r número do resultado (ponteiro para um buffer)

Explicação:

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
}

Sugerir em bcopy(r,r+1,++i)vez dememmove(r+1,r,++i)
— tetocat 21/08

1

Python 2 , 97 95 bytes

Agradecimentos a Chas Brown por -2 bytes.

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

Experimente online!


1

Java 10, 131 bytes

Um lambda pegando os parâmetros em ordem como strings e retornando uma 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;}

Experimente Online

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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.