语言展示


507

笔记

  • 仅由于社区决定例外,此线程才被打开和解锁。请不要将此问题用作您可以在此处提出类似问题的证据。请不要创建其他问题。

  • 这不再是一场,也不再受片段计数的限制。如果您以前知道此线程,请确保您熟悉更改。

该线程专用于展示您喜欢的编程语言必须提供的有趣,有用,晦涩和/或独特的功能。这既不是挑战,也不是竞争,而是一种协作,以展示尽可能多的编程语言。

如何运作

  • 所有答案均应在帖子顶部包含编程语言的名称,并以开头#

  • 答案可能包含一个(并且只有一个)事实,即,没有描述该语言的代码的几句话。

  • 除了事实以外,答案还应包括代码片段,这些代码片段可以(但不一定是)程序或函数。

  • 这些片段不需要关联。实际上,过于相关的摘要可能是多余的。

  • 由于这不是竞赛,因此无论创建哪种语言,都欢迎使用所有编程语言。

  • 包含少量代码片段的答案应使用堆栈片段折叠除事实和片段之一以外的所有内容。

  • 只要有可能,每种编程语言都应该只有一个答案。这是一个社区Wiki,因此即使您自己未创建摘要,也可以随时在任何答案中添加摘要。有一个用于压缩帖子堆栈片段,这应减轻30,000个字符限制的影响。

这些指南之前的答案应进行编辑。请帮助根据需要更新它们。

当前答案,按语言名称按字母顺序排序

$.ajax({type:"GET",url:"https://api.stackexchange.com/2.2/questions/44680/answers?site=codegolf&filter=withbody",success:function(data){for(var i=0;i<data.items.length;i++){var temp=document.createElement('p');temp.innerHTML = data.items[i].body.split("\n")[0];$('#list').append('<li><a href="/a/' + data.items[i].answer_id + '">' + temp.innerText || temp.textContent + '</a>');}}})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><base href="http://codegolf.stackexchange.com"><ul id="list"></ul>

Answers:


414

Mathematica

您可能需要从上至下阅读此书,因为这是它的编写顺序,并且一些解释将参考以前的摘录,或者从更下层开始进行解释。

该列表增长了很长的时间。我已经开始删除不太有趣的代码段,现在我将开始跳过这些代码段。参见修订历史记录的片段长达41对于一些真正的宝石的完整列表,请访问片段8164442319128

长度为143和144的摘要

终于……我已经等了一段时间了(打高尔夫球已经有那么久了,所以我不必再等了)。前面我提到过,您还可以数值方程式,也可以求解微分方程式。我想展示一个简单的例子。

考虑杆上的双摆(即,一个摆与另一个摆相连)。每个杆都有单位长度,两个摆锤的重量都有单位质量。我还使用了单位重力来简化方程式。以下143个字符的代码片段求解了这种系统的拉格朗日运动方程(根据摆的角度和角动量)。可以在此PDF中找到派生方法,尽管如果您熟悉拉格朗日力学的话,这是相当简单的练习。

这是非常难以理解的,因为我不得不将它压低很多:

d@t@t;NDSolve[{#''@t==-#4#2''[t]Cos@d-##3#2'@t^2Sin@d-Sin@#@t&@@@{{θ,φ,1,.5},{φ,θ,-1,1}},θ@0==2,φ@0==1,θ'@t==φ'@t==0/.t->0},{θ,φ},{t,0,60}]

整洁的是,Mathematica立即显示了解决方案的大致缩图:

在此处输入图片说明

好的,但是有点la脚。我们想知道摆子的运动实际上是什么样的。因此,这是一个144个字符的代码段,它在描绘出下摆的轨迹时对摆进行了动画处理:

Graphics@{Line@{{0,0},p=θ~(h={Sin@#@#2,-Cos@#@#2}&)~t,p+φ~h~t},White,{0,0}~Circle~2.2}~Show~ParametricPlot[θ~h~u+φ~h~u,{u,0,t}]~Animate~{t,0,60}

产生的动画如下所示:

在此处输入图片说明

我不得不稍微作弊:如果您在之外绘图t = 30,则ParametricPlot默认情况下使用的绘图点太少,并且线条变得锯齿状。但是大多数有趣的动态变化都是在那之后发生的,因此我使用该选项PlotPoints -> 200使动画的后半部分看起来更平滑。两者之间没有什么实质性的区别,而且上半部分无论如何看起来都无法区分。

我认为这将是我的最后一句话,除非我提出了令人难以置信的东西。希望你喜欢这个!

长度为100片段

GeoGraphics[{GeoStyling[Opacity[0.5]], NightHemisphere[]}, GeoBackground -> GeoStyling["ReliefMap"]]

我当时在考虑Geo100代码段的一些不错的功能,但最终我在Tweet-a-Program上发现了一些非常不错的东西,我只是不得不窃取。上面的代码通过将半球半夜形状的浮雕图覆盖在地形图上,从而生成了当前时间和日期的非常漂亮的地球太阳图:

在此处输入图片说明

长度81片段

CellularAutomaton[{{0,2,3,If[0<Count[#,1,2]<3,1,3]}[[#[[2,2]]+1]]&,{},{1,1}},i,n]

我保证这是最后的细胞自动机。但是那是Wireworld中的81个字符。这次我没有将规则编码为一个数字,a)因为我认为规则太大了(我不想弄清楚),并且b)向您展示了的另一用法CellularAutomaton。这次,将规则简单指定为一个纯函数,该函数接收一个单元邻域并返回该单元的新值。对于具有两种以上颜色/状态的细胞自动机,这是一种更可行的方法。

无论如何,我已经在Wikipedia中建立了示例i(两个时钟生成信号和一个XOR门),并使其运行约50个步骤:

在此处输入图片说明

如果您有兴趣,实际的绘图和动画可能是片段77:

ListAnimate[ArrayPlot[#,ColorRules->{0->Black,1->Blue,2->Red,3->Yellow}]&/@w]

长度69片段

DSolve[r^2*R''[r]+2r*R'[r]-R[r]==0&&(R[r]==1&&R'[r]==2/.r->1),R[r],r]

回到有用的东西。除了正常的方程组外,Mathematica还可以求解微分方程组。以上从技术上讲只是一个带边界条件的微分方程,但您也可以将其作为三个方程的系统来提供。与积分函数相似的DSolve是精确的解决方案,而NDSolve将数值地求解系统。以上产生一个解决方案

{{R[r] -> 1/2 r^(-(1/2) - Sqrt[5]/2) (1 - Sqrt[5] + r^Sqrt[5] + Sqrt[5] r^Sqrt[5])}}

现在可以轻松地将其用于进一步的计算或作图。

长度为64片段

CellularAutomaton[{224,{2,{{2,2,2},{2,1,2},{2,2,2}}},{1,1}},i,n]

我答应了你更多的CellularAutomaton魔法!此摘要使用步骤的初始条件i来计算Conways的生命游戏,n并为您提供所有中间时间步的结果。

关于参数的几句话:2是单元状态的数量。{{2,2,2},{2,1,2},{2,2,2}}给出3x3邻域中9个单元的权重。它确保了小区本身与8个邻居的总和是可区分的。{1,1}说,CA规则取决于在任一方向上相距1步的像元。最后,224是将实际更新规则编码为单个数字。弄清楚这个数字可能有些棘手,但是文档中有一个相当有用的教程。对于更复杂的自动机,一个数字不会删减它(因为这个数字很大)。也许明天再到那儿!;)

无论如何,如果我将随机网格馈入i,将200 馈入n,并通过animation发送结果ArrayPlot,则可以看到它实际上在工作:

在此处输入图片说明

长度59片段

SphericalPlot3D[Re[Sin[θ]Cos[θ]Exp[2I*φ]],{θ,0,π},{φ,0,2π}]

还记得片段26中的极坐标图吗?我们可以在3D中做同样的事情!(实际上,有两个功能:RevolutionPlot3D用于圆柱极坐标和SphericalPlot3D球形极坐标。)就像Graphics3D在Mathematica中所有三维图都可以自动旋转一样,因此您不必担心预先准备好的相机角度。上面绘制了类似球谐函数的东西(虽然不完全),看起来像:

在此处输入图片说明

长度52片段

Manipulate[Plot[x^2a+x*b,{x,-3,3}],{a,.1,3},{b,0,3}]

这个很漂亮。Manipulate接受任何表达式,使用一堆变量对其进行参数化,然后提供一个小部件,您可以在其中微调参数并实时查看表达式的变化。作为表达,您通常会有某种情节。如果您在讲座中使用Mathematica来演示解决方案系列如何响应修改参数,则此功能特别有用。上面显示了ab系数如何缩放和移动抛物线:

在此处输入图片说明

长度48片段

Import["http://www.google.com/doodles","Images"]

Import是一个非常强大的命令。它既可以用来从光盘上加载文件,也可以用来从网络上加载文件。它知道很多不同的文件格式,并且对于其中某些文件格式(例如HTML页面),它实际上可以立即提取数据。上面的代码从Google的Doodle页面下载了所有图像。

长度为45片段

EdgeDetect@ExampleData@{"TestImage","Splash"}

是时候进行一些图像处理了。Mathematica附带了一堆示例数据,包括图像(如Lena),纹理,3D模型和音频片段。首先,我们加载其中一个:

在此处输入图片说明

要检测边缘吗?这是一个函数调用:

在此处输入图片说明

长度为44片段

ArrayPlot@CellularAutomaton[110,{{1},0},100]

最后,我有足够的字符来使用CellularAutomaton并呈现结果。:)据我所知,CellularAutomaton是Mathematica中与CA相关的唯一功能。但是斯蒂芬·沃尔夫拉姆(Stephen Wolfram)在细胞自动机方面似乎认为自己是第一人,因此此功能非常强大。上面显示了最简单的用法。这将模拟一个100步的一维元胞自动机-并且实际上将在每个步骤中返回自动机的状态,因此结果是二维的。规则是第一个参数,可以通过列表详细指定,也可以仅编码为一个数字。在此示例中,我选择了比较著名的图灵完成规则110{{1},0}定义初始条件:单个1在零背景前。CellularAutomaton当我有更多可用的字符时,也许将来我会展示一些更多的功能:它可以使用更大的邻域和两个以上的州来模拟更高维度的CA。

ArrayPlot是另一个不错的绘图工具,它只是将2D列表绘制为纯色网格以指示其值。在最简单的情况下,0将映射为白色和1黑色。该代码段的结果是:

在此处输入图片说明

长度为43片段

HighlightGraph[graph,FindVertexCover@graph]

自从我提到图表以来已经有一段时间了。Mathematica内置了很多常见的图形理论问题,以及漂亮的可视化工具。对于给定的值graph,以上内容将找到图的最小顶点覆盖,然后使用高亮的那些顶点来渲染图。例如,如果graphPetersenGraph[7,2]从片段18回,我们得到:

在此处输入图片说明

长度42片段

Animate[Plot[Sin[t-x],{x,0,10}], {t,0,10}]

在Mathematica中对事物进行动画处理非常简单(它们甚至不必是图像)。您只需为其提供要针对每个框架进行评估的表达式,以及一堆随框架而变化的参数。上面只是简单地绘制了正弦波的动画。动画将类似于以下GIF:

在此处输入图片说明

长度40片段

SortBy[PlanetData[#, "EscapeVelocity"]&]

SortBy达到您的期望:根据将给定函数映射到每个列表元素所获得的值对列表进行排序。但是,等等,上面的调用根本不包含列表。从Mathematica 10开始,支持对某些功能进行周期性部分应用。这不是像更纯粹的功能语言中那样的语言功能,而是只是为通常有用的全部功能手动实现的。这意味着上面的代码片段返回一个新函数,该函数获取一个列表,然后按给定的函数进行排序。如果您在整个代码中经常使用这种排序顺序,则这将非常有用。

是的,还有另一个不错的*Data功能-上面的功能将根据行星的逃逸速度对行星名称进行排序。

长度39片段

f[1]=1
f[2]=1
f[n_]:=f[n]=f[n-1]+f[n-2]

我答应让斐波那契功能更有效。此摘要显示了Mathematica中的琐碎记忆。请注意,所有更改仅是f[n]=第三行中的附加内容。因此,当f调用新值时(例如f[3]),f[3]=f[3-1]+f[3-2]将对其进行评估。这将进行计算f[2]+f[1],然后将其分配给f[3](使用=,而不是使用:=!),并最终返回初始调用的值。因此,调用此函数将为此值添加一个新定义,该定义显然比一般规则更具体-因此将用于以后f对该值的所有调用。

还记得其他的斐波那契函数花了30秒的4秒值吗?300,000个值需要3秒。

长度37片段

l//.{a___,x_,b___,x_,c___}:>{a,x,b,c}

在上一个片段中,我提到了模式。这些是规则中最常用的规则(除其他事项外),这些规则可用于修改与特定模式匹配的结构。因此,让我们看一下这段代码。

{a___,x_,b___,x_,c___}:>{a,x,b,c}是一个规则。x_带有单个下划线的模式是指单个任意值(其本身可以是列表或类似值)的模式。a___是一个序列模式(另请参见代码段15),它表示0或更多值的序列。请注意,我使用了x_两次,这意味着列表的这两部分必须具有相同的值。所以这个模式匹配包含两次值的任何名单,称该元素x,并呼吁各地这两个因素的三个序列abc。替换为{a,x,b,c}-即x删除了第二个。

现在//.将应用规则,直到模式不再匹配为止。因此,以上代码段从列表中删除了所有重复项l。但是,它的功能要强大得多://.在所有级别应用规则。因此,如果l本身包含列表(不限深度),这些子列表中的重复项也将被删除。

长度36片段

f[1]=1
f[2]=1
f[n_]:=f[n-1] + f[n-2]

是时候使用新的语言功能了!Mathematica关于定义函数有一些好处。首先,您可以为相同的名称,不同数量或类型的参数提供多个函数定义。您可以使用模式来描述定义适用于哪种参数。此外,您甚至可以为单个值添加定义。然后,Mathematica将为任何函数调用选择最特定的适用定义,并对未定义的调用进行评估。与其他If基本情况相比,这使得(除其他外)以更自然的方式编写递归函数。

关于上述摘要,需要注意的另一件事是我同时使用=:=。不同之处在于=,在定义时,其右侧仅被评估一次,而:=每次引用左侧时都被重新评估。实际上,:=甚至在分配变量时也可以使用,这些变量将具有动态值。

因此,以上内容当然只是斐波那契函数。效率很低。计算前30个数字在我的计算机上花费大约4秒钟。不久我们将看到如何在不脱离递归定义的情况下提高性能。

长度35片段

StreamPlot[{x^2,y},{x,0,3},{y,0,3}]

一个非常整洁的图,它输出2D矢量场的流线。这类似于法线向量图,因为每个箭头都与向量场相切。但是,箭头不是放置在固定网格上,而是连接成线(流线)。这些线的意义在于,如果矢量场是速度场,它们将指示粒子的轨迹(例如在流体中)。上面的输入看起来像:

在此处输入图片说明

长度34片段

Solve[a*x^4+b*x^3+c*x^2+d*x==0, x]

Mathematica也可以求解方程式(或方程式系统,但现在我们只有这么多的字符)。像往常一样,结果将是象征性的。

{
  {x -> 0}, 
  {x -> -(b/(3 a)) - (2^(1/3) (-b^2 + 3 a c))/(3 a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) + (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)/(3 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 + I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 - I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/(6 2^(1/3) a)}, 
  {x -> -(b/(3 a)) + ((1 - I Sqrt[3]) (-b^2 + 3 a c))/(3 2^(2/3) a (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3)) - ((1 + I Sqrt[3]) (-2 b^3 + 9 a b c - 27 a^2 d + Sqrt[4 (-b^2 + 3 a c)^3 + (-2 b^3 + 9 a b c - 27 a^2 d)^2])^(1/3))/( 6 2^(1/3) a)}
}

请注意,解决方案是作为规则给出的,我可能会在以后的一些摘要中更详细地说明。

长度为33的摘要

Dynamic@EdgeDetect@CurrentImage[]

感谢benwaffle的这个想法。CurrentImage[]加载您的网络摄像头的当前图像。EdgeDetect将图像转换为黑白图像,边缘为白色,其余部分为黑色(有关示例,请参见代码段45)。真正的乐趣来自Dynamic于表达式本身的更新。因此,这样做的结果将实际上是从网络摄像头流式传输图片并对其进行实时边缘检测。

长度为32片段

NumberLinePlot[x^2<2^x,{x,-2,5}]

一种非常不寻常的情节类型。它可以沿数字线绘制一系列不同的事物,例如点和间隔。您还可以为其指定条件,它将向您显示该条件为真的区域:

在此处输入图片说明

箭头指示该区域继续无穷大。白色圆圈表示这些是开放时间间隔(端点不是时间间隔的一部分)。对于封闭端,将填充圆圈。

长度28片段

Graphics3D@{Sphere[],Cone[]}

是时候制作一些3D图形了。上面的代码使用默认参数渲染了叠加的球体和圆锥体,看起来像水晶球:

在此处输入图片说明

在Mathematica中,您实际上可以单击并拖动此小部件来旋转它。

长度27片段

CountryData["ITA", "Shape"]

更多*DataCountryData非常疯狂。塑造一个国家的形态甚至都不是冰山一角。关于国家/地区的数据太多,您可能会写一本关于此功能的完整书籍。就像...有FemaleLiteracyFraction。您还可以查询该数据的不同时间点。有关完整列表,请参见参考。

在此处输入图片说明

长度26片段

PolarPlot[Sin[5θ],{θ,0,π}]

是时候进行更有趣的情节了。PolarPlot只是极坐标图。您可以为给定的角度θ指定半径r,而不是为给定的x指定y:

在此处输入图片说明

长度25片段

{{1,5},{2,3},{7,4}}.{8,9}

我们终于有了足够的字符来进行一些矢量数学运算。上面的代码计算了2x3矩阵和第2行矢量的矩阵乘法:

{53, 43, 92}

长度23片段

Rotate[Rectangle, Pi/2]

h 呵呵。您认为您知道这是什么。但是你没有。Rectangle本身只是一个命名函数。要真正获得代表矩形的对象,您需要使用一些参数来调用该函数。那么,当您尝试旋转时,您认为会发生什么Rectangle呢?这个:

在此处输入图片说明

长度22片段

30~ElementData~"Color"

另一个内置*Data功能。是的,对于化学元素,您不仅可以获得原子序数,熔点和名称之类的东西,还可以在室温下获得它们的颜色。上面给出了锌的颜色:

SlateGray

长度21片段

Integrate[E^(-x^2),x]

我们前段时间有所区别。整合时间。Mathematica可以处理定积分和不定积分。特别是,Integrate它将为您提供精确的解决方案,并且可以处理大量标准积分和积分技术(对于数值结果,请参见NIntegrate)。如果您知道微积分,您会注意到上面的高斯积分实际上没有闭合形式的不定积分...除非您考虑误差函数闭合形式。Mathematica返回:

1/2 Sqrt[π] Erf[x]

长度为20片段

"Sun"~StarData~"Age"

返回内置数据*Data对于可能想到的所有功能,至少必须有两个功能。它们每个都为您想要数据的事物提供一个标识符,并获取一个属性(或属性列表)。上面的内容只是您可以得到的最短的内容之一SunStar而且Age都非常简短,因为我迫不及待想要展示此功能。

哦,是的,我是否提到Mathematica(自9开始)支持单位数量?(稍后会有更多说明。)上面的计算结果为:

Quantity[4.57*10^9, "Years"]

显示为

在此处输入图片说明

长度19片段

MandelbrotSetPlot[]

是的...非常有用的功能...我一直在使用它。(有时,他们支持任何可能可计算的事物的愿望可能会变得有些远...)

Mathematica图形

在防御方面,该功能比这有用得多:您可以为它指定要绘制的图形的特定部分。

长度18片段

PetersenGraph[7,2]

从Mathematica 8开始,它了解什么是图形,因此它附带了各种与图形理论相关的功能。如果它不包含大量内置函数,则不是Mathematica。上面生成了广义Petersen图的图数据。它确实产生了可以操纵的实际数据结构,但是Mathematica立即以图形方式显示该图形数据:

Mathematica图形

长度17片段

Plot[x^x,{x,0,2}]

最后,足够的字符来做一些绘图。以上实际上只是一维绘图的最简单示例。我保证以后会炫耀一些阴谋

Mathematica图形

长度15片段

{##4,#,#2,#3}&

这显示了两个更强大的功能(以及高尔夫有用的功能)。整个过程是一个未命名的纯函数,与lambdaPython中的s或Ruby中的Procs 相当。纯函数仅以终止&。该运算符的优先级非常低,因此它通常包含几乎所有剩余的优先级。纯函数的参数由引用#,有时后面还有其他内容。第一个参数是#or #1,第二个参数是#2,依此类推。

另一个功能是Sequences。这些基本上就像其他语言中的splats一样。序列就像列表,列表周围没有列表-实际上,它只是一个值序列,可以在列表,函数参数等##中使用。特别是所有纯函数参数的序列。##2是从第二个开始的所有参数的序列。因此,如果我们将上面的函数命名为f,并将其命名为

f[1,2,3,4,5]

我们会得到

{4,5,1,2,3}

因此该函数将输入参数向左旋转3个元素。请注意,##44,5其中提到的内容展平到列表中。

长度12片段

D[x^y^x,x,y]

偏微分。D会相对于其他参数依次区分第一个表达式,从而为您提供一个符号表达式。因此,上面是d²(x ^ y ^ x)/ dxdy(其中d s是局部的),Mathematica报告说是

x^y^x (y^(-1 + x) + y^(-1 + x) Log[x] + x y^(-1 + x) Log[x] Log[y]) + 
  x^(1 + y^x) y^(-1 + x) Log[x] (y^x/x + y^x Log[x] Log[y])

长度9片段

Exp[I*Pi]

我们还没有完成任何复杂的算术运算!如您所见,π实际上只是的别名Pi。无论如何,以上内容实际上将正确返回integer -1

长度8片段

Sunset[]

是的 谈论疯狂的内置程序。如果没有参数,则实际上不会为您提供当前位置下一个日落的日期时间对象。它还需要其他日期,其他位置等的参数。这就是我现在的样子:

在此处输入图片说明

长度7片段

9!/43!!

该代码片段展示了一些很酷的东西。

Mathematica不仅具有内置的阶乘运算符!,还具有双阶乘!!(将每个其他数字从n向下乘以)相乘1。此外,它支持任意精度的整数。该43!!会准确地评估,到最后一位。此外,还将对有理数进行精确评估。因此,由于分子和分母都有整数,因此Mathematica将尽可能减少分数,然后为您提供

128/198893132162463319205625

当然,您可以随时使用浮点数,但是通常,如果输入不包含浮点数,则结果将是准确的。

长度4片段

Here

现在是时候开始使用Mathematica丰富的疯狂内置函数了。上面的内容如其在罐子上所说的,并且(对我而言)评估为GeoPosition[{51.51, -0.09}]

长度3片段

x-x

只是为了展示原始的Factoid:即使x尚未定义,上述方法仍然有效,并且0在这种情况下实际上会产生结果。

长度2片段

3x

通过并列相乘!如果很明显一个标识符结束并且另一个开始,则您不需要一个*或什至空格将它们相乘。这几乎适用于所有内容,包括尚无值的字符串和变量。打高尔夫球非常方便。;)

长度1片段

π

猜猜是Pi。实际上,它不是某种近似的浮点表示形式,恰好是Pi,因此,如果已知,则所使用的各种复杂和三角函数都将产生精确的结果。

类固醇

Mathematica可以执行符号操作,因此变量不需要值即可使用它们。


19
片段23很好奇。如果您这样做了,Translate[Scale[Rectangle, 80], {0, 0, 100}]那么这个巨大的字词Rectangle会浮现在您的显示器前吗?
加尔文的爱好2015年

53
@ Calvin'sHobbies刚刚尝试了一下...选择了一个不幸的z补偿...在我脸上打了一下。
马丁·恩德

45
Mathematica官方网站应绝对链接至此。
Caridorc

7
@ durron597通过将其保留为符号,并使所有三角函数和复杂函数都知道如何处理π。
马丁·恩德

16
当我看到传奇人物马丁·布特纳(MartinBüttner)发布了Mathematica答案时,我知道我没有机会赢得人气竞赛。先生,您真是个向导。
Alex A.

187

臭名昭著的莎士比亚编程语言

莎士比亚编程语言由两位瑞典学生KarlHasselström和JonÅslund于2001年创建,并结合了作者的主张

BASIC的表现力和汇编语言的用户友好性。

答案从上到下。另外,经常看到我指的是较早或以前的代码段。

我自己的链接:编辑

类固醇:

正如人们所期望的那样,莎士比亚的代码类似于莎士比亚的戏剧,其中变量是戏剧中的角色,变量的值在被“侮辱”或赞扬时会发生变化。

长度1片段:

I

莎士比亚的代码分为“使徒行传”,而行为本身也分为“场景”,以求“因果关系”。Act I举例来说,将Act定义为意味着它将成为要运行的代码的第一部分-但不仅限于此。

长度2片段:

as

用于两个“字符”之间的比较。

长度3片段:

day

到现在为止,您可能已经感到SPL非常冗长。而且很奇怪 而且您还什么都没有看到。day在SPL中为1。所有“正”和“中性”名词都被视为1,所有“负” 都被视为-1

长度4片段:

rich

什么rich啊 一个形容词。在SPL中,形容词使所附加名词的值乘以2。参见代码段14的实现。

长度5片段:

Act I

第一个代码段的实施。Act I: Hamlet must die!解析器会忽略所有数字的标题,例如,因为罗马数字后面的所有内容都会被忽略。

长度6片段:

better

每种语言都有条件,SPL也不例外。除此之外,由于这是一种语法冗长的语言(我是否提到过它很奇怪?),因此它的条件语句将很长。让Ophelia问Juliet Am I better than you?就像使用if (Ophelia > Juliet)大多数“普通”语言一样。并且,当然,您可以提出另一种解决方法:Am I not better than you?等于if (Ophelia < Juliet)。现在您已经可以猜出该如何=转换为SPL:as good as-使用代码段2。

但是,good/better并不是使用这种莎士比亚语言进行比较的唯一方法,您可以使用任何形容词。摘要3的相同原理也适用于此,“正”形容词的取值>,而“负” 形容词的取值<

长度为7的摘要:

Juliet:

这是一个变量的调用;之后,他/她的指示/声明/之后的内容将随之而来。

SPL的局限性在于变量数量有限:Romeo,Juliet,Hamlet,Ophelia,MacBeth等是在莎士比亚程序中出现的“字符”的一些示例。

长度8片段:

[Exeunt]

[Exeunt]当所有“角色”都离开“舞台”时放置。希望我以后可以详细介绍角色之间的交互。通常不是任何SPL程序的最后一条指令,尽管[Exeunt]不是该语言的终端“字符”。有关另一个示例,请参见代码段27。

长度9片段:

as bad as

九个字符仅代表一个=片段-使用摘要2.我是否提到过SPL很奇怪?有关示例,请参见摘要30。(是的,有多种方法可以输出它)

长度10片段:

difference

一种奇特的表示方式-,一种减法。您可能需要对SPL进行数学运算,即使您可能需要整整一天才能正确处理。

Factoid (由于我设法以某种方式达到了十段代码,所以让我们稍作休息,再谈一谈关于SPL的事实)

如果您想在所有方面都运行您的莎士比亚代码,则可以使用该站点 -我仍在对其进行测试,因为我什至没有在五分钟前发现它。还有一种使用翻译器将其翻译为C的方法。

运行SPL另一个代码的网站是这一个,通过在内部翻译SPL代码到另一个深奥的语言工作:甲骨文的PL / SQL。

长度11片段:

[Exit Romeo]

是! 最后我可以谈谈角色之间的互动!为了改变其价值或与他人互动,必须在舞台上输入“字符”,并使用[Enter Romeo]。如果某个字符已寻址但不存在,则表示运行时错误,程序停止。因为在SPL中,变量的值是由舞台上其他字符对其赞扬或侮辱的名称数量设置的。我觉得我应该举个例子来消除我la脚的解释可能造成的一些混乱,但是也许最好延迟一些摘要。

长度为12的摘要:

Remember me.

SPL非常“基本”,可以-但是有堆栈!例如,当罗密欧告诉朱丽叶“记住他”时,他实际上是在告诉亲人将罗密欧的价值推向她的栈。弹出值是用Recall your happy childhood!,或Recall your love for me或基本上以任何开头的句子完成的Recall-其余的只是艺术小品,如摘要22。

长度13片段

Let us return

莎士比亚式的方式goto。这就是使徒行传和场景很方便的地方。如果Romeo告诉Juliet we shall return to Act II(是的,再次有多种写法),程序将跳转到代码的特定部分。在条件语句旁边也可以看到它。

长度14片段

my little pony

是的,那是80年代的系列。在这里2*1。为什么?因为a pony是一个(某种程度上)正名词,并且little是一个形容词。因此,记住片段3和4,我们有little = "2 *"pony = "1"

长度15片段

Speak thy mind!

在SPL程序中,您会看到很多(或Speak your mind!相同)。基本上,这将以数字,字母或其他任何形式输出每个“字符”的值,具体取决于计算机使用的字符集。也有几乎一样的事情,尽管只是以数字形式输出。Open your mind.

长度16片段

You are nothing!

当有人在现实生活中告诉您这一点时,您会感到沮丧。当奥菲莉亚在莎士比亚节目中告诉哈姆雷特时,哈姆雷特感到一文不值。这是什么意思?那Hamlet = 0

长度17片段

Ophelia, a wench.

在剧本中,必须在实际播放开始之前显示角色。在大多数编程语言中,变量也必须在使用前声明。看到SPL是一种类似于电影剧本的编程语言,这就是通过声明哪些是在程序中出现的变量来声明其变量的方式。

但是“笨蛋”是什么意思?这是否意味着它是一个特定的(很酷的)数据类型名称?好吧...我不想让您失望,但这没什么意思:解析器忽略了逗号后的所有内容,这意味着您可以在其中放置您能想到的最残酷的文件。

长度18片段

lying sorry coward

-4对于所有尘世生物 为什么?因为2*2*(-1) = -4

长度19片段

Romeo:
 Remember me.

最后!!!我终于可以输出完整的正确语法指令(尽管很短)!这就是您使用片段12的方式:首先,您声明正在讲话的人,然后在下一行中编写“对话”。通常,舞台上只有两个“字符”,以避免使解析器感到悲伤和困惑。当您需要另一个“角色”时,您可以从舞台上拿走一个角色,并用新的角色替换它。

长度为20片段

cube of thy codpiece

我想为此做些详细说明,但是,说实话,对于这段摘要,我想到的东西仍然太短了。因此,我带给您的是,这最终是-1-因为(-1)3 = -1(并且codpiece是“负”名词,因为它们很不舒服)。SPL将更多复杂的算术运算理解为一些幂和平方根。

Factoid (还有另一个,因为我们已经达到另一个里程碑)

莎士比亚语中的“ Hello World Program”有89行,超过2400个字符,如此处所示

长度21片段

Listen to your heart.

在摘要15中,您输出了一些内容;在这里,您向程序输入一个数字。如果要输入一个字符,将使用Open your mind.来代替。并且,不用说,此值将存储在要说的“字符”中。

长度22片段

Recall your childhood!

如代码片段12所述,使用此方法从堆栈中弹出整数。例如,当Ophelia告诉Hamlet上述句子时,它会使Hamlet从其堆栈中获取整数并采用该值。

当然,只要单词recall是句子的开头,您就可以用创造性的莎士比亚式思维所需要的任何东西来填充其余部分。

长度23片段

Are you better than me?

片段6的实现。当一个“字符”向另一个人提出这样的问题时,他/她在做什么等同于if (x > y)使用更常见的编程语言。必须延迟此指令的后续操作,直到我有更多可用字符为止。

长度为24片段

[Enter Romeo and Juliet]

是的,“字符”可以成对输入。不需要让一个“角色”进入舞台,然后再跟随另一个。

长度25片段

remainder of the quotient

只写一个25个字符%。剩下的25个字符。并使用它?嗯,甚至更大-请参阅摘要75。

长度26片段

Let us return to scene II.

这就是gotoSPL中的a,它可以像编程语言中所期望的那样工作。一件事是:您可以在同一行为的场景之间进行跳转,也可以在行为之间进行跳转;但是您不能以不同的动作在场景之间跳转。

长度27片段

[Exeunt Ophelia and Hamlet]

当一个以上的“角色”离开舞台,而不是Exit与SPL的戏剧性质保持传统时,将使用拉丁语“ Exeunt”。有时,只需替换为片段8。

长度28片段

Scene I: Ophelia's flattery.

声明场景。如您所愿,如果您一直在与我打交道,那么重要的一点是Scene I,其余就是艺术上的毛茸茸。

已经有一些编译器(例如用SPL编译成C的这种编译器,用Python编写),而是引用了Act / Scene编号之后的文本。尽管比较合乎逻辑(毕竟,在戏剧中,让角色说“让我们回到第一幕”这样的字眼可能很愚蠢),但我还是坚持原来的做法。

长度29片段

You pretty little warm thing!

是的,另一个常量(因为我们需要更多的字符才能进行算术运算)。这等于8,因为2*2*2*1 = 8

长度30片段

You are as cowardly as Hamlet!

例如,对罗密欧说这意味着Romeo = Hamlet。就像片段9。

Factoid (是的,到达了另一个里程碑!)

该语言是为“语法分析”课程中的作业创建的-因此,作者没有创建SPL编译器。更多:SPL的作者似乎已经切断了与创作的联系,因为自2001年以来似乎没有对该语言进行任何修改...

长度31片段

Am I as horrid as a flirt-gill?

是的,我知道,它有点重复片段23,尽管在这里,我们正在将说话的“角色”与“调情with”(如果愿意的话if (Ophelia == -1))进行比较。事情是...

长度为32片段

If so, let us return to scene I.

...现在,我将介绍thenSPL的,条件跳转以及Shakesperian实现循环的方式。例如,您可以使Romeo假定该值0,在执行其他任务时增加其值,并在他达到10时停止,然后继续执行程序。

长度为33的摘要

If not, let us return to scene I.

提醒一下,如果测试的条件为false,我们可以继续前进到另一个场景。

长度34片段

Open your mind! Remember yourself.

连续两个指令,yippie!第一个读取一个字符,第二个将其压入另一个字符的内存堆栈。

长度35片段

Act I: Death!

Scene I: Oh, shit.

声明行为和场景的正确方法。高雅地添加艺术糊状。

长度36片段

Thou art as sweet as a summer's day!

换句话说,说“字符”将获得价值1-因为夏天的日子很愉快。

长度37片段

Art thou more cunning than the Ghost?

奥菲莉亚(Ophelia)向哈姆雷特(Hamlet)提出这个问题,将其翻译成一种不太可读的编程语言if (Hamlet > the Ghost)。是第23个摘要,是的-但它向您显示了不需要询问“字符”是否彼此更好:任何其他问题也可以解决。

长度38片段

[Enter the Ghost, Romeo and the Ghost]

是的,我两次调用“字符”-因为我想让程序给我一个错误。调用已经在舞台上的“字符”,或者告诉一个不存在的“字符”会对解析器/编译器造成极大的痛苦。

长度39片段

the sum of a fat lazy pig and yourself!

完整的指令看起来更好,我给你,但是...这是我们的第一个算术运算!这到底是什么意思?好吧,pig是一种肮脏的动物(虽然很美味),所以它等效于-1具有两个形容词,意思是fat lazy pigequals 2*2*(-1) = -4。但是呢yourself?它是反身代词,不是名称也不是形容词。好吧,请记住,SPL是基于“字符”之间的对话的;因此,yourself是指舞台上的另一个“字符”。因此,我们到达最后,发现“胖懒猪和你自己的总和”实际上是-4 + x

长度40片段

the sum of a squirrel and a white horse.

是的,还有另一个总和,但是这个总和比摘要39更简单。如果我的数学正确,这只是1 + 2- 3

Factoid (在这四十段艺术毛茸茸的片段之后还和我在一起吗?您应该得到奖赏。)

可以在此处下载SPL(1.2.1版)。

长度41片段

Juliet:
 Speak thy mind!

[Exit Romeo]

有时,“角色”只是在舞台上被调用才能改变其值-在实际游戏中,这将是非常奇怪的事情。无论如何,在这里,朱丽叶让她心爱的罗密欧(Romeo)打印出他的储值,然后退出舞台。

长度42片段

Speak YOUR mind! You are as bad as Hamlet!

一行中又有两条指令(我们可以有多个指令,但是代码段长度尚不允许);在这里,我们有一个“字符”,告诉另一个人输出其值并假定哈姆雷特具有的值。令人困惑?可能

长度为43片段

Am I as horrid as a half-witted flirt-gill?

朱丽叶问这并不意味着她有自卑感(尽管在现实生活中可能如此)。它只是另一个if,如代码片段23和37。哦,我差点忘了:转换为if (Juliet == -2)

长度为44片段

You are as evil as the square root of Romeo!

是的,平方根很邪恶,不是吗?无论如何,该指令很简单,足以理解其作用:将说出的“字符”归因于存储在罗密欧中的值的平方根。

长度为45片段

Hamlet:
 Art thou more cunning than the Ghost?

摘录37已正确地写上了说话的人。

长度46片段

the product of a rural town and my rich purse.

好的,无论如何,SPL可能是世界上唯一一种允许您用皮包繁衍城镇的语言。这意味着(2*1)*(2*1),如果我不太误解的话,它等于4

长度47片段

Romeo:
 Speak your mind.

Juliet:
 Speak YOUR mind!

我会告诉你的:这可能是历史上最奇怪的对话之一。但是,这是您选择一种奇怪的语言来展示时所得到的。简而言之,罗密欧与朱丽叶互相告诉对方要输出自己的价值观。

长度48片段

You lying fatherless useless half-witted coward!

直接翻译2*2*2*2*(-1)-16, 对?

长度49片段

Scene V: Closure.

Hamlet:
 Speak your mind!

[Exeunt]

如何在SPL中终止程序的示例。您可以为其专门声明一个场景(尽管不是必需的),然后Hamlet要求另一个“字符”输出它们的值,然后它们都退出舞台。是的,所有这些人都必须下台。

长度50片段

Othello, a young squire.
Lady Macbeth, an old fart.

在适当说明之前,请先进行更多“字符”演示。与往常一样,对编译器而言唯一重要的是Othelloand Lady Macbeth,因此其余的行都值得抢购...

还有一件事:“角色”不必彼此关联即可出现在SPL程序中-因此,您可以在同一戏剧中让Romeo,Othello和Hamlet在一起。

Factoid (这些东西有半个世纪了?Ph!在此之后,我想我会讨厌威廉·莎士比亚...)

之前提到并由SPL创作者开发的SPL到C转换器是基于FlexBison的

长度51片段

Othello:
 Recall your great dreams. Speak your mind!

(非常讨厌罗密欧,朱丽叶和哈姆雷特...让我们把奥赛罗带上来,换个零钱吧!)

Recall您可以猜到,这是关键。奥赛罗正在寻址的“字符”将从其堆栈中获取一个值,并假定该值,然后将其输出。

长度52片段

Thou art as pretty as the sum of thyself and my dog!

另外一笔。打哈欠。假设这是给哈姆雷特(Hamlet)的,意味着Hamlet = Hamlet + 1。或者Hamlet += 1。或者Hamlet++

长度53片段

Romeo:
 You are as vile as the sum of me and yourself!

嗯,是的,我之前忘记提到过:说话的“人物”可以按照自己的语言来提及自己。

长度54片段

Juliet:
 Is the sum of Romeo and me as good as nothing?

条件中包含的先前片段的另一个示例。所以我们这里是if (Romeo + Juliet == 0)

长度55片段

Juliet:
 You are as lovely as the sweetest reddest rose.

因此,在这里,朱丽叶称赞她正在与之交谈的“角色”(为了莎士比亚的缘故,假设是罗密欧),宣布他/她为4。是的,是另一种价值观的分配。

长度56片段

Othello:
 You lying fatherless useless half-witted coward!

片段48正确完成,带有“字符”。如果您懒得向上滚动(就像我想的那样),这意味着被侮辱的人收到的值为-16。

长度57片段

Romeo:
 If not, let us return to Act I. Recall thy riches!

我已经大致解释了条件如何在SPL上起作用。但是,需要进行更加内联的分析。我们else在这里没有:在每个实例中,在此示例中,如果条件失败,程序将返回到第一幕;但是如果是真的,它将继续执行下一条指令,即Recall-从堆栈弹出。

长度58片段

Romeo:
 You are as disgusting as the square root of Juliet!

抓取摘要44,并介绍如何呈现该指令。如果这是Romeo和Othello之间的对话,那么我们可以将其翻译为Java Othello = Math.sqrt(Juliet)

长度59片段

Othello:
 You are as vile as the sum of yourself and a toad!

好吧,如果奥赛罗正在与罗密欧交谈,那将等同于Romeo+(-1); Romeo--,简而言之。很基本吧?那就是您的SPL。

长度60片段

Is the quotient between the Ghost and me as good as nothing?

简而言之,if (The Ghost/Hamlet == 0)假设“我”属于哈姆雷特。

长度61片段

Thou art as handsome as the sum of yourself and my chihuahua!

一旦剥夺了单词和侮辱的层次,您会发现SPL几乎是基本的东西,没有很酷的功能和内容。因此,程序主体上有大量的算术函数。因此,如果这封信寄给朱丽叶,那就相当于Juliet++

长度为62片段

twice the difference between a mistletoe and a oozing blister!

是的,是的,还有更多的算术运算。大致来说,这62个SPL字节可以转换为2*(1-2*(-1))。这将是一种非常棒的高尔夫语言,对吗?对。

长度63片段

You lying stupid fatherless rotten stinking half-witted coward!

段48输出-16,这个人是等于-64: 2*2*2*2*2*2*(-1)

长度为64片段

your coward sorry little stuffed misused dusty oozing rotten sky

根据我对SPL的了解,这是完全合法的。您有很多侮辱性的形容词,它们沿用“正”名词。由于形容词是否为否定词(它们的唯一值是将其右边的数字乘以2)没有特别的区别,所以我们可以像这样一个完全愚蠢的句子。相当于256。因为2*2*2*2*2*2*2*2*1=256

长度65片段

You are nothing! You are as vile as the sum of thyself and a pig.

嗯,太讨厌了,不是吗?因此,我们在这里所拥有的等同于y=0; y=y+(-1);可能已经“推销”到了You are a pig!,但是。

长度66片段

You are as beautiful as the difference between Juliet and thyself.

那么,从你自己身上减去朱丽叶吧?这很容易解码:Romeo=Juliet-Romeo;,假设正在与罗密欧交谈。

长度67片段

Juliet:
 Am I better than you?

Romeo:
 If so, let us proceed to Act V.

大多数条件如何在SPL上起作用。您测试表达式,如果它是真实的(或者不是,请参见代码段33),则跳到程序的另一部分;否则,您将继续下一个句子。

长度68片段

The Ghost:
 You are as small as the sum of yourself and a stone wall!

是的,是的,我有点单调。但是SPL就是这样。如前所述,它的表达式是算术运算的混合体。因此,这是又一个增量-因为stone wall是中性的“名词”。

长度69片段

Thou art as disgusting as the difference between Othello and thyself!

除了总和,我们还是在两个字符之间进行了减法,即“黑白棋”和与之交谈的人。

长度70片段

You are as handsome as the sum of Romeo and his black lazy squirrel!

我们返回添加项,是的-叫我公式化,嘿。我们将此翻译为Romeo + 2*2*1

长度71片段

Scene I: Dialogues.

[Enter Juliet]

Othello:
 Speak your mind!

[Exit Juliet]

场景可以这么小。Juliet进入舞台,奥赛罗叫她输出自己的储值,然后她再次下台。

长度72片段

twice the difference between a mistletoe and an oozing infected blister!

另一种算术运算-因为SPL充满了它们。我们可以将其翻译为2*(1-2*2*(-1))

长度73片段

You are nothing! Remember me. Recall your unhappy story! Speak your mind!

连续四个指令?实际上,我为自己感到骄傲。无论如何,我们假设这是罗密欧与朱丽叶之间的对话(他正在讲话):这意味着朱丽叶的值从0开始;然后,朱丽叶(Juliet)将罗密欧(Romeo)的价值推入她的记忆库中,将其弹出并以输入的形式输出。简单吧?

长度74片段

You are as sweet as the sum of the sum of Romeo and his horse and his cat!

是的,是的,我知道无聊的例子。但这是X = (Romeo + 1) + 1

长度75片段

Is the remainder of the quotient between Othello and me as good as nothing?

好吧,这很简单。如果您的解码技能出现故障,则表示为if (Othello % X == 0)

长度76片段

Thou art as rich as the sum of thyself and my dog! Let us return to scene I.

从片段26前面带有表达式的跳转。一goto对SPL并不总是找到附近的情况下,也可以是这样的-而且,当然,这种类型的goto总会在动作或场景的末尾找到,因为后的指令将永远不会被编译/执行。第一条指令非常简单:x=x+1

长度77片段

[Exit Hamlet]

[Enter Romeo]

Juliet:
 Open your heart.

[Exit Juliet]

[Enter Hamlet]

所以,我们在舞台上有朱丽叶和哈姆雷特。但是我们需要罗密欧的价值。因此,为了使编译器免于头疼的麻烦,首先我们从舞台上删除了Hamlet(尽管可能是朱丽叶一个人去了),我们告诉罗密欧上台,朱丽叶给了他一条输出指令。号码(请参见摘要21的说明),然后罗密欧离开舞台,哈姆雷特回来。非常简单明了。

长度78片段

The Ghost:
 Speak thy mind.

Lady Macbeth:
 Listen to thy heart! Remember thyself.

因此,The Ghost(哈姆雷特的已故父亲)告诉Macbeth夫人输出她的价值,而她命令The Ghost读取一个数字并将其推入他的堆栈。


32
这非常有趣,而且您的个人资料图片非常适合,他看起来就像我想象的SPL程序员的样子。
演员

3
@overactor我不知道被侮辱还是被比作Gumby感到自豪。^ _ ^
Rodolfo Dias 2015年

9
奇怪的是,这里的例子并不是最晦涩难懂……似乎与“最不实际”联系在一起。
HRRambler 2015年

6
ROFL这里+1助您一臂之力-再次违反Rodolfo!
HRRambler 2015年

3
@RodolfoDias您可以开始。我在等着他们。您有120票赞成票。
ghosts_in_the_code 2015年

176

皮耶特

类固醇

Piet是一种编程语言,其中的源代码由图像组成。程序流程从左上像素开始,并在像素和像素组之间在图像周围移动,直到终止。

为了清晰起见,Piet程序通常以放大版本显示。在这种情况下,该术语codel用于描述与源图像中的单个像素相对应的一组同色像素。

对于此挑战,由于Piet不使用字符,因此示例程序将使用每个表决一个编解码器。

1个编解码器

1个编解码器

这是一个有效的程序,它不执行任何操作并终止。控制流从左上角(仅)像素开始,没有出路,从而结束了程序。

在这种情况下,像素可以是任何颜色,以获得完全相同的效果。

2个密码

2个密码

这将连续从stdin读取字符并保持其unicode值的运行总计(尽管对此总计未做任何操作,并且不会显示)。

程序流在两个编解码器之间来回移动,因为每个编解码器的唯一出路是进入另一个编解码器。通过从两个编解码器或区域移动到另一个编解码器或区域,来执行piet中的命令,具体取决于这两个区域的色相和亮度的差异。的input是移动左到右指令,然后add是从右到左。在第一个add命令上,由于堆栈上只有一个值,因此什么也不会发生,并且规范说没有足够可用值的命令将被忽略。

该程序是一个永无休止的循环,因为大多数piet程序的尺寸都非常小,因为它至少需要一些代码才能正确地“捕获”程序流并结束它。

3个密码

3个密码

这是一个基本的回显型程序,它将一次从stdin读取一个字符并将其打印到stdout。

同样,这是一个无限循环。该程序通过从左到右移动开始,input然后执行output。只要有可能,程序将继续沿相同方向流动。在浅绿色的编解码器上,唯一的出口就是开始以另一种方式向后移动。当从右向左移动时,它会尝试执行subtractadd命令,但是堆栈为空,因此它们变为无操作。

4个密码

4个密码

无限期地输出2到标准输出。

从功能上来说,这并不是一个特别有趣的程序,但是现在我们终于有了复合数量的代码,我们可以展示比从左到右略微高级的流程。当程序流尝试退出编解码器时,它将首先尝试当前方向。如果无法(在这种情况下,由于图像的边缘),它将顺时针旋转90度并尝试再次退出。在这种情况下,程序一次绕顺时针旋转1个编解码器,将push1两次写入堆栈,add将它们在一起,然后output得到结果。

5个密码

5个密码

一次一次从stdin重复读取一个字符,并跟踪其unicode值的总和。

这本质上与2编解码器版本具有相同的功能,但是这个挑战在于展示语言,而关于piet的一件很酷的事情是如何拥有外观相同的图片来做同样的事情。

在这里,我们第一次看到白色编码,它允许程序流在其上滑动而无需执行指令。洋红色和蓝色代码在这里完成所有工作。从蓝色到红色行不通,因为它穿过中间的白色编码。2个红色的push数字只是将数字1放到堆栈上,pop当它从左到右然后从右到左穿过它们,然后穿过白色编码时,它会退避,因此不执行任何指令。

6个密码

6个密码

同样,以不同的外观重复早期的功能。这是另一个回声程序,它一次从stdin到stdout读取一个字符。

在这里,我们看到了我们的第一个黑色编码。程序流无法输入黑色编码,因此从右上角的浅洋红色编码中,由于图像边缘,程序将无法正确退出,由于黑色编码而无法退出,然后向左弹回红色编码。蓝色和绿色编码是纯装饰性的,程序将永远不会输入它们。

7个密码

7个密码

另一个具有不同外观的回声程序。

在这里,我们看到第一个大于大小1的编解码块。在Piet中,相同颜色的任何连续编解码块都被视为一个块。除了执行push指令时,块的大小无关紧要,因此该程序与3-codel版本完全一样,只是颜色不同。

8个编码

8个编码

重复从stdin读取数字并将平方输出到stdout。

控制流是基本的顺时针模式,就像在4-codel程序中一样。从左上角开始,为了操作是inputduplicate(推堆栈顶部值的额外拷贝到堆栈)multiplyoutput。然后,push将值1放到堆栈上,滑过白色,因此不执行任何命令,然后pop在从左下编码转换为左上编码时,从堆栈中减去1。这会将其返回到具有空堆栈的程序的开头,然后重复执行。

9个密码

9个密码

加1 + 2 = 3,然后终止。

现在,我们有了一个在两个维度上都具有大于2个编解码器的程序,我们最终可以建立一个区域来捕获程序并结束该程序,而不是永远循环。从红色编码转换到深红色区域的第一个操作是push1,然后程序旋转并向下流入中间的浅红色编码,并且pushes值为2。执行从浅红色到浅黄色的流一项add操作。底部的浅黄色条导致程序结束,因为所有角都被挡住了,所以它无法流出。


1高​​和2高的程序很快就变得丑陋和无趣,因此从这一点开始,我将重点关注在每个方向上至少允许几个编解码器的数字。

12个密码

12个密码

最终,一个程序执行了可能被认为有用的事情(尽管仍然有些困难)。依次从stdin读取2个数字,然后输出它们的总和,然后重复进行。

程序横跨4个横杠perfoming 2流到左到右inputs后跟一个add命令。然后,它移至右下编码,并执行output,然后跨白色区域向左返回起点。

这本可以用8个编解码器完成的,但是由于我们有多余的空间,因此我们可以制作出一些受旧的无信号电视显示器启发的产品。

15条密码

15条密码

从stdin读取一个数字并输出其平方。

这使用了一些技巧来使实际执行某些操作的程序具有一些对称外观。利用最下面这两个红色阴影看起来(至少对我而言)这一事实,最左端的红色条与其他编码在底部编解码器上具有不同的颜色。程序将从较浅的红色区域向右移动到浅蓝色编码,然后直接越过程序的中间移动到被捕获的右侧的浅绿色。它执行inputduplicatemultiply,和output操作。

较暗的红色编码和中间列顶部和底部的中号绿色编码均具有装饰性,程序将永远无法访问它们。

20个密码

20个密码

从stdin读取数字,直到读取为0,这时它将输出所有输入数字的总和,然后退出。

我们最终有足够的空间以操作的形式进行控制流pointer。顶部的4个编解码器执行inputduplicatenot操作,然后执行另一个not操作,从右上角的洋红色移动到其下方的2个编解码器黄色。该not操作将最高值弹出堆栈,如果最高值是0,则将其压入1,否则将其压入1。因此,双精度数not将用1替换任何非零值。从黄色条向下移动到深蓝色将执行pointer操作,该操作将栈顶值弹出堆栈,并沿顺时针方向移动方向指针多次。

如果最高值为1(即我们未输入零),则方向指针将指向左侧,移至洋红色编码,以进行add操作(由于堆栈上只有一个值,首次将其忽略),并且然后通过白色回到程序的开始。

如果在指针操作时堆栈的最高值为零,则方向指针将保持不变,并且程序将继续向下运行。移入较浅的蓝色带将使pop从堆栈中输入的0消失,仅保留累加数字的总和。移到底部的青色栏将output得出该总和,然后由于捕获了程序流而结束。

25个密码

25个密码

倒数!从stdin读取一个数字,然后打印倒数到1以一次输出一个数字。例如,如果读取5,将打印54321。

从青色到黄色的第一个操作是input。然后黄色是程序“循环”开始的地方。黄色>洋红色>蓝色是a,duplicate然后是output,因此它将在堆栈上打印最高值,但保留一份副本。向下移动的右侧,我们push值1到堆栈然后执行subtraction,由1减小我们的输入值接下来是duplicatenot和另一个not从光品红朝着右下到深黄色它旁边。这与上一个程序相同的零/非零检查。向左移动进入浅蓝色编解码器将执行一个pointer操作,如果完成,则将向左移动至深青色以结束程序,或者向上移动至黄色以在没有初始输入但原始值减小的情况下重新启动循环加1。

所有三个红色代码均具有装饰性,并且可以是任何颜色。

30个密码

30个密码

斐波那契发电机。将斐波那契数列的术语输出到stdout并不会停止。

这是roll运算符的首次引入,也是第一次与push运算符一起使用大于1的区域大小将特定值存储到堆栈中。

一如既往地从左上角开始向右移动。由于斐波那契数列以两个1开头,因此前2个运算push将1 运算到堆栈上,然后执行1 运算output,但是主程序循环只会打印1次。然后再将push2个1s放到堆栈中,以右上角的深洋红色结束,开始主程序循环。

向下移动我们duplicateoutput打印出序列的下一项,然后duplicate再次获得当前序列值的副本。在底部向左移动将执行2个push操作。由于右下角的浅红色区域的大小为3个编解码器,因此第一个push将3推入堆栈,而不是1。

向上移动到浅蓝色是一项roll操作。这将从堆栈中弹出前2个值,并执行等于第一个弹出值的滚动数,直到达到与第二个弹出值相等的深度。在这种情况下,它将执行1次滚动到3的深度。一次滚动到深度n将获取堆栈的最大值(我们重复的当前值)并将其埋入n深处。我们的堆栈现在只有3个深,因此它将把最高值埋在底部。

再次向上移动将执行一个add操作,将当前序列值与前一个序列值相加。现在,我们的堆栈在顶部具有下一个(新的当前)序列值,在其下方具有最后一个值。现在,程序将白色右移到深洋红色以再次开始循环。

从未使用中间的黄色图案。

54条密码

54条密码

打印“嗨!” 到标准输出

并不是特别长的消息,但是用piet打印需要占用大量空间。通过使用unicode值进行打印,并通过使用要退出的区域的大小将整数压入堆栈。由于针对此挑战的代码数量非常有限,因此我们使用一些数学方法来达到所需的可打印范围。

该程序从push左侧青色区域的5 开始。从这里开始,它沿着顶部流动,执行6次duplicate操作,以5s为堆填充堆栈。接下来是push1,subtract将4放在堆栈顶部,然后进行2个multiply运算以将4 * 5 * 5 = 100放在堆栈顶部。然后duplicate2 100秒。

现在程序从黑色开始反弹,并开始从底部向左工作。Push3和2的运算,然后a roll将2 100埋在5之下。下一个是push1,减去后加,得到100 + 5-1 = 104在堆栈顶部,即unicode“ h”。接下来的2个操作为push1,pointer绕到拐角处并开始沿中间位置右移,然后output打印“ h”。

接下来是add堆栈顶部的100 + 5 = 105,并output打印“ i”。现在,堆栈包含两个5。Push1, addmultiply给出(1 + 5)* 5 = 30。最后是push3和add33,最后output是“!”。然后,程序在剩余的空白区域中右移,以右侧的绿色结尾。


5
嗯,是的,正在等待:)
Sp3000

与2D角色语言有什么不同?这只是传达单元格值的方式。
JDługosz

25
@jdlugosz,当您深入了解它时,许多深奥的编程语言只是一些基本的堆栈操作命令,它们以独特的方式对命令进行编码。我个人认为将它们编码为图像是一个好主意。
Spencer 2015年

13
如果我们在谈论功能等效性,您可以问:“与图灵机有何不同?” 但随后您可以对猫,木星或其他任何语言发出相同的问题……
trichoplax

3
9个编解码器示例看起来像一个迷你手球。真好
The_Basset_Hound

155

> <>(鱼)

(注意:某些代码段是在以前的代码段的基础上构建的,因此与大多数答案不同,我决定将其从最早到最新。)

类固醇:

像Befunge一样,> <>是基于堆栈的2D语言。这意味着指令不会像大多数传统语言那样线性执行-程序流可以向上,向下,向左或向右!

长度1片段:

X

X是> <>中的无效命令,因此将显示错误消息something smells fishy...。实际上,这是> <>中的唯一错误消息,无论原因是被零除还是试图弹出空堆栈。

长度2片段:

1n

> <>中的程序流从左上方开始,最初是向右。1将1压入堆栈,然后将其n打印为数字(而不是ASCII字符)。但是> <>程序是环形的,这意味着指令指针在到达行尾时会回绕。因此,在n我们开始包装后,按1,打印,然后开始包装,按1,打印...,我们将1永远打印s!

长度3片段:

"o;

"是字符串解析,o输出为ASCII字符并;终止程序。但是该程序实际上整体上是做什么的?

好吧,首先我们开始字符串解析,将看到的每个字符推入堆栈,直到找到结束符"。我们先按o,然后按;... ,然后将指令指针包装回起点。但是现在我们在进行操作,"因此我们停止了字符串解析,最后我们像平常一样执行o;,以打印堆栈的顶部(;)并终止。

是的,我们只是使用相同的引号char来开始和结束字符串!

长度4片段:

42n;

根据到目前为止所看到的内容,您可能希望将其推入42,然后将其输出为数字然后终止。但是> <>中的所有指令都是单字符,因此实际上是压入4和2,然后将堆栈的顶部输出为数字(仅2)并终止。

长度5片段:

<v
;>

请记住,> <>是2D语言。这意味着必须有改变程序流程方向的方法!

像Befunge一样,一种方法是通过箭头>^v<。为了说明它们如何工作,让我们看一下上面的程序:

  • 程序流程最初是向右的
  • < 使程序向左流动-我们离开左侧并环绕到 v
  • v 使程序向下流动-我们进入 >
  • > 使程序向右流动-我们向右走,然后绕到 ;
  • 最后,我们终止。

长度6片段:

";"00p

> <>的另一个很酷的功能是它具有自反性-该程序可以即时修改自己的源代码!

在这里,我们推一个;,然后是两个零。p然后弹出顶部三个元素yxvy作为堆栈的顶部)和地方v的位置处x,y。换句话说,p该程序中的将分号放在该位置0,0,将代码转换为;;"00p。然后,这将使程序终止,因为指令指针现在回绕并执行新放置的;

长度为7的摘要:

\7*n;
6

像Befunge,> <>还具有反射镜(\/|_#),其反映程序流的方向。所以我们在这里:

  • 从右边开始,但\反映出我们向下
  • 推6并包好
  • 撞到的背面\并向右反射
  • 推7
  • 乘以堆栈的前两个
  • 输出并终止

通过_镜子水平移动或通过镜子垂直移动|是禁止操作的。

长度8片段:

"r00g>o<

如果允许抛出错误,那可能是最简单的> <>奎因。这里的两个新指令是:

  • r:反转堆栈
  • g:获取—弹出yx然后将处的字符压入x,y堆栈(对应于p

使用以前的字符串包装技巧,程序首先按入,r00g>o<然后再次击中第一个引号。然后将堆栈反转,得到<o>g00r。之后,我们推的char 0,0",给<o>g00r"。最后,我们将a捕获o在两个箭头之间,输出堆栈的顶部,直到没有剩余任何东西,然后得到一个错误。

长度9片段:

x0\>
\1n>

x(小写)在随机方向上移动指令指针,程序通过永久打印随机位来展示此功能。尝试按照箭头和镜子确定其工作原理!(不要忘记检查所有四个方向,包括向上和向左)

长度10片段:

;a comment

> <>中没有注释语法-不需要注释语法。只要在任何地方写下您想要的内容,并确保它不会作为代码执行即可!

长度11片段:

1!X2!X+!Xn;

!是一个跳过说明的蹦床。与条件条件蹦床一起使用时?,它特别有用,条件蹦床会弹出栈顶并在弹出的元素为非零时执行下一条指令。稍后我们将了解其工作原理。

上面的代码通过跳过Xs来打印3 ,仅执行1! 2! +! n;

长度为12的摘要:

01v
ao>:@+:n

从第二个开始一直打印Fibonacci编号1,每行一个。新命令是:

  • a:按下10,这是换行所需的。a-f分别按10到15。
  • ::堆栈顶部重复
  • @:旋转堆栈的前三个元素,例如[5 4 3 2 1] -> [5 4 1 3 2]

跟踪前几次迭代:

在此处输入图片说明

长度13片段:

i:d=?v
l?!;o>

一个“ tac”程序,它读入一行输入并将其输出反转。感谢@tomsmeding的摘录。

=弹出顶部的两个元素,如果相等则按1,否则按0。第一行一直保持输入状态,直到找到ASCII字符13(回车)为止,然后移至第二行。

l?!;o循环是在> <>一个重要的构建体,其输出整个堆叠。不同于>o<,它不会引起任何错误。它是这样工作的:

  • l 推栈的长度
  • 我们用以下方法检查长度?
    • 如果长度不为零,则执行下一条指令!,跳过;
    • 如果长度零,那么我们不执行!和终止因;

请注意,直到您按下回车键,才有输出。

长度14片段:

32.

   X67*n;

除了改变程序流程的方向,您实际上还可以将指令指针移动到任何您喜欢的位置!

.弹出yx并将指令指针传送到x,y,保持方向。但是请注意,您需要在要移动的位置之前移到一个正方形-在执行下一条指令之前更新指令指针。因此,这里的指令指针落在invalid上X,但由于指针6在继续执行之前移到了上,所以一切都很好。

.可以将大多数> <>程序转换为单行程序,但是为什么要失去2D的乐趣?:)

长度15片段:

01+:aa*=?;:nao!

将数字打印099,每行一个。该程序演示了!蹦床的巧妙用法-确保将初始0推入一次。

长度16片段:

"r00g!;oooooooo|

esolang页面上的quine启发,不会出错的适当quine 。

如果您想知道如何修改先前的quine(代码段8),以免导致错误并想到“为什么我不只是添加大量o指令?”,那么您可能会意识到,每o添加一次,您需要输出另一个o!此提篮通过在|镜子末端放置一个镜子来巧妙地解决了这个问题,每个镜子o可以使用两次

如果我们切换到单引号(也用于字符串解析),则不使用的替代quine g

'r3d*!;oooooooo|

长度17片段:

b2,63,.

   17,n;

我们有加法(+),减法(-),乘法(*),模(%)...但是除法呢?它在那里,但是由于/已经是一个镜像,所以已经为分区分配了,符号。有趣的是,除法是浮点除法,而不是整数除法!

上面的程序尝试跳到来探索一些未定义的行为11/2, 6/3。在Python的intepreter似乎没关系,如果第一个坐标不是整数(尽管它跳到错误的地方),但扼流圈如果第二是没有的。

长度为18的摘要:

123456${{$}nnnnnn;

我们已经看到了r哪个使堆栈反向,@哪个使顶部三个元素旋转。以下是一些在堆栈上移动元素的命令:

  • $:交换前两个元素
  • {:向左移动整个堆栈
  • }:将整个堆栈右移

为了显示其工作原理,这是程序跟踪:

123456 ------> 123465 ------> 234651 ------> 346512 ------> 346521 ------> 134652
       $ Swap        { L shift      { L shift       $ Swap        } R shift

然后我们输出,给出256431

长度为19的摘要:

"reward"4[roooo]oo;

到目前为止,我一直在说“堆栈”,“堆栈” ...

尽管大多数程序仅使用一个堆栈,但> <>实际上可以具有多个堆栈!以下是相关说明:

  • [:弹出x并将顶部x元素移动到新堆栈
  • ]:删除当前堆栈,并将其值移动到基础堆栈。

这是上述程序的跟踪:

       [r e w a r d]       Push "reward"
4[     [r e] [w a r d]     Move four elements to a new stack
r      [r e] [d r a w]     Reverse the current stack
oooo   [r e] []            Output "ward"
]      [r e]               Remove the current stack, no values to move
oo     []                  Output "er", giving "warder" altogether

请注意,由于堆栈具有“先进先出”的性质,因此只需简单地推入reward然后再输出,oooooo就可以打印drawer出来。

长度为20的摘要:

aa*5+\
7a*2+\
oo;  \

> <>的一个鲜为人知的功能是,像Python一样,在许多情况下,反斜杠可用于行继续。*

上面的代码在功能上与

aa*5+7a*2+oo;

*免责声明:之所以可行,可能是因为完全不同的原因

长度22片段:

1&fv ;n&<
&1->:0=?^:&*

除堆栈外,> <>还具有寄存器(每个堆栈一个),可用于存储值。&第一次调用会将堆栈的最高值移至寄存器,然后&再次执行将其移回。当累加一个值(例如和和阶乘)时,这可能非常有用。

上面的程序计算f(15)的阶乘,打印1307674368000。这是f替换为的跟踪4

在此处输入图片说明

长度为24的摘要:

"Hello, World!"rl?!;of0.

我们有足够的字符供大家喜爱的程序使用!在这里,我们将.传送器用于输出回路。

长度25片段:

0i:0(?v$a*$"0"-+!
   ;n~<

不幸的是,> <>一次只能从STDIN读取一个字符,这使得在数字读取中有些棘手。对于由数字0-9组成的输入,此程序实质上是atoi,它将一串数字从STDIN转换为堆栈上的数字(然后打印)。

另一个需要注意的是,在EOF上,i将-1压入堆栈。通过使用(或“小于” 与0比较,可以轻松检查EOF 。

此代码段还使用~,弹出并丢弃堆栈的顶部元素。

长度为33的摘要:

i>:nao:1=?;\
 ^  ,2v?%2:/
 ^+1*3<

到目前为止,大多数片段还是相对线性的,或者仅仅是展示> <>功能的简单示例。现在,我举一个例子,突出显示使用布局合理的程序在> <>中可视化程序流是多么容易。

该程序读取一个ASCII字符,并3x+1在其代码点上运行算法(在> <>中,字符基本上是整数)。算法的每一步都将被打印,直到我们达到1。

这是使用输入a(代码点97)进行的前几次迭代的跟踪:

在此处输入图片说明

长度44片段:

a&>i:0(?v"+"$\
/&^?=0l< "a*"/
\:1+&2p/\0
n
;

我不觉得我已经完成了p命令正义,只在代码片段6中一直使用了一次,所以这里有一个不同的atoi函数。这个有什么好玩的?程序读取输入时会写出计算数字所需的表达式

因此,对于like这样的输入573,在读取完所有字符后,第三行的末尾将看起来像\0a*5+a*7+a*3+,其值为573!

再次,输入应仅是数字。在此处跟踪GIF

长度74片段:

>i:'A'(?v:'N'(?v:'['(?v\
  :'a'(?v:'n'(?v:'{'(?v\
^      o<    +d<  -d-d<o

如果您设法到达这里,那么当我说这是一个非常易读的ROT13程序时,您可能会同意我的看法。鉴于一个char c1,我们发现的第一个字符c2AN[an{,这样c1 < c2,然后申请加入/减去适当的偏移d(13)。请注意,[{是分别在Z和之后的字符z

在控制台中进行尝试,然后观察键入时字母的变化!

(您也可以通过管道输入,但是由于我缺少EOF检查,:0(?;因此当尝试将-1打印为字符时,它将停止并显示错误)


13个代码段的想法:i:d=?v NEWLINE o;!?l<-向后打印输入行
断言

12
希望我能多投

6
+1用于从顶部开始和向下(也因为阅读很有趣)。
mbomb007

5
@ mbomb007遗憾的是,订单不能左右移动并环绕到页面底部:P
krs013 2015年

如果您something smells fishy...在下一行写的话,您的长度为8的代码段将是一个真正的担子。
wizzwizz4 2016年

148

C – 编辑

感谢您的投票!与其他语言相比,它们只能以有限的字节数进行处理,因此C语言看起来过时,繁琐且过于依赖开发人员。从许多方面讲,它是:具有自动内存管理功能的脚本化和高级语言比C具有更大的表现力和更快的生产速度。

那么为什么要使用功能C?

所有这些脚本语言背后的隐藏秘密是,解释器可能是用C(或更近期的C ++或Java)编写的。最初的C ++编译器实际上已编译为C代码。实际上,在没有直接编译器市场之前,编写编译器生成C然后进行编译通常会更具成本效益。

如果您在非常小的平台上工作,甚至可能没有可用的操作系统,那么您很可能都在C语言中工作。这些天,几乎每个设备都嵌入了微控制器,无疑是用C语言编写的。小而快速,C是必经之路。(还有福斯,对于受虐狂。)

知道C可以使您尽可能地接近金属,而无需进入汇编器,并用其他语言为您提供帮助。您有个好主意,C ++虚函数可能如何工作。您知道在用PHP编写这些按值传递递归函数时,在内部它在进行大量内存分配和复制,因此您本能地尝试按引用传递。回调和引用不会吓坏C开发人员,但是Haskell可能会这么做。

正如Kernighan和Ritchie在经典的C编程语言(第二版)的序言中提到的那样,C并不是一门大语言,也不是一本好书。我正在尝试遵循以下建议:如果可能,示例应承担两倍,三倍或更多的职责。

所有的代码片段至少可以自己编译。那些可链接的和可执行的是这样表示的。我知道这不是必需条件,但是它比尝试解释使任何代码段正常工作所需的框架要简单。

我还尝试确保每个代码段都尽可能短,以便我不会引入多余的空格以填充一定的长度。如果代码缩进,则缩进不包括在长度中,每一行仅包含一个字符。

类固醇

C岩。

长度为0的代码段

世界上最短的自我复制程序http://www.ioccc.org/1994/smr.hint

长度1片段

;

C区分编译和链接。C语言中的许多实体只是稍后进行编译和链接-一个示例是所有静态和动态库。

仅包括其他实体,它们本身不会生成任何代码。

上面的分号一定会编译成目标代码,什么也不做!

长度2片段

x;

作为一种较旧的编程语言,C经过了多次迭代。最早的广泛使用是由Kernighan和Ritchie开发的,缩写为K&R。如果您未明确提供代码,则K&R C会对代码做出很多假设。

特别是,在K&R C中,假定上面的代码是一个x初始化为0 的全局整数。在K&R模式下对其进行编译将生成一个目标文件,该文件提供任何与该变量链接的程序以供使用。

长度3片段

??/

C如此广泛,以至于它需要为不具有它使用的所有字符的系统提供兼容性功能。上面是反斜杠的三元组,在C中用作行继续符。上面的代码将会编译,可能会发出警告,提示后面没有一行。

在C语言中,一种常见的文化是忽略编译警告,并且在构建大型代码库时,总是会有一些或更多警告。

长度4片段

f();

再次使用K&R,以上内容在编译时“填写”是指“存在一个具有全局链接的函数f,稍后将提供该函数,该函数采用固定但未指定的参数数量并返回整数”。

请注意此与之间的根本区别f;

长度5片段

s="";

K&R C以真正的宽容而著称。编译后,此代码将为s全局链接提供一个整数,该整数将初始化为空字符串的起始地址(我认为)。如果整数不足够容纳地址,K&R会悄悄地处理所有强制,包括截断。

正是这种结构产生了许多难以发现的错误,并为IOCCC比赛提供了很多启发。

长度6片段

o=042;

甚至还有一些古老的计时器,立即数前加0表示后面的数字以八进制为底。上面的代码在编译后将提供一个o用于全局链接的整数,该整数初始化为十进制34。

C的这一功能已吸引了许多开发人员,他们努力增加自己的数字,以使他们排列得井井有条!

长度7片段

f(){f;}

上面的代码是带有主体的函数。但是它是做什么的呢?它检索函数的地址,并且不执行任何操作!通常,函数将返回的内容是不确定的。这样的荒谬代码通常可以在没有警告的情况下进行编译。

长度8片段

main(){}

这代表了C中最短的可编译和可链接代码。尽管在C的现代版本中,通常不能隐式定义函数,但由于历史原因,此限制已被放宽main

程序的奇迹,除了返回0之外什么都不做,将编译为不可忽略的大小,并链接到各种C运行时例程中。您可以将详细程度设置为full进行编译和链接,以了解幕后情况。

长度9片段

#define Z

C头文件的主体是#define预处理器指令。C程序在各个阶段进行编译,并且在这些阶段之一中,这些定义将替换为其实际值。

当缺少参数时,C表示1,因此以上代码将替代源代码中使用的1任何Z位置。

通常将上述内容放入头文件中,并#include根据需要放入d中。

长度10片段

enum{P,Q};

enum关键字提供了有时类型安全的方式来定义一系列常量。像定义一样,它们通常用在头文件中。如果包含上述代码,则将其定义P为0和Q1 的整数。

长度11片段

volatile v;

volatile关键字是让编译器知道一个变量可以通过其他代理来改变,而不是作出假设,它仍将访问之间不变。

长度12片段

#pragma once

#pragma once 是一个非标准但受到广泛支持的预处理器指令,用于指示当前源文件在单个编译中仅包含一次。

传统且完全受支持的技术是使用#include带有添加代码和可能发生名称冲突的缺点的防护措施。

长度13片段

w(){for(;;);}

C语言中有许多约定,其中之一是如何表示无限循环。在这种情况下,for(;;)表示没有初始化,没有退出检查,默认为1,表示true-即不中断,也没有循环代码。

有时,可以在()和内完成所有操作,而循环本身不需要任何主体。在这种情况下,在末尾添加一个虚拟分号。

在上面的代码中,当编译时,它将提供一个函数,该函数将进入紧密的繁忙循环-软件设计中的禁忌之一,并且永远不会返回。

长度14片段

int a[]={1,2};

C中的数组不需要指定的长度。空方括号[]告诉编译器“自己弄清楚它”。但是,在C语言中,与其他语言不同,没有内置的方法可以防止在这些范围之外访问数组,从而导致C语言广为人知的“脚踏实地”的比喻。

上面的代码在编译时将提供一个a由1和2初始化的两个整数的全局可变数组。

长度15片段

const long k=7;

所述constspecifer是后来除了C来自C ++借来的。常见的面试问题是“将变量定义为volatile const吗?”。const随着enuminline旨在减少对依赖#define它具有类型安全问题。

长度16片段

extern void **q;

extern用于指示在其他位置声明了变量。该void *类型是C语言中的标准泛型类型,这意味着不需要在赋值语句中将其显式转换为强制类型。所述**操纵基因序列指指针的指针,这往往吹新手心中,但是完全有效的,并经常使用C.

长度17片段

double d=4/3-1/3;

如果要打印以上内容,结果将是一个,那么您会认为,超级!更改为double d=4/3-2/3;,答案是什么?还是一个!C正在使用整数算术来计算4/3→1和2/3→0,以及1-0→1!

长度18片段

main(){puts("!");}

最终,我们得到了一些实际起作用的代码!puts是C高尔夫球手的最爱,因为它不需要使用头文件。

puts还将在输出中添加换行符。相反,其对应对象gets将删除换行符。gets除非在非常可控制的情况下,否则永远不要使用它-它无法防止缓冲区溢出,并且是许多漏洞利用的根本原因。

长度19片段

#include <stdlib.h>

头文件的包含通常是开发人员的个人签名。许多包括libio无论是否需要它们。某些命令对头文件进行排序,因此长度增加或减少。大多数放在<>前面""。我个人曾在助教期间使用此签名来检查学生是否作弊:相同的标头签名?细看!

长度为20片段

char*p=(char*)0x300;

C被设计用于非常低级的基础平台。在某些情况下,您可能需要直接访问特殊的内存映射端口。

在上面的代码中,端口的地址定义为十六进制的300。您可以通过使用来访问端口的值*p,例如*p=0xff;打开所有位或v=*p;检索当前值。

长度21片段

int w=sizeof(double);

sizeof运营商提供的类型的字节大小。使用变量名时,不需要括号double d;int w=sizeof d;

长度22片段

asm("xorl %ecx,%ecx");

asm编译器定义了如何使用。上面是英特尔平台上Linux gcc内联代码的示例。

最初的Unix在汇编器中只占很小的一部分,但却不可忽略。即使在今天,如果速度是最主要的考虑因素,而绝对不是可移植性,那么您会发现它已被使用。

在兼容的系统上,上面的代码将被编译,并且实际上是孤立的汇编指令,没有常规的访问方法!BTW xor R,R是一种常见的汇编语言惯用法,用于快速清除寄存器。

长度23片段

union u{char c;int i;};

A union将为最大元素提供至少足够的空间。您可能会看到它与void *在某些库中提供常见的“不透明”类型一起使用。在这种情况下,联合通常将是较大结构的一部分,并且该结构具有标识联合类型的字段。

长度为24片段

/*INTS*/int i,j,k;//INTS

原始的C注释以分隔/* comment */,并// comment to end of line从C ++ 借用了格式。

长度25片段

int main(void){return 1;}

这是上面长度为8的代码段的更合规版本。指定了返回类型和函数类型,并且具有显式返回的值。

C中的约定是使用0成功或1失败的返回值,或者如果您要严格遵循EXIT_SUCCESSEXIT_FAILURE如中定义,则使用返回值stdlib.h

长度26片段

typedef struct{int x,y;}P;

typedef特别有用typedef struct。用现代术语来说,您可以将其称为“对象定向光”。

包括上述内容之后,该代码即可P在声明和函数中用作常规类型,并进行完整的类型检查。但是与C ++不同,您不能定义+,*或<<之类的运算符,因此不能定义“ object-orientation-light”。

长度27片段

#define C(x,y)(((x)+1)*(y))

C具有方便的宏#define语法。

常见的新手错误是省略了内部和/或外部方括号,从而导致难以发现的运算符优先级错误。

长度28片段

struct f{int s:1,e:8,m:23;};

C可以显式定义可以像任何整数一样进行分配,读取和操作的位域。

上面是IEEE单宽度浮点数据结构的近似值。

长度36片段

f(unsigned x){return!!x&!(x&(x-1));}

在许多语言中,您无需关心数字的表示方式。在C语言中,您需要密切注意其内部表示形式。

我能想到的最好的例子是确定整数是否是两个{1、2、4、8,...}的幂。那些不熟悉C的人会为O(log(n))运行时进行循环和移位以及各种形式的工作,这不错,但是上面的函数将在O(1)运行时做同样的事情。我将其保留为练习,以供读者确认它是否有效,但是它确实可以...

!!约定通常用于强制将非零和零的整数分别强制为1和0。许多C开发人员喜欢使用这些技巧(通常与那些重视代码清晰性的人有些矛盾)。

超级敏锐的C开发人员可以确认上述内容将在1互补和签名硬件上工作。对于那些想知道的人,您几乎可以肯定现在正在使用二进制补码硬件。只有真正幸运的人(或不幸的人,取决于您的观点)才需要担心!

长度48片段

#include<complex.h>
double complex c=3.0+I*4.0;

C99包括对复数的支持。从代码中可以看到,它采用实型修饰符的形式。您也可以在int complex c=3+I*4;内部使用它强制为浮点类型。上面的代码将使用编译在gcc中gcc -std=c99 -c length-48.c

如果要查看更多内部信息,请尝试使用-E开关进行编译。对于我的gcc版本,上面的声明变为double _Complex c=3.0+(__extension__ 1.0iF)*4.0;。请注意,复杂类型是语言的重要补充,而不仅仅是一些廉价的宏。

这只是一个预告片,当我们使用超过125个字符时,便可以开始使用复数了。

长度51片段

#include <math.h>
main(){double d=sqrt(sin(3.2));}

由于各种原因,C不会自动链接到标准数学函数,例如sin,cos,tan,sqrt等。因此,如果使用了它们但未链接,则开发人员将看到未定义的链接器错误。'sqrt'或其他错误。

在gcc中,以上代码将使用进行编译和链接gcc length-51.c -lm

注意sin(3.2)将返回一个负数,其平方根在实际域中不合法。在C语言中,将NaN返回一个特殊值来指示此错误,程序可以随意忽略该错误!

在C99中,有许多新的异常处理函数可为这些数学错误提供非常安全且细粒度的控制,几乎没有人使用!

长度63片段

static int w;static int X(int x){static int s=0;s^=x;return s;}

或更合理地格式化:

static int w;
static int X(int x)
{
    static int s=7;
    s^=x;
    return s;
}

您可能已经猜到了,这全都与static在C语言中具有多个含义的关键字有关。

在前两种情况下,static告诉编译器在此文件或编译单元之外看不到整数w和函数X,即它们是内部的。

这些函数无意在外部调用,因此它们可能不会检查参数的有效性,也可能会弯腰。因为他们有内部的范围,你可以重新定义wX其他文件,它们通常是分开的。

在最后一种情况下,static指示整数s在函数调用之间保留其值。第一次X调用s将是它的初始值7,当它与异或时x,将保留新值。

在内部,尽管它依赖于实现,但通常的内存组织是s驻留在堆上,特别是初始化的内存,而参数x驻留在堆栈上。例如,如果要实现递归算法,变量所处的位置很重要。

C语言中的陷阱与全局变量发生冲突。直到wX实际定义为static,如果它们在某处全局定义,则w并且X将改为引用全局实体。

在此处qw可能未将其初始化为相同的值,因为w正在使用global 进行设置q

static int q = w;
static int w;

如果w不存在全局变量,则编译将失败。

在这里qw将被初始化为相同的值:

static int w;
static int q = w;

通常,设计人员可以通过在全局变量和函数中添加独特的前缀或后缀来减少名称冲突。

在C99中,static已获得另一种用途,例如int Y(int a[static 10]);,这意味着存在一个函数Y,该函数采用至少 10个整数的数组。

长度74片段

void f(register int*p,register int*q,register int l){while(l--)*p++=*q++;}

或布置得很好:

void f(register int *p, register int *q, register int l)
{
    while (l--)
        *p++ = *q++;
}

关键字register向编译器提供了一个提示,即在此处使用硬件寄存器将是有益的。上面的函数会将l整数从复制qp如果可能,使用硬件寄存器。

有时加速可能会很大。例如,在68K微处理器系列中,如果不使用,则该行*p++ = *q++可以转换为一条指令,MOVE.W (Ap)+,(Aq)+而不是6或8条register。68K微处理器具有明确的后递增和前递减模式,因此,精明的开发人员(如果他知道该平台)将使用x++和以及--y++x和来定制代码y--

如今register,编译器大多会忽略,除了不允许使用它们的地址外(例如,在上面&l会导致编译器错误)。

长度88片段

#include<stdio.h>
int f(int x){return(x>1)?x*f(x-1):1;}int main(){printf("%d\n",f(12));}

或更合理的布局:

#include <stdio.h>

int f(int x)
{
    return (x > 1)? x * f(x - 1): 1;
}

int main()
{
    printf("%d\n", f(12));
}

啊,递归!该代码段是一个完整的程序,可以进行编译,链接和运行。该函数使用递归公式f(x)= x * f(x-1)f计算其自变量的阶乘x。阶乘真的很快变大,因此例如f(12),带符号的32位整数可以获得最大值。

有关真正递归代码的示例,请研究Ackermann函数的简单实现

inline当常量作为参数提供时,智能编译器可以使用提示来“ 优化”函数,并“展开”函数,以便:

f(12)

成为:

12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1

无需任何函数调用!

其他编译器可以重新组织功能:

int f(int x)
{
    return (x < 2)? 1: f(x - 1);
}

并实现所谓的尾递归。实际上,这将最后一个函数调用替换为简单的goto,并让该函数处理返回值。这样做的好处是减少了堆栈抖动,加快了代码编写的速度,并使代码更小。

在汇编语言中,这些类型的优化机会确实很容易发现,并且可以通过所谓的“锁孔优化器”来实现,该方法基本上是寻找小的模式,并用更快和/或更小的模式来代替它们。

长度117片段

#include<stdio.h>
int main(int c,char**v){int a,b;sscanf(v[1],"%d%*[\t ,]%d",&a,&b);printf("%d\t%d\n",a,b);return 0;}

要么:

#include <stdio.h>

int main(int c, char **v)
{
    int a, b;

    sscanf(v[1], "%d%*[\t ,]%d", &a, &b);
    printf("%d\t%d\n", a, b);

    return 0;
}

C借鉴了当时的当代语言,通用I / O的概念可以一致地应用于任何设备,无论是控制台,打孔卡,磁带,光盘还是打印机,但是以真正的C形式,它允许开发人员创建非常简洁但有力的陈述。

在上面的代码片段中,它将使用命令行输入,解析两个由空格,制表符或逗号分隔的整数,然后输出它们。它利用了更新的scanf说明符%*[\t ,],该说明符将:[\t ,]拉出所有制表符,空格和逗号,以及:*忽略它们。

我记得修改过一些C ++代码,使开发人员以“纯” C ++方式完成所有工作,<<并使用了大量的诸如find和方法substr。至少有十几行,但仍不能将逗号作为分隔符。我用sscanf上面的一行替换了所有笨拙的代码!

长度132摘要

#include<stdio.h>
int main(int c,char**v){while(--c){++v;printf("|%s|\n|%5s|\n|%-5s|\n|%.5s|\n|%5.5s|\n",*v,*v,*v,*v,*v);}return 0;}

要么:

#include <stdio.h>

int main(int c, char **v)
{
    while (--c)
    {
        ++v;
        printf("|%s|\n|%5s|\n|%-5s|\n|%.5s|\n|%5.5s|\n", *v, *v, *v, *v, *v);
    }

    return 0;
}

的功能printfsprintffprintf等使用的格式说明来定义输出的宽度和填充。

使用命令行参数编译并运行以上命令以查看各种输出:

> main xyz 123456
|xyz|                                                                                                                                                
|  xyz|                                                                                                                                              
|xyz  |                                                                                                                                              
|xyz|                                                                                                                                                
|  xyz|                                                                                                                                 
|123456|                                                                                                                                             
|123456|                                                                                                                                             
|123456|                                                                                                                                             
|12345|                                                                                                                                              
|12345| 

请注意.5,将说明符的输出限制为最多五个字符,而前导5确保输出至少为五个字符,并-指示左对齐。组合它们将输出设置为恰好五个字符。


4
我认为不需要为每个upvote添加新的拟事实:)
Optimizer

28
C语言中的一种常见文化是忽略编译警告,我认为这与事实不符!
Shahbaz 2015年

4
如果您有一个大型项目并考虑使用多个编译器,则尝试消除所有警告可能是徒劳的。
feersum

5
太好了

4
我是C程序员,并且不怕Haskell。
Shahbaz

138

x86机器代码

类固醇:

x86机器代码是处理器实际运行的x86汇编的汇编版本。它是在内存和存储空间昂贵的情况下进行开发的,并且旨在一直向后兼容Intel8008。保持可执行代码较小是目标之一,并且它利用可变长度指令和CISC架构来帮助实现目标。实现这一点(其缺点是提高现代处理器的性能变得更加复杂)。通常,这与汇编和机器代码的准系统性质一起,使x86程序具有极其紧凑的功能。

长度1:

现在开始第一个程序:

0xC3

打开一个十六进制编辑器,输入该字节,然后将其保存为test.com。

您现在有了有效的MS-DOS程序,由于0xC3是指令“ RET”,因此它无需执行任何操作即可立即返回。但是,这确实显示了使用x86打高尔夫球的另一个有趣方面:.com文件格式。这种可执行格式绝对没有头-文件只是从地址0x100开始加载到内存中,然后从0x100开始执行。这意味着不会在元数据上浪费字节!

长度2:

我们的下一个程序:

0x4D 0x5A

或ASCII中的“ MZ”。

好吧,我作弊了一点,那确实不是一个有用的程序,因为它与指令相对应

DEC     BP
POP     DX

实际上对启动.com程序没有用。实际上,这就是这两个值的重点-没有合理的.com文件应该以它们开头!.com文件的大小限制为65280字节(64KiB-0x100),因此当开始需要更大的程序时,必须开发一种新格式。这是.exe文件格式,它确实具有标题。但是,MS-DOS需要在某些组件上保留.com扩展名以便向后兼容,因此它需要一种方法来检测.com文件是否确实是.exe。他们选择字符串“ MZ”作为该魔术数字,直到今天,如果您在十六进制编辑器中打开Windows .exe(或.dll)文件,您都会看到它们以这两个字节开头。让我感到很高兴的是,即使是最现代的Windows程序也从70年代的兼容性约束开始。

长度3:

现在进行无限循环:

41 E2 FD

转化为

start:
inc cx
loop start 

该程序递增CX的值(开始时该值将> 0),然后执行循环指令。循环是CISC指令的一个很好的例子,因为它将3个简单的操作组合为一个特殊用途的操作:它递减CX的值,检查它是否为0,否则跳转到目标标签。除了CX为0时结束之外,还有其他形式的循环检查其他标志。我们可以为2字节无限循环执行“跳转开始”操作,但这更有趣。

长度4:

最小有用的程序:

40 CD 10 C3

转换为汇编:

inc ax    ; 1 byte
int 10h   ; 2 bytes
ret       ; 1 byte

该程序将控制台设置为40x25字符,清除屏幕,然后返回命令行。将AX设置为我们想要的视频模式(1),然后在返回之前调用BIOS中断10h来实际设置视频模式并清除窗口。希望将来会看到更多此类BIOS中断。

长度5:

我们现在可以实现一个暂停程序:

B4 01 CD 21 C3

转换为汇编:

mov ah,1  ; 2 bytes
int 21h   ; 2 bytes
ret       ; 1 byte

该程序告诉BIOS等待按键被按下并在返回之前将其回显到屏幕。这也说明了如何在x86上部分读取或写入某些寄存器。在这种情况下,我们将AX(AH)的高位字节设置为1。在32位处理器上,您也可以在低16位上进行操作而不会影响高16位。这种修改部分寄存器的能力对于汇编程序员来说很方便,但是对于现代处理器尝试执行无序执行来说却有缺点,因为它们会引入错误的数据依赖性。

长度9:

现在实际显示输出:

68 00 B7 07 AB 40 79 FC C3

转换为汇编:

; These two instructions set up ES, the 'extra segment'
push 0xb700 ; 3 bytes
pop  es     ; 1 byte
label:
stosw       ; 1 byte, Store Word - Copy AX to [ES:DI] then add 2 to DI
inc  ax     ; 1 byte
jns  label  ; 2 bytes, Jump Not Signed - Jump unless the sign flag is set (when inc AX yields 0x8000
ret         ; 1 byte

输出是以不同颜色重复的默认字符集。AX的低字节是字符代码,高字节指定要使用的颜色。 默认字符集以不同的颜色重复

16位程序只能直接寻址多达64KiB。为了解决这个问题,x86使用了“段”-特殊寄存器,该寄存器将乘以16并添加到所有内存访问中,以提供20位可寻址内存。程序可以更改这些段寄存器的值,以便访问更多内存-或内存的特殊区域:该程序修改多余的段,以便写入视频内存。不同类型的内存访问使用了不同的段寄存器,从而允许在不同内存块中同时访问代码,数据和堆栈。默认段也可以被许多指令覆盖。

长度20:

让我们进行一些可识别的操作-我们将使用“规则90”绘制Sierpinski三角形。

B0 13 CD 10 68 0F A0 1F AC 31 C2 88 94 3E 01 87 D3 93 EB F4

组装中:

mov al,13h      ; 2b
int 10h         ; 2b - Set the video mode to 13h

push    0xA00F  ; 3b
pop     ds      ; 1b - Set the data segment to video memory

start:          ; This loop runs 'Rule 90' to draw Sierpinski triangles
lodsb           ; 1b - load al with [ds:si] then increment si

xor     dx,ax   ; 2b - xor the left and right values of the previous row of pixels
mov     [si+318],dl ;4b - store result to memory

xchg    dx,bx   ; 2b - swap register values
xchg    ax,bx   ; 1b - swapping with ax is 1 byte shorter

jmp     start   ; 2b - infinite loop

样本输出: 谢尔宾斯基三角形

对于此程序,我们使用有些著名的“模式13”-一种具有256色分辨率为320x200的图形模式。许多流行的DOS游戏(例如Doom)都使用了它。

长度21

让我们看看谁制造了我们正在运行的CPU。

0F A2 66 60 BB EE FF B9 0C 00 8A 17 43 B4 02 CD 21 E2 F7 FF E1

转换为汇编:

cpuid         ; 2b  CPU ID - retrieve processor information based on the value in AX. For AX=0,
              ;     the 12 bytes in EBX, ECX, and EDX are loaded with a vendor identification string
pushad        ; 2b  Push all registers on the stack (32 bit version)
mov  bx,0xffee; 3b  Start of the vendor identification string on the stack
mov  cx,12    ; 3b  12 characters to print
print:    
mov  dl,[bx]  ; 2b  Character to print
inc  bx       ; 1b  Advance string position
mov  ah,2     ; 2b  Set AH to the 'Print character to STDOUT' value
int  21h      ; 2b  Call the bios interrupt to print
loop print    ; 2b  Decrement CX and jump if it is not zero
jmp  cx       ; 2b  Instead of restoring the stack, just jump right to the exit point

样本输出:

c:\misc>cpuid.com
GenuineIntel

该程序使用CPUID指令来获取有关正在运行的处理器的信息,尤其是供应商标识字符串。除非他们的CPU制造商不多或在某些虚拟机上运行,​​否则大多数人会看到“ GenuineIntel”或“ AuthenticAMD”。

长度26

我们现在可以制作有趣的动画

B0 13 CD 10 C4 07 BB 40 01 59 99 89 F8 F7 F3 31 D0 AA E2 F6 26 FE 05 47 EB FA

组装中

mov al,13h     ;2b
int 10h        ;2b Enter Video Mode 13h

les ax,[bx]    ;2b Set ES to (roughtly) video memory
mov     bx,320 ;3b Set up  BX asdivisor
pop     cx     ;1b Zeroize CX

start:
cwd            ;1b Sign extend AX to DX, AX will never have the sign bit set so this zeroizes DX in 1 byte
mov     ax,di  ;2b Copy video memory pointer
div     bx     ;2b Divide by width to get AX = Y pos, DX = X pos
xor     ax,dx  ;2b X pos ^ Y pos
stosb          ;1b Store and increment video pointer
loop    start  ;2b CX starts at 0, so this will loop until it wraps around

cycle:
inc     byte [es:di];3b Increment value in video memory to animate
inc     di     ;1b Increment video memory pointer
jmp     cycle  ;2b Infinite loop 

输出将如下所示:

行军异或

函数X pos ^ Y pos产生有趣的分形,尤其是在动画时

长度27

您不仅可以在小型x86 .com程序中生成文本和图形,还可以生成声音和音乐:

BA 31 03 B0 3F EE BA 30 03 B0 93 EE B4 01 CD 21 3C 1B EE 3C 1B B0 7F EE 75 EC C3

组装中:

    mov dx,0x331            ; value for the midi control port
    mov al,0x3F             ; command value to set midi mode to UART
    out dx,al               ; output the command to the midi control port
play_loop:
    mov dx,0x330            ; value for the midi data port
    mov al,0x93             ; midi instrument value (piano)
    out dx,al               ; output to midi data port
    mov ah,1
    int 0x21                ; read character from stdin, with echo
    cmp al,27               ; test if it is escape
    out dx,al               ; output the ascii value as the midi note to play
    mov al,0x7F             ; note duration
    out dx,al               ; output note duration
    jne play_loop           ; loop if escape was not pressed
    ret  

该程序使用midi卡将键盘变成钢琴。为此,将MIDI卡设置为UART模式,该模式会在收到MIDI音符后立即播放它们。接下来,程序等待一个字符被按下,并将ASCII值作为注释输出到Midi卡。该程序将一直运行,直到按逃脱键为止。

长度29

让我们使用一个迭代函数系统来生成龙曲线分形:

B0 13 CD 10 89 D0 01 CA 29 C1 D1 FA D1 F9 73 03 83 E9 7A B4 01 CD 16 B8 02 0C 74 E6 C3

转换为汇编:

mov  al,13h
start:
int  0x10    ; This does double duty, setting the video mode to 13h at program start,
             ; and calling the 'draw pixel at coordinates' interrupt when looping
mov  ax,dx   ; The next couple instructions are our IFS, the algorithm is aproximately
add  dx,cx   ; f(y) = 0.5x + 0.5y
sub  cx,ax   ; f(x) = 0.5x - 0.5y OR f(x) = 0.5x - 0.5y - 1
sar  dx,1    ;
sar  cx,1    ;
jnc  skip    ; This jump handles pseudo-randomly switching between the two functions for x,
             ; based on if the previous value of x was odd or not.
sub  cx,122  ; Magic number, chosen since it provides sufficent 'randomness' for a filled in
             ; fractal and a good scale to the fractal. 102 and 130 also work.
skip:
mov  ah,1
int  0x16    ; Get keyboard state, zero flag will be set if no key has been pressed
mov  ax,0xC02; Set up AH for the draw pixel function when int 0x10 is executed,
             ; AL = color, CX = column, DX = row
jz   start   ; Loop if a key hasn't been pressed
ret  

输出:

龙曲线

按下非控制键将导致程序退出。这是基于Pouet.net上Desire 的Fire Coral制作的。

长度52

该程序有点双重功能,它展示了一些x87浮点协处理器和自修改代码。

B3 07 D9 E8 B1 11 DE 0E 32 01 E2 FA BE 0A 24 56 B1 09 DF 34 AC D4 10 
86 E0 05 30 30 50 E2 F5 44 B4 2E 50 89 E2 B4 09 CD 21 FE 06 03 01 4B
75 D2 CD 20 0A 00

运行时,程序将输出几个数学常数:

1.00000000000000000
3.32192809488736235
1.44269504088896341
3.14159265358979324
0.30102999566398120
0.69314718055994531
0.00000000000000000

它们是1,Log2(10),Log2(e),Pi,Log10(2),Log e(2)和零。

组装中:

组织100h

mov     bl,7         ;Counter for the total number of constants to print
start:
fld1                 ;Floating point constant to load on the FP stack,
                     ;start with 1 since it's op-code is the lowest

mov     cl,17        ;Multiply the constant by 10, 17 times to get the
mult:                ;printing part as an integer
fimul   word[ten]
loop    mult

mov     si,10+'$'*256;ASCII new line (10) and the end-of-string ($)
                     ;characters. These are used both as
push    si           ;a constant memory location, and stored to the
                     ;stack to format and printing

mov     cl,9         ;print 18 digits (9 pairs)
fbstp   [si]         ;store the integer part of the floating point
                     ;number on top of the FP stack as a packed
                     ;binary-coded decimal number (1 digit/nibble),
                     ;and then pop the number off the FP stack

convert:
lodsb                ;load a pair of packed digits

db 0xd4,16 ; AAM 16  ;ASCII Adjust For Multiply instruction using
                     ;non-standard base 16. This puts AL/16 in AH,
                     ;and AL%16 in AL, unpacking the digit pair.

xchg    ah,al        ;Swap the digit order
add     ax,'00'      ;Convert the digits to ASCII values
push    ax           ;Store digits on the stack
loop    convert

inc     sp           ;AX now holds the 1st 2 digits to print,
mov     ah,'.'       ;so to insert a decimal point, the 2nd digit
push    ax           ;is replaced with a '.', the stack pointer
                     ;is adjusted to overwrite 1 byte, and then
                     ;AX is pushed on the stack

mov     dx,sp        ;Load DX with the start of the print string
mov     ah,9         ;Load AH with the 'Print String' constant
int     21h          ;Call the 'Print String' interrupt to display
                     ;the constant

inc     byte[start+1];Self-modifying code - increment the load
                     ;floating point constant op-code to iterate
                     ;through all of them

dec     bx
jnz     start        ;Exit when all 7 constants have been printed
int     20h


ten: dw  10

x86系统上的浮点运算最初是由可选的x87协处理器处理的,直到486才将其移至同一芯片上。x87还具有完全不同的体系结构,它是基于堆栈的,具有8个80位寄存器。它还具有各种舍入模式,精度和可以设置的可屏蔽异常。

该程序将打印出烘焙到处理器中的七个常量的值。指令空间浪费在简单的常量(如0和1)上似乎很奇怪,但是请记住,指令集是在内存较小时创建的,并且这些指令通常比等效操作小2个字节。该程序还使用了模糊的指令FBSTP-“存储BCD整数和弹出”。早在开发x86时,对BCD编号的操作就更为普遍,并且x86 / x87具有一些专门用于简化BCD数学的指令,例如程序中也使用了AAM“ ASCII调整为倍数”指令。

在早期x86程序使用的不受保护的内存模型中,数据和代码之间没有区别。因此,通过简单地增加适当的值,就很容易遍历顺序编码的“加载常数”指令。

长度64

交叉张贴我参加Mandelbrot挑战赛的文章时,可以编写一个程序,该程序仅以64个字节显示320x200的彩色Mandelbrot分形。

B0 13 CD 10 C4 07 99 89 F8 B9 40 01 F7 F1 83 E8 64 FE CE 31 DB 31 F6 
89 F5 0F AF F3 01 F6 0F AF DB 70 19 0F AF ED 70 14 01 EB 70 10 29 EB
29 EB C1 FB 06 01 D3 C1 FE 06 01 C6 E2 DB 91 AA EB C6

组装中:

mov al,13h ; set up graphics mode 13
int 10h

les ax,[bx]; trick to set video memory

FillLoop:
cwd
mov ax,di  ; di is the current position on screen
mov cx,320 ; convert di int x,y screen coordinates
div cx     ; CX is the iteration counter, exit the loop if it hits
           ; zero before the value escapes.
sub ax,100 ; center the fractal vertically
dec dh     ; center the fractal horizontally

xor bx,bx
xor si,si

MandelLoop: ; Fairly standard Mandelbrot routine,
mov bp,si   ; exits if the values overflow
imul si,bx
add si,si
imul bx,bx
jo MandelBreak
imul bp,bp
jo MandelBreak
add bx,bp
jo MandelBreak
sub bx,bp
sub bx,bp

sar bx,6   ; We use fixed point math with the lowest 6
add bx,dx  ; bits being the fractional portion, so this
sar si,6   ; rescales the values after multiplication
add si,ax

loop MandelLoop

MandelBreak:
xchg ax,cx ; Write the escape itteraction as the color
stosb
jmp FillLoop

最终结果是此图像:

Mandelbrot分形

该程序使用定点数学生成分形,因为它占用较少的字节。16位寄存器的最低6位被认为是数字的小数部分,并且值相乘后会重新缩放。


7
在PPCG上可以看到的所有语言中,我没有想到这一点。
Alex A.

23
哇。加上其他字符以使其成为注释。不过实话说。哇。
krs013

2
@Michael Edenfield这就是DOSBox的目的!
Sir_Lagsalot,2015年

1
20字节的Sierpinski非常令人印象深刻。
qwr

1
我认为自己是一个优秀的程序员,但是当我看这个时,我必须承认失败。
Stephan Bijzitter

121

哈斯克尔

您可能想从头开始阅读。有时我会参考较低的代码段,但不会参考较高的代码段,因此这可能有助于理解。

不认识Haskell的读者:我清楚吗?我什么时候不清楚?我不知道

长度86片段

我们的树数据结构的可折叠实例(摘要23)。可折叠是类型类-就像类型的类(/组)一样。这些与Java中的接口并行。它们实质上是对类型进行泛化,统一具有共同特征的类型。例如,它们可以加在一起(Monoid),容器(Functor),可以打印为文本(Showshow函数中我们已经见过),等等。这一类将数据类型统一为列表,因为它们可以在列表上迭代或展平为列表。

在此代码段中,我们通过定义来定义实例,该实例foldr实际上是从右到左对数据类型进行迭代。现在,我们可以使用一堆通用的预编写代码。首先,我们定义一个辅助函数来获得一个单树,以避免所有的混乱:s a = N E a E。现在:

sum (N (s 3) 7 (N E 5 (s 8))     === 23
product (N (s 3) 7 (N E 5 (s 8)) === 840
toList (N (s 3) 7 (N E 5 (s 8))  === [3,7,5,8]

等等。

这是我们的树的图片:

7
| \
3  5
    \
     8

长度70片段

primes=sieve[2..] where
 sieve(p:xs)=p:sieve(filter(\x->x`mod`p/=0)xs)

这是一个主要的筛子!

(注意:/=!=是其他语言的意思)

通过定义一个sieve过滤列表的功能并仅保留不可被任何先前质数整除的数字来起作用。它是递归定义的-to的sieve定义是将列表拆分为第一个元素p和一个尾部,从尾部过滤可除以psieve剩余位的任何数字,并附p加到该数字的开头,然后返回。

同样,我们在这里使用无限列表-但只要您不需要无限数量的素数,计算就会及时停止。

take 4 primes === [2,3,5,7]

长度68片段

最后是一个奎奴!

main=do putStr s;print s where s="main=do putStr s;print s where s="

在您第一次阅读本文时,您可能会认为此quine的输出将缺少引号,为什么您一次写putStr一次print?听起来一样。

在Haskell中,putStr是一个仅打印获取到stdout的字符串的内容的函数。print,但是,将内容打印到stdout。因此,print 4等同于putStr "4\n",但putStr 4毫无意义- 4不是字符串!因此,当print获取值时,它将首先将其转换为字符串,然后打印该字符串。通常,将事物转换为字符串的方法是找到将其记录在代码中的方法。因此,abc在Haskell代码中将字符串写入字符串的方式是"abc"print "abc"实际上是print "abc",而不是abc

我现在有足够多的选票是多么幸运的,我不必打高尔夫球

长度为33的摘要:

main=go 0
go n=do print n;go(n+1)

需要注意的重要一点是我们没有使用循环。Haskell不循环。Haskell递归。Haskell没有循环。不仅如此:Haskell甚至没有Control flow。您可能会问如何?好吧,它不需要任何东西。

关于细节。该程序打印从0开始的无限递增的整数序列。从go输入开始打印整数 ,然后main在上调用它0

do是Haskell的一种特殊语法功能。在这种情况下,它就像执行操作一样组合了I / O操作>>(请参见代码片段22)。

长度26片段:

map f=foldr(\x y->f x:y)[]

这使用定义了map每个人都可能熟悉的功能foldr。请注意,虽然我们没有宣布map的类型,电脑莫名其妙地知道它的类型(a -> b) -> [a] -> [b],即给出从功能ab,和列表aS,返回列表b秒。

怎么知道的?;-)

长度25片段:

main=putStr"Hello World"

标准的Hello World。注意类型:main具有类型IO ()putStr具有类型String -> IO ()(从字符串到I / O操作的函数,不返回任何内容)。

长度23片段:

data T a=E|N(T a)a(T a)

这是树的标准定义。比用Java,C或其他任何方式定义树所需的所有这些行简单得多。

(请参见代码段10)

让我们分解一下:

data-此声明声明数据类型。 T a-包含类型为的元素的树a。这就是我们正在定义的类型。 =-的每个值都是T a以下任意值,并用竖线分隔|E- T s空树的可能值之一。 N (T a) a (T a)-树的另一个可能值-节点。每个节点由左子(T a)元素(a),元素()和右子元素((T a))组成。

长度22片段:

main=putStrLn"y">>main

Haskell yes函数。 >>是组合两个I / O操作并对其进行排序的运算符。类型为>> :: IO a -> IO b -> IO b

mainI / O操作本身是递归定义的,它是先打印"y"然后执行任何操作的I / O操作main

长度为18的摘要:

fix f=r where r=f r

的更好定义fix。(请参见代码段14。)第一个定义的问题fix f = f(fix f)是,每当我们调用fix f fixRecalls时fix f,即会fix f产生相同计算的无尽副本。此版本通过定义r(结果)为结果来解决该问题;因此,f r = r。因此,让我们定义r = f r。现在我们返回r

长度17片段:

f n=product[1..n]

这是定义阶乘的功能方法。

长度16片段:

f n=(\x->x+x+x)n

(\x -> x + x + x)是lambda(有人认为它\类似于字母。)。

(\x -> x + x + x) n是应用于的lambda n(与完全相同n + n + n)。

f是乘以三的函数(也是f = (*3)

长度15片段:

sum=foldl (+) 0

sum使用折叠定义功能。折叠基本上是一个具有累加器的列表元素上的循环。
foldl将累加器和列表的一些函数f和一些初始值作为参数。该函数应获取输入的前一个累加器值和列表的当前值,并返回下一个累加器。 然后,折叠遍历列表值,应用到前一个累加器,然后返回最后一个累加器。xxsf
f

考虑折痕的另一种方式是f,在列表值之间以及在一侧中的初始累加器之间的折痕“插入” 。例如,foldl (*) 1 [4,2,5]计算为1 * 4 * 2 * 5

长度14片段:

fix f=f(fix f)

y组合子。它之所以被命名fix是因为它找到了方程的定点f x = x。请注意,x = infinite loop有时它也可以是一个解决方案,因此fix (\x -> x^2 + 5*x + 7)不会求解方程式x^2 + 4*x + 7 = 0,而是返回一个无限循环。

您可能还会注意到x = infinite loop,由于Haskell的懒惰,并非总是一个解决方案。

此版本是时间和空间泄漏;我们将在更长的代码段中对其进行重新定义。

长度13片段:

f=sum.map(^2)

这定义了给定列表返回其平方和的函数 f。它是功能的组合物的功能 sum功能map(^2),而这又是函数 map施加到函数 (^2)(的平方 函数),这是反过来的部分功能 ^(部在片段2进行了介绍,并组合物在片段3 )。

如您所见,函数在像Haskell这样的功能语言中非常重要。实际上,人们已经说过Haskell是具有最标准库函数的语言,该函数函数作为输入或返回函数作为输出(这通常称为高阶函数)

顺便说一句,从技术上讲,每个两个或多个参数函数都是一个将函数作为输出返回的函数(这称为currying)。

长度10片段:

data B=T|F

这是具有不同名称的Haskell布尔值的定义。布尔类型名为B
该定义引入了两个构造函数:true(T)和false(F)。
该代码段基本上告诉编译器,每个布尔值(B)均为true(T)或false(F),或者换句话说为B=T|F

实际上,所有数据类型都可以在Haskell中定义,而在其他语言中,数字,引用和数组数据类型需要编译器的特殊支持。实际上,在Haskell中有特殊的支持,否则会很不方便,但是例如,Bool数据类型是完全用语言定义的。

长度9片段:

main=main

这个荒谬的程序将被定义main为主要程序。由于Haskell是惰性的,因此如果我们不使用它们的实际值,则可以无限使用需要无限循环才能计算的值。这样的包含无​​限循环的值(例如我们main的)称为“底部”。

一个有趣的事实是,GHC Haskell编译器可以在运行时检测到此类无限循环并抛出可捕获的(!)异常。

长度8片段:

f(x:_)=x

这定义了f给定非空列表的函数将返回其头的函数。

Haskell中的模式就像Python的序列解压缩一样,但适用于所有类型。模式可以拒绝或匹配值,如果匹配,则可以将变量绑定到值。

此代码段中的模式是:

  • _:匹配任何内容且不绑定变量的模式。
  • x:绑定任何东西并将其绑定到变量的模式x
  • ::此模式进入子模式,即一个用于头部,一个用于尾巴。如果列表不为空,则将其与头部和尾部匹配。

模式匹配高度概括。实际上,仅定义新数据类型将自动引入使用它们的模式。

长度5片段:

x=2:x

哇,这方面有很多要解释的地方。

首先,Haskell很懒。这意味着仅在绝对必要时才评估子表达式。

注意:此代码段不显示分配,而是定义。Haskell没有任务。

此代码段已定义x,一个无限列表完全由组成2。通常,在x评估之前必须先评估其他语言2:x,但是在Haskell中我们可以这样做。

Haskell无限列表是迭代器和常规链接列表的混合体:它们的作用类似(例如,范围内的迭代将使用常量内存)。

长度4片段:

2:[]

该代码段仅对单例列表进行编码[2]:是Haskell中的Cons运算符。实际上,常规列表语法只是cons运算符和空列表文字的语法糖。这与Haskell处理模式匹配和数据类型(尤其是构造函数的概念)的方式紧密相关。

长度3片段:

f.g

在Haskell中,.代表功能组合。Haskell可以以“无点”样式编写,其特征是不命名函数参数,而是使用.运算符来操纵数据流。

长度2片段:

1-

如果将此代码括在括号中(出于语法原因),则称为“节”。然后,它是一个给定数字的函数,“填满”空白点并返回一个减去该数字的数字。在诸如Haskell之类的功能语言中,此概念有时很有用,否则将需要lambda。

长度1片段:

1

在Haskell中,1既可以是一个IntFloatDoubleWord等等。实际上,您可以编写代码来定义1任何类型的版本并自由使用它。
在JavaScript,Python等中也可以做到这一点,但与那些方法不同的是,它具有完全类型安全性。

事实:

最初,Haskell委员会打算以Haskell B. Curry的名字来称呼该语言为“ Curry”,但由于可能会出现一些双关语,因此决定将该名称更改为Haskell。直到后来,他们才注意到Haskell与“ Pascal”和“ Hassle”的相似之处!


我不知道我是否应该用Haskell在其标准库中具有最多函数/运算符的事实来替换事实,从其他函数生成函数(从技术上讲,每个两个或多个参数函数都是这样的)。我是不是该?
2015年

在代码段中展示它,并在说明中添加它。
马丁·恩德

f=0:1:zipWith(+)f(tail f) -- 25 chars,该函数返回延迟计算的斐波那契数字的列表。
chamini2

嗯,我添加了一堆代码片段,然后我的计算机关闭了
骄傲的haskeller 2015年

@proudhaskeller保存操作。我从来没有亲自做过,但是如果您一次要进行大型编辑,则可以在保存时在外部文档中执行编辑,然后在完成时将其粘贴。
mbomb007

99

C#

C#是Java,C,Haskell,SQL和许多其他语言的有趣而疯狂的功能组合,它提供了许多非常好的功能和API。在这里也因其冗长而闻名,但我们将拭目以待!

我将忽略通常需要的样板:

class Program { public static void Main(string[] args) { ... } }

长度1:

;

在C#中,命令以分号终止!空行是完全有效的语法。

长度5:

x=5f;

当您在C#中指定文字数字时,编译器将假定它们为整数或双精度数(基于它们是否具有小数点)。如果要使用文字浮点数,则应通过在数字后附加'f'来指定该数字,否则将在运行时进行强制转换,这会产生少量费用。

长度7(字节):

s=@"
";

如果为字符串文字加上@符号作为前缀,它将成为“ verbatim”字符串文字。普通字符串文字将“ \ n”之类的转义序列解析为特殊字符,而逐字文字则不这样做,从而使您可以使用反斜杠字符而不必对其进行转义。它们还可以包括行返回,如图所示。这样可以为您节省一些时间,也可以使多行字符串文字更具可读性。只要注意缩进包含在字符串中即可。

长度8:

()=>x=y;

此表达式是一个匿名函数。它返回Action可以传递的类型的对象,也可以像函数一样调用。匿名函数继承了声明它们的作用域,并且它们随处随处将该作用域中的任何局部变量与它们一起拉。

长度9:

(a)=>a.p;

这是另一个使用参数和返回值的匿名函数。表达式返回一个类型的对象Func(Func本身返回类型a.p。您将使用Func很多接口来与Linq交互。

长度10:

enm.Any();

这是我们对Linq的第一个介绍!Linq是一组扩展方法,可以在任何可枚举(实现IEnumerable接口)的对象(如Array和)上调用List。IEnumerable采用了惰性评估:它一次浏览一个集合,而不了解整个集合-甚至可能是无限的!

那就是Any进来的地方- true如果Enumerable包含至少1个项目,它将返回。比计算出整个长度要好得多。

长度11:

var a=1.5f;

var关键字指示编译器自动确定的类型aa在这种情况下将键入为Single。对于代码高尔夫球非常方便,因为它比几乎任何类型的名称都短,尽管许多人不喜欢在生产代码中使用它。

长度15:

yield return 0;

这是您可能不太熟悉的疯狂声明。您知道可以通过继承IEnumerable来枚举对象,但是您知道函数可以枚举吗?声明一个返回类型为的函数IEnumerable,并yield return根据需要进行多次。当您对函数使用枚举数时,每次调用GetNext都会使程序执行直到下一个的所有代码yield return,返回该值,然后暂停直到再次前进。您用于yield break结束迭代。

长度16

[Obsolete]int a;

此代码段显示了一个属性。属性是一种标签,可以粘贴在代码中的任何声明上。有些指令会指示编译器执行某些操作,例如,如果您调用,则会发出过时警告a。您可以通过扩展来创建自己的Attribute,也可以使用Reflection来查询它们(可能会在稍后进行介绍)。您可以转到meta并限制可与该AttributeUsage属性一起使用的属性的声明类型。

长度17

c.Count(t=>t==3);

这是一种方便的高尔夫方法。给定一个Func映射可枚举的元件cbool,则返回元件的数量c为其中该Func返回true。比编写循环好得多。

长度18:

foreach(T t in c);

这是一个for-each循环。这么多关于不可思议事物的讨论,这是一个非常需要的结构。foreach是一种语法糖,它将为其建立枚举器c(必须枚举),并一次迭代一个元素t。您可以更改或检查每个元素,但是更改集合本身会使枚举器无效。

长度19

c.Select(t=>t.a/2);

这是您的“地图”功能,适用于功能性编程爱好者。Select是一种很好的简洁方法,可以Func对可枚举的每个元素执行一些任意转换(由传入定义)。它返回一个IEnumerable,当您迭代它时,它会吐出“ converted”元素。

长度21

Console.Write("Hi!");

该行将一些文本写入stdout,这可能是C#很少用于打高尔夫球的主要原因之一!

长度23

typeof(T).GetMethods();

C#支持一个非常强大的功能,称为反射。反射使您可以在运行时检查代码的结构。例如,此调用将返回指定类型上所有方法的数组。您可以检查,调用这些方法,甚至可以修改字段和属性的值。属性(请参见长度16)是标记代码部分以与反射一起使用的好方法。

长度25

from t in c select t.a/2;

那是SQL吗?在C#代码中?八九不离十。此表达式与长度为19的表达式相同。

长度27

for(var l;;l=new object());

C#是一种垃圾收集语言,这意味着new只要不存在对内存的引用,分配给您的任何内存(使用关键字)都可以自动释放。即使我从未明确释放创建的内存,此代码也将永远幸福地运行。不过,垃圾收集有成本-在网上搜索以了解更多信息。

长度29

var e=Enumerable.Range(0,99);

Enumerable.Range是一种潜在的便捷高尔夫功能。它返回一个可以枚举的结构,并将按顺序产生指定范围内的每个数字。第二个参数是计数,而不是索引。

长度31

public int pr{get;private set;}

在这里,我们可以显示一个简单的“属性”,一个OOP功能以及C#的另一个标志。如果您曾经使用过Java,则可能已经对字段进行了“获取”和“设置”方法,以区分它们的可访问性或在更改时运行代码。好吧,C#使您可以在字段顶部声明该代码,还可以为获取和设置设置单独的访问修饰符。这个特定的代码段会自动创建一个默认的getter和setter,但会将setter设为私有。

长度32

public static void m(this T o){}

此代码段显示了一个非常适合API设计的C#功能。通过将this修饰符应用于静态方法的第一个参数,该方法将成为“扩展”方法。声明之后,T.m就可以像实际上是T的方法一样在T类型的任何对象上对其进行调用。这可以用于向任何现有类添加新功能,而无需修改甚至无法访问其源代码。

长度38

int f(int a,ref int b,out int c){c=0;}

此方法展示了C#中可以使用的不同类型的参数传递。未修改的参数按值传递。带前缀的参数ref通过引用传递:您可以为它们分配一个全新的对象,它们会将其带回到方法之外。带前缀的参数out就像其他返回值一样:您需要在方法中为它们分配一个值,并且它们像ref参数一样被执行。

长度42

Console.Write("It is \{DateTime.Now()}.");

当您必须使用字符串插值输出组合的字符串时,新的C#6标准可以为您节省一些字符。此功能使您可以在字符串文字内的花括号中编写任何表达式,并且在运行时该字符串将自动与这些表达式的值组合在一起。

长度48

IEnumerable f(){for(int a=0;;)yield return a++;}

现在只有足够的角色才能完成实际目的!此方法使用了我们上面探讨的一些思想,以创建一个无限的Enumerable,该整数将简单地从0开始一对一地返回整数。请记住,C#对Enumerables使用了惰性求值,因此无限序列是完全有效的-您可以根据需要迭代尽可能多的序列,然后随时进行迭代。

长度56

int p{get{return mP;}set{mP=Math.Max(value,0);}};int mP;

这是“财产”的另一个示例(请参见摘要31)。在这里,我实际上是定义不同的代码片段getset,而不是像以前那样使用自动的。此示例演示如何使用属性来验证分配给变量的值-在这里,该值不允许小于0。属性的其他良好用法包括:更改值时通知事件,或重建缓存的值可能基于这一点。

长度65

int v;public static implicit operator int(Program o){return o.v;}

此功能称为隐式强制转换。它有点像扩展方法,因为它是在特定类上运行的静态代码(请参见代码段32)。但是,隐式转换不是通过调用它来使用的-它只是通过将Program对象视为整数(例如int i=new Program())来使用。当您执行此操作时,根据隐式强制转换的代码,该对象将被静默转换为您使用它的类型。最佳做法是仅在转换没有信息丢失的情况下执行此操作。


1
让我们看看您将如何使用这些字符... ;-)
骄傲的haskeller 2015年

9
我要说的是,实际上它比C更贴近Java
骄傲的haskeller

注意。我想我们几乎有能力做一些Linq-今晚来!
BMac

公共静态隐式运算符int(MyClass o){return o.objVal;} // 65。使用此代码,此行有效:MyClass o1 = new MyClass(10); int o2 = o1; // o2现在是10。msdn.microsoft.com/en-us/library/85w54y0a.aspx
Zukki

请提供更多摘要
Cyoce '16

98

爪哇


长度为44片段

Object a=System.out.append("Hello, World!");

打印Hello, World!到STDOUT。

长度为43片段

float[][][][][]a=new float[5][3][7][2][10];

a包含10个数组,每个数组包含2个数组,每个数组包含7个数组,每个数组包含3个数组,每个数组包含5 floats。

长度42片段

interface A{static void main(String[]a){}}

一个完整的程序。由于an中的所有内容interface都是固有的public,因此我们可以public从main方法中省略该词。

长度36片段

class A{class B extends A{B.B.B b;}}

A有一个内部阶层B。这意味着我们可以声明一个type变量A.B

B是的一个子类A,这意味着它具有的所有方法,字段的和内部类A。因此,我们也可以引用类型B.B

在此代码中,我们将更进一步,并提供Btype的实例变量B.B.B

道德:遵循SO上的热门问题可以教给您很多有趣的技术(如果没有意义的话)。

长度35片段

l.stream().map("a"::equals).count()

如果l是字符串列表,这将告诉我们其中有多少相等"a"

长度34片段

public static void main(String[]a)

程序主要方法的方法签名。仅需增加11个字符,我们就可以编写完整的程序!

长度为33的摘要

enum D {NORTH, EAST, SOUTH, WEST}

NORTHEASTSOUTH,和WEST有型的所有常量D

长度为32片段

Files.readAllBytes("hello.txt");

读取整个文件,返回其中byte[]的内容。

长度31片段

new String(new char[]{'h','i'})

等同于"hi"。如果"密钥已损坏,则很有用。

长度30片段

new JFrame().setVisible(true);

创建一个新的可见框架,您可以在其中放置其他组件。

长度29片段

throws ClassNotFoundException

强制每个调用此方法的方法使用try- catch块,否则将错误传递给堆栈。受检查的异常是Java设计人员中最具争议的决策之一。

长度28片段

int f(int x){return f(x-1);}

此功能不会永远运行;实际上,在一台典型的计算机上花费的时间不到一秒钟。谢谢,堆栈溢出。

长度27片段

Object a=new String[]{"a"};

创建一个新的字符串数组。

长度26片段

Object.class.newInstance()

创建一个新的Object

长度25片段

((Supplier)()->-~0).get()

最好避免对常数进行硬编码。这是一种在1不使用以外的任何常量的情况下获取值的面向对象的方式0

长度为24片段

(Function<Long,?>)x->x+1

后继功能。

长度23片段

l.removeIf(x->x%10==0);

如果l是整数列表,则将删除所有可被10整除的值。

长度22片段

int i=(new int[7])[5];

创建一个由七个整数组成的新数组,并获取第五个元素。

长度21片段

Arrays.asList(2L,"a")

使用这些元素创建一个ArrayList。

长度为20片段

System.out.print(s);

印刷品s

长度19片段

import java.util.*;

允许使用简洁像类ListMapScannerTimer,和Random

长度18片段

Math.addExact(x,y)

将两个整数x和相加y。如果发生溢出,则该方法将引发异常,而不是给出错误的答案。

长度17片段

Double.MIN_NORMAL

type的最小正值double,其中有效位数的前导位为0。

长度16片段

System.in.read()

从控制台读取单个字符。

长度15片段

Long.reverse(x)

反转的二进制表示形式的位x

长度14片段

int x=050+120;

x现在是160,因为任何以开头的东西0都被视为八进制。

长度13片段

private C(){}

私有构造函数可防止其他类实例化它。SystemMath类等使用此模式。私有构造函数也可以用于强制执行Singleton模式。

长度12片段

static class

允许创建内部类而无需封闭外部类,这许多程序员面临问题 的解决方案

长度11片段

throw null;

通常有必要抛出NullPointerException,但也很罗word。这是一个简单得多的选择。

长度10片段

int[]a,b[]

定义两个变量:aba是类型int[]b也是类型int[][]

长度9片段

switch(x)

根据的值转到一个位置x

长度8片段

break a;

跳出标记为的块a

长度7片段

goto x;

goto关键字是用C,C ++和Java保留。如果x是标签,则此代码将程序发送到相应的标签-C和C ++。但是它是Java,它触发了一个神秘的事物RuntimeException。实际上,根本没有办法goto在Java中使用关键字。

长度6片段

\u003b

结束声明。Java很奇怪

长度5片段

a-=-a

双打a减去它的否定。

长度4片段

a&=b

将的值设置为a按位的和的ab

长度3片段

...

任意数量的参数,合并为一个数组。

长度2片段

<>

允许编译器弄清楚您可能表示的泛型类型。非常不像Java。

长度1片段

@

指示一个注释,以允许显示有关方法和类的附加信息。

类固醇

在Java中,无限循环有时会导致编译器错误。例如,如果while(true);不退出方法就无法终止循环,因此此后的任何代码都将触发“无法到达的语句”错误。正如@Optimizer指出的那样,只有一些无限循环会被这种方式捕获。


5
在Java中,无限循环不会导致编译器错误。它是您的IDE,可检测到它们并产生错误。Java仅具有Unreachable语句的概念,因此,如果while(true);代码中包含类似内容,则该行之后的任何内容都会引发Unreachable语句的编译错误。检测此类语句的逻辑非常严格,因此它不会以任何方式识别所有无限循环
Optimizer

4
您刚刚投票了,我想这意味着您必须删除一个代码段!;)(不赞成投票的原因是“ Java很奇怪”)
Simon Forsberg,2015年

1
似乎#36片段是递归的,可以无限期扩展:class A{class B extends A{B.B.B.B.B.B.B b;}}仍然可以编译。
Natix

3
为了帮助您制定一个完整的程序而
投票

1
But it Java, [goto] triggers a mysterious RuntimeException错误。goto甚至不编译。
dorukayhan

93

蟒蛇

现在从最新开始,为您提供方便!要最早读取长度30,请转到修订历史记录。

如果有人有建议,请随时发表评论。

长度52:

i=0
while s[i-n:]:print(' '*n+s)[i:n+i];i+=1;i**7**7

摘自我在“ 伪字幕文本”挑战赛中的参赛作品。s并且n需要提前设置为字符串和整数。在我使用的免费Python 2解释器中,它实际上不能很好地工作,因此我在其中加上了括号(' '*n+s)[i:n+i],您可以在此处看到它在Python 3解释器中运行。

长度43:

#-*-coding:rot13-*-
cevag h"Una fubg svefg"

在Python中,您可以使用特定的编解码器对源进行编码。这显示了如何在Rot13中编写源代码。一般语法是这样的:# -*- coding: <codec-name-goes-here> -*-

此处翻译为:

#-*-coding:rot13-*-
print u"Han shot first"

u下列字符串文字指定为Unicode字符串。如果您希望您的字符串也位于Rot13中,则这是必需的,否则尽管进行了加密,源中的每个字符串仍易于读取。或者,您可以.encode("Rot13")在每个字符串之后使用(也不要忘记在其上使用Rot13。)根据本文所述,一些替代编码为“ base64”,“ uuencode”,“ zlib”或“ bz2”。

长度33:

import cmath
print cmath.sqrt(-1)

这是Python的复数(虚数)模块。这版画1j,因为Python符合工程标准和使用j为虚数单位,虽然我比较喜欢i,这是数学中比较常用,使用jki四元数,但我离题。在此处阅读错误/更改顺序(不会更改)。

长度30:

f=lambda n:n*f(n-1)if n else 1

现在,我们使用递归和三元if-else定义自己的阶乘函数!据我所知,这与Python一样。也可以这样写:f=lambda n:n and f(n-1)*n or 1,展示了几个Python的布尔运算符(也用30个字符完成)。有关lambda语法的信息,请参见长度15的代码段。

长度29:

import math
math.factorial(7)

找到7的阶乘,返回5040

长度25:

import math
print math.pi

Python的math模块提供了许多有用的函数和常量。这是PI。返回3.14159265359。(在上面的代码中,我将换行符视为一个字符。)

长度24:

f=lambda y:lambda x:x**y

这是关闭的示例。调用cube = f(3)将创建一个立方函数,然后可以使用print cube(24)print 对其进行调用13824

长度19:

print"Hello World!"

最后,有足够的空间来打印一些基本输出!这里不需要空格,因为引号和括号也是定界符。这仅在Python 2中有效,因为Python 3将该print函数更改为像其他函数一样被调用。在Python 3中,使用print("Hello World!")。有关打印功能以及Python 2和3之间的区别的更多信息,请参见Python 3.0中的新增功能

长度16

[x*3 for x in l]

再一次,假设l是列表或任何其他可迭代对象,例如字符串或生成器。此语句称为列表理解。它比使用标准的循环结构要短得多。在这里,它返回一个列表,其中所有数字都乘以3。此外,字符串可以相乘!因此,列表中的任何字符串将被添加(连接到自身)该次数。

长度15:

import this #:)

这实际上是一个长度为11的代码段,但我意识到我忘了展示Python的(很棒的)复活节彩蛋!导入该模块会打印出Python的《禅宗》(请参阅Factoid。)有趣的事实:该模块this.py是用rot13编码的,我希望稍后再进行介绍。

长度14:

lambda x:x**.5

这使用Python lambda语法为函数文字定义了平方根函数。Python中的函数文字只能包含表达式,不能包含语句。该lambda可以分配给变量,可以传递给函数,也可以与串联执行(lambda x:x**.5)(9),返回3.0。对平方根使用指数是sqrtmath模块中导入函数的替代方法。

长度13:

1 if x else 0

这是Python三元if运算符的示例。在Python 2.5中添加了此功能,以阻止编码人员使用布尔运算手动实现它。在此,1如果x计算为True0则返回,否则返回。

长度12:

s=input(">")

这将打印>提示文本,并允许用户输入一个值。Python 2会解释输入的任何值,因此任何字符串都需要加引号。Python 3更改了此设置,因此不会自动解释输入的输入。要输入输入而不在Python 2中解释输入,请使用raw_input()。在Python 2中,input()等效于eval(raw_input())

长度11:

eval("2e3")

2e3是浮法2 x10³的科学记数法。该eval函数将任何字符串解释并评估为表达式。在这种情况下,其结果与使用文字2e3或相同float("2e3")。它返回2000.0

长度10:

range(013)

此函数返回从0到八进制值的整数列表,该值01311(不包括),表示该列表将是[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]。该函数最多包含三个参数,类似于slice我们之前介绍的函数:range(start, stop[, step])。区别在于,仅使用一个参数,该参数表示停止值。

请注意,Python 3.x没有等效项。它range是相似的,但实际上是一样的Python 2中的xrange,返回一个发电机对象而不是列表。

长度9:

a,b = b,a

多次分配。这是一个简单但优雅的功能,使您可以同时分配多个值。在提供的代码段中,它交换ab。您问评估的顺序如何?在进行任何赋值之前,将评估赋值运算符右边的所有表达式。这击败了许多需要对临时变量进行中间分配的语言。

长度8:

#comment

你知道那是什么...等等,你不知道吗?您知道吗,那些使您可以键入任意文本来描述一行代码,使其更易于理解的东西?没有?哦好的...

长度7:

l[::-1]

再次假设l是列表,这将以相反的顺序返回列表。第三个参数指示步长。由于所有三个参数都可以为负值,因此负步长意味着以相反的顺序进行迭代。空的第一和第二个参数表明我们正在遍历整个列表。

我们现在可以开始使用一些更有趣的构造了!

长度6:

l[-6:]

这称为切片操作。如果l是列表,则将返回一个新列表,其中包含列表的最后六个元素l-6表示起始索引(从末尾开始为6),而冒号表示继续直到其后的终止索引(我们将其留为空白,直到末尾。)。如果我们的列表包含数字1到10,则返回[5, 6, 7, 8, 9, 10]

长度5:

1<x<5

Python的出色功能之一是允许您链接比较运算符。在许多其他语言中,它将被键入为1 < x && x < 5。当您考虑多个比较时,它会变得更好: 1 < x < y < 5完全有效!

长度4:

0256

前导零的整数是文字八进制值。对于代码混淆而言,这也是一个不错的技巧。返回十进制值174。在Python 3.x中,八进制值将写为0o256

长度3:

`3`

将表达式括在反引号中与使用相同repr(),该函数返回对象的字符串表示形式。该函数尝试以这种方式返回字符串,当将其作为参数传递给eval函数时,它将返回原始对象。它是一样的使用str(),尽管有时结果相同。对于此输入,'3'两种情况都将返回。这是我的代码高尔夫的最爱!

仅适用于Python 2!

长度2:

[]

空列表。

长度1:

_

下划线字符是常用的一次性变量名称。但是,如果您使用的是Python shell(交互式解释器),则它将保存最后执行的语句的结果(并将再次返回该语句。)此外,根据该线程,它还用于i18n中的翻译查找。

Factoid:Python是类似于Java和C的语言。它是根据特定的设计原理构建的(摘自“ PEP 20 – Python的禅宗 ”:

  • 美丽胜于丑陋
  • 显式胜于隐式
  • 简单胜于复杂
  • 复杂胜于复杂
  • 可读性计数

因此,尽管允许使用分号作为语句定界符,但通常会省略分号,以利于使用多行以提高可读性。另外,行缩进非常重要!


任何时候!我不会再添加片段(无法抵抗长度9的片段!),因为您已经在其中做得很好。祝好运!
nasser-sh

1
长度6:它将返回[5, 6, 7, 8, 9, 10](列表中的最后6个数字)
Vincent 2015年

长度16:l不必是列表,它可以是任何可迭代的对象;元组,列表和生成器,例如全部工作
nasser-sh

@ Sp3000:我已经将其用于[受限源]挑战。
Robbie Wxyz

4
没有爱的好老import antigravity吗?
密码

87

的JavaScript

这是最新到最旧的。自己链接:[ 编辑 ]

长度51片段:

console.log(require('fs').readFileSync(__filename))

这次是一个Node.JS quine,尽管由于读取其自己的源代码而无法满足任何“ strict quine”要求。

长度为50的摘要:

a=new XMLHttpRequest;a.open('GET','file');a.send()

最后!一个AJAX请求(使用Vanilla.JS)。我们初始化,打开并发送请求,但我没有足够的空间来添加处理程序,并且实际上对结果执行任何操作。

长度49片段:

msg=new SpeechSynthesisUtterance('Hello World!');

准备一个有声的“ Hello World!”。实际说出来还需要更多工作。我们还可以调整音量,音高,速率和重音。请参阅HTML5Rocks上的语音合成APIFirefox尚不支持,当然IE也不支持

长度为48的摘要:

function repeat(){setTimeout(repeat,48)}repeat()

setInterval通过递归进行模拟setTimeout

长度47片段:

module.exports=function MyModule(a) {this.a=a};

再次使用NodeJS,但是原理在JS中到处都是一样的。这是一个非常基本的构造函数,它创建一个具有一个属性(a)的对象。设置module.exports通过require()-ing 导出要使用的功能。

长度46片段:

canvas.getContext('2d').fillRect(46,46,46,46);

这需要一个<canvas id="canvas"></canvas>元素。它利用以下事实:具有ID的元素被填充为全局变量,因此可以canvas从JS 访问该元素。然后我们在x = 46,y = 46处填充一个46x46的正方形。

长度45片段:

JSON.parse(require('fs').readFileSync('jsn'))

返回节点。在这里,我们解析一个jsn从当前目录命名的JSON文件。

长度44片段:

(a=document.createElement('a')).href="/url";

建立在#39。现在,我们创建一个元素并分配一个属性。它仍然不在DOM中。

长度43片段:

sq=[1,2,3,4,5].map(function(n){return n*n})

使用创建一个前5个正方形的数组map()

长度42片段:

six="1+5",nine="8+1";eval(six+' * '+nine);

这个工作原理与相同,但是JS缺乏#define,因此变得难看。当然,它返回了生命,宇宙和一切的答案

长度41片段:

c=function(){var i;return function(){}}()

关闭的开始。c现在是一个可以访问内部变量的函数(内部函数)i,但是它什么都不做。

长度40片段:

$('p').click(function(){$(this).hide()})

我们完全删除了这些段落并使用了jQuery。

长度39片段:

script=document.createElement('script')

这是添加新的外部脚本的开始。创建一个空<script>元素,并保留对其的引用。

长度38片段:

document.getElementsByClassName('abc')

找到.abc文档中的所有元素。当然,使用jQuery只是$('.abc')...

长度37片段:

b=JSON.parse(JSON.stringify(a={3:7}))

创建两个相同但解耦的对象ab。如果你愿意

a={a:1};
b=a;
b.a=3;

您最终会遇到a=={a:3},因为ab指向同一个对象。我们使用JSON解耦它们。

长度36片段:

(function f(){return "("+f+")()"})()

一个奎因。它打印自己的源代码。

长度35片段:

document.body.style.display="none";

参见#32。这只是隐藏文档,而不覆盖内容。

长度34片段:

Object.prototype.toString.call(34)

调用Object.prototype.toString是判断对象类型的好方法。尽管34..toString()"34",该片段是[object Number]

长度为33的摘要:(此信用额归匿名用户所有

+0%-0.&(v\u0061r=~void[{}<<!(0)])

认为这不是有效的JavaScript吗?最好尝试一下...(使用Chrome);)

长度为32的摘要:

document.body.innerHTML="hacked"

!十一!!!!

长度31片段:

a=[];for(i=0;i<31;i++)a.push(i)

别开玩笑了,我已经等了很久才能够真正使用for循环!这将创建一个从0到30的数组。

长度为30的摘要:

new Date().getDay()==1?"S":"E"

第一次使用三元运算符。我不能超过30个字符,因此我们只知道今天是星期天还是其他。:P

长度为29的摘要:

Object.keys(window).push('i')

Object.keys(window)将获得一个全局变量数组(的属性window)。.push()将一个项目追加到该数组。觉得这相当于window.i=undefined什么?不!

长度28片段:

setTimeout("a=confirm()",28)

等待28毫秒不是那么有用,除了创建新线程。

长度为27的摘要:

document.querySelector('a')

DOM名称这么长真是可惜。我在这里只能得到一个链接。

长度26片段:

JSON.stringify({twenty:6})

参见#16。现在我们得到实际的JSON-字符串。

长度25片段:

new Badge("Good Answer");

假设Badge()有一个带参数的构造函数... 刚刚创建了一个良好答案徽章!

长度为24的摘要:

do {alert(24)} while(!1)

我实际上一点也不用do..while,但是有些用。如果这是一个普通while循环,则不会发出任何警告,因为它始终为假。do..while它将始终至少运行一次,因此我们可以看到24。

长度23片段:

window.parent==self.top

这些都指向同一个对象,通常称为window。如果您正常调用函数,则还有this。这是访问全局对象的5种方式!

长度22片段:

for(i in self)alert(i)

提醒所有全局变量。恰好是那样self==window。(请参阅下一个代码段。)

长度21片段:

"2"+1==21 && 2+1=="3"

哦,看,这又是JS的转换规则。顺便说一句,这句话是正确的。

长度为20的摘要:

Math.random()<.5?0:1

从0-1中选择一个随机数,然后使用三元运算符四舍五入。虽然会更容易使用Math.round...

长度为19的摘要:

[1,2,3].map(i=>i*i)

这是新的。喜欢,真的很新。它使用ES6箭头函数来计算1、2和3的平方。目前,Firefox仅支持它。

长度为18的摘要:

location.href="/";

就像#15一样,但这一次,它转到PPCG主页,而不是SE。

长度17片段:

(function(){})()

这是14岁以下的片段,但更好!现在是IIFE。

长度16片段:

obj={not:'json'}

这解释了我的其中一种愤怒。这是一个对象而不是JSONJSON格式是一种基于JavaScript对象的数据交换格式,但是采用了更为严格的格式。

长度15片段:

open('//s.tk/')

想象一下。使用http://s.tk/打开SE主页重定向。

长度14片段:

function f(){}

W00t!职能!太可惜了没有空间任何事情。

长度13片段:

Math.random()

生成一个从0到1的随机数。是否要定义自己的限制?倒霉。(并非如此,这很容易。)

长度为12的摘要:

new Date<=12

该语句在JS中从未如此。在1970年1月1日00:00:00.012之后很长时间才创建了JS,直到95年代(见事实)。

长度11片段:

Math.PI*121

半径为11的圆的面积。

长度10片段:

if('j')9+1

如果您没有注意到,我喜欢用代码中的代码片段做一些事情。这个返回10,并使用j,即字母表的第十个字母。

长度9片段:

[9].pop()

用一个项目制作一个数组。鼬鼠pop去了9。

长度8片段:

document

所有DOM工作的基础。但是我们无能为力,因为时间太长。:(去jQuery!

长度为7的摘要:

alert()

好家伙!一个函数调用!终于能够做些东西了!

长度6片段:

var x=6

基于#3。不过好多了,因为现在全局是显式的。:P

长度5片段:

[][5]

void 0得到还要短undefined。顺便说一句:''.a更短;只有4个字符。

长度4片段:

+"4"

这将从4字符串中创建数字"4"。您可以按不同的顺序重复使用这些完全相同的4个字符来执行相反的操作!

长度3片段:

x=3

天哪,我们只是做了一个隐式全局变量...

长度2片段:

{}

这是做什么的?如果说创建对象文字,那是错误的。它实际上是一个空块。打开控制台并尝试!它返回undefined,而不是{}

在2018年,{}Chrome的控制台实际上返回了一个空对象。

长度1片段:

1

而已。任何数字都是有效的JS表达式。

Factoid: JavaScript最初称为LiveScript。当时(1995年),它被更改为JavaScript以利用Java的流行。就个人而言,他们应该保留旧名称;从那以后,JavaScript一直令人困惑。实际上,Java和JavaScript与“ car”和“ carpet”差不多。


1
片段33在Firefox上不起作用。它真的有效吗?
Oriol

我发现对对象进行字符串化和重新解析以使其非常脏。ECMAScript 6引入了Object.assign,因此片段37变成了b = Object.assign({ }, a = {3 : 7})
Oriol 2015年

@Oriol是的,很好,只有Firefox现在支持它,所以我们现在必须坚持这种肮脏的方式。至少比更好eval(uneval(a)),对吧?;)
Scimonster 2015年

关于#38,总有document.querySelectorAll("element#id.classname[attribute]:not(somethingwedontwant)")。(支持任何有效的CSS选择器)。
Mateon1,2015年

#40片段本身并不那么有趣,但是评论是无价的。
Scimonster 2015年

85

[R

Factoid: R编程语言最初是S编程语言的GNU实现。它主要用于统计和相关应用程序。

注意:尽管不是比赛的要求,但此处的每个片段都可以在R中单独运行。


长度32:

`[.data.frame`(swiss,3,2,drop=F)

这看起来有点神秘……确实应该!有一种更好的方法来编写此代码:

swiss[3, 2, drop = FALSE]

这看起来应该比较熟悉。当我们运行以下任何一段代码时,都会发生以下情况:

> `[.data.frame`(swiss,3,2,drop=F)
             Agriculture
Franches-Mnt        39.7

swiss数据帧的船舶有R像其他几个人我们迄今为止看到的。它包含了1888年左右以来瑞士47个法语省的生育率和社会经济指标。第三行是弗朗什-蒙特省,第二列是每个省从事农业作为职业的男性百分比。因此,在1888年,瑞士的弗朗什-蒙特省的男性有39.7%从事农业工作。

当您使用更简单的表示法从数据框中提取行或列时,R实际上是[.data.frame在后台使用的。正如我们在代码片段24中所看到的,几乎任何东西都可以定义为函数名称,只要它被反勾号包围,因此即使函数名称在技术上包含不匹配的括号,我们的代码片段也是合法的。

drop=参数告诉R是否希望将结果降低到较小的维数。确实,如果我们说drop=TRUE,我们会得到:

> `[.data.frame`(swiss,3,2,drop=T)
[1] 39.7

在以前结果是数据帧的地方,R现在给我们加倍。


长度31:

print(fortune("hadleywickham"))

fortune()函数来自“全知” fortunes程序包,该程序包提供了来自各种明智人士的各种明智报价。该代码段将通过打印到控制台为您提供以下来自Hadley Wickham(23)的宝石:

That's a casual model, not a causal model - you can tell the difference by looking
for the word "excel".
    -- Hadley Wickham (commenting on an Excel chart showing student's SAT score
       increases with family income, without considering future covariates)
       http://twitter.com/#!/hadleywickham (February 2012)

长度30:

pie(rep(1,12),col=rainbow(12))

谁不喜欢一个好的饼图?该pie()函数将为您提供基于矢量的新鲜出炉的饼图。rep()通过重复第一个元素r次来创建向量,其中r是第二个参数。该col=参数说明pie()如何为切片着色。魔术函数rainbow()生成指定长度的向量,该向量包含用于“等距”彩虹颜色的十六进制代码。

您所拥有的是基本的“此图表中每种颜色的数量”图表:

在此处输入图片说明


长度29:

summary(lm(mag~depth,quakes))

这里发生了一些事情,因此让我们一次迈出一步。

quakes是带有R的数据集。它包含有关自1964年以来斐济附近里氏震级的1000次地震事件的信息,地震强度大于4.0。数据集中的两个列mag分别是,和depth,分别是震中深度,以千米为单位。

lm()代码段28所述,该函数适合线性模型。它返回一个lm对象,或更确切地说,返回class的对象lm。有两种方法可以指定预测变量(或变量)和响应(或变量),并且我选择了公式方法。采取形式response ~ predictor。多个预测变量指定为y ~ x1 + x2。在下一个参数提供的上下文中评估公式中的对象。

因此,lm(mag ~ depth, quakes)正在做的事情是使用普通最小二乘回归拟合线性模型,其中幅度是响应,深度是预测因子。它知道是什么magdepth是因为我们告诉他们它们来自quakes

summary()是通用函数,主要用于汇总拟合模型的结果。它调用特定于其参数类的方法。自从我们传递了一个lm对象以来,它实际上正在调用一个名为的函数summary.lm()

综合起来,我们得到了线性模型的总结,试图从地震深度来解释地震。具体来说,这是R吐出的内容:

> summary(lm(mag~depth,quakes))

Call:
lm(formula = mag ~ depth, data = quakes)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.72012 -0.29642 -0.03694  0.19818  1.70014 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.755e+00  2.179e-02 218.168  < 2e-16 ***
depth       -4.310e-04  5.756e-05  -7.488 1.54e-13 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3921 on 998 degrees of freedom
Multiple R-squared:  0.05319,   Adjusted R-squared:  0.05225 
F-statistic: 56.07 on 1 and 998 DF,  p-value: 1.535e-13

注意它告诉您的第一件事是函数调用吗?这是因为lm()函数使用match.call(),就像我们在代码段28中所做的一样!


长度28:

f<-function(x,y)match.call()

R函数通常喜欢跟踪您告诉他们的内容。实际上,有时您提交的命令会作为返回对象的属性返回给您。(一个示例是lm()创建线性模型的示例。)使用match.call()该函数可以调用精确的指令。这捕获或匹配解释的函数调用。

在这里,我们定义了一个带有f()两个参数的函数,然后告诉您所看到的。

> f(1,2)
f(x = 1, y = 2)

当开发通用功能(而不是仅针对您)时(例如在包开发中),这主要有用。如果您想看一个match.call()狂野的示例,请lm()通过提交查看源代码stats:::lm。它做的第一件事就是使用捕获函数调用match.call()


长度27:

install.packages("ggplot2")

这看似微不足道,但它显示了R之所以如此流行的原因之一:它很容易通过包进行扩展。任何人都可以开发并自由共享他们的软件包!

install.packages()确实如其名称所示。它使用默认的CRAN(全面的R存档网络)镜像对软件包进行搜索,然后将其安装在R可以找到它们的系统上。您也可以让它从本地源代码安装软件包。

还记得代码片段23,我们在哪里使用了该ggplot2软件包?该软件包不附带R,但是只需安装27个字符,您就可以实现所有ggplot2梦想。


长度26:

filled.contour(t(volcano))

volcano数据集附带R.它是包含在Maungawhau(或伊甸山)火山在新西兰奥克兰的地形信息的矩阵。矩阵的行对应于从东到西延伸的网格线,列是从南到北延伸的网格线。

为了迷失方向,让我们交换方向,所以列现在是东西向的,行是南北的。我们可以使用矩阵转置来完成此操作,该转置通过完成t()。为什么不在绘制轮廓图呢?filled.contour()就是那样。

在此处输入图片说明


长度25:

pmatch("s",c("n","size"))

pmatch()函数提供了到目前为止我们所看到的所有部分匹配背后的魔力。第一个参数是一个字符串,将其与第二个参数的每个元素(向量)进行比较。如果存在唯一匹配项,则返回匹配元素的索引,否则得到NA

这里的代码片段是使用此功能的“真实世界”示例。回想一下使用sample()功能的代码片段13 。它接受的论点nsizereplace,和prob,但只需要在第2位。在摘要13中,我们用作的s=简写size=。实际在后台发生的是如下代码片段,将我们提供的内容与预期的内容进行比较。由于“ s”唯一匹配“ size”,因此s=用作速记完全合法。


长度24:

`(`=function(x)9;2*(3-1)

一个不应该做的完美例子!曾经!

您可以将字符分配为函数,只要在定义函数时将它们放在反勾中即可。在这里,我们告诉R,(无论输入如何,该函数始终返回9。像许多其他语言一样,;可用于在一行上包含两个命令。所以我们告诉R的是定义函数(,然后打印2*(3-1)

现在,几乎任何人都会告诉您2 *(3-1)应该是4,因为您执行3-1 = 2,然后是2 * 2 = 4。但是我们已经告诉R,括号内的任何东西都是9。因此,当3-1 = 2时,我们现在有(3-1)= 9。然后我们得到2 *(3-1)= 2 * 9 = 18。

由于这样的事情很可能发生,因此每次您提交的表达式中包含括号的代码(即不是函数调用)时,R解释器实际上都会查找所有被调用的函数,(而不管您是否已将其定义(为函数。通常,您写的越多,R解释器所做的工作就越多。


长度23:

qplot(Na,y=RI,data=fgl)

最后,对于一个(非常)简单的ggplot2示例,足够的投票。该ggplot2软件包是图形语法的R实现,由传奇的R神Hadley Wickham创建。通常,语法与基本R图形非常不同,并且需要一些习惯。但是,它qplot()是该程序包某些核心功能的一个更简单的接口,并且语法类似于plot()在基础R中。但是与我向您展示的许多示例不同,qplot()它不支持函数参数名称的部分匹配。

fgl数据集来自MASS包。它包含法医玻璃碎片的性能测量。在这里,我们使用变量Na,即重量百分比的钠(Na)和RI,即玻璃的折射率。

在此处输入图片说明


长度22:

unique(presidential$n)

unique()函数返回一个包含唯一值的向量,该唯一值从其输入向量中按出现在输入中的顺序排列。该presidential数据集附带的ggplot2封装(27)。(感谢Jemus42纠正了该错误!)其描述:

每位总统的姓名,任期的开始和结束日期,以及从艾森豪威尔(Eisenhower)到布什W的10位美国总统组成的党派。

presidential是数据框,数据框包含列,就像列表包含项一样。列通过使用名称进行引用$。这个特定的数据集有一个名为的列name,其中包含总裁的姓名。但是等等,我们只指定了n!实际上,这是部分匹配(13、16 )的又一个示例,因此n完全合法。

提交此结果很有趣:

[1] "Eisenhower"  "Kennedy"  "Johson"   "Nixon"  "Ford"  "Carter"
[7] "Reagan"      "Bush"     "Clinton"

请注意Lyndon B. Johnson的名字是如何拼写的...糟糕。

(注意:发布此消息一年多后,我已经注意到约翰逊错字已得到修复。RIP幽默。)


长度21:

integrate(dexp,0,Inf)

R具有内置函数,用于在有限或无限间隔内对单个变量的函数进行自适应正交。在R中,无穷指定Inf为+无穷和- -Inf无穷。该dexp()函数是指数分布的概率分布函数。由于指数分布的支持度为[0,+无穷大],并且概率分布积分为1,因此我们希望结果为1。

1 with absolute error < 5.7e-05

长度20:

deriv(~cos(x^3),"x")

R可以做符号导数!返回:

expression({
    .expr1 <- x^3
    .value <- cos(.expr1)
    .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
    .grad[, "x"] <- -(sin(.expr1) * (3 * x^2))
    attr(.value, "gradient") <- .grad
    .value
})

通过查看,您可以看到它如何解析函数并使用链式规则。进行第一年微积分运算的函数都应该能够完成!deriv()在某些情况下,该函数的第一个参数是R表达式(它是实际的R类型)x。第二个参数是与之对应的派生变量的名称,此处为"x"

想看到真正整洁的东西吗?将上述内容分配给变量,例如dx。将变量定义x为数值向量。然后提交eval(dx)。R评估x


长度19:

c(matrix(1,3,3),"a")

在R中 c() “ combine”或“ concatenate”的缩写,根据其参数创建一个向量。向量的元素必须具有相同的类型,并且所有元素的长度都为1。但是,R不会对您生气,而是将具有结构的元素(在这种情况下为矩阵)弄平,并将所有内容转换为相同的类型。

如果参数c()仅包含一个类型,则不会进行类型转换,例如,如果所有参数均为逻辑(TRUEFALSE),则向量将全部为逻辑。如果包含逻辑和数字,则将全部为数字。如果包含字符和其他任何内容,则将全部为字符。因此,我们的代码段为我们提供了以下功能:

> c(matrix(1,3,3),"a")
[1] "1" "1" "1" "1" "1" "1" "1" "1" "1" "a"

请注意,将3 x 3矩阵展平,并且添加“ a”会使所有内容变成字符。


长度18:

(1-1/3-1/3-1/3)==0

关于机器精度的一课。这返回FALSE


长度17:

example(readline)

example()函数将为您提供有关如何使用任何内置函数的示例。如果您需要了解使用方法readline(),R为您提供了一个自鸣得意的答案。

> example(readline)

readln> fun <- function() {
readln+   ANSWER <- readline("Are you a satisfied R user? ")
readln+   ## a better version would check the answer less cursorily, and
readln+   ## perhaps re-prompt
readln+   if (substr(ANSWER, 1, 1) == "n")
readln+     cat("This is impossible.  YOU LIED!\n")
readln+   else
readln+     cat("I knew it.\n")
readln+ }

readln> if(interactive()) fun()
Are you a satisfied R user?

谦虚的方式,R。


长度16

acf(lh,t="part")

acf()函数返回时间序列的自相关函数。lh是R附带的数据集。其描述:

一个定期的时间序列,以48分钟的间隔从人类女性那里以10分钟的间隔给出血液样本中的黄体生成素。

在此示例中,部分匹配使用了两次:一次是使用function参数,一次是使用传递给参数的字符串值。完整的参数名称是type和公认的值是"correlation""covariance""partial"。只需要提供足够的字符串来唯一地标识它,因此我们可以使用"part"for "partial",这为我们提供了部分自相关函数(PACF)。

在此处输入图片说明


长度15:

p3d(bunny,p=99)

我们再次看到臭名昭著的兔子(11)。该onion软件包使用3D绘图功能为我们提供了一种更好的方式来查看有史以来最有用的数据集p3d()。这persp()在后台调用基础图形函数,该函数采用旋转参数phi。使用参数名称的部分匹配(13),我们可以指定只p=到位phi=

在此处输入图片说明


长度14:

stats:::rgamma

R是开源的,但您不必是查看源代码的向导;您只需输入包名称和要查看其代码的函数,并用三个冒号(:::)分隔即可。这为您提供了定义rgamma()函数的代码,该函数生成与gamma分布的随机偏差。提交此内容将提供:

function (n, shape, rate = 1, scale = 1/rate)
{
    if (!missing(rate) && !missing(scale)) {
        if (abs(rate * scale - 1) < 1e-15)
            warning("specify 'rate' or 'scale' but not both")
        else stop("specify 'rate' or 'scale' but not both")
    }
    .External(C_rgamma, n, shape, scale)
}
<bytecode: 0x00000000098cd168>
<environment: namespace:stats>

请注意,它使用一个函数.External()。这就要求用其它语言编写,典型地C和Fortran,其包括许多R的定位的基础的语言的功能的是源代码并采取一些魔术的。编辑: @Vlo指出,凡人确实可以查看使用.Internal().Primitive()使用该pryr程序包调用的底层C代码。谢谢@Vlo!


长度13:

sample(9,s=4)

看起来不多,但是它体现了R中一个强大的概念:函数参数的部分匹配sample()函数中的命名参数是sizereplaceprob,但是您只需要提供足够的命名参数字母即可唯一地标识它。因此,对于sample(),您可以使用s=代替,size=因为没有其他参数名称以字母“ s”开头。这里的代码从1到9的整数中选择大小为4的随机样本。


长度12:

LETTERS[-pi]

有一个称为的内置向量LETTERS,其中包含所有大写英文字母的字母顺序。与许多其他语言不同,可以使用浮点数对向量进行索引。没什么激动人心的事。R仅取整数部分。-在向量的索引之前使用会从向量中删除具有该索引的元素。pi是一个内置常数,您可以猜到它是无理数π。因此,这将从向量中删除元素3,并通过省略“ C”返回“ A”至“ Z”。


长度11:

plot(bunny)

onion包中,有一个名为数据集bunny。绘制它可以为您提供历史上最有用的图形:

在此处输入图片说明


长度10:

????sample

假设您真的对该sample()功能感到困惑,并且非常需要帮助。?sample您可以打出四个问号,而不是像通常那样拉起R手册页。R听到您的困境并尝试提供帮助...

Contacting Delphi...the oracle is unavailable.
We apologize for any inconvenience.

唉。


长度9:

isTRUE(1)

乍一看,这似乎违背了R基本包其余部分中的约定is,即函数名称中的后一个单词用分隔.。但是,这仅适用于参数是否为某种类型的逻辑测试,如下(8)所示。在这种情况下,我们正在测试是否为TRUE,这不是一种类型。这使用的严格定义TRUE,即1在通常意义上不是“ true”。isTRUE(1)返回FALSE


长度8:

is.na(8)

与大多数其他编程语言不同.,函数和变量名称中的有效字符是有效字符。它不表示任何类型的方法或层次结构;它只是名称的一部分。该is.na()函数检查其参数是否为NA(missing)并返回TRUEFALSE


长度7:

stop(7)

这会将输入作为错误消息发出错误。如果在函数内部调用,函数执行将停止。但是在函数外部调用它不会停止脚本。在这种情况下,输出为Error: 7


长度6:

x < -1

尽管这似乎微不足道,但它显示了对赋值运算符的主要批评<-:即,含义根据空格的位置而变化。如前所述,x <- 1将1分配给x。如上分隔<-使用单个空格会将其更改为是否x小于-1 的逻辑测试。因此,许多人更喜欢=分配。


长度5:

x<<-1

<-除外类似,<<-无论当前范围如何,始终将变量分配给全局范围。


长度4:

x<-1

R用于<-在当前范围内分配变量。此代码段将值分配给1 x


长度3:

!0i

!操作者为R为“不”,和0i是复数0+0i,AKA 0在复平面。TRUE由于0为假,因此提交此语句将返回。


长度2:

NA

这将返回特殊的R值NA,代表“不可用”,表示缺少值。


长度1:

T

这返回TRUE。在R中,TF分别是布尔值TRUE和的同义词FALSE


耶R "!"(T)
Vlo 2015年

@Vlo:"!"(T)计算为FALSE。但是,语句“ Yay R”绝不会错误。;)
Alex A.

如何为更多条目投票更多????“定位该源代码并采取一些魔术的”是平凡的.Internal.Primitive- >pryr::show_c_source(.Primitive("sum"))
VLO

@Vlo:我没听说过这个pryr包裹。很酷!感谢您指出了这一点。非常高兴您喜欢到目前为止的参赛作品,感谢您的支持。:)
Alex A.

2
@ Jemus42啊,看来您需要先做data(bunny)
Alex A.

75

脑干

类固醇: Brainfuck(也称为brainf * ck)是一种实验性的深奥语言,由创建,用于创建有史以来最小的图灵完整语言解释器,并且是同类中最著名的语言。它只有八个命令,易于学习,但难于使用。

Brainf * ck的磁带库具有30000个单元格和一个可移动指针,可以像这样可视化:

0 0 0 0 0 0
    ^

随着 ^表示指针字符,0的表示用于每个单元的值。

Brainfuck有八条指令:

Instruction  C Equivalent              Description
+            mem[ptr]++;               Add one to the value under the cell
-            mem[ptr]--;               Subtract one from the value under the cell
>            ptr++;                    Go on cell to the right
<            ptr--;                    Go on cell to the left
,            mem[ptr] = getchar();     Read a ASCII character from input and put the result in the value under the cell
.            putchar(mem[ptr]);        Write a ASCII character to the output using the value under the cell
[            while (mem[ptr]) {        Start a while loop: Continue to matching ']' when value under the cell is 0
]            }                         End a while loop: Go back to matching '[' when value under the cell is NOT 0

脑干到C:

#include <stdlib.h>

int main(void) {
    unsigned char* mem = calloc(30000, sizeof(unsigned char));
    unsigned int ptr = 0;

    // Put your brainfuck code here, converted to the matching expressions under "C equivalent"

    return 0;
}

长度1片段

读取一个字符并将其放在当前单元格中。

,

存储器(带输入:abc

0 0 97 0 0 0
    ^

长度2片段

将一个添加到当前单元格,然后将指针向右移动。

+>

记忆

0 0 1 0 0 0
      ^

长度3片段

从当前单元格中删除一个,直到它为零;将当前单元格设置为零

[-]

可能的内存:

内存:(之前)

0 0 100 0 0 0
    ^

内存:(之后)

0 0 0 0 0 0
    ^

长度4片段

评论:在动脑筋中,所有非指令都将被忽略。因此,以下程序是一个完全有效(但为空)的“头脑操”程序:

Hey!

长度5片段

一个简单的cat程序(将输入写入输出)

,[.,]

感谢tomsmede的评论

长度6片段

将当前单元格的值移到右边的单元格(假设右边的单元格为0,否则它将当前单元格的值添加到右边单元格的值):

[>+<-]

通常,人们使用此代码来移动变量。

内存:(之前)

10 0 100 0 0 0
     ^

内存:(之后)

10 0 0 100 0 0
     ^

长度25片段

反转六个字符的输入并打印,然后打印每个ASCII字符(N-1).. 1(其中N是第一个输入字符的值)。

,>,>,>,>,>,.<.<.<.<.<[.-]

长度53片段

main(){i=0;j=0;if(i>=0){if(j<=i)i+=1;i-=1;}return 0;}

这个缩小的C程序也是变相的Brainfuck程序,反之亦然!实际上,他们(几乎)做同样的事情。这是不带“注释”(C代码)的Brainfuck代码。

><+-

让我解释一下Brainfuck代码(和C代码)。如您所见,它使用两个单元格(ij)。它将第一个单元格递增(递增i1)。然后,它递减同一单元格(递减i1)。

这只是一些源代码能够被编译为两种不同语言并(实际上)运行相同语言的愚蠢示例。


2
,[.,]-5个字符,cat程序
断定

13
这可能是我见过的最好的“ Brainfuck 101”。
hoosierEE 2015年

长度6:将总和放在右边的单元格中,将左边的零置零。不动吧?
Filip Haglund

在长度6中添加了一个虚拟变量,以更好地解释该概念。该程序实际上会将3号单元格添加到4号单元格中,并使3号单元格为
0。– YoYoYonnY 2015年

58票-您能更新吗?:)
Conor O'Brien

65

C ++

凭借其预处理器,模板,lambda,类型特征和无数其他人无法完全理解的复杂功能,C ++的每一代新标准都重新发现了C ++。通过利用其在编译时进行处理的多种方式,人们可以编写零开销的抽象程序,例如库,该库允许将物理单元附加到数字数据类型,以便在编译时检查其合理性(例如,您不能将kg* 的结果分配mN

长度1

#

通常会引入预处理器语句, #可以自己站在一行上。从本质上讲,它什么都没有,而且似乎也很陌生,以至于我看到的大多数语法突出显示都不知道。

长度2

%:

当然,并不是每个人都有#钥匙,因此C ++很慷慨(好吧,它实际上是从远古的C继承过来的),允许您使用此替代标记(也称为digraph)编写它

长度3

??=

这是有关C ++的历史课程。尽管实现可以支持它们,但如今这些日子已不再有效,这是三部曲。这个序列被翻译成#在支持系统上,但是为了不干扰原始字符串文字,在这些序列中不允许这样做。实现可以选择完全放弃支持。

长度4

auto

是较新的发明(自C ++ 11起),使处理通用代码变得容易。它用于推导表达式的类型,并且从C ++ 14开始,它甚至可以用于推导lambda参数和函数的返回类型。

长度5

 catch

是C ++中存在的许多其他语言也都知道的关键字,但是优秀的惯用C ++程序员几乎永远不会使用它。惯用的C ++的构造函数和析构函数使用一种被广泛称为RAII(资源获取即初始化)的原则,或者有时我更喜欢用它来称呼它:SBRM(范围绑定资源管理)。由于使用了诸如智能指针之类的类,因此可以将动态分配的资源(不仅是内存!)的生命周期绑定到其他对象。当这些对象超出范围时(例如,抛出异常),这些对象将自动清理资源。这允许不需要使用的安全和易于使用的异常代码catch

长度6

[](){}

[]{}()

正如斯蒂芬在评论中提到的那样,您可以将其[]{}用作最短的lambda对象,因此这是调用 lambda 的最短形式。以下文本适用于旧版本:

可能是lambda的最短形式。C ++中的Lambda是对象(具有实现定义的类型),它们可以捕获它们创建时所使用的范围的一部分([]语法对此进行控制),并且是可调用的((()语法对此进行控制))。他们的代码({}部分)可以访问这些变量,就好像它们在其范围之内一样。借助C ++ 14中引入的可选返回类型推导和自动参数推导,它们成为可用于所有可调用标准库算法工具(例如,第三个std :: sort参数)。

长度7

virtual

是在C ++(面向对象编程的基本模块之一)中开始使用运行时多态性的关键字。这遵循“不为您不使用的东西付钱”的原则,在其他语言中,默认情况下所有功能都是虚拟的。作为一种多范式语言,对于认为“ C ++是面向对象”的人们看到几乎不使用该关键字的程序或库(例如,因为它们遵循通用编程原理),可能会感到惊讶。

长度8

override

与virtual关键字一起工作override是C ++的后续新增功能之一,可使编译器为您完成更多工作。通过使用它,您可以表达在基类中重写虚拟函数的意图,如果您犯了一个错误并且该类没有指定的函数,则编译器将出错。通常,如果您的代码表达了意图,而不是摆弄代码,则被认为是好的样式。

长度9

constexpr

也是C ++的后续版本,constexpr允许程序员表示函数或变量,它们在编译时是已知的,应该在编译时可计算。这允许将这些函数用于需要编译时表达式的上下文中(例如,作为模板参数或数组大小)。许多标准库函数(如果可能)已经是constexpr,因此可以在此处使用。

长度10

for(i:c){}

是一个完整的循环,遍历一个容器,或一个类似容器的容器,该容器支持std::beginstd::end获取迭代器(包括C样式数组)。它基本上等同于for(auto __i = std::begin(c); __i != std::end(c); ++__i){ auto& i = *__i; }。这样可以轻松循环通用代码。

长度11

void f()&&;

是在成员函数和可以调用的对象上声明属性的新方法。在以前的C ++版本中,我们只能选择void f() const;告诉编译器能够在const对象上调用该函数(因此,如果没有const,则不能在非const对象上调用它们)。现在我们以同样的方式&&使用r值引用的语法来调用rvalue上的那些函数。

长度12

int main(){}

这可能是您可以编译链接并运行的最短的完整程序。它将不执行任何操作并返回0。此返回是C ++中可能遇到的许多特殊情况之一。通常不返回任何内容都是未定义的行为,但是对于入口点函数main,不返回任何内容表示返回0。

长度13

auto f()->int

是一种声明函数返回类型的相当新的方法。通常,如果您已经知道类型,则不会执行此操作,但是在通用编程中,很多情况下类型取决于模板参数和您使用的变量。这样,可以更轻松地访问template<class T> auto f( const T& t ) -> decltype(t.foo())而不是中的参数template<class T> decltype(std::declval<T>().foo()) g( const T& t ) { return t.foo(); }


2
我建议将其;用作备用的1个字符的代码段,因为它不是预处理程序宏,并且您完全可以在C ++中使用1个字符的语句这一事实似乎令人困惑。
Joe Z.

1
[](){}不是lambda的最短形式:由于参数列表为空,因此可以省略。因此[]{}是最短的λ。平凡,[]{}()是一个lambda ;-)的最短执行ideone.com/k8fAvs
斯特凡

@stefan:的确,我总是忘记了它,因为它看起来不像当时的功能;)我将其添加到了答案中。
PlasmaHH 2015年

@PlasmaHH我绝对讨厌它,因为确实它看起来不像一个函数。;-)
stefan

59

正则表达式

长度2片段

[]

JavaScript:空字符类,不匹配任何字符。

PCREJavaPythonreRuby(在2.0版上测试):语法错误。

长度1片段

.

.我有机会看到的各种口味的,都称为dot-all。

它匹配什么?

I̧n͟g̨͜e҉̡͞n̵͢e͜͝r̷͝a͘l̢҉,̴.̸̸̡̡̢́͟m͞ąt̴̨c͞h̛e͢͡s̶͘s̛͜͠a͘n͢ỳ̸͢c̵̡hár͘͝a̕͢ćt̷̀e͏̀͠r̷̀n̢̕͜e҉w̢̕͜͡l̶

JavaPattern:在默认模式下,点号-all匹配任何代码点,这5个代码点除外\r\n\u0085\u2028\u2029。随着UNIX_LINES模式上(但没有DOTALL),点所有的任何代码点相匹配,除\n。随着DOTALL对模式,点所有的任何代码点一致。从Java 5开始,Pattern在代码点上进行操作,因此,星号字符由全点匹配。

Pythonre(在2.7.8和3.2.5上测试,在3.3+上可能有所不同):在默认模式下,dot-all匹配任何UTF-16代码单元(包括0000至FFFF)\nre.DOTALL解除异常并使之.与任何UTF-16代码单元匹配。在这些版本中,它们re在UTF-16代码单元上运行,因此.只能在星体平面中匹配一个字符的代码单元。

.NET:与Python相同。.NET中的全点模式称为Singleline

JavaScript(C ++ 11 <regex>:在默认模式下,点号匹配所有UTF-16代码单元,但这4个代码点除外\n\r\u2028\u2029。随着s国旗,点全部匹配任何UTF-16代码单元。JavaScript还可以在UTF-16代码单元上运行。

PCRE:根据构建选项的不同,dot-all可以在默认模式下排除\r\n\r\n,或所有3个CR LF序列或任何Unicode换行序列。在默认模式下,引擎以代码单元(可以是8位,16位或32位代码单元)运行,因此点号-all匹配除换行序列以外的任何代码单元。在UTF模式下,引擎在代码点上运行,因此点号-all匹配除换行符序列以外的任何代码点。点全模式称为PCRE_DOTALL

PHP(在ideone上测试):PCRE,编译为UTF-8库,\n默认情况下是唯一的换行序列。全点模式可通过s标志访问。

Postgres:在默认模式下,dot-all匹配任何代码点,无一例外。

Ruby(已在2.0.0版上测试):在默认模式下,.匹配除之外的任何代码点\n。全点模式可通过m标志(!)访问。

s 标志用于指示Ruby中的Windows-31J编码。


类固醇

Ŗ͞e̡͟҉ǵ͟͢e̴̢͘͡x̡́͞ ̛̀҉҉̢c҉̷̨a̸̛͞n҉̛͠ ̷̸̀p̴͠͡҉̵ą̧͜͢r̸̸̷̢͝s̢̀͡e̷̷̷͘͞ ̨̧̀H̨̧͜͜T̷​​͞M̷̛͜L͢。̴̡́在我之后重复。R̶̶̢̧̰̞̻̮̳̦̥ͭͯ̓̈ͯͤ̇͊͊͟ĕ̹̩̪͈͈͍̗͎̝͚̽̈ͨ̐̽ͪͮ̍͐ͮͧ̔̏̓ͣĝ̵̢̢̖̤̜̭͔͊͒ͦ͛ͤ͗ͬͧͪ̾͘͟eͦ̄ͭ̑̾҉̨̨̝̬̹̘̭͔͟͢x̸̣̻͓̠͈͕̥̜͚̝̫͚̳̦͈̥̬̺͇̾̍ͦ̑̈̋̌̉͊ͮ͗̄̆̒ͧͧ͐ͮ̌ͤ̈̒̆ͣ̈̏̔͊̐̚̚ç̨̬̪̳̦͎̖͕̦͔ͨ̿̓̈ȁ̸̳̺̠̭ͮ̓̐͘̕͜͡ņ̨̫͔͍̬̤̘͎͚̣̟̦͍̜ͭͭ̈ͦ̈̽͗ͥ̑͝͡解析͉̭̫̰͔̝͓̼̮͚̻͎͎͉̐͗͗͊̇ͣ͒͗͑̆͐̐ͬ͛ͮ͝H̢̥͕̼͓̫͙̺̼̮ͣͦ̍ͨ͒̔̌T̪̦̻̦͖̞̤͒̑ͭ̐̑ͭͣ͐̒̉͊͜͜M̞̪͇͕̩͉͗ͧ̌ͯ͋̉̍ͭ̓̇̐̌͜͠Ĺ̷̨̳̘̯͚͓͛͌ͭ̉̍.ͯ͆̊ ҉


35
对于任何无法获得事实证明的人,我感到很难过。
Robobenklein

6
@robobenklein我知道一种让您痛苦的秘方:启发我们吧!
瑕疵的

24
@flawr对于那些不知道著名问题的人:您正在寻找的第一个答案在stackoverflow.com/questions/1732348/…
Robobenklein

1
您可以阅读Zalgo的文字,但不要在两个方向上都太重视它们。盲目地遵循Zalgo的方式是很明显的错误,但是Zalgo文本并非一直都是错误的。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

12
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳,您不是要使用所有这些投票来向我们展示如何解析HTML吗?
mbomb007

57

Ĵ

PS:现在,片段链接到tryJ.tk,让您可以在浏览器中运行在JavaScript中运行的片段,而无需安装J。

PPS:我调换了订单;这对于加入的人们以及以后的参考更有意义。

PPS:我认为,由于时间限制,我每天会添加一个摘要

事实:

J是APL的后代(有关家族史,请参见此处)减去有趣的字符集。

长度1片段

_

当附加到数字文字(与动词相反)时,J _既用作无穷大指标又用作否定指示符-

长度2片段

a.

a.被称为Alphabet,包含所有1字节字符。因此,J不包含像之类的函数atoi,因为它们是字母中的简单查找:a. i. 'z' =122

长度3片段

i.9

i.一元化时用于整数(即,仅一个参数,右一个参数,通常称为y)。当用于dyadically它充当的指数,如在上面的例子。

长度4片段

!!6x

J支持任意精度整数和有理数。这将计算6阶乘的阶乘(1747数字)。

长度5片段

^.^:_ 

一个密集的...首先,动词(如J调用函数)按主题进行组织。所有^动词都与取幂相关联。^用于取幂exp使用时,^.用于对数^:是一个特殊的幂次合(高阶函数),该函数应用多次函数。当右实参为infinity(_)时,执行其左实参(在的例子中^.在其自己的输出),直到它收敛。实际上,^.^:_是一个动词解决x = ln(x)当应用于任何参数,但是如图1所示,从而产生0.318132j1.33724

长度6片段

^0j1p1

或同等

^o.0j1

欧拉公式在J.如上引用,^exp()。除了任意精度的整数和有理数之外,它还支持pi和复数的幂以及它们的组合作为文字。0j1p1意味着(0 + j) * pi ^ 1

长度7片段

+/&.:*:

采取任何向量的2范数的动词。这说明了两件事:

  • 所述插入副词接通添加动词+通过其自变量的每个元素之间将其插入到求和。因此(0+1+2+3) = +/ i.4

  • 连词Under在用作时v &.: u y等同于vi u v y,其中正面(通常vi反面)。

是的,J知道函数逆。将这些词组合起来,可以使摘录中的动词等同于%: @: (+/) @: *:,或sqrt(sum(y.^2))例如在Matlab中。

长度8片段

$#:I.@:,

由3个动词不参照参数。这允许在J中称为默认(无点)编程。f g h在单例情况下(如本例所示),叉子等效于(f y) g (h y)。作为分叉,多维数组是J的固有部分。“索引”返回向量中1的索引,但不会扩展到更高的维度。本示例使用ShapeAntibaseI.@:,作为实现I.的fork的3个分支,用于更高维的数组,例如:

 ($#:I.@:,) 5 = i. 5 5 NB. indices of 5 in i. 5 5

长度9片段

<"1 i.4 6 

盒装数组是J中的一种数据类型,允许将异构内容(类型和大小)组合为一个值。Monadic < 它的参数。等级是J中的中心概念,它允许将动词自动扩展到更高维度的数组。名词和动词都具有等级。

名词等级是动词$@$可以告诉您的任何名词的维数。例如i. 2 3 4,一个排列为3的数组。

动词等级是动词将对其应用的等级。每个动词都有一个内在等级,可以使用基本连词查询。v b. 0返回3个数字,表示动词v的单数,左进和右进。

一个动词对等于动词等级的等级的名词单元起作用,并在名词rank-verb rank框架中替换结果。可以使用Rank连词限制动词的等级,如此处所做的那样,将等级1的单元格(行)装箱而不是对等级_进行运算,即。装箱整个数组。有关排名的更多信息,请参见此处

长度10片段

<./ .+~^:_

该摘录是一个动词,用于计算加权有向图上的最短路径。它引入了minimum(<./)和Dot并列。点连接是矩阵乘积的一般化,可以写成+/ . *。通常,u . v等价于u@(v"(1+lv,_))lv是动词v的左秩。或者用词“在u的“左参数单元格”和右参数into的列表中将v应用于结果。(请参阅上面的等级)

因此,内部动词<./ .+~用所有k y(i,j)的最小值替换item y(i,k)+y(k,j)

^:_ 重复此步骤,直到收敛为止。

例如,显示原始和最短路径距离:

(]; <./ .+~^:_ ) wtm=: _6]\0 2 5 _ _ _ _ 0 4 1 3 _ _ _ 0 _ _2 _ _ _ 4 0 _ 5 _ _ _ _1 0 6 _ _ _ _ _ 0

长度11片段

<.@o.10x^99

此代码段引入了特殊的代码:为某些用例专门编写的代码支持某些J代码,这些J代码在解析时可以识别并进行优化;为了更高的精度(如此处的情况)或更高的性能(请参阅特殊组合

该短语给出pi的99位(尽管移了99个小数位)。特殊代码取决于确切的措词,通常等效的代码不如摘要代码那么精确:<.o.10x^99 失去了扩展的精度。

长度12片段

($-.1:)($,)]

有时,您最终会遇到由于选择数据而导致单维运行的情况。这个方便的实用程序在Matlab中称为squeeze,可挤出所有单例尺寸。叉子的左齿会($-.1:)产生所有尺寸,而没有尺寸,而中间的($,)会将已排列的数组重塑为保留的尺寸。正确的尖叉]只是为了使其成为叉子,并引用了正确的参数。

长度13片段

1 :'-u%u d.1'

牛顿法找到可微函数根的近似值。此显式副词将应用于寻求其根的功能,并表示迭代过程的一个步骤。 u是引用该函数的参数,在应用副词后将被替换。d. 是表示符号的合取函数,在这里可以用D.相同的数值代替(但应用于更高等级的函数时有所不同)。结果是一个钩子从参数中减去forku除以其派生)。

例如:

(_2 + *:) (1 :'-u%u d. 1')^:_ ] 1 NB. root of x^2-1; ] is there to avoid combining _ and 1 into an array.

长度14片段

(%-.-*:)t.i.10

Fibonacci级数的前10个数字由的Taylor展开 x / (1 - x - x^2)。分析钩子%-.-*:会得到(y % (-.-*:) y) = (y % ( (1 - y) - *: y)

长度15片段

(#{.+//.)!/~i.9

斐波那契数列的另一种观点。这次从另一个角度来看;从Pascale的三角形'!/~i.9'开始。

/当使用dyadically表示Table时,将绑定到它的动词应用于其参数的每个单元格之间,从而生成参数x和y之间的运算表。在这种情况下!,将其作为合并(或超出)使用~使动词Reflexive,即。也使用它的右参数作为左参数。

副词/.是一个奇怪的副词,它沿数组的反对角线应用它的动词(即,在此处尝试</.!/~i.5

因此,此摘要将帕斯卡三角形上的9个第一个反对角线的和取,这恰好是另一个斐波纳契数列。

长度16片段

;/@~.,. <"0@#/.~:

好的,我添加了一个空格,仅达到16 :)。此代码段演示了使用Key的fork :列出参数中的所有项目及其频率。

x u/. y适用u到在组块y,其中x是唯一的,或者以J: (=x) u@# y,其中,=自分类,其产生在它们出现在位置含有1层的一个布尔数组nub 〜。 在这里它是反射性应用的,因此 对y中的每个唯一项执行Tally,计算出现次数。

由于J中的大多数动词都保持nub顺序(新的唯一项的出现顺序,例如unique在Matlab中相反,Matlab对它的参数进行排序),因此可以将其按频率编排,就像这里所做的那样。;/@~.用于制作所有项目的装箱清单。

需要注意的是由于prevasive概念排名,此代码对任何维度

长度17片段

*./ @:(#&>)@C.@A.

J支持一些特定于置换的原语:

  • 字谜A。以单向方式找到字谜索引,以二元方式将左参数中的字谜索引指定的排列应用于右参数。
  • 循环-置换C. 在置换的直接表示和循环表示之间进行转换。

此代码段是一个动词,需要在左侧(0到之间!#y)和右侧参数y一个要置换的数组anagram索引。然后,它计算周期长度的LCM ,即。返回原始数组的时间段:*./#&>

]n=: (p=:?!9) *./ @:(#&>)@C.@A. i.9 NB. period of a random permutation
p&A.^:n i.9 NB. applies permutation n times.

长度21

<:@(#/.~)@(i.@#@[,I.)

这个小动词来自“ stats / base”加载项,称为直方图。确实做到了,给定bin列表,将]bn-1,bn]bn是bin编号n的起点的间隔内所有数据的出现求和。

它利用间隔索引I.来查找以下间隔:

如果y的形状为x的项,则xI。y是最小的非负j,使得j {x在顺序中跟随y,或者#x如果y在顺序中跟随{:x或x具有没有项目。

如清单16中突出显示的那样,使用key完成每个间隔的总计。

链接到tryj.tk的代码段使用此直方图演示了中心极限定理:

(bins=:(%~>:@i.)10) ( [ (graph=:(,&":"0 1 '#'#"0 1~])) (histogram=:<:@(#/.~)@(i.@#@[,I.)) ) (+/%#) ?5 200 $ 0

长度22

=,&(+/)(~:#[)e.&~.~:#]

J中的乐趣。这实现了一个策划引擎,将秘密数组作为左参数,将猜测作为右。返回的值是白色和黑色钉子的数量。分开:

NB.   ExactMatch: checks where digits correspond:
ExactMatch =: =

NB.   GoodDigitWrongPlace: Copies non-matched numbers from both arguments (left and right
NB.   pairs of parentheses, and checks them for same elements(e.), after eliminating
NB.   doubles in both (&~.)
GoodDigitWrongPlace =: (~: # [) (e.&~.) (~: # ])

NB.   Piecing the conditions together, after summing the booleans:
mm =: ExactMatch ,&(+/) GoodDigitWrongPlace

secret (=,&(+/)(~:#[)e.&~.~:#]) guess

哪里secret和哪里guess是任何数组。实际上,它适用于任何数据类型。


17
好吧,要么您得到一个不可读取的奇怪符号堆,要么您得到了一个不可读的ASCII符号堆。选择你的毒药。
John Dvorak

16
@JanDvorak在您学习所有语言之前,所有语言都是不可读的。;-)
Gareth

5
我以前认为冗长的描述性名称有助于理解代码。然后我 开悟了
hoosierEE 2015年

@Gareth但并不是所有的甚至是不可读之后你学到了他们。不会命名任何名字。
瑕疵

45

RPL(红石编程语言) [和Minecraft]

关于是否可以将其视为一种真正的编程语言,这是一个很大的延伸,但是我们还是会尝试。并且,由于这两种“语言”实际上是相同的,因此我将它们结合起来,有时以“ Minecraft”语言(红石等)发布片段,有时以RPL发布。另外,由于Minecraft中将包含许多摘要,因此我将发布图片链接而不是图片本身,以节省空间。此外,所有代码段都是Minecraft中的编程概念,而不是通用的红石(即,不会出现红石门)。字符将被计数的以字节为单位(在RPL)或作为根据(在的Minecraft)。

类固醇:

RPL是发明家Tossha的编程语言,它将代码转换为Minecraft红石和命令块。它可以执行输入和输出,循环,整数操作,触发函数,根等操作。

长度1:

按钮(1个字节)是Minecraft中最简单的输入形式。它还可以启动或停止“程序”。类似地,杠杆(也是1个字节)是另一种输入形式,并且由于其处于“打开”和“关闭”状态,因此也可以用于启动和停止程序。需要记住的一点是,Minecraft实际上是一种3D编程语言,因此在程序中放置按钮/杠杆的位置会产生很大的不同。

长度2:

红石灯上的按钮几乎是您最基本的猫程序。这需要输入(具有按钮或杆,或者01offon)),并输出它的形式为光从灯如任一01off或者on)。

在此处输入图片说明

长度3:

如下所示,这是最短的源代码修改程序之一(因为您可以在运行时使用Minecraft修改源代码!)。现在,这个特定的程序确实没有用,但是可以将其与其他概念组合起来以创建一些很棒的程序(以更多的投票方式)。运行时,该程序将删除其输入源,并使其自身无法再次运行。 在此处输入图片说明

长度4

该“片段”实际上显示了两个概念:延迟和“非”门。使用某些具有红石刻度延迟的红石元素来进行延迟。红石刻度等于十分之一秒。不同的红石组件具有不同的延迟:火炬具有1rt延迟(1 redstone-tick),比较器具有1rt延迟,中继器可以具有1、2、3或4rt延迟,具体取决于其设置方式。在此示例中,红石中继器设置为4rt延迟。

接下来是NOT门。非门接收输入并将其反相。因此,在此设置中,如果输入关闭,则输出将打开;如果输入打开,则输出将关闭。

长度5

“或”门在Minecraft中非常容易实现。两个输入连接到同一输出。这就对了。没有有趣的诡计或任何东西,这很简单。

在此处输入图片说明

长度6

这是压缩“代码”的技巧。如果您知道两个输入的信号强度足够小而不会干扰相应的输出,则可以将红石连接正确。在下面的示例中,有一个简单的料斗计时器,该计时器在每个料斗中约0.5s内来回传送物品,并连接到输出信号强度为1的比较器。这意味着两个输出不会互相干扰。在示例中,这些灯仅用于演示目的,不计入总块数。

在此处输入图片说明


7
您有13个投票,我可以有10个投票程序吗?
Rɪᴋᴇʀ

4
您的程序实际上都不是用RPL编写的,因此请不要将其照做。这纯粹是Minecraft的“代码”。
mbomb007 '16

2
您有14个程序m8的赤字。我想看看您的想法;)
Conor O'Brien

4
您有21个投票,我可以有15个投票程序吗?
wizzwizz4 2016年

1
您有29个投票,我可以有23个投票程序吗?
bb010g,2016年

42

TI-BASIC

[语言根据使用的计算器而异,但除非另有说明,否则它们将使用TI-84。]

长度31片段

Menu("","1",A,"2",B
Lbl A
Lbl B

这演示了菜单的使用。上面的代码是无用的,因为它什么也没做,但是它们可用于导航程序的不同部分。第一个参数是菜单标题,后跟选项对(显示的字符串后跟1或2个字母的标签)。这是一个更直观的示例:

Menu("CHOOSE VALUE","AREA",A,"CIRCUMFERENCE",C
Lbl A
Disp πR²
Stop
Lbl C
2πR

Lbl也可以用于与分支Goto。菜单有一些使它们烦人的限制,但是:菜单只能有七个,每个标题最多可以有十四个字符,因此整个内容可以放在一个屏幕上。

长度29片段

Real
√(-16
a+bi
Ans
re^θi
Ans

Real(默认情况下处于启用状态)将计算器置于实数模式,因此涉及复数的计算会引发NONREAL ANS错误。处于a+bi模式时,计算器将答案显示为复数(如果适用),因此第二个示例返回4ire^θi模式使用极坐标而不是直角坐标,因此输出4e^(1.570796327i)

长度23片段

If A≥9
Then
1→X
7→Y
End

尽管可以Else声明,但这只是一个简单的条件。如果只是一个陈述ThenEnd则不需要。

长度21片段

(-B+√(B²-4AC))/(2A)→X

每个人的最爱,二次方。X假设a,b和c存储在它们各自的变量中,例如ax 2 + bx + c,则存储二次方程的第一个解。

长度为20片段

Shade(|X/2|-3,5-X²,0

这将使用两个可选参数来阴影化两个函数的交点:x的最小值和最大值以及阴影线的方向和距离。

长度18片段

LinReg(ax+b) L1,L2

在这里,我们计算线性回归方程或与一组点最匹配的线性方程,其中x值作为列表存储在中L1,y 值存储在中L2。还有许多其他回归选项可用,包括二次回归,三次回归和指数回归。

长度17片段

dbd(1.2711,1.2115

这将计算两个日期之间的天数,在此情况下,此日期为网站的开始日期为2011年1月27日,而撰写日期为2015年1月21日。(对于懒惰者来说,这是1455天。)编码日期的方式有些奇怪:DDMM.YY或MM.DDYY,前导零为可选。

长度16片段

For(A,0,5
Disp A

这显示了语言编程方面的两个部分。第一个是您的典型for循环,类似于for(var A=0;a<5;a++)其他语言。(您还应该使用End命令来中断循环。)第二个是不言自明的:A由于循环,它显示,在这种情况下,显示5次。

长度15片段

Y1=|X³-4|
Y2=3X

这是图形计算器的一个众所周知的功能的两个示例:图形方程。您可以在同一平面上绘制10个不同的方程式,并且有许多有用的命令来查找相交,最大值,x的值等。在标准窗口上绘制时,这些方程式如下所示:

图形

长度14片段

[[1,2][34,5]]T

方括号用于制作矩阵,并T转置矩阵:

[[1 34]
 [2 5]]

长度13片段

dayOfWk(9,1,6

找到公元1月6日星期几。输出是一个数字,其中1是星期日,2是星期一,依此类推。这个特定的日期是星期二,因此输出是3

长度12片段

Circle(1,3,5

第一个基本绘图工具,它在图形上绘制一个圆,其中心为(1,3),半径为5。

长度11片段

randInt(0,8

这将生成一个介于0和8之间(含0和8)的(伪)随机整数。第三个可选参数告诉您要生成多少个整数。还有其他几种随机函数,包括一个用于正态分布和二项式分布的函数,一个用于随机矩阵的函数和一个用于无重复的随机有序列表的函数。randInt可以通过存储一个数字作为接种rand2→rand

长度10片段

4>5 or 2≠7

在这里,我们有TI-BASIC的(不)等式和逻辑运算符。不平等语句评估首先0 or 1,和or如果任何一方是真实的返回true,那么这个显示器1

长度9片段

.656▶F◀▶D

这可以从十进制转换为分数,反之亦然,这非常有用。也有专门的▶Frac▶Dec只走一条路的功能。82/125在这种情况下打印。

长度8片段

lcm(14,6

这将打印14和6的最小公倍数,即42。

长度7片段

getDate

不言而喻,在这种情况下,只需将当前系统日期打印为列表即可{2015 1 19}

长度6片段

√({4,9

数组(或列表)用花括号括起来,并用逗号分隔。这与map许多语言的功能相似,在该语言中,它遍历列表的每个元素,并对括号(在本例中为平方根)应用运算,因此结果为{2 3}。请注意,右括号是可选的,因此从现在起将省略它们。

长度5片段

4iii6

我们这里发生了一些很酷的事情。首先,将实数部分4和6相乘,然后将虚数部分相乘:i^3-i。这些乘以-24i。这展示了看起来时髦的并列乘法以及TI-BASIC对虚数的处理。

长度4片段

8°5′

这是8度,5弧分,转换为度为8.0333...

长度3片段

8→T

这显示了如何将数字存储为变量,这有点不寻常,因为数字排在最前面,然后是存储箭头,然后是变量名称。如事实书中所述,θθ也可以用作变量,并且变量只能是一个大写字母。

长度2片段

4M

与Mathematica相似,可以并列相乘,没有*必要。默认情况下,所有变量都初始化为0,因此除非您为该变量存储了其他内容,否则它将输出0(请参见代码段3)。

长度1片段

e

这是欧拉数的常数,显示为2.718281828

类固醇

变量只能存储某些数据类型。例如,AZ(和θ)存储数值,str0str9存储字符串,以及[A][J]存储矩阵(二维数组)。


顺便说一下,小写字母n(not n)也可以用作变量。
Ypnypn

有趣。我从未使用过该变量。
NinjaBearMonkey 2015年

3
一个人可以争论str0是1个字符还是4个字符。TI-BASIC中的所有指令的长度都是1个字符。
Ismael Miguel

我曾考虑过@IsmaelMiguel,但它们是1或2 个字节,因此我决定正常计算字符数。
NinjaBearMonkey 2015年

1
我尊重你的决定。在这种情况下,它很有帮助。我真的很喜欢在我的老式TI-83上进行编程。(我什至设计了一个绘画程序!)
Ismael Miguel

41

GNU Sed

我在自我施加一个更严格的要求-所有的片段将是完整的sed程序。

类固醇

sed 一种图灵完整的语言。 这是一个证明。

长度0片段

我不认为严格要求长度为0的代码段,但是由于它实际上在sed中执行了某些操作,因此它是:

Sed是“流编辑器”,即它从STDIN逐行读取流,进行编辑,然后输出到STDOUT。零长度sed程序只需将STDIN复制到STDOUT。因此,cat实用程序可以通过sed进行仿真。以下是等效的:

cat a.txt b.txt > c.txt

sed '' a.txt b.txt > c.txt

长度1片段

=

该sed程序将每行的行号打印到STDOUT。这大约等于:

nl

要么

cat -n

尽管sed版本将行号放在自己的行上。

长度2片段

5q

q在第5行之后将STDIN复制到STOUT和uit。这等效于:

head -n5

您可能会在这里开始看到一些模式- sed可用于模拟许多标准的core-utils工具。

长度3片段

iHi

insert在每行之前插入“ Hi \ n”。嗯

长度4片段

/a/d

sed的强大功能在于其正则表达式功能。此程序使匹配正则表达式的所有行 ad从流eleted。所有其他行仍将输出到STDOUT。这等效于:

grep -v "a"

长度5片段

:l;bl

这是一个无限循环。我们都喜欢占用CPU的无限循环。定义一个标签l,然后对其进行b牧场(跳转)。广告无限。

长度7片段

s/a/A/g

缺省情况下,sed应用s命令,使其仅与每行的第一个匹配。如果您需要它来匹配(并替换)一行中的每个匹配项,则命令g末尾的标志s将执行此操作。

长度8片段

y/01/10/

很少使用的y命令类似于trshell实用程序(尽管不够灵活)。该程序将用切换所有0s,1反之亦然。

长度9片段

1!G;$p;h

该代码段实际上是8个字节,但是需要sed -n参数来抑制默认输出,因此根据标准代码高尔夫球规则,我将其计为9。此程序反转了流中的行。所以:

sed -n '1!G;$p;h'

完全等同于:

tac

长度10片段

s/[ <TAB>]+$//

这是对(错误的)长度为6的代码段的重新访问。这将从行中剥离尾随空白(空格和TAB)。


2
另请参见有用的-LINE脚本SED,这基本上是我学会了如何sed
亚当·卡茨

您还有更多票。我们可以再加一些吗?
luser droog

2
您的事实404版本。
Wauzl,

1
很好,但是请注意,其中许多使用GNU扩展,它们不是标准扩展名,特别是长度3(标准为i\<newline>Hi<newline>),长度5(标准为sed -e :l -e bl:l<newline>bl<newline)和长度10(需要+转为a *才能使用)。需要注意的是长度为9段-n '1!G;$p;h' 标准的,而tac。:)
通配符

1
@Wildcard是-我已将其限制为GNU sed。
Digital Trauma

39

蟒蛇

mbomb007的帖子中已经包含了大量的Python代码段,但我认为我会加入一些更奇怪的事实)

类固醇

Python是一种动态类型化的语言,着重于可读性。

长度1片段

1

在Python 3中,以上内容True1 == True(和0 == False)方面等效。请注意,这在Python 2中不一定成立,您可以在其中重新定义的值True

长度2片段

<>

<>是等效于的过时比较运算符!=。它仍然可以在Python 2中使用(尽管不鼓励使用),并且已从Python 3中完全删除。

长度3片段

...

Python具有许多内置未使用的功能,但仅出于第三方库的目的而存在。此Ellipsis对象是其中之一,通常用于切片。例如,如果我们具有以下3D numpy数组:

array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])

然后a[..., 0](等于a[:,:,0])给出所有的第一个元素:

array([[1, 4], [7, 10]])

在Python 3中的...文字可以切片语法,好玩让你在的地方使用它作为一个“待办事项”标记之外使用passNotImplemented

def f(x):
    ... # TODO

长度4片段

(1,)

Python中的一个元素元组。

Python有列表(例如[1, 2, 3, 4]),其是可变的,和元组(例如(1, 2, 3, 4)),这是即时可变的。元组的一种常见用法是用作字典键,因为列表不可散列。

初学者常见的错误是忽略上面的逗号,即(1),它只是用括号括起来的数字1。单元素元组是您唯一需要在逗号前加逗号的元组- SyntaxError如果尝试将一个元组放入空元组中(),则会引发a ,并且对于长度至少为2的元组是可选的。

长度5片段

0or x

此代码段中发生了一些事情,所以让我们来看一下!

or就像||许多语言一样。在Python中,A or B发生短路时,如果返回true,则返回A(不求值BA,否则返回B。例如,1 or x总是返回1,因为1总是truthy,如果连工作x没有定义。另一方面,如果定义了if,则0 or x返回,x如果x未定义,则抛出NameError

打高尔夫球时,我们通常可以将空格放在数字和an之间or,例如1 or x变为1or x。这是可能的,因为1or以数字开头,使其成为非法的Python标识符。

但是,有一个例外- 0or神秘地抛出SyntaxError。为什么?因为Python中的八进制文字以0o(例如0o20 == 16)开头,所以解析器在到达r!时就会窒息!

注意:在Python 2中,八进制文字也可以以前导零开头,例如020

长度6片段

*x,y=L

此代码段演示了Python中的一种特殊类型的分配,其中L是列表,元组或任何其他可迭代的类型。

在Python中,您可以像这样“解包”元组和列表:

a,b = [1,2]

这会将1分配给a,将2 分配给b。此语法还用于多重分配,例如

a,b = b,a+b

这在编写计算斐波那契数列的程序时很有用。

如果两边的长度不匹配,则ValueError抛出a。但是,Python 3引入了一种新的语法,扩展了可迭代的拆包(或更通俗地说是“加星标的分配”),它允许您执行以下操作:

*x,y = [1, 2, 3, 4, 5]

这种分配y到最后一个元素,5,并x列表的其余部分,即[1, 2, 3, 4]。您甚至可以执行以下操作:

a,b,*c,d,e = [1, 2, 3, 4, 5, 6, 7]

分配1至a,2至b[3, 4, 5]c,6至d和7至e

长度7片段

zip(*x)

zip 是一个函数,它需要一堆列表,然后将它们压缩:

>>> zip([1, 2, 3], [4, 5, 6])
[(1, 4), (2, 5), (3, 6)]

注意:在Python 3中,将zip返回一个对象,因此,如果您想要上面的列表,则需要将调用包装在其中list()

如果您有两个或多个相关列表,并且想要链接它们各自的条目,那么这是一个非常方便的功能。

现在说您要解压缩列表-您将如何解压缩?我们可以尝试zip再次使用,但是不幸的是,这样做可以:

>>> zip([(1, 4), (2, 5), (3, 6)])
[((1, 4),), ((2, 5),), ((3, 6),)]

问题在于所有内容都在一个列表中,但是zip将各个列表作为单独的函数参数。为了解决这个问题,我们引入了*splat运算符,该运算符包含一个list / tuple / etc。并将它们解压缩为函数参数:

f(*[1,2]) ==> f(1, 2)

结果是:

>>> zip(*[(1, 4), (2, 5), (3, 6)])
[(1, 2, 3), (4, 5, 6)]

长度8片段

x='a''b'

第一次看到这个,我有点退缩–两根弦彼此相邻意味着什么?答案很简单:

>>> x
'ab'

Python只是连接两个字符串!这对于提高可读性非常有用,因为它使您可以像这样分解长字符串(注意周围的括号):

x = ('This is a very long sentence, which would not look very nice '
     'if you tried to fit it all on a single line.')

长度9片段

0!=2 is 2

您可能已经知道Python允许链接比较运算符,因此5 < x <= 7仅当5 < x和时为真x <= 7。如果您不知道……那就感到惊讶!

总之,鲜为人知的事实是,自从is/ is not/ in/ not in也比较运营商,他们可以过链接。换句话说,以上代码等效于(0 != 2) and (2 is 2),即True

注意:由于2 is 2一半is检查两个事物是否是同一对象,而不是两个事物是否具有相同的,所以对一半有一些微妙之处。Python的缓存小整数那么1+1 is 2就是True,但是999+1 is 1000False

长度10片段

x=[];x+=x,

向自己添加列表时会发生什么?如果尝试打印x,则会得到:

[[...]]

幸运的是,Python print足够聪明,不会在尝试打印递归列表时爆炸。然后,我们可以做很多有趣的事情,例如:

>>> x[0][0][0][0][0]
[[...]]
>>> x[0] == x
True

此功能也可用于词典,并且是一种创建带有循环的数据结构(例如图形)的方法。

长度11片段

help(slice)

help功能对于在Python中进行调试非常有用。当在REPL中不带任何参数的情况下调用时,将help()启动一个帮助会话,您可以在其中查找函数/数据类型/等的文档。当使用特定参数调用时,help将提供有关相关项目的信息。

例如,help(slice)给出以下信息(由于它很长,因此被截断了):

Help on class slice in module __builtin__:

class slice(object)
 |  slice(stop)
 |  slice(start, stop[, step])
 |  
 |  Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).
 |  
 |  Methods defined here:
 |  
 |  __cmp__(...)
 |      x.__cmp__(y) <==> cmp(x,y)
 |  
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |
 | ...

至于slice,我们可以看到我们可以创建slice用于索引的对象。例如:

>>> L = list(range(10))
>>> L[slice(2, 5)]         # L[2:5]
[2, 3, 4]
>>> L[slice(2, None)]      # L[2:]
[2, 3, 4, 5, 6, 7, 8, 9]

调试的另一个有用功能是dir(),当不带参数调用时,它将返回当前作用域中的所有名称,而带参数调用时,将返回给定对象的所有属性。

长度12片段

round(5.0/2)

这算什么呢?答案取决于您的Python版本!

在Python 2中,两个整数之间的除法导致整数除法(即5/2 == 2),而在Python 3中,我们得到浮点除法(即5/2 == 2.5)。但是,这是浮点数和整数之间的除法,应始终导致浮点数。那为什么我们会得到不同的结果呢?

如果我们查看round两个Python版本的文档,就会找到答案:

  • Python 2中round抢七通过舍入为0来舍入。
  • Python 3中round抢七通过四舍五入到最接近的偶数整数

换句话说,5.0/2 = 2.5舍入到3在Python 2,但舍入到2在Python 3舍入向最接近偶数听起来不可思议,但它实际上是所谓银行家舍,并试图以同样对待正值和负值,以减少偏差。

长度13片段

class C:__x=1

作为面向对象的,Python具有类。上面是一个C将单个属性__x设置为1的类。

我们可以使用点表示法访问类属性。例如,如果我们有课程

class MyClass(): my_attr = 42

然后打印MyClass.my_attr将得到42,如预期的那样。

但是,如果执行相同的操作并尝试C.__x按上述定义进行访问,则会得到:

AttributeError: type object 'C' has no attribute '__x'

这是怎么回事?C显然具有__x属性!

原因是,以__“私有”变量开头的属性是Python所没有的。Python会修饰以开头的任何属性的名称,并__附加类名称,从而避免名称重用冲突。在上面的示例中,如果我们真的确定要访问,1则必须做

>>> C._C__x
1

长度14片段

NotImplemented

Python不仅具有类,而且还具有运算符重载。例如,您可以上一堂课

class Tiny():
    def __lt__(self, other):
        return True

__lt__小于运算符在哪里。现在,如果我们创建的实例Tiny,我们可以做到这一点

>>> t = Tiny()
>>> t < 1
True
>>> t < "abc"
True

因为我们定义__lt__了总是返回True。请注意,我们也可以

>>> 42 > t
True

但以下中断:

>>> t > 42
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    t > 42
TypeError: unorderable types: Tiny() > int()

等一下,那怎么办?我们没有指定大于的行为Tiny,因此最后一种情况中断并不奇怪。但是,如何int(42)知道它大于我们的Tiny对象呢?

Python有一个内置常数NotImplemented,可以通过比较特殊方法返回。让我们尝试一下:

class Unknown():
    def __gt__(self, other):
        # __gt__ for greater-than
        print("Called me first!")
        return NotImplemented

现在,如果我们创建新类的实例:

>>> u = Unknown()

我们做得到:

>>> t < u
True
>>> u > t
Called me first!
True

正如我们所看到的,发生的事情u > t是Python尝试首先调用大于方法Unknown,发现它没有实现,然后尝试为另一个类(Tiny)尝试小于方法!

长度15片段

x=[],;x[0]+=[1]

这有点有趣。首先,我们将指定x为的是[],元组内部的空列表,即([],)。然后,我们x[0]+=[1]尝试将第二个列表扩展为空列表[1]

现在,请记住列表是可变的,元组是IM可变的-当你试图改变一个不可改变的对象内可变对象会发生什么?

>>> x=[],;x[0]+=[1]
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    x=[],;x[0]+=[1]
TypeError: 'tuple' object does not support item assignment

哦,所以它给出了一个错误,我想这是可以预料的。但是,如果我们尝试打印x怎么办?

>>> x
([1],)

??列表已更改!

如果您对这里发生的事情感到好奇,请务必查看此博客文章

长度16片段

@lru_cache(None)

只需添加缓存!这是Python 3中提供的装饰器的简单示例。

假设我们有以下朴素的斐波那契实现:

def f(n):
    if n < 2: return 1
    return f(n-1) + f(n-2)

正如大多数编程课程的介绍可能会告诉您的那样,这是实现Fibonacci的一种非常不好的方法,导致指数级的运行时间,因为我们实际上只是在基本情况下增加了1。f(10)?瞬间运行。f(32)?花一点时间,但它到达了那里。f(100)?不。

但是,如果我们缓存结果,事情将会变得更快。我们总是可以使用字典作为缓存,但是让我们尝试其他方法:

from functools import lru_cache

@lru_cache(None)
def f(n):
    if n < 2: return 1
    return f(n-1) + f(n-2)

如我们所见,我所做的只是lru_cachefunctools模块导入并添加@lru_cache(None)到函数之前。@表示装饰器,该装饰器环绕一个函数,在这种情况下用于记忆。lru_cache的第一个参数是maxsize,缓存的最大大小–在这里,我们将其设置None为表示没有最大大小。

现在,如果我们尝试使用它:

>>> f(100)
573147844013817084101

而且甚至都不需要一秒钟!

注意:f(1000)导致递归深度错误,但这是另一个故事


Python为is运算符“捕获”了什么范围的小整数?
mbomb007

@ mbomb007从这个问题,这似乎是-5到256你可以尝试-5-1 is -6255+2 is 257测试。
Sp3000 2015年

37

记号

Factoid:我可以用2个upvotes定义Jot,并证明它是图灵完整的8(不使用长度4、6或7)。

长度1

1

这是Jot中两个功能的示例。第一个是空字符串,其值为身份函数。第二个是1,这是Jot的分组运算符。1的计算结果为λxy.[F](xy)lambda演算符号),在(此处为空字符串)[F]之前的程序在哪里1。因此,该程序是λxy.(λz.z)(xy)简化到的功能λxy.xy

长度2

10

现在,我们在Jot中引入另一个符号:0。再次,if [F]表示到目前为止程序的值,从组合逻辑中0求出[F]SK,,S和。我已经定义了整个语言。K

长度5

11100

现在,通过定义从组合逻辑到Jot 的映射,我将证明Jot已经完成。这个Jot程序是K组合器

长度8

11111000

这是S组合器。

长度3

1AB

在这里,A并且B不是Jot的一部分,而是任意表达式的占位符。AB组合逻辑中的表达式映射到1ABin Jot中,AB通过这三个规则进行递归转换。优质教育

长度N

1
10
11
100
101
110
[...]

每个以二进制表示的自然数都是有效的Jot程序。因此,我可以通过算法生成更多任意长度的代码段。只要有足够的赞成票,我就可以解决停顿的问题


2
给出了两次投票。现在定义语言。
John Dvorak

@JanDvorak正在研究...很久以来,我研究了这件事,以至于忘记了所有事情:)
Phil Frost

1
我不知道为什么这应该继续获得更多支持。您只是要生成长度增加的随机二进制数:|
Optimizer

1
您说的是投票数4。但是,我们在这里查看的是“您刚刚生成的随机数”
Optimizer

1
您如何解决停顿问题?我猜它与使用无限(无限数量)程序有关吗?
Filip Haglund

37

重击

类固醇:

自1989年以来,Bash中就出现了极为严重的ShellShock错误,至今已有25年未发现。Bash的许多特质和不一致性使编写Bash的许多乐趣变得无处不在。

长度1片段:

[

test内置别名,允许格式的代码if [ a == b ]; then-实际上[是独立命令,而不是语法元素,并且]纯粹是装饰性的(尽管[必需,但它的要求是任意的,您可以使用来取消它alias [=test)。

长度2片段:

||

or大多数语言中的逻辑一样,但适用于流程。将在之后执行命令||仅在命令返回非零值才。

长度3片段:

x=y

分配。美观且可预测...但是与大多数其他语言不同,不允许有多余的空格。这很有趣,因为您可以在bash中的事物之间的几乎其他任何地方都留有多余的空间,而不仅仅是在=

长度4片段:

$IFS

内部场分离器 -此变量影响Bash如何拆分许多内置操作的数据,例如在for循环中迭代以及从字符串填充数组。正确使用它可能会非常强大。但是通常是导致细微和无法预测的错误的原因。

长度5片段:

${x^}

将字符串替换为x,但将第一个字符大写!如此频繁使用的功能使其具有自己专用的语言语法。

长度6片段:

x=($y)

从字符串或元素y的列表填充数组x,拆分当前IFS设置为的任何内容-默认情况下为空白。高级bash编程的一项非常有用的功能。

长度为7的摘要:

${x[y]}

数组!但是等等,那是什么... y是一个字符串,而不是数字索引?是的,的确,Bash支持关联数组!许多人不知道这一点。您只需declare -A x要先。

长度8片段:

${x##*,}

替换x,直到最后一个,字符(或您指定的任何字符)为止的所有内容。获取csv的最后一个字段很有用-这是您无法轻松完成的事情cut,它仅从左侧开始计数字段。%和%%允许从右侧剪切;%和#是根据它们在美式键盘上的位置选择的,因此很明显哪个表示左,哪个表示右,但这对于不使用美式键盘的每个人都没有太大的价值:)

长度9片段:

[ a = b ]

在大多数其他语言中,比较操作中的单个等于将产生分配形式的意外行为。但是,不在Bash中。不管您做什么,都不要忽略任何空格!

长度10片段:

if [ a=b ]

如果您忘记了必需的空格,就会发生这种情况。不会抛出错误。 始终将返回true-即使ab是未设置的变量,或者它们设置为什么都无所谓-它将始终返回true。考虑类似的代码if [ "$password"="$correctpass" ],看看这种“功能”的潜在乐趣。

长度11片段:

x=${y//a/b}

正则表达式样式的子字符串替换!将x设置为y的值,但将a的每个实例替换为b。

长度为12的摘要:

[[:upper:]]*

模式匹配-你是不是只限于使用*通配符的外壳,你可以使用任何POSIX标准的比赛,例如alnumalphadigit等。

长度13片段:

function x(){

有点C语法已经神秘地出现了!花括号的许多完全不同的用途之一,以及使Bash看起来更像其他语言的可选装饰元素的另一个示例- 此处一个()或一个function可以省略(但不能同时省略)。对于不一致的空格,也更有趣- {强制后面的空格,而不是结束之前的空格},例如function x { y;}

长度14片段:

echo {Z..A..3}

花括号的另一个完全不相关的用法。用指定的步长扩展范围。在这种情况下,将产生从Z到A的每个第3个字母。可用于在不使用seq的情况下生成序列,但不能与变量一起使用,因此功能有限。

长度15片段:

echo {a,b,c,d}x

花括号在序列生成中的另一种相似但不相同的用法;prints ax bx cx dx,对于在单个命令中根据序列或列表生成字符串列表很有用。再次,由于它不能与花括号内的变量一起使用,因此其用途受到限制。


其实]不是纯粹的装饰。[如果最后一个参数不是,它将拒绝运行]
FUZxxl 2015年

是的,但除了化妆品外,它没有其他用途。如果[用其他形式替换test,则]可以在不更改调用的任何其他内容的情况下将其省略-我只是指出这不是实际的bash语法,只是视觉上的糖。
骚乱

您说对了,因为它不是bash语法,但是结尾][语法,您必须提供它,就像必须使用分号终止C中的语句一样。
FUZxxl 2015年

的确,它是强制性的,但与C分号完全不同。对它的要求完全是任意的,就像您只是简单地alias [=test写然后看到的那样if [ 1 = 1; then。但是我将澄清您的措辞以考虑到您的观点:)
Riot 2015年

1
关于function x(){语法:正如您所说,您可以删除括号,但是也可以仅删除function部分。实际上,这就是POSIX shell定义函数的方式,因此它更可移植。您可以用13个字符定义完整功能。例如:x(){ startx;}
kojiro 2015年

37

杀伤人员地雷

类固醇

APL( P在AGC 大号 anguage)开始作为用于通过设计出一种式符号解释器肯艾弗森。设计语言时,人们使用打字机与计算机进行通信。这些字符集受到限制,但由于其结构,可以将多个字符放在同一位置以组成复杂的字符。APL大量使用了此功能,从而使其声名狼藉,成为一种只读语言。

您可以在http://www.tryapl.org上尝试大多数示例。

长度1

这个角色被称为灯罩,由于其形状和从它的存在中获得的启发,它都引入了注释。从历史上看,它是通过过度击打(慢跑)和(击穿鞋)而创建的。

长度2

⍳3

单子函数(一个参数)(iota)生成前几个自然数的向量。例如,前面提到的⍳3将产生1 2 3前三个自然数的向量。在APL的一些实现,它会产生0 1 2相反,这要看价值⎕IO中,太田Ò rigin。

长度3

5\3

与monadic相反,二进\(展开)函数复制右侧参数的次数与复制左侧参数的次数相同。因此,5\3产量3 3 3 3 3。您可能想使用向量参数(例如1 2 3\4 5 6)来看看它的作用。

长度4

A←⍳3

这将分配给A的值⍳3(左箭头)是赋值运算符。赋值不一定是语句中最左边的内容。像函数调用一样解析分配,并产生分配的值以备将来使用。

长度5

∘.×⍨A

三乘三乘法表,即

1 2 3
2 4 6
3 6 9

这有点复杂,所以让我解释一下。⍺∘.f⍵(读:阿尔法小额点˚F欧米加)是外积以上f。外积是应用的结果的一个表f的每个可能对从元件。在此示例中,fis ×(乘)产生一个乘法表。操作者(波浪分音符号)通勤 它的参数,即,⍺f⍨⍵等于⍺f⍵f⍨⍵没有左边的操作数是等于⍵f⍵。如果没有通勤操作员,此代码段将为a∘.×a。外部产品操作员非常灵活;检查您是否替换发生什么事=×

长度6

{×/⍳⍵}

阶乘函数。一对花括号将dfn(动态函数)括起来,即一个匿名函数(参见lambda表达式)。dfn的参数绑定到变量或者仅当dfn被称为单子函数(单参数,而不是二元参数,是两个参数)时绑定到变量。我们适用于右参数,从产生的整数1。的/(斜线)操作者减少,即f/⍵插入f的项之间。例如,+/⍳5is 1+2+3+4+5。在这种情况下,我们将简化为×,得到的项乘积⍳⍵,这只是的阶乘

长度7

2×3*4+5

产量39366⍺*⍵(alpha star omega)被提升为的力量。APL有一个非常简单的优先规则:一切都是从右到左评估的,所有功能都是右关联的。运算符比函数的绑定强,并且从左到右进行求值。因此,与2×(3*(4+5))通常的相比,上面带有显式括号的表达式将被编写(2×(3*4))+5

长度8

¯1+3 3⍴A

此代码段产生

0 1 2
3 4 5
6 7 8

并展示了两个重要的概念:第一个概念是(rho)函数,该函数其右参数重塑为在其左参数中指定的形状。阵列的形状是阵列中每个轴长度的向量。标量的形状是空向量。因此,3 3⍴A重塑A为三乘三矩阵。第二个概念是在此处使用加法的方式:我们在¯1数组中添加(加号1),表示负数(¯是指定负数的前缀,-而是运算符)。这两个操作数具有不同的形状,因此形状较小的操作数将分配到另一个操作数上,从生成的矩阵的每个项目中减去一个。

长度9

+.×⍨3 3⍴A

A,重整为3 x 3的矩阵,再与自身相乘。的.(点)运算符采用两个功能和构造一个内积,其中,所述第一函数表示加法和第二函数乘法。对于布尔矩阵,普通的,旧的矩阵乘法是+.×,一个常见的变式是≠.∧(其中不等于,(上尖号)是逻辑和);可以将许多有趣的事物建模为内部产品,并使用某些运算符代替+×

长度10

(.5×⊢+÷)⍣≡

(阅读:左括号点五乘以右大头钉加除以右括号星号-diæresis相同)使用巴比伦方法计算实数的平方根。左边的参数是您要计算平方根的数字,右边的参数是平方根的初始猜测。我最初想提供一个有意义的初始猜测,但是我用完了所有字符(追加将数字本身用作初始猜测)。

那么这是如何工作的呢?让我们从左边的部分开始(.5×⊢+÷)。此表达式使用源自J的默认符号,后来又移植回Dyalog APL。隐性符号对于初学者来说有点难,所以请仔细阅读本节。+/÷≢“正常”解析规则不能解析为单个语音部分的孤立序列称为“火车”。具有两个或三个功能的序列产生一个函数,并且(通过重复解析),任何长度的功能序列也产生一个函数。三种功能甲列车fgh行为像{(⍺f⍵)g⍺h⍵},即,fh被施加到所得到的功能和这些结果的参数被应用到g。一列数组和两个函数,例如Afg行为类似于{Af⍺g⍵},这是,g应用于结果函数的参数,A并将结果应用于f。一列两个函数也具有语义,该语义在文档中进行了说明,但在本示例中未使用。

在这列特定的火车中,使用了一项新功能(正确定位)。它的行为类似于{⍵},产生正确的论点。因此,整个表达式等于{.5×⍵+⍺÷⍵},这只是巴比伦公式的迭代步骤。很容易看出默许符号对高尔夫球手的好处。它可以让您在适用的情况下剃掉很多珍贵的角色。

最后一个难题是(stardiæresis),运算符。如果正确的参数是一个数组,则f⍣A⍵适用fA次数。例如,f⍣3⍵等于fff⍵。计数可以是负数,在这种情况下,APL会尝试推断反函数f并将其应用。如果正确的参数是一个函数,也f⍣g⍵适用f直到(fY)gY这里Y是重复应用的结果f。值得注意的是,如果g=(等于)或(相同),则f⍣≡计算一个固定点f。这正是巴比伦方法所需要的!我们要迭代直到结果收敛。最后,如果应用到对事物被调用作为二元函数,左边参数绑定到f左侧,即,⍺f⍣g⍵等于(⍺∘f)⍣g⍵,其中A∘f类似的行为{Af⍵}


您还有更多票!我们可以再吃点吗?
luser droog

@luserdroog当然,让我想到更多。
FUZxxl

我可以编辑和扩展吗?
阿达姆,2013年

@Adám是的,请。
FUZxxl

∘.×⍨a 给我一个值错误。我使用正确吗?
Cyoce

37

Matlab的

片段26-遍历矩阵

这是我最近发现的。通常,您在for循环中迭代给定的向量。但是,除了向量,还可以使用矩阵(rand(10)产生一个10x10的矩阵,其数字在0和1之间均匀分布)。

for k=rand(10);disp(k);end

然后,每次迭代显示随机矩阵的一列向量。

片段25-易于绘制

我们知道在matlab中绘制是很容易的,但是有一个超级简单的函数ezplotE-Z知道吗?花了一段时间,直到我终于得到它,因为我Z总是用sed而不是拼写c,等等……)每个人都喜欢椭圆曲线:

ezplot('y^2-x^3+9*x-10.3')

椭圆曲线

片段24-整合

用于积分的老式单词(但仍在数值计算中使用)是“正交”,您能猜出下一个的结果是什么吗?

quad(@(x)4./(1+x.^2),0,1)

摘要23-图片

当然,在必须处理图像(例如医学图像分析)的科学家中,Matlab也很受欢迎,因此这是一个非常方便的功能。第一个参数是图像,第二个参数是angle,第三个可选参数告诉函数将其裁剪为原始大小。

imrotate(rand(99),9,'c')

这里

片段22-音乐

load handel;sound(y,Fs)

听起来像这样(YouTube链接)

片段21-差异化和整合

polyint(polyder(p),c)

通过使用这两个函数,可以轻松地区分和集成多项式。集成时,您可以传递第二个参数,该参数将是常量。

片段20-返回多项式

p=poly(r);cp=poly(A)

是否想要根源为多项式r?容易:p=poly(r)。是否需要矩阵的特征多项式A?容易:cp=poly(A)。所以,roots(p)正是r(或置换r)。

片段19-另一个魔术

fminsearch(fun,x0);

有些人绝对喜欢此功能。这基本上只是在没有任何条件的情况下搜索fun具有初始值x0(可以是向量)的最小值fun。这非常适合拟合无法(或过于懒惰)以区分误差/惩罚/目标函数的小型模型。它使用Nelder-Mead单纯形算法,对于无法进行任何假设的函数而言,该算法非常快。

片段18-多项式简介

p=polyfit(x,y,deg)

Matlab有一个很好的解决多项式的解决方案。这样一来,polyfit您便得到了deg近似平方度的最小二乘多项式x,y。您将获得一个p存储多项式系数的向量,因为这是表示多项式的唯一条件。如果您返回片段15,则可以通过编写来做同样的事情c = polyfit(x,y,2)。因此,例如[1,-2,3]表示多项式x^2 - 2*x+3。当然,还有适合其他基本功能或任意功能的功能。

片段17-角度和不连续性

unwrap(angle(c))

如果要获取复数的“连续”向量的参数,则通常会返回似乎具有不连续性的值。例如angle([-1-0.2i,-1-0.1i,-1,-1+0.1i,-1+0.2i])[-2.94,-3.04,3.14,3.04,2.94]因为angle仅返回-pi和之间的夹角,您会得到帮助pi。该功能unwrap将解决这个问题!如果您遇到这样的不连续性,它只会添加的倍数2*pi以删除那些不连续性:'[-2.94,-3.04,-3.14,-3.24,-3.34]'这甚至适用于二维矩阵!如果仅用负的实数绘制复数的参数,则将获得第一个图形,而获得第一个图像,展开则将获得第二个图像:

没有拆开 带包装

[x,y] = meshgrid(-1:0.01:0,-0.5:0.01:0.5);
z = x+i*y;
imagesc(angle(z))
imagesc(unwrap(angle(z)))

摘要16-标量产品

[1;2;3]'*[4;5;6]

当然有内置的方法(如dot),但是使用矩阵变换运算符'就这么简单。如果你不知道你是否有行或列向量,你可以只使用a(:)'*b(:)其中a(:)总是返回的列向量。

片段15-线性最小二乘法,使用魔术棒的丑陋方法

[x.^2,x,x.^0]\y

x是具有x轴y值(嘈杂的y值)的(列)向量。键入c=[x.^2,x,x.^0]\y,您将得到2次多项式的系数。当然,您可以使用matlab数十亿个内置拟合函数之一(多么无聊),为什么不使用魔术棒呢?=)

x = (-1:0.1:2)';
y = 3*x.^2-2*x+1+randn(size(x)); %add some gaussian (normal) noise
A = [x.^2,x,x.^0];
c = A\y              %output: c = ]3.0049; -2.3484; 1.1852]
plot(x,y,'x',x,A*c,'-')

林雷格

片段14-图形

gplot(graph,x)

这就是如何绘制图形。graph应该包含一个正方形邻接矩阵,并且x应该是一个nx2矩阵,其中包含每个节点的坐标。让我们制作一个随机图:(graph = triu( rand(8)>.7)制作一个包含0和1的矩阵,只得到有趣图的上三角)。x = rand(8,2)然后以一些奇特的风格进行绘制gplot(graph,x,'k-.d')

图形 (我宣布这是现代艺术。)

片段13-Meshgrid

meshgrid(a,b)

这是最强大的功能之一,简单但有用。如果要根据两个变量绘制实值函数,则只需为x轴定义一个向量,为y轴定义一个向量(a和b)。然后,使用meshgrid,可以创建大小为len(a)x len(b)的两个矩阵,其中一个矩阵仅将向量a作为列,而另一个矩阵仅将列b作为向量。用法示例:(a = -3:0.2:3;[x,y]=meshgrid(a)如果两个向量都相同,则只需传递一个就足够了。)然后您可以键入z=x.^2+-y.^2和例如mesh(x,y,z)。这适用于任意数量的尺寸!因此,这不仅适用于绘图,而且还适用于获取不同向量的所有可能组合等。(因此,如果您想创建一种新的代码高尔夫语言,则应该在其中,只需确保使用较短的语言即可。函数名称...)

啮合

摘要12-绘图

plot(x,x.^2)

取一个向量x=-3:0.5:3plot剩下的就做。还有很多用于绘制的函数,这只是您可以一直使用的非常基本的函数。写入就足够了plot(v),其中的数据v将相对于数组索引进行绘制。这有多简单?如果要为绘图设置样式,只需添加一个字符串作为第三个参数即可:例如,'r:o'将在数据点周围绘制一条带圆圈的红色虚线。如果要多个图,只需添加更多参数,或使用矩阵代替向量。万无一失。情节

片段11-功能句柄

f=@(x,y)x+y

这是一个存储在中的函数句柄的示例f。现在您可以致电f(1,2)并获取3。matlab中的函数句柄对于数学函数(例如,绘图)非常有用,您可以在一行中定义它们。但是一个缺点是您不能有条件的或分段的(因此不能递归)。如果需要,则必须使用该function语句并声明一个新函数,并且每个函数都必须存储在单独的文件中...(WHYYYYYY ????)

PS:如果您why在控制台中键入,还会得到另一个有趣的复活节彩蛋:它们具有强大的功能,可以产生如下随机消息:

The tall system manager obeyed some engineer.
The programmer suggested it.
It's your karma.
A tall and good and not excessively rich and bald and very smart and good tall and tall and terrified and rich and not very terrified and smart and tall and young hamster insisted on it.

...如果您不顾一切地问控制台,这将非常令人安慰why...

片段10-我的矩阵看起来如何?

spy(eye(9))

如您所知,现在eye(9)创建9x9身份矩阵。spy只需创建一个显示矩阵的零/非零条目的。但是您也可以将其用于显示任何二进制2d数据。如果您spy不带参数调用,您会得到一个漂亮的复活节彩蛋=)

监视身份 间谍Easteregg

片段9

kron(a,b)

kron函数评估两个矩阵的Kronecker乘积。这对于离散的多维线性算子非常有用。我还时不时地将其用于代码打高尔夫球。您想要a和条目的所有可能的乘积bkron(a,b), 干得好。

片段8

5*a\b.*b

好的,在这里我混合了3个不同的运算符。您可以只使用将任意矩阵乘以标量*。(然后,矩阵的每个条目都将乘以该标量)。而且*还执行矩阵乘法。如果在点前面加一个.*运算符,则该运算符会将两个大小相同但输入明智的矩阵相乘。(这也可以使用除法运算符,例如/和来完成\。)

接下来,反斜杠运算符可以用作左除法(与/您惯常的右除法相反),它也是matlab最强大和最典型的运算符:它执行“矩阵除法”。假设您有线性方程组,A*x=b并且想对其求解x,则可以键入x=A\b。并且\(您也可以使用,/但是对于矩阵来说这不太常见),它首先快速分析矩阵,然后使用结果找到最快的算法来执行此求逆运算!(例如参见此处

但是,您也可以将其用于定义不足或定义过度的系统(其中不存在反函数或矩阵不均方的系统,例如最小二乘法)。这确实是matlab的魔杖

片段7

[a,b;c]

好的,看起来并不多,但是它是一个非常方便的工具:矩阵级联。两个表达式之间的逗号表示它们在水平方向上串联在一起(这意味着它们必须具有相同的高度),而分号表示前一个“行”将在下一个“行”之上(按行表示两个分号之间的所有内容)。只是一个简单的例子: a = [1,2;3,4]; b = [5;6]; c =[7,8,9]; d=[a,b;c];将导致相同dd=[1,2,5; 3,5,6; 7,8,9](明白了吗?)。

抢断6

eye(7)

此函数产生完整的7x7身份矩阵。就这么简单。像nan,inf,ones,zeros,rand,randi,randn这样的其他功能也以相同的方式工作。(如果传递两个参数,则可以设置结果矩阵的高度/宽度。)如我稍后将显示的那样,您可以轻松地创建(并以非常直观的方式)连接矩阵(二维数组),这真是太有用了如果您必须用数值​​方法求解偏微分方程,那么这很容易。(当求解PDE时,一般的方法是离散导数运算符,基本上,您将得到需要求解的庞大的线性方程组。这些矩阵通常是稀疏的(只有很少的非零元素)并且具有某种形式的这就是为什么您可以轻松地“组合”所需矩阵的原因。

片段5

a(a>0.5)

我希望您不要对访问数组的所有方式感到厌倦。这显示了获取满足某些条件的数组所有元素的简便方法。在这种情况下,您将获得一个a大于0.5 的所有元素的向量。表达式a>0.5只返回一个大小相等的矩阵,其中a每个矩阵满足条件,每个矩阵不满足条件0

片段4

a(:)

这再次只是将a列的内容作为列向量(nx1矩阵)返回。如果您不知道是将数据存储为列向量还是行向量,或者数据是二维的(例如,用于2d有限差分方法),则此方法很好。

片段3

1:9

您可以使用分号运算符轻松制作矢量(在本例中为1xn矩阵)。在这种情况下,您将得到vector [1,2,3,4,5,6,7,8,9]。这对于访问其他向量的切片也特别好,例如a(2:4)访问向量的第二,第三和第四元素a。您也可以将其以步进大小使用0:0.5:10

片段2

i;

分号禁止输出到控制台。您可以将其视为好事或坏事,但我喜欢将其用于调试工作。只要不用分号禁止输出,任何计算行等都会自动将其结果打印到控制台。

片段1

i

复数是基本数字类型。(很糟糕,许多人i在for循环中用作计数变量,在这种情况下它会被覆盖。)

介绍

对于那些不知道的人,MatLab是一种编程语言(具有不错的IDE,也称为MatLab?),首先要用于数值计算*和数据处理。(有一个名为“ Octave”的开放源代码副本)由于仅**解释,它不是很快,但是其优势在于您可以轻松地操纵矩阵,并且许多算法以优化的方式实现,因此它们运行起来非常快当应用于矩阵时。它也是一种非常容易学习的语言,但是我不建议您将其作为入门语言,因为您会养成非常糟糕的“编程”习惯。

*由于它是一种解释型语言,因此对于昂贵的项目可能会非常慢,但是您具有内置的并行化方法,还可以将多台计算机一起使用来运行程序。但是,如果您真的想快速入门,我认为您仍然需要使用C或Fortran或类似的疯狂工具。但是,仍然有许多已实现的算法(矩阵乘法,线性方程组的求解系统等)进行了高度优化,并且性能良好。但是,如果您在Matlab中本身编写相同的算法,就必须等待=)(当您来自其他语言时,真正不直观的地方是,如果您对操作进行向量化而不是使用for循环,则可以在Matlab中节省大量时间)

**您可以对程序进行某种程度的编译,但是主要是将源代码转换为不可读的文件(对于人类),执行时并没有那么快。


1
我经常i遇到这个问题...设置为某种东西,然后在它不是复杂的单元时遇到意外的行为。
feersum

3
复活节彩蛋不错!如果您输入“ edit spy”,则会发现代码混淆的示例:-)
Abulafia,2015年

1
我去投票支持,然后意识到我已经拥有了。las,只要我能再次投票赞成。让他们来吧,@ flawr!
Alex A.

2
如果您对显示的东西没有灵感,我可以推荐Mathworks博客:Loren Vershure撰写的关于MATLAB的艺术通常,它们描述了可以在字符数限制内显示的最佳实践。出于好奇,请考虑使用Abandon Matlab;对于未记录的功能和功能,您可以转到Yair Altman
Dennis Jaheruddin

1
@flawr-对于事实,还可以提及以下事实:在历史上,MATLAB最初是为新墨西哥大学计算机科学专业的学生创建的(当时Cleve Moler担任主席),是与LINPACKEISPACK(...现在被LAPACK取代)而无需学习FORTRAN...。由于它的易用性,它很快传播到了其他学术机构:)
rayryeng

35

贾姆

在这里尝试以下片段

长度为20的摘要:

q~{]__~z\z<=\~*0>*}*

最小模数计算器。问题摘录:

minmod功能是熟悉的一种变型分钟,出现在偏微分方程斜率限制性高分辨率方案。给定许多坡度,它会选择最平坦的坡度,同时注意坡度之间的相对符号。

该函数接受任意数量的参数。然后将minmod(x 1,x 2,...,x n定义为:

  • min(x 1,x 2,...,x n,如果所有x i都严格为正
  • max(x 1,x 2,...,x n,如果所有x i均为负
  • 0,否则。

长度为18的摘要:

l'[,65>Dm>_el+_$er

ROT13编码器。a-zA-Z通过STDIN 仅移动输入字符串中的字符

长度15片段:

T1{_2$+}ri2-*]p

完整的程序,用于打印N斐波那契数列的第一个数字,N并通过STDIN作为输入提供。

长度为12的摘要:

{{_@\%}h;}:G

一个简单的GCD功能。可以像2706 410 G将GCD放在堆栈上一样使用。

长度11片段:

123456 789#

#是电源操作员。此代码片段显示了CJam的一个很酷的功能,它支持BigInts几乎用于所有数学运算。所以上面代码的输出是

1596346205622537943703716803040694151242100030904924074732295184521676912291137885341977590649991707684635184329980991487148618486236239062505001539322685142817506810040361209550544146292158784625519911512640361780862459268161619223326802388689703997604303632605734938879647069477372395799326590488746599202521617640394227957532720581758771344616555153473551874187964029973716015080326283503474062024803237072761129557356772954771383125420283743787215768524095651476398918270831514362626616089349128838080859262141293069421199363839940462244772673481244848208112002212957221705577938865719802035511067875502253218277834350725436729497351901219311577128600087062378434520948898301738545267825952998284599001356281260973911216650526574435975050678439968995805415462116669892745933523276658479456263859786003695570642598885206779863730608803831608206418317758451327165760242416052588688579435998154295782751455020445483571514197850814391880423853968520336337963918534259580183058727377932419280412466915889059399591196961188841001024998633317094826403760131868252088477018937989608302521450181593409274231460335072324865982559395114735391976545471553525054490202974741119144469523879456646833238659929705233941114530149037245274032070536718197592615630616792756562341411027203615235147973615347081993563361626845258162606172599728677944001956482301240050182368840648532697569098833480384074404562991348377266778603059081932412368912313845464302833428950934701568958836851009236647605585910687215977468114323293396641238344799575626940766355697576957869656153567798618227770961980620119004224798449940378878601283741944503399682599666873704888519152796472231721010884561046439019823540214190109829183178504573391524533915085342799888899681052113605127068137552531204917650779012455136663716975904242872042805633443567570913936237754642040107392687168596924804730637819953463737212774674563401663682370631910559669378413063684132477269578881395521544729393136204246705936061735379354437327940116154383441927197123218522827575163913310005036963663583344508839784971260123709283218409462028161021477446586507813599051643059982983426688872855309396405653159417356549291603532443699350168178837164682957610433456205211423600319694496115159970718912091395232327389520091646132878609779171226748990343349416763319432268713023302555895744813731889452605219001900815755497209921418814092923394321459962373890912709775151652200071533644718727513889263907829300496554849544461628702471995210369421320165755673222520834013956492183306187393652197405863508709529644837118590847002900783148394313160749018413291215958936871830666201928218294362550829287373305552379418641499562597137520153409556227576809855521876196531587454478159211299517511047868125975115347272184123454929507976958328038242400918390689757262398695703472270927183494613959476164389143107240083171566284628032072645081703351075328092783401422849512230275075331561337345714881104575020436358133210849231625973013523497330004645467493618279226202227586584610761439335895760888873155403816627190368675397978355381544497413492223577022267403347927237298551052219150516984577176643706356698282552857754120841266435149587248192704898338826251727748499150285409036076919533685800933215325289882260771526293167171975367192287689881199864600661035143522211647660445960687046757311913589429739868592726372013684511683081229044622752191694278221303073075505531920922815724661725685493922212700535444400760813940151761980008355835574184921854364539924999643954874549857103642483664109073938527328920827803218865362851320233433429604394590974694396314165313743853607609394553133883545319222169958204731303672940856293527174545435349105954532301106962634516087237739490953930886293289854731305112253177512851251930821765454042415085420000484369355605183062368648992392499663861508991984554431113080399485470268940148600970493633737364443822752829774334511729579419931500217970224646496435527826186627011323464848141074486509849545954714213290443775688291020289759390171236344528896

长度10片段:

"`%W_"_W%`

我们已经完成了奎因,让我们反向吧!这是CJam中最短的反向提条之一。反向quine是一种反向打印其源代码的quine。

长度9片段:

5,K,+_&S*

此摘要展示了CJam的许多功能,

5, "create an array of numbers 0 to 4"
K, "create an array of numbers 0 to 19"
+  "List concatination"
_  "Duplicate top stack element"
&  "Set distinct operator in this case"
S* "Join array elements with space character"

长度8片段:

"`_~"`_~

CJam中最小的藜之一。从某种意义上说,这实际上是一条真理,因为它实际上并未以任何方式读取源代码。(在CJam中甚至无法读取源代码)

长度为7的摘要:

"AB"_m*

m*创建前两个堆栈元素的所有笛卡尔乘积。例如,上面的代码将放["AA" "AB" "BA" "BB"]于堆,这是的笛卡尔乘积"AB""AB"

长度6片段:

"_~"_~

漂亮的重复代码。不要运行此:)。这种代码表示形式是CJam中最简单的方法的基础。您将字符串"_~"放在堆栈上,进行复制(_)并对其求值。依次执行相同的操作(并再次..),直到达到最大递归异常为止。

长度5片段:

{A}:F

这是基本功能在CJam中的工作方式,以上表达式将代码块分配{A}给variable F。现在在您的代码中,您可以在F任何地方运行代码块(10在这种情况下,可以获取)

长度4片段:

"A"~

您可以使用来评估任何代码块或字符串,甚至单个字符~。上面的表达式结果为10

长度3片段:

Kmr

典型的随机数生成器,范围从0到K20。

长度2片段:

es

这给出了当前时间戳(从纪元开始的毫秒数)。CJam还具有et更可用格式的本地时间,该格式返回包含当前时间各个部分(天,小时等)的数组。

长度1片段:

A

CJam几乎所有大写字母都作为预定义变量。A是10,B是11,直到K20。Ppi (3.141592653589793)N是换行符,还有许多其他内容。当您需要变量中的初始值,或者甚至需要在1个字节中输入两位数时,这些便会非常方便。

类固醇

CJam受到GolfScript的启发,但在其之上构建了许多功能,包括对网络GET调用的支持:D

PS:我将尝试每5个投票或每2小时(以较早的一个为准)更新答案


您的ROT13示例有一些问题:p但是,我对
奎因

@aditsu是什么问题?
Optimizer

它更改了nz字母的大小写。另外,它无缘无故地带有@,您可以将D放在那里。
aditsu

@aditsu非常确定其ROT 13跨a-zA-Z范围,这就是更改大小写的原因。你看不懂吗?它是您自己的唯一语言:P @有18个字符,我猜:D
Optimizer

那不是ROT13通常所做的。我不明白您为什么要问我是否可以阅读自己的语言,问题不在于了解程序的功能,而在于它没有达到预期的效果。
2015年

34

普通Lisp

Lisp(来自LISt Processing)是当今仍在使用的最古老的语言之一(仅FORTRAN更旧)。它以代码是数据而数据是代码的第一语言而著称。称为同音。它也是第一种具有垃圾回收的语言。最初由约翰·麦卡锡(John McCarthy)在1958年的一篇论文中设计为一种完全理论性的语言,当史蒂夫·罗素(Steve Russel)意识到可以在计算机上实现评估功能时,它成为一种真正的语言。它在人工智能中最流行,并且由于其括号中的括号而立即可以识别出来。Common Lisp旨在将许多较旧的Lisp方言统一为更标准化的形式。

我将尝试使每个代码片段都可以独立运行,尽管不一定有任何价值。另外,由于我使用的是Common Lisp,因此基本概念和很多语法都适用于其他方言,但是某些功能(例如Scheme)无法使用。

长度1

*

由于强调使用S表达式和列表进行编码,因此Lisp中很少有不包含括号(称为原子)的有效表达式。直接输入到REPL(读取评估打印循环)中的任何内容都将被视为变量,并以此进行评估。*保留由REPL打印的先前值。

长度2

()

这是空列表,这是Lisp中最重要的符号之一。Lisp中的每个适当列表都以一个空列表结尾,类似于C中每个适当的字符串以结尾\0

长度3

(*)

这是一个基本的函数调用,由括在括号中的符号组成。Lisp不包含运算符,它们也只是函数。我之所以选择乘法是因为它实际上不是二进制函数。Lisp中的乘法运算符采用不确定数量的参数。如果未提供任何参数,则返回1,用于乘法的标识运算符。

长度4

`(1)

这是一个缺点单元格,这只是表示它是一对元素的另一种方式。在Lisp中,每个列表都由连接到con单元格的cons单元格组成,其中第一个元素(car)是值,第二个元素(the cdr)指向下一个cons单元格。这构成了Lisp基于链表的基础。这个特殊的con单元格有1车,空列表有cdr。

长度7

(not t)

我想谈谈Lisp中的真值。这将返回nil。在Common Lisp中,t是true的符号nil()表示false,并且彼此相等,但是请注意,该定义不是所有Lisp方言的标准;例如,Scheme区分#f'()列表和空列表。

长度9

(cdr ())

就像我之前说过的那样,cdr是列表的tail元素,您可以通过function获得它cdr。同样,您可以使用函数获得head元素,即car car。很简单,对吧?空清单的汽车和cdr都是nil

长度10

(cons 1 2)

最后,有足够的长度来开始使用列表。cons创建一个cons单元格,第一个参数为car,第二个参数为cdr。但是它没有打印出来(1 2),而是给出了(1 . 2)。回到长度为2的代码段,应该以空列表结尾一个正确的列表,因此最后一个cons单元格的cdr应该指向空列表。在这种情况下,最后一个cons单元指向2,因此Lisp告知我们列表不正确,但仍然允许我们执行该列表,例如如何在不使用C的情况下制作C弦\0

长度11

(cons 1 ())

现在,我们创建了第一个格式正确的列表。这是一个单个cons单元格,其车位为,1而cdr为()。您会注意到,对于其他所有列表,我都用反引号/勾号将其引出;任何其他适当的列表都将尝试将其第一个参数评估为一个函数,其余元素作为参数。严格来说,()这不是列表。它是一个由a (和a 组成的符号),代表空列表。Lisp允许您在符号名称中使用几乎所有可打印字符,并使您可以根据需要重新定义任何符号。

长度12

(cdr `(1 2))

这将输出(2),而2不像某些人所猜测的那样输出。记住,每个cdr应该指向另一个cons单元格或空列表。显然2不是空列表,因此它必须是的第一个缺点单元格的汽车2和的cdr ()

长度13

'#1=(1 . #1#)

这将生成仅具有单个值1的循环列表。如果打印,它将永远打印“(1 1 1 1 ...”),因此在实践中可以将其视为无限列表(可以对其进行cdr无限次)来获得始终相同的结果!)除非有人将T全局变量赋值*print-circle*,否则将其打印为#1=(1 . #1#)


最后编辑!很快,有人制作了以甲壳虫为主题的esolang:D
fede s。

1
@fedes。约翰·麦卡锡(John McCarthy),保罗·麦卡尼(Paul McCartney)...这种语言应称为CarthyCartney。

33

GNU Make

我会在这条腿上走一走。我认为这很可能是makePPCG中首次出现。

类固醇

Make可能被认为是一种功能语言。

长度为0的代码段

我认为长度为0的代码段不是必需的,但无论如何这是一个。我认为这可能是所有长度为0的程序中最有用的。对于一个空的Makefile(甚至根本没有Makefile),make仍然有很多内置规则。例如,如果当前目录中存在.c文件,则存在默认的内置规则将.c文件编译为.o或二进制文件。因此,如果我们这样做:

make hello.o

make将找到.c到.o规则并编译hello.c以提供hello.o

同样,如果我们这样做:

make goodbye

如果当前目录中有一个goodbye.c文件,它将被编译为再见二进制文件。

长度1片段

TAB

是的,TAB字符。尽管这本身并不能做很多事情,但在Make中具有重大意义。具体来说,遵循规则中目标定义的所有配方行必须以TAB开头。当TAB和空格混合在一起时,调试makefile时,这会导致各种挫败感。

长度2片段

$@

这是用于配方的自动变量。它将扩展为规则目标的文件名。还有其他有用的自动变量

长度3片段

a:=

最短的简单扩展变量分配。首次解析Makefile时,变量a立即设置为“”。如果相反a=,则递归扩展该赋值,即,将扩展推迟到实际引用该变量的时间。

长度4片段

W:;w

最短的边际有用的完整规则规范。这W使用简单运行wshell命令的规则定义目标。从而

make W

等效于:

w

这是另一种规则语法,因为配方在同一行上跟随目标,并由新行分隔。更常见的是,配方行紧跟在单独的目标行之后,TAB每个配方行以字符开头。

长度5片段

$(@D)

另一个自动变量。与相似$@,但是它扩展到path的目录部分,并删除文件名和尾随/。


也许一些字符串函数像$(basename )$(patsubst )?(例如
luser droog 2013年

32

马氏

长度14片段

}0}1
Mulx
HxHx

该片段展示了更多的Marbelous库,并引入了一个新概念,即多单元板。该Mulx板将两个弹珠作为输入,并输出两个弹珠。进入的最左侧单元格的弹子Mulx将对应}0于该板上的设备,而最右侧的单元格对应于}1。类似地,输出也将来自不同的单元。板的宽度可以计算为MAX(1, highest output device + 1, highest input device + 1):与输入设备不对应的单元将丢弃掉落在其上的大理石。

长度13片段

7E
??
>Y!!
{0

这是一块木板,将在每个刻度上吐出一个可打印的随机ASCII字符。Marbelous有两种生成随机值的方式。有??返回0并且其接收,包括所输入的大理石之间的随机值,并且?n?0高达?Z分别。哪个行为很相似??!!即使不是所有的输出都被填满,我们也可以用它来终止电路板。您能弄清楚如何将这些?n设备实现为Marbelous中的板子??吗?

长度12片段

}0}1
Fb//
Dp

在这里,我们看到了Marbelous的一些库函数。 Fb输出第n个斐波那契数,其中n是输入大理石。Dp将输入的大理石打印为十进制数字到STDOUT。这些都在Marbelous中实现,并且可以在您检查在线解释器包含库时调用,对于python解释器,您必须明确地包含每个文件。这些板的补充可以在github上找到。请注意,此特定程序需要2个输入,并将两次调用Fibonacci板。被调用的板在调用它们的板的一刻之内返回。

长度11片段

}0}0
{<{0{>

这需要一些解释。这些}0设备是归因设备,因为它们具有相同的数字(0),所以在调用此板时它们将包含相同的值。下一行的三个设备是输出。{<输出到板子的左侧,在板子{0的第一个单元下面{>输出,并向右输出。仅当所有不同的输出设备都装满时才推送输出。但是,在这种情况下,永远不会到达正确的输出设备。董事会将由于缺乏活动而退出,并始终输出其具有的两个值。您能想象一个人如何/\成为Marbelous董事会?

长度10片段

..40
FF
\\

这里有些事情在Marbelous中起着重要的作用。首先,有补充。如果您跟踪板上的两个弹珠的路径,您会注意到它们最终将同时出现在同一单元格上。发生这种情况时,会将它们添加在一起。(有趣的事实:在某些时候,人们认为不应该将弹子加在一起,而应该将它们堆叠在一起。)但是,Marbelous是8位语言,因此,将弹子加到FF等效于从中减去1。

长度9片段

00
\\/\]]

这是在Marbelous中实现基本版cat的最短方法。00 \ / \是一个循环,每隔一秒便00]]设备上放置一个数值大理石。这是一个STDIN设备。当大理石降落在此设备上时,它将尝试从STDIN读取第一个字符,如果有第一个字符,则将其下压(在这种情况下,将再次打印)。如果没有,则将原始杂音推到右侧。(在这种情况下,将其丢弃)

长度8片段

}0
~~
{0

此片段显示了一些功能。首先,它通过} 0进行输入。在这种情况下,这是主板,将由命令行输入代替。您也可以调用此函数,在这种情况下,将采用参数而不是命令行输入。然后是~~,这不是按位运算符。之后,转到}0,如果所有}n设备都装满,则这些值将作为函数的返回值返回。(Marbelous每个函数支持多个返回值)

长度7片段

00
\\/\

这是您可以在Marbelous中创建的最紧凑的无限循环。该\\设备将所有大理石推向右侧,/\复制大理石,然后将一个副本推向左侧,另一个推向右侧。由于木板只有两格宽,因此右侧的大理石却被扔掉了。

长度6片段

46MB75

这是一个递归示例,MB(隐式命名的主板在每个刻度上都会被调用,但不会Fu在每次调用上打印到STDOUT 之前被调用。(导致以下结果:FuFuFuFuFuFu...这显然会使调用栈溢出。

长度5片段

2A
++

用某种算术,具有价值的大理石2A在第一个刻度上掉落,并在++单元格上找到自己。这是操作员。这个特殊的运算符会增加落在其上的大理石的大小并使其掉落。大理石现在很有价值2B,可以从板上掉下来。这将打印+到STDOUT。

长度4片段

:
24

在这里,两个解释器不同意,在此示例中,我为文件的第一块板指定了名称(名称为空字符串)。python解释器假定这是主板,并在运行程序(显示$)时调用此主板。javascript解释器找不到主板,因此没有入口点。在为Marbelous编写库文件时,这很有用。

长度3片段

:Bo

这是一个命名的板,没有主体,我们可以通过Bo在任何板(包括Bo其自身)的单元格中进行写入来调用该板

长度2片段

3A

此代码是1x1单元(每个单元为两个字符宽)板MB的主体,其隐式命名(对于“主板”)。3A当大理石从板上掉下时,它将打印十六进制值的ascii值。该程序的输出恰好是以下代码的源代码:

长度1片段

:

与一起#,这是marbelous中仅有的两个有效的1字符程序之一。#是评论的指标,因此不是很有趣。:告诉marbelous您将要宣布一个董事会。这两个编译器都不关心您实际上没有命名或定义板。该程序不执行任何操作。

事实:

Marbelous是由该站点上的人员开发的,使用该语言的一些名称包括RubeMarbles


2
击败我。不错的摘要!
Sparr 2015年

您的长度为12的代码段似乎需要两个输入,并打印出两个不同的斐波那契数。那是故意的吗?
Sparr 2015年

@Sparr,是的,这是为了展示一些功能如何在Marbelous中工作。
演员

也许将其添加到解释中?从您写的内容来看,我希望代码段可以输入一个并输出一个fib编号。
Sparr 2015年

我真的希望您能达到40分,这样我的斐波那契功能将适合...
Sparr 2015年

31

向前

Forth只有两种类型:整数和浮点数(浮点数是可选的!),但是它仍然设法包含字符,字符串,长整数,指针,函数指针,结构等。这就是您使用方式的全部!

长度1

.

.命令(或我们所说的“单词”)将整数值打印在数据堆栈的顶部;如果堆栈为空,则会出现运行时错误。它还会从堆栈中删除值-投票查看我们如何保持它!

长度2

.s

.s单词显示当前堆栈中的值,而不删除其中的任何一个。它还显示值的总数。在Gforth中,.s默认情况下被限制为仅显示前9个值。也许我们会找出更多展示方式?

长度3

see

键入see任何Forth单词,然后查看该单词的源代码。大多数Forth单词是在Forth本身中定义的,而在汇编中只定义了少数几个原语。

长度4

1 0=

我是否提到过Forth是带有后缀运算符的基于堆栈的语言?键入1 0=将压1入堆栈,然后执行该0=单词,该单词将从堆栈中弹出最高值truefalse如果不等于0,则将其压入堆栈。 0=是方便的词0 =; 对于通用值+单词组合,有几个类似的速记单词,例如1+0<>。此外,尽管false在Forth中为0且任何非零值都是true,但内置测试字会返回true真实结果,并true一直执行-这是设置了所有位的值,即-1

长度5

-1 u.

-1入堆栈,然后将其弹出并打印为无符号整数。这可以用来快速查看您的Forth版本上无符号int的最大值(而不是其本机支持的最大整数值!)。您可能会问,“我们怎么知道什么时候应该打印int .以及什么时候需要打印u.?” 答:.签名u.时,未签名时。你说:“那不是我的意思。” “我们怎么知道什么时候栈顶的值是有符号的,什么时候是无符号的?” 答:您是程序员-那是您的工作!您必须知道堆栈上的每个整数是否代表一个int,一个无符号int,一个an int*,一个char*,,函数指针或其他函数,否则您会把恶魔藏在鼻子里。Forth不会为您跟踪此事;C,这是什么?

长度6

." Hi"

印刷品Hi."是一个Forth字(与所有Forth字一样,必须紧跟空格或EOF),它从下一个开始向上读取输入流,"并打印出之间的任何字节。如果您在后面放置多个空格."."则会打印,但紧随其后的所有空格除外。转义序列不支持(这样你就不能打印了一个字符串,"在它."),但是Gforth增加.\"的语言,它不支持他们。

长度7

: + - ;

您可以在Forth中定义自己的单词,方法是写一个冒号,单词的名称,您希望单词执行的单词以及分号。一个单词可以是任何非空白字符序列(毕竟,Forth告诉一个单词在哪里结束,另一个单词在哪里开始),空格甚至是标点符号,甚至是运算符(毕竟只是单词)。上面的代码段重新定义+-,因此现在无论何时尝试加法,都应改为减法。使用的任何现有单词+均不受影响,因为它们存储了对的原始定义的引用+

注意:有些单词在其他单词的定义内部执行的操作与在外部单词执行的操作不同,但是除了控制结构以外,它们都非常神秘。大多数单词在定义内与外部在做相同的事情,但是有时那件事并不明显- : show-see see see ;不会做您想的!

长度8

: 42 - ;

当我说一个单词可以是任何空格字符序列时,我的意思是任何序列。不,Forth的每个数字都没有单词。数字只是有点特别。当Forth遇到一个非空白序列时,它首先查看它是否是一个已知单词。如果不是,它将尝试将其解析为数字;如果失败,那么只有错误。定义与数字相同的单词意味着您将无法直接输入该数字的拼写而不获取该单词,但是Gforth和其他各种Forths仍然为您提供了多种拼写数字的方法

长度9

IF 1 THEN

最后,熟悉的东西!显然,此代码测试其参数是否1为true,如果是,则执行,之后的内容THEN,对吗?错误。当执行达到时IF,将弹出堆栈顶部的值,如果值为true(即非零),则执行将继续进行,内部执行IF ... THEN,然后执行THEN; 之后的所有操作。如果值为零,我们直接跳到after THEN。请注意,由于这些单词是如何在内部实现的(就其他Forth单词而言!),IF并且THEN只能在单词定义内部使用,而不能在“解释状态”中使用。

长度12

( x y -- y )

这是一条评论。它立即从(移到下一个)。(在解释器中,换行符也可以结束。)这不是Forth语法的“内置”(是什么?);(只是另一个词,它会丢弃输入流中直到next的所有内容)。(是的-Forth可以操纵其源代码的读取方式。Perl并不是唯一一种不执行就无法解析的语言!)由于这是一个词,因此必须在其后加上一个空格,否则Forth会抱怨(x未定义。我们还可以将其重新定义(为正在进行的射击自己的脚步的一部分。

但是,评论的内容更有趣。该注释具体说明了某些单词的堆栈效果--列表左侧的那部分在您运行单词之前应该在堆栈顶部(顶部在右侧),而的右侧--描述之后堆栈顶部的外观(再次) ,顶部在右侧)。通用约定是在您定义的所有单词的源头之后添加这样的注释: name,并且在命名堆栈元素时要使用非常强的约定,以指示其类型,甚至标准也要遵循。

顺便说一句,所示的堆栈效果是针对该nip单词的。您应该能够仅从评论中看出它的作用。

长度13

1 2 3 4 d+ d.

如前所述,Forth值的类型完全取决于如何使用-如果将值视为指针,则为指针,如果该值不是良好的指针,则将其视为一个是您的错。但是,无论您将值当作什么类型,它都将始终占用数据堆栈中的一个单元格。双格双精度整数除外。这些是由堆栈上的两个值表示的整数,使您可以用通常两倍的位数执行算术运算。较高或较高位的单元位于较低或较低位的单元的顶部,因此1 0是的双单元表示1,和0 1是2 ^ 32还是2 ^ 64,具体取决于您的Forth常规单元格的大小。自然地,为了这样对待一个双单元格值,我们需要使用显式地对双单元格值进行运算的单词。这些通常只是d(或ud无符号的),后跟相应的单单元格单词的名称:d+用于添加,d<比较,d.打印等。


为+1。我开始寻找尚未完成的语言。很高兴在这里看到它。
mbomb007

2
另外,如果您达到+1675,我将输出一个漂亮的ASCII图像。:D
mbomb007

31

腐霉菌

有关更多摘要,我将发布解决高尔夫球挑战的解决方案以及该问题的链接。

长度17:

<ussC,cG\_GUQ*zQQ

找到n永远重复输入字符串形成的无限序列的第一个字符,然后用序列本身填充下划线,然后永远重复。

填空

长度14:

#QX=Qhf>FT.:Q2

给定一个唯一元素列表,通过交换成对的相邻元素对列表进行排序,打印出所有中间结果。

重新排列一组数字

长度13:

?hu]+HG_UQYQY

创建以下结构:[0, [1, [2, [3]]]]

列表范围内的首页

长度12:

uxyG*HQjvz2Z

XOR乘法。

XOR乘法

长度11:

lfqSzST.:wz

计算第一个单词的多少个子字符串是第二个单词的字谜。

在父字符串中检测字谜

长度9:

fqJjQT_J2

查找输入为回文的最低碱基。

最低基回文

长度5:

!%lQ1

检查输入是否为2的幂。取对数为2,取结果为mod 1,不取逻辑。

在不使用+,-运算的情况下检查整数是否为2的幂

长度4:

sjQ2

通过将输入的基数2表示相加来计算输入的汉明权重。

计算无符号16位整数中的1

长度3:

^G2

^ on序列int给出第一个参数与自身的n次乘积的笛卡尔积,其中n是第二个参数。

在这种情况下,由于G是英文字母(abcdefghijklmnopqrstuvwxyz),^G2给出了所有2字母串,aa通过zz

长度2:

lT

l,通常用作len(),也可以用作日志基数2。由于T是初始化为的变量10,因此将打印3.3219280948873626日志基数2,即10。

长度1:

H

H是Pyth中的空字典(哈希表),并且是在Pyth中获得字典的唯一方法,缺少使用v(eval)或$(Python文字)。

类固醇:

除文字外,Pyth还没有多字符构造。而且,Pyth本质上是一对一地编译到Python中。


在以开头的命令之前添加了类事实.吗?
Leaky Nun

@LeakyNun是的..
isaacg
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.