# How many weekdays?

This a simple question.

The start day is a Saturday and let the input be a non-negative number x.

The output should be the number of weekdays (Mon-Fri) in the next x days inclusive.

For example, if x = 3 then the output should be 2. For x from 0 onwards the output should be:

0,0,1,2,3,4,5,5,5,6,7,8,9,10,10,10,11,...


—-—

Now I am regretting not having asked the question for a user specified day of the week instead of just Saturday. It’s too late to change the question now and a new question would probably be marked as a duplicate. If anyone wanted to add an answer for this extension, I would love to see it.

• I found the title on this really confusing. I assumed it meant "how many weekdays until Saturday" which should never exceed five. But actually you're asking something completely different. I suggest revising the title to "how many weekdays" – Level River St Jun 28 at 13:29

# Python 2, 18 bytes

lambda x:x*6/7-x/7


Try it online!

Found by brute-forcing. x*6/7 counts non-Sundays, and -x/7 subtracts the number of Saturdays.

all          x       0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 ...

all - Sun  = x*6/7   0  0  1  2  3  4  5  6  6  7  8  9 10 11 12 12 13 ...
Sat        = x/7     0  0  0  0  0  0  0  1  1  1  1  1  1  1  2  2  2 ...
all - Sun - Sat      0  0  1  2  3  4  5  5  5  6  7  8  9 10 10 10 11 ...


Brute-forcing suggests that this is the unique arithmetical solution of this length or shorter, subject to some limitations like not using parens, using only single-digit constants, and not having too-large intermediate results.

19 bytes

lambda x:x-x/7+-x/7


Try it online!

Found by brute-forcing. But, it has a nice interpretation. x counts all x days. Then -x/7 subtracts the number of Sundays in those x days, and +-x/7 subtracts the number of Saturdays. Note that there's a difference in Python between subtracting x/7 and adding -x/7 aka (-x)/7, because floor-div is not symmetric around zero since it always round down.

all =   x        0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 ...
Sun =   x/7      0  0  0  0  0  0  0  1  1  1  1  1  1  1  2  2  2 ...
Sat = -(-x/7)    0  1  1  1  1  1  1  1  2  2  2  2  2  2  2  3  3 ...

all - Sun - Sat  0  0  1  2  3  4  5  5  5  6  7  8  9 10 10 10 11 ...


20 bytes

lambda x:x*5/7+x%7/4


Try it online!

I found this by hand, noting that f(x) increases asymptotically with slope 5/7 and seeing that the difference to x*5/7 (with floor-division) has a nice period-7 form.

• What does +- do? – Anush Jun 28 at 7:17
• @Anush The +-x/7 adds the term -x/7 AKA (-x)/7, which is different from the earlier term -x/7 which subtracts x/7, since Python's mod isn't symmetric around zero. – xnor Jun 28 at 7:19
• I wonder what you can do in Python 3. – Anush Jun 28 at 7:27
• @Anush That's an interesting question. Since the / will need to be //, it might be that something with % for mod becomes better. I'll see what the brute-forcing gives. – xnor Jun 28 at 7:29
• @Anush Maybe? I don't see an obvious extension, but there's probably some way to incorporate an offset corresponding to the starting day. – xnor Jul 1 at 9:22

# APL (Dyalog Unicode), 7 bytes

+/2≤7|⍳


Try it online!

1-based range is a big win here.

### How it works

+/2≤7|⍳
⍳  ⍝ 1-based range
7|   ⍝ modulo 7; 1 2 3 4 5 6 0 ...
2≤     ⍝ is at least 2; 0 1 1 1 1 1 0 ...
+/       ⍝ sum the booleans


For the bonus question (let the user provide the day of the week to start):

# APL (Dyalog Unicode), 11 bytes

+/⎕⍴⎕⌽7↑5⍴1


Try it online!

We don't need any fancy arithmetic. Just create a bit vector, rotate it to match the requested day of week to start with, cycle it and count ones (i.e. sum).

Accepts Sun, Mon, ..., Sat as the number 0, 1, ..., 6 as the first input, and the number of days as the second (both from stdin). (It actually works for any integers (for the first input) and gives the result as if it was modulo 7.)

### How it works

+/⎕⍴⎕⌽7↑5⍴1
7↑5⍴1  ⍝ 1 repeated 5 times and then overtaken to length 7
⍝ i.e. 1 1 1 1 1 0 0
⎕⌽  ⍝ Take the starting weekday and rotate ^ that many units to the left
⎕⍴    ⍝ Take the number of days and cycle ^ to that length
+/      ⍝ Sum

