我想要蜂窝


39

编写最短的程序来打印此六角形平铺蜂窝状的 ASCII艺术部分:

       __
    __/  \__
 __/  \__/  \__
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
   \__/  \__/
      \__/
  • 请勿输入任何内容。
  • 输出到标准输出或您的语言最接近的替代产品。
  • 您可以编写一个不带任何参数的命名函数,而不是程序,而可以正常打印结果或将其返回为字符串。
  • 输出可以具有任意数量的前导和/或尾随换行符,并且输出中的每一行可以具有任意数量的前导和/或尾随空格(只要模式正确对齐即可)。
  • 以字节为单位的最短代码获胜。

13
您扮演Catan很多吗?
user3490

@ user3490实际上我做^^
加尔文的爱好

2
下周在PCG上:写一个Catan板生成器?
user3490

7
它应该有一个输入IMO,你的情况应该是3
user3819867

3
@ user3819867我确实考虑过,但是更喜欢这个。改变为时已晚,但任何人提出相关挑战都为时不晚。
加尔文的爱好2015年

Answers:


33

CJam,45 43 42 41 40字节

741e8 36+Ab"\__/  "38*21/.{G2$-<\S*.e<N}

CJam解释器中在线尝试。

这个怎么运作

"\__/  "38*21/

重复图案\__/ 38次并将其分成长度为21的块。如果这些块被换行符分隔,则结果如下:

\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  \__
/  \__/  \__/  \__/  
\__/  \__/  \__/  

这显然包含所需的蜂窝。剩下要做的就是用空格替换某些字符,删掉其他一些字符并实际引入换行符。

741e8 36+Ab

生成整数74 100 000 036并将其转换为数组[7 4 1 0 0 0 0 0 0 3 6]。每个数组元素编码必须用空格替换的相应行的前导字符的数量。通过从16减去该数字,我们还获得了该行的正确长度。

.{            } e# Execute for each pair of a digit D and a line L:
  G2$-<         e#   Chop off L after 16 - D characters.
       \S*      e#   Push a string of D spaces.
          .e<   e#   Compute the vectorized minimum.
             N  e#   Push a linefeed.

由于空格的代码点比L的其他字符低,并且矢量化运算符将较长的字符串中与较短的字符串相对应的字符保留不变,.e<因此请用空格替换前D个字符。


2
太好了 辛苦了
Alex A.

28

Python 2,73

i=0
exec"k=max(7-i,i-24,0);print' '*k+('\__/  '*9)[i:][k:16-k];i+=3;"*11

看到它运行。

对于11个输出行中的每一个,计算前导空格的数量,k最多为三个线性函数的最大值,这些线性函数形成了六边形左侧的包络。由于对角线的斜率为3-3,因此最好将行号索引为i=0,3,...30

要创建六边形网格,我们首先要平铺足够的单位'\__/ '。然后,[i:]对于奇数行,移位将其重新对齐3。最后,我们取所需的部分[k:16-k]k在左边和右边留出余量。


22

CJam,65 56 55字节

"Ý6TNð*¯5"303b4b["/\_")"_ "4*S]f=sB/z{_W%"\/"_W%erN}/

CJam解释器中在线尝试。

理念

每行的右半部分是左半部分的反向副本,其中斜杠和反斜杠互换。因此,足以对蜂窝的左半部分进行编码:

       _
    __/ 
 __/  \_
/  \__/ 
\__/  \_
/  \__/ 
\__/  \_
/  \__/ 
\__/  \_
   \__/ 
      \_

与其逐行分析此模式,我们可以逐列进行分析:

   /\/\/\  
  _ _ _ _  
  _ _ _ _  
  /\/\/\/\ 
 _ _ _ _ _ 
 _ _ _ _ _ 
 /\/\/\/\/\
_ _ _ _ _ _

显而易见的模式出现了:

  • 该字符串_ _ _ _出现五次。
  • 每个/后跟一个\

通过替换每一个/\__ _ _ _与一些和空间从0到3,我们可以得到的阵列从基座4号转换成更高的基极和存储在一个紧凑的方式的完整图案。

"Ý6TNð*¯5"303b4b  e# Convert the string from base 303 to base 4.
["/\_")"_ "4*S]f= e# Replace each resulting digit by the corresponding item of the array
                  e# ["/\" "_" "_ _ _ _ " " "].
sB/               e# Split into strings of length 11.
z                 e# Zip: transpose rows with columns.
{             }/  e# For each string:
 _W%              e#     Push a reversed copy.
    "\/"_W%er     e#     Swap slashes and backslashes.
             N    e#     Push a linefeed.

10

