Search code examples
pythonnumbersseries

Strange output while iterating in Python using While loop and If statement


I am trying to iterate over the range (1,10).

For each number in the range, I want to apply the below logic.

  1. If the number is even at the start or turns even at a subsequent stage, I would like to collect the quotient of the number devided by 2 in a list.

  2. If the number is odd at the start or turns odd at a subsequent stage, I would like to collect - triple the number plus one (3*X+1) - in the same list.

  3. I want to repeat steps 1 & 2 on the newly collcted number, as the case may be, until the quotient is 1.

  4. The list shall start with the original number and end with the last quotient, which is 1.

I have written the below code and it is working fine for all initial values, excepting when the initial value is 3 or 6 (ie., when i is 3 or 6). The output for 3 should have been [3,10,5,16,8,4,2,1] and for 6 shall be [6,3,10,5,16,8,4,2,1]. Instead, I am getting just [3,1] and [6,3,1] respectively. Why is this? Any feedback will be appreciated.

d ={}
for i in range(1,10):
    x=i
    l=[x]
    while (x // 2) != 1:
        if (x%2) == 0:
            l.append(x//2)
            x=x//2
        else:
            l.append(x*3+1)
            x=x*3+1
    l.append(x//2)
    d[i] = l
pd.DataFrame(dict([(k,pd.Series(v)) for k,v in d.items()]))

    1       2       3       4       5       6       7       8       9
0   1.0     2.0     3.0     4.0     5.0     6.0     7.0     8.0     9
1   4.0     1.0     1.0     2.0     16.0    3.0     22.0    4.0     28
2   2.0     NaN     NaN     1.0     8.0     1.0     11.0    2.0     14
3   1.0     NaN     NaN     NaN     4.0     NaN     34.0    1.0     7
4   NaN     NaN     NaN     NaN     2.0     NaN     17.0    NaN     22
5   NaN     NaN     NaN     NaN     1.0     NaN     52.0    NaN     11
6   NaN     NaN     NaN     NaN     NaN     NaN     26.0    NaN     34
7   NaN     NaN     NaN     NaN     NaN     NaN     13.0    NaN     17
8   NaN     NaN     NaN     NaN     NaN     NaN     40.0    NaN     52
9   NaN     NaN     NaN     NaN     NaN     NaN     20.0    NaN     26
10  NaN     NaN     NaN     NaN     NaN     NaN     10.0    NaN     13
11  NaN     NaN     NaN     NaN     NaN     NaN     5.0     NaN     40
12  NaN     NaN     NaN     NaN     NaN     NaN     16.0    NaN     20
13  NaN     NaN     NaN     NaN     NaN     NaN     8.0     NaN     10
14  NaN     NaN     NaN     NaN     NaN     NaN     4.0     NaN     5
15  NaN     NaN     NaN     NaN     NaN     NaN     2.0     NaN     16
16  NaN     NaN     NaN     NaN     NaN     NaN     1.0     NaN     8
17  NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     4
18  NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     2
19  NaN     NaN     NaN     NaN     NaN     NaN     NaN     NaN     1

Solution

  • it is because you are using // instead of / in condition of while loop as we know that 3 // 2 is equal to 1 and hence the code in the while loop never gets executed you can try this

    d ={}
    for i in range(1,10):
        x=i
        l=[x]
        while (((x / 2) != 1) and (x != 1)):
            if (x%2) == 0:
                l.append(x//2)
                x=x//2
            else:
                x=x*3+1
                l.append(x)
        l.append(x//2)
        d[i] = l
    pd.DataFrame(dict([(k,pd.Series(v)) for k,v in d.items()]))
    
    

    well this is quite fascinating problem in the field of mathematics that with any number you starts with you will gonna end up in infinite loop of 4, 2, 1 if you don't terminate the process as soon as one is reached.

    Advice: Try the same process with -ve numbers and you will notice there exists multiple loops like 4, 2, 1. ;)