0

I'm new to python, I am doing the TWO + TWO = FOUR, where each letter represents a different number from 1-10. I need to find all combinations. I was wondering if there is a better way to write it, especially 'if' and 'for'

for t in range (1,10):
  for f in range (1,10):
    for w in range(10):
      for o in range(10):
        for u in range(10):
          for r in range(10):
            if 2*(t*100 + w*10 + o) == f*1000 + o*100 + u*10 + r and t is not f and t is not w and t is not o and t is not u and t is not r and f is not w and f is not o and f is not o and f is not u and f is not r and w is not o and w is not u and w is not r and o is not u and o is not r and u is not r:
              print(t,w,o, "and", f,o,u,r)

I've tried writing it like this but it gave me more than 7 results

if 2*(t*100 + w*10 + o) == f*1000 + o*100 + u*10 + r and t != f != w != o != u != r
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Hau Le
  • 3
  • 2
  • Yes, you can. However you need to be really careful with how you express the conditions and how they work (`and`, `or`, `not`, etc...). – Celius Stingher Sep 30 '19 at 03:19
  • 3
    For correctness, first: you should be using `!=`, not `is not`. `==`/`!=` compare values, and `is`/`is not` compare object identity; the latter is almost never what you want for immutable values like integers and strings. – Ry- Sep 30 '19 at 03:24
  • 1
    @ggorlen I assume it's this: https://www.pleacher.com/mp/puzzles/mathpuz/mobcry6.html – NullUserException Sep 30 '19 at 03:28
  • Btw, you might use `print(..., sep='')` to avoid spaces in the output. – o11c Sep 30 '19 at 03:39

3 Answers3

1

You could use a simple hack like this:

for t in range (1,10):
  for f in range (1,10):
    for w in range(10):
      for o in range(10):
        for u in range(10):
          for r in range(10):
            if 2*(t*100 + w*10 + o) == f*1000 + o*100 + u*10 + r and len(set([t,f,w,o,u,r])) == 6:
              print(t,w,o, "and", f,o,u,r)

The idea is set only stores distinct numbers, so if they are pair-wise different then the length of the set should be equal to the number of variables

NullUserException
  • 83,810
  • 28
  • 209
  • 234
ExplodingGayFish
  • 2,807
  • 1
  • 5
  • 14
1

You can use itertools.product:

for t, f, w, o, u, r in itertools.product(range(1, 10), range(1, 10), range(10), range(10), range(10), range(10)):

If you don't want to repeat all the ranges you can do:

for t, f, w, o, u, r in itertools.product(*([range(1, 10)]*2 + [range(10)]*4)):

but honestly that's less readable.

o11c
  • 15,265
  • 4
  • 50
  • 75
  • Hi, thank you for your help! I tried itertools.product but the result had similar set of numbers such as 500+500=1000. `for t, f, w, o, u, r in itertools.product(range(1, 10), range(1, 10), range(10), range(10), range(10), range(10)): if 2*(t*100 + w*10 + o) == f*1000 + o*100 + u*10 + r: print(t,w,o, "and", f,o,u,r)` sorry for the formatting. – Hau Le Sep 30 '19 at 04:29
  • You still have to do the `if len(set ...) != 6: continue` thing – o11c Sep 30 '19 at 05:29
0

Work smart, not hard =)

for t in range (1,10):
  for f in range (1,10):
    if f == t : continue
    for w in range(10):
      if w in [t,f] : continue
      for o in range(10):
        if o in [t,f,w] : continue
        for u in range(10):
          if u in [t,f,w,o] : continue
          for r in range(10):
            if r in [t,f,w,o,u] : continue
            if 2*(t*100 + w*10 + o) == f*1000 + o*100 + u*10 + r :
              print(t,w,o, "and", f,o,u,r)

This will save you a lot of unnecessary iterations.

lenik
  • 23,228
  • 4
  • 34
  • 43
  • From another perspective, the pure brute-force approach is over only 10^6 values – so optimizing it is working harder :) – Ry- Sep 30 '19 at 03:42