This module contains data on various types of numbers in เวลส์.

จำนวน เชิงการนับ เชิงอันดับที่ ตัวย่อเชิงอันดับที่ เชิงกริยาวิเศษณ์ ตัวคูณ Wikipedia link
0 sero serofed 0fed sero
1 un cyntaf 1af unwaith un
2 masculine: dau
feminine: dwy
ail, eilfed 2il, 2fed dwywaith dwbl dau
3 masculine: tri
feminine: tair
masculine: trydydd
feminine: trydedd
masculine: 3ydd
feminine: 3edd
teirgwaith triphlyg tri
4 masculine: pedwar
feminine: pedair
masculine: pedwerydd
feminine: pedwaredd
masculine: 4ydd
feminine: 4edd
pedwarplyg pedwar
5 pump, (before nouns) pum pumed 5ed pump
6 chwech, (before nouns) chwe chweched 6ed chwech
7 saith seithfed 7fed saith
8 wyth wythfed 8fed wyth
9 naw nawfed 9fed naw
10 deg, (before a nasal or optionally a vowel) deng degfed 10fed deg
11 decimal: un deg un
vigesimal: un ar ddeg
(default): unfed ar ddeg
vigesimal: (non-standard) unarddegfed
decimal: un deg unfed
11eg un deg un
12 masculine / decimal: un deg dau
feminine / decimal: un deg dwy
vigesimal: deuddeg
deuddegfed 12fed un deg dau
13 masculine / decimal: un deg tri
feminine / decimal: un deg tair
masculine / vigesimal: tri ar ddeg
feminine / vigesimal: tair ar ddeg
masculine: trydydd ar ddeg
feminine: trydedd ar ddeg
vigesimal: (non-standard) triarddegfed
13eg un deg tri
14 masculine / decimal: un deg pedwar
feminine / decimal: un deg pedair
masculine / vigesimal: pedwar ar ddeg
feminine / vigesimal: pedair ar ddeg
masculine: pedwerydd ar ddeg
feminine: pedwaredd ar ddeg
14eg un deg pedwar
15 decimal: un deg pump
vigesimal: pymtheg
pymthegfed 15fed un deg pump
16 decimal: un deg chwech
vigesimal: un ar bymtheg
(default): unfed ar bymtheg
vigesimal: (non-standard) unarbymthegfed
16eg un deg chwech
17 decimal: un deg saith
masculine / vigesimal: dau ar bymtheg
feminine / vigesimal: dwy ar bymtheg
(default): ail ar bymtheg, eilfed ar bymtheg
masculine / vigesimal: ddeufed ar bymtheg, deufed ar bymtheg
feminine / vigesimal: ddwyfed ar bymtheg, dwyfed ar bymtheg
17eg un deg saith
18 decimal: un deg wyth
vigesimal: deunaw
feminine / vigesimal: tair ar bymtheg, ugain namyn dwy
(default): deunawfed
masculine / vigesimal: trydydd ar bymtheg
18fed un deg wyth
19 decimal: un deg naw
masculine / vigesimal: pedwar ar bymtheg
feminine / vigesimal: pedair ar bymtheg
masculine: pedwerydd ar bymtheg
feminine: pedwaredd ar bymtheg
19eg un deg naw
20 decimal: dau ddeg, (optionally before a nasal or vowel) dau ddeng
vigesimal: ugain
ugeinfed 20fed dau ddeg
21 vigesimal: un ar hugain
decimal: dau ddeg un
unfed ar hugain 21ain
22 masculine / vigesimal: dau ar hugain
feminine / vigesimal: dwy ar hugain
masculine / decimal: dau ddeg dau
feminine / decimal: dau ddeg dwy
(default): ail ar hugain
masculine / vigesimal: ddeufed ar hugain, deufed ar hugain
feminine / vigesimal: ddwyfed ar hugain, dwyfed ar hugain
22ain
23 masculine / vigesimal: tri ar hugain
feminine / vigesimal: tair ar hugain
masculine / decimal: dau ddeg tri
feminine / decimal: dau ddeg tair
masculine: trydydd ar hugain
feminine: trydedd ar hugain
23ain
24 masculine / vigesimal: pedwar ar hugain
feminine / vigesimal: pedair ar hugain
masculine / decimal: dau ddeg pedwar
feminine / decimal: dau ddeg pedair
masculine: pedwerydd ar hugain
feminine: pedwaredd ar hugain
24ain
25 vigesimal: pump ar hugain, (before nouns) pum ar hugain
decimal: dau ddeg pump, (before nouns) dau ddeg pum
pumed ar hugain 25ain
26 vigesimal: chwech ar hugain, (before nouns) chwe ar hugain
decimal: dau ddeg chwech, (before nouns) dau ddeg chwe
chweched ar hugain 26ain
27 vigesimal: saith ar hugain
decimal: dau ddeg saith
seithfed ar hugain 27ain
28 vigesimal: wyth ar hugain
decimal: dau ddeg wyth
wythfed ar hugain 28ain
29 vigesimal: naw ar hugain
decimal: dau ddeg naw
nawfed ar hugain 29ain
30 decimal: tri deg, (optionally before a nasal or vowel) tri deng
vigesimal: deg ar hugain
degfed ar hugain 30ain
31 vigesimal: un ar ddeg ar hugain
decimal: tri deg un
unfed ar ddeg ar hugain 31ain
32 vigesimal: deuddeg ar hugain
masculine / decimal: tri deg dau
feminine / decimal: tri deg dwy
deuddegfed ar hugain 32ain
33 masculine / vigesimal: tri ar ddeg ar hugain
feminine / vigesimal: tair ar ddeg ar hugain
masculine / decimal: tri deg tri
feminine / decimal: tri deg tair
masculine: trydydd ar ddeg ar hugain
feminine: trydedd ar ddeg ar hugain
33ain
34 masculine / vigesimal: pedwar ar ddeg ar hugain
feminine / vigesimal: pedair ar ddeg ar hugain
masculine / decimal: tri deg pedwar
feminine / decimal: tri deg pedair
masculine: pedwerydd ar ddeg ar hugain
feminine: pedwaredd ar ddeg ar hugain
34ain
35 vigesimal: pymtheg ar hugain
decimal: tri deg pump, (before nouns) tri deg pum
pymthegfed ar hugain 35ain
36 vigesimal: un ar bymtheg ar hugain
decimal: tri deg chwech, (before nouns) tri deg chwe
unfed ar bymtheg ar hugain 36ain
37 masculine / vigesimal: dau ar bymtheg ar hugain
feminine / vigesimal: dwy ar bymtheg ar hugain
decimal: tri deg saith
ail ar bymtheg ar hugain 37ain
38 vigesimal: deunaw ar hugain
decimal: tri deg wyth
deunawfed ar hugain 38ain
39 masculine / vigesimal: pedwar ar bymtheg ar hugain
feminine / vigesimal: pedair ar bymtheg ar hugain
decimal: tri deg naw
masculine: pedwerydd ar bymtheg ar hugain
feminine: pedwaredd ar bymtheg ar hugain
39ain
40 decimal: pedwar deg, (optionally before a nasal or vowel) pedwar deng
vigesimal: deugain
deugeinfed 40fed
41 vigesimal: deugain ac un
decimal: pedwar deg un
deugain ac unfed 41fed
42 masculine / vigesimal: deugain ac dau
feminine / vigesimal: deugain ac dwy
masculine / decimal: pedwar deg dau
feminine / decimal: pedwar deg dwy
deugain ac ail 42il
43 masculine / vigesimal: deugain ac tri, tri a deugain
feminine / vigesimal: deugain ac tair
masculine / decimal: pedwar deg tri
feminine / decimal: pedwar deg tair
masculine: deugain ac trydydd
feminine: deugain ac trydedd
masculine: 43ydd
feminine: 43edd
44 masculine / vigesimal: deugain ac pedwar
feminine / vigesimal: deugain ac pedair
masculine / decimal: pedwar deg pedwar
feminine / decimal: pedwar deg pedair
masculine: deugain ac pedwerydd
feminine: deugain ac pedwaredd
masculine: 44ydd
feminine: 44edd
45 vigesimal: deugain ac pump, (before nouns) deugain ac pum
decimal: pedwar deg pump, (before nouns) pedwar deg pum
deugain ac pumed 45ed
46 vigesimal: deugain ac chwech, (before nouns) deugain ac chwe
decimal: pedwar deg chwech, (before nouns) pedwar deg chwe
deugain ac chweched 46ed
47 vigesimal: deugain ac saith
decimal: pedwar deg saith
deugain ac seithfed 47fed
48 vigesimal: deugain ac wyth, wyth ar ddeugain
decimal: pedwar deg wyth
deugain ac wythfed 48fed
49 vigesimal: deugain ac naw
decimal: pedwar deg naw
deugain ac nawfed 49fed
50 decimal: pum deg, (optionally before a nasal or vowel) pum deng
vigesimal: hanner cant
hanner canfed 50fed
51 vigesimal: hanner cant ac un
decimal: pum deg un
hanner cant ac unfed 51fed
52 masculine / vigesimal: hanner cant ac dau
feminine / vigesimal: hanner cant ac dwy
masculine / decimal: pum deg dau
feminine / decimal: pum deg dwy
hanner cant ac ail 52il
53 masculine / vigesimal: hanner cant ac tri
feminine / vigesimal: hanner cant ac tair
masculine / decimal: pum deg tri
feminine / decimal: pum deg tair
masculine: hanner cant ac trydydd
feminine: hanner cant ac trydedd
masculine: 53ydd
feminine: 53edd
54 masculine / vigesimal: hanner cant ac pedwar
feminine / vigesimal: hanner cant ac pedair
masculine / decimal: pum deg pedwar
feminine / decimal: pum deg pedair
masculine: hanner cant ac pedwerydd
feminine: hanner cant ac pedwaredd
masculine: 54ydd
feminine: 54edd
55 vigesimal: hanner cant ac pump, (before nouns) hanner cant ac pum
decimal: pum deg pump, (before nouns) pum deg pum
hanner cant ac pumed 55ed
56 vigesimal: hanner cant ac chwech, (before nouns) hanner cant ac chwe
decimal: pum deg chwech, (before nouns) pum deg chwe
hanner cant ac chweched 56ed
57 vigesimal: hanner cant ac saith
decimal: pum deg saith
hanner cant ac seithfed 57fed
58 vigesimal: hanner cant ac wyth
decimal: pum deg wyth
hanner cant ac wythfed 58fed
59 vigesimal: hanner cant ac naw
decimal: pum deg naw
hanner cant ac nawfed 59fed
60 decimal: chwe deg, (optionally before a nasal or vowel) chwe deng
vigesimal: trigain
trigeinfed 60fed
61 vigesimal: trigain ac un
decimal: chwe deg un
trigain ac unfed 61fed
62 masculine / vigesimal: trigain ac dau
feminine / vigesimal: trigain ac dwy
masculine / decimal: chwe deg dau
feminine / decimal: chwe deg dwy
trigain ac ail 62il
63 masculine / vigesimal: trigain ac tri
feminine / vigesimal: trigain ac tair
masculine / decimal: chwe deg tri
feminine / decimal: chwe deg tair
masculine: trigain ac trydydd
feminine: trigain ac trydedd
masculine: 63ydd
feminine: 63edd
64 masculine / vigesimal: trigain ac pedwar
feminine / vigesimal: trigain ac pedair
masculine / decimal: chwe deg pedwar
feminine / decimal: chwe deg pedair
masculine: trigain ac pedwerydd
feminine: trigain ac pedwaredd
masculine: 64ydd
feminine: 64edd
65 vigesimal: trigain ac pump, (before nouns) trigain ac pum
decimal: chwe deg pump, (before nouns) chwe deg pum
trigain ac pumed 65ed
66 vigesimal: trigain ac chwech, (before nouns) trigain ac chwe
decimal: chwe deg chwech, (before nouns) chwe deg chwe
trigain ac chweched 66ed
67 vigesimal: trigain ac saith
decimal: chwe deg saith
trigain ac seithfed 67fed
68 vigesimal: trigain ac wyth
decimal: chwe deg wyth
trigain ac wythfed 68fed
69 vigesimal: trigain ac naw
decimal: chwe deg naw
trigain ac nawfed 69fed
70 decimal: saith deg, (optionally before a nasal or vowel) saith deng
vigesimal: deg a thrigain
degfed a thrigain 70ain
71 vigesimal: un ar ddeg a thrigain
decimal: saith deg un
unfed ar ddeg a thrigain 71ain
72 vigesimal: deuddeg a thrigain
masculine / decimal: saith deg dau
feminine / decimal: saith deg dwy
deuddegfed a thrigain 72ain
73 masculine / vigesimal: tri ar ddeg a thrigain
feminine / vigesimal: tair ar ddeg a thrigain
masculine / decimal: saith deg tri
feminine / decimal: saith deg tair
masculine: trydydd ar ddeg a thrigain
feminine: trydedd ar ddeg a thrigain
73ain
74 masculine / vigesimal: pedwar ar ddeg a thrigain
feminine / vigesimal: pedair ar ddeg a thrigain
masculine / decimal: saith deg pedwar
feminine / decimal: saith deg pedair
masculine: pedwerydd ar ddeg a thrigain
feminine: pedwaredd ar ddeg a thrigain
74ain
75 vigesimal: pymtheg a thrigain
decimal: saith deg pump, (before nouns) saith deg pum
pymthegfed a thrigain 75ain
76 vigesimal: un ar bymtheg a thrigain
decimal: saith deg chwech, (before nouns) saith deg chwe
unfed ar bymtheg a thrigain 76ain
77 masculine / vigesimal: dau ar bymtheg a thrigain
feminine / vigesimal: dwy ar bymtheg a thrigain
decimal: saith deg saith
ail ar bymtheg a thrigain 77ain
78 vigesimal: deunaw a thrigain
decimal: saith deg wyth
deunawfed a thrigain 78ain
79 masculine / vigesimal: pedwar ar bymtheg a thrigain
feminine / vigesimal: pedair ar bymtheg a thrigain
decimal: saith deg naw
masculine: pedwerydd ar bymtheg a thrigain
feminine: pedwaredd ar bymtheg a thrigain
79ain
80 decimal: wyth deg, (optionally before a nasal or vowel) wyth deng
vigesimal: pedwar ugain
pedwar ugeinfed 80fed
81 vigesimal: pedwar ugain ac un
decimal: wyth deg un
pedwar ugain ac unfed 81fed
82 masculine / vigesimal: pedwar ugain ac dau
feminine / vigesimal: pedwar ugain ac dwy
masculine / decimal: wyth deg dau
feminine / decimal: wyth deg dwy
pedwar ugain ac ail 82il
83 masculine / vigesimal: pedwar ugain ac tri
feminine / vigesimal: pedwar ugain ac tair
masculine / decimal: wyth deg tri
feminine / decimal: wyth deg tair
masculine: pedwar ugain ac trydydd
feminine: pedwar ugain ac trydedd
masculine: 83ydd
feminine: 83edd
84 masculine / vigesimal: pedwar ugain ac pedwar
feminine / vigesimal: pedwar ugain ac pedair
masculine / decimal: wyth deg pedwar
feminine / decimal: wyth deg pedair
masculine: pedwar ugain ac pedwerydd
feminine: pedwar ugain ac pedwaredd
masculine: 84ydd
feminine: 84edd
85 vigesimal: pedwar ugain ac pump, (before nouns) pedwar ugain ac pum
decimal: wyth deg pump, (before nouns) wyth deg pum
pedwar ugain ac pumed 85ed
86 vigesimal: pedwar ugain ac chwech, (before nouns) pedwar ugain ac chwe
decimal: wyth deg chwech, (before nouns) wyth deg chwe
pedwar ugain ac chweched 86ed
87 vigesimal: pedwar ugain ac saith
decimal: wyth deg saith
pedwar ugain ac seithfed 87fed
88 vigesimal: pedwar ugain ac wyth
decimal: wyth deg wyth
pedwar ugain ac wythfed 88fed
89 vigesimal: pedwar ugain ac naw
decimal: wyth deg naw
pedwar ugain ac nawfed 89fed
90 decimal: naw deg, (optionally before a nasal or vowel) naw deng
vigesimal: deg a phedwar ugain
degfed a phedwar ugain 90ain
91 vigesimal: un ar ddeg a phedwar ugain
decimal: naw deg un
unfed ar ddeg a phedwar ugain 91ain
92 vigesimal: deuddeg a phedwar ugain
masculine / decimal: naw deg dau
feminine / decimal: naw deg dwy
deuddegfed a phedwar ugain 92ain
93 masculine / vigesimal: tri ar ddeg a phedwar ugain
feminine / vigesimal: tair ar ddeg a phedwar ugain
masculine / decimal: naw deg tri
feminine / decimal: naw deg tair
masculine: trydydd ar ddeg a phedwar ugain
feminine: trydedd ar ddeg a phedwar ugain
93ain
94 masculine / vigesimal: pedwar ar ddeg a phedwar ugain
feminine / vigesimal: pedair ar ddeg a phedwar ugain
masculine / decimal: naw deg pedwar
feminine / decimal: naw deg pedair
masculine: pedwerydd ar ddeg a phedwar ugain
feminine: pedwaredd ar ddeg a phedwar ugain
94ain
95 vigesimal: pymtheg a phedwar ugain
decimal: naw deg pump, (before nouns) naw deg pum
pymthegfed a phedwar ugain 95ain
96 vigesimal: un ar bymtheg a phedwar ugain
decimal: naw deg chwech, (before nouns) naw deg chwe
unfed ar bymtheg a phedwar ugain 96ain
97 masculine / vigesimal: dau ar bymtheg a phedwar ugain
feminine / vigesimal: dwy ar bymtheg a phedwar ugain
decimal: naw deg saith
ail ar bymtheg a phedwar ugain 97ain
98 vigesimal: deunaw a phedwar ugain
decimal: naw deg wyth
deunawfed a phedwar ugain 98ain
99 vigesimal: cant namyn un
masculine / vigesimal: pedwar ar bymtheg a phedwar ugain
feminine / vigesimal: pedair ar bymtheg a phedwar ugain
decimal: naw deg naw
(default): canfed namyn un
masculine: pedwerydd ar bymtheg a phedwar ugain
feminine: pedwaredd ar bymtheg a phedwar ugain
99ain
100 (default): cant, (before nouns) can
vigesimal: pum ugain
canfed 100fed
101 cant ac un cyntaf wedi'r cant 101af
102 cant a dau ail wedi'r cant
120 (default): cant ac ugain
decimal: cant dau ddeg
vigesimal: chweugain
200 dau gant dau ganfed
300 tri chant tri chanfed
400 pedwar cant pedwar canfed
500 pum cant pum canfed
600 chwe chant chwe chanfed
700 saith cant saith canfed
800 wyth cant wyth canfed
900 naw cant naw canfed
1,000 mil mil
2,000 dau fil dau filfed
3,000 tri mil tri milfed
4,000 pedwar mil pedwar milfed
5,000 pump mil pump milfed
6,000 chwech mil chwech milfed
7,000 saith mil saith milfed
8,000 wyth mil wyth milfed
9,000 naw mil naw milfed
10,000 deg mil, (before a nasal or optionally a vowel) deng mil deg milfed, (before a nasal or optionally a vowel) deng milfed
20,000 dau ddeg mil dau ddeg milfed
30,000 tri deg mil tri deg milfed
40,000 pedwar deg mil pedwar deg milfed
50,000 pum deg mil pum deg milfed
60,000 chwe deg mil chwe deg milfed
70,000 saith deg mil saith deg milfed
80,000 wyth deg mil wyth deg milfed
90,000 naw deg mil naw deg milfed
1,000,000 (106) miliwn
1,000,000,000 (109) biliwn

