Коли відбувається День подяки?


38

Фон

Деякі свята мають фіксовані, легко запам’ятовувані дати, як-от 31 жовтня, 25 грудня та ін. Вони визначаються як такі речі, як "перший понеділок вересня" або "четвертий четвер листопада". Як я повинен знати, коли це?

Все, що я знаю, - це те, що День подяки швидко наближається, тому мені потрібна програма, яка допоможе мені зрозуміти, коли це є. Деякі люди навіть кажуть, що це завтра , тому ваша програма повинна бути якомога коротшою, щоб переконатися, що я можу її ввести повторно.

Змагання

Створіть програму або функцію, яка, відповідно до чотиризначного року (наприклад, 2015 або 1984), виводить або повертає дату Подяки Сполучених Штатів у цьому році. Повідомлення Дня подяки визначається як четвертий четвер листопада на сторінці Вікіпедії . (Підказка: на цій сторінці також міститься якась цікава інформація про шаблон дати.)

Введення : десяткове число з максимумом чотирьох цифр, що представляє рік у загальній епосі (CE). Приклади: 987, 1984, 2101

Результат : дата, включаючи місяць і день, коли день подяки падає або впав, якби він існував, у тому році. Це може бути в будь-якому розумному форматі; використовуйте своє найкраще рішення. Користуйтеся григоріанським календарем у всіх випадках, навіть якщо він тоді не використовувався.

(Примітка. Обов’язково правильно поводьтеся з високосними роками!)

Тестові приклади Введення 1:

2015

Вихід 1:

Nov 26

Введення 2:

1917

Вихід 2:

Nov 22

Оцінка балів

Подання будуть оцінені в байтах . Я рекомендую цьому веб-сайту відстежувати кількість байтів, хоча ви можете використовувати будь-який лічильник, який вам подобається.

Бонуси

-25% до вашого рахунку, якщо ви обробляєте дати BCE як негативні цифри (наприклад, -480 - це рік битви при Термопілеї).

Негативний вхід тестового випадку:

-480

Відповідний вихід:

Nov 25

Це , тому найнижчий бал виграє!

Редагувати: Я відзначаю подання Томаса КВА TI-BASIC як прийняте. Не дозволяйте цьому відштовхувати вас від подання нових записів!

Табло лідерів

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

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes

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

# Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке потім з’явиться у фрагменті таблиць лідерів:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


25
Для всіх, хто цікавиться, коли в цей рік вийде День подяки: День подяки буде завтра.
— TheNumberOne

6
Але я мав подяку 10 жовтня? Вибачте, кажу, що ваше питання запізнюється.
— JimmyJazzx

5
@Downgoat Використовуйте потрібний лічильник байтів. Це лише той, який я особисто використовую і рекомендував би.
— bkul

22
"Деякі свята мають фіксовані, легкі для запам'ятовування дати, наприклад, 31 жовтня, 25 грудня." Ці приклади легко запам’ятати, оскільки вони дійсно в той самий день: восьмий день 31 == десятковий 25. ;-)
— Адріан Маккарті

7
Для відповіді про те, що бонус, чи має бути рік від 1 до 1 чи ні?
— feersum

Відповіді:


40

TI-BASIC, 15 байт * 0,75 = 11,25

Тестовано на моєму калькуляторі TI-84 +

