Vẽ một lục giác ASCII có độ dài cạnh n

Jan 06 2021

Cho một số nguyên dương \$n\$xuất ra một hình lục giác ASCII với độ dài cạnh chéo \$n\$, như trong hình (lưu ý có \$2n\$ _ ký tự ở cạnh trên)

Ví dụ:

\$n = 1\$

 __
/  \
\__/

\$n = 2\$

  ____
 /    \
/      \
\      /
 \____/

\$n = 5\$

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

Vân vân.

Mã ngắn nhất tính bằng byte sẽ thắng. Áp dụng các phương pháp nhập / xuất thông thường .

Trả lời

11 Razetime Jan 06 2021 at 16:01

Canvas , 15 9 byte

 _;1*⁸/∔╬

Hãy thử nó ở đây!

-6 byte sau khi sửa chương trình.

Vẽ một phần tư hình lục giác, và bốn hình vuông.

9 xnor Jan 06 2021 at 17:16

Python 2 , 92 byte

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

Hãy thử nó trực tuyến!

6 Razetime Jan 06 2021 at 15:54

Than củi , 14 byte

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

Hãy thử nó trực tuyến!

Sửa lỗi +1 byte từ ASCII-Only.

Vẽ một nửa của hình lục giác và phản chiếu nó.

6 AZTECCO Jan 07 2021 at 15:50

C (gcc) , 119 109 byte

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

Hãy thử nó trực tuyến!

  • đã cứu được 2 nhờ @ceilingcat

Bảng bên dưới không được cập nhật nên các giá trị có thể khác nhau, nhưng khái niệm là:

  • chúng ta có 2 cặp đường thẳng song song
        . .
_______.______.________   
  | / \ | .
. | / \ | .
 | / \ |.
  | / \ |
  | \ / |.
 | \ / | .
. | \ / |
__ | ___ \ ________ / ___ | ___   
  | . .

chúng tôi lặp lại x, y từ kích thước thành 0 và chúng tôi tính tổng chúng để kiểm tra xem a / có được in hay không, chúng tôi trừ đi để kiểm tra \, chúng tôi sử dụng modulo để kiểm tra cả hai số song song.

    tôi 65432109876543210. j
 tô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 byte

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

Hãy thử nó trực tuyến!

