自我修改相乘


33

...至少对于“自我修改”的某种定义

任务

在此挑战中,您的任务是编写三个字符串AB并且C满足以下属性。

  • 字符串的B长度至少为1。

  • 对于每种n ≥ 0,字符串都是您选择的编程语言中的有效程序(表示完整的可运行程序或函数定义)。上标表示的重复,因此,这意味着字符串,,,等。每一个程序需要一个字符串作为输入,并返回一个串作为输出。ABnCACABCABBCABBBC

  • 对于任何m, n ≥ 0程序,如果程序使用输入运行,它将返回。对于非这种形式的输入,程序可能会执行任何操作,包括崩溃。ABmCABnCABm*n+1C

格式program(input) -> output如下:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

规则和计分

你的分数是总长度AC较低的分数更好。请注意,虽然B不计入分数,但它必须由A和生成,C如第一个示例中所示。

不允许出现标准漏洞。不允许程序直接或间接访问其自己的源代码(除非将它们作为输入提供)。您需要识别字符串ABC以某种方式在您的答案中,并鼓励您解释您的解决方案。

Answers:


16

CJam,9个 8字节

A: 1
B: 0
C:  r,(#0q

CJam解释器中在线尝试。

怎么运行的

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).

12

CJam,15 13 11字节

A: rl"
B: <SP>
C: <LF>",(*SNq

CJam解释器中在线尝试。

怎么运行的

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

最后,堆栈包含读取的令牌r,产生*的空间,推送的空间和换行符SN以及读取的行q。CJam自动打印所有这些。


哈哈,那里的引号很好用:D
Optimizer

9

珀斯10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

我们将源分为两行。第一行是A,第二行是Bs。由于A位于第一行,因此第一行w仅打印A-简单,容易完成。

在Pyth中,前导零是单独的标记,[00)实际上是[0, 0]。请注意,第一行以结尾l[,第二行由组成0000...。因此l[实际上计算了该程序中B的数量。第二个w读入输入的第二行-这是输入的B数。从这里开始,它是一个简单的乘法,增量和输出那么多的零。


9

视网膜25 19字节

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

示例ABC代码:

]\]
]]
m`^]*$
]$0]

该代码有两个替代步骤:

  • 改变输入AB^mCAB^(m*n)C改变每BB^n

    • ]\]匹配B输入中的每个内容,并且通过在模式行中转义来匹配其他内容
    • ]]...]]B^n
  • 变化B^(m*n)B^(m*n+1)

    • m`^]*$走线只]
    • ]$0]]]向其添加额外的一对,使得该行与第一个正则表达式不匹配

我在-s多行标志的乐谱上添加了3个字节,因此整个Retina代码可以存储在一个文件中。

感谢@MartinBüttner,节省了2个字节。


8

Python 3,51个字节

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

用法示例:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

该函数计算n*m+1(1+len("xxx")*(len(s)-51))其中存在m x字符串中的(xxx部分是B^m)。乘以串"x"用这个号码给B^(n*m+1)和功能需要AC出输入并连接所有这些获得AB^(n*m+1)C

J中的相同方法:

J,35个字节

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]

5

CJam,22岁

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

示例运行:

ABBC(ABC) -> ABBBC

转化为

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

输入为

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

提供以下输出:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

运作方式

让我们看一下程序ACABC外观:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

我们注意到C=B_~

让我们看看B正在做什么:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

现在让我们看看AC没有任何输入的情况下将执行的操作:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

哇,输出是ABC

我们基本上算出B代码中有多少个。然后输入多少(使用长度)。将它们相乘,增加两次(C也有B),然后追加_~以获得C

在这里在线尝试


3

Haskell,50个字节

f是一个接受并返回的函数String

字符串B只是一个空格,而C以一个开头。

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

在线尝试!

  • _:b=" "将字符串文字中除第一个空格之外的所有空格都分配给b,使其等于程序的m B副本。
  • s是输入字符串。a:c<-words s将其拆分为以空格分隔的单词,从而a成为A并c成为包含C的单词的列表。由于words挤压了多个空格(程序的其余部分避免了),因此B副本被忽略。
  • drop 50s是一个长度等于输入中B副本数n的字符串。drop 50s>>b串联的许多副本b,并给出mn个空格。
  • unwords$a:(drop 50s>>b):c将所有字符串与空格连接在一起。由于(drop 50s>>b)列表中插入了一个额外的“单词” ,因此也有一个额外的连接空间,自动将+1加到乘法中。

2

Matlab,85岁

对我来说,这是第一次来做这样的抽象挑战,所以对我来说,它更多的是编码挑战,而不是代码高尔夫挑战!

这三个字符串不带引号:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

工作原理:我在空格上分割了输入参数,因此n可以根据字符串部分的数量来确定。B作为一种获得计数器m。为了重新构造答案,我使用拆分中的A和C,重复B m * n + 1次,并使用其ASCII值插入空格,以便在C中不会发生不需要的拆分。

编辑:哎呀,无意中算出了A + B


1

C(gcc),81个字节

除非我们对识别所含内容的标准不严格,否则识别字符串的要求似乎与我们允许非法输入的任意行为相矛盾。自然,我采用了流失最多字节的解释。

在线尝试!

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}

通过识别我的意思,它应该是从你的答案,代码片段是清晰的一个Ç。该程序不是必需的。
Zgarb

1

TI-Basic(83系列),65字节

段A(33个字节):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

B区:

X

段C(32个字节):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

我真的很高兴找到这种像藜一样的挑战!在没有至少一点作弊的情况下,大多数奎因在TI-Basic中不起作用,因为无法逃避该"符号。(在两种意义上都是“转义”。)但是,在这里,我们通过Input命令获得了一个输入字符串,并且在其中键入"是完全可以的。

仍然有一些TI基础知识可以解决:空字符串无效,因此,"XXX...XX"当n = 0时,将字符串插入循环的幼稚解决方案将不起作用。相反,我们手动计算mn + 1的值,然后"X"多次插入字符串。

魔术常数2728在程序是稍微偏离字节计数33和32,因为Str1sub(length(是两个字节令牌仅有助于1为一个字符串的长度。

如果我们使用换行符代替:,看起来什么时候可以通过省略引号来节省一些字节,但这实际上不起作用。首先,在将换行符添加到字符串中之前,需要一个十六进制编辑器:您不能只输入它,因为如果在Input命令中按ENTER键,它将提交输入。当我尝试使用十六进制编辑器方法时,最终遇到了奇怪的缓冲区溢出错误,该错误修改了程序的内容,因此,不要在家中使用昂贵的计算器尝试此操作。


0

Java 11,135 65 + 26 = 91字节

一种

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

B

C

".length())+'"'+'.'+p[2];}

在此处在线尝试(TIO还没有Java 11,因此它依赖于helper方法而不是String::repeat())。

取消高尔夫:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
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.