Quante settimane


13

Il tuo compito è produrre un solo numero; il numero di settimane ISO che un determinato intervallo di date interseca. Per citare Wikipedia:, An average year is exactly 52.1775 weeks longma non si tratta della media.

L'input è costituito da due date ISO separate da spazi:

0047-12-24 2013-06-01

La data di fine non è mai precedente alla data di inizio. Useremo il calendario gregoriano estrapolato per semplicità.

Casi test:

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)

La tua soluzione dovrebbe gestire le date tra 0001-01-01e 9999-12-31.


2
L'input può essere una matrice di stringhe anziché una singola stringa separata da spazio? In alternativa, le due date possono essere due argomenti per una funzione?
Maniglia della porta


Inoltre, le settimane iniziano domenica o lunedì? Secondo il tuo secondo caso di test, è lunedì, ma assicurati.
Maniglia della porta

@Doorknob quote Citazione di Wikipedia: "Una data è specificata dall'anno di numerazione delle settimane ISO nel formato AAAA, un numero di settimana nel formato ww preceduto dalla lettera 'W' e il numero del giorno della settimana, una cifra d da 1 a 7 , a partire da lunedì e finendo con domenica "Quindi, a partire da lunedì secondo ISO 8601
Tensibai,

2
Secondo lo standard ISO,Weeks start with Monday.
Filip Haglund il

Risposte:


2

Rubino, 89 88 86 byte

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

Una soluzione molto primitivo: dato il primo appuntamento ae la seconda data b, incremento a, controllo se si tratta di un Lunedi (in caso affermativo, abbiamo "rotolò" per una nuova settimana), e fermare una volta aè b.

Accetta l'input nel formato esatto specificato nella domanda: una singola stringa separata da spazi. (Il modo in cui analizza l'input è di fantasia: usa l'operatore "splat" di Ruby *. Questo operatore "espande" un array o enumerabile, quindi Time.gm *[2013, 06, 01]diventa Time.gm 2013, 06, 01.)

Importato da una discussione di commento:

Non ci interessa "settimane in un anno;" ci preoccupiamo solo di "settimane complessive". Quindi, se un anno ha 52 o 53 settimane non fa alcuna differenza.

Solo per evitare la futura confusione sul fatto che questo gestisca correttamente i confini dell'anno - secondo Wikipedia , tutte le settimane iniziano sempre lunedì e finiscono domenica.

Per alcuni trucchi più fantasiosi, questi sono tutti equivalenti:

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

Non puoi salvare 1 carattere sostituendolo a==bcon a<b?
Tensibai,

1

VBA, 125 byte

Prevedere 2 ingressi di funzione come stringhe

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

Abbastanza sicuro Questo può essere giocato a golf. Questo è ripetuto ogni giorno tra le 2 date e incrementa il contatore ogni volta che cambia la data ISO.

DatePart("ww",f+i,2,2)è il numero della settimana ISO in VBA i primi 2 mezzi Monday (complies with ISO standard 8601, section 3.17). quindi il secondo 2 significaWeek that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140 byte con input singolo

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 byte

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

Dopo la conversazione con @Doorknob, è finalmente facile come contare il lunedì.

seq consenti di creare un vettore di date (di ogni giorno tra due date) e di trasformarlo in "numero del giorno della settimana", ora conta il numero di volte 1 per ottenere il numero di volte che hai cambiato settimana e aggiungi 1 a prendere in considerazione la settimana precedente.

Un altro approccio ad anello:

R, 85 byte

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

1
Per quanto riguarda il tuo secondo approccio, dovresti aggiungere 1 al numero totale di lunedì se la prima data non cade di lunedì.
DavidC

@DavidCarraher Grazie, leggere la tua risposta mi ha fatto pensare che avrei potuto rimuovere il primo giorno di intervallo,
risolvendo

0

Mathematica 135 79 96 84 74 byte

Coerentemente con il suggerimento di @ Doorknob, questo

  • genera tutte le date nell'intervallo

  • conta il numero di lunedì ( ISOWeekDay== "1") in DateRange(escluso d) e

  • aggiunge 1al totale.


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}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.