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

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]

Related

print the smallest subarray with sum greater than or equal target

```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]

ModuleNotFoundError: No module named 'src'. Python 3 error

I'm facing the dreaded ModuleNotFoundError: No module named 'src' error. I've done quite some extensive reading into this problem and see that this is a common problem. I can't seem to wrap my head around this.
You can pull my repo at https://github.com/mustafahoda/data-structures-and-algos
Here is what my current project directory looks like.
I'm using pipenv and running commands from after entering the env shell.
I'm using python 3
DSandAlgoBenchmarkSuite
src
|---CommonProblems
|---DataStructures
|---SortingAlgorithms
|--sorting_algos.py
test
|---test_bubble_sort_1.py
.gitignore
.benchmarks
.pytest_cache
Pipfile
Pipfile.lock
test.py
test_bubble_sort_2.py
I have two files that I'd like to run:
test/test_bubble_sort_1.py
test_bubble_sort_2.py
Contents of each file.
# test/test_bubble_sort_1.py
from src.SortingAlgorithms import sorting_algos
import pytest
# test_bubble_sort_2.py
from src.SortingAlgorithms import sorting_algos
import pytest
# src/SortingAlgorithms/sorting_algos.py
# ---------BUBBLE SORT-------------
def bubble_sort(A: list) -> list:
sorted = len(A)
for i in range(len(A)):
L = 0
R = 1
while R != len(A) :
# if L > R, then swap
if A[L] > A[R]:
temp = A[L]
A[L] = A[R]
A[R] = temp
L = L + 1
R = R + 1
return A
# -----------------INSERTION SORT----------------------
def shift_items_to_right(B, start, stop):
for i in range(stop, start, -1):
B[i] = B[i - 1]
return B
def insertion_sort(A : list) -> list:
sorted = 0
while sorted != len(A):
hole = 0
for i in A[:sorted + 1]:
value = A[sorted]
if value < A[hole]:
# move all items to the right from the hole onwards
shift_items_to_right(A, hole, sorted)
# store the value in the hole
A[hole] = value
else:
hole = hole + 1
sorted = sorted + 1
return A
# ---------------------MERGE SORT--------------------------------------
def merge(A: list, B: list) -> list:
ptr_A = 0
ptr_B = 0
C = []
while ptr_A <= len(A) - 1 and ptr_B <= len(B) - 1:
if A[ptr_A] >= B[ptr_B]:
C.append(B[ptr_B])
ptr_B = ptr_B + 1
else:
C.append(A[ptr_A])
ptr_A = ptr_A + 1
if ptr_A == len(A):
for i in B[ptr_B:]:
C.append(i)
else:
for i in A[ptr_A:]:
C.append(i)
return C
def merge_sort(A: list) -> list:
print("A: %s" % A)
if len(A) == 1:
return A
# STEP 1: Divide
mid = len(A) // 2
L = A[:mid]
R = A[mid:]
if L is not None:
L = merge_sort(L)
if R is not None:
R = merge_sort(R)
merged = merge(L, R)
print("Merged: %s" % merged)
return merged
# ---------------------QUICK SORT--------------------------------------
def quicksort(A: list) -> list:
return _quicksort(A, 0, len(A) - 1)
def _quicksort(A: list, start: int, end: int) -> list:
if start >= end:
return A
print("A before partition: %s" % A)
pIndex = partition(A, start, end)
print("A after partition: %s" % A)
print("_____________________________")
_quicksort(A, start, pIndex - 1)
_quicksort(A, pIndex, end)
return A
def partition(A, start: int, end: int):
# set_trace()
pivot = A[end]
i = start
pIndex = start
# set_trace()
while i < end:
# set_trace()
if pivot >= A[i]:
# implement swap between pIndex and A[i]
temp = A[i]
A[i] = A[pIndex]
A[pIndex] = temp
pIndex = pIndex + 1
i = i + 1
# once we reach the element before the pivot, we swap pivot into pIndex
temp = A[pIndex]
A[pIndex] = pivot
A[end] = temp
# set_trace()
print(A)
return pIndex
# ---------------------SELECTION SORT-------------------------------------
def find_min_not_in_place(A: list, visited) -> int:
for i in A:
if visited[i] == False:
min = i
break
for i in A[1:]:
# set_trace()
if i < min and visited[i] == False:
# set_trace()
min = i
# visited[min] = True
return min
def selection_sort_not_in_place(A: list) -> list:
B = []
# construct a dictionary that will keep track of visited numbers
visited = dict()
for i in A:
visited[i] = False
# keep repeating the process until theere are no values in dictionary with False
while False in visited.values():
for i in A:
min = find_min_not_in_place(A, visited)
# set_trace()
B.append(min)
visited[min] = True
print(B)
return B
def find_min_in_place(A: list, sorted_index: int) -> int:
min_index = sorted_index
min = A[sorted_index]
# for i in A[sorted_index:]:
for i in range(sorted_index, len(A)):
if A[i] < min:
min = A[i]
min_index = i
return (min, min_index)
def selection_sort_in_place(A: list) -> list:
sorted = 0
while sorted != len(A):
# min, min_index = find_min_in_place(A[sorted + 1:])
min, min_index = find_min_in_place(A, sorted)
# implement swapping
temp = A[sorted]
A[sorted] = min
A[min_index] = temp
sorted = sorted + 1
return A
Ideally, I want pytest-benchmark suite to work but I've isolated the problem to being an import error.
When I run test_bubble_sort_2.py from the main project directory, it works fine!
However, when I run test/test_bubble_sort_1.py from the main project directory, it doesn't work and throws the exception: ModuleNotFoundError: No module named 'src'
I'd like to run test/test_bubble_sort_1.py in order to maintain the project structure and access the functions from my sorting_algos.py file so I can benchmark them.

How to turn the duplicate part in my code to a checking function?

I come up a solution for leetcode "5. Longest Palindromic Substring" with parts of duplicate codes. One of good ways to solve duplicate code is to make a function. How do I write my check here to a function? I am confused what I should return to make both variables - longest and ans - being updated. Thanks!
The part of duplicate code:
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
Full code:
class Solution:
def longestPalindrome(self, s: str) -> str:
if len(s) == 0:
return ''
if len(s) == 1:
return s
longest = 0
ans = ''
for pos in range(len(s)-1):
l, r = pos, pos
if pos > 0 and pos < len(s) - 1 and s[pos-1] == s[pos+1]:
l, r = pos-1, pos+1
while l > 0 and r < len(s) - 1 and s[l-1] == s[r+1]:
l -= 1
r += 1
# duplicate code 1
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
if s[pos] == s[pos+1]:
l, r = pos, pos+1
while l > 0 and r < len(s) - 1 and s[l-1] == s[r+1]:
l -= 1
r += 1
# duplicate code 2
if len(s[l:r+1]) > longest:
longest = len(s[l:r+1])
ans = s[l:r+1]
if ans == '' and len(s) > 0:
return s[0]
return ans
The if statements and while loops before the duplicate code blocks are mostly duplicated as well, as is using the longest variable to keep track of the length of ans when you already have ans -- here's one way you could simplify things via another function:
class Solution:
def find_longest(self, s, left, right):
if s[left] == s[right]:
if right - left + 1 > len(self.ans):
self.ans = s[left:right + 1]
if left > 0 and right < len(s) - 1:
self.find_longest(s, left - 1, right + 1)
def longestPalindrome(self, s: str) -> str:
if len(s) == 1:
return s
self.ans = ''
for pos in range(len(s) - 1):
self.find_longest(s, pos, pos)
self.find_longest(s, pos, pos + 1)
return self.ans

solve n which is an integer above 0 in python

This code works but it is not very efficient is there any help on a faster code in python to find n knowing that n is an integer above 0 and that n has no upper bound, how(x) will return you 1 if x>n, 0 if x = n, and -1 if x
def how(x):
if x > n:
return 1
elif x < n:
return -1
else:
return 0
def find(how):
if how(1) == 1:
return 1
x = 2
while how(x) != 1:
x = x**x
v = x
while how(x) != 0:
if how(x) == 1:
v = x
x = (x+1)//2
else:
x += (v-x+1)//2
return x
Rebecca, I've added some print statements so you can see where goes what wrong. As Patrick Artner said... its a bit confusing which way to go so I've tried to clean-up some things that enable you to continue exploring comparison of two variables against each other (and fake error catching (0).
Lets start and remove the confusing lingo and produce something workable code. With current below script it runs and with value = 1, reference = 1 you get the below print result in a continues loop until YOU stop the script manually:
v1 = n: error
loop1 1
def selector(v1, n):
if v1 > n:
print 'v1 > n', v1, n
return 1
elif v1 < n:
print 'v1 < n', v1, n
return -1
else:
print 'v1 == n: error'
return 0
def find(value, reference):
if selector(value, reference) == 1:
return 1
while selector(value, reference) != 1:
x = value**value
print 'loop1', x
v = x
while selector(value, reference) != 0:
print 'loop2'
if selector(value, reference) == 1:
v = value
x = (value+1)/2
print 'loop2-if', v, x
else:
x += (v-(value+1))/2
print 'loop2-else', x
print ' Almost done...'
return x
if __name__ == '__main__':
n = 1
print find(1, 1)
Happy exploring,....

List Index out of range, trying to get the [-1] position

I've tested to see if the list is empty and I'm sure it's not empty. So why this error continues?
The code is to find the smallest amount of factorial to a sum is equal to N.
def fat(n):
if n == 0 or n == 1:
return 1
else:
return n * fat(n - 1)
n = int(input())
ns = [x+1 for x in range(n)]
listaFat = []
l = []
for x in ns:
if fat(x) < n:
listaFat.append(x)
maior = max(listaFat)
listaFat.remove(maior)
print(listaFat)
print(len(listaFat))
while (fat(listaFat[-1]) + fat(maior)) < n:
l.append(listaFat[-1])
if len(listaFat) > 0:
listaFat.remove(listaFat[-1])
continue
else: break
print(l)
print(listaFat)

Resources