string match string index out of range - python

Could someone please explain to me why this won't work? I could always copy the answer, but then I wouldn't learn why this didn't work.
a scrrenshot of the problem, my work, and the error
Given 2 strings, a and b, return the number of the positions where they contain the same length 2 substring. So "xxcaazz" and "xxbaaz" yields 3, since the "xx", "aa", and "az" substrings appear in the same place in both strings.
def string_match(a, b):
count = 0
if len(a) or len(b) == 0:
return count
else:
if len(a)> len(b):
for n in range(len(a)-2):
if a[n]==b[n]:
count +=1
else:
for n in range(len(b)-2):
if b[n]==a[n]:
count+=1
return count
Thank you so much!!
I tried using index locations to find matching characters in 2 strings

You should use the length of the shortest string in the loop. So you should switch your condition
from
if len(a) > len(b):
for n in range(len(a)-1):
to
if len(a) < len(b):
for n in range(len(a)-1):
That's for the Index out of range error, yet as mentionned in the comments there are some other bugs in your code
# first condition
if len(a) == 0 or len(b) == 0:
return 0
Full code
def string_match(a, b):
count = 0
if len(a) == 0 or len(b) == 0:
return 0
if len(a) < len(b):
for n in range(len(a)):
if a[n] == b[n]:
count += 1
else:
for n in range(len(b)):
if a[n] == b[n]:
count += 1
return count
NOTE your code does not answer the given task, take your time to develop a better solution

thank you for your help! I made the following adjustments and the code works!
def string_match(a, b):
count = 0
n=0
if len(a) == 0 or len(b) == 0:
return 0
else:
if len(a) < len(b):
for n in range(len(a)-1):
if a[n:n+2] == b[n:n+2]:
count += 1
else:
for n in range(len(b)-1):
if a[n:n+2] == b[n:n+2]:
count += 1
return count

Related

Finding sum of a fibonacci consistent subarray

We have an input integer let's say 13. We can find consistent subarray of fibonacci numbers that sums to 10 - [2,3,5]. I need to find next number that is not a sum of consistent subarray. In this case this number will be 14. I have this code, but the catch is, it can be optimized to not iterate through all of the N's from starting Left Pointer = 1 and Right Pointer = 1 but somehow "import" from previous N and i have no clue how to do it so maybe someone smarter might help.
def fib(n):
if n == 1: return 1
if n == 2: return 1
return fib(n-1) + fib(n-2)
def fibosubarr(n):
L_pointer = 1
R_pointer = 2
sumfibs = 1
while sumfibs != n:
if sumfibs > n and L_pointer < R_pointer:
sumfibs -= fib(L_pointer)
L_pointer += 1
elif sumfibs < n and L_poiner < R_pointer:
sumfibs += fib(R_pointer)
R_pointer += 1
else: return False
return True
n = int(input())
while fibosubarr(n):
n += 1
print(n)
Here's a technique called "memoizing". The fib function here keeps track of the current list and only extends it as necessary. Once it has generated a number, it doesn't need to do it again.
_fib = [1,1]
def fib(n):
while len(_fib) <= n:
_fib.append( _fib[-2]+_fib[-1] )
return _fib[n]
With your scheme, 200000 caused a noticeable delay. With this scheme, even 2 billion runs instantaneously.
To get the next subarray sum, you only need one call of the function -- provided you keep track of the least sum value that was exceeding n.
I would also use a generator for the Fibonacci numbers:
def genfib():
a = 1
b = 1
while True:
yield b
a, b = b, a + b
def fibosubarr(n):
left = genfib()
right = genfib()
sumfibs = next(right)
closest = float("inf")
while sumfibs:
if sumfibs > n:
closest = min(sumfibs, closest)
sumfibs -= next(left)
elif sumfibs < n:
sumfibs += next(right)
else:
return n
return closest
Now you can do as you did -- produce the next valid sum that is at least the input value:
n = int(input())
print(fibosubarr(n))
You could also loop to go from one such sum to the next:
n = 0
for _ in range(10): # first 10 such sums
n = fibosubarr(n+1)
print(n)

I'm unable to debug this code, not sure what logic i am missing

