Задний план
Некоторые праздники имеют фиксированные, легко запоминающиеся даты, такие как 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
var QUESTION_ID=64785,OVERRIDE_USER=45162;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?([\d.]+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
Ответы:
TI-BASIC, 15 байтов * 0,75 = 11,25
Проверено на моем калькуляторе TI-84 +
День благодарения - 29 ноября, минус день недели 1 сентября, где 1 - воскресенье, а 7 - суббота. Это выводит в формате
MMDD
.Контрольные примеры:
2015
->1126
,1917
->1122
,-480
->1125
были проверены. TI-BASIC, кажется, использует григорианский календарь для всех дат.TI-BASIC не поддерживает отрицательные годы, но получает бонус, потому что мы добавляем 10000 к входу. Поскольку григорианский календарь имеет период 400 лет, это не меняет день недели.
источник
dayofWK(
иAns
которые являются 2 и 1 байт каждый.PHP,
6548424136 (+2 для-F
) = 38 байтПринимает ввод в качестве первого аргумента командной строки. Работает с предупреждениями, которые приемлемы по нашим правилам. Отпечатки
NovDD
, гдеDD
день благодарения.Нет онлайн-ссылки, потому что ideone не поддерживает аргументы командной строки, и я не знаю онлайн-переводчика, который это делает.
Спасибо Александру О'Мара за то, что он научил меня новому трюку, и primo за значительное сокращение
источник
"4thuXI"
. Вы даже можете оставить место между годами"4thuXI2015"
.-F
, ввод может быть сокращен до"4thuXI$argn"
.Md
кавычек не нужно, сE_NOTICE
отключенным.Mathematica,
5938 байтисточник
WolframAlpha["Thanksgiving " <> #] &
где дата вводится в виде строки.JavaScript (ES6),
424031 байт - 25% = 23,25Поскольку дата «может быть в любом разумном формате», эта функция использует
DD.MM
. Я написал ответ TeaScript с другой техникой, но эта формула была короче.объяснение
Поскольку месяцы начинаются с нуля,
new Date(a,10)
возвращаетDate
объект, представляющий 1 ноября указанного года.Так как
getDay()
возвращает число, представляющее день недели, из которого0..6
мы хотим отобразитьзатем добавьте 22. Получается, что
(11 - new Date(a,10).getDay()) % 7
добьется цели. Как отметил @Thomas Kwa , это то же самое,28-new Date(a,8).getDay()
что и 28 минус день недели 1 сентября.источник
Japt ,
4337363529 байт - 25% = 21,75Japt - это сокращенная версия Ja vaScri pt .
Хахаха, я нашел действительно обманчивый трюк: интерпретатор игнорирует любые скобки внутри строк (используемые для вставки кода) при их распаковке, поэтому мы можем сжать весь исходный код для сохранения байта>: D
Две
?
s должны быть непечатными Unicode U + 0098 и U + 0085, соответственно. Попробуйте онлайн!После распаковки код оценивается следующим образом:
Который оценивает:
Что дает правильный вывод.
Использует технику intrepidcoder, вывод в формате
dd.mm
. Правильно поддерживает отрицательные годы. Предложения приветствуются!Изменить: Начиная с 2 декабря, теперь вы можете использовать этот 11-байтовый код (набрав 8,25 балла ):
(Жаль, что я реализовал это раньше!)
источник
Витси , 44 байта
Я рассчитываю с чистой математикой !
Golfed:
Ungolfed (переместил вызов метода на первую строку, чтобы сделать его читабельным):
Вероятно, есть лучший алгоритм для этого (и это, вероятно, ужасно), но для тех, кто интересуется, мой алгоритм отсюда .
Попробуйте онлайн!
Получу ли я бонусные баллы за его вычисление и имея ровно 42 байта?Мечты разрушены.Спасибо @ Hosch250 за указание на то, что я делаю это неправильно. : D Исправлено.
источник
Python, 38 * 0,75 = 28,5 байт
Это работает с отрицательными годами в порядке, указанном в вопросе, хотя до меня дошло, что в григорианском календаре нет года 0, поэтому такое поведение немного подозрительно.
источник
f=
."Nov "+`...`
-40%7==2
но-40%-7==-5
JavaScript (ES6), 43,5
Фактическое число байт составляет 58. Бонус -25% применяется => 58 * 0,75 = 43,5
Довольно прямолинейно
и глупо, без каких-либо хитрых обходных путей или расчетов.Де-гольф (ES5) + демо:
Обратите внимание, что входной год 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
источник
a<4?x:a>4?y:a+18
эквивалентноa<4?x:a>4?y:22
?TeaScript,
353324 байта - 25% = 18Это тот же метод, что и в моем ответе JavaScript , в котором используется умная формула Томаса Ква .
Альтернативная версия с объяснением
источник
Jython,
141155 байтИспользует классы Java Calendar и Scanner с синтаксисом Python.
Изменить: Незначительные проблемы синтаксиса, добавлено 14 байтов.
Также см. Мою версию Brainfuck .
источник
Python,
838178 байтисточник
import datetime as d
а затем вы можете использоватьd
каждый раз, когда вы используетеdatetime
в своей программе.import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
from datetime import*
даже немного короче, так как вы не будете нуждаться вd.
большеExcel,
36715453 - 25% = 39,75 байтПредполагается, что год проводится в ячейке A1 в формате Date. Возвращает целое число дня ноября, в который проводится День Благодарения.
Это касается только високосных лет. Не учитывается тот факт, что 2100, 2200, 2300 лет не являются високосными.
Это рассчитано только на 1621 год, то есть с тех пор, как начался День Благодарения. (Хотя это, безусловно, будет работать до 0 г. н.э.).
Довольно отпечатанный:
Г! Вместо того, чтобы рассчитывать на основе 1 января, а затем делать много расчетов високосного года, чтобы справиться с 29 февраля, я должен был основывать расчеты на 1 ноября. Nb. Теперь это правильно работает с 2100, 2200 и 2300 годами. , но делает реализацию зависимой от формата даты вашей установки Excel по умолчанию. Эта версия предназначена для дд / мм / гггг:
И теперь, когда я сделал pfaffing, чтобы получить краткие вычисления в Smalltalk, перенесение их в Excel приводит к следующим результатам:
(с годом все еще в A1, но как целое число). Это работает даже для 2100, 2200 и 2300 годов, для всех дат начиная с 7700 до н. Э., С использованием трюка с повторением дат Томаса Ква.
источник
PowerShell,
676484725845 байтМы берем наше входное целое число как
$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
Nov
был остаток того времени, когда я пытался заставить его правильно распознавать двузначные годы, так что я тоже это поменяю. Благодарность!date "11/1/$a"
результаты вThursday, November 1, 2007 12:00:00 AM
. Это потому, что мы не редактируем свойство Calendar.TwoDigitYearMax , поэтому, когда оно анализируется , мы застряли с добавлением двойного нуля, чтобы обойти это.Golfscript, 25 * 0,75 = 18,75 байт
Здесь используется формула Сакамото для дня недели. Так как есть люди, делающие это, результат в форме
dd-mm
. Мое предыдущее представление можно найти ниже:источник
TSQL,
478296 байтПросто для приколов. Как правило, у вас есть таблица измерений даты, чтобы сделать это простым,
select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'
но в отсутствие этого ...Ungolfed:
источник
(28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7
) Да, чтение других ответов очень помогает.Pyth,
3028 * 75% = 21 байтЯ на 100% уверен, что это можно сделать короче, но эй, это моя первая программа Pyth! \ О /
Тестирование
Выводит дату в
dd.mm
формате.Пожалуйста, предложите способы игры в гольф, если вы можете! Я хотел бы узнать больше о Pyth.
источник
Excel,
6448Год в А1
= ДАТА (A1,11, ВЫБРАТЬ (ДЕНЬНЕД (ДАТА (A1,11,1)), 26,25,24,23,22,28,27))источник
13
байтыTEXT
от=TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")
- выходные данные являются целыми числами без форматирования.Befunge, 41 байт
Запустите на этом переводчике .
Пояснение: Обычный год равен 365 = 1 мод 7 дней, поэтому год плюс каждый 4- й год, минус каждый 100- й (
d
в ascii) году плюс каждые 400- й год учитывает любые високосные дни (включая текущий год). Результат:::4"d"*/\"d"/-\4/++
затем можно рассматривать как 5 марта - го , в первый день после февраля впасть в тот же день , как в первый день года в общие годах. После этого мы калибруем по шаблону,5+7%-
вычитая количество дней недели с 28- го (47*
сохраненное ранее) ноября. Затем распечатайте.Версия, исправляющая годы BC, в настоящее время длиннее, чем предусматривает бонус, на 59 -25% = 44,25 байт:
источник
Matlab, 78 байт
источник
Рубин,
605857 * 0,75 = 42,75 байт58 байт
60 байт
Ungolfed:
Использование:
источник
VBA, 124 байта * 75% = 93 байта
Я не уверен, если количество пробелов, это где-то между 102 и 124, не стесняйтесь редактировать.
Если целые числа являются допустимым выводом, я более чем счастлив удалить
Format
часть.источник
PHP 5.3+, 59 байт
Это использует встроенную функцию PHP
strtotime
для анализа даты.Ожидается, что значение будет передано через параметр GET
Y
OR overphp-cli Y=<year>
.Он пытается найти следующий четверг после 19 ноября.
Пока что с проведенными мною тестами все работает нормально.
Имейте в виду, что двузначные годы могут интерпретироваться по-разному.
Я использую,
gmdate
чтобы избежать проблем с часовым поясом, но он работает одинаково хорошо, используяdate
(по крайней мере, там, где я живу).источник
T-SQL
215 байтов248 * 0,75 = 186 байтовUngolfed
который с этим испытательным лесом
дает по желанию
источник
Пайк ,
87 91 107 7776 байт - 25% = 57оставив старый для сравнения, потому что я нахожу его более умным с точки зрения использования модуля календаря, но вышесказанное намного короче.
источник
string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}
то я считаю это как 107 байтов.Smalltalk - Squeak and Pharo ,
6957544935343332 - 25% = 24 байта«Nov nn»:
69B49B (-25% = 36,75B)11nn (anInt):
575432B (-25% = 24B)Предыдущие версии
Выход 11nn
Ноябрь нн выход
выход nn
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
Что сработало!
источник
GNU coreutils, 35 байт
Просто ищет неделю 22-28 ноября для четверга. Запустите его в локали C или POSIX, так как я полагаю, что четверг - единственное сокращение дня, содержащее 'h'.
Вот более умный ответ, хотя и дольше:
Мы извлекаем номер дня недели в довольно произвольную неделю между мартом и сентябрем (таким образом, день и месяц - одна цифра каждая, и на нас не влияет возможный високосный день). Мы выбираем день так, чтобы это было воскресенье (
%w==0
), когда День Благодарения наступает 28-го числа. Затем мы можем вычесть это значение из 28, чтобы получить соответствующий четверг.источник
TSQL,
5352 байтаскрипка
Расчет понедельника до или 2 сентября и добавление 59 дней
(лучше, чем вычисление понедельника до или 4 октября и добавление 31 дня, потому что октябрь является 10-м месяцем, тем самым экономя 1 байт)
источник
Perl, 92 байта
РЕДАКТИРОВАТЬ: Исправлен формат вывода, исправлена ошибка, например, результат 2012 года, используется более короткий формат «для». Благодаря msh210.
источник
use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29
. Но оба сценария страдают от одних и тех же недостатков: (1) они не печатают представление месяца, как требуется; (2) у них неправильный вывод, например, на 2012 год.