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


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.