Home > Enterprise >  Printing numbers that contain only odd digits in a given range
Printing numbers that contain only odd digits in a given range

Time:10-14

I find some difficulties with the task of printing numbers in given range that contain only odd digits. f.e: The first number is 2345 and the second number is 6789. There is one more thing - the printed numbers should be limited only the range according to the digit position 2 to 6 (3,5), 3 to 7(3,5,7), 4 to 8(5,7), 5 to 9(5,7,9) - so it means that the first numbers should be 3355,3357,3359,3375,3377,3379,3555,3557....

The code does not execute it the way output should look:

number_one=int(input())
number_two=int(input())
list_one=[]
list_two=[]
number_one=str(number_one)
number_two=str(number_two)

for i in number_one:
    if int(i)==0 or int(i)%2==0:
        i=int(i) 1
    list_one.append(int(i))

for i in number_two:
    list_two.append(int(i))

a=0
b=0
c=0
d=0

for j in range(list_one[0],list_two[0] 1):
    if j%2==1:
        a=j
    for p in range(list_one[1],list_two[1] 1):
        if p%2==1:
            b=p
        for x in range(list_one[2],list_two[2] 1):
            if x%2==1:
                c=x
            for y in range(list_one[3],list_two[3] 1):
                if y%2==1:
                    d=y
                    print(f"{a}{b}{c}{d}",end=" ")

There are a lot of repetitions in the output that I would like to avoid.

Thank you in advance!

CodePudding user response:

May be this is not an optimal solution. But this is working for positive integers with same length.

number_one=int(input())
number_two=int(input())

if len(str(number_one)) != len(str(number_two)):
    raise Exception("numbers should be of same length")

def print_num(num_one, num_two):
    res = []
    for i,j in zip(num_one, num_two):
        next_odd_for_i = int(i)   (not (int(i)%2))
        prev_odd_for_j = int(j) - (not (int(j)%2))
        temp_str = ""
        for i_next in range(next_odd_for_i, prev_odd_for_j 1, 2):
            temp_str  = str(i_next)
        res.append(temp_str)
    return res


def print_perm(li_of_str):
    if len(li_of_str) == 1:
        return [li_of_str[-1]]
    res = []
    first = li_of_str[0]
    for j in first:
        tmp = [j k for n in print_perm(li_of_str[1:]) for k in n ]
        res.append(tmp)
    return res
print(print_num(str(number_one), str(number_two)))
print(print_perm(print_num(str(number_one), str(number_two))))

CodePudding user response:

One way to solve this problem is with recursion. This function takes in two strings representing numbers and returns all the odd numbers (as strings) that satisfy the conditions you specified:

def odd_digits(num1, num2):
    # split off first digit of string
    msd1, rest1 = int(num1[0]), num1[1:]
    # make the digit odd if required
    msd1  = msd1 % 2 == 0
    # split off first digit of string
    msd2, rest2 = int(num2[0]), num2[1:]
    # make the digit odd if required
    msd2 -= msd2 % 2 == 0
    # if no more digits, just return the values between msd1 and msd2
    if not rest1:
        return [str(i) for i in range(msd1, msd2 1, 2)]
    # otherwise, append the results of a recursive call to each 
    # odd digit between msd1 and msd2
    result = []
    for i in range(msd1, msd2 1, 2):
        result  = [str(i)   o for o in odd_digits(rest1, rest2)]
    return result

print(odd_digits('2345', '6789'))

Output:

[
 '3355', '3357', '3359',
 '3375', '3377', '3379',
 '3555', '3557', '3559',
 '3575', '3577', '3579',
 '3755', '3757', '3759',
 '3775', '3777', '3779',
 '5355', '5357', '5359',
 '5375', '5377', '5379',
 '5555', '5557', '5559',
 '5575', '5577', '5579',
 '5755', '5757', '5759',
 '5775', '5777', '5779'
]

If you want to use integer values just use (for example)

print(list(map(int, odd_digits(str(2345), str(6789)))))

The output will be as above but all values will be integers rather than strings.

If you can use libraries, you can generate ranges for each digit and then use itertools.product to find all the combinations:

import itertools

def odd_digits(num1, num2):
    ranges = []
    for d1, d2 in zip(num1, num2):
        d1 = int(d1)   (int(d1) % 2 == 0)
        d2 = int(d2) - (int(d2) % 2 == 0)
        ranges.append(list(range(d1, d2 1, 2)))
    return [''.join(map(str, t)) for t in itertools.product(*ranges)]

This function takes string inputs and produces string outputs, which will be the same as the first function above.

  • Related