Olası tüm temel temsillerin toplamını bulun


20

Bu zorluğun amacı, yalnızca 2 ile 36 arasında olabildiğince çok sayıda tabandan harf ve rakam içerdiği varsayılan bir girdi dizesini dönüştürmek ve sonuçların temel 10 toplamını bulmak için bir program yazmaktır .

Giriş dizesi, sayının 36: 'ya kadar olan bazlar için standart alfabeye göre tanımlanacağı tüm tabanlara dönüştürülecektir 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Örneğin, girdi 2Tyalnızca 30 ve üstü bazlar için geçerlidir. Program, 30T'den 36'ya kadar olan 2T'yi ondalığa dönüştürür ve sonuçları toplar.

Giriş dizesinin yalnızca harf ve rakam içerdiğini varsayabilirsiniz. Programınız büyük veya küçük harf kullanabilir; her ikisini de destekleyebilir, ancak buna gerek yoktur.


Test senaryoları

Örnek giriş: 2T

Olası bazların grafiği

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

Çıktı: 665

Örnek giriş: 1012

Olası bazların şeması:

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

Çıktı: 444278

Örnek giriş: HELLOworld

Olası bazların grafiği

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Çıktı: 5008425418187214

Bir giriş 0olarak okunacak 02 ile 36 dahil arasındaki tüm bazlardır. Temel 1 diye bir şey yoktur.


Bu kod golf. Standart kurallar geçerlidir. Bayt cinsinden en kısa kod kazanır.


5
Taban dönüşümü için yerleşik yapılara izin veriliyor mu?
lirtosiast

2
Önemli test örneği:0
Martin Ender

Lanet olsun, ben çok benzer bir meydan okuma gönderecektim.
DanTheMan

3
@ MartinBüttner Neden 0önemli bir test örneği? 0olduğu 0her tabanında ve baz 1. diye bir şey yoktur
Arcturus

3
@Eridan çünkü bazı diller bunu taban 1'den dönüştürmeyi deneyebilir ve başarısız olabilir.
Martin Ender

Yanıtlar:


12

Python 3, 72 71 69 bayt

Bir bayt tasarrufu için FryAmTheEggman'a teşekkürler!

2 bayt kazandığı için DSM'ye teşekkürler!

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

@ThomasKwa, sıfır ekleyecek, yalnızca sayısal girişler için çalışmayacak, çünkü taban 10 olup olmadığını kontrol etme işlevi görüyor (bu da bazı sonuçları çok büyük hale getirecek)
Kevin W.

@FryAmTheEggman Teşekkürler! Bunu ayarladıktan
Adnan

Sadece seni kontrol ettim. try exceptTek yapmanız izin verir range(37). İki bayt!
Sherlock9

@ Sherlock9 Sadece sayısal girdiler için işe yaramaz, bunlar temel 10 sayı olarak yorumlanır.
Adnan

Ah doğru, lanet olsun. @Adnan
Sherlock9

10

Pyth, 20 19 11 bayt

sm.xizd0S36

Adnan'ın fikrini Python'un cevabından açıkça çaldı.

Burada deneyin


@orlp Sen kaldırabilirsiniz Skömürü
Mavi

Hayır! Test edin 1012.
orlp

4

Saf Bash (yardımcı program yok), 38

Yerleşik temel dönüşümlere izin verildiğini varsayarsak:

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

Bu, STDERR'a bir hata verecektir. Ben bu meta cevap başına tamam olduğunu varsayıyorum .

Test çıktısı:

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

3

Mathematica, 57 bayt

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

İçin infix formunu kullanabilirsiniz FromDigits.
LegionMammal978

3

Ciddi, 65 bayt

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

Yazdırılamayan, hexdump içerir:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

Ne yazık ki türlere dayalı bir listeden filtrelemek için iyi bir yolum yok. Kendine not: ekle.

Gibi girdi alır "2T"

Çevrimiçi deneyin (girişi manuel olarak girmeniz gerekir)

Açıklama:

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

Belki de alfabeyi ve / veya 0-9 sayılarını üreten bir komuta sahip olmalı?
Arcturus

@Eridan Cidden olmalı - bu endeksi elde etmek baytların yarısına mal oluyor.
Mego

2

Matlab, 98 bayt

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

Oktav, 75 73 bayt

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

Açıklama:

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

