Convertitore base numeri personalizzato


30

I poteri che vogliono essere in grado di convertire rapidamente qualsiasi numero che hanno nella propria base numerica utilizzando qualsiasi formato desiderino.

Ingresso

Il tuo programma deve accettare 3 parametri.

  1. Numero: il numero di stringa da convertire
  2. InputFormat: la stringa di base in cui si trova attualmente il numero
  3. OutputFormat: la stringa di base in cui convertire il numero.

Produzione

Il programma deve convertire il Numberdalla vecchia base numerica InputFormatalla nuova base numericaOutputFormat

Esempi

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

addizionale

Il nuovo test 77 di base non è richiesto se funziona

  1. se sei in una lingua in cui devi prima convertirti in un numero e sei bloccato in 32 Bit puoi saltarlo.
  2. in quanto è un test aggiuntivo.

Tutti gli esempi sono stati generati da PHP 7.2 con l'estensione bcmath usando il seguente codice (var min ma codice formattato). probabilmente ci sarà un modo più breve, questo è solo il modo in cui mi sono inventato per il sistema con cui avevo bisogno di farlo, sarebbe bello vedere se qualcuno potesse trovare una versione più breve.

PHP 7.2 (bcmath - estensione) 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;
}

Provalo online

punteggio

Questo è il codice golf; vince il codice più breve. Si applicano scappatoie standard.


5
@WindmillCookies Indipendentemente dai caratteri presenti nelle stringhe del formato.
Adám,

6
Bella prima domanda! :-)
Giuseppe,


2
Potrebbe valere la pena aggiungere un caso di prova per una base "unica" - ad es ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (o qualunque cosa dovrebbe essere, se non è corretto)
Finisci la causa di Monica il

2
Suggerirei un caso di prova con più di 36 caratteri nei formati, per catturare chiunque utilizzi componenti incorporati che vanno solo alla base 36
Jo King,

Risposte:


13

....................... Sai, ho visto che ha Zafatto la conversione di base ma i documenti su matl.suever non erano chiari sul fatto che accettasse i caratteri della base, quindi non l'ho provato. RIP me!
Giuseppe,

@Giuseppe Haha, me lo sono ricordato solo perché sembrava un comando pronto per (ab) essere usato in qualche hack intelligente o due. Ironico del fatto che il mio primo utilizzo è come una risposta integrata. :)
Sundar - Ripristina Monica il

1
Il mio primo pensiero quando ho visto "Za" era "Lord, Harry Dresden". +1.
Finanzi la causa di Monica il

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

Provalo online!

Uh, questo è stato un doozy. Uso i tipici trucchi di conversione di base per R, ma le manipolazioni delle stringhe in R sono ancora disordinate!


Sfortunatamente questo non funzionerà con n = "0" ... dovresti aggiungere 2 byte facendo log(N+1,T)ma causando uno zero iniziale a volte, ad esempio quando converti 31 dalla base 10 alla base 2 :(
digEmAll

Per evitare il "problema zero" sul logaritmo senza zeri iniziali, non vedo molte altre soluzioni ... si potrebbe log(N+!N,T)ovviamente fare usando !il significato originale
digEmAll

@digEmAtutti i commenti del PO non sono ancora chiari, ma sembra che non sia necessario supportare zero.
Giuseppe,

Oh bene .. va bene allora :)
digEmAll

7

APL (Dyalog Unicode) , 22 byte

Infografica anonima lambda. Prende InputFormatcome argomento di sinistra e OutputFormatcome argomento di destra, e richiede Numberda stdin. Assume ⎕IO( I NDICE O rigine) di essere 0, che è di default su molti sistemi.

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

Provalo online!

{... } "dfn"; è argomento a sinistra, è argomento a destra
(mnemonico: estremità sinistra e destra dell'alfabeto greco)

⍵[... ] indicizza il formato di output con il seguente:

   richiesta di input

  ⍺⍳d ndice di quei caratteri nel formato di input

  (... )⊥ valuta di essere nella seguente base:

   ≢⍺ la lunghezza del formato di input

   cedere che (separa ¯1da (≢⍺))

  (... )⊥⍣¯1 converti nella seguente base:

  ≢⍺ la lunghezza del formato di output


7

Japt, 5 byte

Tornare al golf dopo una pausa di 2 settimane

nV sW

Provalo


Spiegazione

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

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

Questo deve essere compilato con

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

bandiera. (Sì, questo è incredibilmente abbozzato, motivo per cui sto mantenendo la mia vecchia risposta di seguito.) Ciò definisce una macro fche restituisce la risposta a STDOUT.

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

Provalo online!

Questo definisce una funzione fche invia la risposta 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
}

Puoi salvare 2 byte utilizzando putcharinvece di writee modificando leggermente il ciclo di decodifica: provalo online!
ErikF,

Questa indexfunzione mi ha salvato anche un byte con il mio approccio, non lo sapevo;)
Felix Palmen,

6

05AB1E , 5 byte

ÅβIÅв

Provalo online!

