Hari ini adalah Pusat

36

Diberi tanggal sebagai input dalam format apa pun yang nyaman, mengeluarkan kalender dengan tanggal tersebut sebagai pusat tepat dari jendela lima minggu. Header kalender harus menyertakan singkatan dua huruf untuk hari dalam seminggu (yaitu, Su Mo Tu We Th Fr Sa). Tiga huruf atau singkatan lainnya tidak diperbolehkan.

Misalnya, diberikan April 2 2019sebagai input, hasilnya harus

Sa Su Mo Tu We Th Fr
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31  1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19

sehingga tanggal yang diberikan tepat di tengah kalender.

Diberikan February 19 2020, output

Su Mo Tu We Th Fr Sa
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
 1  2  3  4  5  6  7

Untuk September 14 1752, perlihatkan yang berikut:

Mo Tu We Th Fr Sa Su
28 29 30 31  1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  1

  • Input dan output dapat diberikan dengan metode apa pun yang mudah .
  • Input dijamin tidak kosong dan valid (yaitu, Anda tidak akan pernah menerima ""atau Feb 31lain - lain).
  • Asumsikan kalender Gregorian untuk semua tanggal.
  • Tahun kabisat harus diperhitungkan.
  • Tanggal input akan berkisar dari Jan 1 1600hingga Dec 31 2500.
  • Anda dapat mencetaknya ke STDOUT atau mengembalikannya sebagai hasil fungsi.
  • Program lengkap atau fungsi dapat diterima.
  • Berapapun jumlah spasi putih yang asing dapat diterima, asalkan karakter berbaris dengan tepat.
  • Angka nol di depan pada hari satu digit diperbolehkan, seperti halnya menyelaraskan hari dengan digit tunggal untuk dibariskan ke kiri sebagai gantinya.
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.
AdmBorkBork
sumber

Jawaban:

12

R , 77 72 byte

function(d,`~`=format)write(c(strtrim(d+-3:3~"%a",2),d+-17:17~"%e"),1,7)

Cobalah online!

Memperbaiki output untuk menggunakan singkatan 2 hari surat.

-1 byte menggunakan strtrimterima kasih kepada Aaron Hayman .

Pads angka tanggal dengan 0s terkemuka; mengambil input sebagai Date, yang dapat dibuat dengan menggunakan as.Date("YYYY/MM/DD").

Anehnya jawaban R ...

Giuseppe
sumber
8

05AB1E , 175 174 172 171 160 byte

¦WΘ1š-1šVтFY`2ô0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVY})DJIJk18+£35.£¬.•4ιõ÷‡o‹ƶ¸•2ôs`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()DćsćsO7%._s€нT‰J«7ô»

Masukkan dalam format [day, month, year]. Output dengan leading 0s untuk hari satu digit, dan huruf kecil momelalui su(+1 byte dapat ditambahkan jika titlecase wajib).

Cobalah secara online atau verifikasi semua kasus uji .

Sial .. Ini mungkin rekor baru saya untuk jawaban 05AB1E terpanjang, dan kemudian saya sertakan beberapa tantangan sangat rumit yang saya lakukan ...>.> EDIT: Hmm ok, hampir ..; p

Catatan penting: 05AB1E tidak memiliki builtin untuk objek atau perhitungan Date. Satu-satunya bawaan tentang tanggal yang dimilikinya adalah tahun / bulan / hari / jam / menit / detik / hari ini hari ini.

Jadi karena itu, hampir semua kode yang Anda lihat adalah perhitungan manual untuk menghitung hari-hari sebelumnya dan berikutnya (termasuk transisi dari tahun ke tahun dan mengingat tahun kabisat), dan menghitung hari dalam seminggu dengan menggunakan kongruensi Zeller .

Sebagian besar kode disalin dari jawaban saya sebelumnya 05AB1E , yang juga akan relevan untuk penjelasan di bawah ini.

Penjelasan:

Kami mulai dengan pergi ke hari pertama bulan sebelumnya:

¦          # Remove the first item (the days) from the (implicit) input
 W         # Get the minimum (without popping the list itself)
           # (since the year is guaranteed to be above 1599, this is the month)
  Θ        # Check if its exactly 1 (1 if 1, 0 if in the range [2,31])
   1š      # Prepend a 1 as list (so we now have either [1,1] or [1,0]
     -     # Subtract this from the month and year
      1š   # And prepend a 1 for the day
        V  # Pop and store this first day of the previous month in variable `Y`

