通过复制初始代码来创建大小增加的正方形


45

您的任务是编写一个长度均匀的程序,该程序打印一个ASCII艺术字型方块(如下所述),每次将原始源代码粘贴到当前代码中间时,其边长就会增加1个单位。

我很难很好地定义此任务,因此,我举一个例子:

  • 假设您的初始代码是CODE并且已打印:

    0
    
  • 然后,CODE在中间插入:您的代码将变成COCODEDE并且应该打印:

    00
    00
    
  • CODE在中间重新插入:您的代码将变成COCOCODEDEDE 并且应该打印:

    000
    000
    000
    
  • 等等。从理论上讲,您的答案在经过任意多次迭代后都应该可以使用,但是我知道,由于语言性能的限制,它是否不能合理地超过某个阈值。

一些规则:

  • 您可以使用任何可打印的ASCII(32-127)作为用于正方形的字符。您的选择必须是恒定的(每次迭代都应使用相同的字符)。

  • 初始输出平方必须具有边长1

  • ascii-art正方形定义为具有N行的字符串(由N-1个换行符/换行符分隔),并且每行包含N个所选字符的副本。

  • 除尾随换行符外,您的输出不允许包含任何多余的空格。

  • 您可以将默认值用于输入和输出(允许使用程序或功能,但不允许使用代码段)。

  • 代码的中间部分定义为可以将源代码分为两部分,以使两者相等的点。

  • 您的答案将按照原始程序的长度(以字节为单位)进行评分。最低字节数获胜。如果出现平局,则较早提交的答案将获胜。

  • 您可以使用此程序来应用插入,而无需手动进行。


1
我必须承认,我受到之前发布这个问题的启发。如果人们认为它太近了,我会很乐意将其删除。如果我有任何错误,也请原谅,我对这里的规则仍然不太熟悉。:)

2
欢迎来到PPCG!我建议使用沙盒应对您未来的挑战。
user202729 '18

7
欢迎光临本站!很好地利用另一个挑战来激发灵感,而又不会陷入欺骗陷阱:)
Shaggy

您的帮助程序不适用于多行程序。另一个问题的修改版本如何?
Jo King

1
@ user77954但是我的操心代码比您的python短:((以前有人说过吗?)
Jo King

Answers:


41

Pyth,2个字节


5

在线尝试!试试吧一倍两倍

这是如何运作的?

\n是在后面同时返回参数的情况下,在参数末尾带有换行符的命令。因此,每次插入时,您都将整数文字5转换为包含N个副本(共5个)的数字,并且开头的换行符基本上确保了它被打印了适当的次数,从而保持平方。


6
这太短了……
ETHproductions '18

最优性证明(:P):由于字节数必须为偶数且不能为负,因此最小的字节数为0字节。完全有1个0字节的程序无法完成任务。因此,2个字节是最佳的。
Xcoder先生18年

10
每个人(尤其是HNQ选民)也要投票赞成其他答案,并避免FGITW效应。
user202729

25

JavaScript(ES6),42 32 30字节

s=[this.s]+0;  console.log(s);

第二次迭代:

s=[this.s]+0;  s=[this.s]+0;  console.log(s);console.log(s);

这是通过0s每次运行代码的前半部分后附加一个a并在每次运行后半部分时打印s自身来实现的。利用JavaScript的四个怪癖:

  1. 当前环境可以用表示this。这使我们可以this.s代替s
  2. 访问未在对象上定义的属性时,JavaScript不会抛出错误,而是返回undefined
  3. 一个数组加一个数字将返回一个字符串。 [1,2,3] + 4 === "1,2,34"
  4. 对数组进行字符串化时,undefined将转换为空字符串,这表示[undefined] + 0 === "0"

放在一起,这意味着我们可以仅用13个字节来表示前半部分(生成零字符串)。如果允许使用alert代替代替console.log,我们可以通过缩短下半部分再节省4个字节。


恭喜,通过了我的测试!

1
...精巧!:)
Shaggy




9

C(gcc)170 168 96 80 72 70字节

短得多的版本。仍然希望我能找到没有预处理器的解决方案。

i;main(n){for(;i++<n;)printf
#if 0

#endif
(" %*c",n=__LINE__/4, 10);}

在线尝试!

旧的168字节版本:

#ifndef A
#define A p(c){putchar(c);}j,n;main(i){for(
#else
#define A n++,
#endif
A



#ifndef B
#define B i=++n;i--;p(10))for(j=n;j--;)p(64);}
#else
#define B
#endif
B

在线尝试!



@ user202729啊,是的。以为我修正了错字但引入了一个错误。正在还原。
gastropner

8

Python 2,30个字节

False+=1      ;print'*'*False;

在线尝试!第二次第三次迭代

这利用了以下事实:Python中的布尔变量基本上是int和名称,False并且True在Python 2中是可重新分配的。

Python 1,32字节

exit=exit+'*'  ;print exit[30:];

在线尝试!第二次第三次迭代

在Python 1中,内置字符串exitquit存在来通知交互式shell用户如何退出它。默认值为"Use Ctrl-D (i.e. EOF) to exit."


1
我本打算提出建议n=False+=1;print'*'*n;,但我一直忘了那不是Python功能...
ETHproductions '18

6

木炭,6个字节

⊞υωLυ⸿

在线尝试!说明:

  ω     Predefined empty string (any variable would do here)
 υ      Predefined initially empty list
⊞       Push

υ 最终以重复次数的长度结束。

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line

6

Haskell,68个字节

let s@(z:n)="0\n"in case lines<$>[]of(h:t):_->(h:h:t)>>(z:h++n);_->s

在线尝试一次两次三次

由于Haskell的懒惰,按照此Meta问题,像上述表达式那样的表达式算作一个不带参数的函数。




5

脑筋急转弯,74字节

(((((()()()){}){}){}){})((()()()()()<>){})<>([]){({}[()]<(({})<>)<>>)}{}<>

在线尝试!

尝试两倍三倍

说明

(((((()()()){}){}){}){}) # push 48 ("0") onto first stack
((()()()()()<>){})       # push 10 (\n) onto second stack
<>([]){({}[()]<          # a number of times equal to the height of the first stack:
  (({})<>)<>             #   copy the top of the first stack to the second stack
>)}{}<>                  # cleanup and return to second stack

断点在中间 <>位于“推10”部分。打破这一点将在第三个筹码中留下5,直到我们到达相应的下半部分,此时推10将在停下的位置继续。

尽管可以将可打印的ASCII值(空格)压入22个字节,但这将使<>压入中央后即可执行5。通过再添加两个字节,我能够移动,<>以便推入的所有进度10都在第三个堆栈上。另外,这也使所得的正方形在美学上更加令人愉悦。



4

tinylisp,112字节

(load library) (d N((q((x)(i x(inc x)1)))(v(h(t(t(h(t(q())))))))))(join(repeat-val(string(repeat-val 42 N))N)nl)

在线尝试!翻了一番五倍

由于没有可变变量,许多语言正在采用的“在上半部分构建字符串,然后在下半部分打印字符串”方法在tinylisp中不起作用。相反,我们进行了一些认真的代码嵌套。

插入代码的第二个副本后,它将放置在中(q()),该代码将其包装在列表中。然后(h(t(t(h(t(...))))))深入到该列表(d N(v(...))评价它;然后将其传递给未命名的函数(q((x)(i x(inc x)1))),如果为数字,则该函数将递增结果值;如果为空列表,则返回1。将代码的最外层嵌套版本中的最终结果分配给N。本质上,我们已经建立了一种奇怪的递归,它计算嵌套级别的数量。

然后,代码的后半部分创建一个N星号字符串,然后创建一个N这样的字符串列表,然后在换行符上连接该列表。结果以尾随换行符显示。


3

R,44个字节

F=F+1;T=TRUE*TRUE+12;
write(strrep(1,F),"");

在线尝试!

用尾随换行符打印。该T=TRUE*TRUE+12仅仅是垫的长度。

尝试加倍,再尝试加倍


您可以通过删除分号来消除2个字节。我假设有在第一行,其可以用一个#替换的端部的空间:F=F+1;T=TRUE*TRUE+12#<换行符>write(strrep(1,F),"")
安德烈KOSTYRKA

@AndreïKostyrka这将是43个字节,不幸的是,它甚至不相等。
朱塞佩


3

SNOBOL4(CSNOBOL4)130 68字节

现在没有评论!有关旧算法的说明,请参见编辑历史记录

	X =X + 1
	A =ARRAY(X,DUPL(1,X));
I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

在线尝试!

尝试两倍三倍

说明:

	X =X + 1		;* increment X
	A =ARRAY(X,DUPL(1,X));	;* create an x-length array with 1 repeated x times for each element
I	I =I + 1		;* for i < x
	OUTPUT =A<I>	:S(I)	;* output a[i]
END

由于END需要END标签,并且忽略第一个标签之后的所有内容,因此,针对此挑战我们有两个优点:

  • 在节目的前半部分操作重复X多次的X重复
  • (对于口译员)仅存在下半年的一个副本,包括标签

这表明我们在前半部分使用重复,然后可以使用更“常规”的标记方法重复输出X时间。

上半场是

	X =X + 1
	A =ARRAY(X,DUPL(1,X));

重复时,它会增加X适当的次数,并创建一个ARRAY A索引,索引的起始位置是1X,其中的每个元素A都是1重复的字符串X

然后,无论程序重复执行多少次,解释器都只会看到:

I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

这是典型的SNOBOL程序,它一次打印出一个元素,A直到索引超出范围,然后终止该程序。

;是可选的行终止符,通常保留给单行EVALCODE语句,使字节数非常整洁地达到68,并标记了中途点,从而允许将代码附加到此处。




1

Zsh,10个字节

s+=0
<<<$s

在线尝试完整的测试套件!

...是的,这要好一些。附加到字符串N次,然后打印N次。证明<<<foo<<<foo效果很好。


Zsh,64个字节

使用的字符:(空格)。

f(){printf '%*s\n' $1}
:<<'E'

E
repeat $[i=LINENO/3];f $i
exit

在线尝试完整的测试套件!

中点位于第二个E和其后的换行符之间。当E一行单独出现时,一个Heredoc将结束,该行恰好在代码中间。


大声笑@“轻微”的改善。也可以将其表示为s+=0;<<<$s
roblogic
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.