Kjc21793
Kjc21793

Reputation: 79

While Loop to produce Mathematical Sequences?

I've been asked to do the following:

Using a while loop, you will write a program which will produce the following mathematical sequence:

1 * 9 + 2 = 11(you will compute this number)

12 * 9 + 3 = 111

123 * 9 + 4 = 1111

Then your program should run as far as the results contain only "1"s. You can build your numbers as string, then convert to ints before calculation. Then you can convert the result back to a string to see if it contains all "1"s.

Sample Output:

1 * 9 + 2 = 11

12 * 9 + 3 = 111

123 * 9 + 4 = 1111

1234 * 9 + 5 = 11111

Here is my code:

def main():
    Current = 1
    Next = 2
    Addition = 2
    output = funcCalculation(Current, Addition)

    while (verifyAllOnes(output) == True):
           print(output)
           #string concat to get new current number
           Current = int(str(Current) + str(Next))
           Addition += 1
           Next += 1
           output = funcCalculation(Current, Next)

def funcCalculation(a,b):
    return (a * 9 + b)

def verifyAllOnes(val):
    Num_str = str(val)
    for ch in Num_str:
           if(str(ch)!= "1"):
               return False
    return True

main()

The bug is that the formula isn't printing next to the series of ones on each line. What am I doing wrong?

Upvotes: 0

Views: 1438

Answers (2)

metasoarous
metasoarous

Reputation: 2943

Testing all ones

Well, for starters, here is one easy way to check that the value is all ones:

def only_ones(n):
    n_str = str(n)
    return set(n_str) == set(['1'])

You could do something more "mathy", but I'm not sure that it would be any faster. It would much more easily generalize to other bases (than 10) if that's something you were interested in though

def only_ones(n):
    return (n % 10 == 1) and (n == 1 or only_ones2(n / 10))

Uncertainty about how to generate the specific recurrence relation...

As for actually solving the problem though, it's actually not clear what the sequence should be.

What comes next?

123456
1234567
12345678
123456789
?

Is it 1234567890? Or 12345678910? Or 1234567900? Without answering this, it's not possible to solve the problem in any general way (unless in fact the 111..s terminate before you get to this issue).

I'm going to go with the most mathematically appealing assumption, which is that the value in question is the sum of all the 11111... values before it (note that 12 = 11 + 1, 123 = 111 + 11 + 1, 1234 = 1111 + 111 + 11 + 1, etc...).

A solution

In this case, you could do something along these lines:

def sequence_gen():
    a = 1
    b = 1
    i = 2
    while only_ones(b):
        yield b
        b = a*9 + i
        a += b
        i += 1

Notice that I've put this in a generator in order to make it easier to only grab as many results from this sequence as you actually want. It's entirely possible that this is an infinite sequence, so actually running the while code by itself might take a while ;-)

s = sequence_gen()
s.next() #=> 1
s.next() #=> 11

A generator gives you a lot of flexibility for things like this. For instance, you could grab the first 10 values of the sequence using the itertools.islice function:

import itertools as it
s = sequence_gen()
xs = [x for x in it.islice(s, 10)]
print xs

Upvotes: 1

poke
poke

Reputation: 388023

Pseudo-code:

a = 1
b = 2    
result = a * 9 + b
while string representation of result contains only 1s:
    a = concat a with the old value of b, as a number
    b = b + 1
    result = a * 9 + b

This can be literally converted into Python code.

Upvotes: 2

Related Questions