Pizzaları adil bir şekilde paylaşmak


13

Pizzaları arkadaşlarınızla paylaşmanın zorluğu, herkesin diliminde aynı miktarda pepperoni aldığından emin olmanın zor olmasıdır. Yani, göreviniz herkesin mutlu olması için bir pizzayı nasıl dilimleyeceğinize karar vermektir.

Talimatlar

Dairesel bir pizza üzerindeki pepperonis pozisyonlarının bir listesi ve yapılacak dilim sayısı göz önüne alındığında, her dilimin aynı miktarda biberli olması için pizzanın kesilmesi gereken açıların bir listesini veren bir program yazın. o.

  • Pizza sadece bir tepesi vardır: biberli.
  • Arkadaşlarınız dilimlerinin boyutlarını umursamıyorlar, sadece herhangi bir biberli aldatmasınlar.
  • Pizza, menşe merkezli (0, 0)ve yarıçaplı1 bir dairedir .
  • Pepperonlar, girdinin ortalandığını ve yarıçapı olduğunu söylediği her yerde ortalanmış dairelerdir0.1
  • Girdiyi yapılacak dilim sayısını temsil eden bir tamsayı ve pepperonisin kartezyen koordinat sistemindeki konumlarını temsil eden sıralı çiftlerin bir listesini alın . (Makul bir biçimde)
  • Çıktı , pizzanın ( aralıktaki ) "kesiklerinin" konumlarını temsil eden radyan cinsinden verilen açıların bir listesi olmalıdır . (Makul bir biçimde) (Hassasiyet en azından olmalıdır .)0 <= a < 2pi+/- 1e-5
  • Bir dilimde kısmi bir biberli parçaya sahip olabilirsiniz (örn. Bir pizzanın üzerinde bir biberli varsa ve 10 kişi tarafından paylaşılması gerekiyorsa, pizzayı on kez kesin, tüm kesikler biberli dilimlemeyi kesin. !)
  • Bir kesik çoklu pepperonlardan dilimlenebilir (gerekebilir).
  • Pepperonis üst üste gelebilir.

Örnekler

Giriş:

8 people, pepperonis: (0.4, 0.2), (-0.3, 0.1), (-0.022, -0.5), (0.3, -0.32)

Olası geçerli çıktı:

slices at:
0, 0.46365, 0.68916, 2.81984, 3.14159, 4.66842, 4.86957, 5.46554

İşte bu örneğin bir görselleştirmesi (herkes yarım biberli alır):

resim açıklamasını buraya girin

Daha fazla örnek:

Input: 9 people, 1 pepperoni at: (0.03, 0.01)
Output: 0, 0.4065, 0.8222, 1.29988, 1.94749, 3.03869, 4.42503, 5.28428, 5.83985

resim açıklamasını buraya girin

Input: 5, (0.4, 0.3), (0.45, 0.43), (-0.5, -0.04)
Output: 0, 0.64751, 0.73928, 0.84206, 3.18997

resim açıklamasını buraya girin

puanlama

Bu , bu yüzden en az bayt sayısı kazanır.


Başvurular geçerli sayılmak için hangi hassasiyete uymalıdır?
Rainbolt

@Rainbolt 4 veya 5 ondalık basamağın yeterli olması gerektiğini söyleyebilirim. Sen ne önerirsin? Soruya eklemeliyim.
kukac67

Her sorunun çözülebileceğinden emin değilim. Eşit aralıklı 7 dilim ve 3 biberli varsa ne olur?
Nathan Merrill

1
@NathanMerrill O zaman herkes 3/7 bir biberli alır. :) (Dilimlerin boyutu önemli değil.)
kukac67

1
Pizza şapkası girişimi başarısız oldu. Bir dahaki sefere daha kolay bir soru sorun. ;)
Ilmari Karonen

Yanıtlar:


7

Mathematica, 221 bayt

f=(A=Pi.01Length@#2/#;l=m/.Solve[Norm[{a,b}-m{Cos@t,Sin@t}]==.1,m];k=(l/.{a->#,b->#2})&@@@#2;d=1.*^-5;For[Print[h=B=0];n=1,n<#,h+=d,(B+=If[Im@#<0,0,d(Max[#2,0]^2-Max[#,0]^2)/2])&@@@(k/.{t->h});If[B>A,n+=1;Print@h;B-=A]])&

Ungolfed:

f = (
   A = Pi .01 Length@#2/#;
   l = m /. Solve[Norm[{a, b} - m {Cos@t, Sin@t}] == .1, m];
   k = (l /. {a -> #, b -> #2}) & @@@ #2;
   d = 1.*^-5;
   For[Print[h = B = 0]; n = 1, n < #, h += d,
    (
      B += If[Im@# < 0, 0, d (Max[#2, 0]^2 - Max[#, 0]^2)/2]
    ) & @@@ (k /. {t -> h});
    If[B > A, n += 1; Print@h; B -= A]
   ]
) &

Bu, parametre olarak dilim sayısını ve peperoni koordinatları için bir çift listesini alan bir işlevi tanımlar.

f[8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}]

Dilim pizzaya geçerken konsola yazdırır.

Çoğu pizzada, bu oldukça yavaştır, çünkü (gerekli hassasiyeti elde etmek için) 1 ila 5'lik adımlarla peperoni alanını 0'dan 2π'ye entegre ediyorum. Makul bir süre içinde biraz daha az kesin bir sonuç 1.*^-5elde etmek için sonunda değerini olarak değiştirebilirsiniz 1.*^-3.

Nasıl çalışır

Fikir, peperoni parçalarının alanı üzerine entegre olurken pizza dilimlerini süpürmektir. Bu alan kişi başına gerekli miktarda peperoni'ye çarptığında, mevcut açıyı rapor eder ve alan sayacını sıfırlarız.

Peperoni alanını süpürmek için, peperoni ile çizgiyi, çizginin peperoni ile kesiştiği başlangıç ​​noktasından iki mesafeyi kullanmak için kesişiriz. Bir çizgi her iki yönde sonsuza kadar uzandığından, bu mesafeleri negatif olmayan değerlere sıkıştırmamız gerekir. Bu iki sorunu çözer:

  • Her peperoni ile bir kez pozitif ve bir kez negatif olan kavşakların sayılması (aslında 0'ın toplam alanına neden olur).
  • Sadece menşeli peperoni parçalarının takozlarını saymak.

Daha sonra bazı diyagramlar ekleyeceğim.


Evet. Bu benim saldırı planımdı. En azından şimdi daha kolay örnekler verebilirim! : D
kukac67

Uygulamanızın bazen pepperoni olmadan ekstra bir dilim oluşturacak ekstra bir açı verdiğini fark ettim. : (giriş örneğin [8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}])
kukac67

@ kukac67 düzeltildi.
Martin Ender
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.