Partager la pizza équitablement

13

La difficulté de partager une pizza avec des amis est qu'il est difficile de s'assurer que tout le monde reçoit la même quantité de pepperoni sur sa tranche. Donc, votre tâche est de décider comment trancher une pizza de manière équitable afin que tout le monde soit heureux.

instructions

Écrivez un programme qui, étant donné une liste des positions des pepperonis sur une pizza circulaire et le nombre de tranches à faire, affiche une liste des angles sur lesquels la pizza doit être coupée afin que chaque tranche ait la même quantité de pepperoni il.

  • La pizza n'a qu'une seule garniture: le pepperoni.
  • Vos amis ne se soucient pas de la taille de leur tranche, juste qu'ils ne sont pas trompés de pepperoni.
  • La pizza est un cercle centré sur l'origine (0, 0)et avec un rayon de1 .
  • Les pepperonis sont des cercles qui sont centrés partout où l'entrée indique qu'ils sont centrés et ont un rayon de0.1
  • Prenez l'entrée comme un entier qui représente le nombre de tranches à faire et une liste de paires ordonnées qui représentent les positions des pepperonis sur un système de coordonnées cartésiennes. (Dans tout format raisonnable)
  • La sortie doit être une liste d'angles donnée en radians qui représente les positions des "coupes" de la pizza (dans la plage0 <= a < 2pi ). (Dans tout format raisonnable) (La précision doit être d'au moins +/- 1e-5.)
  • Vous pouvez avoir des morceaux partiels de pepperoni sur une tranche (par exemple. Si une pizza a un pepperoni dessus et qu'elle doit être partagée par 10 personnes, coupez la pizza dix fois, toutes les coupes tranchant à travers le pepperoni. Mais assurez-vous que c'est juste !)
  • Une coupe peut (peut-être devoir) couper à travers plusieurs pepperonis.
  • Pepperonis peut se chevaucher.

Exemples

Contribution:

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

Sortie valide possible:

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

Voici une visualisation de cet exemple (tout le monde obtient un demi-pepperoni):

entrez la description de l'image ici

Plus d'exemples:

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

entrez la description de l'image ici

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

entrez la description de l'image ici

Notation

Il s'agit de , donc le moins d'octets gagne.

kukac67
la source
À quelle précision les soumissions doivent-elles adhérer pour être considérées comme valides?
Rainbolt
@Rainbolt Je dirais que 4 ou 5 décimales devraient suffire. Que suggérez-vous? Je devrais l'ajouter à la question.
kukac67
Je ne suis pas sûr que chaque problème soit résoluble. Et s'il y a 7 tranches et 3 pepperoni régulièrement espacés?
Nathan Merrill
1
@NathanMerrill Ensuite, tout le monde obtiendrait 3/7 d'un pepperoni. :) (La taille des tranches n'a pas d'importance.)
kukac67
1
La tentative de chapeau de pizza a échoué. Demandez plus facilement la prochaine fois. ;)
Ilmari Karonen

Réponses:

7

Mathematica, 221 octets

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

Non golfé:

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

Ceci définit une fonction qui prend comme paramètres le nombre de tranches et une liste de paires pour les coordonnées peperoni, comme

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

Il imprimera les tranches sur la console pendant qu'il traverse la pizza.

Sur la plupart des pizzas, c'est assez lent, car (pour obtenir la précision requise) j'intègre la zone peperoni de 0 à 2π par pas de 1e-5. Pour obtenir un résultat légèrement moins précis dans un laps de temps raisonnable, vous pouvez remplacer le 1.*^-5à la fin par 1.*^-3.

Comment ça fonctionne

L'idée est de balayer les tranches de pizza tout en intégrant sur la zone des morceaux de peperoni couverts. Chaque fois que cette zone atteint la quantité requise de peperoni par personne, nous rapportons l'angle actuel et réinitialisons le compteur de zone.

Pour obtenir la zone de peperoni balayée, nous coupons la ligne avec le peperoni pour utiliser les deux distances depuis l'origine, où la ligne coupe avec le peperoni. Puisqu'une ligne s'étend à l'infini dans les deux directions, nous devons restreindre ces distances à des valeurs non négatives. Cela résout deux problèmes:

  • Compter les intersections avec chaque peperoni deux fois, une fois positive et une fois négative (ce qui donnerait en fait une zone globale de 0).
  • En ne comptant que les quartiers de morceaux de peperoni qui comprennent à l'origine.

Je vais inclure quelques diagrammes plus tard.

Martin Ender
la source
Oui. C'était mon plan d'attaque. Au moins, je peux plus facilement faire des exemples maintenant! : D
kukac67
J'ai remarqué que votre implémentation génère parfois un angle supplémentaire qui créerait une tranche supplémentaire sans pepperoni. (par exemple avec entrée: [8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}])
kukac67
@ kukac67 fixe.
Martin Ender