Легализовать отмененную дату

18

Входные данные:

А Дата (содержащий dd, MMи yyyy). Объект даты или три отдельных целых числа также допустимы в качестве входных данных.

Выход:

Каждая часть ( dd, MMа yyyy) индивидуально вернулся и чем округлены до ближайшей действительной даты.

Например (в формате dd-MM-yyyy):
21-10-2016становится12-01-6102

Правила соревнований:

  • Только dd, MM, yyyyдействительно, но порядок и какие отдельные-символы , которые вы используете ваш собственный выбор.
    Так вот некоторые действительные примеры формата: dd-MM-yyyy; MM/dd/yyyy; yyyy MM dd; ddMMyyyyИ т.д.
    И это лишь некоторые примеры недопустимого формата: dd MMM yyyy; dd-MM-'yy; и т.п.
  • Вы также можете просто ввести объект Date, если ваш язык поддерживает его, или три отдельных целочисленных параметра вместо строки, представляющей дату.
  • Пожалуйста, укажите, какой формат даты вы использовали! (И вход, и выход должны быть в одном и том же формате.) Также разрешено выводить объект Date, при условии, что он может обрабатывать все тестовые случаи и приведенное ниже правило вызова.
  • Переход от юлианского к григорианскому календарю в этом вызове игнорируется. Так что 1582это просто действительный перевернутый год для 2851.
    См. Информацию о вызовах / советы для всех действительных лет, месяцев и дней.
  • Поскольку вы не можете иметь февраль как противоположный любому другому месяцу, вам не нужно беспокоиться о високосных годах.

Все обратные годы, месяцы и дни:

  • Год всегда можно без проблем поменять местами , начиная с 0001 (перевернутый 1000) до 9999 (остаётся 9999). ( 0000Это неверный ввод, и для него также нет тестов).
  • Единственные месяцы, которые вы изменили, это: январь (в обратном порядке с октября / 10); Октябрь (в обратном порядке с января / 01); Ноябрь (остается ноябрь / 11); и декабрь (в обратном порядке через месяц / 02- 09, 12).
  • Единственные дни, которые вы изменили: 01 (обратный от 10), 02 (обратный от 20), 03 (обратный от 30), 10 (обратный от 01), 11 (остающийся 11), 12 (обратный от 21), 13 (обратный от 31) , 20 (перевернуто с 02), 21 (перевернуто с 12), 22 (осталось 22), 30 (перевернуто с 03или аналогично 31 за ноябрь!), 31 (перевернуто с 04- 09/ 13-19/ 23- 29).

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте придумать как можно более короткий ответ для «любого» языка программирования.
  • К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с соответствующими параметрами и оператором возврата / вывода, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода.
  • Также, пожалуйста, добавьте объяснение, если это необходимо.

Тестовые случаи ( dd-MM-yyyyкак формат):

21-07-2016   ->   12-12-6102
12-11-1991   ->   21-11-1991
01-01-2000   ->   10-10-0002
27-08-1875   ->   31-12-5781
18-12-2010   ->   31-12-0102
13-01-1981   ->   31-10-1891
04-11-1671   ->   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   ->   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   ->   31-12-5581
30-10-9999   ->   03-01-9999
01-01-2851   ->   10-10-1582
Кевин Круйссен
источник
@ LegionMammal978 Нет, 21-07-2016возвращается, 12-70-6102округляется до 12-12-6102. Не уверен, как вы получите результат ##-10-6107..
Кевин Круйссен
@KevinCruijssen Хорошо, я думал, что это был месяц 70, с возрастом.
LegionMammal978
Является ли 10-10-2действительный вывод в третьем случае?
Луис Мендо
@ LuisMendo Да, конечно. Я видел, как другие тоже это делают. Сложность заключается скорее в правильном реверсировании и округлении дат, чем в формате ввода или вывода.
Кевин Круйссен
Было бы приемлемо взять три строки и ожидать лидирующие нули?
JustinM - Восстановить Монику

Ответы:

3

Выпуклый , 23 байта

Подсчет байтов предполагает кодирование CP-1252.

