代码高尔夫:与Excel列名称等效的数字


76

挑战

按字符计数的最短代码,它将输出与Excel列字符串等效的数字。

例如,A列是1,B是2,依此类推。按下后Z,下一列变为AAAB依此类推。

测试用例:

A:    1
B:    2
AD:   30
ABC:  731
WTF:  16074
ROFL: 326676

代码计数包括输入/​​输出(即完整程序)。


19
代码高尔夫是没有意义的,APL总是最终获胜。
BlueRaja-Danny Pflughoeft 2010年

1
发布解决方案时,请确保该解决方案适用于上述所有情况(运行时的输入/输出效果很好),并请注意在何处不可行。谢谢。

3
为什么在地狱上贴上罗塞塔石碑?
乔什·斯托多拉

2
J是没有希腊语的APL。J永远赢,没有人再说APL。
卡勒姆·罗杰斯

1
@BlueRaja:有趣的是,APL在离开主流市场将近40年之后,仍在2010年赢得了这些胜利。
Kragen Javier Sitaker'4

Answers:


96

Perl,36个 34 33 31 30 17 15 11个字符

$_=()=A..$_

用法:

$ echo -n WTF | perl -ple '$_=()=A..$_'
16074

通过使用echo -n避免chop调用,减少到17 。

通过使用说而不是打印减少到15。

通过使用-p而不是say减少到11。

说明: A在字符串上下文中求值,并A..$_建立一个列表,该列表以“ A”开始,并以字符串递增直至输入字符串。Perl在字母上下文中++(因此..)在字符串上解释运算符,因此例如$_="AZ";$_++;printoutput BA

=()=(aka “ goatse”运算符)强制表达式在列表上下文中求值,并返回该表达式返回的元素数,即$scalar = () = <expr>对应于@list = <expr>; $scalar = @list


2
使用$_$` instead of $ n`,然后print不带参数地调用。
暴徒

4
使用“ -p”并完全放弃打印:echo -n WTF | perl -p -e'$ _ =()= A .. $ _'总代码:11个字符,AH AH!
wazoox '04

2
切换printsay并放下另外2个字符:)
mpeters 2010年

16
啊,我爱山羊皮经营者:)
以太2010年

6
嘿,Perl击败了J!
David

339

Excel,9个字符:)

使用正确的工具进行工作:

=COLUMN()

=COLUMN()


166
在工作中使用正确的语言:葡萄牙语Excel =COL()。6个字符。(见dolf.trieschnigg.nl/excel/excel.html
Debilski

21
大!ROFL尽管它不支持。

63
该解决方案甚至正确地再现了Excel的局限性。
kibibu 2010年

18
它甚至不需要字符串作为输入。并不能解决问题。仅当它在该字符串中恰好以该字符串命名的列中时才有效。完全不符合问题的精神。
phkahler '04

9
为了公平起见,代码高尔夫做出对这类自作聪明的答案。所以你得到我的+1。
雷诺兹2010年

71

J17 12 10个字符

26#.64-~av

例:

26#.64-~av  'WTF'
16074

说明:

  • J从右到左解析。
  • av返回其参数中每个字符的ascii索引列表,例如,av'ABC'return 65 66 67
  • 然后,用动词从该列表的每个元素中减去64 64-~
  • 然后,我们使用#.动词将列表转换为以26为底的数字。

2
在阅读了有关Excel解决方案实际上如何不使用字符串输入的一些注释之后,我将使用最短的解决方案,实际上是使用字符串输入。
Vivin Paliath'4

哇,我实际上可以理解的J解决方案:)
Callum Rogers 2010年

2
@布兰登:只要您不介意花费数年的时间学习如何阅读它,J就是万能的。
David

55

Brainf * ck,81个字符(无空格)

,[>>>[->>+++++[-<+++++>]<+<]>[-<+>]<<++++++++[<++++++++>-]<[<->-]<[>>>+<<<-],]>>>

说明

,[  // get character input into p[0], enter loop if it isn't null (0)
>>>[->>+++++[-<+++++>]<+<] // take what's in p[3] and multiply by 26, storing it in p[4]
>[-<+>] // copy p[4] back to p[3]
<<++++++++[<++++++++>-]< // store 64 in p[1]
[<->-]< // subtract p[1], which is 64, from the input char to get it's alphabetical index
[>>>+<<<-] // add p[0] to p[3]
,] // get another character and repeat
>>> // move to p[3], where our final result is stored

因此,您会注意到我实际上并没有将数值转换为可打印的ascii字符串。那可能会破坏乐趣。但是我很乐意将指针移动到带有结果的单元格,因此至少对机器有用。

嘿,你知道吗,我击败了C#!


16
哈哈@ Beating C#

我很惊讶任何人实际上首先使用Bf
OscarRyz

31

红宝石1.8.7,53 50 46 44 24 17个字符

p ('A'..$_).count

用法:

$ echo -n ROFL | 红宝石-n a.rb
326676
$ echo -n WTF | 红宝石-n a.rb
16074
$ echo -n A | 红宝石-n a.rb
1个

太好了,我已经测试了非常相似的模式,但我没有意识到,p (p(不同的是,:(

使用,echo -n ...以便您可以放下.chop
John La Rooy

@gnibbler:感谢-n的想法,这也使我的perl解决方案也降低到了17。
大卫2010年

您可以使用?A而不是'A'将其提高到16
steenslag

23

杀伤人员地雷

13个字符

将值输入x

x←'WTF'

然后用:

26⊥(⎕aV⍳x)-65

J打败我的唯一原因是因为括号。我认为应该有某种方法可以重新安排它,以避免对它们的需要,但这已经是漫长的一天。有想法吗?

(嘿,您的30个字符解决方案的perl程序员真是太可爱了!)


也许改为26⊥⁻65+⎕aV⍳x?那就是你在APL中写负65的方式,对吗?
Kragen Javier Sitaker'4

我现在没有我的APL环境,但是我认为我尝试过类似的操作,但是它没有用。my没关系(我当然是APL向导中最远的人!)⁻等同于-,并且因为它从右到左求值,所以应用在+之后,所以最终得到26⊥⁻( 65+(⎕aV⍳x))而不是26⊥((⁻65)+⎕aV⍳x),这是您在这里需要的。

公认的Perl解决方案使您的代码胜过两个字符... =)
kolistivra,2010年

14

Excel(不作弊),25个字符

最多支持XFD:

=COLUMN(INDIRECT(A1&"1"))

安装:

  1. 将公式放在单元格A2中。

用法:

  1. 在单元格A1中输入列字符串。
  2. 在单元格A2上读取结果。

54个字符,外加大量说明

还支持ROFL:

(A2)  =MAX(B:B)
(B2)  =IFERROR(26*B1+CODE(MID(A$1,ROW()-1,1))-64,0)

安装:

  1. 清除整个电子表格。
  2. 将公式(A2)放在单元格A2中。
  3. 将公式(B2)放在单元格B2中。
  4. 尽可能多地填充公式(B2)。

用法:

  1. 在单元格A1中输入列字符串。
  2. 在单元格A2上读取结果。

13

C#156 146 118个字符

using System.Linq;class P{static void Main(string[]a){System.Console.Write(
a[0].Aggregate(0,(t,c)=>(t+c-64)*26)/26);}}

取消高尔夫:

using System.Linq;
class P
{
    static void Main(string[] a)
    {
        System.Console.Write(a[0]
            .Aggregate(0, (t, c) => (t + c - 64) * 26) / 26);
    }
}

使用C = System.Console快捷方式在这里无济于事,因为您最终不得不说“系统”。两次。如果只使用“使用系统”,则可以节省5个字符。并相应地更改您的代码。但是我的非linq版本仍然较短。:)
Igby Largeman'4

您是对的,我可以通过使用第一个参数而不是Console.Readline来使其更短。:P
Cameron MacFarland

1
哦,废话,我帮你超越了我!:P
Igby Largeman'4

顺便说一句,感谢您解决我的字符计数问题。我完全分开了。
Igby Largeman'4

3
怎么样Console.Write,而不是WriteLine
Andreas Grech

12

Golfscript-16个字符

[0]\+{31&\26*+}*


$ echo -n WTF | ./golfscript.rb excel.gs
16074
$ echo -n ROFL | ./golfscript.rb excel.gs
326676

11

哈斯克尔,50岁 51 56 字符

main=interact$show.foldl(\x->(26*x-64+).fromEnum)0

用法:

~:166$ echo -n "ROFL" | ./a.out
326676
~:167$ echo -n "WTF" | ./a.out
16074

9

Python,64个49个字符

s=0
for c in raw_input():s=26*s+ord(c)-64
print s

您也可以替换raw_input()input()以将字符数减少4,但是这需要输入在其周围包含引号。

这是一个子程序,其时钟为47个字符:

f=lambda x:len(x)and 26*f(x[:-1])+ord(x[-1])-64

您的#2应该命名为f。现在尝试运行它,它不起作用。并且可以借助lambda和短路评估使其更短(47个字符):f=lambda x:len(x)and 26*f(x[:-1])+ord(x[-1])-64
Ponkadoodle 2010年

@wallacoloo:谢谢。这是一个社区Wiki,因此您可以随时进行编辑。
亚当·罗森菲尔德

单独为x删除len(x)怎么样?变成43个字符:f = lambda x:x和26 * f(x [:-1])+ ord(x [-1])-64
Nas Banov 2010年

9

k4(kdb +),11个字符

26/:1+.Q.A?

说明:

  • k4解析右边的左边
  • .Q.A 在k4内定义-它是向量 "ABC...XYZ"
  • ? 是查找运算符-x arg中y arg中项目的第一个匹配项的索引
  • +1以抵消索引
  • 26/: 转换为基数26

一个警告-仅在传入列出的类型的情况下有效:

  26/:1+.Q.A? "AD"
30

  26/:1+.Q.A? "WTF"
16074

但:

  26/:1+.Q.A? ,"A"
1


8

JavaScript 1.8:66个字符

function a(p)Array.reduce(p,function(t,d)t*26+d.charCodeAt()-64,0)

Javascript 1.8:72个字符

function a(p)(t=0,p.replace(/./g,function(d)t=t*26+d.charCodeAt()-64),t)

JavaScript 1.6:83个字符

function a(p){t=0;p.split("").map(function(d){t=t*26+d.charCodeAt(0)-64});return t}

JavaScript:95个字符

function a(p){r=0;t=1;l=p.length;for(i=0;i<l;i++){r+=(p.charCodeAt(l-1-i)-64)*t;t*=26}return r}

JavaScript:105个字符

function a(p,i){i=i||0;l=p.length;return p?(p.charCodeAt(l-1)-64)*Math.pow(26,i)+a(p.slice(0,l-1),i+1):0}

用法:

a("A")        // 1
a("B")        // 2
a("AD")       // 30
a("ABC")      // 731
a("WTF")      // 16074
a("ROFL")     // 326676

我使用表达式闭包从1.6解决方案中删除了另外4个字符。您可以通过重构(t?g*26:0)零件来进一步缩小尺寸。
大卫·默多克

更新。我只是用[]。降低剃掉了9个字符
大卫默多克

FWIW,我使用string#replace
Chetan S 2010年

@ Chetan,@ David:干得好。那很整齐!
丹尼尔·瓦萨洛


5

C89,58个字符

s;main(c){while(c=getchar()+1)s=26*s+c-65;printf("%d",s);}

输入(stdin)必须仅包含AZ,不允许其他字符(包括换行符)。


1
getchar()返回< 0EOF;EOF没有定义为-1,但是很常见。
斯特拉格

@strager:好点。然后,要确保完整的可移植性,需要添加2个字符(c=getchar()+1(c=getchar())>=0和更改6564)。但是,这几乎可以在所有C实现中使用。
亚当·罗森菲尔德

5

概念解释-Excelcification

真好 很久以前,我在http://aboutdev.wordpress.com/2009/12/19/excelcification-brain-teaser-code/上编写了自己的版本,并作了一些解释 。虽然它不是一个优化的版本!

仅供参考。以26为底的算术称为十六进制,Excel的最大列为XFD,它转换为16383(使用0作为第一个单元格),恰好是2 ^ 14个单元格

谁能猜出它为什么是2 ^ 14?


5
可能是当时他们只想使用64k内存:-)

