Berapa minggu?

13

Tugas Anda adalah menghasilkan satu nomor; jumlah minggu ISO yang memotong rentang tanggal tertentu. Mengutip Wikipedia:, An average year is exactly 52.1775 weeks longtapi ini bukan tentang rata-rata.

Input terdiri dari dua tanggal ISO yang dipisahkan oleh ruang:

0047-12-24 2013-06-01

Tanggal akhir tidak pernah sebelum tanggal mulai. Kami akan menggunakan kalender Gregorian ekstrapolasi untuk kesederhanaan.

Kasus uji:

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)

Solusi Anda harus menangani tanggal antara 0001-01-01dan 9999-12-31.

Filip Haglund
sumber
2
Bisakah input menjadi array string, bukan string yang dipisahkan spasi? Atau, dapatkah kedua tanggal menjadi dua argumen untuk suatu fungsi?
Gagang Pintu
Saya menganggap Anda maksud Kalender Gregorian Proleptik .
Brad Gilbert b2gills
Juga, apakah minggu dimulai pada hari Minggu atau Senin? Menurut test case kedua Anda, ini hari Senin, tapi pastikan saja.
Gagang Pintu
@Doorknob 冰 Kutipan Wikipedia: "Tanggal ditentukan oleh tahun penomoran minggu ISO dalam format YYYY, angka minggu dalam format yang diawali dengan huruf 'W', dan angka hari kerja, digit d dari 1 hingga 7 , dimulai dengan hari Senin dan berakhir dengan hari Minggu "Jadi, mulai hari Senin sesuai ISO 8601
Tensibai,
2
Menurut standar ISO,Weeks start with Monday.
Filip Haglund

Jawaban:

2

Ruby, 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}

Sebuah solusi yang sangat primitif: diberikan tanggal pertama adan tanggal kedua b, selisih a, cek apakah itu hari Senin (jika demikian, kita sudah "berguling" untuk satu minggu baru), dan berhenti setelah aini b.

Mengambil input dalam format persis yang ditentukan dalam pertanyaan: string yang dipisahkan spasi. (Cara mem-parsing input adalah fancy-ish: ia menggunakan operator "splat" Ruby *,. Operator ini "memperluas" array atau menghitung, jadi Time.gm *[2013, 06, 01]menjadi Time.gm 2013, 06, 01.)

Diimpor dari diskusi komentar:

Kami tidak peduli tentang "minggu dalam setahun;" kami hanya peduli tentang "minggu secara keseluruhan." Jadi apakah satu tahun memiliki 52 atau 53 minggu tidak ada bedanya.

Hanya untuk menghindari kebingungan di masa depan dengan apakah ini menangani batas tahun dengan benar — menurut Wikipedia , semua minggu selalu dimulai pada hari Senin dan berakhir pada hari Minggu.

Untuk beberapa trik mewah lainnya, ini semua setara:

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
Gagang pintu
sumber
Tidak bisa Anda dapat menyimpan 1 arang menggantikan a==boleh a<b?
Tensibai
1

VBA, 125 Bytes

Mengharapkan 2 input fungsi sebagai string

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

Cukup yakin Ini bisa bermain golf. Ini adalah perulangan meskipun setiap hari antara 2 tanggal dan menambah penghitung setiap kali tanggal ISO berubah.

DatePart("ww",f+i,2,2)adalah angka minggu ISO dalam VBA 2 artinya pertama Monday (complies with ISO standard 8601, section 3.17). maka yang kedua berarti 2Week that has at least four days in the new year (complies with ISO standard 8601, section 3.17)

140 byte w / input tunggal

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
sumber
1

R, 76 byte

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

Setelah berbicara dengan @Doorknob, akhirnya semudah menghitung hari Senin.

seq memungkinkan untuk membuat vektor tanggal (setiap hari antara dua tanggal) dan strftime mengubahnya menjadi 'jumlah hari dalam seminggu', sekarang hitung berapa kali 1 untuk mendapatkan jumlah waktu Anda mengubah minggu dan tambahkan 1 ke memperhitungkan minggu sebelumnya.

Perulangan pendekatan lain:

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
Tensibai
sumber
1
Mengenai pendekatan kedua Anda, Anda hanya perlu menambahkan 1 ke jumlah total Senin jika tanggal pertama tidak jatuh pada hari Senin.
DavidC
@DavidCarraher Terima kasih, membaca jawaban Anda membuat saya berpikir saya bisa menghapus hari pertama rentang, sehingga memperbaiki masalah :)
Tensibai
0

Mathematica 135 79 96 84 74 byte

Konsisten dengan saran @ Doorknob, ini

  • menghasilkan semua tanggal dalam kisaran

  • menghitung jumlah Senin ( ISOWeekDay== "1") di DateRange(tidak termasuk d), dan

  • menambah 1total.


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
sumber