# Task

John has an important number, and he doesn't want others to see it.

He decided to encrypt the number, using the following steps:
```
His number is always a non strict increasing sequence
ie. "123"

He converted each digit into English words.
ie. "123"--> "ONETWOTHREE"

And then, rearrange the letters randomly.
ie. "ONETWOTHREE" --> "TTONWOHREEE"
```

John felt that his number were safe in doing so. In fact, such encryption can be easily decrypted :(

Given the encrypted string `s`, your task is to decrypt it, return the original number in string format.

Note, You can assume that the input string `s` is always valid; It contains only uppercase Letters; The decrypted numbers are arranged in ascending order; The leading zeros are allowed.


# Example

For `s = "ONE"`, the output should be `1`.

For `s = "EON"`, the output should be `1` too.

For `s = "ONETWO"`, the output should be `12`.

For `s = "OONETW"`, the output should be `12` too.

For `s = "ONETWOTHREE"`, the output should be `123`.

For `s = "TTONWOHREEE"`, the output should be `123` too.

Source: codewars | Difficulty: EASY

Starter code: def original_number(s):
	

Solutions:
from collections import Counter
EXECUTIONS_ORDER = [('Z', Counter('ZERO'), '0'), ('W', Counter('TWO'), '2'), ('U', Counter('FOUR'), '4'), ('X', Counter('SIX'), '6'), ('G', Counter('EIGHT'), '8'), ('O', Counter('ONE'), '1'), ('H', Counter('THREE'), '3'), ('F', Counter('FIVE'), '5'), ('V', Counter('SEVEN'), '7'), ('I', Counter('NINE'), '9')]

def original_number(s):
	(ans, count, executions) = ([], Counter(s), iter(EXECUTIONS_ORDER))
	while count:
		(c, wordCount, value) = next(executions)
		ans.extend([value] * count[c])
		for _ in range(count[c]):
			count -= wordCount
	return ''.join(sorted(ans))


from collections import Counter, defaultdict
NUMBERS = ['ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
VALUES = {num: str(i) for (i, num) in enumerate(NUMBERS)}
counts = Counter(''.join(NUMBERS))
wordsContainningLetter = defaultdict(set)
for n in NUMBERS:
	for c in n:
		wordsContainningLetter[c].add(n)
(EXECUTIONS_ORDER, founds) = ([], set())
while counts:
	for (c, v) in counts.copy().items():
		if v == 1:
			try:
				word = (wordsContainningLetter[c] - founds).pop()
			except KeyError:
				break
			wordCount = Counter(word)
			founds.add(word)
			EXECUTIONS_ORDER.append((c, wordCount, VALUES[word]))
			counts -= wordCount

def original_number(s):
	(ans, count, executions) = ([], Counter(s), iter(EXECUTIONS_ORDER))
	while count:
		(c, wordCount, value) = next(executions)
		ans.extend([value] * count[c])
		for _ in range(count[c]):
			count -= wordCount
	return ''.join(sorted(ans))


def original_number(s):
	dic = {i: 0 for i in range(10)}
	dic[0] = s.count('Z')
	dic[2] = s.count('W')
	dic[4] = s.count('U')
	dic[6] = s.count('X')
	dic[8] = s.count('G')
	dic[1] = s.count('O') - dic[0] - dic[2] - dic[4]
	dic[3] = s.count('H') - dic[8]
	dic[5] = s.count('F') - dic[4]
	dic[7] = s.count('S') - dic[6]
	dic[9] = s.count('I') - dic[5] - dic[6] - dic[8]
	result = ''
	for i in range(10):
		result += str(i) * dic[i]
	return result


def original_number(s):
	(r, s) = ([], list(s))
	for (word, n) in [('ZERO', 0), ('WTO', 2), ('XSI', 6), ('GEIHT', 8), ('THREE', 3), ('UFOR', 4), ('ONE', 1), ('FIVE', 5), ('VSEEN', 7), ('NINE', 9)]:
		while word[0] in s:
			for c in word:
				s.remove(c)
			r.append(n)
	return ''.join((str(e) for e in sorted(r)))


def original_number(s):
	a = s[:]
	code = [0 for _ in range(10)]
	book = [[0, 'Z', 'ZERO'], [2, 'W', 'TWO'], [6, 'X', 'SIX'], [8, 'G', 'EIGHT'], [7, 'S', 'SEVEN'], [5, 'V', 'FIVE'], [4, 'F', 'FOUR'], [3, 'T', 'THREE'], [1, 'O', 'ONE'], [9, 'E', 'NINE']]
	for i in book:
		code[i[0]] = a.count(i[1])
		for j in i[2]:
			a = a.replace(j, '', code[i[0]])
	return ''.join(('0123456789'[k] * j for (k, j) in enumerate(code)))


from collections import Counter
NUMS = {'ZERO': '0', 'EIGHT': '8', 'SIX': '6', 'SEVEN': '7', 'THREE': '3', 'FOUR': '4', 'FIVE': '5', 'NINE': '9', 'TWO': '2', 'ONE': '1'}
KEYS = ['ZERO', 'EIGHT', 'SIX', 'SEVEN', 'THREE', 'FOUR', 'FIVE', 'NINE', 'TWO', 'ONE']

def original_number(s):
	res = ''
	counted = Counter(s)
	for key in KEYS:
		while all((counted[char] > 0 for char in key)):
			for char in key:
				counted[char] -= 1
			res += NUMS[key]
	return ''.join(sorted(res))


import scipy as sc
import scipy.optimize as so

def original_number(s):
	return ''.join([str(k) * int(round(n)) for (k, n) in enumerate(so.nnls(sc.transpose([sc.histogram([ord(c) - 65 for c in d], list(range(27)))[0] for d in ['ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']]), sc.histogram([ord(c) - 65 for c in s], list(range(27)))[0])[0])])


def original_number(s):
	s_list = list(s)
	numbers = [(0, 'ZERO'), (2, 'TWO'), (6, 'SIX'), (4, 'FOUR'), (1, 'ONE'), (5, 'FIVE'), (7, 'SEVEN'), (9, 'NINE'), (3, 'THREE'), (8, 'EIGHT')]
	secret_number = ''
	for (i, number) in numbers:
		while all([c in s_list for c in number]):
			[s_list.remove(c) for c in number]
			secret_number += str(i)
	return ''.join(sorted(secret_number))


import re
original_number = lambda s: ''.join((n * str(i) for (i, n) in enumerate(eval(re.sub('([A-Z])', 's.count("\\1")', '[Z,O-W-U-Z,W,H-G,U,F-U,X,S-X,G,I-G-F+U-X]')))))


def original_number(s):
	s = list(s)
	output = []
	nums = (('Z', 'ZERO', '0'), ('W', 'TWO', '2'), ('U', 'FOUR', '4'), ('X', 'SIX', '6'), ('G', 'EIGHT', '8'), ('O', 'ONE', '1'), ('H', 'THREE', '3'), ('F', 'FIVE', '5'), ('V', 'SEVEN', '7'), ('I', 'NINE', '9'))
	for n in nums:
		while n[0] in s:
			output.append(n[2])
			for c in n[1]:
				del s[s.index(c)]
	return ''.join(sorted(output))