N次程序的N次程序


10

给定一个正整数数组A作为输入,请生成一个程序,该程序重复k多次后,将输出k该数组的th(1-index)值。

例如,如果数组为[1,11],则输出应该是输出的程序1,并且当重复两次时,输出为11。类似于print(end="1");Python 3的代码可以工作:print(end="1");打印1和print(end="1");print(end="1");打印11

解决所有测试用例的最小代码长度总和。您的元代码应在60秒内解决500个测试用例,而每个解决方案代码应在10秒内返回。元代码和解决方案代码不必使用相同的语言,但是您的元程序生成的所有解决方案都应该使用相同的语言。

预测试数据和生成器可以在这里看到。7天后将使用提交时间的总和(例如12:34平均1234)作为随机种子,并生成另一个测试用例作为最终测试用例。


最终种子是GMT + 8中的7335,因此最终测试数据在此处


1
“重复k次”是什么意思?NewSourceCode =重复源代码k次?例如SourceCode =“ ABC”,k = 3,然后NewSourceCode =“ ABCABCABC”?
tsh

print(end="1");重复2次是print(end="1");print(end="1");
l4m2

1
“代码长度总和”是什么意思?我们应该提交多个程序吗?
tsh

您提交一个生成500个程序的程序
l4m2

2
@Emigna不,对于每个列表,它都会生成一个程序。说那个程序就是x。然后x应给出列表的第一个元素,xx应给出列表的第二个元素,xxx应给出第三个元素,依此类推。
克里斯(Chris

Answers:


4

Python 3生成Stax

这使用了多种策略。大多数策略仅在特定条件下适用,但是有一种后备策略始终可用。最后,选择最小的候选程序。


from functools import reduce
from math import sqrt

symbols = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz{|}"

def uncycle(arr):
    for size in range(1, len(arr)):
        if all(e == arr[i % size] for (i, e) in enumerate(arr)):
            return arr[:size]
    return arr

def constant(val):
    return "A" if val == 10 else str(val)

def shift(val):
    if not val: return ""
    return constant(abs(val)) + "+-"[val < 0]

def encode(a, offsetMode):
    result = "";
    if offsetMode:
        for i in range(len(a) - 1, 0, -1):
            a[i] -= a[i - 1]
    for i in range(len(a)):
        parts = []
        signBit = (a[i] < 0) * 2
        continuing = (offsetMode and i == len(a) - 1) * 1
        remain = abs(a[i])
        while remain > 22:
            parts.insert(0, remain % 46 * 2 + continuing);
            remain //= 46
            continuing = 1

        parts.insert(0, remain * 4 + signBit + continuing)
        result += "".join(symbols[p] for p in parts)
    
    return result

def cram(arr):
    flat = encode(arr, False)
    offset = encode(arr, True)
    return offset if len(offset) < len(flat) else flat;

def issquare(num):
    root = int(sqrt(num))
    return root * root == num

def isgeometric(arr):
    r = arr[0]
    return all(r ** (i + 1) == e for (i,e) in enumerate(arr))

def generateProgram(arr):
    candidates = []
    rotated = uncycle(arr)
    rotated = rotated[-1:] + rotated[:-1]

    deltas = [b - a for a,b in zip(arr, arr[1:])]

    # single constant strategy
    if len(arr) == 1:
        candidates.append(constant(arr[0]))

    # repeated constant
    elif len(set(arr)) == 1:
        num = arr[0]
        if num == 10: candidates.append("A")
        if num % 2 == 0: candidates.append(constant(num // 2) + "H")
        if issquare(num): candidates.append(str(int(sqrt(num))) + "J")
        candidates.append(constant(num - 1) +  "^")

    # repdigit
    if len(arr) == 2 and 10 < arr[1] == arr[0] * 11 < 100:
        candidates.append(str(arr[0]) + "p")

    # single digits
    if max(arr) < 10:
        candidates.append("".join(map(str, rotated)) + "E|X@")

    # max 10
    if max(arr) == 10 and rotated[0] != 1:
        candidates.append("".join(str(e - 1) for e in rotated) + "E|X@^")

    fns = [
        ("", lambda x: x),
        ("H", lambda x: 2 * x),
        ("^", lambda x: x + 1),
        ("J", lambda x: x * x),
        ("Hv", lambda x: 2 * x - 1),
        ("H^", lambda x: 2 * x + 1),
        ("^H", lambda x: 2 * x + 2),
        ("HJ", lambda x: 4 * x * x),
        ("JH", lambda x: 2 * x * x),
        (":T", lambda x: x * (x + 1) / 2),
        ("|F", lambda x: reduce(lambda a, b: a*b, range(1, x+1))),
        ("J^", lambda x: x * x + 1),
        ("^J", lambda x: x * x + 2 * x + 1),
    ]
    for (stax, fn) in fns:
        if all(fn(i + 1) == e for (i,e) in enumerate(arr)):
            candidates.append("|X" + stax)

    # fixed delta
    if len(set(deltas)) == 1:
        delta = deltas[0]
        start = arr[0] - delta
        if start == 0:
            candidates.append(shift(delta))
        if delta == 1:
            candidates.append("|X" + shift(start))
        elif delta == -1:
            candidates.append("|x" + shift(start))
        elif delta > 1:
            candidates.append("|X" + constant(delta) + "*" + shift(start))
        elif delta < -1:
            candidates.append("|x" + constant(-delta) + "*" + shift(start))

    # geometric series
    if isgeometric(arr):
        candidates.append(constant(arr[0]) + "*")

    # prefix
    if len(arr) == 2 and arr[1] // 10 == arr[0] < 10:
        candidates.append("." + str(arr[1]) + "|X(")

    # suffix
    if len(arr) == 2 and arr[0] % 10 == arr[1] < 10:
        candidates.append("." + "".join(map(str, arr)) + "|X)")

    # uncycled cram
    candidates.append('"' + cram(rotated) + '"!|X@')
    
    candidates.sort(key=len)
    return candidates[0]

while True:
    arr = eval(input())
    prog = generateProgram(arr)
    print(prog)

在线尝试!

更新:验证 分别执行每个程序的每个多重性将很耗时。可以同时运行它们。为此,必须使用一小段代码。它负责一些事情。

  1. 进行隐式输出(如果有)。通常,在stax程序的末尾,如果没有其他输出,则打印堆栈的顶部。在同一个源文件中运行多个程序时,必须明确地执行此操作。

  2. 清除两个堆栈。

  3. 重置寄存器。对于这些程序,仅使用x寄存器。

该样板应该在每个要执行的程序之后应用。

|d{P}{zP}?0XLd

例如,输入[5,2,7,3]产生stax program 3527E|X@。可以同时测试所有四个多重性。

3527E|X@
|d{P}{zP}?0XLd

3527E|X@3527E|X@
|d{P}{zP}?0XLd

3527E|X@3527E|X@3527E|X@
|d{P}{zP}?0XLd

3527E|X@3527E|X@3527E|X@3527E|X@
|d{P}{zP}?0XLd

在线尝试!

这样,假设没有任何中断,就可以在同一运行中测试所有程序的所有多重性。如果全部完成500个,它可能是有史以来执行的最大的stax程序。


最终得分7862
l4m2

4

Perl 5 -p,生成Perl 5 -p,开销19 17 13

-1感谢 @Dom Hastings

一个输入的分数将是 length of the input + 13。可以通过为较大的输入生成自解压程序来明显改善,但是我不会打扰。

在STDIN的一行上用逗号分隔输入数组。

#!/usr/bin/perl -p
chomp;$_="}{\$_=($_)[\$%++]"

在线尝试!

n没有输入的情况下运行输出连接时间(例如,从/ dev / null重定向)

运行它作为输入的示例方法,2,6,4,7结果程序重复了4次:

perl -p '}{$_=(3,6,4,7)[$%++]}{$_=(3,6,4,7)[$%++]}{$_=(3,6,4,7)[$%++]}{$_=(3,6,4,7)[$%++]' < /dev/null

在线尝试!

如果您不喜欢尝试从STDIN读取的结果程序,请使用此版本,开销为17:

#!/usr/bin/perl -p
chomp;$_="1/!say+($_)[\$-++],"

在线尝试!

运行它作为输入的示例方法,2,6,4,7结果程序重复了4次:

perl -E '1/!say+(2,6,4,7)[$-++],1/!say+(2,6,4,7)[$-++],1/!say+(2,6,4,7)[$-++],1/!say+(2,6,4,7)[$-++],'

在线尝试!

打印所需的输出后,该版本崩溃


我不确定我是否能获得评分,但是此程序是否少了1个字节:s/ /,/g;$_="die say+($_)[\$-++],"
Dom Hastings

@DomHastings确实可以。
Ton Hospel '18

最终分数17106
l4m2


3

APL(Dyalog Unicode)

匿名前缀lambda。返回程序主体。

 {
     1=≢⍵:⍕⍵  single element

     (2=≢⍵)∧(⍵[2]=11×⍵[1]):⍕⍵[1]  2, 22 etc.

     1=≢∪⍵:'⊢',⍕⊃⍵  all the same

     (⊢≡⊃×⍳∘≢)⍵:'+',⍕⊃⍵  linear

     ((⌊=⊢)!⍣¯1⊢⊃⍵)∧(1∧.=1↓⍵):'!',⍕!⍣¯1⊃⍵  factorial followed by all 1s

     (⍵[2]∧.=1↓⍵)∧(⍵[1]=10|2⊃⍵):(⍕⊃⍵),'⌈',(⊃⍕2⊃⍵)  b ab ab ab

     e←{∊⍉2 2'+×',⍕¨⍵}¨⍸(⊃⍵)=∘.×⍨⍳10
     b←⍵∘≡¨e(({0::⍬  ⍎⍵}¨,\)⍴∘⊂)¨⍨(≢⍵)
     ∨/b:⊃b/e

     Q←{'''',⍨⍵/⍨1+''''=⍵}
     (5∧.≤⍵)∧(≢⍕⍵)>6+(+/14=⍵)+≢⍵:'{⍺←⎕AV⍳⊃⋄1⌽⍺⊢⍵}''',Q AV[⍵]  string fallback

     (≢⍕⍵)>9+(+/5=⍵)+≢⍵:'{⍺←¯4+⎕AV⍳⊃⋄1⌽⍺⊢⍵}''',Q AV[4+⍵]  offset string fallback

     '{⍺←⊃⋄1⌽⍺⊢⍵}',⍕⍵  fallback
 }

在线尝试!

方法

本文探讨了各种方法,并返回了第一个可用的方法,最终退回到了普遍适用的方法。

单元素

如果列表仅包含一个元素,则按原样返回。

2、22等

可以重复一位数字来生成大11倍的数字,

全都一样

我们只返回最右边的()数字。

线性的

f(n)= k×n序列只需在第一个项之前插入一个加号。

阶乘后跟全1

当第一个数字n =!m并且后续数字为1时,则!m是一个解,因为!mn和n m!m为1且!1为1。

b ab ab ab

由于所有两位数字都大于所有一位数字,因此解决方案是将第一个数字的前面粘贴到第二个数字的后面,并将其最大化。

三行代码

检查是否有任何类型的公式 +a×b有效。

字符串后备

没有数字小于5的长序列(因为4是换行符)可以被编码为SBCS的字符。

偏移字符串回退

如果数字小于5,我们将上移9个以避免这些数字。

倒退

字符串"{⍺←⊃⋄1⌽⍺⊢⍵}"和字符串化()输入的简单字符串连接。例如[3,1,4]返回程序主体{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4

花括号中的部分是一个矛盾函数,这意味着它可以是前缀函数或中缀函数。因此,它的最左侧实例将以前缀模式运行,所有其他实例均以中缀模式运行。两种模式之间的区别在于,表示左参数的值是否具有值。如果没有,它将被分配功能(第一个)。

后备方法的说明

{} 匿名lambda:

⍺←⊃ 如果没有左参数(),则将函数(第一个)分配给

 然后:

至此,以下代码取决于是否 数字列表(中缀调用)或函数“ first”(前缀调用)的。

 如果是数字列表:

  ⍺⊢⍵ 抛弃左参数,转而支持右参数

  1⌽ 向左旋转那一步

 如果是函数“ first”:

  ⊢⍵ 提出正确的论据

   选择那个的第一个元素

  1⌽ 将其旋转一步(标量上无操作)

后备方法运行示例

执行3 1 4的代码{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4将分配“第一个”功能,从而返回第一个元素。3

执行{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4使最右边的lambda“捕获”左边3 1 4作为其左边的参数,因此它具有一个值,该值被丢弃,有利于将3 1 4其向左旋转一步并得出1 4 3结果。然后,将其用作最左边的lambda的唯一参数,在此处成为“第一个”函数,从而使结果成为第一个元素;1

执行时{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4{⍺←⊃⋄1⌽⍺⊢⍵}3 1 4,将最右边的lambda 3 1 4作为其左参数“捕获”中间的中间内容,然后丢弃该参数以取而代之以右参数3 1 4,该参数在向左旋转一步时为1 4 3。然后将其用作中间lambda的右参数,而最左端3 1 4用作左参数。左边的参数被右边的参数舍弃,它向左旋转了一步,产生4 3 1。然后,这成为最左边的lambda的唯一参数,因此成为“第一个函数”,返回第一个元素;4

计分

当需要使用实际数据进行测试时,请使用此测试工具(链接到预测试数据中)。测试用例放在“输入”字段中,“输出”将是所有500个程序的总字节数。(它也会引发错误,但这仅仅是因为它随后尝试按原样评估Input。)


1
最终分数14028
l4m2

2

木炭

´⎚´§´⪪⪫IA ”y¦ Lυ⊞υω

在线尝试!链接是详细版本的代码。说明:

´⎚´§´⪪

输出文字字符串⎚§⪪

⪫IA 

将输入数组强制转换为字符串,与空格连接并打印。

”y¦ Lυ⊞υω

输出文字字符串¦ Lυ⊞υω

例如,输出5,17,7,13,2⎚§⪪5 17 7 13 2¦ Lυ⊞υω在线尝试!说明:

清除画布,以便仅最后输出可见。

§⪪5 17 7 13 2¦ Lυ

取预定义列表的长度u。使用该索引可索引已在空格上拆分的整数列表并输出所选元素。

⊞υω

将虚拟变量推入预定义列表u,以便下一个副本将输出列表的下一个元素。

总输出长度=(所有列表中所有整数的长度)+(所有列表中整数的数量)+(列表数量* 9)个字符(SBCS)。


2

Haskell生成Haskell

main = interact $ ("main=print$("++) . (++"!!)$ -1\n +1--")

在线尝试!对于第一个测试用例,[5,2,7,3,2,3,15,10,7,2,14,11,16,16,3,3,4,3,8,4]它将生成以下程序:

main=print$([5,2,7,3,2,3,15,10,7,2,14,11,16,16,3,3,4,3,8,4]!!)$ -1
 +1--

尝试一次加倍三倍。这使用与我的Haskell答案相同的方法,即我将源代码加倍,将输出值加倍

每个生成的程序的长度是输入列表的长度(以字符串形式加上25),因此当前可用测试用例的得分为12266 + 500 * 25 = 24766。这表明代码与数据的比率基本相等,并且我怀疑是否可以编写足够小的解压缩代码来降低得分。如果列表更大,则可能是可行的。


1

Python 2生成Python 2

import sys
a=`input()[::-1]`.replace(' ','')
sys.stdout.write('print%s[-open(__file__,"a").tell()/%s]#'%(a,len(a)+37))

在线尝试!

对于输入

[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]

生成的程序是

print[29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10][-open(__file__,"a").tell()/98]#

这是98个字节。

根据“我将源加倍,输出加倍!”中的解决方案改编。

该死,在我写完这个答案之前,弹出了两个简短的答案。


额外的换行符是在端部,这使得它输出用于k
l4m2

预期的行为是“在末尾写入一个'\ n'字符,除非print语句以逗号结尾。” 我不知道为什么TIO在stdout上显示额外的换行符。
Bubbler

更改printsys.stdout.write以删除结尾的“内容”。
Bubbler

最终成绩30606
l4m2

1

Java 8,生成Python 2

interface M{static void main(String[]a){int l=a[0].length();System.out.print("print"+a[0]+"[open(__file__,'a').tell()/"+(l+35+(l+"").length())+"]#");}}

在线尝试。

[3,4,5,6,7]生成此Python 2程序:

print[3,4,5,6,7][open(__file__,'a').tell()/48]#

在线尝试一次 ; 在线尝试两次 ; 在线尝试3次

产生的Python程序是基于@ Mr.Xcoder的回答了第三次的魅力挑战

说明:

Java 8代码:

interface M{                    // Class
  static void main(String[]a){  //  Mandatory main-method
    int l=a[0].length();        //   The length of the first argument
                                //   (Note that this is the length of the input as String,
                                //   not the size of the array)
    System.out.print(           //   Print:
      "print"                   //    Literal "print"
      +a[0]                     //    Appended with the argument
      +"[open(__file__,'a').tell()/"
                                //    Appended with literal "[open(__file__,'a').tell()/"
      +                         //    Appended with an integer that is formed by:
       (l                       //     Getting the length we got earlier
       +35                      //     +34 for the rest of the Python 2 code + 1
       +(l+"").length())        //     + the length of the length (<10→1; 10-99→2; etc.)
       +"]#");}}                //    Appended with literal "]#"

Python 2代码:

print                        # Print
 [3,4,5,6,7]                 #  From this array
 [                           #   The `k`'th item,
  open(__file__,'a').tell()  #   where `k` is the length of its own source code
  /                          #   divided by
  48                         #   the length of its own source code (once) + 1
 ]#                          # With a trailing comment, so we can repeat the program

0

Bash,在Perl 5中输出程序

Bash程序可以称为script.sh 1,2,3

应该使用-E标志来调用Perl程序。

echo "shift@a;@a=($1)unless@a;END{say\$a[0];exec'true'}"

perl输入的生成代码4,7,8是:

shift@a;@a=(4,7,8)unless@a;END{say$a[0];exec'true'}

蛮力的。删除数组的元素(perl并不关心数组最初不存在),如果尚未设置,则对其进行设置。然后,它在末尾回显数组的第一个元素。(该END块最后运行)。该exec 'true'退出程序,从而使进一步END块不被执行。

例:

#Once
$ perl -E "$(bash script.sh 4,7,8)"
4

#Duplicated twice
$ perl -E "$(bash script.sh 4,7,8)$(bash script.sh 4,7,8)"
7

#Duplicated thrice
$ perl -E "$(bash script.sh 4,7,8)$(bash script.sh 4,7,8)$(bash script.sh 4,7,8)"
8

最终得分34106
l4m2

0

Python 2,生成C ++

这不会打破任何记录,我主要是在考虑是否可以找出方法:)使用全局变量在main之前运行的事实,因此可以增加全局变量,然后使用#ifdef以确保main仅定义一次。

import sys
print("""#include <stdio.h>
#ifndef A
#define A
int v;
int d[]={""" + sys.argv[1] + """};
struct C{C(){v++;}};
int main(void){ printf("%d",d[v]); }
#else
C c1;
#endif
""")

0

符文附魔,生成符文

74akw94/85akw
R32B~~?US' Sqq1Ky1Ky
\i<{1[lil1-{S{)]{{1KyB
D'0$'´$$' $     Rl0) ?
R"{Zs$;|1|l;|y"@
"UwR'10<|I+}"$~ /' Su0
       Rakwc4akw/

在线尝试!

将输入作为空格分隔的值列表。

输出完成一次
输出完成两次
输出完成四次

利用在1月12日´提交的连续数值读取模式命令,我在14日发现了这个问题。该命令允许任意长度的值可以被编码,因为没有此功能将很难做到(例如,需要将其表示为,至少需要一个附加循环)。正是我创建广告素材时要解决的问题13921X3+X9+X2+´命令。

在原始代码中,|在串"{Zs$;|1|l;|y""UwR'10<|I+}"与替换\n(其坐在网格和不修改它,因为他们通常会)与w仪式命令:74akw94/Rakwc4akw,和85akw。原始字符实际上可以是任何字符。|被选为象征性的占位符,以视觉方式代表我想要的东西。通过不必反射性地添加一个入口点来节省数个字节(如果是未计分的字节数),例如,wR'10<Ra 写入一个已经存在的位置(position 0,1),然后在循环耗尽之前用垃圾将其堆栈填充为垃圾顺序U"'i34

生成的输出代码通过使用write命令将第二行上的第一个字符更改为正确的R重定向而工作(因此,只有一个IP执行打印语句),并巧妙地利用了越来越高的程序所产生的堆栈长度来确定哪个索引读书。其他每个IP都将同一位置更改为同一指令并终止。其他所有东西都没有使用。

执行流程

图片过时,但足以说明流程。

每次执行都会1Iy维持IP处理越来越大的堆栈(由l命令引起)的能力,堆栈的大小使程序可以确定基本源代码的副本数。最终1值用于l在旋转堆栈(下一个创建)时将前一个递增到所需的数字,以便获得正确的值。该Z命令取反该值,以便堆栈沿正确的方向旋转。

然后,使用连续读取模式对原始输入数组进行编码,并以0开头,以避免递增地修改相同的值,以读取原始输入。需要空间NOP退出连续读取模式,并允许随后的0再次填充堆栈。

3+v.toString().length对于每个数组条目v+23每个数组的得分应大致相等。如果我做对的话,大约(2.55*total length of input)33837作为示例输入。

由于在同一版本中对该s命令引入了副作用,因此将较小的更改引入了我预期的最终程序中,但是同时产生了更好的分数。

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.