Wie viele Wochen?

13

Ihre Aufgabe ist es, eine einzelne Zahl auszugeben; Die Anzahl der ISO-Wochen, die ein bestimmter Datumsbereich überschneidet. Wikipedia zitieren:, An average year is exactly 52.1775 weeks longaber das ist nicht etwa der Durchschnitt.

Die Eingabe besteht aus zwei durch Leerzeichen getrennten ISO-Daten:

0047-12-24 2013-06-01

Das Enddatum liegt niemals vor dem Startdatum. Der Einfachheit halber verwenden wir den extrapolierten Gregorianischen Kalender.

Testfälle:

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)

Ihre Lösung sollte Daten zwischen 0001-01-01und verarbeiten 9999-12-31.

Filip Haglund
quelle
2
Kann die Eingabe ein Array von Zeichenfolgen anstelle einer einzelnen durch Leerzeichen getrennten Zeichenfolge sein? Können die beiden Daten auch zwei Argumente für eine Funktion sein?
Türklinke
Ich nehme an, Sie meinen den proleptischen Gregorianischen Kalender .
Brad Gilbert b2gills
Beginnen die Wochen auch am Sonntag oder Montag? Laut Ihrem zweiten Testfall ist Montag, aber stellen Sie sicher.
Türklinke
@Doorknob 冰 Wikipedia-Zitat: "Ein Datum wird durch die ISO-Wochennummerierung Jahr im Format JJJJ angegeben, eine Wochennummer im Format ww, der der Buchstabe 'W' vorangestellt ist, und die Wochentagsnummer, eine Ziffer d von 1 bis 7 , beginnend mit Montag und endend mit Sonntag "Also ab Montag nach ISO 8601
Tensibai 17.12.15
2
Nach der ISO-NormWeeks start with Monday.
Filip Haglund

Antworten:

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}

Eine sehr primitive Lösung: das erste Datum gegeben aund das zweite Datum b, erhöht a, zu überprüfen , ob es ein Montag ist (wenn ja, wir „überrollen“ zu einer neuen Woche haben), und zu stoppen , sobald aist b.

Nimmt Eingaben in dem genauen Format vor, das in der Frage angegeben ist: eine einzelne durch Leerzeichen getrennte Zeichenfolge. (So wie es parst der Eingang fancy-Ish: es verwendet Ruby „Klecks“ Operator *. Dieser Operator „erweitert“ , ein Array oder enumerable geführt, so Time.gm *[2013, 06, 01]wird Time.gm 2013, 06, 01.)

Aus einer Kommentardiskussion importiert:

Wir kümmern uns nicht um "Wochen in einem Jahr"; Wir kümmern uns nur um "Wochen insgesamt". Ob ein Jahr 52 oder 53 Wochen hat, spielt also keine Rolle.

Nur um künftige Verwechslungen mit dem korrekten Umgang mit Jahresgrenzen zu vermeiden - laut Wikipedia beginnen alle Wochen immer am Montag und enden am Sonntag.

Für einige ausgefallene Tricks sind diese alle gleichwertig:

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
Türknauf
quelle
Können Sie nicht 1 Zeichen sparen, a==bindem Sie es ersetzen a<b?
Tensibai
1

VBA, 125 Bytes

Erwarten von 2 Funktionseingängen als Zeichenfolgen

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

Ziemlich sicher, dass man Golf spielen kann. Dies durchläuft jeden Tag eine Schleife zwischen den beiden Daten und erhöht den Zähler jedes Mal, wenn sich das ISO-Datum ändert.

DatePart("ww",f+i,2,2)ist die ISO-Wochennummer in VBA die erste 2 bedeutet Monday (complies with ISO standard 8601, section 3.17). dann bedeutet die zweite 2Week that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140 Bytes mit einem Eingang

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
JimmyJazzx
quelle
1

R, 76 Bytes

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

Nach dem Gespräch mit @Doorknob ist es endlich so einfach wie die Montagszählung.

seq Erlauben Sie, einen Vektor von Datumsangaben (von jedem Tag zwischen zwei Datumsangaben) zu erstellen und diese in die 'Nummer des Wochentags' umzuwandeln. Zählen Sie nun die Zeiten, zu denen es 1 ist, um die Anzahl der von Ihnen geänderten Wochentage zu erhalten und 1 zu addieren vorherige Woche berücksichtigen.

Eine weitere Annäherungsschleife:

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
Tensibai
quelle
1
In Bezug auf Ihren zweiten Ansatz sollten Sie zur Gesamtzahl der Montage nur 1 addieren, wenn das erste Datum nicht auf einen Montag fällt.
DavidC
@DavidCarraher Danke, als ich Ihre Antwort gelesen habe, dachte ich, ich könnte den ersten Tag der Reichweite entfernen und so das Problem beheben :)
Tensibai
0

Mathematica 135 79 96 84 74 Bytes

In Übereinstimmung mit dem Vorschlag von @ Doorknob

  • Generiert alle Daten im Bereich

  • zählt die Anzahl der Montage (ISOWeekDay == "1") in der DateRange(außer d), und

  • addiert sich 1zur Summe.


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}

DavidC
quelle