Convertidor de base de número personalizado

30

Los poderes que desean poder convertir rápidamente cualquier número que tengan en su propia base de números usando cualquier formato que deseen.

Entrada

Su programa debe aceptar 3 parámetros.

  1. Número: el número de cadena que se convertirá
  2. InputFormat: la cadena base en la que se encuentra actualmente el número
  3. OutputFormat: la cadena base a la que se convertirá el número.

Salida

Su programa debe convertir la Numberbase de números anterior InputFormata la nueva base de númerosOutputFormat

Ejemplos

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

La nueva prueba de base 77 no requiere accesorios si funciona

  1. si está en un idioma donde primero tiene que convertir a un número y está bloqueado dentro de 32 bits, puede omitirlo.
  2. ya que es una prueba adicional.

Todos los ejemplos fueron generados por PHP 7.2 con la extensión bcmath usando el siguiente código (vars minutos pero con formato de código). probablemente habrá una forma más corta, esta es la forma en que se me ocurrió el sistema con el que necesitaba hacer esto, sería bueno ver si alguien podría llegar a una versión más corta.

PHP 7.2 (bcmath - extensión) 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;
}

Pruébalo en línea

Tanteo

Este es el código de golf; el código más corto gana. Se aplican lagunas estándar.

Martin Barker
fuente
55
@WindmillCookies Por los caracteres que estén en las cadenas de formato.
Adám
66
Buena primera pregunta! :-)
Giuseppe
2
Estrechamente relacionado .
AdmBorkBork
2
Puede valer la pena agregar un caso de prueba para una base "única", por ejemplo ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (o lo que sea que debería ser, si eso es incorrecto)
Fund Monica's Lawsuit
2
Sugeriría un caso de prueba con más de 36 caracteres en los formatos, para atrapar a cualquiera que use elementos integrados que solo suben a la base 36
Jo King

Respuestas:

13

MATL , 2 bytes

Za

Pruébalo en línea!
Todos los casos de prueba.

¡Por el señor Za !

sundar - Restablece a Monica
fuente
....................... sabes, vi que Zahizo una conversión de base pero los documentos en matl.suever no estaban claros de que aceptara los caracteres de la base, así que no lo probé ¡Rasgarme!
Giuseppe
@Giuseppe Jaja, lo recordé solo porque parecía un comando que está listo para (ab) usar en algún truco inteligente o dos. Es irónico que mi primer uso sea como una respuesta integrada directa. :)
sundar - Restablecer Monica
1
Mi primer pensamiento cuando vi "Za" fue "señor Harry Dresden". +1.
Financia la demanda de Mónica el
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

Pruébalo en línea!

Ugh, esto fue un doozy. Utilizo los típicos trucos de conversión de bases para R, ¡pero las manipulaciones de cadenas en R siguen siendo desordenadas!

Giuseppe
fuente
Desafortunadamente, esto no funcionará con n = "0" ... debe agregar 2 bytes haciendo log(N+1,T)pero causando un cero
inicial a
Para evitar el "problema de cero" en el logaritmo sin ceros a la izquierda, no veo muchas otras soluciones ... log(N+!N,T)por supuesto, podría hacerlo !con el significado original
digEmAll
@digEmAll Los comentarios del OP todavía no están claros, pero parece que no es necesario que sea compatible con cero.
Giuseppe
Oh bueno ... está bien entonces :)
digEmAll
7

APL (Dyalog Unicode) , 22 bytes

Anónimo infijo lambda. Toma InputFormatcomo argumento izquierdo y OutputFormatcomo argumento derecho, y solicita Numberdesde stdin. Asume ⎕IO( I ndex O rigin) ser 0, que es predeterminado en muchos sistemas.

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

Pruébalo en línea!

{... } "dfn"; es argumento izquierdo, es argumento derecho
(mnemónico: extremos izquierdo y derecho del alfabeto griego)

⍵[... ] indexe el formato de salida con lo siguiente:

   solicitud de entrada

  ⍺⍳ɩ ndices de esos caracteres en el formato de entrada

  (... )⊥ evaluar como estar en la siguiente base:

   ≢⍺ la longitud del formato de entrada

   rendimiento que (se separa ¯1de (≢⍺))

  (... )⊥⍣¯1 convertir a la siguiente base:

  ≢⍺ la longitud del formato de salida

Adán
fuente
7

Japt, 5 bytes

Volviendo al golf después de un descanso de 2 semanas

nV sW

Intentalo


Explicación

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

C (gcc), 79 + 46 = 125 bytes

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

Esto debe compilarse con el

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

bandera. (Sí, esto es increíblemente incompleto, por eso mantengo mi respuesta anterior a continuación). Esto define una macro fque genera la respuesta a STDOUT.

Pruébalo en línea!

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

Pruébalo en línea!

Esto define una función fque genera la respuesta a 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
}
Pomo de la puerta
fuente
Puede guardar 2 bytes utilizando en putcharlugar de writey cambiando ligeramente el ciclo de decodificación: ¡ Pruébelo en línea!
ErikF
Esta indexfunción también me salvó un byte con mi enfoque, no lo sabía;)
Felix Palmen
6

05AB1E , 5 bytes

ÅβIÅв

Pruébalo en línea!

Esto no funciona en la versión heredada de 05AB1E. Solo funciona en la nueva versión, la reescritura de Elixir.

