Skip to content

Instantly share code, notes, and snippets.

@wvega
Created April 1, 2010 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wvega/351371 to your computer and use it in GitHub Desktop.
Save wvega/351371 to your computer and use it in GitHub Desktop.
Natural Numbers Stream
#!/usr/bin/python
# Copyright (c) 2010 Willington Vega, http://wvega.com/
# Licensed under WTFPL (http://sam.zoy.org/wtfpl/)
class NaturalSequence:
def __init__(self, digit, length=None):
"""Creates a stream to generate natural numbers whose first digit is self.digit.
if length is given only numbers of that length will be generated"""
self.digit = digit
self.length = length
self.maxp = length and (10 ** (length - 1))
self.stream = []
# the distance between the digit and the next natural number that
# starts with digit.
# Ex: a(1) = 9 then 1 + 9 = 10; a(2) = 18 then 2 + 18 = 20 and so on...
self.a = 9 * digit
# the prepartion step...
if length is None:
self.current = digit - 1
# p = 10^(m-1); m is the length of the numbers been generated in a given time
self.p = 1
# how much numbers remaining before have to increase the length of
# the numbers been generated
self.k = 1
else:
self.p = self.maxp
# there is 1 number of length 1, 10 numbers of length 2,
# 100 numbers of length 3 ... 10^(m-1) numbers of length m,
# that start with self.digit
self.k = self.p
self.current = (self.digit * self.p) - 1
def next(self, n=1):
"""returns n next numbers of the sequence"""
if self.maxp and self.p > self.maxp:
return None
numbers = []
for i in range(0,n):
# there are no reamining numbers of length log(self.p)
if self.k <= 0:
# (self.p * (self.a - 1)) is the amount of numbers (less 1)
# that DON't start with self.digit before the next number
# that starts with self.digit
self.current = self.current + (self.p * (self.a - 1))
# the length of the numbers has been increased by 1
self.p = self.p * 10
self.k = self.p
if self.maxp and self.p > self.maxp:
break
# get the next number
self.current = self.current + 1
# consume one number
self.k = self.k - 1
numbers.append(self.current)
self.stream = self.stream + numbers
if numbers is None or len(numbers) == 0:
return None
elif n == 1:
return numbers[0]
return numbers
natural = NaturalSequence(3)
print "The first 20 natural numbers that start with digit 3"
print natural.next(10)
print natural.next(10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment