Vấn đề Ender hạnh phúc


32

Các vấn đề kết thúc có hậu (thực sự là một định lý) tiểu bang đó

Bất kỳ tập hợp năm điểm trong mặt phẳng ở vị trí chung đều có tập con gồm bốn điểm tạo thành các đỉnh của một tứ giác lồi.

Vấn đề đã được Paul Erdős đặt tên như vậy khi hai nhà toán học lần đầu tiên nghiên cứu về vấn đề này, Ester Klein và George Szekeres, đã đính hôn và sau đó kết hôn.

Làm rõ:

  • Vị trí chung ở đây có nghĩa là không có ba điểm nào là cộng tuyến.
  • Các tứ giác được hình thành bởi bốn đỉnh sẽ luôn được coi là không giao nhau, không phân biệt thứ tự của các điểm. Ví dụ, với bốn điểm [1 1], [1 2], [2 1], [2 2]tứ giác mục đích là quảng trường, không phải là bow-tie:

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

  • Một tứ giác không giao nhau là lồi nếu không có góc trong vượt quá 180 độ; hoặc tương đương nếu cả hai đường chéo nằm bên trong tứ giác.

Các thách thức

Cho 5 điểm có tọa độ nguyên dương, xuất 4 trong số các điểm đó tạo thành một tứ giác lồi.

Quy tắc

Nếu có một vài giải pháp (nghĩa là, một vài bộ 4 điểm), bạn luôn có thể chọn đầu ra một trong số chúng hoặc tất cả.

Các định dạng đầu vào và đầu ra linh hoạt như bình thường (mảng, danh sách, danh sách danh sách, chuỗi có dấu phân cách hợp lý, v.v.).

Mã golf, ít byte nhất thắng.

Các trường hợp thử nghiệm

  1. Đầu vào:

    [6 8] [1 10] [6 6] [5 9] [8 10]
    

    Chỉ có một đầu ra có thể:

    [6 8] [1 10] [6 6] [5 9]
    
  2. Đầu vào:

    [3 8] [7 5] [6 9] [7 8] [5 1]
    

    Có năm giải pháp:

    [3 8] [7 5] [6 9] [7 8]
    [3 8] [7 5] [6 9] [5 1]
    [3 8] [7 5] [7 8] [5 1]
    [3 8] [6 9] [7 8] [5 1]
    [7 5] [6 9] [7 8] [5 1]
    
  3. Đầu vào:

    [4 8] [1 9] [9 9] [10 2] [1 6]
    

    Có ba giải pháp:

    [4 8] [1 9] [10 2] [1 6]
    [4 8] [9 9] [10 2] [1 6]
    [1 9] [9 9] [10 2] [1 6]
    

    Để minh họa, đây là ba giải pháp cho trường hợp này:

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


14
Tôi đang mong đợi một câu trả lời từ Martin với một cảm xúc tích cực được thể hiện trong đó.
El'endia Starman

1
Vấn đề kết thúc có hậu không bị nhầm lẫn với vấn đề Ender hạnh phúc, đó là tìm cách ngăn những tân binh quân đội phát hiện ra những mô phỏng mà họ đang chơi là có thật .
dùng253751

Câu trả lời:


24

CJam, 37 34 32 byte

{e!Wf<{2*3ew{)f.-~W%.*:-V>},!}=}

Không chắc :-Vlà có đủ hạnh phúc không, nhưng như K Zhang chỉ ra, =}cuối cùng cũng có. :)

Điều này chỉ in một giải pháp vì loại bỏ trùng lặp sẽ tốn kém hơn.

Kiểm tra nó ở đây.

Giải trình

Ý tưởng khá đơn giản. Chúng tôi tạo ra tất cả các tứ giác có thể (bao gồm tất cả các thứ tự của các điểm) và sau đó chỉ cần chọn các tứ giác lồi. Chúng tôi kiểm tra độ lồi bằng cách nhìn vào mọi cặp cạnh và kiểm tra xem tất cả chúng có cùng hướng hay không.

Ý nghĩa xoay có thể thu được khá dễ dàng từ một sản phẩm chấm. Nếu bạn lấy ba điểm liên tiếp trên một hình tứ giác và vẽ các đường thẳng từ điểm thứ nhất đến điểm thứ hai và điểm thứ nhất đến điểm thứ ba, sau đó chiếu điểm thứ hai vào phương vuông góc của điểm trước ... bạn sẽ nhận được một số có dấu hiệu cho bạn biết cho dù ba điểm này rẽ trái hay phải. (Tôi có lẽ nên thêm một sơ đồ cho việc này.) Điều này "chiếu lên vuông góc" nghe có vẻ khá liên quan, nhưng thực sự chỉ có nghĩa là chúng ta đảo ngược một trong hai vectơ và trừ đi các thành phần sau khi nhân thay vì thêm chúng. Vì vậy, đây là mã ...

e!       e# Generate all permutations of the five input points.
Wf<      e# Discard the fifth point in each permutations, giving all
         e# possible quadrilaterals.
{        e# Select the first for which this block gives a truthy result...
  2*     e#   Double the list of points, so that it includes each cyclically
         e#   adjacent set of three points.
  3ew    e#   Get all sublists of length 3, i.e. all sets of three consecutive
         e#   points (with two duplicates).
  {      e#   Filter these sets of three points...
    )    e#     Pull off the last point.
    f.-  e#     Subtract it from the other two, giving vectors from it to
         e#     to those.
    ~    e#     Unwrap the array dumping both vectors on the stack.
    W%   e#     Reverse one of them.
    .*   e#     Element-wise multiplication.
    :-   e#     Subtract the second element from the first. This completes
         e#     the projection.
    V>   e#     Check whether it's greater than 0. This is *false* for right-
         e#     turning sets of three points.
  },     e#   If all corners are right-turning, this will result
         e#   in an empty array.
  !      e#   Logical NOT - hence, only quadrilaterals where all corners
         e#   are right-turning give something truthy.
}=

2
Chắc chắn, một con vịt hạnh phúc!
Luis Mendo

1
@LuisMendo Tôi nghĩ rằng hai nhân vật cuối cùng trông giống như một nụ cười =}
K Zhang

!}cũng có thể được coi là một cái nháy mắt
Jezzamon

2
Jon Skeet của CodeGolf .. điều này thật tuyệt vời
Alex Carlsen

8

MATLAB, 67 byte

I=input('');for k=~eye(5);if nnz(convhull(I(k,:)))>4;I(k,:),end;end

Đầu vào ở dạng ma trận 2D trong đó các cột lần lượt là X và Y:

[6 8; 1 10; 6 6; 5 9; 8 10]
[3 8; 7 5; 6 9; 7 8; 5 1]
[4 8; 1 9; 9 9; 10 2; 1 6]

Tất cả các bộ 4 điểm tạo ra tứ giác lồi được hiển thị theo cùng một định dạng.

Đây là một bản demo được sửa đổi một chút để hoạt động với Octave

Giải trình

Giải pháp này lấy tất cả các tập hợp con gồm 4 điểm của đầu vào (thứ tự không thành vấn đề). Để làm điều này, chúng tôi tạo ma trận danh tính và phủ định nó : ~eye(5). Chúng tôi lặp qua các cột của ma trận này và k(chỉ số vòng lặp) là một mảng logic xác định điểm nào trong 4 điểm cần xem xét. Sau đó, chúng tôi sử dụng điều này để lấy 4 điểm XY này từ đầu vào ( I(k,:)).

Sau đó, chúng tôi tính toán vỏ lồi của 4 điểm này ( convhull). Đầu ra của convhulllà các chỉ số của đầu vào tương ứng với các điểm tạo nên vỏ lồi (với chỉ số đầu tiên được nhân đôi để đóng thân tàu).

Đối với một tứ giác lồi, tất cả bốn điểm sẽ là một phần của thân lồi có cùng điểm ( nnz(convhull(points)) > 4). Nếu chúng tôi phát hiện ra rằng đây là trường hợp, chúng tôi sẽ hiển thị các điểm được sử dụng cho lần lặp cụ thể này.


4

Javascript (ES6), 306 293 283 byte

c=(v,w,x)=>(w[0]-v[0])*(w[1]-x[1])-(w[1]-v[1])*(w[0]-x[0])>0?1:0
i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])
j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}
f=(v)=>(r=[],k(...v),r)

Giải thích :

Hàm ctính tích tích chéo của vectơ giữa 3 điểm liền kề của đa giác và trả về 1 nếu nó dương và 0 nếu không (lưu ý: sản phẩm chéo không thể bằng 0 vì các điểm không thể đồng tuyến tính).

j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}

Hàm kjtạo tất cả các hoán vị tuần hoàn (bỏ qua đảo ngược thứ tự) của mảng đầu vào.

i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])

Hàm 'i' sau đó được gọi cho mỗi hoán vị tuần hoàn để tính tổng của hàm ccho mỗi trong ba bộ ba tọa độ liền kề. Nếu tất cả các sản phẩm chéo đều có cùng một dấu hiệu thì tất cả chúng sẽ là 0 hoặc 1 và tổng là 0 (modulo 4) và đa giác bị lõm và được đẩy vào mảng đầu ra. Nếu bất kỳ bộ ba nào có một dấu hiệu khác thì tổng sẽ là khác không (modulo 4) và đa giác là lồi.

f=(v)=>(r=[],k(...v),r)

Hàm fđược sử dụng để khởi tạo mảng đầu ra và sau đó gọi các hàm trên trước khi trả lại đầu ra.

Các xét nghiệm :

