Знайдіть останню неділю в кожному місяці даного року


21

F # рішення відомі всередині 140 символів , і це проблема коду Розетти .

Необхідний результат у stdout або в рядковій змінній для року введення 2014:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Як було запропоновано, за 1900 рік:

1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30

І 2000 рік:

2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Поставлено тому, що дати здаються незручними для більшості мов. Я більше сподіваюся на те, що я можу їх побачити! Але якщо вона є зовнішньою базовою мовою, заявіть у назві посади (наприклад, C # + NodaTime Джона Скета).

Роз'яснення:

  • Діапазон років 1900 - 3015
  • Григоріанський календар
  • Якщо це важливо інакше, все, що є для Великобританії та Лондона.
  • Програма, що приймає перемикач командного рядка або stdin, чудово, створюючи результат для stdout
  • Функція, яка приймає значення за рік і повертає рядок, також чудово.

Стандартні лазівки виключені . З нетерпінням чекаю рішень APL, J, K та бачимо нові бібліотеки дат.


@ Sp3000 - 1752 може бути особливо незручно :-)
гидливо грифа

@ MartinBüttner: Будь ласка, використовуйте бібліотеки дат, відредагувавши питання, щоб попросити людей оголосити ті, якими вони користуються мовою.
Філ Н

1
Ви повинні вказати діапазон років, які є вагомим внеском, та міркування щодо прийняття Григоріана. (Тобто, якщо діапазон років включає будь-який період до 1930 року, то слід вказати або Григоріанський календар слід використовувати для всього діапазону, незалежно від місцевості; або висновок може змінюватися залежно від мови; або ви повинні вказати дату відсічення, перед якою слід використовувати юліанський календар і перевіряти справи протягом трьох років навколо зміни.
Пітер Тейлор

1
@squeamishossifrage: Я обмежив це 1900 роком та григоріанським, тому що я краще уникати дослідницького проекту щодо встановлення специфіки ...
Phil H

1
@ Adám: Вибачте, що ви так довго чекаєте відповіді :) Так.
Phil H

Відповіді:


1

Dyalog APL з cal від dfns , 19 байт

Краще пізно, ніж ніколи!

Підказки за рік, повертає список дат у форматі yyyy md .

⎕{⍺⍵,2↑⊢⌿cal⍺⍵}¨⍳12

запит на числове введення, і нехай це буде лівий аргумент до

