The Discordian calendar is an alternative calendar used by Discordians.
- The discordian year has 5 seasons, each lasting 73 days: Chaos, Discord, Confusion, Bureaucracy, and The Aftermath.
- The discordian week has 5 days: Sweetmorn, Boomtime, Pungenday, Prickle-Prickle, and Setting Orange. Every year begins with Sweetmorn (and in Chaos).
- 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.
- 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.
- 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.
- 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 code-golf, the shortest code (per language) wins.
- Trailing whitespace is okay.
- Capitalization matters.
- Calling
ddatein 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:
- Malaclypse The Younger. "Principia Discordia, Or How I Found Goddess And What I Did To Her When I Found Her". p. 00034
- ddate(1)
- Sandbox post for those who can see it
-
4\$\begingroup\$ discord is a cool instant messaging client \$\endgroup\$Okx– Okx2017年06月11日 08:14:22 +00:00Commented Jun 11, 2017 at 8:14
-
1\$\begingroup\$ I think today is 16th day of Confusion? What date does the example represent? \$\endgroup\$user202729– user2027292017年06月11日 08:36:12 +00:00Commented Jun 11, 2017 at 8:36
-
2\$\begingroup\$ unrelated \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月11日 08:36:54 +00:00Commented Jun 11, 2017 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– L3viathan2017年06月11日 08:47:44 +00:00Commented Jun 11, 2017 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– Level River St2017年06月11日 11:53:42 +00:00Commented Jun 11, 2017 at 11:53
6 Answers 6
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.
-
\$\begingroup\$ How can I test Mathematica code? \$\endgroup\$L3viathan– L3viathan2017年06月11日 09:23:05 +00:00Commented Jun 11, 2017 at 9:23
-
6\$\begingroup\$ "Wot no builtin?" \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月11日 10:02:44 +00:00Commented Jun 11, 2017 at 10:02
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.
-
2\$\begingroup\$ Welcome on Programming Puzzles & Code Golf! \$\endgroup\$Dada– Dada2017年06月11日 15:41:30 +00:00Commented Jun 11, 2017 at 15:41
-
3\$\begingroup\$ Does this produce the right suffix for 21st, 22nd, 23rd...73rd? @L3viathan
y%4<1would work, but I don't think1-y%4would. \$\endgroup\$Neil– Neil2017年06月11日 17:57:46 +00:00Commented Jun 11, 2017 at 17:57 -
1\$\begingroup\$ 44-byte trivial golf. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月11日 18:49:49 +00:00Commented Jun 11, 2017 at 18:49
-
\$\begingroup\$ @EriktheOutgolfer Can't you save another 4 bytes by eliminating the
evariable? \$\endgroup\$Neil– Neil2017年06月11日 19:31:11 +00:00Commented Jun 11, 2017 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– Jonathan Allan2017年06月12日 01:25:54 +00:00Commented Jun 12, 2017 at 1:25
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.
-
\$\begingroup\$ I don't suppose
e%10*(e/9!=1)works? \$\endgroup\$Neil– Neil2017年06月12日 08:00:26 +00:00Commented Jun 12, 2017 at 8:00 -
\$\begingroup\$ Nope, then it would print
11st,12stand13st(whene/9is 1 it would multiply by zero and theminwould pick that zero) \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月12日 08:05:50 +00:00Commented Jun 12, 2017 at 8:05
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);
}
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();
}
}
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ëû1)+¬<"\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.
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.