洋葱编程


22

仅使用可打印的ASCII(十六进制代码20至7E),编写一个方形N×N 核心程序,不带注释,并由另外4个围绕,创建一个(N + 8)×(N + 8)方形程序(N> 0) 。对于N = 3,布局(将由实际代码替换)如下所示:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • C代表核心3×3程序。
  • 1代表第一层,2代表第二层,依此类推。

程序始终采用一串用空格分隔的整数,例如0 -1 31 -1 2 2 2通过stdin或类似的字符串(它应该只是纯数字,没有引号或方括号或其他任何东西)。输出取决于运行布局的哪些部分。

有五种运行程序的方式(运行中包括换行符)。每个函数都与列表不同:

  1. 只运行核心:

    CCC
    CCC
    CCC
    

    这将计算输入列表元素的绝对值的最大值,并CORE在新行上打印多次。如果最大值为0,则不会输出任何内容(可以使用换行符)。

    • 该输出0 -1 31 -1 2 2 2

      CORE
      CORE
      ...
      

      31次。

  2. 在第1层运行核心:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    这会将列表值的平均值(算术平均值)输出到标准浮点精度。

    • 输出为0 -1 31 -1 2 2 235/7 = 55.0可以)。
  3. 在第1层和第2层运行核心:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    这将输出一个空格分隔的输入列表,该列表反向。

    • 对于输出0 -1 31 -1 2 2 22 2 2 -1 31 -1 0
  4. 用第1、2和3层运行核心(模式应该很明显)。
    这将输出已排序输入列表的以空格分隔的列表。

    • 对于输出0 -1 31 -1 2 2 2-1 -1 0 2 2 2 31
  5. 用第1、2、3和4层运行核心。
    这将输出空格的输入列表的列表,其中删除了重复项,顺序无关紧要。

    • 的输出0 -1 31 -1 2 2 2可能是-1 0 2 31

所有输出都将输出到stdout或类似的替代文件。

仅这5个布局组合具有指定的行为。

笔记

  • 核心或层或其组合中不允许评论。无操作或无建设性的代码不算作注释。
  • 请记住,核心可以具有任何(正)N×N尺寸,但是层只有一个字符厚。
  • 您可以假设输入没有前导或尾随空格,并且数字之间恰好有一个空格。它将始终包含至少一个数字。(输出列表也应采用这种格式。)
  • 您可能会假设输出所需的列表和计算将不会具有使整数上溢(或下溢)的值(只要它们的最大值是合理的,例如2 16)。

计分

通常编写该程序很容易。用一个小的核心来编写它是很难的。

核心大小最小(N最小)的程序获胜。如果是平局,则获胜者是完整程序((N + 8)×(N + 8)平方),其独特字符最少(不包括换行符)。

请在答案顶部报告您的N值。


1
我认为,这也将是这些新类型的另一个
优化

我可以使用一种在换行符之后会忽略所有内容的语言吗?
2014年

1
@isaacg是的(只要不将换行符视为注释字符,那将很奇怪)。
加尔文的爱好2014年

3
@Optimizer不要诱惑我...“ 每个答案都会在代码洋葱中添加一个新层,以便它对列表进行一些新处理...
卡尔文的爱好2014年

1
@Optimizer号。(我知道这些I / O规则很严格,但这是为了确保各种语言之间的一致性。)
卡尔文的爱好2014年

Answers:


10

CJam,N = 5、27(26)个唯一字符

如果我不计算空格,它是26个字符。该程序实际上可以转换为不使用空格的程序,只需用无操作填充所有空白空间即可(例如_;,它复制顶部堆栈元素然后丢弃,或者通过对数组进行一次又一次的排序),但是它可以只会分散实际代码的注意力。

l~]_|S*      
{l~]$S*      
 {l~]W%S*    
  {l~]_,\    
   {l~]{z    
    }%$W=    
    "CORE    
    "*       
         }   
   ;:+d\/ }  
  ;        } 
 ;          }
;            

在这里测试。

核心是

l~]{z
}%$W=
"CORE
"*

(加上一个空行。)