{... анонімна функція (знайдена нижче), застосована до кожного із

⍳12 числа від 1 до 12 (місяці)

Вищенаведена анонімна функція така:

⍺⍵, додати аргументи зліва та справа (тобто рік та місяць)

2↑ перші два символи

⊢⌿ самий нижній ряд

cal календар для

⍺⍵ лівий аргумент і правий аргумент (рік і місяць)

СпробуйтеAPL онлайн:

  1. Поверніться на цю сторінку, натиснувши тут, щоб імпортувати calта його залежності.

  2. Натисніть тут, щоб запустити тестові приклади.


Дуже добре. Сподівався на бібліотеку APL, яка зрозуміла, що означають дати, але cal є розумним!
Phil H

@PhilH дата та дні ?
Adám

1
@PhilH Існує також простір імен дат від MiServer.
Adám

1
@PhilH І Діадичні примітиви Dyalog APL + - < = та робота з об'єктами дати .Net .
Adám

7

Рубі, 91 + 6 = 97

#!ruby -prdate
$_=(Date.new(y=$_.to_i)...Date.new(y+1)).select(&:sunday?).chunk(&:mon).map{|k,v|v[-1]}*' '

Виходить досить добре. select(&:sunday?)це досить, і що дивно, *' 'все форматування робить само собою.


Приємних трюків! Ви можете зберегти ще три символи, використовуючи chunkзамість group_by.
Крістіан Лупаску

Так я можу, приємно.
гістократ

6

Bash 4.x + ncal, 57

Якщо роздільники нового рядка в порядку замість пробілів, то ми можемо видалити -nкомутатор та пробіл із echoзаяви. І я здогадуюсь, що це все ще працюватиме без шебангу, тому я також зняв це:

for i in {01..12};{ echo "$1-$i-`ncal $i $1|tail -c-3`";}

Оригінальний сценарій (73 байти):

#!/bin/bash
for i in {01..12};{ echo -n "$1-$i-`ncal $i $1|tail -c-3` ";}

Використання:

$ bash sundays.sh 2014
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-30
2014-12-28
$

Примітка: версії Bash до 4.0 не опускають початкові нулі за місяці. Це можна виправити, додавши 5 символів, змінивши {01..12}на `seq -w 1 12)`. Крім того, це tail -c-3може спричинити проблеми в деяких системах, де вихід ncalвключає пробіли, але я не знаю жодного з цих дій.


1
Чи справді різниця пов’язана з Дарвіном, а не лише з версією Bash? Додано в Bash 4.0 (хоча пізніше в ньому були деякі помилки). У будь-якому випадку, 1 персонаж все-таки можна пощадити, використовуючи `…`замість доброї звички $(…).
манастирська робота

Ах, могло бути. Дарвін каже, що використовує версію 3.2.53; Debian використовує 4.1.5.
пискливе костіння

@manatwork PS Щойно помітив ваш коментар щодо зворотних кліщів. Гарний улов, дякую!
пискливе костіння

Я не думаю, що вам потрібно розраховувати #!/bin/bashцілі гольфу.
Цифрова травма

@DigitalTrauma Це добре. Схоже, я можу використовувати і розриви рядків замість пробілів. Зараз до 57 байт :-)
писклива косточка

6

IBM DFSORT, 11 3 рядки 71, 72 або 80 символів

 OPTION COPY 
 OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
 ,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X) 

Дві відповіді у форматі стовпчастого виходу витримали перевірку часом. Це дає мені "цикл", наприклад, в OUTFIL REPEAT = копіює поточний запис, який багато разів.

Різна техніка для досягнення цінності, яка здається довшою, але коротшою, тому що я не можу розробити жодного безумовного способу розібратися з 12-м записом, що знаходиться в наступному році, і зробити це умовними засобами, включаючи IFTHEN=(WHEN=, двічі та інші речі. Підвищення на гойдалках (перший місяць - це найпростіший спосіб зробити це) сильно втрачає на кругових роз'їздах (особливі вимоги до синтаксису).

При цьому використовується вбудована функція (всі функції в DFSORT вбудовані), щоб знайти останній день місяця. Потім додає один день (функцію), щоб дістатися до першого наступного місяця, і використовує функцію PREVDSUN, щоб отримати попередню неділю (яка завжди буде останньою неділею попереднього місяця, як і раніше).

При перетворенні року (введення) у дійсну дату використовується двозначний номер послідовності за місяць, і це значення копіюється також і за день, оскільки початкова точка не має значення, наскільки дійсна, як ми після останнього дня місяця спочатку: 5,2коротше, ніж C'01'.

Ось деталь:

OPTION COPY - скопіюйте вхідний файл на вихід

OUTFIL - щоб дозволити декілька вихідних файлів, з різним вибором та форматуванням, створювати форматовані звіти. Вживається в перевазі коротший INRECчерез використання REPEAT=.

REPEAT = 12 - створити 12 копій кожного запису. У цьому прикладі може бути лише один запис вводу (на відміну від попередньої версії) через SEQNUM.

5: - початок з колонки 5 на записі.

SEQNUM, 2, ZD - порядковий номер, за замовчуванням починається одна, дві цифри, "десятична зона" (для непідписаних, якими вони будуть, те саме, що і символ).

1,8 - скопіюйте байти 1 довжиною 8 у поточне місце розташування (9). Це тому, що Y4T потрібно бачити 8, інакше буде використаний інший формат дати.

Y4T - дата в форматі ccyymmdd (через 8 безпосередньо перед нею).

ПОСЛІДНИЙ - Останній день місяця (також можливий тиждень, квартал та рік).

TOJUL = - перетворення дати перетворення для функцій дати (TOJUL на один символ менше, ніж TOGREG)

9,7 - тепер, коли це 7, Y4T буде CCYYDDD.

ДОПОМОГА - додає кількість днів, автоматично підлаштовуючись, якщо переходить у наступний місяць / рік (також можуть бути АДДМОНИ та ДОБАВКИ)

PREVDSUN - приходить дата Джуліана, розміщена попередня неділя, TOGREG, щоб отримати правильний вихідний формат, з сепаратором "-" (може бути як завгодно, як роздільник)

12X - заготовки, щоб очистити безлад, який дозволив нам зробити це таким коротким способом

Вихід із вищезазначеного, за 2014 рік, становить:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28

Щось потрібно, щоб сказати SORT, що робити. За замовчуванням немає. OPTION COPYнайкоротший, SORT FIELDS=COPYрівнозначний, але довший.

Сама робота, яку він зробив цього разу в OUTFIL(щоб дозволити використання REPEAT). Робочий код, мабуть, будь-який із 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) або 138 (70 + 68) (за винятком провідних заготовок, примусового продовження та проміжних заготовок).