local export = {numbers = {}}

local m_numutils = require("Module:number list/utils")
local map = m_numutils.map
local filter = m_numutils.filter
local power_of = m_numutils.power_of

local rfind = mw.ustring.find
local rsubn = mw.ustring.gsub

-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

local numbers = export.numbers

numbers[0] = {
	cardinal = "sero",
	ordinal = "serofed",
	ordinal_abbr = "0fed",
	wplink = "sero",
}

numbers[1] = {
	cardinal = "un",
	ordinal = "cyntaf",
	ordinal_abbr = "1af",
	adverbial = "unwaith",
	wplink = "un",
}

numbers[2] = {
	cardinal = {"dau<tag:masculine>", "dwy<tag:feminine>"},
	ordinal = "ail",
	ordinal_abbr = {"2il", "2fed"},
	adverbial = "dwywaith",
	multiplier = "dwbl",
	wplink = "dau",
}

numbers[3] = {
	cardinal = {"tri<tag:masculine>", "tair<tag:feminine>"},
	ordinal = {"trydydd<tag:masculine>", "trydedd<tag:feminine>"},
	ordinal_abbr = {"3ydd<tag:masculine>", "3edd<tag:feminine>"},
	adverbial = "teirgwaith",
	multiplier = "triphlyg",
	wplink = "tri",
}

numbers[4] = {
	cardinal = {"pedwar<tag:masculine>", "pedair<tag:feminine>"},
	ordinal = {"pedwerydd<tag:masculine>", "pedwaredd<tag:feminine>"},
	ordinal_abbr = {"4ydd<tag:masculine>", "4edd<tag:feminine>"},
	multiplier = "pedwarplyg",
	wplink = "pedwar",
}

numbers[5] = {
	cardinal = {"pump", "pum<q:before nouns>"},
	ordinal = "pumed",
	ordinal_abbr = "5ed",
	wplink = "pump",
}

numbers[6] = {
	cardinal = {"chwech", "chwe<q:before nouns>"},
	ordinal = "chweched",
	ordinal_abbr = "6ed",
	wplink = "chwech",
}

numbers[7] = {
	cardinal = "saith",
	ordinal = "seithfed",
	ordinal_abbr = "7fed",
	wplink = "saith",
}

numbers[8] = {
	cardinal = "wyth",
	ordinal = "wythfed",
	ordinal_abbr = "8fed",
	wplink = "wyth",
}

numbers[9] = {
	cardinal = "naw",
	ordinal = "nawfed",
	ordinal_abbr = "9fed",
	wplink = "naw",
}

numbers[10] = {
	cardinal = {"deg", "deng<q:before a nasal or optionally a vowel>"},
	ordinal = "degfed",
	ordinal_abbr = "10fed",
	wplink = "deg",
}

numbers[11] = {
	cardinal = {"un deg un<tag:decimal>", "un ar ddeg<tag:vigesimal>"},
	ordinal = "unfed ar ddeg",
	ordinal_abbr = "11eg",
	wplink = "un deg un",
}

numbers[12] = {
	cardinal = {"un deg dau<tag:decimal><tag:masculine>", "un deg dwy<tag:decimal><tag:feminine>", "deuddeg<tag:vigesimal>"},
	ordinal = "deuddegfed",
	ordinal_abbr = "12fed",
	wplink = "un deg dau",
}

numbers[13] = {
	cardinal = {"un deg tri<tag:decimal><tag:masculine>", "un deg tair<tag:decimal><tag:feminine>", "tri ar ddeg<tag:vigesimal><tag:masculine>", "tair ar ddeg<tag:vigesimal><tag:feminine>"},
	ordinal = {"trydydd ar ddeg<tag:masculine>", "trydedd ar ddeg<tag:feminine>"},
	ordinal_abbr = "13eg",
	wplink = "un deg tri",
}

numbers[14] = {
	cardinal = {"un deg pedwar<tag:decimal><tag:masculine>", "un deg pedair<tag:decimal><tag:feminine>", "pedwar ar ddeg<tag:vigesimal><tag:masculine>", "pedair ar ddeg<tag:vigesimal><tag:feminine>"},
	ordinal = {"pedwerydd ar ddeg<tag:masculine>", "pedwaredd ar ddeg<tag:feminine>"},
	ordinal_abbr = "14eg",
	wplink = "un deg pedwar",
}

