I am trying to solve a question from HackerRank and when I submit my solution, I get an error stating "Terminated due to timeout".
Please check the code and suggest me how to optimize.
Question:
A left rotation operation on an array of n size shifts each of the array's elements 1 unit to the left. For example, if 2 left rotations are performed on array [1,2,3,4,5], then the array would become [3,4,5,1,2].
Given an array of n integers and a number,d, perform d left rotations on the array. Then print the updated array as a single line of space-separated integers.
Input Format
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains space-separated integers describing the respective elements of the array's initial state.
Output Format
Print a single line of n space-separated integers denoting the final state of the array after performing d left rotations.
Sample Input
5 4
1 2 3 4 5
Sample Output
5 1 2 3 4
Explanation
When we perform d = 4 left rotations
Thus, we print the array's final state as a single line of space-separated values, which is 5 1 2 3 4.
My Code:
def array_left_rotation(ar, n, k):
for j in range(k):
temp = ar[0]
for i in range(0,n-1):
ar[i] = ar[i+1]
ar[n-1] = temp
return ar
n, k = map(int, input().strip().split(' '))
a = list(map(int, input().strip().split(' ')))
answer = array_left_rotation(a, n, k);
print(*answer, sep=' ')
Here the best way is not to actually perform the operations yourself. In this case you are manually rotating the list and that is unnecessary computation.
So first, analyze the problem and how it behaves for various outputs. So lets analyze :
Suppose for an Array of 5 elements
array = [1,2,3,4,5]
If you rotate this 2 times, you get :
[3,4,5,1,2]
Now, try the same for rotation with 7 times on the original array. You again get :
[3,4,5,1,2]
Similar trials will see the pattern emerge. ie, for a rotation of k times, it is same as k % n times.
Now that we have that with us, move to the computation part. For that, simply use list slicing to get the rotation, like this :
#n -> number of elements in array
#k -> number of rotations to be performed
#a -> (list) array
def rotate(a,n,k) :
rotations = k % n
new_array = a[rotations:] + a[:rotations]
return new_array
>>> a = [1, 2, 3, 4, 5]
>>> a[2:] + a[:2]
[3, 4, 5, 1, 2]
>>> ' '.join(str(i) for i in (a[2:] + a[:2]))
'3 4 5 1 2'
>>>
>>> def rotate_list(array, d):
... return array[d:] + array[:d]
>>>
>>> ' '.join(str(i) for i in rotate_list([1, 2, 3, 4, 5], 4))
... '5 1 2 3 4'
number_of_elements = int(input("Enter the number of elements to be inserted in array:"))
rotations = int(input("Enter the number of rotations:"))
array = []
for i in range(number_of_elements):
number = int(input("Enter a number:"))
array.append(number)
array = array[rotations:] + array[:rotations]
print(*array, end=' ')
Related
You are given N sticks, where the length of each stick is a positive integer. A cut operation is performed on the sticks such that all of them are reduced by the length of the smallest stick.
Given the length of N sticks, print the number of sticks that are left before each subsequent cut operations. Note: For each cut operation, you have to recalculate the length of smallest sticks (excluding zero-length sticks).
Input
The first line contains a single integer N.
The next line contains N integers separated by space, where each integer represents the length of the ith stick.
6
5 4 4 2 2 8
Output
For each operation, print the number of sticks that are cut, on separate lines.
6
4
2
1
Explanation
import array as arr
n = int(input())
a = arr.array('i',[1002])
for i in range(n):
c = [int(x) for x in input().split()]
a.append(c)
t=n
for i in range(0,1001):
if a[i] > 0:
print(t)
t=t-a[i]
You can't append a list to an integer array. If you want to merge two arrays you can use the extend method.
a.extend(c)
if a is list then below all satisfies but here a is array so we cant append list with array
a = [1,2,3] # a is a list
c = [4] # c is list
it won't give you correct result in any case
print(a.append(c)) # if we do a.append(c) result is like a = [1,2,3,[4]]
gives you correct result in any case
print(a.extend(c)) # if we do a.extend(c) result is like a = [1,2,3,4]
satisfies if "a" is list and "c" is list or "a" is array and "c" is also an array
a += c # a += c result is same as a.extend(c)
print(a) # a = [1,2,3,4]
I have a program which adds two matrices (lists) and prints the sum.
First, the program asks to specify the number of rows and columns as dimensions of the matrices.
Then it asks to enter the specified number of digits as rows and columns, as follows:
dimension: 2 3
numbers in the list: 1 2 3
numbers in the list: 4 5 6
dimension: 2 3
numbers in the list: 7 8 9
numbers in the list: 7 8 9
I am trying to print the sum of two input lists (matrices) exactly in the following format - two rows in separate lines, three columns, without square brackets:
8 10 12
11 13 15
but end up with this output:
[8, 11, 10, 13, 12, 15]
I have tried several other solutions suggested in other similar posts but haven't been able to make them work.
Without using NumPy, map() or lambda functions, how can I get the desired output?
# input the number of rows and columns (dimensions of the matrix)
rows_cols = input().split()
# save the dimensions as integers in a list
matrix_dim = [int(i) for i in rows_cols]
numbers = 0
matrix_A = []
matrix_B = []
matrices = []
# take the row times the input for the rows of matrix_A
for _ in range(matrix_dim[0]):
numbers = input().split()
matrix_A.append([int(i) for i in numbers])
rows_cols = input().split()
matrix_dim = [int(i) for i in rows_cols]
# take the row times the input for the rows of matrix_B
for _ in range(matrix_dim[0]):
numbers = input().split()
matrix_B.append([int(i) for i in numbers])
# add matrices matrix_A and matrix_B
matrices = [matrix_A[i][k] + matrix_B[i][k] for k in range(len(matrix_A[0])) for i in range(len(matrix_A))]
# print ERROR if the number of columns entered exceed the input number for columns
if len(numbers) != matrix_dim[1]:
print("ERROR")
else:
print(matrices)
The easy way to do this will be to start with the fix suggested by nathan:
matrices = [[matrix_A[i][k] + matrix_B[i][k] for k in range(len(Matrix_A[0]))] for i in range(len(matrix_A))]
That gives you a 2-d array rather than a 1-d array
[[a, b, c], [d, e, f]]
but now we need to print it nicely. Here's a function to turn the matrix into a pretty string:
def prettyString(matrix):
result = ''
for row in matrix:
for value in row:
result += value
result += '\n'
return result
Finally, in your code, you can use the new function:
print(prettyString(matrices))
All you have to do is change how you sum the matrices:
matrices = [[matrix_A[i][k] + matrix_B[i][k] for k in range(len(Matrix_A[0]))] for i in range(len(matrix_A))]
Then to print:
for row in matrices:
# print(row)
print(" ".join(row))
Or
from pprint import pprint
pprint(matrices)
Try this -
First calculate the sum list of lists as output, then join the elements of sublist with spaces and join those sublists strings with \n (newline character). When you then print it, it will print it out one sublist at a time.
output = [[a[i][j] + b[i][j] for j in range(len(a[0]))] for i in range(len(a))]
print_out = '\n'.join([' '.join([str(j) for j in i]) for i in output])
print(print_out)
#sample output
1 2 3
4 5 6
zip function can be helpful when you try to combine lists of lists. This will work for any n x m matrices.
m1 = [
[1,2,3],
[4,5,6]]
m2 = [
[7,8,9],
[7,8,9]]
for row1,row2 in zip(m1,m2):
print(*[el1+el2 for el1,el2 in zip(row1,row2)])
Output:
8 10 12
11 13 15
I have a list of integers like:
1 3 4 4 9 7 10 (the number of elements is between 1 and 200000)
and an integer variable D, it lies between 0 and 10^9.
Let it be 5 for example.
I need to count how many pairs in the list have a difference between each other not bigger than a variable D but the tricky part is that if I took the zero element with value 1 and the first element with the value 3(the difference between them meets the condition) I can't use these elements of a list again.
For example for the sequence above the answer is 3 pairs: (1,3) (4,4) (7,9)
I wrote a code which seems to be correct but I need a hint how to change the input sequence and the variable d the way it will output wrong answer
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
i = 0
while True:
if i >= len(list_of_colors):
break
if i != len(list_of_colors) - 1:
# if the number i in list and i+1 is the same or difference between them not greater than a variable d...
if (int(list_of_colors[i]) == int(list_of_colors[i + 1])) or abs(int(list_of_colors[i]) - int(list_of_colors[i + 1])) <= d:
#print list_of_colors[i]," ",list_of_colors[i + 1]
number_of_pairs += 1 # increasing the number of the acceptable pairs
i += 2 # jump over two elements, we already counted them
continue
i += 1
print number_of_pairs
I need another algorithm to compare it with the results of my algorithm on the various range of the input sequence and the variable d
Suggest your ideas please
I have a greedy solution for this problem:
Sort the input sequence.
Parse the sorted sequence as follows:
For ith element in the sequence,
if |a[i+1]-a[i]| <= D,
then pair up the elements. Proceed to process i+2th element.
else
proceed to process i+1th element.
My solution here is to first "clean" the list what means I made the number of elements even. Then I've converted the list into a list of tuples (pairs).
My result for this example is 3 pairs in order to your condition.
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
# remove the last element if the number of elements is odd
if len(list_of_colors) % 2 != 0:
list_of_colors = list_of_colors[:-1]
# create a list of tuples
list_of_colors = [tuple(list_of_colors[i:i+2]) for i in range(0, len(list_of_colors), 2)]
for i in list_of_colors:
if (int(i[0]) == int(i[1])) or abs(int(i[0])) - int(i[1]) <= d:
number_of_pairs += 1
print number_of_pairs
I'm a stumped on how to speed up my algorithm which sums multiples in a given range. This is for a problem on codewars.com here is a link to the problem
codewars link
Here's the code and i'll explain what's going on in the bottom
import itertools
def solution(number):
return multiples(3, number) + multiples(5, number) - multiples(15, number)
def multiples(m, count):
l = 0
for i in itertools.count(m, m):
if i < count:
l += i
else:
break
return l
print solution(50000000) #takes 41.8 seconds
#one of the testers takes 50000000000000000000000000000000000000000 as input
# def multiples(m, count):
# l = 0
# for i in xrange(m,count ,m):
# l += i
# return l
so basically the problem ask the user return the sum of all the multiples of 3 and 5 within a number. Here are the testers.
test.assert_equals(solution(10), 23)
test.assert_equals(solution(20), 78)
test.assert_equals(solution(100), 2318)
test.assert_equals(solution(200), 9168)
test.assert_equals(solution(1000), 233168)
test.assert_equals(solution(10000), 23331668)
my program has no problem getting the right answer. The problem arises when the input is large. When pass in a number like 50000000 it takes over 40 seconds to return the answer. One of the inputs i'm asked to take is 50000000000000000000000000000000000000000, which a is huge number. That's also the reason why i'm using itertools.count() I tried using xrange in my first attempt but range can't handle numbers larger than a c type long. I know the slowest part the problem is the multiples method...yet it is still faster then my first attempt using list comprehension and checking whether i % 3 == 0 or i % 5 == 0, any ideas guys?
This solution should be faster for large numbers.
def solution(number):
number -= 1
a, b, c = number // 3, number // 5, number // 15
asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2
return 3*asum + 5*bsum - 15*csum
Explanation:
Take any sequence from 1 to n:
1, 2, 3, 4, ..., n
And it's sum will always be given by the formula n(n+1)/2. This can be proven easily if you consider that the expression (1 + n) / 2 is just a shortcut for computing the average, or Arithmetic mean of this particular sequence of numbers. Because average(S) = sum(S) / length(S), if you take the average of any sequence of numbers and multiply it by the length of the sequence, you get the sum of the sequence.
If we're given a number n, and we want the sum of the multiples of some given k up to n, including n, we want to find the summation:
k + 2k + 3k + 4k + ... xk
where xk is the highest multiple of k that is less than or equal to n. Now notice that this summation can be factored into:
k(1 + 2 + 3 + 4 + ... + x)
We are given k already, so now all we need to find is x. If x is defined to be the highest number you can multiply k by to get a natural number less than or equal to n, then we can get the number x by using Python's integer division:
n // k == x
Once we find x, we can find the sum of the multiples of any given k up to a given n using previous formulas:
k(x(x+1)/2)
Our three given k's are 3, 5, and 15.
We find our x's in this line:
a, b, c = number // 3, number // 5, number // 15
Compute the summations of their multiples up to n in this line:
asum, bsum, csum = a*(a+1) // 2, b*(b+1) // 2, c*(c+1) // 2
And finally, multiply their summations by k in this line:
return 3*asum + 5*bsum - 15*csum
And we have our answer!
for programming the Hamming cod in sage ( a compiler based on python) I need to create a matrix in which each column is a binary representation of a number
say Hamming(3) the matrix should look like this
0 0 0 1 1 1 1
0 1 1 0 0 1 1
1 0 1 0 1 0 1
which is the binary represenation of numbers from 1 to 7.
so what i did till now is to convert any given number to it's binary representation:
i made this little function it take two values n and r
and repserent n over r bits
binrep(n,r)
x=n
L=[]
LL=[]
while (n>0):
a=int(float(n%2))
L.append(a)
n=(n-a)/2
while (len(L)<r):
L.append(0)
#print(L)
LL=L[::-1]
return LL
so now i want to collect all the LL i got and make them in one big matrix like the one above
In addition to the other ones, an answer using numpy:
import numpy as np
# we're creating the binary representation for all numbers from 0 to N-1
N = 8
# for that, we need a 1xN matrix of all the numbers
a = np.arange(N, dtype=int)[np.newaxis,:]
# we also need a log2(N)x1 matrix, for the powers of 2 on the numbers.
# floor(log(N)) is the largest component that can make up any number up to N
l = int(np.log2(N))
b = np.arange(l, dtype=int)[::-1,np.newaxis]
# This step is a bit complicated, so I'll explain it below.
print np.array(a & 2**b > 0, dtype=int)
This prints:
[[0 0 0 0 1 1 1 1]
[0 0 1 1 0 0 1 1]
[0 1 0 1 0 1 0 1]]
The line
print np.array(a & 2**b > 0, dtype=int)
does a few things at once. I'll split it up into simpler steps:
# this takes our matrix b and creates a matrix containing the powers of 2
# up to 2^log2(N) == N
# (if N is a power of 2; otherwise, up to the next one below)
powers = 2**b
# now we calculate the bit-wise and (&) for each combination from a and b.
# because a has one row, and b as one column, numpy will automatically
# broadcast all values, so the resulting array has size log2(N)xN.
u = a & powers
# this is almost what we want, but has 4's in the first row,
# 2's in the second row and 1's in the last one.
# one method of getting 1's everywhere is to divide by powers:
print u / powers
# another way is to check where u > 0, which yields an array of bools,
# which we then convert to numbers by turning it into an array of ints.
print np.array(u > 0, dtype=int)
You just have to convert all those binary representations to lists of integers, collect them in a list of lists, and finally transpose that list of lists to get the desired output.
n = 3
binary = []
for i in range(1, 2**n):
s = binrep(i, n)
binary.append(map(int, s))
matrix = zip(*binary)
Or in one line: matrix = zip(*(map(int, binrep(i, n)) for i in range(1, 2**n)))
Result is
[(0, 0, 0, 1, 1, 1, 1),
(0, 1, 1, 0, 0, 1, 1),
(1, 0, 1, 0, 1, 0, 1)]
Also note that there are other ways to convert numbers to binary, e.g. using str.format:
def binrep(n,r):
return "{0:0{1}b}".format(n, r)
Like zoosuck mentioned, I would suggest the bin() function in replacement to your code. To print them in a sequence, assuming that the format is similar:
L = ['10101010', '10101010']
for i in L:
print ' '.join([j for j in i])
In a similar manner, you can append it to a list or a dictionary.