Reputation: 45
I am a novice programmer and I feel that I have very fundamental misunderstandings which I am trying to identify. In this question, I am going to be working out my logic to a coding challenge in order to help you identify the misconceptions I am experiencing. The context of this question is the Hackerrank Interview Kit problem "Left Rotation". https://www.hackerrank.com/challenges/ctci-array-left-rotation/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays&h_r=next-challenge&h_v=zen
It says the following in regards to the input format:
The first line contains two space-separated integers n and d, the size of a and the number of left rotations. The second line contains space-separated integers, each an a[i].
Then it gives an example input:
5 4
1 2 3 4 5
My approach to this problem:
What I want is to create 2 loops. One loop to repeat the following process d times, (ie. 4 times), and a nested loop that goes through the whole second input string (1 2 3 4 5), and does the following:
sets the value of the first index (ie: 1) of the second input string (ie: 1 2 3 4 5) to a variable called temp. (I was thinking the line of code that does this would look something like this: temp = a[1]. But is this correct syntactically? Can i do this? Because will python recognize 1 2 3 4 5 as an array automatically, or do I have to convert this second input line from a string to an array, first?)
Next, for every index of the second input line EXCEPT for the last, change the value of that index to equal the value of the next index in the sequence. So, a[1] = 2, a[2] = 3, a[3] = 4, and a[4] = 5. My logic is that at the end of this step, the line should now be this: 2 3 4 5 5. (I was thinking the line of code that does this would look something like this:
for i in len(a-1):
i = [i + 1].
(Is this correct syntactically? I feel like there is something wrong with this line, but I am not sure what it is.)
Set the last index of the array to the temp value. (I was thinking the line of code that does this would be the following: a[n] = temp. Again, unsure about my syntax. By my logic, I would imagine that the input line now looks like this: 2 3 4 5 1. (Also, how does python know what n: is? I understand that the first input line is in the format n,d, but how does python know what those variables stand for? How do I tell it?)
This process happens d times. So the final result to return once the loop finishes would be the rotated array, which would be: 5 1 2 3 4. But I am even confused on how to write the line for the return statement.
With this logic in mind, here is my code:
def rotLeft(a, d):
i = 0
newArr = []
for i in range (d):
temp = a[1]
for i in len(a-1):
i = [i + 1]
a[n] = temp
a = newArr
return newArr
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
first_multiple_input = input().rstrip().split()
n = int(first_multiple_input[0])
d = int(first_multiple_input[1])
a = list(map(int, input().rstrip().split()))
result = rotLeft(a, d)
fptr.write(' '.join(map(str, result)))
fptr.write('\n')
fptr.close()
I am getting a runtime error, which I know can be caused by a number of things.
Overall, I am wondering if someone can help me identify any places where I am going wrong in my syntax or logic. I think one of my main points of confusion is the relationship between the input strings and the values being passed into the function. Any contributions are severely appreciated. Thank you.
Upvotes: 0
Views: 121
Reputation: 311
Ewan Brown nailed it. For completeness, I'll add an even more concise implementation using itertools:
from itertools import cycle, islice
def rotLeft(a, d):
return islice(cycle(a), d, len(a)+d)
cycle is a functional and abstract way to express the idea of "wrapping around" a collection.
Upvotes: 0
Reputation: 19253
There's a number of syntax errors, but HackerRank likely wouldn't accept an approach where you'd perform one left rotation at a time. (The input size is too big for your algorithm to handle in a small amount of time. If you're just starting to program, don't worry too much about what this means; Ewan Brown is right that correctness is infinitely more important than efficiency. This is solely meant to serve as an explanation to motivate why I'm giving a different approach as opposed to debugging the one you've laid out.)
Instead, what you should do is create a new array that rotates an element by d
(since you know the offset in advance). This is faster: in essence, you'd be performing the left rotation for each element all at once, rather than over many steps.
def rotLeft(a, d):
result = [0] * len(a)
for index, element in enumerate(a):
result[((index - d) + len(a)) % len(a)] = element
return result
Upvotes: 1
Reputation: 637
When you find yourself stuck it's never a bad idea to step back and go to the basics.
I suggest starting your problem by writing down a few of the possible cases on paper and trying to spot patterns, before you write ANY code.
Write your code in iterations, starting with something very simple and slowly work towards your end goal.
Loop through the existing array, adding it's elements to the newlist at the original elements index plus the shift amount, then apply modulus of the length of the original list to have it 'wrap' around.
Here's a helpful link if you aren't sure how modulus works
def rotLeft(a, d):
new_list = []
for i in range(len(a)):
new_list.append(a[(i+d) % len(a)]);
return new_list
Upvotes: 2