I found this old question in the archives of the British informatics olympiads

Question 1:Anagram Numbers

An anagram number is a number that can be multiplied by at least one single digit number (other than 1) to become an anagram of itself. Any anagrams formed by multiplying an anagram number by a digit are said to be generated by that anagram number. Two numbers are anagrams of each other if they can both be formed by rearranging the same combination of digits.

For example:

- 1246878 is an anagram number; multiplying by 6 generates 7481268 or by 7 generates 8728146. These numbers all contain a single 1, 2, 4, 6, 7 and two 8s.
- 1246879 is not an anagram number.

1(a) [ 25 marks ]Write a program which reads in a single number (between 1 and 123456789 inclusive) and determines if it is an anagram number. If the number is not an anagram number you should output the word NO. If it is an anagram number you should output each single digit it can be multiplied by to make an anagram of itself.

Sample run 1

123456789

2 4 5 7 8Sample run 2

100

NO

1(b) [ 2 marks ]85247910 is generated by which anagram numbers?

1(c) [ 3 marks ]

How many anagram numbers between 100,000 and 999,999 contain no duplicated digits?

Here is a quick solution to this program. I am wondering if there is any solution to this that is more efficient?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# Anagram question # http://www.olympiad.org.uk/papers/2010/bio/bio-10-exam.pdf def values(n): output = [0]*10 while n>0: output[n % 10] += 1 n = n // 10 return output def isAnagram(n): anagram = [] for i in range(2,10): if values(n*i)==values(n): anagram.append(i) return anagram def printAnagram(anagramlist): if len(anagramlist)==0: print "NO", else: for i in anagramlist: print i, print def hasDuplicateDigits(n): output = [0]*10 while n>0: if output[n % 10]>0: return False else: output[n % 10] += 1 n = n // 10 return True # 1(a) print "1(a)" printAnagram(isAnagram(1246878)) printAnagram(isAnagram(1246879)) printAnagram(isAnagram(123456789)) print print # 1(b) print "1(b)" for i in range(2, 10): if len(isAnagram(85247910 / i))>0: print i, 85247910 / i print print # 1(c) print "1(c)" anagramsWithDuplicates = 0 for i in range(100000, 999999): if len(isAnagram(i))>0: if hasDuplicateDigits(i): anagramsWithDuplicates += 1 print "Anagrams with Duplicate Digits", anagramsWithDuplicates print print |

Results

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
1(a) 6 7 NO 2 4 5 7 8 1(b) 3 28415970 5 17049582 6 14207985 1(c) Anagrams with Duplicate Digits 138 |