1129-dayOfWk(Ans+ᴇ4,9,1

День подяки - 29 листопада, мінус день тижня 1 вересня, де 1 неділя та 7 - субота. Це виводиться у форматі MMDD.

Тестові приклади: 2015-> 1126, 1917-> 1122, -480-> 1125перевірені. TI-BASIC, здається, використовує григоріанський календар для всіх дат.

TI-BASIC не підтримує негативні роки, але це отримує бонус, оскільки ми додаємо 10000 до вхідних даних. Оскільки григоріанський календар має період 400 років, це не змінює день тижня.


5
О ні. xD Я ніколи не подумав би, що це спрацювало б так, +1.
— Аддісон Кримп

Хороша ідея додати 10000. Приємно.
— квітня 1515

Я рахую 23 букви. Як це може бути 15 байт?
— Стефан Шінкель

1
@StephanSchinkel TI-BASIC використовує маркери, які зберігаються в пам'яті калькуляторів, я вважаю, що всі символи тут є 1 байтом, окрім жетонів, dayofWK(і Ansце 2 та 1 байт кожен.
— FryAmTheEggman

Ви перевірили його на калькуляторі? Ого.

23

PHP, 65 48 42 41 36 (+2 для -F) = 38 байт

<?date(Md,strtotime("4thuXI$argn"));

Вводиться як перший аргумент командного рядка. Працює з попередженнями, прийнятними нашими правилами. Друкує NovDD, де DDдень подяки.

Немає посилання в Інтернеті, оскільки ideone не підтримує аргументи командного рядка, і я не знаю інтерпретатора, який це робить.

Дякую Олександру О'Мара за те, що він навчив мене новій хитрості та приму за значне скорочення


2
Це смішніше, ніж Mathematica.
— lirtosiast

2
@Tryth Ще коротше : "4thuXI". Можна навіть скинути простір між роком "4thuXI2015".
— Олександр О'Мара

1
За допомогою параметра командного рядка -Fвведення можна скоротити до "4thuXI$argn".
— прим

3
Зачекайте, це насправді працює? Це ... це просто ... Я навіть не
— знаю

1
Працює для мене . Поки я на це, Mdне потребує цитат, з E_NOTICEінвалідом.
— прим

18

Математика, 59 38 байт

DayRange[{#,11},{#,12},Thursday][[4]]&

+1 Розумний. Там же, WolframAlpha["Thanksgiving " <> #] &де дата вводиться як рядок.
— DavidC

Вольфрам Альфа повертає день подяки США з 1863 року (коли Лінкольн оголосив це останнім четвергом листопада). США спостерігають День подяки з 1789 року.
— DavidC

@DavidCarraher Однак, в ОП зазначається, що програма повинна працювати принаймні 0 - 9999 CE
— LegionMammal978

17

JavaScript (ES6), 42 40 31 байт - 25% = 23,25

a=>28.11-new Date(a,8).getDay()

Оскільки дата "може бути у будь-якому розумному форматі", ця функція використовує DD.MM. Я написав відповідь TeaScript іншою технікою, але ця формула була коротшою.

Пояснення

Оскільки місяці базуються на нулі, new Date(a,10)повертає Dateоб’єкт, який представляє 1 листопада зазначеного року.

Оскільки getDay()повертається число, що представляє день тижня, з якого 0..6ми хочемо зробити карту

Su Mo Tu We Th Fr Sa 
0  1  2  3  4  5  6  
to to to to to to to
4  3  2  1  0  6  5  

потім додайте 22. Виходить, що (11 - new Date(a,10).getDay()) % 7зробить трюк. Як зазначав @Thomas Kwa , це те саме, 28-new Date(a,8).getDay()що становить 28 мінус дня тижня 1 вересня.


Гарне рішення, я люблю, як воно коротке і що воно все-таки зрозуміліше, ніж більшість записів.
— Марко Грешак

16

Japt , 43 37 36 35 29 байт - 25% = 21,75

Japt - скорочена версія Ja vaScri pt .

`{28.11-?w D?e(U,8).getDay()}

Ха-ха , я виявив дійсно хитру хитрість: інтерпретатор ігнорує будь-які дужки всередині рядків (використовуються для вставки коду) під час їх декомпресії, тому ми можемо стиснути весь вихідний код, щоб зберегти байт>: D

Два ?s повинні бути Unicode unprints U + 0098 та U + 0085 відповідно. Спробуйте в Інтернеті!

Після декомпресії код оцінює це:

"{28.11-new Date(U,8).getDay()}"

Який оцінює:

""+(28.11-new Date(U,8).getDay())+""

Що дає належний вихід.

Використовує техніку intrepidcoder , виводить у форматі dd.mm. Правильно підтримує негативні роки. Пропозиції Ласкаво просимо!

Редагувати: Станом на 2 грудня тепер ви можете використовувати цей 11-байтовий код (набравши 8,25 бала ):

28.11-ÐU8 e

(Мені б хотілося, щоб я це раніше реалізував!)


Дуже красиво зроблено.
— bkul

Це тепер довше, ніж ванільний JavaScript. Томас Ква має набагато коротшу формулу .
— intrepidcoder

@intrepidcoder Спасибі, виправлено.
— ETHproductions

12

Віци , 44 байти

Я рахую з чистою математикою !

Гольф:

Ve2 * V2-V41m + Vaa * Dv1m-Vv4 * 1m + 7M-baa * / + N
/ D1M-

Ungolfed (перемістив виклик методу на перший рядок, щоб зробити його читабельним):

Ve2 * V2-V4 / D1M- + Vaa * Dv / D1M - Vv4 * / D1M- + 7M-baa * / + N

V Збережіть вхід як остаточну змінну.
 e2 * Натисніть 28 на стек.
    V Натисніть на вхід до стеку.
     2- Віднімаємо два.
       V4 / D1M- Отримайте підлогу (вхід / 4).
              + Додайте його до загальної суми.
               Vaa * Dv / D1M- Отримайте підлогу (вхід / 100) та заощадьте 100 як темп
                                    змінна в процесі.
                          - Відняти його від загального.
                           Vv4 * / D1M- Отримайте підлогу (вхід / 400).
                                    + Додайте його до загальної суми.
                                     7М Модуло на сім.
                                       - Віднімаємо результат від 28.
                                        бе * / + Додати .11
                                              N Вихід як число.

Мабуть, для цього є кращий алгоритм (і це, мабуть, жахливо гольф), але для тих, хто цікавиться, мій алгоритм походить звідси .

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

Чи отримую я бонусні бали за його обчислення та маючи рівно 42 байти? Мрії зруйновані.

Завдяки @ Hosch250 за вказівку, що я робив це неправильно. : D Виправлено.


2
Ні, але ви отримуєте +1 від мене;)
— Conor O'Brien

У ньому сказано, що День подяки в 2016 році - це 28 листопада. Це дійсно 24 листопада
— Hosch250

@ Hosch250 Ви маєте рацію - виправлено зараз.
— Аддісон Кримп

10

Python, 38 * 0,75 = 28,5 байт

lambda x:28.11-(x-2+x/4-x/100+x/400)%7

Це працює з негативними роками у спосіб, визначений у запитанні, хоча мені відомо, що в григоріанському календарі немає року 0, тому така поведінка трохи підозріла.


1
Можна кинути f=.
— feersum

1
Як це працює в негативні дати? Чи застосовується модуль в Python до негативів? : O
— Addison Crump

Використовувати рядкові повтори, слід коротше,"Nov "+`...`
— xnor

@VoteToClose Python по модулю дає відповідь з тим же знаком, що і другий аргумент. Таким чином, -40%7==2але-40%-7==-5
— Кінтопія,

@quintopia Зачекай, тримайся, я ідіот. Гаразд. Що має сенс.
— Аддісон Кромп

10

JavaScript (ES6), 43.5

Фактична кількість байтів становить 58. Бонус -25% застосовується => 58 * 0,75 = 43,5

s=>new Date(s,10,(a=new Date(s,10).getDay())<5?26-a:a+21)

Досить прямо і нерозумно, як це могло бути, без жодних хитрих обходжень чи розрахунків.

Де-гольф (ES5) + демонстрація:

function t(s) {
    a = new Date(s, 10).getDay();
    alert(new Date(s,10,a<=4?26-a:a+21))
}

t(prompt())

Зауважимо, що рік, що наступає 0-100, виробляє 1900-2000 рік. Хоча, схоже, що 0-100 років дають ту саму дату, що і 1900-2000, судячи з інших відповідей.


Заміна a+18на 22, тому що вона називається лише в "else", а "else" відбувається лише в тому випадку, якщо a не є ні більшим, ні меншим 4, тобто точно 4.


Заміна a<4?26-a:a>4?a+21:22наa<=4?26-a:a+21


2
Простите мене, якщо я помиляюся, але це не a<4?x:a>4?y:a+18рівнозначно a<4?x:a>4?y:22?
— ETHproductions

До речі, він каже мені неправильний рік для будь-якого введення від 0 до 99. Не знаю, чи це має значення.
— ETHproductions

@Eth LOL, звичайно, ти маєш рацію, не думав, що це завжди 4 + 18: D
— nicael

@Eth hm, від 0 до 99 справді неправильно, дозвольте спробувати це виправити.
— nicael

@Eth Схоже, що 0-100 дають ту саму дату, що і 1900-2000, судячи з інших відповідей.
— nicael

8

TeaScript, 35 33 24 байти - 25% = 18

28.11-new D(x,8).getDay¡

Це той самий метод, що і моя відповідь на JavaScript , в якому використовується розумна формула Томаса Ква .

Альтернативна версія з поясненням

r(22,28)F(#/h/t(new D(x,10,l)))+'-11'

r(22,28)    // Range from 22 to 28
        F(    // filter, keeps elements for which the function returns true. 
          #    // Expands to function(l,i,a,b)
           /h/    // RegExp literal, Thursday is the only day with an 'h'.
              t(    // test, true if date string contains an 'h'.
                new D(x,10,l) // Create date object
                             ))+'-11' // Append '-11' for the month.

Це 35 символів, але 36 байт через ¡:)
— nicael

@nicael Не на цьому веб-сайті , це не;)
— ETHproductions

Хм, отримуючи 36 з mothereff.in / ... .
— nicael

@Downgoat зазвичай використовує цей формат , у якому всі символи до U + 00FF мають 1 байт.
— ETHproductions

5

Jython, 141 155 байт

Використовує класи Java Calendar та Scanner із синтаксисом Python.

import java.util.Scanner as s;import java.util.Calendar as c
d=c.getInstance();k=s(System.in);d.set(c.YEAR,k.nextInt());d.set(c.DAY_OF_WEEK,c.THURSDAY)

Редагувати: Незначні проблеми з синтаксисом, додано 14 байт.

Також дивіться мою версію Brainfuck .


5

Пітон, 83 81 78 байт

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 байти: додано імпорт для імпорту (спасибі @ Κριτικσι Λίθος)
  • -1 байт: змінено на * імпорт ** (спасибі @FryAmTheEggman)
  • -2 байти: змінено на repr, щоб перетворити день (спасибі @willem)

1
Просто пропозиція зменшити кількість байтів: використовувати, import datetime as dа потім ви можете використовувати їх dкожного разу, коли ви користуєтесь datetimeу своїй програмі.
— Kritixi Lithos

2
Ви також можете спробувати панди. import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
— Віллем

@ ΚριτικσιΛίθος, але тоді datetime.datetime буде лише d.datetime, чи не так?
— TanMath

2
from datetime import*навіть трохи коротше, так як ви не будете потребувати d.більше
— FryAmTheEggman

5

Excel, 367 154 53 - 25% = 39,75 байт

Припускаємо, що рік проводиться у комірці A1 у форматі Date. Повертає ціле число дня в листопаді, в який проводиться День подяки.

Це припадає лише на звичайні високосні роки. Не враховується той факт, що роки, 2100, 2200, 2300, не є високосними.

Це розраховано лише на 1621 рік - тобто з моменту початку Дня подяки. (Хоча це, безумовно, буде працювати аж до 0 н.е.).

=IF(MOD(YEAR(A1),4)=0,IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

Симпатичний друк:

=IF(MOD(YEAR(A1),4)=0,
    IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),
    IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

Гах! Замість обчислення на основі 1-го січня, а потім робити багато розрахунків високосного року, щоб впоратися з 29-го лютого, я повинен був би грунтуватися на розрахунках 1-го листопада nb. Тепер це правильно стосується 2100, 2200 та 2300 років , але робить виконання залежним від формату дати за замовчуванням у встановленні Excel. Ця версія розрахована на dd / mm / yyyy:

 =IF(WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy"))))<6,  
     1127-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))),
     1134-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))))

І тепер, коли я зробив pfaffing про те, щоб отримати короткий розрахунок у Smalltalk, підтримуючи його в Excel, результати:

=DATE(A1,11,MOD(12-WEEKDAY(DATE(9600+A1,11,1)),7)+22)

(з роком ще в A1, але як ціле число). Це працює навіть протягом 2100, 2200 та 2300 років для всіх дат від 7700BC / E і далі, використовуючи трюк повторення дати Томаса Ква.


1
Коли я спробую це з датами до 1900 року, це не працює в моїй копії excel.
— Анджело Фукс

Довга версія також не працює.
— Анджело Фукс

Для старих дат використовуйте робочий зошит Excel User до 1900 року. < exceluser.com/downloads/examples/post_900_123/index.html >
— Euan M

Питання про те, чи працює це вбік, я не думаю, що вам дозволяється виводити лише дату в листопаді; вам знадобиться "Nov" або "11" в якійсь формі.
— lirtosiast

@Thomas Kwa Введення дати - це рік у форматі дати. Потім розрахунок визначає день тижня, на який припадає 1 листопада, а потім обчислює дату четвертого четверга листопада.
— Euan M

4

PowerShell, 67 64 84 72 58 45 Байт

param($a)'Nov';28-(date "00$a/9/1").DayOfWeek

Ми приймаємо наше вхідне ціле число як $a, і негайно виводимо Novі новий рядок. Потім ми беремо $aі додаємо його до нулів і 1 вересня, 00$a/9/1перш ніж генерувати нове dateі визначати, що DayOfWeekце таке. Якщо 1 вересня в неділю ( .DayOfWeekрівний 0), День подяки - 28 числа. Якщо 1 вересня в понеділок ( .DayOfWeekрівний 1), День подяки - 27 числа. І так далі. Таким чином, ми віднімаємо цей день тижня від того, 28щоб дати відповідь.

Попередження з подвійними нулями припадає на одно- і двоцифрові роки, не припиняючи розбору на три- або чотиризначні роки. Не працює для негативних чисел, оскільки .NET datetimeне підтримує років менше 0.

Дякуємо TessellingHeckler та Toby Speight за допомогу в цьому.


"{0:D3}/Nov/$_" -f $aкоротше "$($a.ToString("000"))/Nov/$_"і дає такий самий результат, і я думаю, ви можете використовувати його 11замістьNov
— n0rd

@ n0rd Ах, чудово! Так - це Novбув залишок від того, коли я намагався змусити його розпізнати двоцифрові роки належним чином, тому я теж обміняю це. Спасибі!
— AdmBorkBork

@TessellatingHeckler Цей підхід працює, але вам потрібно додати два нулі для обліку одноцифрових років, інакше ви знову в 20XX, в який я зіткнувся. Дякую за допомогу - я оновив відповідь.
— AdmBorkBork

1
@TessellatingHeckler У моїй системі, принаймні, вводяться однозначні роки в date "11/1/$a"результати в Thursday, November 1, 2007 12:00:00 AM. Це тому, що ми не редагуємо властивість Calendar.TwoDigitYearMax , тому, коли він розбирається , ми стикаємося з подвійним нулем-прокладкою, щоб обійти це.
— AdmBorkBork

Правильно, правильно. Подвійне підкладка це.
— TessellatingHeckler

3

Гольфскрипт, 25 * 0,75 = 18,75 байт

~.4/.25/.4/2---+7%28\--11

Тут використовується формула Сакамото для дня тижня. Оскільки є люди, які роблять це, результат є у формі dd-mm. Моє попереднє подання можна знайти нижче:

~.4/.25/.4/2---+7%"Nov "28@-

3

TSQL, 478 296 байт

Тільки для ромашок. Як правило, у вас є таблиця розмірів дати, щоб зробити це просто, select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'але за відсутності цього ...

create function a(@y varchar(4))returns date as begin declare @d date,@i int=0 set @d=convert(date,@y+'-11-01')declare @t table(d date,c int identity)while @i<28 begin if datepart(weekday,@d)=5 insert @t(d) select @d select @d=dateadd(d,1,@d),@i+=1 end select @d=d from @t where c=4 return @d end

Безголовки:

if exists(select * from sys.objects where name='a' and [type]='FN') drop function a
go

create function a(@y varchar(4))returns date
-- select dbo.a('2015')
as
begin
    declare @d date,@i int=0;

    set @d=convert(date,@y+'-11-01'); -- cannot golf out dashes for dates <year 1000

    declare @t table(d date,c int identity)

    while @i<28 
    begin -- populate "November" array
        if datepart(weekday,@d)=5 insert @t(d) select @d -- assumes @@datefirst = 7
        select @d=dateadd(d,1,@d),@i+=1
    end;

    select @d=d from @t where c=4 

    return @d

end

Це справді найкоротший шлях?
— lirtosiast

Я припускаю, що я, можливо, не знайомий з правилами коду гольфу, але у відповідь створюється об’єкт БД, який приймає введення та повертає вихід, щоб відповідати ОП. Можливо, спостерігається очевидне скорочення, якщо вхід може бути прийнятий у вбудований код, але це було моєю думкою щодо типу об’єкта функції. Я впевнений, що це могло б бути в гольфі далі в будь-якому випадку. @ThomasKwa, у вас є пропозиції?
— Пітер Вандів'є,

Що ж, мені здається, ви могли б використовувати формулу чистої математики, про яку йдеться у цій відповіді, і не турбуватись із усіма предметами цього об'єкта.
— lirtosiast

не суто математичне рішення, але читання цієї відповіді, безумовно, дало мені кілька ідей, щоб розіграти 200 символів. Спасибі!!
— Пітер Вандів'є

(Я мав на увазі (28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7) Так, читання інших відповідей, як правило, дуже допомагає.
— lirtosiast

3

Pyth, 30 28 * 75% = 21 байт

Я на 100% впевнений, що це можна скоротити, але ей, це моя перша програма Pyth! \ o /

-28.11%+-+-Q2/Q4/Q100/Q400 7

Тестовий набір

Виводить дату у dd.mmформаті.

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


2

Excel, 64 48

Рік в А1

= ДАТА (A1,11, ВИБІР (ТИЖДЕНЬ (ДАТА (A1,11,1)), 26,25,24,23,22,28,27))

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)

Оскільки Excel заснований на локалізації, і я хотів би це перевірити. Поясніть, будь ласка, які функції виконують, щоб я міг вибрати належну мовою.
— Анджело Фукс

1
Крім того, це не працює на дати до 1900 року (принаймні в моїй копії Excel)
— Angelo Fuchs

Крім того, ви зберегли 13байти на TEXTз =TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")- вихід є цілим числом без форматування.
— користувач3819867

@ user3819867, саме так Excel зберігає свої дати. Форматування залишається за користувачем
— SeanC

@AngeloFuchs, DATE повертає значення дати, використовуючи рік, місяць, день як параметри. MOD повертає решту частини поділу (модуль). WEEKDAY повертає день тижня дати (1 = неділя, 2 = понеділок тощо).
— SeanC

2

Befunge, 41 байт

47*&:::4"d"*/\"d"/-\4/++5+7%-" voN",,,,.@

Запустіть цей перекладач .

Пояснення: Загальний рік становить 365 = 1 моди 7 днів, тому рік плюс кожні 4- й рік, мінус кожні 100- й рік ( dв ассії), плюс кожні 400- ті роки припадає на будь-які високосні дні (включаючи поточний рік). Результат :::4"d"*/\"d"/-\4/++потім можна розглядати як 5 березня - го , в перший день після лютого впасти в той же день , як в перший день року в загальні роках. Після цього ми відкалібруємо за шаблоном, 5+7%-віднісши кількість днів тижня з 28- го ( 47*зберігається раніше) листопада. Потім надрукуйте.

Версія, що виправляється за BC років, наразі довша, ніж передбачено бонусом, на 59 -25% = 44,25 байт:

47*&v
!`0:<+*"(F"_v#
" voN",,,,.@>:::4"d"*/\"d"/-\4/++5+7%-


2

Ruby, 60 58 57 * 0,75 = 42,75 байт

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

58 байт

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

60 байт

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11,1).wday]+21}"}

Безголовки:

-> y {
  puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"
}

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

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

=> Nov 26

0

VBA, 124 байти * 75% = 93 байти

Function e(y)
For i = 1 To 7
x = DateSerial(y, 11, 21) + i
If Weekday(x) = 5 Then e = Format(x, "mmm dd")
Next
End Function

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


Кількість просторів; якщо вони не потрібні програмі, ви можете видалити їх.
— lirtosiast

0

PHP 5.3+, 59 байт

При цьому використовується вбудована функція PHP strtotimeдля аналізу дати.

<?=gmdate('M d',strtotime("Next Thursday $_GET[Y]-11-19"));

Це очікує, що значення буде передано через параметр GET Y АБО більшеphp-cli Y=<year> .

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

Майте на увазі, що двозначні роки можуть трактуватися по-різному.

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


1
Відповідь не є підходящим місцем для обговорення достовірності методу введення. Я створив цю опцію в мета-публікації за замовчуванням вводу-виводу (щоб громада могла проголосувати за неї) і перемістив вашу розмову в чат . (CC @Mego)
— Денніс

0

T-SQL 215 байт 248 * 0,75 = 186 байт

create function t(@y int)returns table return select x=convert(char(6),x,107)from(select x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)from(select d=21+n from(values(0),(1),(2),(3),(4),(5),(6))b(n))c)t where datepart(weekday,x)=5