polyvalbase2decvektörize edilmesine göre bir avantajı vardır , bu yüzden fordöngü gerekmez.

Yalnızca '0' .. '9' ve büyük harf 'A' .. 'Z' giriş olarak desteklenir.


polyvalVectorize etmek için çok akıllıca kullanın !
Luis Mendo

1

Japt , 26 bayt

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

Çevrimiçi deneyin!

Açıklanmamış ve açıklama

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 bayt

V36 .x=+ZizhN ;Z

Çevrimiçi deneyin

Açıklama:

                 # 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 bayt

Reto Koradi'ye 1 bayt kazandığı için teşekkürler.

Bu çok korkunç ...

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

Büyük harf gerektirir.

Burada test edin.

CJam, dizelerden yerleşik base-36 dönüşümüne sahip değildir, bu nedenle dizeleri kendimiz yazmalıyız. Ben divmod shenanigans her türlü deniyorum, ama tüm 36 basamaklı bir dize oluşturmak ve sadece bu dize her karakterin dizin bulmak en kısa gibi görünüyor.


q{'0-_9>7*-}%kadar kısa.
Peter Taylor

@PeterTaylor Oh, right ...
Martin Ender

1

C işlevi, 93 (yalnızca 32 bit tam sayı çıkışı)

Çıktının yalnızca INT_MAX'a kadar çıkabileceğini varsayarsak, bunu yapabiliriz:

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

Son test çantası bunun muhtemelen yeterli olmadığını ima eder. Eğer öyleyse, 64 bit tamsayılarla:

C işlevi, 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);}

Maalesef #include <stdlib.h>dönüş türü strtoll()doğru olduğundan gereklidir. Biz kullanmak gerekir long longeleHELLOworldTest çantasını . Aksi takdirde, bu biraz daha kısa olabilir.

Test sürücüsü:

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

Test çıktısı:

$ ./basesum
0
665
444278
5008425418187214
$ 

#include <stdlib.h>C + C + 'da olduğu gibi boşluk kaldırabilirsiniz ?
Alex A.

@AlexA. Evet - Bunu bilmiyordum - teşekkürler!
Dijital Travma

0

Python 3, 142 bayt

Adnan beni çözümleriyle güçlü bir şekilde dövdü, ama kendi girişimimi eklemek istedim.

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

Bu işlev yalnızca büyük harf girişlerini işler. Ekle .upper()için for i in sve o büyük ve küçük hem idare edecek.


0

Scala 2.11, 93 bayt

Bu scala konsolunda çalıştırılır.

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

0

Haskell, 97 bayt

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

Yalnızca küçük harfleri destekler. Kullanım örneği:

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

Bu çok büyük, çünkü hem char-to-ASCII'yi hem de base dönüşümü kendim uygulamak zorundayım. Karşılık gelen önceden tanımlanmış fonksiyonlar, daha pahalı ithalat gerektiren modüllerde bulunur.

Nasıl çalışır: ibir karakteri cbasamak değerine dönüştürür (örn. i 't'-> 29).fOlası her temel için giriş dizesinin değerini hesaplar ve toplar. İç döngünün anlamsız bir versiyonu map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].


0

JavaScript (ES6), 86 bayt

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

açıklama

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

Ölçek


&&b=v1 bayt tasarruf sağlar ?b=v:0.
Neil

@Neil Test ettiniz mi? Bunun geçersiz bir görev ataması olacağından eminim.
user81655

Üzgünüm başka bir golf benzer bir dava ile karıştırdım.
Neil

0

Perl 6 , 35 bayt

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

kullanımı:

# 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

Seylan, 100 96 bayt

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

İlk önce sadece 69 bayt alan bu daha basit sürüme sahiptim

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

Ancak bu, ilk test senaryosunda başarısız olur, 2000000000665bunun yerine geri döner 665. ( Nedeni olduğunu Tyılında 2T, Tera olarak ayrıştırılır yani çarpar 2 ^ 12 10 ile sayı tabanı 10. olduğunda ) Bu nedenle ayrı ayrı bu durumda yakalamak gerekir. Sayesinde Neil 4 bayt kaydedildi hangi Bunu yapmanın farklı bir yol öneren.

biçimlendirilmiş:

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

Eğer dize bir harf içeriyorsa temel 11'den başlayarak kodu kısaltabilir ve böylece özel durum 10'a sahip olmaktan kaçınabilirsiniz.
Neil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.