# Help me get the day of the week correct

Sometimes, I will think it is one day of the week (e.g Friday) when in reality, it's earlier in the week (e.g Tuesday).

Your challenge is to display the number of days my estimates are off by.

## Challenge

Given a day of the week I think it is, and the day of the week it actually is, output/return the number of days between the two.

## Test Cases

Incorrect date, Actual Date -> Days between
Monday, Monday -> 0
Friday, Tuesday ->  3
Saturday, Sunday -> 6
Tuesday, Friday -> 4
Thursday, Wednesday ->  1
Monday, Friday -> 3


## Rules

• Dates have to be taken as the actual date name (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday). This is non-negotiable.
• Date names must be taken as strings or equivalent in your language (ADTs aren't allowed unless they store their values as the allowed strings)
• Input and output can be given/taken in any reasonable format.
• Full program or function - it doesn't matter.

And finally, this is , so the answer in each language with the fewest bytes wins.

• May I use current system time as the actual day of week?
– tsh
Apr 22, 2021 at 1:29
• @tsh, no the actual day must be taken as input Apr 22, 2021 at 1:30
• Does the day name have to be taken as a string? Or can I e.g. use an ADT a la data WeekDay = Sunday | Monday | Tuesday ... and use that as input instead? Apr 22, 2021 at 1:56
• @MLavrentyev input has to be taken as strings sorry Apr 22, 2021 at 1:57
• Could you include the name of all seven days in the post as a reference?
– tsh
Apr 22, 2021 at 2:02

# JavaScript (ES6), 48 bytes

Expects (day1)(day2).

a=>b=>((g=s=>parseInt(s,34)%72%23)(a)-g(b)+21)%7


Try it online!

### How?

We need a hash function $$\g\$$ that turns a day string into an index. The results of this function are actually quite flexible:

• They can be in ascending or descending order: 0,1,2,3,4,5,6 or 6,5,4,3,2,1,0. (We'll have to compute either $$\g(a)-g(b)\$$ or $$\g(b)-g(a)\$$ accordingly.)
• Day #0 may be any day of the week. For instance, 3,4,5,6,0,1,2 or 4,3,2,1,0,6,5 are also valid.
• The results may be greater than $$\6\$$ as long as they are correct modulo $$\7\$$. Because the sign of the modulo is the sign of the dividend in JS, we'll have to do something like (g(a) - g(b) + k) % 7 anyway, where $$\k\$$ is a large enough multiple of $$\7\$$.

The following function was found by brute-force:

g = s => parseInt(s, 34) % 72 % 23


which gives:

 day         | base34 -> dec | mod 72 | mod 23 | mod 7
-------------+---------------+--------+--------+-------
"Monday"    |      30369728 |   56   |   10   |   3
"Tuesday"   |    1358300452 |    4   |    4   |   4
"Wednesday" | 1702996445748 |   12   |   12   |   5
"Thursday"  |   45612914380 |   52   |    6   |   6
"Friday"    |      21127508 |   44   |   21   |   0
"Saturday"  |   43748842416 |   24   |    1   |   1
"Sunday"    |      38623568 |   32   |    9   |   2

• How you manage to always find a modulo or bitwise formula for challenges always amazes me! Thank you very much for this answer! Apr 22, 2021 at 11:30

# Bash + GNU utilities, 26

date -f- +%u|dc -e??-7+7%p


Inputs are read from lines 1 and 2 of STDIN.

Try it online!

### Explanation

GNU date reads a mostly free format human readable date string. With -f it reads multiple date strings from a file and if the file is -, STDIN is read. The free format is free enough that a single day of the week will be parsed. The parsed date is then output according to the format string. %u simply outputs the {1..7} numerical index of the day of the week, where 1 is "Monday".

This output is piped to a dc expression:

??          # read the first 2 converted inputted dates
-         # find the difference
7%     # find the modulo-7
p    # print the result

• I have simply deleted my pitiful Bash attempt after seeing this. Well done. Apr 22, 2021 at 3:33

# Python 2, 42 bytes

lambda a,b:(hash(b*11)%69-hash(a*11)%69)%7


Try it online!

If we can map both weekdays to their respective values (Monday -> 0, Tuesday -> 1, ...), then we can calculate the days in between with $$\ (a - b) \bmod 7 \$$. To do this, we use the following formula: hash(s*11)%69%7.

# K (ngn/k), 32 26 bytes

Solution:

7!-/13 1 0 2 12 7 5?15!+/'


Try it online!

Explanation:

Found a slightly better lookup. Sum of ASCII chars modulo 15.

7!-/13 1 0 2 12 7 5?15!+/' / the solution
+/' / sum (+/) each (') input string
15!    / 15 modulo result
?       / lookup this value in left list
13 1 0 2 12 7 5        / precalculated result of summing ASCII weekdays
-/                       / subtract to get difference
7!                         / modulo 7 to account for negatives


Edits:

• -6 bytes Lookup table based on sums of ascii chars, rather than Mo/Tu/We etc.

# Factor, 35 bytes

[ [ day-names index ] bi@ - 7 rem ]


Doesn't run on TIO because TIO is missing the calendar.english vocabulary which is perfectly extant on a local copy of Factor 0.98. So have a screenshot of running the quotation in the listener:

## Explanation:

It's a quotation (anonymous function) that takes two strings on the data stack as input and leaves an integer on the data stack as output. Assuming "Tuesday" "Friday" is on the data stack when this quotation is called...

• [ day-names index ] Push a quotation for bi@ to use later.

Stack: "Tuesday" "Friday" [ day-names index ]

• bi@ Apply a quotation to two objects. Inside the quotation now...

Stack: "Tuesday"

• day-names Push a sequence containing the days of the week.

Stack: "Tuesday" { "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" }

• index Take an object and a sequence and return the index of that object in the sequence.

Stack: 2

• Now bi@ will do the same with the other input.

Stack: 2 5

• - Subtract.

Stack: -3

• 7 Push 7 to the stack.

Stack: -3 7

• rem Like mod, except the result is always positive.

Stack: 4

# Emotilang, 1,312 bytes

Input is from the first and second lines of STDIN.

📦✏️💬📜📜
🤔📦⚖️📜♏️🅾️♑️↩️🅰️💹📜
📦✏️💯🕛💯
🤔📦⚖️📜✝️⛎📧💲↩️🅰️💹📜
📦✏️💯🕐💯
🤔📦⚖️📜〰️📧↩️♑️📧💲↩️🅰️💹📜
📦✏️💯🕑💯
🤔📦⚖️📜✝️♓️⛎®️💲↩️🅰️💹📜
📦✏️💯🕒💯
🤔📦⚖️📜🎏®️🕯️↩️🅰️💹📜
📦✏️💯🕓💯
🤔📦⚖️📜💲🅰️✝️⛎®️↩️🅰️💹📜
📦✏️💯🕔💯
🤔📦⚖️📜💲⛎♑️↩️🅰️💹📜
📦✏️💯🕕💯
⚗️✏️💬📜📜
🤔⚗️⚖️📜♏️🅾️♑️↩️🅰️💹📜
⚗️✏️💯🕛💯
🤔⚗️⚖️📜✝️⛎📧💲↩️🅰️💹📜
⚗️✏️💯🕐💯
🤔⚗️⚖️📜〰️📧↩️♑️📧💲↩️🅰️💹📜
⚗️✏️💯🕑💯
🤔⚗️⚖️📜✝️♓️⛎®️💲↩️🅰️💹📜
⚗️✏️💯🕒💯
🤔⚗️⚖️📜🎏®️🕯️↩️🅰️💹📜
⚗️✏️💯🕓💯
🤔⚗️⚖️📜💲🅰️✝️⛎®️↩️🅰️💹📜
⚗️✏️💯🕔💯
🤔⚗️⚖️📜💲⛎♑️↩️🅰️💹📜
⚗️✏️💯🕕💯
🧺✏️📦➖⚗️
🧺✏️🧺🍇💯🕖💯
🖨️🧺


Online interpreter

Here is proof that it passes the test cases:

• Welcome to Code Golf, and nice first answer! Apr 22, 2021 at 14:17
• This looks really cool... is there anywhere online that we can try this out without needing to install 'emotilang' on our own computer? Apr 22, 2021 at 14:28
• I may write an online version at some point... but for now you have to install it on your computer. If you don't trust the .exe you can run python main.py from the src folder on the repo. Thanks! Apr 22, 2021 at 14:30

# Ruby, 91 bytes

require"date"
w=(0..6).map{|i|Date.jd(i).strftime"%A"}
f=->i,a{(w.index(i)-w.index(a)+7)%7}


Testing:

p f["Saturday", "Sunday"]   #=> 6

• You can save some bytes by using Time.at instead of Date.jd: Try it online! Apr 22, 2021 at 2:56
• (This is shorter again. I suspect there's still scope for further golfing.) Apr 22, 2021 at 2:56
• @Dingus Great! I think it's fairer you post it as an answer, I'll upvote it. Apr 22, 2021 at 3:14

# Pari/GP, 114 bytes

v(s,n)=1+Vecsmall(s)[n]%4;
m=[5,x,x,7;3,2,6,1;x,x,x,x;x,x,x,4];
d(n)=m[v(n,6),v(n,1)];
p(a,b)=print((d(a)-d(b))%7)


Explanation: Pari/GP doesn't have calendar functions or, really, much in the way of string processing. I use the ASCII values of the 1st and 6th characters of the weekday name to index into a 4x4 matrix that encodes the weekday numbers, and then I just print the forward difference. I'm pleased with my solution, but there's probably a shorter formula I didn't think of.

Try it online!

# Jelly, 16 bytes

OP€%647%154%8I%7


Try it online!

-2 bytes thanks to Arnauld via finding the modulo chain to get the right values

Previously:

# Jelly, 18 bytes

OP€%17Ḥị“ØỴ¦’D¤I%7


Try it online!

Not convinced this is a good way of doing it, lol.

-2 bytes using integer compressing (thanks Lyxal)

• Can 1234756 be compressed? Apr 22, 2021 at 1:27
• @Lyxal it can actually, lol. forgot about base 250 Apr 22, 2021 at 1:28
• 16 bytes with a modulo chain, but there may be a better way with ḥ. Apr 22, 2021 at 10:06
• @Arnauld Oh wow, nice. (How do you even find these?) That's very impressive; thanks! Apr 22, 2021 at 16:09
• OP€%17ị“ık!’I%7 should do it in 15 using @cairdcoinheringaahing’s fork of Jelly Apr 24, 2021 at 14:59

# PowerShell, 43 41 bytes

-2 bytes thanks @Zaelin Goodman

$x,$y=$args|%{+[dayofweek]$_}
($x-$y+7)%7


Try it online!

• 41 bytes by casting to dayofweek in the foreach-object Try it online! Apr 22, 2021 at 11:15
• nice! thanks.【ツ】 Apr 22, 2021 at 11:19

# Java (JDK), 35 bytes

i->a->(7+a.ordinal()-i.ordinal())%7


Try it online!

Call is done like this:

    f.apply(MONDAY).applyAsInt(TUESDAY);


Since the answer above is not of the taste of some, here's a more "Java is verbose" answer that takes strings as input rather than built-in constants:

# Java (JDK), 113 bytes

i->a->(java.util.Comparator.comparing((String s)->java.time.DayOfWeek.valueOf(s.toUpperCase())).compare(a,i)+7)%7


Try it online!

• You have to take the day names as a string, I don't think this answer is valid Apr 22, 2021 at 10:07
• I apologise for not making this clear in the challenge, but taking input as an ADT isn't allowed (I was asked this question 9 hours ago in the comments). Of course, if this actually does use string objects internally, then this is perfectly fine. Apr 22, 2021 at 11:06
• DayOfWeek is a Java enum. Java enums contain the constant name as part of the spec. The name as a string is accessible with name() and it's why you see the name of the weekday printed out in the 49 outputs. So to me, this is really unclear. DayOfWeek has already been submitted in similar challenges here on PCG, such as this one. Finally, I don't know what ADT is. Apr 22, 2021 at 11:14
• If that's the case, then I see nothing wrong with this answer. Apr 22, 2021 at 11:20
• ADT = Abstract Data Type? Apr 22, 2021 at 11:21

# MATL, 10 9 bytes

23Y2&md7\


Inputs are in reverse order. Try it online! Or verify all test cases.

### Explanation

      % Implicit input: cell array of two strings
23Y2  % Push predefined literal {'Monday', 'Tuesday', 'Wednesday', 'Thursday', ...
% 'Friday', 'Saturday', 'Sunday'}
&m    % Indices of membership. Gives a vector of two numbers
d     % Consecutive differences. Gives one number
7     % Push 7
\     % Modulus
% Implicit display

• Why don't you just drop the P and take the two input days the other way around...? Apr 22, 2021 at 20:59
• @DominicvanEssen I asked Lyxal about that a few hours ago, but no reply yet. I guess it's allowed by default, so I'll go ahead and change it Apr 22, 2021 at 21:38
• Confirmed that reverse order is allowed Apr 23, 2021 at 9:16

# Pyth, 20 bytes

%-Fmx"SMansFr"@d12Q7


Test suite

# Retina 0.8.2, 42 bytes

TaF\hWsMnd
\w+
$* , ,7$*
(1*),\1|1{7}

1


Try it online! Link includes test cases. Explanation:

TaF\hWsMnd
\w+
$*  Convert the day name to a day number. This works as follows: Certain letters in the days are replaced with digits from 0 to 6. No two digits are adjacent, and the first digit is always the correct digit for the day of the week (but descending, because the inputs are in reverse order). When I ask Retina to convert from decimal to unary, it only sees the first digit, and so gives me the desired result. , ,7$*


Add 7 to the second number so that it is always greater than the first.

(1*),\1|1{7}



Take the difference between the numbers and reduce modulo 7.

1


Convert to decimal.

Table of day names and their conversions:

Sunday          Su6d0y          6
Monday          5o6d0y          5
Tuesday         Tue4d0y         4
Wednesday       3ed6e4d0y       3
Thursday        T2ur4d0y        2
Friday          1rid0y          1
Saturday        S0turd0y        0


# 05AB1E, 181715 11 bytes

C813%60%Æ7%


Try it online!

Try all test cases

Takes input as a list, in order [actual date, incorrect date]

I'm not sure exactly how 05AB1E C command works for non binary strings, I just tried some stuff and it worked

uses a hash to map the days to [4, 3, 2, 1, 0, 6, 5] (mod 7, since we do mod 7 anyway after the subtraction). The modulos were found by brute-force

["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
after C:
[2184, 5008, 18736, 9824, 1968, 9256, 2472]
after 813%:
[558, 130, 37, 68, 342, 313, 33]
after 60%:
[18, 10, 37, 8, 42, 13, 33]
after 7%:
[4, 3, 2, 1, 0, 6, 5]


# J, 37 34 bytes

7|-&((678 A.i.7)i.7|318+-/@$3&u:)  Try it online! • 3&u: Convert chars to unicode numbers • 318...$ Reshape cyclically to length 318. I found this by brute forcing a number such that the next step will return unique numbers for each weekday.
• +-/ Reduce by placing + and - alternately between the numbers.
• 7| Mod 7
• (678 A.i.7)i. Find index of above two numbers within 0 6 4 2 1 3 5, which are the unique numbers the weekdays map to.
• -& Subtract after converting both args.
• 7| Mod 7

## J, staightforward approach, 35 bytes

7|-&('MoTuWeThFrSaSu'-:@I.@E.~2&{.)


Try it online!

# Jelly, 10 bytes

⁽Ae,8ḥ)I%7


A monadic Link accepting a list of two lists of characters [incorrect, actual] yields an integer in $$\[0,6]\$$ wrapped in a list.
When run as a full program this accepts a list of two strings and prints the resulting integer (since Jelly's representation of a list containing one element is just the representation of that element).

Try it online!

### How?

Hashes "Thursday" to 1, "Wednesday" to 2, ..., "Friday" to 7, then takes the difference modulo $$\7\$$.

⁽Ae,8ḥ)I%7 - Link: list of lists of characters, [incorrect, actual]
)    - for each (day in [incorrect, actual]):
⁽Ae        -   17352
8      -   eight
,       -   pair -> [17352, 8]
ḥ     -   hash (day) using a salt of 17352 and a domain of [1..8]
I   - differences
%7 - mod seven -> [(ḥ(incorrect) - ḥ(actual)) mod 7]
- implicit print (of Jelly representation of that)


### Alternative 10 byter

Oḅȷ%⁽€ƈI%7


(Same IO as the above.)

Try it online!

Maps "Thursday" to 0, "Wednesday" to 1, ..., "Friday" to 6, then takes the difference modulo $$\7\$$.

Oḅȷ%⁽€ƈI%7 - Link: list of lists of characters, [incorrect, actual]
O          - convert to a list of lists of ordinals
ȷ        - 1000
ḅ         - convert from base (1000) to an integer (vectorises)
⁽€ƈ    - 4157
%       - modulo (4157) (vectorises)
I   - differences
%7 - modulo seven
- implicit print (of Jelly representation of that)


# R, 78 bytes

function(x)diff(which(t(sapply(w,grepl,x))))%%7
w=scan(,'')
M Tu W Th F Sa Su



Try it online!

Well, actually 76 bytes because we could use M Tu W h F t Su as a shorter lookup vector, but I feel the obviousness of the code is worth the extra +2.

# R, 80 bytes

function(a,b,+=function(d)sum(utf8ToInt(d)*169^(nchar(d):1-1))%%467)(+a-+b)%%7


Try it online!

Interprets ASCII values in each string as base-169 digits, then evaluates (incorrectly due to floating-point errors, but the incorrectness is taken into account by the program) modulo 467. This converts the days of the week to 5 6 0 1 2 3 4 on the TIO installation of R.

Somehow my own installation of R evaluates incorrectly differently, requiring interpretation in base-134 and evaluation modulo 978 (to correct the incorrectness), but both programs come out at 80 bytes.

# Red, 70 bytes

func[a b][g: func[d][index? find system/locale/days d](g a)-(g b)// 7]


Try it online!

# Japt, 22 bytes

Going with the numeric modulo would probably be shorter, but I enjoyed this more.

£7ÆÐTTX ÅÃb_øX¯3
r- u7


Explanation:

£7ÆÐTTX ÅÃb_øX¯3
7Æ              // Generate the range [0..6] and map it to
ÐTTX          // new Date(0, 0, X)
ÅÃ       // stringified such as "Sun Dec 31 1899", "Mon Jan 01 1900" etc.
£                // For every input string,
b_     // map to the index of the item that
øX¯3 // contains the first three letters of the input.
r- u7            // Reduce with subtraction, positive modulo 7.


Try it here.

# R, 6866 53 bytes

function(x)diff(match(x,weekdays(Sys.Date()+0:6)))%%7


Try it online!

Depends on system locale.

-13 bytes thanks to @Dominic making it work for edge cases

• 53 bytes... Apr 22, 2021 at 11:47
• Thanks, I thought to use match, but reading help suggested that the result will be the same as with %in%. I should've tried anyway... Apr 22, 2021 at 11:54

# Excel, 69 bytes

=LET(s,TEXT(SEQUENCE(7),"dddd"),MOD(MATCH(A1,s,0)-MATCH(B1,s,0)+7,7))


Input is in the cells A1 and B1. The formula goes anywhere else.

LET(s,TEXT(SEQUENCE(7),"dddd") stores an array of day names so we can reference it using just s.
MATCH(A1,s,0) & MATCH(B1,s,0) finds the input day names in that array.
MOD(MATCH(~)-MATCH(~)+7,7) finds the distance from the second day (B1) to the first (A1).
The MOD(~+7,7) is necessary because Mon→Fri is in the same week but Fri→Mon spans two weeks.

# Charcoal, 28 21 bytes

≔⁰ηＦ²≦⁻﹪⍘Ｓγ⁸⁴⁹⁰⁷ηＩ﹪η⁷


Try it online! Link is to verbose version of code. Edit: Saved 7 bytes thanks to @DominicvanEssen by searching for a suitable base and large modulus which generates descending integers directly instead of needing a look-up table. Explanation:

≔⁰η


Initialise the accumulator to zero.

Ｆ²


Loop over the two days.

≦⁻﹪⍘Ｓγ⁸⁴⁹⁰⁷η


Interpret the day name as a base 95 number (this is the index into printable ASCII). The number is then reduced modulo 84907 and later modulo 7, which was chosen to result in counting downwards from Thursday so that the result is the desired sign. The accumulator is subtracted from this value, so that on the first pass the accumulator becomes the first day and on the second pass it becomes the difference.

Ｉ﹪η⁷


Reduce the difference modulo 7 to account for wrapping past the end of the week.

• Looking at Jonathan Allan's second Jelly answer, can't you just use a single modulo 4157 on the base100 day name, without needing a lookup table? Apr 24, 2021 at 11:51
• @DominicvanEssen Not using Charcoal's native base 1000 conversion, but maybe I can still port his answer.
– Neil
Apr 24, 2021 at 13:36
• @DominicvanEssen I did find a six-digit modulus for Charcoal's base 1000 conversion but I also tried its base 95 conversion and I found a five-digit modulus. (By comparison porting the modulus of 4157 would cost three bytes in the ordinal conversion.)
– Neil
Apr 24, 2021 at 14:26
• I'm glad that that worked-out at least for you: I spent ages finding a base + modulo that would work in R, then needed to re-calculate because TIO gives different floating-point errors, and finally it came-out longer than the 'dumb' solution...! Apr 24, 2021 at 14:42

# Lua, 72 bytes

a,_,b=io.read(2,"l",2)w="SuMoTuWeThFrSa"print((w:find(a)-w:find(b))/2%7)


Try it online!

### Explanation

a,_,b=io.read(2,"l",2)


Take first 2 bytes of each input, discarding rest of first input, and ignoring rest of second. This leaves the remaining input, so running this twice without refreshing the environment (e.g. in a lua console) will not work. This could be resolved by adding ,"l" to the read (+4 bytes).

To make this compatible with older Lua versions, change l to *l (+1 byte).

(w:find(a)-w:find(b))/2%7


find returns the index at which the input was found. w being SuMoTuWeThFrSa, representing the smallest possible unique letter representation of each day. Find the difference in indexes, divide by two (string length of 14), and modulo by 7.