Ottagoni d'arte ASCII


22

Dato un intero di input n > 1, genera un ottagono di arte ASCII con lunghezze laterali composte da ncaratteri. Vedi esempi di seguito:

n=2
 ##
#  #
#  #
 ##

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

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

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

and so on.

È possibile stamparlo su STDOUT o restituirlo come risultato di una funzione.

Qualsiasi quantità di spazio bianco estraneo è accettabile, purché i personaggi siano allineati in modo appropriato.

Regole e I / O

  • Input e output possono essere forniti con qualsiasi metodo conveniente .
  • È possibile utilizzare qualsiasi carattere ASCII stampabile anziché #(tranne lo spazio), ma il carattere "sfondo" deve essere spazio (ASCII 32).
  • È accettabile un programma completo o una funzione.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

1
Possiamo usare caratteri di output diversi o deve essere coerente?
Emigna,

@Emigna Diversi personaggi vanno bene.
AdmBorkBork,

Risposte:


22

05AB1E , 3 byte

7ÝΛ

Provalo online!

Spiegazione

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

Vedi questa risposta per capire la tela 05AB1E.


Sicuramente questo dovrebbe essere di 5 byte? Oppure le sfide del codice golf vedono byte e caratteri come intercambiabili
Doug

3
@Doug: sono 3 byte nella codepage di
05ab1e

Oh, fico! Grazie per il link alla documentazione!
Doug,

> :( dannazione, adnan
solo ASCII l'

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)

Provalo online!

Come?

Questo crea il carattere di output per carattere.

Dato l'ingresso n , calcoliamo:

n'=n-1w=3n'

Per ogni carattere in (X,y) , calcoliamo (h,v) :

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

Le cellule appartenenti all'ottagono soddisfano una delle seguenti condizioni:

  • ( h=0 OR v=0 ) AND h+vn' (in rosso sotto)
  • h+v=n (in arancione sotto)

Ad esempio, con n=4 (e 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, è fantastico! Penso che possa essere semplificato in h + v > n , anche se non sono sicuro che ciò aiuti la logica del golf. h+vn'h+v>n'
Giuseppe,

@Giuseppe Potrebbe davvero essere semplificato in questo modo se entrambe le condizioni fossero testate. Ma nel codice, i casi e h v 0 sono separati. Tuttavia, sto effettivamente testando la condizione opposta ( n > h + v ), che è già più corta di 1 byte. hv=0hv0n'>h+v
Arnauld,

@Giuseppe Il tuo commento mi ha spinto a dare un'occhiata più da vicino alla formula e alla fine ho salvato un byte scrivendolo in modo leggermente diverso. :)
Arnauld,

1
eh, beh, il tuo commento su mi ha spinto a guardare la mia porta della tua logica e salvare un altro paio di byte! hv=0
Giuseppe,

8

Carbone , 5 byte

GH*N#

La mia prima risposta con Charcoal!

Spiegazione:

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

Provalo online!


3
Per coloro che preferiscono il carbone dettagliato, questo è PolygonHollow(:*, InputNumber(), "#");.
Neil,

5

Tela , 15 14 12 byte

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

Provalo qui!

Spiegazione:

/             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 a 12 byte .


4

R , 122 117 115 byte

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

Provalo online!

Porta la logica dalla risposta di Arnauld , in particolare questa revisione nel caso in cui ci siano ulteriori miglioramenti. Altri 2 byte salvati grazie al suggerimento di Arnauld di invertire la logica!


-2 byte facendolo al contrario (non posso farlo h*v&h+v-nin JS perché &è un operatore bit a bit; ma è logico in R, quindi funziona).
Arnauld,

@Arnauld grazie!
Giuseppe,


3

Python 2 , 81 byte

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

Provalo online!


Python 2 , 75 byte

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

Provalo online!

Se la miscelazione dei caratteri di output è OK.


3

Powershell, 91 byte

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#"}

Provalo online!

Se ci fosse un modo economico per invertire il primo tempo, questa risposta sarebbe molto meglio. Costruisce la metà sinistra, quindi il nucleo (che è o x #'so spazi), quindi rispecchia la logica della sinistra per creare la destra. Fatto curioso, non è necessario copiare oltre lo spazio bianco finale.

Srotolato e spiegato:

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 byte

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

Provalo 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 byte grazie a @ceilingcat



1

Python 2 , 130 byte

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

Provalo online!

Su cellulare, quindi non incredibilmente golf.


È possibile rimuovere lo spazio dopo (n+2*i).
Zacharý,

1

Lotto, 260 byte

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

Emette due spazi iniziali su ogni riga. Spiegazione: Il batch non ha un operatore di ripetizione delle stringhe, una capacità di suddivisione delle stringhe limitata e richiede istruzioni separate per eseguire l'aritmetica. È stato quindi più golfoso creare una stringa della lunghezza di input negli spazi (Batch può almeno tradurli in #s per le linee superiore e inferiore) e quindi tagliare da o in una posizione specifica che va da 3 alla lunghezza per generare le diagonali (questo è ciò che raggiunge l'ultima riga della sceneggiatura).


1

Rubino , 96 byte

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

Provalo online!

Non molto ancora golfato. Potrebbe golf se trovo il tempo.


1

Rosso , 171 byte

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]