-p}{cuối cùng là thủ thuật chỉ in dấu phân tách bản ghi đầu ra $\ở cuối. Nó chỉ hoạt động cho một bản ghi đầu vào; tiêu đề được sử dụng để in tất cả trong một liên kết.

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

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

Hãy thử nó trực tuyến!

Một phiên bản đệ quy hơn của câu trả lời này. Sự tùy tiện của thử thách này khiến điều này khá khó chịu.

Giải trình

Câu trả lời này hơi khó giải thích. Như tôi đã nói, thách thức là tùy ý theo một số cách, vì vậy mã chỉ là một tổ hợp các ký hiệu.

Ý tưởng

Ý tưởng của chương trình ở đây là xây dựng hai nửa. Đó là khi tính toán hình lục giác thứ n, chúng ta nhận được hai nửa của hình lục giác thứ n-1 và sử dụng nó để tạo ra hình lục giác lớn nhất tiếp theo.

Có một số lưu ý mặc dù. Chúng tôi xây dựng nửa trên từ trên xuống và chúng tôi xây dựng cả hai nửa được phản chiếu từ trái sang phải. Chúng tôi làm điều này bởi vì nó là thuận tiện để làm theo cách này. Không có lý do sâu xa nó chỉ làm cho mọi thứ ngắn hơn ngay cả khi nó làm cho mọi thứ hơi khó hiểu.

Chi tiết

Dòng đầu tiên khá thẳng về phía trước rlà bí danh cho reverse. Dòng thứ hai không quá thẳng về phía trước. mlà một hàm vô nghĩa, nó tồn tại bởi vì nó hoặc một hoạt động tương tự cần được thực hiện ở một vài nơi. Nó không thực sự có một ý nghĩa ngữ nghĩa. Lời giải thích tốt nhất về những gì nó làm ở đây là mã.

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

Từ đây, chúng ta bắt đầu đi đến fcái nào xử lý về cơ bản tất cả logic. Trường hợp đầu tiên flà trường hợp cơ sở, nó khá tiêu chuẩn

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

Lưu ý rằng chúng tôi trả về danh sách hai mục thay vì một bộ. Trong bất kỳ chương trình lành mạnh nào, chúng tôi sẽ sử dụng một bộ tuple vì nó được cố định ở 2 phần tử. Tuy nhiên sau đó, chúng tôi sẽ ánh xạ cả hai đối số của điều này với cùng một chức năng. Thật khó để làm điều đó với một bộ tuple nhưng dễ dàng với một danh sách, và danh sách không có bất kỳ nhược điểm nào nên chúng tôi sử dụng nó.

Sau đó, chúng ta có trường hợp quy nạp. Đầu tiên, chúng tôi tìm nạp trường hợp trước và lập bản đồ kép của chúng tôi mtrên nó. Điều này làm cho hình lục giác rộng hơn 1 đơn vị (2 ký tự) và di chuyển nó nửa đơn vị (1 ký tự) sang bên phải (mặc dù vì toàn bộ điều này là ngược nên các ký tự khoảng trắng được thêm vào bên phải ). Chúng tôi khớp mẫu này với [w:i,j]vì chúng tôi muốn sử dụng wđể tạo các hàng mới sau này. Nói về cái nào tiếp theo chúng ta thực hiện các hàng. Chúng tôi làm điều này với một đối sánh mẫu:

_:_:k<-r$m w

Đây là một loại mã vô nghĩa. Nó chỉ kết hợp những thứ chúng ta đã có để tạo ra đầu ra chính xác. kvà đảo ngược của nó tạo thành các hàng mới để chúng tôi thêm chúng vào. và trả về.

Sau khi fchúng ta có h, biến đầu ra của fthành một chuỗi. Nó hoàn tác tất cả các biến đổi kỳ quặc mà chúng tôi đã sử dụng trong quá trình xây dựng và đóng gói nó để sử dụng.

Với tất cả những gì chúng tôi chỉ soạn fhcho chức năng cuối cùng.

5 xnor Jan 11 2021 at 00:58

Haskell , 100 byte

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

Hãy thử nó trực tuyến!

Câu trả lời chơi gôn của AZTECCO cộng với một số kỹ thuật mới.

Ý tưởng chính là hình lục giác sẽ đơn giản hơn nếu chúng ta ghép các ncột đầu tiên đến cuối.

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

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

Bây giờ tất cả /\đều nằm trong một dòng duy nhất, và _tất cả đều ở bên trái của chúng. Điều này giúp việc thực hiện chiến lược xác định ký tự từ tọa độ của AZTECCO dễ dàng hơn nhiều. Để triển khai các tọa độ được gắn nhãn lại này, chúng tôi thay thế các xtọa độ [1..4*n]bằng một phiên bản theo chu kỳ và được dịch chuyển [1..3*n]++[1-n..0].

4 Neil Jan 06 2021 at 17:08

Retina 0.8.2 , 94 byte

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

Hãy thử nó trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

.+
$* ¶$&$* 

Chèn hai hàng ndấu cách.

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

Chuyển hàng đầu tiên thành các cạnh trên cùng của hình lục giác.

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

Chuyển hàng thứ hai thành các cạnh dưới cùng của hình lục giác.

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

Chèn dòng trên cùng.

T` `\_` +/$

Thay thế dòng dưới cùng.

4 ovs Jan 06 2021 at 16:32

Python 2 , 119 114 byte

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)

Hãy thử nó trực tuyến!

4 Arnauld Jan 07 2021 at 03:27

JavaScript (ES6),  109  107 byte

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)

Hãy thử nó trực tuyến!

Đã nhận xét

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 byte

Đã lưu 13 14 19 byte nhờ vào trần mèo !!!

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

Hãy thử nó trực tuyến!

Giải thích (trước một số cuộc chơi gôn)

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 byte

-4 ( 7 ) byte nhờ Kevin Cruijssen !

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

Hãy thử nó trực tuyến!

05AB1E có một nội trang canvas có thể hữu ích, nhưng khá khó để làm việc, đây chỉ là nội trang phản chiếu ºvà nội trang tập trung .c.

4 xash Jan 07 2021 at 01:26

J , 50 47 byte

-3 cảm ơn Jonah!

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

Hãy thử nó trực tuyến!

((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 (bản phát hành trước) , 174 byte

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

Hãy thử nó trực tuyến!

-1 byte nhờ @Duncan

-8 byte cảm ơn @Danis

4 AZTECCO Jan 10 2021 at 18:02

Haskell , 129 120 byte

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

Hãy thử nó trực tuyến!

  • đã cứu được 9 nhờ @Wheat Wizard và @xnor.

  • Kiểm tra câu trả lời @xnor và cải tiến lớn của nó về cách tiếp cận vấn đề (tránh mô đun và đường thẳng song song)!

  • Tương đương với câu trả lời C của tôi

Chúng tôi tạo tọa độ Cartesian bằng cách sử dụng khả năng hiểu danh sách | y <- [0..n * 2], x <- [0..a]

[c | ..., để c | ... | ... | ...] và chúng tôi sử dụng ký tự cần thiết dựa trên xy hoặc x + y để vẽ các đường ..
Chúng tôi sử dụng modulo để vẽ nhiều đường (2)
Trường hợp đặc biệt là _không cần tỷ lệ ax / y mà là một dải ô, chúng tôi đã sử dụng modulo để chỉ thực hiện một phép so sánh >thay vì a> x> b như

2 vrintle Jan 06 2021 at 15:15

Ruby , 141 byte

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

Hãy thử nó trực tuyến!

Nếu cho phép một dấu gạch dưới phía trên, thì sẽ mất ít byte hơn một chút, trong khi hình lục giác vẫn đẹp như trước ;-)

Ruby , 114 byte

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

Hãy thử nó trực tuyến!

2 Makonede Jan 07 2021 at 00:45

05AB1E , 70 byte

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

Hãy thử nó trực tuyến!

2 KjetilS. Jan 07 2021 at 00:54

Perl 5 , 143 byte

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}

Hãy thử nó trực tuyến!

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 byte

-18 byte với các bản sửa lỗi của xnor và xóa các khoảng trắng không cần thiết trên dòng cuối cùng

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]

Hãy thử nó trực tuyến!

Không thích:

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