Lalu saya menggunakan tanggal itu sebagai tanggal mulai, dan menghitung 100 hari berikutnya:

тF    # Loop 100 times:
  Y`2ô0Kθ4ÖUD2Qi\28X+ë<731α}‹iY¬>0ëY1¾ǝDÅsD12i>1ë\1Dǝ¤>2}}ǝV
      #  Calculate the next day in line
      #  (see the linked challenge above for a detailed explanation of this)
   Y  #  And leave it on the stack
 })   # After the loop: wrap the entire stack into a list, which contains our 100 days

Kemudian, dengan tanggal input sebagai tengah, saya hanya meninggalkan tanggal 17 sebelum dan 17 setelah tanggal input tersebut dari daftar:

DJ          # Duplicate the 100 dates, and join the day/month/year together to strings
  IJ        # Push the input, also joined together
    k       # Get the 0-based index of the input in this list
            # (the joins are necessary, because indexing doesn't work for 2D lists)
     18+    # Add 18 to this index (18 instead of 17, because the index is 0-based)
        £   # Only leave the first index+18 items from the 100 dates
     35.£   # Then only leave the last 35 items

Sekarang kami memiliki 35 hari. Langkah selanjutnya adalah menghitung hari dalam seminggu, dan membuat header dari tabel output:

¬                # Get the first date of the list (without popping the list itself)
 .•4ιõ÷‡o‹ƶ¸•    # Push compressed string "sasumotuwethfr"
             2ô  # Split it into chunks of size 2
s                # Swap to get the first date again
 `UÐ312*+>13*5÷s3Xα©т%D4÷®т÷©4÷®·()DćsćsO7%
                 # Calculate the day of the week (sa=0; su=1; ...; fr=6)
                 # (see the linked challenge above for a detailed explanation of this)
  ._             # Rotate the list of strings that many times

Lihat ini 05AB1E ujung tambang (bagian Cara string kompres bukan bagian dari kamus? ) Untuk memahami mengapa .•4ιõ÷‡o‹ƶ¸•adalah "sasumotuwethfr".

Lalu kami membuat hari untuk mengisi tabel itu sendiri berdasarkan daftar tanggal yang kami buat sebelumnya. Yang akan kita gabungkan bersama dengan tajuknya. Setelah itu kita dapat mencetak hasil akhir:

s           # Swap to get the list of dates again
 €н         # Only leave the first item of each date (the days)
   T       # Take the divmod 10 of each
     J      # Join those divmod results together
            # (we now have leading 0s for single-digit days)
      «     # Merge this list together with the header list
       7ô   # Split it into chunks of size 7
         »  # Join each inner list by spaces, and then each string by newlines
            # (and output the result implicitly)
Kevin Cruijssen
sumber
2
Itu pekerjaan yang sangat besar!
Luis Mendo
2
Ya, Java mengalahkan 05AB1E! : D Pertama kali, kurasa ;-)
Olivier Grégoire
@LuisMendo Sebagian besar dilakukan terakhir kali dengan tantangan terkait, tapi ya, itu banyak pekerjaan ..;) Penjelasan telah ditambahkan btw.
Kevin Cruijssen
@ OlivierGrégoire Sekarang kita tinggal selamat tinggal. ;)
Kevin Cruijssen
@ OlivierGrégoire Dan sekarang lebih rendah lagi, maaf. ; p
Kevin Cruijssen
6

JavaScript (ES6),  141  126 byte

Disimpan 15 byte dengan meminjam .toUTCString().slice(0,2)dari jawaban Neil

Mengambil input sebagai objek Date.

f=(d,n=0)=>n<42?(D=new Date(d-864e5*(24-n)),n<7?D.toUTCString().slice(0,2):(i=D.getDate())>9?i:' '+i)+`
 `[++n%7&&1]+f(d,n):''

Cobalah online!

Arnauld
sumber
Huh, saya bisa bersumpah bahwa kode saya gagal untuk test case ketiga ketika saya awalnya menulisnya ... yah itu menyelamatkan saya 52 byte ...
Neil
4