Безумовно

set nocount on;
if object_id('dbo.t') is not null drop function dbo.t
go

create function t(@y int)returns table return
    select x=convert(char(6),x,107)
    from (
        select
        x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)
        from (
            select d=21+n 
            from (values (0),(1),(2),(3),(4),(5),(6))b(n)
        )c
    )t
    where datepart(weekday,x)=5
go

який із цим тестовим ешафотом

select 
  [ 2015 = Nov. 26]=(select x from dbo.t( 2015))
 ,[ 1917 = Nov. 22]=(select x from dbo.t( 1917))
 ,[ 1752 = Nov. 23]=(select x from dbo.t( 1752))
 ,[ 1582 = Nov. 25]=(select x from dbo.t( 1582))
 ,[ 1400 = Nov. 27]=(select x from dbo.t( 1400))
 ,[ -480 = Nov. 25]=(select x from dbo.t( -480))
 ,[-5480 = Nov. 28]=(select x from dbo.t(-5480))
;
go

врожай бажано

2015 = Nov. 26  1917 = Nov. 22  1752 = Nov. 23  1582 = Nov. 25  1400 = Nov. 27  -480 = Nov. 25 -5480 = Nov. 28
--------------- --------------- --------------- --------------- --------------- --------------- ---------------
Nov 26          Nov 22          Nov 23          Nov 25          Nov 27          Nov 25          Nov 28

