如何在Python 3.x中使用for循环解决这个谜语?

时间:2019-04-17 20:03:27

标签: python-3.x

问题问

神圣数字蝙蝠侠!谜语者正在计划他在宾夕法尼亚大道某处的下一个雀跃。以他通常的运动方式,他以拼图的形式离开了住址。宾夕法尼亚州的地址是一个四位数的数字,具有以下属性:

  • 所有四个数字都不相同
  • 千位数的数字是十位数的三倍
  • 数字是奇数
  • 数字的总和是27。

编写一个使用一个或多个循环的函数,该函数返回Riddler计划罢工的地址。

所以我知道我必须使用除法然后使用模运算符来弹出数字。但是我无法打印任何内容,因此我回去修复代码但被卡住了

def Riddler():
    #all numbers have to be odd
    # all numbers when added up have to equal 27
    address = 0 #has to basically equal print(ones, tens, hundred, thousands)
    thousands = 0 # thousands = tens * 3
    hundreds = 0
    tens = 0
    ones =  0

    for i in range(1000,10000):
        #print(address)
        one = int(i%10)
        ten = int(i//10)%10
        hundreds = int(i//100)%10
        thousands = int(i//1000)%10
        if (thousands!= hundreds) and (thousands!= tens) and (thousands!= ones) and (hundreds!= tens) and (hundreds!= ones) and (tens !=ones):
            if thousands == (ten*3):
                print(thousands) #was just trying to see what this would print

Riddler()

如果有人可以使用for循环以更好,更干净的方式编写代码,这将极大地帮助我了解如何改进代码。我还没有开始全面学习while循环,但是我也很好奇while循环的样子。

2 个答案:

答案 0 :(得分:0)

为什么循环?使用列表理解:

# The sum of the digits is 27. 
# The digit in the thousands place is three times the digit in the tens place = 3000+
# The number is odd  => 3001+, only odd numbers
# using strings of numbers for next 2 steps
sum27 = [ str(n) for n in range(3001,10000,2) if sum(map(int,str(n)))==27]
print(sum27)

# All four digits are different 
digit_diff = [ n for n in sum27 if len(set(n))==4]
print(digit_diff)


# The digit in the thousands place is three times the digit in the tens place 
solution = [int(n) for n in digit_diff if int(n[0])==3*int(n[2])]
print(solution) # [9837]

或更短:

riddle = [n for n in range(3001,10000,2) 
         if sum(map(int,str(n)))==27 
         and len(set(str(n)))==4
         and int(str(n)[0])==3*int(str(n)[2])]

通过一些逻辑,您可以减少探测:

  • 如果thouten值的3倍,则thou只能是3的倍数:3,6,9
  • ten始终为thou // 3
  • hun不能是thouten
  • one必须为奇数,不能为thouhunten

for thou in {3,6,9}:  
    ten = thou//3 
    for hun in range(10):
        if hun in (thou,ten): 
            continue
        for one in range(1,10,2): # odd values only
            if one in (thou,hun,ten): 
                continue
            elif one+ten+hun+thou == 27:  # sum27
                print(thou, hun, ten, one, sep="")

输出:

9837

答案 1 :(得分:0)

不是最快的方法,但是可以得到结果:

def riddler():
    for n in range(9031,10000,2):
        d = [int(c) for c in str(n)]
        if sum(d) == 27:
            if d[0]==(d[2]*3):
                if not any(True if d[i] in d[i+1:] else False for i in range(len(d))):
                    return n

riddler()

边注

我知道练习的目的是使用for循环,但是,请注意,蛮力是没有用的,因为一点推理就足以得出结果。

请注意,从条件2开始,可能的千位/十位数只有三种可能的组合:(3,1), (6,2), (9,3)

但是,只有(9,3)对中的总和足够大(12)才能使25与其他两位数字一起使用。因此,您瞬间获得9的成千上万,3的数十个。那另外两位数字呢?好吧,总和必须为25,所以有四个潜在对:(6,9), (9,6), (7,8), (8,7)

很明显(6,9)(9,6)违反了条件1,(7,8)违反了条件3,因此数百位和一位数字的唯一好对是(8,7)

您将获得解决方案:9837