经过多年的准备,你参加了第 51 届星际编程奥林匹克竞赛。考试开始的那一刻,你翻开试卷。令你惊讶的是,它只有一道题,而且……与你学过的任何编程语言都无关。
问题描述了一种名为Easy的编程语言,它只能做五件事。
- 它可以将变量设置为 0,如果变量不存在则创建它。
- 如果变量已经存在,它可以增加变量。
- 它可以创建包含任意指令集的循环(可能是无限的)。循环可以嵌套。
- 如果两个指定的变量相等,它可以跳出循环。当此类语句用于嵌套循环时,它只会跳出最内层的循环。
- 它可以返回一个变量并停止程序。
语法与 Java 语法非常相似。上述每条指令都算作 1 条指令。
下面是一个返回 1 的 Easy 程序示例,说明语法:
i = 0;
j = 0;
i++;
loop {
j++;
if (i == j) break;
}
return j;
问题分为三个部分:
-
a) 编写一个最多包含 15 条指令的程序,返回一个大于 20 的整数。
-
b) 编写一个最多包含 20 条指令的程序,返回大于 1000 的整数。
-
c) 编写一个最多有 25 条指令的程序,返回一个在该宇宙中无法容纳的十进制表示的整数。
奖励:每个部分您可以返回的最大数字是多少?
注意:由于一些看似温和的 Easy 程序可以返回巨大的数字,因此 Easy 不是通过直接运行代码来运行的,而是通过使用超级智能编码 AI 扫描代码并让其通过弄清楚每个代码段的作用来计算返回的值。
\endgroup
17
最佳答案
3
for
首先,定义一个用作的宏
for (i) { CODE }
它接受一个变量i
和任意行CODE
。它扩展为
i = 0; loop { CODE if (i == x) break; i++; }
添加444指示CODE
。如果CODE
保持不变x − i十−我x-i,然后
for
运行CODE
x + 1十+1x+1次。
接下来定义一个函数fn(十)fn(十)f_n(x)为了n≥0n≥0n\ge0作为
for (i_1) { for (i_2) { ... for (i_n) { x++; i_1++; i_2++; ... i_n++; } ... } }
它使用5 n + 15n+15n+1说明。请注意
增加两者十十x和我钾我钾i_k保持每个不变量x −我钾十−我钾x-i_k,因此每个fnfnf_n运行fn − 1fn−1f_{n-1}为了x + 1十+1x+1次。
正式来说,fnfnf_n递归定义为
fn(x )= {x + 1 ,fx + 1n − 1(十),n = 0n≥1。fn(十)={十+1,n=0fn−1十+1(十),n≥1。f_n(x)=\begin{cases}x+1,&n=0\\f_{n-1}^{x+1}(x),&n\ge1\end{cases}.
例如,
f0f0f_0增量十十x, 所以f1f1f_1增量十十x为了x + 1十+1x+1次,给予
f1(x )= x + (x + 1 )= 2x + 1 。f1(十)=十+(十+1)=2十+1.f_1(x)=x+(x+1)=2x+1.
最后,定义程序磷n磷nP_n作为
x = 0; x++; x++; f_n(x); return x;
它使用5n + 55n+55n+5指令和输出fn(2 )fn(2)f_n(2)。
磷2磷2P_2用途151515指令和输出
f2(2 )=f31(2 )=f21(5 )=f1(11 )= 23 > 20。f2(2)=f13(2)=f12(5)=f1(11)=23>20.f_2(2)=f_1^3(2)=f_1^2(5)=f_1(11)=23>20.
磷3磷3P_3用途202020指令和输出
f3(2 )=f32(2 )=f22(23 )>f2(2二十八)>22二十八> (1080)106,f3(2)=f23(2)=f22(23)>f2(2二十八)>22二十八>(1080)106,f_3(2)=f_2^3(2)=f_2^2(23)>f_2(2^{28})>2^{2^{28}}>(10^{80})^{10^6},这大约是宇宙中原子的数量的百万次方。
磷4磷4P_4用途二十五二十五25指令和输出
f4(2 )f4(2)f_4(2),一个极大的数。
为了说明目的,这里完整地写了三个程序。
磷2磷2P_2:
x = 0; x++; x++; i = 0; loop { j = 0; loop { x++; i++; j++; if (j == x) break; j++; } if (i == x) break; i++; } return x;
磷3磷3P_3:
x = 0; x++; x++; i = 0; loop { j = 0; loop { k = 0; loop { x++; i++; j++; k++; if (k == x) break; k++; } if (j == x) break; j++; } if (i == x) break; i++; } return x;
磷4磷4P_4:
x = 0; x++; x++; i = 0; loop { j = 0; loop { k = 0; loop { l = 0; loop { x++; i++; j++; k++; l++; if (l == x) break; l++; } if (k == x) break; k++; } if (j == x) break; j++; } if (i == x) break; i++; } return x;
\endgroup
4
-
\begingroup
非常好!我们可以谈谈fff在中?
\endgroup
– -
\begingroup
@BenjaminWang 我认为我们的fnfnf_n相当于fnfnf_n在 FGH 中为有限nnn。
\endgroup
– -
\begingroup
回答得好!a 部分还可以做得更好。
\endgroup
– -
\begingroup
@noedne 看起来是对的。
\endgroup
–
|
(a) 的代码:
a = 0; a++; // (repeated x5) b = 0; loop{ a++; // (repeated x2) if(a==b) break; b++; // (repeated x3) } return a;
这个想法是
循环反复将b加三,将a加二,因此当它们相等时,a已经增加了三倍。但是,从5开始意味着我们只能得到 15。但是通过将b++行放在 if 语句之后,我们可以“免费”获得两行a++行,因此我们可以得到 21。
\endgroup
1
-
2\begingroup
不错的解决方案!看起来,如果您将重复次数从 (x5, x2, x3) 更改为 (x1, x4, x5),则可以达到 25。
\endgroup
–
|
该代码恰好有 15 条指令,并返回 2 的幂次增加,直至无穷大。
这里是:
a = 0;
b = 0;
c = 0;
a++;
c++;
loop {
loop {
b++;
c++;
if (a == b) break;
}
loop {
a++;
if (a == c) break;
}
return c;
b = 0;
}
\endgroup
1
-
1\begingroup
我应该澄清一下,程序在返回一个数字后就会停止。(如果不是这样,创建一个返回每个自然数的程序就很简单了。)不过,这是很好的代码。
\endgroup
–
|
我投票关闭这个问题,因为这是一个。根据问题,答案并不要求证明最优性,而只是试图得到一个大数字。这很容易导致答案的数量无限,人们在没有明确终点的情况下进行渐进式改进。
\endgroup
–
我喜欢这个问题!
\endgroup
–
我假设循环可以嵌套,并且跳出只能退出最内层循环?
\endgroup
–
如果 Puzzling 不喜欢这个问题,也许 Codegolf stackexchange 会喜欢这个问题。
\endgroup
–
我正在考虑 Codegolf,但决定先在这里发帖,因为我在这个网站上有更多的经验。
\endgroup
–
|