Encuentra la suma de todas las representaciones base posibles

20

El objetivo de este desafío es escribir un programa para convertir una cadena incorporada de lo que se puede suponer que contiene solo letras y números de tantas bases entre 2 y 36 como sea posible, y encontrar la base 10 de la suma de los resultados.

La cadena de entrada se convertirá a todas las bases en el que se define el número según el alfabeto estándar para bases hasta 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Por ejemplo, la entrada 2Tsería válida solo en bases 30 y superiores. El programa convertiría 2T de las bases 30 a 36 en decimal y sumaría los resultados.

Puede suponer que la cadena de entrada contiene solo letras y números. Su programa puede usar mayúsculas o minúsculas; puede, pero no necesita, soportar ambos.


Casos de prueba

Entrada de muestra: 2T

Gráfico de posibles bases

Base   Value
30     89
31     91
32     93
33     95
34     97
35     99
36     101

Salida: 665

Entrada de muestra: 1012

Gráfico de posibles bases:

Base   Value
3      32
4      70
5      132
6      224
7      352
8      522
9      740
10     1012
11     1344
12     1742
13     2212
14     2760
15     3392
16     4114
17     4932
18     5852
19     6880
20     8022
21     9284
22     10672
23     12192
24     13850
25     15652
26     17604
27     19712
28     21982
29     24420
30     27032
31     29824
32     32802
33     35972
34     39340
35     42912
36     46694

Salida: 444278

Entrada de muestra: HELLOworld

Gráfico de posibles bases

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Salida: 5008425418187214

Una entrada de 0se leería como 0en todas las bases entre 2 y 36 inclusive. No existe tal cosa como la base 1.


Este es el código de golf. Aplican reglas estándar. El código más corto en bytes gana.

Arcturus
fuente
55
¿Están permitidos los incorporados para la conversión de base?
lirtosiast
2
Caso de prueba importante:0
Martin Ender
Maldita sea, iba a publicar un desafío muy similar.
DanTheMan
3
@ MartinBüttner ¿Por qué es 0un caso de prueba importante? 0está 0en cada base, y no existe tal cosa como la base 1.
Arcturus
3
@Eridan porque algunos idiomas pueden intentar convertir eso desde la base 1 y fallar.
Martin Ender

Respuestas:

12

Python 3, 72 71 69 bytes

¡Gracias a FryAmTheEggman por guardar un byte!

¡Gracias a DSM por guardar 2 bytes!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)
Adnan
fuente
@ThomasKwa que agregará un cero, que no funcionará para entradas puramente numéricas, ya que funciona como verificar si es base 10 (lo que hará que algunos resultados sean demasiado grandes)
Kevin W.
@FryAmTheEggman ¡Gracias! Lo he ajustado
Adnan
Acabo de comprobar por ti. El try exceptte dejará hacer range(37). ¡Dos bytes!
Sherlock9
@ Sherlock9 No funcionará para entradas puramente numéricas, estas se interpretarán como números de base 10.
Adnan
Oh cierto, maldita sea. @Adnan
Sherlock9
10

Pyth, 20 19 11 bytes

sm.xizd0S36

Se robó descaradamente la idea de Adnan de su respuesta de Python.

Pruébalo aquí

orlp
fuente
@orlp Puedes eliminar el Scarbón
Azul
No Prueba 1012.
orlp
4

Pure Bash (sin utilidades), 38

Asumiendo que las conversiones base incorporadas están permitidas:

