Kenar uzunluğu n olan bir ASCII altıgen çizin

Jan 06 2021

Pozitif bir tam sayı verildiğinde \$n\$çapraz kenar uzunluğuna sahip bir ASCII altıgen çıktı \$n\$, resimde gösterildiği gibi (unutmayın \$2n\$ _ üst kenardaki karakterler)

Örnekler:

\$n = 1\$

 __
/  \
\__/

\$n = 2\$

  ____
 /    \
/      \
\      /
 \____/

\$n = 5\$

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

vb.

Bayt cinsinden en kısa kod kazanır. Genel girdi / çıktı yöntemleri geçerlidir.

Yanıtlar

11 Razetime Jan 06 2021 at 16:01

Tuval , 15 9 bayt

 _;1*⁸/∔╬

Burada deneyin!

Programı düzelttikten sonra -6 bayt.

Altıgenin dörtte birini çizer ve dörtlü palindromize eder.

9 xnor Jan 06 2021 at 17:16

Python 2 , 92 bayt

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

Çevrimiçi deneyin!

6 Razetime Jan 06 2021 at 15:54

Kömür , 14 bayt

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

Çevrimiçi deneyin!

Yalnızca ASCII'den +1 bayt düzeltme.

Altıgenin yarısını çizer ve yansıtır.

6 AZTECCO Jan 07 2021 at 15:50

C (gcc) , 119109 bayt

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

Çevrimiçi deneyin!

  • @ceilingcat sayesinde 2 kurtardı

Değerler farklı olabileceği için aşağıdaki tablo güncellenmemiştir, ancak konsept şu şekildedir:

  • 2 çift paralel çizgimiz var
        . .
_______.______.________   
  | / \ | .
. | / \ | .
 . | / \ |.
  | / \ |
  | \ / |.
 . | \ / | .
. | \ / |
__ | ___ \ ________ / ___ | ___   
  | . .

x'i, y'yi boyuttan 0'a yineleriz ve a / yazdırılması gerekip gerekmediğini kontrol etmek için toplarız, kontrol etmek için çıkarırız, her iki paralelliği kontrol etmek için modulo kullanırız.

    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 bayt

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

Çevrimiçi deneyin!

