Hari apa hari ini (atau tanggal lainnya)?

12

Tugas

Tulis program atau fungsi yang menghitung nama hari-hari dari tanggal yang dimasukkan pengguna.

Input output

Input adalah string YYYYMMDD,.

Contoh nilai input:

20110617: 17 Juni 2011
19040229: 29 Februari 1904
06661225: 25 Desember 666
00000101: 1 Januari 0
99991231: 31 Desember 9999

Anda dapat mengasumsikan bahwa semua input valid. Perhatikan bahwa tahun nol adalah valid.

Output adalah bilangan bulat antara 0dan 6. Setiap bilangan bulat mewakili nama hari kerja. Anda dapat memutuskan bilangan bulat mana yang mewakili nama hari kerja, seperti ini

0: Senin
1: Selasa
2: Rabu
...
6: Minggu

(dalam urutan) atau yang ini

0: Senin
1: Rabu
2: Minggu
...
6: Sabtu

(tidak berurutan).

Uji Kasus

Input Output Hari-Hari ([0..6 -> Senin..Sunday] digunakan dalam contoh ini.)

20110617 Jumat 4
19500101 Minggu 6
22220202 Sabtu 5
19000228 Rabu 2
19000301 Kamis 3
19450815 Rabu 2
19040229 Senin 0
19040301 Selasa 1
17760704 Kamis 3
20000228 Senin 0
20000229 Selasa 1
20000301 Rabu 2
20121223 Minggu 6
00000401 Sabtu 5
66660606 Rabu 2
59161021 Sabtu 5

Larangan

Anda tidak boleh menggunakan segala jenis fungsi / kelas / ... yang terkait dengan stempel waktu atau tanggal, seperti Datekelas di Java/ JavaScript/ ActionScript, atau getdatefungsi dalam PHP.

Anda harus menggunakan kalender Gregorian , yang digunakan oleh banyak orang sekarang.

Tentu saja, kode terpendek menang. Jika dua kode memiliki panjang yang sama, maka kode dengan suara terbanyak menang.

(Jatuh tempo: Ketika ada lebih dari 5 kode yang memiliki lebih dari (atau setara) +1suara.)

JiminP
sumber
Hari ini? Kenapa, Hari Natal!
Joey Adams
3
Solusi Optimis ditulis dalam Bash (6 karakter): echo 4.
kebenaran
1
@trutheality Tidak, saya tidak bermaksud seperti itu. Yang saya inginkan adalah kode yang mencetak / mengembalikan hari dalam seminggu dari tanggal seseorang mengetik, bukan hanya mencetak hari dalam seminggu hari ini.
JiminP
Oh saya tahu. Itulah yang dilakukan orang ini.
kebenaran
Benar setidaknya 14% dari waktu!
Draco18s tidak lagi mempercayai SE

Jawaban:

2

Ruby, 95 92 karakter

Implementasi ruby ​​langsung polos dengan 0: Senin, ...

p ((y=(d=gets.to_i)/(k=100)/k-((m=d/k%k)<3?1:0))+y/4-y/k+y/400+"squsptrotqro"[-m].ord+d%k)%7
Howard
sumber
4

PHP - 101 97 103 125 karakter

  • Algoritma Sakamoto
  • 0 = Minggu

Kode

<?php fscanf(STDIN,"%4d%2d%2d",$y,$m,$d);@$a=a032503514624;$y-=$m<3;$z=$y+1;echo($y+$y/4%$z-$y/100%$z+$y/400%$z+$a[$m]+$d)%7;

Catatan

Sayangnya, karena dinamis, lemah mengetik PHP, algoritma Sakamoto tidak berfungsi dengan baik tanpa secara eksplisit lantai operasi masing-masing divisi.

