Lập trình xoắn ốc


14

Viết hàm hoặc chương trình được đặt tên chấp nhận một số nguyên N duy nhất và in (sang STDOUT) hoặc trả về (dưới dạng chuỗi) các thanh N đầu tiên của hình xoắn ốc bên dưới, bắt đầu bằng thanh dọc ở giữa và xoắn ốc theo chiều kim đồng hồ.

        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /

Bạn có thể giả sử rằng 0 <N <= 278. Đầu ra của bạn không thể chứa bất kỳ khoảng trắng nào phía trước ký tự ngoài cùng bên trái của hình xoắn ốc. Bạn có thể tùy ý in một dòng mới duy nhất.

Đối với đầu vào là 10, đầu ra đúng là

   _
  / \ 
  | | 
\___/

Đối với đầu vào là 2, đầu ra đúng là

/
|

Đối với đầu vào là 20, đầu ra đúng là

  ___
 / _ \
/ / \ \ 
| | | |
\___/ /

Một đầu ra sẽ không chính xác bởi vì ký tự ngoài cùng bên trái có trước khoảng trắng là

       ___
      / _ \
     / / \ \ 
     | | | |
     \___/ /

Người chiến thắng là bài nộp ngắn nhất, tính bằng byte.


Đây là một hình xoắn ốc kỳ lạ, 6/8 mặt phát triển lớn hơn trên mỗi cuộc cách mạng và 2 vẫn giữ nguyên kích thước 1
Devon Parsons

1
@DevonParsons Hãy nghĩ rằng nó có hình xoắn ốc hình lục giác, trong đó các thanh dọc ( |) chỉ là ký tự gần nhất có thể đại diện cho cuộc họp của a /\.
mbomb007

Câu trả lời:


5

CJam - 156/147

L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_z::e<2<f{[\\]z::-}$_W=0=)S50*a*\{~3$3$=\tt}/N*

Dùng thử trực tuyến

Nó hoạt động với các đầu vào bao gồm từ 1 đến 378 (nhiều hơn 100 yêu cầu)

Sử dụng cam kết mới nhất (có sẵn công khai trong hg) nhưng mã CJam chưa được phát hành tại thời điểm thử thách này được đăng, giải pháp có thể được rút ngắn xuống còn 147 ký tự:

L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_:.e<2<f.-$_W=0=)S50*a*\{~3$3$=\tt}/N*

Giải trình:

Chương trình lặp lại xây dựng tất cả các hình xoắn ốc như các mảng của [ký tự xy] bắt đầu bằng [0 0 '|], lấy hình xoắn ốc được yêu cầu, điều chỉnh tọa độ sao cho x và y tối thiểu bằng 0, tạo ra một ma trận các khoảng trắng (với số lượng hàng và 50 cột chính xác ) sau đó đặt các ký tự từ hình xoắn ốc và nối các hàng với dòng mới.

L                   start with an empty array (spiral no. 0)
{…}A,1>fX           for X in 1..9 (A=10)
                    each X represents a full 360° tour with groups of X /'es and \'es
    [W1]{…}%        transform the array [-1 1] (W=-1) applying the block to each item
                    the block generates a series of triplets dx, dy, character
                    note: dx is down, dy is right; -1 handles ↑↗→↘, 1 handles ↓↙←↖
        :I          store the current item in I
        0'|         add 0 and |, which will form a triplet with the previous I
        {…}X*       repeat X times
            IIW*    add I and -I
            :J'/    also store -I in J, and add /
        [0J'_]      make an array [0 J _]
        X2*I+*      repeat the array X*2+I times
        [J0_]       make an array [J 0 0]
                    (a 0 instead of a character means only changing the position)
        I1={\}*     if I=1, swap the two arrays (the position adjustment is different
                    for the upper and lower horizontal sections)
        {…}X*       repeat X times
            J_'\    add J, J and \
        0I0         add 0, I and 0 (another position adjustment)
    L*              flatten the array (since we added a few inner arrays)
    3/              split into [dx dy char] triplets
    {…}/            for each triplet
        ~_          dump the 3 items on the stack and duplicate the character
        {…}         if the character is not 0
            [UV@]   make an array [U V char] (U and V are initially 0)
                    U represents "x" and V represents "y"
            a3$+    add it as an element to a copy of the previous spiral
        {…}         else
            ;@      pop the character and bring the previous spiral to the top
        ?           end if
        V@+:V;      V+=dy
        U@+:U;      U+=dx
]                   put all the spirals in an array
ri=                 read token, convert to integer and get that spiral
_z::e<              copy the spiral and get a triplet with the minimum values
2<                  keep only the first 2 items (xmin and ymin)
f{…}                for each triplet and the array [xmin ymin]
    [\\]z::-        subtract xmin and ymin from x and y in the triplet
                    (in the latest CJam code this is simply ".-")
$                   sort the spiral (putting the triplets in order by x then y)
_W=0=)              get the maximum (updated) x and increment it
S50*                make a string of 50 spaces
a*                  put it in an array and repeat it xmax+1 times
                    this is the initial matrix of spaces
\                   swap with the spiral
{…}/                for each triplet in the spiral
    ~               dump the 3 items (x y char) on the stack
    3$3$=           copy the matrix and x, and get the x'th row
    \t              swap with the character and put that character in the y'th position
    t               put the modified row in the x'th position in the matrix
N*                  join the matrix rows with newlines

8

Con trăn 2 290 289

Có lẽ nó rất tệ, nhưng tôi đã thử: D

