Encontre a soma de todas as representações básicas possíveis

20

O objetivo desse desafio é escrever um programa para converter uma sequência inserida do que pode ser assumido como contendo apenas letras e números de tantas bases entre 2 e 36 quanto possível e encontrar a soma da base 10 dos resultados.

A cadeia de caracteres de entrada será convertido para todas as bases em que o número poderia ser definidas de acordo com o alfabeto padrão de bases até 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Por exemplo, a entrada 2Tseria válida apenas nas bases 30 e superiores. O programa converteria 2T das bases 30 a 36 em decimal e somaria os resultados.

Você pode assumir que a sequência de entrada contém apenas letras e números. Seu programa pode usar maiúsculas ou minúsculas; ele pode, mas não precisa, suportar os dois.


Casos de teste

Entrada de amostra: 2T

Quadro de possíveis bases

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

Saída: 665

Entrada de amostra: 1012

Quadro de possíveis 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

Saída: 444278

Entrada de amostra: HELLOworld

Quadro de possíveis bases

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Saída: 5008425418187214

Uma entrada de 0seria lida como 0em todas as bases entre 2 e 36 inclusive. Não existe base 1.


Isso é código de golfe. Aplicam-se regras padrão. O menor código em bytes vence.

Arcturus
fonte
5
Os buildins para conversão base são permitidos?
precisa saber é o seguinte
2
Caso de teste importante:0
Martin Ender
Dang it, eu estava indo para postar um desafio muito semelhante.
precisa
3
@ MartinBüttner Por que 0um caso de teste importante? 0está 0em todas as bases e não existe base 1. #
Arcturus
3
@ Eridan, porque alguns idiomas podem tentar convertê-lo da base 1 e falhar.
Martin Ender

Respostas:

12

Python 3, 72 71 69 bytes

Agradecemos a FryAmTheEggman por salvar um byte!

Obrigado ao DSM por economizar 2 bytes!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)
Adnan
fonte
@ThomasKwa que irá adicionar um zero, o que não vai funcionar para as entradas puramente numéricos como que funciona como verificar se é base 10 (que fará com que alguns resultados muito grande)
Kevin W.
@FryAmTheEggman Thanks! Eu ajustei
Adnan
Apenas verificado para você. O try exceptdeixará você fazer range(37). Dois bytes!
Sherlock9
@ Sherlock9 Não funcionará para entradas puramente numéricas, estas serão interpretadas como números da base 10.
Adnan
Oh, certo, droga. @Adnan
Sherlock9
10

Pitão, 20 19 11 bytes

sm.xizd0S36

Roubou descaradamente a idéia de Adnan de sua resposta em Python.

Experimente aqui

orlp
fonte
@orlp Você pode remover o Schar
Blue
Não. Teste 1012.
Orlp 04/12/2015
4

Pure Bash (sem utilitários), 38

Supondo que conversões básicas internas sejam permitidas:

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

Isso produzirá um erro para STDERR. Estou assumindo que está tudo bem, de acordo com esta meta resposta .

Saída de teste:

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

Mathematica, 57 bytes

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&
alefalpha
fonte
Você pode usar o formulário infix para o FromDigits.
LegionMammal978
3

Sério, 65 bytes

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

Contém não imprimíveis, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Infelizmente, não tenho uma boa maneira de filtrar de uma lista com base em tipos. Nota para si mesmo: adicione isso.

Toma entrada como "2T"

Experimente on-line (você precisará inserir manualmente a entrada)

Explicação:

,û    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
fonte
Talvez Seriamente deva ter um comando que produza o alfabeto e / ou os números de 0 a 9?
quer
@ Eridan É sério - conseguir esse índice custa metade dos 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
fonte
2

Oitava, 75 73 bytes

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

Explicação:

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

polyvaltem uma vantagem base2decem ser vetorizada, portanto, nenhum forloop é necessário.

Apenas '0' .. '9' e maiúsculas 'A' .. 'Z' são suportados como entrada.

taça
fonte
Uso muito inteligente de polyvalvetorizar!
Luis Mendo
1

Japonês , 26 bytes

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

Experimente online!

Ungolfed e explicação

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
ETHproductions
fonte
1

Pitão, 16 bytes

V36 .x=+ZizhN ;Z

Experimente online

Explicação:

                 # 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
fonte
1

CJam, 28 27 bytes

Agradecemos a Reto Koradi por economizar 1 byte.

Isso é meio horrível ...

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

Requer letras maiúsculas.

Teste aqui.

Como o CJam não possui conversão interna de base 36 a partir de strings, temos que escrever as strings por nós mesmos. Eu tenho tentado todos os tipos de travessuras divmod, mas parece ser o mais curto para construir uma sequência de todos os 36 dígitos e apenas encontrar o índice de cada caractere nessa sequência.

Martin Ender
fonte
q{'0-_9>7*-}%é tão curto.
Peter Taylor
@PeterTaylor Oh, certo ... #
Martin Ender
1

Função C, 93 (somente saída inteira de 32 bits)

Assumindo que está OK para a saída subir apenas para INT_MAX, podemos fazer isso:

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

O último caso de teste implica que isso provavelmente não é suficiente. Nesse caso, com números inteiros de 64 bits, temos:

Função 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);}

Infelizmente, #include <stdlib.h>é necessário que o tipo de retorno strtoll()esteja correto. Precisamos usar long longpara lidar com oHELLOworld testcase. Caso contrário, isso poderia ser um pouco mais curto.

Driver de teste:

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

Saída de teste:

$ ./basesum
0
665
444278
5008425418187214
$ 
Trauma Digital
fonte
Em C, você pode remover o espaço #include <stdlib.h>como em C ++?
Alex A.
@AlexA. Sim - eu não sabia disso - obrigado!
Digital Trauma
0

Python 3, 142 bytes

Adnan me bateu profundamente com a solução deles, mas eu queria adicionar minha própria tentativa.

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 função lida apenas com entradas maiúsculas. Adicione .upper()a for i in s, e ele manipulará maiúsculas e minúsculas.

Sherlock9
fonte
0

Scala 2.11, 93 bytes

Isso é executado no console scala.

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

Suporta apenas caracteres minúsculos. Exemplo de uso:

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

É tão massivo, porque eu mesmo tenho que implementar a conversão de char para ASCII e base. As funções predefinidas correspondentes estão em módulos que exigem importações ainda mais caras.

Como funciona: iconverte um caractere cem seu valor de dígito (por exemplo i 't'- -> 29). fcalcula o valor da sequência de entrada para cada base possível e a soma. Uma versão não-pointfree do loop interno é map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].

nimi
fonte
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)`)

Explicação

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

Teste

user81655
fonte
&&b=veconomiza 1 byte ?b=v:0.
Neil
@ Neil Você testou? Tenho certeza de que seria uma mão esquerda inválida.
user81655
Desculpe, eu confundi com um caso semelhante em outro golfe.
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
fonte
0

Ceilão, 100 96 bytes

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

Eu tive essa versão mais simples pela primeira vez, com apenas 69 bytes:

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

Mas isso falha com o primeiro caso de teste, retornando em 2000000000665vez de 665. ( O motivo é que oT in 2Té analisado como Tera, ou seja, multiplica o 2 por 10 ^ 12, quando o raio é 10. ) Portanto, precisamos pegar esse caso separadamente. Agradecemos a Neil por sugerir uma maneira diferente de fazer isso, que economizou 4 bytes.

Formatado:

// 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
fonte
Você pode encurtar o código iniciando na base 11 se a string contiver uma letra, evitando assim a base 10 de casos especiais?
Neil