Gambarkan segi enam ASCII konsentris

15

Tuliskan program sesingkat mungkin yang mencakup satu set bilangan bulat positif yang berbeda dan menghasilkan rendering ASCII dari segi enam konsentris dengan panjang sisi tersebut, dibuat dari garis miring, garis bawah, spasi, dan baris baru.

Program terpendek dalam byte yang dihitung oleh https://mothereff.in/byte-counter menang.

Contohnya

(Mereka terlihat lebih baik dengan lebih sedikit spasi baris.)

Jika inputnya adalah 1output harus segi enam dengan panjang sisi 1:

 __ 
/  \
\__/

Perhatikan bahwa dua garis bawah digunakan untuk bagian atas dan bawah segi enam sehingga lebih proporsional.

Secara umum, ukuran N hexagon berisi N garis miring pada setiap sisi miring dan 2 * N menggarisbawahi pada kedua bagian atas dan bawah.

Jika inputnya adalah 1 2output harus hexagon konsentris dengan panjang sisi 1 dan 2:

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

Jika inputnya adalah 1 3output harus:

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

Jika inputnya adalah 1 3 2output harus:

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

dll.

Aturan I / O

Input harus berasal dari baris perintah atau stdin tetapi mungkin dalam format apa pun yang paling nyaman.

Sebagai contoh, Anda mungkin memberikan setiap nomor sebagai argumen baris perintah: > myprogram 1 3 2, atau Anda mungkin meminta pengguna untuk memasukkan nomor sebagai daftar terformat: [1, 3, 2].

Output harus menuju stdout atau setara dengan bahasa Anda.

Aturan tambahan

  • Input akan selalu menjadi satu set bilangan bulat positif yang berbeda, tidak harus dalam urutan apa pun .
  • Outputnya harus ...
    • tidak mengandung karakter apa pun selain /\ _dan baris baru.
    • tidak memiliki ruang tambahan atau ruang utama yang tidak perlu.
    • tidak mengandung baris baru yang mengarah asing tetapi mungkin memiliki satu baris tambahan opsional .
  • Jika tidak ada input maka tidak menghasilkan apa-apa (kecuali mungkin satu baris baru).
  • Jika ini membantu Anda dapat mengasumsikan bahwa bilangan bulat input kurang dari 16 .
Hobi Calvin
sumber
Apakah 1merujuk ke segi enam terdalam atau terluar?
NinjaBearMonkey
@ hsl 1(atau nomor apa saja) merujuk ke segi enam dengan panjang sisi 1. (Dengan peringatan bahwa 1 garis miring = 2 menggarisbawahi.) Jadi 1akan selalu merujuk ke segi enam terdalam.
Calvin Hobbies

Jawaban:

4

CJam, 148 116 109 byte

Ini memakan waktu lebih lama dari yang saya harapkan. Awalnya, saya hanya ingin secara iteratif membangun kuadran kiri atas, seperti pada tantangan intan, dan kemudian mendapatkan sisanya dari mirroring. Tetapi saya tidak memperhatikan bahwa garis bawah tidak mematuhi simetri cermin antara bagian atas dan bawah. Jadi saya harus mengulang sebagian besar dari itu, untuk menghasilkan setengah kanan berulang dan kemudian hanya mirror sekali (ke kiri).

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

Uji di sini.

Contoh Fibonacci-esque:

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

Penjelasan:

Seperti yang dinyatakan di atas, saya mulai dengan membangun setengah kanan berulang. Yaitu, pada awalnya saya hanya memiliki satu ruang di grid, dan kemudian untuk setiap cincin yang mungkin, saya mengelilingi kotak yang ada di ruang atau semi-hexagon baru.

Setelah selesai, saya mirror setiap baris ke kiri dan pad dengan ruang terkemuka untuk perataan yang benar. Berikut ini adalah rincian kode:

"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.";
Martin Ender
sumber
5