Зважаючи на те, що одержувач повинен знати, що вони роблять, я думаю, що можу сказати, що код DFSORT, який слід перераховувати в останню неділю кожного місяця за будь-який рік з 1900 року (працюватиме з 0001 року, але я уникаю досліджень, оскільки добре) до 9999 (хоча DFSORT підтримує роки до 9999, попереднє рішення не працювало б у 9999 році, оскільки 12-та дата переходить у наступний рік) можна твітувати.

Чому код настільки довгий, якщо є особливо влучні вбудовані функції?

Польові визначення є ефемерними. Поле визначається лише як певне місце в даних (яке є записом) для його негайного використання. Інакше кажучи, поля не визначаються як такі, але визначаються для кожного використання та лише для використання. Функції дати повинні знати, який (з багатьох) форматів дати використовується для джерела, а висновок повинен бути у форматі дати, так що потрібно вказати.

Тепер, коли у нас є юліанські побачення .... TBC?


 OPTION COPY 
 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
 ,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
 46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
 DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
 T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
 8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
 ,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
 39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),11:X,18,120,6X) 

Потреби деякі JCL

//LASTSUNG EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//SYSIN    DD * 

І вхідний файл (інший рядок JCL та три вхідні елементи даних):

//SORTIN DD *
2014 
1900 
2000 

Виробляє:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Дійсно працюватиме до 9999 року.

DFSORT - продукт сортування мейнфреймів IBM. Даними можна керувати, але оскільки сортування є ключовим, а сортування часто велике і тривале, керуючі карти DFSORT не мають петельних конструкцій, тому ми не можемо помістити SORT у цикл. Робить речі трохи затятими для таких завдань, як Golf.

Чому публікувати відповідь, це тому, що DFSORT має PREVDdayфункцію. Тож остання неділя місяця проста. Це неділя попереднього (PREVDSUN) до першого дня наступного місяця.

Це було також цікаво робити це в одному "операнді" (OVERLAY), трохи схоже на те, щоб робити це все в межах sprintfабо подібних.

Ось це невольф:

 OPTION COPY 

 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8, 
         1,8,1,8,1,8,1,8, 
         1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4, 
         14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
         62:C'9',69:C'10',77:C'11',85:C'12', 
        127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
          1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         11:X,18,120,6X) 

Хоча це не зовсім зловживання, не було б звичайним намагатися зафіксувати все це в одному ЗАВДАННІ, і є деякі, здавалося б, непотрібні речі, які необхідні для того, щоб все це перейшло в один НАДЗОР. Є місце для гольфу, але оскільки це видалить не більше однієї лінії, я не спокушаюся.

INREC обробляється для кожного запису.

OVERLAY дозволяє змінювати вміст існуючого запису. Якщо запис буде продовжено понад його довжину в процесі, це не є проблемою.

