Dzisiaj jest Centrum

36

Biorąc pod uwagę datę jako dane wejściowe w dowolnym dogodnym formacie, wydrukuj kalendarz z tą datą jako dokładnym środkiem pięciotygodniowego okna. Nagłówek kalendarza musi zawierać dwuliterowe skróty dla dni tygodnia (tj Su Mo Tu We Th Fr Sa.). Trzyliterowe lub inne skróty dni są niedozwolone.

Na przykład dane April 2 2019wejściowe powinny mieć wartość wyjściową

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

tak aby podana data była dokładnym środkiem kalendarza.

Biorąc pod uwagę February 19 2020wydajność

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

Dla September 14 1752pokaż następujące:

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

  • Dane wejściowe i wyjściowe można podać dowolną dogodną metodą .
  • Wejście jest gwarantowana niepusty i ważne (czyli nigdy nie otrzyma ""lub Feb 31itd.).
  • Załóżmy kalendarz gregoriański dla wszystkich dat.
  • Lata przestępne należy uwzględnić.
  • Daty wprowadzania będą się wahać od Jan 1 1600do Dec 31 2500.
  • Możesz wydrukować go do STDOUT lub zwrócić jako wynik funkcji.
  • Dopuszczalny jest pełny program lub funkcja.
  • Dopuszczalna jest dowolna ilość obcych białych znaków, o ile znaki są odpowiednio ustawione w jednej linii.
  • Zera wiodące w jednocyfrowych dniach są dozwolone, podobnie jak wyrównanie jednocyfrowych dni, aby zamiast tego były wyrównane do lewej.
  • Standardowe luki są zabronione.
  • To jest więc obowiązują wszystkie zwykłe zasady gry w golfa, a wygrywa najkrótszy kod (w bajtach).
AdmBorkBork
źródło

Odpowiedzi:

12

R , 77 72 bajtów

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

Wypróbuj online!

Naprawiono wyjście do używania 2-literowych skrótów dnia.

-1 bajt strtrimdzięki Aaronowi Haymanowi .

Podpisuje daty z wiodącymi zerami; przyjmuje dane wejściowe jako Date, które można utworzyć za pomocą as.Date("YYYY/MM/DD").

Dziwnie skrótowe dla R odpowiedzi ...

Giuseppe
źródło
8

05AB1E , 175 174 172 171 160 bajtów

¦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ô»

Wprowadź w formacie [day, month, year]. Wyjście z wiodących 0s dla dni jednocyfrowe i małe litery moprzez su(+1 bajt może być dodany jeśli titlecase jest obowiązkowe).

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Cholera jasna ... To może być mój nowy rekord dla najdłuższej odpowiedzi 05AB1E, a potem dołączę kilka bardzo złożonych wyzwań które zrobiłem ...>.> EDYCJA: Hmm ok, prawie ..; p

Ważna uwaga: 05AB1E nie ma żadnych wbudowanych obiektów Data ani obliczeń. Jedynym wbudowanym pod względem dat jest dzisiejszy rok / miesiąc / dzień / godziny / minuty / sekundy / mikrosekundy.

Z tego powodu prawie cały kod, który widzisz, to ręczne obliczenia do obliczenia poprzednich i następnych dni (w tym przejście przez lata i pamiętanie lat przestępnych) oraz obliczenie dnia tygodnia przy użyciu zgodności Zellera .

Ogromne części kodu są kopiowane mojej wcześniejszej odpowiedzi 05AB1E , która będzie również istotna dla wyjaśnienia poniżej.

Wyjaśnienie:

Zaczynamy od pierwszego dnia poprzedniego miesiąca:

¦          # 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`

Następnie używam tej daty jako daty początkowej i obliczam następne 100 dni:

т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

Następnie, z datą wejścia jako środkiem, zostawiam 17 przed i 17 po tej dacie z listy:

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

Teraz mamy 35 dni. Następnym krokiem jest obliczenie dnia tygodnia i utworzenie nagłówka tabeli wyników:

¬                # 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

Zobacz moją wskazówkę 05AB1E (sekcja Jak kompresować ciągi znaków nie będące częścią słownika? ), Aby zrozumieć, dlaczego tak .•4ιõ÷‡o‹ƶ¸•jest"sasumotuwethfr" .

Następnie tworzymy dni do wypełnienia samej tabeli na podstawie naszej wcześniej utworzonej listy dat. Które połączymy razem z nagłówkiem. Po czym możemy wydrukować wynik końcowy:

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
źródło
2
To ogrom pracy!
Luis Mendo
2
Tak, Java pokonuje 05AB1E! : D Chyba pierwszy raz ;-)
Olivier Grégoire
@LuisMendo Most został zrobiony ostatnim razem z połączonym wyzwaniem, ale tak, to było dużo pracy ..;) Dodano objaśnienie.
Kevin Cruijssen
@ OlivierGrégoire Teraz jesteśmy tym samym bye-count. ;)
Kevin Cruijssen
@ OlivierGrégoire A teraz przepraszamy. ; p
Kevin Cruijssen
6