C,148 144 140个字节

k,r,c,d,p;f(){for(;k<187;k++){r=k/17;c=k%17;d=c+r%2*3;p=3*r+c-7<33u&3*r-c+8<33u;putchar(c==16?10:p&(d+5)%6<2?95:p&d%6==3?47:!p|d%6?32:92);}}

使用空格,没有编译器警告,并且在一些代码进行调整以节省一些字节之前:

#include <stdio.h>

int k, r, c, d, p;

void f() {
    for ( ; k < 187; k++) {
        r = k / 17;
        c = k % 17;
        d = c + 3 * (r % 2);
        p = 3 * r + c - 7 < 33u && 3 * r - c + 8 < 33u;
        putchar(
            c == 16 ? 10 :
            p && (d + 5) % 6 < 2 ? 95 :
            p && d % 6 == 3 ? 47 :
            p && d % 6 == 0 ? 92 :
            32);
    }
}

这种方法不使用任何字符/字符串表。它循环遍历所有187个(11行,包括换行符的17列),并根据条件的组合来决定为每个位置打印哪个字符。

条件包括使用4个线方程对4个角的内侧/外侧进行测试,并将结果存储在variable中p。剩下的大部分则每6个字符重复一次,奇数行相对于偶数行偏移3个字符。


2
对于打高尔夫球的人,可以使用hidden-int并删除int
luser droog 2015年

一些微小的改进:k;f(r,c,d,p){for(;k<187;putchar(c>15?10:p&d<2&p?95:p&d<3?47:!p|d-5?32:92))r=k/17,c=k++%17,d=(5+c+r%2*3)%6,p=3*r+c-7<33u&3*r-c+8<33u;}
丹尼斯


6

JavaScript的(ES6),129 130

那是一个纯字符串替换/替换/替换……不利用任何几何特性。

使用模板字符串,所有换行符都很重要并且很重要。

在Firefox中运行代码段进行测试

f=_=>`70
405
 055
9992 3051
6301`[R='replace'](/9/g,`55123
30551
`)[R](/5/g,1230)[R](/\d/g,n=>['__','/',,'\\'][n]||' '.repeat(n))

// TEST

O.innerHTML = f()
<pre id=O></pre>


6

PHP - 139 137 107 101 91 87个字节

我不知道这是否是打高尔夫球的最佳方法,但是我尝试一下:

30 36 46 -50个字节,感谢Ismael Miguel

在这里在线测试

<?='       __
    __',$a='/  \__',"
 __$a$a
",$c="$a$a/  \
\__$a$a/
","$c$c   \__$a/
      \__/";

<script src="http://ideone.com/e.js/WHWEZS" type="text/javascript" ></script>

旧代码:

<?php $a="/  \\__";$c=$a.$a."/  \\\n\__".$a.$a."/\n";echo "       __\n    __".$a."\n __".$a,$a."\n".$c,$c,$c."   \\__".$a."/\n      \\__/";

欢迎使用编程难题和Code Golf。您的PHP代码可以减少很多。您可以使用<?而不是 <?php保存3个字节。代替$c=$a.$a."/ \\\n\__".$a.$a."/\n";,您可以编写$c="$a$a/ \\\n\__.$a$a/\n";(因为PHP用字符串扩展变量)。您可以将相同的逻辑应用于,echo以进一步缩短其长度。另外,您不需要在echo和字符串之间留有空格。
Ismael Miguel

1
谢谢,每次尝试打高尔夫球我都会学到一些新东西。
蒂莫,2015年

别客气。这是一个99字节长的解决方案:ideone.com/WHWEZS。它看起来一团糟,但是要短得多。\n可以使用真正的 换行符代替每行保存1个字节,而不必使用。
伊斯梅尔·米格尔

同时,我将其减少了2个字节。现在它有97个字节。
伊斯梅尔·米格尔

1
这是一个单行代码:<?="\t __\n\t__",$a='/ \__',"\n __$a$a\n",$c="$a$a/ \\\n\__$a$a/\n","$c$c \__$a/\n\t \__/";。切记\t用制表符和\n真实的换行符代替。
伊斯梅尔·米格尔

4

卢阿146

T="       __\n    __/  \\__\n __/  \\__/  \\__\n"
S="/  \\__/  \\__/  \\\n\\__/  \\__/  \\__/\n"
B="   \\__/  \\__/\n      \\__/"
io.write(T,S,S,S,B)

(为清楚起见添加了换行符)


1
这不是码比期望的输出,因为它只是包含输出加逃逸,字符串处理的东西?
卡雷布(Caleb)2015年