因为他们希望能够进行需要符号位的偏移量(xy)。但这只有15位,那么第16位是怎么回事?它用作标志吗?
phkahler

1
这不是完全以26为底的,因为它没有0。如果让A代表1,并乘以26^nfor位置n(withn = 0代表最右边的字母),则一切正常。
托马斯

@phkahler:使用1位,可以表示0..2 ^ 0范围内的所有无符号整数。因此,使用16位,您可以表示0..2 ^ 15。带走1个符号位,最大值将为2 ^ 14-1(= 16383)。
stakx-不再贡献

1
@phkahler:您不需要符号位来表示偏移量,只要您不需要界外值的可分辨表示即可(即,您可以检查处理器溢出位以查看是否超出范围) )。
Kragen Javier Sitaker

5

Common Lisp,103 128个字符

(defun x(s)(reduce(lambda(x y)(+(* 26 x)y))(map 'vector(lambda(b)(-(char-code b)(char-code #\A)-1))s)))

5

C#,117个字符

与Perl,Ruby和APL之类的产品相比,这没有什么可比的,但是到目前为止,其他C#/ Java答案都得到了改进。

这使用了霍纳法则

class C{static void Main(string[]a){int t=0;foreach(var c in a[0]){t=(t+c-64)*26;}System.Console.Write(t/26);}}

1
您可以通过删除[]和'a'之间的空格以及foreach大括号来节省3个字符。
卡梅隆·麦克法兰

我不知道字符串实现IEnumerable。甜!不幸的是,有关霍纳法则的页面让我头疼,但显然是一种制胜法宝。由于输出混乱,我不喜欢使用Console.Write()。+1
伊比·莱格曼

4

Perl,34个字符

map$\=26*$\-64+ord,pop=~/./g;print

感谢mobrule的一些建议。


您可以说pop=~/./g而不是split//,$ARGV[0]您可以$_ord通话中省略。您可以使用$` instead of $ s`然后说print
暴徒

4

C#,148个字符

using System;class P{static void Main(string[]a){var r=0d;int j=0,i=a[0].
Length;while(i-->0)r+=(a[0][i]-64)*Math.Pow(26,j++);Console.WriteLine(r);}}

取消高尔夫:

using System;
class P
{
    static void Main(string[] a)
    {
        var r = 0d;
        int j = 0, i = a[0].Length;
        while (i-- > 0)
            r += (a[0][i] - 64) * Math.Pow(26, j++);

        Console.WriteLine(r);
    }
}

4

Python-63个字符

>>> f = lambda z:reduce(lambda x,y:26 * x + y,[z中c的ord(c)-64])

>>> f('ROFL')

326676


4

Clojure:

user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "AD"))
30
user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "ROFL"))
326676