1,4 - рік, що настає. До нього додається буквальна цифра 0201, а потім наступні 1,8 секунди повторюють це 11 разів, щоб дати один довгий патрон з 96 байт,

Дванадцятий рік за розширеним поточним записом додає до нього 1, а його місяць - 1 (січень).

Решта 10 місяців змінюються на 3 - 11.

Тоді є 12, у зворотному порядку (за рахунок НАДОБРЕНОГО) такого типу речей:

127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),

N: - це номер стовпця на записі. X вставляє порожню. 89,8 приймає дані з цього стовпця / довжини, Y4T трактує це як дату CCYYMMDD, PREVDSUM працює в попередню неділю, TOGREG = Y4T (-) виводить їх як дату григоріанського CCYY-MM-DD.

Оскільки ви отримуєте сміття, якщо джерело та ціль певної частини ОВЕРЛАЙ деструктивно перекриваються, остаточне 11:X,18,120,6X)перестановлення та маскування трохи заплутане.

Посібники та документи можна знайти за посиланням: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 та містить посібник з програмування програми DFSORT на 900+ сторінок.

Як і у всіх продуктах IBM, всі посібники доступні безкоштовно (за винятком вибачливо невеликої кількості дуже дорогих, які лише дуже мала кількість людей у ​​світі навіть претендує на розуміння).

Усі контрольні картки DFSORT повинні починатися з порожнього поля. Стовпець 72 використовується лише для продовження (будь-яке незаповнене буде, але * є звичайним). У стовпці 72 слідує область послідовних номерів, яка ігнорується, роблячи кожен запис 80 байтами.

Можливо, ще одна пара рішень.


5

Баш, 63 байти

for i in {01..12};{  date -v30d -v${i}m  -v2014y  -vsun +%Y-%m-%d;}

Вихід:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-24
2014-09-28
2014-10-26 
2014-11-30
2014-12-28

for i in {1..12};{ date -v30d -v${i}m -v$1y -v0w +%Y-%m-%d;}- 60 байт
Цифрова травма

-vparam до dateє специфічним для дати BSD. Отже, це працює на OSX, але не на більшості Linux - можливо, про це слід сказати у відповіді.
Цифрова травма

@DigitalTrauma, працює на mac та моєму Linux.
michael501

4

Python 2 - 189 байт

y=input()
for m in range(12):
 d=[31-(1322>>m&1),28+(y%400<1or 1>y%4<y%100)][m==1];Y=y-(m<2);Z=Y%100;C=Y/100
 while(d+13*((m-2)%12+4)/5+Z+Z/4+C/4-2*C)%7-1:d-=1
 print"%d-%02d-%d"%(y,m+1,d),

Введіть дату через STDIN.

Ще набагато більше гольфу, що можна зробити. Програма трохи за бортом, просто для розваги:

  • Жоден імпорт, зокрема не використовуючи жодних вбудованих функцій дати
  • Використовує відповідність Зеллера для розрахунку днів тижня

Примітки

  • 1322 - це чарівна таблиця пошуку для визначення того, чи має не лютий місяць 30 чи 31 день
  • Ніяких років zfillне потрібно через діапазон введення, а також днів, оскільки їх завжди буде більше 20

Python 2 - 106 байт

Не цікаве рішення:

from calendar import*
y=input();m=1
while m<13:w,n=monthrange(y,m);print"%d-%02d-%d"%(y,m,n-(n+w)%7),;m+=1

calendar.monthrange повертає два числа: будній день місяця починається (w ) та кількість днів у місяці ( n). Рішення є мало протизаконним через улов - повернений будній день починається з 0 для понеділка , а не неділі! Однак це компенсується тим, що nна основі 1.


1
Дуже дурна відповідь Піта:$from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
FryAmTheEggman

3

JavaScript (ES6) 155 145

Редагування Виправлені проблеми часового поясу Можливо, буде коротше, якщо зробити його рекурсивним. Можливо.

