100 种语言速通:第 27 集:每当

Q神日志 2023-06-26 22:08:17

每当是一种鲜为人知的深奥语言,其中的程序是待办事项列表。

任何可操作的项目都可以执行,无论程序感觉如何。

哦,没有变量,没有函数,也没有任何常见的东西,所以这会很有趣!

你好世界!

你好世界!非常简单 - 只需打印一项待办事项"Hello, World!"。由于程序的待办事项列表中没有其他项目,因此这就是将要发生的事情。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-comment-color)"><code><span style="color:var(--syntax-literal-color)">1</span> <span style="color:var(--syntax-name-color)">print</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-string-color)">"Hello, World!"</span><span style="color:var(--syntax-text-color)">);</span>
</code></span></span>

 

它完全符合我们的预期:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>$ whenever hello.txt
Hello, World!
</code></span></span>

 

任意订单

让我们

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 print("Cats");
2 print("Are Better Than");
3 print("Dogs");
</code></span></span>

 

有 6 种可能的输出,这里是其中的两种:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>$ whenever anyorder.txt
Dogs
Are Better Than
Cats
$ whenever anyorder.txt
Cats
Are Better Than
Dogs
</code></span></span>

 

环形

这是一个不带变量的简单循环,打印 1 到 10。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#9;
2 defer (1) print(11 - N(2));
</code></span></span>

 

这到底是怎么回事?

  • 2#9意味着将待办事项多次放入2列表中。9
  • defer (1)表示如果任务仍处于待处理状态,则该任务2无法完成1
  • N(2)2检查任务在待办事项列表中出现的次数,包括当前的任务。第一次执行的时间N(2)10
  • 所以11 - N(2)开始为11 - 10,即1
  • 2下一次执行该行时,N(2)9,所以11 - N(2),即2,被打印
  • 依此类推11 - 1,直到 ,即10,被打印出来,并且没有什么可做的

奇偶

在我们做 Fizz Buzz 之前,让我们尝试一些更简单的东西 - 奇偶循环。

修改原始程序以打印 等非常容易"1 is odd""3 is odd"直到达到某个预定义值。A - N(lineno) * 2对于某个值,我们需要将公式调整为步长为 2 A(我们可以通过数学计算,或者调整直到找到正确的值)。

"2 is even"修改原来的程序来打印等也同样容易"4 is even"

唯一的困难是使循环同步运行,为此它们应该查看彼此的计数器状态defer

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#4,3#4;
2 defer (1 || N(2) < N(3)) print((11 - N(2) * 2) + " is odd");
3 defer (1 || N(2) == N(3)) print((12 - N(3) * 2) + " is even");
</code></span></span>

 

生成:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>$ whenever oddeven.txt
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
</code></span></span>

 

嘶嘶声

为了保持较低的复杂性,我们来做 Fizz - 仅使用 Fizz 规则的 FizzBu​​zz 版本。

我们可以只做 3 个互锁循环。为了简单起见,我们让它们保持相同的迭代次数,这样它就会打印数字 1 到 18:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#5,3#5,4#5;
2 defer (1 || N(2) < N(4)) print(19 - N(2) * 3);
3 defer (1 || N(3) == N(2)) print(20 - N(3) * 3);
4 defer (1 || N(4) == N(3)) print("Fizz");
</code></span></span>

 

哪个输出:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>$ whenever fizz.txt
1
2
Fizz
4
5
Fizz
7
8
Fizz
10
11
Fizz
13
14
Fizz
16
17
Fizz
</code></span></span>

 

我们可以为 FizzBu​​zz 执行 15 个这样的循环,并在条件中添加一些+1s 以使其打印不相等数量的循环,但是我们尝试其他方法怎么样?

模拟变量

这段代码更长,但可能更容易理解:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#-1,3#-1,4#-1,6#-1,7#-1;
2 2;
3 defer(1) print(N(2));
4 defer(1) print("Fizz");
5 defer(1 || 3 || 4) 2,3,6;
6 defer(1 || 3 || 4) 2,3,7;
7 defer(1 || 3 || 4) 2,4,5;
</code></span></span>

 

它产生无限的嘶嘶声:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>whenever fizz2.txt | head -n 20
1
2
Fizz
4
5
Fizz
7
8
Fizz
10
11
Fizz
13
14
Fizz
16
17
Fizz
19
20
</code></span></span>

 

这里没有什么魔力,而且是非常系统的编程方式:

  • 第 1 行初始化所有计数器。它们以 开头1,2,3,4,5,6,7,但我们只想将其5作为待办事项列表,因此我们删除了其他所有内容。
  • 为了确保初始化程序运行,除了1and之外的所有内容2都有defer(1)条件。
  • 2 2;是一个待办事项列表,在执行时只是重新安排自己,所以我们基本上创建了一个变量。因为它什么也不做,所以不需要defer(1)对其施加条件。
  • 每当不允许混合print语句和行语句时,因此待办事项34进行各种打印。如果需要打印任何内容,则此后的所有内容都会被推迟。
  • 接下来的一切都是循环条件。5这样做2,3,6就像N(2)+=1(2)、print(N(2))(3)和goto 6(6)。

菲兹巴兹