• Thank you for the bonus answer! – Anush Jun 29 at 5:50

# 05AB1E, 8 6 bytes

Ý7%1›O


Try it online!

Very similar to the APL answer

## Explained

Ý    | Generate a list between 0 and input
7%   | Mod each number by 7
1›   | Determine if each number is greater than 1
O    | Summate the list and output it


# JavaScript (ES6), 16 bytes

n=>n*20/7+n%7>>2


Try it online!

### How?

The expression $$\\lfloor 5n/7\rfloor\$$ gives the correct answer when $$\n\bmod 7\$$ is less than or equal to $$\3\$$ but is off by $$\1\$$ otherwise.

 n           | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16
-------------+---+---+---+---+---+---+---+---+---+---+----+----+----+----+----+----+----
floor(5n/7) | 0 | 0 | 1 | 2 | 2 | 3 | 4 | 5 | 5 | 6 |  7 |  7 |  8 |  9 | 10 | 10 | 11
expected    | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 5 | 5 | 6 |  7 |  8 |  9 | 10 | 10 | 10 | 11
difference  | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 |  0 |  1 |  1 |  1 |  0 |  0 |  0
n mod 7     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 1 | 2 |  3 |  4 |  5 |  6 |  0 |  1 |  2


This can be adjusted with:

$$f(n)= \left\lfloor\frac{5n}{7}\right\rfloor+\left\lfloor\frac{n\bmod 7}{4}\right\rfloor$$

which may also be expressed as:

$$f(n)= \left\lfloor\frac{20n/7+(n\bmod 7)}{4}\right\rfloor$$

# JavaScript (Node.js), 15 bytes

In order to use @xnor's formula without adding explicit floor operations, we have to work with BigInts. So this version expects a BigInt as input.

n=>n*6n/7n-n/7n


Try it online!

• Does 20/7*n run the risk of a floating-point rounding error in a way n*20/7 would not? – Neil Jun 28 at 10:22
• @Neil I'm almost certain it's safe in this case. But since you're right in the general case, I've updated it anyway. – Arnauld Jun 28 at 10:35
• I really like this answer because I can read it and it comes with math. More languages have integer division than I had expected! – Anush Jun 29 at 6:09
• @Anush Just to clarify, JS doesn't have integer division (which is why I use a right-shift instead) unless we work with BigInts. I've added a port of xnor's answer to illustrate that. – Arnauld Jun 29 at 7:04
• How come 20/7 doesn't return a float in that case? Are you assuming BigInts there too? – Anush Jun 29 at 8:28

# Japt, 7 bytes

Port of Bubbler's APL solution so be sure to +1 them, too.

õu7 x¨2


Try it - Includes all test cases

# bc, 29 bytes

define f(n){return n*6/7-n/7}


Try it online!

# Jelly, 6 bytes

R%7>1S


Try it online!

Interestingly equal-length in all regards to Lyxal's 05AB1E answer, so I've copy-pasted the explanation, swapping out the commands.

R    | Generate a list between 0 and input
%7   | Mod each number by 7
>1   | Determine if each number is greater than 1
S    | Summate the list and output it

• An all-ASCII Jelly answer, isn't that world first? :P – Sok Jun 29 at 15:17

# C (gcc), 18 bytes

f(n){n=n*6/7-n/7;}


Try it online!

Port of xnor's formula from his Python 2 answer.

# Java, 12 bytes

x->x*6/7-x/7


$_=$_*6/7-$_/7  Try it online! Uses the same algorithm as the Python 2 solution from @xnor. The -Minteger switch makes perl use integer division. # x86-16 machine code, 16 bytes 33 DB XOR BX, BX ; clear BX sum MLOOP: E3 0B JCXZ DONE ; handle x = 0 8A C1 MOV AL, CL ; loop counter to AL D4 07 AAM 7 ; AL = AL mod 7 3C 01 CMP AL, 1 ; AL <= 1 ? 7E 01 JLE IS_WEEKEND ; if so, is a weekend 43 INC BX ; otherwise increment count IS_WEEKEND: E2 F3 LOOP MLOOP ; loop until 0 DONE: C3 RET ; return to caller  Callable function, input in CL (unsigned byte) output to BX. Or 22 bytes to operate on 16 bit unsigned WORD in CX: 33 DB XOR BX, BX ; clear BX sum MLOOP: E3 11 JCXZ DONE ; handle x = 0 8B C1 MOV AX, CX 33 D2 XOR DX, DX ; clear DX (high word of quotient) BF 0007 MOV DI, 7 ; set up WORD divisor F7 F7 DIV DI ; DX = DX:AX mod DI 80 FA 01 CMP DL, 1 ; DL <= 1 ? 7E 01 JLE IS_WEEKEND ; if so, is a weekend 43 INC BX ; otherwise increment count IS_WEEKEND: E2 ED LOOP MLOOP DONE: C3 RET ; return to caller  # Retina 0.8.2, 22 bytes .+$*
.(.{0,5}).?
$1 .  Try it online! Link includes test cases. Explanation: .+$*


