Trova la somma di tutte le possibili rappresentazioni di base


20

L'obiettivo di questa sfida è quello di scrivere un programma per convertire una stringa inserita di ciò che si può presumere che contenga solo lettere e numeri da quante più basi tra 2 e 36 possibili e trovare la somma base 10 dei risultati.

La stringa di input sarà convertita a tutte le basi in cui il numero sarebbe definito secondo l'alfabeto standard per basi fino a 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Ad esempio, l'input 2Tsarebbe valido solo nelle basi da 30 in poi. Il programma converte 2T dalle basi 30 a 36 in decimale e somma i risultati.

Si può presumere che la stringa di input contenga solo lettere e numeri. Il programma può utilizzare lettere maiuscole o minuscole; può, ma non è necessario, supportare entrambi.


Casi test

Input di esempio: 2T

Grafico delle possibili basi

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

Uscita: 665

Input di esempio: 1012

Grafico delle possibili basi:

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

Produzione: 444278

Input di esempio: HELLOworld

Grafico delle possibili basi

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Produzione: 5008425418187214

Un input di 0verrebbe letto come 0in tutte le basi tra 2 e 36 inclusi. Non esiste una base 1.


Questo è il codice golf. Si applicano le regole standard. Vince il codice più breve in byte.


5
Sono consentiti i builtin per la conversione di base?
lirtosiast,

2
Caso di test importante:0
Martin Ender il

Maledizione, stavo per pubblicare una sfida molto simile.
DanTheMan il

3
@ MartinBüttner Perché è 0un caso di test importante? 0è 0in ogni base, e non esiste nulla come la base 1.
Arcturus,

3
@Eridan perché alcune lingue potrebbero provare a convertirlo dalla base 1 e fallire.
Martin Ender,

Risposte:


12

Python 3, 72 71 69 byte

Grazie a FryAmTheEggman per aver salvato un byte!

Grazie a DSM per aver salvato 2 byte!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)

@ThomasKwa che aggiungerà uno zero, che non funzionerà per input puramente numerici in quanto funziona come controllo se è base 10 (il che renderà alcuni risultati troppo grandi)
Kevin W.

@FryAmTheEggman Grazie! L'ho modificato
Adnan il

Ho appena controllato per te. Il try exceptti consente di fare range(37). Due byte!
Sherlock9,

@ Sherlock9 Non funzionerà con input puramente numerici, questi saranno interpretati come numeri di base 10.
Adnan,

Oh giusto, dannazione. @Adnan
Sherlock9,

10

Pyth, 20 19 11 byte

sm.xizd0S36

Ha palesemente rubato l'idea di Adnan dalla sua risposta Python.

Provalo qui


@orlp Puoi rimuovere il Scarattere
Blue

No. Test 1012.
orlp,

4

Pure Bash (nessuna utility), 38

Supponendo che le conversioni di base integrate siano consentite:

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

Questo genererà un errore a STDERR. Suppongo che questo sia OK secondo questa meta risposta .

Uscita di prova:

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

3

Mathematica, 57 byte

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&

È possibile utilizzare il modulo infix per il FromDigits.
LegionMammal978,

3

Scherzi a parte, 65 byte

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

Contiene non stampabili, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Sfortunatamente non ho un buon modo per filtrare da un elenco in base ai tipi. Nota per sé: aggiungilo.

Accetta input come "2T"

