The code works perfectly fine for the first test case but gives wrong answer for the second one. Why is that?
arr = [1,2,3,4,5,6,7]
arr2 = [-1,-100,3,99]
def reverse(array, start, end):
while start < end:
array[start], array[end] = array[end], array[start]
start += 1
end -= 1
return array
def rotate(array, k):
reverse(array, 0, k)
reverse(array, k+1, len(array)-1)
reverse(array, 0, len(array)-1)
return array
print(rotate(arr, 3)) # output: [5, 6, 7, 1, 2, 3, 4]
# print(reverse(arr, 2, 4))
rotate(arr2, 2)
print(arr2) # output: [99, -1, -100, 3] (should be [3, 99, -1, -100])
Your existing logic does the following -
Move k + 1 item from front of the list to the back of the list.
But the solution needs to move k elements from back of the list to the front. Or another way to think is move len(array) - k element from front to the back.
To do so, two changes required in the rotate() -
Update k to len(array) - k
Change your logic to move k instead of k + 1 element from front to back
So, your rotate() needs to be changed to following -
def rotate(array, k):
k = len(array) - k
reverse(array, 0, k-1)
reverse(array, k, len(array)-1)
reverse(array, 0, len(array)-1)
return array
I think there are better ways to solve this but with your logic this should solve the problem.
Related
Que: https://en.wikipedia.org/wiki/Line_wrap_and_word_wrap
What I tried & issue faced: I tried a recursive approach to solve this problem. Currently, unable to find the overlapping subproblems. Can anyone help me how can I optimize, memoize and modify/update my recursion approach?. (I am thinking my approach is Wrong)
approach: Either the word is in the current line(if and only if space is left) or will be in the new line.
Code Flow:
Input text = "Cat is on Floor" .
I stored len in an array = [3,2,2,5]
ans(a,b,c) : a: index, b: line (currently no use), c: current line sum
base condn if all elements are over a>=size: return pow(spaceleft,2)
will return min( subproblem(word in current line),subproblem(word in new line)+pow(spaceleft,2))
Initially : ans(1,1,3)
ans(2,1,6) ans(2,2,2)
ans(3,2,2) ans(3,2,5) ans(3,3,2)
ans(4,3,5) ans(4,3,5) ans(4,4,5)
The below code is in python3.x :
n=6
arr=[3,2,2,5]
size = 4
def ans(a,b,c):
if(a>=size):
return pow((n-c),2);
if(c+arr[a]+1 > n):
return (pow((n-c),2)+ans(a+1,b+1,arr[a]))
return (min(ans(a+1,b,c+arr[a]+1),pow((n-c),2)+ans(a+1,b+1,arr[a])))
print(ans(1,1,3))
Thanks in advance for giving your valuable time and helping me....
I think your formulation might be missing some cases. It surely is hard to understand. Here's one that seems to get the right answer.
class LineWrapper:
def __init__(self, lens, width):
self.lens = lens
self.width = width;
def cost(self, ptr=0, used=0):
remaining = self.width - used
# Case 1: No words: Cost is due to partially used line.
if ptr == len(self.lens):
return remaining ** 2 if used else 0
# Case 2: First word of line. Must skip.
if used == 0:
return self.cost(ptr + 1, self.lens[ptr])
# Case 3: Out of space. Must wrap.
needed = 1 + self.lens[ptr]
if remaining < needed:
return remaining ** 2 + self.cost(ptr)
# Case 4: Min cost of skip and wrap.
return min(self.cost(ptr + 1, used + needed), remaining ** 2 + self.cost(ptr))
There's lots of overlap among subproblems in this formulation, and yours, too. A simple example is [1, 1, 1, 1] with a width of 7. The solution will try putting this on all combinations of 1, 2, 3, and 4 lines. May sub-combinations will repeat.
To see this more obviously, we can memoize and check for hits:
def memo_cost(self, ptr=0, used=0):
args = (ptr, used)
print(args)
if args in self.memos:
print(f'Memo hit: {args}')
return self.memos[args]
remaining = self.width - used
# Case 1: No words has cost of partially used line
if ptr == len(self.lens):
r = remaining ** 2 if used else 0
self.memos[args] = r
print(f'Done: {r}')
return r
# Case 2: First word of line. Must skip.
if used == 0:
r = self.memo_cost(ptr + 1, self.lens[ptr])
self.memos[args] = r
print(f'Must skip: {r}')
return r
# Case 3: Out of space. Must wrap.
needed = 1 + self.lens[ptr]
if remaining < needed:
r = remaining ** 2 + self.memo_cost(ptr)
self.memos[args] = r
print(f'Must wrap: {r}')
return r
# Case 4: Min cost of skip wrap and wrap.
r = min(remaining ** 2 + self.memo_cost(ptr), self.memo_cost(ptr + 1, used + needed))
self.memos[args] = r
print(f'Min: {r}')
return r
print(LineWrapper([1, 1, 1, 1], 7).memo_cost())
When run, this produces:
$ python3 lb.py
(0, 0)
(1, 1)
(1, 0)
(2, 1)
(2, 0)
(3, 1)
(3, 0)
(4, 1)
Done: 36
Must skip: 36
(4, 3)
Done: 16
Min: 16
Must skip: 16
(3, 3)
(3, 0)
Memo hit: (3, 0)
(4, 5)
Done: 4
Min: 4
Min: 4
Must skip: 4
(2, 3)
(2, 0)
Memo hit: (2, 0)
(3, 5)
(3, 0)
Memo hit: (3, 0)
(4, 7)
Done: 0
Min: 0
Min: 0
Min: 0
Must skip: 0
0
My answer with memo thanks to #Gene
n=7
arr=[3,2,2,5]
INF = 9223372036854775807
size = 4
dp = [[INF for i in range(n+1)] for j in range(size+1)]
def ans(a,b,c):
if(dp[a][c]!=INF):
return dp[a][c]
if(a>=size):
dp[a][c] = pow((n-c),2)
return pow((n-c),2)
if(c+arr[a]+1 > n):
dp[a][c] = (pow((n-c),2)+ans(a+1,b+1,arr[a]))
return dp[a][c]
dp[a][c] = (min(ans(a+1,b,c+arr[a]+1),pow((n-c),2)+ans(a+1,b+1,arr[a])))
return dp[a][c]
print(ans(1,1,3))
First I would like to thank you in advance.
I tried to write a quick sort in python3, but it recurs infinitely.
Here's my code:
def partition(lst, l, h):
lst.append(float("inf"))
pivot = lst[0]
i, j = l+1, h
while i < j:
while lst[i] < pivot:
i += 1
while lst[j] > pivot:
j -= 1
if i < j:
lst[i] , lst[j] = lst[j], lst[i]
else:
lst = lst[1:i] + [pivot] + lst[i:]
return lst[:-1], i
def quickSort(lst, l, h):
if l < h-1:
mid = (l + h)//2
lst[l:h], mid = partition(lst[l:h], 0, h-l)
quickSort(lst, l, mid)
quickSort(lst, mid, h)
lst1 = [10, 12, 8, 16, 2, 6, 3, 9, 5]
quickSort(lst1, 0, 9)
In recursive algorithms, you should be careful about the initial step of the algorithm. For example, in your case, you need to sort the given array manually without any recursion with the size of 2.
If there is arr = [1, 2, 3] so len(arr) is 3 right?
for i in range(0, len(arr)+1):
print(arr[i])
It is no secret that you can not do that, simply IndexError: list index out of range.
So how is this possible?
def max_sequence(arr):
if arr:
li = []
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr)+1)}
li.append(max(x.items()))
for ii in li:
print(ii)
return li[0][0]
else:
return 0
print(max_sequence([26, 5, 3, 30, -15, -7, 10, 20, 22, 4]))
I simply had to find the maximum sum of a contiguous subsequence in a list of integers.
If I write this part:
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr))}
It shows that maximum sum is 94, that is incorrect.
If I write this:
x = {sum(arr[i:j]): arr[i:j] for i in range(0, len(arr))
for j in range(1, len(arr)+1)}
Maximum sum is 98, it is correct. But why is so? If I write "for j in range(1, len(arr)+1)" why there is no IndexError?
We can generate a sequence of numbers using range() function. Range(10) will generate numbers from 0 to 9 (10 numbers).
We can also define the start, stop and step size as range(start, stop,step_size).
Here in your example, "for j in range(1, len(arr)+1)"
len(arr) is 10.
So range will generate numbers from 1 to 10.
Also, your li is an empty array so its length can be varied. You are storing the result i.e. the sum in li array as well as it will store the original array and this j will help it to store it.
I am relatively a noobie in programming and trying to learn python. I was trying to implement a Fibonacci series into a list within 10.
fibo= [0,1]
for k in range(11):
i= fibo[-1]
j = fibo[-2]
k= fibo[i]+fibo[j]
fibo.append(k)
k=+1
print(fibo)
Not sure what I did wrong? Any help is really appreciated!
Output:
[0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
You can use this code to print fibonacci series upto N.
N = int(input()) # Length of fibonacci series
fibo = [0, 1]
a = fibo[0]
b = fibo[1]
for each in range(2, N):
c = a + b
a, b = b, c
fibo.append(c)
print(fibo[:N])
OUTPUT
N = 10
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
I can see few issues here:
fibo = [0,1]
# Your loop should start at index 2, otherwise
# you will try to access fibo[-2] and fibo[-1] with k=0
# and fibo[-1] and fibo[0] with k=1
# Also, if you only want 10 values, you should change 11
# to 10 since fibo already has two values.
# for k in range(11):
for k in range(2, 10):
# You don't want the content of fibo, but the indexes!
# i = fibo[-1]
# j = fibo[-2]
i = k - 1
j = k - 2
# You are already using k, so you need to use an other variable
# k = fibo[i] + fibo[j]
v = fibo[i] + fibo[j]
fibo.append(v)
# You don't need k+=1 because it will be incremented
# according to range(2, 10). The loop will start with
# k = 2 and it will stop when k = 9
# k += 1
print(fibo)
Your code did not crash because you technically can access fibo[-1] and fibo[-2]. It will respectively return the last value of your array, and the value before the last one.
I am trying to define a function, median, that consumes a list of numbers and returns the median number from the list. If the list is empty, then I want to return None. To calculate the median, I need to find the middle index of the list after it has been sorted. Do not use a built-in function.
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
def median(SURVEY_RESULTS):
length = 0
order = sorted(SURVEY_RESULTS)
I'm not sure how to use indexing to now determine the median.
Here is my implementation:
def QuickSort(myList,start,end):
if start < end:
i,j = start,end
base = myList[i]
while i < j:
while (i < j) and (myList[j] >= base):
j = j - 1
myList[i] = myList[j]
while (i < j) and (myList[i] <= base):
i = i + 1
myList[j] = myList[i]
myList[i] = base
QuickSort(myList, start, i - 1)
QuickSort(myList, j + 1, end)
return myList
def median(l):
half = len(l) // 2
return (l[half] + l[~half])/2 # Use reverse index
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
# Sort first
QuickSort(SURVEY_RESULTS, 0, len(SURVEY_RESULTS)-1)
result = median(SURVEY_RESULTS)
print (result)