Vẽ các hình lục giác ASCII đồng tâm


15

Viết chương trình ngắn nhất có thể có trong một tập hợp các số nguyên dương khác biệt và đưa ra kết xuất ASCII đồng tâm hình lục giác với những độ dài phụ, làm từ gạch chéo, dấu gạch dưới, không gian, và dòng mới.

Chương trình ngắn nhất tính theo byte được tính bởi https://otherseff.in/byte-count thắng.

Ví dụ

(Chúng trông đẹp hơn với khoảng cách dòng ít hơn.)

Nếu đầu vào là 1đầu ra thì phải là hình lục giác có cạnh dài 1:

 __ 
/  \
\__/

Lưu ý rằng hai dấu gạch dưới được sử dụng cho đỉnh và đáy của hình lục giác để nó được cân đối hơn.

Nói chung, hình lục giác kích thước N chứa N dấu gạch chéo ở mỗi cạnh góc và 2 * N gạch dưới ở cả trên và dưới.

Nếu đầu vào là 1 2đầu ra thì phải là các hình lục giác đồng tâm có độ dài cạnh 1 và 2:

  ____
 / __ \
/ /  \ \
\ \__/ /
 \____/

Nếu đầu vào là 1 3đầu ra nên:

   ______
  /      \
 /   __   \
/   /  \   \
\   \__/   /
 \        /
  \______/

Nếu đầu vào là 1 3 2đầu ra nên:

   ______
  / ____ \
 / / __ \ \
/ / /  \ \ \
\ \ \__/ / /
 \ \____/ /
  \______/

Vân vân.

Quy tắc I / O

Đầu vào phải đến từ dòng lệnh hoặc stdin nhưng có thể ở bất kỳ định dạng nào thuận tiện nhất.

Ví dụ: bạn có thể cung cấp cho mỗi số dưới dạng đối số dòng lệnh: > myprogram 1 3 2hoặc bạn có thể nhắc người dùng nhập các số dưới dạng danh sách được định dạng sẵn:[1, 3, 2] .

Đầu ra phải đi đến thiết bị xuất chuẩn hoặc tương đương gần nhất với ngôn ngữ của bạn.

Quy tắc bổ sung

  • Đầu vào sẽ luôn là một tập hợp các số nguyên dương riêng biệt, không nhất thiết phải theo bất kỳ thứ tự nào .
  • Đầu ra phải ...
    • không chứa bất kỳ ký tự nào ngoài /\ _ và dòng mới.
    • không có không gian dấu hoặc không gian hàng đầu không cần thiết.
    • không chứa các dòng mới hàng đầu bên ngoài nhưng có thể có một dòng mới tùy chọn .
  • Nếu không có gì là đầu vào thì đầu ra không có gì (ngoại trừ có thể là một dòng mới).
  • Nếu nó giúp bạn có thể giả sử rằng các số nguyên đầu vào nhỏ hơn 2 16 .

1đề cập đến hình lục giác trong cùng hoặc ngoài cùng?
NinjaBearMonkey

@hsl 1(hoặc bất kỳ số nào) đề cập đến hình lục giác có độ dài cạnh là 1. (Với thông báo rằng 1 dấu gạch chéo = 2 dấu gạch dưới.) Vì vậy, 1sẽ luôn luôn đề cập đến hình lục giác trong cùng.
Sở thích của Calvin

Câu trả lời:


4

CJam, 148 116 109 byte

Điều này mất nhiều thời gian hơn tôi mong đợi. Ban đầu, tôi chỉ muốn lặp đi lặp lại xây dựng góc phần tư phía trên bên trái, như trong các thử thách kim cương, và sau đó nhận phần còn lại từ việc phản chiếu. Nhưng tôi đã không nhận thấy rằng phần dưới không tuân theo sự đối xứng gương giữa nửa trên và nửa dưới. Vì vậy, tôi đã phải làm lại hầu hết điều đó, để tạo ra một nửa bên phải lặp đi lặp lại và sau đó chỉ phản chiếu một lần (bên trái).

