Dessinez un hexagone ASCII de longueur de côté n

Jan 06 2021

Étant donné un entier positif \$n\$sortie un hexagone ASCII avec une longueur de côté diagonale \$n\$, comme illustré (notez qu'il y a \$2n\$ _ caractères sur le bord supérieur)

Exemples:

\$n = 1\$

 __
/  \
\__/

\$n = 2\$

  ____
 /    \
/      \
\      /
 \____/

\$n = 5\$

     __________
    /          \
   /            \
  /              \
 /                \
/                  \
\                  /
 \                /
  \              /
   \            /
    \__________/

etc.

Le code le plus court en octets l'emporte. Les méthodes habituelles d'entrée / sortie s'appliquent.

Réponses

11 Razetime Jan 06 2021 at 16:01

Toile , 15 9 octets

 _;1*⁸/∔╬

Essayez-le ici!

-6 octets après avoir corrigé le programme.

Dessine un quart de l'hexagone et le quad se palindromise.

9 xnor Jan 06 2021 at 17:16

Python 2 , 92 octets

k=n=input()
while 1:a=k^k>>n;print" "*a+"\/_"[k/n-2]+"_ "[-n<k<n]*2*(2*n+~a)+"\_/"[k/n];k-=1

Essayez-le en ligne!

6 Razetime Jan 06 2021 at 15:54

Charbon , 14 octets

←×_θ↖θ→↗θ×_θ‖M

Essayez-le en ligne!

Correction de +1 octet à partir d'ASCII uniquement.

Dessine la moitié de l'hexagone et la reflète.

6 AZTECCO Jan 07 2021 at 15:50

C (gcc) , 119 109 octets

a,i,j;f(n){for(i=a+=a=j=n*2;~j;)putchar(!i--?i=a,j--,13:i%(n*3)<n|j%(n*2)?(i-~j-n)%a?(i-j+n)%a?32:92:47:95);}

Essayez-le en ligne!

  • sauvé 2 grâce à @ceilingcat

Le tableau ci-dessous n'est pas mis à jour donc les valeurs peuvent différer, mais le concept est:

  • nous avons 2 paires de lignes parallèles
        . .
_______.______.________   
  | / \ | .
. | / \ | .
 . | / \ |.
  | / \ |
  | \ / |.
 . | \ / | .
. | \ / |
__ | ___ \ ________ / ___ | ___   
  | . .

nous itérons x, y de la taille à 0 et nous les additionnons pour vérifier si un / doit être imprimé, nous soustrayons pour vérifier \, nous utilisons modulo pour vérifier les deux parallèles.

    Je 65432109876543210. j
 i + jn ________ 8 
13 + 7-4 => / \ 7 
14 + 6-4 / \ 6 
15 + 5-4 / \ 5 
      / \ 4 
      \ 1 + 3-4 => / 3
       \ 2 + 2-4 / 2
        \ 3 + 1-4 / 1
         \ ________ / 0
5 NahuelFouilleul Jan 07 2021 at 03:22

Perl 5 ( -p), 102 octets

s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- for($\=' __ / \ \__/')x--$_}{

Essayez-le en ligne!

-pet }{à la fin est une astuce pour imprimer uniquement le séparateur d'enregistrement de sortie $\à la fin. Cela ne fonctionne que pour un enregistrement d'entrée; l'en-tête est utilisé pour imprimer le tout en un seul lien tio.

$\=' __ 
/  \
\__/'   # output record separator initialized with hexagon (size 1)

s/_+/__$&/g,s/^|$/ /gm,s/^ *\S /$& /gm,s-( +)\\ -$&/ $1 \\ \\ $1 /
- # regexes to increase the hexagon by 1

for .. --$_ # to repeat n-1 times where n is the input
5 WheatWizard Jan 08 2021 at 23:56

Haskell , 150 octets

r=reverse
m(o:c:k)=o:c:c:c:k++" "
f 1=[["\\  /","__ "],["/__\\"]]
f n|[w:i,j]<-map m<$>f(n-1),_:_:k<-r$m w=[r k:w:i,k:j]
h[i,j]=unlines$r<$>r i++j
h.f

Essayez-le en ligne!

Une version plus récursive de cette réponse. L'arbitraire de ce défi rend cela assez frustrant.

Explication

Cette réponse est un peu difficile à expliquer. Le défi est, comme je l'ai déjà dit, arbitraire à certains égards, de sorte que le code n'est en quelque sorte qu'un nid de symboles.

Idée

L'idée du programme ici est de construire les deux moitiés. C'est-à-dire que lors du calcul du nième hexagone, nous obtenons les deux moitiés du n-1e hexagone et l'utilisons pour créer le prochain plus grand.

Il y a cependant quelques mises en garde. Nous construisons la moitié supérieure à l'envers et nous construisons les deux moitiés en miroir de gauche à droite. Nous faisons cela parce que c'est pratique de le faire de cette façon. Il n'y a aucune raison profonde que cela rend les choses plus courtes même si cela rend les choses un peu incompréhensibles.

Détails

La première ligne est assez simple rest un alias pour reverse. La deuxième ligne n'est pas si simple. mest une fonction absurde, elle existe car elle ou une opération similaire doit être effectuée à quelques endroits. Cela n'a pas vraiment de sens sémantique. La meilleure explication de ce qu'il fait ici est le code.

m(o:c:k)=o:c:c:c:k++" "

À partir de là, nous commençons à déterminer fqui gère essentiellement toute la logique. Le premier cas fest le cas de base, c'est assez standard

f 1=[["\\  /","__ "],["/__\\"]]

Notez que nous retournons une liste de deux éléments au lieu d'un tuple. Dans tout programme sensé, nous utiliserions un tuple car il est fixé à 2 éléments. Cependant, plus tard, nous mapperons les deux arguments de ceci avec la même fonction. C'est difficile à faire avec un tuple mais facile avec une liste, et la liste ne pose aucun inconvénient, nous l'utilisons donc.

Ensuite, nous avons le cas inductif. D'abord, nous récupérons le cas précédent, et nous le mdoublons. Cela élargit l'hexagone d'une unité (2 caractères) et le déplace d'une demi-unité (1 caractère) vers la droite (bien que puisque tout cela est à l'envers, les caractères d'espacement sont ajoutés à droite ). Nous faisons correspondre ceci à [w:i,j]parce que nous voulons utiliser wpour créer de nouvelles lignes plus tard. En parlant de qui ensuite nous faisons les lignes. Nous faisons cela avec une correspondance de motif:

_:_:k<-r$m w

C'est une sorte de code absurde. Il ne fait que regrouper les choses que nous avions déjà pour produire le bon résultat. ket sa forme inverse forme les nouvelles lignes afin que nous les ajoutions. et renvoyons cela.

Après fnous avons hqui transforme la sortie de fen une chaîne. Il annule toutes les transformations farfelues que nous avons utilisées pendant la construction et les conditionne pour être utilisée.

Avec tout ce que nous venons de composer fet hpour la fonction finale.

5 xnor Jan 11 2021 at 00:58

Haskell , 100 octets

f n=unlines[q<$>[1..3*n]++[1-n..0]|y<-[-n..n],let q x|abs y==n,x>n='_'|x==y='\\'|x+y==1='/'|1>0=' ']

Essayez-le en ligne!

La réponse d'AZTECCO au golf et de nouvelles techniques.

L'idée principale est que l'hexagone est plus simple si l'on transplante les premières ncolonnes jusqu'à la fin.

|-|
   ______   
  /      \  
 /        \ 
/          \
\          /
 \        / 
  \______/  

         |-|
______      
      \    /
       \  / 
        \/  
        /\  
       /  \  
______/    \

Maintenant, tous les /et \sont sur une seule ligne, et les _sont tous à gauche de ceux-ci. Cela rend beaucoup plus facile la stratégie d'AZTECCO de déterminer le caractère à partir des coordonnées. Pour implémenter ces coordonnées réétiquetées, nous remplaçons les xcoordonnées [1..4*n]par une version cyclée et décalée [1..3*n]++[1-n..0].

4 Neil Jan 06 2021 at 17:08

Retina 0.8.2 , 94 octets

.+
$* ¶$&$* \G ¶$%'/$`$%_$%_$`\
r` \G
$%`\$'$%_$%_$%'/¶ ^¶( *) $1 $.&$*_$.&$*_$& T` `\_` +/$

Essayez-le en ligne! Le lien comprend des cas de test. Explication:

.+
$* ¶$&$* 

Insérez deux rangées d' nespaces.

\G 
¶$%'/$`$%_$%_$`\

Convertissez la première rangée dans les côtés supérieurs de l'hexagone.

r` \G
$%`\$'$%_$%_$%'/¶

Convertissez la deuxième rangée dans les côtés inférieurs de l'hexagone.

^¶( *)
$1 $.&$*_$.&$*_$&

Insérez la ligne supérieure.

T` `\_` +/$

Remplacez la ligne du bas.

4 ovs Jan 06 2021 at 16:32

Python 2 , 119 114 octets

i=n=input()
d=0
exec"k=i/n|d;print' '*i+'\_/'[~k]+'_ '[i-d<n]*2*(2*n+~i)+'\_/'[k]\nif i==d:d=i=-1\ni-=d|1;"*(n-~n)

Essayez-le en ligne!

4 Arnauld Jan 07 2021 at 03:27

JavaScript (ES6),  109  107 octets

w=>(x=0,W=w*4,i=g=y=>~y?`
 /\\_`[x++-W?y*!i|w/x|x>w*3?(x+~y+w)%W?(x+y)%W-w?1:3:2:4:x=i=0&y--]+g(y):'')(w*2)

Essayez-le en ligne!

Commenté

w => (                        // w = input
  x = 0,                      // initialize x to 0
  W = w * 4,                  // W = total width
  i =                         // initialize i to a non-zero value
  g = y =>                    // g is a recursive function taking y
  ~y ?                        //   if y is not equal to -1:
    `\n /\\_`[                //     list of characters
      x++ - W ?               //     if this is not the end of the row:
        y * !i |              //       if this is neither the first nor the last row
        w / x |               //       or x is less than or equal to w
        x > w * 3 ?           //       or x is greater than w * 3:
          (x + ~y + w) % W ?  //         if (x - y - 1 + w) mod W is not equal to 0:
            (x + y) % W - w ? //           if (x + y) mod W is not equal to w:
              1               //             draw a space
            :                 //           else:
              3               //             draw a '\'
          :                   //         else:
            2                 //           draw a '/'
        :                     //       else:
          4                   //         draw a '_'
      :                       //     else:
        x = i = 0 & y--       //       decrement y, set x and i to 0 and draw a linefeed
    ] + g(y)                  //     append the result of a recursive call
  :                           //   else:
    ''                        //     stop the recursion
)(w * 2)                      // initial call to g with y = w * 2
4 Noodle9 Jan 06 2021 at 21:18

C (gcc) , 194 \$\cdots\$ 149 144 octets

Sauvegardé 13 14 19 octets grâce à plafonnier !!!

p(n,c){for(;n--;)printf(L"/\\ _\n"+c);}i;t;f(n){p(n,2);for(i=t=p(2*n,3);i>=p(1,4);t=i/n?--i,1:t)i+=!p(!p(n+i<<!p(!p(n+~i,2),t),t&!i|2),!t)-2*t;}

Essayez-le en ligne!

Explication (avant certains golfs)

p(n,c){for(;n--;)                     // Helper function to print  
         putchar("/\\ _\n"[c]);}      //  one of '/', '\', ' ', '_' , or  
                                      //  newline n times, this function  
                                      //  also returns 0 
i;t;f(n){                             // Main function prints an n hexagon  
        p(n,2);                       // Print n leading spaces for the 1st  
                                      //  line 
        for(                          // Main loop
            i=t=p(2*n,3);             // Set i and t to 0,  
                                      //  and print 2*n '_'s for the 1st line
            i>=p(1,4);                // Loop until i goes below 0, and 
                                      //  print a newline
                                      // At the end of each loop:  
            i+=1-2*t,                 //  increment i for the 1st half  
                                      //   and then decrement i in the 2nd  
            t=i/n?--i,1:t)            //  keep t as t unless i equals n,   
                                      //  then make t 1 and decrement i   
                                      // In the main loop:
                p(n+~i,2),            //  print n-i-1 leading spaces     
                p(1,t),               //  print a '/' in the 1st half and a  
                                      //   '\' in the 2nd    
                p(n+i<<1,t&!i|2),     //  print the 2*(n+i) middle spaces  
                                      //   unless at the bottom print '_'s  
                p(1,!t);              //  print a '\' in the 1st half and a  
                                      //   '/' in the 2nd    
   }  
 
4 ovs Jan 07 2021 at 05:12

05AB1E , 33 29 25 octets

-4 ( 7 ) octets grâce à Kevin Cruijssen !

L+<'/úíºI·'_ך»∊¶¡`ðs‡).c