rintaun
sumber
Bisakah Anda menguji lagi? Selama beberapa tahun ini memberi saya hasil yang berbeda (mis. Testcase 17760704 menghasilkan Selasa bukan Rabu).
Howard
@ Bagaimana itu sangat aneh; untuk 17760704, saya mendapatkan hari Rabu. Saya mendapatkan inkonsistensi lain, yang tidak dapat saya pertanggungjawabkan, misalnya 19040229 kembali pada hari Selasa. Tidak yakin apa yang menyebabkan ini. Saya mendapatkan hasil yang sama ketika saya mengembangkan kembali algoritma y+y/4-y/100+y/400.
rintaun
Saya bisa melihatnya terjadi dengan 497 * y / 400: y=4dalam kasus itu mengembalikan 4, bukan 5 yang benar dari y+y/4+y/100+y/400(di mana hanya dua istilah pertama ikut bermain). Itulah yang mengganggu jawaban JavaScript saya. Apakah mungkin dobel dibuat bukan int? (PHP saya terlalu lemah untuk diketahui.)
DocMax
@ DocMax: Meninggalkan ekspresi diperluas memiliki hasil yang sama (497y / 400 harus sama: y / 100 dikurangi dan y / 400 ditambahkan lagi terlepas). Saya menduga bahwa PHP hanya memotong semua setelah desimal daripada membulatkannya. Saya menguji ini dengan pembulatan sebelum modulo. Ini memperbaiki dua anomali, tetapi 19040229 masih mengembalikan hasil yang sama. Ada ide lain?
rintaun
@ rintaun saya tidak berpikir itu pembulatan. Mereka secara fundamental berbeda. Ambil contoh dari atas (y = 4): 497 * 4/400 = 1988/400 = 4 tetapi di sisi lain 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . Persyaratan / 100 dan / 400 mendapatkan terlalu banyak berat dalam perhitungan Anda sehingga 2000 tidak dapat dijangkau.
Howard
2

C - 129

main(y,m,d,s)
{
    scanf("%04d%02d%02d",&y,&m,&d);
    y-=s=86400;
    d+=y+"-addgbegcfadf"[m];
    m>2?y++:0;
    putchar(48+(d+y/4-y/100+y/400+s+s)%7);
}

Ini menyalahgunakan bagaimana pembagian berputar ke nol, setidaknya pada sistem saya (Linux x86).

Konstanta ajaib 86400,, melayani dua tujuan:

  • Kurangi dari tahun untuk membuatnya negatif, tanpa memengaruhi hari dalam seminggu. Ini membuatnya sehingga divisi akan mengumpulkan bukan ke bawah.
  • Geser nomor hari sehingga Senin akan menjadi 0.

Itu juga merupakan jumlah detik dalam sehari.

Joey Adams
sumber
Gunakan y+=m>2;alih-alih m>2?y++:0;dan cukur beberapa byte.
jelas
2

Javascript, 126 123 karakter

Menggunakan algoritma Sakamoto dengan 0 = Minggu:

prompt().replace(/(....)(..)(..)/,function(_,y,m,d){y-=m<3;alert((+d+y-~(y/4)+~(y/100)-~(y/400)+ +".621462403513"[+m])%7)})

Saya curiga divisi-divisi itu bisa runtuh, tetapi saat ini saya tidak melihatnya.

Sunting: Memperbaiki divisi (tidak perlu ~~ketika Anda bisa saja ~).

DocMax
sumber
2

Python 2 , 83 116 113 109 byte

Menerapkan algoritma Sakamoto . Saran bermain golf diterima. Cobalah online!

Sunting: Saya harus memperbaikinya beberapa waktu yang lalu. -6 byte dari saran Jonathan Allan +2 byte untuk benar-benar memperbaiki kode.

def w(s):m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:]);return(y+y/4-y/100+y/400+int('032503514624'[m-1])+d)%7
Sherlock9
sumber
Input harus berupa string tunggal.
msh210
int('032503514624'[m-1])hemat 6
Jonathan Allan
0

Perl - 110 byte

Berikut ini adalah solusi untuk dijalankan dengan perl -p source.pl ATAU perl -pe 'di sini adalah kode'.

s/((..)(..))(..)(..)/(1+3*$1+$2-2*($1%4+$2%4)-(2<$4?$4+(1&$4&&4-(8&$4)):(2^$4)+(!($3%4)-!-$3+!($2%4)))+$5)%7/e

Cukup salin-tempel kasus uji ke stdin.

Ini tampaknya menjadi satu-satunya kode tanpa variabel, konstanta string, dan divisi.

Layosh
sumber
0

JavaScript (ES6), 73 byte (Tidak bersaing)

d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)

Cobalah

f=
d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)
o.innerText=f(i.value="59161021")
oninput=_=>i.value.length==8&&(o.innerText=f(i.value))
<input id=i type=number><pre id=o>

Shaggy
sumber
Kenapa tidak bersaing?
programmer5000
@ programmer5000, periksa tanggal tantangan itu diposting;)
Shaggy