Questo non funziona nella versione legacy di 05AB1E. Funziona solo con la nuova versione, la riscrittura dell'Elisir.

Come funziona

ÅβIÅв - Programma completo.
Åβ: converte da base personalizzata a decimale.
  I - Premere il terzo ingresso.
   Åв - Converti da decimale a base personalizzata. 

Dichiari che funziona solo in 05AB1E v2 (non sei sicuro che sia il numero di versione corretto ..), ma hai comunque fornito un collegamento TIO. La versione Elixir è già su TIO ?! : S O funziona per la maggior parte dei casi di test, ma ci sono alcuni casi limite in cui funziona solo nella nuova versione?
Kevin Cruijssen,

2
05AB1E v2 è ora disponibile su TIO. 05AB1E (legacy) (cercalo nella barra tio) è il nome del vecchio 05AB1E e 05AB1E è il nome di quello nuovo. So che l'hai già visto nella chatroom, ma lo lascerò qui come riferimento per altri utenti.
Mr. Xcoder,

5

MATL , 5 byte

Sundar ha trovato il vero strumento per farlo! Vai a votare quella risposta invece della mia stupida :-(

ZAwYA

Provalo 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

Carbone , 5 byte

⍘⍘SSS

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

  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 BaseStringfunzione converte automaticamente tra numero e stringa in base al tipo del primo parametro.


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

Provalo online!

Una funzione anonima (grazie, Erik Outgolfer !) Che converte il numero originale in un numero intero di base 10, quindi passa l'intero e la nuova stringa di base alla funzione g (), che converte ricorsivamente nella nuova base. Ora passa la lunghezza di OutputFormat come parametro a g ().

Aggiornato g () per un numero inferiore di byte. (grazie, Dennis !)

Sostituito index () con find (). (grazie, signor Xcoder !)

Spiegazione non golfata:

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
Non è necessario f=, le funzioni anonime sono consentite per impostazione predefinita.
Erik the Outgolfer

@Erik the Outgolfer È consentito quando la funzione anonima chiama un'altra funzione, comunque?
Triggernometria

Finché includi le altre cose nel tuo Bytecount, sì, sei autorizzato a definire le variabili e importare i moduli.
Erik the Outgolfer

1
La funzione di aiuto può diventare g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis,

1
E quello principale può diventare 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 byte

iⱮ’ḅL{ṃ⁵ṙ1¤

Provalo online!

Ordine argomento: InputFormat, Number, OutputFormat. Assicurati di citare gli argomenti con una corretta evasione!


Hrm non sono sicuro di aver dichiarato esplicitamente l'ordine dei parametri ...
Martin Barker,

@MartinBarker I parametri sono presi nell'ordine 2, 1, 3 qui. Non riesco a vedere un requisito per un ordine specifico nella sfida e questo sarebbe scoraggiato.
Erik the Outgolfer

3
@MartinBarker Pro Suggerimento: sii flessibile con queste cose. Trovo che l'ordine degli ingressi sia completamente irrilevante quando si risolve un'attività, quindi suggerisco di consentire qualsiasi ordinamento arbitrariamente scelto dei parametri
Mr. Xcoder

lo avrei lasciato incollare comunque solo provando a provarlo ora.
Martin Barker,

2

Pyth, 21 byte

s@LeQjimx@Q1dhQl@Q1le

Suite di test

Spiegazione:
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 byte

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

Provalo online!

Blocco di codice anonimo che accetta 3 stringhe in ordine, input, formato di input e formato di output, quindi restituisce una stringa

Spiegazione:

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

Una subroutine dichiarata che accetta input, nnella lingua ye li proietta in lingua 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 byte

Accetta input come (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

Provalo online!


Siamo spiacenti, questo non è valido poiché stai modificando il formato di input della stringa in un array che non è qualcosa che può essere fatto tramite un input CLI. e deve essere programmato, è necessario dividere la stringa nell'array affinché il primo parametro sia valido.
Martin Barker,

@MartinBarker A quale regola ti riferisci? Aggiornato per prendere comunque 3 stringhe.
Arnauld,

Tutti e 3 i parametri di input indicano "stringa" come C ++ in cui una stringa può essere letta direttamente e utilizzata come array con javascript che non può essere.
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));}

Provalo online!

-1 byte utilizzando index invece di strchr.

Questo è un semplice approccio iterativo, riutilizzando alcune variabili (e quindi abusando sizeof(int) == sizeof(char *)su TIO) per salvare byte.

Ingresso:

  • i numero di input
  • s caratteri base sorgente
  • t personaggi base bersaglio

Produzione:

  • r numero risultato (puntatore a un buffer)

Spiegazione:

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
}

Suggerisci bcopy(r,r+1,++i)invece dimemmove(r+1,r,++i)
ceilingcat il

1

Python 2 , 97 95 byte

Grazie a Chas Brown per -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

Provalo online!


1

Java 10, 131 byte

Una lambda che prende i parametri in ordine di stringhe e restituisce una stringa.

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

Provalo 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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.