Essayez-le en ligne!

05AB1E a une toile qui builtin pourrait être utile, mais il est assez difficile de faire fonctionner correctement , c'est juste le miroir builtins ºet et la commande interne centralisent .c.

4 xash Jan 07 2021 at 01:26

J , 50 47 octets

-3 merci à Jonah!

' \/_'{~]|."1((0,]+2*|.)@=@i.,.3,3,~0$~<:,])@+:

Essayez-le en ligne!

((0,]+2*|.)@=@i.  ,.  3,3,~0$~<:,])@+:
     0 0 0 0            3 3 3 3
     1 0 0 2            0 0 0 0
     0 1 2 0            0 0 0 0
     0 2 1 0            0 0 0 0
     2 0 0 1            3 3 3 3

    ]|."1
0 0 3 3 3 3 0 0
0 2 0 0 0 0 1 0
2 0 0 0 0 0 0 1
1 0 0 0 0 0 0 2
0 1 3 3 3 3 2 0

' \/_'{~ 
  ____
 /    \    
/      \    
\      /  
 \____/  
4 Anakhand Jan 06 2021 at 17:25

Python 3.8 (pré-version) , 174 octets

n=int(input())
b,a,s="\/ "
z,f=range(n),lambda c,d,t:((n-1-i)*s+c+2*(n+i)*s+d for i in t)
print(f"{'_'*2*n:^{4*n}}",*f(a,b,z),*f(b,a,z[:0:-1]),f"{b:>{n}}{'_'*2*n}/",sep="\n")

Essayez-le en ligne!

-1 octet grâce à @Duncan

-8 octets grâce à @Danis

4 AZTECCO Jan 10 2021 at 18:02

Haskell , 129 120 octets

g=mod
f n|a<-n*4=[c|y<-[-n..n],x<-[0..a],let c|x<1='\n'|g x(n*3+1)>n,abs y==n='_'|g(x+y)a==1='/'|g(x-y)a<1='\\'|1>0=' ']

Essayez-le en ligne!

  • sauvé 9 grâce à @Wheat Wizard et @xnor.

  • Vérifiez la réponse @xnor et sa grande amélioration sur l'approche du problème (en évitant les lignes modulo et parallèles)!

  • Équivalent de ma réponse C

Nous créons des coordonnées cartésiennes en utilisant la compréhension de liste | y <- [0..n * 2], x <- [0..a]

[c | ..., soit c | ... | ... | ...] et nous YELD le caractère nécessaire en fonction xy ou x + y pour dessiner des lignes ..
Nous utilisons modulo pour tracer plusieurs lignes (2)
Cas particulier est pour _qui ne rapport pas besoin de hache / y , mais une gamme, nous utilisé modulo pour faire une seule comparaison >au lieu d'un a> x> b comme

2 vrintle Jan 06 2021 at 15:15

Rubis , 141 octets

->(n,g=->c,d{(1..n).map{|i|" "*(n-i)+d+" "*2*(n+i-1)+c}},l=g[?/,e=?\\].reverse){[" "*n+?_*n*2,g[e,?/],l[0..-2],l[-1].sub(/ +(?=\/)/,?_*n*2)]}

Essayez-le en ligne!

Si un trait de soulignement supérieur est autorisé, cela prendrait un peu moins d'octets, tandis que l'hexagone est aussi joli qu'il l'était auparavant ;-)

