How is this possible? Maximum subarray sum - python-3.x

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.

Related

what is wrong with my code? leetcode - 189. Rotate Array

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.

Printing fibonacci series using lists in python

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.

Start counting indexes from 1 instead of 0 of a list

I created a program to get the the max value of a list and the position of its occurrences (list starting at indexing with 1 not 0) but I can't manage to find any useful solutions.
The input is always a string of numbers divided by zero.
This is my code:
inp = list(map(int,input().split()))
m = max(inp)
count = inp.count(m)
print(m)
def maxelements(seq): # #SilentGhost
return [i for i, j in enumerate(seq) if j == m]
print(maxelements(inp))
I expect to output the maximum value and then all the positions of its occurrences. (also is it possible to do without brackets as in the example below?)
Input: 4 56 43 45 2 56 8
Output: 56
2 6
If you want to shift index values, you could just do
return [i + 1 for i, j in enumerate(seq) if j == m]
more generally any transformation of i or j!
def f(i, j):
# do whatever you want, and return something
return i + 1
return [f(i, j) for i, j in enumerate(seq) if j == m]
Without brackets, as a string:
return " ".join(str(i + 1) for i, j in enumerate(seq) if j==m)
Specifiy start=1 with enumerate():
>>> l = [4, 56, 43, 45, 2, 56, 8]
>>> max_num = max(l)
>>> [i for i, e in enumerate(l, start=1) if e == max_num]
[2, 6]
By default enumerate() uses start=0, because indices start at 0.

How to determine the maximum,minimum and average values of the matrix

I need to create a matrix, where the user can input his values and determine the maximum value of the matrix, the minimum value and the average value of all matrix's data
I created the matrix, where I can input my own values and I tried to write which could determine the maximum and minimum value. However, after several checks, I understood, that my piece of code, which determines max and min values, doesn't work.
line = int(input('Enter the amount of lines:'))
columns = int(input('Enter the amount of columns:'))
matrix = []
for i in range(0, columns):
matrix.append([])
for i in range(0, line):
for j in range(0, columns):
matrix[i].append(j)
matrix[i][j] = 0
for i in range(0, line):
for j in range(0,columns):
matrix[i][j] = int(input('Enter the value:'))
avg = matrix
for i in range(0, line):
for j in range(0, columns):
max_val = matrix[j]
min_val = matrix[j]
for j in range(0, len(matrix[j]), 1):
max_val = max(max_val, matrix[j])
min_val = min(min_val, matrix[j])
maxVal = max_val[0]
minVal = min_val[0]
for i in range(0, len(max_val), 1):
maxVal = max(maxVal, max_val[i])
minVal = min(minVal, min_val[i])
print(matrix)
print('The maximum value is ' + str(maxVal))
print('The minimum value is ' + str(minVal))
I excepted the result, which will print me the matrix, maximum value, minimum value and average value
One way of doing it with Python lists is this:
(I'll just do find_min(), as find_max() and compute_mean() would be pretty much the same.)
import random
def gen_random_matrix(rows, cols, min_val=1, max_val=100):
return [
[random.randint(min_val, max_val) for j in range(cols)]
for i in range(rows)]
def find_min(matrix):
rows = len(matrix)
cols = len(matrix[0])
min_i, min_j = 0, 0
min_val = matrix[min_i][min_j]
for i in range(rows):
for j in range(cols):
if matrix[i][j] < min_val:
min_i = i
min_j = j
min_val = matrix[i][j]
return min_val, min_i, min_j
random.seed(0)
matrix = gen_random_matrix(3, 4)
print(matrix)
# [[50, 98, 54, 6], [34, 66, 63, 52], [39, 62, 46, 75]]
print(find_min(matrix))
# (6, 0, 3)

Optimization of CodeWars Python 3.6 code: Integers: Recreation One

I need help optimizing my python 3.6 code for the CodeWars Integers: Recreation One Kata.
We are given a range of numbers and we have to return the number and the sum of the divisors squared that is a square itself.
"Divisors of 42 are : 1, 2, 3, 6, 7, 14, 21, 42. These divisors squared are: 1, 4, 9, 36, 49, 196, 441, 1764. The sum of the squared divisors is 2500 which is 50 * 50, a square!
Given two integers m, n (1 <= m <= n) we want to find all integers between m and n whose sum of squared divisors is itself a square. 42 is such a number."
My code works for individual tests, but it times out when submitting:
def list_squared(m, n):
sqsq = []
for i in range(m, n):
divisors = [j**2 for j in range(1, i+1) if i % j == 0]
sq_divs = sum(divisors)
sq = sq_divs ** (1/2)
if int(sq) ** 2 == sq_divs:
sqsq.append([i, sq_divs])
return sqsq
You can reduce complexity of loop in list comprehension from O(N) to O(Log((N)) by setting the max range to sqrt(num)+1 instead of num.
By looping from 1 to sqrt(num)+1, we can conclude that if i (current item in the loop) is a factor of num then num divided by i must be another one.
Eg: 2 is a factor of 10, so is 5 (10/2)
The following code passes all the tests:
import math
def list_squared(m, n):
result = []
for num in range(m, n + 1):
divisors = set()
for i in range(1, int(math.sqrt(num)+1)):
if num % i == 0:
divisors.add(i**2)
divisors.add(int(num/i)**2)
total = sum(divisors)
sr = math.sqrt(total)
if sr - math.floor(sr) == 0:
result.append([num, total])
return result
It's more the math issue. Two maximum divisors for i is i itself and i/2. So you can speed up the code twice just using i // 2 + 1 as the range stop instead of i + 1. Just don't forget to increase sq_divs for i ** 2.
You may want to get some tiny performance improvements excluding sq variable and sq_divs ** (1/2).
BTW you should use n+1 stop in the first range.
def list_squared(m, n):
sqsq = []
for i in range(m, n+1):
divisors = [j * j for j in range(1, i // 2 + 1 #speed up twice
) if i % j == 0]
sq_divs = sum(divisors)
sq_divs += i * i #add i as divisor
if ((sq_divs) ** 0.5) % 1 == 0: #tiny speed up here
sqsq.append([i, sq_divs])
return sqsq
UPD: I've tried the Kata and it's still timeout. So we need even more math! If i could be divided by j then it's also could be divided by i/j so we can use sqrt(i) (int(math.sqrt(i)) + 1)) as the range stop. if i % j == 0 then append j * j to divisors array. AND if i / j != j then append (i / j) ** 2.

Resources