I have the code:
n = int(input())
l = []
for i in range(n):
l.append([])
for j in range(n):
if i==j:
l[i].append("*")
elif i+j==n-1:
l[i].append("*")
else:
l[i].append("")
# if i+j==n-1:
# l[i].append("*")
# else:
# l[i].append("")
for i in l:
print(*i)
Which gives me , diagonals.
As j1-lee said, it's enough to add n = 2 * n - 1 after reading it.
But wanted to show alternative approach if you want to just print result:
string = "{0: >{width_1}}{1: >{width_2}}"
n = int(input())
for i in range(1, n):
print(string.format("*", "*", width_1=i, width_2=2 * n - 2 * i))
print("{0: >{width}}".format("*", width=n))
for i in range(n - 1, 0, -1):
print(string.format("*", "*", width_1=i, width_2=2 * n - 2 * i))
{0: >5}.format("abc") syntax means reserve 5 cells to variable and put there "abc". So to achieve that we increase width_1 and deacrese width_2 in loop, then print middle star and then deacrese width_1 and increase width_2 in loop again.
This program gives out the output as
1 6 7 9 11
how can I make it give output as
[1, 6, 7, 9, 11]
Code:
def RemoveElements(my_lst2, n, k):
mp = {i:0 for i in range(len(my_lst2))}
for i in range(n):
mp[my_lst2[i]] += 1
for i in range(n):
if (mp[my_lst2[i]] <= 1):
print(my_lst2[i], end = " ",)
if __name__ == '__main__':
my_lst2 = [0,1,2,3,2,3,4,5,4,5,6,7,9,11,0,5]
n = len(my_lst2)
k = 2
RemoveElements(my_lst2, n, k)
Right now you are doing print(my_lst2[i], end = " ",) which prints it out as you currently have. If you store the my_lst2[i] in a list and then print out that list, you will get what you want.
def RemoveElements(my_lst2, n, k):
mp = {i:0 for i in range(len(my_lst2))}
for i in range(n):
mp[my_lst2[i]] += 1
l = []
for i in range(n):
if (mp[my_lst2[i]] <= 1):
l.append(my_lst2[i])
print(l)
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 have the following code which is used to print diagonal matrix alternatively. Please look at my code and tell me what is wrong with it ?
class Solution:
def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:
# No. of rows
m=len(matrix)
# No. of columns
n=len(matrix[0])
# Counter to alternatively switch the direction.
up=True
# list to store the result
l=[]
i,j,count=0,0,0
# loop for traversing all the elements.
while(count<=m*n):
if(up):
while(i>=0 and j<n):
l.append(matrix[i][j])
count+=1
i-=1
j+=1
if(i<0 and j<n):
i=0
if(j==n):
i=i+2
j=j-1
else:
while(j>=0 and i<m):
l.append(matrix[i][j])
count+=1
j-=1
i+=1
if(j<0 and i<m):
j=0
if(i==m):
j=j+2
i=i-1
up= not up
print(l)
Input :
[
[1,2,3],
[4,5,6],
[7,8,9]
]
Expected Answer :
[1,2,4,7,5,3,6,8,9]
Actual Answer :
Line 22: IndexError: list index out of range
Your code works, just change your while (count <= m * n) to while (count < m * n).
def findDiagonalOrder(matrix):
# No. of rows
m = len(matrix)
# No. of columns
n = len(matrix[0])
# Counter to alternatively switch the direction.
up = True
# list to store the result
l = []
i, j, count = 0, 0, 0
# loop for traversing all the elements.
while (count < m * n):
if (up):
while (i >= 0 and j < n):
l.append(matrix[i][j])
count += 1
i -= 1
j += 1
if (i < 0 and j < n):
i = 0
if (j == n):
i = i + 2
j = j - 1
else:
while (j >= 0 and i < m):
l.append(matrix[i][j])
count += 1
j -= 1
i += 1
if (j < 0 and i < m):
j = 0
if (i == m):
j = j + 2
i = i - 1
up = not up
print(l)
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
findDiagonalOrder(matrix)
#[1, 2, 4, 7, 5, 3, 6, 8, 9]
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))