1

I was recently trying to solve a HackerEarth problem. The code worked on the sample inputs and some custom inputs that I gave. But, when I submitted, it showed errors for exceeding the time limit. Can someone explain how I can make the code run faster?

Problem Statement: Cyclic shift

A large binary number is represented by a string A of size N and comprises of 0s and 1s. You must perform a cyclic shift on this string. The cyclic shift operation is defined as follows:

If the string A is [A0, A1,..., An-1], then after performing one cyclic shift, the string becomes [A1, A2,..., An-1, A0].

You performed the shift infinite number of times and each time you recorded the value of the binary number represented by the string. The maximum binary number formed after performing (possibly 0) the operation is B. Your task is to determine the number of cyclic shifts that can be performed such that the value represented by the string A will be equal to B for the Kth time.

Input format:

First line: A single integer T denoting the number of test cases For each test case: First line: Two space-separated integers N and K Second line: A denoting the string

Output format:

For each test case, print a single line containing one integer that represents the number of cyclic shift operations performed such that the value represented by string A is equal to B for the Kth time.

Code:

import math


def value(s):
    u = len(s)
    d = 0
    for h in range(u):
        d = d + (int(s[u-1-h]) * math.pow(2, h))
    return d


t = int(input())
for i in range(t):
    x = list(map(int, input().split()))
    n = x[0]
    k = x[1]
    a = input()
    v = 0
    for j in range(n):
        a = a[1:] + a[0]
        if value(a) > v:
            b = a
            v = value(a)
    ctr = 0
    cou = 0
    while ctr < k:
        a = a[1:] + a[0]
        cou = cou + 1
        if a == b:
            ctr = ctr + 1
    print(cou)
James Albert
  • 75
  • 2
  • 7
  • 1
    @Nick, Not necessarily. For example, in the case of the binary number 010101, the number of shifts required to get from the first occurrence of the largest number to the second occurrence of the largest number is 2[and not (2-1)*6 = 6]. – James Albert Aug 15 '20 at 06:56
  • @Nick I don't think your equation will work if the value of K is less than M. For example, in the case of 010101, the value of M is 3. If we give the value of K as 2, the number of shifts between the 1st and 2nd occurrence is 2, which is not satisfied by your equation – James Albert Aug 15 '20 at 07:30
  • @JamesAlbert you're right, I'm going to delete all those comments... – Nick Aug 15 '20 at 07:33

2 Answers2

2

In the problem, the constraint on n is 0<=n<=1e5. In the function value(), you calculating integer from the binary string whose length can go up to 1e5. so the integer calculating by you can go as high as pow(2, 1e5). This surely impractical.

As mentioned by Prune, you must use some efficient algorithms for finding a subsequence, say sub1, whose repetitions make up the given string A. If you solve this by brute-force, the time complexity will be O(n*n), as maximum value of n is 1e5, time limit will exceed. so use some efficient algorithm.

  • Please note you are answering a already answered question. Here is a guide on [How to Answer](http://stackoverflow.com/help/how-to-answer). Please make sure you add either a new solution, or a substantially better explanation, especially when answering older questions. – help-info.de Aug 19 '20 at 07:33
1

I can't do much with the code you posted, since you obfuscated it with meaningless variables and a lack of explanation. When I scan it, I get the impression that you've made the straightforward approach of doing a single-digit shift in a long-running loop. You count iterations until you hit B for the Kth time.

This is easy to understand, but cumbersome and inefficient.

Since the cycle repeats every N iterations, you gain no new information from repeating that process. All you need to do is find where in the series of N iterations you encounter B ... which could be multiple times.

In order for B to appear multiple times, A must consist of a particular sub-sequence of bits, repeated 2 or more times. For instance, 101010 or 011011. You can detect this with a simple addition to your current algorithm: at each iteration, check to see whether the current string matches the original. The first time you hit this, simply compute the repetition factor as rep = len(a) / j. At this point, exit the shifting loop: the present value of b is the correct one.

Now that you have b and its position in the first j rotations, you can directly compute the needed result without further processing.

I expect that you can finish the algorithm and do the coding from here.


Ah -- taken as a requirements description, the wording of your problem suggests that B is a given. If not, then you need to detect the largest value.

To find B, append A to itself. Find the A-length string with the largest value. You can hasten this by finding the longest string of 1s, applying other well-known string-search algorithms for the value-trees after the first 0 following those largest strings.

Note that, while you iterate over A, you look for the first place in which you repeat the original value: this is the desired repetition length, which drives the direct-computation phase in the first part of my answer.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Thank you for the clarification. I will implement this algorithm to see how it works. I apologize for the code structure. I will improve it further on. – James Albert Aug 15 '20 at 07:50
  • Hi @Prune could you explain what you mean by "check to see whether the current string matches the original". If it matches the original then it itself is an original string, which means that when you exit the shift loop, you'll end up with the input, no? – Vocaloidas Oct 23 '20 at 22:43
  • That's correct. Once you repeat the value of `B`, you exit the shifting loop. You compute the output from the data gathered so far; there is nothing new to discover by additional shifting. – Prune Oct 23 '20 at 23:48
  • @Prune but it's not clear how this finds the value of B. I understand that he's attempting to transcribe the binary string into some integer and then attempting to find the max, but the binary string is way too big to be represented by the available structures. I'm trying to understand how to find B without actually having to convert it into the value. Based on your explanation, It seems that all you get is some j index at which the original pattern repeats itself, but how does this help finding B? Could you elaborate an example please. – Vocaloidas Oct 24 '20 at 18:01