F=y=>{
  for(n=i=o=[];!o[11];)
    d=new Date(Date.UTC(y,0,++i)),m=d.getMonth(),
    d.getDay()||(m!=n&&o.push(p.toISOString().slice(0,10)),p=d,n=m);
  return o.join(' ')
}

Можна використовувати new Date(y,0,++i,9). Крім того, це не вдається для 2100 і вище високосних років, оскільки JS не має інформації про ці високосні роки, і, таким чином, взагалі немає Feb 29у високосні роки 2100 і вище.
Оптимізатор

@Optimizer це не JS: 2100,2200,2300 - це не високосні роки. 2014 рік - високосний, і JS знає. Щодо використання години 9, я не можу перевірити, але я думаю, що це не спрацює, якщо ви, наприклад, в Мельбурні ...
edc65

А .. Ніколи не знав, що ми скидаємо 3 дні на 400 років. Про 9 - я змінив свій часовий пояс з -1000 (Гаваї) на +1100 (Мельбурн) і new Date(2014,0,26,9)в неділю дав правильний ISOрядок, а getDay()також 0.
Оптимізатор

3

JavaScript, ES6, 222 219 199 байт

Я не побачив жодної відповіді на JavaScript у вікі розетки.

Ось і ми:

S=Y=>{for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)if(!(d=new Date(Y,0,++i,9)).getDay()){p.getMonth()-d.getMonth()&&l.push(p);p=new Date(d)}return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")}

Це створює функцію, Sяка повертає рядок з потрібним результатом. функція також бере участь у високосні роки.

Завдяки ES6, це працює лише в останньому Firefox.

Завдяки апсилерам за наконечник, який отримав його, зменшено до 200 байт

Знайдіть внизу версію, яка не використовується, як фрагмент стека, який ви можете запустити тут самі:

S=Y=>{
  for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)
    if(!(d=new Date(Y,0,++i,9)).getDay()){
      p.getMonth()-d.getMonth()&&l.push(p);
      p=new Date(d)
    }
  return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")
}

alert(S(parseInt(prompt())))


Ви можете використовувати + prompt (), а не розбирати і обстригати деякі байти
Jacob

@Jacob Цей рядок не додається до кількості байтів.
Оптимізатор

OIC. Я повинен був прочитати питання ...
Яків

@apsillers Дякую тонну! Виправили проблему та значно скоротили її на основі підказки.
Оптимізатор

Вхідний 2100вихід 2100-01-31 2100-02-28 2100-03-28 2100-04-25 2100-05-30 2100-06-27 2100-07-25 2100-08-29 2100-09-26 2100-10-31 2100-11-28 2100-12-26 2101-01-02неправильний.
Qwertiy

3

Ребол - 120 116 80 79 76

d: do join"1-1-"input print collect[for m 2 13 1[d/2: m keep d - d/weekday]]


Недоліковані + кілька приміток:

d: do join "1-1-" input         ;; golfy way to create Rebol date! datatype 1-Jan-(year)

print collect [
    for m 2 13 1 [              ;; loop thru months 2 to 13!
        d/2: m                  ;; move to (1st of) next month
        keep d - d/weekday      ;; collect/keep last sunday of month
    ]
]

Приклад розрахунку неділі в консолі Rebol:

>> ; get last sunday of Jan 2014

>> d: 1-1-2014
== 1-Jan-2014

>> d/month: d/month + 1
== 2

>> d
== 1-Feb-2014

>> d/weekday
== 6

>> d - d/weekday
== 26-Jan-2014

>> ; above is last sunday of Jan 2014
>> ; and when pass end of year (ie. month 13!)

>> d/month: 13
== 13

>> d
== 1-Jan-2015

