Octogones d'art ASCII


22

Étant donné un entier en entrée n > 1, sortez un octogone de type ASCII avec des longueurs latérales composées de ncaractères. Voir les exemples ci-dessous:

n=2
 ##
#  #
#  #
 ##

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

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

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

and so on.

Vous pouvez l'imprimer sur STDOUT ou le renvoyer en tant que résultat de fonction.

N'importe quelle quantité d'espace blanc étranger est acceptable, tant que les caractères s'alignent correctement.

Règles et E / S

  • L'entrée et la sortie peuvent être fournies par n'importe quelle méthode pratique .
  • Vous pouvez utiliser n'importe quel caractère ASCII imprimable à la place de #(sauf l'espace), mais le caractère "d'arrière-plan" doit être de l'espace (ASCII 32).
  • Un programme complet ou une fonction sont acceptables.
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.

1
Pouvons-nous utiliser différents caractères de sortie, ou doit-il être cohérent?
Emigna

@Emigna Différents personnages vont bien.
AdmBorkBork

Réponses:


22

05AB1E , 3 octets

7ÝΛ

Essayez-le en ligne!

Explication

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

Voir cette réponse pour comprendre la toile 05AB1E.


Cela devrait sûrement être de 5 octets? Ou est-ce que les défis de golf de code voient les octets et les caractères comme interchangeables
Doug

3
@Doug: Il s'agit de 3 octets dans la page de codes de
05ab1e

Oh cool! Merci pour le lien vers les documents!
Doug

> :( damnit, adnan
ASCII uniquement

11

JavaScript (ES6), 114 106 105 104 103 octets

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)

Essayez-le en ligne!

Comment?

Cela construit le caractère de sortie par caractère.

Étant donné l'entrée n , nous calculons:

n=n1w=3n

Pour chaque caractère en (x,y) , nous calculons (h,v) :

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

Les cellules appartenant à l'octogone remplissent l'une des conditions suivantes:

  • ( h=0 OU v=0 ) ET h+vn (en rouge ci-dessous)
  • h+v=n (en orange ci-dessous)