Given an array of integers arr of even length n and an integer k.
We want to divide the array into exactly n/2 pairs such that the sum of each pair is divisible by k.
Return True If you can find a way to do that or False otherwise.
e.g.
arr = [1,2,3,4,5,10,6,7,8,9], k = 5, output: True
arr = [-1,-1,-1,-1,2,2,-2,-2], k = 3, output: False
The code i've written:
def canArrange(self, arr: List[int], k: int) -> bool:
dictt = {}
for i in range(len(arr)):
arr[i] = arr[i] % k
if arr[i] not in dictt:
dictt[arr[i]] = 1
else:
dictt[arr[i]] += 1
count = 0
for num in arr:
if (k-num) == num:
if dictt[num] > 1:
dictt[num] -= 2
count += 1
else:
dictt[num] -= 1
if (k-num) in dictt and dictt[(k-num)] != 0 and dictt[num] != 0:
dictt[(k-num)] -= 1
dictt[num] -= 1
count += 1
elif num == 0 and dictt[num] > 1:
dictt[num] -= 2
count += 1
if count == len(arr)//2:
return True
else:
return False
My logic is I am first taking the count of "every element % k" and the finding its another pair and reducing the count of both to avoid duplicates, one special case is when the values in a pair are same so for that i am already decrementing the value in my dictionary and at last i am checking whether the number of pairs are equal to half of elements or not
I am able to pass 93/97 test cases on leetcode, and unable to debug for the rest as the length of these 4 test cases are huge hence not possible manually, i must be missing some points while setting my logic, kindly help
Edit: DONE (I have edited the code above)

Python lowest missing integer: Codility Demo Task. What am I missing?

I'm playing with the Codality Demo Task. It's asking to design a function which determines the lowest missing integer greater than zero in an array.
I wrote a function that works, but Codility tests it as 88% (80% correctness). I can't think of instances where it would fail.
def solution(A):
#If there are negative values, set any negative values to zero
if any(n < 0 for n in A):
A = [(i > 0) * i for i in A]
count = 0
else: count = 1
#Get rid of repeating values
A = set(A)
#At this point, we may have only had negative #'s or the same # repeated.
#If negagive #'s, or repeated zero, then answer is 1
#If repeated 1's answer is 2
#If any other repeated #'s answer is 1
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
#Sort the array
A = sorted(A)
for j in range(len(A)):
#Test to see if it's greater than zero or >= to count. If so, it exists and is not the lowest integer.
#This fails if the first # is zero and the second number is NOT 1
if (A[j] <= count or A[j] == 0): #If the number is lt or equal to the count or zero then continue the count
count = count + 1
elif (j == 1 and A[j] > 1): return 1
else:
return count
return count
UPDATE:
I got this to 88% with the fixes above. It still fails with some input. I wish Codility would give the inputs that fail. Maybe it does with a full subscription. I'm just playing with the test.
UPDATE 2: Got this to 100% with Tranbi's suggestion.
def solution(A):
#Get rid of all zero and negative #'s
A = [i for i in A if i > 0]
#At this point, if there were only zero, negative, or combination of both, the answer is 1
if (len(A) == 0): return 1
count = 1
#Get rid of repeating values
A = set(A)
#At this point, we may have only had the same # repeated.
#If repeated 1's answer is 2
#If any other repeated #'s only, then answer is 1
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
#Sort the array
A = sorted(A)
for j in range(len(A)):
#Test to see if it's >= to count. If so, it exists and is not the lowest integer.
if (A[j] <= count): #If the number is lt or equal to the count then continue the count
count = count + 1
else:
return count
return count
Besides that bug for len=1, you also fail for example solution([0, 5]), which returns 2.
Anyway... Since you're willing to create a set, why not just make this really simple?
def solution(A):
A = set(A)
count = 1
while count in A:
count += 1
return count
I don't think this is true:
#At this point, we may have only had negative #'s or the same # repeated. If so, then the answer is 1+ the integer.
if (len(A) == 1):
return list(A)[0]+1
If A = [2] you should return 1 not 3.
Your code is quite confusing though. I think you could replace
if any(n < 0 for n in A):
A = [(i > 0) * i for i in A]
with
A = [i for i in A if i > 0]
What's the point of keeping 0 values?
I don't think this is needed:
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
It's already taken into account afterwards :)
Finally got a 100% score.
def solution(A):
# 1 isn't there
if 1 not in A:
return 1
# it's easier to sort
A.sort()
# positive "hole" in the array
prev=A[0]
for e in A[1:]:
if e>prev+1>0:
return prev+1
prev=e
# no positive "hole"
# 1 is in the middle
return A[-1]+1

prime number function python from list