numbers[15] = {
	cardinal = {"un deg pump<tag:decimal>", "pymtheg<tag:vigesimal>"},
	ordinal = "pymthegfed",
	ordinal_abbr = "15fed",
	wplink = "un deg pump",
}

numbers[16] = {
	cardinal = {"un deg chwech<tag:decimal>", "un ar bymtheg<tag:vigesimal>"},
	ordinal = "unfed ar bymtheg",
	ordinal_abbr = "16eg",
	wplink = "un deg chwech",
}

numbers[17] = {
	cardinal = {"un deg saith<tag:decimal>", "dau ar bymtheg<tag:vigesimal><tag:masculine>", "dwy ar bymtheg<tag:vigesimal><tag:feminine>"},
	ordinal = "ail ar bymtheg",
	ordinal_abbr = "17eg",
	wplink = "un deg saith",
}

numbers[18] = {
	cardinal = {"un deg wyth<tag:decimal>", "deunaw<tag:vigesimal>"},
	ordinal = "deunawfed",
	ordinal_abbr = "18fed",
	wplink = "un deg wyth",
}

numbers[19] = {
	cardinal = {"un deg naw<tag:decimal>", "pedwar ar bymtheg<tag:vigesimal><tag:masculine>", "pedair ar bymtheg<tag:vigesimal><tag:feminine>"},
	ordinal = {"pedwerydd ar bymtheg<tag:masculine>", "pedwaredd ar bymtheg<tag:feminine>"},
	ordinal_abbr = "19eg",
	wplink = "un deg naw",
}

numbers[20] = {
	cardinal = {"dau ddeg<tag:decimal>", "ugain<tag:vigesimal>"},
	ordinal = "ugeinfed",
	ordinal_abbr = "20fed",
	wplink = "dau ddeg",
}

numbers[30] = {
	cardinal = {"tri deg<tag:decimal>", "deg ar hugain<tag:vigesimal>"},
	ordinal = "degfed ar hugain",
	ordinal_abbr = "30ain",
}

numbers[40] = {
	cardinal = {"pedwar deg<tag:decimal>", "deugain<tag:vigesimal>"},
	ordinal = "deugeinfed",
	ordinal_abbr = "40fed",
}

numbers[50] = {
	cardinal = {"pum deg<tag:decimal>", "hanner cant<tag:vigesimal>"},
	ordinal = "hanner canfed",
	ordinal_abbr = "50fed",
}

numbers[60] = {
	cardinal = {"chwe deg<tag:decimal>", "trigain<tag:vigesimal>"},
	ordinal = "trigeinfed", -- FIXME: trigainfed? Misspelling?
	ordinal_abbr = "60fed",
}

numbers[70] = {
	cardinal = {"saith deg<tag:decimal>", "deg a thrigain<tag:vigesimal>"},
	ordinal = "degfed a thrigain",
	ordinal_abbr = "70ain",
}

numbers[80] = {
	cardinal = {"wyth deg<tag:decimal>", "pedwar ugain<tag:vigesimal>"},
	ordinal = "pedwar ugeinfed",
	ordinal_abbr = "80fed",
}

numbers[90] = {
	cardinal = {"naw deg<tag:decimal>", "deg a phedwar ugain<tag:vigesimal>"},
	ordinal = "degfed a phedwar ugain",
	ordinal_abbr = "90ain",
}

-- Templates for vigesimal numbers 21-99, not counting even multiples of 10. Some vigesimal numbers are actually
-- vigesimal and take units in the 11-19 range, while others take units in the 1-9 range even when they would be
-- expected to take units in the 11-19 range. An example of the latter is 52, formed as "hanner cant ac" + the number
-- for 2 (hence masculine "hanner cant ac dau", feminine "hanner cant ac dwy"). An example of the former is 74, formed
-- as the number for 14 + "a thrigain" (hence masculine "pedwar ar ddeg a thrigain" and feminine
-- "pedair ar ddeg a thrigain").
--
-- We determine the unit by taking either mod 10 or mod 20 of the overall number (depending on the second element of the
-- two-element table below), and fetching the corresponding units cardinal(s) or ordinal(s). If at least one element in
-- the resulting unit form(s) has a <tag:vigesimal> modifier, this means the number has different decimal and vigesimal
-- forms (this happens with numbers 11 and above), so filter down to only the ones with the vigesimal tag, and remove
-- it; otherwise take all forms. Then substitute the resulting unit form(s) into the template where it says UNIT, taking
-- care to move tags on the unit form(s) to the end; map() does this automatically. Also add "<tag:vigesimal>" at the
-- end of the return value to map(), i.e. directly after the template; any modifiers from the units forms will be tacked
-- on after that.
local vigesimal_templates = {
	[2] = {"UNIT ar hugain", 10},
	[3] = {"UNIT ar hugain", 20},
	[4] = {"deugain ac UNIT", 10},
	[5] = {"hanner cant ac UNIT", 10},
	[6] = {"trigain ac UNIT", 10},
	[7] = {"UNIT a thrigain", 20},
	[8] = {"pedwar ugain ac UNIT", 10},
	[9] = {"UNIT a phedwar ugain", 20},
}

local ordinal_suffixes = { "fed", "ed", "af", "il", "ydd", "edd", "eg", "ain" }

-- Generate the numbers from 20 to 99. This is not easy both because there are two systems for forming cardinals
-- (decimal and vigesimal) and because of all sorts of complexities, including masculine and feminine variants of
-- certain numbers (exactly which numbers differs between the decimal and vigesimal systems), apocopated variants of
-- certain numbers before nouns (e.g. 5 and 6), and nasalized variants of [[deg]] (10) and certain derivatives of it.
for ten_multiplier=2, 9 do
	for one=1, 9 do
		local num = ten_multiplier * 10 + one

		-- First, the decimal forms. Only the cardinal is decimal. Formation is "TEN_UNIT deg ONE_UNIT" where
		-- TEN_UNIT = the cardinal associated with `ten_multiplier` and ONE_UNIT = the cardinal associated with `one`.
		-- Irregularities in the word "deg" follow the even multiples of 10, so we just copy them.
		local decimal_ten_card = filter(function(card) return card:find("<tag:decimal>") end, numbers[ten_multiplier * 10].cardinal)
		if #decimal_ten_card ~= 1 then
			error(("Internal error: Multiple or no decimal ten multiplier forms for number %s: %s"):format(num, table.concat(decimal_ten_card, ", ")))
		end
		local decimal_cardinal = map(function(unit_card)
			return map(function(ten_card) return ten_card .. " " .. unit_card end, decimal_ten_card)
		end, numbers[one].cardinal)

		-- Now the vigesimal forms. See the comment above `vigesimal_template`.
		local vigesimal_template, unit_mod = unpack(vigesimal_templates[ten_multiplier])
		local vigesimal_unit = num % unit_mod

		-- First cardinal forms.
		local vigesimal_unit_card = filter(function(card) return card:find("<tag:vigesimal>") end, numbers[vigesimal_unit].cardinal)
		if #vigesimal_unit_card > 0 then
			for i, unit_card in ipairs(vigesimal_unit_card) do
				vigesimal_unit_card[i] = rsub(unit_card, "<tag:vigesimal>", "")
			end
		else
			vigesimal_unit_card = numbers[vigesimal_unit].cardinal
		end
		local vigesimal_cardinal = map(function(unit_card) return rsub(vigesimal_template, "UNIT", unit_card) .. "<tag:vigesimal>" end,
			vigesimal_unit_card)

		-- Next ordinal forms.
		vigesimal_unit_ord = vigesimal_unit == 1 and "unfed" or numbers[vigesimal_unit].ordinal -- ordinals always vigesimal
		local vigesimal_ordinal = map(function(unit_ord) return rsub(vigesimal_template, "UNIT", unit_ord) end,
			vigesimal_unit_ord)

		-- Now combine vigesimal + decimal cardinal forms, possibly with special form for 99; similarly, take the
		-- ordinal forms, possibly combining with special form for 99.
		local combined_card
		local combined_ord
		if num == 99 then -- include special forms for 99 before regular forms
			combined_card = {"cant namyn un<tag:vigesimal>"}
			combined_ord = {"canfed namyn un"}
		else
			combined_card = {}
			-- don't set combined_ord; it just uses the vigesimal forms directly.
		end
		local function insert(dest, source)
			if type(source) ~= "table" then
				source = {source}
			end
			for _, item in ipairs(source) do
				table.insert(dest, item)
			end
		end
		insert(combined_card, vigesimal_cardinal)
		insert(combined_card, decimal_cardinal)
		if combined_ord then
			insert(combined_ord, vigesimal_ordinal)
		else
			combined_ord = vigesimal_ordinal
			if #combined_ord == 1 then
				combined_ord = combined_ord[1]
			end
		end

		local ordinal_abbr = map(function(ord)
			for _, suffix in ipairs(ordinal_suffixes) do
				if rfind(ord, suffix .. "$") then
					return num .. suffix
				end
			end
			error(("Ordinal %s doesn't end with any of the recognized suffixes %s; please update the suffix list"):format(
				ord, table.concat(ordinal_suffixes, ",")))
		end, vigesimal_ordinal)

		-- If all (both) ordinal abbrevs are the same, reduce to one.
		if type(ordinal_abbr) == "table" and #ordinal_abbr > 1 then
			if #ordinal_abbr > 2 then
				error(("Don't currently know how to handle more than two ordinal variants, but saw %s"):format(
					table.concat(ordinal_abbr)))
			end
			local abbr1 = rsub(ordinal_abbr[1], "<.*>", "")
			local abbr2 = rsub(ordinal_abbr[2], "<.*>", "")
			if abbr1 == abbr2 then
				-- Remove masculine/feminine tag
				ordinal_abbr = rsub(ordinal_abbr[1], "<tag:[a-z]+ine>", "")
			end
		end

		numbers[num] = {
			cardinal = combined_card,
			ordinal = combined_ord,
			ordinal_abbr = ordinal_abbr,
		}
	end
end
	
numbers[100] = {
	cardinal = {"cant", "can<q:before nouns>"},
	ordinal = "canfed",
	ordinal_abbr = "100fed",
}

numbers[101] = {
	cardinal = "cant ac un",
	ordinal = "cyntaf wedi'r cant",
	ordinal_abbr = "101af",
}

numbers[102] = {
	cardinal = "cant a dau",
	ordinal = "ail wedi'r cant",
}

for hundred, form in ipairs { "dau gant", "tri chant", "pedwar cant", "pum cant", "chwe chant",
	"saith cant", "wyth cant", "naw cant" } do
	local num = (hundred + 1) * 100
	numbers[num] = {
		cardinal = form,
		ordinal = rsub(form, "t$", "") .. "fed",
	}
end

for thousand, form in ipairs { "mil", "[[dau]] [[mil|fil]]", "[[tri]] [[mil]]", "[[pedwar]] [[mil]]",
	"[[pump]] [[mil]]", "[[chwech]] [[mil]]", "[[saith]] [[mil]]", "[[wyth]] [[mil]]", "[[naw]] [[mil]]" } do
	local ordinal
	if thousand == 2 then
		ordinal = "[[dau]] [[milfed|filfed]]"
	else
		ordinal = rsub(form, "%]%]$", "fed]]")
	end
	numbers[thousand * 1000] = {
		cardinal = form,
		ordinal = ordinal,
	}
end

-- Handle 10000 through 90000.
for num=10000, 90000, 10000 do
	local multiplier = numbers[num / 1000].cardinal
	local decimal_mult = filter(function(card) return card:find("<tag:decimal>") end, multiplier)
	if #decimal_mult > 0 then
		decimal_mult = map(function(card) return rsub(card, "<tag:decimal>", "") end, decimal_mult, "include modifiers")
	else
		decimal_mult = multiplier
	end
	local cardinal = map(function(card) return ("[[%s]] [[mil]]"):format(card) end, decimal_mult)
	local ordinal = map(function(card) return ("[[%s]] [[milfed]]"):format(card) end, decimal_mult)

	numbers[num] = {
		cardinal = cardinal,
		ordinal = ordinal,
	}
end

-- Is this still used?
--[=[
numbers[10000] = {
	cardinal = "myrdd",
	ordinal = "myrddfed",
}
]=]

-- Is this still used?
--[=[
numbers[100000] = {
	cardinal = {"milcant", "milcan<q:before nouns>"},
	ordinal = "milcanfed",
}
]=]

numbers[1000000] = {
	cardinal = "miliwn",
	-- ordinal = "miliwnfed" or "miliyenfed"?
}

numbers[power_of(9)] = {
	cardinal = "biliwn",
	-- ordinal = "biliwnfed" or "biliyenfed"?
}

-- Temporary hacks for newly added cardinals.
table.insert(numbers[43].cardinal, "tri a deugain<tag:vigesimal><tag:masculine>")
table.insert(numbers[48].cardinal,  "wyth ar ddeugain<tag:vigesimal>")
table.insert(numbers[100].cardinal, "pum ugain<tag:vigesimal>")
numbers[120] = {}
numbers[120].cardinal = {}
table.insert(numbers[120].cardinal, "[[cant]] [[ac]] [[ugain]]")
table.insert(numbers[120].cardinal, "[[cant]] [[dau ddeg]]<tag:decimal>")
table.insert(numbers[120].cardinal, "chweugain<tag:vigesimal>")
local denquals="<tag:decimal><q:optionally before a nasal or vowel>"
table.insert(numbers[20].cardinal, "dau ddeng"..denquals)
table.insert(numbers[30].cardinal, "tri deng"..denquals)
table.insert(numbers[40].cardinal, "pedwar deng"..denquals)
table.insert(numbers[50].cardinal, "pum deng"..denquals)
table.insert(numbers[60].cardinal, "chwe deng"..denquals)
table.insert(numbers[70].cardinal, "saith deng"..denquals)
table.insert(numbers[80].cardinal, "wyth deng"..denquals)
table.insert(numbers[90].cardinal, "naw deng"..denquals)

-- And also some ordinals.
function add(num, form, value)
	if numbers[num][form] then
		if type(numbers[num][form]) == 'string' then
			numbers[num][form] = { numbers[num][form] }
		end
	else
		numbers[num][form] = {}
	end
	table.insert(numbers[num][form], value)
end

add(18, 'cardinal', "tair ar bymtheg<tag:vigesimal><tag:feminine>") -- Really sesquidecimal.
add(18, 'cardinal', "ugain namyn dwy<tag:vigesimal><tag:feminine>")
add(2, 'ordinal', "eilfed")
add(11, 'ordinal', "unarddegfed<q:non-standard><tag:vigesimal>")
add(11, 'ordinal', "un deg unfed<tag:decimal>")
add(13, 'ordinal', "triarddegfed<q:non-standard><tag:vigesimal>")
add(16, 'ordinal', "unarbymthegfed<q:non-standard><tag:vigesimal>")
add(17, 'ordinal', "eilfed ar bymtheg")
add(17, 'ordinal', "ddeufed ar bymtheg<tag:vigesimal><tag:masculine>")
add(17, 'ordinal', "ddwyfed ar bymtheg<tag:vigesimal><tag:feminine>")
add(17, 'ordinal', "deufed ar bymtheg<tag:vigesimal><tag:masculine>")
add(17, 'ordinal', "dwyfed ar bymtheg<tag:vigesimal><tag:feminine>")
add(18, 'ordinal', "trydydd ar bymtheg<tag:vigesimal><tag:masculine>")
add(22, 'ordinal', "ddeufed ar hugain<tag:vigesimal><tag:masculine>")
add(22, 'ordinal', "ddwyfed ar hugain<tag:vigesimal><tag:feminine>")
add(22, 'ordinal', "deufed ar hugain<tag:vigesimal><tag:masculine>")
add(22, 'ordinal', "dwyfed ar hugain<tag:vigesimal><tag:feminine>")

return export