Minggu apa ini?

8

Hari dalam seminggu dan bulan dalam setahun tampaknya mendapat banyak perhatian tetapi tampaknya tidak ada yang peduli dengan minggu dalam setahun. Saya percaya ini saatnya untuk mengubahnya, jadi tugas Anda adalah menulis program atau fungsi yang ketika diberi tanggal menghasilkan bilangan bulat antara 1 dan 53 yang sesuai dengan minggu berjalan tahun ini.

Untuk keperluan tantangan ini, kita akan mengatakan bahwa hari Minggu pertama tahun itu menandai awal tahun sehingga satu - satunya kasus ketika 1 Januari dianggap sebagai minggu 1 adalah ketika jatuh pada hari Minggu.

  • Input dapat berupa format tanggal apa pun yang tidak secara eksplisit menyertakan nomor minggu (cukup cantumkan format dalam jawaban Anda) untuk tanggal antara 1JAN1900dan 31DEC2100.
  • Output adalah bilangan bulat antara 1 dan 53
  • Anda dapat menggunakan metode standar apa pun untuk menyediakan input / output.

Uji Kasus

17MAY2017 -> 20

3JAN2013 -> 53

1JAN2017 -> 1

17MAY1901 -> 19

31DEC2100 -> 52

7JUL2015 -> 27
  • Ini adalah sehingga semua aturan standar golf berlaku, dan kode terpendek (dalam byte) menang.
J_Lard
sumber
5
Minggu ISO akan lebih standar; IIRC mereka berdasarkan pada hari Kamis pertama dalam setahun.
Neil
Bisakah kita menggunakan format input tanggal lainnya (yaitu, 07/07/2015)? Bisa 7JUL2015menjadi 07JUL2015?
Stephen
@StephenS Ya, tidak apa-apa. 7/7/2015, 2015-07-07juga valid.
J_Lard
2
@ Neil: Tidak benar-benar cocok dengan definisi standar adalah hal yang baik di sini, itu membuatnya lebih kecil kemungkinannya bahwa masalah hanya dapat diselesaikan melalui builtin, sementara membuatnya tidak lebih sulit untuk diselesaikan tanpa.
4
Catatan untuk orang-orang yang menggunakan %U: Seperti yang ditunjukkan oleh @J_Lard, Anda perlu berhati-hati mengenai apakah minggu 0 adalah minggu 52 atau 53 tahun sebelumnya. Ini minggu ke 53 pada tahun 2001, 2007, 2013, 2018, 2024, 2029 dan berulang dalam siklus 28 tahun. Tahun-tahun lain minggu ke 52.
Neil

Jawaban:

2

Ohm , 12 33 byte

EDIT : Memperbaiki kasing tepi untuk "% U".

IΩDÖ?┼╓y≤s"-12-31"C"%F"╓₧Ω
"%U"╓&

Asumsikan input bisa berupa cap waktu. Penjelasan yang akan datang.

Cobalah online!

Nick Clifford
sumber
1
Minggu 0 berbeda pada tahun-tahun seperti 1995 dan 2023.
Neil
@ Neil Itu benar, tetapi tantangannya mengatakan bahwa jawabannya harus di antara 1 dan 53, dan saya pada dasarnya melakukan hal yang sama dengan semua jawaban lainnya.
Nick Clifford
Maaf, tahun-tahun saya campur aduk. Bagaimanapun, 52 dalam beberapa tahun, dan 53 pada yang lain.
Neil
@Neil Kita mulai.
Nick Clifford
1
Memang, ini memberikan jawaban yang benar untuk misalnya Jan 1 2018 dan 2019.
Neil
6

MATL , 50 byte

Terima kasih kepada @Neil dan @NickClifford karena menunjukkan kesalahan, sekarang diperbaiki

ZO1)TThXJYOXIGYO&:8XO!s310=sJ4B-YOIq&:8XO!s310=sX\

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

Ini menggunakan tiga fungsi konversi tanggal / waktu yang ada di MATL:

  • XO: mengonversi tanggal dan waktu ke format string;
  • YO: mengonversi tanggal dan waktu ke nomor tanggal seri;
  • ZO: konversi tanggal dan waktu ke vektor komponen.

Menentukan apakah minggu "0" harus menjadi 52 atau 53 itu mahal, karena MATL tidak dapat mendefinisikan fungsi yang dapat dipanggil untuk menggunakan kembali 8XO!s310=sbagian itu. Menggunakan kembali dengan cara loop dengan cabang hanya menghemat satu byte , dan menyulitkan penjelasan, jadi mungkin tidak sepadan.

Juga, sesuatu dapat diperoleh dengan memasukkan tanggal sebagai array [tahun, bulan, hari]; tetapi saya tidak akan menggunakan ketiga fungsi tanggal :-)

Pertimbangkan input '17MAY2017'sebagai contoh.

       % Implicit input
       % STACK: '17MAY2017'
ZO     % Convert to date vector
       % STACK: [2017 5 17]
1)     % Get first entry: year
       % STACK: 2017
TTh    % Append [1 1]
       % STACK: [2017 1 1]
XJ     % Copy to clipboard J
YO     % Convert to date number
       % STACK: 736696
XI     % Copy to clipboard I
GYO    % Push input again. Convert to date number
       % STACK: [736696 736832]
&:     % Binary range
       % STACK: [736696 736697 736698 ... 736832]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: ['Sun'; 'Mon'; 'Tue'; ... ; 'Wed']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: [310 298 302 ...  288]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: [1 0 0 ... 0]
