diff --git a/package.json b/package.json index 783c06b..02869c7 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "scripts": { "start": "tsdx watch", "build": "tsdx build", - "test": "tsdx test --verbose", + "test": "tsdx test", "lint": "tsdx lint", "prepare": "tsdx build" }, diff --git a/src/common/NumberSystem.ts b/src/common/NumberSystem.ts new file mode 100644 index 0000000..0aa53ab --- /dev/null +++ b/src/common/NumberSystem.ts @@ -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, + } +} diff --git a/src/common/NumberSystemNameTable.ts b/src/common/NumberSystemNameTable.ts new file mode 100644 index 0000000..63a75dc --- /dev/null +++ b/src/common/NumberSystemNameTable.ts @@ -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, +} diff --git a/src/common/interfaces.ts b/src/common/interfaces.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/systems/de/names.json b/src/systems/de/names.json new file mode 100644 index 0000000..e4d88e6 --- /dev/null +++ b/src/systems/de/names.json @@ -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" +} diff --git a/src/systems/en.ts b/src/systems/en.ts new file mode 100644 index 0000000..55bdba6 --- /dev/null +++ b/src/systems/en.ts @@ -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 diff --git a/src/systems/en/base/hundredTimes.test.ts b/src/systems/en/base/hundredTimes.test.ts new file mode 100644 index 0000000..f2b7d3e --- /dev/null +++ b/src/systems/en/base/hundredTimes.test.ts @@ -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) +}) diff --git a/src/systems/en/base/hundredTimes.ts b/src/systems/en/base/hundredTimes.ts new file mode 100644 index 0000000..e13daf5 --- /dev/null +++ b/src/systems/en/base/hundredTimes.ts @@ -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 diff --git a/src/systems/en/base/kilo/combiningPrefix.test.ts b/src/systems/en/base/kilo/combiningPrefix.test.ts new file mode 100644 index 0000000..53ef7f6 --- /dev/null +++ b/src/systems/en/base/kilo/combiningPrefix.test.ts @@ -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) +}) + diff --git a/src/systems/en/base/kilo/combiningPrefix.ts b/src/systems/en/base/kilo/combiningPrefix.ts new file mode 100644 index 0000000..32c5c96 --- /dev/null +++ b/src/systems/en/base/kilo/combiningPrefix.ts @@ -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 diff --git a/src/systems/en/base/kilo/hundreds.test.ts b/src/systems/en/base/kilo/hundreds.test.ts new file mode 100644 index 0000000..caa97dd --- /dev/null +++ b/src/systems/en/base/kilo/hundreds.test.ts @@ -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) +}) diff --git a/src/systems/en/base/kilo/hundreds.ts b/src/systems/en/base/kilo/hundreds.ts new file mode 100644 index 0000000..7b261d2 --- /dev/null +++ b/src/systems/en/base/kilo/hundreds.ts @@ -0,0 +1,9 @@ +import NAMES from '../../names.json' + +interface Hundreds { + (kiloHundreds: number): string, +} + +const hundreds: Hundreds = (kiloHundreds) => NAMES.kiloHundreds[kiloHundreds] + +export default hundreds diff --git a/src/systems/en/base/kilo/ones.test.ts b/src/systems/en/base/kilo/ones.test.ts new file mode 100644 index 0000000..8cf0aa4 --- /dev/null +++ b/src/systems/en/base/kilo/ones.test.ts @@ -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) + }) +}) diff --git a/src/systems/en/base/kilo/ones.ts b/src/systems/en/base/kilo/ones.ts new file mode 100644 index 0000000..0e6fa8f --- /dev/null +++ b/src/systems/en/base/kilo/ones.ts @@ -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 diff --git a/src/systems/en/base/kilo/tens.test.ts b/src/systems/en/base/kilo/tens.test.ts new file mode 100644 index 0000000..f6984ac --- /dev/null +++ b/src/systems/en/base/kilo/tens.test.ts @@ -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) +}) diff --git a/src/systems/en/base/kilo/tens.ts b/src/systems/en/base/kilo/tens.ts new file mode 100644 index 0000000..bfe97e0 --- /dev/null +++ b/src/systems/en/base/kilo/tens.ts @@ -0,0 +1,9 @@ +import NAMES from '../../names.json' + +interface Tens { + (kiloTens: number): string, +} + +const tens: Tens = (kiloTens) => NAMES.kiloTens[kiloTens] + +export default tens diff --git a/src/systems/en/base/ones.test.ts b/src/systems/en/base/ones.test.ts new file mode 100644 index 0000000..6f722ab --- /dev/null +++ b/src/systems/en/base/ones.test.ts @@ -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) +}) + diff --git a/src/systems/en/base/ones.ts b/src/systems/en/base/ones.ts new file mode 100644 index 0000000..f63ea33 --- /dev/null +++ b/src/systems/en/base/ones.ts @@ -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 diff --git a/src/systems/en/base/tenPlus.test.ts b/src/systems/en/base/tenPlus.test.ts new file mode 100644 index 0000000..a8cf9ca --- /dev/null +++ b/src/systems/en/base/tenPlus.test.ts @@ -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) +}) diff --git a/src/systems/en/base/tenPlus.ts b/src/systems/en/base/tenPlus.ts new file mode 100644 index 0000000..fe87a0d --- /dev/null +++ b/src/systems/en/base/tenPlus.ts @@ -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 diff --git a/src/systems/en/base/tenTimes.test.ts b/src/systems/en/base/tenTimes.test.ts new file mode 100644 index 0000000..fef4f8b --- /dev/null +++ b/src/systems/en/base/tenTimes.test.ts @@ -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) +}) diff --git a/src/systems/en/base/tenTimes.ts b/src/systems/en/base/tenTimes.ts new file mode 100644 index 0000000..7366877 --- /dev/null +++ b/src/systems/en/base/tenTimes.ts @@ -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 diff --git a/src/systems/en/short/getHundredName.test.ts b/src/systems/en/construct/tens.test.ts similarity index 51% rename from src/systems/en/short/getHundredName.test.ts rename to src/systems/en/construct/tens.test.ts index f2441a8..636a52d 100644 --- a/src/systems/en/short/getHundredName.test.ts +++ b/src/systems/en/construct/tens.test.ts @@ -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('')) }) }) - diff --git a/src/systems/en/construct/tens.ts b/src/systems/en/construct/tens.ts new file mode 100644 index 0000000..04e53fc --- /dev/null +++ b/src/systems/en/construct/tens.ts @@ -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 diff --git a/src/systems/en/getKiloCount.test.ts b/src/systems/en/getKiloCount.test.ts new file mode 100644 index 0000000..495cc71 --- /dev/null +++ b/src/systems/en/getKiloCount.test.ts @@ -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('')) + }) + }) +}) diff --git a/src/systems/en/getKiloCount.ts b/src/systems/en/getKiloCount.ts new file mode 100644 index 0000000..c4c84f9 --- /dev/null +++ b/src/systems/en/getKiloCount.ts @@ -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 diff --git a/src/systems/en/getLongKiloName.test.ts b/src/systems/en/getLongKiloName.test.ts new file mode 100644 index 0000000..44d12c7 --- /dev/null +++ b/src/systems/en/getLongKiloName.test.ts @@ -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) +}) diff --git a/src/systems/en/getLongKiloName.ts b/src/systems/en/getLongKiloName.ts new file mode 100644 index 0000000..e4d290e --- /dev/null +++ b/src/systems/en/getLongKiloName.ts @@ -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 diff --git a/src/systems/en/getShortKiloName.test.ts b/src/systems/en/getShortKiloName.test.ts new file mode 100644 index 0000000..1047bd9 --- /dev/null +++ b/src/systems/en/getShortKiloName.test.ts @@ -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) +}) diff --git a/src/systems/en/getShortKiloName.ts b/src/systems/en/getShortKiloName.ts new file mode 100644 index 0000000..2fd635e --- /dev/null +++ b/src/systems/en/getShortKiloName.ts @@ -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 diff --git a/src/systems/en/names.json b/src/systems/en/names.json new file mode 100644 index 0000000..fe5fa34 --- /dev/null +++ b/src/systems/en/names.json @@ -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" +} diff --git a/src/systems/en/short/getHundredName.ts b/src/systems/en/short/getHundredName.ts deleted file mode 100644 index 66725b3..0000000 --- a/src/systems/en/short/getHundredName.ts +++ /dev/null @@ -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 diff --git a/src/systems/en/short/getThousandName.test.ts b/src/systems/en/short/getThousandName.test.ts deleted file mode 100644 index 95b80e3..0000000 --- a/src/systems/en/short/getThousandName.test.ts +++ /dev/null @@ -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) - }) -}) diff --git a/src/systems/en/short/getThousandName.ts b/src/systems/en/short/getThousandName.ts deleted file mode 100644 index 7b129a0..0000000 --- a/src/systems/en/short/getThousandName.ts +++ /dev/null @@ -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 diff --git a/src/systems/en/short/names.json b/src/systems/en/short/names.json deleted file mode 100644 index 0026606..0000000 --- a/src/systems/en/short/names.json +++ /dev/null @@ -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" - } -} diff --git a/src/systems/tl/names.json b/src/systems/tl/names.json new file mode 100644 index 0000000..18d74e6 --- /dev/null +++ b/src/systems/tl/names.json @@ -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" +} diff --git a/src/systems/tl/short/getBaseHundredUnit.test.ts b/src/systems/tl/short/getBaseHundredUnit.test.ts deleted file mode 100644 index aeb542d..0000000 --- a/src/systems/tl/short/getBaseHundredUnit.test.ts +++ /dev/null @@ -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) -}) diff --git a/src/systems/tl/short/getBaseHundredUnit.ts b/src/systems/tl/short/getBaseHundredUnit.ts deleted file mode 100644 index 2cd5b95..0000000 --- a/src/systems/tl/short/getBaseHundredUnit.ts +++ /dev/null @@ -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 diff --git a/src/systems/tl/short/getBaseTenUnit.ts b/src/systems/tl/short/getBaseTenUnit.ts deleted file mode 100644 index 2c4b929..0000000 --- a/src/systems/tl/short/getBaseTenUnit.ts +++ /dev/null @@ -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 diff --git a/src/systems/tl/short/getHundredName.test.ts b/src/systems/tl/short/getHundredName.test.ts deleted file mode 100644 index 9fc48fe..0000000 --- a/src/systems/tl/short/getHundredName.test.ts +++ /dev/null @@ -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('')) - }) -}) diff --git a/src/systems/tl/short/getHundredName.ts b/src/systems/tl/short/getHundredName.ts deleted file mode 100644 index 9102d4d..0000000 --- a/src/systems/tl/short/getHundredName.ts +++ /dev/null @@ -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 diff --git a/src/systems/tl/short/getTenPlusName.test.ts b/src/systems/tl/short/getTenPlusName.test.ts deleted file mode 100644 index caf65ee..0000000 --- a/src/systems/tl/short/getTenPlusName.test.ts +++ /dev/null @@ -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) - }) -}) diff --git a/src/systems/tl/short/getTenPlusName.ts b/src/systems/tl/short/getTenPlusName.ts deleted file mode 100644 index a5a5d10..0000000 --- a/src/systems/tl/short/getTenPlusName.ts +++ /dev/null @@ -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 diff --git a/src/systems/tl/short/getThousandName.test.ts b/src/systems/tl/short/getThousandName.test.ts deleted file mode 100644 index 7115f06..0000000 --- a/src/systems/tl/short/getThousandName.test.ts +++ /dev/null @@ -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) - }) -}) diff --git a/src/systems/tl/short/getThousandName.ts b/src/systems/tl/short/getThousandName.ts deleted file mode 100644 index 48497fb..0000000 --- a/src/systems/tl/short/getThousandName.ts +++ /dev/null @@ -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 diff --git a/src/systems/tl/short/names.json b/src/systems/tl/short/names.json deleted file mode 100644 index 01c68a7..0000000 --- a/src/systems/tl/short/names.json +++ /dev/null @@ -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" - } -}