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


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.