Python Program to find out the number of rooms in which a prize can be hidden


Suppose, in a game show there are 2n number of rooms that are arranged in a circle. In one of the rooms, there is a prize that the participants have to collect. The rooms are numbered from 1, 2, 3,...., n, -n, -(n - 1),...., -1. in a clockwise manner. Each room has a door and by that door, a different room can be visited. Every door has a marking x on it, which means another room is located at a distance of x from the current room. If the value of x is positive, then the door opens to the xth room in the clockwise direction from that room. If the value of x is negative, then it means the room opens to the xth room in the anti-clockwise direction. We have to find out the number of rooms in which the prize can be kept and the participants have difficulty finding the prize.

So, if the input is like input_array = [[4, 2]], then the output will be [2]

The input has two values, the first value is n that is half the number of rooms, and the second value is the room number where the participants start finding for the prize. Here, there are 2x4 = 8 rooms and the participants start finding the prize from the 2nd room in the clockwise direction. The rooms are numbered like this in a clockwise manner 1, 2, 3, 4, -4, -3, -2, -1. The participants will start visiting the rooms in this manner: 2, -4, -1, 1, 3, -2, -1, 1, 3, -2, ...... So rooms 4 and -3 never get visited, if the prize is hidden in one of these two rooms then the participants can't find it.

To solve this, we will follow these steps −

  • Define a function prime_num_find() . This will take n
    • p_nums := a new list initialized with value 2

    • check := a new list containing byte representations of elements

  • for value in range 3 to n, increase by 2, do

    • if check[value] is non-zero, then
      • go for next iteration
    • insert value at the end of p_nums
    • for i in range 3 * value to n, update in each step by 2 * value, do
      • check[i] := 1
    • return p_nums
  • Define a function factor_finder() . This will take p
    • p_nums := prime_num_find(45000)
    • f_nums := a new map
  • for each value in p_nums, do
    • if value * value > p is non-zero, then
      • come out from the loop
    • while p mod value is same as 0, do
      • p := floor value of (p / value)
      • if value is in f_nums, then
        • f_nums[value] := f_nums[value] + 1
      • else,
        • f_nums[value] := 0
  • if p > 1, then
    • f_nums[p] := 1
    • return f_nums
  • Define a function euler_func() . This will take p
    • f_nums := factor_finder(p)
    • t_value := 1
  • for each value in f_nums, do
    • t_value := t_value * ((value-1) * value^(f_nums[value] - 1))
      • return t_value
  • From the main function/method, do the following −
  • output := a new list
  • for each item in input_array, do
    • p := item[0]
    • q := item[1]
    • r := 2 * p + 1
    • r := floor value of (r / gcd value of (r, q mod r))
    • t_value := euler_func(r)
    • for each value in factor_finder(t_value), do
      • while t_value mod value is same as 0 and (2 ^ floor value of(t_value / value) mod r) is same as 1, do
        • t_value := floor value of (t_value / value)
    • insert 2 * p - t_value at the end of output
  • return output

Example

Let us see the following implementation to get better understanding −

 Live Demo

import math
def prime_num_find(n):
   p_nums = [2]
   check = bytearray(n)
   for value in range(3, n, 2):
      if check[value]:
         continue
      p_nums.append(value)
      for i in range(3 * value, n, 2 * value):
         check[i] = 1
   return p_nums
def factor_finder(p):
   p_nums = prime_num_find(45000)
   f_nums = {}
   for value in p_nums:
      if value * value > p:
         break
      while p % value == 0:
         p //= value
         f_nums[value] = f_nums.get(value,0) + 1
   if p > 1:
      f_nums[p] = 1
   return f_nums
def euler_func(p):
   f_nums = factor_finder(p)
   t_value = 1
   for value in f_nums:
      t_value *= (value-1) * value ** (f_nums[value]-1)
   return t_value
def solve(input_array):
   output = []
   for item in input_array:
      p, q = item[0], item[1]
      r = 2 * p + 1
      r //= math.gcd(r, q % r)
      t_value = euler_func(r)
      for value in factor_finder(t_value):
         while t_value % value == 0 and pow(2, t_value // value, r) == 1:
t_value //= value
         output.append(2 * p - t_value)
   return output
print(solve([[4, 2]]))

Input

[[4, 2]]

Output

[2]

Updated on: 18-May-2021

369 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements