ASCII连接的六边形


21

总览

给定许多六角形,将它们排列成50乘50 ASCII艺术图像范围内的连接形状。您可以选择任意形状-只要您将其连接,就可以发现最适合打高尔夫球的形状。如果它们大于一个六边形,则可能会有孔(否则,六边形的数量将是不明确的)。


布局

所有六边形都必须采用以下形式(仅此大小和方向有效):

 __
/  \
\__/    Note there are 2 underscores per horizontal edge.

如果两个六边形共享一条边,则它们直接相连

 __               __
/  \__           /  \
\__/  \          \__/
   \__/    or    /  \
                 \__/

如果两个六角形仅共享一个顶点,则它们不连接:

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

共享半边也不算是已连接:

 __
/  \
\__/
 /  \
 \__/

如果存在仅使用直接连接的六边形从任意六边形到其他任意六边形的路径,则连接六边形的集合。

孔洞

相连的六边形集合中的六边形大小的孔算作六边形,因此任何给定的ASCII艺术作品都具有明确的六边形数。

这并不会因为未来的孔是一个六边形算作一个孔:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      7 hexagons (not 6 with a hole)

确实算作一个孔,因为它不对应于单个六角形:

    __
 __/  \__
/  \__/  \__
\__/  \__/  \
/  \__   \__/
\__/  \__/  \
   \__/  \__/
      \__/      8 hexagons with a hole

输入输出

输入值

1至255之间的整数。

输出量

如上所述,表示连接的六边形的输入数量的ASCII艺术字串。

  • 行数(以换行符分隔的子字符串)最多为50,另外还有一个可选的尾随换行符。
  • 行的长度不必相同,但每行的长度最多为50。
  • 如果总行数不超过50,则零长度行可以存在于连接形状的上方或下方。
  • 如果总行数不超过50,则仅空格行可以存在于连接形状的上方或下方。
  • 如果行的长度不超过50(形状不需要向左对齐),则形状的左侧可能会出现空格。
  • 如果行的长度不超过50,则形状的右侧可能会出现空格。
  • 不构成连接形状一部分的任何字符都必须是空格或换行符。

如果输出正确,则不需要从一次运行到下一次运行保持一致。

例子

输入: 6

有效输出:

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

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

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

无效的输出:

    __
 __/  \__
/  \__/  \
\__/  \__/
/  \__/  \
\__/  \__/
   \__/      Invalid for 6 as the centre hole counts as a 7th hexagon.

 __    __    __      __
/  \__/  \__/  \    /  \
\__/  \__/  \__/    \__/
   \__/  \__/                Invalid as the 6 hexagons are not connected.

 __    __    __  __
/  \__/  \__/  \/  \
\__/  \__/  \__/\__/
   \__/  \__/           Invalid as vertex touching does not count as connected.

 __    __       __
/  \__/  \     /  \
\__/  \__/     \__/
/  \__/  \
\__/  \__/
   \__/       Invalid as the 6 connected hexagons are not the only visible characters.

获奖

以字节为单位的最短有效答案为准。


排行榜

