ASCII Art Achtecke


22

Geben Sie bei einer gegebenen Ganzzahl n > 1ein ASCII-Achteck mit Seitenlängen aus, die aus nZeichen bestehen. Siehe Beispiele unten:

n=2
 ##
#  #
#  #
 ##

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

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

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

and so on.

Sie können es an STDOUT drucken oder als Funktionsergebnis zurückgeben.

Beliebige Leerzeichen sind zulässig, sofern die Zeichen richtig ausgerichtet sind.

Regeln und I / O

  • Die Ein- und Ausgabe kann auf jede bequeme Weise erfolgen .
  • Sie können anstelle von #(außer Leerzeichen) ein beliebiges druckbares ASCII-Zeichen verwenden , das "Hintergrund" -Zeichen muss jedoch ein Leerzeichen sein (ASCII 32).
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig.
  • Standardlücken sind verboten.
  • Dies ist daher gelten alle üblichen Golfregeln, und der kürzeste Code (in Byte) gewinnt.

1
Können wir verschiedene Ausgabezeichen verwenden oder muss es konsistent sein?
Emigna

@Emigna Verschiedene Charaktere sind in Ordnung.
AdmBorkBork

Antworten:


22

05AB1E , 3 Bytes

7ÝΛ

Probieren Sie es online!

Erläuterung

      # implicit input as length
      # implicit input as string to print
7Ý    # range [0...7] as directions
  Λ   # canvas print

Sehen Sie sich diese Antwort an, um die Leinwand 05AB1E zu verstehen.


Das sollten doch 5 Bytes sein? Oder Code Golf Herausforderungen sehen Bytes und Zeichen als austauschbar
Doug

3
@ Doug: Es ist 3 Bytes in 05ab1e Codepage
Emigna

Oh cool! Danke für den docs Link!
Doug

> :( verdammt, adnan
ASCII

11

JavaScript (ES6), 114 106 105 104 103 Byte

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)

Probieren Sie es online!

Wie?

Dies baut die Ausgabe zeichenweise auf.

Mit der Eingabe n berechnen wir:

n=n1w=3n

Für jedes Zeichen bei (x,y) berechnen wir (h,v) :

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

Die zum Achteck gehörenden Zellen erfüllen eine der folgenden Bedingungen:

  • ( h=0 ODER v=0 ) UND h+vn (in rot unten)
  • h+v=n (in orange unten)

Zum Beispiel mit n=4 (und n=3 ):

(0,0)(1,0)(2,0)(3,0)(4,0)(4,0)(3,0)(2,0)(1,0)(0,0)(0,1)(1,1)(2,1)(3,1)(4,1)(4,1)(3,1)(2,1)(1,1)(0,1)(0,2)(1,2)(2,2)(3,2)(4,2)(4,2)(3,2)(2,2)(1,2)(0,2)(0,3)(1,3)(2,3)(3,3)(4,3)(4,3)(3,3)(2,3)(1,3)(0,3)(0,4)(1,4)(2,4)(3,4)(4,4)(4,4)(3,4)(2,4)(1,4)(0,4)(0,4)(1,4)(2,4)(3,4)(4,4)(4,4)(3,4)(2,4)(1,4)(0,4)(0,3)(1,3)(2,3)(3,3)(4,3)(4,3)(3,3)(2,3)(1,3)(0,3)(0,2)(1,2)(2,2)(3,2)(4,2)(4,2)(3,2)(2,2)(1,2)(0,2)(0,1)(1,1)(2,1)(3,1)(4,1)(4,1)(3,1)(2,1)(1,1)(0,1)(0,0)(1,0)(2,0)(3,0)(4,0)(4,0)(3,0)(2,0)(1,0)(0,0)


Wow, das ist großartig! Ich denke, kann zu h + v > n ' vereinfacht werden , obwohl ich nicht sicher bin, ob das der Golflogik überhaupt hilft. h+vnh+v>n
Giuseppe

@ Giuseppe Es könnte in der Tat so vereinfacht werden, wenn beide Bedingungen getestet würden. Im Code werden jedoch die Fälle und h v 0 getrennt. Tatsächlich teste ich jedoch die gegenteilige Bedingung ( n > h + v ), die bereits 1 Byte kürzer ist. hv=0hv0n>h+v
Arnauld

@ Giuseppe Ihr Kommentar hat mich dazu veranlasst, mir die Formel genauer anzuschauen, und ich habe endlich ein Byte gespeichert, indem ich es etwas anders geschrieben habe. :)
Arnauld

1
Ihr Kommentar zu hat mich dazu veranlasst, meinen Port Ihrer Logik zu überprüfen und ein paar weitere Bytes zu speichern! hv=0
Giuseppe

8

Kohle , 5 Bytes

GH*N#

Meine erste Antwort mit Holzkohle!

Erläuterung:

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

Probieren Sie es online!


3
Für diejenigen, die verbose Holzkohle bevorzugen, ist das PolygonHollow(:*, InputNumber(), "#");.
Neil

5

Canvas , 15 14 12 Bytes

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

Probieren Sie es hier aus!

Erläuterung:

/             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

Alternative 12-Byte .


4

R , 122 117 115 Bytes

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,,"")}

Probieren Sie es online!

Portiert die Logik aus Arnauld's Antwort , speziell diese Überarbeitung, falls es weitere Verbesserungen gibt. Weitere 2 Bytes gespart dank Arnauld's Vorschlag, die Logik umzukehren!


-2 Bytes, indem Sie es umgekehrt machen (ich kann es h*v&h+v-nin JS nicht tun, weil &es ein bitweiser Operator ist; aber es ist ein logischer in R, damit das funktioniert).
Arnauld

