Сьогодні це Центр


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 або повернути його як результат функції.
  • Прийнятна або повна програма, або функція.
  • Будь-яка кількість сторонніх пробілів є прийнятною, доки символи не належним чином розташовуються.
  • Дозволяються провідні нулі в одноцифрових днях, як і вирівнювання одноцифрових днів, щоб замість них вирівняти ліворуч.
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Відповіді:


12

R , 77 72 байти

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

Спробуйте в Інтернеті!

Фіксований вихід для використання 2-х літерних скорочень.

-1 байт, використовуючи strtrimзавдяки Аарону Хейману .

Номери дат прокладки з провідними 0; приймає введення як a Date, яке можна створити за допомогою as.Date("YYYY/MM/DD").

Дивно короткий варіант відповіді на R ...


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, і тоді я включаю деякі дуже складні виклики в я робив ...>.> EDIT: Хм добре, майже ..; 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 Мост робився останній раз із пов'язаним викликом, але так, це було багато роботи ..;) Пояснення було додано btw.
Кевін Кройсейсен

@ OlivierGrégoire Тепер ми такі ж, до побачення. ;)
Кевін Круїссен

@ OlivierGrégoire А тепер знову нижче, вибачте. ; p
Кевін Круїссен

6

JavaScript (ES6),  141  126 байт

Збережені 15 байт шляхом запозичення .toUTCString().slice(0,2)з відповіді Нілу

Вводить дані як об'єкт дати.

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

Спробуйте в Інтернеті!


Так, я міг присягнути, що мій код не вдався до третього тестового випадку, коли я його спочатку написав ... добре, що врятує мене 52 байти ...
Ніл

4

JavaScript (Node.js) , 205 152 145 байт

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>

Спробуйте в Інтернеті! Вводить дані як об’єкт дати JavaScript або часову позначку. Редагувати: Збережено 1 байт завдяки @EmbodimentofIgnorance, який потім дозволив мені зберегти ще 7 байт, додавши у вихідний рядок наступний новий рядок. Збережено 52 байти, коли я виявив, що я займаюся поведінкою, яка насправді не була насправді баггі ...


padStart(2)-> padStart(3), видаліть пробіл у рядку приєднання на -1 байт
Втілення Незнання



2

Мова Вольфрама (Mathematica) , 123 байти

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

Спробуйте в Інтернеті!

Я не знаю, чому Gridне працює TIO, але цей код виводить це

enter image description here

@DavidC зберег 1 байт


Можливо Grid, не працює, оскільки TIO не може центрирувати елементи, як на вашому малюнку?
AdmBorkBork

@AdmBorkBork Існує спосіб завантаження такої графіки в TIO. Хтось мені показав минулого року, я думаю. Але я не можу пригадати, як це зробити ... Тож якщо хтось знає, повідомте нам!
J42161217

2

MATL , 34 33 31 байт

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

Спробуйте в Інтернеті!

Пояснення

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

2

Java (JDK) , 149 байт

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

Спробуйте в Інтернеті!

Кредити



1
@KevinCruijssen Зачекайте ... що? Вітаю вас! Я намагався це зробити, але не міг знайти спосіб це зробити, і все ж ви це зробили! Дуже приємно :-)
Олів'є Грегоар

1
Можливо, ви бачите щось більше, щоб поєднати iі jякось? Або щось коротше для j++%7<1?10:32якоїсь побіжної магії? Але це я залишу вам. Я повертаюся до роботи, хаха. ;)
Кевін Круїссен

1
Ах, звичайно .. Приємна командна робота! ;) PS: Де знаходиться wпідставка? Чому не hдля заголовка?
Кевін Кройсейсен

1
@KevinCruijssen wна "день w eek". Також біт-подвійність може призвести лише до того, (i%7+6)/7*22+10що набагато довше.
Олів'є Грегоар

2

PHP ,197 189 187 байт

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

Спробуйте в Інтернеті!

Введення - STDINце рядок дати. Бігайте з 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 

Перевірте всі тестові випадки

Або 174 байти з однозначними цифрами, заповненими нулем.


1

Excel VBA, 190 159 байт

Дякую @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

Бере введення у формі дійсного рядка дати для Excel VBA (наприклад, 19 лютого 2020; 2/19/2020; 19-лютого-2019) і повертає масив із заданим календарем, орієнтованим на ньому.


Це рішення можна зменшити до 159, видаливши з цього рішення пробіл,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
Тейлор Скотт

@TaylorScott Спасибі, використовував лише вбудований редактор, який автоматично заселяє ці простори.
william porter


0

T-SQL, 203 байти

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

Інтернет-версія дещо інша, ця розміщена версія працює в MS-SQL Studio Management. Це економить 1 байт порівняно з онлайн-версією, але не дає правильного результату в Інтернеті

Спробуйте в Інтернеті


0

Python 2 , 115 байт

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

Спробуйте в Інтернеті!

Не впевнений, чи це дозволено ... приймає вхід від STDIN у формі date(year, month, day). Це також можна представити як __import__('datetime').date(year, month, day). Це справді __import__('datetime').dateоб’єкти.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.