多年来的编程语言


167

在这一挑战中,用户将轮流使用允许逐渐变老的编程语言来完成三个相当简单的编码任务。

第一个答案必须使用2015年制作的编程语言。一旦至少有一种2015年语言的答案,答案就可以使用2014年制作的编程语言。类似地,不允许使用2013年语言的答案。直到至少有一个2014年答案。

通常,直到提交了使用Y + 1年的语言的答案后,才允许使用Y年的编程语言。唯一的例外是Y = 2015。

寻找你的语言年

要回答这个问题,您必须知道您的编程语言的“制造年份”。当然,这是一个主观术语;一些语言是在多年的发展过程中开发的,并且每年仍在升级许多语言。让“制造”该语言的年份成为该语言的实现在公众中出现的第一年。

例如,Python1991年制造的,尽管它的开发自1989年以来一直在进行,而1.0版直到1994年才发布。

如果今年仍然是主观的,请使用常识选择最合适的年份。不要因对年份的选择而陷入一点分歧。请提供指向您的语言的来源的链接。

编程语言的不同版本或标准(例如Python 1、2、3)被视为具有相同初始年份的相同语言。

因此,除非您的语言年份是2015年,否则您只能在提交了其语言年份为您的前一年的答案后才能提交答案。

如果已经存在与您年份相同的有效答案,则可以回答。您的语言是在今年早些时候还是晚些时候开发都没有关系。

任务

您必须完成任务1到3。任务0是可选的。

这些任务或多或少地被选择为与编程的三个重要方面相对应:提供输出(任务1),循环(任务2)和递归(任务3)。

任务0-语言历史记录(可选)

至少写一个段落来说明您所选择的编程语言的历史:谁开发了它,为什么,怎么做等等。如果您本人是在语言诞生时就在身边的,甚至可能在语言的发展中发挥了作用,则尤其值得鼓励。随意将有关该语言对您或您的工作或类似事情的影响的个人轶事联系起来。

如果您太年轻而又不做大量研究就不了解您的语言历史,请考虑给老用户留下笔记,说他们可以编辑您的帖子并添加一些第一手的历史记录。

任务1-“你好,世界!” 变体

编写一个打印程序

[language name] was made in [year made]!

到您的语言的标准输出区域(最新语言的标准输出)。

例如,如果语言是Python,则输出为:

Python was made in 1991!

任务2-ASCII Art N

编写一个程序,让用户在奇正整数输入(你可以假设输入始终有效),并打印出来使用字符的ASCII艺术字母N制成N

如果输入为1,则输出为:

N

如果输入为3,则输出为:

N N
NNN
N N

如果输入为5,则输出为:

N   N
NN  N
N N N
N  NN
N   N

如果输入为7,则输出为:

N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

模式继续这样下去。输出中可能包含尾随空格。

任务3- GCD

编写一个程序,让用户输入两个正整数(您可能会假设输入始终有效),并输出其最大公约数。这被定义为最大的正整数,该整数将两个数相除而没有余数。使用欧几里得算法可以很容易地计算出它。

例子:

8124
1284
3303
568921
2348766

您可以使用内置函数,但是请尝试找出语言的第一版中是否存在该函数。如果没有,请尝试不使用它。

规则

  • 您可能会回答多次,但是每个新答案必须使用一种比您上一次回答中的语言至少早五年的语言。因此,如果您使用2015年的语言回答,则只有在允许使用2010年的语言后,您才能再次回答。如果您以2010年的答案开头,那么您就不能将2015年的答案作为第二个答案,因为2015年不在2010年之前。
  • 如果可能,编写您的代码,使其可以在您的语言的第一个版本中使用(或尽可能旧的版本)。(这不是必需的,因为找到某些语言的旧编译器/解释器可能很困难。)
  • 除非发布的答案有重大错误,或者完成任务的方式截然不同,否则请不要发布已经发布的语言。
  • 打高尔夫球的代码很好,但不是必需的。
  • 任何程序输出中的尾随换行符都可以。
  • 对于任务2和3,所有低于某个合理最大值(如2 16)的输入值都应起作用(至少为256)。
  • 在发布此问题之前,您的语言必须已经存在。
  • 非常古老的编程语言可能具有与我们今天想象的形式不同的输入和输出形式。这可以。在您的语言环境中,以最大的能力完成任务。

计分

您提交的分数是:

upvotes - downvotes + (2015 - languageYear) / 2 

因此,在2015年之前的每年投票数中增加0.5,这有利于使用较旧的语言。得分最高的提交者获胜。

答案列表

下面的堆栈摘录根据其语言年份列出了所有有效答案。

您必须以此Markdown行开始您的帖子,以确保正确列出该帖子:

#[year] - [language name]

例如:

#1991 - Python

语言名称可能在链接中(它将与答案列表中的链接相同):

#1991 - [Python](https://www.python.org/)

不遵循此格式的答案,或者不允许使用的年份,或者来自过去五年来已经回答过的用户的答案都标记为无效。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>$(function(){function e(e,r){var a="https://api.stackexchange.com/2.2/questions/48476/answers?page="+e.toString()+"&pagesize=100&order=asc&sort=creation&site=codegolf&filter=!YOKGPOBC5Yad160RQxGLP0r4rL";$.get(a,r)}function r(e){if(e.items.forEach(function(e){var r=e.link,a=e.owner.display_name,i=e.body.match(/<h1\b[^>]*>(\d{4}) - (.*?)<\/h1>/);if(i&&i.length>=3)var h=parseInt(i[1]),u=i[2];h&&u&&n>=h&&h>=t&&(!d.hasOwnProperty(e.owner.user_id)||d[e.owner.user_id]-h>=p)?(d[e.owner.user_id]=h,h==t&&--t,o.hasOwnProperty(h)||(o[h]=[]),o[h].push({language:u,user:a,link:r,score:e.score+(n-h)/2})):s.push(' <a href="'+r+'">'+a+"</a>")}),e.has_more)runQuery(++a,r);else{for(var i=n,h=[];o.hasOwnProperty(i);){for(var u=$("<tr>").append($("<td>").text(i.toString())),l=$("<td>"),c=$("<td>"),g=$("<td>"),f=0;f<o[i].length;f++){var v=o[i][f];l.append(v.language),c.append($("<a>").html(v.user).attr("href",v.link)),g.append(v.score),f+1<o[i].length&&(l.append("<br><br>"),c.append("<br><br>"),g.append("<br><br>"))}u.append(l).append(c).append(g),h.push(u),--i}$("#answers").find("tbody").append(h),s.length>0?$("#invalid").append(s):$("#invalid").remove()}}var a=1,n=2015,t=n-1,p=5,o={},s=[],d={};e(1,r)})</script><style>html *{font-family: Helvetica, Arial, sans-serif;}table{border: 4px solid #a4a; border-collapse: collapse;}th{background-color: #a4a; color: white; padding: 8px;}td{border: 1px solid #a4a; padding: 8px;}div{font-size: 75%;}</style><table id='answers'> <tr> <th>Year</th> <th>Language</th> <th>User (answer link)</th> <th>Score</th> </tr></table><div id='invalid'><br>Invalid Answers:</div>


2
应该有所帮助。
2015年

20
维基百科有一切的列表:这一个非深奥的语言的一年。
桑契斯2015年

2
任务3应该实际使用递归还是足以产生正确的结果?如果我需要编写自己的GCD函数,通常只使用一个循环,但是我专门针对此挑战编写了一个递归循环。有许多提交的答案仅使用循环。
CJ丹尼斯

5
我想做一个第二个帐户只是为了让我们了解1971
。– marinus

5
如果我们可以将其追溯到1952年,我有一个人正在编织一台历史悠久的机器,该机器可以执行1951年(飞马)解决方案并对其进行测试!
Brian Tompsett-汤莱恩2015年

Answers:


172

2013-总督

Dogescript是Zach Bruggeman于2013年创建的一种语言。它无非是Java语言的语法替代,使其看起来像模因Shiba Inus的内部独白。

你好总督

console dose loge with "Dogescript was made in 2013!"

ASCII艺术

such N much N
          much i as 0 next i smaller N next i more 1
              very doge is ("N" + " ".repeat(N-2) + "N").split('')
              s[i] is "N";
              console dose loge with doge.join('')
                              wow
                                      wow

GCD

such gcd_doge much doge, dooge
    rly dooge
              gcd_doge(dooge, doge % dooge)
  but
    rly doge smaller 0
           -doge
    but
          doge
  wow
        wow

112
哇+1 非常答案。很多质量。
Alex A.

27
我加入codegolf只是为了支持这个答案!
德里克·托姆斯

21
我什至无法读懂GCD的照片
Cole Johnson

16
我无法将gcd_doge读为good_dog。帮助
Yann 2015年

太棒了 但是,根据LANGUAGE.md,不支持双引号。也想解释s[i]一下!
医生

66

2015年- 视网膜

Retina是一种基于正则表达式的编程语言,我编写该程序语言的目的是能够通过仅使用正则表达式的答案来应对PPCG挑战,而无需以某种宿主语言调用正则表达式。视网膜是图灵完整的。为了证明这一点,我已经实现了2标签系统求解器以及Rule 110。它是用C#编写的,因此它同时支持.NET风格(默认)和ECMAScript风格(通过标志)。

视网膜可以在多种模式下运行,但是与计算最相关的一种(以及图灵完备的一种)是替换模式。在替换模式下,您为Retina分配了偶数个源文件。然后将它们配对,每对中的第一对是正则表达式,第二对为替换。然后按顺序执行这些命令,逐步操作输入。正则表达式也可以在配置之前(以分隔`)。最重要的选项(使Retina Turing完成)是+,这使Retina循环应用替换,直到结果停止更改。在以下示例中,我还将使用;,它抑制中间阶段的输出。

在以下每个提交中,每一行都放在单独的源文件中。(或者,您可以使用new -s选项,并将所有行放入一个文件中。)空文件/行用表示<empty>。包含单个空格的文件/行表示为<space>

解释很长,因此我将其移至帖子末尾。

程序

“你好,世界!” 变体

<empty>
Retina was made in 2015!

ASCII艺术N

假定STDIN以换行符终止。

;`^
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
N
;`.(?<=(?=(.*\n)).*)|\n
$1
;`N(?=N\n.*\n.*\n`$)
<space>
;+`N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n)
<space>
;`(?<=^.*\n.*\nN)N
S
;+`(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N
S
S
<space>

GCD

这要求STDIN 以换行符终止。

;`\b(?=\d)
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
1
;`^(.+)\1* \1+$
$1
;`$
#:0123456789
;+`^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))
$1#$3
#|:.*
<empty>

说明

“你好,世界!” 变体

这是相当琐碎的。它不接受任何输入(即,空字符串),不匹配任何内容并将其替换为Retina was made in 2015!。也可以通过[\s\S]*例如将模式替换为任意输入来使其工作。那将吞噬STDIN并将其全部替换为输出。

ASCII艺术N

这有很多阶段。想法是将输入转换为一元,创建Ns 的N x N块,然后“切出”两个三角形。让我们经历各个阶段。请记住,这;只是抑制中间输出,而是+使替换循环应用。

;`^
#

简单:#在输入前面加上a 。这将用作向一元转换的标记。

;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#

这会将一位转换为一进制。它接受已经转换的数字(\d*)并重复10次。然后,它取下一个数字并附加适当数量的数字。在此阶段,数字的实际值无关紧要。当#到达数字的末尾时,正则表达式不再匹配,并且转换完成。例如,该数字127将被处理为

#127
1#27
111111111122#7
1111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111221111111111227777777#

最后一行正好包含127位数字字符。

;`#
<empty>
;`\d
N

摆脱这两个简单的阶段,#然后将所有数字转换为N。在下文中,我将使用输入7作为示例。所以现在我们有了

NNNNNNN

下一阶段

;`.(?<=(?=(.*\n)).*)|\n
$1

N整个字符串替换每个字符串(请记住它包含尾随换行符),并且还删除尾随换行符本身。因此,这会将单行变成正方形网格:

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN
NNNNNNN

现在是上三角。首先,我们通过将右下角的N变成一个空格来开始:

;`N(?=N\n.*\n.*\n`$)
<space>

前瞻性确保我们正在修改正确的N。这给

NNNNNNN
NNNNNNN   
NNNNNNN
NNNNNNN
NNNNN N
NNNNNNN
NNNNNNN

现在

;+`N(?=.?(.)+\n.* (?<-1>.)+(?(1)!)\n)
<space>

是一个正则表达式,它匹配N空格字符左上角或左上角的,并将其替换为空格。由于替换是重复进行的,因此本质上是泛洪,它将第三个八分位数从初始空间变为更多空间:

N     N
NN    N   
NNN   N
NNNN  N
NNNNN N
NNNNNNN
NNNNNNN

最后,我们对下三角形重复相同的操作,但是我们使用了不同的字符,因此,现有的空间不会导致错误的填充:

;`(?<=^.*\n.*\nN)N
S

设置种子:

N     N
NN    N   
NSN   N
NNNN  N
NNNNN N
NNNNNNN
NNNNNNN

然后

;+`(?<=\n(?(1)!)(?<-1>.)+S.*\n(.)+N?)N
S

进行洪水填充。

N     N
NN    N   
NSN   N
NSSN  N
NSSSN N
NSSSSNN
NSSSSSN

最后

S
<space>

将它们S变成空间,我们完成了:

N     N
NN    N   
N N   N
N  N  N
N   N N
N    NN
N     N

GCD

一元代码中的GCD实际上与正则表达式无关紧要。其中大部分由十进制到一进制和一进制到十进制的转换组成。可以更紧凑地完成此操作,但这不是代码高尔夫球,所以...

;`\b(?=\d)
#
;+`(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)
$1$1$1$1$1$1$1$1$1$1$2$3$4$5$6$7$8$9$10#
;`#
<empty>
;`\d
1

这些阶段与上面的阶段基本相同,除了两个输入数字都被转换,并且结果使用1s代替Ns(无关紧要)。因此,如果输入为18 24,则将产生

111111111111111111 111111111111111111111111

现在

;`^(.+)\1* \1+$
$1

是整个GCD计算。我们通过捕获多个1s 匹配一个共同的除数,然后使用反向引用确保通过重复该字符串(以及其他所有内容)可以写入两个数字。由于正则表达式引擎中的回溯是如何工作的(即.+贪婪的),这将始终自动产生最大的公约数。由于匹配覆盖了整个字符串,因此我们只需写回第一个捕获组即可获得GCD。

最后,一元到十进制的转换...

;`$
#:0123456789

在字符串后附加一个标记#,一个定界符:和所有数字。这是必要的,因为您不能在正则表达式替换中有条件地产生新字符。如果要有条件替换,则需要从字符串本身中提取字符,因此我们将它们放在此处。

;+`^(?=1)(1*)\1{9}(#(?=.*(0))|1#(?=.*(?<3>1))|11#(?=.*(?<3>2))|111#(?=.*(?<3>3))|1111#(?=.*(?<3>4))|11111#(?=.*(?<3>5))|111111#(?=.*(?<3>6))|1111111#(?=.*(?<3>7))|11111111#(?=.*(?<3>8))|111111111#(?=.*(?<3>9)))
$1#$3

这与先前的一元扩展相反。我们找到适合当前字符串的10的最大倍数。然后,我们根据余数选择下一个数字,并将倍数除以10,同时将标记移动到各个数字中。

#|:.*
<empty>

最后,只是清除步骤,以摆脱标记,定界符和辅助数字。


我认为您应该添加指令以将数字输入转换为一元字符串,并添加指令以将一元字符串转换回数字输入。使用纯正则表达式的转换很酷,但又太笨拙了。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2015年

8
+1我非常确定2015年提交的内容将是CodeGolf使用的语言。
零光纤

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳我早些时候考虑过。我认为对于大多数代码高尔夫,我可能只会采用一元输入(除非挑战明确指定“十进制”或其他内容)。我考虑过要这样做,但这不是代码编程,我想证明我也可以处理十进制输入和输出。
Martin Ender

6
优秀作品。视网膜真的很酷。顺便说一句,看到您名字旁边的钻石也很酷!:)
Alex A.

有趣的是,尽管古老的语言在这场比赛中受到青睐,但这个最年轻的语言仍在获胜=)
Claudiu 2015年

60

2013-快拍

快点是基于伯克利大学(Serchch)的语言,是由伯克利大学(Berkeley University)制造的。它是对Scratch的升级,具有一流的数据和自定义块(功能)。与Scratch一样,它也不是基于文本的,而是通过视觉上的“块”结合在一起来完成的。

快点用JavaScript编写的,是用Squeak Smalltalk编写的BYOB的后继产品。快点20133月发布的Beta版,供公众使用。

快点实际上不是一种深奥的语言。它被用作伯克利(Berkeley )等学院的计算机美容与欢乐(BJC) AP CS课程的编程语言。

我提供了测试和其他方面的帮助。

“ Hello World”变体

ASCII艺术“ N”

在此处输入图片说明

这会将stdlib用于某些块。

很基本的循环在这里。接受输入。然后,我们将所有内容加在一起并说出来(n = 5的结果):

在此处输入图片说明

我在这里随意使用2个空格而不是1个空格,因为Snap!没有说等距中的东西。

GCD

欧几里得算法不是很快,但是它可以工作并且非常简单。(对不起,我在块名称中打了错字。现在我关闭了选项卡,没有保存。它只需要留下即可。)

在此处输入图片说明

然后,此函数定义将产生以下代码块:

在此处输入图片说明


3
这看起来很像在Alice中编程...
mbomb007

4
这就是您使用基于块的语言所获得的。谈到它,很多语言看起来都差不多。;)
Scimonster 2015年

1
甚至Scratch都具有mod函数,因此我假设您可以使用基于if(b == 0)然后else GCM(b,a%b)的块来使GCM / GCD函数更快,
Alchymist 2015年

55

2007年-LOLCODE

语言史

LOLCODE由兰开斯特大学的研究员Adam Lindsay于2007年创建。它的语法基于Cheezburger,Inc.推广的lolcats模因。

“你好,世界!” 变体

HAI
VISIBLE "LOLCODE wuz maed in 2007!"
KTHXBYE

ASCII艺术N

HAI

BTW, read n from stdin
GIMMEH n

BTW, convert n from YARN to NUMBR
n R PRODUKT OF n AN 1

BOTH SAEM n AN 1, O RLY?
    YA RLY
        VISIBLE "N"
    NO WAI
        VISIBLE "N"!

        I HAS A butt ITZ 1
        IM IN YR toilet UPPIN YR butt TIL BOTH SAEM butt AN DIFF OF n AN 1
            VISIBLE " "!
        IM OUTTA YR toilet

        VISIBLE "N"

        I HAS A kat ITZ 2
        IM IN YR closet UPPIN YR kat TIL BOTH SAEM kat AN n
            VISIBLE "N"!
            BOTH SAEM kat AN 2, O RLY?
                YA RLY
                    VISIBLE "N"!
                NO WAI
                    I HAS A doge ITZ 1
                    IM IN YR l00p UPPIN YR doge TIL BOTH SAEM doge AN DIFF OF kat AN 1
                        VISIBLE " "!
                    IM OUTTA YR l00p
                    VISIBLE "N"!
            OIC

            I HAS A brd ITZ 1
            IM IN YR haus UPPIN YR brd TIL BOTH SAEM brd AN DIFF OF n AN kat
                VISIBLE " "!
            IM OUTTA YR haus

            VISIBLE "N"
        IM OUTTA YR closet

        VISIBLE "N"!

        I HAS A d00d ITZ 1
        IM IN YR lap UPPIN YR d00d TIL BOTH SAEM d00d AN DIFF OF n AN 1
            VISIBLE " "!
        IM OUTTA YR lap

        VISIBLE "N"
OIC

KTHXBYE

值使用从stdin中读取为字符串(YARN)GIMMEH。可以将它们乘以1转换为数字(NUMBR)。

使用会将值打印到标准输出VISIBLE。默认情况下会添加换行符,但是可以通过添加感叹号来取消它。

GCD

HAI

GIMMEH a
a R PRODUKT OF a AN 1

GIMMEH b
b R PRODUKT OF b AN 1

I HAS A d00d ITZ 1
IM IN YR food UPPIN YR d00d TIL BOTH SAEM b AN 0
    I HAS A kitty ITZ a
    I HAS A doge ITZ b
    a R doge
    b R MOD OF kitty AN doge
IM OUTTA YR food

VISIBLE SMOOSH "gcd is " a

KTHXBYE

SMOOSH 执行字符串连接。


13
最后,一种人人都能理解的语言。
ASCIIThenANSI

26
IM IN YR toilet UPPIN YR butt好的变量名
Cole Johnson

13
@ColeJohnson:我总是尽量选择变量名,在这种情况有意义,而不是x1x2等等
亚历A.

2
搞笑 我不应该在工作中阅读此书。
艾伦·胡佛

@AlanHoover:显然,lolz比jobz更重要。
Alex A.

43

1982年-PostScript

PostScript是用于创建矢量图形和打印的语言。

Adobe成立于1982年,他们的第一个产品是PostScript。打印机使用了该语言:打印机解释命令以创建光栅图像,然后将其打印到页面上。直到1990年代,它都是激光打印机的非常常见的组件。但这显然在打印机上占用大量CPU,并且随着计算机处理器功能的增强,在计算机上进行栅格化比在打印机上更有意义。尽管PostScript在许多更高端的打印机上仍然存在,但在消费型打印机上已基本消失。

替代PostScript的标准是一种鲜为人知的格式,称为PDF。

在我开始编程时,PostScript已经过时了,但是当我在大学时,我学到了一些知识,这是为TeX创建文档的另一种方式。它与我使用的其他编程语言(反向插入符号,堆栈,打印到页面而不是控制台)有很大不同,但是很高兴可以用这种旧语言来获得一些乐趣。

由于PostScript是一种打印语言,因此似乎更适合使用它来打印某些内容,然后将输出发送到控制台。

任务1

/Courier findfont
12 scalefont
setfont
newpath

100 370 moveto
(PostScript was made in 1982!\n) show

前几行设置了要绘制的画布。然后,该moveto命令告诉PS在特定位置绘制,并将show字符串打印到页面上。请注意,括号是在PostScript中标记字符串,而不是引号。

任务2

/asciiartN {% stack: N row col
            % output: draws an "ASCII art" N

  % PostScript doesn't allow you to pass variables directly into a function;
  % instead, you have to pass variables via the global stack. Pop the variables
  % off the stack and define them locally.
  6 dict begin
  /row exch def
  /col exch def
  /N exch def

  % Define how much space will be between each individual "N"
  /spacing 15 def

  % Get the width of the "N". We need this to know where to draw the right-hand
  % vertical
  /endcol col spacing N 1 sub mul add def

  % One row is drawn at a time, with the bottom row drawn first, and working
  % upwards. This stack variable tracks which column the diagonal is in, and so
  % we start on the right and work leftward
  /diagcol endcol def

  % Repeat N times: draw one row at a time
  N {
    % Left-hand vertical of the "N"
    col row moveto
    (N) show

    % Right-hand vertical of the "N"
    endcol row moveto
    (N) show

    % Diagonal bar of the "N"
    diagcol row moveto
    (N) show

    % Advance to the next row. This means moving the row one space up, and the
    % diagonal position one place to the left.
    /row row spacing add def
    /diagcol diagcol spacing sub def

  } repeat

  end
} def

1 100 200 asciiartN
3 150 200 asciiartN
5 230 200 asciiartN

我编写了一个用于绘制“ ASCII art” N的函数,但PostScript函数无法接受参数。取而代之的是,将参数推入堆栈,然后再将其取回。就是那条/x exch def线。

一个示例:假设堆栈为8 9 2。首先,我们将名称压入/x堆栈,因此堆栈为8 9 2 /x。该exch运营商交换两个堆栈值,所以现在的堆栈8 9 /x 2。然后def弹出顶部的两个堆栈值,并定义/x为具有该值2。现在是堆栈8 9

当我开始使用PostScript时,我发现这有点令人困惑。我已经将堆栈作为一个理论概念进行了阅读,但这是我第一次在实践中使用它。

该功能的其余部分是一些绘图代码:从右下角开始,从左到右到对角线一次填充一行。

任务3

/modulo {% stack: x y
         % output: returns (x mod y)
  3 dict begin
  /y exch def
  /x exch def

  % If x = y then (x mod y) == 0
  x y eq {0} {

    % If x < y then (x mod y) == x
    x y lt {x} {

      % If x > y then subtract floor(x/y) * y from x
      /ycount x y div truncate def
      /x x ycount y mul sub def

      /x x cvi def
      x

    } ifelse
  } ifelse
} def

/gcd {% stack: a b
      % returns the gcd of a and b
  2 dict begin
  /b exch def
  /a exch def

  % I'm using the recursive version of the Euclidean algorithm

  % If b = 0 then return a
  b 0 eq {a} {

    % Otherwise return gcd(b, a mod b)
    /a a b modulo def
    b a gcd
  } ifelse

} def

/displaygcd {% stack: a b xcoord ycoord
             % displays gcd(a,b) at position (xcoord, ycoord)
  5 dict begin
  /ycoord exch def
  /xcoord exch def
  /b exch def
  /a exch def
  /result a b gcd def

  xcoord ycoord moveto
  result 20 string cvs show

  % end
} def

8 12 100 80 displaygcd
12 8 150 80 displaygcd
3 30 200 80 displaygcd
5689 2 250 80 displaygcd
234 876 300 80 displaygcd

同样,我使用了一种形式的Euclid算法,但是我忘记了PostScript具有内置的模运算符,因此我必须编写自己的模运算符。事实证明,这是对基于堆栈的编程的限制的有用提示。我的第一个实现modulo是基于递归的:

