¿Cuantas semanas?


13

Tu tarea es generar un solo número; El número de semanas ISO que un intervalo de fechas determinado se cruza. Para citar Wikipedia: An average year is exactly 52.1775 weeks longpero no se trata del promedio.

La entrada consta de dos fechas ISO separadas por espacios:

0047-12-24 2013-06-01

La fecha de finalización nunca es anterior a la fecha de inicio. Utilizaremos el calendario gregoriano extrapolado por simplicidad.

Casos de prueba:

Format: input -> output
2015-12-31 2016-01-01 -> 1    (both are within week 53 of 2015)
2016-01-03 2016-01-04 -> 2    (the 3rd is within week 53, and the 4th is in week 1)
2015-12-24 2015-12-24 -> 1    (this single day is of course within a single week)

Su solución debe manejar fechas entre 0001-01-01y 9999-12-31.


2
¿Puede la entrada ser una matriz de cadenas en lugar de una sola cadena separada por espacios? Alternativamente, ¿pueden las dos fechas ser dos argumentos para una función?
— Pomo de la puerta


Además, ¿comienzan las semanas el domingo o el lunes? Según su segundo caso de prueba, es lunes, pero solo asegurándose.
— Pomo de la puerta

@Doorknob quote Cita de Wikipedia: "La fecha se especifica mediante el año de numeración semanal ISO en el formato AAAA, un número de semana en el formato ww con el prefijo de la letra 'W' y el número del día de la semana, un dígito d del 1 al 7 , comenzando con el lunes y terminando con el domingo "Comenzando el lunes según ISO 8601
— Tensibai

2
De acuerdo con la norma ISO,Weeks start with Monday.
— Filip Haglund

Respuestas:


2

Ruby, 89 88 86 bytes

->s{a,b=s.split.map{|x|Time.gm *x.split(?-)}
n=1
(a+=86400).wday==1&&n+=1until a==b
n}

Una solución muy primitiva: dada la primera fecha ay la segunda fecha b, el incremento a, cheque si es un lunes (si es así, que hemos "dio la vuelta" a una nueva semana), y para una vez que aes b.

Toma entrada en el formato exacto especificado en la pregunta: una sola cadena separada por espacios. (La forma en que analiza la entrada es elegante: utiliza el operador "splat" de Ruby *. Este operador "expande" una matriz o enumerable, por lo que se Time.gm *[2013, 06, 01]convierte Time.gm 2013, 06, 01).

Importado de una discusión de comentarios:

No nos importan las "semanas en un año"; solo nos interesan las "semanas en general". Entonces, si un año tiene 52 o 53 semanas no hace ninguna diferencia.

Solo para evitar futuras confusiones sobre si esto maneja los límites de año correctamente acuerdo con Wikipedia , todas las semanas siempre comienzan el lunes y terminan el domingo.

Para algunos trucos más elegantes, todos son equivalentes:

until a==b;a+=86400;n+=a.wday==1?1:0;end
[a+=86400,n+=a.wday==1?1:0]until a==b
n+=(a+=86400).wday==1?1:0 until a==b
(a+=86400).wday==1&&n+=1 until a==b
(a+=86400).wday==1&&n+=1until a==b

¿No se puede guardar 1 carácter sustitución a==bpor a<b?
— Tensibai

1

VBA, 125 bytes

Esperando 2 entradas de función como cadenas

Function u(k,j)
f=DateValue(k)
For i=0 To (DateValue(j)-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then u=u+1
j=q
Next
End Function

Estoy bastante seguro de que esto se puede jugar al golf. Esto se repite todos los días entre las 2 fechas e incrementa el contador cada vez que cambia la fecha ISO.

DatePart("ww",f+i,2,2) es el número de semana ISO en VBA los primeros 2 significa Monday (complies with ISO standard 8601, section 3.17) . entonces segundo 2 significaWeek that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140 bytes con entrada única

Function g(k)
y=Split(k)
f=DateValue(y(0))
For i=0 To (DateValue(y(1))-f)
q=DatePart("ww",f+i,2,2)
If q<>j Then g=g+1
j=q
Next
End Function

1

R, 76 bytes

d=as.Date(scan("","raw"));sum(strftime(seq(d[1],d[2],"day")[-1],"%w")==1)+1

Después de la conversación con @Doorknob, finalmente es tan fácil como contar los lunes.

seq permite crear un vector de fechas (de cada día entre dos fechas) y el tiempo de trabajo lo transforma en el 'número del día de la semana', ahora cuenta las veces que es 1 para obtener el número de veces que cambiaste la semana y agrega 1 a Tener en cuenta la semana anterior.

Otro enfoque de bucle:

R, 85 bytes

n=1;d=as.Date(scan("","raw"));z=d[1];while(z<d[2]){n=n+(strftime(z<-z+1,"%w")==1)};n

1
Con respecto a su segundo enfoque, solo debe agregar 1 al número total de lunes si la primera fecha no cae en lunes.
— DavidC

@DavidCarraher Gracias, leer su respuesta me hizo pensar que podría eliminar el primer día de rango, solucionando así el problema :)
— Tensibai

0

Mathematica 135 79 96 84 74 bytes

De acuerdo con la sugerencia de @ Doorknob, esto

  • genera todas las fechas en el rango

  • cuenta el número de lunes ( ISOWeekDay== "1") en DateRange(excluyendo d), y

  • se suma 1al total.


Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&

Count[DateString[#,"ISOWeekDay"]&/@Rest@(DateRange@@StringSplit@#),"1"]+1&
/@ {"2015-12-31 2016-01-01", "2016-01-04 2016-01-05","2016-01-03 2016-01-04", 
"2015-12-24 2015-12-24", "1876-12-24 2016-01-01"}

{1, 1, 2, 1, 7255}

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.