Что это за формат даты?

11

Для григорианских календарей формат даты варьируется от страны к стране. Существует три основных формата:

  1. YY-MM-DD (Большой обратный порядок байт)
  2. DD-MM-YY (Прямой порядок байтов)
  3. MM-DD-YY (Средний порядок байт)

Ваша задача - написать программу, которая с учетом входной строки, представляющей дату, выведет все возможные форматы даты, по которым эту строку можно интерпретировать как дату.

правила

  • Дата ввода указывается в формате xx-xx-xx, где каждое поле состоит из двух цифр и дополняется нулями.
  • Дата всегда действительна (поэтому вы не можете получить такие вещи, как 14-13-17)
  • Дата всегда соответствует как минимум одному из указанных выше форматов (поэтому вы не можете получить такие вещи, как 17-14-11)
  • Поскольку мы на самом деле в параллельном мире, на каждый месяц года выделяется 31 день , и, следовательно, нет високосных лет.
  • Дата между 1 января 2001 г. и 31 декабря 2099 г.
  • Если для даты существует только один формат, код должен печатать только ее (разрешены только конечные переводы строки)
  • Если для даты существует несколько форматов, они должны быть разделены запятой, пробелом, символом новой строки или их комбинацией.
  • Вы должны вывести точное название (я) формата (ов). Использование разных произвольных значений не допускается.
  • Не допускаются начальные или конечные символы, кроме пробела
  • Вывод должен быть строчным
  • Вам не разрешено использовать какие-либо встроенные функции даты или календаря
  • Выходные форматы не должны быть отсортированы

Примеры

Input      Output
30-05-17   big-endian, little-endian
05-15-11   middle-endian
99-01-02   big-endian
12-11-31   big-endian, little-endian, middle-endian
02-31-33   middle-endian

Это поэтому выигрывает самый короткий код в байтах. Пояснения приветствуются.

Джим
источник
3
Вероятно, вам следует добавить тестовый пример, используя 31 февраля, чтобы убедиться, что ответы поддерживают этот странный случай: P
ETHproductions
Можем ли мы вывести три разных значения для трех допустимых форматов или это должны быть три точные строки?
ETHproductions
3
there are 31 days for every month of the year, and consequently no leap yearsТаким образом, это означает, что любая библиотека дат фактически бесполезна для этого?
TheLethalCoder
1
@TheLethalCoder Да, большинство библиотек дат, вероятно, непригодны для использования.
Джим
1
Есть много других форматов .
Угорен

Ответы:

3

05AB1E , 40 байт

'-¡©2£13‹`®Á2£32‹*)˜“Œ±„¥„ê“#Ï’-„–ian’«»

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

объяснение