Par exemple, avec n=4 (et 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, c'est génial! Je pense que peut être simplifié en h + v > n , bien que je ne sois pas sûr que cela aide la logique du golf du tout. h+vnh+v>n
Giuseppe

@Giuseppe Cela pourrait en effet être simplifié de cette façon si les deux conditions étaient testées. Mais dans le code, les cas et h v 0 sont séparés. Cependant, je teste en fait la condition opposée ( n > h + v ), qui est déjà plus courte d'un octet. hv=0hv0n>h+v
Arnauld

@Giuseppe Votre commentaire m'a incité à regarder de plus près la formule et j'ai finalement enregistré un octet en l'écrivant un peu différemment. :)
Arnauld

1
heh, eh bien ton commentaire sur m'a incité à aller regarder mon port de ta logique et à économiser encore quelques octets! hv=0
Giuseppe

8

Fusain , 5 octets

GH*N#

Ma première réponse avec Charcoal!

Explication:

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

Essayez-le en ligne!


3
Pour ceux qui préfèrent le charbon verbeux, c'est PolygonHollow(:*, InputNumber(), "#");.
Neil

5

Toile , 15 14 12 octets

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

Essayez-le ici!

Explication:

/             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 octets .


4

R , 122 117 115 octets

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

Essayez-le en ligne!

Transmet la logique de la réponse d' Arnauld , en particulier cette révision au cas où il y aurait d'autres améliorations. Encore 2 octets économisés grâce à la suggestion d'Arnauld d'inverser la logique!


-2 octets en le faisant dans l'autre sens (je ne peux pas le faire h*v&h+v-ndans JS car &c'est un opérateur au niveau du bit; mais c'est un opérateur logique dans R, donc ça marche).
Arnauld

@Arnauld merci!
Giuseppe



3

Powershell, 91 octets

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

2

PowerShell , 107 97 octets

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

Essayez-le en ligne!

S'il y avait un moyen bon marché d'inverser la première moitié, cette réponse se sentirait beaucoup mieux. Il construit la moitié gauche, puis le noyau (qui est soit x #'ssoit des espaces), puis reflète la logique de gauche pour faire la droite. Fait amusant, vous n'avez pas besoin de copier sur un espace blanc à la fin.

Déroulé et expliqué:

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 octets

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

Essayez-le en ligne!

Non 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 octets grâce à @ceilingcat



1

Python 2 , 130 octets

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

Essayez-le en ligne!

Sur mobile, donc pas incroyablement golfé.


Vous pouvez supprimer l'espace après (n+2*i).
Zacharý

1

Lot, 260 octets

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

Génère deux espaces de tête sur chaque ligne. Explication: Batch n'a pas d'opérateur de répétition de chaîne, une capacité de découpage de chaîne limitée et nécessite des instructions distinctes pour effectuer l'arithmétique. Il était donc le plus golfique de composer une chaîne de la longueur d'entrée dans les espaces (Batch peut au moins les traduire en #s pour les lignes supérieure et inférieure), puis de découper à partir de ou vers une position spécifique allant de 3 à la longueur pour générer les diagonales (c'est ce que réalise la dernière ligne du script).


1

Rubis , 96 octets

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

Essayez-le en ligne!

Pas encore très golfé. Pourrait jouer au golf si je trouve le temps.


1

Rouge , 171 octets

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]

Essayez-le en ligne!

Explication:

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

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

Cette solution a été fournie par Adám - merci!

Essayez-le en ligne!

Ma solution (presque) originale:

APL (Dyalog Unicode) , 61 octets SBCS

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

Essayez-le en ligne!

Merci à Adám pour son aide!

L'idée est de trouver le "diamant" qui se trouve en partie dans le carré et d'appliquer un filtre de détection de bord pour "délimiter" l'octagone.



1
Vous ne pouvez pas réellement utiliser Classic ici à cause de . Comptez plutôt 1 octet / caractère en vous référant à SBCS selon Meta .
Adám

@ Adám Merci! Je ne sais pas comment modifier l'en-tête, pouvez-vous le faire pour moi?
Galen Ivanov

Que voulez-vous dire en modifiant l'en-tête?
Adám

1
Modifiez et copiez à partir d' ici .
Adám

1

Perl 5, 201 197 188 187 186 octets:

$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

Essayez-le en ligne!

Lit la taille de l'octogone à partir de la première ligne de STDIN.


Bienvenue chez PPCG! Vous pouvez probablement raser quelques octets ici et là en utilisant des astuces trouvées dans ce post .
Mego

@Mego Yep. J'ai pu enregistrer 4 octets en utilisant $"au lieu de " ".
Nathan Mills

1

Perl 5, 176 octets

$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

Basé sur la réponse de Nathan Mills ci-dessus (que je n'ai pas suffisamment de représentants pour commenter!).

$epeut être simplifié pour $a-1économiser 6 octets; $fpeut être affecté en chaîne; enregistrer deux octets; Je ne sais pas d'où viennent les deux autres!

Bien qu'il $epuisse être remplacé $a-1dans les deux endroits, il se produit, les supports supplémentaires nécessaires signifient que cela ne fait qu'équilibrer.

Non 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 octets

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)

Essayez-le en ligne!


0

Perl 5, 170 168 166 166 octets

$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

Cela fonctionne par la magie des regex. Le "si" n'est nécessaire que pour traiter le cas pathologique de n = 2, qui autrement génère quelque chose comme:

 ##
 ##
#  #
 ##

cela peut probablement être codé.

Je pense qu'il peut y avoir beaucoup plus à gagner en créant une chaîne jusqu'au milieu puis en l'inversant. Bien sûr, nous devons ensuite insérer / supprimer un espace supplémentaire si n est impair (ou utiliser un espace fin: p).

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

Je pense que cela peut probablement être joué un peu plus, mis à part des changements importants comme pousser sur $@ et imprimer à la fin.

[Des espaces golfés autour ..et déplacé l'impression avant les affectations dans deux cas, économisant sur les points-virgules.]


sauvé 20 octets en réorganisant certaines instructions TIO , pourquoi \set pas seulement un espace dans le dernier regex
Nahuel Fouilleul


0

Perl 5, 98 octets

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

TIO

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.