Потенціал 87: d: 1-1-1 d / рік: збирати друк для введення даних [повторити m 12 [d / month: m + 1
Keep

@rgchris Дякую Кріс. Був в змозі поголити ще 7 символів.
draegtun

Приємно !! Це погано, але ніколи насправді не думайте про ЗА як про ярлик.
rgchris

2

CJam, 122 102 байти

30li:X400%){[1387Yb30f+~28I!I4%!I100%e&|g+\]W%{\_2$>7*-\7%7\m1$+}/}fI;]12/W=12,{101+s1>}%]z{X+W%'-*S}/

Тут не використовується жодна форма бібліотеки дат. Думаю, це ще може бути багато гольфу.

Тестуйте це тут.


3
Я настільки вражаюче розчулився, що відповідь CJam - це не найкраща відповідь у виклику коду-гольфу на один раз. Я можу померти щасливим .. Сьогодні хороший день (поки явно не вийде до 6 байт, очевидно)
Брендон

@Brandon: Це була така причина, яку я вважав, що це буде цікаво. Дуже сподіваючись побачити дивовижну бібліотеку, яка робить це легко, але розчаровано поки що.
Філ Х

1

R, 128 символів

P=paste;f=format;a=strptime(P(1:366,scan()),"%j %Y");cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

З розривами рядків:

P=paste
f=format
a=strptime(P(1:366,scan()),"%j %Y")
cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

1

C # 255

Безумовно

static void Main(string[] a)
    {
        int y = Int32.Parse(Console.ReadLine());
        DateTime d = new DateTime(y, 1, 1);
        while (d.Year == y)
        {
            if (d.DayOfWeek == DayOfWeek.Sunday && d.Day>(DateTime.DaysInMonth(y,d.Month)-7))
                Console.WriteLine(d.ToShortDateString());
            d = d.AddDays(1);
        }
        Console.ReadKey();
    }

Редагувати: змінено для друку лише минулої неділі :)


Не потрібний вихідний формат. + Це код гольфу
edc65

1

q, 67

