2010-04-15 19 views
8

這不是家庭作業。幫我完成這個Python 3.x自我挑戰

我看到this article praising Linq library and how great it is做combinatorics的東西,我心想:Python可以以更具可讀性的方式做到這一點。

用Python打了半個小時後我失敗了。請結束我離開的地方。另外,請儘可能採用最爲Pythonic和高效的方式。

from itertools import permutations 
from operator import mul 
from functools import reduce 
glob_lst = [] 
def divisible(n): return (sum(j*10^i for i,j in enumerate(reversed(glob_lst))) % n == 0) 
oneToNine = list(range(1, 10)) 
twoToNine = oneToNine[1:] 
for perm in permutations(oneToNine, 9): 
    for n in twoToNine: 
     glob_lst = perm[1:n] 
     #print(glob_lst) 
     if not divisible(n): 
      continue 
    else: 
     # Is invoked if the loop succeeds 
     # So, we found the number 
     print(perm) 

謝謝!

+1

待辦事項你想要Pythonic還是最有效的?他們可能是非常不同的東西。 :) – 2010-04-15 23:07:21

+0

我想這一切,我想現在;)嗯...每一個以及兩者之一。沒有最好的答案,但我不得不選擇一個。如果您願意的話,請包括timeit one-liner進行性能測試。 – 2010-04-15 23:13:28

+3

爲什麼你在可分的函數中使用按位異或?你的意思是**而不是^? – dan04 2010-04-16 01:57:17

回答

24

這裏有一個簡短的解決方案,使用itertools.permutations

from itertools import permutations 

def is_solution(seq): 
    return all(int(seq[:i]) % i == 0 for i in range(2, 9)) 

for p in permutations('123456789'): 
    seq = ''.join(p) 
    if is_solution(seq): 
     print(seq) 

我故意1和9省略整除的檢查,因爲他們永遠是滿意的。

+0

+ 999非常好! – 2010-04-15 23:06:14

+0

+1;比鏈接文章中的解決方案更優雅(儘管LINQ的「Enourmous表現力」) – SingleNegationElimination 2011-06-30 23:49:29

2

這裏是我的解決方案(而不是優雅的馬克,但它仍然有效):

from itertools import permutations 

for perm in permutations('123456789'): 
    isgood = 1 
    for i in xrange(9): 
     if(int(''.join(perm[:9-i])) % (9-i)): 
      isgood = 0 
      break 
    if isgood: 
     print ''.join(perm) 
+0

我想要時間,但我看到Python 2.x代碼,我不想比較蘋果和桔子。 – 2010-04-15 23:10:31

+0

哦,是的,它確實說了Python 3.x,oops – 2010-04-15 23:14:43

+0

我的任何地方都沒有達到最佳狀態,因爲它可能是..但是爲什麼要這樣呢? – 2010-04-15 23:16:42

1

這是我的解決方案,這是非常相似的商標,但它運行約兩倍的速度

from itertools import permutations 

def is_solution(seq): 
    if seq[-1]=='9': 
     for i in range(8,1,-1): 
      n = -(9-i) 
      if eval(seq[:n]+'%'+str(i))==0: 
       continue 
      else:return False 
     return True 
    else:return False 
for p in permutations('123456789'): 
    seq = ''.join(p) 
    if is_solution(seq): 
     print(seq) 
3

這是我的解決方案。我喜歡所有事情自下而上;-)。在我的機器運行比標誌約580倍的速度(3.1毫秒爲1.8秒):

def generate(digits, remaining=set('123456789').difference): 
    return (n + m 
     for n in generate(digits - 1) 
      for m in remaining(n) 
       if int(n + m) % digits == 0) if digits > 0 else [''] 

for each in generate(9): 
    print(int(each)) 

編輯:另外,這個工作和快兩倍(1.6毫秒):

from functools import reduce 

def generate(): 
    def digits(x): 
     while x: 
      x, y = divmod(x, 10) 
      yield y 
    remaining = set(range(1, 10)).difference 
    def gen(numbers, decimal_place): 
     for n in numbers: 
      for m in remaining(digits(n)): 
       number = 10 * n + m 
       if number % decimal_place == 0: 
        yield number 
    return reduce(gen, range(2, 10), remaining()) 

for each in generate(): 
    print(int(each))