Code Golf:蜂巢

Lir*_*una 31 language-agnostic code-golf rosetta-stone

挑战

按字符数排序的最短代码,将根据用户输入生成蜂窝.

蜂窝被定义为由用户输入的大小的六边形网格,作为两个大于零的正数(不需要验证输入).第一个数字(W)代表蜂箱的宽度 - 或 - 每行有多少个六边形.第二个数字(H)表示蜂箱的高度 - 或 - 每列上有多少个六边形.

:一个六边形由三个ASCII字符制成_,/并且\,和三线:

 __
/  \
\__/
Run Code Online (Sandbox Code Playgroud)

六边形相互完成:蜂巢的第一列将为"低",第二列将为高 - 交替并以相同的图案重复形成W六边形.这将重复H次以形成总共WxH六边形.

测试用例:

Input:
    1 1
Output:
     __
    /  \
    \__/
Run Code Online (Sandbox Code Playgroud)
Input:
    4 2
Output:
        __    __
     __/  \__/  \
    /  \__/  \__/
    \__/  \__/  \
    /  \__/  \__/
    \__/  \__/
Run Code Online (Sandbox Code Playgroud)
Input:
    2 5
Output:
        __ 
     __/  \
    /  \__/
    \__/  \
    /  \__/
    \__/  \
    /  \__/
    \__/  \
    /  \__/
    \__/  \
    /  \__/
    \__/
Run Code Online (Sandbox Code Playgroud)
Input:
    11 3
Output:
        __    __    __    __    __
     __/  \__/  \__/  \__/  \__/  \__
    /  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/
    /  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/
    /  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/
Run Code Online (Sandbox Code Playgroud)

代码计数包括输入/​​输出(即完整程序).

mob*_*mob 21

Perl,99个字符

@P=map{$/.substr$".'__/  \\'x99,$_,$W||=1+3*pop}0,(3,6)x pop;
chop$P[0-$W%2];print"    __"x($W/6),@P
Run Code Online (Sandbox Code Playgroud)

最后编辑:保存一个字符替换-($W%2)0-$W%2(感谢A.雷克斯)

说明:

对于宽度W和高度H,输出为2 + 2*H线长,3*W + 1个字符宽,输出中间有很多重复.

为方便起见,我们设$W3*W + 1,输出宽度为字符.

顶行由模式组成" __",重复W/2 == $W/6次.

偶数行由重复模式组成"\__/ ",截断为$W字符.第二行输出是一种特殊情况,第二行的第一个字符应该是空格而不是空格\.

奇数行由重复模式组成"/ \__",截断为$W字符.

我们构造一个字符串: " " . "__/ \" x 99.请注意,此字符串的开头是第二行的所需输出.从位置3开始的该行是奇数行的期望输出,并且对于偶数行从位置6开始.

map调用的LIST参数以0开头,然后是(3,6)的H次重复.该map调用创建一个从适当位置开始并且$W= 3*W + 1个字符长的子串列表.

在打印结果之前还需要进行一项调整.如果W是奇数,则第二行($P[0])上有一个额外的字符需要chop关闭.如果W是偶数,则在底线($P[-1])上有一个额外的字符来切断.

  • 我知道Python不会长时间击败Perl. (3认同)

rec*_*ive 10

Python 2.6 - 包括换行符在内的144个字符

如果输入允许以逗号分隔,我可以节省大约20个字符.

C,R=map(int,raw_input().split())
print C/2*"    __"+"\n "+("__/  \\"*99)[:3*C-C%2]
r=0
exec'r+=3;print ("\__/  "*99)[r:r+3*C+1-r/6/R*~C%2];'*2*R
Run Code Online (Sandbox Code Playgroud)

从命令行获取输入的版本是4个字节:

import sys
C,R=map(int,sys.argv[1:])
print C/2*"    __"+"\n "+("__/  \\"*99)[:3*C-C%2]
r=0
exec'r+=3;print ("\__/  "*99)[r:r+3*C+1-r/6/R*~C%2];'*2*R
Run Code Online (Sandbox Code Playgroud)


str*_*ger 10

C89(136个字符)

x;y;w;main(h){for(h=scanf("%d%d",&w,&h)*h+2;y++
<h;++x)putchar(x>w*3-(y==(w&1?2:h))?x=-1,10:
"/  \\__"[--y?y-1|x?(x+y*3)%6:1:x%6<4?1:5]);}
Run Code Online (Sandbox Code Playgroud)

  • @DigitalRoss,我可以编写一个"C编译器",它接受任何输入并生成二进制打印蜂窝给定参数的蜂窝,并调用我编写的非标准C代码.符合*some*标准是合理的,可接受的方案 (4认同)
  • 'for'循环需要'{'和'}'吗? (2认同)

eph*_*ent 6

Perl,160个字符

$w=shift;for$h(-1..2*shift){push@a,join'',(('\__','/  ')x($w+$h))[$h..$w+$h]}
$a[0]=~y#\\/# #;$a[1]=~s/./ /;s/_*$//for@a;$a[$w%2||$#a]=~s/. *$//;print$_,$/for@a
Run Code Online (Sandbox Code Playgroud)

根本不涉及聪明:只需用数字填充数组,然后清除看起来很难看的那些.

当移植到Perl时,strager的杰作只有137个字符,但所有功劳都归功于他.

$w=shift;$\=$/;for$y(1..($h=2+2*shift)){print map+(split//,'_ \__/  ')
[$y-1?$y-2|$_?($_+$y%2*3)%6+2:1:$_%6<4],0..$w*3-!($w&1?$y-2:$y-$h)}
Run Code Online (Sandbox Code Playgroud)


eph*_*ent 6

J,143个字符

4(1!:2)~(10{a.)&,"1({.4 :0{:)".(1!:1)3
|:(18,(}:,32-+:@{:)3 3 8 1 1 10$~3*x){(,' '&(0})"1,' '&(0 1})"1)(,}."1)(}."1,}:"1)(3++:y)$"1'/\',:' _'
)
Run Code Online (Sandbox Code Playgroud)

在处理可变长度字符串以及在其他语言中假设的面向控制台的用户交互时,使用J感觉非常尴尬.不过,我想这是不是糟糕......

再一次窃取想法(一旦你找到一种以阵列结构方式查看问题的方法,J就更容易使用了),这里的mobrule的杰作移植到124(ick,它比原来的更长):

4(1!:2)~({.4 :0{:)".(1!:1)3
(x}~' '_1}(x=.-1-+:2|x){])((10{a.),(' ',,99#'__/  \',:'    __'){~(i.>:3*x)+])"0]595 0,3 6$~+:y
)
Run Code Online (Sandbox Code Playgroud)

  • 所有表情符号都去了哪里?! (2认同)

Jef*_*ang 5

C#,216个字符

class B{static void Main(string[]a){int b=0,i=0,w=int.Parse(a[0])+1,z=2*w*(int.Parse(a[1])+1);for(;i<z;b=(i%w+i/w)%2)System.Console.Write("\\/ "[i>w&(w%2>0?i<z-1:i!=2*w-1)?b>0?0:1:2]+(++i%w<1?"\n":b>0?"__":"  "));}}
Run Code Online (Sandbox Code Playgroud)

少混淆:

class B{
    static void Main(string[]a){
       int b=0,
           i=0,
           w=int.Parse(a[0])+1,
           z=2*w*(int.Parse(a[1])+1);

       for(;i<z;b=(i%w+i/w)%2)
           System.Console.Write(
             "\\/ "[i>w&(w%2>0?i<z-1:i!=2*w-1)?b>0?0:1:2]
             +
             (++i%w<1?"\n":b>0?"__":"  ")
           );
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用以下方法:

input: 4 2
cols:  0 00 1 11 2 22 3 33 4 44     
row 0:" |  | |__| |  | |__| |"
    1:" |__|/|  |\|__|/|  |\|"
    2:"/|  |\|__|/|  |\|__|/|"
    3:"\|__|/|  |\|__|/|  |\|"
    4:"/|  |\|__|/|  |\|__|/|"
    5:"\|__|/|  |\|__|/|  | |"
Run Code Online (Sandbox Code Playgroud)
  1. 从零到(W + 1)*(H*2 + 1)迭代.*2是因为每个梳子高2行,而+1用于说明第一行和行尾.
  2. 每次迭代渲染两个六边形的"块":
  3. 在第一部分中决定"","\"和"/"
  4. 第二部分决定"__",""和"\n"

如果你看一个足够大的蜂窝,这种模式就很明显了.逻辑的一半仅用于解决第一行,第二行结束和最后一个单元格中的异常.