6
@Caleb:我怀疑您实际上没有数过,只是猜想在发表这一评论。根据我的文本编辑器,点阵中有165个字符(包括换行符)。由于重复S3次,我少了19个字符。
凯尔·坎诺斯

2
但是您是正确的,转义符和换行符确实限制了我的代码在此特定游戏中竞争的能力。但是获胜也不是我这样做的原因,这是为了娱乐和学习。
凯尔·坎诺斯

3

飞镖-113

main({r:"/  \\__"}){print("       __\n    __$r\n __$r$r\n${"$r$r/  \\\n\\__$r$r/\n"*3}   \\__$r/\n      \\__/");}

纯字符串插值解决方案,没什么花哨的。诸如“子字符串”之类的字符串操作过于冗长,无法在实践中竞争。

DartPad上运行它。


3

Javascript(ES7草案),96 94 93字节

灵感来自这里的一些解决方案...

编辑:从edc65 -1

f=z=>[for(x of[741e6]+36)' '.repeat(x)+'/  \\__'.repeat(4,z^=3).slice(+x+z,16-x+z)].join(`
`)

// For snippet demo:
document.write('<pre>'+f()+'</pre>');

评论:

f=z=>[                                 
        for(x of [741e6] + 36)        // for each character "x" in "74100000036"
            ' '.repeat(x) +           // x spaces
            '/  \\__'.repeat(4,       // build pattern string
            z ^= 3).                  // toggle z offset (3) for even lines
            slice(+x + z, 16 - x + z) // get appropriate substring
    ].join(`                          // join with newlines
    `)

好东西。.substr(+x+z,16-x-x)-> .slice(+x+z,16-x+z)-1
edc65

@ edc65好抓住!
nderscore 2015年

快速的问题:为什么它+x不只是x
尼克·哈特利

1
@QPaysTaxes强制x转换为数字。如果没有它,它将串联z
nderscore

2

Python 3中,100个 87字节

n=0x85208e08e08dd445
while n:l=n>>2&15;print(' '*(8-l)+('\__/  '*4)[n&3:n&3|l*2]);n>>=6

以及下面的代码的可读版本。想法是对间隔(开始,长度)进行硬编码,然后填充正确数量的空格以使间隔居中。

hexagon_string = '\__/  ' * 4
for i in range(11):
    # Pick the begin and length of the i-th interval using hardcoded numbers
    b = (0x00030303111 >> 4*i) & 3   # n is a combination of these two numbers
    l = (0x25888888741 >> 4*i) & 15  #
    # Print the interval with appropriate whitespace in front of it
    spaces = ' ' * (8-l)
    print(spaces + hexagon_string[b : b+l*2])

2

视网膜,66字节

<empty line>
sss __<LF>ssa__<LF> aa__<LF>lll dau<LF>ssdu
l
/daa<LF>\aau<LF>
a
ud
u
__/
d
s\
s

每行应转到其自己的文件,并<LF>表示文件中的实际换行符。每个额外的文件1个字节添加到字节数中。

您可以将代码与-s标志一起作为一个文件运行,保留<LF>标记,并且可以根据需要将标记更改为输出中的换行符。

该算法是从一个空的输入字符串开始的5个简单的替换步骤(将奇数行内容更改为偶数行内容)。每个步骤之后的结果(以=s 分隔):

sss __
ssa__
 aa__
lll dau
ssdu
============
sss __
ssa__
 aa__
/daa
\aau
/daa
\aau
/daa
\aau
 dau
ssdu
============
sss __
ssud__
 udud__
/dudud
\ududu
/dudud
\ududu
/dudud
\ududu
 dudu
ssdu
============
sss __
ss__/d__
 __/d__/d__
/d__/d__/d
\__/d__/d__/
/d__/d__/d
\__/d__/d__/
/d__/d__/d
\__/d__/d__/
 d__/d__/
ssd__/
============
sss __
ss__/s\__
 __/s\__/s\__
/s\__/s\__/s\
\__/s\__/s\__/
/s\__/s\__/s\
\__/s\__/s\__/
/s\__/s\__/s\
\__/s\__/s\__/
 s\__/s\__/
sss\__/
============
       __
    __/  \__
 __/  \__/  \__
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
/  \__/  \__/  \
\__/  \__/  \__/
   \__/  \__/
      \__/

1

Javascript,154151字节

b="\n",c="\t",d="/  \\",f="__",g="\\",h="/",a=f+d,j=a+a,i=d+j+b+g+j+f+h+b,k="   ";console.log(c+k+f+b+c+a+f+b+" "+j+f+b+i+i+i+k+g+a+f+h+b+c+"  "+g+f+h)
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.