共有誕生日パーティー


9

オフィス(「オフィス」と呼ぶことにします)は、オフィスの誕生日パーティーを統合することで、2019年の無駄な時間を削減します。同じ週の月曜日から金曜日(含む)の間に誕生日がある2人は、その週のいつかで共有誕生日パーティーで祝われます。誕生日が土曜日または日曜日に当たる人々はパーティーをまったく開催しません。

実際の誕生日を共有しない人と誕生日パーティーを共有したくない人もいます。彼らは共有の誕生日パーティーを持つことは非常に怒っています。

オフィスをシミュレートして、共有の誕生日パーティーについて誰かが非常に怒る最初の週を見つけます。

チャレンジ

次の基本ルールに従って、シミュレートされたオフィスの誰かが共有誕生日パーティー非常に怒る 2019年の最初のISO週番号を出力するプログラムまたは関数を記述します。

  • N > 1の整数を入力します。これは、オフィスの労働者の数です。
  • Nの誕生日自体は(2月29無視する)1月1日から12月31日にランダムに一様に分布しています。
  • ただし、共有誕生日パーティーを決定するための稼働週は、2019-W01-1(2018-12-31)と2019-W52-7(2019-12-29)の間の2019 ISO週日です。新しいISO週が毎週月曜日に始まります。(これが、この課題のISO週間について本当に知っておく必要があるすべてだと思います)。
  • 以下のためのNのオフィスの人々 、それぞれが持つ1/3の確率がある非常に怒っている 共有の誕生日パーティーのあなたもそれをシミュレートする必要がありますので、性格のタイプを。
  • しかし、パーティーが同じ誕生日を持っている人々と共有されれば、彼らは怒ることはありません。
  • 非常に怒っている人の最初の発生に対して、ISO週番号(週番号が明確である限り、これの正確な形式は柔軟です)を出力します。怒っている人がいない場合は、ISOウィークと混同しないものを出力したり、プログラムでエラーが発生する可能性があります。

いくつかの単純化する仮定:

  • 私が述べたように、2月29日問題を完全に無視してください(不要な複雑化)
  • 祝日(これは国際社会なので祝日は異なります)を無視し、平日にオフィスが開いていると想定します。

ルール

これはコードゴルフです。各言語のバイトでの最短の回答が勝ちます。デフォルトの抜け穴は禁止されています。

コードの説明を歓迎します。

実施例

入力N = 7の考案された例1。最初の列と2番目の列は規則で説明されているようにランダムです(もちろん、実際にはランダムではありません)。

Angry Type
Person?    Birthday   ISO Week   Comment
================================================================================
   N       2018-12-31      W01   In the 2019 ISO week date year 
   Y       2018-12-31      W01   Same birthday, so no anger happens
   N       2019-02-05      W06   
   Y       2019-03-15      W11   No anger happens because other W11 b-day is a Saturday     
   N       2019-03-16      W11
   N       2019-09-08      W36   My birthday!
   Y       2019-12-30       -    Not in the 2019 ISO week date year

したがって、怒り​​は起こりません。プログラムまたは関数がエラーになるか、ISO週番号と混同されないものを出力する可能性があります。

Nが指定されていない例2 。

Angry Type
Person?    Birthday   ISO Week   Comment
================================================================================
   N       2019-01-19      W03   
   Y       2019-02-04      W06   
   N       2019-02-05      W06   No anger because not an angry person
  ...             ...      ...   (No angry people until...)
   Y       2019-03-12      W11   Very Angry Person!
   N       2019-03-14      W11   
  ...             ...      ...   ... 

出力は、W11または同等のものになります。


3
... 2019年2月29日はありません。機能する例を追加できますか?
シャギー

N

4
@Shaggyで誕生日が2月29日の人がそこで働いている可能性があります。無意味なエッグケースIMOを追加するだけなので、その可能性を無視するように言っています。
ngm '25

1
怒っている人がいない場合は、W01からW52に相当しない適切な出力、またはエラーメッセージで問題ありません。私が携帯電話を使用していないときに、質問を編集してこれを反映します。
ngm

1
たぶん私なのかもしれませんが、誕生日パーティーを共有するのではなく、むしろ共有します。週末に誕生日を迎えるすべての人を引き裂きます。
Kevin Cruijssen、2018

回答:


5

パイソン2172の 202バイト