for((b=36;s+=$b#$1;b--));{ :;}
echo $s

Esto generará un error en STDERR. Supongo que esto está bien según esta meta respuesta .

Prueba de salida:

$ for t in 0 2T 1012 HELLOworld; do ./basesum.sh $t; done 2> /dev/null
0
665
444278
5008425418187214
$ 
Trauma digital
fuente
3

Mathematica, 57 bytes

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&
alephalpha
fuente
Puede usar el formulario infijo para FromDigits.
LegionMammal978
3

En serio, 65 bytes

,û;╗rk`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`MSd:37:@x`╜¿`MΣ.

Contiene no imprimibles, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Desafortunadamente, no tengo una buena manera de filtrar de una lista basada en tipos. Nota para uno mismo: agregue eso.

Toma entrada como "2T"

Pruébelo en línea (deberá ingresar la entrada manualmente)

Explicación:

,û    get input and convert to uppercase
;╗    make a copy and save to register 0
rk    explode string into list
`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`M  map the function over the list:
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu    get the character's index in the string and add one to get a value in [1,36]
Sd    get maximum element (maximum base aka max_base) from list by sorting and popping the last element off and pushing it to the stack
:37:@x  push range(max_base,37)
`╜¿`M  map the function over the list:
    ╜¿    convert value in register 0 to an int, interpreting it as a base-n int (n is value from list)
Σ.    sum and print
0x7f  quit
Mego
fuente
¿Quizás en serio debería tener un comando que produce el alfabeto y / o los números 0-9?
Arcturus
@Eridan En serio debería: obtener ese índice cuesta la mitad de los bytes.
Mego
2

Matlab, 98 bytes

function y=f(s)
[~,m]=max(bsxfun(@eq,s,[48:57 65:90]'));y=0;for n=max(m):36
y=y+base2dec(s,n);
end
Luis Mendo
fuente
2

Octava, 75 73 bytes

function v=u(a) m([48:57 65:90])=0:35;v=sum(polyval(t=m(a),max(t)+1:36));

Explicación:

function v=u(a) 
   m([48:57 65:90])=0:35; %// create a map: '0'-'9' = 0-9
                          %//               'A'-'Z' = 10-35
   t=m(a);                %// convert string to mapped values
   b=max(t)+1;            %// find minimum base
   p=polyval(t,b:36);     %// calculate polynomial for each base (vectorized)
   v=sum(p);              %// and return the sum of the resulting vector

polyvaltiene una ventaja sobre base2decque está vectorizado, por lo que no forse requiere bucle.

Solo se admiten '0' ... '9' y mayúsculas 'A' ... 'Z' como entrada.

cubilete
fuente
¡Uso muy inteligente de polyvalvectorizar!
Luis Mendo
1

Japt , 26 bytes

1+U¬r@XwYn36}0)o37 £UnX} x

Pruébalo en línea!

Sin golfos y explicación

1+U¬ r@   XwYn36}0)o37 £    UnX} x
1+Uq rXYZ{XwYn36}0)o37 mXYZ{UnX} x

           // Implicit: U = input string
Uq rXYZ{   // Split U into chars, and reduce each item Y and previous value X by:
XwYn36     //  Choosing the larger of X and parseInt(Y,36),
}0         // starting at 0.
1+   )o37  // Add 1 and create a range from this number to 36.
mXYZ{UnX}  // Map each item X in this range to parseInt(U,X)
x          // and sum.
           // Implicit: output last expression
ETHproducciones
fuente
1

Pyth, 16 bytes

V36 .x=+ZizhN ;Z

Pruébalo en línea

Explicación:

                 # Implicit: Z = 0, z = input
V36              # For N in range 36
    .x           # Try except
      =+Z        # Z = Z + izhN
         izhN    # Convert z from base N+1 to decimal
              ;  # Infinite ), for closing the for loop
               Z # Print Z
Adnan
fuente
1

CJam, 28 27 bytes

Gracias a Reto Koradi por guardar 1 byte.

Esto es un poco horrible ...

qA,s'[,65>+f#_:e>)37,>\fb:+

Requiere letras mayúsculas.

Pruébalo aquí.

CJam no tiene una conversión de base 36 incorporada de cadenas, por lo que tenemos que escribir las cadenas nosotros mismos. He estado probando todo tipo de travesuras divmod, pero parece ser más corto construir una cadena de los 36 dígitos y solo encontrar el índice de cada personaje en esa cadena.