Below is my code to make a prime number list from Fibonacci list, but the prime list is not working.
what am I missing? I need to make a prime number list from Fibonacci list.
a1 = []
a2 = []
count = 0
n = int(input())
def fib(n):
a = 1
b = 1
a1.append(a)
a1.append(b)
for i in range(n):
c = a + b
a = b
b = c
if len(a1) <= n - 1:
a1.append(c)
print(a1)
print(len(a1))
fib(n)
def pr(a1):
count = 0
for i in a1:
for j in range(2, i):
if i % j == 0:
count += 1
if count > 0:
a2.append()
print(a2)
why the prime number list not working?
I made some fixes to your code:
def fib(n):
a = 1
b = 2
a1.append(a)
a1.append(b)
for i in range(n):
c=a+b
a=b
b=c
if len(a1)<=n-1:
a1.append(c)
print(a1)
print(len(a1))
def pr(a1):
for i in a1:
isPrime = True
for j in range(2,i):
if i % j == 0:
isPrime = False
break
if isPrime:
a2.append(i)
print(a2)
a1=[]
a2=[]
n=int(input())
fib(n)
pr(a1)
You never called the function pr(). It seems a bit, like you are not quite sure how functions work, maybe read a bit into them (or just ask away :) )
Since you already append a and b anyway, why not start them of with the correct fibonacci sequence (1, 2,..) to avoid duplicates?
I changed the code to find prime numbers a bit, to make it a tiny bit faster. I'm sure this is by no means the optimized, but at least it immedately breaks the loop, if it is clear, that we don't have a prime number.
In pr() you used the append() method without an argument. You need to tell the program what you want to append to the list. As far as I can tell this is, where you got an exception.
Hope this helps a bit.
Try the below code. Edited your code and a2 will give prime numbers in the fibonacci list.
a1 = []
a2 = []
def recur_fibo(n):
if n <= 1:
return n
else:
return(recur_fibo(n-1) + recur_fibo(n-2))
n = 10
if n > 0:
for i in range(n):
a1.append(recur_fibo(i))
for num in a1:
if num > 1:
for i in range(2,num):
if (num % i) == 0:
break
else:
a2.append(num)
print(a2)

Python given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A in O(n) time complexity

