15
\$\begingroup\$

The Discordian calendar is an alternative calendar used by Discordians.

  1. The discordian year has 5 seasons, each lasting 73 days: Chaos, Discord, Confusion, Bureaucracy, and The Aftermath.
  2. The discordian week has 5 days: Sweetmorn, Boomtime, Pungenday, Prickle-Prickle, and Setting Orange. Every year begins with Sweetmorn (and in Chaos).
  3. Every fourth year (which happens to align with Gregorian leap years), an extra day is inserted between Chaos 59 and Chaos 60 called St. Tib's Day. It is outside of the Discordian week, meaning the day after St. Tib's Day will be Setting Orange, the day before Prickle-Prickle.
  4. The Gregorian and Discordian calendars line up; both start on the same day, which is called January 1st in the Gregorian calendar, and Chaos 1 in the Discordian one.
  5. The first Year of Our Lady of Discord (YOLD 1) was 1166 BC in the Gregorian calendar, meaning this year (2017 AD) is YOLD 3183.
  6. The Discordian calendar also has holidays, but they are not important for this challenge and you should not output them or anything about them.

Write a program or function that outputs or returns today's date (at the time of execution):

Today is Boomtime, the 16th day of Confusion in the YOLD 3183

The format is "Today is $day_of_the_week, the $ordinal day of $season in the YOLD $year", where $day_of_the_week is the capitalized (title-case) day of the week, $ordinal is the day of the season as an ordinal (1st, 2nd, 3rd, 4th, ...), $season is the capitalized (title-case) season, and $year is the year.

If your program or function is executed on St. Tib's Day, it should instead output or return "Today is St. Tib's Day in the YOLD $year".

Rules:

  • Standard loopholes apply.
  • If your language of choice has no way of getting the current date, it may also take the current Gregorian date in any reasonable format as input.
  • This is , the shortest code (per language) wins.
  • Trailing whitespace is okay.
  • Capitalization matters.
  • Calling ddate in any way is banned
  • Your program should be guaranteed to work from 3067 to 3265 YOLD (1901 to 2099 AD), outside that range it can give incorrect values

See also:

\$\endgroup\$
  • 4
    \$\begingroup\$ discord is a cool instant messaging client \$\endgroup\$ – Okx Jun 11 '17 at 8:14
  • 1
    \$\begingroup\$ I think today is 16th day of Confusion? What date does the example represent? \$\endgroup\$ – user202729 Jun 11 '17 at 8:36
  • 2
    \$\begingroup\$ unrelated \$\endgroup\$ – Jonathan Allan Jun 11 '17 at 8:36
  • 1
    \$\begingroup\$ @user202729 Yes, the date in the example is from when I originally wrote the challenge, I will update it to show today's date, which is indeed the 16th day of Confusion. \$\endgroup\$ – L3viathan Jun 11 '17 at 8:47
  • 1
    \$\begingroup\$ @L3viathan in that case (for those using a language with large native type) can you clarify a) how to handle turn of the century years that aren't leap years in the gregorian cal as "every 4th year" of the discordian cal contradicts with "aligns with the gregorian" b) how to handle years before introduction of the gregorian cal. I was suggesting the max range which is properly defined by your current spec. If you reject this, you should define what the program should do outside that range. Also you should avoid invalidating the existing answer. en.wikipedia.org/wiki/Gregorian_calendar \$\endgroup\$ – Level River St Jun 11 '17 at 11:53
5
\$\begingroup\$

Mathematica, 403 401 bytes

Version to count number of bytes: (removed spaces and newlines - unfortunately this part is quite hard)