qS/Wf%_1=:=31^sCs¶.e<S*

Формат ввода / вывода есть dd mm yyyy.

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

Это прямой порт моего ответа CJam . Convex в значительной степени основан на CJam, и поэтому единственным отличием является использование оператора Convex, который упаковывает два верхних элемента стека в список, сохраняя байты [...].

Мартин Эндер
источник
8

CJam, 24 байта

qS/Wf%[_1=:=31^sCs].e<S*

Формат ввода / вывода есть dd mm yyyy.

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

Одинаковое количество байтов, формат ввода / вывода mm dd yyyy:

qS/Wf%_0=:=1231^s2/.e<S*

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

объяснение

qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e<     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.

Другая версия работает аналогично, за исключением того, что мы начинаем с целого числа 1230или 1231перед преобразованием его в ["12" "30"] или ["12" "31"].

Мартин Эндер
источник
2
Языки со встроенной датой ...
Leaky Nun
1
@LeakyNun Это не использует встроенную дату, и я не вижу, как это поможет.
Мартин Эндер
Тогда откуда ты знаешь, что в ноябре 30 дней?
Утренняя монахиня
2
@LeakyNun Я добавлю объяснение позже, но получу 1=перевернутый месяц, проверим, :=равны ли его цифры, и ^сожжет результат в 31, получив 30 для месяца 11и 31 для всего остального.
Мартин Эндер
О, я не читал спецификации ...
Дрянная Монахиня
5

Pyth, 55 53 46 43 41 байт

