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.