'-¡©                                      # split on "-" and store a copy in register
    2£13‹                                 # compare the first 2 elements to 13
         `                                # split as separate to stack
                                          # the bottom element is true if it is middle endian
                                          # the top value is true if it can be big/little
          ®Á                              # retrieve the list from register and rotate right
            2£32‹                         # compare the first 2 elements to 32
                 *                        # multiply with the result of the comparison to 13
                  )˜                      # wrap in a flattened list
                    “Œ±„¥„ê“#             # push the list ['middle', 'big', 'little']
                             Ï            # index into this with the flattened list
                                          # this leaves the types the date could be
                              ’-„–ian’«   # append "-endian" to each
                                       »  # join on newlines
Emigna
источник
4

Python 2 , 123 байта

a,b,c=map(int,input().split('-'))
for a,b,c in[[b,c,'big'],[b,a,'little'],[a,b,'middle']]:print(c+'-endian')*(a<13)*(b<32),

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


Python 2 , меньше разбор ввода, 123 байта

d=input()
for a,b,c in[[3,6,'big'],[3,0,'little'],[0,3,'middle']]:print(c+'-endian')*(int(d[a:a+2])<13)*(int(d[b:b+2])<32),

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

овс
источник
Вам разрешено расставаться с символами новой строки, поэтому вы можете удалить трейлинг ,.
Джонатан Аллан
4

JavaScript (ES6), 121 119 118 112 байт

Возвращает разделенную пробелами строку с завершающим пробелом.

s=>['big','little','middle'].map((v,i)=>[b<13&c<32,b<13&a<32,a<13][i]?v+'-endian ':'',[a,b,c]=s.split`-`).join``

Как?

Разобьем входные данные на a , b и c . Поскольку дата гарантированно является действительной, мы точно знаем, что b меньше 32. Поэтому достаточно проверить, меньше ли a, чем 13, чтобы проверить формат среднего порядка байтов. Для форматов с прямым порядком байтов и байтов с обратным порядком байтов b должно быть меньше 13, а для проверки дня - еще один тест для a и c соответственно.

Отсюда 3 теста:

  • Big-endian: b <13 & c <32
  • Little-endian: b <13 & a <32
  • Middle-endian: <13

Контрольные примеры

Arnauld
источник
3

Баш, 240 125 116 112 байт

IFS=- read a b c<<<$1
d=-endian
((b<13))&&(((a<32))&&echo little$d;((c<32))&&echo big$d);((a<13))&&echo middle$d

Golfed.

Спасибо manatwork за несколько советов

Сохранено 9 байт, удаляющих проверку менее 32 в ответе Арнольда

Сохранено 4 байта с использованием различных переменных вместо массива

Попробуй это!

DrnglVrgs
источник
Есть несколько арифметических связанных советы в Советы для игры в гольф в Bash . Вы можете немного уменьшить его: попробуйте онлайн!
manatwork
Спасибо @manatwork, у меня есть этот вопрос, отмеченный закладкой, очень полезный, будет ли это
удачным решением
1

C #, 180 байт

t=(n,m)=>int.Parse(n)<13&int.Parse(m)<32;s=>{var a=s.Split('-');return$"{(t(a[1],a[2])?"big-endian":"")} {(t(a[1],a[0])?"little-endian":"")} {(t(a[0],a[1])?"middle-endian":"")}";};

Выходы с только значениями, разделенными пробелами, также могут иметь начальные и конечные пробелы. Обновится, когда ОП уточнит этот момент, если это необходимо.

Полная / Отформатированная версия:

Func<string, string, bool> t = (n, m) => int.Parse(n) < 13 & int.Parse(m) < 32;

Func<string, string> f = s =>
{
    var a = s.Split('-');

    return $"{(t(a[1], a[2]) ? "big-endian" : "")} {(t(a[1], a[0]) ? "little-endian" : "")} {(t(a[0], a[1]) ? "middle-endian" : "")}";
};
TheLethalCoder
источник
Я сделал правило более ясным:No leading or trailing characters others than a trailing space are allowed
Джим
1

PHP, 151 байт

[$a,$b,$c]=sscanf($argn,"%d-%d-%d");$z="-endian ";echo($m=$b&&$b<13)&&$c&&$c<32?big.$z:"",$m&&$a&&$a<32?little.$z:"",$a&&$a<13&&$b&&$b<32?middle.$z:"";

Testcases

Йорг Хюльсерманн
источник
1

Пакет, 138 байт

@echo off
set/ps=
call:l little %s:-= %
exit/b
:l
call:e big %4 %3
call:e middle %3 %2
:e
if %2 leq 31 if %3 leq 12 echo %1-endian

Смутно, основываясь на ответе @ ovs.

Нил
источник
1

Java 232 байта

(String s)=>{String[]i=s.split("-");String e="-endian",b="big"+e,m="middle"+e,l="little"+e;int p=Integer.valueOf(i[0]);System.out.print(p<13?Integer.valueOf(i[1])<13?Integer.valueOf(i[2])<32?b+","+m+","+l:m+","+l:m:p<32?b+","+l:b);}

Вот более хорошая версия

String[] i = s.split("-");

String e = "-endian",
       b = "big" + e,
       m = "middle" + e,
       l = "little" + e;

int p = Integer.valueOf(i[0]);

Я действительно не знал, как отформатировать эту часть ...

System.out.print(
        p < 13 ? Integer.valueOf(I[1]) < 13 ? Integer.valueOf(I[2]) < 32 ? b + "," + m + "," + l
                                                                         : m + "," + l
                                            : m 

               : p < 32 ? b + "," + l 
                        : b
);
cheemcheem
источник
1
Слишком много порядков String e="-endian",b="big"+e,m="middle"+e,l="little"+e;.
manatwork
Хороший момент, когда я решил не делать этого, я включил дополнительную строку «String» в свой счетчик байтов. @manatwork
cheemcheem
1

PHP, 131 байт

[$a,$b,$c]=explode('-',$argn);foreach([[big,b,c],[little,b,a],[middle,a,b]]as[$t,$x,$y])echo$$x*$$y&&$$x<13&$$y<32?"$t-endian ":"";
user63956
источник