Octágonos de arte ASCII


22

Dado un entero de entrada n > 1, genera un octágono de arte ASCII con longitudes laterales compuestas de ncaracteres. Ver ejemplos a continuación:

n=2
 ##
#  #
#  #
 ##

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

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

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

and so on.

Puede imprimirlo en STDOUT o devolverlo como resultado de una función.

Cualquier cantidad de espacios en blanco extraños es aceptable, siempre y cuando los caracteres se alineen apropiadamente.

Reglas y E / S

  • La entrada y salida se pueden dar por cualquier método conveniente .
  • Puede usar cualquier carácter ASCII imprimible en lugar del #(excepto el espacio), pero el carácter "de fondo" debe ser el espacio (ASCII 32).
  • Un programa completo o una función son aceptables.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

1
¿Podemos usar diferentes caracteres de salida o debe ser coherente?
Emigna

@Emigna Diferentes personajes están bien.
AdmBorkBork

Respuestas:


22

05AB1E , 3 bytes

7ÝΛ

Pruébalo en línea!

Explicación

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

Vea esta respuesta para comprender el lienzo 05AB1E.


¿Seguramente esto debería ser de 5 bytes? O los desafíos de golf de código ven los bytes y los caracteres como intercambiables
Doug

3
@Doug: Son 3 bytes en la página de códigos de
05ab1e

Oh genial! Gracias por el enlace de documentos!
Doug

> :( damnit, adnan
solo ASCII

11

JavaScript (ES6), 114 106 105 104 103 bytes

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)

Pruébalo en línea!

¿Cómo?

Esto construye la salida carácter por carácter.

Dada la entrada , calculamos:norte

norte=norte-1w=3norte

Para cada carácter en , calculamos :(X,y)(h,v)

h=w/ /2-El |X-w/ /2El |v=w/ /2-El |y-w/ /2El |

Las celdas que pertenecen al octágono satisfacen una de las siguientes condiciones:

  • ( h=0 0 OR v=0 0 ) Y h+vnorte (en rojo a continuación)
  • h+v=norte (en naranja debajo)

Por ejemplo, con norte=4 4 (y norte=3 ):

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


Wow, esto es asombroso! Creo que puede simplificarse a h + v > n , aunque no estoy seguro de si eso ayuda a la lógica del golf. h+vnorteh+v>norte
Giuseppe

@Giuseppe De hecho, podría simplificarse de esa manera si se probaran ambas condiciones. Pero en el código, los casos y h v 0 están separados. Sin embargo, en realidad estoy probando la condición opuesta ( n ' > h + v ), que ya es 1 byte más corta. hv=0 0hv0 0norte>h+v
Arnauld

@Giuseppe Su comentario me llevó a echar un vistazo más de cerca a la fórmula y finalmente guardé un byte al escribirlo un poco diferente. :)
Arnauld

1
heh, bueno, tu comentario sobre me llevó a mirar mi puerto de tu lógica y guardar otro par de bytes. hv=0 0
Giuseppe

8

Carbón de leña , 5 bytes

GH*N#

Mi primera respuesta con carbón!

Explicación:

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

Pruébalo en línea!


3
Para aquellos que prefieren carbón vegetal detallado, eso es PolygonHollow(:*, InputNumber(), "#");.
Neil

5

Lienzo , 15 14 12 bytes

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

Pruébalo aquí!

Explicació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

Alternativa de 12 bytes .


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

Pruébalo en línea!

Transmite la lógica de la respuesta de Arnauld , específicamente esta revisión en caso de que haya más mejoras. ¡Otros 2 bytes guardados gracias a la sugerencia de Arnauld de invertir la lógica!


-2 bytes haciéndolo al revés (no puedo hacerlo h*v&h+v-nen JS porque &es un operador bit a bit; pero es lógico en R, por lo que funciona).
Arnauld

@Arnauld gracias!
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 bytes

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

Pruébalo en línea!

Si hubiera una forma barata de revertir la primera mitad, esta respuesta se sentiría mucho mejor. Construye la mitad izquierda, luego el núcleo (que es x #'so espacios), luego refleja la lógica de la izquierda para hacer la derecha. Dato curioso, no necesita copiar sobre espacios en blanco finales.

Desenrollado y explicado:

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

Pruébalo en línea!

Sin golf:

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 gracias a @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

Pruébalo en línea!

En dispositivos móviles, por lo que no es increíblemente golf.


Puede eliminar el espacio después (n+2*i).
Zacharý

1

Lote, 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%%#

Emite dos espacios iniciales en cada línea. Explicación: Batch no tiene operador de repetición de cadenas, capacidad limitada de corte de cadenas y requiere declaraciones separadas para realizar operaciones aritméticas. Por lo tanto, era más divertido hacer una cadena de la longitud de entrada en espacios (Batch al menos puede traducirlos a #s para las líneas superior e inferior) y luego cortar desde o hacia una posición específica que varía de 3 a la longitud para generar las diagonales (esto es lo que logra la última línea del guión).


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

Pruébalo en línea!

No muy golfizado todavía. Podría jugar golf si encuentro el tiempo.


1

Rojo , 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]

Pruébalo en línea!

Explicación:

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

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

Esta solución fue proporcionada por Adám, ¡gracias!

Pruébalo en línea!

Mi (casi) solución original:

APL (Dyalog Unicode) , SBCS de 61 bytes

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

Pruébalo en línea!

¡Gracias a Adám por su ayuda!

La idea es encontrar el "diamante" que se encuentra en parte en el cuadrado y aplicar un filtro de detección de bordes para "delinear" el octagono.



1
Realmente no puedes usar Classic aquí debido a . Más bien cuente 1 byte / char refiriéndose a SBCS según Meta .
Adám

@ Adám ¡Gracias! No sé cómo editar el encabezado, ¿puedes hacerlo por mí?
Galen Ivanov el

¿Qué quieres decir con editar el encabezado?
Adám

1
Edita y copia desde aquí .
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

Pruébalo en línea!

Lee el tamaño del octágono desde la primera línea de STDIN.


Bienvenido a PPCG! Probablemente pueda reducir algunos bytes aquí y allá utilizando los trucos que se encuentran en esta publicación .
Mego

@Mego Sí. Pude guardar 4 bytes usando en $"lugar de " ".
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

Basado en la respuesta anterior de Nathan Mills (¡que no tengo suficiente representante para comentar!

$ese puede simplificar para $a-1ahorrar 6 bytes; $fse puede asignar en cadena; guardar dos bytes; ¡No estoy seguro de dónde vienen los otros dos!

Si bien $epuede reemplazarse $a-1en los dos lugares donde ocurre, los corchetes adicionales necesarios significan que esto solo se iguala.

Sin golf:

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

Pruébalo en línea!


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

Esto funciona por la magia de la expresión regular. El "si" solo es necesario para tratar el caso patológico de n = 2, que de otro modo genera algo como:

 ##
 ##
#  #
 ##

probablemente esto se puede codificar.

Creo que puede haber mucho más que ganar creando una cadena hasta el punto medio y luego invirtiéndola. Por supuesto, entonces necesitamos insertar / eliminar un espacio extra si n es impar (o usar el espacio delgado: p).

Sin golf

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

Creo que esto probablemente se pueda jugar un poco más, aparte de cambios significativos como empujar $@e imprimir eso al final.

[Espacios de golf alrededor ..y movió la impresión antes de asignar en dos casos, ahorrando en punto y coma.]


ahorró 20 bytes reordenando algunas instrucciones TIO , por qué \sy no solo un espacio en la última expresión regular
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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.