JavaScript (Node.js) , 205 152 145 byte

f=
d=>`012345`.replace(g=/./g,r=>`0123456
`.replace(g,c=>`${new Date(d-864e5*(24-c-r*7))[+r?`getUTCDate`:`toUTCString`]()}`.slice(0,2).padStart(3)))
<input type=date oninput=o.textContent=f(this.valueAsDate)><pre id=o>

Cobalah online! Mengambil input sebagai objek Tanggal atau waktu JavaScript. Sunting: Disimpan 1 byte berkat @EmbodimentofIgnorance, yang kemudian memungkinkan saya untuk menyimpan 7 byte lebih lanjut dengan menambahkan baris baru ke output. Menyimpan 52 byte ketika saya menemukan bahwa saya sedang mengerjakan perilaku yang sebenarnya tidak bermasalah pada awalnya ...

Neil
sumber
padStart(2)-> padStart(3), hapus spasi dalam string bergabung selama -1 byte
Perwujudan Ketidaktahuan
3

Perl 6 , 87 byte

{~rotate(<Th Fr Sa Su Mo Tu We>,.day-of-week),|comb 21,($_-17..$_+17)>>.day.fmt('%2d')}

Cobalah online!

Mengambil Dateobjek, mengembalikan daftar garis.

nwellnhof
sumber
2

Bahasa Wolfram (Mathematica) , 123 byte

(s=#;Grid@Join[{StringTake[ToString@DayName[s~d~#]&/@Range[-3,3],2]},Partition[Last@d[s,#]&/@Range[-17,17],7]])&
d=DatePlus

Cobalah online!

Saya tidak tahu mengapa Gridtidak bekerja pada TIO tetapi kode ini menghasilkan ini

masukkan deskripsi gambar di sini

@ Davidvid menyimpan 1 byte

J42161217
sumber
Mungkin Gridtidak berfungsi karena TIO tidak dapat memusatkan item seperti pada gambar Anda?
AdmBorkBork
@ AdmBorkBork Ada cara untuk memuat gambar seperti ini di TIO. Seseorang telah menunjukkan kepada saya tahun lalu saya pikir. Tetapi saya tidak ingat bagaimana melakukannya ... Jadi jika ada yang tahu, beri tahu kami!
J42161217
2

MATL , 34 33 31 byte

YO-17:17+t7:)8XOO3Z(!1ew7XOU7e!

Cobalah online!

Penjelasan

YO       % Implicit input. Convert to date number. This is a single number
         % that specifies the date
-17:17   % Push [-17 -16 ... 16 17]
+        % Add to date number, element-wise. This gives a row vector of 35
         % date numbers centered around the input date
t        % Duplicate
7:       % Push [1 2 ... 7]
)        % Index into the 35-element vector. This keeps the first 7 entries
8XO      % Convert to day-of-week in 3 letters. Gives a 3-col char matrix
O3Z(     % Write char 0 (equivalent to space for display purposes) into the
         % 3rd column
!1e      % Tranpose and linearize into a row. This produces a string such as
         % 'Tu We Th Fr Sa Su Mo ', to be used as column headings
w        % Swap. This brings to top the row vector of 35 date numbers
         % computed from the input
7XO      % Convert to day-of-month. Gives a 2-col char matrix
U        % Convert each row to number
7e!      % Reshape into 7-row matrix and transpose
         % Implicit display. This prints the string with the headings and
         % the matrix. The latter has a minimum-one-space separation between
         % columns, so it is aligned with the headings
Luis Mendo
sumber
2

Java (JDK) , 149 byte

d->{d.add(5,-24);for(int i=0,w;i<42;d.add(5,1))System.out.printf("%c%2s",i%7<1?10:32,i++<7?"SaSuMoTuWeThFr".substring(w=d.get(7)%7*2,w+2):d.get(5));}

Cobalah online!

Kredit

Olivier Grégoire
sumber
1
159 byte
Kevin Cruijssen
1
@KevinCruijssen Tunggu ... apa? Saya mengucapkan selamat kepada Anda! Saya mencoba melakukan ini, tetapi tidak dapat menemukan cara untuk melakukannya, namun Anda berhasil! Sangat bagus :-)
Olivier Grégoire
1
Mungkin Anda melihat sesuatu yang lebih untuk menggabungkan idan jentah bagaimana? Atau sesuatu yang lebih pendek j++%7<1?10:32dengan sihir bitwise? Tapi aku akan menyerahkan itu padamu. Saya akan kembali bekerja, lol. ;)
Kevin Cruijssen
1
Ah, tentu saja .. Kerja tim yang bagus! ;) PS: Di mana wberdiri untuk? Kenapa tidak huntuk tajuk?
Kevin Cruijssen
1
@KevinCruijssen wuntuk "day of w eek". Juga, sedikit memutar-mutar hanya dapat menyebabkan (i%7+6)/7*22+10yang lebih lama.
Olivier Grégoire
2

