Related
I have a unsorted list. I'm asked to print k-times number of positive values in a segment.The boarders for segment start with 1 not 0. So, if the boarder [1,3] it means that we should find all positives among elements with indices [0,1,2]
For example,
2 -1 2 -2 3
4
1 1
1 3
2 4
1 5
The answer needs to be:
1
2
1
3
Currently, I'm creating a list with length as original where i equals 1 if original is positive and 0 if original is negative or zero. After that I sum for this segment:
lst = list(map(int, input().split()))
k = int(input())
neg = [1 if x > 0 else 0 for x in lst]
for i in range(k):
l,r = map(int, input().split())
l = l - 1
print(sum(neg[l:r]))
Despite the fact that it's the fastest code that I created so far, it is still too slow for this task. How would I optimize it (or make it faster)?
If I understand you correctly, there doesn't seem to be a lot of room for optimization. The only thing that comes to mind really is that the lst and neg steps could be combined, which would save one loop:
positive = [int(x) > 0 for x in input().split()]
k = int(input())
for i in range(k):
l, r = map(int, input().split())
print(sum(positive[l-1:r]))
We can just have bools in the positive list, because bool is just a subclass of int, meaning True is treated like 1 and False like 0. (Also I would call the list positive instead of neg.)
The complexity is still O(n) though.
Given an integer n <= 10^18 which is the product of Fibonacci numbers, I need to factor it into said Fibonacci numbers.
Each factorization has a score, which is one less than the count of factors plus the sum of the indices of the factors in the Fibonacci sequence that begins with f(1) = 1, f(2) = 2.
If multiple such factorizations are possible, I need the factorization that minimizes the score.
Example:
104 = 13 * 8 or 104 = 13 * 2 * 2 * 2
f(6) = 13, f(5) = 8, f(2) = 2
For 104 = 13*8 = f(6)*f(5), we have a count of 2, indices of 6 & 5, giving us 2 + 6 + 5 - 1 = 12.
For 104 = 13 * 2 * 2 * 2 = f(6) * f(2) * f(2) * f(2), we have a count of 4 and indices of 6, 2, 2, 2, giving us 4 + 6 + 2 + 2 + 2 - 1 = 15.
We should pick 13 * 8 since it has the lower score.
The biggest problem I've come across is when we have a number like 1008, which is divisible by 144 and 21, but needs to be divided by 21 because 1008 % 7 == 0. Because my program is first dividing by the biggest numbers, number 144 is 'stealing' 3 from number 21 so my program doesn't find a solution.
Carmichael's theorem proves that each Fibonacci number after 144 has at least one prime divisor that doesn't divide any earlier Fibonacci number.
There aren't many Fibonacci numbers under 10^18; fewer than 90.
Make an array of all the Fibonacci numbers <= 10^18.
Given an input n which is the product of Fibonacci numbers, its factorization into Fibonacci numbers must include every Fibonacci number above 144 that divides it, repeated as many times as it divides it.
Go through your Fibonacci numbers in descending order and keep dividing n by any such number that divides it, until you get to 144.
Now we need to be careful because two Fibonacci numbers don't have any prime factors not seen in previous Fibonacci numbers. These are 8 and 144. Since 8 is 2^3 and 2 is a Fibonacci number, you can't render your number unfactorable into Fibonacci numbers by taking the 8. Under your optimization, you will always choose the 8.
Then 144 is the only factor that you might need to reject for a smaller factor. This can only happen if 34 or 21 are factors, and the 144 eliminates a needed 2 or 3.
34 = 2 * 17, 21 = 3 * 7
That was long-winded, but it gets us to a simple approach.
Go through the Fibonacci numbers <= n in descending order until you get to 144, then skip to 34, then 21, then back to 144 and descending down to 2.
This will give you the optimal factorization under your weird scoring scheme.
----- this order -----
[679891637638612258, 420196140727489673, 259695496911122585, 160500643816367088, 99194853094755497, 61305790721611591, 37889062373143906, 23416728348467685, 14472334024676221, 8944394323791464, 5527939700884757, 3416454622906707, 2111485077978050, 1304969544928657, 806515533049393, 498454011879264, 308061521170129, 190392490709135, 117669030460994, 72723460248141, 44945570212853, 27777890035288, 17167680177565, 10610209857723, 6557470319842, 4052739537881, 2504730781961, 1548008755920, 956722026041, 591286729879, 365435296162, 225851433717, 139583862445, 86267571272, 53316291173, 32951280099, 20365011074, 12586269025, 7778742049, 4807526976, 2971215073, 1836311903, 1134903170, 701408733, 433494437, 267914296, 165580141, 102334155, 63245986, 39088169, 24157817, 14930352, 9227465, 5702887, 3524578, 2178309, 1346269, 832040, 514229, 317811, 196418, 121393, 75025, 46368, 28657, 17711, 10946, 6765, 4181, 2584, 1597, 987, 610, 377, 233, 34, 21, 144, 89, 55, 13, 8, 5, 3, 2]
I am iterating through the array and every time I would like to find 2 elements with the minimum difference from the remaining array.
e.g given array=[5,3,6,1,3], if iterator i is at index 2 so array[i]=6, I would like to find the minimum difference that 2 elements from the array excluding 6 could give.
I was thinking of finding first and second maximum elements for every iteration, but I do not know how to ignore array[i] element. Any tips would be appreciated.
On the outer loop, track the index using enumerate(). Then on the inner loop which iterates the rest of the items (to get the minimum difference), also track the index so that we can skip it if it is equal to the outer loop's index.
Here are some solutions for you. We don't need to get all the differences of all pairs of numbers as that would result to a factorial time complexity (since we will get all possible combinations/pairs). What we can do is simply sort the array, then once sorted
We only need to get the difference of each consecutive number e.g. [1, 3, 10, 11, 12] we just need to subtract 3 - 1, 10 - 3, 11 - 10, and 12 - 11. There is no more point of doing e.g. 12 - 1 because we are sure that it would be greater than any of the consecutive pairs.
Aside from consecutive pairs, we also need to get alternating pairs so that if we removed a number, we will still consider the difference of its previous and next e.g. [10, 12, 14]. If we are at item 12, then 12 -10 and 14 - 12 shouldn't be considered. But 14 - 10 should be!
Solution 1
A bit complicated, but is only O(n log n) in time complexity.
Sort the array. The sorted values must contain the original indices.
Store the differences in sorted order, but keep it at a maximum of 3 items only wherein those 3 items are the least differences (same idea with bounded min heaps).
Why 3 items? Say for example we have [1, 10, 12, 14, 100]. Then we know that the minimum difference is 2 which is the result of 12 - 10 and 14 - 12. For item 1, the min diff is 2, same with items 10, 14, and 100. But for 12, it shouldn't be 2 because if we remove 12, the next min diff is 14 - 10 which is 4. This would be the worst case. So we need to store maximum of 3 minimum differences, which here will be 2 from 12 - 10, 2 from 14 - 12, and 4 from 14 - 10 so that we can catch the case for 12 which should pick the third option (4 from 14 - 10).
Iterate the original array. For each item, see the first applicable difference and display it. This would be the difference that wasn't a result of using the current item in the subtraction.
from bisect import insort
numbers = [14, 10, -11, 27, 12, 4, 20]
numbers_sorted = sorted(enumerate(numbers), key=lambda value: value[1]) # O(n log n)
differences = []
for index in range(1, len(numbers_sorted)): # O(n), the binary search and pop on <differences> are negligible because it is fixed at the constant size of 3
for prev in range(1, 2 if index == 1 else 3): # Subtract consecutive and alternating
diff_tup = (
numbers_sorted[index][1] - numbers_sorted[index-prev][1],
numbers_sorted[index-prev],
numbers_sorted[index],
)
insort(differences, diff_tup)
if len(differences) > 3:
differences.pop()
for index, num in enumerate(numbers): # O(n), the iteration of <differences> is negligible because it is fixed at the constant size of 3
for diff in differences:
if index != diff[1][0] and index != diff[2][0]:
print(f"{num}: min diff {diff[0]} from {diff[1][1]} and {diff[2][1]}")
break
Solution 2
More straight-forward, but is O(n ^ 2) in time complexity.
Sort the array. The sorted values must contain the original indices.
Iterate the array in the primary loop.
For each item, iterate the sorted array.
Skip if the item if it is the one in the primary loop.
Otherwise, subtract the numbers.
If it is less than the current minimum, set it as the new minimum.
Display the minimum for the current number
from bisect import insort
numbers = [14, 10, -11, 27, 12, 4, 20]
numbers_sorted = sorted(enumerate(numbers), key=lambda value: value[1]) # O(n log n)
for num_index, num in enumerate(numbers): # O(n ^ 2)
min_diff = None
min_subtractors = None
for index in range(1, len(numbers_sorted)):
for prev in range(1, 2 if index == 1 else 3): # Subtract consecutive and alternating
if num_index == numbers_sorted[index][0] or num_index == numbers_sorted[index-prev][0]:
continue
diff = numbers_sorted[index][1] - numbers_sorted[index-prev][1]
if min_diff is None or diff < min_diff:
min_diff = diff
min_subtractors = (numbers_sorted[index-prev][1], numbers_sorted[index][1])
print(f"{num}: min diff {min_diff} from {min_subtractors[0]} and {min_subtractors[1]}")
Output
14: min diff 2 from 10 and 12
10: min diff 2 from 12 and 14
-11: min diff 2 from 10 and 12
27: min diff 2 from 10 and 12
12: min diff 4 from 10 and 14
4: min diff 2 from 10 and 12
20: min diff 2 from 10 and 12
t = int(input())
lis =[]
for i in range(t):
col = list(map(int,input()))
colindex = col[0] - 1
count = 0
matsize = col[0] * col[0]
mat = list(map(int,input().split()))
while len(lis) != matsize:
for j in range(len(mat)):
if colindex < len(mat):
if mat[j] == mat[colindex]:
lis.append(mat[j])
colindex += col[0]
count += 1
colindex = col[0] - 1
colindex -= count
for i in lis:
print(i,end= ' ')
Given a square matrix mat[][] of size N x N. The task is to rotate it by 90 degrees in anti-clockwise direction without using any extra space.
Input:
The first line of input contains a single integer T denoting the number of test cases. Then T test cases follow. Each test case consist of two lines. The first line of each test case consists of an integer N, where N is the size of the square matrix.The second line of each test case contains N x N space separated values of the matrix mat.
Output:
Corresponding to each test case, in a new line, print the rotated array.
Constraints:
1 ≤ T ≤ 50
1 ≤ N ≤ 50
1 <= mat[][] <= 100
Example:
Input:
2
3
1 2 3 4 5 6 7 8 9
2
5 7 10 9
Output:
3 6 9 2 5 8 1 4 7
7 9 5 10
Explanation:
Testcase 1: Matrix is as below:
1 2 3
4 5 6
7 8 9
Rotating it by 90 degrees in anticlockwise directions will result as below matrix:
3 6 9
2 5 8
1 4 7
https://practice.geeksforgeeks.org/problems/rotate-by-90-degree/0
It doesn't look like there is a problem with j. Can colindex ever be below 0? One way to identify this would be to simply keep track of the counters. For example, you can add an extra if condition if colindex >= 0: before if mat[j] == mat[colindex].
Rather than using one dimensional list, we can use two dimensional list to solve this challenge. From the given statement and sample test case, we get the following information:
Print the rotated matrix in a single line.
If the given matrix has n columns, the rotated matrix will have the sequential elements of n-1th column, n-2th column, .. 0th column.
Here is my accepted solution of this challenge:
def get_rotated_matrix(ar, n):
ar_2d = []
for i in range(0, len(ar)-n+1, n):
ar_2d.append(ar[i:i+n])
result = []
for i in range(n-1, -1, -1):
for j in range(n):
result.append(str(ar_2d[j][i]))
return result
cas = int(input())
for t in range(cas):
n = int(input())
ar = list(map(int, input().split()))
result = get_rotated_matrix(ar, n)
print(" ".join(result))
Explanation:
To make the solution simple, I created a 2 dimensional list to store the input data as a 2D matrix called ar_2d.
Then I traverse the matrix column wise; from last column to first column and appended the values to our result list as string value.
Finally, I have printed the result with space between elements using join method.
Disclaimer:
My solution uses a 1D list to store the rotated matrix elements thus usages extra space.
As you can see, dividing 3/7 yields a fraction. But when I do 3%7 it yields 3. How could this be? I suppose I expected an output value of 4 (because it would take 4 to complete 7) or 0, (because there is no remainder at all if you use integer division such as 3//7).
>>> 3/7
0.42857142857142855
>>> 3%7
3
>>>
Just trying to understand the depths of Python. Thanks!
Remember long division? Before you learned about fractions, 50 divided by 7 would be 7, remainder 1. The remainder is the modulus. It is the numerator of the 1/7 remaining after integer division.
Let's use different numbers for demonstration.
42 divided by 5 gives a quotient of 8 and a remainder of 2. That means 42 // 5 == 8 and 42 % 5 == 2.
3 divided by 7 gives a quotient of 0 and a remainder of 3. That means 3 // 7 == 0 and 3 % 7 == 3.
In Python, // and % represent the quotient and remainder you probably learned about before you learned about fractions and real numbers. The only (possible) difference is that // floors and % matches the sign of the right-hand operand.
modulo returns the whole number after integer (floor) division.
>>>3//7
0 # with remainder 3
>>>3%7
3
>>>2//5
2 # with remainder 1
>>>2%5
1
Re-reading your question, it occurred to me you got your terms mixed up and that may have been the underlying confusion that none of us properly answered.
But when I do 3%7 it yields 3. How could this be? I suppose I expected an output value of 4 (because it would take 4 to complete 7)
So first that issue was masked when you said 4. Since 4 is greater than 3, 3 can be subtracted a second time, leaving 1. So 1 is the output of 7 % 3.
But you asked about 3 % 7, even though you then proceeded to explain 7 % 3. 3 % 7 is less than 1 (because 7 > 3). So that is why the modulus is still 3. Integer division gives you 0, so 3 is left.
Take the first term (3) divided by the second term (7) using integer division (resulting in 0). Subtract that number from the first term (3) and you get 3. So: 3 % 7 = 3