def f(n):
 D=set();A=[];R=randint
 while n:
	n-=1;w,d=R(1,52),R(1,5)
	if R(0,364)>104:D|={(w,d)};A+=[w]*(R(0,2)>1)
 return next((a for a in sorted(A)if[w for w,d in D].count(a)>1),0)
from random import*

オンラインでお試しください!

おっとっと!要件を満たしていません。コストは30バイトです。

OPによって、誕生日が2月29日でないことが示されています。

12月30日が誕生日の場合、2019年のISO週には該当しません。そのため、いずれにしても、2019年の非常に怒っているISO週になることはできません。

それはあなたが非常に怒っているとみなすために他の364の誕生日を残します。これらのうち104件は、非常に怒ることはないと約束した週末に当てはまります。したがって、私たちはあなたの260/365だけを気にします。つまり、R(0,364)>104randintの範囲は包括的です)。この制約がある場合、平日の誕生日が2019年のISOの52週のいずれかに該当し、その週のすべての平日に該当する可能性はほぼ同じです。そして、独立して、あなたは非常に怒っている人である可能性が3分の1であること。

Dは、(weeknum,weekday)怒りの可能性のある人物が実際の誕生日を共有する場合、その週に誕生日を迎える別の人物がいない限り、Amgryである必要がないようにするためのセットです。

ISO 2019の週に非常に怒っている人が現れない場合は0が返されます。それ以外の場合、最も早いメルトダウンのISO週番号が返されます。


2019年12月31日のエッジケースも考慮に入れるべきではありませんか?
チャーリー

1
@チャーリー:確かに!しかし、31年12月2018 1月1日と同じISO週2019年である2019年、それはうまくいくので、その「嫉妬パーティ週」の一部となるように。
Chas Brown

私はPythonの専門家ではありませんが、あなたの答えはこれを説明に失敗していると思います。「パーティーが同じ誕生日の人と共有されれば、彼らは怒らないでしょう。」あなたはまだ私の賛成票を得ました。
OOBalance 2018

@OOBalance:おっと!それを逃した; 修正されました!
Chas Brown

2

ゼリー 36 32  33 バイト

+1バイトで、気が付かなかった12月30日のエッジケースを修正しました(OPの下のコメントでChas Brownが指摘したように)

-4 Erik the Outgolferに感謝(インラインヘルパーと外部製品の使用)

7R2<52×þFX)Ġị$,3XỊ¤€ṁ@\PṢ€Ḋ€Fḟ0Ḣ

[052]0

オンラインでお試しください!

または、このバージョンを参照して、各人の誕生日のある週(週末は0)をグループ化して表示し、それらの人が非常に怒っているタイプかどうかのリストの同じ順序のリストを出力して、最後に結果を出力します。


1

Java 8、198バイト

double r(){return Math.random();}

n->{int r=52,a[]=new int[r];for(;n-->0;)if(r()*364>104)++a[(int)(r()*r)];for(;++n<52;)r=r>51&a[n]>1&r()<1-5/Math.pow(5,a[n])&r()<1-Math.pow(2./3,a[n])?n:r;return r;}

出力はゼロベース(0-51)です。値52は、非常に怒っている人がいないことを示します。こちらからオンラインでお試しください。

非ゴルフ:

double r() { return Math.random(); } // shortcut for Math.random(), saves a few bytes

n -> { // lambda taking an intger argument and returning an integer
    int r = 52, // this will hold the result; set to the value for "no Very Angry people" for now
    a[] = new int[r]; // array counting the people whose birthday lies in each week
    for(; n-- > 0; ) // for each person:
        if(r() * 364 > 104) // determine whether their birthday is on a weekday that is not the 30th of December ...
            ++a[(int) (r() * r)]; // ... only if so, increment the counter for a random ISO week
    for(; ++n < 52; ) // loop through the weeks; n is -1 before the loop
        r = r > 51   // if r is still the default ...
          & a[n] > 1 // ... and there is more than one person with a birthday that week ...
          & r() < 1 - 5/Math.pow(5, a[n]) // ... and at least two people have a different birthday ...
          &r() < 1 - Math.pow(2./3, a[n]) // ... and at least one person has the Very Angry personality type ...
          ? n  // ... set the current week as the result ...
          : r; // ... otherwise leave it the same
    return r;  // return the result
}

提案する91>26代わりに364>104
ceilingcat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.