For example:
input: A = [ 6 4 3 -5 0 2 -7 1 ]
output: 5
Since 5 is the smallest positive integer that does not occur in the array.
I have written two solutions to that problem. The first one is good but I don't want to use any external libraries + its O(n)*log(n) complexity. The second solution "In which I need your help to optimize it" gives an error when the input is chaotic sequences length=10005 (with minus).
Solution 1:
from itertools import count, filterfalse
def minpositive(a):
return(next(filterfalse(set(a).__contains__, count(1))))
Solution 2:
def minpositive(a):
count = 0
b = list(set([i for i in a if i>0]))
if min(b, default = 0) > 1 or min(b, default = 0) == 0 :
min_val = 1
else:
min_val = min([b[i-1]+1 for i, x in enumerate(b) if x - b[i - 1] >1], default=b[-1]+1)
return min_val
Note: This was a demo test in codility, solution 1 got 100% and
solution 2 got 77 %.
Error in "solution2" was due to:
Performance tests ->
medium chaotic sequences length=10005 (with minus) got 3 expected
10000
Performance tests -> large chaotic + many -1, 1, 2, 3 (with
minus) got 5 expected 10000
Testing for the presence of a number in a set is fast in Python so you could try something like this:
def minpositive(a):
A = set(a)
ans = 1
while ans in A:
ans += 1
return ans
Fast for large arrays.
def minpositive(arr):
if 1 not in arr: # protection from error if ( max(arr) < 0 )
return 1
else:
maxArr = max(arr) # find max element in 'arr'
c1 = set(range(2, maxArr+2)) # create array from 2 to max
c2 = c1 - set(arr) # find all positive elements outside the array
return min(c2)
I have an easy solution. No need to sort.
def solution(A):
s = set(A)
m = max(A) + 2
for N in range(1, m):
if N not in s:
return N
return 1
Note: It is 100% total score (Correctness & Performance)
def minpositive(A):
"""Given an list A of N integers,
returns the smallest positive integer (greater than 0)
that does not occur in A in O(n) time complexity
Args:
A: list of integers
Returns:
integer: smallest positive integer
e.g:
A = [1,2,3]
smallest_positive_int = 4
"""
len_nrs_list = len(A)
N = set(range(1, len_nrs_list+2))
return min(N-set(A)) #gets the min value using the N integers
This solution passes the performance test with a score of 100%
def solution(A):
n = sorted(i for i in set(A) if i > 0) # Remove duplicates and negative numbers
if not n:
return 1
ln = len(n)
for i in range(1, ln + 1):
if i != n[i - 1]:
return i
return ln + 1
def solution(A):
B = set(sorted(A))
m = 1
for x in B:
if x == m:
m+=1
return m
Continuing on from Niroj Shrestha and najeeb-jebreel, added an initial portion to avoid iteration in case of a complete set. Especially important if the array is very large.
def smallest_positive_int(A):
sorted_A = sorted(A)
last_in_sorted_A = sorted_A[-1]
#check if straight continuous list
if len(sorted_A) == last_in_sorted_A:
return last_in_sorted_A + 1
else:
#incomplete list, iterate to find the smallest missing number
sol=1
for x in sorted_A:
if x == sol:
sol += 1
else:
break
return sol
A = [1,2,7,4,5,6]
print(smallest_positive_int(A))
This question doesn't really need another answer, but there is a solution that has not been proposed yet, that I believe to be faster than what's been presented so far.
As others have pointed out, we know the answer lies in the range [1, len(A)+1], inclusively. We can turn that into a set and take the minimum element in the set difference with A. That's a good O(N) solution since set operations are O(1).
However, we don't need to use a Python set to store [1, len(A)+1], because we're starting with a dense set. We can use an array instead, which will replace set hashing by list indexing and give us another O(N) solution with a lower constant.
def minpositive(a):
# the "set" of possible answer - values_found[i-1] will tell us whether i is in a
values_found = [False] * (len(a)+1)
# note any values in a in the range [1, len(a)+1] as found
for i in a:
if i > 0 and i <= len(a)+1:
values_found[i-1] = True
# extract the smallest value not found
for i, found in enumerate(values_found):
if not found:
return i+1
We know the final for loop always finds a value that was not marked, because it has one more element than a, so at least one of its cells was not set to True.
def check_min(a):
x= max(a)
if x-1 in a:
return x+1
elif x <= 0:
return 1
else:
return x-1
Correct me if i'm wrong but this works for me.
def solution(A):
clone = 1
A.sort()
for itr in range(max(A) + 2):
if itr not in A and itr >= 1:
clone = itr
break
return clone
print(solution([2,1,4,7]))
#returns 3
def solution(A):
n = 1
for i in A:
if n in A:
n = n+1
else:
return n
return n
def not_in_A(a):
a=sorted(a)
if max(a)<1:
return(1)
for i in range(0,len(a)-1):
if a[i+1]-a[i]>1:
out=a[i]+1
if out==0 or out<1:
continue
return(out)
return(max(a)+1)
mark and then find the first one that didn't find
nums = [ 6, 4, 3, -5, 0, 2, -7, 1 ]
def check_min(nums):
marks = [-1] * len(nums)
for idx, num in enumerate(nums):
if num >= 0:
marks[num] = idx
for idx, mark in enumerate(marks):
if mark == -1:
return idx
return idx + 1
I just modified the answer by #najeeb-jebreel and now the function gives an optimal solution.
def solution(A):
sorted_set = set(sorted(A))
sol = 1
for x in sorted_set:
if x == sol:
sol += 1
else:
break
return sol
I reduced the length of set before comparing
a=[1,222,3,4,24,5,6,7,8,9,10,15,2,3,3,11,-1]
#a=[1,2,3,6,3]
def sol(a_array):
a_set=set()
b_set=set()
cnt=1
for i in a_array:
#In order to get the greater performance
#Checking if element is greater than length+1
#then it can't be output( our result in solution)
if i<=len(a) and i >=1:
a_set.add(i) # Adding array element in set
b_set.add(cnt) # Adding iterator in set
cnt=cnt+1
b_set=b_set.difference(a_set)
if((len(b_set)) > 1):
return(min(b_set))
else:
return max(a_set)+1
sol(a)
def solution(A):
nw_A = sorted(set(A))
if all(i < 0 for i in nw_A):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
For better performance if there is a possibility to import numpy package.
def solution(A):
import numpy as np
nw_A = np.unique(np.array(A))
if np.all((nw_A < 0)):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
def solution(A):
# write your code in Python 3.6
min_num = float("inf")
set_A = set(A)
# finding the smallest number
for num in set_A:
if num < min_num:
min_num = num
# print(min_num)
#if negative make positive
if min_num < 0 or min_num == 0:
min_num = 1
# print(min_num)
# if in set add 1 until not
while min_num in set_A:
min_num += 1
return min_num
Not sure why this is not 100% in correctness. It is 100% performance
def solution(A):
arr = set(A)
N = set(range(1, 100001))
while N in arr:
N += 1
return min(N - arr)
solution([1, 2, 6, 4])
#returns 3

Categories

Resources