-2

Problem Statement -:

Suppose "arr" is an array of 101 elements with every value ranging from 1 to 256.

Now, we need to select 3 different values a, b, c from arr (basically no repetition which means index_value of a, b, c w.r.t. arr should be different) which satisfies below 2 equations.

Eq1 -> 3z = (a - b + 3y - x)%m + 1

Eq 2 -> 2z = (a - c + y)%m + 1

Total no of permutations which needs to be checked will be 101x100x99

% (mod) is the remainder operator in python

x, y, z & arr are known. m is 256. We need to find all possible [a, b, c].

My Try -:

"""Known Values - x, y, z & arr"""
m = 256
no_diff_max = 100
set_value = [0 for i in range(3)]
temp_arr = [i for i in range(no_diff_max + 1)]

"""arr also has (no_diff_max+1) elements, i.e. 101 elements"""

"""To prevent running the loop for full size of 101*100*99, first 2 position arr will be iterated"""
"""Finds all permutations of size 2 (without repeatitions) from temp_arr. Size of perm_arr would be 101*100"""
perm_arr = permutation(temp_arr, 2) 

for perm_set in perm_arr:
  
  """To put the first two values of perm_set in set_value. Third value will be looked in next step"""
  set_value[0] = perm_set[0]
  set_value[1] = perm_set[1]
  
  """Value of a & b are assigned as per the two different index values in perm_set"""
  a = arr[set_value[0]]
  b = arr[set_value[1]]
  
  """Find the value of z from Eq1 as mentioned above. solve_c3 function solves this."""
  z = solve_c3(x, y, a, b, m)
  
  """From value of z, find c. After that, we will find this value in arr"""
  c = (a - 2*z + y)%m + 1
  
  """This will find all the index in arr which equates to s2, meaning arr[index] == s2"""
  indices = find_indices(arr, c)
  if (len(indices) > 0): #If c is present in arr for at least 1 times
    
    """To find the third value of set_value. Total iterations are reduced as we are iterating in limited index values only as against to 99 values"""
    for set_value[2] in indices:
      
      """This condition is to make sure that set_value[2] != set_value[0] & set_value[1]."""
      """This line makes sure that set_value has unique elements always"""
      if (len(set_value) == len(set(set_value))):
        """Here, we can say for sure that set_value array exists with all the unique values. So, one set_value will be counted as one result"""
        

Is there any shorter method possible mathematically to solve this more quickly?

It would be great if someone could suggest me a better method to solve this.

Any help would be appreciated. Thanks in advance!

2 Answers2

0

numpy.linalg.solve can be used to solve linear algebra. But it does not support modulo/reminder option. By looking at your equation we will be able to deduce one equation by subtracting Eq2 from Eq1. Eq3 = Eq1 - Eq2 = Eq3 = 1z = (-b + c + 2y)%m (Where m = 256) As per your question, you know the value of x, y, z and m. By running your code against Eq3 with different combination of b and c, you will be able to get b and c with a = 0

(or) Convert both Eq1 and Eq2 modulo function into linear equation and use numpy.linalg.solve

KJG
  • 93
  • 9
  • Thanks @KJG for answer. My aim is to get all possible a, b, c values, all of them will be choosen from arr and which should also satisfy both equations. So, what I was looking for is if there exist smaller method to determine this compared to my method. Not sure if your suggested method will be able to reduce the computation time. – Vineet Mangal Jul 06 '23 at 15:45
0

You have two equations for three unknowns. In good cases this means that fixing one unknown we get at most one answer. Your case is good.

Working with equations modulo some number (or in fancy words, equations over a finite ring/field) is much more convenient than working with equations that have modulo operations sticked in random places. These look like a = b (mod m) and are equivalent to a % m = b % m. From the two given equations three can be derived for pairwise differences of a, b, c mod 256:

  1. a - b = 3z - 3y + x - 1 (mod 256)
  2. a - c = 2z - y - 1 (mod 256)
  3. c - b = z - 2y + x (mod 256)

This means that if either of the right hand sides is zero (mod 256), difference of two variables is zero and there is no solution due to the requirement that the three variables are different. Perhaps such cases are already excluded. If not, it would be prudent to check this first.

Now to the implementation. Iterate over the 101 possible a values. Knowing a mod 256 you know b mod 256 and c mod 256, so it is trivial to check if such values are present in the array (for example by creating a size-256 boolean array describing what values are present).

Since the desired solutions should be not in 0..255 but in 1..256, 0 "becomes" 256. Since the original equations were not mod 256 but merely contained a modulo operation, each solution should be checked to satisfy the original formulation. But in fact they violate original equations if and only if either z <= 0 or z > 256 / 3 (while the right hand side is always in 1..256), and these cases can be checked beforehand too.

maxplus
  • 502
  • 1
  • 12