# 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" Jun 28, 2020 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?
– user9207
Jun 28, 2020 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, 2020 at 7:19
• I wonder what you can do in Python 3.
– user9207
Jun 28, 2020 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, 2020 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, 2020 at 9:22

# 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


# 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!
– user9207
Jun 29, 2020 at 5:50

# 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


$$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, 2020 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. Jun 28, 2020 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!
– user9207
Jun 29, 2020 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. Jun 29, 2020 at 7:04
• How come 20/7 doesn't return a float in that case? Are you assuming BigInts there too?
– user9207
Jun 29, 2020 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, 2020 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  # 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 Jul 5, 2020 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. Jul 5, 2020 at 10:04 # 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.

# 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!

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

• Also 7 bytes: t-Qy/Q7 Feb 15, 2021 at 21:48

# 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.

# 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)


# Vyxal, s, 5 bytes

ʀ7%1>


Try it Online!

Another port of my 05AB1E answer

# x86-16 machine code, 18 16 bytes (No Loop):

Bytecode: "\xD4\x07\x88\xC1\xC1\xE8\x08\x6B\xC0\x05\x49\x78\x02\x01\xC8\xC3"

0:  d4 07                   aam    0x7          ; eax contains n, with aam 0x7 -> al = n % 7 and ah = n / 7
2:  88 c1                   mov    cl,al        ; keep result of n%7 in ecx
4:  c1 e8 08                shr    ax,0x8       ; by shifting 8 times ax, ax=al=n/7;
7:  6b c0 05                imul   ax,ax,0x5    ; we multiply by 5
a:  49                      dec    ecx          ; ecx = ecx - 1 -> give 65535 if n was power of 7
b:  78 02                   js     11 <end>     ; if it happened we don't care about the remainder so we can just return n/7*5, the Signed Flag will be set so we can jump 2 bytes forward.
d:  01 c8                   add    eax,ecx      ; if not then we add (n%7)-1 to n/7*5
00000011 <end>:
f:  c3                      ret


obtained from assembling thanks to objdump -d -mi8086 dayofweek.s

global dayofweek

bits 16

section .text

dayofweek:
aam  7
mov  cl, al
shr  ax, 8
imul ax,5
dec  ecx
js   end
end:
ret


Test: main.c

int main() {
for (short i = 0; i < 50; i++)
printf("%2d %2d\n", dayofweek(i), (i*20/7+i%7)/4);
return 0;
}


output:

0  0
0  0
1  1
2  2
3  3
...
33 33
34 34
35 35
35 35


It is not as short as @640KB (16 bytes) but I believe it is still an interesting answer as it provides a better performance (no loop)

edit: Thanks to Peter -2 bits

NB (Peter): Do note that aam only divides AL, not AX, so you might as well declare the arg in C as uint8_t, as well as specifying the gcc -mregparm=3 calling convention to put it in the reg you want.

• You say this is supposed to be 16-bit code, and you even used bits 16, but you have a 66 operand-size prefix on instructions using 16-bit registers but not on instructions like add eax, ecx. That's backwards; that machine code is what you'd get if you assembled for 32-bit mode. Did you take this machine code from before you added bits 16 to the source? Feb 21, 2021 at 6:09
• Good point, I got the bytecodes from defuse.ca/online-x86-assembler.htm#disassembly , how could I get the 16 bits version in local ? Feb 21, 2021 at 6:13
• Just use nasm -fbin -l/dev/stdout to get a listing, or objdump -d -mi8086 to disassemble as 16-bit if you have machine code in an ELF object. And IDK what good gcc-multilib would be for 16-bit code, I guess you actually built that as 32-bit so you could call from C easily. I was going to say I guess you disassembled that by mistake, but yeah, using a 32-bit-mode online assembler would have the same problem. Feb 21, 2021 at 6:16
• Also obviously use 16-bit (or 8-bit) operand-size as much as possible to save bytes, with your return value only in AX. (So the C return type is unsigned short). Or just do this in 32-bit code; unless 16-bit lets you avoid high garbage in EAX outside what aam deals with. Also, you seem to be using dec ecx after only writing CL, so the sign flag will depend on garbage left in high bytes of ECX. (And you haven't documented a calling convention, but it looks like gcc -mregparm=3 so first arg in EAX). Feb 21, 2021 at 6:22
• xchg al, ah / imul ax, 5 might work to leave a valid result in the low byte of EAX (aka AL). The low bits of a multiply don't depend on the high bits of the inputs (think of it as adding at various left shifts, and adding only propagates carry from low to high). Or perhaps xchg ax,cx (1 byte) / mov al, ch (2B) / imul ax, 5 (3B) to also replace the mov cl,al. As long as your result fits in 1 byte, you're fine, but that might not be justified. So perhaps movzx ax, ch (3B) to still allow xchg but avoid the immediate shift. That'd allow 32-bit mode. Feb 21, 2021 at 6:24

# PowerShell, 42 bytes

function x($y){[math]::floor($y*6/7-$y/7)}  Try it online! Fork of Python 2 answer • Wasif, $y*6/7-$y/7 = $y*5/7 :) Try it online! Feb 22, 2021 at 5:36