# Hey You !

Sort these integers for me ...

By name ...

Do it now !


---

## Input

* Range is ```0```-```999```

* There may be duplicates

* The array may be empty

## Example

* Input: 1, 2, 3, 4
* Equivalent names: "one", "two", "three", "four"
* Sorted by name: "four", "one", "three", "two"
* Output: 4, 1, 3, 2

## Notes
* Don't pack words together:
 * e.g. 99 may be "ninety nine" or "ninety-nine"; but not "ninetynine"
 * e.g 101 may be "one hundred one" or "one hundred and one"; but not "onehundredone"
* Don't fret about formatting rules, because if rules are consistently applied it has no effect anyway:
 * e.g. "one hundred one", "one hundred two"; is same order as "one hundred **and** one", "one hundred **and** two"
 * e.g. "ninety eight", "ninety nine"; is same order as "ninety-eight", "ninety-nine"
 
```if:c
* For `C` code the input array may be NULL. The return value is freed if non-NULL.
```

Difficulty: EASY
Tags: String algorithms

Sorting
Skill types: Sorting

Starter code:
def sort_by_name(arr):
	

Solutions:
def int_to_word(num):
	d = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
	assert 0 <= num
	if num < 20:
		return d[num]
	if num < 100:
		if num % 10 == 0:
			return d[num]
		else:
			return d[num // 10 * 10] + '-' + d[num % 10]
	if num < 1000:
		if num % 100 == 0:
			return d[num // 100] + ' hundred'
		else:
			return d[num // 100] + ' hundred and ' + int_to_word(num % 100)

def sort_by_name(arr):
	return sorted(arr, key=int_to_word)


S = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
TENTH = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']

def convertToString(n):
	if not n:
		return 'zero'
	(c, t, u) = map(lambda v: n % (v * 10) // v, (100, 10, 1))
	return ' '.join((s for s in ['{} hundred'.format(S[c]) * bool(c), TENTH[t], S[u + 10 * (t == 1)]] if s))

def sort_by_name(arr):
	return sorted(arr, key=convertToString)


def sort_by_name(arr):
	return sorted(arr, key=convert)

def convert(a):
	if not a:
		return 'zero'
	d = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety'}
	r = []
	if a // 100:
		r.append('{} hundred'.format(d[a // 100]))
	if a % 100:
		if a % 100 <= 20:
			r.append(d[a % 100])
		else:
			b = d[a % 100 // 10 * 10]
			if a % 10:
				b += ' {}'.format(d[a % 10])
			r.append(b)
	return ' '.join(r)


ones = {'0': 'zero', '1': 'one', '2': 'two', '3': 'three', '4': 'four', '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine'}
teens = {'11': 'eleven', '12': 'twelve', '13': 'thirteen', '14': 'fourteen', '15': 'fifteen', '16': 'sixteen', '17': 'seventeen', '18': 'eighteen', '19': 'nineteen'}
tens = {'1': 'ten', '2': 'twenty', '3': 'thirty', '4': 'forty', '5': 'fifty', '6': 'sixty', '7': 'seventy', '8': 'eighty', '9': 'ninety'}
hundreds = {'100': 'one hundred', '200': 'two hundred', '300': 'three hundred', '400': 'four hundred', '500': 'five hundred', '600': 'six hundred', '700': 'seven hundred', '800': 'eight hundred', '900': 'nine hundred'}

def num_to_word(n):
	str_num = str(n)
	if n >= 100:
		first_digit = str_num[0] + '00'
		second_digit = str_num[1]
		third_digit = str_num[2]
	elif n > 9:
		first_digit = str_num[0]
		second_digit = str_num[1]
	else:
		return ones[str_num]
	if n > 99:
		if second_digit == '0' and third_digit != '0':
			return '{} {}'.format(hundreds[first_digit], ones[third_digit])
		elif second_digit != '0' and third_digit == '0':
			return '{} {}'.format(hundreds[first_digit], tens[second_digit])
		elif int(second_digit + third_digit) > 10 and int(second_digit + third_digit) < 20:
			return '{} {}'.format(hundreds[first_digit], teens[second_digit + third_digit])
		elif third_digit != '0':
			return '{} {}-{}'.format(hundreds[first_digit], tens[second_digit], ones[third_digit])
		else:
			return hundreds[str_num]
	elif n > 10 and n < 20:
		return teens[str_num]
	elif second_digit != '0':
		return '{}-{}'.format(tens[first_digit], ones[second_digit])
	else:
		return tens[first_digit]
int_to_word = {_: num_to_word(_) for _ in range(1000)}
word_to_int = {num_to_word(_): _ for _ in range(1000)}

def sort_by_name(arr):
	return [word_to_int[word] for word in sorted((int_to_word[num] for num in arr))]


num2words1 = {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen'}
num2words2 = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']

def sort_by_name(arr):
	return sorted(arr, key=lambda x: words(x))

def words(n):
	res = []
	if n >= 100:
		res.append(num2words1[n // 100])
		res.append('hundred')
		n -= n // 100 * 100
	if n >= 20:
		res.append(num2words2[n // 10])
		n -= n // 10 * 10
	if n > 0:
		res.append(num2words1[n])
	if not res:
		res.append('zero')
	return ' '.join(res)


words = 'zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty forty fifty sixty seventy eighty ninety'
words = words.split(' ')

def num2word(n):
	if n < 20:
		return words[n]
	elif n < 100:
		return words[18 + n // 10] + ('' if n % 10 == 0 else '-' + words[n % 10])
	else:
		return num2word(n // 100) + ' hundred' + (' ' + num2word(n % 100) if n % 100 > 0 else '')

def sort_by_name(arr):
	return sorted(arr, key=num2word)


def sort_by_name(arr):
	(comparing_list, before_sort_dict, resulty_list) = ([], {}, [])
	nu_dict = {'0': '', '1': 'one', '2': 'two', '3': 'three', '4': 'four', '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine', '10': 'ten', '11': 'eleven', '12': 'twelve', '13': 'thirteen', '14': 'fourteen', '15': 'fifteen', '16': 'sixteen', '17': 'seventeen', '18': 'eighteen', '19': 'nineteen'}
	for number in map(str, arr):
		if len(number) == 3:
			if 10 <= int(number[1:]) < 20:
				temp_word = number[1] + number[2]
				numberly_str = '{hundreds} hundred {tens}'.format(hundreds=nu_dict[number[0]], tens=nu_dict[temp_word])
			else:
				numberly_str = '{hundreds} hundred {tens}ty {deci}'.format(hundreds=nu_dict[number[0]], tens=nu_dict[number[1]], deci=nu_dict[number[2]])
		elif len(number) == 2:
			if 10 <= int(number) < 20:
				temp_word = number[0] + number[1]
				numberly_str = '{tens}'.format(tens=nu_dict[temp_word])
			else:
				numberly_str = '{tens}ty {deci}'.format(tens=nu_dict[number[0]], deci=nu_dict[number[1]])
		elif number == '0':
			numberly_str = 'zero'
		else:
			numberly_str = '{deci}'.format(deci=nu_dict[number[0]])
		temp_list = numberly_str.split()
		for (pos, word) in enumerate(temp_list):
			if word == 'ty':
				temp_list[pos] = ''
		numberly_str = ' '.join(temp_list)
		numberly_str = numberly_str.replace('  ', ' ').replace('fourty', 'forty').replace('twoty', 'twenty')
		numberly_str = numberly_str.replace('threety', 'thirty').replace('fivety', 'fifty').replace('eightty', 'eighty')
		numberly_str = numberly_str.rstrip()
		comparing_list.append(numberly_str)
	for (index, crypt) in enumerate(comparing_list):
		before_sort_dict[index] = crypt
	sorted_dict = {k: v for (k, v) in sorted(before_sort_dict.items(), key=lambda item: item[1])}
	for (key, value) in sorted_dict.items():
		resulty_list.append(arr[key])
	return resulty_list


def sort_by_name(arr):
	num_dict = {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'therteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty', 60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninety', 0: 'zero', -1: '', -10: ''}
	raw_list = []
	for i in arr:
		if i in num_dict:
			raw_list.append(tuple([num_dict[i], i]))
		else:
			raw_i = str(i)
			nums = len(raw_i)
			if nums == 2:
				j = int(raw_i[1])
				if 10 < i < 20:
					raw_list.append(tuple([num_dict[i], i]))
					continue
				if j != 0:
					raw_list.append(tuple(['{} {}'.format(num_dict[int(raw_i[0]) * 10], num_dict[int(raw_i[1])]), i]))
					continue
				else:
					raw_list.append(tuple(['{}'.format(num_dict[int(raw_i[0]) * 10]), i]))
					continue
			else:
				z = int(raw_i[1])
				k = int(raw_i[2])
				if z == 0:
					z = -1
				if k == 0:
					k = -1
				if 10 < int(raw_i[1] + raw_i[2]) < 20:
					raw_list.append(tuple(['{} hundred {}'.format(num_dict[int(raw_i[0])], num_dict[int(raw_i[1] + raw_i[2])]).replace('  ', ' '), i]))
					continue
				raw_list.append(tuple(['{} hundred {} {}'.format(num_dict[int(raw_i[0])], num_dict[z * 10], num_dict[k]).replace('  ', ' '), i]))
	raw_list.sort(key=lambda x: x[0])
	out_list = []
	for i in raw_list:
		out_list.append(i[1])
	return out_list


from enum import Enum

class Numbers(Enum):
	zero = 0
	one = 1
	two = 2
	three = 3
	four = 4
	five = 5
	six = 6
	seven = 7
	eight = 8
	nine = 9
	ten = 10
	eleven = 11
	twelve = 12
	thirteen = 13
	fourteen = 14
	fifteen = 15
	sixteen = 16
	seventeen = 17
	eighteen = 18
	nineteen = 19
	twenty = 20
	thirty = 30
	forty = 40
	fifty = 50
	sixty = 60
	seventy = 70
	eighty = 80
	ninety = 90

def number_to_name(number):
	return Numbers(number).name if number < 20 else Numbers(number).name if number < 100 and (not number % 10) else f'{Numbers(number // 10 * 10).name}-{Numbers(number % 10).name}' if number < 100 else f'{Numbers(number // 100).name} hundred' if not number % 100 else f'{Numbers(number // 100).name} hundred and {number_to_name(number % 100)}'

def sort_by_name(arr):
	return sorted(arr, key=number_to_name)