Znajdź sumę wszystkich możliwych reprezentacji podstawowych


20

Celem tego wyzwania jest napisanie programu do konwersji wprowadzonego ciągu znaków, który może zawierać tylko litery i cyfry z jak największej liczby baz między 2 a 36, ​​i znaleźć sumę 10 wyników podstawowych.

Łańcuch wejściowe zostaną zamienione na wszystkich bazach, w których liczba będzie określone zgodnie z normą alfabetu dla baz do 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Na przykład dane wejściowe 2Tbyłyby ważne tylko w bazach 30 i wyższych. Program konwertuje 2T z baz od 30 do 36 na dziesiętne i sumuje wyniki.

Możesz założyć, że ciąg wejściowy zawiera tylko litery i cyfry. Twój program może używać wielkich lub małych liter; może, ale nie musi, obsługiwać oba te elementy.


Przypadki testowe

Przykładowe dane wejściowe: 2T

Tabela możliwych zasad

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

Wyjście: 665

Przykładowe dane wejściowe: 1012

Tabela możliwych zasad:

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

Wynik: 444278

Przykładowe dane wejściowe: HELLOworld

Tabela możliwych zasad

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Wynik: 5008425418187214

Dane wejściowe 0będą odczytywane jak 0we wszystkich bazach od 2 do 36 włącznie. Nie ma czegoś takiego jak baza 1.


To jest kod golfowy. Obowiązują standardowe zasady. Najkrótszy kod w bajtach wygrywa.


5
Czy dozwolone są wbudowane funkcje konwersji?
lirtosiast

2
Ważny przypadek testowy:0
Martin Ender

Cholera, zamierzałem postawić bardzo podobne wyzwanie.
DanTheMan

3
@ MartinBüttner Dlaczego jest 0to ważny przypadek testowy? 0jest 0w każdej bazie i nie ma czegoś takiego jak baza 1.
Arcturus

3
@Eridan, ponieważ niektóre języki mogą próbować przekonwertować to z bazy 1 i zawieść.
Martin Ender,

Odpowiedzi:


12

Python 3, 72 71 69 bajtów

Dzięki FryAmTheEggman za uratowanie bajtu!

Dzięki DSM za oszczędność 2 bajtów!

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

@ThomasKwa, który doda zero, co nie będzie działać dla czysto numerycznych danych wejściowych, ponieważ działa to jako sprawdzanie, czy jego podstawa 10 (co spowoduje, że niektóre wyniki będą zbyt duże)
Kevin W.

@FryAmTheEggman Thanks! Mam dostosować go
Adnan

Właśnie sprawdziłem dla ciebie. try exceptPozwoli Ci zrobić range(37). Dwa bajty!
Sherlock9,

@ Sherlock9 To nie zadziała dla danych czysto numerycznych, będą interpretowane jako liczby podstawowe 10.
Adnan

Jasne, skarbie. @Adnan
Sherlock9,


4

Pure Bash (bez narzędzi), 38

Zakładając, że dozwolone są wbudowane konwersje podstawowe:

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

Spowoduje to wyświetlenie błędu do STDERR. Zakładam, że tak jest zgodnie z tą meta odpowiedzią .

Wyjście testowe:

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


3

Poważnie, 65 bajtów

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

Zawiera materiały niedrukowalne, zrzut heksowy:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Niestety nie mam dobrego sposobu na filtrowanie listy na podstawie typów. Uwaga do siebie: dodaj to.

Przyjmuje dane wejściowe jak "2T"

Wypróbuj online (konieczne będzie ręczne wprowadzenie danych wejściowych)

Wyjaśnienie:

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

Być może Poważnie powinieneś mieć polecenie, które tworzy alfabet i / lub cyfry 0-9?
Arcturus,

@Eridan Poważnie powinno - uzyskanie tego indeksu kosztuje połowę bajtów.
Mego

2

Matlab, 98 bajtów

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

Oktawa, 75 73 bajtów

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

Wyjaśnienie:

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

polyvalma tę przewagę base2dec, że jest wektoryzowany, więc nie forjest wymagana pętla.

Jako dane wejściowe obsługiwane są tylko „0” .. „9” i wielkie litery „A” .. „Z”.