S]2[l~]:(f#:+2bW%{_,2/~:T;{IT):T1<'\'/?S?S++}%__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+}fI{)T)2*2$,-*1$W%"\/"_W%er@N}/

Kiểm tra nó ở đây.

Một ví dụ về Fibonacci-esque:

8 3 1 5 2
        ________________
       /                \
      /                  \
     /     __________     \
    /     /          \     \
   /     /   ______   \     \
  /     /   / ____ \   \     \
 /     /   / / __ \ \   \     \
/     /   / / /  \ \ \   \     \
\     \   \ \ \__/ / /   /     /
 \     \   \ \____/ /   /     /
  \     \   \______/   /     /
   \     \            /     /
    \     \__________/     /
     \                    /
      \                  /
       \________________/

Giải trình:

Như đã nói ở trên, tôi bắt đầu bằng cách xây dựng một nửa đúng vòng lặp. Đó là, ban đầu tôi chỉ có một khoảng trống trong lưới và sau đó với mỗi vòng có thể, tôi sẽ bao quanh lưới hiện có trong các khoảng trắng hoặc một hình lục giác mới.

Khi đã xong, tôi phản chiếu từng dòng sang trái và đệm nó với các khoảng trắng hàng đầu để căn chỉnh chính xác. Đây là một sự cố về mã:

"Prepare the input and the grid:";
S]2[l~]:(f#:+2bW%
S]                "Push string with a space and wrap it in an array. This is the grid.";
  2               "Push a 2 for future use.";
   [l~]           "Read and evaluate the input, wrap it in an array.";
       :(         "Decrement each number by 1.";
         f#       "Map each number i to 2^i.";
           :+     "Sum them all up.";
             2b   "Get the base two representation.";
               W% "Reverse the array.":
"At this point, the stack has the proto-grid at the bottom, and an array of 1s and
 0s on top, which indicates for each hexagon if it's present or not.";

"Next is a for loop, which runs the block for each of those 0s and 1s, storing the
 actual value in I. This block adds the next semi-hexagon or spaces.";
{ ... }fI

"First, append two characters to all existing lines:";
_,2/~:T;{IT):T1<'\'/?S?S++}%
_                            "Duplicate the previous grid.";
 ,2/                         "Get its length, integer-divide by 2.";
    ~:T;                     "Get the bitwise complement and store it in T. Discard it.";
        {                 }% "Map this block onto each line of the grid.";
         I                   "Push the current hexagon flag for future use.";
          T):T               "Push T, increment, store the new value.";
              1<'\'/?        "If T is less than 1, push \, else push /.";
                     S?      "If the current flag is 0, replace by a space.";
                       S++   "Append a space and add it to the current line.";

"So for hexagons this appends '\ ' to the top half and '/ ' to the bottom half.
 For empty rings, it appends '  ' to all lines.";

"Now add a new line to the top and the bottom:"    
__,2/=,2/I'_S?*_S+a@+\I'/S?S++a+
__                               "Get two copies of the grid.";
  ,2/                            "Get its length, integer-divide by 2.";
     =                           "Get that line - this is always the middle line.";
      ,2/                        "Get ITS length, integer'divide by 2.";
         I'_S?*                  "Get a string of that many _ or spaces depending on the 
                                  current flag.";
               _S+               "Duplicate and a space.";
                  a@+            "Wrap in an array, pull up the grid, and prepend the line.";
                     \           "Swap with the other copy.";
                      I'/S?      "Choose between / and a space depending on the flag.";
                           S++   "Append a space, and add both characters to the line.";
                              a+ "Wrap in an array, and append line to the grid.";

"This is all. Rinse and repeat for all rings. The result will look something like this:

_____ 
     \ 
___   \ 
__ \   \ 
_ \ \   \ 
 \ \ \   \ 
_/ / /   / 
__/ /   / 
___/   / 
      / 
_____/ 

Note that there are still trailing spaces.";

"Finish up all lines. These will not be joined together any more, but simply left
 on the stack in pieces to printed out back-to-back at the end of the program.
 The following runs the given block for each line:";
{ ... } /

"This generates the necessary indentation, then mirrors the lines and puts them
 in the right order:"
)T)2*2$,-*\_W%"\/"_W%er\N
)                         "Slice off that trailing space, but leave it on the stack.";
 T                        "Remember T? That still has something like the the size of
                           the grid from the last iteration. In fact it's N-1, where
                           N is the largest visible hexagon. We can use that to figure
                           out how many spaces we need.";
  )2*                     "Increment and double.";
     2$                   "Copy the current line.";
       ,-                 "Subtract its length from 2*N.";
         *                "Repeat the space that often. This is our indentation.";
          \_              "Swap with the line and duplicate.";
            W%            "Reverse the line.";
              "\/"_W%er   "Replace slashes with backslashes and vice versa.";
                       \  "Swap with the original line.";
                        N "Push a line break.";

