Narysuj sześciokąt ASCII o boku n

Jan 06 2021

Biorąc pod uwagę dodatnią liczbę całkowitą \$n\$wypisz sześciokąt ASCII o przekątnej długości boku \$n\$, jak na zdjęciu (uwaga: są \$2n\$ _ znaki na górnej krawędzi)

Przykłady:

\$n = 1\$

 __
/  \
\__/

\$n = 2\$

  ____
 /    \
/      \
\      /
 \____/

\$n = 5\$

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

itp.

Wygrywa najkrótszy kod w bajtach. Zastosowanie mają zwykłe metody wejścia / wyjścia .

Odpowiedzi

11 Razetime Jan 06 2021 at 16:01

Płótno , 15 9 bajtów

 _;1*⁸/∔╬

Wypróbuj tutaj!

-6 bajtów po naprawieniu programu.

Rysuje ćwiartkę sześciokąta i czwórkę palindromizów.

9 xnor Jan 06 2021 at 17:16

Python 2 , 92 bajty

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

Wypróbuj online!

6 Razetime Jan 06 2021 at 15:54

Węgiel drzewny , 14 bajtów

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

Wypróbuj online!

Poprawka +1 bajta z tylko ASCII.

Rysuje połowę sześciokąta i tworzy jego lustrzane odbicie.

6 AZTECCO Jan 07 2021 at 15:50

C (gcc) , 119 109 bajtów

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

Wypróbuj online!

  • uratował 2 dzięki @ceilingcat

Poniższa tabela nie jest aktualizowana, więc wartości mogą się różnić, ale koncepcja jest taka:

  • mamy 2 pary równoległych linii
        . .
_______.______.________   
  | / \ | .
. | / \ | .
 . | / \ |.
  | / \ |
  | \ / |.
 . | \ / | .
. | \ / |
__ | ___ \ ________ / ___ | ___   
  | . .

iterujemy x, y od rozmiaru do 0 i sumujemy je, aby sprawdzić, czy powinno zostać wydrukowane /, odejmujemy, aby sprawdzić \, używamy modulo, aby sprawdzić obie podobieństwa.

    i 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 bajty

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

Wypróbuj online!

-pa }{na końcu jest sztuczka, aby wydrukować tylko separator rekordów wyjściowych $\na końcu. Działa tylko dla jednego rekordu wejściowego; nagłówek służy do wydrukowania łącza „wszystko w jednym”.

$\=' __ 
/  \
\__/'   # 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 bajtów

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

Wypróbuj online!

Bardziej rekurencyjna wersja tej odpowiedzi. Arbitralność tego wyzwania sprawia, że ​​jest to dość frustrujące.

Wyjaśnienie

Ta odpowiedź jest trochę trudna do wyjaśnienia. Wyzwanie jest, jak już powiedziałem, arbitralne na kilka sposobów, więc kod jest rodzajem zbioru symboli.

Pomysł

Ideą programu jest tutaj zbudowanie dwóch połówek. Oznacza to, że podczas obliczania n-tego sześciokąta otrzymujemy dwie połówki z n-pierwszego sześciokąta i używamy tego do utworzenia następnego największego.

Są jednak pewne zastrzeżenia. Budujemy górną połowę do góry nogami i tworzymy obie połówki w lustrzanym odbiciu od lewej do prawej. Robimy to, ponieważ jest to wygodne w ten sposób. Nie ma głębokiego powodu, że to po prostu skraca rzeczy, nawet jeśli sprawia, że ​​są one trochę niezrozumiałe.

Detale

Pierwsza linia jest dość prosta, rto alias dla reverse. Druga linia nie jest taka prosta. mto nonsensowna funkcja, istnieje, ponieważ ją lub podobną operację trzeba wykonać w kilku miejscach. Tak naprawdę nie ma znaczenia semantycznego. Najlepszym wyjaśnieniem tego, co robi tutaj, jest kod.

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

Od ftego momentu zaczynamy dochodzić do tego, który obsługuje w zasadzie całą logikę. Pierwszy przypadek fto podstawa, jest dość standardowy

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

Zwróć uwagę, że zamiast krotki zwracamy listę dwóch elementów. W każdym rozsądnym programie używalibyśmy krotki, ponieważ jest ona ustalona na 2 elementach. Jednak później zmapujemy oba argumenty tej samej funkcji. Trudno to zrobić z krotką, ale łatwo z listą, a lista nie ma żadnych wad, więc jej używamy.

Następnie mamy przypadek indukcyjny. Najpierw pobieramy poprzedni przypadek i podwójnie mapujemy mgo. To sprawia, że ​​sześciokąt jest o 1 jednostkę szerszy (2 znaki) i przesuwa go o pół jednostki (1 znak) w prawo (chociaż ponieważ całość jest odwrócona, znaki spacji są dodawane po prawej stronie ). Dopasowujemy to do wzorca, [w:i,j]ponieważ chcemy użyć go wdo późniejszego utworzenia nowych wierszy. Mówiąc o tym, co dalej robimy rzędy. Robimy to za pomocą dopasowania do wzorca:

_:_:k<-r$m w

To rodzaj bzdurnego kodu. Po prostu zderza ze sobą rzeczy, które już mieliśmy, aby wygenerować poprawny wynik. ka jego odwrotność tworzą nowe wiersze, więc dodajemy je i zwracamy.

Po tym f, hco zamienia wyjście z fna łańcuch. Cofa wszystkie zwariowane transformacje, których użyliśmy podczas tworzenia, i pakuje je do użycia.

Z tym wszystkim po prostu komponujemy fi hdo ostatecznej funkcji.

5 xnor Jan 11 2021 at 00:58

Haskell , 100 bajtów

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=' ']

Wypróbuj online!

Gra w golfa Odpowiedź AZTECCO plus kilka nowych technik.

Główną ideą jest to, że sześciokąt jest prostszy, jeśli przeszczepimy pierwsze nkolumny do końca.

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

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

Teraz wszystkie /i \znajdują się w jednej linii, a _wszystkie są po lewej stronie. To znacznie ułatwia realizację strategii AZTECCO polegającej na określaniu znaku ze współrzędnych. Aby zaimplementować te zmienione współrzędne, zastępujemy współrzędne x-współrzędne [1..4*n]wersją cykliczną i przesuniętą [1..3*n]++[1-n..0].

4 Neil Jan 06 2021 at 17:08

Retina 0.8.2 , 94 bajty

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

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

.+
$* ¶$&$* 

Wstaw dwa rzędy nspacji.

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

Przekształć pierwszy rząd w górne boki sześciokąta.

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

Przekształć drugi rząd w dolne boki sześciokąta.

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

Wstaw górną linię.

T` `\_` +/$

Wymień dolną linię.

4 ovs Jan 06 2021 at 16:32

Python 2 , 119 114 bajtów

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)

Wypróbuj online!

4 Arnauld Jan 07 2021 at 03:27

JavaScript (ES6),  109  107 bajtów

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)

Wypróbuj online!

Skomentowano

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 bajty

Zapisano 13 14 19 bajtów dzięki Ceilingcat !!!

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

Wypróbuj online!

Wyjaśnienie (przed niektórymi golfami)

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 bajtów

-4 ( 7 ) bajtów dzięki Kevinowi Cruijssenowi !

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

Wypróbuj online!

05AB1E ma polecenie wbudowane płótnie, które mogą być przydatne, ale jest dość skomplikowany, aby dostać pracę, to dopiero builtins lustro ºi oraz wbudowane Centralizacja .c.

4 xash Jan 07 2021 at 01:26

J , 50 47 bajtów

-3 dzięki Jonah!

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

Wypróbuj online!

((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 (wersja wstępna) , 174 bajty

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

Wypróbuj online!

-1 bajt dzięki @Duncan

-8 bajtów dzięki @Danis

4 AZTECCO Jan 10 2021 at 18:02

Haskell , 129 120 bajtów

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=' ']

Wypróbuj online!

  • uratował 9 dzięki @Wheat Wizard i @xnor.

  • Sprawdź odpowiedź @xnor i jej duże ulepszenie w podejściu do problemu (unikanie linii modulo i równoległych)!

  • Odpowiednik mojej odpowiedzi w C.

Tworzymy współrzędne kartezjańskie przy użyciu funkcji list | y <- [0..n * 2], x <- [0..a]

[c | ..., niech c | ... | ... | ...] i potrzebujemy znaku na podstawie xy lub x + y, aby narysować linie.
Używamy modulo do rysowania wielu linii (2)
Specjalny przypadek _nie wymaga stosunku ax / y, ale zakres, my użył modulo do zrobienia tylko jednego porównania >zamiast a> x> b jak

2 vrintle Jan 06 2021 at 15:15

Ruby , 141 bajtów

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

Wypróbuj online!

Jeśli dozwolone jest górne podkreślenie, zajęłoby to trochę mniej bajtów, podczas gdy sześciokąt jest tak samo ładny jak wcześniej ;-)

Ruby , 114 bajtów

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

Wypróbuj online!

2 Makonede Jan 07 2021 at 00:45

05AB1E , 70 bajtów

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

Wypróbuj online!

2 KjetilS. Jan 07 2021 at 00:54

Perl 5 , 143 bajty

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}

Wypróbuj online!

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 bajtów

-18 bajtów z poprawkami xnora i usuwaniem niepotrzebnych spacji w ostatniej linii

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]

Wypróbuj online!

Ungolfed:

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