Provalo online!

Spiegazione:

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×⊢)

Questa soluzione è stata fornita da Adám - grazie!

Provalo online!

La mia (quasi) soluzione originale:

APL (Dyalog Unicode) , SBCS da 61 byte

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

Provalo online!

Grazie ad Adám per il suo aiuto!

L'idea è quella di trovare il "diamante" che si trova in parte nel quadrato e applicare un filtro di rilevamento dei bordi per "delineare" l'ottagono.



1
In realtà non puoi usare Classic qui a causa di . Piuttosto conta 1 byte / carattere facendo riferimento a SBCS come da Meta .
Adám,

@Adám Grazie! Non so come modificare l'intestazione, puoi farlo per me?
Galen Ivanov,

Cosa intendi con la modifica dell'intestazione?
Adám,

1
Modifica e copia da qui .
Adám,

1

Perl 5, 201 197 188 187 186 byte:

$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

Provalo online!

Legge la dimensione dell'ottagono dalla prima riga di STDIN.


Benvenuti in PPCG! Probabilmente puoi radere qualche byte qua e là usando i trucchi trovati in questo post .
Mego

@Mego Yep. Sono stato in grado di salvare 4 byte utilizzando $"invece di " ".
Nathan Mills,

1

Perl 5, 176 byte

$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

Basato sulla risposta di Nathan Mills sopra (di cui non ho un rappresentante sufficiente per commentare!).

$epuò essere semplificato per il $a-1salvataggio di 6 byte; $fpuò essere assegnato a catena; salvataggio di due byte; Non sono sicuro da dove vengano gli altri due!

Mentre $epuò essere sostituito con $a-1nei due punti in cui si verifica, le parentesi extra necessarie significano che ciò si interrompe solo.

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

1

Perl 6 , 76 73 byte

-3 byte grazie a Jo King

{(' 'x$_-1~\*x$_,{S/.\S(.)+/* {' 'x$0}*/}...*)[^$_,$_ xx$_-2,[R,] ^$_;*]}

Provalo online!

Restituisce un elenco di righe.



0

Python 3 , 224 byte

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)

Provalo online!


0

Perl 5, 170 168 166 byte

$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

Questo funziona con la magia di regex. Il "if" è necessario solo per affrontare il caso patologico di n = 2, che altrimenti produce qualcosa di simile a:

 ##
 ##
#  #
 ##

probabilmente questo può essere codificato.

Penso che ci possa essere molto di più da guadagnare creando una stringa fino al punto medio e invertendola. Ovviamente dobbiamo quindi inserire / eliminare uno spazio extra se n è dispari (o usare thin-space: 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...

Penso che questo possa probabilmente essere giocato un po 'di più, a prescindere da cambiamenti significativi come la spinta $@e la stampa alla fine.

[Gli spazi golfizzati attorno ..e spostato la stampa prima di assegnare in due casi, risparmiando sui punti e virgola.]


salvato 20 byte riordinando alcune istruzioni TIO , perché \se non solo uno spazio nell'ultima regex
Nahuel Fouilleul


0

Perl 5, 98 byte

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

TIO

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.