I recently got onto the following problem: we consider the following array:
A = [2, 3, 6, 1, 6, 4, 12, 24]
we need to count the number of times these two conditions are satisfied within the array:
A[i] * A[j] * A[k] = A[l] so that 0 <= i < j < k < l < len(A)
for this example the result should be 8. example of satisfied conditions within the array:
2 * 3 * 1 = 6
2 * 6 * 1 = 12
6 * 1 * 4 = 24
3 * 1 * 4 = 12
The straightforward solution I created using python:
A = [2, 3, 6, 1, 6, 4, 12, 24]
result = 0
for i in range(len(A)):
for j in range(i + 1, len(A)):
for k in range(j + 1, len(A)):
for l in range(k + 1, len(A)):
if A[i] * A[j] * A[k] == A[l]:
result += 1
print(result)
I need to find a way to speed up the program using dynamic, maybe memoization or pre computing.
result = 0
for i in range(A):
for j in range(i + 1, A):
for k in range(j + 1, A):
#TODO
print(result)
I was thinking of creating a dictionary that contains a set of dictionaries for each number, to indicate the number and its position, example:
speed_up = {
6: {
2: True
4: True
},
1: {
3: True
},
...
}
then we check like the following:
result = 0
for i in range(A):
for j in range(i + 1, A):
for k in range(j + 1, A):
x = A[i] * A[j] * A[k]
if x in speed_up:
result += len([z[0] for z in speed_up[x].items() if z[0] > k])
This way we will count all occurrences of the same number after the index k at once, we will not have to go through all array.
Please let me know if my optimisation is flawed, and if there's better optimisation using dynamic programming techniques such as memoization or pre computing.