Tôi không biết


22

Lưu ý: Tiêu đề của câu hỏi này phải là "Lặp lại", nhưng vì tiêu đề cần có ít nhất 15 ký tự, nên có một số khoảng trống vô hình. Lưu ý này là như vậy mà thách thức có thể được tìm kiếm.


Thử thách

Đưa ra một danh sách hữu hạn các điểm tích phân duy nhất trong mặt phẳng, tìm một đa giác có các đỉnh chính xác là các điểm đó, không tự giao nhau.

Chi tiết

  • Là đầu vào, bạn có thể lấy ví dụ hai danh sách với mỗi tọa độ x và y hoặc danh sách các cặp.
  • Danh sách đầu vào chứa ít nhất 3 điểm.
  • Lưu ý rằng điều này có nghĩa là không bao giờ có một giải pháp duy nhất.
  • Danh sách các đầu vào có thể được coi là không cùng tuyến tính (các điểm không thể được chứa trong một dòng), điều này có nghĩa là thực sự có một đa giác không tự giao nhau như vậy.
  • Các góc ở mỗi đỉnh là tùy ý, điều này bao gồm 180 °.
  • Đối với đầu vào có độ dài n, đầu ra phải là hoán vị (p1,p2,p3,...,pn)trong (1,2,3,...,n)đó kmục -th pkđại diện cho pđiểm thứ trong danh sách đầu vào. Điều này có nghĩa là chúng ta có một dòng từ p1đến p2, một dòng từ p2đến p3vv, cũng như một dòng từ pnđến p1. (Bạn cũng có thể sử dụng các chỉ số dựa trên 0.) Ngoài ra, bạn chỉ có thể xuất danh sách các điểm đầu vào theo đúng thứ tự.

Ví dụ

Giả sử chúng ta có điểm [(0,0),(0,1),(1,0),(-1,0),(0,-1)]và chúng ta muốn biểu diễn đường dẫn sau:

nhập mô tả hình ảnh ở đây

Điều này có nghĩa là chúng tôi sẽ đưa ra danh sách [5,1,4,2,3]

Dưới đây là một số gợi ý khác để thử (Tôi khuyên bạn nên xem các ô tương ứng để xác minh mục tiêu.)

Triangle
[(0,0),(0,1),(1,0)]

S-Curve
[(0,0),(0,1),(0,2),(0,3),(0,4),(1,0),(2,0),(2,1),(2,2),(2,3),(2,4),(3,4),(4,0),(4,1),(4,2),(4,3),(4,4)]

L-Shape
[(4,0),(1,0),(3,0),(0,0),(2,0),(0,1)]

Menger Sponge
[(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1),(21,1),(22,1),(23,1),(24,1),(25,1),(26,1),(27,1),(1,2),(3,2),(4,2),(6,2),(7,2),(9,2),(10,2),(12,2),(13,2),(15,2),(16,2),(18,2),(19,2),(21,2),(22,2),(24,2),(25,2),(27,2),(1,3),(2,3),(3,3),(4,3),(5,3),(6,3),(7,3),(8,3),(9,3),(10,3),(11,3),(12,3),(13,3),(14,3),(15,3),(16,3),(17,3),(18,3),(19,3),(20,3),(21,3),(22,3),(23,3),(24,3),(25,3),(26,3),(27,3),(1,4),(2,4),(3,4),(7,4),(8,4),(9,4),(10,4),(11,4),(12,4),(16,4),(17,4),(18,4),(19,4),(20,4),(21,4),(25,4),(26,4),(27,4),(1,5),(3,5),(7,5),(9,5),(10,5),(12,5),(16,5),(18,5),(19,5),(21,5),(25,5),(27,5),(1,6),(2,6),(3,6),(7,6),(8,6),(9,6),(10,6),(11,6),(12,6),(16,6),(17,6),(18,6),(19,6),(20,6),(21,6),(25,6),(26,6),(27,6),(1,7),(2,7),(3,7),(4,7),(5,7),(6,7),(7,7),(8,7),(9,7),(10,7),(11,7),(12,7),(13,7),(14,7),(15,7),(16,7),(17,7),(18,7),(19,7),(20,7),(21,7),(22,7),(23,7),(24,7),(25,7),(26,7),(27,7),(1,8),(3,8),(4,8),(6,8),(7,8),(9,8),(10,8),(12,8),(13,8),(15,8),(16,8),(18,8),(19,8),(21,8),(22,8),(24,8),(25,8),(27,8),(1,9),(2,9),(3,9),(4,9),(5,9),(6,9),(7,9),(8,9),(9,9),(10,9),(11,9),(12,9),(13,9),(14,9),(15,9),(16,9),(17,9),(18,9),(19,9),(20,9),(21,9),(22,9),(23,9),(24,9),(25,9),(26,9),(27,9),(1,10),(2,10),(3,10),(4,10),(5,10),(6,10),(7,10),(8,10),(9,10),(19,10),(20,10),(21,10),(22,10),(23,10),(24,10),(25,10),(26,10),(27,10),(1,11),(3,11),(4,11),(6,11),(7,11),(9,11),(19,11),(21,11),(22,11),(24,11),(25,11),(27,11),(1,12),(2,12),(3,12),(4,12),(5,12),(6,12),(7,12),(8,12),(9,12),(19,12),(20,12),(21,12),(22,12),(23,12),(24,12),(25,12),(26,12),(27,12),(1,13),(2,13),(3,13),(7,13),(8,13),(9,13),(19,13),(20,13),(21,13),(25,13),(26,13),(27,13),(1,14),(3,14),(7,14),(9,14),(19,14),(21,14),(25,14),(27,14),(1,15),(2,15),(3,15),(7,15),(8,15),(9,15),(19,15),(20,15),(21,15),(25,15),(26,15),(27,15),(1,16),(2,16),(3,16),(4,16),(5,16),(6,16),(7,16),(8,16),(9,16),(19,16),(20,16),(21,16),(22,16),(23,16),(24,16),(25,16),(26,16),(27,16),(1,17),(3,17),(4,17),(6,17),(7,17),(9,17),(19,17),(21,17),(22,17),(24,17),(25,17),(27,17),(1,18),(2,18),(3,18),(4,18),(5,18),(6,18),(7,18),(8,18),(9,18),(19,18),(20,18),(21,18),(22,18),(23,18),(24,18),(25,18),(26,18),(27,18),(1,19),(2,19),(3,19),(4,19),(5,19),(6,19),(7,19),(8,19),(9,19),(10,19),(11,19),(12,19),(13,19),(14,19),(15,19),(16,19),(17,19),(18,19),(19,19),(20,19),(21,19),(22,19),(23,19),(24,19),(25,19),(26,19),(27,19),(1,20),(3,20),(4,20),(6,20),(7,20),(9,20),(10,20),(12,20),(13,20),(15,20),(16,20),(18,20),(19,20),(21,20),(22,20),(24,20),(25,20),(27,20),(1,21),(2,21),(3,21),(4,21),(5,21),(6,21),(7,21),(8,21),(9,21),(10,21),(11,21),(12,21),(13,21),(14,21),(15,21),(16,21),(17,21),(18,21),(19,21),(20,21),(21,21),(22,21),(23,21),(24,21),(25,21),(26,21),(27,21),(1,22),(2,22),(3,22),(7,22),(8,22),(9,22),(10,22),(11,22),(12,22),(16,22),(17,22),(18,22),(19,22),(20,22),(21,22),(25,22),(26,22),(27,22),(1,23),(3,23),(7,23),(9,23),(10,23),(12,23),(16,23),(18,23),(19,23),(21,23),(25,23),(27,23),(1,24),(2,24),(3,24),(7,24),(8,24),(9,24),(10,24),(11,24),(12,24),(16,24),(17,24),(18,24),(19,24),(20,24),(21,24),(25,24),(26,24),(27,24),(1,25),(2,25),(3,25),(4,25),(5,25),(6,25),(7,25),(8,25),(9,25),(10,25),(11,25),(12,25),(13,25),(14,25),(15,25),(16,25),(17,25),(18,25),(19,25),(20,25),(21,25),(22,25),(23,25),(24,25),(25,25),(26,25),(27,25),(1,26),(3,26),(4,26),(6,26),(7,26),(9,26),(10,26),(12,26),(13,26),(15,26),(16,26),(18,26),(19,26),(21,26),(22,26),(24,26),(25,26),(27,26),(1,27),(2,27),(3,27),(4,27),(5,27),(6,27),(7,27),(8,27),(9,27),(10,27),(11,27),(12,27),(13,27),(14,27),(15,27),(16,27),(17,27),(18,27),(19,27),(20,27),(21,27),(22,27),(23,27),(24,27),(25,27),(26,27),(27,27)]

