簡體   English   中英

查找所有三個“兩位數字”,沒有重復的數字

[英]Find all three “two digit numbers” with no repeated digit

寫發現正整數的所有的三元組的節目(i, j, k)使得ijk是兩位數字,無位發生在一次以上ijk

我寫道:

for i in range(10,100):
    for j in range(10,100):
        for k in range(10,100):
                if i%10 !=i//10 !=j%10 !=j//10 != k%10 != k//10:
                    print(i,j,k)

為什么仍然不正確? 它仍然在ijk包含相同的數字。 怎么了?

正如Arya McCarthy所提到的,您的代碼僅檢查它們是否相同。 下面的代碼檢查ijk是否沒有重復的數字。

for i in range(10,100):
    for j in range(10,100):
        for k in range(10,100):
            digits = {i%10, i//10, j%10, j//10, k%10, k//10}
            if len(digits) == 6:
                print(i,j,k)

您可以直接從兩位數字構建一個集合,並檢查長度是否為6; 保存所有數學:

for i in range(10,100):
    for j in range(10,100):
        for k in range(10,100):
            if len(set('{}{}{}'.format(i,j,k))) == 6:
                    print(i,j,k)

如果您選擇堅持數學,則可以用divmod替換%// ,然后檢查:

len(set(divmod(i,10)+divmod(j,10)+divmod(k,10))) == 6

使用itertools.combinations另一種方法:

from itertools import combinations

possible_values = combinations(range(10, 100), 3)

satisfies_condition = {(x, y, z) for x, y, z in possible_values if 
                        len({x%10, x//10, y%10, y//10, z%10, z//10}) == 6}

print('\n'.join(map(str, satisfies_condition)))

印刷品:

(17, 40, 82)
(74, 90, 28)
(29, 37, 40)
(73, 96, 10)
(31, 97, 85)
(83, 70, 91)
(15, 23, 69)
(23, 49, 15)
(56, 18, 37)

從技術上講,為了匹配您的工作,可以使用itertools.permutations (因為順序對您的方法很重要)。 但我認為,從這個問題的核心出發,長度三的組合是最合適的。

有一種更快的方法可以解決這個問題。 使用combinationspermutations

from itertools import combinations, permutations

l = range(10)

for c in combinations(l, 6):  # all 6-combinations of the numbers 0-9
    for c1, c2, c3, c4, c5, c6 in permutations(c):  # all permutations of these numbers
        if c1 == 0 or c3 == 0 or c5 == 0:
            continue  # exclude those where the first digit of any number is 0
        else:
            print('{}{} {}{} {}{}'.format(c1, c2, c3, c4, c5, c6))

它從數字0到9取6個數字(無替換!),然后遍歷這些數字的所有排列。 唯一的檢查是每個數字的第一位數字都不為0 (否則根據問題它就不會是兩位數字)。 要獲取數字,您可以使用:

i = 10*c1 + c2
j = 10*c3 + c4
k = 10*c5 + c6

如果您需要它們。

使用這種方法,與原始方法相比,您不需要扔掉那么多數字。

您甚至可以更進一步,並使用一set數字來繪制數字:

l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}  # set of allowed numbers

for n1 in l - {0}:  # all numbers except 0
    for n2 in l - {n1}:  # all numbers except the first number
        for n3 in l - {0, n1, n2}:  # all numbers except 0 and the first and second number
            for n4 in l - {n1, n2, n3}:  # ...
                for n5 in l - {0, n1, n2, n3, n4}:
                    for n6 in l - {n1, n2, n3, n4, n5}:
                        print('{}{} {}{} {}{}'.format(n1, n2, n3, n4, n5, n6))

這將用set差異替換if條件,並且不會生成“不必要的”對。

定時

為了了解該方法可以帶來什么不同,我對不同的答案進行了計時:

%%timeit

l = set(range(10))

for n1 in l - {0}:
    for n2 in l - {n1}:
        for n3 in l - {0, n1, n2}:
            for n4 in l - {n1, n2, n3}:
                for n5 in l - {0, n1, n2, n3, n4}:
                    for n6 in l - {0, n1, n2, n3, n4, n5}:
                        pass

每個循環57.3 ms±295 µs(平均±標准偏差,運行7次,每個循環10個)

%%timeit

from itertools import combinations, permutations

l = range(10)

for c in combinations(l, 6):
    for c1, c2, c3, c4, c5, c6 in permutations(c):
        if c1 == 0 or c3 == 0 or c5 == 0:
            continue
        else:
            pass

每個循環61.2 ms±101 µs(平均±標准偏差,運行7次,每個循環10個)

%%timeit

for i in range(10,100):
    for j in range(10,100):
        for k in range(10,100):
            digits = {i%10, i//10, j%10, j//10, k%10, k//10}
            if len(digits) == 6:
                pass

每個循環1.7 s±2.36毫秒(平均±標准偏差,共7次運行,每個循環1次)

%%timeit

for i in range(10,100):
    for j in range(10,100):
        for k in range(10,100):
            if len(set('{}{}{}'.format(i,j,k))) == 6:
                pass

每個循環3.29 s±40.1 ms(平均±標准偏差,共7次運行,每個循環1次)

%%timeit

from itertools import combinations

possible_values = combinations(range(10, 100), 3)

satisfies_condition = {(x, y, z) for x, y, z in possible_values if 
                        len({x%10, x//10, y%10, y//10, z%10, z//10}) == 6}

for i in satisfies_condition:
    pass

每個循環300 ms±7.73 ms(平均±標准偏差,共7次運行,每個循環1次)

因此,生成較少被排除的對(前兩個)的方法比使用C循環的方法(@not_a_robot給出的combinations方法)快約5倍,但是這種方法並不能提供所有解決方案,因此練習會慢得多),並且比range(10, 100)的三個循環range(10, 100)快30倍左右(@Will Da Silva的答案-@Moses Koledoye的答案甚至更慢,因為字符串格式或元組串聯是比使用設定文字慢很多)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM