แชร์ปาร์ตี้วันเกิด


9

สำนักงาน (เรียกว่า "สำนักงาน") กำลังจะลดเวลาที่เสียไปในปี 2562 โดยรวมงานวันเกิดของสำนักงาน บุคคลสองคนใดที่มีวันเกิดระหว่างวันจันทร์ถึงวันศุกร์ (รวม) ในสัปดาห์เดียวกันจะได้รับการเฉลิมฉลองด้วยปาร์ตี้วันเกิดที่ใช้ร่วมกันในบางครั้งในสัปดาห์นั้น ผู้ที่มีวันเกิดตกในวันเสาร์หรือวันอาทิตย์จะไม่มีปาร์ตี้เลย

บางคนไม่ชอบแบ่งปันปาร์ตี้วันเกิดกับคนที่ไม่ได้แบ่งปันวันเกิดจริง พวกเขาจะโกรธมากที่จะมีปาร์ตี้วันเกิดร่วมกัน

พวกเราจะไปจำลองสำนักงานและพบว่าในสัปดาห์แรกที่มีคนได้รับโกรธมากเกี่ยวกับพวกเขาที่ใช้ร่วมกันงานเลี้ยงวันเกิด

ความท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ส่งออกหมายเลขสัปดาห์ ISO แรกสำหรับปี 2019 ซึ่งบางคนในสำนักงานจำลองได้โกรธมากเกี่ยวกับงานวันเกิดร่วมของพวกเขาภายใต้กฎพื้นฐานต่อไปนี้:

  • ป้อนจำนวนเต็มN > 1 ซึ่งเป็นจำนวนพนักงานในสำนักงาน
  • ไม่มีวันเกิดตัวเองจะกระจายอย่างสม่ำเสมอที่สุ่ม ม.ค. 01-31 ธันวาคม (ละเว้น 29 กุมภาพันธ์)
  • แต่สัปดาห์การทำงานเพื่อจุดประสงค์ในการกำหนดวันเกิดที่ใช้ร่วมกันคือ 2019 ISO สัปดาห์วันซึ่งอยู่ระหว่าง 2019-W01-1 (2018-12-31) และ 2019-W52-7 (2019-12-29) สัปดาห์ ISO ใหม่จะเริ่มทุกวันจันทร์ (ฉันคิดว่านี่คือทั้งหมดที่คุณต้องรู้เกี่ยวกับ ISO สัปดาห์สำหรับความท้าทายนี้)
  • สำหรับคนNในสำนักงานแต่ละคนมีโอกาส 1/3 ในการมีบุคลิกภาพแบบวันเกิดแชร์โกรธมาก ดังนั้นคุณจะต้องจำลองสิ่งนั้นด้วย
  • แต่พวกเขาจะไม่โกรธถ้ามีการแบ่งปันปาร์ตี้กับคนที่มีวันคล้ายวันเกิด
  • เอาท์พุทหมายเลขสัปดาห์ ISO (รูปแบบที่แน่นอนสำหรับสิ่งนี้จะยืดหยุ่นตราบเท่าที่หมายเลขสัปดาห์ชัดเจน) สำหรับการเกิดขึ้นครั้งแรกของบุคคลที่โกรธมาก หากไม่มีคนโกรธคุณสามารถส่งออกสิ่งที่ไม่สับสนกับสัปดาห์ ISO หรือโปรแกรมอาจผิดพลาดเป็นต้น

สมมติฐานที่ทำให้เข้าใจง่ายบางอย่าง:

  • ดังที่ฉันได้กล่าวไปแล้วให้เพิกเฉยต่อปัญหา 29 กุมภาพันธ์อย่างสมบูรณ์ (ภาวะแทรกซ้อนที่ไม่จำเป็น)
  • ละเว้นวันหยุดนักขัตฤกษ์ (นี่เป็นประชาคมระหว่างประเทศดังนั้นวันหยุดของเราจะแตกต่างกันไป) และเพียงแค่สมมติว่าสำนักงานเปิดทำการในแต่ละวันธรรมดา

กฎระเบียบ

นี่คือรหัสกอล์ฟ คำตอบสั้น ๆ เป็นไบต์สำหรับแต่ละภาษาที่ชนะ ช่องโหว่เริ่มต้นที่ต้องห้าม

ยินดีต้อนรับคำอธิบายเกี่ยวกับรหัส

ตัวอย่างการทำงาน

ตัวอย่างที่มีการประดิษฐ์ 1 พร้อมอินพุตN = 7 คอลัมน์แรกและคอลัมน์ที่สองสุ่มตามที่อธิบายไว้ในกฎ (แต่ไม่ได้สุ่มที่นี่แน่นอน)

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

ตัวอย่างที่ 2 ที่ไม่มีการระบุN

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
... ไม่มีวันที่ 29 กุมภาพันธ์ในปี 2019! คุณสามารถเพิ่มตัวอย่างที่ใช้งานได้ไหม
Shaggy

