Hexplosive ASCII艺术挑战


20

在策略游戏“ Hexplode”中,玩家轮流将令牌放置在六角形板上。一旦令牌的数量等于相邻图块的数量,该图块h就会爆炸,并将其上的所有tokes移至周围的邻居。您可以在此处在线玩游戏。

我喜欢这个游戏,但有时很难确切知道在特定图块上有多少令牌。我一直在计算邻居的数量。如果我有ASCII艺术来帮助我记住每个图块上有多少令牌,那将真的很方便。

您需要编写一个程序或函数,将正整数作为输入,并生成大小为N的六边形的ASCII表示形式。每个图块将是该图块具有的邻居数。由于1是一个奇怪的极端情况,邻居数为零,因此您只需要处理大于1的输入。

您可以采用任何合理的格式(例如STDIN,函数参数,命令行参数,来自文件等)的数字。输出也可以采用任何合理的格式,例如打印至STDOUT,写入文件,返回字符串列表,换行符分隔的字符串等。

这是前5个输入的一些示例输出:

2)

 3 3
3 6 3
 3 3


3)

  3 4 3
 4 6 6 4
3 6 6 6 3
 4 6 6 4
  3 4 3


4)

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

5)

    3 4 4 4 3
   4 6 6 6 6 4
  4 6 6 6 6 6 4
 4 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 4
  4 6 6 6 6 6 4
   4 6 6 6 6 4
    3 4 4 4 3

6)

     3 4 4 4 4 3
    4 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
 4 6 6 6 6 6 6 6 6 4
3 6 6 6 6 6 6 6 6 6 3
 4 6 6 6 6 6 6 6 6 4
  4 6 6 6 6 6 6 6 4
   4 6 6 6 6 6 6 4
    4 6 6 6 6 6 4
     3 4 4 4 4 3

并且模式以相似的方式继续。像往常一样,存在标准漏洞,并且字节数最少的答案将成为赢家!

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

# Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

# Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


1
相关的(但是询问过程而不是邻居的数目)。
trichoplax

1
为了这个挑战,我很想学六角形。;)
Kevin Cruijssen

Answers:


11

MATL39 37字节

4*3-:!G:+o~YRtP*!tPw4LY)vtI5&lZ+47+*c

在线尝试!验证所有测试用例

说明

我再次使用卷积!

考虑输入n = 3。该代码首先通过广播将列向量添加到行向量来构建大小为4*n-3× 的矩阵。这意味着计算所有成对加法的2D数组数组:n[1; 2; ...; 9][1, 2, 3]

 2  3  4
 3  4  5
 4  5  6
 5  6  7
 6  7  8
 7  8  9
 8  9 10
 9 10 11
10 11 12

用棋盘格图案替换偶数1和奇数0

1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

这将用于生成六边形网格(的一部分)。一个代表网格中的点,一个零代表空格。

通过将矩阵的主“对角线”上方的所有条目清零,可以删除右上角:

1 0 0
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1
0 1 0
1 0 1

在此矩阵上乘以元素本身的垂直翻转版本,将它逐个元素地相乘也会删除右下角。转置后给出

1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

这开始看起来像六角形。使用对称性,将网格扩展为产生上半部分:

0 0 1 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 1 0 0

现在,我们需要用邻居数替换等于1的每个条目。为此,我们使用具有3×5邻域的卷积(也就是说,内核是3×5的1的矩阵)。结果,

2 3 4 5 5 5 4 3 2
4 5 7 7 8 7 7 5 4
4 6 7 8 7 8 7 6 4
4 5 7 7 8 7 7 5 4
2 3 4 5 5 5 4 3 2

有两个问题(稍后将解决):

  1. 这些值已针对所有位置进行了计算,而我们只需要在零一网格中的位置上使用它们即可。
  2. 对于这些位置中的每个位置,邻居计数都包括该点本身,因此其偏移量为1

该代码现在添加47到每个计算值。这相当于减去1以解决问题(2),然后加上48(ASCII为'0'),这将每个数字转换为其对应字符的代码点。

然后,将所得矩阵乘以零一网格的副本。这解决了上面的问题(1),使不属于六边形网格的点再次等于零:

 0  0 51  0 52  0 51  0  0
 0 52  0 54  0 54  0 52  0
51  0 54  0 54  0 54  0 51
 0 52  0 54  0 54  0 52  0
 0  0 51  0 52  0 51  0  0

最后,此数字数组转换为char数组。零个字符显示为空格,它给出最终结果:

  3 4 3  
 4 6 6 4 
3 6 6 6 3
 4 6 6 4 
  3 4 3  

15

的JavaScript(ES6),118个 117字节

n=>[...Array(m=n+--n)].map((_,i,a)=>a.map((_,j)=>(k=j-(i>n?i-n:n-i))<0?``:k&&++j<m?i/2%n?6:4:3+!i%n).join` `).join`\n`

