14
\$\begingroup\$

Someone gave my wife a decorative calendar consisting of four cubes. Here it is showing today's date (as of the posting of this challenge) on the front:

enter image description here

When I first saw it, I looked at it from the wrong angle (from directly above) and couldn't figure out why it gave this information:

[["February", "January"], [3], [7], ["Monday", "Tuesday"]]

Your job is to replicate my error for any date in 2019.

Challenge

Write a program or function that takes any date from 2019, and outputs what appears on the top of all the cubes when that date is displayed facing out from the front of the calendar.

Here are all six sides for all the cubes. To display a 6 you just turn the 9 upside down. The 0 is vertically symmetrical, so 0 upside down is still 0. There might be more than one correct answer for some dates (e.g. any 11th of any month will have more than one way to use the cubes, and the 0 thing) so you can output any correct answer.

enter image description here

Rules

  1. Standard loopholes forbidden.
  2. Input/output format is flexible.
  3. The output does have to be in order by cube, but not within a cube. The order must be month cube first, then the two number cubes, followed by the weekday cube. But when a cube has two elements on top, those two elements can be in either order.
  4. You can replace January to December 0-11 or 1-12 if you like.
  5. You can replace the days of the week with 0-6 or 1-7 if you like, and you can start the week on either Sunday or Monday (but you can't start the week on any other day - this is PPGC, not some sort of crazy-town.)
  6. This is . Fewest bytes for each language wins.
  7. Explanations encouraged.

Test cases

(Tue) 2019-01-29   [[ "July", "August" ], [3], [7], [ "Thursday", "Wednesday" ]]
                   [[ "August", "July" ], [3], [7], [ "Wednesday", "Thursday" ]]

                   etc. since the order within each cube doesn't matter.


(Thu) 2019-07-11   [[ "May", "June" ], [3], [8], [ "Saturday", "Friday" ]]
                   [[ "May", "June" ], [8], [3], [ "Saturday", "Friday" ]]

                   since the two 1 cubes could be either way.

(Sun) 2019-10-27   [[ "January", "February" ], [3], [6], [ "Friday", "Saturday" ]]

(Wed) 2019-05-01   [[ "March", "April" ], [8], [3], [ "Monday", "Tuesday" ]]
                   [[ "March", "April" ], [6], [3], [ "Monday", "Tuesday" ]]
                   [[ "March", "April" ], [9], [3], [ "Monday", "Tuesday" ]]

                   since the 0 cube could have either the 8 side or the 6 side facing up, and the 6 could also be considered a 9.


(Sat) 2019-08-24   [[ "February", "January" ], [8], [5], [ "Sunday" ]]
\$\endgroup\$
  • \$\begingroup\$ So... I've been wondering, how is this decorative thing able to show all dates? \$\endgroup\$ – Erik the Outgolfer Dec 19 '18 at 18:42
  • \$\begingroup\$ @ErikTheOutgolfer which date is missing? \$\endgroup\$ – ngm Dec 19 '18 at 19:00
  • \$\begingroup\$ Not related to the challenge, but, since I can't ping you over chat, how do you use the two middle cubes? I mean, all 10 digits should be able to be represented. \$\endgroup\$ – Erik the Outgolfer Dec 19 '18 at 19:04
  • 1
    \$\begingroup\$ The cubes can be used in either order. Let's call the two numeric cubes Top Right and Bottom Left as in the graphic. To get 18 you use 1 from Top Right and 8 from Bottom Left. To get 13 you use 1 from Bottom Left and 3 from Top Right. And so on. 0 1 and 2 have to be on both cubes. The fact that 6 and 9 share the same cube face gives you everything from 01 to 31 which is all that is needed. \$\endgroup\$ – ngm Dec 19 '18 at 19:32
  • 1
    \$\begingroup\$ According to the pictures, 27 in 2019-10-27 should go to 36, not 32. \$\endgroup\$ – japh Dec 20 '18 at 10:55
5
\$\begingroup\$

C (glibc), 327 319 286 bytes

#define C strftime(s
#define U(B,E)S[6]=E-1,C+B,99,"%A"+2*!E,S)
S[9],s[99];f(M,D){S[4]=112233107696>>3*M&7;C,9,"%B",S);S[4]^=1;
C+3,9,"%B",S);M=161102>>(D+M*23/9-1-2*(M>2))%7*3&7;U(6,M);U(9,(M^1));
printf("%s/%s %d%d %s/%s\n",
s,s+3,D>29?4:D%10<6?8:3,D>29?8:1070160091>>D%10*3&7,s+6,s+9);}

