Find a 10-digit number, where each digit represents the number of that ordinal number in the whole number. So, the first digit represents the number of 0's in the whole 10 digits. The second digit represents the number of 1's in the whole 10 digits. And so on. The first digit is not a 0.As I promised at the end of the "brain only" post, we'll do better than simply finding an answer, we'll find all of them (with the aid of a computer).
Making the Problem Smaller
Without any thinking, there are 9 billion (9⋅109) total choices. This is not only intractable for the human brain, but becomes difficult for a computer too. A 3 GHz processor in the most optimal case can only perform 3 billion operations per second but there is a lot of counting, lists to create, and otherwise to find a number which fits the criteria.To start, we write our number as
n=d0,d1d2d3,d4d5d6,d7d8d9.
d0+d1+d2+d3+d4+d5+d6+d7+d8+d9=10
d1+2d2+3d3+4d4+5d5+6d6+7d7+8d8+9d9=10
0≤d5,d6,d7,d8,d9≤1
Listing All Choices
Now for the fun part: programming (in Python). We now have 90,000 (9⋅104) choices for our first 5 digits and 32 choices for our last 5 digits.We can use Python's range(10**4, 10**5) to represent the 5-digit numbers between 10,000 and 99,999 (inclusive). For the 32 choices for the last 5 digits, we use itertools.product. To see it in action on a smaller set of data:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>> import itertools | |
>>> for pair in itertools.product((0, 1), repeat=2): | |
... print pair | |
... | |
(0, 0) | |
(0, 1) | |
(1, 0) | |
(1, 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>> len(list(itertools.product((0, 1), repeat=5))) | |
32 |
Checking Candidates
Before we can iterate through all of our combinations, we need a way to check if a given number fits the criterion. To do that we implement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def fits_criterion(digit_list): | |
for i in xrange(10): | |
if digit_list.count(i) != digit_list[i]: | |
return False | |
return True |
Exhaustive Search
Now we can use our accumulated tools, loop through all choices and print any matches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for first5 in xrange(10**4, 10**5): | |
first5_list = map(int, str(first5)) | |
for last5 in itertools.product((0, 1), repeat=5): | |
digit_list = first5_list + list(last5) # last5 is a tuple | |
if fits_criterion(digit_list): | |
print digit_list |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[6, 2, 1, 0, 0, 0, 1, 0, 0, 0] |
6,210,001,000