Когда День Благодарения?


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 Томаса Ква как принятое. Не позволяйте этому отговорить вас от подачи новых записей!

Leaderboards

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# 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 Используйте тот счетчик байтов, который вы хотите. Это только тот, который я использую лично и рекомендую.
2015 г.

22
«Некоторые праздники имеют фиксированные, легко запоминающиеся даты, например, 31 октября, 25 декабря». Эти примеры легко запомнить, потому что они на самом деле один и тот же день: восьмеричное 31 == десятичное 25. ;-)
Адриан МакКарти

7
Для ответа, который дает бонус, должен ли быть год 0 между -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. Хорошо.
agtoever

Я считаю 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 не поддерживает аргументы командной строки, и я не знаю онлайн-переводчика, который это делает.

Спасибо Александру О'Мара за то, что он научил меня новому трюку, и primo за значительное сокращение


2
Это смешнее, чем Mathematica.
lirtosiast

2
@ Трис Еще короче "4thuXI". Вы даже можете оставить место между годами "4thuXI2015".
Александр О'Мара

1
Используя параметр командной строки -F, ввод может быть сокращен до "4thuXI$argn".
Примо

3
Подождите, это на самом деле работает? Это ... это просто ... я даже не ...
ETHproductions

1
Работает для меня . Пока я на этом, Mdкавычек не нужно, с E_NOTICEотключенным.
Примо

18

Mathematica, 59 38 байт

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

+1 Умный. Там же, WolframAlpha["Thanksgiving " <> #] &где дата вводится в виде строки.
DavidC

WolframAlpha возвращает даты Дня Благодарения в США с 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 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

(Жаль, что я реализовал это раньше!)


Очень красиво сделано.
2015 г.

Это теперь дольше, чем ванильный JavaScript. Томас Ква имеет гораздо более короткую формулу .
intrepidcoder

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

12

Витси , 44 байта

Я рассчитываю с чистой математикой !

Golfed:

Ve2 * V2-V41m + Vaa * Dv1m-VV4 * 1m + 7M-бе * / + N,
/ D1M-

Ungolfed (переместил вызов метода на первую строку, чтобы сделать его читабельным):

Ve2 * V2-V4 / D1M- + Vaa * Dv / D1M - VV4 * / D1M- + 7M-бе * / + N,

V Сохранить ввод как окончательную переменную.
 e2 * Нажмите 28 в стек.
    V Вставьте вход в стек.
     2- Вычтите два.
       V4 / D1M - Получить этаж (вход / 4).
              + Добавьте это к общему итогу.
               Vaa * Dv / D1M - получить слово (input / 100) и сохранить 100 как темп
                                    переменная в процессе.
                          - вычтите это из общего.
                           Vv4 * / D1M - Get floor (input / 400).
                                    + Добавьте это к общему итогу.
                                     7М по модулю семь.
                                       - Вычтите результат из 28.
                                        baa * / + Добавить .11
                                              N Выведите как число.

Вероятно, есть лучший алгоритм для этого (и это, вероятно, ужасно), но для тех, кто интересуется, мой алгоритм отсюда .

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

Получу ли я бонусные баллы за его вычисление и имея ровно 42 байта? Мечты разрушены.

Спасибо @ Hosch250 за указание на то, что я делаю это неправильно. : D Исправлено.


2
Но ты получаешь +1 от меня;)
Конор О'Брайен

В нем говорится, что День Благодарения в 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
Эддисон Крамп

Короче использовать строковых повторений,"Nov "+`...`
xnor

@VoteToClose Python по модулю дает ответ с тем же знаком, что и второй аргумент. Таким образом, -40%7==2но-40%-7==-5
Quintopia

@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 хм, от 0 до 99 действительно неправильно, позвольте мне попытаться это исправить.
Никель

@ Похоже, 0-100 дают ту же дату, что и 1900-2000, судя по другим ответам.
Никель

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/… .
Никель

@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

Python, 83 81 78 байт

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2 байта: добавлено имя для импорта (спасибо @ Κριτικσι Λίθος)
  • -1 байт: изменено на * import ** (спасибо @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 по умолчанию. Эта версия предназначена для дд / мм / гггг:

 =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 годов, для всех дат начиная с 7700 до н. Э., С использованием трюка с повторением дат Томаса Ква.


1
Когда я пробую это с датами до 1900 года, это не работает в моем экземпляре Excel.
Анджело Фукс

Длинная версия не работает так же хорошо.
Анджело Фукс

Для старых дат используйте книгу Excel до 1900 года. < exceluser.com/downloads/examples/post_900_123/index.html >
Euan M

Вопросы о том, работает ли это в стороне, я не думаю, что вам разрешено выводить только дату в ноябре; вам нужно «ноябрь» или «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.

Спасибо TessellatingHeckler и Toby Speight за помощь в этом.


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

@ n0rd Ах, отлично! Да, это Novбыл остаток того времени, когда я пытался заставить его правильно распознавать двузначные годы, так что я тоже это поменяю. Благодарность!
AdmBorkBork

@TessellatingHeckler Этот подход работает, но вам нужно добавить два ноля, чтобы учесть годы с одной цифрой, иначе вы вернетесь в 20ХХ, с которыми я столкнулся. Спасибо за помощь - я обновил ответ.
AdmBorkBork

1
@TessellatingHeckler В моей системе, по крайней мере, ввод однозначных лет в date "11/1/$a"результаты в Thursday, November 1, 2007 12:00:00 AM. Это потому, что мы не редактируем свойство Calendar.TwoDigitYearMax , поэтому, когда оно анализируется , мы застряли с добавлением двойного нуля, чтобы обойти это.
AdmBorkBork

Верно-верно. Двойная обивка это.
TessellatingHeckler

3

Golfscript, 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

Ungolfed:

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

Я предполагаю, что я, возможно, не знаком с правилами игры в гольф, но ответ создает объект БД, который принимает входные данные и возвращает выходные данные, соответствующие OP. Существует некоторое очевидное сокращение, которое может произойти, если ввод может быть принят во встроенный код, но это была моя мысль о типе объекта функции. Я уверен, что это может быть дальше в любом случае. @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! \ О /

-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)
Анджело Фукс

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

@ user3819867, вот как Excel хранит свои даты. форматирование оставлено на
усмотрение

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

2

Befunge, 41 байт

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

Запустите на этом переводчике .

Пояснение: Обычный год равен 365 = 1 мод 7 дней, поэтому год плюс каждый 4- й год, минус каждый 100- й ( dв ascii) году плюс каждые 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

Рубин, 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}"}

Ungolfed:

-> 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 OR over 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

Ungolfed

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

Это не похоже на ввод.
Питер Тейлор

да, меня это смутило, некоторые решения имеют определение функции, а некоторые просто используют переменную, которая нигде не определена, поэтому я не уверен, что я должен использовать для bytecount.
eMBee

Я думаю, что ответы, которые вы видите как использующие « переменную, которая нигде не определена », на самом деле используют очень короткий синтаксис объявления функции. Есть один или два ответа, которые используют esolangs, которые имеют специальную обработку 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

Smalltalk - Squeak and Pharo , 69 57 54 49 35 34 33 32 - 25% = 24 байта

«Nov nn»: 69B 49B (-25% = 36,75B)
11nn (anInt): 57 54 32B (-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 Это предоставляется как программа, а именно как выражение рабочей области, а не как метод.

Предполагается, что ввод является заданным (согласно фразе «задан год до четырех цифр»).
Включение объявления и выдачи ввода добавит еще 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

РЕДАКТИРОВАТЬ: Исправлен формат вывода, исправлена ​​ошибка, например, результат 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.