Martin Ender
fuente
q{'0-_9>7*-}% Es igual de corto.
Peter Taylor
@PeterTaylor Oh, cierto ...
Martin Ender
1

Función C, 93 (solo salida de entero de 32 bits)

Suponiendo que está bien que la salida solo suba a INT_MAX, entonces podemos hacer esto:

i,n,x;f(char *s){char *e;for(i=36,x=0;n=strtol(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%d\n",x);}

El último caso de prueba implica que esto probablemente no sea suficiente. Si es así, con enteros de 64 bits tenemos:

Función C, 122

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

Desafortunadamente, #include <stdlib.h>se requiere para que el tipo de devolución strtoll()sea ​​correcto. Necesitamos usar long longpara manejar el caso de HELLOworldprueba. De lo contrario, esto podría ser un poco más corto.

Conductor de prueba:

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

int main (int argc, char **argv)
{
    f("0");
    f("2T");
    f("1012");
    f("HELLOworld");
}

Prueba de salida:

$ ./basesum
0
665
444278
5008425418187214
$ 
Trauma digital
fuente
En C, ¿puedes eliminar el espacio #include <stdlib.h>como en C ++?
Alex A.
@AlexA. Sí, no lo sabía, ¡gracias!
Trauma digital
0

Python 3, 142 bytes

Adnan me ha golpeado con su solución, pero quería agregar mi propio intento.

def f(s):
 t=0
 for x in range(37):
  n=0
  for i in s:
   try:m=int(i)
   except:m=ord(i)-55
   if x<=m:n=0;break
   n=n*x+m
  t+=n
 return t

Esta función solo maneja entradas en mayúscula. Agregar .upper()a for i in s, y manejará tanto mayúsculas como minúsculas.

Sherlock9
fuente
0

Scala 2.11, 93 bytes

Esto se ejecuta en la consola scala.

val i=readLine
var s=0
for(j<-2 to 36)try{s=s+Integer.parseInt(i,j)}catch{case _:Exception=>}
J Atkin
fuente
0

Haskell, 97 bytes

i c|'_'<c=fromEnum c-87|1<2=read[c]
f s=sum$map((`foldl1`map i s).((+).).(*))[1+i(maximum s)..36]

Solo admite caracteres en minúsculas. Ejemplo de uso:

f "2t"           -> 665
f "helloworld"   -> 5008425418187214

Es muy masivo, porque tengo que implementar tanto char-to-ASCII como conversión de base. Las funciones predefinidas correspondientes se encuentran en módulos que requieren importaciones aún más caras.

Cómo funciona: iconvierte un carácter ca su valor de dígito (por ejemplo, i 't'-> 29). fcalcula el valor de la cadena de entrada para cada base posible y lo suma. Una versión sin bucle del bucle interno es map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].

nimi
fuente
0

JavaScript (ES6), 86 bytes

s=>eval(`p=parseInt;b=2;[...s].map(d=>(v=p(d,36))>b?b=v:0);for(r=0;++b<37;)r+=p(s,b)`)

Explicación

s=>
  eval(`                     // use eval to enable for loop without return keyword or {}
    p=parseInt;
    b=2;                     // b = minimum base of s
    [...s].map(d=>           // iterate through each digit d
      (v=p(d,36))            // get it's base-36 value
        >b?b=v:0             // set b to the max value
    );
    for(r=0;++b<37;)         // r = sum of all base values
      r+=p(s,b)              // add each base value from b to 36 to r
  `)                         // implicit: return r

Prueba

usuario81655
fuente
&&b=vahorra 1 byte ?b=v:0.
Neil
@Neil ¿Lo probaste? Estoy bastante seguro de que sería una asignación izquierda no válida.
user81655
Lo siento, lo confundí con un caso similar en otro golf.
Neil
0

Perl 6 , 35 bytes

{[+] map {+(":$^a"~"<$_>")||0},^37}

uso:

# store it somewhere
my &code = {[+] map {+(":$^a"~"<$_>")||0},^37}

say code 'HELLOworld' # 5008425418187214

say map &code, <2T 1012>
# (665 444278)

say code 'qwertyuiopasdfghjklzxcvbnm1234567890'
# 79495849566202185148466281109757186006261081372450955140
Brad Gilbert b2gills
fuente
0

Ceilán, 100 96 bytes

Integer b(String s)=>sum(((any(s*.letter)then 11else 2)..36).map((r)=>parseInteger(s,r)else 0));

Primero tuve esta versión más simple con solo 69 bytes:

Integer b(String s)=>sum((2..36).map((r)=>parseInteger(s,r)else 0));

Pero esto falla con el primer caso de prueba, regresando en 2000000000665lugar de 665. ( La razón es que el Ten 2Tse analiza como Tera, es decir, se multiplica el 2 con 10 ^ 12, cuando el radix es 10. ) Por lo tanto tenemos que coger este caso por separado. Gracias a Neil por sugerir una forma diferente de hacer esto que ahorró 4 bytes.

Formateado:

// Find sum of all possible base representations.
//
// Question:  /codegolf//q/65748/2338
// My Answer: /codegolf//a/65836/2338

Integer b(String s) =>
// take the sum of ...
        sum(
    // span from 2 to 36. (Though
    // if there are letters in there, we start at 11,
    // because the other ones can't be valid.
    // Also, parseInteger(s, 10) behaves a bit strange in Ceylon.)
    ((any(s*.letter) then 11 else 2) .. 36)
    // map each r of them to ...
        .map((r) =>
            // try parsing s as a number using base r
            parseInteger(s, r)
            // if that didn't succeed, use 0.
                    else 0
    )
);
Paŭlo Ebermann
fuente
¿Tal vez pueda acortar el código comenzando desde la base 11 si la cadena contiene una letra, evitando así tener que usar la base 10 de casos especiales?
Neil