N'th
You are encouraged to solve this task according to the task description, using any language you may know.
Write a function/method/subroutine/... that when given an integer greater than or equal to zero returns a string of the number followed by an apostrophe then the ordinal suffix.
Example returns would include 1'st 2'nd 3'rd 11'th 1001'st
- Task
Use your routine to show here the output for at least the following (inclusive) ranges of integer inputs:
0..25, 250..265, 1000..1025
Note: apostrophes are now optional to allow correct apostrophe-less English.
Ada
<lang Ada>with Ada.Text_IO;
procedure Nth is
function Suffix(N: Natural) return String is begin if N mod 10 = 1 and then N mod 100 /= 11 then return "st"; elsif N mod 10 = 2 and then N mod 100 /= 12 then return "nd"; elsif N mod 10 = 3 and then N mod 100 /= 13 then return "rd"; else return "th"; end if; end Suffix; procedure Print_Images(From, To: Natural) is begin for I in From .. To loop
Ada.Text_IO.Put(Natural'Image(I) & Suffix(I));
end loop; Ada.Text_IO.New_Line; end Print_Images;
begin
Print_Images( 0, 25); Print_Images( 250, 265); Print_Images(1000, 1025);
end Nth;</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
ALGOL 68
<lang algol68># PROC to suffix a number with st, nd, rd or th as appropriate # PROC nth = ( INT number )STRING: BEGIN
INT number mod 100 = number MOD 100;
- RESULT #
whole( number, 0 ) + IF number mod 100 >= 10 AND number mod 100 <= 20 THEN # numbers in the range 10 .. 20 always have "th" # "th" ELSE # not in the range 10 .. 20, suffix is st, nd, rd or th # # depending on the final digit # CASE number MOD 10 IN # 1 # "st" , # 2 # "nd" , # 3 # "rd" OUT "th" ESAC FI
END; # nth #
- PROC to test nth, displays nth for all numbers in the range from .. to #
PROC test nth = ( INT from, INT to )VOID: BEGIN
INT test count := 0; FOR test value FROM from TO to DO STRING test result = nth( test value ); print( ( " "[ 1 : 8 - UPB test result ], nth( test value ) ) ); test count +:= 1; IF test count MOD 8 = 0 THEN print( ( newline ) ) FI OD; print( ( newline ) )
END; # test nth #
main: (
test nth( 0, 25 ); test nth( 250, 265 ); test nth( 1000, 1025 )
)</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Applesoft BASIC
<lang ApplesoftBasic>0 OP = 1 10 FOR N = 0 TO 25 : GOSUB 100 : NEXT 20 FOR N = 250 TO 265 : GOSUB 100 : NEXT 30 FOR N = 1000 TO 1025 : GOSUB 100 : NEXT 40 END
100 GOSUB 200"NTH 110 PRINT NTH$ " "; 120 RETURN
200 M1 = N - INT(N / 10) * 10 210 M2 = N - INT(N / 100) * 100 220 NTH$ = "TH" 230 IF M1 = 1 AND M2 <> 11 THEN NTH$ = "ST" 240 IF M1 = 2 AND M2 <> 12 THEN NTH$ = "ND" 250 IF M1 = 3 AND M2 <> 13 THEN NTH$ = "RD" 260 IF NOT OP THEN NTH$ = "'" + NTH$ 270 NTH$ = STR$(N) + NTH$ 280 RETURN</lang>
- Output:
0'TH 1'ST 2'ND 3'RD 4'TH 5'TH 6'TH 7'TH 8'TH 9'TH 10'TH 11'TH 12'TH 13'TH 14'TH 15'TH 16'TH 17'TH 18'TH 19'TH 20'TH 21'ST 22'ND 23'RD 24'TH 25'TH 250'TH 251'ST 252'ND 253'RD 254'TH 255'TH 256'TH 257'TH 258'TH 259'TH 260'TH 261'ST 262'ND 263'RD 264'TH 265'TH 1000'TH 1001'ST 1002'ND 1003'RD 1004'TH 1005'TH 1006'TH 1007'TH 1008'TH 1009'TH 1010'TH 1011'TH 1012'TH 1013'TH 1014'TH 1015'TH 1016'TH 1017'TH 1018'TH 1019'TH 1020'TH 1021'ST 1022'ND 1023'RD 1024'TH 1025'TH
AutoHotkey
<lang AutoHotkey>for k, v in [[0, 25], [250, 265], [1000, 1025]] { while v[1] <= v[2] { Out .= Ordinal(v[1]) " " v[1]++ } Out .= "`n" } MsgBox, % Out
Ordinal(n) { s2 := Mod(n, 100) if (s2 > 10 && s2 < 14) return n "th" s1 := Mod(n, 10) return n (s1 = 1 ? "st" : s1 = 2 ? "nd" : s1 = 3 ? "rd" : "th") }</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
AWK
<lang AWK>
- syntax: GAWK -f NTH.AWK
BEGIN {
prn(0,25) prn(250,265) prn(1000,1025) exit(0)
} function prn(start,stop, i) {
printf("%d-%d: ",start,stop) for (i=start; i<=stop; i++) { printf("%d%s ",i,nth(i)) } printf("\n")
} function nth(yearday, nthday) {
if (yearday ~ /1[1-3]$/) { # 11th,12th,13th nthday = "th" } else if (yearday ~ /1$/) { # 1st,21st,31st,etc. nthday = "st" } else if (yearday ~ /2$/) { # 2nd,22nd,32nd,etc. nthday = "nd" } else if (yearday ~ /3$/) { # 3rd,23rd,33rd,etc. nthday = "rd" } else if (yearday ~ /[0456789]$/) { # 4th-10th,20th,24th-30th,etc. nthday = "th" } return(nthday)
} </lang>
output:
0-25: 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250-265: 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000-1025: 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Babel
<lang babel>((irregular ("st" "nd" "rd"))
(main
{(0 250 1000) { test ! "\n" << } each})
(test {
<- {iter 1 - -> dup <- + ordinalify ! << {iter 10 %} {" "} {"\n"} ifte << } 26 times})
(ordinalify {
<- {{ -> dup <- 100 % 10 cugt } ! { -> dup <- 100 % 14 cult } ! and not { -> dup <- 10 % 0 cugt } ! { -> dup <- 10 % 4 cult } ! and and} { -> dup <- %d "'" irregular -> 10 % 1 - ith . . } { -> %d "'th" . } ifte }))</lang>
This code produces the following output when run:
<lang babel>25'th 24'th 23'rd 22'nd 21'st 20'th 19'th 18'th 17'th 16'th 15'th 14'th 13'th 12'th 11'th 10'th 9'th 8'th 7'th 6'th 5'th 4'th 3'rd 2'nd 1'st 0'th 275'th 274'th 273'rd 272'nd 271'st 270'th 269'th 268'th 267'th 266'th 265'th 264'th 263'rd 262'nd 261'st 260'th 259'th 258'th 257'th 256'th 255'th 254'th 253'rd 252'nd 251'st 250'th 1025'th 1024'th 1023'rd 1022'nd 1021'st 1020'th 1019'th 1018'th 1017'th 1016'th 1015'th 1014'th 1013'th 1012'th 1011'th 1010'th 1009'th 1008'th 1007'th 1006'th 1005'th 1004'th 1003'rd 1002'nd 1001'st 1000'th</lang>
Common Lisp
<lang lisp>(defun add-suffix (number)
(let* ((suffixes #10("th" "st" "nd" "rd" "th")) (last2 (mod number 100)) (last-digit (mod number 10)) (suffix (if (< 10 last2 20) "th" (svref suffixes last-digit)))) (format nil "~a~a" number suffix)))
(loop for (low high) in '((0 25) (250 265) (1000 1025))
do (progn (format t "~a to ~a: " low high) (loop for n from low to high do (format t "~a " (add-suffix n)) finally (terpri))))</lang>
- Output:
0 to 25: 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250 to 265: 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000 to 1025: 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
C
<lang c>#include <stdio.h>
char* addSuffix(int num, char* buf, size_t len) {
char *suffixes[4] = { "th", "st", "nd", "rd" }; int i;
switch (num % 10) { case 1 : i = (num % 100 == 11) ? 0 : 1;
break;
case 2 : i = (num % 100 == 12) ? 0 : 2; break; case 3 : i = (num % 100 == 13) ? 0 : 3; break; default: i = 0; }; snprintf(buf, len, "%d%s", num, suffixes[i]); return buf;
}
int main(void) {
int i;
printf("Set [0,25]:\n"); for (i = 0; i < 26; i++) { char s[5]; printf("%s ", addSuffix(i, s, 5)); } putchar('\n');
printf("Set [250,265]:\n"); for (i = 250; i < 266; i++) { char s[6]; printf("%s ", addSuffix(i, s, 6)); } putchar('\n');
printf("Set [1000,1025]:\n"); for (i = 1000; i < 1026; i++) { char s[7]; printf("%s ", addSuffix(i, s, 7)); } putchar('\n');
return 0;
}</lang>
- Output:
Set [0,25] : 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th Set [250,265] : 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th Set [1000,1025] : 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
C#
<lang csharp> using System;
namespace Nth {
class Sulfix { public string addSulfix(int i) { string s = i.ToString(); int t = i % 10; if (i > 10 && i < 20) s += "th"; else switch (t) { case 1: s += "st"; break; case 2: s += "nd"; break; case 3: s += "rd"; break; default: s += "th"; break; }
return s; } }; class Program { static void Main(string[] args) { Sulfix s = new Sulfix(); for (int x = 0; x < 26; x++) { if (x % 5 == 0) Console.WriteLine(); Console.Write("{0,7} ", s.addSulfix(x)); }
Console.WriteLine(); for (int x = 250; x < 266; x++) { if (x % 5 == 0) Console.WriteLine(); Console.Write("{0,7} ", s.addSulfix(x)); }
Console.WriteLine(); for (int x = 1000; x < 1026; x++) { if (x % 5 == 0) Console.WriteLine(); Console.Write("{0,7} ", s.addSulfix(x)); }
Console.ReadKey(); } }
} </lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011st 1012nd 1013rd 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
D
<lang d>import std.stdio, std.string, std.range, std.algorithm;
string nth(in uint n) pure {
static immutable suffix = "th st nd rd th th th th th th".split; return "%d'%s".format(n, (n % 100 <= 10 || n % 100 > 20) ? suffix[n % 10] : "th");
}
void main() {
foreach (r; [iota(26), iota(250, 266), iota(1000, 1026)]) writefln("%-(%s %)", r.map!nth);
}</lang>
- Output:
0'th 1'st 2'nd 3'rd 4'th 5'th 6'th 7'th 8'th 9'th 10'th 11'th 12'th 13'th 14'th 15'th 16'th 17'th 18'th 19'th 20'th 21'st 22'nd 23'rd 24'th 25'th 250'th 251'st 252'nd 253'rd 254'th 255'th 256'th 257'th 258'th 259'th 260'th 261'st 262'nd 263'rd 264'th 265'th 1000'th 1001'st 1002'nd 1003'rd 1004'th 1005'th 1006'th 1007'th 1008'th 1009'th 1010'th 1011'th 1012'th 1013'th 1014'th 1015'th 1016'th 1017'th 1018'th 1019'th 1020'th 1021'st 1022'nd 1023'rd 1024'th 1025'th
Go
<lang go>package main
import "fmt"
func ord(n int) string {
s := "th" switch c := n % 10; c { case 1, 2, 3: if n%100/10 == 1 { break } switch c { case 1: s = "st" case 2: s = "nd" case 3: s = "rd" } } return fmt.Sprintf("%d%s", n, s)
}
func main() {
for n := 0; n <= 25; n++ { fmt.Printf("%s ", ord(n)) } fmt.Println() for n := 250; n <= 265; n++ { fmt.Printf("%s ", ord(n)) } fmt.Println() for n := 1000; n <= 1025; n++ { fmt.Printf("%s ", ord(n)) } fmt.Println()
}</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Haskell
<lang haskell>import Data.Array
ordSuffs :: Array Integer String ordSuffs = listArray (0,9) ["th", "st", "nd", "rd", "th",
"th", "th", "th", "th", "th"]
ordSuff :: Integer -> String ordSuff n = show n ++ suff n
where suff m | m >= 11 && m <= 13 = "th" | otherwise = ordSuffs ! (m `rem` 10)
printOrdSuffs :: [Integer] -> IO () printOrdSuffs = putStrLn . unwords . map ordSuff
main :: IO () main = do
printOrdSuffs [ 0.. 25] printOrdSuffs [ 250.. 265] printOrdSuffs [1000..1025]</lang>
Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011st 1012nd 1013rd 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Icon and Unicon
The following works in both languages. <lang unicon>procedure main(A)
every writes(" ",nth(0 to 25) | "\n") every writes(" ",nth(250 to 265) | "\n") every writes(" ",nth(1000 to 1025) | "\n")
end
procedure nth(n)
return n || ((n%10 = 1, n%100 ~= 11, "st") | (n%10 = 2, n%100 ~= 12, "nd") | (n%10 = 3, n%100 ~= 13, "rd") | "th")
end</lang>
Output:
->nth 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13h 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013h 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th ->
J
Implementation:
<lang J>suf=: (;:'th st nd rd th'){::~4<.10 10(* 1&~:)~/@#:]
nth=: [:;:inv (":,',suf)each</lang>
Task:
<lang J> thru=: <./ + i.@(+ *)@-~
nth 0 thru 25
0'th 1'st 2'nd 3'rd 4'th 5'th 6'th 7'th 8'th 9'th 10'th 11'th 12'th 13'th 14'th 15'th 16'th 17'th 18'th 19'th 20'th 21'st 22'nd 23'rd 24'th 25'th
nth 250 thru 265
250'th 251'st 252'nd 253'rd 254'th 255'th 256'th 257'th 258'th 259'th 260'th 261'st 262'nd 263'rd 264'th 265'th
nth 1000 thru 1025
1000'th 1001'st 1002'nd 1003'rd 1004'th 1005'th 1006'th 1007'th 1008'th 1009'th 1010'th 1011'th 1012'th 1013'th 1014'th 1015'th 1016'th 1017'th 1018'th 1019'th 1020'th 1021'st 1022'nd 1023'rd 1024'th 1025'th</lang>
Note the cute colorization caused by the interaction between this task's imposition of the quote character and this wiki's syntax support.
Java
<lang java>public class Nth { public static String ordinalAbbrev(int n){ String ans = "th"; //most of the time it should be "th" if(n % 100 / 10 == 1) return ans; //teens are all "th" switch(n % 10){ case 1: ans = "st"; break; case 2: ans = "nd"; break; case 3: ans = "rd"; break; } return ans; }
public static void main(String[] args){ for(int i = 0; i <= 25;i++){ System.out.print(i + ordinalAbbrev(i) + " "); } System.out.println(); for(int i = 250; i <= 265;i++){ System.out.print(i + ordinalAbbrev(i) + " "); } System.out.println(); for(int i = 1000; i <= 1025;i++){ System.out.print(i + ordinalAbbrev(i) + " "); } } }</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Mathematica
I borrowed the logic form the Python code. <lang Mathematica>suffixlist = {"th", "st", "nd", "rd", "th", "th", "th", "th", "th","th"}; addsuffix[n_] := Module[{suffix},
suffix = Which[ Mod[n, 100] <= 10, suffixlist[[Mod[n, 10] + 1]], Mod[n, 100] > 20, suffixlist[[Mod[n, 10] + 1]], True, "th" ]; ToString[n] <> suffix ]
addsuffix[#] & /@ Range[0, 25] (* test 1 *) addsuffix[#] & /@ Range[250, 265] (* test 2 *) addsuffix[#] & /@ Range[1000, 1025] (* test 3 *) </lang>
- Output:
{"0th", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th"} {"250th", "251st", "252nd", "253rd", "254th", "255th", "256th", "257th", "258th", "259th", "260th", "261st", "262nd", "263rd", "264th", "265th"} {"1000th", "1001st", "1002nd", "1003rd", "1004th", "1005th", "1006th", "1007th", "1008th", "1009th", "1010th", "1011th", "1012th", "1013th", "1014th", "1015th", "1016th", "1017th", "1018th", "1019th", "1020th", "1021st", "1022nd", "1023rd", "1024th", "1025th"}
PARI/GP
(Spurious apostrophes intentionally omitted, following Perl 6.)
<lang parigp>ordinal(n)=my(k=n%10,m=n%100); Str(n,if(m<21&&m>3,"th",k==1,"st",k==2,"nd",k==3,"rd","th")); apply(ordinal, [0..25]) apply(ordinal, [250..265]) apply(ordinal, [1000..1025]) </lang>
- Output:
%1 = ["0th", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th", "21st", "22nd", "23rd", "24th", "25th"] %2 = ["250th", "251st", "252nd", "253rd", "254th", "255th", "256th", "257th", "258th", "259th", "260th", "261st", "262nd", "263rd", "264th", "265th"] %3 = ["1000th", "1001st", "1002nd", "1003rd", "1004th", "1005th", "1006th", "1007th", "1008th", "1009th", "1010th", "1011st", "1012nd", "1013rd", "1014th", "1015th", "1016th", "1017th", "1018th", "1019th", "1020th", "1021st", "1022nd", "1023rd", "1024th", "1025th"]
Perl
<lang perl>my %irregulars = ( 1 => 'st',
2 => 'nd', 3 => 'rd', 11 => 'th', 12 => 'th', 13 => 'th');
sub nth {
my $n = shift; $n . ($irregulars{$n % 100} // $irregulars{$n % 10} // 'th');
}
sub range { join ' ', map { nth($_) } @{$_[0]} } print range($_), "\n" for ([0..25], [250..265], [1000..1025]) </lang>
- Output:
Same as Perl 6
Perl 6
(Spurious apostrophes intentionally omitted.) <lang perl6>my %irregulars = <1 st 2 nd 3 rd>, (11..13 X=> 'th');
sub nth ($n) { $n ~ ( %irregulars{$n % 100} // %irregulars{$n % 10} // 'th' ) }
say .list».&nth for [^26], [250..265], [1000..1025];</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
If you want to get Unicodally fancy, use this version instead: <lang perl6>my %irregulars = <1 ˢᵗ 2 ⁿᵈ 3 ʳᵈ>, (11..13 X=> 'ᵗʰ');
sub nth ($n) { $n ~ ( %irregulars{$n % 100} // %irregulars{$n % 10} // 'ᵗʰ' ) }
say .list».&nth for [^26], [250..265], [1000..1025];</lang>
- Output:
0ᵗʰ 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ᵗʰ
250ᵗʰ 251ˢᵗ 252ⁿᵈ 253ʳᵈ 254ᵗʰ 255ᵗʰ 256ᵗʰ 257ᵗʰ 258ᵗʰ 259ᵗʰ 260ᵗʰ 261ˢᵗ 262ⁿᵈ 263ʳᵈ 264ᵗʰ 265ᵗʰ
1000ᵗʰ 1001ˢᵗ 1002ⁿᵈ 1003ʳᵈ 1004ᵗʰ 1005ᵗʰ 1006ᵗʰ 1007ᵗʰ 1008ᵗʰ 1009ᵗʰ 1010ᵗʰ 1011ᵗʰ 1012ᵗʰ 1013ᵗʰ 1014ᵗʰ 1015ᵗʰ 1016ᵗʰ 1017ᵗʰ 1018ᵗʰ 1019ᵗʰ 1020ᵗʰ 1021ˢᵗ 1022ⁿᵈ 1023ʳᵈ 1024ᵗʰ 1025ᵗʰ
PicoLisp
<lang PicoLisp>(de rangeth (A B)
(mapcar '((I) (pack I (if (member (% I 100) (11 12 13)) 'th (case (% I 10) (1 'st) (2 'nd) (3 'rd) (T 'th) ) ) ) ) (range A B) ) )
(prinl (glue " " (rangeth 0 25))) (prinl (glue " " (rangeth 250 265))) (prinl (glue " " (rangeth 1000 1025)))
(bye)</lang>
- Output:
0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Python
<lang python>_suffix = ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th']
def nth(n):
return "%i'%s" % (n, _suffix[n%10] if n % 100 <= 10 or n % 100 > 20 else 'th')
if __name__ == '__main__':
for j in range(0,1001, 250): print(' '.join(nth(i) for i in list(range(j, j+25))))</lang>
- Output:
0'th 1'st 2'nd 3'rd 4'th 5'th 6'th 7'th 8'th 9'th 10'th 11'th 12'th 13'th 14'th 15'th 16'th 17'th 18'th 19'th 20'th 21'st 22'nd 23'rd 24'th 250'th 251'st 252'nd 253'rd 254'th 255'th 256'th 257'th 258'th 259'th 260'th 261'st 262'nd 263'rd 264'th 265'th 266'th 267'th 268'th 269'th 270'th 271'st 272'nd 273'rd 274'th 500'th 501'st 502'nd 503'rd 504'th 505'th 506'th 507'th 508'th 509'th 510'th 511'th 512'th 513'th 514'th 515'th 516'th 517'th 518'th 519'th 520'th 521'st 522'nd 523'rd 524'th 750'th 751'st 752'nd 753'rd 754'th 755'th 756'th 757'th 758'th 759'th 760'th 761'st 762'nd 763'rd 764'th 765'th 766'th 767'th 768'th 769'th 770'th 771'st 772'nd 773'rd 774'th 1000'th 1001'st 1002'nd 1003'rd 1004'th 1005'th 1006'th 1007'th 1008'th 1009'th 1010'th 1011'th 1012'th 1013'th 1014'th 1015'th 1016'th 1017'th 1018'th 1019'th 1020'th 1021'st 1022'nd 1023'rd 1024'th
Racket
<lang racket>#lang racket (define (teen? n) (<= 11 (modulo n 100) 19)) (define (Nth n)
(format "~a'~a" n (match* ((modulo n 10) n) [((or 1 2 3) (? teen?)) 'th] [(1 _) 'st] [(2 _) 'nd] [(3 _) 'rd] [(_ _) 'th])))
(for ((range (list (in-range 26) (in-range 250 266) (in-range 1000 1026))))
(displayln (string-join (for/list ((nth (sequence-map Nth range))) nth) " ")))</lang>
- Output:
0'th 1'st 2'nd 3'rd 4'th 5'th 6'th 7'th 8'th 9'th 10'th 11'th 12'th 13'th 14'th 15'th 16'th 17'th 18'th 19'th 20'th 21'st 22'nd 23'rd 24'th 25'th 250'th 251'st 252'nd 253'rd 254'th 255'th 256'th 257'th 258'th 259'th 260'th 261'st 262'nd 263'rd 264'th 265'th 1000'th 1001'st 1002'nd 1003'rd 1004'th 1005'th 1006'th 1007'th 1008'th 1009'th 1010'th 1011'th 1012'th 1013'th 1014'th 1015'th 1016'th 1017'th 1018'th 1019'th 1020'th 1021'st 1022'nd 1023'rd 1024'th 1025'th
REXX
This version adds suffixes without apostrophes.
Negative numbers and fractions are also handled. <lang rexx>/*REXX pgm shows ranges of numbers with ordinal (st/nd/rd/th) suffixes. */ call tell 0, 25 /*show the 1st range of numbers. */ call tell 250, 265 /* " " 2nd " " " */ call tell 1000, 1025 /* " " 3rd " " " */ exit /*stick a fork in it, we're done.*/ /*───────────────────────────────────TELL subroutine────────────────────*/ tell: procedure; parse arg L,H; $= /*get Low & High #s, nullify list*/
do j=L to H /*process the range, low───►high.*/ $=$ j || th(j) /*append the Nth number to list*/ end /*j*/ /* [↑] $ has a leading blank. */
say 'numbers from ' L " to " H ' (inclusive):' /*display the title.*/ say strip($) /*display the list. */ say /*display the sep. */ return /*return to invoker.*/ /*───────────────────────────────────TH subroutine──────────────────────*/ th: procedure; parse arg x; x=abs(x)
return word('th st nd rd', 1+x//10*(x//100%10\==1)*(x//10<4))</lang>
output using the default inputs:
numbers from 0 to 25 (inclusive): 0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th numbers from 250 to 265 (inclusive): 250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th numbers from 1000 to 1025 (inclusive): 1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th
Ruby
Code (slightly adapted) and methodname taken from ActiveSupport (Ruby on Rails). <lang ruby>class Integer
def ordinalize num = self.abs ordinal = if (11..13).include?(num % 100) "th" else case num % 10 when 1; "st" when 2; "nd" when 3; "rd" else "th" end end "#{self}#{ordinal}" end
end
[(0..25),(250..265),(1000..1025)].each{|r| puts r.map(&:ordinalize).join(", "); puts} </lang>
- Output:
0th, 1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th, 11th, 12th, 13th, 14th, 15th, 16th, 17th, 18th, 19th, 20th, 21st, 22nd, 23rd, 24th, 25th 250th, 251st, 252nd, 253rd, 254th, 255th, 256th, 257th, 258th, 259th, 260th, 261st, 262nd, 263rd, 264th, 265th 1000th, 1001st, 1002nd, 1003rd, 1004th, 1005th, 1006th, 1007th, 1008th, 1009th, 1010th, 1011th, 1012th, 1013th, 1014th, 1015th, 1016th, 1017th, 1018th, 1019th, 1020th, 1021st, 1022nd, 1023rd, 1024th, 1025th
Tcl
<lang tcl>proc ordinal {n} {
if {$n%100<10 || $n%100>20} {
set suff [lindex {th st nd rd th th th th th th} [expr {$n % 10}]]
} else {
set suff th
} return "$n'$suff"
}
foreach start {0 250 1000} {
for {set n $start; set l {}} {$n<=$start+25} {incr n} {
lappend l [ordinal $n]
} puts $l
}</lang>
- Output:
0'th 1'st 2'nd 3'rd 4'th 5'th 6'th 7'th 8'th 9'th 10'th 11'th 12'th 13'th 14'th 15'th 16'th 17'th 18'th 19'th 20'th 21'st 22'nd 23'rd 24'th 25'th 250'th 251'st 252'nd 253'rd 254'th 255'th 256'th 257'th 258'th 259'th 260'th 261'st 262'nd 263'rd 264'th 265'th 266'th 267'th 268'th 269'th 270'th 271'st 272'nd 273'rd 274'th 275'th 1000'th 1001'st 1002'nd 1003'rd 1004'th 1005'th 1006'th 1007'th 1008'th 1009'th 1010'th 1011'th 1012'th 1013'th 1014'th 1015'th 1016'th 1017'th 1018'th 1019'th 1020'th 1021'st 1022'nd 1023'rd 1024'th 1025'th