# Function for recognize quantity of unique combinations browsing

• posted
1

Hello pythonista community. Can someone adwise me formula for recognize quantity of unique combinations when you count to some max digit with sign "-" (minus)? Answer can't be under zero.

Example1:
sign = '-'
max = 2
2-2
2-1
1-1

• we have only three unique combinations.

Example2:
answer can't be upper max:
max = 2
1+1

• we have only one unique example.

I already have formula for two signs "+-": unic_col=max**2

But i need formula for '+' and '-'
And maybe someone know for:
+-×
+-/
+-×/

So, i need function like that:

def uniques_col(operators, max):
if operators == '+-':
return max**2
elif operators == '+':
return .....
elif operators == '-':
return .....
elif operators == '+-×':
return .....
......

• posted
0

@lyubomyr83 please try this and tell us if non integer result is allowed for division

``````def uniques_col(operators, max):
col = 0
if len(operators) > 1:
for op in operators:
col += uniques_col(op, max)
return col
if operators == '+':
for i in range(1,max):
for j in range(1,max-i+1):
print(i,operators,j,i+j)
col += 1
elif operators == '-':
for i in range(1,max+1):
for j in range(1,i+1):
print(i,operators,j,i-j)
col += 1
elif operators == 'x':
for i in range(1,max+1):
for j in range(1,1+int(max/i)):
print(i,operators,j,i*j)
col += 1

return col

while True:
op = input('operator\n')
max = int(input('max\n'))
``````

• posted
0

@lyubomyr83, here’s a version that tries to be smart where possible. Unfortunately, finding the number of unique combinations for multiplication `*` seems to be directly related to finding the factors of an integer, for which there is no straight-forward formula (hence, public key cryptography works), so we still have to brute-force it.

``````from functools import reduce
from itertools import product

def unique_cols(ops, maximum):

counts = {
'-': lambda m: m*(m+1)//2,
'+': lambda m: m*(m-1)//2,
'/': lambda m: m**2,
'*': lambda m: len(list(filter(
lambda c: 0 <= eval(''.join(c)) <= m,
product([str(i+1) for i in range(m)], '*', [str(i+1) for i in range(m)])
)))
}
return sum([counts[op](maximum) for op in ops])

maximum = int(input('Maximum integer: '))
ops = input('Operations (one of more of +-*/): ')

print('Unique combinations:', unique_cols(ops, maximum))``````

• posted
0

For multiplication, it seems the number would be something like this:. Consider building the 2d multiplication table, 1..N in cold and rows. Then count how many you have in each row that are <=N. To avoid double counting, handle the diagonal separately.

For each row of the multiplication table, excluding the diagonal, you get

``````1*x (x!=1)    ==>  N-1 different possiblities
2*x (x!=2)    ==>  (N//2)-1
...
K*x  (x!=K)    ==>  (N//k)-1
``````

Then for the diagonal, it is the number of x**2<N
Or, x<=sqrt(N)

So the total is:

``````sum([(N//k) for k in range(1,N+1)])-N+floor(sqrt (N) )

Or

sum([(N//k) for k in range(2,N+1)])+floor(sqrt (N) )
``````

Not quite brute force, but order N instead of N**2. You could also make use of the symmetry to only count through sqrt(N), which makes it order sqrt (N)..

``2*sum([(N//k)-k for k in range(1,1+floor(sqrt(N))])+floor(sqrt (N) )``

• posted
0

@JonB, impressive! Need to spend some more time to really follow the logic, but the results match with the brute-force results, so here is the updated version:

``````from itertools import product
from math import floor, sqrt

def unique_cols(ops, maximum):

counts = {
'-': lambda m: m*(m+1)//2,
'+': lambda m: m*(m-1)//2,
'/': lambda m: m**2,
'*': lambda m:
2 * sum([(m//k)-k
for k in range(1, 1 + floor(sqrt(m)))]) +
floor(sqrt(m)),
}
return sum([counts[op](maximum) for op in ops])

maximum = int(input('Maximum integer: '))
ops = input('Operations (one of more of +-*/): ')

print('Unique combinations:', unique_cols(ops, maximum))``````

• posted
0

@mikael shouldn't + and - be the same? In the table of allowables, in the subtraction case you are allowed everything above the diagonal that is along (1,1) to (N,N) (assuming zero is not allowed?). In the plus case, everything above the other diagonal. So both cases are (NN-N)/2==N(N-1)/2

I guess it depends on whether you allow 1-1=0 and the like. If so you'd add back N, and get N*(N+1)/2.

• posted
0

@JonB for multiplication, do you think it is different of mine

``````        for i in range(1,max+1):
col += int(max/i)
``````

• posted
0

@cvp, oh my goodness, my apologies, it looked so simple I did not even understand it is a solution. Which also checks against the brute-force values, hence the simplified version below.

@JonB, yes, we include 1-1 as per the ”rules”.

``````def unique_cols(ops, maximum):

counts = {
'-': lambda m: m*(m+1)//2,
'+': lambda m: m*(m-1)//2,
'/': lambda m: m**2,
'*': lambda m: sum([m//i for i in range(1, m+1)]),
}
return sum([counts[op](maximum) for op in ops])

maximum = int(input('Maximum integer: '))
ops = input('Operations (one or more of +-*/): ')

print('Unique combinations:', unique_cols(ops, maximum))``````

• posted
0

@mikael said:

it looked so simple

Haha 😂

• posted
0

As terribly interesting as this has been, I am still wondering what it is for...

• posted
0

My last version, still without division due to an unanswered question

``````def uniques_col(operators, max):
col = 0
if len(operators) > 1:
for op in operators:
col += uniques_col(op, max)
return col
if operators == '+':
for i in range(1,max):
col += max - i
# comment next lines if you don't want detail
for j in range(1,max-i+1):
print(i,operators,j,i+j)
elif operators == '-':
for i in range(1,max+1):
col += i
# comment next lines if you don't want detail
for j in range(1,i+1):
print(i,operators,j,i-j)
elif operators == 'x':
for i in range(1,max+1):
col += int(max/i)
# comment next lines if you don't want detail
for j in range(1,1+int(max/i)):
print(i,operators,j,i*j)

return col

while True:
op = input('operator\n')
max = int(input('max\n'))
print(uniques_col(op,max))

``````

Internal error.

Oops! Looks like something went wrong!