JavaScript (ES6),  141  126 bajtów

Zaoszczędzono 15 bajtów, pożyczając .toUTCString().slice(0,2)od odpowiedzi Neila

Pobiera dane wejściowe jako obiekt 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):''

Wypróbuj online!

Arnauld
źródło
Huh, mógłbym przysiąc, że mój kod nie zadziałał w trzecim przypadku testowym, kiedy go pierwotnie napisałem ... no cóż, oszczędza mi 52 bajty ...
Neil
4

JavaScript (Node.js) , 205 152 145 bajtów

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>

Wypróbuj online! Pobiera dane wejściowe jako obiekt daty JavaScript lub znacznik czasu. Edycja: Zapisałem 1 bajt dzięki @EmbodimentofIgnorance, co pozwoliło mi zaoszczędzić kolejne 7 bajtów, dodając końcowy znak nowej linii do wyniku. Zaoszczędziłem 52 bajty, gdy odkryłem, że pracowałem nad zachowaniem, które w rzeczywistości nie było błędne ...

Neil
źródło
padStart(2)-> padStart(3), usuń spację w ciągu łączenia dla -1 bajtów
Embodiment of Ignorance
3

Perl 6 , 87 bajtów

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

Wypróbuj online!

Bierze Dateobiekt, zwraca listę linii.

nwellnhof
źródło
2

Wolfram Language (Mathematica) , 123 bajty

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

Wypróbuj online!

Nie wiem, dlaczego Gridnie działa na TIO, ale ten kod to wyświetla

enter image description here

@DavidC zapisał 1 bajt

J42161217
źródło
Może Gridnie działa, ponieważ TIO nie może wyśrodkować elementów jak na zdjęciu?
AdmBorkBork
@AdmBorkBork Istnieje sposób na załadowanie takiej grafiki w TIO. Chyba ktoś mi pokazał w zeszłym roku. Ale nie pamiętam, jak to zrobić ... Jeśli ktoś wie, daj nam znać!
J42161217
2

MATL , 34 33 31 bajtów

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

Wypróbuj online!

Wyjaśnienie

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
źródło
2

Java (JDK) , 149 bajtów

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));}

Wypróbuj online!

Kredyty

Olivier Grégoire
źródło
1
159 bajtów
Kevin Cruijssen
1
@KevinCruijssen Poczekaj ... co? Gratuluję ci! Próbowałem to zrobić, ale nie mogłem znaleźć sposobu, aby to zrobić, a jednak to zrobiłeś! Bardzo miło :-)
Olivier Grégoire
1
Może widzisz coś więcej, aby połączyć ii jjakoś? A może coś krótszego j++%7<1?10:32z odrobiną magii? Ale zostawię to tobie. Wracam do pracy, lol. ;)
Kevin Cruijssen
1
Ach, oczywiście .. Niezła praca zespołowa! ;) PS: Gdzie jest wskrót? Dlaczego nie hnagłówek?
Kevin Cruijssen
1
@KevinCruijssen wna „dzień wag tyg”. Także kręcenie bitów może prowadzić tylko do (i%7+6)/7*22+10tego, że jest znacznie dłuższy.
Olivier Grégoire
2

PHP ,197 189 187 bajtów

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);

Wypróbuj online!

Dane wejściowe są STDINciągiem daty. Uruchom z 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 

Sprawdź wszystkie przypadki testowe

Lub 174 bajty z zerowanymi pojedynczymi cyframi.

640 KB
źródło
1

Excel VBA, 190 159 bajtów

Dzięki @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

Pobiera dane wejściowe w postaci prawidłowego ciągu daty dla Excel VBA (np. 19 lutego 2020 r .; 2/19/2020; 19 lutego 2015 r.) I zwraca tablicę z danym kalendarzem na środku.

William Porter
źródło
Możesz zmniejszyć to rozwiązanie do 159, usuwając spację z tego rozwiązania,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 Dzięki, korzystałem tylko z wbudowanego edytora, który automatycznie wypełnia te przestrzenie.
William Porter
0

Czerwony , 153 131 bajtów

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]]]

Wypróbuj online!

Galen Iwanow
źródło
0

T-SQL, 203 bajty

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

Wersja online jest nieco inna, ta opublikowana wersja działa w MS-SQL Studio Management. To oszczędza 1 bajt w porównaniu z wersją online, ale nie daje poprawnego wyniku online

Wypróbuj online

t-clausen.dk
źródło
0

Python 2 , 115 bajtów

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

Wypróbuj online!

Nie jestem pewien, czy jest to dozwolone ... pobiera dane wejściowe ze STDIN w formularzu date(year, month, day). Można to również przedstawić jako __import__('datetime').date(year, month, day). To są naprawdę __import__('datetime').dateprzedmioty.

Erik the Outgolfer
źródło