Rubis , 114 octets

->n{[" "*n+?_*2*n,(g=->c,d{(1..n).map{|i|" "*(n-i)+c+" "*2*(n+i-1)+d}})[?/,e=?\\],g[e,?/].reverse," "*n+?‾*n*2]}

Essayez-le en ligne!

2 Makonede Jan 07 2021 at 00:45

05AB1E , 70 octets

ðש'_¹·×«©¶«©¹'/1Λ¹·Ì'.2Λ¹'\3.Λ«©„./`.;©¶¡Â‚€»`s'.ð:,¹3*>(£„._`:„/\‡,

Essayez-le en ligne!

2 KjetilS. Jan 07 2021 at 00:54

Perl 5 , 143 octets

sub f{$n=pop;@b=map{join'',$"x($n-$_),'/','  'x($n+$_-1),'\\',$/}1..$n;join('',$"x$n,$u=__ x$n,$/,@b,map y|/\\|\\/|r,reverse@b)=~s| +/$|$u/|sr}

Essayez-le en ligne!

sub f{
  $n=pop;             #n = input
  @b=map{             #set array @b to line 2 - n+1
    join'',           #join parts into a line string
    $" x ($n-$_), #space times n-1 '/', #char / ' ' x ($n+$_-1), #space times n+iterator minus 1 '\\', #char \ $/                #char newline
  } 1..$n; #n lines join('', #return string of these joined: $" x $n, #n spaces $u = __ x$n, #n*2 underscores $/,               #char newline
    @b,               #lines 2 to n+1 constructed above
    map y|/\\|\\/|r,  #and bottom part which is the same
      reverse@b       #as top part reversed and /\ rotated
  )=~s| +/$|$u/|sr    #and change last spaces of last line to _'s
}
2 StevenFontanella Jan 07 2021 at 12:31

Haskell , 186 168 octets

-18 octets avec les correctifs de xnor et suppression des espaces inutiles sur la dernière ligne

s=' '
(!)=replicate
e=reverse
h n=unlines$(\m->(n!s++(2*n)!'_'++n!s):e(e<$>m)++init m++[(n-1)!s++'\\':(2*n)!'_'++"/"])$(\i->i!s++'\\':(4*n-2*i-2)!s++'/':i!s)<$>[0..n-1]

Essayez-le en ligne!

Non golfé:

hex :: Int -> String
hex n = unlines $ first: middle ++ (init $ reverse (map reverse middle)) ++ [last]
  where
    first = replicate n ' ' ++ replicate (2*n) '_' ++ replicate n ' '
    f i = replicate i ' ' ++ "/" ++ replicate (n-i + 2*n + n-i -2) ' ' ++ "\\" ++ replicate i ' '
    middle = map f [n-1,n-2..0]
    last = replicate (n-1) ' ' ++ "\\" ++ replicate (2*n) '_' ++ "/" ++ replicate (n-2) ' '