{({{1<>x mod 7}-[;1]/x}')14h$1_til[13]+13h$"D"$(($)x),".01.01"}

Чи не існують бібліотеки дат, які можна використовувати для цього в q?
Філ Н

1

"О, ні, він знову!"

Java - 259 246 байт

void g(int y){for(int i=;i<12;i++){GregorianCalendar c=new GregorianCalendar(y,i,0);c.set(c.DAY_OF_WEEK,c.SUNDAY);c.set(c.DAY_OF_WEEK_IN_MONTH,-1);System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");}}

Негольована версія:

void g(int y){
    for (int i = 0; i < 12;i++) {
        GregorianCalendar c = new GregorianCalendar(y, i, 0);
        c.set(c.DAY_OF_WEEK, c.SUNDAY);
        c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
        System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
    }
}

Використання:

import java.util.GregorianCalendar;
import java.util.Scanner;

public class LastSundayInYear {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Year?");
        int year = scanner.nextInt();
        LastSundayInYear sunday = new LastSundayInYear();
        sunday.g(year); 
    }

    void g(int y){
        for (int i = -1; ++i < 12;) {
            GregorianCalendar c = new GregorianCalendar(y, i, 0);
            c.set(c.DAY_OF_WEEK, c.SUNDAY);
            c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
            System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
        }
    }
}

Вихід:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Ще одна відповідь "давайте поставимо відповідь Java лише для ударів". Що ж, добре. Але, принаймні, так як ви потрудилися дійти до цієї точки моєї відповіді, я спробую ще трохи набриднути вам і пояснити свої міркування.

Метод gотримує бажаний рік і за кожен місяць створює GregorianCalendarоб’єкт (місяці йдуть від 0 до 11). Потім перший c.setвизначає день тижня як неділю, а другий оголошує, що ми хочемо останній тиждень місяця - як це видно на офіційної документації . У System.out.printlnроздруковує дату цієї неділі (якщо ми робимо це правильно, рік буде надрукований як c.get(c.YEAR), але з використанням yзнову збриває 13 символів), місяць повинен бути відформатований для додавання ведучого нуля з січня по вересня (і значення збільшується, оскільки, ну, місяці тут представлені 0-11) і друкується день останньої неділі. І цю процедуру повторюють інші одинадцять місяців.


0

C #, 212 , 237

string x(int y){var s="";var t="";var d=new DateTime(y,1,1);for(;;){if(d.Year!=y){return s;}t=(d.DayOfWeek==DayOfWeek.Sunday)?t=string.Format("{0}-{1}-{2} ",d.Year,d.Month,d.Day):t;s=(d.AddDays(1).Month!=d.Month)?s+=t:s;d=d.AddDays(1);}}

З розривами рядків

string x(int y)
    {
        var s = "";
        var t = "";
        var d = new DateTime(y,1,1);
        for (;;)
        {
            if (d.Year != y) {
                return s;
            }
            t = (d.DayOfWeek == DayOfWeek.Sunday) ? t = string.Format("{0}-{1}-{2} ", d.Year, d.Month, d.Day) : t;
            s=(d.AddDays(1).Month!=d.Month)?s+=t:s;
            d=d.AddDays(1);
        }
    }

Вихід на 2014 рік

"2015-1-25 2015-2-22 2015-3-29 2015-4-26 2015-5-31 2015-6-28 2015-7-26 2015-8-30 2015-9-27 2015-10-25 2015-11-29 2015-12-27"

Не потрібний вихідний формат
edc65

Там, зафіксовано. Краще?
Даррен Брін

0

C # 171

Функція, що повертає рядок.

string S(int y){var r="";for(int m=1;m<13;++m){var d=new System.DateTime(y,1,1).AddMonths(m).AddDays(-1);r+=y+string.Format("-{0:00}-{1} ",m,d.Day-d.DayOfWeek);}return r;}

Безумовно

string S(int y)
{
    var r="";
    for (int m=1;m<13;++m)
    {
        var d = new System.DateTime(y, 1, 1).AddMonths(m).AddDays(-1);
        r += y + string.Format("-{0:00}-{1} ", m, d.Day - d.DayOfWeek);
    }
    return r;
}

0

C # 194

використовуючи Linq:

string d(int y){return string.Join(" ",Enumerable.Range(1,12).Select(m=>new DateTime(y,m,DateTime.DaysInMonth(y,m))).Select(d=>d.AddDays(-(int)d.DayOfWeek)).Select(d=>d.ToString("yyy-MM-dd")));}

Безумовно

string d(int y)
{
    return string.Join(" ",Enumerable.Range(1,12)
        .Select(m => new DateTime(y, m, DateTime.DaysInMonth(y, m)))
        .Select(d => d.AddDays(-(int)d.DayOfWeek))
        .Select(d => d.ToString("yyy-MM-dd")));
}

Вихідні дані

2013-01-27 2013-02-24 2013-03-31 2013-04-28 2013-05-26 2013-06-30 2013-07-28 2013-08-25 2013-09-29 2013-10-27 2013-11-24 2013-12-29

0

Математика - 171

Загорнутий в анонімну функцію, повертає рядок

StringJoin[Last@#~DateString~{"Year","-","Month","-","Day"," "}&/@GatherBy[Select[DateRange[DateObject[{#}],DateObject[{#+1}]],DayName@#==Sunday&],DateValue[#,"Month"]&]]&

Перший математичний гольф. Я відчуваю, що це може бути значно зменшено.


0

VB-192

Function z(y)
For i = 1 To 11
a = 0
s = IIf(i <> 11, DateSerial(y, i + 1, 1), DateSerial(y + 1, 1, 1))
While Weekday(s - a) <> 1
a = a + 1
Wend
r = r + Str(s - a) + " "
Next
z = r
End Function

Могло бути гірше ^^

Мій другий і останній запис (не думаю, що я можу отримати його меншим)

142

Function z(y)
Dim m(12)
For i = 1 To 366
s = DateSerial(y, 1, 1) + i
If Weekday(s) = 1 Then m(Month(s)) = s
Next
z = Join(m, " ")
End Function

0

Рубін 76

Використовує параметр командного рядка ruby sundays.rb 1900. Використовується бібліотека дат.

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.