我相当确定这N = 4不可能在CJam中完成(并且我确信Dennis会说服我:D)。上面有17个字符,虽然有可能将其降低到16个字符(例如,如果CJam没有要塞的bug :z,这需要{z}%或使用ARGV),但我认为您不适合在布局中不引入换行符CORE

所有实现都是对给定任务非常简单的解决方案。他们都以l~]读取STDIN的方式,对其进行求值并将其放入数组中。

上一层始终被包围在 {...},这使它成为一个不会自动执行的块。而且,除了执行它之外,我还只是使用将该其从堆栈中丢弃;,因此没有层依赖于上一层中的代码。在第1层中,代码不适合第一行,因此我在丢弃核心块之后继续执行。

现在为实际程序:

  • 核心:

    {z}%$W="CORE
    "*
    

    映射abs到列表,对其进行排序,获取最后一个元素,然后重复CORE(和换行)多次。

  • 第1层:

    _,\:+d\/
    

    复制列表,获取长度,交换堆栈元素,获取总和,转换为 double,交换堆栈元素,除法。我认为这可以缩短时间,但是没有动力这样做。

  • 第2层:

    W%S*
    

    反转数组,用空格修饰。

  • 第3层:

    $S*
    

    排序数组,用空格修饰。

  • 第4层:

    复制,取固定的并,用空格修饰。

也可以进行其他一些优化,例如重用第2层的;*S,但这仍然不会影响得分。


17

Python 2-N = 17、53个字符

噢,我喜欢使用Python进行源代码布局挑战...

i=4                     ;
ii=3                    ;
iii=2                   ;
iiii=1                  ;
iiiii=0;R=raw_input     ;
iiiii;w=R().split()     ;
iiiii;n=map(int,w)      ;
iiiii;S=set(n);M=max    ;
iiiii;s=sorted(n)       ;
iiiii;J="\n".join       ;
iiiii;j=" ".join        ;
iiiii;k=M(map(abs,n))   ;
iiiii;A=J(["CORE"]*k)   ;
iiiii;B=sum(n)/len(n)   ;
iiiii;C=j(w[::-1])      ;
iiiii;D=j(map(str,s))   ;
iiiii;E=j(map(str,S))   ;
iiiii;P=A,B,C,D,E       ;
iiiii;print P[i]        ;
iiiii;" /__----__\  "   ;
iiiii;"|/ (')(') \| "   ;
iiii;"  \   __   /  "   ;
iii;"   ,'--__--'.   "  ;
ii;"   /    :|    \   " ;
i;"   (_)   :|   (_)   ";

但是,仍有一些未使用的空格。

我仍然可以改善唯一字符数,但是我会坚持更好的可读性-如果有的话。

编辑:噢,这是斯坦再次


你也许可以通过混叠打印,而不是节省一些线i=*把戏
M.Herzkamp

@ M.Herzkamp:别名print是不可能使用Python 2,但肯定的是,有可能提升的空间-也许使用Python 3
Falko

我不了解Python,但是在核心代码输出中不是不是缺少绝对值c*max(n)
吗?

@nutki:你是对的!我没有仔细阅读。但是我能够解决它。
Falko 2014年

6

Python 3:N = 11,40个不同的字符

if 1:              
 if 1:             
  if 1:            
   if 1:           
    p=print;R=0    
    a=input()      
    b=a.split()    
    m=map;a=abs    
    E=max;l=len    
    n=m(int,b);    
    C=['CORE']     
   "R=E(m(a,n))"   
   OO=C*R;s=sum    
   "x='\n'.join"   
   "p(x(O))    "   
  "p(s(n)/l(b)) "  
 "p(*b[::-1])    " 
"p(*sorted(n))    "
p(*set(n))         

感谢@Falko成为我的缪斯女神。这是可行的,因为Python不会为每个if语句创建新的作用域,因此变量会保留在外部print语句中。一件令人讨厌的事情是,一个map对象(在我们的例子中n)只能使用一次。因此有必要将R=E(...),但是R未定义。因此,我很幸运第一行还剩下四个空格!

可以通过提供多个元素*b[::-1]而不是列表来解决输出。替代方案' '.join(...)可能太长了。