那么让我们尝试一下 FizzBu​​zz:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#-1,3#-1,4#-1,5#-1,6#-1,8#-1,9#-1,10#-1,11#-1,12#-1,13#-1,14#-1,15#-1,16#-1,17#-1,18#-1,19#-1,20#-1,21#-1;
2 2;
3 defer(1 || N(2) > 100) print(N(2));
4 defer(1 || N(2) > 100) print("Fizz");
5 defer(1 || N(2) > 100) print("Buzz");
6 defer(1 || N(2) > 100) print("FizzBuzz");
7 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,8;
8 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,9;
9 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,4,10;
10 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,11;
11 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,5,12;
12 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,4,13;
13 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,14;
14 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,15;
15 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,4,16;
16 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,5,17;
17 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,18;
18 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,4,19;
19 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,20;
20 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,3,21;
21 defer(1 || 3 || 4 || 5 || 6 || N(2) > 100) 2,6,7;
22 defer(N(2) <= 100) 2#-N(2),3#-N(3),4#-N(4),5#-N(5),6#-N(6),7#-N(7),8#-N(8),9#-N(9),10#-N(10),11#-N(11),12#-N(12),13#-N(13),14#-N(14),15#-N(15),16#-N(16),17#-N(17),18#-N(18),19#-N(19),20#-N(20),21#-N(21);
</code></span></span>

 

它工作完美:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>$ whenever fizzbuzz.txt
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
...
</code></span></span>

 

它比通常的 FizzBu​​zz 长很多,但实际上并没有那么复杂:

  • 初始化器1仅留下722, 重置其他所有内容
  • 2是唯一的变量
  • 3to6是各种print陈述
  • 如果初始化器是 todo,或者如果N(2) > 100
  • 7to21是各种循环部分 - 每个部分都会递增变量,安排一些打印并进入循环的下一步
  • 如果初始化程序是 todo,或者任何打印是 todo,或者如果N(2) > 100
  • finally22是退出条件 - 如果N(2) > 100它是唯一可以执行的东西,并且它将所有其他计数设置为0

另一个嘶嘶声

让我们尝试一种不同的方法,再次从 Fizz 部分开始。

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#-1,3#-1,4#-1,5#-1,6#-1;
2 2;
3 3;
4 defer(1 || (N(5) + N(6)) != 1) 5#-N(5),6#-N(6);
5 defer(1 || N(3) == 0) print(N(2));
6 defer(1 || 3) print("Fizz");
7 defer(1 || 4) 2,3,-3#((N(3)/3)*3),4,5,6,7;
</code></span></span>

 

这里发生了什么?

  • 初始化器1仅在 leaves中7,重置其他所有内容
  • 2是可变的N
  • 3是可变的N % 3
  • 4-6print系统。要发出打印命令,所有这些命令都应该只安排一次。
  • 4看到其中一个打印命令已完成(因此只剩下 1 个),因此它会清除所有命令。
  • 56是各种print陈述,取决于N(3),即N % 3
  • 条件3是 的快捷方式N(3) != 0,文档说!3应该适用于相反的条件,但实际上并未实现
  • 如果我们可以在同一个语句中进行打印和更改,那么我们就可以摆脱 just6 defer(1 || 3) print("Fizz"),-5;而不需要 need 4,但这只是每当设计的一部分。
  • 7是我们的循环迭代
  • 7增量2N)
  • 7递增3,然后递减((N(3)/3)*3)。该表达式是0“如果N(3)小于3,则变为” 3。因此,N(3)循环 0、1、2、0、1、2 等。
  • 7使用45,安排打印6- 打印系统将运行 ( 5then 4) 或 ( 6then 4),具体取决于N(3)
  • 7安排自己再次运行,但它将等待打印系统。

另一个菲兹巴兹

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code>1 2#-1,3#-1,4#-1,5#-1,6#-1,7#-1,8#-1,9#-1;
2 2;
3 3;
4 4;
5 defer(1 || (N(6) + N(7) + N(8) + N(9)) != 3) 6#-N(6),7#-N(7),8#-N(8),9#-N(9);
6 defer(1 || N(3) == 0 || N(4) == 0) print(N(2));
7 defer(1 || 3 || N(4) == 0) print("Fizz");
8 defer(1 || N(3) == 0 || 4) print("Buzz");
9 defer(1 || 3 || 4) print("FizzBuzz");
10 defer(1 || 5 || N(2) >= 100) 2,3,-3#((N(3)/3)*3),4,-4#((N(4)/5)*5),5,6,7,8,9,10;
11 defer(1 || 5 || N(2) < 100) -2#N(2),-3#N(3),-4#N(4),-10#N(10);
</code></span></span>

 

它遵循之前 Fizz 的所有模式 - 只需额外变量 for N%54)、更多打印 ( 59)、循环退出条件 ( 11) 以及循环退出主循环迭代中的额外检查 ( 10)。

你应该尝试随时吗?

我完全是偶然发现了这种语言,我从未见过类似的语言,据我所知,即使在深奥的语言爱好者中,它也几乎是未知的。

现有的 Java 解释器质量有点低:

  • 如果没有一些微不足道的调整,它就无法在最新的 Java 上编译(enum现在是一个关键字,因此可以进行搜索和替换)
  • 它没有良好的调试输出(我们想要的是状态)
  • 它不会优化掉 NOP,因此它可能会非常慢,试图执行什么都不做的代码(像变量2 2;或带有延迟检查的代码会阻止它运行)。
  • 它甚至没有完全遵循自己的规范,尤其是缺少!运算符

但语言本身就很精彩。我希望有人为它编写一个更好的解释器,具有浏览器内可视化功能。老实说,我非常喜欢它,甚至可能在某个时候这样做。

我绝对推荐尝试一下。

、关注我的博客,您将在其中获得提示、技巧和挑战,以保持您的技能敏锐。记得关注我哦!

...全文
39 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

6

社区成员

发帖
与我相关
我的任务
社区描述
分享
java-rocketmqpygame前端 个人社区 广东省·广州市
社区管理员
  • Q shen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