c=(v,w,x)=>(w[0]-v[0])*(w[1]-x[1])-(w[1]-v[1])*(w[0]-x[0])>0?1:0
i=(v,w,x,y)=>(c(v,w,x)+c(w,x,y)+c(x,y,v)+c(y,v,w))%4==0&&r.push([v,w,x,y])
j=(v,w,x,y)=>{i(v,w,x,y);i(v,w,y,x);i(v,x,w,y)}
k=(v,w,x,y,z)=>{j(v,w,x,y);j(v,w,x,z);j(v,w,y,z);j(v,x,y,z);j(w,x,y,z)}
f=(v)=>(r=[],k(...v),r)

tests = [
  [[6,8],[1,10],[6,6],[5,9],[8,10]],
  [[3,8],[7,5],[6,9],[7,8],[5,1]],
  [[4,8],[1,9],[9,9],[10,2],[1,6]]
];

tests.forEach(
  (test,i)=>{
    console.log( "Test " + (i+1) );
    f(test).forEach(
      (x)=>console.log( "  " + x.map((e)=>"("+e[0]+","+e[1]+")").join(','))
    );
  }
);

Chỉnh sửa :

Cũng có thể xử lý các điểm đồng tuyến tính bằng phiên bản gốc và thay đổi hai dòng đầu tiên thành:

t=(a,b,c)=>Math.sign((b[0]-a[0])*(b[1]-c[1])-(b[1]-a[1])*(b[0]-c[0]))
p=(a,b,c,d)=>[t(a,b,c),t(b,c,d),t(c,d,a),t(d,a,b)].filter(x=>x).reduce((p,c,i,a)=>p&c==a[0],1)
q=(a,m,n,o)=>[a[0],a[m],a[n],a[o]]
f=(a)=>{r=[];for(i=0;i<5;i++){b=a.slice();b.splice(i,1);r.push(q(b,1,2,3));r.push(q(b,1,3,2));r.push(q(b,2,1,3))}return r.filter((a)=>p(...a))}

Tuy nhiên, vì trường hợp đó được loại trừ cụ thể trong câu hỏi nên các ký tự phụ không cần thiết.


3

Toán học 105 96 byte

Select[#~Subsets~{4},f@#&]&chọn, từ một danh sách (5) điểm, những tập hợp con gồm 4 điểm thỏa mãn f.

fđược thỏa mãn khi mỗi điểm, trong 4 điểm trong một tập, dối trá trên RegionBoundarycủa ConvexHullcủa 4 điểm.

f@p_:=Apply[And,RegionBoundary@ConvexHullMesh@p~RegionMember~#&/@p];
Select[#~Subsets~{4},f@#&]&

Các trường hợp thử nghiệm

1. Chúng ta hãy nhìn vào 5 vỏ con lồi của các tập con (mỗi điểm 4) của {{6, 8}, {1, 10}, {6, 6}, {5, 9}, {8, 10}} .

Select[#~Subsets~{4},f@#&[{{6, 8}, {1, 10}, {6, 6}, {5, 9}, {8, 10}}]

{{{6, 8}, {1, 10}, {6, 6}, {5, 9}}}


{{6, 8}, {1, 10}, {6, 6}, {5, 9}} là giải pháp duy nhất; mỗi trong bốn điểm đóng vai trò là một đỉnh của thân lồi (có cùng 4 điểm).

dung dịch


{{6, 8}, {1, 10}, {6, 6}, {8, 10}} không phải là một giải pháp; thân tàu lồi chỉ có 3 đỉnh. {6, 8} nằm trong thân tàu.

thất bại1


Các tập con còn lại cũng không phải là giải pháp:

thất bại2

thất bại3

thất bại4


2. {{4, 8}, {1, 9}, {9, 9}, {10, 2}, {1, 6}} có ba giải pháp.

Select[#~Subsets~{4},f@#&[{{4, 8}, {1, 9}, {9, 9}, {10, 2}, {1, 6}}]

{
{{4, 8}, {1, 9}, {10, 2}, {1, 6}},
{{4, 8}, {9, 9}, {10, 2}, {1, 6 }},
{{1, 9}, {9, 9}, {10, 2}, {1, 6}}
}


3. {{3, 8}, {7, 5}, {6, 9}, {7, 8}, {5, 1}} có 5 giải pháp.

Select[#~Subsets~{4},f@#&[{{3, 8}, {7, 5}, {6, 9}, {7, 8}, {5, 1}}]

{
{{3, 8}, {7, 5}, {6, 9}, {7, 8}},
{{3, 8}, {7, 5}, {6, 9}, {5, 1 }},
{{3, 8}, {7, 5}, {7, 8}, {5, 1}},
{{3, 8}, {6, 9}, {7, 8}, {5 , 1}},
{{7, 5}, {6, 9}, {7, 8}, {5, 1}}
}

Lưu ý rằng mỗi điểm trong năm điểm nằm trên đường biên của thân lồi của tất cả các điểm.

Nếu bất kỳ một trong các điểm bị loại bỏ, 4 điểm còn lại sẽ là các đỉnh của thân lồi giảm.

sol2

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.