ASCII艺术八边形


22

给定输入整数n > 1,输出边长由n字符组成的ASCII八角形。请参阅以下示例:

n=2
 ##
#  #
#  #
 ##

n=3
  ###
 #   #
#     #
#     #
#     #
 #   #
  ###

n=4
   ####
  #    #
 #      #
#        #
#        #
#        #
#        #
 #      #
  #    #
   ####

n=5
    #####
   #     #
  #       #
 #         #
#           #
#           #
#           #
#           #
#           #
 #         #
  #       #
   #     #
    #####

and so on.

您可以将其打印到STDOUT或将其作为功能结果返回。

只要字符正确排列,任何数量的外部空格都是可以接受的。

规则和I / O

  • 输入和输出可以通过任何方便的方法给出。
  • 您可以使用任何可打印的ASCII字符来代替#(空格除外),但是“背景”字符必须为空格(ASCII 32)。
  • 完整的程序或功能都是可以接受的。
  • 禁止出现标准漏洞
  • 这是因此所有常用的高尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

1
我们可以使用不同的输出字符,还是需要保持一致?
Emigna '18年

@Emigna可以使用不同的字符。
AdmBorkBork

Answers:



11

的JavaScript(ES6),114个 106 105 104 103字节

n=>(g=x=>v=x*2>w?w-x:x,F=x=>~y?`# 
`[~x?(h=g(x--))*g(y)>0&h+v!=n|n>h+v:(y--,x=w,2)]+F(x):'')(y=w=--n*3)

在线尝试!

怎么样?

这将逐字符构建输出。

给定输入ñ,我们计算:

ñ=ñ-1个w=3ñ

对于(x,y)处的每个字符,我们计算(h,v)

h=w/2|xw/2|v=w/2|yw/2|

属于八边形的像元满足以下条件之一:

  • h=0 OR v=0)AND h+vn(在下文中红色)
  • h+v=n(在下面的橙色)

例如,当n=4(并且n=3)时:

001个02030404030201个00001个1个1个21个31个41个41个31个21个1个1个01个021个22232424232221个202031个32333434333231个303041个42434444434241个404041个42434444434241个404031个32333434333231个303021个22232424232221个20201个1个1个21个31个41个41个31个21个1个1个01个001个02030404030201个000


哇,太棒了!我认为可以简化为^ h + v > ñ ',但我不知道是否有帮助高尔夫球逻辑可言。H+vñH+v>ñ
朱塞佩

@Giuseppe如果同时测试了两个条件,则确实可以简化这种方式。但是在代码中,h v 0的情况是分开的。但是,我实际上正在测试相反的条件(n ' > h + v),它已经短了1个字节。Hv=0Hv0ñ>H+v
Arnauld

@Giuseppe您的评论促使我仔细研究了该公式,最后我以不同的方式写了一个字节,从而节省了一个字节。:)
Arnauld

1
嘿,您对评论促使我去看一下您的逻辑端口并节省了另外两个字节!Hv=0
朱塞佩

8

木炭,5字节

GH*N#

我对木炭的第一个答案!

说明:

GH*N#      //Full program
GH          //Draw a hollow polygon
   *         //with 8 sides
    N       //of side length from input
      #      //using '#' character

在线尝试!


3
对于那些喜欢冗长的木炭的人,那就是PolygonHollow(:*, InputNumber(), "#");
尼尔

5

画布15 14 12 字节

/⁸⇵╷+×+:⤢n╬┼

在这里尝试!

说明:

/             a diagonal of length n
 ⁸            the input,
  ⇵           ceiling divided by 2, (storing the remainder)
   ╷          minus one
    #×        repeat "#" that many times
      +       append that to the diagonal
       :⤢n    overlap that with its transpose
          ╬┼  quad-palindromize with the overlap being the remainder stored earlier

替代12圈


4