0

Щука , 87 91 107 77 76 байт - 25% = 57

string t(int y){return"Nov "+((11-Calendar.Day(y,11,1)->week_day())%7+22);}

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

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}

Схоже, це не бере участь.
— Пітер Тейлор

так, я збентежився тим, що деякі рішення мають визначення функції, а деякі просто використовують змінну, яка ніде не визначена, тому я не впевнений, що я повинен використовувати для облікового запису.
— eMBee

Я думаю, що відповіді, які ви бачите як використання " змінної, яка ніде не визначена ", насправді використовують синтаксис декларації дуже коротких функцій. Є один або два відповіді, в яких використовуються езолангси, які мають спеціальне лікування stdin, і тому сприяють написанню повних програм. Я не знаю Пайк, але якщо ви можете видалити пробіл і скоротити ім'я функції, щоб отримати, string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}я вважаю це 107 байтами.
— Пітер Тейлор

я думав, що я бачив декілька, які не функціонували декларацій, але вони, здається, були виправлені, тільки приклад smalltalk не підходить. якщо це дійсно, я міг би поголити ще 17 байт цього ...
— eMBee

Версія Smalltalk написана як програма - конкретно вираз Workspace. Нам сказали, що нам надають вклад, а не прохання про введення.
— Euan M

0