Nếu chúng ta có 4 điểm O (0,0), A (1,0), B (0,1), C (0,2), thì đa giác OABC có tự giao nhau không?
ngn

@ngn Đó là một điểm tốt tôi không xem xét! Tôi sẽ phải suy nghĩ về nó. Nếu bạn có bất kỳ lý lẽ cho hoặc chống lại điều này xin vui lòng cho tôi biết.
flawr

@ngn Tôi tính đa giác này là tự giao nhau. Lý do là tôi định nghĩa một đa giác sẽ tự giao nhau nếu có một điểm chung của hai cạnh không phải là điểm cuối.
flawr

@flawr Tôi phải rút câu trả lời của mình sau đó, nó thất bại khi có nhiều điểm đồng tuyến tính ở góc tối đa từ điểm tham chiếu.
ngn

Câu trả lời:


10

Toán học 29 28 byte

FindShortestTour (16 Byte) thực hiện thủ thuật nhưng cung cấp một số thông tin không liên quan không được yêu cầu (độ dài đường dẫn và trở về điểm bắt đầu).

Most@*Last@*FindShortestTour

chỉ đưa ra câu trả lời (-1 byte nhờ @ user202729)

Để hình dung, sử dụng Graphics@Line[g[[%]]], nơi %hoán vị được tìm thấy ở trên và g là danh sách điểm ban đầu.

Dưới đây là hình dung của giải pháp cho miếng bọt biển Menger: nhập mô tả hình ảnh ở đây

Đây là một giải pháp trên 1000 điểm ngẫu nhiên:

nhập mô tả hình ảnh ở đây

Chìa khóa ở đây là biết rằng giải pháp cho vấn đề nhân viên bán hàng du lịch hoặc du lịch ngắn nhất sẽ không bao giờ mang lại giao điểm khi khoảng cách Euclide được sử dụng làm số liệu. Một trong những bước để bản địa hóa một giải pháp và đảm bảo sự tối ưu là loại bỏ các giao điểm đó.


6
Sử dụng thuật toán NP để giải quyết vấn đề P chỉ vì nó ngắn hơn. +1 (???).
dùng202729

1
@*dường như để tiết kiệm một byte.
dùng202729


6

JavaScript (ES6), 365 341 byte

Không có bất kỳ tích hợp nào, điều này hóa ra dài hơn tôi mong đợi. Nhiều byte được dành để phát hiện các phân đoạn chồng chéo.

Đưa đầu vào như một mảng [x,y]tọa độ. Trả về một hoán vị của đầu vào.

f=(a,p=[],o=([p,P],[q,Q],[r,R])=>Math.sign((S=[(p>q?r<q|r>p:r<p|r>q)|(P>Q?R<Q|R>P:R<P|R>Q),...S],Q-P)*(r-q)-(q-p)*(R-Q)))=>[...p,p[0]].some((A,i,P)=>P.some((C,j)=>j>i+1&&P[++j+!i]&&[E=o(A,B=P[i+1],C,S=[]),F=o(A,B,D=P[j]),G=o(C,D,A),H=o(C,D,B)].some(v=>!v&!S.pop())|E!=F&G!=H))?0:a[0]?a.some((_,i)=>r=f(b=[...a],p.concat(b.splice(i,1))))&&r:p

Bản giới thiệu

Đoạn mã này ghi lại đầu ra và vẽ đường dẫn tương ứng trong một khung vẽ.

Làm sao?

Đây là cấu trúc của hàm đệ quy chính f () , bỏ qua mã kiểm tra giao nhau:

