Делиться пиццей честно


13

Сложность совместного использования пиццы с друзьями заключается в том, что трудно убедиться, что каждый получает одинаковое количество пепперони на свой ломтик. Итак, ваша задача - решить, как правильно нарезать пиццу, чтобы все остались довольны.

Направления

Напишите программу, которая, учитывая список положений пепперониса на круглой пицце и количества готовых ломтиков, выводит список углов, под которыми пицца должна быть нарезана, чтобы на каждом ломтике было одинаковое количество пепперони. Это.

  • Пицца имеет только один топпинг: пепперони.
  • Ваши друзья не заботятся о размере своего среза, просто они не обмануты из пепперони.
  • Пицца представляет собой круг с центром в начале координат (0, 0)и радиусом1 .
  • Pepperonis - это круги, которые центрированы там, где на входе написано, что они центрированы и имеют радиус0.1
  • Возьмите входные данные как целое число, которое представляет количество срезов, которые должны быть сделаны, и список упорядоченных пар, которые представляют позиции пепперониса в декартовой системе координат. (В любом разумном формате)
  • Выходными данными должен быть список углов, приведенных в радианах, который представляет положение «порезов» для пиццы (в диапазоне0 <= a < 2pi ). (В любом разумном формате) (Точность должна быть как минимум +/- 1e-5.)
  • Вы можете иметь частичные кусочки пепперони на ломтике (например, если пицца имеет одну пепперони на ней, и ее нужно разделить на 10 человек, нарежьте пиццу десять раз, все нарезки прорезают пепперони. Но убедитесь, что это справедливо !)
  • Разрез может (возможно, придется) прорезать несколько пепперони.
  • Pepperonis может перекрываться.

Примеры

Входные данные:

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

Возможный действительный вывод:

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

Вот визуализация этого примера (каждый получает половину пепперони):

введите описание изображения здесь

Больше примеров:

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

введите описание изображения здесь

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

введите описание изображения здесь

счет

Это , поэтому выигрывает наименьшее количество байтов.


С какой точностью должны соответствовать заявки, чтобы считаться действительными?
Rainbolt

@Rainbolt Я бы сказал, что 4 или 5 десятичных знаков должно быть достаточно. Что ты посоветуешь? Я должен добавить это к вопросу.
kukac67

Я не уверен, что каждая проблема разрешима. Что если равномерно распределить 7 ломтиков и 3 пепперони?
Натан Меррилл

1
@NathanMerrill Тогда каждый получит 3/7 пепперони. :) (Размер ломтиков не имеет значения.)
kukac67

1
Попытка пиццы не удалась. Спроси проще в следующий раз. ;)
Илмари Каронен

Ответы:


7

Mathematica, 221 байт

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

Это определяет функцию, которая принимает в качестве параметров количество срезов и список пар для координат peperoni, например

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

Он будет печатать ломтики на консоль, когда она пересекает пиццу.

На большинстве пицц это довольно медленно, потому что (для достижения требуемой точности) я интегрирую область пеперони от 0 до 2π с шагом 1e-5. Чтобы получить чуть менее точный результат за разумное время, вы можете изменить 1.*^-5в конце 1.*^-3.

Как это устроено

Идея состоит в том, чтобы подметать кусочки пиццы, интегрируя их по всей поверхности покрытых кусочками пеперони. Всякий раз, когда эта область достигает требуемого количества пеперони на человека, мы сообщаем текущий угол и сбрасываем счетчик площади.

Чтобы получить область пеперони, мы пересекаем линию с пеперони, чтобы использовать два расстояния от начала координат, где линия пересекается с пеперони. Так как линия продолжается до бесконечности в обоих направлениях, нам нужно ограничить эти расстояния неотрицательными значениями. Это решает две проблемы:

  • Подсчет пересечений с каждым peperoni дважды, один раз положительный и один раз отрицательный (что фактически привело бы к общей площади 0).
  • Считайте только кусочки пеперони, которые входят в происхождение.

Я включу некоторые диаграммы позже.


Ага. Это был мой план атаки. По крайней мере, теперь я могу легко привести примеры! : D
kukac67

Я заметил, что ваша реализация иногда выводит один дополнительный угол, который создает дополнительный срез без пепперони. (например , с помощью ввода: [8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}])
kukac67

@ kukac67 исправлено.
Мартин Эндер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.