Temukan jumlah semua representasi dasar yang mungkin

20

Tujuan dari tantangan ini adalah untuk menulis sebuah program untuk mengonversi string yang dimasukkan dari apa yang dapat dianggap hanya berisi huruf dan angka dari sebanyak mungkin basis antara 2 dan 36, dan menemukan basis 10 jumlah hasil.

Input string akan dikonversi ke semua basis di mana jumlahnya akan ditetapkan sesuai dengan abjad standar untuk basis hingga 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Misalnya, input 2Takan valid hanya dalam basis 30 dan lebih tinggi. Program akan mengkonversi 2T dari basis 30 hingga 36 menjadi desimal dan menjumlahkan hasilnya.

Anda dapat mengasumsikan bahwa string input hanya berisi huruf dan angka. Program Anda dapat menggunakan huruf besar atau kecil; itu bisa, tetapi tidak perlu, mendukung keduanya.


Uji kasus

Input sampel: 2T

Bagan pangkalan yang mungkin

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

Output: 665

Input sampel: 1012

Bagan pangkalan yang mungkin:

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

Keluaran: 444278

Input sampel: HELLOworld

Bagan pangkalan yang mungkin

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Keluaran: 5008425418187214

Masukan dari 0akan dibaca seperti 0dalam semua pangkalan antara 2 dan 36 inklusif. Tidak ada yang namanya base 1.


Ini kode golf. Aturan standar berlaku. Kode terpendek dalam byte menang.

Arcturus
sumber
5
Apakah bawaan untuk konversi basis diizinkan?
lirtosiast
2
Kasing penting:0
Martin Ender
Sial, aku akan memposting tantangan yang sangat mirip.
DanTheMan
3
@ MartinBüttner Mengapa 0uji kasus penting? 0ada 0di setiap basis, dan tidak ada yang namanya base 1.
Arcturus
3
@ Eropa karena beberapa bahasa mungkin mencoba mengubahnya dari basis 1 dan gagal.
Martin Ender

Jawaban:

12

Python 3, 72 71 69 byte

Terima kasih kepada FryAmTheEggman karena telah menghemat satu byte!

Terima kasih kepada DSM karena telah menghemat 2 byte!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)
Adnan
sumber
@ThomasKwa yang akan menambahkan nol, yang tidak akan berfungsi untuk input numerik murni karena berfungsi memeriksa apakah basis 10 (yang akan membuat beberapa hasil terlalu besar)
Kevin W.
@FryAmTheEggman Terima kasih! Saya telah menyesuaikannya
Adnan
Baru diperiksa untukmu. The try exceptakan membiarkan Anda melakukan range(37). Dua byte!
Sherlock9
@ Sherlock9 Ini tidak akan berfungsi untuk input numerik murni, ini akan ditafsirkan sebagai basis 10 angka.
Adnan
Oh benar, sial. @Adnan
Sherlock9
10

Pyth, 20 19 11 byte

sm.xizd0S36

Secara terang-terangan mencuri ide Adnan dari jawaban Python-nya.

Coba di sini

orlp
sumber
@ orlp Anda dapat menghapus Schar
Blue
Nggak. Tes 1012.
orlp
4

Bash Murni (tanpa utilitas), 38

Dengan asumsi konversi basis bawaan diizinkan:

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

Ini akan menampilkan kesalahan ke STDERR. Saya berasumsi ini tidak apa-apa sesuai jawaban meta ini .

Output tes:

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

Mathematica, 57 byte

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&
alephalpha
sumber
Anda dapat menggunakan formulir infix untuk FromDigits.
LegionMammal978
3

Serius, 65 byte

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

Berisi unsintables, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Sayangnya saya tidak memiliki cara yang baik untuk memfilter dari daftar berdasarkan tipe. Catatan untuk diri sendiri: tambahkan itu.

Mengambil input seperti "2T"

Cobalah online (Anda harus memasukkan input secara manual)

Penjelasan:

,û    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
sumber
Mungkin Serius harus memiliki perintah yang menghasilkan alfabet dan / atau angka 0-9?
Arcturus
@ Eropa Harus serius - mendapatkan biaya indeks setengah 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
Luis Mendo
sumber
2

Oktaf, 75 73 byte

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

Penjelasan:

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

polyvalmemiliki kelebihan dibandingkan base2decvektornya, jadi tidak fordiperlukan loop.

