共享生日聚会


9

办公室(我们称其为“办公室”)将通过合并办公室生日聚会来减少2019年的浪费时间。在同一周的星期一至星期五(含)之间生日的任何两个人,将在该周的某个时间举行“ 共享生日派对”来庆祝。生日在周六或周日的人们根本不会参加任何聚会。

有些人不喜欢与未共享实际生日的人共享生日聚会。他们会很生气有一个共享的生日派对

我们将模拟一个办公室,并寻找某人对共同生日聚会感到非常生气的第一周。

挑战

编写一个程序或函数,以输出2019年的第一个ISO周编号,其中模拟办公室中的某人对其共享生日聚会非常生气,但要遵循以下基本规则:

  • 输入整数N > 1,即办公室中的工人人数。
  • 所述Ñ生日本身是均匀分布的随机从1月1日至12月31日(忽略年02月29)。
  • 但是用于确定共享生日聚会的工作周是2019 ISO周日期,其介于2019-W01-1(2018-12-31)和2019-W52-7(2019-12-29)之间。新的ISO周每个星期一开始。(我认为这是您应对此挑战的ISO周真正需要的全部内容)。
  • 对于办公室中的N个人,每个人都有1/3的机会拥有“ 非常生气的 共享生日聚会”个性类型,因此您也必须进行模拟。
  • 但如果与同一个生日的人共享聚会,他们不会生气。
  • 输出第一次出现“ 非常生气”的人的ISO周号(精确的格式,只要周号清晰即可)。如果没有生气的人,您可以输出与ISO周无关的任何内容,否则程序可能会出错等。

一些简化的假设:

  • 正如我提到的,完全忽略2月29日的问题(不必要的并发症)
  • 忽略公共假期(这是一个国际社会,因此我们的假期会有所不同),只是假设办公室在每个工作日都开放。

规则

这是代码高尔夫球。每种语言的最短答案(以字节为单位)获胜。禁止默认漏洞。

欢迎使用代码说明。

工作实例

输入N = 7的人为设计的示例1。第一和第二列是规则中所述的随机变量(当然,此处实际上并不是随机变量)。

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日没有!您能添加一个可行的示例吗?
毛茸茸的

如果没有人“非常生气”,输出应该是什么?对于小规模企业,这很容易发生ñ
FryAmTheEggman

4
@Shaggy可能会有人在那工作,生日是2月29日。我是说忽略这种可能性,因为这只会增加毫无意义的IMO案例。
ngm

1
如果没有生气的人,则可以使用任何非W01至W52或等效值的合适输出,或一条错误消息。我将编辑问题以在不使用手机时反映出来。
ngm

1
也许是我,但我宁愿参加一个共同的生日聚会,而不是根本不参加。撕开所有在周末过生日的人。
凯文·克鲁伊森

Answers:


5

Python 2中172个 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年的52个ISO周中的任何一个以及该周的任何一个工作日中;而且,有三分之一的人很可能会非常生气。

D是一组,(weeknum,weekday)所以如果一个潜在的愤怒的人共享一个实际生日,那么除非有另一个人在那个星期生日,否则不必Amgry。

如果在任何ISO 2019星期内没有任何表现出非常生气的人,则返回0;否则,将返回最早熔毁的ISO周编号。


您是否不应该考虑2019年12月31日的边缘情况?
查理

1
@查理:当然!但是,31日年12月2018年在同一ISO周2019年1年1月2019这样,那就是“嫉妒方周”的一部分,所以它的作品了。
Chas Brown '18

我不是Python专家,但我相信您的回答无法说明这一点:“但如果与同一个生日的人共享聚会,他们不会生气。” 你仍然得到我的支持。
OOBalance

@OOBalance:糟糕!错过了;修改!
查斯·布朗

2

果冻 36 32  33 字节

+1个字节来修复我没有注意到的30 Dec边缘情况(如Chas Brown在OP下方的注释中指出的那样)

-4感谢Outgolfer的Erik(在线帮助程序和外部产品的使用)

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

单链链接产生一个整数 [052] 哪里 0 表示一年中根本没有非常生气的人,其他输出是ISO周数。

在线尝试!

或查看此版本该版本将每个人生日的几周打印出来(周末为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 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.