print the smallest subarray with sum greater than or equal target - python-3.x

```import sys
# Function to find the smallest subarray
# with sum greater than or equal target
def minlt(arr, target, n):
# DP table to store the
# computed subproblems
dp = [[-1 for _ in range(target + 1)]\
for _ in range(len(arr)+1)]
#pf = [-1 for _ in range(len(arr)+1)]
for i in range(len(arr)+1):
# Initialize first
# column with 0
dp[i][0] = 0
for j in range(target + 1):
# Initialize first
# row with 0
dp[0][j] = sys.maxsize
for i in range(1, len(arr)+1):
for j in range(1, target + 1):
# Check for invalid condition
if arr[i-1] > j:
dp[i][j] = dp[i-1][j]
else:
# Fill up the dp table
#if dp[i-1][j] == 1 or (1 + dp[i][j-arr[i-1]]) == sys.maxsize:
dp[i][j] = min(dp[i-1][j], \
1 + dp[i][j-arr[i-1]])
return dp[-1][-1]
# Print the minimum length
if dp[-1][-1] == sys.maxsize:
return(-1)
else:
return dp[-1][-1]
# Driver Code
arr = [10,9,2,1]
target = 11
n = len(arr)
print(minlt(arr, target, n))
can anyone make change to this program such that it will print the smallest subarray not the length
This code returns only length of smallest subarray whose sum is greater or equal to given target
Thanks in Advance

Here's how In would do what you want.
#First the function definition
def minlt(arr, target):
rslt = (None, None, None) #tuple containing the (subarray_sum, subarray_start, sub_array_length)
for i in range(len(arr)-1):
for k in range(i+1, len(arr)):
arsm = sum(arr[i:k])
if arsm >= target:
if rslt[0] == None or rslt[2] > k-i+1 or (rslt[2] == k-i+1 and rslt[0] > arsm):
rslt = (arsm, i, k-i+1)
return arr[rslt[1]:rslt[2]]
Then the call setup:
arr = [10,9,2,1]
target = 11
minlt(arr, target)
Yielding:
[9, 2]

Related

Given a target, find the sum of the target from a list

Given a list of numbers and a target value, I am to find the sum of two numbers that matches the target and returns the indexes of the sum from the array.
I have tried:
nums = [2,5,5,11]
target = 10
def nums_sum_target(nums, target):
for i in range(len(nums)):
for j in range(len(nums)):
if j == len(nums) - 1:
target_sum = nums[i]
else:
print(j+1, "inner loop 2")
target_sum = nums[i] + nums[j+1]
if target_sum == target:
print([nums[i], nums[j+1]])
return [i, j+1]
I expected: [1,2]
I had: [1,1]
If the numbers are sorted, you can take advantage of that and just iterate from both ends like so:
def find_sum(numbers, target):
assert numbers # Should have at least 1 number
left = 0
right = len(numbers) - 1
while left < right:
total = numbers[left] + numbers[right]
if total == target:
return (left, right)
elif total < target:
left += 1
else:
right -= 1
raise LookupError(f"Sum {target} not found")
Testing the function:
numbers = [2, 3, 4, 5]
target = 6
indices = find_sum(numbers, target)
print(indices) # prints (0, 2)
No need for a dictionary or anything else, just the list and the target, and this is an extremely efficient way, with a worse case of O(n).

658. Find K Closest Elements - for loop 'comp' comparison variable not updating as expected

So I am working on problem 658 'Find K Closest Elements'(https://leetcode.com/problems/find-k-closest-elements/), which asks to return a list from the given list, 'arr'. This return list will be the length of 'k' and will contain the 'k' # of values closest to the given 'x' value. I've created all the base cases and constraints, and am now stuck on the comparison part below:
I've created an empty list, 'a'. While the length of 'a' is not 'k', the function will go through the list and compare abs(i - x) < abs(comp - x), 'comp' starting at 'arr[0]' and updating to 'i' if the comparison is true. The problem is that the comparison is not working correctly. Here is an example case I'm trying to figure out:
arr = [1,1,1,10,10,10], k = 4, x = 9
Below is the portion of the code I am focusing on:
a = []
comp = arr[0]
iteration = 0
i_index = 0
while len(a) != k:
for i in arr:
comp_1 = abs(i - x)
comp_2 = abs(comp - x)
if comp_1 < comp_2:
comp == i
print(f"comp: {comp}")
arr.pop(arr.index(comp))
a.append(comp)
return a
I am including the entirety of the code just in case below:
def findClosestElements(self, arr: List[int], k: int, x: int) -> List[int]:
# Constraints
if k < 1 or k > len(arr):
return "k must be greater than 0 and less than the arr length"
if len(arr) < 1 or len(arr) > 10**4:
return "arr length must be greater than 0 and less than 10^4"
if x > 10**4:
return "x must be less than 10^4"
if sorted(arr) != arr:
return "arr must be sorted"
for i in arr:
if i < -10**4:
return "arr item cannot be less than -10^4"
#Variables 1
begin = arr[:k]
end = arr[-k:]
# Base cases
if len(arr) == k:
return arr
if x < arr[0]:
return begin
elif x > arr[-1]:
return end
try:
x_index = arr.index(x)
half_k = int(k/2)
#if k == x and x_index != None:
# return [x]
# Captures all other lists that begin at arr[0] or end at arr[-1]
if x_index - half_k < 0:
return begin
elif x_index + half_k > len(arr) - 1:
return end
# Create list out of interior of arr if necessary
else:
return arr[x_index - half_k : x_index + half_k]
# Means x is not in arr
except ValueError:
a = []
comp = arr[0]
iteration = 0
i_index = 0
while len(a) != k:
for i in arr:
print(f"{iteration} - {i_index}:")
print(f"i: {i}")
print(f"comp_1: {abs(i - x)}")
print(f"comp_2: {abs(comp - x)}")
comp_1 = abs(i - x)
comp_2 = abs(comp - x)
if comp_1 < comp_2:
comp == i
print(f"comp: {comp}")
i_index += 1
print("\n")
iteration += 1
arr.pop(arr.index(comp))
a.append(comp)
return a
I would take the approach of:
finding the shortest distance from x to the elements of arr.
sorting arr by the distances.
So, this is a good method:
arr = [1,1,1,10,10,10]
k = 4
x = 9
distances = [abs(x - n) for n in arr]
Z = [a for _,a in sorted(zip(distances,arr))]
print(Z[:k])
result
[10, 10, 10, 1]

How to search for the index of the number from the last of list to first?

I was checking the documentation to find the index of the number from last to first.
I could use - list.index(number, start, end). In my example, if I omit the start and end I don't get any exception. However, I get an exception when I change the start to the last index and end to the first element index i.e. 0. I am sure I am doing something wrong but I am unable to think about what is going wrong here.
def nonConstructibleChange(coins):
# o(log n) - sorting
coins.sort() # O(log n)
max_amount = sum(coins)
print(max_amount)
# range is [start, end)
if len(coins) == 0:
return 1
for change in range(1, max_amount+1):
if change == 1:
if 1 not in coins:
return 1
else:
max_limit = change - 1
while max_limit not in coins and max_limit != -1:
max_limit -=1
print(coins.index(max_limit, len(coins)-1, 0)) # throws exception
print(coins.index(max_limit)) # this works
if __name__ == '__main__':
coins = [5, 7, 1, 1, 2, 3, 22]
nonConstructibleChange(coins)
You can find the index of the last occurrence of an element by applying index function on the reversed list. In your case this would be:
print(coins[::-1].index(max_limit))
def nonConstructibleChange(coins):
# o(log n) - sorting
coins.sort() # O(log n)
max_amount = sum(coins)
num = None
#print(coins)
#print(max_amount)
# range is [start, end)
if len(coins) == 0:
return 1
for change in range(1, max_amount+1):
if change == 1:
if 1 not in coins:
return 1
else:
max_limit = change
while max_limit not in coins and max_limit != -1:
max_limit -=1
right_index = coins.index(max_limit)
while 1:
try:
# the last index is not included therefore len(coins)
right_index = coins.index(max_limit, right_index +1 , len(coins))
except ValueError:
# print(f'final right_index = {right_index}')
break
print(f'right_index = {right_index}')
print(f'change = {change}')
print(f'max_limit = {max_limit}')
num = change
for idx in reversed(range(right_index + 1)):
if coins[idx] > num:
#print(f'coins[idx] = {coins[idx]} and num = {num}')
continue
#print(f'idx = {idx}')
num = num - coins[idx]
#print(f'num = {num}')
if (num in coins[0:idx-1] or num == 0) and idx != 0:
#print(f'Setting num = {num}')
num = 0
break
if num != 0:
return change
return max_amount + 1
if __name__ == '__main__':
coins = [5, 7, 1, 1, 2, 3, 22]
#coins = [1, 1, 1, 1, 1]
print(nonConstructibleChange(coins))

Counting weighted average doesn't work properly sometimes

I've made a program that counts weighted average and required weighted value to average being equal to our preference. If I want the average be equal to 85 from (the first value in the list is the weight of next values) [[4,72,78],[3,56],[6,93]] and x value of 6 weight it does not output the right value.
def choice(x):
c = 0
Choice = True
choices = []
while Choice:
if choices == []:
if x != 0:
fill = "weight of required value"
else:
fill = "weight of next values"
else:
if x != 0:
fill = "value of wanted weighted average"
else:
fill = "value"
try:
c = input("Give {}\n" .format(fill))
except:
continue
if isinstance(c, str):
if c == "":
Choice = False
if choices == []:
choices = False
break
else:
try:
choices.append(float(c))
except:
continue
if x != 0 and len(choices) == x:
break
c = 0
return choices
def av(x):
c = 0
alist = x[:]
alist.pop(0)
for a in alist:
c += a*x[0]
return c
def average(k,args):
c = 0
n = 0
for y in range(len(args)):
for a in range(len(args)):
c += (av(args[a]))/2
for b in range(len(args)):
n += (args[b][0]*(len(args[b])-1))/2
if k == 1:
return ([float("{0:.2f}".format(c/n)),c,n])
else:
j = float("{0:.2f}".format(c/n))
print("Weighted average {} from {}" .format(j,args))
def rmark(q,args):
alist = average(1,args)
a = float("{:.2f}" .format((((q[1]*(alist[2]+q[0]))-alist[1])/q[0])))
print("To get weighted average {}, u have to add the value equal to {} of weight {}" .format(q[1],a,q[0]))
# return a
Continue = True
list_choices = []
while Continue:
x = 0
x = choice(0)
if isinstance(x, list):
list_choices.append(x)
elif x == False:
break
print(list_choices)
rmark(choice(2),list_choices)
average(0,list_choices)
Let me break it down for you.
av function is reducing the size of your lists (x1, x2 and x3) to 1 by popping (alist.pop(0)) one element.
Hence, value of len(x1)-1 is 0, which means value of all multipliers in the denominator of (av(x1) + av(x2) + av(x3))/((x1[0]*(len(x1)-1)) + (x2[0]*(len(x2)-1)) + (x3[0]*(len(x3)-1))) is 0. Thus, the error divide by zero.

Puzzler solver program: How many different solutions are there to (1/a)+(1/b)+(1/c)+(1/d)+(1/e)+(1/f)+(1/g) = 1?

I wrote the python code below that solves and prints each possible solution for anything under 6 unit fractions, but given how I programmed it, it takes infinitely long to check for 7 fractions. Any ideas on how to modify the code to find all the possible solutions more efficienty?
import sys
from fractions import Fraction
import os
#myfile = open('7fractions.txt', 'w')
max = 7 #>2 #THIS VARIABLE DECIDES HOW MANY FRACTIONS ARE ALLOWED
A = [0] * max
A[0] = 1
def printList(A):
return str(A).strip('[]')
def sumList(A):
sum = 0
for i in A:
if i != 0:
sum += Fraction(1, i)
return sum
def sumTest(A):
sum = 0
v = 0
for i in range(0, len(A)):
if A[i] == 0 and v == 0:
v = Fraction(1,A[i-1])
if v != 0:
sum += v
else:
sum += Fraction(1, A[i])
return sum
def solve(n, A):
if n == max - 2:
while (sumTest(A) > 1):
print(A)
if sumList(A) < 1:
e = 1 - sumList(A)
if e.numerator == 1 and e.denominator>A[n-1]:
A[n+1] = e.denominator
#myfile.write(printList(A) + '\n')
print(A)
A[n+1] = 0
A[n] += 1
else:
while (sumTest(A) > 1):
if sumList(A) < 1:
A[n+1] = A[n] + 1
solve(n+1, A)
A[n+1] = 0
A[n] += 1
#execute
solve(0, A)

Resources