5

Con trăn - 251, 240, 239 228

l=input()+[0];m=max(l);A=abs;R=range
for j in R(2*m+1):print''.join([[' \\'[(A(j-i+m-1)/2.in l)*(2*m-i)/(j-m-.5)>1],'/'][(A(3*m-i-j)/2.in l)*(i-m-j+.5)/(j-.5-m)>0],'_'][(A(m-j)in l)*(A(2*m-i-.5)<A(m-j))]for i in R(4*m)).rstrip()

Phương pháp thay thế (251):

l=input()+[0]
l.sort()
m=max(l)
M=2*m
s=[[' ']*m*4for j in' '*(M+1)]
for i in l:
 I=2*i;s[m-i][M-i:M+i]=s[m+i][M-i:M+i]='_'*I
 for k in range(i):K=k+1;s[m-k][M-I+k]=s[m+K][M+I-K]='/';s[m-k][M+I-K]=s[m+K][M-I+k]='\\'
for t in s:print''.join(t).rstrip()

3

APL (222 byte trong UTF-8)

(và 133 ký tự)

Vì câu hỏi này đặc biệt yêu cầu số lượng byte trong biểu diễn UTF8, tôi đã thực sự không hiểu nó một chút để nó dài hơn nhưng đại diện UTF8 của nó ngắn hơn. (Cụ thể, ký tự của toán tử đi làm là ba byte trong khi ()chỉ có hai byte , do đó tối ưu hóa không còn hoạt động nữa và nó cũng khiến cho việc gán rất tốn kém.)