APJ_Mczd = HhS, 12sH = GhS, sGC @. "❤❤ó» î "H%"% 02d% 02d% s "[GHeJ 
APJ_Mczd = hS, 12sH = hS, sGC @." »Ó »î" H% "% 02d% 02d% s" [GHeJ 
APJ_Mcz \ -% "% 02d% 02d% s" [hS, sGx31q11sHhS, 12sHeJ 
APJ_Mczdjd [> 2+ \ 0hS, sGx31q11sH> 2+ \ 0hS, 12sHeJ
APJ_Mczdjd. [L \ 02 [ `hŠ, sGx31q11sH`hS, 12sHeJ

где ❤❤были два непечатаемых, соответственно U + 001C и U + 001F.

Тестирование.

Дрянная Монахиня
источник
3

Python 3, 82 байта

lambda x:[min(x[0][::-1],['31','30'][x[1]=='11']),min(x[1][::-1],'12'),x[2][::-1]]

Анонимная функция, которая принимает через аргумент ввод даты в виде списка строк формы ['dd', 'mm', 'yyyy']и возвращает проверенную обратную дату в том же формате.

Как это устроено

Python сравнивает символы и строки по их кодам Unicode. Это означает, что любое сравнение двух или более целых чисел возвращает то же самое сравнение с этими целыми числами как строки. Следовательно, вызов minдвух целых чисел в виде строк возвращает наименьшее целое число в виде строки; принимая перевернутую часть даты в качестве одного аргумента и максимальное значение в качестве другого, день и месяц ограничиваются требуемым диапазоном. Части даты переворачиваются с помощью индексации с помощью шагов -1( [::-1]), и максимальное значение для месяца изменяется с '31'на, '30'если месяц является ноябрьским, путем индексации в список с логическим результатом условия.

Попробуйте это на Ideone

TheBikingViking
источник
2

Дьялог АПЛ , 32 33 байта

⍕¨{⍵-3↑31 11≡2↑⍵}31 12 1E4⌊⍎∊⍕⌽¨⎕

Ввод / вывод - это список из трех строк ( 'dd' 'mm' 'yyyy').

ПопробуйтеAPAPL , но обратите внимание, что (запрос на ввод) был заменен на, а вся строка заключена в {..., }чтобы включить онлайн-тестирование, и (выполнить выражение) была заменена на 2⊃⎕VFI(проверить и исправить ввод), потому что выполнение произвольного кода заблокировано ,

Адам
источник
2

C # 314 305 299 249 232 223 байта

using System.Linq;string f(int d,int m,int y){Func<int,string>r=i=>string.Concat((""+i).PadLeft(2,'0').Reverse());Func<string,int,string>x=(j,k)=>int.Parse(j)>k?""+k:j;return x(r(d),m==11?30:31)+"-"+x(r(m),12)+"-"+r(y);}

Спасибо @KevinCruijssen за указание на то, что я могу сократить объявление переменной, что также позволило псевдонимам строки сохранять некоторые байты.

Сохранено 50 байтов, в которых хранится функция реверсирования для повторного использования, и еще 13, выполнив то же самое для округления и удаления объявлений переменных.

Последнее обновление делает псевдоним строки больше не заставкой байтов.

Безголовая версия:

using System.Linq;
    string dateReverse(int day, int month, int year)
{
    //setup a resuable function to reverse
    Func<int, string> reverse = intToReverse => string.Concat((""+intToReverse).PadLeft(2, '0').Reverse());

    //another function for rounding
    Func<string, int, string> round = (strToRound, maxVal) => int.Parse(strToRound) > maxVal ? "" + maxVal : strToRound;

    //Join the strings into the "dd-mm-yyyy" date format
    return 
        //Round down the day value, if november cap to 30 otherwise cap to 31
        round(reverse(day), month == 11 ? 30 : 31) + "-" +

        //Round the month down
        round(reverse(month), 12) + "-" +

        //we can use the reverse function here too and pad left just won't do anything
        reverse(year);
}

Проверьте это здесь

Джастин М - Восстановить Монику
источник
Вы можете игнорировать пробел между using System.Linq;и функцией, так что это -1 байт. Кроме того, var n=...;var e=...;можно использовать 1 байт, используя это вместо этого: string n=...,e=...;это не так много, но все равно -2 байта. ;)
Кевин Круйссен
Хороший улов на этом месте, хотя, похоже, мой счетчик байтов на самом деле не учитывал его, так что я просто засорю его до проблемы копирования-вставки. Кроме того, я думаю, что с помощью этого стиля объявления переменных я смогу выиграть еще несколько байтов с помощью псевдонима строки.
JustinM - Восстановить Монику
2

Javascript, 106 105 94 байтов

d=>d.split`,`.map((a,b,r)=>(e=[...a].reverse().join``,f=!b?r[1]==11^31:b<2&&12,f&&f<e?f:e))+''

Тестовый пакет (ред. 3)


объяснение

d=>d.split`,`                 // split into sections by `,`

.map((a,b,r)=>(               // map each section

e=[...a].reverse().join``,    // spread a date section into array and reverse and 
                              // join with `` to get string result

f=!b?r[1]==11^31              // if section being mapped is day (section 0), 
                              // then max (f) is 30 for November(month 11) or else 31

:b<2&&12,                     // if part being mapped is month (section 1), then max (f) is 12

f&&f<e?f:e))                  // if there is a max (f)
                              // and the max (f) is less than the reversed string (e),
                              // then return the max (f), 
                              // else return the reversed string (e)

+''                           // join all the sections back together with `,` 
                              // (concatenating [] with a string will do this)

Благодаря @KevinCruijssen для экономии 1 байт для b==1к b<2. Спасибо @Neil за сохранение 11 байтов, предложив шаблонный литерал ES6 и ,разделитель.

CShark
источник
Я плохо b==1разбираюсь в JS, так что поправьте меня, если я скажу что-то не так, но не могу проиграть, b<2чтобы сэкономить байт? Это больше не может быть 0, так как вы уже проверили это в !b?части кода. Кажется, он работает в вашем тестовом наборе, когда я его меняю.
Кевин Круйссен,
@KevinCruijssen Да, ты прав, спасибо! Я просто упустил это. Я не занимался гольфом в javascript из-за внешнего вида, поэтому иногда скучаю по таким вещам
CShark
* Я имел в виду «очень долго», а не «очень внешне»
CShark
2
Поскольку вы ориентируетесь на ES6, вы можете использовать строки шаблона для сокращения кода - join``вместо, join('')например - но вы можете сэкономить немного больше, используя в ,качестве разделителя, который позволяет вам +''объединять три значения вместе.
Нил
@ Нет, вы имеете ,в виду в качестве разделителя на входе?
CShark
1

Ruby, 92 84 + 1 ( -pфлаг) = 93 85 байт

Используется -как разделитель.

d,m,y=chomp.split(?-).map &:reverse
$_=[[d,m=="11"?"30":"31"].min,[m,"12"].min,y]*?-
Значение чернил
источник
0

Python 2, 154 байта

z=input().split("-");r=[x[::-1]for x in z];z[1]=r[1]if r[1]<'12'else '12';z[0]=r[0]if r[0]<'31'else '30'if z[1]=='11'else '31';z[2]=r[2];print "-".join(z)

Принимает входные данные в виде строки, поэтому во входных данных необходимо указывать кавычки, например, «11-04-2016».

Джереми
источник
Просто базовое улучшение, так как я не игрок в Python z=[x[::-1]for x in z];z[1]=min(z[1],'12');z[0]=min(z[0],['31','30'][z[1]=='11']);print"-".join(z). По сути, вам вообще не нужно его использовать r, и вы minвыполняете много вещей, которые вы хотите сделать.
Value Ink
0

05AB1E , 24 байта

#íÐÅsË31^12‚øεßт+¦}sθªðý

Порт ответа CJam от @MartinEnder , а также ввод и вывод в виде строки в форматеdd MM yyyy .

Попробуйте онлайн или проверьте все тесты .

Объяснение:

#                         # Split the (implicit) input by spaces
                          #  i.e. "04 11 1671" → ["04","11","1671"]
                          #  i.e. "20 01 2000" → ["20","01","2000"]
 í                        # Reverse each string
                          #  i.e. ["04","11","1671"] → ["40","11","1761"]
                          #  i.e. ["20","01","2000"] → ["02","10","0002"]
  Ð                       # Triplicate this list
   Ås                     # Pop one of them, and push it's middle element (the months)
                          #  i.e. ["40","11","1761"] → "11"
                          #  i.e. ["02","10","0002"] → "10"
     Ë                    # Check if the digits are the same (1 for 11; 0 otherwise)
                          #  i.e. "11" → 1 (truthy)
                          #  i.e. "10" → 0 (falsey)
      31^                 # Bitwise-XOR with 31 (30 for November, 31 for other months)
                          #  i.e. 1 → 30
                          #  i.e. 0 → 31
         12              # Pair it with 12
                          #  i.e. 30 → [30,12]
                          #  i.e. 31 → [31,12]
            ø             # Zip/transpose; swapping rows and columns
                          # (implicitly removes year)
                          #  i.e. ["40","11","1761"] and [30,12] → [["40",30],["11",12]]
                          #  i.e. ["02","10","0002"] and [31,12] → [["02",31],["10",12]]
             ε    }       # Map each pair to:
              ß           # Get the minimum (implicitly converts to integer unfortunately)
                          #  i.e. [["40",30],["11",12]] → [30,11]
                          #  i.e. [["02",31],["10",12]] → [2,10]
               т+         # Add 100
                          #  i.e. [30,11] → [130,111]
                          #  i.e. [2,10] → [102,110]
                 ¦        # Remove the first character
                          #  i.e. [130,111] → ["30","11"]
                          #  i.e. [102,110] → ["02","10"]
                   s      # Swap so the triplicated list is at the top of the stack again
                    θ     # Pop and only leave it's last element (the year)
                          #  i.e. ["40","11","1761"] → "1761"
                          #  i.e. ["02","10","0002"] → "0002"
                     ª    # Append it to the list
                          #  i.e. ["30","11"] and "1761" → ["30","11","1761"]
                          #  i.e. ["02","10"] and "0002" → ["02","10","0002"]
                      ðý  # Join the list by spaces (and output implicitly)
                          #  i.e. ["30","11","1761"] → "30 11 1761"
                          #  i.e. ["02","10","0002"] → "02 10 0002"
Кевин Круйссен
источник