f = (a, p = []) =>                    // a = array of points, p = current path
  [...p,                              // build a closed path array P[] by adding the first
         p[0]]                        // point at the end of p[]
  .some((A, i, P) =>                  // for each point A at position i in P:
    P.some((C, j) =>                  //   for each point C at position j in P:
      j > i + 1 &&                    //     test whether C is at least 2 positions after A
      P[++j +                         //     and C is not the last point
              !i] &&                  //     and i > 0 or C is not the penultimate point
      intersection(                   //     and there's an intersection between
        A, P[i + 1], C, P[j]          //     the segments (A, P[i + 1]) and (C, P[j + 1])
      )                               //     (j was incremented above)
    )                                 //   end of inner some()
  ) ?                                 // end of outer some(); if truthy:
    0                                 //   discard this path by stopping recursion
  :                                   // else:
    a[0] ?                            //   if there's at least one remaining point:
      a.some((_, i) =>                //     for each remaining point at position i:
        r = f(                        //       do a recursive call with:
          b = [...a],                 //         a copy b[] of a[] without a[i] and
          p.concat(b.splice(i, 1)))   //         the extracted point added to the path
      ) && r                          //     end of some(); return the result, if any
    :                                 //   else:
      p                               //     this is a valid path: return it

Dưới đây là chi tiết của bài kiểm tra giao lộ () . Trang này cung cấp một lời giải thích toàn diện về thuật toán được sử dụng.

[                                     // build an array containing:
  E = o(A, B = P[i + 1], C, S = []),  //   E = test of (A, B, C) (+ initialization of S[])
  F = o(A, B, D = P[j]),              //   F = test of (A, B, D)
  G = o(C, D, A),                     //   G = test of (C, D, A)
  H = o(C, D, B)                      //   H = test of (C, D, B)
]                                     //
.some(v =>                            // the segments are collinear and overlapping if:
  !v &                                //   any value above is 0
  !S.pop()                            //   and the corresponding entry in S[] is falsy
) |                                   // the segments intersect if:
E != F & G != H                       //   E is not equal to F and G is not equal to H

Cuối cùng, đây là định nghĩa của hàm trợ giúp o () :

o = (                                             // given three points represented by
  [p, P], [q, Q], [r, R]                          // a lowercase letter for x
) =>                                              // and an uppercase letter for y:
  Math.sign(                                      //
    (                                             //   1) prepend to the array S[]
      S = [                                       //      a boolean which is true if the
        (p > q ? r < q | r > p : r < p | r > q) | //      segment (P, Q) would not contain
        (P > Q ? R < Q | R > P : R < P | R > Q),  //      the point R, assuming that the
        ...S                                      //      3 points are collinear
      ],                                          //
                                                  //   2) return the orientation of P, Q, R:
      Q - P                                       //        -1 = counterclockwise
    ) * (r - q) - (q - p) * (R - Q)               //         0 = collinear
  )                                               //        +1 = clockwise

... vui lòng giải thích?
dùng202729

1
@ user202729 (* lau tay qua trán *) Xong!
Arnauld

5

APL (Dyalog Classic) , 42 38 byte

{⍋(⍪,(|z)ׯ1*⊢=⌈/)12z0j1⊥¨⍵-⍵[⊃⍋↑⍵]}

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

Đầu vào là danh sách các cặp tọa độ. Đầu ra là một hoán vị dựa trên 0.

là danh sách các điểm - đối số để { }

⍵[⊃⍋↑⍵] là điểm thấp nhất bên trái

⍵- dịch tất cả các điểm sao cho thấp nhất bên trái ở gốc tọa độ của hệ tọa độ

0j1 đơn vị tưởng tượng i = sqrt (-1)

0j1⊥¨ giải mã tọa độ như thể các chữ số trong hệ thống số cơ sở i - tức là biến (x, y) thành một số phức ix + y

z← giao cho z

12○tính toán các đối số của số phức, còn gọi là góc theta hoặc hàm tròn APL 12

(⍪,(|z)ׯ1*⊢=⌈/)là một chuyến tàu tính toán mặt nạ boolean trong đó các góc cực đại ( ⊢=⌈/), biến 0 1 trong mặt nạ thành 1 ¯1 bằng cách tăng ¯1 lên công suất tương ứng ( ¯1*), nhân với độ lớn của các số phức |z, và nối nó ở bên phải ( ,) của ma trận 1 cột mỏng cao ( ) của các góc.

lớp - trả về hoán vị sẽ sắp xếp các hàng của ma trận theo từ vựng theo thứ tự tăng dần


@ user202729 chúng sẽ được sắp xếp theo tiêu chí thứ hai - khoảng cách (tức là hàm tròn 10, còn gọi là cường độ phức tạp)
ngn
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.