在参加今年的Google Code Jam 竞赛之后,我不禁注意到使用C/C++和Java的[成功]参赛者人数众多.在这里可以看到整个比赛中使用的语言分布.
在用C/C++编程好几年后,我最近因其可读/直接的性质而爱上了Python.最近,我学习了OCaml,Scheme等功能语言,甚至像Prolog这样的逻辑语言.这些语言当然有它们的优点,在我看来,在某些情况下,它可以比C++和Java更容易应用.例如,Scheme使用call/cc简化了回溯(回答几个问题所需的工具)和Prolog的逻辑规范,虽然由于其强力性质而效率低下,但可以极大地简化(甚至自动解决)某些难以解决的问题.包裹一个人的大脑.
很明显,竞赛选手应该使用最适合挑战的工具.即使是x86程序集也是图灵完成的 - 这并不能证明解决它的问题.在这种情况下,为什么使用不太常用的语言(如Scheme/Lisp,Prolog,甚至Python)的参赛者比使用C/C++和Java的参赛者要少得多?换句话说,为什么没有成功的参赛者使用的语言虽然可能不那么主流,但可以说是更好的工具?
我的问题有几个动机.最重要的是,我希望成为一名更好的程序员 - 无论是在实践方面还是在竞争方面.在介绍了诸如功能和逻辑编程之类的美妙范例之后,看到有这么多人抛弃它们而转向支持C/C++和Java是令人沮丧的.它甚至让我怀疑我对这些范例的钦佩,担心我不能在编程竞赛中成为Lisp/Scheme/Prolog程序员.
好问题!作为一个自己涉及编程竞赛的人,我可能有话要说.
[让我们得到标准的免责声明:比赛编程只与"现实世界中的编程"松散相关,同时它测试算法和解决问题的技巧以及能够提供快速无错工作代码的能力时间压力,它不一定与能够构建大型软件项目,编写可维护代码等相关(超出了结构良好的程序更容易调试的事实).
现在回答一些问题:
C++/Java在现实世界中比其他语言更常见,因此您可以期望在任何地方看到更高的比例.(但在竞赛人群中甚至更高.)
这些参与者中有许多是学生,或者作为学生参加竞赛,而C++/Java是学生学习的更常见的"第一语言".(这些天的本科生可以从Scheme,Haskell,Python等开始,但是高中生(通常是自学成才的)不那么经常.)事实上,许多东欧参与者仍然使用Pascal,并且更加惊人比我们其他人都会用任何语言.
学校和大学级别的比赛通常使用这些语言.国际信息学奥林匹克(IOI)只允许使用C,C++和Pascal(或者它现在允许使用Java;我没有跟上),而ACM校际编程竞赛(ACM ICPC)只允许使用C,C++和Java.TopCoder允许C++,Java,C#和VB(真的:p); 最近,Python.所以你可以说"竞赛生态系统"中有更多的C++/Java程序员.实际上,Google Code Jam和IPSC是少数允许使用任何语言编写代码的竞赛之一.
现在的问题是,在GCJ,参赛者可以自由选择一种语言,他们为什么不选择Python或Scheme?最相关的因素是这些语言很慢.当然,对于大多数真实世界的编程来说,它们很容易就足够快,但是对于所有测试用例在n秒限制下运行程序通常涉及的紧密循环,这些语言不会削减任何算法上涉及更多的问题.(设计用于接受O(n log n)解决方案而不是用于C/C++的Θ(n 2)解决方案的问题经常排除在较慢语言中的最佳O(n log n)解决方案.甚至Java曾经被赋予了障碍USACO;我不确定是否仍然如此.)
另一个因素是库:C++和Java有更好的库用于经常使用的算法和数据结构(例如红黑树,C++的next_permutation),而Python的库(对于现实世界来说足够好)在这里不太有用,Prolog和Scheme ......我不知道他们的图书馆.这是一个相对较小的因素,因为这些程序员可以在必要时编写自己的代码.:-)
通用的多范式语言对于在比赛的时间限制内完成任务比使用强制理念或对你做事的方式的语言更有用.这就是为什么Prolog将永远不受欢迎的原因.(一般哲学:有些语言是"启用"语言,可以让你做任何事情,包括用脚射击自己,有些是"指挥",迫使你以正确的方式做事.)这也是为什么C++比三倍更受欢迎的原因. Java在一般比赛参赛者中,并且在顶级选手中更受欢迎.由于代码不必被其他任何人读取,因此可以使用循环宏,甚至是有用的FOR(i,n)
(输入的代码越少,更重要的是在匆忙时制造错误的机会越少).没有什么可以反对Java,也有一些顶级程序员也使用Java.:-)
最后,虽然许多顶级程序员可能将C++/Java/Pascal作为他们的"第一语言",但由于他们的语言不好,所以你不必对此感到绝望.这些相同的程序员中的许多人都赢得了像ICFP竞赛这样的竞赛,即使故意使用疯狂的语言,如shell脚本,m4(用于autoconf)和汇编(团队名为"你不能在没有ASM的情况下拼写真棒").
我喜欢Jerry Coffin关于策划Google AI竞赛参赛者的想法,因此我将所有结果绘制出来并绘制它们(计算平均值,标准偏差,然后绘制Excel中的正态分布曲线).
有了Lua和JS,得到了这个:
没有(参赛者很少,所以结果可能会有所偏差):
看起来Java参与者的确比其他参与者差得多,而Go,Common Lisp和C则更好.
为什么我们都说英语而不是世界语?嗯,它刚刚发生了.即使英语不一致和臃肿,世界语也被故意设计为"更好的工具".
因此,一个原因是传统.在大多数学校,编程仍然用C/C++,Java,Pascal甚至Basic编写.参加那些比赛的大多数学生,选择他们更熟悉的语言.
此外,您可以注意到大多数算法书籍都采用Pascal或Ada风格的psedudocode,而且很少 - Lisp.我不知道为什么,也许也是一种传统.或者它可能对算法不太好.
另一个原因是速度.虽然对于Google Code Jam来说这不是问题,但在几乎所有比赛中,2x速度差距是"接受"和"时间限制"判断之间的差异.
换句话说,如果C++中的最佳算法运行速度比Ruby快10倍,那么可能意味着C++中的次优算法仍然比Ruby中的优秀算法快.如果可以实现O(n*logn),比赛作者通常不希望允许O(n ^ 2)提交.
首先,我会质疑你的前提[编辑:或者我认为是一个前提 - 使用C++和Java的竞争对手同样如此好].例如,以下是Google最近的人工智能竞赛前100个地方和最后 100个地方的参赛作品使用的语言:
使用C++和Java参赛者似乎没有在任何地方接近,以同样成功的那场比赛.使用Python的参赛者似乎也没有特别好,尽管他们的数量相当少,在这方面削弱了任何结论.
其次,当然,很多解释(正如其他人指出的那样)无疑只是熟悉每种语言的人数.现在可能有更多人参加Java课程,而不是编写任何Lisp,Scheme或Prolog的人数.
编辑:我认为第三种可能性就是多功能性.要选择一个极端的例子,Prolog是非常好适合一些问题,但同样不佳适用于许多其他问题.很少有人能够(或至少确实)学习一种或两种以上的语言,足以在比赛中使用它们,所以大多数对这类事情感兴趣的人都可能会选择几乎可以在任何事情上都能很好地运作的语言,而不是试图为可能被选择的每个问题学习专门的语言.
在几乎所有Google Code Jam轮次中,更多表现更出色的参赛者都使用C++编写代码.
以下是Google Code Jam 2012第1A,1B和1C轮(从上到下列出)的语言统计信息.每轮参赛者人数分别为3,686人,3,281人和3,189人.
有趣的问题,可能应该是社区维基.
查看各国的决赛入围人数:http://www.go-hero.net/jam/10/regions.请注意来自东欧和俄罗斯的人数.出于多种原因,这些地方拥有非常强大的C++社区以及Java.
在限定符中查看数字语言:http://www.go-hero.net/jam/10/languages/0和finals:http://www.go-hero.net/jam/10/languages/6.C++的开始时间不到一半,总决赛的比例为75%.要么优秀的程序员更喜欢C++,要么C++就是程序员.可能在你掌握C++的时候,其他事情变得微不足道.
你可以自由地得出自己的结论.
首先,正如您所指出的C++
并且Java
是主流语言.这些自动意味着开始编程比赛的人将首先被介绍给他们 - 通过学习Lisp
第一语言的方式:)我也经常参加这样的比赛 - 我C++
用来竞争,尽管我最喜欢的语言是Java
.只是我想练习另一种语言Java
- 也是C++
是一个不那么冗长,运行得更快,这对编程比赛很重要.现在,我认为 - 人们首先成为主流语言的专家.要参加编程比赛,您必须非常了解所使用的语言.你没有时间在互联网上搜索愚蠢的东西 - 比如忘了一个构造.只是速度是那里的一个重要因素.使用Lisp
在比赛中,你必须喜欢它.我不认为那里有这么多人.如果我错了,请纠正我.老实说,你提到的专业知识就像简化了回溯:无论语言回溯是多么简单 - 声明一个方法,然后再为每一个可能的结果再次调用它.这简直太简单了.直到现在我还没有感觉到我正在使用的语言试图让我的脚步参加编程比赛.