13
\$\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\$
12
  • 3
    \$\begingroup\$ You should probably add a test-case using February 31st to make sure answers support that weird case :P \$\endgroup\$ Commented May 30, 2017 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\$ Commented May 30, 2017 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\$ Commented May 30, 2017 at 15:53
  • 1
    \$\begingroup\$ @TheLethalCoder Yes, most date libraries are probably unusable. \$\endgroup\$
    – Jim
    Commented May 30, 2017 at 15:59
  • 1
    \$\begingroup\$ There are many more formats out there. \$\endgroup\$
    – ugoren
    Commented May 30, 2017 at 21:55

9 Answers 9

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\$
1
  • \$\begingroup\$ You're allowed to separate with newlines, so can remove the trailing ,. \$\endgroup\$ Commented May 31, 2017 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\$

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\$
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\$
2
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\$
1
  • \$\begingroup\$ I made the rule more clear: No leading or trailing characters others than a trailing space are allowed \$\endgroup\$
    – Jim
    Commented May 30, 2017 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\$
2
  • 1
    \$\begingroup\$ Too many endians: String e="-endian",b="big"+e,m="middle"+e,l="little"+e;. \$\endgroup\$
    – manatwork
    Commented May 30, 2017 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
    Commented May 30, 2017 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 and acknowledge you have read our privacy policy.

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