Python - 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()

Pendekatan alternatif (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()
Falko
sumber
3

APL (222 byte dalam UTF-8)

(dan 133 karakter)

Karena pertanyaan ini secara khusus meminta jumlah byte dalam representasi UTF8, saya harus benar-benar ungolf sedikit sehingga lebih lama tetapi representasi UTF8 lebih pendek. (Khususnya, karakter operator bolak-balik adalah tiga byte sementara ()hanya dua, sehingga optimalisasi tidak berfungsi lagi, dan itu juga membuat penugasan menjadi sangat mahal.)

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

Versi sebelumnya, yang lebih pendek dalam karakter (124) tetapi menggunakan lebih banyak byte ketika diwakili dalam UTF-8 (230, yang akan menempatkannya di tempat kedua):

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

Uji:

      {⎕←(~⌽∧\⌽⍵=' ')/⍵}¨↓⊃{⍵{⍺=' ':⍵⋄⍺}¨K↑(-.5×(K←⍴⍵)+⍴⍺)↑⍺}/{Z⍪⌽⊖Z←↑(⊂(⍵/' '),(2×⍵)/'-'),⍵{((-⍵)↑'/'),((2 4-.×⍵⍺)/' '),'\'}¨⌽⍳⍵}¨N[⍋N←,⎕]
⎕:
      3 1 5 2
     ----------
    /          \
   /   ------   \
  /   / ---- \   \
 /   / / -- \ \   \
/   / / /  \ \ \   \
\   \ \ \  / / /   /
 \   \ \ -- / /   /
  \   \ ---- /   /
   \   ------   /
    \          /
     ----------
marinus
sumber
Ini tampaknya tidak memenuhi spesifikasi untuk sisi atas dan bawah (mereka harus menggarisbawahi, bukan tanda hubung) dan akibatnya diimbangi dengan satu garis untuk sisi bawah.
Martin Ender
1

Perl 5, 352 (349 byte + 3 untuk anE bendera)

Ini mungkin bisa bermain golf lebih banyak ..

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

Tidak Disatukan:

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

Contoh ( 1 5 3 14):

              ____________________________
             /                            \
            /                              \
           /                                \
          /                                  \
         /                                    \
        /                                      \
       /                                        \
      /                                          \
     /                 __________                 \
    /                 /          \                 \
   /                 /   ______   \                 \
  /                 /   /      \   \                 \
 /                 /   /   __   \   \                 \
/                 /   /   /  \   \   \                 \
\                 \   \   \__/   /   /                 /
 \                 \   \        /   /                 /
  \                 \   \______/   /                 /
   \                 \            /                 /
    \                 \__________/                 /
     \                                            /
      \                                          /
       \                                        /
        \                                      /
         \                                    /
          \                                  /
           \                                /
            \                              /
             \____________________________/
es1024
sumber
1

C # - 388 316 byte

Sunting: Mengubah cara menghindari pencetakan spasi tambahan dan melemparkan beberapa LINQ

Program sederhana yang mengambil argumen baris perintah. Itu beralih melalui setiap kemungkinan char di setiap baris persegi panjang yang ditentukan oleh dimensi segi enam maksimum dan menambahkannya ke garis saat ini, sebelum memotong garis dan mencetaknya secara berturut-turut (menghasilkan garis-trailing opsional baru).

Kode Golf:

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

Kode tidak dikunci:

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
        }
    }
}
VisualMelon
sumber
0

APL (Dyalog Classic) , 151 byte (93 dengan pengkodean APL klasik)

{a0⍴⍨1 0+1 2×n←⌈/⍵⋄a[⊃,/i,¨¨⍵+⍵-1+i←⍳¨⍵]←1⋄a←(⊖⍪-)a⋄a[⊃,/(n+⍵,-⍵),¨¨,⍨i]←2⋄' /_\'[4|(⌽,-)a]}

Cobalah online!

ngn
sumber