Спільний день народження


9

Офіс (назвемо його "Офіс") збирається скоротити витрачений час у 2019 році шляхом консолідації офісних свят. Будь-які двоє людей, які мають день народження між понеділком та п’ятницею (включно) того ж тижня, будуть відзначатися спільною вечіркою дня народження деякий час цього тижня. Люди, дні народження яких припадають на суботу чи неділю, взагалі не проводять вечірок.

Деяким людям не подобається ділитися днем ​​народження з людьми, які не діляться власним днем ​​народження. Вони будуть дуже сердиті, щоб влаштувати спільну вечірку на день народження .

Ми збираємось імітувати офіс і знайдемо перший тиждень, коли хтось дуже сердиться про свою спільну день народження .

Змагання

Напишіть програму або функцію, яка виводить перший номер тижня ISO на 2019 рік, коли хтось із імітованого офісу дуже сердиться за свою спільну день народження , дотримуючись наступних основних правил:

  • введіть ціле число N > 1, що становить кількість працівників в офісі.
  • в N днів народження самі по собі розподілені рівномірно у випадковому порядку з 1 січня по 31 грудня (ігнорувати 29 февр).
  • однак робочими тижнями для визначення спільних учасників дня народження є дати проведення тижневих тижнів 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 байт.

ОП надає, що день народження не 29 лютого.

Якщо ваш день народження - 30 грудня, він не припадає на будь-який тиждень ISO 2019 року, тому в будь-якому випадку ви не можете бути дуже сердитим тижнем ISO 2019 року.

Це залишає ще 364 дні народження, щоб вважати вас дуже злим. 104 з цих припадають на вихідні, коли ми домовились, що ви не будете дуже сердитися з цього приводу. Тож ми дбаємо лише про вас 260/365 того часу; тобто коли R(0,364)>104( randintдіапазон включно). Враховуючи це обмеження, безсумнівно, що день народження у будній день припадає на будь-яку з 52 тижнів ISO 2019 та будь-який будній день цього тижня; і незалежно від того, що ви є третім серед людей, які, ймовірно, є дуже сердитою людиною.

D - це набір (weeknum,weekday)так, що якщо потенційно Сердитий чоловік ділиться справжнім днем ​​народження, то не потрібно бути Амґрі, якщо тільки на цьому тижні не буде ще одна людина, яка має день народження.

0 повертається, якщо протягом будь-якого тижня ISO 2019 не проявляється дуже злих людей; в іншому випадку повертається номер тижня ISO, який проводиться якнайшвидше.


Чи не варто також розглянути крайню справу від 31 грудня 2019 року?
Чарлі

1
@Charlie: Звичайно! Але 31 грудня 2018 року перебуває в тому ж тижні ISO 2019, що і 1 січня 2019 року, таким чином, він буде частиною цього "тижня ревнощів вечірки", тому це виходить.
Час Браун

Я не експерт Python, але я вважаю, що ваша відповідь не враховує цього: "але вони не будуть розлючені, якщо вечірку поділять з людьми, які мають день народження". Ти все ще отримав моє рішення.
OOBalance

@OOBalance: На жаль! Пропустив це; поправки!
Час Браун

2

Желе ,  36 32  33 байт

+1 байт для виправлення корпусу 30-ти крайових випадків я не помічав (на що вказував Час Браун у коментарях нижче ОП)

-4 завдяки Erik the Outgolfer (вбудований помічник та використання зовнішнього продукту)

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

Монадійне посилання, яке дає ціле число в [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 вказує на відсутність дуже сердитих людей. Спробуйте його онлайн тут .

Безголівки:

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
roofcat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.