Bardzo sprytne użycie polyvalwektoryzacji!
Luis Mendo,

1

Japt , 26 bajtów

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

Wypróbuj online!

Bez golfa i wyjaśnienia

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 bajtów

V36 .x=+ZizhN ;Z

Wypróbuj online

Wyjaśnienie:

                 # 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 bajtów

Dzięki Reto Koradi za uratowanie 1 bajtu.

To trochę okropne ...

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

Wymaga wielkich liter.

Sprawdź to tutaj.

CJam nie ma wbudowanej konwersji bazowej 36 z ciągów, więc sami musimy napisać litery. Próbowałem różnego rodzaju shenaniganów divmod, ale wydaje się, że najkrótszym jest zbudowanie ciągu wszystkich 36 cyfr i po prostu znalezienie indeksu każdego znaku w tym ciągu.


q{'0-_9>7*-}%jest równie krótki.
Peter Taylor,

@PeterTaylor Oh, racja ...
Martin Ender

1

Funkcja C, 93 (tylko 32-bitowe wyjście całkowite)

Zakładając, że jest OK, aby dane wyjściowe przechodziły tylko do INT_MAX, możemy to zrobić:

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

Ostatni test testowy sugeruje, że prawdopodobnie nie jest to wystarczające. Jeśli tak, to przy 64-bitowych liczbach całkowitych mamy:

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

Niestety #include <stdlib.h>jest wymagany, więc typ zwrotu strtoll()jest prawidłowy. Musimy użyć long longdo obsługi HELLOworldskrzynki testowej. W przeciwnym razie może to być nieco krótsze.

Kierowca testowy:

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

Wyjście testowe:

$ ./basesum
0
665
444278
5008425418187214
$ 

Czy w C możesz usunąć spację #include <stdlib.h>tak jak w C ++?
Alex A.,

@AlexA. Tak - nie wiedziałem o tym - dzięki!
Cyfrowy uraz

0

Python 3, 142 bajty

Adnan mocno mnie pobił swoim rozwiązaniem, ale chciałem dodać własną próbę.

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

Ta funkcja obsługuje tylko duże litery. Dodaj .upper()do for i in s, a obsłuży zarówno wielkie, jak i małe litery.


0

Scala 2.11, 93 bajty

Jest to uruchamiane na konsoli 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 bajtów

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

Obsługuje tylko małe litery. Przykład użycia:

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

Jest tak ogromny, ponieważ sam muszę zaimplementować konwersję char-to-ASCII i konwersję bazy. Odpowiednie predefiniowane funkcje znajdują się w modułach, które wymagają jeszcze droższego importu.

Jak to działa: ikonwertuje znak cna jego wartość cyfrową (np. i 't'-> 29). foblicza wartość ciągu wejściowego dla każdej możliwej podstawy i sumuje ją. Wersja bez pętli wewnętrznej pętli jest map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].


0

JavaScript (ES6), 86 bajtów

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

Wyjaśnienie

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=voszczędza 1 bajt ?b=v:0.
Neil,

@Neil Czy to przetestowałeś? Jestem prawie pewien, że byłaby to nieprawidłowa lewa ręka.
user81655,

Przepraszam, pomyliłem to z podobną sprawą w innym golfie.
Neil,

0

Perl 6 , 35 bajtów

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

stosowanie:

# 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 bajtów

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

Najpierw miałem tę prostszą wersję, zajmującą zaledwie 69 bajtów:

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

Ale nie udaje się to w przypadku pierwszego przypadku testowego, który powraca 2000000000665zamiast 665. ( Powodem jest to, że Tin 2Tjest analizowane jako Tera, tzn. Mnoży 2 przez 10 ^ 12, gdy podstawa wynosi 10. ) Dlatego musimy złapać ten przypadek osobno. Podziękowania dla Neila za zasugerowanie innego sposobu zrobienia tego, co pozwoliło zaoszczędzić 4 bajty.

Sformatowany:

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

Czy możesz skrócić kod, zaczynając od podstawy 11, jeśli ciąg znaków zawiera literę, unikając w ten sposób potrzeby specjalnego przypadku podstawy 10?
Neil,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.