この問題のアルゴリズムの 1 つは、ほとんどの生徒が通常幼稚園で習う「リップル キャリー」加算のようなものですが、わずかに変更が加えられています。2 つの数を足すときは、1 桁ずつ足します。最初に 1 の位、次に 10 の位、次に 100 の位というように。 =15)、次にマイナス 10 を書き留めて、その 10 を次の場所に「持ち越し」、そこで足します (1 になります)。これは、多くの場所で「さざなみ」になる可能性があります (例: 999+1=1000)。このアルゴリズムを使用して 1 を繰り返し追加することで、1 つずつカウントアップできます。
私たちが求めているものを明確にすることが重要です。異なる場所に異なる拠点を持つことは何を意味するのでしょうか。場所に任意の数の範囲を持たせ、任意の数を表すことを許可すると、いくつかの悪いことが起こる可能性があります: 数が複数の方法で記述されたり、一部の 10 進数が記述されなかったりする可能性があります。したがって、場所iの基数がb iである場合、有効な数字は 0,1,2,..., b i -1であるという「健全な」スキームに限定します(通常、10 進数の場合と同様)。 ) であり、その桁は右側のすべての基数の積のb i倍を表します ( b i-1 x b i-2 x ...). For example, if our bases were [10,10,10], the values of the digits would be [1000,100,10,1]; if our bases were [5,10,5], the values of the digits would be [250,50,5,1]
How to add 1 to a number:
Increment the least-significant digit (LSD)
Perform ripple-carry as follows:
Set the current place to the LSD
Repeat as long as the current place exceeds its allowed max digit:
Set the digit at the current place to 0
Advance the current place one to the left
Increment the number at the new place (now on the left)
Repeat the above algorithm until you have all numbers you desire.
Python:
from itertools import *
def multibaseCount(baseFunction):
currentDigits = [0]
while True:
yield currentDigits[::-1]
# add 1
currentDigits[0] += 1
# ripple-carry:
for place,digit in enumerate(currentDigits):
if currentDigits[place]>=baseFunction(place): # if exceeds max digit
currentDigits[place] = 0 # mod current digit by 10
if place==len(currentDigits)-1: # add new digit if doesn't exist
currentDigits += [0]
currentDigits[place+1] += 1 # add 1 to next digit
else: # doesn't exceed max digit; don't need to carry any more
break
Demo, where place n has base n+1:
>>> for digits in islice(multibaseCount(lambda n:n+1),30):
... print( ''.join(map(str,digits)).zfill(5) )
...
00000
00010
00100
00110
00200
00210
01000
01010
01100
01110
01200
01210
02000
02010
02100
02110
02200
02210
03000
03010
03100
03110
03200
03210
10000
10010
10100
10110
10200
10210