其中\n代表文字换行符。说明:假设n=4。我们从以下以空格分隔的数字正方形开始:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

|n-i| 0s个被删除,但空格保留:

   0 0 0 0
  0 0 0 0 0
 0 0 0 0 0 0
0 0 0 0 0 0 0
 0 0 0 0 0 0
  0 0 0 0 0
   0 0 0 0

瞬间六角!然后0通过检查我们是在第一行还是最后一行和/或列上,就可以计算出适当的值来代替每个值。编辑:由于@Arnauld,节省了1个字节。


使用您的一些公式,我得出了一个107字节的版本,带有/ console.log():n=>{for(i=n+--n;i--;)console.log(' '.repeat(l=i>n?i-n:n-i)+(j=3+!l%n)+` ${l-n?6:4}`.repeat(2*n-l-1)+' '+j)}
Arnauld

@Arna我要那样3+!i%n
尼尔

7

Python 2,125 123字节

def h(n):m=n-1;t=[' '*(m-r)+' '.join(('46'[r>0]*(r+m-1)).join('34'[r%m>0]*2))for r in range(n)];print'\n'.join(t+t[-2::-1])

测试在ideone上

从顶部一直延伸到中间的行,for r in range(n)构造字符串:
-制作两个角或两个边缘'34'[r%m>0]*2
-通过重复'6''4',将它们连接起来'46'[r>0]*(r+m-1);
-通过连接角和边缘' '
-以空格开头' '*(m-r)

然后将其打印出来,并将其反映在中间的行中,并用新行连接起来, print'\n'.join(t+t[-2::-1])


4

Python 2,96字节

n=input();m=n-1
while n+m:n-=1;j=abs(n);c='34'[0<j<m];print' '*j+c+' '+'46  '[j<m::2]*(2*m+~j)+c

这看起来很凌乱,有点打高尔夫球。


3

Java中,375个 363 361 339 329 317 293字节

interface J{static void main(String[]r){int i=0,k,h=Integer.decode(r[0]),a=1,l,n=0;for(;i++<h*2-1;n+=a){if(n==h-1)a=-1;String s="";for(k=0;k<n+h;k++,s+=" ")s+=n==0?k==0||k==n+h-1?3:4:k!=0&&k!=n+h-1?6:n==h-1?3:4;l=(h*4-3-s.trim().length())/2;System.out.printf((l==0?"%":"%"+l)+"s%s\n","",s);}}}

不打高尔夫球

interface J {
    static void main(String[] r) {
        int i = 0, k, h = Integer.decode(r[0]), a = 1, l, n = 0;
        for (; i++ < h * 2 - 1; n += a) {
            if (n == h - 1) {
                a = -1;
            }
            String s = "";
            for (k = 0; k < n + h; k++, s += " ") {
                s += n == 0 ? k == 0 || k == n + h - 1 ? 3 : 4 : k != 0 && k != n + h - 1 ? 6 : n == h - 1 ? 3 : 4;
            }
            l = (h * 4 - 3 - s.trim().length()) / 2;
            System.out.printf((l == 0 ? "%" : "%" + l) + "s%s\n", "", s);
        }
    }
}

用法

$ java J 5
    3 4 4 4 3     
   4 6 6 6 6 4    
  4 6 6 6 6 6 4   
 4 6 6 6 6 6 6 4  
3 6 6 6 6 6 6 6 3 
 4 6 6 6 6 6 6 4  
  4 6 6 6 6 6 4   
   4 6 6 6 6 4    
    3 4 4 4 3

我敢肯定,可怕的嵌套if-else块可以重写为较小的块,但目前无法确定。任何建议,欢迎:-)

更新资料

  • 遵循Kevin Cruijssen的建议,并使用解码而不是parseInt。
  • 通过使用三元运算符重写一些if。
  • 更多三元运算符。
  • 摩尔三元运算符!我想我创造了一个怪物!
  • 重写有关打印的if-else块。

1
我没有仔细研究您使用的方法,但是您当前代码的一些小技巧:Integer.parseInt可以使用Integer.decodel=(h*4-3-s.trim().length())/2;if(l==0)可以打高尔夫球if((l=(h*4-3-s.trim().length())/2)==0)。另外,仅发布不带类的方法也是完全可以接受的(除非问题另有说明),所以void f(int i){...use i...}代替interface J{static void main(String[]r){...i=Integer.decode(r[0])...use i...},应该也可以节省很多字节。当我有更多时间时,我会进一步看。
凯文·克鲁伊森

@KevinCruijssen:谢谢您的建议。l=(h*4-3-s.trim().length())/2;if(l==0)的长度实际上与相同if((l=(h*4-3-s.trim().length())/2)==0)
Master_ex

2

05AB1E,44个字节

FN_i4ë6}ð«¹ÍN+×ðìN_N¹<Q~i3ë4}.ø¹<N-ð×ì})¦«»

说明

