Mutlu Ender sorunu


32

Mutlu son sorun (aslında bir teoremi) devletler bu

Genel pozisyondaki düzlemdeki beş nokta kümesinin dışbükey bir dörtgen köşesini oluşturan dört noktadan oluşan bir alt kümesi vardır.

Problem Paul Erdős tarafından, ilk olarak problem üzerinde çalışan iki matematikçi, Ester Klein ve George Szekeres’in nişanlanıp daha sonra evlenmeleri olarak adlandırılmıştı.

Açıklamalar:

  • Buradaki genel pozisyon , üç noktanın hiçbirinin ortak olmadığı anlamına gelir.
  • Dört köşenin oluşturduğu dörtgen, puanların sırasına bakılmaksızın her zaman kesişmeyen sayılır. Örneğin, dört puan verilir [1 1], [1 2], [2 1], [2 2]amaçlanan dörtgen, kare, yay olup-kravat:

    görüntü tanımını buraya girin

  • Kesişmeyen bir dörtgen, iç açı 180 dereceyi geçmediğinde dışbükeydir ; veya her iki köşegen dörtgen içinde uzanıyorsa eşit olarak.

Meydan okuma

Pozitif tamsayı koordinatlarına sahip 5 puan verildiğinde, dışbükey bir dörtgen oluşturan noktaların 4'ünü verin.

kurallar

Birkaç çözüm varsa (yani, 4 noktadan oluşan birkaç küme), sürekli olarak bunlardan birini veya hepsini çıkarmayı seçebilirsiniz.

Giriş ve çıkış biçimleri her zamanki gibi esnektir (diziler, listeler, listeler listesi, makul ayırıcılara sahip dizeler, vb.).

Kod golf, en az bayt kazanır.

Test durumları

  1. Giriş:

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

    Sadece bir tane çıktı var:

    [6 8] [1 10] [6 6] [5 9]
    
  2. Giriş:

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

    Beş çözüm var:

    [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. Giriş:

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

    Üç çözüm var:

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

    Açıklamak gerekirse, bu durumda bu üç çözüm:

görüntü tanımını buraya girin


14
Martin'den, burada ifade edilen olumlu bir duygu ile bir cevap bekliyorum.
El'endia Starman

1
Mutlu son problemi, asker askerlerinin oynadıkları simülasyonları keşfetmelerini engellemenin bir yolunu bulmak olan mutlu Ender problemiyle karıştırılmamasıdır .
user253751

Yanıtlar:


24

CJam, 37 34 32 bayt

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

:-VYeterince mutlu olup olmadığından emin değilim , ama K Zhang'ın işaret ettiği =}gibi, sonunda var. :)

Bu yalnızca bir çözümü yazdırır, çünkü kopyaları kaldırmak daha pahalı olacaktır.

Burada test et.

açıklama

Fikir oldukça basit. Olası tüm dörtgenleri (tüm puanların sıraları dahil) üretiriz ve sonra dışbükeyleri seçeriz. Her iki kenara da bakarak ve hepsinin aynı yönde dönüp dönmediğini kontrol ederek konveksiteyi test ediyoruz.

Dönme hissi bir nokta üründen oldukça kolay bir şekilde elde edilebilir. Ardışık üçlü bir dörtlü noktadan alırsanız, ilkinden ikincisine, ilkinden üçüncüsüne çizgi çizer ve ikincisini eskinin dikine yansıtırsanız, işareti size söyleyen bir sayı alırsınız. Bu üç noktanın sola mı sağa mı döndüğü. (Bunun için muhtemelen bir diyagram eklemeliyim.) Bu "dikine yansıtma" oldukça ilgili seslerdir, ancak gerçekten sadece iki vektörden birini tersine çevirdiğimiz ve bileşenleri eklemek yerine çarpma işleminden sonra çıkardığımız anlamına gelir. Demek kod burada ...

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
Tabii, mutlu bir ördek!
Luis Mendo

1
@LuisMendo Son iki karakterin bir surat gibi göründüğünü düşünüyorum =}
K Zhang

!}göz kırpması da düşünülebilir
Jezzamon

2
CodeGolf'dan Jon Skeet .. bu muhteşem
Alex Carlsen

8

MATLAB, 67 bayt

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

Girdi, sütunların sırasıyla X ve Y olduğu bir 2D matris şeklindedir:

[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]

Dışbükey dörtgenler oluşturan tüm 4 nokta kümeleri aynı formatta görüntülenir.

İşte Octave ile çalışmak için biraz değiştirilmiş bir demo

açıklama

Bu çözüm, girişin 4 noktasındaki tüm alt kümelerini alır (sıra önemli değildir). Bunu yapmak için, biz kimlik matris oluşturmak ve bunu reddetmiyorum: ~eye(5). Bu matrisin sütunlarında dolaşıyoruz ve k(döngü indeksi), göz önünde bulundurulacak 4 noktadan hangisini belirleyen mantıksal bir dizidir. Bunu daha sonra bu 4 XY noktasını girdiden ( I(k,:)) almak için kullanırız.

Daha sonra bu 4 puanın ( convhull) dışbükey kabuğunu hesaplıyoruz . Çıkışı convhull, dışbükey gövdeyi oluşturan noktalara karşılık gelen giriş endeksleridir (gövdeyi kapatmak için ilk indeks kopyalanır).

Dışbükey bir dörtgen için, dört noktanın tümü aynı noktaların dışbükey gövdesinin bir parçası olacaktır ( nnz(convhull(points)) > 4). Bunun böyle olduğunu tespit edersek, bu belirli yineleme için kullanılan noktaları görüntüleriz.


4

Javascript (ES6), 306 293 283 bayt

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)

Açıklama :

İşlev c, vektörün çapraz ürününü poligonun 3 bitişik noktası arasında hesaplar ve pozitifse 0 ise 1 ile döner (not: çapraz ürün, noktalar birlikte doğrusal olamayacağından sıfır olamaz).

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

İşlev kve jgiriş dizisinin tüm döngüsel permütasyonlarını (sırasını ters çevirerek) üreten.

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])

Daha sonra 'i' fonksiyonu, her bir döngüsel permütasyon için c, bitişik koordinatların 4 üçlüsünün her birinin fonksiyonunun toplamını hesaplamak için çağrılır . Çapraz ürünlerin hepsi aynı işarete sahipse, hepsi 0 veya 1 olacaktır ve toplam 0 (modulo 4) olacaktır ve poligon içbükeydir ve çıkış dizisine itilir. Herhangi bir üçlünün farklı bir işareti varsa, toplam sıfır olmayacaktır (modulo 4) ve poligon dışbükeydir.

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

İşlev f, çıkış dizisini başlatmak ve ardından çıkışı döndürmeden önce yukarıdaki işlevleri çağırmak için kullanılır.

Testler :

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(','))
    );
  }
);

Düzenle :

Orijinal sürümü kullanarak ve ilk iki satırı şu şekilde değiştirerek eş doğrusal noktaları da kaldırabilir:

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

Ancak, bu dava soruda özellikle dışlandığı için fazladan karakterler gerekli değildir.


3

Mathematica 105 96 bayt

Select[#~Subsets~{4},f@#&]&(5) nokta listesinden, 4 noktanın tatmin edici alt kümelerini seçer f.

fkarşılandığı zaman bir dizi 4 puan her bir nokta, üzerinde yer alır RegionBoundaryve ConvexHull4 puan.

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

Test Kılıfları

1. {{6, 8}, {1, 10}, {6, 6}, {5, 9}, {8, 10}} alt kümelerinin 5 dışbükey kabuğuna bakalım. .

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}} tek çözümdür; dört noktadan her biri dışbükey gövdenin tepe noktası olarak hizmet eder (aynı 4 noktadan).

çözüm


{{6, 8}, {1, 10}, {6, 6}, {8, 10}} bir çözüm değildir; dışbükey gövdesi sadece 3 köşeye sahiptir. {6, 8} gövde içinde uzanır.

fail1


Kalan alt kümeler de çözüm değildir:

Fail2

fail3

fail4


2. {{4, 8}, {1, 9}, {9, 9}, {10, 2}, {1, 6}} üç çözüme sahiptir.

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}} 5 çözüme sahiptir.

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

Beş noktanın her birinin, tüm noktaların dışbükey kabuğunun sınırında olduğunu unutmayın.

Noktalardan herhangi biri kaldırılırsa, kalan 4 puanın her biri azaltılmış dışbükey gövdenin tepe noktaları olacaktır.

sol2

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.