The weekly challenge 362 - Task 2: Spellbound Sorting
1 #!/usr/bin/env perl
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
64
65
66
67
68
69 use v5.36;
70
71 spellbound_sorting(6, 7, 8, 9 ,10);
72 spellbound_sorting(-3, 0, 1000, 99);
73 spellbound_sorting(1, 2, 3, 4, 5);
74 spellbound_sorting(0, -1, -2, -3, -4);
75 spellbound_sorting(100, 101, 102);
76
77 sub spellbound_sorting(@ints) {
78 say "Input: (" . join(", ", @ints) . ")";
79 say "Output for English: (" .
80 join(", ", sort { number_to_english($a) cmp number_to_english($b) } @ints) . ")";
81 say "Output for French: (" .
82 join(", ", sort { number_to_french($a) cmp number_to_french($b) } @ints) . ")";
83 }
84
85 sub number_to_english($number) {
86 return "minus " . number_to_english(-$number) if $number < 0;
87 my @numbers = ("zero", "one", "two", "three", "four", "five",
88 "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
89 "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
90 "eighteen", "nineteen", "twenty");
91 return $numbers[$number] if $number < 21;
92 my $tens = { 20 => "twenty", 30 => "thirty", 40 => "forty",
93 50 => "fifty", 60 => "sixty", 70 => "seventy",
94 80 => "eighty", 90 => "ninety" };
95 if(20 < $number && $number < 100) {
96 my $t = 10 * int($number / 10);
97 if($number % 10) {
98 return $tens->{$t} . "-" . $numbers[$number % 10];
99 } else {
100 return $tens->{$t};
101 }
102 }
103 if($number < 1000) {
104 my $h = int($number / 100);
105 return $numbers[$h] . " hundred " . number_to_english($number % 100) if $number % 100;
106 return $numbers[$h] . " hundred";
107 }
108 my $t = int($number / 1000);
109 return $numbers[$t] . " thousand " . number_to_english($number % 1000) if $number % 1000;
110 return $numbers[$t] . " thousand";
111 }
112
113 sub number_to_french($number) {
114 return "moins " . number_to_french(-$number) if $number < 0;
115 my @numbers = ("zéro", "un", "deux", "trois", "quatre", "cinq",
116 "six", "sept", "huit", "neuf", "dix", "onze", "douze",
117 "treize", "quatorze", "quinze", "seize", "dix-sept",
118 "dix-huit", "dix-neuf", "vingt");
119 return $numbers[$number] if $number < 21;
120 my $tens = { 20 => "vingt", 30 => "trente", 40 => "quarante",
121 50 => "cinquante", 60 => "soixante", 80 => "quatre-vingts" };
122 if(20 < $number && $number < 70) {
123 my $t = 10 * int($number / 10);
124 if($number % 10) {
125 return $tens->{$t} . " et un" if $number % 10 == 1;
126 return $tens->{$t} . "-" . $numbers[$number % 10];
127 } else {
128 return $tens->{$t};
129 }
130 }
131 if($number < 80) {
132 return "soixante-dix" if $number == 70;
133 return "soixante et onze" if $number == 71;
134 return "soixante-" . $numbers[$number - 60];
135 }
136 if($number < 100) {
137 return "quatre-vingts" if $number == 80;
138 return "quatre-vingt-" . $numbers[$number - 80];
139 }
140 if($number < 200) {
141 return "cent" if $number == 100;
142 return "cent " . number_to_french($number % 100);
143 }
144 if($number < 1000) {
145 my $h = int($number / 100);
146 return $numbers[$h] . " cent " . number_to_french($number % 100) if $number % 100;
147 return $numbers[$h] . " cent";
148 }
149 my $t = int($number / 1000);
150 if($number < 2000) {
151 return "mille " . number_to_french($number % 1000) if $number % 1000;
152 return "mille";
153 } else {
154 return $numbers[$t] . " mille " . number_to_french($number % 1000) if $number % 1000;
155 return $numbers[$t] . " mille";
156 }
157 }