Kaç hafta?


13

Göreviniz tek bir sayı çıkarmaktır; belirli bir tarih aralığının kesiştiği ISO haftalarının sayısı. Wikipedia'dan alıntı yapmak için: An average year is exactly 52.1775 weeks longama bu ortalama ile ilgili değil.

Girdi , boşlukla ayrılmış iki ISO tarihinden oluşur:

0047-12-24 2013-06-01

Bitiş tarihi asla başlangıç ​​tarihinden önce değildir. Basitlik için dışlanmış Gregoryen takvimini kullanacağız.

Test senaryoları:

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)

Çözümünüz 0001-01-01ve arasındaki tarihleri ​​işlemelidir 9999-12-31.


2
Girdi, boşlukla ayrılmış tek bir dize yerine bir dize dizisi olabilir mi? Alternatif olarak, iki tarih bir işleve iki argüman olabilir mi?
Kapı Tokmağı


Ayrıca, haftalar Pazar veya Pazartesi başlıyor mu? İkinci test durumunuza göre, Pazartesi, ama sadece emin olun.
Kapı Tokmağı

@Doorknob 冰 Wikipedia alıntı: "Bir tarih, ISO hafta numaralandırma yılı YYYY biçiminde, ww biçiminde ww biçiminde ww biçiminde bir hafta numarası ve hafta içi numarası, 1'den 7'ye kadar bir d sayısı ile belirtilir , Pazartesi ile başlayan ve Pazar ile biten "Yani Pazartesi günü başlayan ISO 8601
Tensibai

2
ISO standardına göre,Weeks start with Monday.
Filip Haglund

Yanıtlar:


2

Yakut, 89 88 86 bayt

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

Çok ilkel bir çözüm: ilk tarihi verilmiş ave ikinci tarih b, artım abu Pazartesi ise (biz yeni bir haftaya "takla" ettik eğer öyleyse) onay, ve bir kez durdurun aolduğunu b.

Girdiyi soruda belirtilen biçimde alır: boşlukla ayrılmış tek bir dize. (Girdiyi ayrıştırma şekli fantezi-ish: Ruby'nin "uyarısı" işlecini kullanır *. Bu işleç bir diziyi "genişletir" veya numaralandırılabilir, böylece Time.gm *[2013, 06, 01]olur Time.gm 2013, 06, 01.)

Yorum tartışmasından içe aktarıldı:

"Yılda haftalar" umurumda değil; biz sadece "genel olarak haftaları" önemsiyoruz. Yani bir yılın 52 veya 53 haftası olsun hiç fark etmez.

Bunun, yılın sınırlarını doğru bir şekilde ele alıp almadığı konusunda gelecekteki karışıklığı önlemek için - Wikipedia'ya göre , tüm haftalar her zaman Pazartesi günü başlar ve Pazar günü biter.

Daha süslü hileler için bunların hepsi eşdeğerdir:

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

Eğer 1 karakter değiştirerek kaydedebilirsiniz Can a==btarafından a<b?
Tensibai

1

VBA, 125 Bayt

Dizge olarak 2 işlev girişi bekleniyor

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

Eminim Bu golf olabilir. Bu, 2 tarih arasında her gün dönüyor ve ISO tarihi her değiştiğinde sayacı artırıyor.

DatePart("ww",f+i,2,2)ilk 2 anlamına gelen VBA'daki ISO hafta sayısıdır Monday (complies with ISO standard 8601, section 3.17). sonra ikinci 2 demekWeek that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140 bayt, tek girişli

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 bayt

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

@ Doorknob ile konuştuktan sonra, Pazartesi günleri saymak kadar kolay.

seq bir tarih vektörü oluşturmaya izin verin (iki tarih arasındaki her günün) ve strftime 'haftadaki günün sayısına' dönüştürün, şimdi haftada değiştirdiğiniz zamanı almak için 1 sayısını ve önceki hafta hesaba katmak.

Döngü oluşturan başka bir yaklaşım:

R, 85 bayt

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

1
İkinci yaklaşımınızla ilgili olarak, ilk tarih Pazartesi günü geçmezse, toplam Pazartesi sayısına yalnızca 1 eklemeniz gerekir.
DavidC

@DavidCarraher Teşekkürler, cevabınızı okumak aralığın ilk gününü kaldırabileceğimi düşündürdü, böylece sorunu çözdü :)
Tensibai

0

Mathematica 135 79 96 84 74 bayt

@ Doorknob'un önerisine uygun olarak, bu

  • aralıktaki tüm tarihleri ​​oluşturur

  • (hariç ) Pazartesi günleri ( ISOWeekDay== "1") sayar veDateRanged

  • 1toplama ekler .


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}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.