The number of combinations of the number 196225 - python

I wanted to write a program that will show the number of combinations of the number 196225 but I failed because it showed very strange numbers and I can't quite understand why
my code:
list = []
liczba = [1,9,6,2,2,5]
n_num = 0
iter=0
#ijlkmn
for i in range(6):
n_num = liczba[i]*10**5
for j in range(6):
if j != i:
n_num += liczba[j]*10**4
for l in range(6):
if l != i and l != j:
n_num += liczba[l]*10**3
for k in range(6):
if k != i and k != j and k!= l:
n_num += liczba[k]*10**2
for m in range(6):
if m != i and m != j and m != l and m!= k:
n_num += liczba[m]*10
for n in range(6):
if n != i and n != j and n != l and n!= k and n!= m:
n_num += liczba[n]
if (n_num in list) == False:
list.append(n_num)
iter += 1
I know it looks very primitive but I only wanted the result which turned out to be incorrect, here are some of its numbers ~
196225, 196277, 196502, 196554, 197076, 197098, 199723, 199775, 200040
could someone tell me where did these numbers come from?

if you want to make all the possible numbers using tose digits , you can use itertools module :
import itertools
liczba = [1, 9, 6, 2, 2, 5]
numbers = itertools.permutations(liczba, 6)
for num in numbers:
print(num)

You are adding to previous answers on each of your internal loops. Because the value of n_num is not reset at each iteration. For example:
digits = [1,2,3]
for k in range(3):
n_num = digits[k]*10**2
for k2 in range(3):
if k2!=k:
n_num += digits[k2]*10
print(n_num)
prints
120
150
210
240
310
330
because when k2 = 2 the first time, 30 is added to 120 yielding 150... etc etc

I see what's wrong with your code - let's look into smaller example to see it clearly and find a solution
liczba = [1, 2, 3]
for i in range(3):
n_num = liczba[i] * 10 ** 2 # it start with 1 * 100 = 100, good one!
for j in range(3):
if j != i: # for j = 0 it just pass
n_num += liczba[j] * 10 # j = 1, n_num is now 100 + 20 = 120
for l in range(3):
if l != i and l != j: we skip 0 and 1
n_num += liczba[l] # n_num = 123, great
list.append(n_num)
Now we back to second loop:
for j in range(3): # j jumps to 2
if j != i:
n_num += liczba[j] * 10 # wait - here is the problem, our n_num should be 100 here again but now it's 123, so we add 30 to previous solution
for l in range(3):
if l != i and l != j: # l = 1
n_num += liczba[l] # adding 2, but instead of 100 + 30 + 2 we have 123 + 30 + 2
list.append(n_num)
How to fix it? Very simple - you can just calculate number once at the end. You have all indexes already, so write
n_num = liczba[i] * 10 ** 5 + liczba[j] * 10 ** 4 + ...
And one small hint for the end - if you use set instead of list you won't need a check if n_num is already in result.

Related

How can I get below result using nested for loop where is input is 3?

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.

Remove elements from the array which appear more than k times

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)

Nested-loop odd pattern in Python

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

How to fix my code for Traverse Diagonal Matrix (alterate version)?

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]

My FB HackerCup code too slow of large inputs

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))

Categories