python - Optimized way for finding the number which satisfies specific conditions -


i saw question somewhere. there 8 digit number. first digit left right tells how many zeroes in number. second digit tells how many 1s in number, third digit tells u how many 2 in number , on till 8th digit tells u how many 7 in number. find number. wrote piece of code in python find out digit. apart conditions mentioned above, have few additional checks 'sum of digits should 8' , 'no 8 or 9 should present in number'. i've pasted code below. brute force since take every number , check conditions. curious know if there better way of solving problem

def returnstat(number, digit, count):     number = str(number)         digit = str(digit)     print "analysing ",digit," see if appears ",count, " times in ",number,"."             actcnt = number.count(digit)     count = str(count)     actcnt = str(actcnt)     if (actcnt == count):         return 1     else:         return 0  def validatenum(number):     numlist = str(number)     if '8' in numlist:         print "skipping ",number, " since has 8 in it"         return (-1)     elif '9' in numlist:         print "skipping ",number, " since has 9 in it"         return (-1)     elif (sum(int(digit) digit in numlist) != 8):         print "skipping ",number, " since sum not equal 8"         return (-1)     index = 0     flag = 0     num in numlist:         if (returnstat(number,index,num)) :             index = index+1             continue         else:             flag = 1             break  if (flag == 1):     return (-1) else:     return number  num in range(0,80000000): number = '{number:0{width}d}'.format(width=8,number=num)  desirednum = "-1" desirednum = validatenum(number) if (desirednum == -1):     print number," not satisfy "     continue else:     print "the number satisfies contition ",number     break 

even if iterate on 8 digit numbers no 8s or 9s in them, there's not many possibilities (actually, 8^8 = 1<<24 ~= 17 million).

here's naive program tries them all:

import itertools  digs in itertools.product(range(8), repeat=8):     counts = [0] * 8     d in digs:         counts[d] += 1     if counts == list(digs):         print digs 

it completes (with 1 solution) in 15 seconds on machine.

to make faster, can consider 8-digit numbers digits add 8. here's same code before, uses sum_k produce possibilities. (sum_k(n, k) generates n-digit tuples digits less 8 sum k).

def sum_k(n, k):     if k < 0 or n * 7 < k: return     if n == 1:         yield k,         return     d in xrange(8):         s in sum_k(n-1, k-d):             yield (d,) + s  digs in sum_k(8, 8):     counts = [0] * 8     d in digs:         counts[d] += 1     if counts == list(digs):         print digs 

this code completes in 0.022 seconds on machine.

adapting code solve general case produces these solutions:

1210 2020 21200 3211000 42101000 521001000 6210001000 72100001000 821000001000 9210000001000 

Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -