Ділиться піцу справедливо


13

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

Напрямки

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

  • Піца має лише один начинка: пепероні.
  • Ваших друзів не хвилює розмір їхнього шматочка, лише щоб їх не обдурили жодні перчинки.
  • Піца - це коло з центром походження (0, 0)та радіусом1 .
  • Пеппероніс - це кола, які розташовані по центру, де б вхід не говорив, що вони по центру і мають радіус0.1
  • Введіть введення як ціле число, яке представляє кількість фрагментів, які потрібно зробити, і список упорядкованих пар, які представляють положення пепероніса на декартовій системі координат. (У будь-якому розумному форматі)
  • Вихід повинен бути переліком кутів, наведеним у радіанах, що представляє позиції "надрізів" піци (в діапазоні0 <= a < 2pi ). (У будь-якому розумному форматі) (Точність повинна бути як мінімум +/- 1e-5.)
  • Ви можете мати частинки шматочка пепероні на шматочку (напр., Якщо піца містить один пепероні на ній, і його потрібно ділити 10 людьми, піцу виріжте десять разів, а всі надрізи проріжте через пепероні. Але переконайтеся, що це справедливо !)
  • Розріз може (можливо, доведеться) прорізати через кілька пепперонісів.
  • Пеппероніс може перекриватися.

Приклади

Вхід:

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

Математика, 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]])&

Безголівки:

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

Це визначає функцію, яка приймає в якості параметрів кількість зрізів і список пар для координат пепероні, як

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.

Як це працює

Ідея полягає в тому, щоб підмітати шматочки піци, інтегруючи їх над площею покритих шматочків пепероні. Щоразу, коли ця площа потрапляє на необхідну кількість пепероні на людину, ми повідомляємо про поточний кут і скидаємо лічильник площі.

Щоб одержати область пепероні, ми перетинаємо лінію з пепероні, щоб використати дві відстані від початку, де лінія перетинається з пепероні. Оскільки лінія поширюється на нескінченність в обох напрямках, нам потрібно зафіксувати ці відстані до негативних значень. Це вирішує дві проблеми:

  • Підрахунок перехресть з кожним пепероном двічі, один раз позитивним і один раз негативним (що фактично призведе до загальної площі 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.