Cannot fix "list index out of range" - python

I'm trying to write a simple code in python to find the first missing positive integer. My algorithm is to create an array full of zeros with the size of maximum positive integer in the input array+1 (for example if the maximum number is 7, the size of 0's array would be 8). Then I trace the input array and whenever I find a positive number I change the index value+1 in the second array to 1. This is my code:
def minPositive(a):
max_a = max(a)
b = [0]*(max_a+1) # This is the second array initialized to zero
for i in range(len(a)):
if a[i] > 0:
b[a[i]+1]= 1
for j in range(len(b)):
if j != 0:
if b[j] == 0:
return j
But when I code this I face "List index out of range". I traced my program several times but I cannot find the error.

Python indexes from 0, so a list of length n has no nth element. Likewise, a list with n+1 elements has no n+1th element.
One option is for every positive value in a (rather than the value plus 1), the index corresponding to that value in b will be set to 1. You could rewrite your function like this (simplified a bit):
def minPositive(a):
b = [1 if n in a and n > 0 else 0 for n in range(max(a) + 1)]
return b
Or you could just make your list b one element longer.

Related

I am getting error in code in taking input and append it to array

You are given N sticks, where the length of each stick is a positive integer. A cut operation is performed on the sticks such that all of them are reduced by the length of the smallest stick.
Given the length of N sticks, print the number of sticks that are left before each subsequent cut operations. Note: For each cut operation, you have to recalculate the length of smallest sticks (excluding zero-length sticks).
Input
The first line contains a single integer N.
The next line contains N integers separated by space, where each integer represents the length of the ith stick.
6
5 4 4 2 2 8
Output
For each operation, print the number of sticks that are cut, on separate lines.
6
4
2
1
Explanation
import array as arr
n = int(input())
a = arr.array('i',[1002])
for i in range(n):
c = [int(x) for x in input().split()]
a.append(c)
t=n
for i in range(0,1001):
if a[i] > 0:
print(t)
t=t-a[i]
You can't append a list to an integer array. If you want to merge two arrays you can use the extend method.
a.extend(c)
if a is list then below all satisfies but here a is array so we cant append list with array
a = [1,2,3] # a is a list
c = [4] # c is list
it won't give you correct result in any case
print(a.append(c)) # if we do a.append(c) result is like a = [1,2,3,[4]]
gives you correct result in any case
print(a.extend(c)) # if we do a.extend(c) result is like a = [1,2,3,4]
satisfies if "a" is list and "c" is list or "a" is array and "c" is also an array
a += c # a += c result is same as a.extend(c)
print(a) # a = [1,2,3,4]

Need help in Python hackerrank problem solving

So, I am stuck on a question and I am not sure what I am doing wrong with my code.
Question is- Given an array of integers, find the longest subarray where the absolute difference between any two elements is less than or equal to .
Example a = [1,1,2,2,4,4,5,5,5]
There are two subarrays meeting the criterion: and .
The maximum length subarray has elements.
[1,1,2,2] and [4,4,5,5,5]
Returns
int: the length of the longest subarray that meets the criterion
or visit the link Hackerrank Problem
def pickingNumbers(a):
a.sort()
answer = 0
flag = False
for i in range(len(a)-1,1,-1):
count = 0
temp = [list(l) for l in list(itertools.combinations(a,i))]
for j in temp:
for k in range(len(j)-1):
if abs( j[k+1] - j[k] ) <= 1:
count +=1
if count == len(j):
answer = len(j)
break
Note that the statement asks you to to find a subarray, not subsequence. A subarray is a continuous chain of elements from the parent array. Here by sorting the array you are destroying the parent array's order whenever the array given to you is ascending. Hence your program will give wrong output

Smallest Missing Number

I'd like some insight on the following code. The problem says, devise an algorithm that finds the smallest missing number in an array
My Approach:
def small(arr: list) -> int:
s = {*arr}
i = 1
while True:
if i not in s:
return i
i += 1
Easy right?
The problem is this uses space complexity of (n) when I create that extra set
Better Approach:
# Linear time routine for partitioning step of Quicksort
def partition(arr):
pIndex = 0
# each time we find a positive number, `pIndex` is incremented, and
# that element would be placed before the pivot
for i in range(len(arr)):
if arr[i] > 0: # pivot is 0:
arr[i], arr[pIndex] = arr[pIndex], arr[i]
pIndex += 1
# return index of the first non-positive number
return pIndex
# Function to find the smallest missing positive number from an unsorted array
def findSmallestMissing(arr, n):
# Case 1. The missing number is in range 1 to `n`
# do for each array element
for i in range(n):
# get the value of the current element
val = abs(arr[i])
# make element at index `val-1` negative if it is positive
if val - 1 < n and arr[val - 1] >= 0:
arr[val - 1] = -arr[val - 1]
# check for missing numbers from 1 to `n`
for i in range(n):
if arr[i] > 0:
return i + 1
# Case 2. If numbers from 1 to `n` are present in the array,
# then the missing number is `n+1` e.g. [1, 2, 3, 4] —> 5
return n + 1
if __name__ == '__main__':
arr = [1, 4, 2, -1, 6, 5]
k = partition(arr)
print("The smallest positive missing number is",
findSmallestMissing(arr, k))
I don't understand why do we need
if val - 1 < n and arr[val - 1] >= 0:
arr[val - 1] = -arr[val - 1]
findSmallestMissing is really very similar to your set-based solution. The difference is that it uses the sign-bit in the input array as that set. That sign has nothing to do with the value that is stored at the same spot, but with the index. If the sign bit is set it means: I have encountered a value that is this index (after translating a value to an index by subtracting one).
The code you asked about:
if val - 1 < n and arr[val - 1] >= 0:
arr[val - 1] = -arr[val - 1]
First of all, the subtraction of one is there to covert a 1-based value to a 0-based index.
Since we use the array also as a set, this code first checks that the index is in range (of the "set") and then it checks that this index is not yet in the set, i.e. the sign bit at that index is still 0. If so, we add the index to the set, i.e. we set the sign bit at that index to 1.
All in all, one may argue that we cheat here: it is as if we didn't allocate extra memory for maintaining a set, but in reality we used an unused bit. In theory this means we still use extra memory, while in practice that memory was already allocated, but not used. The algorithm assumes that the none of the values in the array are negative.

Non-decreasing Array List Index out of Range

This is a coding challenge from Daily Interview Pro where you are given an array in arbitrary order, and you have to make it an increasing array with 1 modification to the array or less. This is my code:
def check(lst):
count = 0
for i in lst:
if i == lst[-1]:
break
**if i > lst[i+1]:**
count += 1
if count <= 1:
return True
else:
return False
check([13, 4, 7])
#Should return True
The Error is where the stars are. Error: list index out of range. I do not understand this error because I made an if statement for the for loop to break when the for loop gets to the last number. (I have made my indenting correctly, the stars make it look like the indenting is off)
I checked and the value of 'i' is 13 and your list is only if len 3. The value of 'i' depends on the value at the list index. That's why it is giving an error
In your example, the counter i iterates through your list elements - first it becomes 13, then 4, and last 7.
So, when you say lst[i+1], it becomes lst[13+1] == lst[14], which does not exist in your lst, since it goes from lst[0] up to lst[2].
I think you probably mean to iterate using range:
for i in range(len(lst)):
...

python - checking if an array consisting of N integers is a permutation

I am analyzing the routine which checks if an array of N integers is a permutation (sequence containing each element from 1 to N).
I am new to python. I can't grasp how this routine gets the correct answer. Could anybody explain the logic behind the loop? especially the use of the counter[element-1].
Is the counter a built-in function working on every element of A? does the counter[element-1] reference position/value of elements of A by default because the loop is defined on an array?
A=[4,1,3,2]
def solution(A):
counter = [0]*len(A)
limit = len(A)
for element in A:
if not 1 <= element <= limit:
return 0
else:
if counter[element-1] != 0:
return 0
else:
counter[element-1] = 1
return 1
Update:
I modified the code to see the values used within the loop, for example
def solution(A):
counter = [0]*len(A)
limit = len(A)
for element in A:
if not 1 <= element <= limit:
print element
print 'outside'
return 0
else:
if counter[element-1] != 0:
print 'element %d' % element
print [element-1]
print counter[element-1]
return 0
else:
counter[element-1] = 1
print 'element %d' % element
print [element-1]
print counter[element-1]
return 1
gives me
element 4
[3]
1
element 1
[0]
1
element 3
[2]
1
element 2
[1]
1
1
I still don't get the logic. For example fot the first element, why [3] gives 1?
The idea behind the code is twofold. A permutation of the list [1, 2, ..., N] has two properties. It has only elements between 1 and N and each element just appear one time in the list.
I will try explain it to you part by part this idea in the code.
def solution(A):
counter = [0]*len(A)
limit = len(A)
Assume as an example, a list [1, 3, 2].
counter is initialized as a list of zeros of size len(A) = 3. Each 0 correspond to one of the elements of the list
for element in A:
if not 1 <= element <= limit:
return 0
This part condition is the most easy one. If the element is not in this range, the list cannot be a permutation of [1, 2,...N]. For instance, [1, 3, 2] is a permutation of [1, 2, 3] but [1, 6, 2] is not.
else:
if counter[element-1] != 0:
return 0
else:
counter[element-1] = 1
This next part is related with the uniqueness of each term. The if checks if a number = element has already passed through this loop. The second else make sure that this number is marked, so if a repeated number is found in the next iterations, the if will be true and return 0.
For instance, for the list [1, 2, 2]. The first 2 would not trigger the if, while the second 2 would trigger it, returning 0. On the other hand, [1, 3, 2], would never trigger the if.
If all the number pass this conditions, the two properties were true and the list is a permutation.
Quite a cunning algorithm actually.
The input is a sequence of length N.
Each element of input is presumed to be an integer (if not, either comparison or indexing will throw an exception).
counter is an array of flags - of length N, too.
No integers outside of [1,N] range are allowed
No duplicates are allowed (see how it's done)
Can you now prove that the only way for both conditions to stay true is for the sequence to be a permutation?

Categories

Resources