查找所有可能的基本表示形式的总和


20

这项挑战的目的是编写一个程序,以转换输入字符串(假定该字符串包含字母和数字),并尽可能多地使用2到36之间的基数,并找到结果的基数10。

输入字符串将被转换为所有在其数量会根据用于碱基高达36标准字母表来定义的碱基:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ。例如,输入2T仅在以30为基数的有效值。该程序会将2T从30到36的基数转换为十进制并求和。

您可以假定输入字符串仅包含字母和数字。您的程序可以使用大写或小写;它可以但不需要同时支持两者。


测试用例

输入样例: 2T

可能基准图

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

输出:665

输入样例: 1012

可能基准的图表:

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

输出: 444278

输入样例: HELLOworld

可能基准图

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

输出: 5008425418187214

的输入0将被读为02到36之间(包括2和36)的所有基数。没有以1为底的东西。


这是代码高尔夫。适用标准规则。以字节为单位的最短代码获胜。


5
是否允许用于基本转换的内建函数?
lirtosiast

2
重要测试案例:0
Martin Ender 2015年

it,我要发一个非常相似的挑战。
DanTheMan 2015年

3
@MartinBüttner为什么要0使用重要的测试用例?00在每一个基地,而且也为基地1个没有这样的事
大角星

3
@Eridan,因为某些语言可能会尝试将其从基数1转换而失败。
马丁·恩德

Answers:


12

Python 3,72 71 69字节

感谢FryAmTheEggman节省了一个字节!

感谢DSM节省了2个字节!

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

@ThomasKwa将添加一个零,这对于纯数字输入将不起作用,因为它的功能是检查它是否以10为底(这会使某些结果太大)
Kevin W.

@FryAmTheEggman谢谢!我已对其进行了调整
Adnan

刚刚为您检查。该try except会让你做range(37)。两个字节!
Sherlock15年

@ Sherlock9不适用于纯数字输入,这些将被解释为以10为底的数字。
阿德南(Adnan)2015年

哦,对,该死。@Adnan
Sherlock9年5


4

纯Bash(无实用程序),38

假设允许进行内置的基本转换:

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

这将向STDERR输出错误。我假设按照这个元答案这是可以的。

测试输出:

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


3

严重的是65个字节

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

包含不可打印的内容,十六进制转储:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

不幸的是,我没有一种基于类型从列表中进行过滤的好方法。自我注意:添加。

像输入 "2T"

在线尝试(您将必须手动输入输入)

说明:

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

也许认真地应该有一个产生字母和/或数字0-9的命令?
Arcturus

@Eridan 认真应该-获取该索引花费一半的字节。
Mego 2015年

2

Matlab,98个字节

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

八度,75 73字节

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

说明:

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

polyval具有base2dec矢量化的优势,因此没有for循环。

仅支持“ 0” ..“ 9”和大写字母“ A” ..“ Z”作为输入。


非常聪明地使用polyval矢量化!
路易斯·门多

1

Japt,26个字节

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

在线尝试!

脱节和解释

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个字节

V36 .x=+ZizhN ;Z

在线尝试

说明:

                 # 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字节

感谢Reto Koradi节省了1个字节。

这有点可怕...

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

需要大写字母。

在这里测试。

CJam没有从字符串内置的base-36转换,因此我们必须自己对字符串进行字母输出。我一直在尝试各种divmod恶作剧,但构建所有36位数字的字符串并找到该字符串中每个字符的索引似乎最短。


q{'0-_9>7*-}%一样短。
彼得·泰勒

@PeterTaylor哦,对...
Martin Ender

1

C函数93(仅32位整数输出)

假设输出可以正常到INT_MAX,那么我们可以这样做:

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

最后一个测试用例暗示这可能还不够。如果是这样,那么对于64位整数,我们有:

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

不幸的是,这#include <stdlib.h>是必需的,因此返回类型strtoll()正确。我们需要使用long long来处理HELLOworld测试用例。否则,这可能会短一些。

测试驱动程序:

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

测试输出:

$ ./basesum
0
665
444278
5008425418187214
$ 

在C中,#include <stdlib.h>您可以像在C ++ 中一样删除空间吗?
Alex A.

@AlexA。是的-我不知道-谢谢!
Digital Trauma 2015年

0

Python 3,142个字节

Adnan让我坚决反对他们的解决方案,但我确实想补充一下自己的尝试。

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

此功能仅处理大写输入。添加.upper()for i in s,它将同时处理大写和小写字母。


0

Scala 2.11,93字节

这在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个字节

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

仅支持小写字符。用法示例:

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

它是如此之大,因为我必须自己实现char-to-ASCII和base转换。相应的预定义功能位于需要更昂贵的进口件的模块中。

工作原理:i将字符c转换为其数字值(例如i 't'-> 29)。f计算每个可能的基数的输入字符串的值并将其求和。内循环的非无点版本是map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ]


0

JavaScript(ES6),86个字节

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

说明

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

测试


&&b=v节省1个字节?b=v:0
尼尔

@Neil测试了吗?我很确定那将是无效的左手作业。
user81655 2015年

抱歉,我在另一场高尔夫比赛中将它与类似的情况混淆了。
尼尔2015年

0

Perl 6、35个字节

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

用法:

# 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

锡兰,100 96字节

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

我首先有一个仅占用69个字节的简单版本:

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

但这在第一个测试用例中失败,返回2000000000665而不是665。(原因是Tin 2T被解析为Tera,即当基数为10时将in 2乘以10 ^ 12。)因此,我们需要分别处理这种情况。感谢Neil建议使用另一种方法来节省4个字节。

格式:

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

如果字符串中包含字母,您是否可以通过从11开始开始缩短代码,从而避免以10为特殊情况?
尼尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.