modulo(x, y)
    if (x = y) return 0
    elif (x < y) return x
    else return module(x - y, y)

这很好,直到您尝试在x大而y小(例如5689和2)时运行它为止。堆栈上最多只能包含250个元素,因此我的表现远远超出了堆栈限制。哎呀。我不得不回到那个图板上。

GCD代码本身非常简单。但是就像函数不能接受参数一样,它们也没有返回值。取而代之的是,您必须将结果推送到堆栈中,以便其他人稍后可以将其弹出。这就是ab a gcd行的作用:完成评估后,便将值推入堆栈。

如果将所有代码放在文档中并打印,则输出结果如下所示:

在此处输入图片说明


8
哈哈,我喜欢印刷纸的照片。感觉适合1982
。– Alex A.15年

1
另外,感谢您对(字面上的)堆栈溢出如何发生的描述-现在,我更加直观地理解了为什么语言具有最大递归深度。
DLosc

2
@AlexA .:是的,但是点矩阵打印输出(在纸张的侧面有孔)会更合适。;-)
阿莫斯·M·卡彭特

@ AmosM.Carpenter:并非如此,我认为任何点矩阵打印机都不支持PostScript。它一直与激光打印机息息相关。
ninjalj

41

2009年- > <>

受Befunge启发,> <>(鱼)是一种基于深奥堆栈的2D语言,即程序流可以向上,向下,向左或向右。最初的版本> <>功能的多线程这里[]创建和结束线程,但为简单起见这些指令改为创建和删除分别新栈。

当前用于> <>的官方解释器可以在这里找到。不幸的是,到Esolang Wiki上的旧解释器的链接已断开。

“你好,世界!” 变体

"!9002 ni edam saw ><>"l?!;obb+0.

请注意,该字符串是如何向后写的-> <>从技术上讲没有字符串,唯一的数据类型是char,int和float的怪异混合。"切换字符串解析,将每个字符压入堆栈,直到"遇到关闭为止。

然后,代码的后半部分增加堆栈的长度l,检查堆栈的长度是否为零,?!然后终止程序;。否则,指令指针将继续o执行bb+0.,并在执行之前输出堆栈的顶部,并将其传送到(22, 0)恰好位于之前的位置l,从而创建循环。

ASCII艺术N

&0 > :&:&:*=?;  :&:&%  :0=?v  :&:&1-=?v  :{:{-&:&,{=?v   " " o   \

                           > ~"N"o                           v    
   +                                  > ~"N"oao              v    
   1                                                 >"N"o   v    

   \                                                         <   /

带有空格以保持清晰。您可以在此处的新在线解释器中进行尝试,并查看指令指针四处走动-只需记住在“初始堆栈”文本框中输入数字即可。如果您通过Python解释器运行,请使用该-v标志初始化堆栈,例如

py -3 fish.py ascii.fish -v 5

对于此程序,我们将输入n与一起放入寄存器&并推入0,我们将其称为i“迭代”。该程序的其余部分是一个巨大的循环,如下所示:

:&:&:*=?;          If i == n*n, halt. Otherwise ...
:&:&%              Push i%n
:0=?v              If i%n == 0 ...
>~"N"o               Print "N"
:&:&1-=?v          Else if i%n == n-1 ...
>~"N"oao             Print "N" and a newline
:{:{-&:&,{=?v      Else if i%n == i//n, where // is integer division...
>~"N"o               Print "N"
" "o               Otherwise, print a space
1+                 Increment i

然后我们从头开始重复循环。

箭头^>v<改变程序流程的方向,而镜子则/\反映程序流程的方向。

GCD

>:{:}%\
;n{v?:/
v~@/

这是一个打高尔夫球的<<>程序的外观示例。再一次,您可以在在线解释器中尝试此操作(例如,在“初始堆栈”框中输入两个逗号分隔的值111, 87),或者使用-vPython解释器的标志,例如

py -3 fish.py gcd.fish -v 111 87

该程序使用欧几里得算法。这是我之前准备的GIF:

在此处输入图片说明

请注意,> <>是环形的,因此当v执行左下方的指令时,指令指针将向下,环绕并重新出现在顶部。


编辑:通过使代码完全从右到左运行,@randomra设法用

<~@v!?:%}:{:
;n{/

猜猜我还没打下去:)


27
这就是我发现这个名字><>是回文的原因。
Zev Eisenberg 2015年

33

2012- 元素

这是我在2012年初发明的一种简单的高尔夫语言。我的意思是说,几乎没有操作员重载。与大多数现代高尔夫语言相比,操作员更简单,人数也更少。

这种语言最有趣的功能是它的数据结构。有两个堆栈和一个散列用于存储信息。

m堆栈是主堆栈,在其中进行算术运算和大多数其他操作。当输入或打印数据时,就在这里或从中获取数据。

C堆栈是控制堆栈。这是布尔算术发生的地方。If和While循环将c堆栈的最高值用作条件。

哈希是存储变量的位置。该;~存储分别从哈希检索数据。

元素是一种非常弱类型的语言。它使用Perl的功能将数字自由解释为字符串,反之亦然。

当我在使用它时,我不妨包括该语言的所有文档。 您可以在此处找到用Perl编写的原始 2012解释器。更新:我创建了一个更可用的版本,您可以在此处找到。

OP    the operator.  Each operator is a single character
STACK tells what stacks are affected and how many are popped or pushed
      "o" stands for "other effect"
HASH  tells if it involves the hash
x & y represent two values that are already on the stack, so the effect of
      the operator can be more easily described

OP     STACK  HASH   DESCRIPTION
text     ->m         --whenever a bare word appears, it pushes that string onto 
                       the main stack
_       o->m         --inputs a word and pushes onto main stack
`       m->o         --output.  pops from main stack and prints
xy;    mm->    yes   --variable assignment.  the top stack element y is assigned 
                       the value x
~       m->m   yes   --variable retrieval.  pops from main stack, pushes contents 
                       of the element with that name
x?      m->c         --test. pops x and pushes 0 onto control stack if x is '0' or 
                       an empty string, else pushes 1
><=     m->c         --comparison. pops two numbers off of stack and performs 
                       test, pushes 1 onto control stack if true and 0 if false
'       m->c         --pops from main stack and pushes onto control stack
"       c->m         --pops from control stack and pushes onto main stack
&|     cc->c         --AND/OR. pops two items from control stack, performs and/or 
                       respectively, and pushes result back onto control stack
!       c->c         --NOT. pops a number off of control stack, pushes 1 if 0 or 
                       empty string, 0 otherwise
[]       c           --FOR statement (view the top number number from control stack 
                       and eval those many times)
{}       c           --WHILE (loop until top number on control stack is 0, also 
                       does not pop)
#       m->          --discard. pops from main stack and destroys
(       m->mm        --pops from main stack, removes first character, pushes the 
                       remaining string onto stack, and pushes the removed character 
                       onto stack
)       m->mm        --pops from main stack, removes last character, pushes the 
                       remaining string onto stack, and pushes the removed character 
                       onto stack
+-*/%^ mm->m         --arithmetic. pops two most recent items, adds/negates
                       /multiplies/divides/modulates/exponentiates them, and places 
                       the result on the stack 
xy@    mm->o         --move. pops x and y and moves xth thing in stack to move to 
                       place y in stack
x$      m->m         --length. pops x and pushs length of x onto the stack
xy:    mm->o         --duplication. pops x and y and pushes x onto the stack y times
xy.    mm->m         --concatination. pops x and y and pushes x concatonated with y
\        o           --escapes out of next character, so it isn't an operator and can
                       be pushed onto the stack
,      m->mm         --character conversion. pops from main stack, coverts it to char
                       and pushes, and converts to num and pushes
Newlines and spaces separate different elements to be pushed 
onto the stack individually, but can pushed onto the stack using \

任务1-打印文字

Element\ was\ made\ in\ 2012\!`

语言中比较尴尬的部分之一是缺少字符串定界符,这就是为什么在此字符串中需要转义字符的原因。将`在最后打印字符串。

任务2-ASCII Art N

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\ [#N]`"#]\
`]

在这里,您将见证一些堆栈操作。为了使说明更容易格式化,我将换行符替换为L,将空格替换为S

_+'[y~1+y;0[1+4:"2:'=1=|y~=|\S[#N]`"#]\L`]
_+'      input line, convert to #, move to c-stack
[        FOR loop
 y~1+y;  increment the y-pos
 0       set the x-pos (the top # on the stack) to zero
 [       FOR loop
  1+4:   increment x-pos and make 3 additional copies (4 is total #)
  "2:'   make a copy of the N size on the main stack
  =      if x-pos == size
  1=     or if x-pos == 1
  y~=|   of if x-pos == y-pos
  \S     (always) push a space
  [      the IF body (technically a FOR loop)
   #N    if true, remove the space and push an N
  ]      end IF
  `      output the pushed character
  "#     remove the result of the conditional
 ]       end x-pos FOR
 \L`     output a newline
]        end y-pos FOR

在对这个答案进行了一些极端的研究之后,我发现了一个39字节的解决方案,尽管它要复杂得多。

_'1[y~+y;[#1+3:"2:'%2<y~=|\ [#N]`"]\
`]

任务3-GCD

__'{"3:~2@%'}`

这是基于堆栈的方法。

__                 input the two numbers
  '                use one of the number as a condition so the WHILE loop starts
   {        }      a WHILE loop. Repeats while the c-stack has a true value on top
    "              get the number back from the c-stack to do operations on it
     3:            make it so that there are threes copies on the stack
       ~           takes one of the copies from earlier and converts it to a zero
        2@         take the top item on the stack and move it behind the other two #s
          %        modulo operation
           '       use this number as the condition
             `     since one number is zero (and on the c-stack) print the 
                   other number, which is on m-stack

29

2012年- 朱莉娅

语言史

Julia是由Jeff Bezanson,Stefan Karpinski和Viral Shah于2012年开发的,而Jeff在Alan Edelman教授的指导下是麻省理工学院(MIT)的学生。他们渴望一种开源,快速,动态(同时还有许多其他事物)同时又易于在各种应用程序中使用的编程语言。产品是Julia,这是一种高性能科学计算的新方法。

“你好,世界!” 变体

println("Julia was made in 2012!")

在Julia中打印到STDOUT非常简单!

ASCII艺术N

function asciin(n)
    # Create an nxn matrix of spaces
    m = fill(" ", (n, n))

    # Fill the first and last columns with "N"
    m[:,1] = m[:,n] = "N"

    # Fill the diagonal elements with "N"
    setindex!(m, "N", diagind(m))

    # Print each row of the matrix as a joined string
    for i = 1:n
        println(join(m[i,:]))
    end
end

代码缩进以提高可读性,但是Julia对空格没有任何限制。

GCD

function g(a, b)
    b == 0 ? a : g(b, a % b)
end

函数中列出的最后一件事是隐式返回的。


27

1988年-Mathematica

还是应该将其称为Wolfram语言

任务0

Mathematica的创建者是Wolfram Research的创始人兼首席执行官Stephen Wolfram。在开发Mathematica之前,他是物理学家。物理学中有大量的代数计算,因此他成为Macsyma的用户。

沃尔夫拉姆(Wolfram)于1979年获得博士学位,当时他20岁。他认为自己需要比Macsyma更好的CAS来进行物理学,因此他开始编写SMP(“符号操纵程序”)。SMP的第一个版本发布于1981年。SMP是Mathematica的前身。尽管它对Mathematica产生了深远的影响,但Mathematica从未使用过任何代码。

1986年,Wolfram决定编写一个“最终计算系统”。他于1986年开始编写代码,并于1987年成立了Wolfram Research。最后,Mathematica 1.0于1988年6月23日发布。

Mathematica 1.0

我没有找到Mathematica 1.0。实际上,Mathematica 1.0既没有Windows版本也没有Linux版本。但是我在中文网站上找到了Mathematica 2.0。它仍然可以在Windows XP上运行。

Mathematica 2.0

任务1

Print["Mathematica was made in 1988!"]

或者简单地:

"Mathematica was made in 1988!"

任务2

在当今的Mathematica中,我们可以写:

asciiArtN[n_] := Print @@@ SparseArray[{i_, 1 | i_ | n} -> "N", {n, n}, " "]

就像JuliaR一样,这是一个矩阵解决方案。在Mathematica中,可以使用模式匹配来定义稀疏矩阵。

但是,它SparseArray是在Mathematica 5.0中引入的,因此我们不能在Mathematica 1.0中使用它。

这是在Mathematica 1.0中可用的解决方案:

asciiArtN[n_] := Block[{f},
  f[i_, 1]  = "N";
  f[i_, i_] = "N";
  f[i_, n]  = "N";
  f[__]     = " ";
  Apply[Print, Array[f, {n, n}], 1];
]

我们不能写,f[i_, 1 | i_ | n] = "N"因为它Alternatives是在Mathematica 2.0中引入的。

任务3

我们可以只使用内置函数:

gcd = GCD

或者我们可以使用GCD的定义:

gcd = Max[Intersection @@ Divisors[{##}]] &;

或者我们可以使用LCM,尽管更常见的是LCM是根据GCD计算的:

gcd = Times[##]/LCM[##] &;

或者我们可以将欧几里得算法与模式匹配一​​起使用:

gcd[a_, 0] := a
gcd[a_, b_] := gcd[b, Mod[a, b]]

或作为匿名函数:

gcd = If[#2 == 0, #1, #0[#2, Mod[##]]] &;

Mathematica 1.0中引入了以上所有功能。


3
这是比我更好的答案。我要删除我的
马丁·恩德

25

1999年-XSLT

万维网联盟(W3C)创建XSLT来转换XML转换为HTML,文本等下面的例子假定输入被封闭在<input>..</input>标签。

任务1

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">XSLT was made in 1999!</xsl:template>
</xsl:stylesheet>

这很简单。它input在顶层匹配一个标签,并用所需的输出替换它。

任务2

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">
    <xsl:call-template name="loop">
      <xsl:with-param name="i">1</xsl:with-param>
      <xsl:with-param name="n">
        <xsl:value-of select="."/>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="loop">
    <xsl:param name="i"/>
    <xsl:param name="n"/>
    <xsl:choose>
      <xsl:when test="$i = 1 or $i = $n">
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$n - 2"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N&#13;&#10;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$i - 2"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N</xsl:text>
        <xsl:call-template name="spaces">
          <xsl:with-param name="n">
            <xsl:value-of select="$n - $i - 1"/>
          </xsl:with-param>
        </xsl:call-template>
        <xsl:text>N&#13;&#10;</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="$i &lt; $n">
      <xsl:call-template name="loop">
        <xsl:with-param name="i">
          <xsl:value-of select="$i + 1"/>
        </xsl:with-param>
        <xsl:with-param name="n">
          <xsl:value-of select="$n"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
      <xsl:template name="spaces">
    <xsl:param name="n"/>
    <xsl:if test="$n &gt; 0">
      <xsl:text> </xsl:text>
      <xsl:call-template name="spaces">
        <xsl:with-param name="n">
          <xsl:value-of select="$n - 1"/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

这个定义了2个递归模板,loopspacesloop带有参数i并从位置开始n生成所需的输出。with参数将生成空格。nispacesnn

任务3

为此输入必须在<input><num>..</num><num>..</num></input>标签中。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
  <xsl:template match="/input">
    <xsl:call-template name="gcd">
      <xsl:with-param name="a"><xsl:value-of select="num[1]"/></xsl:with-param>
      <xsl:with-param name="b"><xsl:value-of select="num[2]"/></xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="gcd">
    <xsl:param name="a"/>
    <xsl:param name="b"/>
    <xsl:choose>
      <xsl:when test="$b = 0"><xsl:value-of select="$a"/></xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="gcd">
          <xsl:with-param name="a"><xsl:value-of select="$b"/></xsl:with-param>
          <xsl:with-param name="b"><xsl:value-of select="$a mod $b"/></xsl:with-param>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

这只是一个gcd使用欧几里得算法的递归模板。


他们说INTERCAL很奇怪!
kirbyfan64sos

2
@ kirbyfan64sos坦白地说,无论如何都不应将其用于此东西……
LegionMammal978

24

2014年-CJam

CJam由PPCG用户aditsu创建,并于2014年4月左右发布。

“你好,世界!” 变体

"CJam was made in 2014!"

CJam在程序末尾自动打印堆栈的内容

ASCII艺术N

ri:R'#*a_R2-,{_)S*'#+\R((-zS*+}%+\+R<zN*

代码说明:

ri:R                                       "Read the input as integer in R";
    '#*a                                   "Get a string of R # and wrap it in an array";
        _R2-,{                }%           "Copy that string and then run this loop R-2";
                                           "times for the diagonal";
              _)S*                         "Get iteration index + 1 spaces";
                  '#+                      "Append the hash";
                     \R((-zS*+             "Append remaining spaces";
                                +\+        "Append and prepend the initial # string";
                                   R<      "Take only R columns/rows. This is for";
                                           "tackling input 1";
                                     zN*   "Transpose and join with new lines";

通过STDIN输入N的高度/宽度。在这里在线尝试

GCD

l~{_@\%}h;

通过STDIN将两个数字作为输入。在这里在线尝试


我意识到这不是[code-golf],但是您可以将ASCII-art N程序缩短为ri_S*0'NtW'Nta1$*\,Sf*'Nf+..e>N*现代CJam。
Esolanging Fruit '18

24

1990年-Haskell

Haskell是一种流行的(或者我应该说:最受欢迎)纯函数式语言。它以其不寻常的评估模型(默认情况下,一切都是懒惰的,或者从技术上来说,是非严格的)和基于Hindley-Milner的类型系统(即使到现在仍是最强大的类型系统)而从主流中脱颖而出的。

任务1

main = putStrLn "Haskell was made in 1990!"

任务2

-- Infinite list of growing letters 'N'
bigNs :: [[[Char]]]
bigNs = ["N"]
      : ["NN","NN"]
      : [ ins (ins 'N' t) $ map (ins ' ') n | n@(t:_) <- tail bigNs ]

-- Insert a new element after the head (i.e. at the second position).
ins :: a -> [a] -> [a]
ins x (l:ls) = l:x:ls

演示,打印整个无限列表(直到用户中止或世界结束...)

GHCi> mapM_ (putStrLn . unlines) bigNs
N

NN
NN

N N
NNN
N N

N  N
NN N
N NN
N  N

N   N
NN  N
N N N
N  NN
N   N

N    N
NN   N
N N  N
N  N N
N   NN
N    N

...

当然,通过仅访问无限列表中的一个元素,您可以轻松地获得其中之一:

main :: IO ()
main = do
   i <- readLn
   putStrLn . unlines $ bigNs!!i

任务3

gcd' :: Integer -> Integer -> Integer
gcd' a 0 = a
gcd' a b = gcd' b $ a`mod`b

23

1972年-INTERCAL

而且您认为Fortran和Cobol很奇怪。疯了吧!

任务1

DO ,1 <- #27
DO ,1SUB#1 <- #110
DO ,1SUB#2 <- #32
DO ,1SUB#3 <- #72
PLEASE DO ,1SUB#4 <- #136
DO ,1SUB#5 <- #88
DO ,1SUB#6 <- #136
PLEASE DO ,1SUB#7 <- #64
DO ,1SUB#8 <- #80
DO ,1SUB#9 <- #46
PLEASE DO ,1SUB#10 <- #22
DO ,1SUB#11 <- #104
DO ,1SUB#12 <- #184
PLEASE DO ,1SUB#13 <- #202
DO ,1SUB#14 <- #78
DO ,1SUB#15 <- #48
PLEASE DO ,1SUB#16 <- #96
DO ,1SUB#17 <- #128
DO ,1SUB#18 <- #162
PLEASE DO ,1SUB#19 <- #110
DO ,1SUB#20 <- #32
DO ,1SUB#21 <- #114
PLEASE DO ,1SUB#22 <- #120
DO ,1SUB#23 <- #240
DO ,1SUB#24 <- #128
PLEASE DO ,1SUB#25 <- #208
DO ,1SUB#26 <- #200
DO ,1SUB#27 <- #52
DO READ OUT ,1
DO GIVE UP

我不会尝试解释INTERCAL的输入和输出系统;只是读这篇,希望你不会死。

任务2

DO WRITE IN 7
DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .8 <- .3
DO .5 <- .7
DO .6 <- .8
DO ,9 <- #2

DO (100) NEXT
DO (1) NEXT

(100) DO (99) NEXT
DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
PLEASE GIVE UP

(99) DO .1 <- .7
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(1) PLEASE DO (3) NEXT
PLEASE DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
PLEASE GIVE UP

(4) DO (8) NEXT
DO ,9SUB#1 <- #176
DO ,9SUB#2 <- #80
PLEASE DO READ OUT ,9
DO .6 <- .8
DO .1 <- .5
DO .2 <- #1
DO (1010) NEXT
DO .5 <- .3
DO .1 <- '.5~.5'~#1
PLEASE DO FORGET .1
DO RESUME #1

(8) DO (5) NEXT

(5) PLEASE DO (6) NEXT
PLEASE DO FORGET #1
DO (5) NEXT

(6) PLEASE DO (7) NEXT
DO RESUME #2

(7) DO (10) NEXT
DO .1 <- .6
DO .2 <- #1
PLEASE DO (1010) NEXT
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(10) DO (11) NEXT
DO (13) NEXT
DO (14) NEXT
DO (15) NEXT

(11) DO (111) NEXT
DO (112) NEXT

(13) DO (113) NEXT
DO (112) NEXT

(14) DO (114) NEXT
DO (112) NEXT

(111) DO .1 <- .6
DO .2 <- .8
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(112) DO ,9SUB#1 <- #142
DO ,9SUB#2 <- #114
PLEASE DO READ OUT ,9
DO RESUME #3

(113) DO .1 <- .6
DO .2 <- #1
DO (1000) NEXT
DO .1 <- .5
DO .2 <- .3
DO (1010) NEXT
DO .1 <- '.3~.3'~#1
PLEASE DO FORGET .1
DO RESUME #1

(114) DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

(15) DO ,9SUB#1 <- #252
DO ,9SUB#2 <- #4
PLEASE DO READ OUT ,9
DO RESUME #2

天哪 这花了我一些时间来弄清楚。标签号是一团糟,因此反映了这一点。除非有人问,否则我不会尝试解释这一点。

任务3

DO WRITE IN .5
DO WRITE IN .6

DO (1) NEXT

(1) PLEASE DO (3) NEXT
DO FORGET #1
DO (1) NEXT

(3) DO (4) NEXT
DO READ OUT .5
PLEASE GIVE UP

(4) DO .1 <- .5
DO .2 <- .6
PLEASE DO (1040) NEXT
DO .1 <- .3
DO .2 <- .6
PLEASE DO (1039) NEXT
DO .2 <- .3
DO .1 <- .5
DO (1010) NEXT
DO .5 <- .6
DO .6 <- .3
DO .1 <- '.6~.6'~#1
PLEASE DO FORGET .1
DO RESUME #1

这有点简单。由于INTERCAL的...怪异,您必须输入如下数字:

THREE FIVE

例如,要获取42和16的GCD,请输入:

FOUR TWO
ONE SIX

它还会以罗马数字打印数字...因为这对您而言是INTERCAL!


2
不是19 7 2吗?(写完:P后,我可以理解您是否有点头晕)由于此错误,您的答案被认为是无效的,这是很遗憾的。
marinus

@marinus谢谢!固定!
kirbyfan64sos 2015年

5
请解释一下。(当然,有时间的时候;;)
DLosc 2015年

1
INTERCAL是我从未学习过的最喜欢的语言!
CJ丹尼斯

1
PLEASE GIVE UP。我已经做到了..
RedClover

23

1967年-APL

1957年,肯·艾弗森(Ken Iverson)在哈佛大学开始为数组处理开发数学符号。在1960年代,他的表示法在IBM被发展成为一种编程语言。第一个部分实现创建于1963年,甚至在高中时还用于向学生传授先验功能。完整,可用的实现必须等到1965年。两年来,它仅在IBM内部使用。1967年,IBM公开发布了在IBM 1130计算机上运行的APL解释器,该解释器已于1966年完成。您可以理解,选择一年是多么困难,但是,我认为应该是1967年,因为这是向公众提供全面实施的第一年。如果有人真的不同意,我可以更改它。

APL \ 360的源代码和仿真器一样,都 在线上。这就是我用来测试这些示例的内容。它可以追溯到1967年,与APL \ 1130(对于前面提到的IBM 1130)一样,它或多或少是真正的原始版本。不出所料,这是非常原始的。它缺乏对小写字母等细腻的支持,任何运算符都只能使用内置函数,并且内置函数集非常稀疏(尤其only or,并且 不能作为double gcd)。原始的完整描述 在这里,但是,我注意到我所拥有的版本相对于该文档甚至还不完整,缺乏其他版本。

我已经以Unicode格式(以便您可以阅读)和原始编码(因此可以将它们剪切并粘贴到模拟器的APL窗口中)提供了程序。

令人难以置信的是,在现代版本的Dyalog,NARS2000和GNU APL中,这些程序可以正常运行且没有任何更改(除了编码)。所以我想我已经找到了编写便携式APL的方法:假装是1967年!

任务1:

Unicode:

⎕←'APL WAS MADE IN 1967!'

APL \ 360:

L[Kapl was made in 1967ÝK

任务2:

Unicode:

⎕←' N'[1+((2⍴N)⍴(⍳N)∊1,N)∨(⍳N)∘.=⍳N←⎕]

APL \ 360:

L[K nK;1-::2Rn"R:In"E1,n"(:In"J.%In[L'

任务3:

我已经解决了标准的递归方法。从理论上讲,您可以做一些聪明且面向数组的事情,例如J答案;但是实际上,它具有O(N)的内存使用量,并很快使Flower-Power时代的硬件和软件不堪重负。

Unicode:

∇R←A GCD B
R←A
→(B=0)/0
R←B GCD B|A
∇

⎕←⎕ GCD ⎕

APL \ 360:

Gr[a gcd b
r[a
{:b%0"/0
r[b gcd bMa
G

L[L gcd L

这太棒了。
Alex A.

22

1996年- 奥卡姆

我等了一天多来填补1996年,所以我可以填写Ruby。好吧,为什么不学习OCaml,似乎类似于haskell ...

你好,世界

print_endline "OCaml was made in 1996!";;

ASCII码

let ascii n =
  let rec ascii' = function
    | 0 -> ()
    | i ->
        let s = "N" ^ String.make (n-2) ' ' ^ "N" in
        String.fill s (n-i) 1 'N';
        print_endline s;
        ascii' (i-1)
  in ascii' n;;

可变字符串!

GCD

let rec gcd a b = if b = 0 then a else gcd b (a mod b);;

==,中缀mod,很可爱


抱歉,我填写了Ruby :)
零光纤

4
+1用于学习语言以应对这一挑战。:)
Alex A.

您也刚刚学习了F#!(这是CLR上的OCaml以及一些其他功能)。
罗伯特·弗雷泽

22

2005- 前奏

Prelude是一种非常有趣的语言,其源代码由并行执行的多个“语音”组成,非常喜欢用来解决问题。它旨在作为其姊妹语言赋格的ASCII表示形式,赋格实际上以.midi文件作为其源代码,并将Prelude中的指令编码为声音旋律中的间隔。

前奏相当简单,但图灵完成了(前提是您至少使用了2种声音)。正如我所说,声音(代码行)是逐列同时执行的。每个声音都在其自己的堆栈上运行,该堆栈初始化为无限数量的零。Prelude支持以下说明:

0-9 ... Push the corresponding digit.
+   ... Add the top two numbers on the stack.
-   ... Subtract the top number from the one beneath.
#   ... Discard the top of the stack.
^   ... Copy the top value from the voice above.
v   ... Copy the top value from the voice below.
?   ... Read a number and push it onto the stack.
!   ... Print the top number (and pop it from the stack).
(   ... If the top of the stack is zero, jump past the matching ')'.
)   ... If the top of the stack is zero, jump to the column after the matching '('.

一些附加说明:

  • 声音是循环的,因此^顶部声音是底部声音的副本(反之亦然)。
  • 多个?!同一列从上到下执行。
  • 按照语言规范?!使用相应的字符代码读写字符。但是,Python解释器在其代码中也有一个开关来代替自己打印数字。出于测试目的,我实际上使用的是修改版本,该版本也可以读取数字而不是字符。但是,这里的共识是数字输入/输出实际上可以作为字节值给出,因此这些修改对于制作有效的处理数字的程序不是必需的。
  • 匹配()不需要相同的声音。用于该条件的声音始终(出现的声音。因此,的垂直位置)完全不相关。
  • 由于Prelude同时执行的性质,与a相同列中的任何指令(仅在循环开始之前执行一次,而无论是否进入循环。同样,在)每次迭代结束时都执行与a相同列中的任何指令,而不管该迭代之后是否退出循环。

我将首先向您展示这三个程序,而无需多加评论。您可以在下面找到详细的说明。

程序

“你好,世界!” 变体

9(1-)v98+^++!9v+!  v88++2+!^  ! ^9-3-! v      !    v2-!55+!
8 8+ !     7v+! 1v+!88+^+!^4-!^ v8-^ !!!9v+  !^9+9+!  v5+!
     ^98++4+! ^8-! ^4-   ^ #!^6-!    ^^  #5+! v    ^2-!1+!

如果您使用的是Python解释器,请确保NUMERIC_OUTPUT = False

ASCII艺术N

      v2-(1-)v         
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
     v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#

为了易于使用,该程序受益于将输入读取为数字,但输出不得为数字。因此,如果您使用的是经过修改的Python解释器,请设置

NUMERIC_INPUT = True
NUMERIC_OUTPUT = False

GCD

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
     ^^ (##v^v+)#  0 (0 )   
      1) ^ #  - 1+(#)#

最好与所有数字输入/输出一起使用,即

NUMERIC_INPUT = True
NUMERIC_OUTPUT = True

说明

“你好,世界!” 变体

这是相当直接的。我正在使用3种声音依次为中的所有字符生成字符代码Prelude was made in 2005!。我从计算开始8 + 9*8 = 80,这是以下字符代码P

 9(1-)
 8 8+

之后,我基本上只复制前一个字符代码,然后将差值加或减到下一个字符代码。这是代码,但每个代码都!替换为要打印的字符(_空格和%数字):

9(1-)v98+^++r9v+u  v88++2+w^  _ ^9-3-a v      _    v2-%55+!
8 8+ P     7v+l 1v+e88+^+_^4-s^ v8-^ de_9v+  n^9+9+%  v5+%
     ^98++4+e ^8-d ^4-   ^ #a^6-m    ^^  #5+i v    ^2-%1+!

最终会55+!打印尾随换行符,只是因为它更好。

顺便说一句,此任务的声音数量几乎是任意的,但是3相当方便,因为它是每个声音可以直接访问彼此声音的最大数量。

ASCII艺术N

      v2-(1-)v         
9(1-)?1-( v!  (1-55+!      0     (0)#  ))55+!
4-4+                  v^-#
     v!      v! v1-v!(1- ^(#^!0)# v! )v!
6 8+           v#

到目前为止,这5种声音无疑是我编写的最复杂的程序之一。这些声音大致具有以下目的:

  1. 仅仅是一个辅助声音,可以存储N-1在内部循环中使用。
  2. 这是一种“主要”语音,它读取输入,包含一个重要的开关,还包含一个外部循环(即行中的一个)。
  3. 这样32可以方便地打印空间。
  4. 这包含内部循环(列上的一个)。
  5. 这将存储一个78以方便打印N

让我们逐一遍查代码。首先,我要创建32as -4 + 9*478as 6 + 9*8

9(1-)
4-4+

6 8+

现在,我N在阅读输入N和存储N-1以及N-2前两种声音的同时打印一张(因为我们总是需要一张):

      v2-
     ?1-

     v!

接下来,有一个以为条件的“循环” N-1。在循环结束时,第二个声音始终减小为0,并且循环在第一次迭代后退出。因此,本质上仅此if(N > 1){...}。循环之后,我们打印一条尾随换行符。回顾一下,我们现在有了以下框架:

      v2-
9(1-)?1-(                               )55+!
4-4+
     v!
6 8+

在此条件内,我们首先用N-2空格和一个空格隔开N以完成第一行,并且还将N-1第一个声音存储起来以备将来使用:

         (1-)v         
          v!  

             v!

现在是代码的实质。首先,有一个外部循环,它打印N-1行。对于每一行,我们首先打印一个换行符和一个N。然后我们循环N-2时间,打印空格或Ns(稍后再介绍)。最后,我们打印另一个N

               1-55+!  

                v1-v!(               )v!
               v#

最后,有趣的部分:打印每一行(并获得N正确的位置)。Prelude中实际上并没有if / else,因此我必须使用两个循环以不同的声音自己构建它。通过减去内循环变量和外循环变量可以轻松获得条件- 0如果要打印N,则得到;如果要打印空格,则为非零。

Prelude中if / else的基本思想是在相关值(“ if”(或非零)代码)之后放置一个循环,然后通过按下来立即退出0。在另一个声音上,您保留一个非零值,并在“ if”循环之后保留另一个循环。 “ if”循环中,您应在其他声音之上加上零,以防止执行“ else”。您可以将零值推到非零值之上,还是在下面有零的情况下直接丢弃非零值,则具有一定的灵活性,但这是通常的想法。如果您想继续使用相关的声音,则可能还需要随后进行一些清理。代码如下所示:

                           0     (0)#
                      v^-#
                      1- ^(#^!0)# v! 

就是这样!

GCD

这“只是”欧几里得算法的迭代实现。但是Prelude中的模数有点烦人,主要是因为您不容易检查数字是正数还是负数。这段代码利用了我之前写的signum实现。即代码的很大一部分只是变成一个数字,或。然后可以通过加或减轻松将其变为正数或负数的条件。-1011

?(                         v)
? (^-(0 # v   #       ^+0)#^ !
     ^^ (##v^v+)#  0 (0 )   
      1) ^ #  - 1+(#)#

所以这次我们有四个声音。第一个声音仅跟踪b并包含主要终止条件(即,当b变为时,循环退出0)。第二个声音包含a并在声音的帮助下进行了三个和四个计算a % b,然后与前一个交换结果b。最后,!打印ab == 0

让我们先看一下signum部分:

     (0 # v   #
     ^^ (##v^v+)#
      1) ^ #  -

n在这些声音中的第一个(完整程序中的第二个声音)上找到了输入号码。结果将以低声结束。预期其他两个声音为空(即填充零)。请注意,如果n == 0,则将跳过两个循环,并且底部语音仍包含0,正是我们想要的。

如果n非零,则进入第一个小循环。我们推一个零立即退出它,将两个副本n放到中间语音中,将一个副本1放到底部语音中。现在的基本思想是增加一个副本,n同时减少另一个副本,n直到其中一个副本为零。在执行此操作时,1底部语音始终会翻转其符号(通过从0堆栈下方的符号减去该符号很容易实现)。进行设置时,其中一个数字为零时,底部的声音将包含正确的符号。

现在模减去实现ba直到结果是否定的。发生这种情况时,我们b再次添加一个。就是这样:

  (^-  signum         ^+0)#
       signum      0 (0 )   
       signum   1+(#)#

请注意底部的if / else构造,与我用于任务2的构造类似。


2
这确实应该是Prelude教程的一部分。
Alex A.

21

2007年-从头开始

Scratch是由MIT出于教育目的而使用的一种语言。我已经参与了5年;稍后再讨论。

所有这些都可以在这里查看。

我现在非常着急,稍后将解释这些片段。希望他们是不言自明的。

任务1

在此处输入图片说明

任务2

在此处输入图片说明

任务3

在此处输入图片说明


以后吗?
dfeuer

21

1972年-C

我们都知道C,不是吗?C是在Bell Labs和Unix一起创建的。Unix主要是用C编写的。所有现代Unix派生类仍然主要是用C编写的。C的语法影响了许多编程语言。它可能是最古老的编程语言,仍在新开发中广泛使用。

C本身是B的后代,我希望它也能出现在此列表中。没有“ A”编程语言:B是BCPL的变体,而BCPL又是精简的CPL。这些语言都不曾很流行。但是,BCPL是编写第一个“ Hello World”程序的语言。另一个有趣的事实是B同时拥有/* *///注释,但C放弃了//注释。后来将它们重新引入C99标准的C语言中。

这里的C程序已使用1974年的Unix V5 C编译器进行了测试。这是我能找到并使用的最古老的C编译器,并且这些程序无法在现代C编译器上进行编译。(所做的更改之一是,变异运算符+=曾经被编写=+。)

#include <... >还不存在。标准库也没有太多。我必须自己写atoi。我浏览了一些V5源代码以弄清楚哪些是允许的,哪些是不允许的。我使用的版本是第一个包含structs的版本,但是由于我没有使用s,并且直到V7(如K&R C),语法似乎并没有太大变化,这可能也适用于早期版本。

我已尽力以与V5源代码使用的样式相同的方式编写代码。(但是,这并不是非常一致的。)

在此处查找 指向Unix V5(一个仿真器)的链接,以及在现代计算机上运行它的说明。

任务1

main()
{
   write(1, "C was made in 1972!\n", 20);
}

任务2

atoi(str)
char *str;
{
    register num, digit;
    while (digit = *str++) {
        num =* 10;
        num =+ digit - '0';

    }
    return num;
}

N(n)
{
    register x, y;
    for (y=1; y<=n; y++) {
        for (x=1; x<=n; x++) {
            write(1, " N"+(x==1||x==y||x==n), 1);
        }
        write(1, "\n", 1);
    }
}

main(argc, argv)
char *argv[];
{
    N(atoi(argv[1]));
}

任务3

atoi(str)
char *str;
{
    register num, digit;
    while (digit = *str++) {
        num =* 10;
        num =+ digit - '0';
    }
    return num;
}

gcd(a, b)
{
    return b ? gcd(b, a%b) : a;
}

main(argc, argv)
char *argv[];
{
    printf("%d\n", gcd(atoi(argv[1]), atoi(argv[2])));
}

哇,我从未意识到C发生了多大的变化……您从哪里获得了该编译器?
kirbyfan64sos 2015年

1
编译器是Unix V5附带的编译器。描述中有一个博客文章的链接,该博客文章向您显示在哪里获取文件以及如何在现代计算机上运行它们。(在这里)。一旦运行,就可以使用将代码加载到该代码上cat > file.c。(和往常一样,以Ctrl-D结尾)。同样,C的变化少于您的想像:如果您在现代等效项and中交换=*=+atoi功能,现代GCC可以很好地编译它们并且它们也可以运行。几乎没有任何警告。*=+=
marinus

1
minnie.tuhs.org/cgi-bin/utree.pl?file=V2/c是我可以找到的最早的C编译器(来自V2,发布日期为'72)。
Oberon 2015年

20

2009年- 伊德里斯

Idris是一种依赖类型的纯函数式语言,除了提供依赖类型可以实现的极其严格的证明可能性之外,它强调实际上实际上可用于实际应用。

任务1

module Main

main : IO ()
main = putStrLn "Idris was made in 2009!"

任务2

module InN

import Data.Fin
import Data.Vect

genN : Vect n (Vect n Char)
genN = [[ if inN x y then 'N' else ' ' | x<-range ]| y<-range ]

||| Helper function, determines whether the char at coordinate (x,y)
||| is part of the letter:
inN : Fin n -> Fin n -> Bool
inN {n=S _} x y = x==0 || x==y || x==last

这不是一个程序,而是一个函数(更确切地说是从属值),将所需的字母N生成为二维数组。

$ idris ascii-n.idr 
     ____    __     _                                          
    /  _/___/ /____(_)____                                     
    / // __  / ___/ / ___/     Version 0.9.17.1-
  _/ // /_/ / /  / (__  )      http://www.idris-lang.org/      
 /___/\__,_/_/  /_/____/       Type :? for help               

Idris is free software with ABSOLUTELY NO WARRANTY.            
For details type :warranty.
Type checking ./ascii-n.idr
*ascii-n> genN {n=4}
[['N', ' ', ' ', 'N'],
 ['N', 'N', ' ', 'N'],
 ['N', ' ', 'N', 'N'],
 ['N', ' ', ' ', 'N']] : Vect 4 (Vect 4 Char)

任务3

module gcd

gcd' : Nat -> Nat -> Nat
gcd' a Z = a
gcd' a b = gcd' b $ a`mod`b

请注意,我必须选择名称,gcd'因为该名称gcd已经在Idris前奏中定义。

Type checking ./gcd.idr
*gcd> gcd' 8 12
4 : Nat
*gcd> gcd' 12 8
4 : Nat
*gcd> gcd' 234 876
6 : Nat

这看起来好像他们把哈斯克尔,交换:::,改_Z
wchargin 2015年

@WChargin Z实际上是的构造函数0 : Nat。下划线在Idris中使用,就像在Haskell中一样。
停止转动counterclockwis

哦,那你走了!:)
wchargin 2015年

19

2014年-Pyth

由于我们拥有CJam,因此我们也可能还有Pyth以确保完整性:)

Pyth是一个高尔夫语言@isaacg其编译为Python的。值得注意的是在过程上和使用前缀表示法。Pyth 于2014年6月左右首次出现。

“你好,世界!” 变体

"Pyth was made in 2014!

请注意,缺少引号,如果Pyth程序以字符串结尾,则该引号是可选的。

ASCII艺术N

VQ+\Nt+P++*Nd\N*t-QNd\N

在线尝试。等效的Python是:

Q = eval(input())
for N in range(Q):
    print("N"+((" "*N+"N"+(Q-N-1)*" ")[:-1]+"N")[1:])

或展开(第一行和第三行是隐式的):

Q = eval(input())                                        # 
for N in range(Q):                                       #   VQ
    print(                                          )    # 
          "N"+                                           #     +\N
              (                                )[1:]     #        t
                                           +"N"          #         +              \N
               (                     )[:-1]              #          P
                         +(Q-N-1)*" "                    #           +      *t-QNd
                     +"N"                                #            +   \N
                " "*N                                    #             *Nd

GCD

=GvwWQAGQ,Q%GQ)G

该程序使用欧几里得算法,并用换行符分隔两个数字。在线尝试

Q = eval(input())     #
G = eval(input())     #    =Gvw
while Q != 0:         #        WQ
  G, Q = Q, G % Q     #          AGQ,Q%GQ)
print(G)              #                   G

i.uQ如果我们将内置函数用于GCD,则长度会更短。这等效于print(gcd(*eval(input())))(以两个逗号分隔的数字作为输入)。


Drat-我要去做Pyth xP
theonlygusti

@isaacg我不禁想知道,不妨在这里问:pyth是否受到pyg的任何形式,形状或形式的启发?
ɐɔıʇǝɥʇuʎs

@ɐɔıʇǝɥʇuʎs我在制作Pyth之前见过PYG,它可能影响了1个字符-1个概念的方法。但是,如果有什么启发了Pyth,那可能就是golfscript。
isaacg 2015年

17

1964年- 达特茅斯BASIC

BASIC是一系列通用,高级编程语言,其设计理念强调易用性。1964年,John G. Kemeny和Thomas E. Kurtz在新罕布什尔州的达特茅斯学院设计了原始的BASIC语言。他们希望使科学和数学以外的其他领域的学生能够使用计算机。

我正在看的是1964年的BASIC 手册,以及运行它的Darthmouth分时系统的仿真器。服务器仍在运行,但可悲的是,注册帐户似乎是不可能的。目前,这些程序在理论上应该可以工作:

任务1

10 PRINT "BASIC WAS MADE IN 1964"
20 END

任务2

10 READ N
15 FOR Y = 1 TO N STEP 1
20 FOR X = 1 TO N STEP 1
25 IF X = 1 THEN 50
30 IF X = N THEN 50
35 IF X = Y THEN 50
40 PRINT " ",
45 GO TO 55
50 PRINT "N",
55 NEXT X
60 PRINT
65 NEXT Y
70 DATA 5
75 END

输出类似:

N                       N
N     N                 N
N           N           N
N                 N     N
N                       N

注意如何在程序(70 DATA 5)中输入输入内容;READ顶部的指令方式从那里获取数据。没有字符串连接,但是手册的第3.1节描述了如何将PRINT结果写入输出中的表格“区域”。

任务3

Euclid算法的慢速版本:

10 READ A, B
20 IF A = B THEN 80
30 IF A < B THEN 60
40 LET A = A - B
50 GO TO 20
60 LET B = B - A
70 GO TO 20
80 PRINT A
85 DATA 144, 250
90 END

输出:

2

最后,有人做了BASIC。
marinus

16

2010- WTFZOMFG

WTFZOMFG是基于Brainfuck的深奥语言。它是由Jay Songdahl在2010年制造的。“ WTFZOMFG”是“什么功能?Zen优化恶意文件密码器”的缩写。。

这是* nix系统编译器

任务1

'WTFZOMFG was made in 2010!\n"

任务2

/&(-.N%3 >&>s-{-(-. ).N}>{-(-. ).N}_0 '\n")

说明:

抱歉。我不擅长写解释。

/                                           # read the number and store it in cell 0
 &                                          # copy it to cell 1
  (                                         # loop while cell 0 isn't 0
   -                                        # decrease the value of cell 0
    .N                                      # print "N"
      %3                                    # copy cell 0 to cell 3
                                            # a space must be added after the number. I don't know if it's a bug of the compiler or a feature.
         >                                  # move to cell 1
          &                                 # copy cell 1 to cell 2
           >                                # move cell 2
            s                               # let cell 2 = cell 2 - cell 3
             -                              # decrease the value of cell 2
              {                             # if cell 2 isn't 0
               -                            # decrease the value of cell 2
                (-. )                       # while cell 2 isn't 0, decrease it and print " "
                     .N                     # print "N"
                       }                    # end if
                        >                   # move cell 3
                         {                  # if cell 3 isn't 0
                          -                 # decrease the value of cell 3
                           (-. )            # while cell 3 isn't 0, decrease it and print " "
                                .N          # print "N"
                                  }         # end if
                                   _0       # move to cell 0
                                      '\n"  # print a newline
                                          ) # 

任务3

/>>/(<<&>dm<s&>>%0 <&>)<<\

欧几里得算法。WTFZOMFG没有用于mod的命令,因此我必须使用d(除),m(乘)和s(减)。


16

2009年-开始

Go是Google开发的编程语言。开发始于2007年,但Go于2009年11月宣布。

Go是受C影响的静态类型语言,它强调简洁,简单和安全。

任务1:

package main
import "fmt"

func main(){
    fmt.Println("Go was made in 2009!")
}

第一行声明代码包。即使是打印一行的简单示例也必须成为一个包装的一部分。可执行文件总是被调用main

任务2:

package main

import (
        "fmt"
        "strings"
)

func main(){
    var n int
    fmt.Scan(&n)

    for i := 0; i < n; i++ {
        a := make([]string, n, n)
        for j := 0; j < n; j++ { a[j] = " " }

        a[0] = "N"
        a[i] = "N"
        a[n-1] = "N"

        s := strings.Join(a, "")
        fmt.Println(s)
    }
}

Go具有非常简洁的变量声明(i := 0与相同var i int = 0),并且编译器确定类型。这通常是动态语言中更常见的功能。使用这种简短的符号,将函数分配给变量(f := func(x int) int {/* Code */})并创建闭包也非常容易。

任务3:

package main

import "fmt"

func gcd(a, b int) int {
    for b != 0 {
        a, b = b, a%b
    }
    return a
}

func main(){
    var a, b int
    fmt.Scan(&a)
    fmt.Scan(&b)

    fmt.Println(gcd(a, b))
}

在这里,您可以看到 a, b = b, a%b语法,这非常好。我不知道确切的名字,但是在Python中它称为元组解包。使用相同的方法,您可以从函数(func f() (int, string) { return 42, "Hallo"})返回多个值。

这段代码中发生的另一件事是循环。for循环是Go中唯一的循环。While循环或do-while循环不存在。但是您可以轻松地为while循环for condition {}或无限循环创建一个等效项for {}


16

1991年-Python

语言史

在1980年代后期,Guido van Rossum开始将Python开发为一种爱好。它的名字来自Monty Python的Flying Circus,这是英国电视节目,Rossum是其粉丝。Python的第一个实现始于1989年,并于1991年发布。多年来,它已迅速普及,成为许多计算机入门课程的首选语言。

“你好,世界!” 变体

print("Python was made in 1991!")

请注意输入到的括号print。尽管此语法在Python 2中有效,但通常在Python 2中,您会省略这些括号。但是,它们在Python 3中是必需的。正如Zach Gates所建议的那样,在整个过程中都使用了括号,以确保此处提供的代码可在各个版本中使用。

ASCII艺术N

def asciin(n):
    if n == 1:
        print("N")
    else:
        print("N" + " "*(n-2) + "N")

        for i in range(2, n):
            print("N" + " "*(i-2) + "N" + " "*(n-i-1) + "N")

        print("N" + " "*(n-2) + "N")

使用定义功能def。字符串连接使用进行+,字符串重复使用进行*

GCD

def gcd(a, b):
    if b == 0:
        return(a)
    else:
        return(gcd(b, a % b))

请注意,Python需要结构化的空格。


16

1968年-Algol 68

IFIP工作组2.1将Algol 68定义为Algol 60的后继产品。

这是一种面向表达的语言,其中的每件事都具有价值。它也是正交的,您可以在其中以任何方式使用任何构造。例如,这意味着表达式可以位于分配的RHS和LHS上。

所有控件结构都具有缩写形式以及使用表达式的长形式。它还允许定义运算符。

语言的目标被引用为:

ALGOL 68设计的主要目的和原则:

  • 描述的完整性和清晰度
  • 正交设计
  • 安全,
  • 效率
  • 静态模式检查
  • 与模式无关的解析
  • 独立编译
  • 循环优化
  • 表示形式-最小和较大字符集

这些程序已经使用Algol 68 Genie解释器进行了测试,该解释器是该语言的完整实现。

现代程序员可能发现的一些功能有所不同,即不允许使用空语句。您不能随便添加;任何地方。SKIP如果您想明确地什么都不做,则必须使用该语句。它还允许非常轻松地对并发程序进行编码。值得注意的是,Algol 68还使用反向关键字作为终止符,例如esacodfi等。

例如,该语言具有一种用于编写代码的表示形式,该代码使用了许多字体,这些字体以粗体显示关键字,以斜体显示标识符。当时并且可能仍然没有编译器实现此设计功能。该语言允许使用踩踏模式对程序进行几种不同的具体表示。这样就可以使用有限的字符集来编写程序,例如在1960年代的计算机中可能会发现这种字符集。考虑一个简短的程序片段,它表示为:

如果 i < 0, 跳过 fi

可以为编译器在加速模式下准备如下:

'IF' I 'LT' 0 'THEN' 'SKIP' 'FI'

旋转模式下,这将是:

.IF I .LT 0 .THEN .SKIP .FI

情况下荡刀模式,这将是:

IF i < 0 THEN SKIP FI

当我从事一种编译器实现以及多年来专门用该语言进行编程时,我对这种语言非常满意。

任务1

打印((“ Algol 68于1968年制造!”,换行符))

这里要注意的是双括号。这是因为print是一个带有单个参数的函数,该参数是所有类型联合的可变长度数组。内括号是数组构造函数。这就是在这种强类型语言中处理多态的方式。

如果是暂存模式:

print (("Algol 68 was made in 1968!", newline))


C:\>a68g HelloWorld.a68
Algol 68 was made in 1968!

任务2

     int n ;
     ((n));
     对于 1 Ñ
          用于 Ĵ 1 Ñ
               ¢这里我们使用缩写IF子句¢
               打印(((Ĵ = 1 OR Ĵ = OR Ĵ = Ñ |
                    “N”
               |
                    “”
               )))
          OD ;
     打印((换行符))
     od

如果是暂存模式:

 INT n;
 read ((n));
 FOR i FROM 1 TO n DO
        FOR j FROM 1 TO n DO
            CO here we use an abbreviated IF clause CO
            print (( ( j = 1 OR j = i OR j = n |
                 "N"
            |
                 " "
            ) ))
        OD ;
        print ((newline))
    OD

C:\>a68g ASCIIart.a68
8
N      N
NN     N
N N    N
N  N   N
N   N  N
N    N N
N     NN
N      N

任务3

     ¢我们可以在陵定义我们自己的运营商68 ¢
     运算 =诠释 一个b诠释
          ((b = 0 |
               一个
          |
               b 一个 b
          ));
     int ij ;
     ((ij));
     打印((i j换行符

如果是暂存模式:

COMMENT we can define our own operators in Algol 68 COMMENT
OP % = ( INT a, b) INT:
    ((b = 0 |
        a
    |
       b % (a MOD b)
    ));
INT i,j;
read((i,j));
print(( i % j , newline))


C:\>a68g GCD.a68
4 12
         +4

7
这些可能是我30多年来编写并执行的第一个Algol 68程序。我发现它感人至深,甚至使我流泪。我从未意识到“世界你好!” 节目可能是如此激动!
Brian Tompsett-汤莱恩2015年

1
我非常期待60年代的语言,并且准备好使用BCPL,Simula,CORAL66,Fortran 66,PL / 1,SNOBL4,POP-1和更多其他语言,才发现我有规则等待5年的语言...至少还有很多人可以耕作。
Brian Tompsett-汤莱恩2015年

看到Fortran66(彻底的打孔卡暴力混乱),APL(超级大国符号的怪异混乱)和Algol68(实际上非​​常漂亮)之间的区别真的很酷。今天,您需要研究深奥的语言才能找到各种各样的方法...那时,这是相当主流的,不是吗?
停止转动逆时针

当然,修订报告要到1976年才发布。至少那是施普林格给出的版权年。我发现的扫描提到1978
。– Rhialto

[1] A. van Wijngaarden(ed。),Bl Mailloux,1.EL Peck,CBA Koster,算法语言ALGOL 68的报告,Numer。数学。14(1969)79-218;同样在Kibenietika 6(1969)和7(1970)中。[2] A. van Wijngaarden,Bl Mailloux,1.EL Peck,CBA Koster,M:Sintzoff,CBLindsey,LGLT Meertens和RG Fisker,关于算法语言ALGOL 68的修订报告,Acta Informat。5(1975)第1-3部分(重印本由柏林的Springer出版,以及阿姆斯特丹Mathematisch Centrum发行的Mathematical Center Tract 50);也在SIGPLAN Notices 12(5)(1977)中
Brian Tompsett-汤莱恩

16

1962年-斯诺博

“面向导向的符号语言”。起初表面上称为符号表达解释器“ SEXI”,然后必须对其进行更改,以防止1960年代时代的书呆子在提交工作时脸红。真实的故事。

这是最早可以本地处理字符串和模式的语言之一。确实,SNOBOL的第一个版本将字符串作为唯一的数据类型。然后通过解析完成数学运算。最初的实现是在IBM 7090上完成的。它似乎已经很久了,至少我找不到。我发现的是描述它的原始论文以及JavaSNOBOL3解释器,该解释器可以在现代计算机上运行

第一个SNOBOL 仅具有模式匹配和基本算法。然后SNOBOL 3添加了功能并更改了I / O,但否则似乎仍然向后兼容。SNOBOL 4更改了语法,并从那里发展成为Icon,它保持了模式匹配,但在其他情况下几乎看起来像是一种“常规”编程语言。

我编写的程序仅使用原始文件中描述的功能,因此应该与原始SNOBOL一起使用,但I / O除外,我以SNOBOL3样式进行了此操作,以便Java解释器可以运行它们。从本文看来,区别在于SNOBOL1使用带有特殊SYS变量的模式匹配,而SNOBOL3使用输入和输出变量:

  • 输入:
    • 1个 SYS .READ *DATA*
    • 3 DATA = SYSPPT
  • 输出:
    • 1个 SYS .PRINT 'A STRING' AND VARIABLES
    • 3 SYSPOT = 'A STRING' AND VARIABLES

进行这些替换将使您“真正”的SNOBOL1。当然,您将无法运行它。

任务1

START   SYSPOT = 'SNOBOL WAS MADE IN 1962!'

任务2

这显示了数学,字符串处理和流控制。SNOBOL3具有有用的功能,例如EQ检查是否相等。原始的SNOBOL没有,所以我没有使用过它们。

* READ N FROM INPUT
START   SYSPOT = 'SIZE?'
        SZ = SYSPPT

* INITIALIZE
        CS = ''
        ROW = '0'

* OUTPUT PREVIOUS ROW AND START NEXT ONE
ROW     COL = '0'
        SYSPOT = CS
        CS = ''

COL     SUCC = 'N'
        EQ1 = COL
        FAIL = 'CHKE'
        EQ2 = '0'         /(EQUAL)
CHKE    FAIL = 'CHKR'
        EQ2 = SZ - '1'    /(EQUAL)
CHKR    FAIL = 'SPACE'
        EQ2 = ROW         /(EQUAL)

* CONCATENATE THE RIGHT CHARACTER TO THE CURRENT LINE         
SPACE   CS = CS ' '       /(NEXT)
N       CS = CS 'N'       /(NEXT)

* FOR NUMBERS, SUBSTRING MATCH IS ENOUGH IF IT IS KNOWN A<=B
NEXT    COL = COL + '1'
        COL SZ            /F(COL)
        ROW = ROW + '1'
        ROW SZ            /F(ROW)S(FIN)

* THERE SEEMS TO BE NO EQUALITY CHECK, JUST SUBSTRING MATCHING
* OF COURSE, EQ1 == EQ2 IFF EQ1 CONTAINS EQ2 AND VICE VERSA
* THIS ALSO ILLUSTRATES INDIRECTION
EQUAL   EQ1 EQ2           /F($FAIL)
        EQ2 EQ1           /S($SUCC)F($FAIL)

* OUTPUT THE LAST LINE
FIN     SYSPOT = CS     

任务3

首先,无聊。唯一需要注意的是小于校验,它精确显示了面向字符串的SNOBOL的实际(B - A) '-'含义:表示“ BA的结果是否包含减号?”。SNOBOL3也可以LE(B,A),但是SNOBOL 1无法做到(至少本文没有提及)。

* READ A AND B
START   SYSPOT = 'A?'
        A = SYSPPT
        SYSPOT = 'B?'
        B = SYSPPT

* GCD LOOP
STEP    '0' (A - B)          /S(DONE)
        (B - A) '-'          /S(AB)F(BA)
AB      A = A - B            /(STEP)
BA      B = B - A            /(STEP)
DONE    SYSPOT = 'GCD: ' A

当然,当您拥有完全基于字符串和模式匹配的语言时,如果不真正使用模式匹配和替换,这将是一个耻辱。因此,这是那些基于一元的GCD之一,包括用于与一元之间进行转换的例程。

* READ A AND B
START   SYSPOT = 'A?'
        A = SYSPPT
        SYSPOT = 'B?'
        B = SYSPPT

* CONVERT TO UNARY
        UNA.IN = A
        UNA.FIN = 'ADONE'          /(UNA)
ADONE   A = UNA.R
        UNA.IN = B
        UNA.FIN = 'BDONE'          /(UNA)
BDONE   B = UNA.R


* USE STRING MATCHING TO FIND GCD
STEP    '' B                       /S(GDONE)
MATCH   A B =                      /S(MATCH)
        C = B
        B = A
        A = C                      /(STEP)

* CONVERT BACK TO DECIMAL
GDONE   DEC.IN = A
        DEC.FIN = 'DONE'           /(DEC)
DONE    SYSPOT = 'GCD: ' DEC.R     /(FIN)

***************************** 
* DECIMAL TO UNARY SUBROUTINE
UNA     UNA.R =
UNA.DGT UNA.IN *.DGT/'1'* =        /F($UNA.FIN)
        .X = UNA.R
        UNA.R =
UNA.MUL .X *.Y/'1'* =              /F(UNA.ADD)
        UNA.R = UNA.R '##########' /(UNA.MUL)
UNA.ADD '1' .DGT                   /S(UNA.1)
        '2' .DGT                   /S(UNA.2)
        '3' .DGT                   /S(UNA.3)
        '4' .DGT                   /S(UNA.4)
        '5' .DGT                   /S(UNA.5)
        '6' .DGT                   /S(UNA.6)
        '7' .DGT                   /S(UNA.7)
        '8' .DGT                   /S(UNA.8)
        '9' .DGT                   /S(UNA.9)
        '0' .DGT                   /S(UNA.DGT)
UNA.1   UNA.R = UNA.R '#'          /(UNA.DGT)
UNA.2   UNA.R = UNA.R '##'         /(UNA.DGT)
UNA.3   UNA.R = UNA.R '###'        /(UNA.DGT)
UNA.4   UNA.R = UNA.R '####'       /(UNA.DGT)
UNA.5   UNA.R = UNA.R '#####'      /(UNA.DGT)
UNA.6   UNA.R = UNA.R '######'     /(UNA.DGT)
UNA.7   UNA.R = UNA.R '#######'    /(UNA.DGT)
UNA.8   UNA.R = UNA.R '########'   /(UNA.DGT)
UNA.9   UNA.R = UNA.R '#########'  /(UNA.DGT)

*****************************
* UNARY TO DECIMAL SUBROUTINE
DEC     DEC.R =
DEC.DGT '' DEC.IN                  /S($DEC.FIN)
        .X = DEC.IN
        DEC.IN =
DEC.DIV .X '##########' =          /F(DEC.ADD)
        DEC.IN = DEC.IN '#'        /(DEC.DIV)
DEC.ADD '' .X                      /S(DEC.0)
        '#' .X                     /S(DEC.1)
        '##' .X                    /S(DEC.2)
        '###' .X                   /S(DEC.3)
        '####' .X                  /S(DEC.4)
        '#####' .X                 /S(DEC.5)
        '######' .X                /S(DEC.6)
        '#######' .X               /S(DEC.7)
        '########' .X              /S(DEC.8)
        '#########' .X             /S(DEC.9)
DEC.0   DEC.R = '0' DEC.R          /(DEC.DGT)
DEC.1   DEC.R = '1' DEC.R          /(DEC.DGT)
DEC.2   DEC.R = '2' DEC.R          /(DEC.DGT)
DEC.3   DEC.R = '3' DEC.R          /(DEC.DGT)
DEC.4   DEC.R = '4' DEC.R          /(DEC.DGT)
DEC.5   DEC.R = '5' DEC.R          /(DEC.DGT)
DEC.6   DEC.R = '6' DEC.R          /(DEC.DGT)
DEC.7   DEC.R = '7' DEC.R          /(DEC.DGT)
DEC.8   DEC.R = '8' DEC.R          /(DEC.DGT)
DEC.9   DEC.R = '9' DEC.R          /(DEC.DGT)

FIN     START

出色的背景工作!没有太多的1961年-它看起来像COMIT是我们所有的....
布莱恩Tompsett -汤莱恩

15

2012-打字稿

TypeScript是由Microsoft开发和维护的一种免费和开放源代码编程语言。

主要目标是:任何浏览器。任何主机。任何操作系统。开源。2012年10月发行

你好打字稿

Task1(name:string,year:number) {
    return name + " was made in "+ year +"!";
}

ASCII艺术

Task2(n:number,separator:string,space:string) {
    var result:string = "";
    for (var k = 0; k < n; k++)
    {
        for (var j = 0; j < n; j++)
        {
            var i = ((n * k) + j) % n;
            result+=(i == 0 || i == n - 1 || i == k) ? "N" : space;
        }
        result+=separator;
    }
    return result;
}

GCD

Task3(a:number,b:number) {
    while (a != 0 && b != 0)
        {
            if (a > b)
                a %= b;
            else
                b %= a;
        }

        if (a == 0)
            return b;
        else
            return a;
}

在线试用,并进行截屏


4
您忘了提到一件事:TypeScript是Javascript的超集,几乎没有语法更改,并且允许(?)强类型变量和参数。
Ismael Miguel

1
我的天哪,MS开源了!
Mega Man

15

2011年-飞镖

Dart是Google开发的一种开源编程语言,可以替代Javascript(尽管它可以编译为javascript)。它是Google在2011年的GOTO会议上揭幕的。

“你好,世界!” 变体:

main() {
  print('Dart was made in 2011!');
}

ASCII Art N:

Bruteforce方法在0(n²)处运行,但是除非您使用大数,否则它并不重要。

asciiN(int number){
    if(number == 1){
        print('N');
    }else{
        for(var i = 1; i <= number; i++){
            String currentLine = "";
            for(var j = 1; j <= number; j++){
                if(j==1 || j == number || j == i){
                    currentLine = currentLine + "N";
                }else{
                    currentLine = currentLine + " ";
                }
            }
            print(currentLine);
        }
    }
}

GCD

从Snap移植的简单Euclid方法!上面的例子。

int gcd(int first, int second){
if(second > first){
   return gcd(second, first);
    }else{
        if(first == 0){
            return second;
        }else{
            if(second ==0){
                return first;
            }else{
                return gcd(second, first-second);
            }
        }
    }
}

5
我不认为您可以在不到O(n²)的情况下输出××ASCII图形。
圣保罗Ebermann

@PaŭloEbermann我不太熟悉大O表示法或如何计算复杂度,但是Julia的示例看起来好像不是O(n²)。
Nzall 2015年

@AlexA。println()函数打印n个字符的字符串。我认为函数调用至少需要时间O(n)才能执行。在循环中,所以整个程序为O(n²)。
圣保罗Ebermann

@AlexA。我认为Ebermann所说的是在您的打印函数中有N个字符串串联操作。我们都在函数中执行n²字符串连接。我在每个内循环迭代中都执行一次,对于每个println()都执行一次。
Nzall

1
如果这不是科学技术,则显示N为O(n)(在屏幕上绘制3行,每行为O(n),因此复杂度为O(n))。或者,您可以说,使N具有O(N)复杂度...

15

2010-

Rust是Mozilla Research开发的通用,多范式,已编译的编程语言。它被设计为“安全,并发,实用的语言”,支持纯功能,并发角色,命令性过程和面向对象的样式。维基百科

任务1

fn main()
{
    println!("Rust was made in 2010!");
}

任务2

fn main()
{
    // get commandline arguments
    // "test 3"
    let args : Vec<_> = std::env::args().collect();

    // convert 2nd argument to integer
    let n = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap();
    print_n( n );
}

fn print_n( n: u32 )
{
    for y in range( 0, n )
    {
        for x in range( 0, n )
        {
            if x == 0 || x == y || x + 1 == n
            {
                print!("N");
            }
            else
            {
                print!(" ");
            }
        }
        println!("");
    }
}

说明:

if x == 0 || x == y || x + 1 == n

只打印垂直(左和右|)和对角线(\

任务3

Euclidean_algorithm的简单实现

fn main()
{
    // get commandline arguments
    // "test 453 3"
    let args : Vec<_> = std::env::args().collect();

    // convert 2nd and 3rd argument to integers
    let a = u32::from_str_radix( args[1].as_ref(), 10 ).unwrap();
    let b = u32::from_str_radix( args[2].as_ref(), 10 ).unwrap();
    let g = gcd( a, b );
    println!( "GCD of {} and {} is {}", a, b, g );
}

fn gcd( mut a: u32, mut b: u32 ) -> u32
{
    while b != 0
    {
        let c = a % b;
        a = b;
        b = c;
    }
    return a;
}

您能否添加一个片段,说明如何从标准输入中输入两个空格分隔的整数?
零光纤

3
Rust是2010年制造的吗?编程语言的时间轴是这样说的,但实际文章说它只是在2010年宣布(实际上是2011年,由参考文献证明),而版本0.2是在2012
。– EMBLEM

1
@SampritiPanda,请查看hastebin.com/raw/lapekowogu
wasikuss 2015年

1
看起来有点现代。它可以编译为编译器的第一个<s>发行版</ s>发布的工作版本吗?
六。

15

2015年-松饼MC

Muffin MC是由Franck Porcher(http://franckys.com)于2015年2月中旬编写的图灵完备,有趣(但很严肃),功能强大且极简的宏语言,它是必要的(快速)工具,可用于电子表格将用作唯一的前端控制器,以引导和驱动与基于Prestashop的商户站点相关的所有库存相关操作,以用于新的大溪地时尚品牌:Mutiny Tahitihttp : //mutinytahiti.com-即将推出推出)。

松饼MC为的缩写MU微小˚F unctional ˚F lexible IN线中号 ACRO Ç ommand语言。

为了满足我们的要求,Muffin MC的核心功能是围绕灵活高效的第一类内置语义构造(如迭代器惰性求值多函数字符串乘积)设计的

Muffin MC扎根于(实用的)函数式编程FLisp和Perl。它完全支持递归性(无需任何优化),动态类型化和动态范围化(浅绑定)。除了基本数据类型原子(原子,字符串,数字)外,它仅向用户提供一种数据结构:列表!

松饼MC列表语义(的一种)借鉴了幂集语义,即:

  1. 所有Muffin MC操作都会产生一个列表,可能为空。
  2. 访问任何单个列表元素始终会产生一个由该元素组成的单值列表(将其视为单例)。
  3. 空列表是列表操作中的中性元素。

为了与此相符,以下内容可能会有所帮助:

  • 可以将列表可视化为具有最大基数的列表幂集的元素。
  • 将列表的元素可视化为列表的幂集元素,该元素是由该元素组成的单例。
  • 将空列表可视化为空集;也就是说,空集幂集的唯一元素。

这样,访问一个空列表元素将产生一个空列表,而不是一个错误!确实,Muffin MC尝试通过扩展许多传统操作的语义来尽力减少错误。

任务1

#(say "MuffinMC was born in 2015 out of necessity !")

#(...)是Muffin MC宏命令,用于在非逃避的参数列表上应用函数,这里是say从Perl借来的内置函数。

#(say 1 2 3 ...) 在功能上与 map {say $_} (1,2,3,...)

任务2

定义功能ascii-art()

=(ascii-art
    '( =(*  x   #(2- $(_1))
        I   I( *($(x) " ") N)
            foo '( #(. #(I $(x))) ))
    #(say ?( #(== $(_1) 1) N "N#(map foo #(.. 1 $(_1)))N" ))
 ))

Ascii-art()的最短工作格式(88字节):

=(f'(=(* x#(2-)I I(*($(x)" ")N)g'(#(.#(I$(x)))))#(say?(#(==$(_1)1)N"N#(map g#(..))N"))))
  • =(var val...)是Muffin MC宏命令,用于定义或重新分配变量。

  • $(var)是Muffin MC宏命令,用于访问变量的值。它自然接受$(v1 v2 ...)一次访问多个变量的形式。

  • =(* var1 val1 var2 val2 ...)是Muffin MC宏命令的扩展,=(...)用于处理并行分配。

  • 变量_1, _2...是动态范围(浅绑定机制),并自动设置为绑定到函数的参数。从Perl5借用的系统变量#(参数数量)和@(参数列表)也会自动设置。

  • 函数只是绑定到任意数量的Muffin MC语句的变量。

这个有趣的解决方案来自于结合了两个自然的Muffin MC内置功能:

  1. Muffin MC I(...)宏命令,用于定义循环迭代器,随后与功能形式一起使用#(my-iterator want-number-of-values)

  2. Muffin MC 字符串乘积构造是自然变量插值的扩展,给定任何字符串"F1 F2 F3..."(其中F i是Muffin MC字符串文字或Muffin MC宏命令(又称函数形式)),它都会产生与由产品基数(F1)x基数(F2)x ...给出。

例如,给定xa变量包含2个值,即a和b,y另一个变量包含3个值,即1 2 3,那么对字符串的求"x=$(x) y=$(y))"值将产生6个不同的值,即按该顺序:

  • “ x = ay = 1”
  • “ x = ay = 2”
  • “ x = ay = 3”
  • “ x = by = 1”
  • “ x = by = 2”
  • “ x = by = 3”

这是MUTINY项目为Muffin MC设计的非常理想的功能之一。

运行 !

#(ascii-art 1)

N


#(ascii-art 3)

N N  
NNN  
N N 


#(map '( #(ascii-art $(_1))) 5 7 9)

N   N
NN  N
N N N
N  NN
N   N

N     N
NN    N
N N   N
N  N  N
N   N N
N    NN
N     N

N       N
NN      N
N N     N
N  N    N
N   N   N
N    N  N
N     N N
N      NN
N       N

它是如何工作的

我们的算法基于以下几点:

给定对ascii-art(n)的调用,{n = 2p + 1 | p整数,p> = 0},生成的艺术包括n个字符串,每个n个字符,其中,最左边和最右边的两个是固定的,并且始终相同:'N'。这样可以减少仅产生中弦的问题。例如,给定n = 5,我们将除草以产生以下5个中间字符串,每个中间字符串由n-2个字符组成(为了更好地可视化,我们用'_'替换了空格):

    The 5 strings :
        _ _ _
        N _ _ 
        _ N _
        _ _ N
        _ _ _

    can be seen as resulting from splitting in groups of 3 characters
    the following infinite sequence of 4 characters :


        /---- < _ _ _ N > ----\
       |                       |
        \---------------------/    


    which, once unfolded, yields the infinite ruban : 

        _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N _ _ _ N ...
              ^     ^     ^     ^     
        _ _ _ |     |     |     |
              N _ _ |     |     | 
                    _ N _ |     |
                          _ _ N |
                                _ _ _
  • 通过('_' '_' '_' 'N')在5组3组的4个元素序列上循环可以容易产生这样的中弦。给定n,即函数的输入,此序列由n-2个字符组成'_',后跟该字符'N'。在此序列上循环仅需将序列嵌入Muffin MC I(sequence)内置迭代器(一个迭代器将在其初始值序列上永久循环)就不需要了。

  • 然后,通过要求迭代器给我们下一个n-2个值(n-2个字符),我们便简单地生成了长度为n-2的中间字符串,将它们串联在一起以生成预期的中间字符串。

  • 通过使用地图收集n个结果(n个n-2个字符的字符串)来重复上述过程的n次,从而生成n个中间字符串。

  • 我们使用另一个强大的Muffin MC内置结构(即字符串乘积)来生成n个最终字符串:"N#(map...)N"

  • 就是这样!

    Commented script  
    
    =(ascii-art                    Define the 'ascii-art' variable to hold
                                   the function's definition.
                                   When called, its argument, the actual
                                   value of n, will be bound to the system
                                   variable _1, accessed as $( _1 ).
    
        '(                         '(...) quote macro-command -- protects 
                                   its arguments, here the function 
                                   definition, from being evaluated.
                                   We want to keep it literally for further evaluation.
    
           =(*                     =(*...) // assignment macro-command.
                                   Similar to the Lisp (let (...)...),
                                   not the let* !
    
               x #(2- $(_1))       Define the variable x to hold the value 
                                   n-2.   
    
               I I(                Define I to be an iterator over the 
                                   the x+1 characters sequence :
                    *( $(x) " ")   . x white-space characters
                    N              . 1 'N' character (here the atom N)
                 )
    
               foo '(              Define the variable foo as a function 
                      #(.          to catenate ( #(. s1...) )
                         #(I $(x)) the iterator's next x elements.
                       )            
               )
           )                       End of =(*...
    
        #(say                      Print each element of:
           ?(                      If
              #(== $(_1) 1)        n equals 1
      N                    the atom N,
      "N#(map foo #(.. 1 $(_1)))N" else the n strings as a string-product 
                                   resulting from foo-computing the  
           )                       n middle-strings.
         )
     ))
    

任务3

定义功能gcd()

=(gcd '( ?( #(== $(_2) 0)
        $(_1)
            #(self $(_2) #(mod $(_1) $(_2)))) ))

gcd()实际最短的形式(37个字节- 2字节获得感谢Rodolvertice)

=(g'(?(#(z$(_2))$(_1)#(g$(_2)#(mod)))))

运行 !

#(gcd 225 81)

产生9。

而已。

感谢您的精彩游戏,也可能是您的兴趣。任何想玩,使用,甚至扩展它的人都可以使用该语言。索要它,我将很高兴将其发送。

干杯

法兰克


PS。Muffin MC的当前实现在Perl5中。源代码大约包含2000行现代Perl,包括注释,并且与非回归测试套件捆绑在一起,对于学习动手的Muffin MC构造和语义非常有用。


非常好!最短形式的ascii-art具有缩短的功能名称,但GCD最短的名称没有。这是有意的,因为如果不是这样,则可以删除另外2个字节。+1
rodolphito

当然,这是故意的。我是不是该 ?是的,让我们开始;)感谢您的帖子,以及您的赞赏。
Franck Porcher 2015年

1
由于您正试图摆脱多余的字符(并且由于我可能是个讨厌的语法),因此您可以(应该)删除第一个任务的感叹号前的空格。该空间在法语afaik中是正确的,但在英语中却不正确。
阿莫斯·卡彭特
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.