Convert to unary.

.(.{0,5}).?


For each week, match Sunday, then up to five weekdays, then optionally match Saturday.

$1  Keep just the weekdays. .  Count the resulting weekdays. # Charcoal, 10 bytes ＩΣ…⪫00×⁵1Ｎ  Try it online! Link is to verbose version of code. This is actually 3 bytes shorter than trying to calculate the result arithmetically. Explanation:  1 Literal string 1 ×⁵ Repeated 5 times i.e. 11111 00 Literal string 00 ⪫ Join its characters giving 0111110 … Ｎ Cyclically extend to the input number of days Σ Sum the digits Ｉ Cast to string Implicitly print  # Pyth, 8 bytes lf<1%T7S  Try it online! Port of Bubbler's APL solution. ## Explanation lf<1%T7S l : length of f : filter on S : 1-based range to input <1%T7 : where mod 7 is greater than 1  # AWK, 29 bytes {print int($0*6/7)-int(\$0/7)}


Try it online!

Port of @xnor's Python 2 answer.

# Befunge-93, 12 bytes

&:6*7/\7/-.@


Try it online!

Another port of xnor's algorithm.

# Pyth, 7 bytes

sm<1%d7


Try it online!

Port of Lyxal's 05AB1E answer.

sm<1%d7
m        For each number from 0-input:
%d7     Mod 7
<1        Greater than 1
s         Take the sum, implicit print


# Io, 44 bytes

It seems like ranging is too costly here.

f :=method(x,if(x>0,if(x%7>1,1,0)+f(x-1),0))


Try it online!

# Io, 46 bytes

method(x,Range 0 to(x)map(i,if(i%7>1,1,0))sum)


Try it online!

# brainfuck, 142 bytes

(Due to number-wrapping problems) The maximum supported input is 255.

>,[[>+>+<<-]>[-<+>]<->>>+++++++<[>->+<[>]>[<+>-]<<[<]>-]>[-]>>+<[<<<+>>>>[-<<<<[-]>+>>>]<<<<[->>+<<]>[->>>+<<<]>>>-<-]>[-]<<[-<<<<+>>>>]<<<]<.


Try it online!

If you are not sure whether this output is correct, try this link.

## Explanation

>,


[


While the input is nonzero:

[>+>+<<-]>[-<+>]


>x 0 0 -> x 0 >x

<->>>+++++++<[>->+<[>]>[<+>-]<<[<]>-]>[-]


Modulo by 7

>>+<[<<<+>>>>[-<<<<[-]>+>>>]<<<<[->>+<<]>[->>>+<<<]>>>-<-]>[-]<<


Check if this number is greater than 1

[-<<<<+>>>>]<<<


Add it to the accumulator (at the first item of the tape)

]


End while

<.


Move to the accumulator, print the value.

# Julia, 143 Bytes

function weekdays(days)
r = mod(days, 7)
if r <= 2 r=0
else r -= 2
end
wd::Int64 = floor(days/7)
return(5 * wd + r)
end


Try it online!

To use a custom start date, I add an offset argument, and days += offset at the start of the function

• Golfed, 89 bytes – Lyxal Jul 5 at 4:40
• Welcome to the site! These tips for golfing in Julia might be helpful. Also note that you should avoid using spaces (where possible) to minimise your byte count. – Dingus Jul 5 at 10:04

# Keg, 10 bytes

0&1ɧ⑷7%1>⑼


Try it online!

Total not a port of Lyxal's my 05AB1E answer... (spoiler, it is). ;P

## Explained

0&1ɧ⑷7%1>⑼
0&              # Store 0 in the register, as this will be used to keep track of the number of weekdays
1ɧ            # Create a range between 1 and the implicit input
⑷           # Map the following to each item in the stack:
7%1>⑼     # Increment the register by whether or not ((item % 7) > 1)