由于六边形的顶部和底部被镜像,因此我们只需要生成上部。
因此,对于X的输入,我们需要生成X行。那就是主循环的作用。

F                                        }

然后我们做行的中心部分。第一行
4,其余的是6(因为我们只做上部)。
我们将这个数字与一个空格连接起来,因为模式将需要数字之间的间隔。

N_i4ë6}ð«

然后,我们将此字符串重复X-2 + N次,其中N是当前行0索引的位置,并在左侧添加一个空格字符。

¹ÍN+×ðì

在此之后,该死了。他们将3的第一和最后一排和4对中间行。

N_N¹<Q~i3ë4}.ø

现在,我们需要通过在每行的前面添加空格来确保行正确对齐。添加的空格数将为X-1-N

¹<N-ð×ì

现在我们已经完成了网格的上部,我们将行添加到列表中,创建一个反向副本并从该副本中删除第一项(因为我们只需要一次中心行),然后将这两个列表合并在一起,打印。

)¦«»

在线尝试!

其他解决方案,也是44个字节:

ÍÅ10.øvN_i4ë6}ð«¹ÍN+×ðìyi4ë3}.ø¹<N-ð×ì})¦«»

2

Ruby,87个字节

匿名函数将n作为参数并返回字符串数组。

->n{(1-n..n-=1).map{|i|j=i.abs
" "*j+(e=j%n>0?"4 ":"3 ")+["6 ","4 "][j/n]*(2*n-1-j)+e}}

取消测试程序

通过标准输入。将整个形状写入stdout。很自我解释。

f=->n{
  (1-n..n-=1).map{|i|            #reduce n by 1 and iterate i from -n to n
    j=i.abs;                     #absolute magnitude of i
    " "*j+                       #j spaces +
    (e=j%n>0?"4 ":"3 ")+         #start the string with 3 or 4 +
    ["6 ","4 "][j/n]*(2*n-1-j)+  #2*n-1-j 6's or 4`s as appropriate +
    e                            #end the string with another 3 or 4
  }
}

puts f[gets.to_i]

1

V,60字节

Àé x@aA4 xr3^.òhYpXa 6^òkyHç^/:m0
Pç 3.*6/^r4$.
òÍ6 4./6

在线尝试!

这真的太长了。这是一个十六进制转储,因为其中包含不可打印的字符:

0000000: c0e9 2078 4061 4134 201b 7872 335e 2ef2  .. x@aA4 .xr3^..
0000010: 6859 7058 6120 361b 5ef2 6b79 48e7 5e2f  hYpXa 6.^.kyH.^/
0000020: 3a6d 300a 50e7 2033 2e2a 362f 5e72 3424  :m0.P. 3.*6/^r4$
0000030: 2e0a f2cd 3620 9334 852e 2f36            ....6 .4../6

1

球拍,487字节

(λ(n c e o)(let((sp(append(range(- n 1)-1 -1)(reverse(range(- n 1)0 -1))))
(mm(append(range(- n 2)(-(+ n(- n 1))2))(range(-(+ n(- n 1))2)(-(- n 1)2)-1)))
(r""))(for((i sp)(j mm))(define str"")(for((ss i))(set! str(string-append str" ")))
(set! str(string-append str(if(or(= i 0)(= i(- n 1))(= i(* 2(- n 1))))c e)" "))
(for((jj j))(set! str(string-append str(if(= j(- n 2))e o)" ")))(set! r(if(or(= i 0)
(= i(- n 1))(= i(* 2(- n 1))))c e))(set! str(string-append str r))(displayln str))))

测试:

(f 4 "3" "4" "6") 

   3 4 4 3
  4 6 6 6 4
 4 6 6 6 6 4
3 6 6 6 6 6 3
 4 6 6 6 6 4
  4 6 6 6 4
   3 4 4 3

(f 5 "o" "*" "-") 

    o * * * o
   * - - - - *
  * - - - - - *
 * - - - - - - *
o - - - - - - - o
 * - - - - - - *
  * - - - - - *
   * - - - - *
    o * * * o

详细版本:

(define(f1 n c e o)
  (let ((sp(append(range(sub1 n) -1 -1)
                  (reverse(range(sub1 n) 0 -1))))
        (mm(append(range(- n 2)(-(+ n(sub1 n)) 2))
                  (range(-(+ n(sub1 n)) 2)(-(sub1 n)2) -1) ))
        (r ""))
    (for((i sp)(j mm))
      (define str "")
      (for((ss i))(set! str(string-append str " ")))
      (set! str(string-append str
                              (if(or(= i 0)(= i(sub1 n))
                                    (= i(* 2(sub1 n)))) c e)
                              " "))
      (for((jj j))
        (set! str(string-append str
                                (if(= j(- n 2)) e o)
                                " ")))
      (set! r(if(or(= i 0)
                   (= i(sub1 n))
                   (= i(* 2(sub1 n)))) c e))
      (set! str(string-append str r))
      (displayln str))))
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.