Малі розмови - Скріп і Фаро , 69 57 54 49 35 34 33 32 - 25% = 24 байти

"Листопада пп": 69B 49B (-25% = 36.75B)
11nn (anInt): 57 54 32В (-25% = 24B)

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn
 Methods Date>>y:m:d: and >>w created as duplicates 
 of year:month:day and weekdayIndex"
(12-(Date y:y m:11d:1)w)\\7+1122

Попередні версії

11nn вихід

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn"
(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

"Year supplied as an integer value, y  
 Result provided as an integer value, d, prefixed by 11"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

Листопадовий вихід

"Year supplied as an integer value, y  Result provided as a string, 'Nov nn'"
'Nov ', (12-(Date year:y month:11 day:1) weekdayIndex\\7+22) asString

nn вихід

"Year supplied as an integer value, y  Result provided as an integer value, d"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+22

nb Це надається як програма, зокрема вираз Workspace, а не як метод.

Він передбачає, що введення є заданим (згідно з фразою "дано чотиризначний рік".
У тому числі оголошення та надання вводу додасть ще 11 символів:

|y|y:=2015.(12-(Date y:y m:11 d:1)w)\\7+1122

Завдяки eMBee за те, що показав, як видалити ще один знак - пробіл безпосередньо перед «w».

Насправді, це надихнуло мене на спробу видалити пробіл перед 'd:':
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
Що спрацювало!


Відповідно до уточнення ОП , версія номера дня не є дійсною.
— Mego

Я згоден - але, враховуючи, що в списку є досить багато версій, що містять лише кількість днів, я помістив її для порівняння яблук до яблук
— Euan M

0

GNU coreutils, 35 байт

seq -f$1-11-2%g 2 8|date -f-|grep h

Просто шукайте тиждень 22-28 листопада на четвер. Запустіть його в мові C або POSIX, оскільки я залежу від того, що четвер є єдиною абревіатурою дня, яка містить "h".


Ось розумніша відповідь, хоч на байт довше:

echo Nov $((28-`date -d$1-5-5 +%w`))

Ми отримуємо номер дня тижня в досить довільному тижні між березнем і вереснем (тому день і місяць - одна цифра кожна, і на нас не впливає можливий високосний день). Ми обираємо день так, щоб настала неділя ( %w==0), коли День подяки - це 28-й. Потім ми можемо відняти це значення від 28, щоб отримати відповідний четвер.


2
Це працює, якщо Шон Коннері не керує ним.
— bkul

0

TSQL, 53 52 байти

DECLARE @ CHAR(4)=2000

PRINT DATEADD(d,59,DATEDIFF(d,1,DATEADD(m,9,@))/7*7)

Скрипка

Розрахунок понеділка до або 2 вересня та додавання 59 днів

(краще, ніж обчислювати понеділок до або 4 жовтня і додавати 31 день, тому що жовтень - 10-й місяць, таким чином, заощаджуючи 1 байт)


-1

Perl, 92 байти

use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print "Nov $_":0for 22..28

EDIT: виправлений вихідний формат, виправлена ​​помилка, наприклад, результат 2012 року, використовується коротший формат "для". Завдяки msh210.


Це коротше і робить те ж саме: use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29. Але обидва сценарії страждають одними і тими ж вадами: (1) вони не друкують представлення місяця, як потрібно; (2) вони мають неправильний вихід, наприклад, 2012.
— msh210
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.