Hanya '0' .. '9' dan huruf besar 'A' .. 'Z' didukung sebagai input.

gelas kimia
sumber
Penggunaan sangat pintar polyvaluntuk membuat vektor!
Luis Mendo
1

Japt , 26 byte

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

Cobalah online!

Tidak terseret dan penjelasan

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
Produksi ETH
sumber
1

Pyth, 16 byte

V36 .x=+ZizhN ;Z

Cobalah online

Penjelasan:

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

CJam, 28 27 byte

Terima kasih kepada Reto Koradi karena menghemat 1 byte.

Ini agak mengerikan ...

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

Membutuhkan huruf besar.

Uji di sini.

CJam tidak memiliki konversi basis-36 bawaan dari string, jadi kami harus mengirimkan sendiri string ke string. Saya sudah mencoba segala macam shenanigans divmod, tetapi tampaknya paling pendek untuk membangun string dari semua 36 digit dan hanya menemukan indeks masing-masing karakter dalam string itu.

Martin Ender
sumber
q{'0-_9>7*-}%sama pendeknya.
Peter Taylor
@PeterTaylor Oh, benar ...
Martin Ender
1

Fungsi C, 93 (hanya keluaran integer 32 bit)

Dengan asumsi OK untuk output hanya naik ke INT_MAX, maka kita bisa melakukan ini:

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

Testcase terakhir menyiratkan bahwa ini mungkin tidak cukup. Jika demikian, maka dengan bilangan bulat 64-bit yang kita miliki:

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

Sayangnya #include <stdlib.h>diperlukan sehingga jenis pengembalian strtoll()sudah benar. Kita perlu menggunakan long longuntuk menangani HELLOworldtestcase. Kalau tidak, ini bisa sedikit lebih pendek.

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

Output tes:

$ ./basesum
0
665
444278
5008425418187214
$ 
Trauma Digital
sumber
Di C dapatkah Anda menghapus ruang #include <stdlib.h>seperti yang Anda bisa di C ++?
Alex A.
@AlexA. Ya - saya tidak tahu itu - terima kasih!
Trauma Digital
0

Python 3, 142 byte

Adnan menyuruh saya mengalahkan dengan solusi mereka, tetapi saya ingin menambahkan usaha saya sendiri.

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

Fungsi ini hanya menangani input huruf besar. Tambahkan .upper()ke for i in s, dan itu akan menangani huruf besar dan kecil.

Sherlock9
sumber
0

Scala 2.11, 93 byte

Ini dijalankan pada konsol scala.

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

Hanya mendukung karakter huruf kecil. Contoh penggunaan:

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

Ini sangat besar, karena saya harus mengimplementasikan konversi char-to-ASCII dan basis sendiri. Fungsi yang telah ditentukan sebelumnya sesuai dalam modul yang membutuhkan impor lebih mahal.

Cara kerjanya: imengonversi karakter cke nilai digitnya (mis. i 't'-> 29). fmenghitung nilai string input untuk setiap basis yang mungkin dan menjumlahkannya. Versi non-pointfree dari loop dalam adalah map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].

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

Penjelasan

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

Uji

pengguna81655
sumber
&&b=vmenghemat 1 byte lebih ?b=v:0.
Neil
@ Neil Apakah Anda mengujinya? Saya cukup yakin itu akan menjadi tugas kiri yang tidak valid.
user81655
Maaf saya bingung dengan kasus serupa di golf lain.
Neil
0

Perl 6 , 35 byte

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

pemakaian:

# 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
sumber
0

Ceylon, 100 96 byte

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

Saya pertama kali memiliki versi yang lebih sederhana ini hanya mengambil 69 byte:

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

Tetapi ini gagal dengan kasus uji pertama, kembali 2000000000665bukannya 665. ( Alasannya adalah bahwa Tdalam2T diuraikan sebagai Tera, yaitu mengalikan 2 dengan 10 ^ 12, ketika radix adalah 10. ) Oleh karena itu kita perlu menangkap kasus ini secara terpisah. Terima kasih kepada Neil karena menyarankan cara berbeda untuk melakukan ini yang menyelamatkan 4 byte.

Diformat:

// 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
sumber
Bisakah Anda mempersingkat kode dengan mulai dari basis 11 jika string berisi surat, sehingga menghindari keharusan untuk basis kasus khusus 10?
Neil