挑战
按字符计数的最短代码,将输出 Excel 列字符串的数字等效项。
例如,A
列是 1,B
是 2,依此类推。一旦您点击Z
,下一列将变为AA
,然后AB
以此类推。
测试用例:
A: 1
B: 2
AD: 30
ABC: 731
WTF: 16074
ROFL: 326676
代码计数包括输入/输出(即完整程序)。
为工作使用正确的工具:
=COLUMN()
$_=()=A..$_
用法:
$ echo -n WTF | perl -ple '$_=()=A..$_'
16074
通过使用 echo -n 减少到 17 以避免chop
调用。
通过使用 say 而不是 print 减少到 15。
通过使用 -p 而不是 say 减少到 11。
说明:
A
在字符串上下文中进行评估,并A..$_
从“A”开始构建一个列表,字符串递增到输入字符串。Perl 在字母上下文中解释字符串上的++
运算符(以及因此..
),例如$_="AZ";$_++;print
输出BA
。
=()=
(又名“goatse”运算符)强制在列表上下文中计算表达式,并返回该表达式返回的元素数,即$scalar = () = <expr>
对应于@list = <expr>; $scalar = @list
.
26#.64-~av
例子:
26#.64-~av 'WTF'
16074
解释:
av
返回其参数中每个字符的 ascii 索引列表,例如av'ABC'
返回65 66 67
。64-~
。#.
然后我们使用动词将列表转换为 base 26 。,[>>>[->>+++++[-<+++++>]<+<]>[-<+>]<<++++++++[<++++++++>-]<[<->-]<[>>>+<<<-],]>>>
,[ // 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#!
p ('A'..$_).count
用法:
$ 回声-n ROFL | ruby -n a.rb 326676 $回声-n WTF | ruby -n a.rb 16074 $ 回声-n A | ruby -n a.rb 1
13 个字符
将值放入x
:
x←'WTF'
然后计算它:
26⊥(⎕aV⍳x)-65
J击败我的唯一原因是括号。我在想应该有一些方法来重新安排它以避免对它们的需要,但这是漫长的一天。想法?
(呵呵,你们这些拥有 30 多个字符解决方案的 perl 程序员真是太可爱了!)
最多支持 XFD:
=COLUMN(INDIRECT(A1&"1"))
安装:
用法:
还支持 ROFL:
(A2) =MAX(B:B)
(B2) =IFERROR(26*B1+CODE(MID(A$1,ROW()-1,1))-64,0)
安装:
用法:
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);
}
}
[0]\+{31&\26*+}*
$ echo -n WTF | ./golfscript.rb excel.gs
16074
$ echo -n ROFL | ./golfscript.rb excel.gs
326676
main=interact$show.foldl(\x->(26*x-64+).fromEnum)0
用法:
~:166$ echo -n "ROFL" | ./a.out
326676
~:167$ echo -n "WTF" | ./a.out
16074
26/:1+.Q.A?
解释:
.Q.A
在 k4 中定义 - 它是向量"ABC...XYZ"
?
是 find 运算符 - x arg 内 y arg 中项目的第一个匹配项的索引26/:
转换为基数 26一个警告 - 这仅适用于传入列出的类型:
26/:1+.Q.A? "AD"
30
26/:1+.Q.A? "WTF"
16074
但:
26/:1+.Q.A? ,"A"
1
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
[char[]]$args[($s=0)]|%{$s=$s*26+$_-64};$s
function a(p)Array.reduce(p,function(t,d)t*26+d.charCodeAt()-64,0)
function a(p)(t=0,p.replace(/./g,function(d)t=t*26+d.charCodeAt()-64),t)
function a(p){t=0;p.split("").map(function(d){t=t*26+d.charCodeAt(0)-64});return t}
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}
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
斯卡拉,30个字符
print((0/:args(0))(_*26+_-64))"
例子:
C:\>scala -e "print((0/:args(0))(_*26+_-64))" AD
30
与 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);}}
好的。很久以前,我在 http://aboutdev.wordpress.com/2009/12/19/excelcification-brain-teaser-code/上写了我自己的版本并进行了更多解释。虽然不是很优化的版本!
供参考。以 26 为底的算术称为十六进制,Excel 的最大列是XFD,它转换为 16383(使用 0 作为第一个单元格),恰好是2^14 个单元格。
谁能猜到为什么它是 2^14?
s;main(c){while(c=getchar()+1)s=26*s+c-65;printf("%d",s);}
输入(stdin)必须只包含 AZ,不允许其他字符(包括换行符)。
(defun x(s)(reduce(lambda(x y)(+(* 26 x)y))(map 'vector(lambda(b)(-(char-code b)(char-code #\A)-1))s)))
map$\=26*$\-64+ord,pop=~/./g;print
感谢 mobrule 的一些建议。
Common Lisp,86 个字符。
(defun z(s)(let((a 0))(map nil(lambda(v)(setf a(+(* 26 a)(digit-char-p v 36)-9)))s)a))
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);
}
}
Clojure:
user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "AD"))
30
user> (reduce #(+ (* 26 %1) %2) (map #(- (int %) 64) "ROFL"))
326676
51 个字符,加上输入字符串中的字符数。
Python - 63 个字符
>>> f=lambda z: reduce(lambda x,y: 26*x+y, [ord(c)-64 for c in z])
>>> f('ROFL')
326676
C:
int r=0;
while(*c)r=r*26+*c++-64;
字符串存储在“c”中,值存储在“r”中。
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
p('A'..$*[0]).count
用法:
$ ruby a.rb ABC
731
在VBA中我把它降到了98
Sub G(s)
Dim i, t
For i = 0 To Len(s) - 1
t = t + ((Asc(Left(Right(s, i + 1), 1)) - 64)) * ((26 ^ i))
Next
MsgBox t
End Sub
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
$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
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);}}
Common Lisp,81 个字符
(defun y(s)(reduce(lambda(x y)(+(* 26 x)(-(char-code y)64)))s :initial-value 0))
有趣的是,作为一个新用户,我可以发布自己的答案,但不能评论别人的答案。哦,好吧,如果我做错了,请道歉!
x=0 for c in(...):gfind(".")do x=x*26-64+c:byte()end print(x)
with(prompt())for(l=length,i=0,v=i--;++i<l;)v+=(charCodeAt(l-1-i)-64)*Math.pow(26,i);alert(v)
PHP:56 55 个字符
for($i='a';$i++!=strtolower($argv[1]);@$c++){}echo++$c;
PHP:44 43 个字符,仅用于大写字母
for($i='A';$i++!=$argv[1];@$c++){}echo++$c;
将所需字符串存储在变量 w 中:
w←'rofl'
假设字符是小写的:
26⊥⎕a⍳w
假设字符是大写的:
26⊥⎕A⍳w
混合大小写或不确定大小写(14 个字符,但可能会改进):
26⊥⊃⌊/⎕a⎕A⍳¨⊂w
Smalltalk arguments first reverse inject:0into:[:o :e|o*26+e digitValue]
瓦祖克斯:
回声-n WTF | perl -ple '$ =()=A..$ '
这将打印一个新行,因此答案在 shell 上更具可读性。
for($a=A;++$c,$a++!=$argv[1];);echo$c;
用法,例如
php -r 'for($a=A;++$c,$a++!=$argv[1];);echo$c;' WTF
chomp($n=<>);@c=split(//,uc($n));$o=64;$b=0;$l=$#c;for($i=$l;$i>=0;$i--){$b+=((26**($l-$i))*(ord($c[$i])-$o));}print$b;
用法:
vivin@serenity ~/Projects/code/perl/excelc
$ echo WTF | perl e.pl
16074
vivin@serenity ~/Projects/code/perl/excelc
$ echo ROFL | perl e.pl
326676
我敢肯定这里的一些 Perl 大师可以想出一些更小的东西。
chop($l=<>);$_=A;$.++,$_++while$_ ne$l;die$.,$/
Applescript: 188
这是 188 个字符的必要 applescript,这是一种非常难以使非冗长的语言。它也恰好是迄今为止所有语言中最长的答案。如果有人知道如何缩短它,请分享。
在运行时 将 {o, c} 设置为 {0, 0} 与(s 的第 1 项)的字符相反的 i 重复 将 m 设置为 26 ^ c 作为整数 将 c 设置为 c + 1 将 o 设置为 o + ((i 的 ASCII 数字) - 64) * m 结束重复 结束运行
用法:
osascript /path/to/script.scpt ROFL
p ("A"..$*[0]).to_a.size
(相反)
dc
无法处理字符输入,所以我编写了相反的代码:输入列号并输出列名:
?[26~64+rd0<LP]dsLxP
dc exccol.dc 326676 ROFL
系数:47 个字符
反向 [ 26 交换 ^ 交换 64 - * ] 映射索引总和
public class A{public static void main(String[] z){int o=0,c=0;for(int i=z[0].length()-1;i>=0;i--,c++)o+=(z[0].charAt(i)-64)*Math.pow(26,c);System.out.println(o);}}
public class A
{
public static void main(String[] z)
{
int m,o=0,c=0;
for(int i=z[0].length()-1;i>=0;i--,c++)
{
m=(int)Math.pow(26,c);
o+=(z[0].charAt(i)-64)*m;
}
System.out.println(o);
}
}
假设一个大写输入(通过命令行参数)。没有技巧的明显方法。
序言:49 个字符
c([],A,A)。 c([H|T],I,R):-J 是 H-64+I*26,c(T,J,R)。
使用上面的代码:
| ?- c("WTF",0,R)。 R = 16074 ? 是的 | ?- c("ROFL",0,R)。 R = 326676 ? 是的
F#(37 个字符):
Seq.fold (fun n c -> int c-64+26*n) 0
过滤器:97 个字符
{ read c;i=0;while [ $c ];do eval s=({A..${c:0:1}});i=$((i*26+${#s[@]}));c=${c:1};done;echo $i;}
用法:
echo ROFL | { read c;i=0;while [ $c ];do eval s=({A..${c:0:1}});i=$((i*26+${#s[@]}));c=${c:1};done;echo $i;}
326676
功能:98个字符
C(){ i=0;while [ $1 ];do eval s=({A..${1:0:1}});i=$((i*26+${#s[@]}));set -- ${1:1};done;echo $i;}
用法:
C ROFL
326676
过滤器版本说明:
read c;i=0;
初始化列和总计。
while [ $c ];do
虽然还有列字符
eval s=({A..${c:0:1}});
${c:0:1}
返回列的第一个字符;s=({A..Z})
使 s 成为一个包含从 A 到 Z 的字母的数组
i=$((i*26+${#s[@]}));
$((...))
包装算术评估;${#s[@]}
是数组 $s 中的元素个数
c=${c:1};done;
${c:1}
是 $c 中第一个之后的字符。 done
结束while循环
echo $i
嗯我忘记了
更好但可疑
删除 5 个字符“echo”将导致输入“ROFL”的输出为
326676: command not found
此外,i=0
如果您确定当前 shell 中没有设置该变量,则可能没有必要。
26_sv -64+_ic
用法:
26_sv -64+_ic"ROFL"
326676
解释:
php 29 个字符:
while($i++!=$t)$c++;echo$c+1;
Josl 48 个字符
main 0 0 argv each 64 - swap 26 * + next print
例子:
$ josl numequiv.j A
1
$ josl numequiv.j ABC
731
$ josl numequiv.j ROFL
326676
从标准输入读取:
main 0 STDIN read-line each 64 - swap 26 * + next print
范围(“WTF”)。列
OOBasic:178 个字符,不包括缩进空格
这个版本通过了所有的测试用例。我怀疑如果它不“利用”有一个使用这种编号系统的电子表格这一事实,它会更成功地打高尔夫球。请参阅下面原始版本的注释,了解为什么这不是特别有用。我没有很努力地降低分数。
另请注意,由于显而易见的原因,这仅在作为 OO calc 电子表格中的宏运行时才有效。
Function C(st as String) as Long
C = 0
while len(st)
C = C*26 + ThisComponent.Sheets(0).getCellRangeByName(left(st,1) &"1").CellAddress.Column+1
st = mid(st,2)
wend
End Function
OOBasic (OpenOffice Basic),字符太多 (124):
Function C(co As String) As Long
C = ThisComponent.Sheets(0).getCellRangeByName(co &"1").CellAddress.Column+1
End Function
限制:
笔记:
无论如何,在单元格中输入=C("A")
,=C("ABC")
等适用于前四个测试用例;最后两个给出错误。
使用列表推导:
s=input()
print sum([((26**(len(s)-i-1))*(ord(s[i])-64)) for i in range(len(s))])
Python
import string
letters = string.uppercase
colnum = lambda s: sum((letters.index(let)+1)*26**idx for idx, let in enumerate(s[::-1]))
print colnum('WTF')
# 16074
print colnum('ROFL')
# 326676
我的 Javascript 解决方案只有82 个字符长,并使用 Integer.parseInt 和 Radix 36。如果有人可以将它附加到该线程的 Javascript 部分,那就太好了!:-)
a=function(b){t=0;b.split('').map(function(n){t=parseInt(n,36)-9+t*26});return t};
PHP:
<?$t=0;$s=str_split($argv[1]);$z=count($s);foreach($s as$v){$z--;$t+=(ord($v)-64)*pow(26,$z);}echo$t?>
用法: php 文件名.php ROFL
输出: 326676
reduce(lambda a,b:a*26+ord(b)-64,raw_input(),0)
仅适用于大写字母
Matlab 38个字符
仅适用于大写字母。不确定它是否也必须使用小写字母(示例中没有)。
x=input('')'-64;26.^(size(x)-1:-1:0)*x
如果新行不计 37(省略分号):
x=input('')'-64
26.^(size(x)-1:-1:0)*x
我看到 Matlab 胜过很多语言。谁会想到。
例子:
Input: 'ROFL' (dont forget the '' )
Output: ans = 326676
Groovy:51 个字符
char[] a=args[0];t=0;for(i in a)t=26*t+i-64;print t
调用为
groovy *scriptname* ROFL
或者
groovy -e "char[] a=args[0];t=0;for(i in a)t=26*t+i-64;print t" ROFL
这与 Java 基本相同。我想象使用范围和闭包的一些可能性,但这个例子没有想到。其他人看到缩短这个的方法吗?
不幸的是,带有闭包的外观更时髦的版本要长一些。
t=0;args[0].toCharArray().each{t=t*26+it-64};print t
围棋:106 个字符
它不是所有语言中最短的。但它可能是 C、C++、Java 和 C# 中最短的一个。
package main
import("os"
"fmt")
func main(){t:=0
for _,c := range os.Args[1]{t=t*26+c-64}
fmt.Println(t)}
格式化版:
package main
import (
"os"
"fmt"
)
func main() {
t := 0
for _, c := range os.Args[1] {
t = t*26 + c - 64
}
fmt.Println(t)
}
我在真正的高尔夫上也失败了。
Private Sub CB1_Click()
Dim C, S
Range("A1").Select
Do
S = Len(ActiveCell)
x = 0
C = 0
Do
C = (Asc(Mid(ActiveCell, (S - x), 1)) - 64) * (26 ^ x) + C
x = x + 1
Loop Until x = S
ActiveCell.Offset(0, 1) = C
ActiveCell.Offset(1, 0).Activate
Loop Until ActiveCell = ""
End Sub
使用 A 列输入,输出到 B 列,单击 VB 命令按钮运行。=D
伊朗,53/78
外壳,53 个字符:
F=fun(S)->lists:foldl(fun(C,A)->A*26+C-64end,0,S)end.
模块,78 个字符:
-module(g).
-export([f/1]).
f(S)->lists:foldl(fun(C,A)->A*26+C-64end,0,S).
让 e2n (c : string) = c |> Seq.map (fun x -> (int)x - 64) |> Seq.reduce(fun ea -> a*26+e)
Excel - 99 个字符
输入为数组公式 - 我不计算 Excel 添加 { }
=SUM((CODE(MID(A1,ROW(INDIRECT("1:" & LEN(A1))),1))-64)*26^(LEN(A1)-ROW(INDIRECT("1:" & LEN(A1)))))
将运算符定义为的新语言怎么样
# - 将 EXCEL 的 =COLUMN() 作为字符串数字返回
, - 读入一个字符串
. - 写出一个字符串
那么执行此操作的程序是
,#。