-pve }{sonunda yalnızca çıktı kaydı ayırıcısını $\en sonunda yazdırmak için bir numara var . Yalnızca bir giriş kaydı için çalışır; başlık, hepsini tek bir bağlantıda yazdırmak için kullanılır.

$\=' __ 
/  \
\__/'   # 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 bayt

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

Çevrimiçi deneyin!

Bu cevabın daha özyinelemeli bir versiyonu. Bu meydan okumanın keyfi olması, bunu oldukça sinir bozucu hale getiriyor.

Açıklama

Bu cevabın açıklaması biraz zor. Zorluk, daha önce de söylediğim gibi, birkaç yönden gelişigüzel, bu yüzden kod bir tür semboller yuvasıdır.

Fikir

Buradaki programın amacı iki yarıyı oluşturmaktır. Bu, n'inci altıgeni hesaplarken n-1'inci altıgenin iki yarısını elde ederiz ve bunu bir sonraki en büyük altıgeni yapmak için kullanırız.

Yine de bazı uyarılar var. Üst yarıyı baş aşağı inşa ediyoruz ve her iki yarıyı da soldan sağa aynalanmış şekilde oluşturuyoruz. Bunu, bu şekilde yapmak uygun olduğu için yapıyoruz. Her şeyi biraz anlaşılmaz hale getirse bile işleri kısaltmasının derin bir sebebi yok.

Detaylar

İlk satır oldukça yalındır r, için bir takma addır reverse. İkinci satır o kadar düz değil. msaçma bir işlevdir, çünkü bu veya benzeri bir işlemin birkaç yerde yapılması gerekir. Gerçekten anlamsal bir anlamı yok. Burada ne yaptığının en iyi açıklaması koddur.

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

Buradan f, temelde tüm mantığı hangi mantığın işlediğini öğrenmeye başlıyoruz . İlk durum ftemel durumdur, oldukça standarttır

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

Bir tuple yerine iki öğeden oluşan bir liste döndürdüğümüzü unutmayın. Herhangi bir aklı başında programda, 2 öğede sabitlendiği için bir demet kullanırdık. Ancak daha sonra, bunun her iki argümanını da aynı işlevle eşleyeceğiz. Bunu bir tuple ile yapmak zordur, ancak bir liste ile kolaydır ve liste herhangi bir dezavantaj oluşturmaz, bu yüzden onu kullanırız.

O zaman tümevarımlı durumumuz var. İlk önce bir önceki vakayı getiriyoruz ve müzerinde çift ​​harita oluşturuyoruz . Bu, altıgen 1 birimini daha geniş yapar (2 karakter) ve onu yarım birim (1 karakter) sağa hareket ettirir (her ne kadar bu şey geriye doğru olduğundan, boşluk karakterleri sağ tarafa eklenir ). Bunu daha sonra yeni satırlar yapmak [w:i,j]için kullanmak istediğimiz için kalıbı eşleştiriyoruz w. Bundan sonra sıraları yapacağımızdan bahsetmişken. Bunu bir kalıp eşleşmesi ile yapıyoruz:

_:_:k<-r$m w

Bu bir çeşit saçma kod. Sadece doğru çıktıyı üretmek zorunda olduğumuz şeyleri bir araya getiriyor. kve bunun tersi yeni satırları oluşturur, böylece onları ekleriz ve onu döndürürüz.

Sonra felimizdeki hçıktısını döndüğü fbir dizeye. İnşaat sırasında kullandığımız tüm tuhaf dönüşümleri geri alır ve kullanılmak üzere paketler.

Sadece oluşturduğumuz her şeyle fve hson işlev için.

5 xnor Jan 11 2021 at 00:58

Haskell , 100 bayt

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

Çevrimiçi deneyin!

Golf AZTECCO'nun cevabı artı bazı yeni teknikler.

Ana fikir, ilk nsütunları sonuna kadar nakledersek altıgenin daha basit olmasıdır .

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

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

Artık tüm /ve \tek bir satır vardır ve _bunlardan sola tümü. Bu, AZTECCO'nun karakteri koordinattan belirleme stratejisini yapmayı çok daha kolaylaştırır. Bu yeniden etiketlenmiş koordinatları uygulamak için, xkoordinatları döngülü [1..4*n]ve kaydırılmış bir versiyonla değiştiriyoruz [1..3*n]++[1-n..0].

4 Neil Jan 06 2021 at 17:08

Retina 0.8.2 , 94 bayt

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

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Açıklama:

.+
$* ¶$&$* 

İki satır nboşluk ekleyin .

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

İlk sırayı altıgenin üst taraflarına dönüştürün.

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

İkinci sırayı altıgenin alt kenarlarına dönüştürün.

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

En üst satırı ekleyin.

T` `\_` +/$

Alt satırı değiştirin.

4 ovs Jan 06 2021 at 16:32

Piton 2 , 119 114 bayt

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)

Çevrimiçi deneyin!

4 Arnauld Jan 07 2021 at 03:27

JavaScript (ES6),  109  107 bayt

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)

Çevrimiçi deneyin!

Yorum yaptı

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 bayt

Kaydedilen 13 14 19 sayesinde bayt 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;}

Çevrimiçi deneyin!

Açıklama (bazı golflerden önce)

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 bayt

Kevin Cruijssen sayesinde -4 ( 7 ) bayt !

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

Çevrimiçi deneyin!

05AB1E , yararlı olabilecek bir tuval yerleşikine sahiptir, ancak çalışması oldukça zordur, bu yalnızca ayna yerleşikleri ºve merkezileştirilmiş yerleşiktir .c.

4 xash Jan 07 2021 at 01:26

J , 50 47 bayt

-3 teşekkürler Jonah!

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

Çevrimiçi deneyin!

((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 (yayın öncesi) , 174 bayt

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

Çevrimiçi deneyin!

@Duncan sayesinde -1 bayt

@Danis sayesinde -8 bayt

4 AZTECCO Jan 10 2021 at 18:02

Haskell , 1229120 bayt

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

Çevrimiçi deneyin!

  • @Wheat Wizard ve @xnor sayesinde 9 tasarruf sağladı.

  • @Xnor cevabını ve soruna yaklaşımdaki büyük gelişimini kontrol edin (modulo ve paralel çizgilerden kaçınarak)!

  • C cevabımın karşılığı

Listeyi anlama | y <- [0..n * 2], x <- [0..a] kullanarak kartezyen koordinatlar yapıyoruz

[c | ..., let c | ... | ... | ...] ve çizgi çizmek için xy veya x + y'ye göre gerekli karakteri sararız ..
Birden çok çizgi çizmek için modulo kullanırız (2) Ax / y oranına değil, bir aralığa ihtiyaç duyan
özel durum _, biz >a> x> b benzeri yerine tek bir karşılaştırma yapmak için modulo kullandı

2 vrintle Jan 06 2021 at 15:15

Ruby , 141 bayt

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

Çevrimiçi deneyin!

Bir üst alt çizgiye izin veriliyorsa, bayt biraz daha az alırken, altıgen eskisi kadar güzel ;-)

Ruby , 114 bayt

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

Çevrimiçi deneyin!

2 Makonede Jan 07 2021 at 00:45

05AB1E , 70 bayt

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

Çevrimiçi deneyin!

2 KjetilS. Jan 07 2021 at 00:54

Perl 5 , 143 bayt

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}

Çevrimiçi deneyin!

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 , 186168 bayt

Xnor'un düzeltmeleriyle ve son satırdaki gereksiz boşlukları kaldırarak -18 bayt

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]

Çevrimiçi deneyin!

Golfsüz:

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