@ Arnauld danke!
Giuseppe



3

Powershell, 91 Bytes

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

2

PowerShell , 107 97 Byte

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

Probieren Sie es online!

Wenn es einen billigen Weg gäbe, die erste Hälfte umzukehren, würde sich diese Antwort viel besser anfühlen. Es bildet die linke Hälfte, dann den Kern (entweder x #'soder Leerzeichen) und spiegelt dann die Logik der linken Seite, um die rechte zu bilden. Unterhaltsame Tatsache, Sie müssen nicht über den nachgestellten Leerraum kopieren.

Abgerollt und erklärt:

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 = 199 180 Bytes

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);}

Probieren Sie es online!

Ungolfed:

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 Bytes dank @ceilingcat



1

Python 2 , 130 Bytes

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

Probieren Sie es online!

Auf dem Handy also nicht unglaublich golfen.


Sie können das Leerzeichen danach entfernen (n+2*i).
Zacharý

1

Batch, 260 Bytes

@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%%#

Gibt zwei führende Leerzeichen in jeder Zeile aus. Erläuterung: Batch verfügt über keinen Operator für die Zeichenfolgenwiederholung, eine eingeschränkte Funktion zum Schneiden von Zeichenfolgen und erfordert separate Anweisungen, um eine Arithmetik auszuführen. Es war daher am besten, eine Zeichenfolge mit der eingegebenen Länge in Leerzeichen zu bilden (Batch kann diese mindestens in #s für die obere und untere Zeile übersetzen) und dann von oder zu einer bestimmten Position im Bereich von 3 bis zur Länge zu schneiden, um die Diagonalen zu generieren (Dies ist, was die letzte Zeile des Skripts erreicht).


1

Ruby , 96 Bytes

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

Probieren Sie es online!

Noch nicht sehr gut gespielt. Könnte Golf spielen, wenn ich die Zeit finde.


1

Rot , 171 Bytes

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]

Probieren Sie es online!

Erläuterung:

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 Byte SBCS

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

Diese Lösung wurde von Adám zur Verfügung gestellt - danke!

Probieren Sie es online!

Meine (fast) originelle Lösung:

APL (Dyalog Unicode) , 61 Byte SBCS

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

Probieren Sie es online!

Vielen Dank an Adám für seine Hilfe!

Die Idee ist, den "Diamanten" zu finden, der teilweise im Quadrat liegt, und einen Kantenerkennungsfilter anzuwenden, um das Oktagon zu "umreißen".



1
Sie können Classic hier nicht verwenden, weil . Zählen Sie lieber 1 Byte / Zeichen, indem Sie sich auf SBCS gemäß Meta beziehen .
Adám

@ Adám Danke! Ich weiß nicht, wie ich den Header bearbeiten soll. Können Sie das für mich tun?
Galen Ivanov

Was meinst du mit Bearbeiten des Headers?
Adám

1
Bearbeiten und kopieren Sie von hier .
Adám

1

Perl 5, 201 197 188 187 186 Bytes:

$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

Probieren Sie es online!

Liest die Größe des Achtecks ​​aus der ersten Zeile von STDIN.


Willkommen bei PPCG! Sie können wahrscheinlich hier und da ein paar Bytes abschneiden, indem Sie die in diesem Beitrag beschriebenen Tricks anwenden .
Mego

@ Mego Yep. Ich konnte 4 Bytes sparen, indem ich $"anstelle von " ".
Nathan Mills

1

Perl 5, 176 Bytes

$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

Basierend auf der obigen Antwort von Nathan Mills (zu der ich nicht genug Repräsentanten habe, um sie zu kommentieren!).

$ekann vereinfacht werden, $a-1um 6 Bytes zu sparen; $fkann einer Kette zugeordnet werden; Speichern von zwei Bytes; Ich bin mir nicht sicher, wo die anderen beiden herkommen!

Während an den beiden Stellen, an denen es vorkommt, $eersetzt werden kann $a-1, bedeutet die zusätzliche Klammer, dass dies nur die Gewinnschwelle erreicht.

Ungolfed:

$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 Bytes

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)

Probieren Sie es online!


0

Perl 5, 170 168 166 Bytes

$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

Dies funktioniert durch die Magie von Regex. Das "if" wird nur benötigt, um den pathologischen Fall von n = 2 zu behandeln, der ansonsten etwa Folgendes ausgibt:

 ##
 ##
#  #
 ##

wahrscheinlich kann dies weg codiert werden.

Ich denke, dass es noch viel mehr zu gewinnen gibt, wenn Sie eine Zeichenfolge bis zur Mitte erstellen und dann umkehren. Natürlich müssen wir dann ein zusätzliches Leerzeichen einfügen / löschen, wenn n ungerade ist (oder Thin-Space verwenden: p).

Ungolfed

$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...

Ich denke, das kann wahrscheinlich ein bisschen mehr gespielt werden, abgesehen von wesentlichen Änderungen wie dem Aufschieben $@und Drucken am Ende.

[Vor dem Zuweisen wurden ..in zwei Fällen Leerzeichen gesetzt und der Druck verschoben, wobei Semikolons gespart wurden.]


20 Bytes gespart, um einige Anweisungen neu zu ordnen TIO , warum \sund nicht nur ein Leerzeichen in der letzten Regex
Nahuel Fouilleul


0

Perl 5, 98 Bytes

$_=2x$_.1x$_.$/;s/2//;s/.$/ #/,y/1/ /while$a.=$_,$b=$_.$b,s/2[#1]/# /;$_=$a.$_ x("@F"-2).$b;y/2/ /

TIO

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.