51个字符,加上输入字符串中的字符数。


4

C:

int r=0;
while(*c)r=r*26+*c++-64;

字符串存储在“ c”中,值存储在“ r”中。


4

Ruby 1.9,21个字符

p'A'.upto(gets).count

测试:

$ echo -n A| ruby x.rb
1
$ echo -n WTF| ruby x.rb
16074
$ echo -n ROFL| ruby x.rb
326676

您可以使用印章代替剥离来获得1个字符
JRL 2010年

谢谢@JRL,我在使用时出现了问题echo A |,应该是echo A|
YOU

echo -n像其他人一样使用并摆脱chop
Daniel C. Sobral

谢谢@Daniel,我已经更新了它,但看起来echo -n在Windows上无法使用。

4

普通Lisp,86个字符。

(defun z(s)(let((a 0))(map nil(lambda(v)(setf a(+(* 26 a)(digit-char-p v 36)-9)))s)a))

3

Java:112 124个字符

class C{public static void main(String[]a){int r=0;for(int b:a[0].getBytes())r=26*r+b-64;System.out.print(r);}}

3

Common Lisp,81个字符

(defun y(s)(reduce(lambda(x y)(+(* 26 x)(-(char-code y)64)))s :initial-value 0))

有趣的是,作为新用户,我可以发布自己的答案,但不能对其他人的评论发表评论。哦,好,如果我做错了,就深表歉意!


我认为您必须注册:)然后,您就可以发表评论。
Vivin Paliath'4

3

MATLAB:24个字符

polyval(input('')-64,26)

用法:

>> polyval(input('')-64,26)
(after pressing enter) 'WTF'

ans =

       16074

注意:如果将字符串预存储在中,则可以将其减少到16个字符x,但我有点认为它在作弊:

>> x = 'WTF'

x =

WTF

>> polyval(x-64,26)

ans =

       16074

我怎么会忘记polyval .. +1寻求更好的解决方案
George

3

PHP-73个字符

$n=$argv[1];$s=$i=0;while($i<strlen($n))$s=$s*26+ord($n[$i++])-64;echo$s;

用法:

php -r '$n=$argv[1];$s=$i=0;while($i<strlen($n))$s=$s*26+ord($n[$i++])-64;echo$s;' AA

> 27

1
通过删除while函数周围的花括号并转储变量初始化,可能会丢失10个字符。
ChiperSoft
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.