{⎕←(~⌽∧\⌽⍵=' ')/⍵}¨↓⊃{⍵{⍺=' ':⍵⋄⍺}¨K↑(-.5×(K←⍴⍵)+⍴⍺)↑⍺}/{Z⍪⌽⊖Z←↑(⊂(⍵/' '),(2×⍵)/'-'),⍵{((-⍵)↑'/'),((2 4-.×⍵⍺)/' '),'\'}¨⌽⍳⍵}¨N[⍋N←,⎕]

Phiên bản trước, ký tự ngắn hơn (124) nhưng sử dụng nhiều byte hơn khi được biểu thị bằng UTF-8 (230, sẽ đặt nó ở vị trí thứ hai):

M←' '⋄{⎕←⍵/⍨~⌽∧\⌽⍵=M}¨↓⊃{⍵{⍺=M:⍵⋄⍺}¨K↑⍺↑⍨-.5×(K←⍴⍵)+⍴⍺}/{Z⍪⊖⌽Z←↑(⊂(⍵/M),'-'/⍨2×⍵),⍵{('/'↑⍨-⍵),'\',⍨M/⍨2 4-.×⍵⍺}¨⌽⍳⍵}¨N[⍋N←,⎕]

Kiểm tra:

      {⎕←(~⌽∧\⌽⍵=' ')/⍵}¨↓⊃{⍵{⍺=' ':⍵⋄⍺}¨K↑(-.5×(K←⍴⍵)+⍴⍺)↑⍺}/{Z⍪⌽⊖Z←↑(⊂(⍵/' '),(2×⍵)/'-'),⍵{((-⍵)↑'/'),((2 4-.×⍵⍺)/' '),'\'}¨⌽⍳⍵}¨N[⍋N←,⎕]
⎕:
      3 1 5 2
     ----------
    /          \
   /   ------   \
  /   / ---- \   \
 /   / / -- \ \   \
/   / / /  \ \ \   \
\   \ \ \  / / /   /
 \   \ \ -- / /   /
  \   \ ---- /   /
   \   ------   /
    \          /
     ----------

Điều này dường như không đáp ứng được thông số kỹ thuật cho các mặt trên và dưới (chúng phải là dấu gạch dưới, không phải dấu gạch nối) và do đó được bù bởi một dòng cho các mặt dưới.
Martin Ender

1

Perl 5, 352 (349 byte + 3 cho anEcờ)

Điều này có lẽ có thể được đánh golf xuống nhiều hơn nữa ..

@b=sort{$a>$b}@F;map{$_<$j||($j=$_)}@b;$k=++$j;for(;$j--;){$z=$"x$j;for($e=$k;--$e>$j;){$z.=$e~~@b?'/ ':'  '} $z.=($j~~@b?'_':$")x(2*$j);$z.=$_~~@b?' \\':'  'for($j+1..$k-1);say$z}for(0..$k-2){$z=$"x$_;for($e=$k;--$e>$_;){$z.=($e-$k+1?$":'').($e~~@b?'\\':$")}$z.=(($_+1)~~@b?'_':$")x(2*$_+2);$z.=($_~~@b?'/':$").($_-$k+1?$":'')for($_+1..$k-1);say$z}

Ung dung:

# sort list of side lengths 
@b=sort{$a>$b}@F; 
# set $k and $j to max side length + 1
map{$_<$j||($j=$_)}@b;$k=++$j;
for(;$j--;){
  $z=$"x$j;
  for($e=$k;--$e>$j;){$z.=$e~~@b?'/ ':'  '}
  $z.=($j~~@b?'_':$")x(2*$j);
  $z.=$_~~@b?' \\':'  'for($j+1..$k-1);
  say$z
}
for(0..$k-2){
  $z=$"x$_;
  for($e=$k;--$e>$_;){$z.=($e-$k+1?$":'').($e~~@b?'\\':$")}
  $z.=(($_+1)~~@b?'_':$")x(2*$_+2);
  $z.=($_~~@b?'/':$").($_-$k+1?$":'')for($_+1..$k-1);
  say$z 
}

Ví dụ ( 1 5 3 14):

              ____________________________
             /                            \
            /                              \
           /                                \
          /                                  \
         /                                    \
        /                                      \
       /                                        \
      /                                          \
     /                 __________                 \
    /                 /          \                 \
   /                 /   ______   \                 \
  /                 /   /      \   \                 \
 /                 /   /   __   \   \                 \
/                 /   /   /  \   \   \                 \
\                 \   \   \__/   /   /                 /
 \                 \   \        /   /                 /
  \                 \   \______/   /                 /
   \                 \            /                 /
    \                 \__________/                 /
     \                                            /
      \                                          /
       \                                        /
        \                                      /
         \                                    /
          \                                  /
           \                                /
            \                              /
             \____________________________/

1

C # - 388 316 byte

Chỉnh sửa: Thay đổi cách nó tránh in dấu cách và ném vào một số LINQ

Chương trình đơn giản có các đối số dòng lệnh. Nó lặp qua mọi char có thể trong mỗi dòng của một hình chữ nhật được xác định bởi kích thước hình lục giác tối đa và nối nó với dòng hiện tại, trước khi cắt các dòng và in chúng liên tiếp (nó tạo ra dòng mới theo dõi tùy chọn).

Mã đánh gôn:

using System.Linq;class P{static void Main(string[]A){var I=A.Select(int.Parse);int m=I.Max(),i,j,y,x;for(j=m+1;j-->-m;){var r="";for(i=-2*m-1;++i<2*m-(y=j<0?-j-1:j);)r+="/\\_- "[(x=i<0?-i-1:i)>y&(x+=y)%2>0&x/2<m&&I.Contains(x/2+1)?(i^j)&1:x-y<(y=j<0?-j:j)&y<=m&I.Contains(y)?j<0?2:3:4];System.Console.WriteLine(r);}}}

Mã bị đánh cắp:

using System.Linq; // all important

class P
{
    static void Main(string[]A)
    {
        var I=A.Select(int.Parse); // create int array

        for(int m=I.Max(),j=m+1,i,y,x;j-->-m;) // for each line...
        {
            var r=""; // current line

            for(i=-2*m-1;++i<2*m-(y=j<0?-j-1:j);) // for each char...
                r+="/\\_- "[// append something to the current line
                (x=i<0?-i-1:i)>y&(x+=y)%2>0&x/2<m&&I.Contains(x/2+1)?
                    (i^j)&1: // slashes as appropriate - I can't work out why this bit works, but it seems to
                x-y<(y=j<0?-j:j)&y<=m&I.Contains(y)?
                    j<0?2:3: // _ or - if required
                4]; // otherwise a space

            System.Console.WriteLine(r); // print current line
        }
    }
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.