Сегодня Центр

36

Учитывая дату в качестве ввода в любом удобном формате, выведите календарь с этой датой в качестве точного центра пятинедельного окна. Заголовок календаря должен включать двухбуквенные сокращения для дней недели (т. Е. Su Mo Tu We Th Fr Sa). Трехбуквенные или другие сокращения дней не допускаются.

Например, в April 2 2019качестве входных данных выходные данные должны быть

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

так что данная дата является точной серединой календаря.

Учитывая February 19 2020, выходной

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

Для September 14 1752, показывают следующее:

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

  • Вход и выход могут быть заданы любым удобным способом .
  • Вход гарантированно не пуст и действителен (т. Е. Вы никогда не получите ""и Feb 31т. Д.).
  • Предположим, григорианский календарь на все даты.
  • Високосные годы должны быть учтены.
  • Даты ввода будут варьироваться от Jan 1 1600до Dec 31 2500.
  • Вы можете распечатать его в STDOUT или вернуть как результат функции.
  • Либо полная программа или функция приемлемы.
  • Любое количество посторонних пробелов является приемлемым, при условии, что символы выстраиваются соответствующим образом.
  • Допускаются начальные нули в однозначные дни, а также выравнивание однозначных дней для выравнивания по левому краю.
  • Стандартные лазейки запрещены.
  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).
AdmBorkBork
источник

Ответы:

12

R , 77 72 байта

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

Попробуйте онлайн!

Исправлен вывод для использования двухбуквенных сокращений дня.

-1 байт strtrimблагодаря Аарону Хейману .

Числа даты колод с ведущими 0; принимает входные данные как Date, которые могут быть созданы с помощью as.Date("YYYY/MM/DD").

Странно коротко для R ответ ...

Giuseppe
источник
8

05AB1E , 175 174 172 171 160 байтов

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

Ввод в формате [day, month, year]. Выход с ведущими 0с для однозначных дней, и в нижнем регистре moчерезsu (+ 1 байт может быть добавлен , если titlecase является обязательным).

Попробуйте онлайн или проверьте все тесты .

Черт возьми ... Это может быть мой новый рекорд для самого длинного ответа 05AB1E, и затем я включаю несколько очень сложных задач я сделал ...>.> РЕДАКТИРОВАТЬ: Хм хорошо, почти ..; p

Важная заметка: 05AB1E не имеет встроенных функций для объектов Date или расчетов. Единственная встроенная функция, касающаяся дат, это текущий год / месяц / день / часы / минуты / секунды / микросекунды.

Таким образом, почти весь код, который вы видите, представляет собой ручные вычисления для вычисления предыдущих и следующих дней (включая переход по годам и с учетом високосных годов) и вычисления дня недели с использованием конгруэнтности Целлера .

Огромные части кода скопированы из этого моего более раннего ответа 05AB1E , который также будет важен для пояснения ниже.

Объяснение:

Начнем с первого дня предыдущего месяца:

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

Затем я использую эту дату в качестве даты начала и вычисляю следующие 100 дней:

т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

Затем, с вводимой датой в качестве середины, я оставляю только 17 до и 17 после этой входной даты из списка:

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

Теперь у нас есть 35 дней. Следующим шагом является вычисление дня недели и создание заголовка выходной таблицы:

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

Посмотрите эту подсказку 05AB1E (раздел Как сжимать строки, не являющуюся частью словаря? ), Чтобы понять, почему .•4ιõ÷‡o‹ƶ¸•это так "sasumotuwethfr".

Затем мы создаем дни для заполнения самой таблицы на основе нашего ранее созданного списка дат. Который мы объединяем вместе с заголовком. После чего мы можем напечатать окончательный результат:

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)
Кевин Круйссен
источник
2
Это огромный объем работы!
Луис Мендо
2
Да, Java побеждает 05AB1E! : D Впервые, наверное ;-)
Оливье Грегуар
@LuisMendo Большинство было сделано в прошлый раз со связанным вызовом, но да, это было много работы ..;) Пояснение было добавлено между прочим.
Кевин Круйссен
@ OlivierGrégoire Теперь мы одни и те же. ;)
Кевин Круйссен
@ OlivierGrégoire А теперь опять опять извините. ; p
Кевин Круйссен
6

JavaScript (ES6),  141  126 байт

Saved 15 bytes by borrowing .toUTCString().slice(0,2) from Neil's answer

Takes input as a Date object.

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):''

Try it online!

Arnauld
источник
Huh, I could have sworn that my code failed for the third test case when I originally wrote it... well that saves me 52 bytes...
Neil
4

JavaScript (Node.js), 205 152 145 bytes

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>

Try it online! Takes input as JavaScript Date object or timestamp. Edit: Saved 1 byte thanks to @EmbodimentofIgnorance, which then allowed me to save a further 7 bytes by adding a trailing newline to the output. Saved 52 bytes when I discovered that I was working around behaviour that was not actually buggy in the first place...

Neil
источник
padStart(2) -> padStart(3), remove the space in the join string for -1 byte
Embodiment of Ignorance
3

Perl 6, 87 bytes

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

Try it online!

Takes a Date object, returns a list of lines.

nwellnhof
источник
2

Wolfram Language (Mathematica), 123 bytes

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

Try it online!

I don't know why Grid doesn't work on TIO but this code outputs this

enter image description here

@DavidC saved 1 byte

J42161217
источник
Maybe Grid doesn't work because TIO can't center the items like in your picture?
AdmBorkBork
@AdmBorkBork There is a way to load graphics like this in TIO. Someone had shown me last year I think. But i can't remember how to do it... So if anyone knows, let us know!
J42161217
2

MATL, 34 33 31 bytes

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

Try it online!

Explanation

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
источник
2

Java (JDK), 149 bytes

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

Try it online!

Credits

Olivier Grégoire
источник
1
159 bytes
Kevin Cruijssen
1
@KevinCruijssen Wait... what? I congratulate you! I tried to do this, but couldn't find a way to do it, and yet you did it! Very nice :-)
Olivier Grégoire
1
Maybe you see something more to combine the i and j somehow? Or something shorter for j++%7<1?10:32 with some bitwise magic? But I'll leave that to you. I'm going back to work, lol. ;)
Kevin Cruijssen
1
Ah, of course.. Nice teamwork! ;) PS: Where does the w stand for? Why not h for header?
Kevin Cruijssen
1
@KevinCruijssen w for "day of week". Also, bit twiddling can only lead to (i%7+6)/7*22+10 which is much longer.
Olivier Grégoire
2

PHP, 197 189 187 bytes

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

Try it online!

Input is STDIN as a date string. Run with 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 

Verify all test cases

Or 174 bytes with zero-padded single digits.

640KB
источник
1

Excel VBA, 190 159 bytes

Thanks @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

Takes input in the form of a valid date string for Excel VBA (e.g. February 19, 2020; 2/19/2020; 19-Feb-2019), and returns an array with the given calendar centered on it.

william porter
источник
You can get this solution down to 159 by removing the whitespace from this solution, 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 Thanks, was only using the built in editor which autopopulates those spaces.
william porter
0

Red, 153 131 bytes

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

Try it online!

Galen Ivanov
источник
0

T-SQL, 203 bytes

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

The online version is slightly different, this posted version works in MS-SQL Studio Management. It saves 1 bytes compared with the online version, but doesn't give the correct result online

Try it online

t-clausen.dk
источник
0

Python 2, 115 bytes

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

Try it online!

Not sure if this is allowed... takes input from STDIN in the form date(year, month, day). This can also be represented as __import__('datetime').date(year, month, day). These are really __import__('datetime').date objects.

Erik the Outgolfer
источник