Implement Latin power with long and short count for English. Removed Tagalog system to integrate the new directory structure.master
@@ -13,7 +13,7 @@ | |||
"scripts": { | |||
"start": "tsdx watch", | |||
"build": "tsdx build", | |||
"test": "tsdx test --verbose", | |||
"test": "tsdx test", | |||
"lint": "tsdx lint", | |||
"prepare": "tsdx build" | |||
}, | |||
@@ -0,0 +1,10 @@ | |||
export type GetKiloCount = (hundreds: number, tens: number, ones: number) => string | |||
export type GetKiloName = (thousandPower: number) => string | |||
export default interface NumberSystem { | |||
getKiloCount: GetKiloCount, | |||
getKiloName: { | |||
short?: GetKiloName, | |||
long?: GetKiloName, | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
export default interface NumberSystemNameTable { | |||
units: string[10], | |||
tenPlus: string[10], | |||
tenTimes: string[10], | |||
hundred: string, | |||
thousand: string, | |||
kiloSpecialUnits: string[10], | |||
kiloUnits: string[10], | |||
kiloTens: string[10], | |||
kiloHundreds: string[10], | |||
kiloThousand: string, | |||
kiloEvenSuffix: string, | |||
kiloOddSuffix: string, | |||
} |
@@ -0,0 +1,88 @@ | |||
{ | |||
"units": [ | |||
"zero", | |||
"ein", | |||
"zwei", | |||
"drei", | |||
"vier", | |||
"fünf", | |||
"sechs", | |||
"sieben", | |||
"acht", | |||
"neun" | |||
], | |||
"tenPlus": [ | |||
"zehn", | |||
"elf", | |||
"zwölf", | |||
"dreizehn", | |||
"vierzehn", | |||
"fünfzhen", | |||
"sechzehn", | |||
"siebzehn", | |||
"achtzehn", | |||
"neunzehn" | |||
], | |||
"tenTimes": [ | |||
"zero", | |||
"zehn", | |||
"zwanzig", | |||
"dreißig", | |||
"vierzig", | |||
"fünfzig", | |||
"sechzig", | |||
"siebzig", | |||
"achtzig", | |||
"neunzig" | |||
], | |||
"hundred": "hundert", | |||
"thousand": "tausend", | |||
"kiloSpecialUnits": [ | |||
"m", | |||
"b", | |||
"tr", | |||
"quadr", | |||
"quin", | |||
"sex", | |||
"sept", | |||
"oct", | |||
"non" | |||
], | |||
"kiloUnits": [ | |||
"un", | |||
"duo", | |||
"tre", | |||
"quattuor", | |||
"quin", | |||
"sex", | |||
"septen", | |||
"octo", | |||
"novem" | |||
], | |||
"kiloTens": [ | |||
"dec", | |||
"vigin", | |||
"trigin", | |||
"quadragin", | |||
"quinquagin", | |||
"sexagin", | |||
"septuagin", | |||
"octogin", | |||
"nonagin" | |||
], | |||
"kiloHundreds": [ | |||
"cen", | |||
"duocen", | |||
"trecen", | |||
"quadringen", | |||
"quingen", | |||
"sescen", | |||
"septingen", | |||
"octingen", | |||
"nongen" | |||
], | |||
"kiloThousand": "millia", | |||
"kiloEvenSuffix": "llion", | |||
"kiloOddSuffix": "lliard", | |||
"and": "und" | |||
} |
@@ -0,0 +1,14 @@ | |||
import NumberSystem from '../common/NumberSystem' | |||
import getKiloCount from './en/getKiloCount' | |||
import getLongKiloName from './en/getLongKiloName' | |||
import getShortKiloName from './en/getShortKiloName' | |||
const en: NumberSystem = { | |||
getKiloCount, | |||
getKiloName: { | |||
short: getShortKiloName, | |||
long: getLongKiloName, | |||
} | |||
} | |||
export default en |
@@ -0,0 +1,28 @@ | |||
import hundredTimes from './hundredTimes' | |||
it('should exist', () => { | |||
expect(hundredTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundredTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundredTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'one hundred'} | |||
${2} | ${'200'} | ${'two hundred'} | |||
${3} | ${'300'} | ${'three hundred'} | |||
${4} | ${'400'} | ${'four hundred'} | |||
${5} | ${'500'} | ${'five hundred'} | |||
${6} | ${'600'} | ${'six hundred'} | |||
${7} | ${'700'} | ${'seven hundred'} | |||
${8} | ${'800'} | ${'eight hundred'} | |||
${9} | ${'900'} | ${'nine hundred'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundredTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,21 @@ | |||
import NAMES from '../names.json' | |||
interface HundredTimes { | |||
(x100: number): string | |||
} | |||
/** | |||
* Get the name of some number in the hundreds place. | |||
* @param {number} x100 - The number in the hundreds place. | |||
* @returns {string} The name of the number in the hundreds place. | |||
*/ | |||
const hundredTimes: HundredTimes = (x100) => ( | |||
x100 === 0 | |||
? NAMES.units[0] | |||
: [ | |||
NAMES.units[x100], | |||
NAMES.hundred, | |||
].join(' ') | |||
) | |||
export default hundredTimes |
@@ -0,0 +1,187 @@ | |||
import combiningPrefix from './combiningPrefix' | |||
it('should exist', () => { | |||
expect(combiningPrefix).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof combiningPrefix).toBe('function') | |||
}) | |||
it('should accept 4 arguments', () => { | |||
expect(combiningPrefix).toHaveLength(4) | |||
}) | |||
describe('on 0 in hundreds place', () => { | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
value | display | name | |||
${1} | ${'1'} | ${'mi'} | |||
${2} | ${'2'} | ${'bi'} | |||
${3} | ${'3'} | ${'tri'} | |||
${4} | ${'4'} | ${'quadri'} | |||
${5} | ${'5'} | ${'quinti'} | |||
${6} | ${'6'} | ${'sexti'} | |||
${7} | ${'7'} | ${'septi'} | |||
${8} | ${'8'} | ${'octi'} | |||
${9} | ${'9'} | ${'noni'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(0, 0, value)).toBe(name) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${1} | ${'deci'} | |||
${2} | ${'viginti'} | |||
${3} | ${'triginti'} | |||
${4} | ${'quadraginti'} | |||
${5} | ${'quinquaginti'} | |||
${6} | ${'sexaginti'} | |||
${7} | ${'septuaginti'} | |||
${8} | ${'octoginti'} | |||
${9} | ${'nonaginti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${tensName} | |||
${1} | ${'un' + tensName} | |||
${2} | ${'duo' + tensName} | |||
${3} | ${'tre' + tensName} | |||
${4} | ${'quattuor' + tensName} | |||
${5} | ${'quin' + tensName} | |||
${6} | ${'sex' + tensName} | |||
${7} | ${'septen' + tensName} | |||
${8} | ${'octo' + tensName} | |||
${9} | ${'novem' + tensName} | |||
`(`should return "$display" for ${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(0, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'cen'} | |||
${2} | ${'duocen'} | |||
${3} | ${'trecen'} | |||
${4} | ${'quadringen'} | |||
${5} | ${'quingen'} | |||
${6} | ${'sescen'} | |||
${7} | ${'septingen'} | |||
${8} | ${'octingen'} | |||
${9} | ${'nongen'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
describe.each` | |||
tens | tensName | |||
${0} | ${'ti'} | |||
${1} | ${'deci'} | |||
${2} | ${'viginti'} | |||
${3} | ${'triginti'} | |||
${4} | ${'quadraginti'} | |||
${5} | ${'quinquaginti'} | |||
${6} | ${'sexaginti'} | |||
${7} | ${'septuaginti'} | |||
${8} | ${'octoginti'} | |||
${9} | ${'nonaginti'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | display | |||
${0} | ${hundredsName + tensName} | |||
${1} | ${hundredsName + 'un' + tensName} | |||
${2} | ${hundredsName + 'duo' + tensName} | |||
${3} | ${hundredsName + 'tre' + tensName} | |||
${4} | ${hundredsName + 'quattuor' + tensName} | |||
${5} | ${hundredsName + 'quin' + tensName} | |||
${6} | ${hundredsName + 'sex' + tensName} | |||
${7} | ${hundredsName + 'septen' + tensName} | |||
${8} | ${hundredsName + 'octo' + tensName} | |||
${9} | ${hundredsName + 'novem' + tensName} | |||
`(`should return "$display" for ${hundreds}${tens}$ones`, ({ ones, display, }) => { | |||
expect(combiningPrefix(hundreds, tens, ones)).toBe(display) | |||
}) | |||
}) | |||
}) | |||
describe.each` | |||
hundredThousands | hundredThousandsName | |||
${1} | ${'cen'} | |||
${2} | ${'duocen'} | |||
${3} | ${'trecen'} | |||
${4} | ${'quadringen'} | |||
${5} | ${'quingen'} | |||
${6} | ${'sescen'} | |||
${7} | ${'septingen'} | |||
${8} | ${'octingen'} | |||
${9} | ${'nongen'} | |||
`('on $hundredThousands in hundred thousands place', ({ hundredThousands, hundredThousandsName, }) => { | |||
describe.each` | |||
tenThousands | tenThousandsName | |||
${0} | ${''} | |||
${1} | ${'dec'} | |||
${2} | ${'vigin'} | |||
${3} | ${'trigin'} | |||
${4} | ${'quadragin'} | |||
${5} | ${'quinquagin'} | |||
${6} | ${'sexagin'} | |||
${7} | ${'septuagin'} | |||
${8} | ${'octogin'} | |||
${9} | ${'nonagin'} | |||
`('on $tenThousands in ten thousands place', ({ tenThousands, tenThousandsName, }) => { | |||
test.each` | |||
thousands | display | name | |||
${0} | ${hundredThousands + '' + tenThousands + '0000'} | ${hundredThousandsName + tenThousandsName + 'milliati'} | |||
${1000} | ${hundredThousands + '' + tenThousands + '1000'} | ${hundredThousandsName + 'un' + tenThousandsName + 'milliati'} | |||
${2000} | ${hundredThousands + '' + tenThousands + '2000'} | ${hundredThousandsName + 'duo' + tenThousandsName + 'milliati'} | |||
${3000} | ${hundredThousands + '' + tenThousands + '3000'} | ${hundredThousandsName + 'tre' + tenThousandsName + 'milliati'} | |||
${4000} | ${hundredThousands + '' + tenThousands + '4000'} | ${hundredThousandsName + 'quattuor' + tenThousandsName + 'milliati'} | |||
${5000} | ${hundredThousands + '' + tenThousands + '5000'} | ${hundredThousandsName + 'quin' + tenThousandsName + 'milliati'} | |||
${6000} | ${hundredThousands + '' + tenThousands + '6000'} | ${hundredThousandsName + 'sex' + tenThousandsName + 'milliati'} | |||
${7000} | ${hundredThousands + '' + tenThousands + '7000'} | ${hundredThousandsName + 'septen' + tenThousandsName + 'milliati'} | |||
${8000} | ${hundredThousands + '' + tenThousands + '8000'} | ${hundredThousandsName + 'octo' + tenThousandsName + 'milliati'} | |||
${9000} | ${hundredThousands + '' + tenThousands + '9000'} | ${hundredThousandsName + 'novem' + tenThousandsName + 'milliati'} | |||
`(`should return "$name" for $display`, ({ thousands, name, }) => { | |||
const kiloHundreds = ( | |||
hundredThousands * 1000 | |||
+ tenThousands * 100 | |||
+ thousands / 100 | |||
) | |||
expect(combiningPrefix( | |||
kiloHundreds, | |||
0, | |||
0, | |||
)).toBe(name) | |||
}) | |||
}) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'1000000'} | ${'milliamilliati'} | |||
${2} | ${'2000000'} | ${'duomilliamilliati'} | |||
${3} | ${'3000000'} | ${'tremilliamilliati'} | |||
${4} | ${'4000000'} | ${'quattuormilliamilliati'} | |||
${5} | ${'5000000'} | ${'quinmilliamilliati'} | |||
${6} | ${'6000000'} | ${'sexmilliamilliati'} | |||
${7} | ${'7000000'} | ${'septenmilliamilliati'} | |||
${8} | ${'8000000'} | ${'octomilliamilliati'} | |||
${9} | ${'9000000'} | ${'novemmilliamilliati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10000, 0, 0)).toBe(name) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'1001000'} | ${'milliamilliaunmilliati'} | |||
${2} | ${'2002000'} | ${'duomilliamilliaduomilliati'} | |||
${3} | ${'3003000'} | ${'tremilliamilliatremilliati'} | |||
${4} | ${'4004000'} | ${'quattuormilliamilliaquattuormilliati'} | |||
${5} | ${'5005000'} | ${'quinmilliamilliaquinmilliati'} | |||
${6} | ${'6006000'} | ${'sexmilliamilliasexmilliati'} | |||
${7} | ${'7007000'} | ${'septenmilliamilliaseptenmilliati'} | |||
${8} | ${'8008000'} | ${'octomilliamilliaoctomilliati'} | |||
${9} | ${'9009000'} | ${'novemmilliamillianovemmilliati'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(combiningPrefix(value * 10010, 0, 0)).toBe(name) | |||
}) | |||
@@ -0,0 +1,109 @@ | |||
import NAMES from '../../names.json' | |||
import ones from './ones' | |||
import tens from './tens' | |||
import hundreds from './hundreds' | |||
interface CombiningPrefix { | |||
( | |||
kiloHundreds: number, | |||
kiloTens: number, | |||
kiloOnes: number, | |||
kiloPower?: number, | |||
): string, | |||
} | |||
const combiningPrefix: CombiningPrefix = ( | |||
kiloHundredsRaw, | |||
kiloTens, | |||
kiloOnes, | |||
kiloPower = 0, | |||
) => { | |||
let kiloHundreds = kiloHundredsRaw | |||
let prefix = '' | |||
const isMillia = kiloHundredsRaw >= 10 | |||
if (isMillia) { | |||
prefix += combiningPrefix( | |||
Math.floor(kiloHundredsRaw / 1000), | |||
Math.floor(kiloHundredsRaw / 100 % 10), | |||
Math.floor(kiloHundredsRaw / 10 % 10), | |||
kiloPower + 1, | |||
) | |||
kiloHundreds = kiloHundredsRaw % 10 | |||
} | |||
const hasHundreds = kiloHundreds > 0 | |||
if (hasHundreds) { | |||
prefix += hundreds(kiloHundreds) | |||
} | |||
if ( | |||
( | |||
kiloPower > 0 | |||
&& ( | |||
( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes > 1 | |||
) | |||
|| ( | |||
( | |||
kiloHundreds > 0 | |||
|| kiloTens > 0 | |||
) | |||
&& kiloOnes > 0 | |||
) | |||
|| ( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 1 | |||
&& prefix.endsWith(NAMES.kiloThousand) | |||
) | |||
) | |||
) | |||
) { | |||
// http://www.isthe.com/chongo/tech/math/number/howhigh.html | |||
// Section: Titanic size numbers < 10^3000003 | |||
prefix += ones( | |||
kiloOnes, | |||
false | |||
) | |||
} | |||
if (kiloPower === 0 && kiloOnes > 0) { | |||
const special = kiloHundreds === 0 && kiloTens === 0 | |||
prefix += ones( | |||
kiloOnes, | |||
special | |||
) | |||
if (special && [5, 6].includes(kiloOnes)) { | |||
prefix += 't' | |||
} | |||
} | |||
if (kiloTens > 0) { | |||
prefix += tens(kiloTens) | |||
} | |||
if (kiloPower > 0) { | |||
if (!( | |||
kiloHundreds === 0 | |||
&& kiloTens === 0 | |||
&& kiloOnes === 0 | |||
)) { | |||
for (let p = 0; p < kiloPower; p += 1) { | |||
prefix += NAMES.kiloThousand | |||
} | |||
} | |||
return prefix | |||
} | |||
if ( | |||
(kiloHundreds === 0 && kiloTens > 1) | |||
|| (kiloHundreds > 0 && kiloTens !== 1) | |||
|| kiloHundredsRaw >= 10 | |||
) { | |||
prefix += 't' | |||
} | |||
return prefix + 'i' | |||
} | |||
export default combiningPrefix |
@@ -0,0 +1,28 @@ | |||
import hundreds from './hundreds' | |||
it('should exist', () => { | |||
expect(hundreds).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof hundreds).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(hundreds).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'100'} | ${'cen'} | |||
${2} | ${'200'} | ${'duocen'} | |||
${3} | ${'300'} | ${'trecen'} | |||
${4} | ${'400'} | ${'quadringen'} | |||
${5} | ${'500'} | ${'quingen'} | |||
${6} | ${'600'} | ${'sescen'} | |||
${7} | ${'700'} | ${'septingen'} | |||
${8} | ${'800'} | ${'octingen'} | |||
${9} | ${'900'} | ${'nongen'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(hundreds(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Hundreds { | |||
(kiloHundreds: number): string, | |||
} | |||
const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds] | |||
export default hundreds |
@@ -0,0 +1,49 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(ones).toHaveLength(2) | |||
}) | |||
describe('on ordinary units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'un'} | |||
${2} | ${'2'} | ${'duo'} | |||
${3} | ${'3'} | ${'tre'} | |||
${4} | ${'4'} | ${'quattuor'} | |||
${5} | ${'5'} | ${'quin'} | |||
${6} | ${'6'} | ${'sex'} | |||
${7} | ${'7'} | ${'septen'} | |||
${8} | ${'8'} | ${'octo'} | |||
${9} | ${'9'} | ${'novem'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, false)).toBe(name) | |||
}) | |||
}) | |||
describe('on special units', () => { | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${''} | |||
${1} | ${'1'} | ${'m'} | |||
${2} | ${'2'} | ${'b'} | |||
${3} | ${'3'} | ${'tr'} | |||
${4} | ${'4'} | ${'quadr'} | |||
${5} | ${'5'} | ${'quin'} | |||
${6} | ${'6'} | ${'sex'} | |||
${7} | ${'7'} | ${'sept'} | |||
${8} | ${'8'} | ${'oct'} | |||
${9} | ${'9'} | ${'non'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value, true)).toBe(name) | |||
}) | |||
}) |
@@ -0,0 +1,13 @@ | |||
import NAMES from '../../names.json' | |||
interface Ones { | |||
(kiloOnes: number, special: boolean): string, | |||
} | |||
const ones: Ones = (kiloOnes, special = false) => ( | |||
special | |||
? NAMES.kiloSpecialUnits[kiloOnes] | |||
: NAMES.kiloUnits[kiloOnes] | |||
) | |||
export default ones |
@@ -0,0 +1,28 @@ | |||
import tens from './tens' | |||
it('should exist', () => { | |||
expect(tens).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tens).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tens).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'dec'} | |||
${2} | ${'20'} | ${'vigin'} | |||
${3} | ${'30'} | ${'trigin'} | |||
${4} | ${'40'} | ${'quadragin'} | |||
${5} | ${'50'} | ${'quinquagin'} | |||
${6} | ${'60'} | ${'sexagin'} | |||
${7} | ${'70'} | ${'septuagin'} | |||
${8} | ${'80'} | ${'octogin'} | |||
${9} | ${'90'} | ${'nonagin'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tens(value)).toBe(name) | |||
}) |
@@ -0,0 +1,9 @@ | |||
import NAMES from '../../names.json' | |||
interface Tens { | |||
(kiloTens: number): string, | |||
} | |||
const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens] | |||
export default tens |
@@ -0,0 +1,30 @@ | |||
import ones from './ones' | |||
it('should exist', () => { | |||
expect(ones).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof ones).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(ones).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'0'} | ${'zero'} | |||
${1} | ${'1'} | ${'one'} | |||
${2} | ${'2'} | ${'two'} | |||
${3} | ${'3'} | ${'three'} | |||
${4} | ${'4'} | ${'four'} | |||
${5} | ${'5'} | ${'five'} | |||
${6} | ${'6'} | ${'six'} | |||
${7} | ${'7'} | ${'seven'} | |||
${8} | ${'8'} | ${'eight'} | |||
${9} | ${'9'} | ${'nine'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(ones(value)).toBe(name) | |||
}) | |||
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface Ones { | |||
(x1: number): string | |||
} | |||
/** | |||
* Get the name of some number in the ones place. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number in the ones place. | |||
*/ | |||
const ones: Ones = (x1) => NAMES.units[x1] | |||
export default ones |
@@ -0,0 +1,29 @@ | |||
import tenPlus from './tenPlus' | |||
it('should exist', () => { | |||
expect(tenPlus).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenPlus).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenPlus).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${0} | ${'10'} | ${'ten'} | |||
${1} | ${'11'} | ${'eleven'} | |||
${2} | ${'12'} | ${'twelve'} | |||
${3} | ${'13'} | ${'thirteen'} | |||
${4} | ${'14'} | ${'fourteen'} | |||
${5} | ${'15'} | ${'fifteen'} | |||
${6} | ${'16'} | ${'sixteen'} | |||
${7} | ${'17'} | ${'seventeen'} | |||
${8} | ${'18'} | ${'eighteen'} | |||
${9} | ${'19'} | ${'nineteen'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenPlus(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenPlus { | |||
(ones: number): string | |||
} | |||
/** | |||
* Get the name of some number plus ten. | |||
* @param {number} x1 - The number in the ones place. | |||
* @returns {string} The name of the number plus ten. | |||
*/ | |||
const tenPlus: TenPlus = (x1) => NAMES.tenPlus[x1] | |||
export default tenPlus |
@@ -0,0 +1,28 @@ | |||
import tenTimes from './tenTimes' | |||
it('should exist', () => { | |||
expect(tenTimes).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof tenTimes).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(tenTimes).toHaveLength(1) | |||
}) | |||
test.each` | |||
value | display | name | |||
${1} | ${'10'} | ${'ten'} | |||
${2} | ${'20'} | ${'twenty'} | |||
${3} | ${'30'} | ${'thirty'} | |||
${4} | ${'40'} | ${'forty'} | |||
${5} | ${'50'} | ${'fifty'} | |||
${6} | ${'60'} | ${'sixty'} | |||
${7} | ${'70'} | ${'seventy'} | |||
${8} | ${'80'} | ${'eighty'} | |||
${9} | ${'90'} | ${'ninety'} | |||
`('should return "$name" on $display', ({ value, name, }) => { | |||
expect(tenTimes(value)).toBe(name) | |||
}) |
@@ -0,0 +1,14 @@ | |||
import NAMES from '../names.json' | |||
interface TenTimes { | |||
(x10: number): string | |||
} | |||
/** | |||
* Get the name of some number in the tens place. | |||
* @param {number} x10 - The number in the tens place. | |||
* @returns {string} The name of the number in the tens place. | |||
*/ | |||
const tenTimes: TenTimes = (x10) => NAMES.tenTimes[x10] | |||
export default tenTimes |
@@ -1,15 +1,15 @@ | |||
import getHundredName from './getHundredName' | |||
import tensFn from './tens' | |||
it('should exist', () => { | |||
expect(getHundredName).toBeDefined() | |||
expect(tensFn).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getHundredName).toBe('function') | |||
expect(typeof tensFn).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(getHundredName).toHaveLength(2) | |||
expect(tensFn).toHaveLength(2) | |||
}) | |||
describe('on 0 in tens place', () => { | |||
@@ -26,7 +26,7 @@ describe('on 0 in tens place', () => { | |||
${8} | ${'eight'} | |||
${9} | ${'nine'} | |||
`(`should return "$onesName" for $ones`, ({ ones, onesName, }) => { | |||
expect(getHundredName(0, ones)).toBe(onesName) | |||
expect(tensFn(0, ones)).toBe(onesName) | |||
}) | |||
}) | |||
@@ -44,38 +44,37 @@ describe('on 1 in tens place', () => { | |||
${8} | ${'eighteen'} | |||
${9} | ${'nineteen'} | |||
`(`should return "$tenPlusName" for 1$ones`, ({ ones, tenPlusName, }) => { | |||
expect(getHundredName(1, ones)).toBe(tenPlusName) | |||
expect(tensFn(1, ones)).toBe(tenPlusName) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${2} | ${'twenty'} | |||
${3} | ${'thirty'} | |||
${4} | ${'forty'} | |||
${5} | ${'fifty'} | |||
${6} | ${'sixty'} | |||
${7} | ${'seventy'} | |||
${8} | ${'eighty'} | |||
${9} | ${'ninety'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
tens | tensName | |||
${2} | ${'twenty'} | |||
${3} | ${'thirty'} | |||
${4} | ${'forty'} | |||
${5} | ${'fifty'} | |||
${6} | ${'sixty'} | |||
${7} | ${'seventy'} | |||
${8} | ${'eighty'} | |||
${9} | ${'ninety'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${' one'} | |||
${2} | ${' two'} | |||
${3} | ${' three'} | |||
${4} | ${' four'} | |||
${5} | ${' five'} | |||
${6} | ${' six'} | |||
${7} | ${' seven'} | |||
${8} | ${' eight'} | |||
${9} | ${' nine'} | |||
`(`should return "${tensName}$onesName" for ${tens}$ones`, ({ ones, onesName, }) => { | |||
expect(getHundredName(tens, ones)).toBe([ | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${' one'} | |||
${2} | ${' two'} | |||
${3} | ${' three'} | |||
${4} | ${' four'} | |||
${5} | ${' five'} | |||
${6} | ${' six'} | |||
${7} | ${' seven'} | |||
${8} | ${' eight'} | |||
${9} | ${' nine'} | |||
`(`should return "${tensName}$onesName" for ${tens}$ones`, ({ ones, onesName, }) => { | |||
expect(tensFn(tens, ones)).toBe([ | |||
tensName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) | |||
@@ -0,0 +1,33 @@ | |||
import ones from '../base/ones' | |||
import tenPlus from '../base/tenPlus' | |||
import getBaseTenTimesName from '../base/tenTimes' | |||
interface Tens { | |||
(x10: number, x1: number): string, | |||
} | |||
const tens: Tens = (x10, x1) => { | |||
switch (x10) { | |||
case 0: | |||
return ones(x1) | |||
case 1: | |||
if (x1 > 0) { | |||
return tenPlus(x1) | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
return ( | |||
x1 > 0 | |||
? [ | |||
getBaseTenTimesName(x10), | |||
ones(x1), | |||
] | |||
.join(' ') | |||
: getBaseTenTimesName(x10) | |||
) | |||
} | |||
export default tens |
@@ -0,0 +1,100 @@ | |||
import getKiloCount from './getKiloCount' | |||
it('should exist', () => { | |||
expect(getKiloCount).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getKiloCount).toBe('function') | |||
}) | |||
it('should accept 3 arguments', () => { | |||
expect(getKiloCount).toHaveLength(3) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'one hundred'} | |||
${2} | ${'two hundred'} | |||
${3} | ${'three hundred'} | |||
${4} | ${'four hundred'} | |||
${5} | ${'five hundred'} | |||
${6} | ${'six hundred'} | |||
${7} | ${'seven hundred'} | |||
${8} | ${'eight hundred'} | |||
${9} | ${'nine hundred'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${' one'} | |||
${2} | ${' two'} | |||
${3} | ${' three'} | |||
${4} | ${' four'} | |||
${5} | ${' five'} | |||
${6} | ${' six'} | |||
${7} | ${' seven'} | |||
${8} | ${' eight'} | |||
${9} | ${' nine'} | |||
`(`should return "${hundredsName}$onesName" for ${hundreds}0$ones`, ({ ones, onesName, }) => { | |||
expect(getKiloCount(hundreds, 0, ones)).toBe([ | |||
hundredsName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) | |||
describe('on 1 in tens place', () => { | |||
test.each` | |||
ones | tenPlusName | |||
${0} | ${' ten'} | |||
${1} | ${' eleven'} | |||
${2} | ${' twelve'} | |||
${3} | ${' thirteen'} | |||
${4} | ${' fourteen'} | |||
${5} | ${' fifteen'} | |||
${6} | ${' sixteen'} | |||
${7} | ${' seventeen'} | |||
${8} | ${' eighteen'} | |||
${9} | ${' nineteen'} | |||
`(`should return "${hundredsName}$tenPlusName" for ${hundreds}1$ones`, ({ ones, tenPlusName, }) => { | |||
expect(getKiloCount(hundreds, 1, ones)).toBe([ | |||
hundredsName, | |||
tenPlusName | |||
].join('')) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${2} | ${' twenty'} | |||
${3} | ${' thirty'} | |||
${4} | ${' forty'} | |||
${5} | ${' fifty'} | |||
${6} | ${' sixty'} | |||
${7} | ${' seventy'} | |||
${8} | ${' eighty'} | |||
${9} | ${' ninety'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${' one'} | |||
${2} | ${' two'} | |||
${3} | ${' three'} | |||
${4} | ${' four'} | |||
${5} | ${' five'} | |||
${6} | ${' six'} | |||
${7} | ${' seven'} | |||
${8} | ${' eight'} | |||
${9} | ${' nine'} | |||
`(`should return "${hundredsName}${tensName}$onesName" for ${hundreds}${tens}$ones`, ({ ones, onesName, }) => { | |||
expect(getKiloCount(hundreds, tens, ones)).toBe([ | |||
hundredsName, | |||
tensName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) | |||
}) |
@@ -0,0 +1,24 @@ | |||
import { GetKiloCount, } from '../../common/NumberSystem' | |||
import constructTens from './construct/tens' | |||
import hundredTimes from './base/hundredTimes' | |||
const getKiloCount: GetKiloCount = ( | |||
x100, | |||
x10, | |||
x1 | |||
) => { | |||
if (x100 < 1) { | |||
return constructTens(x10, x1) | |||
} | |||
if (x10 === 0 && x1 === 0) { | |||
return hundredTimes(x100) | |||
} | |||
return [ | |||
hundredTimes(x100), | |||
constructTens(x10, x1), | |||
] | |||
.join(' ') | |||
} | |||
export default getKiloCount |
@@ -0,0 +1,129 @@ | |||
import getKiloName from './getLongKiloName' | |||
it('should exist', () => { | |||
expect(getKiloName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getKiloName).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(getKiloName).toHaveLength(1) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${0} | ${''} | |||
${1} | ${'thousand'} | |||
${2} | ${'million'} | |||
${3} | ${'thousand million'} | |||
${4} | ${'billion'} | |||
${5} | ${'thousand billion'} | |||
${6} | ${'trillion'} | |||
${7} | ${'thousand trillion'} | |||
${8} | ${'quadrillion'} | |||
${9} | ${'thousand quadrillion'} | |||
${10} | ${'quintillion'} | |||
${11} | ${'thousand quintillion'} | |||
${12} | ${'sextillion'} | |||
${13} | ${'thousand sextillion'} | |||
${14} | ${'septillion'} | |||
${15} | ${'thousand septillion'} | |||
${16} | ${'octillion'} | |||
${17} | ${'thousand octillion'} | |||
${18} | ${'nonillion'} | |||
${19} | ${'thousand nonillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${20} | ${'decillion'} | |||
${40} | ${'vigintillion'} | |||
${60} | ${'trigintillion'} | |||
${80} | ${'quadragintillion'} | |||
${100} | ${'quinquagintillion'} | |||
${120} | ${'sexagintillion'} | |||
${140} | ${'septuagintillion'} | |||
${160} | ${'octogintillion'} | |||
${180} | ${'nonagintillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${200} | ${'centillion'} | |||
${400} | ${'duocentillion'} | |||
${600} | ${'trecentillion'} | |||
${800} | ${'quadringentillion'} | |||
${1000} | ${'quingentillion'} | |||
${1200} | ${'sescentillion'} | |||
${1400} | ${'septingentillion'} | |||
${1600} | ${'octingentillion'} | |||
${1800} | ${'nongentillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${2000} | ${'milliatillion'} | |||
${4000} | ${'duomilliatillion'} | |||
${6000} | ${'tremilliatillion'} | |||
${8000} | ${'quattuormilliatillion'} | |||
${10000} | ${'quinmilliatillion'} | |||
${12000} | ${'sexmilliatillion'} | |||
${14000} | ${'septenmilliatillion'} | |||
${16000} | ${'octomilliatillion'} | |||
${18000} | ${'novemmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${20000} | ${'decmilliatillion'} | |||
${40000} | ${'viginmilliatillion'} | |||
${60000} | ${'triginmilliatillion'} | |||
${80000} | ${'quadraginmilliatillion'} | |||
${100000} | ${'quinquaginmilliatillion'} | |||
${120000} | ${'sexaginmilliatillion'} | |||
${140000} | ${'septuaginmilliatillion'} | |||
${160000} | ${'octoginmilliatillion'} | |||
${180000} | ${'nonaginmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${200000} | ${'cenmilliatillion'} | |||
${400000} | ${'duocenmilliatillion'} | |||
${600000} | ${'trecenmilliatillion'} | |||
${800000} | ${'quadringenmilliatillion'} | |||
${1000000} | ${'quingenmilliatillion'} | |||
${1200000} | ${'sescenmilliatillion'} | |||
${1400000} | ${'septingenmilliatillion'} | |||
${1600000} | ${'octingenmilliatillion'} | |||
${1800000} | ${'nongenmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${2000000} | ${'milliamilliatillion'} | |||
${4000000} | ${'duomilliamilliatillion'} | |||
${6000000} | ${'tremilliamilliatillion'} | |||
${8000000} | ${'quattuormilliamilliatillion'} | |||
${10000000} | ${'quinmilliamilliatillion'} | |||
${12000000} | ${'sexmilliamilliatillion'} | |||
${14000000} | ${'septenmilliamilliatillion'} | |||
${16000000} | ${'octomilliamilliatillion'} | |||
${18000000} | ${'novemmilliamilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) |
@@ -0,0 +1,29 @@ | |||
import { GetKiloName, } from '../../common/NumberSystem' | |||
import NAMES from './names.json' | |||
import getKiloCombiningPrefix from './base/kilo/combiningPrefix' | |||
const getLongKiloName: GetKiloName = thousandPower => { | |||
if (thousandPower === 0) { | |||
return '' | |||
} | |||
if (thousandPower === 1) { | |||
return NAMES.thousand | |||
} | |||
const kilo = thousandPower | |||
const kiloHundreds = Math.floor(kilo / 2 / 100) | |||
const kiloTens = Math.floor(kilo / 2 / 10 % 10) | |||
const kiloOnes = Math.floor(kilo / 2 % 10) | |||
const baseKiloName = getKiloCombiningPrefix( | |||
kiloHundreds, | |||
kiloTens, | |||
kiloOnes | |||
) + NAMES.kiloEvenSuffix | |||
return ( | |||
thousandPower % 2 === 0 | |||
? baseKiloName | |||
: NAMES.thousand + ' ' + baseKiloName | |||
) | |||
} | |||
export default getLongKiloName |
@@ -0,0 +1,120 @@ | |||
import getKiloName from './getShortKiloName' | |||
it('should exist', () => { | |||
expect(getKiloName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getKiloName).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(getKiloName).toHaveLength(1) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${0} | ${''} | |||
${1} | ${'thousand'} | |||
${2} | ${'million'} | |||
${3} | ${'billion'} | |||
${4} | ${'trillion'} | |||
${5} | ${'quadrillion'} | |||
${6} | ${'quintillion'} | |||
${7} | ${'sextillion'} | |||
${8} | ${'septillion'} | |||
${9} | ${'octillion'} | |||
${10} | ${'nonillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${11} | ${'decillion'} | |||
${21} | ${'vigintillion'} | |||
${31} | ${'trigintillion'} | |||
${41} | ${'quadragintillion'} | |||
${51} | ${'quinquagintillion'} | |||
${61} | ${'sexagintillion'} | |||
${71} | ${'septuagintillion'} | |||
${81} | ${'octogintillion'} | |||
${91} | ${'nonagintillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${101} | ${'centillion'} | |||
${201} | ${'duocentillion'} | |||
${301} | ${'trecentillion'} | |||
${401} | ${'quadringentillion'} | |||
${501} | ${'quingentillion'} | |||
${601} | ${'sescentillion'} | |||
${701} | ${'septingentillion'} | |||
${801} | ${'octingentillion'} | |||
${901} | ${'nongentillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${1001} | ${'milliatillion'} | |||
${2001} | ${'duomilliatillion'} | |||
${3001} | ${'tremilliatillion'} | |||
${4001} | ${'quattuormilliatillion'} | |||
${5001} | ${'quinmilliatillion'} | |||
${6001} | ${'sexmilliatillion'} | |||
${7001} | ${'septenmilliatillion'} | |||
${8001} | ${'octomilliatillion'} | |||
${9001} | ${'novemmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${10001} | ${'decmilliatillion'} | |||
${20001} | ${'viginmilliatillion'} | |||
${30001} | ${'triginmilliatillion'} | |||
${40001} | ${'quadraginmilliatillion'} | |||
${50001} | ${'quinquaginmilliatillion'} | |||
${60001} | ${'sexaginmilliatillion'} | |||
${70001} | ${'septuaginmilliatillion'} | |||
${80001} | ${'octoginmilliatillion'} | |||
${90001} | ${'nonaginmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${100001} | ${'cenmilliatillion'} | |||
${200001} | ${'duocenmilliatillion'} | |||
${300001} | ${'trecenmilliatillion'} | |||
${400001} | ${'quadringenmilliatillion'} | |||
${500001} | ${'quingenmilliatillion'} | |||
${600001} | ${'sescenmilliatillion'} | |||
${700001} | ${'septingenmilliatillion'} | |||
${800001} | ${'octingenmilliatillion'} | |||
${900001} | ${'nongenmilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) | |||
test.each` | |||
thousandPower | name | |||
${1000001} | ${'milliamilliatillion'} | |||
${2000001} | ${'duomilliamilliatillion'} | |||
${3000001} | ${'tremilliamilliatillion'} | |||
${4000001} | ${'quattuormilliamilliatillion'} | |||
${5000001} | ${'quinmilliamilliatillion'} | |||
${6000001} | ${'sexmilliamilliatillion'} | |||
${7000001} | ${'septenmilliamilliatillion'} | |||
${8000001} | ${'octomilliamilliatillion'} | |||
${9000001} | ${'novemmilliamilliatillion'} | |||
`('should return "$name" for 1000^$thousandPower', ({ name, thousandPower, }) => { | |||
expect(getKiloName(thousandPower)).toBe(name) | |||
}) |
@@ -0,0 +1,24 @@ | |||
import { GetKiloName, } from '../../common/NumberSystem' | |||
import NAMES from './names.json' | |||
import getKiloCombiningPrefix from './base/kilo/combiningPrefix' | |||
const getKiloName: GetKiloName = thousandPower => { | |||
if (thousandPower === 0) { | |||
return '' | |||
} | |||
if (thousandPower === 1) { | |||
return NAMES.thousand | |||
} | |||
const kilo = thousandPower - 1 | |||
const kiloHundreds = Math.floor(kilo / 100) | |||
const kiloTens = Math.floor(kilo / 10 % 10) | |||
const kiloOnes = Math.floor(kilo % 10) | |||
return getKiloCombiningPrefix( | |||
kiloHundreds, | |||
kiloTens, | |||
kiloOnes | |||
) + NAMES.kiloEvenSuffix | |||
} | |||
export default getKiloName |
@@ -0,0 +1,92 @@ | |||
{ | |||
"units": [ | |||
"zero", | |||
"one", | |||
"two", | |||
"three", | |||
"four", | |||
"five", | |||
"six", | |||
"seven", | |||
"eight", | |||
"nine" | |||
], | |||
"tenPlus": [ | |||
"ten", | |||
"eleven", | |||
"twelve", | |||
"thirteen", | |||
"fourteen", | |||
"fifteen", | |||
"sixteen", | |||
"seventeen", | |||
"eighteen", | |||
"nineteen" | |||
], | |||
"tenTimes": [ | |||
"zero", | |||
"ten", | |||
"twenty", | |||
"thirty", | |||
"forty", | |||
"fifty", | |||
"sixty", | |||
"seventy", | |||
"eighty", | |||
"ninety" | |||
], | |||
"hundred": "hundred", | |||
"thousand": "thousand", | |||
"kiloSpecialUnits": [ | |||
"", | |||
"m", | |||
"b", | |||
"tr", | |||
"quadr", | |||
"quin", | |||
"sex", | |||
"sept", | |||
"oct", | |||
"non" | |||
], | |||
"kiloUnits": [ | |||
"", | |||
"un", | |||
"duo", | |||
"tre", | |||
"quattuor", | |||
"quin", | |||
"sex", | |||
"septen", | |||
"octo", | |||
"novem" | |||
], | |||
"kiloTens": [ | |||
"", | |||
"dec", | |||
"vigin", | |||
"trigin", | |||
"quadragin", | |||
"quinquagin", | |||
"sexagin", | |||
"septuagin", | |||
"octogin", | |||
"nonagin" | |||
], | |||
"kiloHundreds": [ | |||
"", | |||
"cen", | |||
"duocen", | |||
"trecen", | |||
"quadringen", | |||
"quingen", | |||
"sescen", | |||
"septingen", | |||
"octingen", | |||
"nongen" | |||
], | |||
"kiloThousand": "millia", | |||
"kiloEvenSuffix": "llion", | |||
"kiloOddSuffix": "lliard", | |||
"and": "and" | |||
} |
@@ -1,31 +0,0 @@ | |||
import NAMES from './names.json' | |||
interface GetHundredName { | |||
(tens: number, ones: number): string, | |||
} | |||
const getHundredName: GetHundredName = (tens, ones) => { | |||
switch (tens) { | |||
case 0: | |||
return NAMES.base.units[ones] | |||
case 1: | |||
if (ones > 0) { | |||
return NAMES.base.tenPlus[ones] | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
return ( | |||
ones > 0 | |||
? [ | |||
NAMES.base.tens[tens], | |||
NAMES.base.units[ones], | |||
] | |||
.join(' ') | |||
: NAMES.base.tens[tens] | |||
) | |||
} | |||
export default getHundredName |
@@ -1,30 +0,0 @@ | |||
import getThousandName from './getThousandName' | |||
it('should exist', () => { | |||
expect(getThousandName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getThousandName).toBe('function') | |||
}) | |||
it('should accept 3 arguments', () => { | |||
expect(getThousandName).toHaveLength(3) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'one hundred'} | |||
${2} | ${'two hundred'} | |||
${3} | ${'three hundred'} | |||
${4} | ${'four hundred'} | |||
${5} | ${'five hundred'} | |||
${6} | ${'six hundred'} | |||
${7} | ${'seven hundred'} | |||
${8} | ${'eight hundred'} | |||
${9} | ${'nine hundred'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
it(`should return "${hundredsName}" on ${hundreds}00`, () => { | |||
expect(getThousandName(hundreds, 0, 0)).toBe(hundredsName) | |||
}) | |||
}) |
@@ -1,29 +0,0 @@ | |||
import getHundredName from './getHundredName' | |||
import NAMES from './names.json' | |||
interface GetThousandName { | |||
(hundreds: number, tens: number, ones: number): string, | |||
} | |||
const getThousandName: GetThousandName = (hundreds, tens, ones) => { | |||
if (hundreds === 0) { | |||
return getHundredName(tens, ones) | |||
} | |||
if (tens === 0 && ones === 0) { | |||
return [ | |||
NAMES.base.units[hundreds], | |||
NAMES.hundred, | |||
] | |||
.join(' ') | |||
} | |||
return [ | |||
NAMES.base.units[hundreds], | |||
NAMES.hundred, | |||
getHundredName(tens, ones), | |||
] | |||
.join(' ') | |||
} | |||
export default getThousandName |
@@ -1,32 +0,0 @@ | |||
{ | |||
"base": { | |||
"units": ["zero" , "one" , "two" , "three" , "four" , "five" , "six" , "seven" , "eight" , "nine" ], | |||
"tenPlus": ["ten" , "eleven" , "twelve" , "thirteen" , "fourteen" , "fifteen" , "sixteen" , "seventeen" , "eighteen" , "nineteen"], | |||
"tens": ["zero" , "ten" , "twenty" , "thirty" , "forty" , "fifty" , "sixty" , "seventy" , "eighty" , "ninety" ] | |||
}, | |||
"prefix": { | |||
"units": { | |||
"formal": ["" , "un" , "duo" , "tre" , "quattuor" , "quin" , "sex" , "septen" , "octo" , "novem" ], | |||
"informal": ["" , "un" , "do" , "tre" , "quattuor" , "quin" , "sex" , "septen" , "octo" , "novem" ] | |||
}, | |||
"tens": { | |||
"formal": ["" , "dec" , "vigin" , "trigin" , "quadragin" , "quinquagin" , "sexagin" , "septuagin" , "octogin" , "nonagin" ], | |||
"informal": ["" , "dec" , "vigin" , "trigin" , "quadragin" , "quinquagin" , "sexagin" , "septuagin" , "octogin" , "nonagin" ] | |||
}, | |||
"hundreds": { | |||
"formal": ["" , "cen" , "duocen" , "trecen" , "quadringen" , "quingen" , "sescen" , "septingen" , "octingen" , "nongen" ], | |||
"informal": ["" , "cen" , "ducen" , "trecen" , "quadringen" , "quingen" , "sescen" , "septingen" , "octingen" , "nongen" ] | |||
}, | |||
"special": { | |||
"formal": ["" , "mi" , "bi" , "tri" , "quadri" , "quin" , "sex" , "sept" , "oct" , "non" ], | |||
"informal": ["" , "mi" , "bi" , "tri" , "quadri" , "quin" , "sex" , "sept" , "oct" , "non" ] | |||
} | |||
}, | |||
"hundred": "hundred", | |||
"thousand": "thousand", | |||
"millia": "millia", | |||
"suffix": { | |||
"llion": "llion", | |||
"lliard": "lliard" | |||
} | |||
} |
@@ -0,0 +1,92 @@ | |||
{ | |||
"units": [ | |||
"sero", | |||
"isa", | |||
"dalawa", | |||
"tatlo", | |||
"apat", | |||
"lima", | |||
"anim", | |||
"pito", | |||
"walo", | |||
"siyam" | |||
], | |||
"tenPlus": [ | |||
"sampu", | |||
"labing-isa", | |||
"labindalawa", | |||
"labintatlo", | |||
"labing-apat", | |||
"labinlima", | |||
"labing-anim", | |||
"labimpito", | |||
"labingwalo", | |||
"labinsiyam" | |||
], | |||
"tenTimes": [ | |||
"sero", | |||
"sampu", | |||
"dalawampu", | |||
"tatlumpu", | |||
"apatnapu", | |||
"limampu", | |||
"animnapu", | |||
"pitumpu", | |||
"walumpu", | |||
"siyamnapu" | |||
], | |||
"hundred": "daan", | |||
"thousand": "libo", | |||
"kiloSpecialUnits": [ | |||
"", | |||
"mi", | |||
"bi", | |||
"tri", | |||
"kuwadri", | |||
"kuwin", | |||
"seks", | |||
"sept", | |||
"okt", | |||
"non" | |||
], | |||
"kiloUnits": [ | |||
"", | |||
"un", | |||
"duo", | |||
"tre", | |||
"kuwatuwor", | |||
"kuwin", | |||
"seks", | |||
"septen", | |||
"okto", | |||
"nobem" | |||
], | |||
"kiloTens": [ | |||
"", | |||
"des", | |||
"bigin", | |||
"trigin", | |||
"kuwadragin", | |||
"kuwinkuwagin", | |||
"seksagin", | |||
"septuwagin", | |||
"oktogin", | |||
"nonagin" | |||
], | |||
"kiloHundreds": [ | |||
"", | |||
"sen", | |||
"duosen", | |||
"tresen", | |||
"kuwadringen", | |||
"kuwingen", | |||
"sesen", | |||
"septingen", | |||
"oktingen", | |||
"nongen" | |||
], | |||
"kiloThousand": "milya", | |||
"kiloEvenSuffix": "lyon", | |||
"kiloOddSuffix": "lyard", | |||
"and": "at" | |||
} |
@@ -1,28 +0,0 @@ | |||
import getBaseHundredUnit from './getBaseHundredUnit' | |||
it('should exist', () => { | |||
expect(getBaseHundredUnit).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getBaseHundredUnit).toBe('function') | |||
}) | |||
it('should accept 3 arguments', () => { | |||
expect(getBaseHundredUnit).toHaveLength(1) | |||
}) | |||
test.each` | |||
hundreds | hundredsName | hundredsDisplay | |||
${1} | ${'sandaan'} | ${100} | |||
${2} | ${'dalawandaan'} | ${200} | |||
${3} | ${'tatlongdaan'} | ${300} | |||
${4} | ${'apatnaraan'} | ${400} | |||
${5} | ${'limandaan'} | ${500} | |||
${6} | ${'animnaraan'} | ${600} | |||
${7} | ${'pitongdaan'} | ${700} | |||
${8} | ${'walongdaan'} | ${800} | |||
${9} | ${'siyamnaraan'} | ${900} | |||
`('should return "$hundredsName" on $hundredsDisplay', ({ hundreds, hundredsName, }) => { | |||
expect(getBaseHundredUnit(hundreds)).toBe(hundredsName) | |||
}) |
@@ -1,28 +0,0 @@ | |||
import NAMES from './names.json' | |||
interface GetBaseHundredUnit { | |||
(hundreds: number): string | |||
} | |||
const getBaseHundredUnit: GetBaseHundredUnit = hundreds => { | |||
let hundredsUnit = NAMES.base.units[hundreds] | |||
const hundredsSuffix = NAMES.hundred | |||
const unitLastCharacter = hundredsUnit.slice(-1) | |||
switch (unitLastCharacter) { | |||
case 't': | |||
case 'm': | |||
return hundredsUnit + 'nar' + hundredsSuffix.slice(1) | |||
case 'a': | |||
if (hundredsUnit.startsWith('i')) { | |||
hundredsUnit = hundredsUnit.slice(1) | |||
} | |||
return hundredsUnit + 'n' + hundredsSuffix | |||
case 'o': | |||
default: | |||
break | |||
} | |||
return hundredsUnit + 'ng' + hundredsSuffix | |||
} | |||
export default getBaseHundredUnit |
@@ -1,30 +0,0 @@ | |||
import NAMES from './names.json' | |||
interface GetBaseTenUnit { | |||
(tens: number): string | |||
} | |||
const getBaseTenUnit: GetBaseTenUnit = (tens) => { | |||
let tenUnit = NAMES.base.units[tens] | |||
const tenSuffix = NAMES.ten | |||
const unitLastCharacter = tenUnit.slice(-1) | |||
switch (unitLastCharacter) { | |||
case 't': | |||
case 'm': | |||
return tenUnit + 'na' + tenSuffix | |||
case 'o': | |||
tenUnit = tenUnit.slice(0, -1) + 'u' | |||
break | |||
case 'a': | |||
if (tenUnit.startsWith('i')) { | |||
tenUnit = tenUnit.slice(1) | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
return tenUnit + 'm' + tenSuffix | |||
} | |||
export default getBaseTenUnit |
@@ -1,62 +0,0 @@ | |||
import getHundredName from './getHundredName' | |||
it('should exist', () => { | |||
expect(getHundredName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getHundredName).toBe('function') | |||
}) | |||
it('should accept 2 arguments', () => { | |||
expect(getHundredName).toHaveLength(2) | |||
}) | |||
describe('on 0 in tens place', () => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${'sero'} | |||
${1} | ${'isa'} | |||
${2} | ${'dalawa'} | |||
${3} | ${'tatlo'} | |||
${4} | ${'apat'} | |||
${5} | ${'lima'} | |||
${6} | ${'anim'} | |||
${7} | ${'pito'} | |||
${8} | ${'walo'} | |||
${9} | ${'siyam'} | |||
`(`should return "$onesName" for $ones`, ({ ones, onesName, }) => { | |||
expect(getHundredName(0, ones)).toBe(onesName) | |||
}) | |||
}) | |||
describe.each` | |||
tens | tensName | |||
${2} | ${'dalawampu'} | |||
${3} | ${'tatlumpu'} | |||
${4} | ${'apatnapu'} | |||
${5} | ${'limampu'} | |||
${6} | ${'animnapu'} | |||
${7} | ${'pitumpu'} | |||
${8} | ${'walumpu'} | |||
${9} | ${'siyamnapu'} | |||
`('on $tens in tens place', ({ tens, tensName, }) => { | |||
test.each` | |||
ones | onesName | |||
${0} | ${''} | |||
${1} | ${"'t isa"} | |||
${2} | ${"'t dalawa"} | |||
${3} | ${"'t tatlo"} | |||
${4} | ${"'t apat"} | |||
${5} | ${"'t lima"} | |||
${6} | ${"'t anim"} | |||
${7} | ${"'t pito"} | |||
${8} | ${"'t walo"} | |||
${9} | ${"'t siyam"} | |||
`(`should return "${tensName}$onesName" for ${tens}$ones`, ({ ones, onesName, }) => { | |||
expect(getHundredName(tens, ones)).toBe([ | |||
tensName, | |||
onesName | |||
].join('')) | |||
}) | |||
}) |
@@ -1,34 +0,0 @@ | |||
import NAMES from './names.json' | |||
import getTenPlusName from './getTenPlusName' | |||
import getBaseTenUnit from './getBaseTenUnit' | |||
interface GetHundredName { | |||
(tens: number, ones: number): string, | |||
} | |||
const getHundredName: GetHundredName = (tens, ones) => { | |||
switch (tens) { | |||
case 0: | |||
return NAMES.base.units[ones] | |||
case 1: | |||
if (ones > 0) { | |||
return getTenPlusName(ones) | |||
} | |||
break | |||
default: | |||
break | |||
} | |||
if (ones > 0) { | |||
return [ | |||
getBaseTenUnit(tens), | |||
"'", | |||
NAMES.and.slice(1), | |||
' ', | |||
NAMES.base.units[ones], | |||
].join('') | |||
} | |||
return getBaseTenUnit(tens) | |||
} | |||
export default getHundredName |
@@ -1,31 +0,0 @@ | |||
import getTenPlusName from './getTenPlusName' | |||
it('should exist', () => { | |||
expect(getTenPlusName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getTenPlusName).toBe('function') | |||
}) | |||
it('should accept 1 argument', () => { | |||
expect(getTenPlusName).toHaveLength(1) | |||
}) | |||
describe('on 1 in tens place', () => { | |||
test.each` | |||
ones | tenPlusName | |||
${0} | ${'sampu'} | |||
${1} | ${'labing-isa'} | |||
${2} | ${'labindalawa'} | |||
${3} | ${'labintatlo'} | |||
${4} | ${'labing-apat'} | |||
${5} | ${'labinlima'} | |||
${6} | ${'labing-anim'} | |||
${7} | ${'labimpito'} | |||
${8} | ${'labingwalo'} | |||
${9} | ${'labinsiyam'} | |||
`(`should return "$tenPlusName" for 1$ones`, ({ ones, tenPlusName, }) => { | |||
expect(getTenPlusName(ones)).toBe(tenPlusName) | |||
}) | |||
}) |
@@ -1,34 +0,0 @@ | |||
import NAMES from './names.json' | |||
interface GetTenPlusName { | |||
(ones: number): string, | |||
} | |||
const getTenPlusName: GetTenPlusName = (ones) => { | |||
if (ones === 0) { | |||
return NAMES.base.tens[1] | |||
} | |||
const unit = NAMES.base.units[ones] | |||
const tenPlusPrefix = NAMES.tenPlus | |||
const unitFirstCharacter = unit.charAt(0) | |||
switch (unitFirstCharacter) { | |||
case 'i': | |||
case 'a': | |||
return tenPlusPrefix + 'ng-' + unit | |||
case 'd': | |||
case 't': | |||
case 'l': | |||
case 's': | |||
return tenPlusPrefix + 'n' + unit | |||
case 'p': | |||
return tenPlusPrefix + 'm' + unit | |||
default: | |||
break | |||
} | |||
return tenPlusPrefix + 'ng' + unit | |||
} | |||
export default getTenPlusName |
@@ -1,41 +0,0 @@ | |||
import getThousandName from './getThousandName' | |||
it('should exist', () => { | |||
expect(getThousandName).toBeDefined() | |||
}) | |||
it('should be a callable', () => { | |||
expect(typeof getThousandName).toBe('function') | |||
}) | |||
it('should accept 3 arguments', () => { | |||
expect(getThousandName).toHaveLength(3) | |||
}) | |||
describe.each` | |||
hundreds | hundredsName | |||
${1} | ${'sandaan'} | |||
${2} | ${'dalawandaan'} | |||
${3} | ${'tatlongdaan'} | |||
${4} | ${'apatnaraan'} | |||
${5} | ${'limandaan'} | |||
${6} | ${'animnaraan'} | |||
${7} | ${'pitongdaan'} | |||
${8} | ${'walongdaan'} | |||
${9} | ${'siyamnaraan'} | |||
`('on $hundreds in hundreds place', ({ hundreds, hundredsName, }) => { | |||
test.each` | |||
ones | onesName | |||
${1} | ${'isa'} | |||
${2} | ${'dalawa'} | |||
${3} | ${'tatlo'} | |||
${4} | ${'apat'} | |||
${5} | ${'lima'} | |||
${6} | ${'anim'} | |||
${7} | ${'pito'} | |||
${8} | ${'walo'} | |||
${9} | ${'siyam'} | |||
`(`should return "${hundredsName} at $onesName" on ${hundreds}0$ones`, ({ ones, onesName, }) => { | |||
expect(getThousandName(hundreds, 0, ones)).toBe(hundredsName + ' at ' + onesName) | |||
}) | |||
}) |
@@ -1,34 +0,0 @@ | |||
import getHundredName from './getHundredName' | |||
import NAMES from './names.json' | |||
import getBaseHundredUnit from './getBaseHundredUnit' | |||
interface GetThousandName { | |||
(hundreds: number, tens: number, ones: number): string, | |||
} | |||
const getThousandName: GetThousandName = (hundreds, tens, ones) => { | |||
if (hundreds === 0) { | |||
return getHundredName(tens, ones) | |||
} | |||
if (tens === 0 && ones === 0) { | |||
return getBaseHundredUnit(hundreds) | |||
} | |||
if (tens === 0) { | |||
return [ | |||
getBaseHundredUnit(hundreds), | |||
NAMES.and, | |||
NAMES.base.units[ones], | |||
] | |||
.join(' ') | |||
} | |||
return [ | |||
getBaseHundredUnit(hundreds), | |||
getHundredName(tens, ones), | |||
] | |||
.join(' ') | |||
} | |||
export default getThousandName |
@@ -1,180 +0,0 @@ | |||
{ | |||
"base": { | |||
"units": [ | |||
"sero", | |||
"isa", | |||
"dalawa", | |||
"tatlo", | |||
"apat", | |||
"lima", | |||
"anim", | |||
"pito", | |||
"walo", | |||
"siyam" | |||
], | |||
"tenPlus": [ | |||
"sampu", | |||
"labing-isa", | |||
"labindalawa", | |||
"labintatlo", | |||
"labing-apat", | |||
"labinlima", | |||
"labing-anim", | |||
"labimpito", | |||
"labingwalo", | |||
"labinsiyam" | |||
], | |||
"tens": [ | |||
"sero", | |||
"sampu", | |||
"dalawampu", | |||
"tatlumpu", | |||
"apatnapu", | |||
"limampu", | |||
"animnapu", | |||
"pitumpu", | |||
"walumpu", | |||
"siyamnapu" | |||
], | |||
"hundreds": [ | |||
"sero", | |||
"sandaan", | |||
"dalawandaan", | |||
"tatlongdaan", | |||
"apatnaraan", | |||
"limandaan", | |||
"animnaraan", | |||
"pitongdaan", | |||
"walongdaan", | |||
"siyamnaraan" | |||
], | |||
"thousands": [ | |||
"sero", | |||
"sanlibo", | |||
"dalawanlibo", | |||
"tatlonglibo", | |||
"apatnalibo", | |||
"limanlibo", | |||
"animnalibo", | |||
"pitonglibo", | |||
"walonglibo", | |||
"siyamnalibo" | |||
] | |||
}, | |||
"prefix": { | |||
"units": { | |||
"formal": [ | |||
"", | |||
"un", | |||
"duo", | |||
"tre", | |||
"kuwatuwor", | |||
"kuwin", | |||
"seks", | |||
"septen", | |||
"okto", | |||
"nobem" | |||
], | |||
"informal": [ | |||
"", | |||
"un", | |||
"do", | |||
"tre", | |||
"kuwatuwor", | |||
"kuwin", | |||
"seks", | |||
"septen", | |||
"okto", | |||
"nobem" | |||
] | |||
}, | |||
"tens": { | |||
"formal": [ | |||
"", | |||
"des", | |||
"bigin", | |||
"trigin", | |||
"kuwadragin", | |||
"kuwinkuwagin", | |||
"seksagin", | |||
"septuwagin", | |||
"oktogin", | |||
"nonagin" | |||
], | |||
"informal": [ | |||
"", | |||
"des", | |||
"bigin", | |||
"trigin", | |||
"kuwadragin", | |||
"kuwinkuwagin", | |||
"seksagin", | |||
"septuwagin", | |||
"oktogin", | |||
"nonagin" | |||
] | |||
}, | |||
"hundreds": { | |||
"formal": [ | |||
"", | |||
"sen", | |||
"duosen", | |||
"tresen", | |||
"kuwadringen", | |||
"kuwingen", | |||
"sesen", | |||
"septingen", | |||
"oktingen", | |||
"nongen" | |||
], | |||
"informal": [ | |||
"", | |||
"sen", | |||
"dusen", | |||
"tresen", | |||
"kuwadringen", | |||
"kuwingen", | |||
"sesen", | |||
"septingen", | |||
"oktingen", | |||
"nongen" | |||
] | |||
}, | |||
"special": { | |||
"formal": [ | |||
"", | |||
"mi", | |||
"bi", | |||
"tri", | |||
"kuwadri", | |||
"kuwin", | |||
"seks", | |||
"sept", | |||
"okt", | |||
"non" | |||
], | |||
"informal": [ | |||
"", | |||
"mi", | |||
"bi", | |||
"tri", | |||
"kuwadri", | |||
"kuwin", | |||
"seks", | |||
"sept", | |||
"okt", | |||
"non" | |||
] | |||
} | |||
}, | |||
"and": "at", | |||
"ten": "pu", | |||
"hundred": "daan", | |||
"tenPlus": "labi", | |||
"thousand": "libo", | |||
"millia": "milya", | |||
"suffix": { | |||
"llion": "lyon", | |||
"lliard": "lyard" | |||
} | |||
} |