tags:

views:

291

answers:

3

Suppose i have a unsigned integer, call it low and one another call it high such that high>low. The problem is to find distinct digit set numbers over this range. For example, suppose low is 1 and high is 20 then the answer is 20, because all the numbers in this range are of distinct digit sets. If suppose low is 1 and high is 21, then the answer is 20, because 12 and 21 have same digit set i.e.1, 2. I am not looking for a bruteforce algo., if anyone has a better solution then a usual bruteforce approach, please tell..

A: 

Maybe this will get you started: mathematic combinations

http://www.codeguru.com/cpp/cpp/algorithms/combinations/article.php/c5117

Tom
I don't think this will help. If it is going right way, i wish to know how?
evil.coder
Are you after the algorithm or the code to do this? Oops sorry wrong place for my comment.
ChrisBD
+1  A: 

I think I finally wrapped my head around the problem.

Let's take range [low,high] and put the numbers within this range in sets depending on their digits as such:

  • "121" --> set "112"
  • "122" --> set "122"
  • "211" --> set "112"

We want to know the number of sets that will contain a unique element.

I would suggest that the simplest way to do this is actually... to do it like this.

def rangeCount(low, high):
  sets = defaultdict(list)
  for i in range(low, high+1):
    key = `i`.sort()            # obtain digits and sort them
    sets[key].append(i)

  count = 0
  for v in sets.values():
    if len(v) == 1: count = count + 1
  return count

Okay, it's bruteforce, but at least everybody should be on the same page now :)

Matthieu M.
I have already implemented this, but what if the range is 1 to 10 billion.how many sets are there? I was expecting someone will discover any mathematical series behind this.
evil.coder
They may, I just wrote it down so it would be easier for anyone coming up with something else to test its result.
Matthieu M.
Thanks Matthieu, now I better understand the question (but I have no idea so far how to bring the complexity under O(high-low))
Doc Brown
+1  A: 

There obviously is a mathematical answer to this, although I'll admit that I haven't worked it out as yet.

Simply put if the low = 1 and high = 99 then we have the following:

0 - 9 = 10 unique numbers
10-19 = 10 unique numbers
20-29 = 9 unique numbers
30-31 = 8 unique numbers
40-49 = 7 unique numbers
50-59 = 6 unique numbers
60-69 = 5 unique numbers
70-79 = 4 unique numbers
80-89 = 3 unique numbers
90-99 = 2 unique numbers

It would perhaps be easier to work out if we assumed that all numbers had to have the same number of digits, with leading zeros where required. For example 01, 02, 03, 04 for 1, 2, 3, 4. This would mean that 01 and 10 would match. Then our number distribution changes to:

0 - 9 = 10 unique numbers
10-19 = 9 unique numbers
20-29 = 8 unique numbers
30-31 = 7 unique numbers
40-49 = 6 unique numbers
50-59 = 5 unique numbers
60-69 = 4 unique numbers
70-79 = 3 unique numbers
80-89 = 2 unique numbers
90-99 = 1 unique numbers

You can see that it should be possible to base a recursive formula on this using factors of 10 to determine how many unique numbers there may be. The difficulty will be how to cope with the starting and ending points being variable e.g. low = 25 and high = 87. Still this is a start, I'll think further on it.

ChrisBD
Your examples are... strange. I think you messed up on the ranges. `10-19` = `{10, 11, 12, 13, 14, 15, 16, 17, 18, 19}` which gives 10 unique numbers. Did you meant that `0-19` would only have `9` more numbers than `0-9` ?
Matthieu M.
@Matthieu - in the second example I was suggesting that we include a leading zero. Thus 01 and 10 are the same.
ChrisBD