美丽!很高兴看到处理python中可变行开头的另一种方法。只是一些简短的if语句,所有这些空格都很好。:)
Falko 2014年

@Falko:缺点是:Stan没有空间:(
M.Herzkamp 2014年

2

C(gcc),N = 15,47个唯一字符

假设sizeof(int) == 4sizeof(int*) >= sizeof(int)

;                     ;
 ;                   ; 
  ;                 ;  
   ;           float   
    s;c(a,b)int*a,*    
    b;{b=*b-*a;}i,n    
    ,*f;*q,*R,C,E ;    
    main(a){for(;0<    
    scanf("%i",&a);    
    i=i<abs(a)?a:i,    
    s+=f[n-!0]=a)f=    
    realloc(f,++n*4    
    );qsort(f,n*C,4    
    ,c);for(i=q?R?n    
    :!0:i;i--;a=f[i    
    ])!E|n-i<2|a!=f    
    [i]&&printf(q?R    
    ?R:q:"CORE\n",!    
    q+R?f[i]:s/n);}    
   ;*q="%f";       ;   
  ;*R="%.0f ";      ;  
 ;C=!0;              ; 
;E=!0;                ;

4层

3层

2层

1层

核心


0

符文附魔N = 9 N = 8,38个字符

/ o/\  \     \S\
" //RiU\      \}
@            q "
"        }+1\r @
}   ^U \    {q "
     \{\?)}\+  }
  o\/'|A:{:/R' S
 //r/Ril2=?\?R :
   ,A~/"OC"/=? {
   @| \"RE"\3= =
 D$\' /rqka/l2S?
    i \*@   il\/
   'R1i     Ui ~
 R$/Rak      U \
 ?!D  Rlril1-{=
R   R: }S:{=?\~

在线尝试!

原来我错o,由于之前遇到过“对列表排序”问题,我忘记了已经有一个显式的rt命令。但是,由于sort命令的内部成本,这确实限制了最终程序可以接受的输入大小(8个值)。稍作调整即可以1个唯一字符为代价将输入大小增加到13个,或者 19个个 2个唯一字符(所有其他字符都位于第1层并同时添加,但是IP堆栈的增加容量并没有增加)直到第3层(C,L1和L2可以执行其计算而无需将整个输入都保存在内存中)为止。

核心:在线试用!

第1层:在线尝试!

第2层:在线尝试!

第3层:在线尝试!

第4层:在线尝试!

由于较小的空间需要增加流量控制字符的数量,因此进一步压缩的可能性极小。我发现在内核程序中有9个空白的安排,但这还不够,因为我们需要(正确安排)15。

没有可视化的IP路径图,很难解释这些程序的工作方式,这很麻烦且耗时。初始入口点是Core程序(^)的左上角,它允许在添加新层时进行一致的流控制,因为每一层都有机会在顶部或底部的新添加的行上进行拦截。

第1层和第2层在底部截取(以便在以后的层中,顶行保持空白),然后沿右边缘(垂直排列的循环)执行其操作。第1层稍长,沿上边缘也需要3个字符,但是\右上角的对角反射器()将IP与下一个循环迭代重新对齐。

第3层沿着顶部边缘进行截取,以便在重定向到底部边缘之前获取第一个输入值(第4层在此列的底行上留下NOP),并使用底部边缘循环读取完整的输入,在Down上进行重定向D左下角的命令()。IP会从那里反弹几次,然后结束于$左下角的output()循环中,以便对值进行空间分隔。

第4层利用了第3层的所有功能(因此留有空白),但在第3层的处理结束时在其自己的新顶部边缘(左上方)进行了拦截,以执行其自身的功能。左上角插入一个字符串"@",该字符串用于表示数组的末尾,然后沿着底部进入处理循环。如果找到重复的值,则将其弹出(~,右下角),否则将使用新的右边缘的分支被采用。该侧分支检查是否已到达数组的末尾,如果已到达,则中断并转到与第3层相同的空格分隔的输出循环。否则,请使用第3层上的空格返回到主数组。环。

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.