s      % Sum of array. If is 0, it needs to be transformed into 52 or 53,
       % depending on the number of Sundays the previous year contains.
       % STACK: 20
J      % Paste from clipboard J
       % STACK: 20, [2017 1 1]
4B-    % Push [1 0 0] and subtract element-wise
       % STACK: 20, [2016 1 1]
YO     % COnvert to date number
       % STACK: 20, 736330
I      % Paste from clipboard I
       % STACK: 20, 736330, 736696
q      % Subtract 1
       % STACK: 20, 736330, 736695
&:     % Binary range
       % STACK: 20, [736330 736331 736332 ... 736695]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: 20, ['Fri'; 'Sat'; 'Sun'; ... ; 'Sat']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: 20, [289 296 310 ... 296]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: 20, [0 0 1 ... 0]
s      % Sum of array
       % STACK: 20, 52
X\     % 1-based modulo
       % STACK: 20
       % Implicit display
Luis Mendo
sumber
2
Selamat atas 50k! Saya ada di belakang Anda :)
Digital Trauma
1
2 poin lagi ... dan booming! Selamat!
Jonathan Allan
Apakah ini bekerja dengan kasus tepi yang ditunjukkan oleh Neil? Saya tahu itu tidak digunakan %U, tetapi saya hanya ingin memastikan.
Nick Clifford
Ini sepertinya berpikir bahwa 1 Januari 2019 ada di Minggu 53, tetapi ini baru di Pekan 52.
Neil
@Neil Ya, Anda benar. Menariknya kasus uji lainnya benar.
J_Lard
4

JavaScript (ES6), 82 80 byte

Mengambil input sebagai (year,month,day).

let f =

(y,m,d)=>-~((((x=new Date(y,m-1,d))-new Date(y,0,1))/864e5+372-x.getDay())/7%53)

console.log(f(2017, 5,17)) // 20
console.log(f(2013, 1, 3)) // 53
console.log(f(2017, 1, 1)) // 1
console.log(f(1901, 5,17)) // 19
console.log(f(2100,12,31)) // 52
console.log(f(2015, 7, 7)) // 27

Arnauld
sumber
4

JavaScript (Firefox 34+), 70 byte

with(new Date())y.value=getFullYear(),m.value=getMonth()+1,d.value=getDate()+1
f=
(y,m,d)=>new Date(y,--m,d-new Date(y,m,d).getDay()).toLocaleFormat`%U`
<div oninput=w.value=f(y.value,m.value,d.value)><input id=y type=number><input id=m type=number min=1 max=12><input id=d type=number min=1 max=31><input id=w readonly placeholder=Output>

Bekerja dengan menemukan hari pertama dalam minggu yang berisi tanggal yang diberikan, kemudian menemukan nomor minggu hari itu (yang tidak pernah nol).

Neil
sumber
+1 untuk with. Selalu beri +1 untuk with!
Shaggy
2

Python 2, 70 64 byte

Input => (year,month,day)

from datetime import*;lambda*v:int(date(*v).strftime('%U'))or 53

print(f(2017, 5,17)) #20
print(f(2013, 1, 3)) #53
print(f(2017, 1, 1)) #1
print(f(1901, 5,17)) #19
print(f(2100,12,31)) #52
print(f(2015, 7, 7)) #27

-6 byte, terima kasih kepada @ovs

Wondercricket
sumber
2

JavaScript (Hanya Firefox), 77 byte

Mengambil tanggal sebagai string: mis Jan 1, 2017

s=>+new Date(s)[k='toLocaleFormat']`%U`||new Date(s.slice(-4)-1,11,31)[k]`%U`
powelles
sumber
Usaha yang bagus tetapi "minggu 0" tidak selalu minggu yang sama (1995 dan 2023 berbeda).
Neil
Maaf, kasus pengujian salah. Saya harus memposting komentar yang tepat pada pertanyaan itu.
Neil
@Neil Ini harus diperbaiki.
powelles
2

PHP, 125 Bytes

for($w=53,$a=0;($c=date_create)($argn)>=$n=date_modify($c("07JAN1900"),"+$a week");$a++)$w=date_format($n,z)<7?1:$w+1;echo$w;

Cobalah online!

PHP, 28 Bytes

Versi untuk Senin, bukan Minggu

<?=date(W,strtotime($argn));

Cobalah online!

Jörg Hülsermann
sumber
2

C #, 138 123 121 byte

namespace System.Globalization{d=>CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d,(CalendarWeekRule)1,(DayOfWeek)0);}

Ternyata ada built-in untuk itu, meskipun agak besar ...

namespace System.Globalization
{
    Func<DateTime, int> f = d =>
        CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, (CalendarWeekRule)1, (DayOfWeek)0);
 }
TheLethalCoder
sumber
1

Powershell, 260 + 8 = 268 byte

+8 byte karena -DateTimebendera


Terima argumen sebagai "day month year"format.

function W([datetime]$DateTime = (Get-Date)) {
$cultureInfo = [System.Globalization.CultureInfo]::CurrentCulture
$cultureInfo.Calendar.GetWeekOfYear($DateTime,$cultureInfo.DateTimeFormat.CalendarWeekRule,$cultureInfo.DateTimeFormat.FirstDayOfWeek)
}

Bukan ahli Powershell, tidak bisa bermain golf


Kasus cobaan

>W -DateTime "11 March 2015"
11
stevefestl
sumber