Оу, чувак, эта дата истечения срока не записывает месяцы с буквами! Я не могу сказать, истекает ли это 10 марта или 3 октября ... Подождите, нет, неважно, год говорит о 2012. (alley-ой наполовину использованный кирпич сыра в мусорное ведро как профессионал)
Итак, давайте на минутку предположим, что вы слишком заняты, чтобы попытаться выяснить, когда должен закончиться срок действия этой банки маринары. Вы просто хотите версию Cliff Notes: насколько вероятно, что она просрочена? Давайте напишем некоторый код!
Вы знаете, что производители печатают дату в виде упорядоченной тройки целых чисел в одном из трех форматов:
YEAR MONTH DAY
MONTH DAY YEAR
DAY MONTH YEAR
И вы знаете, что некоторые даты можно интерпретировать только одним или двумя способами, а не всеми тремя: 55-й год 55-11-5
должен быть годом, означающим, что срок действия этой конкретной коробки Twinkies истек 5 ноября 1955 года. Год иногда дается в четыре цифры и не два, которые могут исключить некоторые варианты. Когда это две цифры, однако, 50..99 означает 1950..1999, а 0..49 означает 2000..2049.
Ваша задача - написать программу или функцию, которая принимает массив целых чисел, который является действительной датой хотя бы в одной из приведенных выше интерпретаций, и выдает процентную вероятность того, что это все еще хорошо. Процент вероятности - это просто процент действительных интерпретаций даты, которые относятся к сегодняшней дате или позже .
Массив целых чисел будет [Int]
типом вашего языка длины три, если он является аргументом функции, и задан как целые, разделенные пробелом или пробелом (вы можете выбрать), если он используется в качестве входных данных для STDIN для полная программа. *
«Сегодняшняя дата» может быть текущей фактической датой, полученной с помощью функции date, или датой, указанной в дополнительном аргументе функции или дополнительном параметре в STDIN. Это могут быть секунды эпохи Unix, другая тройка год-месяц-день, введенная одним из трех указанных выше способов, или другой более удобный способ.
Давайте иметь несколько примеров! Ввод даты окончания срока действия будет выполнен в стиле, разделенном тире, и для приведенных ниже примеров предполагается, что сегодняшняя дата - 5 июля 2006 года.
14-12-14
- Обе действительные интерпретации для этого (DMY и YMD) эквивалентны, 14 декабря 2014 года. Результат - 100, потому что этот продукт определенно все еще хорош.8-2-2006
- Последний номер, конечно же, год, поскольку он состоит из четырех цифр. Это может быть 8 февраля (истек) или 2 августа (все еще хорошо). Выход 50 .6-7-5
- Это может быть что угодно! Интерпретация «5 июля 2006 г.» все еще хороша (только на один день), но остальные два - в 2005 г. и должны быть отброшены как можно быстрее. Выход 33 .6-5-7
- Здесь две из трех интерпретаций безопасны. Вы можете округлить десятичную дробь вверх или вниз, так что с 66 или 67 все в порядке.12-31-99
- Хорошо, этот однозначно относится к рубежу веков (годы с 50 по 99 - 19XX, а 31 не может быть месяцем). Большой жирный 0 , и вы действительно должны почистить холодильник чаще.
Вы можете смело предположить, что любой вход, который не соответствует вышеуказанным стандартам, не относится к вышеприведенным правилам вывода.
Нет веб-запросов или стандартных лазеек. Библиотеки обработки даты разрешены. Это код гольф: пусть победит самая короткая программа.
* Если вы используете brainfuck или какой-либо подобный язык с недостатками типа данных, вы можете предположить, что значения ASCII первых трех символов на входе являются целыми числами для даты. Конечно, это исключает логику четырехзначного года, но я думаю, что мы были бы слишком изумлены, увидев решение этой проблемы в Brainfuck, чтобы подсказать вам за это.
Ответы:
k4
(90)(88)(87)(82)Вызовите
x
из.z.D
(встроенного) для сравнения с сегодняшним днем или литералом даты по вашему выбору в противном случае:По сути, это порт Python-решения @ Alex-l, в который добавлено несколько разных хитростей:
источник
"012201210"
, так как он#
принимает его элементы циклически. На самом деле, вы можете сэкономить на секунду CHAR таким образом, меняя последние два случая:3 3#.:'"0122102"
.{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
.Рубин, 115 знаков
Это определяет функцию,
f
которая принимает два аргумента: массив, содержащий входные данные, и «сегодняшнюю» дату.Примеры:
источник
Python 2.7 - 172
Я использую модуль datetime для валидности и сравнения дат. Если
date
не удается сделать правильное время и дату из входных данных, они повышаютсяValueError
. Этот способs
представляет собой сумму дат с истекшим сроком действия иt
общее количество действительных дат. Я пользуюсь тем, чтоTrue == 1
для целей добавления и индексации в Python. Я также сохраняю персонажа, используя 25 * (76,80) вместо (1900,2000).Обратите внимание, что строки на втором уровне отступа используют символ табуляции, а не 2 пробела.
Добавьте это в конец, чтобы проверить:
источник
PowerShell,
183173168Ввод как
int[]
через параметр, напримерtry
/catch
, пока я не знаю, разрешен ли вывод на stderr или нет.+"-1"
даты, которая интерпретируется как.AddDays(-1)
смещение текущей даты на один день, чтобы мы могли сравнить ее со вчерашним днем (а не только с сегодняшним днем). Это решает проблему, заключающуюся в том, что мы получаем дату с 0:00 как время, но нужно сравнить с датой со временем с сегодняшнего дня.источник
R 269
Я ожидал, что это будет легко в R, но годы с одной цифрой были довольно большим кривая. Я чувствую, что это может быть намного лучше, чем есть.
lubridate
это пакет от CRAN, вам может потребоваться его установкаinstall.packages("lubridate")
.Использование:
f(c(d1,d2,d3))
гдеc(d1,d2,d3)
находится вектор целых чисел.например,
f(c(6,10,14))
возвращается0.3333333
.lubridate
Пакет имеет ряд функций - оболочек для разбора дат в различных порядках. Я использую их, чтобы увидеть, какие форматы дают действительные даты, выбрасывать недействительные, а затем посмотреть, какие еще не произошли.источник
Mathematica,
163153164 байта( редактировать: фиксированные даты вне диапазона 1950 - 2049)
Это определяет функцию, которую вы можете вызвать как
В настоящее время процент не округляется (в ожидании разъяснения ОП).
Вот немного длинное объяснение , которое должно быть понятно без знания Mathematica (заметим , что
&
делает все от него осталось анонимная функция, параметры которой называют#
,#2
,#3
...):Это определяет функцию, которая превращает 3 параметра
a,b,c
в 3 списка{{a,b,c},{c,b,a},{c,a,b}
. Обратите внимание, что##
это просто последовательность всех параметров.Применительно к дате истечения срока действия, это дает список
{y,m,d}
для каждой из трех возможных перестановок.Это анонимная функция, которая принимает три параметра
a,b,c
и возвращает список из трех, где первый был преобразован в год согласно заданным правилам: числа между50
и99
(по модулю100
) превращаются в год 20-го века, числа между0
и49
( по модулю100
) превращены в год 21 века, все остальные остались вместе. Здесь,##2
представляет собой последовательность параметров , начиная со второго, то естьb,c
.Применительно к каждому из трех предыдущих результатов это просто канонизирует форматы года. Давайте вызовем это,
canonicalDates
чтобы сократить следующее выражение:Это отфильтровывает неверные интерпретации.
DateList@d
делает полное{y,m,d,h,m,s}
представление из различных форматов даты. Он будет интерпретировать списки в том же порядке, но выгода заключается в том, что вы можете передавать ему такие вещи, как{8,2,2006}
в этом случае он будет вычислять8 years + 2 months + 2006 days
. Поэтому мы проверяем, что первые три элемента возвращенного списка идентичны входным данным (что может произойти, только если месяц и день находятся в соответствующих диапазонах).Чтобы сократить следующие строки, я буду ссылаться на результат этого выражения
validDates
с этого момента :Другая анонимная функция, которая принимает дату и возвращает разницу в днях до сегодняшнего дня (получена из
Date[]
).Сопоставьте это с действительными интерпретациями даты.
Еще одна анонимная функция, которая, учитывая list (
#
), возвращает процент неположительных чисел в этом списке. Это.
не умножение, а просто десятичная цифра, чтобы избежать рациональных чисел в результате (вы получите такие вещи, как100/3
вместо33.333
- я на самом деле не знаю, если это проблема).Применительно к списку различий дат это дает нам часть интерпретаций, которые еще не истекли.
источник
JavaScript (E6) 159
164 172Edit Спасибо nderscore за подсказки и за то, что подтолкнул меня к мысли снова. Реорганизован D, избегая параметров и сокращая некоторые символы.
Редактировать 2 Еще один трюк от nderscore, 2 функции объединены в 1. Затем две круглые скобки убрали объединение выражений через запятую в одно. Читаемость около 0. Sidenote: Не округление может спасти еще 2 символа (| 0).
Консоль Test In FireFox
Выход:
Ungolfed
Примечание: функция D пытается создать дату с указанным годом, месяцем, днем, но возвращает false, если созданная дата не соответствует назначению (! = День или месяц)
источник
C # в LINQPad -
446408272 байтаТретье редактирование: Спасибо Ле Канар Фу за указание, что DateTime.Today является правильным, а не DateTime.Now. Второе редактирование: спасибо VisualMelon за это умное решение!
Изменить: Спасибо podiluska и edc65 за помощь в создании кода! Я также заметил, что мое решение не было правильным, если годовой ввод был 4 байта, поэтому я включил исправление для этой проблемы. Оценка для этого решения составляет 408 байт.
Несмотря на то, что я не бью ни одного из предыдущих ответов, я все же хотел поделиться своим решением C #. Любая помощь / предложения приветствуются! ;)
Отформатированная и разглаженная версия:
Я попытался создать решение, при котором «DateTime.TryParse» -Part не повторяется, как в этом решении, но оно было на 21 байт длиннее.
Решение без повторения «DateTime.TryParse»: 467 байт
Безголовая версия:
источник
int s=0;int a=d[2];int b=d[1];int e=d[0];
->int s=0,a=d[2],b=d[1],e=d[0];
DateTime.TryParse
вызовов было моим первым инстинктом, заменил его лямбда-выражением, которое также возвращает значение в q. Также выполнил некоторые другие шаги ( pastebin ), чтобы получить 328 знаков:void g(int[]d){var q=new List<DateTime>();var p=".";int a=d[2],b=d[1],e=d[0],y;DateTime c;y=(a<100)?(a>49)?1900+a:2000+a:a;Action<string>z=(x)=>{if(DateTime.TryParse(x,out c))q.Add(c);};z(e+p+b+p+y);z(b+p+e+p+y);y=(e<100)?(e>49)?1900+e:2000+e:e;z(a+p+b+p+y);(q.Where(i=>i>=DateTime.Now).Count()*100/(q.Any()?q.Count:1)).Dump();}
Action<string>
раньше, поэтому я мог кое-что узнать от вас;) Я смог получить ваш ответ до 318 символов, заменивq.Where(i=>i>=DateTime.Now).Count
наq.Count(i=>i>=DateTime.Now
. Я также убрал квадратные скобки,x
чтобы сохранить еще 2 символа!Haskell,
171165 знаковИмя функции есть
%
. Запустите тестовую дату в виде кортежа в каноническом (y, m, d) порядке с указанием фактического года и отметки на коробке в виде кортежа из трех чисел:источник
Эрланг, 146
Тестовая функция будет:
Ungolfed
Это решение основано на списках. Он заимствует трюк по модулю на год из решения Haskell. Он также используется
calendar:valid_date/1
для обработки невозможных дат из-за количества дней в данном месяце (например, «29-2-2» может быть только в формате YMD). Кроме того, Today вdate()
формате Erlang (кортеж YMD).источник
APL (85)
При этом используются некоторые новые функции Dyalog APL 14, но нет внешних библиотек. Для разнообразия работает на TryAPL .
Это функция, которая принимает массив из 3 элементов в качестве
⍵
аргумента right side ( ), а дату, с которой сравнивается как⍺
аргумент left side ( ), - как целое числоYYYYMMDD
формата. Т.е. дата2014-07-09
представляется в виде числа20140709
.Контрольная работа:
Объяснение:
Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵
: преобразовать указанную дату в формат YMD, щелкнув(⊂⌽⍵)
, повернув ее влево на 2(⊂2⌽⍵)
или просто ничего не делая⊂⍵
. По крайней мере, одна из них теперь является правильной датой в формате YMD, возможно, больше, чем одна, если дата неоднозначна.{∧/12 31≥1↓⍵}¨Z
: test, если каждая дата действительна: год (первый элемент) отбрасывается, а затем месяц должен быть не выше 12, а день не должен быть выше 31.Z/⍨
: отфильтровать действительные даты отZ
.{
...}¨
: на каждую действительную дату:⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵
: если год не выше 99, добавьте 1900, затем 100, если год меньше 50.(3/100)⊥
: расшифруйте его так, как если бы это был набор чисел base-100. (Год больше 100, но это не имеет значения, поскольку это первый элемент.) Это дает число для каждой действительной даты в том же формате, что и левый аргумент.⍺≤
: для каждой даты посмотрите, не меньше ли она чем⍺
. Это даст двоичный вектор, где 1 означает,OK
а 0 означаетspoiled
.100×(+/÷⍴)
: разделите сумму двоичного вектора на его длину и умножьте на 100.источник
{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
Java: 349 символов (3 без пробелов)
Вот содержащий класс, который может быть использован для его тестирования, включая (немного) дегольфированную версию метода:
Это мой первый раунд гольф-кода, и я думаю, я понял, почему я обычно не вижу очень много игроков в гольф Java.
источник
int[]
качестве аргумента, а не триint
с.C # 287 байт
Первый раз играю в гольф, ищу советы. В частности, удаление байтов из-за пространства имен.
Злоупотребление фактом, что требуется только функция, а не фактическая программа. Кроме того, функция всегда приводит к необработанному исключению.
Ungolfed
источник
Математика , 118
Используя код m.buettner в качестве отправной точки, у меня есть несколько улучшений:
источник