Fiesta de cumpleaños compartida


9

Una oficina (llamémosla "The Office") reducirá el tiempo perdido en 2019 al consolidar las fiestas de cumpleaños de la oficina. Cualquier dos personas con un cumpleaños entre el lunes y el viernes (inclusive) de la misma semana se celebrarán con una fiesta de cumpleaños compartida en algún momento de esa semana. Las personas cuyos cumpleaños son sábados o domingos no tienen fiesta.

A algunas personas no les gusta compartir una fiesta de cumpleaños con personas que no comparten su cumpleaños real. Estarán muy enojados por tener una fiesta de cumpleaños compartida .

Vamos a simular una oficina y encontrar la primera semana en la que alguien se pone muy enojado acerca de su fiesta de cumpleaños compartido .

El reto

Escriba un programa o función que genere el primer número de semana ISO para 2019 en el que alguien en una oficina simulada se enoje mucho por su fiesta de cumpleaños compartida , sujeto a las siguientes reglas básicas:

  • ingrese un número entero N > 1, que es el número de trabajadores en la oficina.
  • los N cumpleaños se distribuyen uniformemente al azar del 1 de enero al 31 de diciembre (ignore el 29 de febrero).
  • pero las semanas laborales para determinar las fiestas de cumpleaños compartidas son las fechas de la semana ISO 2019, que se encuentran entre 2019-W01-1 (2018-12-31) y 2019-W52-7 (2019-12-29). Una nueva semana ISO comienza todos los lunes. (Creo que esto es todo lo que realmente necesita saber sobre las semanas ISO para este desafío).
  • para las N personas en la oficina, cada uno tiene una probabilidad de 1/3 de tener un tipo de personalidad de fiesta de cumpleaños compartida muy enojada , por lo que también tendrá que simular eso.
  • pero no se enojarán si la fiesta se comparte con personas que tienen el mismo cumpleaños.
  • muestra el número de semana ISO (el formato exacto para esto es flexible siempre que el número de semana sea claro) para la primera aparición de una persona muy enojada . Si no hay personas enojadas, puede generar cualquier cosa que no se confunda con una semana ISO o el programa puede generar errores, etc.

Algunos supuestos simplificadores:

  • como mencioné, ignore por completo el problema del 29 de febrero (una complicación innecesaria)
  • ignore los días festivos (esta es una comunidad internacional por lo que nuestros días festivos serán diferentes) y asuma que la oficina está abierta cada día laborable.

Reglas

Este es el código de golf. La respuesta más corta en bytes para cada idioma gana. Lagunas predeterminadas prohibidas.

Código de explicaciones de bienvenida.

Ejemplos trabajados

Ejemplo 1 contribuido con entrada N = 7. La primera y segunda columnas son aleatorias como se describe en las reglas (pero en realidad no son aleatorias aquí, por supuesto).

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

Entonces no ocurre enojo. El programa o la función pueden generar errores o generar algo que no se confunda con un número de semana ISO.

Ejemplo 2 con N no especificado.

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 salida sería W11o algo equivalente.


3
... ¡No hay 29 de febrero en 2019! ¿Puedes agregar un ejemplo trabajado, por favor?
Shaggy

N

44
@ Shaggy podría haber personas que trabajan allí cuyo cumpleaños es el 29 de febrero. Estoy diciendo que ignore esa posibilidad, ya que solo agrega un caso egde inútil IMO.
ngm

1
Si no hay personas enojadas, cualquier salida adecuada que no sea W01 a W52 o equivalente, o un mensaje de error, está bien. Editaré la pregunta para reflejar esto cuando esté fuera del móvil.
ngm

1
Tal vez soy yo, pero prefiero tener una fiesta de cumpleaños compartida que ninguna. Destripa a todos los que cumplen años el fin de semana.
Kevin Cruijssen

Respuestas:


5

Python 2 , 172202 bytes

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*

Pruébalo en línea!

¡Uy! Perdí un requisito; Cuesta 30 bytes.

El OP indica que su cumpleaños no es el 29 de febrero.

Si su cumpleaños es el 30 de diciembre, no caerá en ninguna semana ISO de 2019, por lo que, en cualquier caso, no puede ser una semana ISO muy enojada de 2019.

Eso deja 364 otros cumpleaños para considerar que estás muy enojado. 104 de estos caen los fines de semana cuando hemos estipulado que no te enojarás mucho al respecto. Así que solo nos preocupamos 260/365 de las veces; es decir, cuándo R(0,364)>104( randintel rango es inclusivo). Dada esa restricción, es equiprobable que el cumpleaños de su día de la semana caiga en cualquiera de las 52 semanas ISO de 2019, y cualquier día de la semana de esa semana; e, independientemente, que eres 1 de cada 3 es probable que seas una persona muy enojada.

D es entonces un conjunto de (weeknum,weekday)modo que si una persona potencialmente enojada comparte un cumpleaños real, entonces no hay necesidad de ser Amgry a menos que haya otra persona que tenga un cumpleaños esa semana.

0 se devuelve si no se manifiestan personas muy enojadas durante cualquier semana ISO 2019; de lo contrario, se devuelve el número de semana ISO de la primera fusión.


¿No debería considerar también el caso límite del 31 de diciembre de 2019?
Charlie

1
@ Charlie: ¡Claro! Pero el 31 de diciembre de 2018 se encuentra en la misma semana ISO 2019 que el 1 de enero de 2019, por lo que sería parte de esa "semana de fiesta celosa", por lo que funciona.
Chas Brown

No soy un experto en Python, pero creo que su respuesta no tiene en cuenta esto: "pero no se enojarán si la fiesta se comparte con personas que tienen el mismo cumpleaños". Sin embargo, todavía tienes mi voto positivo.
OOBalance

@OOBalance: ¡Vaya! Eché de menos eso; modificado!
Chas Brown

2

Gelatina ,  36 32  33 bytes

+1 byte para arreglar el caso límite de 30 dic que no había notado (como lo señaló Chas Brown en los comentarios debajo del OP)

-4 gracias a Erik the Outgolfer (ayuda en línea y uso de producto externo)

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

[0,52]0

Pruébalo en línea!

O vea esta versión que imprime las semanas en las que se celebra el cumpleaños de cada persona (0 para los fines de semana) agrupadas, luego imprime una lista ordenada de listas de si esas personas son del tipo Muy enojado, y finalmente imprime el resultado.


1

Java 8, 198 bytes

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 salida está basada en cero (0-51); un valor de 52 indica que no hay personas muy enojadas . Pruébelo en línea aquí .

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

Sugerir en 91>26lugar de364>104
ceilingcat
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.