PHP ,197 189 187 byte

for($d=date_create($argn)->sub($i=new DateInterval(P17D)),$i->d=1;$x++<35;$h.=$x<8?substr($d->format(D),0,2).' ':'',$d->add($i))$o.=str_pad($d->format(j),3,' ',2);echo wordwrap($h.$o,20);

Cobalah online!

Input adalah STDINsebagai string tanggal. Jalankan dengan php -nF.

$ echo April 2 2019|php -nF cal.php

Sa Su Mo Tu We Th Fr 
16 17 18 19 20 21 22 
23 24 25 26 27 28 29 
30 31  1  2  3  4  5 
 6  7  8  9 10 11 12 
13 14 15 16 17 18 19 

Verifikasi semua kasus uji

Atau 174 byte dengan digit tunggal empuk nol.

640KB
sumber
1

Excel VBA, 190 159 byte

Terima kasih @TaylorScott

Function z(i)
Dim d(5,6)
v=DateValue(i)-17
For x=1To 5
For y=0To 6
d(0,y)=Left(WeekdayName(Weekday(v+y)),2)
d(x,y)=day(v+y+(x-1)*7)
Next y,x
z=d()
End Function

Mengambil input dalam bentuk string tanggal yang valid untuk Excel VBA (mis. 19 Februari 2020; 2/19/2020; 19-Feb-2019), dan mengembalikan larik dengan kalender yang dipusatkan di atasnya.

william porter
sumber
Anda bisa mendapatkan solusi ini hingga 159 dengan menghapus spasi putih dari solusi ini,Function z(i) Dim d(5,6) v=DateValue(i)-17 For x=1To 5 For y=0To 6 d(0,y)=Left(WeekdayName(Weekday(v+y)),2) d(x,y)=Day(v+y+(x-1)*7) Next y,x z=d() End Function
Taylor Scott
@TaylorScott Terima kasih, hanya menggunakan editor bawaan yang mengisolasi ruang-ruang itu.
william porter
0

Merah , 153 131 byte

func[d][s: d - 24 loop 7[prin[""copy/part system/locale/days/(s/10) 2]s:
s + 1]loop 5[print""loop 7[prin pad/left s/4 3 s: s + 1]]]

Cobalah online!

Galen Ivanov
sumber
0

T-SQL, 203 byte

DECLARE @f date='2020-02-19'

,@ char(20)=0,@d char(105)=0SELECT
@=left(format(d,'D'),2)+' '+@,@d=right(d,2)+char(32-n%7/6*19)+@d
FROM(SELECT dateadd(d,number-17,@f)d,number n
FROM spt_values WHERE'P'=type)x ORDER BY-n
PRINT @+'
'+@d

Versi online sedikit berbeda, versi yang diposting ini berfungsi di MS-SQL Studio Management. Ini menghemat 1 byte dibandingkan dengan versi online, tetapi tidak memberikan hasil online yang benar

Cobalah online

t-clausen.dk
sumber
0

Python 2 , 115 byte

from datetime import*
d=input()
for i in range(42):print(d+timedelta(i-24)).strftime('%'+'da'[i<7])[:2]+i%7/6*'\n',

Cobalah online!

Tidak yakin apakah ini diizinkan ... menerima input dari STDIN dalam formulir date(year, month, day). Ini juga dapat direpresentasikan sebagai __import__('datetime').date(year, month, day). Ini benar-benar __import__('datetime').datebenda.

Erik the Outgolfer
sumber