[R 122个 117 115字节

function(n){n=n-1
m=matrix(0,y<-3*n+1,y)
v=t(h<-(w=3*n/2)-abs(row(m)-1-w))
m[h*v&h+v-n|h+v<n]=' '
write(m,1,y,,"")}

在线尝试!

Arnauld的答案中移植逻辑,特别是在有进一步改进的情况下进行的修订。多亏了Arnauld建议反转逻辑,节省了另外2个字节!


通过相反的方式来处理-2个字节(我不能h*v&h+v-n在JS中这样做,因为&它是按位运算符;但是它在R中是一个逻辑运算符,因此可以工作)。
Arnauld

@Arnauld谢谢!
朱塞佩


3

Python 2,81个字节

a=d=n=input()-1
while a<=n:print' '*a+'#'+' #'[a==n]*(3*n-a+~a)+'#';d-=1;a-=d/n+1

在线尝试!


Python 2,75个字节

a=d=n=input()-1
while a<=n:print' '*a+`' `'[a==n]*(3*n-a+~a)`;d-=1;a-=d/n+1

在线尝试!

如果混合输出字符就可以了。


3

Powershell,91字节

param($n)($s=' '*--$n+'#'*$n+'#')
--$n..0+,0*$n+0..$n|%{' '*$_+"#$(' '*(3*$n-2*$_+2))#"}
$s

2

PowerShell107 97字节

param($n)($z=$n-1)..1+,0*$n+1..$z|%{" "*$_+"#"+($x=" "*($z-$_))+(" ","#")[!($_-$z)]*($n-2)+"$x#"}

在线尝试!

如果有便宜的方法可以逆转前半部分,那么这个答案会好很多。它先构建左半部分,然后构建核心(x #'s或空格),然后镜像左逻辑以构成右半。有趣的是,您无需复制尾随空格。

展开并说明:

param($n)
($z=$n-1)..1 + ,0*$n + 1..$z |%{  #Range that repeats 0 n times in the middle
" "*$_ + "#" +($x=" "*($z-$_)) +  #Left side
(" ","#")[!($_-$z)]*($n-2) +      #Core that swaps when it's the first or last row
"$x#"}                            #Right side which is left but backwards

2

C(clang)-DP=printf( -DF=for(i + 179 = 199180字节

i;*m="%*s%*s\n";g(n){P"%*s",n,H;F;--i;)P H;P"\n");}f(n){g(n);F;--i;)P m,i,(H,3*n-i+~i,H;F-2;i--;)P"#%*s\n",3*n-3,H;F;--i;)P m,n-i,(H,n+i+i-1,H;g(n);}

在线尝试!

取消高尔夫:

f(n){
	int i;
	printf("%*d",n,0);
	for(i=0;i<n-1;i++){
		printf("0");
	}
	printf("\n");
	for(i=1;i<n;i++){
		printf("%*d%*d\n",n-i,0,n+i+i-1,0);
	}
	for(i=0;i<n-2;i++){
		printf("0%*d\n",n+n+n-3,0);
	}
	for(i=n-1;i>0;i--){
		printf("%*d%*d\n",n-i,0,n+i+i-1,0);
	}
	printf("%*d",n,0);
	for(i=0;i<n-1;i++){
		printf("0");
	}
}

-19个字节,感谢@ceilingcat



1

Python 2,130个字节

def f(n):
 a=[' '*~-n+n*'#']
 b=[' '*(n-i-2)+'#'+' '*(n+2*i) +'#'for i in range(n-2)]
 return a+b+['#%*s'%(3*n-3,'#')]*n+b[::-1]+a

在线尝试!

在移动设备上,因此难以置信地打高尔夫球。


您可以在之后删除空格(n+2*i)
扎卡里

1

批处理,260字节

@echo off
set s=
for /l %%i in (1,1,%1)do call set s= %%s%%
echo %s% %s: =#%
call:c %1,-1,3
for /l %%i in (1,1,%1)do echo   #%s:~2%%s%%s:~2%#
call:c 3,1,%1
echo %s% %s: =#%
exit/b
:c
for /l %%i in (%*)do call echo %%s:~,%%i%%#%%s:~%%i%%%s%%%s:~%%i%%#

在每行上输出两个前导空格。说明:批处理没有字符串重复运算符,字符串切片能力有限,并且需要单独的语句来执行算术。因此,最有技巧的方法是在空格中组成一串输入长度的字符串(批处理至少可以将它们转换成#用于顶行和底行的s),然后从3到该长度的特定位置进行切片或剪切到特定位置以生成对角线(这是脚本的最后一行所实现的)。


1

红宝石,96字节

->n{[*(n-=2).step(z=n*3+2,2),*[z]*n,*z.step(n,-2)].map{|x|([?#]*2*('# '[x<=>n]*x)).center(z+2)}}

在线尝试!

还不太打高尔夫球。如果我有时间,可以打高尔夫球。


1

红色,171字节

func[n][c:(a: n - 1)* 2 + n
b: collect[loop c[keep pad/left copy"^/"c + 1]]s: 1x1 s/1: n
foreach i[1x0 1 0x1 -1x1 -1x0 -1 0x-1 1x-1][loop a[b/(s/2)/(s/1): #"#"s: s + i]]b]

在线尝试!

说明:

Red[]
f: func [ n ] [
    a: n - 1                                         ; size - 1
    c: a * 2 + n                                     ; total size of widht / height 
    b: collect [                                     ; create a block
        loop c [                                     ; composed of size - 1 rows
            keep pad/left copy "^/" c + 1            ; of empty lines of size c (and a newline)
        ]
    ]
    s: a * 1x0 + 1                                   ; starting coordinate
    foreach i [ 1x0 1 0x1 -1x1 -1x0 -1 0x-1 1x-1 ] [ ; for each offset for the 8 directions
        loop a [                                     ; repeat n - 1 times  
            b/(s/2)/(s/1): #"#"                      ; set the array at current coordinate to "#"
            s: s + i                                 ; next coordinate
        ]        
    ]
    b                                                ; return the block 
]

1

APL(Dyalog Unicode),46 字节SBCS

(' '@~5 6∊⍨1⊥⊢∘,)⌺3 3⊢<(⍉⌽⌊⊢)⍣2∘(∘.+⍨∘⍳¯2+3×⊢)

此解决方案由Adám提供-谢谢!

在线尝试!

我的(几乎)原始解决方案:

APL(Dyalog Unicode),61 字节SBCS

(((⊃∘' #'¨1+5∘=+6∘=)⊢)1⊥⊢∘,)⌺3 3⊢<(((⊖⌊⊢)⌽⌊⊢)(∘.+⍨(⍳¯2+3×⊢)))

在线尝试!

感谢Adám的帮助!

这个想法是找到部分位于正方形中的“菱形”,并应用边缘检测滤镜来“勾勒”八边形。



1
由于,您实际上不能在此处使用Classic 。而是通过根据Meta引用SBCS来计数1个字节/字符。
亚当

@Adám谢谢!我不知道如何编辑标题,您能帮我吗?
Galen Ivanov

编辑标题是什么意思?
亚当

1
此处编辑并复制。
亚当

1

Perl 5,201 197 188 187 186字节:

$a=<>;$b=3*$a-4;$c='$"x($e-$_)."#".$"x$f."#\n"';$e=($b-$a)/2+1;$d=$"x$e."#"x$a.$/;$f=$a;print$d,(map{(eval$c,$f+=2)[0]}1..$a-2),("#".$"x$b."#\n")x$a,(map{$f-=2;eval$c}reverse 1..$a-2),$d

在线尝试!

从的第一行读取八边形的大小STDIN


欢迎来到PPCG!你或许可以通过使用发现这里的技巧剃光了几个字节,并且这个职位
Mego

@Mego Yep。我使用$"代替节省了4个字节" "
内森·米尔斯

1

Perl 5,176个字节

$f=$a=<>;$b=3*$a-4;$c='$"x($e-$_)."#".$"x$f."#\n"';$e=$a-1;$d=$"x$e."#"x$a.$/;print$d,(map{(eval$c,$f+=2)[0]}1..$a-2),("#".$"x$b."#\n")x$a,(map{$f-=2;eval$c}reverse 1..$a-2),$d

基于内森·米尔斯(Nathan Mills)的上述回答(我对此没有足够的评论!)。

$e可以简化为$a-1节省6个字节; $f可以分配链;节省两个字节;不知道其他两个来自哪里!

虽然$e可以$a-1在两个位置上将其替换,但所需的额外括号表示仅收支平衡。

取消高尔夫:

$f = $a = <>;
$b = 3 * $a - 4;
$c = '$"x($e-$_)."#".$"x$f."#\n"';
$e = $a - 1;
$d = $" x $e . "#" x $a . $/;
print $d, ( map { ( eval $c, $f += 2 )[0] } 1 .. $a - 2 ),
  ( "#" . $" x $b . "#\n" ) x $a,
  ( map { $f -= 2; eval $c } reverse 1 .. $a - 2 ), $d



0

Python 3,224字节

n=int(input())
z=" "*(n-1)+"#"*n+" "*(n-1)
print(z)
for i in range(n-2):print(" "*(n-i-2)+"#"+" "*(i*2+n)+"#")
print((("#"+" "*(n*3-4)+"#\n")*n)[:-1])
for i in range(n-3,-1,-1):print(" "*(n-i-2)+"#"+" "*(i*2+n)+"#")
print(z)

在线尝试!


0

Perl 5中,170个 168 166字节

$a=<>-1;$\="#\n";print$x=$_=$"x$a."#"x$a;if(s/^( *)  #*/$1 #  $1 /){print}while (s/ #/#  /){print}$z=$_;for(1..$a){print$_=$z}while(s/#  (\s{$a})/ #$1/){print}print$x

正则表达式的神奇作用。仅需要“ if”来处理n = 2的病理情况,否则将输出类似以下内容:

 ##
 ##
#  #
 ##

可能可以将其编码掉。

我认为通过创建一个到中点的字符串然后反转它可能会获得更多的收益。当然,如果n为奇数,则我们需要插入/删除一个额外的空格(或使用Thin-space:p)。

不打高尔夫球

$a = <> -1;                          # Subtracting one is very useful! 
$\ = "#\n";                          # Every line ends with a '#' let perl provide.  
$x=$_ = " " x $a. "#" x $a;          # The horiz line (one short)  
print;                               # print it plus the extra #
if(s/^( *)  #*/$1 #  $1 /){print}    # create a hole and remove a leading space(if n=2 this fails)
while (s/ #/#  /){                   # make the hole bigger      
    print;                           # and print (with a trailing #)
}
$z=$_;                               # store $_ for later use
for (1 .. $a) {                      # nice that we don't have to do 2..$a but not golf-nice  
  $_ =$z;                            # restore $_ (we could use $z but since we have
  print;                             # to restore somewhere, doing  it here saves us bytes)
}
while (s/#  (\s{$a})/ #$1/){         # now move the # to the right and reduce the trailing spaces  
  print;
}
print $x;                            # and finish...

我认为,除了重大的变化(例如推入$@并最终打印出来)以外,还可以再打些高尔夫球。

[ ..在两种情况下,分配前先打高尔夫球并移动打印件,节省分号。]


保存了20个字节,对一些指令TIO进行了重新排序,为什么\s还不只是最后一个正则表达式中的空格
Nahuel Fouilleul


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.