ผลลัพธ์ที่ควรจะเป็นถ้าไม่มีใคร "โกรธมาก"? เรื่องนี้อาจเกิดขึ้นได้ง่ายสำหรับคนตัวเล็กN.
FryAmTheEggman

4
@Shaggy อาจจะมีคนที่ทำงานที่นั่นวันเกิดคือ 29 กุมภาพันธ์ฉันกำลังบอกว่าจะเพิกเฉยต่อความเป็นไปได้นั้นเพราะมันเพิ่งเพิ่ม IMO กรณีไร้จุดหมายอย่างไร้จุดหมาย
ngm

1
ถ้าไม่มีคนโกรธเอาท์พุทที่เหมาะสมที่ไม่ใช่ W01 ถึง W52 หรือเทียบเท่าหรือข้อความแสดงข้อผิดพลาดก็ดี ฉันจะแก้ไขคำถามเพื่อสะท้อนสิ่งนี้เมื่อไม่ได้ใช้อุปกรณ์พกพา
ngm

1
อาจจะเป็นฉัน แต่ฉันอยากจะมีปาร์ตี้วันเกิดร่วมมากกว่าไม่มีเลย ฉีกทุกคนที่มีวันเกิดในวันหยุดสุดสัปดาห์
Kevin Cruijssen

คำตอบ:


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 ว่าวันเกิดของคุณไม่ได้เป็น 29 กุมภาพันธ์

หากวันเกิดของคุณคือ 30 ธันวาคมจะไม่ตกในสัปดาห์ ISO ใด ๆ ของปี 2019 ดังนั้นในกรณีใด ๆ คุณจะไม่สามารถเป็นสัปดาห์ ISO ที่โกรธมากของปี 2019

นั่นทำให้เหลือวันเกิดอีก 364 ครั้งเพื่อพิจารณาว่าคุณโกรธมาก 104 ของฤดูใบไม้ร่วงในวันหยุดสุดสัปดาห์เมื่อเราได้กำหนดไว้ว่าคุณจะไม่โกรธมาก ดังนั้นเราสนใจคุณเพียง 260/365 ครั้งเท่านั้น นั่นคือเมื่อR(0,364)>104( randintรวมช่วงของ) เนื่องจากข้อ จำกัด ดังกล่าวเป็นสิ่งที่เหมาะสมมากที่วันเกิดวันทำงานของคุณจะอยู่ในช่วง 52 สัปดาห์ ISO ของปี 2019 และในวันธรรมดาของสัปดาห์นั้น และอย่างอิสระว่าคุณเป็น 1 ใน 3 น่าจะเป็นคนที่โกรธมาก

D คือชุดของ(weeknum,weekday)ดังนั้นหากผู้ที่มีโอกาสโกรธแชร์วันเกิดจริงไม่จำเป็นต้องเป็น Amgry เว้นแต่ว่าจะมีบุคคลอื่นที่มีวันเกิดในสัปดาห์นั้น

0 จะถูกส่งคืนหากไม่มีคนที่โกรธมากในช่วง ISO 2019 สัปดาห์ใด ๆ มิฉะนั้นจะส่งคืนหมายเลข ISO สัปดาห์ของการหลอมละลายที่เร็วที่สุด


คุณไม่ควรพิจารณากรณีที่เป็นขอบของวันที่ 31 ธันวาคม 2019
Charlie

1
@ Charlie: แน่นอน! แต่วันที่ 31 ธันวาคม2018อยู่ในช่วงสัปดาห์ ISO เดียวกันปี 2019 ซึ่งเป็นวันที่ 1 มกราคม2019ดังนั้นจึงเป็นส่วนหนึ่งของ
Chas Brown

ฉันไม่ใช่ผู้เชี่ยวชาญของ Python แต่ฉันเชื่อว่าคำตอบของคุณไม่สามารถอธิบายสิ่งนี้ได้: "แต่พวกเขาจะไม่โกรธถ้ามีการแบ่งปันงานปาร์ตี้กับคนที่มีวันคล้ายวันเกิด" คุณยังได้ upvote ของฉันแม้ว่า
OOBalance

@OOBalance: อ๊ะ! พลาดที่; แก้ไขเพิ่มเติม!
Chas Brown

2

เยลลี่ ,  36 32  33 ไบต์

+1 ไบต์เพื่อแก้ไขกรณีขอบ 30 ธันวาคมที่ฉันไม่ได้สังเกตเห็น (ตามที่ Chas Brown ชี้ไว้ในความคิดเห็นด้านล่าง OP)

-4 ขอบคุณ Erik the Outgolfer (ผู้ช่วยแบบอินไลน์และการใช้ผลิตภัณฑ์ด้านนอก)

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

ลิงก์ monadic ที่ให้ค่าจำนวนเต็ม [0,52] ที่ไหน 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 บ่งบอกว่าไม่มีคนโกรธมาก ลองออนไลน์ได้ที่นี่

Ungolfed:

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.