## DEV Community is a community of 606,348 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

loading...

# Daily Challenge #248 - Chinese Numerals

Create a function that takes a Number as its argument and returns a Chinese numeral string. You don't need to validate the input argument, it will always be a Number in the range [0, 99999] with no decimals.

Simplified Chinese numerals have characters representing each number from 0 to 9 and additional numbers representing larger numbers like 10, 100, 1000, and 10000.

``````0 líng 零
1 yī 一
2 èr 二
3 sān 三
4 sì 四
5 wǔ 五
6 liù 六
7 qī 七
8 bā 八
9 jiǔ 九
10 shí 十
100 bǎi 百
1000 qiān 千
10000 wàn 万
``````

Multiple-digit numbers are constructed by first the digit value (1 to 9) and then the place multiplier (such as 10, 100, 1000), starting with the most significant digit. A special case is made for 10 - 19 where the leading digit value (yī 一) is dropped. Note that this special case is only made for the actual values 10 - 19, not any larger values. Trailing zeros are omitted, but interior zeros are grouped together and indicated by a single 零 character without giving the place multiplier.

10 十
11 十一
18 十八
21 二十一
110 一百一十
123 一百二十三
24681 二万四千六百八十一

### Tests

`to_chinese_numeral(9)`
`to_chinese_numeral(10)`
`to_chinese_numeral(110)`
`to_chinese_numeral(111)`
`to_chinese_numeral(1000)`
`to_chinese_numeral(10000)`

Good luck!

This challenge comes from ConstableBrew on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

## Discussion (4)  SavagePixie • Edited

I didn't quite get what the deal was with the zero, and since there were no examples to show how it worked, I decided to do Japanese numerals, which are basically the same but without the zero. Here's my JavaScript implementation. It could probably be a lot simpler, but oh well.

``````const numerals = {
0: '0',
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九',
}

const units = {
0: '',
1: '十',
2: '百',
3: '千',
4: '万',
}

const toJapaneseNumeral = n => n
.toString()
.split('')
.reverse()
.map((x, i) => numerals[x] + units[i])
.reverse()
.join('')
.replace('一十', '十')
.replace(/0.?/g, '')
`````` Michael Kohl

I didn't quite get what the deal was with the zero

Wikipedia has a decent explanation: "Interior zeroes before the unit position (as in 1002) must be spelt explicitly. The reason for this is that trailing zeroes (as in 1200) are often omitted as shorthand, so ambiguity occurs. One zero is sufficient to resolve the ambiguity. Where the zero is before a digit other than the units digit, the explicit zero is not ambiguous and is therefore optional, but preferred. "

There are a few examples too, but they use traditional instead of simplified characters. Peter Lau

Add more test cases.

``````// 28901 二万八千九百零一
// 28911 二万八千九百一十一
// 20911 二万零九百一十一
// 20901 二万零九百零一
// 20001 二万零一
// 29000 二万九

let numberArray = [
'零',
'一',
'二',
'三',
'四',
'五',
'六',
'七',
'八',
'九',
]

let unitArray = ['', '十', '百', '千', '万']

const toChineseNumeral = input => {
return input.toString().split('').map(
(number, idx) => {
return numberArray[parseInt(number)]
}
).reduce(
(acc, current) => {
let last = acc[acc.length - 1]
if (last == '零' && current == '零')
acc[acc.length - 1] = ' '
if (acc.length == (input.length - 1) && current == '零')
current = ''
acc.push(current)
return acc
},
[]
).map(
(elem, idx) => {
if (elem == ' ' || elem == '零')
return elem.trim()
return elem + unitArray[input.length-1 - idx]
}
).join('').replace(/^一十/, '十')
}

console.log(toChineseNumeral(29389))
console.log(toChineseNumeral(29000))
console.log(toChineseNumeral(20001))
console.log(toChineseNumeral(20901))

console.log([
10,
11,
18,
21,
110,
123,
24681
].map(toChineseNumeral))
`````` Ray M. Perry

First time doing one of these. Figured I'd throw out one of those weird languages (Raku):

``````use v6;

sub toChineseNumeral(Int \$number = 0) {
my \$numerals = <零 一 二 三 四 五 六 七 八 九>;
my \$places = \$number.polymod(10, 10, 10, 10).reverse;
my Str \$numbers = join "", do for ^4 {
my Int \$number = \$places[\$_];
next if \$number == 0;
\$numerals[\$number] ~ <万 千 百 十>[\$_];
}

given \$number {
when 0..9 { \$numerals[\$places.tail] }
when 10 { \$numbers.substr(1) }
when 11..19 { \$numbers.substr(1) ~ \$numerals[\$places.tail] }
default { \$numbers ~ \$numerals[\$places.tail] }
}
}

sub MAIN() {
for [9, 10, 11, 18, 21, 110, 111, 123, 1000, 10000, 24681] {
say \$_ ~ ": " ~ toChineseNumeral(\$_)
}
}
``````