10
\$\begingroup\$

For Gregorian calendars, the date format varies from a country to another. There are three main formats recognized:

  1. YY-MM-DD (big-endian)
  2. DD-MM-YY (little-endian)
  3. MM-DD-YY (middle-endian)

Your task is to write a program which, given an input string representing a date, output all the possible date formats by which this string can be interpreted as a date.

Rules

  • The input date is in the format xx-xx-xx, where each field is two digits and zero-padded.
  • The date is always valid (so you cannot get things like 14-13-17)
  • The date is always at least one of the formats above (so you cannot get things like 17-14-11)
  • Because we are in fact in a parallel world, there are 31 days for every month of the year, and consequently no leap years
  • The date is between January 01, 2001 and December 31, 2099
  • If there is only one format for the date, the code must print only it (only trailing newlines are allowed)
  • If there are several formats for the date, they must be either separated by a comma, a space, a newline, or a combination of those
  • You must output the exact name(s) of the format(s). Using distinct arbitrary values is not allowed.
  • No leading or trailing characters others than a trailing space are allowed
  • The output must be lowercase
  • You are not allowed to use any built-in date or calendar functions
  • The output formats do not have to be sorted

Examples

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

This is so the shortest code in bytes wins. Explanations are encouraged.

\$\endgroup\$
  • 3
    \$\begingroup\$ You should probably add a test-case using February 31st to make sure answers support that weird case :P \$\endgroup\$ – ETHproductions May 30 '17 at 15:36
  • \$\begingroup\$ Can we output any three distinct values for the three valid formats, or must it be those three exact strings? \$\endgroup\$ – ETHproductions May 30 '17 at 15:48
  • 3
    \$\begingroup\$ there are 31 days for every month of the year, and consequently no leap years So this means any date library is effectively useless for this then? \$\endgroup\$ – TheLethalCoder May 30 '17 at 15:53
  • 1
    \$\begingroup\$ @TheLethalCoder Yes, most date libraries are probably unusable. \$\endgroup\$ – Jim May 30 '17 at 15:59
  • 1
    \$\begingroup\$ There are many more formats out there. \$\endgroup\$ – ugoren May 30 '17 at 21:55
3
\$\begingroup\$

05AB1E, 40 bytes

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

Try it online!

Explanation

'-¡©                                      # 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
\$\endgroup\$
4
\$\begingroup\$

Python 2, 123 bytes

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

Try it online!


Python 2, less input parsing, 123 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You're allowed to separate with newlines, so can remove the trailing ,. \$\endgroup\$ – Jonathan Allan May 31 '17 at 4:24
4
\$\begingroup\$

JavaScript (ES6), 121 119 118 112 bytes

Returns a space-delimited string with a trailing space.

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``

How?

We split the input into a, b and c. Because the date is guaranteed to be valid, we know for sure that b is less than 32. Therefore, it's enough to test whether a is less than 13 to validate the middle-endian format. Little-endian and big-endian formats require b to be less than 13 and another test on a and c respectively to validate the day.

Hence the 3 tests:

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

Test cases

let f =

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``

console.log(f("30-05-17")) // big-endian, little-endian
console.log(f("05-15-11")) // middle-endian
console.log(f("99-01-02")) // big-endian
console.log(f("12-11-31")) // big-endian, little-endian, middle-endian
console.log(f("02-31-33")) // middle-endian

\$\endgroup\$
3
\$\begingroup\$

Bash, 240 125 116 112 bytes

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.

Thanks to manatwork for some tips

Saved 9 bytes removing the verification for less than 32 in the middle-endian follwing Arnauld answer

Saved 4 bytes by using different variables instead of an array

Test it!

\$\endgroup\$
1
\$\begingroup\$

C#, 180 bytes

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":"")}";};

Outputs with only space separated values, can also have leading and trailing spaces. Will update when the OP has clarified on that point if needed.

Full/Formatted version:

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" : "")}";
};
\$\endgroup\$
  • \$\begingroup\$ I made the rule more clear: No leading or trailing characters others than a trailing space are allowed \$\endgroup\$ – Jim May 30 '17 at 18:42
1
\$\begingroup\$

PHP, 151 Bytes

[$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

\$\endgroup\$
1
\$\begingroup\$

Batch, 138 bytes

@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

Vaguely based on @ovs's answer.

\$\endgroup\$
1
\$\begingroup\$

Java 232 bytes

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

Here's a nicer version

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

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

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

I didn't really know how to format this part...

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
);
\$\endgroup\$
  • 1
    \$\begingroup\$ Too many endians: String e="-endian",b="big"+e,m="middle"+e,l="little"+e;. \$\endgroup\$ – manatwork May 30 '17 at 16:54
  • \$\begingroup\$ Good point, when I decided not to do that I was including an extra "String " in my byte count. @manatwork \$\endgroup\$ – cheemcheem May 30 '17 at 17:00
1
\$\begingroup\$

PHP, 131 bytes

[$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 ":"";
\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.