Provalo online (dovrai inserire manualmente l'input)

Spiegazione:

,û    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

Forse sul serio dovrebbe avere un comando che produce l'alfabeto e / o i numeri 0-9?
Arcturus,

@Eridan Dovrebbe seriamente : ottenere quell'indice costa la metà dei byte.
Mego,

2

Matlab, 98 byte

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

2

Ottava, 75 73 byte

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

Spiegazione:

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

polyvalha un vantaggio rispetto base2decal fatto che è vettorializzato, quindi non forè richiesto alcun loop.

Solo '0' .. '9' e 'A' .. 'Z' maiuscole sono supportati come input.


Uso molto intelligente di polyvalvettorializzare!
Luis Mendo,

1

Japt , 26 byte

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

Provalo online!

Ungolfed e spiegazione

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

1

Pyth, 16 byte

V36 .x=+ZizhN ;Z

Provalo online

spiegazione:

                 # 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

1

CJam, 28 27 byte

Grazie a Reto Koradi per aver salvato 1 byte.

Questo è un po 'orribile ...

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

Richiede lettere maiuscole.

Provalo qui.

CJam non ha una conversione base 36 incorporata dalle stringhe, quindi dobbiamo scrivere le stringhe noi stessi. Ho provato tutti i tipi di shenanigans divmod, ma sembra essere il più breve per costruire una stringa di tutte e 36 le cifre e trovare l'indice di ogni personaggio in quella stringa.


q{'0-_9>7*-}%è altrettanto breve.
Peter Taylor,

@PeterTaylor Oh, giusto ...
Martin Ender il

1

Funzione C, 93 (solo uscita intera a 32 bit)

Supponendo che sia OK per l'output salire solo a INT_MAX, quindi possiamo farlo:

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

L'ultimo testcase implica che ciò probabilmente non è sufficiente. In tal caso, quindi con numeri interi a 64 bit abbiamo:

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

Purtroppo #include <stdlib.h>è necessario, quindi il tipo di ritorno di strtoll()è corretto. Dobbiamo usare long longper gestire la HELLOworldtestcase. Altrimenti questo potrebbe essere un po 'più breve.

Test driver:

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

Uscita di prova:

$ ./basesum
0
665
444278
5008425418187214
$ 

In C puoi rimuovere lo spazio #include <stdlib.h>come puoi in C ++?
Alex A.

@AlexA. Sì, non lo sapevo, grazie!
Digital Trauma,

0

Python 3, 142 byte

Adnan mi ha battuto profondamente con la loro soluzione, ma volevo aggiungere il mio tentativo.

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

Questa funzione gestisce solo input maiuscoli. Aggiungi .upper()a for i in se gestirà sia lettere maiuscole che minuscole.


0

Scala 2.11, 93 byte

Questo viene eseguito sulla console della scala.

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

0

Haskell, 97 byte

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

Supporta solo caratteri minuscoli. Esempio di utilizzo:

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

È così enorme, perché devo implementare io stesso sia la conversione da char a ASCII che la conversione di base. Le corrispondenti funzioni predefinite si trovano in moduli che richiedono importazioni ancora più costose.

Come funziona: iconverte un carattere cnel suo valore in cifre (ad es. i 't'-> 29). fcalcola il valore della stringa di input per ogni base possibile e la somma. Una versione non pointfree del loop interno è map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].


0

JavaScript (ES6), 86 byte

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

Spiegazione

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

Test


&&b=vsalva 1 byte sopra ?b=v:0.
Neil,

@Neil L'hai provato? Sono abbastanza sicuro che sarebbe una mano sinistra non valida dell'incarico.
user81655

Mi dispiace di averlo confuso con un caso simile in un altro golf.
Neil,

0

Perl 6 , 35 byte

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

utilizzo:

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

say code 'HELLOworld' # 5008425418187214

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

say code 'qwertyuiopasdfghjklzxcvbnm1234567890'
# 79495849566202185148466281109757186006261081372450955140

0

Ceylon, 100 96 byte

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

Prima ho avuto questa versione più semplice prendendo solo 69 byte:

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

Ma questo fallisce con il primo caso di test, restituendo 2000000000665invece di 665. ( Il motivo è che Tin 2Tviene analizzato come Tera, cioè moltiplica il 2 per 10 ^ 12, quando il radix è 10. ) Pertanto dobbiamo prendere questo caso separatamente. Grazie a Neil per aver suggerito un modo diverso di fare ciò che ha salvato 4 byte.

formattato:

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

Puoi forse abbreviare il codice partendo dalla base 11 se la stringa contiene una lettera, evitando così di dover usare la base 10 per i casi speciali?
Neil,
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.