(使用Martin的页首横幅代码段


我担心每个人都会使用第一个示例输出模式,因为它可能最容易实现。
致命

1
@Fatalize我的示例仅适用于的输入6。对于255六边形的水平行的输入,不适合50 x 50的ASCII图形。
trichoplax

每当您达到50个字符的限制时,您仍然可以简单地循环并在下面填充行
Fatalize 2015年

1
@Fatalize的挑战是最大程度地减少代码中的字节数。我不介意这些模式是否简单,只是看看人们尝试什么以及适合不同语言的事情会很有趣。
trichoplax

@Fatalize:我不知道它是否会简短,但是一个更“有趣”的答案可能会进行实际搜索,以查看它可以放置六边形的位置,从而获得更有趣的输出。
Alex Van Liew

Answers:


13

CJam,64 57 55字节

" __
/  \
\__/"N/{_SS/\+_47>S3*f{\+}_2>\@?}q~(*]:..e>N*

在这里测试。

这将按生成以下模式:

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

说明

这是基于丹尼斯的优良尖端,使用.e>组装从几件的ASCII艺术输出。正如他所说,.e>它采用两个数组(或字符串)的元素方式最大值,并且由于空格具有最低的字符代码,因此我们可以使用它在字符串网格上加上其他任何字符。此外,如果两个数组的长度不同,则较长数组的无关元素将简单地原样复制。这意味着不同的图案甚至不必具有相同的大小。要将其应用于二维数组(因为我们不希望在最后插入换行符),所以我们.e>将成对应用于行,从而得到..e>

该代码的基本思想是生成N移动到正确位置的单个六边形的副本。我们通过在前面加上空行来“移动”六边形,并在前面加上空格来“移动”六边形。一旦完成,我们将使用漂亮的:..e>(可能是我在CJam程序中使用过的最长的运算符)将所有副本折叠在一起。

这是代码:

" __
/  \
\__/"N/    e# Get a 2D character grid of the hexagon.
{          e# Read input N, repeat this block N-1 times.
  _        e#   Make a copy, so we leave the last hexagon on the stack.
  SS/\+    e#   Prepend two empty lines.
  _47>     e#   Make a copy and discard the first 47 lines.
  S3*f{\+} e#   Prepend 3 spaces to each line. This copy has been moved back to
           e#   the top and one column to the right.
  _2>      e#   Make a copy and discard another two lines.
  \@?      e#   If any lines were left after that, pick the copy in the next column,
           e#   otherwise, stay in the same column.
}q~(*      
]:..e>     e# Wrap all the hexagons in an array and fold them into a single grid.
N*         e# Join them with newline characters.

伙计,我真的应该学习其中一种高尔夫球语言。
Alex Van Liew

@AlexVanLiew你应该!:)但这不是因为它增加了赢得代码高尔夫球的机会,而是因为CJam是一种很漂亮的语言,编程很有趣,而且我不知道上述解决方案所使用的其他语言(我认为这很优雅)本来是有道理的。;)
Martin Ender 2015年

我可能会学Pyth或两者都学;他们俩几乎是同一件事还是比其他人更好?
Alex Van Liew

@AlexVanLiew我对Pyth的了解不多,但是我知道它们与同一件事相去甚远。CJam是一种基于堆栈的语言,而Pyth最初是Python的简写(但现在有自己的内置插件集)。Pyth 在打高尔夫球方面可能会占上风,但是我个人真的很喜欢使用其他范例进行编程,因此我会坚持使用CJam。
Martin Ender

啊哈,我明白了。我非常了解Python,这就是为什么我想学习Pyth,但是如果有时间的话,我也可以尝试CJam!
Alex Van Liew

7

Python 2,219207个字符

b=bytearray(' ');h=['__ ','/  \\','\\__/'];k=range;x=input();g=[b*50for _ in k(50)]
for i in k(x):
 c=i*3%48+1;r=(i*3+1)/48*2+i%2
 for m in k(i>15,3):n=m==0;g[r+m][c+n:c+4-n]=h[m]
print"\n".join(map(str,g))

在stdin上接受输入。