Đầu ra chứa các khoảng trắng ở cuối, nhưng điều đó không bị cấm trong thông số kỹ thuật.

Cập nhật: đã lưu 1 byte khi thay đổi \nthành ;.

m=x=y=c=0
l,f=1,[31*[' ']for t in[0]*31]
for i in[0]*input():
 k=m%4;f[14+y+(2<m<6)][14+x-(m>3)],x,y,c='|/_\\'[k],x+(k>0)*(2*(4>m)-1),y+(k!=2)*(2*(2<m<6)-1),c+1
 if(c==l)*(m%2)+(k==0)+(k==2)*(c==2*l-1+m//3):m,c,l=(m+1)%8,0,l+m//7
print'\n'.join(''.join(e[16-l*2:])for e in f if[' ']*31!=e)

Không gian lưu thông là tốt. Tôi đã thử nghiệm điều này. Công việc tốt!
Rainbolt

4

JavaScript (ES6) 256 288 321

Chỉnh sửa các bước hợp nhất.
Chỉnh sửa mã Golfed fiddling để cắt thêm một số char

Xây dựng đầu ra lặp đi lặp lại vào mảng r, theo dõi vị trí x và y hiện tại và hướng hiện tại. Khi vị trí x hoặc y <0, toàn bộ mảng r được điều chỉnh lại.

Các biến chính:

  • mảng kết quả hoặc hàng
  • x, y vị trí hiện tại.
  • s hướng hiện tại (0..7) (hoặc trạng thái hiện tại)
  • d ký hiệu hiện tại để vẽ (0..3) -> '| \ _ /'
  • l vị trí runnig trên chuỗi hiện tại (xuống 0)
  • bán kính xoắn ốc hiện tại (nhiều hơn hoặc ít hơn)
F=n=>
  (w=>{
    for(r=b=[],s=y=x=d=0;n--;
      d&&--l||((s=s+1&7,d=s&3)?l=d-2?w:s/2-2+w+w:w+=!s))
      s>0&s<4?++x:s>4?x?--x:r=r.map(v=>' '+v):b+='  ',
      q=r[s>2&s<6?++y:y]||b,
      r[y]=(q+b).slice(0,x)+'|/_\\'[d]+q.slice(x+1),
      s<2|s>6?y?--y:r=[,...r]:x+=!d*2,x-=!d
  })(1)||r.join('\n')

Ung dung

F=n=>{
  var r=[], s,x,y,d,w,l, q
  for(l=w=1, s=x=y=d=0; n--;)
  {
    if (s>2 && s<6) ++y; // right side, inc y before drawing

    if (x < 0) // too left, adjust
    {
      r = r.map(v=>' '+v) // shift all to right
      ++x; // move current position to right
    }
    if (y < 0) // too up
    {
      r = [q='',...r] // shift all to bottom
      ++y; // move current position to bottom
    }
    q = r[y] || ''; // current row, if undefined convert to empty string
    r[y] = (q+' '.repeat(x)).slice(0,x) + '|/_\\'[d] + q.slice(x+1); // add current symbol in the x column

    if (s<2 || s>6) --y; // left side, dec y after drawing

    if (s>0 && s<4) // always change x after drawing
      ++x;
    else if (s > 4)
      --x;

    --l; // decrement current run
    if (l == 0) // if 0, need to change direction
    {
      s = (s+1) % 8; // change direction
      d = s % 4; // change symbol
      if (d == 0)
      { 
        // vertical direction, adjust x and if at 0 increase radius
        l = 1 // always 1 vertical step
        if (s == 0)
          ++x, ++w
        else
          --x
      }
      else
      {
        if (d != 2)
        {
          l = w; // diaagonal length is always w
        }
        else if (s == 2)
        {
          l = w+w-1 // top is radius * 2 -1
        }
        else
        {
          l = w+w+1 // bottom is radius * 2 +1
        }
      }
    }
  }    
  return r.join('\n')
}  

Kiểm tra trong bảng điều khiển Firefox / FireBug (hoặc JSFiddle thx @Rainbolt)

;[1, 2, 10, 20, 155, 278].forEach(x=>console.log(F(x)))

Đầu ra

|

/
|

   _
  / \
  | |
\___/

  ___
 / _ \
/ / \ \
| | | |
\___/ /

      ___________
     / _________ \
    / / _______ \ \
   / / / _____ \ \ \
  / / / / ___ \ \ \ \
 / / / / / _ \ \ \ \ \
/ / / / / / \ \ \ \ \ \
| | | | | | | | | | | |
\ \ \ \ \___/ / / / /
 \ \ \ \_____/ / / /
  \ \ \_______/ / /
   \ \_________/ /
    \___________/

        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /

Tôi đã thử nghiệm điều này và nó hoạt động. Đây là một jsfiddle cho thấy câu trả lời của bạn hoạt động. Hãy kết hợp nó vào câu trả lời của bạn.
Rainbolt

2

Bình thường 166 165

Tôi vừa dịch câu trả lời Python của mình cho Pyth, với các kỹ năng Pyth không tuyệt vời của tôi. Nôn kết quả là dưới đây.

Jm*31]d*31dK0=G0=H0=Y1VQ X@J++14H&<2K<K6+14-G<3K@"|/_\\"%K4~G*<0%K4-*2>4K1~H*n2%K4-*2&<2K>6K1~Z1I||&qZY%K2!%K4&q2%K4qZ+-*2Y1/K3~Y/K7=K%+1K8=Z0;jbmj>d-16*2Ykfn*31]dTJ
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.