Warm tip: This article is reproduced from serverfault.com, please click

Weaving Numbers In Python

发布于 2020-11-28 16:19:16

I am trying to write a code which returns a list of all possible woven numbers from two user inputted numbers. For Example,

if A = 27 and B = 54 then there are four numbers that can be woven

2574

5247

7425

4752

Weaving a number can be done by weaving from the beginning, starting with A, weaving from the beginning, starting with B, weaving from the end, starting with A, weaving from the end, starting with B. While weaving two numbers A and B, if all the digits of A are weaved and some more digits are there in B, the remaining digits of B are just appended at the end.

I am trying

num_a = input()
num_b = input()
weaved_nums = []

def permutations(string):
    if len(string) == 1:
        return string

    recursive_perms = []
    for c in string:
        for perm in permutations(string.replace(c,'',1)):
            recursive_perms.append(c+perm)

    return set(recursive_perms)

num_a_perms = list(permutations(num_a))
num_b_perms = list(permutations(num_b))

def weave(num_1, num_2):
    new_string = ''
    for i in range(len(min([num_1, num_2], key = len))):
        new_string += num_1[i] + num_2[i]
    new_string += max(num_1, num_2, key=len)[len(num_1):]
    weaved_nums.append(new_string)

for i in range(len(num_a_perms)):
    for k in range(len(num_b_perms)):
        weave(num_a_perms[i], num_b_perms[k])
        weave(num_b_perms[k], num_a_perms[i])
        

print(weaved_nums)

However my program returns

['2475', '4257', '2574', '5247', '7425', '4752', '7524', '5742']

for inputs 27 and 54

Questioner
RISHABH AGRAWAL
Viewed
0
wwii 2020-11-29 01:13:15

Another solution - limited to two inputs:

  • start at the beginning r first: zip(r,s)
  • start at the end r first: zip(r[::-1],s[::-1])
  • start at the beginning s first: zip(s,r)
  • start at the end s first: zip(s[::-1],r[::-1])

def f(r,s):
    combos = ((r,s),(r[::-1],s[::-1]),(s,r),(s[::-1],r[::-1]))
    for combo in combos:
        yield ''.join(c for x,y in zip(*combo) for c in (x,y))

for thing in f('27','54'):
    print(thing)

For strings of unequal length use itertools.zip_longest(*combo,fillvalue='') instead of zip.

def f(r,s):
    combos = ((r,s),
              (r[::-1],s[::-1]),
              (s,r),
              (s[::-1],r[::-1]))

    for combo in combos:
        yield ''.join(c for x,y in itertools.zip_longest(*combo,fillvalue='') for c in (x,y))

>>> for thing in f('27','543'):
        print(thing)
25743
73245
52473
37425