피자를 공정하게 공유


13

피자를 친구들과 공유하는 데 어려움은 모든 사람이 슬라이스에서 같은 양의 페퍼로니를 얻는 것이 어렵다는 것입니다. 따라서 당신의 임무는 모든 사람이 행복하도록 피자를 공정하게 슬라이스하는 방법을 결정하는 것입니다.

지도

원형 피자에서 페퍼로니의 위치 목록과 만들 슬라이스 수를 제공하여 각 슬라이스가 같은 양의 페퍼로니를 갖도록 피자를 잘라야하는 각도 목록을 출력하는 프로그램을 작성하십시오. 그것.

  • 피자에는 단 하나의 토핑이 있습니다 : 페퍼로니.
  • 친구들은 슬라이스 크기에 신경 쓰지 않고 페퍼로니로 속이지 않습니다.
  • 피자는 원점을 중심으로 원이다 (0, 0)와 함께 반경1 .
  • 페퍼로니는 입력이 중앙에 있고 반경이0.1
  • 직교 좌표계에서 페퍼로니의 위치를 ​​나타내는 슬라이스 수와 정렬 된 쌍목록 을 나타내는 정수 로 입력하십시오 . (합리적인 형식으로)
  • 출력은 피자에 대한 "컷"위치를 나타내는 라디안 으로 표시된 각도 목록이어야합니다 ( 범위0 <= a < 2pi ). (적절한 형식으로) (정밀도 이상이어야 +/- 1e-5합니다.)
  • 페퍼로니 조각 한 조각을 슬라이스에 넣을 수 있습니다 (예 : 피자에 페퍼로니가 하나 있고 10 명이 공유해야하는 경우 피자를 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 1

모든 문제를 해결할 수 있는지 잘 모르겠습니다. 7 개의 슬라이스와 3 개의 페퍼로니가 고르게 간격을두고 있다면 어떨까요?
Nathan Merrill

1
@NathanMerrill 그러면 모든 사람이 페퍼로니의 3/7을 얻게됩니다. :) (조각의 크기는 중요하지 않습니다.)
kukac67

1
피자 모자 시도에 실패했습니다. 다음에 더 쉽게 물어보십시오. ;)
Ilmari Karonen

답변:


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

피자를 가로 지르면서 슬라이스를 콘솔에 인쇄합니다.

대부분의 피자에서 이것은 (필요한 정밀도를 달성하기 위해) peperoni 영역을 1e-5 단계로 0에서 2π까지 통합하기 때문에 상당히 느립니다. 합리적인 시간 내에 약간 덜 정확한 결과를 얻으려면 1.*^-5끝에를로 변경하면 됩니다 1.*^-3.

작동 원리

아이디어는 피자 조각을 쓸어 넘기면서 덮은 페페로니 조각의 영역을 통합하는 것입니다. 해당 영역이 1 인당 필요한 양의 페페로니에 도달 할 때마다 현재 각도를보고하고 영역 카운터를 재설정합니다.

페페로니 영역이 스윕 아웃되도록하기 위해 선을 페페로니와 교차시켜 선이 페페로니와 교차하는 원점으로부터 두 거리를 사용합니다. 선은 양방향으로 무한대로 확장되므로이 거리를 음이 아닌 값으로 고정해야합니다. 이렇게하면 두 가지 문제가 해결됩니다.

  • 각 페페로니와의 교차점을 두 번, 한 번은 긍정적이고 한 번은 부정적인 것으로 계산합니다 (실제로 전체 영역 0에 도달 함).
  • 원산지에 포함 된 peperoni 조각의 웨지 만 계산합니다.

나중에 몇 가지 다이어그램을 포함하겠습니다.


네. 이것이 나의 공격 계획이었다. 적어도 지금은 더 쉽게 예제를 만들 수 있습니다! : D
kukac67

구현시 때때로 페퍼로니가없는 여분의 슬라이스를 생성하는 하나의 여분의 각도를 출력하는 것으로 나타났습니다. (예를 들어, 입력으로 [8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}])
kukac67

@ kukac67 수정되었습니다.
Martin Ender
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.