"Setting Orange"["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle"][[#~Mod~5]]<>", the "<>SpokenString@p[[Mod[#,73,1]]]~StringExtract~2<>" day of "<>{"Chaos","Discord","Confusion","Bureaucracy","The Aftermath"}[[⌈#/73⌉]]&;
Row@{"Today is ",#2," in the YOLD ",1166+#}&[#,If[4∣#,If[#2>60,%[#2-1],If[#2<60,%@#2,"St.Tib's Day"]],%@#2]]&@@FromDigits/@DateString@"ISOOrdinalDate"~StringSplit~"-"

Version to read:

"Setting Orange"["Sweetmorn", "Boomtime", "Pungenday", 
     "Prickle-Prickle"][[#~Mod~5]] <>
   ", the " <>
   SpokenString@p[[Mod[#, 73, 1]]]~StringExtract~2 <>
   " day of " <>
   {"Chaos", "Discord", "Confusion", "Bureaucracy", 
     "The Aftermath"}[[Ceiling[#/73]]] &;
Row@{
      "Today is ",
      #2,
      " in the YOLD ",
      1166 + #
      } &[#,
   If[4 ∣ #,
    If[#2 > 60, %[#2 - 1],
     If[#2 < 60, %@#2, "St.Tib's Day"]
     ], %@#2
    ]] & @@ FromDigits /@ DateString@"ISOOrdinalDate"~StringSplit~"-"

The answer can be tested with arbitrary date by replacing DateString@"ISOOrdinalDate" by DateString[{year,month,day},"ISOOrdinalDate"] for year, month and day replaced by numbers.

\$\endgroup\$
  • \$\begingroup\$ How can I test Mathematica code? \$\endgroup\$ – L3viathan Jun 11 '17 at 9:23
  • 6
    \$\begingroup\$ "Wot no builtin?" \$\endgroup\$ – Jonathan Allan Jun 11 '17 at 10:02
4
\$\begingroup\$

Python 2, 423 Bytes

Short version:

import time
y,d=time.gmtime()[0::7]
t="Today is "
o=" in the YOLD "+`y+1166`
if y%4<1 and d>59:
 if d==60:print"%sSt. Tib's Day%s%d"%(t,o);quit()
 d-=1
s,e=divmod(d-1,73)
print t+["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"][(d-1)%5]+", the %d%s day of %s"%(e+1,'tsnrthtddh'[min(e*(e/10-1 and 1)%10,4)::5],["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"][s]+o)

Longer, more readable form:

import time

# now = time.strptime("2017.06.11", "%Y.%m.%d")  # for testing
now = time.gmtime()
year, day_of_year = now[0::7]
leapyear = year % 4 < 1
today = "Today is "
yold = " in the YOLD " + `y+1166`

if leapyear and day_of_year>59:
    if day_of_year==60:
        print "%sSt. Tib's Day%s%d"% (today, yold)
        quit()  # dirty, but ... hey.
    day_of_year -= 1
season, day = divmod(day_of_year-1,73)

print today + \
    ["Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"][(day_of_year-1)%5] + \
    ", the %d%s day of %s" % (
        day+1,
        'tsnrthtddh'[min(day*(day/10-1 and 1)%10,4)::5],
        ["Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"][season] + yold
    )

Update: Fixed with help of the great @Neil and @EriktheOutgolfer. But @Jonathans answer is way shorter.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome on Programming Puzzles & Code Golf! \$\endgroup\$ – Dada Jun 11 '17 at 15:41
  • 3
    \$\begingroup\$ Does this produce the right suffix for 21st, 22nd, 23rd...73rd? @L3viathan y%4<1 would work, but I don't think 1-y%4 would. \$\endgroup\$ – Neil Jun 11 '17 at 17:57
  • 1
    \$\begingroup\$ 44-byte trivial golf. \$\endgroup\$ – Erik the Outgolfer Jun 11 '17 at 18:49
  • \$\begingroup\$ @EriktheOutgolfer Can't you save another 4 bytes by eliminating the e variable? \$\endgroup\$ – Neil Jun 11 '17 at 19:31
  • \$\begingroup\$ Welcome to PPCG! Nice first post. I was planning to give you a bit off here and there, but noticed and fixed the suffix problem and golfed the code more than I thought I would so I ended up submitting my own version. \$\endgroup\$ – Jonathan Allan Jun 12 '17 at 1:25
2
\$\begingroup\$

Python 2, 346 bytes

Note: This is a golf (and fix) of jammon's answer - I originally thought I'd submit a comment, but I changed quite a bit in the end (plus the day-suffixes have been fixed).

import time
y,d=time.gmtime()[::7]
t="Today is %s in the YOLD "+`y+1166`
r=y%4<1<59<d
d-=r+1
e=d%73
print t%[["Sweetmorn","Boomtime","Pungenday","Prickle-Prickle","Setting Orange"][d%5]+", the %d%s day of "%(e+1,'snrttddh'[min(e%10+3*(e/9==1),3)::4])+["Chaos","Discord","Confusion","Bureaucracy","The Aftermath"][d/73],"St. Tib's Day"][(r*d)==58]

Try it online! or see some hard-coded test dates.

\$\endgroup\$
  • \$\begingroup\$ I don't suppose e%10*(e/9!=1) works? \$\endgroup\$ – Neil Jun 12 '17 at 8:00
  • \$\begingroup\$ Nope, then it would print 11st, 12st and 13st (when e/9 is 1 it would multiply by zero and the min would pick that zero) \$\endgroup\$ – Jonathan Allan Jun 12 '17 at 8:05
2
\$\begingroup\$

JavaScript (ES6), 387 380 bytes

f=(d=new Date(),a=d.getDate()-1,y=d.getFullYear()+1166)=>d.getMonth()?f(d,a+d.getDate(d.setDate(0))):`Today is ${y%4-2|a<59||59-a--?`Sweetmorn,Boomtime,Pungenday,Prickle-Prickle,Setting Orange`.split`,`[a%5]+`, the ${d=a%73+1}${[,`st`,`nd`,`rd`][d-10-(d%=10)&&d]||`th`} day of `+`Chaos,Discord,Confusion,Bureaucracy,The Aftermath`.split`,`[a/73|0]:`St. Tib's Day`} in the YOLD `+y

Takes an optional date parameter. Ungolfed:

function discordian(date) {
    var a = date.getDate();
    while (date.getMonth()) {
        date.setDate(0);
        a += date.getDate();
    }
    if (date.getYear() % 4 == 0) {
        if (a == 60) return "Today is St. Tib's day in the YOLD " + (date.getYear() + 1166);
        if (a > 60) a--;
    }
    var weekday = ['Setting Orange', 'Sweetmorn', 'Boomtime', 'Pungenday', 'Prickle-Prickle'][a % 5];
    var seasonday = (a - 1) % 73 + 1;
    var ordinal = seasonday % 10 == 1 && seasonday != 11 ? 'st' : seasonday % 10 == 2 && seasonday != '12' : 'nd' : seasonday % 10 == 3 && seasonday != '13' ? 'rd' : 'th';
    var season = ['Chaos', 'Discord', 'Confusion', 'Bureaucracy', 'The Aftermath'][Math.floor((a - 1) / 73)];
    return "Today is " + weekday + ", the " + seasonday + ordinal + " day of " + season + " in the YOLD " + (date.getYear() + 1166);
}
\$\endgroup\$
1
\$\begingroup\$

C#, 392 bytes

using System;s=>{var t=DateTime.Now;int d=t.DayOfYear,y=t.Year,m=d%73;return"Today is "+(DateTime.IsLeapYear(y)&d==60?"St. Tib's Day":"Sweetmorn|Boomtime|Pungenday|Prickle-Prickle|Setting Orange".Split('|')[d%5-1]+", the "+ m+(m<2|m==21|m>30?"st":m==2|m==22?"nd":m==3|m==23?"rd":"th")+" day of "+"Chaos|Discord|Confusion|Bureaucracy|The Aftermath".Split('|')[d/73])+" in the YOLD "+(y+1166);}

Full/Formatted version:

using System;

class P
{
    static void Main()
    {
        Func<string, string> f = s =>
        {
            var t = DateTime.Now;
            int d = t.DayOfYear, y = t.Year, m = d % 73;

            return "Today is " + (DateTime.IsLeapYear(y) & d == 60
                   ? "St. Tib's Day"
                   : "Sweetmorn|Boomtime|Pungenday|Prickle-Prickle|Setting Orange".Split('|')[d % 5 - 1] +
                     ", the " +
                     m +
                     (m < 2 | m == 21 | m > 30 ? "st" : m == 2 | m == 22 ? "nd" : m == 3 | m == 23 ? "rd" : "th") +
                     " day of " +
                     "Chaos|Discord|Confusion|Bureaucracy|The Aftermath".Split('|')[d / 73])
                   + " in the YOLD " + (y + 1166);
        };

        Console.WriteLine(f(null));

        Console.ReadLine();
    }
}
\$\endgroup\$
1
\$\begingroup\$

Pyth, 295 bytes

J.d2A<J2Kt+s<+,31 28*2t*3,30 31tH@J2=Y&&!%G4<58K!qH3=N%K73%"Today is %s in the YOLD %d",@,++@c"SweetmornZBoomtimeZPungendayZPrickle-PrickleZSetting Orange"\Z%K5%", the %d%s day of ",+N1@c"stndrdth"2h.mb,3+%NT*3q1/N9@c." yNlSFk.»&ô?Z#u!%ô6'mçM«_ôvëû¹)+¬<"\Z/K73"St. Tib's Day"q*YK59+G1166

Note: contains binary, may not be safe to copy-paste from here. Copy-pasting from TIO should work.

Try it online!

You can test arbitrary dates by replacing .d2 at the start with a 3-tuple of (year, month, day) like this: (2020 2 29).

This one was a bit annoying since Pyth doesn't have any way to get "day of year" so I had to compute it myself.

\$\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.