Related
I want to make a pattern as shown below:
N = 1
*
N = 3
*
***
*
N = 5
*
***
*****
***
*
and so on...
Nevertheless, I write this program only works for N = 5. Could anybody please explain what the mistake is and what the solution is? Thanks.
N = int(input())
k = 1
for i in range(1, N - 1):
for j in range(1, N + 1):
if(j <= N - k):
print(' ', end = '')
else:
print('*', end = '')
k = k + 2
print()
k = 2
for i in range(1, N - 2):
for j in range(1, N + 1):
if(j >= N - k):
print('*', end = '')
else:
print(' ', end = '')
k = k - 2
print()
You are trying to print a pyramid of N lines with two for-loops using range. So the sum of of the lengths of your two ranges should be N.
Now consider the sum of for i in range(1, N - 1) and for i in range(1, N - 2) with some large N. Take N=99 for example:
len(range(1, 99 - 1)) + len(range(1, 99 - 2))
>>> 193
This is your first mistake. The function only works with N=5 because of the two minuses you have chosen for your ranges. What you need to do here is to rewrite your math:
len(range((99+1)//2)) + len(range((99-1)//2))
>>> 99
Note that I removed the starting value from ranges, as it is not needed here. By default, range starts to count from 0 and ends one number before the ending value.
The second mistake you have is with how you are printing the bottom half of the triangle. Basically, you have tried to reverse everything to print everything in reverse, but that has somehow broken the logic. What here we want to do is to print k empty spaces for each line, incrementing k by two for each line.
Function with minimal fixes:
N = int(input())
k = 1
for i in range((N+1)//2):
for j in range(1, N + 1):
if(j <= N - k):
print(' ', end = '')
else:
print('*', end = '')
k = k + 2
print()
k = 2
for i in range((N-1)//2):
for j in range(1, N + 1):
if(j > k):
print('*', end = '')
else:
print(' ', end = '')
k = k + 2
print()
List comprehension is one pythonic trick to avoid multiple nested loops and can be very efficient. Another general guideline is to break down into smaller testable functions
N = 5
def print_pyramid(n):
for i in [min(2*i+1, 2*n-2*i-1) for i in range(n)]:
print((" " * (n-i)) + ("*" * i))
k = 1
while k <= N:
print("N = " + str(k))
print_pyramid(k)
print("")
k += 2
I'm taking an algorithms course online and I am trying to calculate the maximum pairwise product in a list of numbers. This question has already been answered before:
maximum pairwise product fast solution and
Python for maximum pairwise product
I was able to pass the assignment by looking at those two posts. I was hoping that maybe someone could help me figure out how to correct my solution. I was able to apply a stress test and found out if the largest number in the array is in the starting index it will just multiply itself twice.
This is the test case I failed using the assignment automatic grader
Input:
2
100000 90000
Your output:
10000000000
Correct output:
9000000000
Here is my pairwise method and stress test
from random import randint
def max_pairwise_product(numbers):
n = len(numbers)
max_product = 0
for first in range(n):
for second in range(first + 1, n):
max_product = max(max_product,
numbers[first] * numbers[second])
return max_product
def pairwise1(numbers):
max_index1 = 0
max_index2 = 0
#find the highest number
for i, val in enumerate(numbers):
if int(numbers[i]) > int(numbers[max_index1]):
max_index1 = i
#find the second highest number
for j, val in enumerate(numbers):
if j != max_index1 and int(numbers[j]) > int(numbers[max_index2]):
max_index2 = j
#print(max_index1)
#print(max_index2)
return int(numbers[max_index1]) * int(numbers[max_index2])
def stressTest():
while True:
arr = []
for x in range(5):
random_num = randint(2,101)
arr.append(random_num)
print(arr)
print('####')
result1 = max_pairwise_product(arr)
result2 = pairwise1(arr)
print("Result 1 {}, Result2 {}".format(result1,result2))
if result1 != result2:
print("wrong answer: {} **** {}".format(result1, result2))
break
else:
print("############################################# \n Ok", result1, result2)
if __name__ == '__main__':
stressTest()
'''
length = input()
a = [int(x) for x in input().split()]
answer = pairwise1(a)
print(answer)
'''
Any feedback will be greatly appreciated.
Thanks.
When max number is on position 0, you will get both max_index1 and max_index2 as 0.
That's why you are getting like this .
Add the following lines before #find the second highest number in pairwise1 function .
if max_index1==0:
max_index2=1
else:
max_index2=0
So function will be like:
def pairwise1(numbers):
max_index1 = 0
max_index2 = 0
#find the highest number
for i, val in enumerate(numbers):
if int(numbers[i]) > int(numbers[max_index1]):
max_index1 = i
if max_index1==0:
max_index2=1
else:
max_index2=0
#find the second highest number
for j, val in enumerate(numbers):
if j != max_index1 and int(numbers[j]) > int(numbers[max_index2]):
max_index2 = j
#print(max_index1)
#print(max_index2)
return int(numbers[max_index1]) * int(numbers[max_index2])
I'm trying to loop over a matrix and replacing the entries using operations involving the matrices around it:
For example,
xarray = np.array([3,35,7,9,8,7,6])
yarray = np.array([2,5,1,7,3,59,2])
zarray = np.array([3,5,6,3.5,69,2,1])
barray = np.array([1,5,56,7,24,2,1])
carray = np.array([1,5,56,7,24,2,1])
darray = np.array([1,5,56,7,24,2,1])
earray = np.array([1,5,56,7,24,2,1])
Q = np.array([xarray,yarray,zarray,barray,carray,darray,earray])
k = np.shape(Q)
for i in range(k[0]):
for j in range(k[1]):
$taking into account entries on the corners which don't have the same amount of surrounding matrices
if i==0 or j==0 or i == k[0] or j == k[1]:
Q[i,j] = Q[i,j]
else:
Q[i,j] = (Q[i,j]+Q[i-1,j]+Q[i+1,j]+Q[i,j+1]+Q[i-1,j-1]+Q[i-1,j+1])*3
print Q
But I get the error above. Any help would be appreciated.
Remember that in python indexes start from 0, which means if i or j is equal to the length of the array, you'll get an error
All I've done here is switched range(k[x]) for range(k[x] - 1)
for i in range(k[0] - 1):
for j in range(k[1] - 1):
if i==0 or j==0:
Q[i,j] = Q[i,j]
else:
Q[i,j] = (Q[i,j]+Q[i-1,j]+Q[i+1,j]+Q[i,j+1]+Q[i-1,j-1]+Q[i-1,j+1])*3
I'm really new at Python so I apologize in advance if this is a really dumb question. Pretty much, I'm writing a longest common subsequence algorithm with dynamic programming.
Whenever I try to run it, I get the IndexError: list index out of range, and I don't know why because the array I'm adding values to never changes in size. Code snippet for clarity:
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n)]for number in range(0, m)]
for i in range(1, n):
for j in range(1, m):
if(sequence1[i] == sequence2[j]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
There seem to be two problems:
In the definition of D, you should swap n and m
D = [[0 for num in range(0, m)] for number in range(0, n)]
You have to print (or better: return) the last element of the matrix
return D[n-1][m-1] # or just D[-1][-1]
The issue is with total rows and columns of the matrix(D). Size should be (m+1)*(n+1) and then loop over the matrix. Otherwise you need to return D[m-1][n-1].
def LCS(sequence1, sequence2):
n = len(sequence1)
m = len(sequence2)
D = [[0 for num in range(0,n+1)]for number in range(0, m+1)]
for i in range(1, n+1):
for j in range(1, m+1):
if(sequence1[i-1] == sequence2[j-1]):
D[i][j] = D[i-1][j-1] + 1
else:
D[i][j] = max(D[i-1][j], D[i][j-1])
print D[n][m]
LCS('abcdef' , 'defjkl')
I was solving the Find the min problem on facebook hackercup using python, my code works fine for sample inputs but for large inputs(10^9) it is taking hours to complete.
So, is it possible that the solution of that problem can't be computed within 6 minutes using python? Or may be my approaches are too bad?
Problem statement:
After sending smileys, John decided to play with arrays. Did you know that hackers enjoy playing with arrays? John has a zero-based index array, m, which contains n non-negative integers. However, only the first k values of the array are known to him, and he wants to figure out the rest.
John knows the following: for each index i, where k <= i < n, m[i] is the minimum non-negative integer which is not contained in the previous *k* values of m.
For example, if k = 3, n = 4 and the known values of m are [2, 3, 0], he can figure out that m[3] = 1.
John is very busy making the world more open and connected, as such, he doesn't have time to figure out the rest of the array. It is your task to help him.
Given the first k values of m, calculate the nth value of this array. (i.e. m[n - 1]).
Because the values of n and k can be very large, we use a pseudo-random number generator to calculate the first k values of m. Given positive integers a, b, c and r, the known values of m can be calculated as follows:
m[0] = a
m[i] = (b * m[i - 1] + c) % r, 0 < i < k
Input
The first line contains an integer T (T <= 20), the number of test
cases.
This is followed by T test cases, consisting of 2 lines each.
The first line of each test case contains 2 space separated integers,
n, k (1 <= k <= 10^5, k < n <= 10^9).
The second line of each test case contains 4 space separated integers
a, b, c, r (0 <= a, b, c <= 10^9, 1 <= r <= 10^9).
I tried two approaches but both failed to return results in 6 minutes, Here's my two approaches:
first:
import sys
cases=sys.stdin.readlines()
def func(line1,line2):
n,k=map(int,line1.split())
a,b,c,r =map(int,line2.split())
m=[None]*n #initialize the list
m[0]=a
for i in xrange(1,k): #set the first k values using the formula
m[i]= (b * m[i - 1] + c) % r
#print m
for j in range(0,n-k): #now set the value of m[k], m[k+1],.. upto m[n-1]
temp=set(m[j:k+j]) # create a set from the K values relative to current index
i=-1 #start at 0, lowest +ve integer
while True:
i+=1
if i not in temp: #if that +ve integer is not present in temp
m[k+j]=i
break
return m[-1]
for ind,case in enumerate(xrange(1,len(cases),2)):
ans=func(cases[case],cases[case+1])
print "Case #{0}: {1}".format(ind+1,ans)
Second:
import sys
cases=sys.stdin.readlines()
def func(line1,line2):
n,k=map(int,line1.split())
a,b,c,r =map(int,line2.split())
m=[None]*n #initialize
m[0]=a
for i in xrange(1,k): #same as above
m[i]= (b * m[i - 1] + c) % r
#instead of generating a set in each iteration , I used a
# dictionary this time.
#Now, if the count of an item is 0 then it
#means the item is not present in the previous K items
#and can be added as the min value
temp={}
for x in m[0:k]:
temp[x]=temp.get(x,0)+1
i=-1
while True:
i+=1
if i not in temp:
m[k]=i #set the value of m[k]
break
for j in range(1,n-k): #now set the values of m[k+1] to m[n-1]
i=-1
temp[m[j-1]] -= 1 #decrement it's value, as it is now out of K items
temp[m[k+j-1]]=temp.get(m[k+j-1],0)+1 # new item added to the current K-1 items
while True:
i+=1
if i not in temp or temp[i]==0: #if i not found in dict or it's val is 0
m[k+j]=i
break
return m[-1]
for ind,case in enumerate(xrange(1,len(cases),2)):
ans=func(cases[case],cases[case+1])
print "Case #{0}: {1}".format(ind+1,ans)
The last for-loop in second approach can also be written as :
for j in range(1,n-k):
i=-1
temp[m[j-1]] -= 1
if temp[m[j-1]]==0:
temp.pop(m[j-1]) #same as above but pop the key this time
temp[m[k+j-1]]=temp.get(m[k+j-1],0)+1
while True:
i+=1
if i not in temp:
m[k+j]=i
break
sample input :
5
97 39
34 37 656 97
186 75
68 16 539 186
137 49
48 17 461 137
98 59
6 30 524 98
46 18
7 11 9 46
output:
Case #1: 8
Case #2: 38
Case #3: 41
Case #4: 40
Case #5: 12
I already tried codereview, but no one replied there yet.
After at most k+1 steps, the last k+1 numbers in the array will be 0...k (in some order). Subsequently, the sequence is predictable: m[i] = m[i-k-1]. So the way to solve this problem is run your naive implementation for k+1 steps. Then you've got an array with 2k+1 elements (the first k were generated from the random sequence, and the other k+1 from iterating).
Now, the last k+1 elements are going to repeat infinitely. So you can just return the result for m[n] immediately: it's m[k + (n-k-1) % (k+1)].
Here's some code that implements it.
import collections
def initial_seq(k, a, b, c, r):
v = a
for _ in xrange(k):
yield v
v = (b * v + c) % r
def find_min(n, k, a, b, c, r):
m = [0] * (2 * k + 1)
for i, v in enumerate(initial_seq(k, a, b, c, r)):
m[i] = v
ks = range(k+1)
s = collections.Counter(m[:k])
for i in xrange(k, len(m)):
m[i] = next(j for j in ks if not s[j])
ks.remove(m[i])
s[m[i-k]] -= 1
return m[k + (n - k - 1) % (k + 1)]
print find_min(97, 39, 34, 37, 656, 97)
print find_min(186, 75, 68, 16, 539, 186)
print find_min(137, 49, 48, 17, 461, 137)
print find_min(1000000000, 100000, 48, 17, 461, 137)
The four cases run in 4 seconds on my machine, and the last case has the largest possible n.
Here is my O(k) solution, which is based on the same idea as above, but runs much faster.
import os, sys
f = open(sys.argv[1], 'r')
T = int(f.readline())
def next(ary, start):
j = start
l = len(ary)
ret = start - 1
while j < l and ary[j]:
ret = j
j += 1
return ret
for t in range(T):
n, k = map(int, f.readline().strip().split(' '))
a, b, c, r = map(int, f.readline().strip().split(' '))
m = [0] * (4 * k)
s = [0] * (k+1)
m[0] = a
if m[0] <= k:
s[m[0]] = 1
for i in xrange(1, k):
m[i] = (b * m[i-1] + c) % r
if m[i] < k+1:
s[m[i]] += 1
p = next(s, 0)
m[k] = p + 1
p = next(s, p+2)
for i in xrange(k+1, n):
if m[i-k-1] > p or s[m[i-k-1]] > 1:
m[i] = p + 1
if m[i-k-1] <= k:
s[m[i-k-1]] -= 1
s[m[i]] += 1
p = next(s, p+2)
else:
m[i] = m[i-k-1]
if p == k:
break
if p != k:
print 'Case #%d: %d' % (t+1, m[n-1])
else:
print 'Case #%d: %d' % (t+1, m[i-k + (n-i+k+k) % (k+1)])
The key point here is, m[i] will never exceeds k, and if we remember the consecutive numbers we can find in previous k numbers from 0 to p, then p will never reduce.
If number m[i-k-1] is larger than p, then it's obviously we should set m[i] to p+1, and p will increase at least 1.
If number m[i-k-1] is smaller or equal to p, then we should consider whether the same number exists in m[i-k:i], if not, m[i] should set equal to m[i-k-1], if yes, we should set m[i] to p+1 just as the "m[i-k-1]-larger-than-p" case.
Whenever p is equal to k, the loop begin, and the loop size is (k+1), so we can jump out of the calculation and print out the answer now.
I enhanced the performance through adding map.
import sys, os
import collections
def min(str1, str2):
para1 = str1.split()
para2 = str2.split()
n = int(para1[0])
k = int(para1[1])
a = int(para2[0])
b = int(para2[1])
c = int(para2[2])
r = int(para2[3])
m = [0] * (2*k+1)
m[0] = a
s = collections.Counter()
s[a] += 1
rs = {}
for i in range(k+1):
rs[i] = 1
for i in xrange(1,k):
v = (b * m[i - 1] + c) % r
m[i] = v
s[v] += 1
if v < k:
if v in rs:
rs[v] -= 1
if rs[v] == 0:
del rs[v]
for j in xrange(0,k+1):
for t in rs:
if not s[t]:
m[k+j] = t
if m[j] < k:
if m[j] in rs:
rs[m[j]] += 1
else:
rs[m[j]] = 0
rs[t] -= 1
if rs[t] == 0:
del rs[t]
s[t] = 1
break
s[m[j]] -= 1
return m[k + ((n-k-1)%(k+1))]
if __name__=='__main__':
lines = []
user_input = raw_input()
num = int(user_input)
for i in xrange(num):
input1 = raw_input()
input2 = raw_input()
print "Case #%s: %s"%(i+1, min(input1, input2))