(Some line breaks added for clarity)

f takes a month (1–12) and a day (1–31). Prints to stdout. Try it online!

Test cases:

2019-01-29: July/August 37 Thursday/Wednesday
2019-07-11: May/June 83 Saturday/Friday
2019-10-27: January/February 36 Friday/Saturday
2019-05-01: March/April 83 Monday/Tuesday
2019-08-24: February/January 85 /Sunday

Ungolfed

#include <stdio.h>
#include <time.h>
void f(int M, int D) {
    int month_cube[] = {6,3,0,5,2,7,4,1,4,0,5,1};
    int day_cube[] = {3,3,3,4,5,2,2,6,7,7};
    int week_cube[] = {6,1,5,2,7,4,0}; /* 1=Sun, 7=Sat, 0=none */
    int D1 = D/10, D2 = D%10;
    char s[4][99] = {{0}};
    struct tm t;

    t.tm_mon = month_cube[M-1];
    strftime(s[0], 99, "%B", &t);
    t.tm_mon = month_cube[M-1]^1;
    strftime(s[1], 99, "%B", &t);

    if (D1 >= 3) { /* D = 30, 31 */
        D1 = 4, D2 = 8;
    } else {
        if (D2 <= 5) {
            D1 = 8; /* 012[69]78: 012 -> 8 */
        } else {
            D1 = 3; /* 012345: 012 -> 3 */
        }
        D2 = day_cube[D2];
    }

    int W = (D + M*23/9 - 1 - 2*(M>2)) % 7; /* day of week */
    if (week_cube[W]) {
        t.tm_wday = week_cube[W] - 1;
        strftime(s[2], 99, "%A", &t);
    }
    if (week_cube[W]^1) {
        t.tm_wday = (week_cube[W]^1) - 1;
        strftime(s[3], 99, "%A", &t);
    }

    printf("%s/%s %d%d %s/%s\n", s[0], s[1], D1, D2, s[2], s[3]);
}

Digit cubes

These are the possibilities for the digits:

Cube 1:
0 1 2 3 4 5
3 3 3 4 5 2
5

Cube 2:
0 1 2        6 7 8 9
8 8 8        2 6 7 7
6                2
9

The following mapping seems like the best choice for golfing:

   01 02 03 04 05 06 07 08 09
   83 83 84 85 82 32 36 37 37

10 11 12 13 14 15 16 17 18 19
83 83 83 84 85 82 32 36 37 37

20 21 22 23 24 25 26 27 28 29
83 83 83 84 85 82 32 36 37 37

30 31
48 48

Cheats

strftime is meant to be called with a struct tm as input. Instead, I declare int S[9] and use S[4] as tm_mon and S[6] as tm_wday. This works if the C library uses the same list of struct members as the ISO standard.

s[99] is used to store various strings from strftime, but making it an int array saves a few bytes in indexing.

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

JavaScript (ES6), 142 bytes

Takes input as (year, month, day0, day1) where \$month\$ is 1-indexed, \$day0\$ is the first digit of the date and \$day1\$ is the second digit.

Returns (month0, month1, day0, day1, weekDay0, weekDay1) where week days are 0-indexed with \$0\$ for Sunday. If the second week day is blank, it is set to \$-1\$.

(y,m,t,u)=>[M=-~((s='45226276204264')[m--+6]||4*m%2),M+1,t<3?u<6?8:3:s[t-3],u<3?3:s[u-3],D=s[(new Date(y,m,t*10+u).getDay()+6)%7+7],-~D%7||-1]

Try it online!

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