For base $b = 10$, I want to list all numbers with $d$ digits (no leading zeros) and digit sum $x$, in increasing order.
For example for $d = 6$ and $x = 40$ we would get:
139999, 148999, 149899, 149989, 149998, 157999, 158899, 158989, 158998, 159799, 159889, 159898, 159979, 159988, 159997, 166999, 167899, 167989, 167998, 168799, 168889, 168898, 168979, 168988, 168997, 169699, 169789, 169798, 169879, 169888, 169897, 169969, 169978, 169987, 169996, 175999, 176899, 176989, 176998, 177799, 177889, 177898, 177979, 177988, 177997, 178699, 178789, 178798, 178879, 178888, 178897, 178969, 178978, 178987, 178996, 179599, 179689, 179698, 179779, 179788, 179797, 179869, 179878, 179887, 179896, 179959, 179968, 179977, 179986, 179995, 184999, 185899, 185989, 185998, 186799, 186889, 186898, 186979, 186988, 186997, 187699, 187789, 187798, 187879, 187888, 187897, 187969, 187978, 187987, 187996, 188599, 188689, 188698, 188779, 188788, 188797, 188869, 188878, 188887, 188896, 188959, 188968, 188977, 188986, 188995, 189499, 189589, 189598, 189679, 189688, ...
Now, using the generalized stars-bars problem creating a program, which produces an unordered list is easy. But for large $d$ and $x \rightarrow d \cdot b/2$, the list gets huge, so sorting it needs lots of RAM and it gets pretty slow.
I suspect (hope) there exists a ready-made algorithm, that for a number $n$ gives the nearest number $n'$, so that $n'$ has the same digit sum as $n$. Could you give me a hint?
EDIT: This is my solution in Python so far. The function returns the next integer with the same digit sum. I tested it for quite a huge range of numbers. But I don't know if it is correct. If you find an error, please let me know.
def next_same_xsum(x):
BASE = 10
t = 1
u = 1
while x % (u * BASE) == 0:
u *= BASE
if u > 1:
y = next_same_xsum(x // u)
w = 1
while x // u // (w * BASE) < y // (w * BASE):
w *= BASE
s = y % w
return s + (y - s) * u
while x // (t * BASE * BASE) < (x + BASE - 1) // (t * BASE * BASE):
t *= BASE
if t > 1:
z = next_same_xsum(x // t)
r = BASE - x % BASE - 1
return t - 1 + (z - r) * t
return x + BASE - 1