差不多只是创建一个50x50的空格网格,并在适当的地方绘制六边形。16六边形后,我并不需要的第一行h(六边形为2D阵列),所以我使用i>15以1而不是0开始的范围内c=i*3%48+1;r=(i*3+1)/48*2+i%2计算所述Ç olumn和- [R流我需要在启动。n是一个布尔值,但用作固定边界的整数(因为h[0]只有3个字符才能避免覆盖内容)。

我对此感到非常满意,自从最初的版本以来就节省了大约50个字节,尤其是在我记得a[x:y]=b语法的时候。

输出(n = 30):

  __    __    __    __    __    __    __    __
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
 /  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/
 \__/  \__/  \__/  \__/  \__/  \__/  \__/  \
    \__/  \__/  \__/  \__/  \__/  \__/  \__/
(plus 44 lines of spaces each 50 wide)

由于允许使用空白行,因此我将创建的时间g改为50 bytearrays,而不是3+(x>1)+x/16*2,这是所需的确切行数,减少了12个字节。


6

迅速2.0,601个 591字节

import Cocoa
var a=Int(Process.arguments[1])!,b="/  \\__".join([String](count:9,repeatedValue:""))+"/",c="\\__/  ".join([String](count:9,repeatedValue:""))+"\\",d=c.startIndex,e=c.endIndex,j=[c.stringByReplacingOccurencesOfString("\\",withString:" ").stringByReplacingOccurencesOfString("/",withString:" ").substringToIndex(advance(d,3*a,e)),b.substringToIndex(advance(d,3*a+a%2,advance(e,-1)))]
while a>0{j+=[c.substringToIndex(advance(d,3*a+1,e)),b.substringToIndex(advance(d,3*a+(a+1)%2,e)]
a<=16 ?j+=[" "+j.removeLast().substringFromIndex(advance(d,1))]:()
a-=16}
for l in j{print(l)}

跑步: swift hexagons.swift 21

输出:

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

斯威夫特substringToIndexstringByReplacingOccurencesOfString占用这么多字...


我一点都不了解Swift,但是没有办法用更少的代码来构造那个重复的字符串吗?
Reto Koradi 2015年

我知道重复字符串的唯一方法是使用stringByPaddingToLength,但是在这种情况下,它比输入完整字符串要长11个字符。
David Skrundz

6
我看到苹果真的很喜欢过于冗长的字符串连接。不像stringByAppendingString在Objective-C中那样糟糕,但仍然...
致命

在代码高尔夫之外,这确实很棒,因为它使查找方法变得非常容易。
JustSid 2015年

4

C,238字节

#define h(A) c[m+A/4][n+A%4]
i,m,n;
f(a)
{
    char c[50][51];
    for(i=0;i<50;i++)for(m=0;m<51;m++)c[i][m]=m-50?32:0;
    for(;a;)
        m=a/12*2,n=a%12*3,a--%2?m=a/12*2+1,n=a%12*3+3:0,
        h(1)=h(2)=h(9)=h(10)=95,h(4)=h(11)=47,h(7)=h(8)=92;
    for(;i;)puts(c-i--+50);
}

仅考虑字符计数所需的空格和换行符。

它只是创建一个字符矩阵,以相反的顺序填充它们,然后打印整个内容。


2

JavaScript(ES6),265字节

A=Array;f='forEach';U=x=1;y=0;a=A.from(A(51),_=>A.from(A(51),_=>' '));d=h=>(` __
/  \\
\\__/`.split`
`[f]((l,i)=>[...l][f]((c,j)=>{if('_/\\'.indexOf(a[x+i][y+j])<0)a[x+i][y+j]=c})),(x+=U*-2+1),(U=!U),(C-y<=3?((U=x+=2),y=0):y+=3),--h?d(h):a.map(d=>d.join``).join`
`)

连续六边形从左向右镶嵌六边形,像蜂窝一样上下交替,直到到达行尾为止。

不含说明(在Firefox中有效):

'use strict';
const CAP = 51;
var a = Array.from(Array(51), () => Array.from(Array(51),() => ' '))

function draw (hexagons, x, y, a, up) {
  // x, y (row, col) represents the current position of the cursor
  /*
  
    Here's a map of the first three iterations:
    
            01234567
     0        __
     1     __/  \__
     2    /  \__/  \
     3    \__/  \__/

    For the first 17 iterations, the cursor will be at:
    
      # | x | y
      ----------
      1 | 1 | 0
      2 | 0 | 3
      3 | 1 | 6
      4 | 0 | 9
      5 | 1 | 12
      6 | 0 | 15
      7 | 1 | 18
      8 | 0 | 21
      9 | 1 | 24
     10 | 0 | 27
     11 | 1 | 30
     12 | 0 | 33
     13 | 1 | 36
     14 | 0 | 39
     15 | 1 | 42
     16 | 0 | 45
     17 | 3 | 0      <- moves back to the first row

  */
` __
/  \\
\\__/`
  // split the hexagon into three lines
  .split('\n').forEach((line, index) => {
    // and for each line
    ;[...line].forEach((char, j) => {
      // if the cursor position (x, y) translated
      // by (index, j) is not already part of a hexagon
      // then replace it with the current (index, j) piece
      // of the hexagon
      /*
         0123
       0  __
       1 /  \
       2 \__/
       
      */
      if ('_/\\'.indexOf(a[x + index][y + j]) < 0)
        a[x + index][y + j] = char
    })
  })
  
  // `up` represents the next hexagon
  // if true, the next hexagon will be drawn attached to
  // the top right edge of the current hexagon
  if (up) {
    x -= 1
  // otherwise, it'll be drawn attached to the bottom right edge
  } else {
    x += 1
  }

  // move three columns to the right
  y += 3
  // change directions
  up = !up

  // if within the right boundary of the 51x51 matrix,
  // move back to the left edge and down 2 rows
  // and draw the next hexagon as an `up` hexagon
  if (51 - y <= 3) {
    y = 0
    x += 2
    up = true
  }

  // if hexagons > 0, then recurse and draw the next hexagon
  // otherwise, return the array (join the columns in each row, then join each row
  // by a new line)
  return --hexagons ?
    draw(hexagons, x, y, a, up)
    : a.map(d => d.join('')).join('\n')
}

var n = parseInt(prompt('Number to draw:'))
var r = draw(n, 1, 0, a, true)
document.write('<pre>' + r.replace(/\n/g, '<br>') + '</pre>')


2

红宝石120

->n{a=(1..50).map{' '*50}
n.times{|i|x=i%16*3
3.times{|j|a[47-i/16*2-x/3+j][x..x+3]=[' __ ','/  \\','\__/'][j]}}
puts a}

创建一个由50个空格组成的50个字符串的数组,然后在3行中替换4个字符以添加六边形:

" __ "
"/  \"
"\__/"

由于第一行包含空格,因此一旦绘制了六边形,我们就无法在其下方绘制另一个,因为这些空格会覆盖之前的六边形。

因此,六边形从底部到顶部以16x16菱形(扭曲的矩形)的形式添加,并从左下角到右上角倾斜。

" __ "然后,该字符串将在需要时附加\并覆盖/

取消测试程序

g=->n{
  a=(1..50).map{' '*50}              #make an array of 50 strings of 50 spaces
  n.times{|i|                        #loop through all hexagons
    x=i%16*3                         #x coordinate of top left corner of hexagon, 16 per row
    3.times{|j|                      #loop through 3 lines to print hexagon.
      a[47-i/16*2-x/3+j][x..x+3]=    #47-i/16*2 : start at the bottom and work up. each row is 2 lines high and contains 16 hexagons. x/3 : slant upwards as the row moves right. 
       [' __ ','/  \\','\__/'][j]    #These are the symbols for each of the 3 lines required for a hexagon. [x..x+3] defines which characters have to be replaced in each string.
    }      
  }
  puts a                             #print to stdout
}

N=gets.to_i
g.call(N) 

典型输出(n = 250)

这里的顶部应该有几行空白,以使总数达到50,但是我不知道是否有办法使Stackexchange格式化以包括它们。

                                              __  
                                           __/  \ 
                                        __/  \__/ 
                                     __/  \__/  \ 
                            __    __/  \__/  \__/ 
                         __/  \__/  \__/  \__/  \ 
                      __/  \__/  \__/  \__/  \__/ 
                   __/  \__/  \__/  \__/  \__/  \ 
                __/  \__/  \__/  \__/  \__/  \__/ 
             __/  \__/  \__/  \__/  \__/  \__/  \ 
          __/  \__/  \__/  \__/  \__/  \__/  \__/ 
       __/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
    __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
 __/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \ 
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/ 
\__/  \__/  \__/  \__/  \__/  \__/  \__/  \__/    
/  \__/  \__/  \__/  \__/  \__/  \__/  \__/       
\__/  \__/  \__/  \__/  \__/  \__/  \__/          
/  \__/  \__/  \__/  \__/  \__/  \__/             
\__/  \__/  \__/  \__/  \__/  \__/                
/  \__/  \__/  \__/  \__/  \__/                   
\__/  \__/  \__/  \__/  \__/                      
/  \__/  \__/  \__/  \__/                         
\__/  \__/  \__/  \__/                            
/  \__/  \__/  \__/                               
\__/  \__/  \__/                                  
/  \__/  \__/                                     
\__/  \__/                                        
/  \__/                                           
\__/                                              
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.