Is there a known math formula or algorithm to determine delivery date of dependent work

Say that an item is an indivisible piece of work that needs to be achieved by one resource (worker).
Each item must be:
 Step 1: prepared by one of the resources from group A,
 Step 2: And then transformed by one of the resources from group B.
Step 1 takes 1 day (one resource achieves one item in one day), while step 2 takes 4 days.
Is there a known math formula or algorithm to determine when all the items will be achieved?
Considering that the number of items is known in advance, as well as the number of resources per group (and one resource cannot move from one group to another). For instance, I can compute when group A will be finished:
= CEILING(Number of items / count of resources in group A) * Work duration
But then I need to compute the (dependent) work for group B that will have a discretely increasing workload (one resource of group B can only start when one item has passed step 1).

For an algorithm, you can simply simulate the process with each day being represented by one step, and count the simulation steps. That's not a closed formula but given relatively small numbers can be evaluated quickly enough.
Just for fun I've written a small python program (beware, this is python2):
#!/usr/bin/env python num_a = 5 dur_a = 1 num_b = 20 dur_b = 4 num_items = 100
num_buffered = 0
num_finished = 0
active_a = []
active_b = []t = 0
while num_items + num_buffered + len(active_a) + len(active_b) > 0:
# print progress
print("{:>3}: {} idle A, {} idle B, {} items, {} buffered, {} finished".format(
t,
num_a,
num_b,
num_items,
num_buffered,
num_finished))# count down time worked active_a = map(lambda x: x1, active_a) active_b = map(lambda x: x1, active_b) # finished workers put items into buffer or result and return to their work group done_a = len(filter(lambda x: x==0, active_a)) num_a += done_a active_a = filter(lambda x: x>0, active_a) num_buffered += done_a done_b = len(filter(lambda x: x==0, active_b)) num_b += done_b active_b = filter(lambda x: x>0, active_b) num_finished += done_b # workers pick up work and start for _ in range(0,min(num_a,num_items)): active_a.append(dur_a) num_a = 1 num_items = 1 for _ in range(0,min(num_b,num_buffered)): active_b.append(dur_b) num_b = 1 num_buffered = 1 # time increments by 1 t += 1
print("{:>3}: done".format(t))