Maximum riders' meaningful vectors: (3,3), (3,2), (3,1), (3,0); others are (2,2), (2,1), (2,0), (1,1), (1,0)
Leapers-only meaningful vectors: (7,7)-(7,0), (6,6)-(6,0), (5,5)-(5,0), (4,4)-(4,0).
Distinct directions (ie. with coprime numbers) where different directions cannot interact in terms of leapers&riders combinations: (1,0),(1,1),(2,1),(3,1),(3,2), and leaper-only ones: (4,1),(4,3),(5,1),(5,2),(5,3),(5,4),(6,1),(6,5),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6)
The leaper-only directions can be freely combined with others, so 2^14 combinations.
For each interacting direction where riders and leapers are both possible, I will consider which combinations of leapers and riders are equivalent.
Now, these combinations are only the same if the reachable squares are the same and for each reachable square, the squares required to be empty (cannot leap over) are also the same. I will call the squares required to be empty "dependence", and denote a leaper or rider that goes n squares in that direction as n-leaper or n-rider. A 1-rider in any direction is not equivalent to a 1~n-leaper in that direction because the former cannot leap across (n-1) points. For a direction with 2 destination possibilities, there are 5 combinations: 4 combinations of leapers (1, 2, 12, nothing) and a rider (goes to 1 and 2 but cannot leap over the square in the middle). For a direction with 3 destinations (123), 3 can depend on leaping over 1 or 2 but not only one of them, and 2 can depend on 1 or not, and if either 3 or 2 is dependent, then there must be a 1-rider. So 1 1-rider-only possibility (2 and 3 are dependent), 1 1-rider+2-leaper possibility (only 3 has dependence), 1 1-rider+3-leaper possibility (only 2 has dependence), 2^3 leaper possibilities with no dependence, in total 11 combinations. Luckily there are no directions with 4-6 possibilities, only with 7 possibilities.
For 7 possible target squares, let's call them 1234567, you can have 1-rider (2-7 all dependent on previous squares), or 2-rider (4,6 dependent), 3-rider (6 dependent) but that's all the meaningful riders.
I found it error-prone to count all cases, so here's some code to do it for arbitrary number of target squares in a direction:
import math
def getBitVector(x,n):
binary = [int(i) for i in (bin(x)[2:]).zfill(n)]
return binary
def isRiderRelevant(stride,dep_list): # assuming dep_list represents the dependency of a square k*stride (k>1)
ans=True
for x in dep_list:
if x==0:
ans=False
break
if x%stride==0:
#hypothetically the 8-th square can depend on a 2-rider component and a 4-rider component,
#but the 4-rider makes the 2-rider irrelevant for this target square
#in particular, any other rider that goes to a square makes the 1-rider irrelevant for that square
ans=False
break
if x==stride:
ans=False
break # just in case
return ans
def listEqual(l1,l2):
#2-layer list equality check, assuming sub-lists are sorted
if len(l1)!=len(l2):return False
for i,x in enumerate(l1):
y=l2[i]
if len(x)!=len(y):return False
for j,n in enumerate(x):
if n!=y[j]: return False
return True
def pretty_print_possibilities(l):
for x in l:
output=[]
for y in x:
if len(y)==0: output.append("_")
elif len(y)==1: output.append(str(y[0]))
else: output.append(','.join([str(z) for z in y]))
print(*output, sep=' ')
#dependency entries:
#[] means not accessible, [0] means no dependencies (from leaper or the first step of a rider),
#[1] means depends on 1,2,3..., [2] means 2,4...etc, [2,3] means both 2,4... and 3,6,... would be OK
def counts(n):
riders=[x+1 for x in range (math.floor(n/2))]
leapers=[x+1 for x in range (n)]
rider_count=len(riders)
leaper_count=len(leapers)
print(f'riders is {riders}')
print(f'leapers is {leapers}')
possibilities=[]
for r_indices in range (2**rider_count): # iterate over all combinations
r_entries=getBitVector(r_indices,rider_count)
for l_indices in range (2**leaper_count):
l_entries=getBitVector(l_indices,leaper_count)
dependency=[([]) for x in range (n+1)]
for i,r_value in enumerate(r_entries):
if r_value==0: continue
stride=riders[i]
dependency[stride]=[0] # other entries don't matter for the first step
current=stride*2
while current<=n:
if isRiderRelevant(stride,dependency[current]):
dependency[current]=[x for x in dependency[current] if stride%x!=0]
dependency[current].append(stride)
dependency[current].sort()#keep it sorted
# if stride is included in this list or any entry is divided by it (makes it obsolete)
# or any entry is 0 (leaper), skip it; otherwise add stride to the list,
# and remove any entry that is made obsolete by it (divides stride)
current=current+stride
for i,l_value in enumerate(l_entries):
if l_value==0: continue
stride=leapers[i]
dependency[stride]=[0] # other entries don't matter for the leaper
isNew=True
for p in possibilities:
if listEqual(dependency,p)==True:
isNew=False
break
if isNew==True:
possibilities.append(dependency)
return possibilities
result=counts(7)
pretty_print_possibilities(result)
print(f'count is {len(result)}')
According to the code, the number of ways to combine leapers and riders in a direction with 7 possible target squares is 329 (and for 2 and 3 it agrees with manual analysis too).
So the total number of combinations is
2^14 (leapers-only directions) * 329 ( 1,0 direction) * 329 (1,1 direction) * 11 (2,1 direction) * 5 (3,1 direction) * 5 (3,2 direction) = 487690649600
or 487690649599 (minus 1) if you exclude the possibility of having no movement at all. If (0,0) is considered a valid vector (a move that passes the turn/does nothing) then it's like another "direction" and the total number is doubled :
487690649600 * 2 = 975381299200
Or 975381299199 if you exclude the possibility of having no abilities at all.
I hope I didn't make more mistakes, but please let me know if you found any errors.