Cómo funciona

ÅβIÅв - Programa completo.
Åβ - Convertir de base personalizada a decimal.
  I - Empuje la tercera entrada.
   Åв - Convertir de decimal a base personalizada. 
Sr. Xcoder
fuente
Usted afirma que solo funciona en 05AB1E v2 (no estoy seguro si ese es el número de versión correcto ...), pero aún así proporcionó un enlace TIO. ¿La versión Elixir ya está en TIO? : S ¿O funciona para la mayoría de los casos de prueba, pero hay algunos casos extremos donde solo funciona en la nueva versión?
Kevin Cruijssen
2
05AB1E v2 ya está disponible en TIO. 05AB1E (heredado) (búscalo en la barra de tio) es el nombre del antiguo 05AB1E y 05AB1E es el nombre del nuevo. Sin embargo, sé que ya lo has visto en la sala de chat, pero lo dejaré aquí como referencia para otros usuarios.
Sr. Xcoder
5

MATL , 5 bytes

¡Sundar encontró al verdadero constructor para hacer esto! Vota esa respuesta en lugar de la tonta :-(

ZAwYA

Pruébalo en línea!

          % 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
fuente
4

Carbón de leña , 5 bytes

⍘⍘SSS

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

  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

La BaseStringfunción convierte automáticamente entre número y cadena dependiendo del tipo del primer parámetro.

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

Pruébalo en línea!

Una función anónima (¡gracias, Erik the Outgolfer !) Que convierte el número original en un entero base 10, luego pasa el entero y la nueva cadena base a la función g (), que se convierte recursivamente a la nueva base. Ahora pasa la longitud de OutputFormat como parámetro a g ().

Se actualizó g () para un bytecount más bajo. (gracias, Dennis !)

Se reemplazó index () con find (). (¡Gracias, señor Xcoder !)

Explicación no golfista:

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
Triggernometry
fuente
1
No es necesario f=, las funciones anónimas están permitidas de forma predeterminada.
Erik the Outgolfer
@Erik the Outgolfer ¿Está permitido cuando la función anónima llama a otra función, aunque?
Triggernometry
Siempre que incluya las otras cosas en su bytecount, sí, puede definir variables e importar módulos.
Erik the Outgolfer
1
La función auxiliar puede convertirse g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis
1
Y el principal puede convertirse lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
Sr. Xcoder
2

Jalea , 11 bytes

iⱮ’ḅL{ṃ⁵ṙ1¤

Pruébalo en línea!

Orden de argumento: InputFormat, Number, OutputFormat. ¡Asegúrese de citar los argumentos con el escape adecuado!

Erik el Outgolfer
fuente
No estoy seguro de haber declarado explícitamente el orden de los params ...
Martin Barker
@MartinBarker Los parámetros se toman en orden 2, 1, 3 aquí. No puedo ver un requisito para un orden específico en el desafío, y eso sería desalentado.
Erik the Outgolfer
3
@MartinBarker Pro Consejo: Sea flexible con tales cosas. Creo que el orden de las entradas es completamente irrelevante al resolver una tarea, por lo que le sugiero que permita cualquier orden arbitrariamente elegido de los parámetros
Sr. Xcoder
Iba a dejarlo pegar de todos modos solo tratando de probarlo ahora.
Martin Barker
2

Pyth, 21 bytes

s@LeQjimx@Q1dhQl@Q1le

Banco de pruebas

Explicación:
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
fuente
2

Haskell , 119 bytes

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

Pruébalo en línea!

ბიმო
fuente
2

Perl 6 , 100 97 bytes

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

Pruébalo en línea!

Bloque de código anónimo que toma 3 cadenas en orden, entrada, formato de entrada y formato de salida, luego devuelve una cadena

Explicación:

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

VBA, 182 bytes

Una subrutina declarada que toma datos, nen el idioma yy los proyecta en el 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
Taylor Scott
fuente
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

Pruébalo en línea!

Arnauld
fuente
Lo sentimos, esto no es válido ya que cambia el formato de entrada de la cadena a una matriz que no es algo que se pueda hacer a través de una entrada CLI. y tiene que ser programado, necesita dividir la cadena en la matriz para que el primer parámetro sea válido.
Martin Barker
@MartinBarker ¿A qué regla te refieres? Actualizado para tomar 3 cuerdas de todos modos.
Arnauld
Los 3 parámetros de entrada dicen "cadena" como C ++, una cadena puede leerse directamente y usarse como una matriz con javascript que no puede ser.
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));}

Pruébalo en línea!

-1 byte usando en indexlugar de strchr.

Este es un enfoque iterativo simple, reutilizando algunas variables (y por lo tanto abusando sizeof(int) == sizeof(char *)de TIO) para guardar bytes.

Entrada:

  • i número de entrada
  • s caracteres base de origen
  • t personajes base objetivo

Salida:

  • r número de resultado (puntero a un búfer)

Explicación:

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
fuente
Sugerir en bcopy(r,r+1,++i)lugar dememmove(r+1,r,++i)
ceilingcat
1

Python 2 , 97 95 bytes

Gracias 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

Pruébalo en línea!

ovs
fuente
1

Java 10, 131 bytes

Una lambda que toma los parámetros en orden como cadenas y devuelve una cadena.

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

Pruébalo en línea

Sin golf

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