ピザを公平に共有する


13

友人とピザを共有することの難しさは、スライスで全員が同じ量のペパロニを確実に摂取できるようにするのが難しいことです。だから、あなたの仕事は、みんなが幸せになるようにピザをどのように公正にスライスするかを決めることです。

行き方

円形ピザのペパロニの位置と作成するスライスの数のリストを指定して、各スライスが同じ量のペパロニになるようにピザをカットする角度のリストを出力するプログラムを作成しますそれ。

  • ピザのトッピングはペパロニのみです。
  • お友達は、ペパロニからだまされないというだけで、スライスのサイズを気にしません。
  • ピザは、原点(0, 0)を中心とし、半径が1円です
  • ペパロニは、入力が中央にあり、半径が0.1
  • 入力を、作成するスライスの数を表す整数、およびデカルト座標系でのペパロニの位置を表す順序ペアのリストとして受け取ります。(合理的な形式で)
  • 出力は、ピザの「カット」の位置を表すラジアン単位の角度のリストである必要があります(範囲内0 <= a < 2pi)。(合理的な形式で)(精度は少なくともでなければなりません+/- 1e-5。)
  • スライスにペパロニの部分的な部分を置くことができます(例えば、ピザにペパロニが1つあり、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

ここに画像の説明を入力してください

得点

これはなので、最小バイト数が勝ちます。


提出物を有効とみなすためには、どの程度の精度が必要ですか
レインボルト14

@Rainbolt小数点以下4桁または5桁で十分だと思います。何を指示してるんですか?質問に追加する必要があります。
kukac67 14

すべての問題が解決できるかどうかはわかりません。7つのスライスと3つのペパロニが等間隔に配置されている場合はどうなりますか?
ネイサンメリル14

1
@NathanMerrillそうすると、誰もが3/7のペパロニを手に入れることになります。:)(スライスのサイズは関係ありません。)
kukac67 14

1
ピザハットの試みは失敗しました。次回は簡単に聞いてください。;)
イルマリカロネン14

回答:


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

ゴルフをしていない:

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

ピザを横断するときに、スライスをコンソールに出力します。

ほとんどのピザでは、(必要な精度を達成するために)1e-5のステップで0から2πまでのペペロニ領域を統合しているため、これはかなり低速です。妥当な時間内にわずかに精度の低い結果を得るには1.*^-5、最後にをに変更し1.*^-3ます。

使い方

アイデアは、覆われたペペロニの部分の領域を統合しながら、ピザのスライスを一掃することです。そのエリアが1人あたり必要なペペロニ量に達するたびに、現在の角度を報告し、エリアカウンターをリセットします。

掃き出されたペペローニ領域を取得するには、線をペペローニと交差させて、原点からの2つの距離を使用します。ここで、線はペペローニと交差します。線は両方向に無限に伸びているため、これらの距離を非負の値に固定する必要があります。これにより、2つの問題が解決されます。

  • 各ペペロニとの交点を2回、1回は正、1回は負と数えます(実際には全体の面積は0になります)。
  • 起源に含まれるペペローニのくさびのみを数えます。

後でいくつかの図を含めます。


うん。これが私の攻撃計画でした。少なくとも今はもっと簡単に例を作ることができます!:D
kukac67 14

あなたの実装は、ペパロニのない余分なスライスを作成する1つの余分な角度を時々出力することに気付きました。(たとえば、入力:[8, {{0.4, 0.2}, {-0.3, 0.1}, {-0.022, -0.5}, {0.3, -0.32}}]
kukac67 14

@ kukac67が修正されました。
マーティンエンダー14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.