Fête d'anniversaire partagée

9

Un bureau (appelons-le "The Office") va réduire le temps perdu en 2019 en regroupant les fêtes d'anniversaire de bureau. Deux personnes avec un anniversaire entre le lundi et le vendredi (inclus) de la même semaine seront célébrées avec une fête d'anniversaire partagée au cours de la semaine. Les personnes dont l'anniversaire tombe un samedi ou un dimanche n'obtiennent aucune fête.

Certaines personnes n'aiment pas partager une fête d'anniversaire avec des personnes qui ne partagent pas leur anniversaire réel. Ils seront très en colère d'avoir une fête d'anniversaire partagée .

Nous allons simuler un bureau et trouver la première semaine où quelqu'un se met très en colère au sujet de sa fête d'anniversaire partagée .

Le défi

Écrivez un programme ou une fonction qui génère le premier numéro de semaine ISO pour 2019 dans lequel une personne dans un bureau simulé se met très en colère contre sa fête d'anniversaire partagée , sous réserve des règles de base suivantes:

  • entrez un entier N > 1, qui est le nombre de travailleurs dans le bureau.
  • les N anniversaires eux-mêmes sont distribués uniformément au hasard du 1er janvier au 31 décembre (ignorez le 29 février).
  • mais les semaines de travail pour déterminer les fêtes d'anniversaire partagées sont les dates de la semaine ISO 2019, qui sont comprises entre 2019-W01-1 (2018-12-31) et 2019-W52-7 (2019-12-29). Une nouvelle semaine ISO commence chaque lundi. (Je pense que c'est tout ce que vous devez vraiment savoir sur les semaines ISO pour ce défi).
  • pour les N personnes au bureau, chacune a 1/3 de chance d'avoir un type de personnalité Fête d'anniversaire partagée très en colère , vous devrez donc simuler cela aussi.
  • mais ils ne seront pas en colère si la fête est partagée avec des gens qui ont le même anniversaire.
  • sortir le numéro de semaine ISO (le format exact est flexible tant que le numéro de semaine est clair) pour la première occurrence d'une personne très en colère . S'il n'y a pas de gens en colère, vous pouvez générer tout ce qui n'est pas confondu avec une semaine ISO ou le programme peut générer des erreurs, etc.

Quelques hypothèses simplificatrices:

  • comme je l'ai mentionné, ignorer complètement le problème du 29 février (une complication inutile)
  • ignorez les jours fériés (il s'agit d'une communauté internationale, donc nos jours fériés seront différents) et supposez simplement que le bureau est ouvert chaque jour de semaine.

Règles

C'est du code-golf. La réponse la plus courte en octets pour chaque langue gagne. Les failles par défaut sont interdites.

Les explications du code sont les bienvenues.

Exemples travaillés

Exemple 1 avec entrée N = 7. Les première et deuxième colonnes sont aléatoires comme décrit dans les règles (mais pas réellement aléatoires ici bien sûr).

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

Donc, aucune colère ne se produit. Le programme ou la fonction peut générer des erreurs ou produire quelque chose qui ne soit pas confondu avec un numéro de semaine ISO.

Exemple 2 avec N non spécifié.

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   
  ...             ...      ...   ... 

La sortie serait W11ou quelque chose d'équivalent.

ngm
la source
3
... Il n'y a pas de 29 février 2019! Pouvez-vous ajouter un exemple concret, s'il vous plaît?
Shaggy
N
4
@Shaggy il pourrait y avoir des gens qui travaillent là-bas et dont l'anniversaire est le 29 février. Je dis simplement d'ignorer cette possibilité car cela ajoute simplement un cas egde inutile IMO.
ngm
1
S'il n'y a pas de gens en colère, toute sortie appropriée qui n'est pas W01 à W52 ou équivalent, ou un message d'erreur, est très bien. Je modifierai la question pour refléter cela lorsque je ne serai pas mobile.
ngm
1
C'est peut-être moi, mais j'ai plutôt une fête d'anniversaire partagée que pas du tout. Déchirez tous ceux qui ont leur anniversaire le week-end.
Kevin Cruijssen

Réponses:

5

Python 2 , 172 202 octets

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*

Essayez-le en ligne!

Oops! Manqué une exigence; coûte 30 octets.

L'OP indique que votre anniversaire n'est pas le 29 février.

Si votre anniversaire est le 30 décembre, il ne tombera dans aucune semaine ISO de 2019, donc en aucun cas vous ne pouvez être une semaine ISO très en colère de 2019.

Cela laisse 364 autres anniversaires pour vous considérer comme très en colère. 104 d'entre eux tombent le week-end lorsque nous avons stipulé que vous ne vous fâcherez pas. Nous ne nous soucions donc que de vous 260/365 du temps; c'est-à-dire quand R(0,364)>104( randintla plage de est incluse). Compte tenu de cette contrainte, il est tout à fait probable que votre anniversaire de semaine tombe dans l'une des 52 semaines ISO de 2019 et dans n'importe quel jour de la semaine de cette semaine; et, indépendamment, que vous êtes 1 personne sur 3 susceptible d'être une personne très en colère.

D est alors un ensemble de (weeknum,weekday)sorte que si une personne potentiellement en colère partage un anniversaire réel, il n'est pas nécessaire d'être Amgry à moins qu'une autre personne n'ait un anniversaire cette semaine-là.

0 est renvoyé si aucune personne très en colère ne se manifeste au cours d'une semaine ISO 2019; sinon, le numéro de semaine ISO de la première fusion est renvoyé.

Chas Brown
la source
Ne devriez-vous pas également considérer le cas de bord du 31 décembre 2019?
Charlie
1
@Charlie: Bien sûr! Mais le 31 décembre 2018 est dans la même semaine ISO 2019 que le 1er janvier 2019 ferait donc partie de cette "semaine de fête jalouse", donc ça marche.
Chas Brown
Je ne suis pas un expert de Python, mais je pense que votre réponse ne tient pas compte de cela: "mais ils ne seront pas en colère si la fête est partagée avec des gens qui ont le même anniversaire." Vous avez quand même eu mon vote positif.
OOBalance
@OOBalance: Oups! Manqué ça; modifié!
Chas Brown
2

Gelée ,  36 32  33 octets

+1 octet pour corriger le cas de bord du 30 décembre que je n'avais pas remarqué (comme l'a souligné Chas Brown dans les commentaires sous l'OP)

-4 merci à Erik l'Outgolfer (aide en ligne et utilisation du produit extérieur)

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

[0,52]0

Essayez-le en ligne!

Ou consultez cette version qui imprime les semaines pendant lesquelles l'anniversaire de chaque personne se trouve (0 pour les week-ends), puis imprime une liste ordonnée de listes indiquant si ces personnes sont du type Très en colère, et imprime enfin le résultat.

Jonathan Allan
la source
1

Java 8, 198 octets

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;}

La sortie est basée sur zéro (0-51); une valeur de 52 indique qu'il n'y a pas de personnes très en colère . Essayez-le en ligne ici .

Non golfé:

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
}
OOBalance
la source
Suggérer à la 91>26place de364>104
plafondcat