DEV Community

Daily Challenge #248 - Chinese Numerals

dev.to staff on May 23, 2020

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 ...
Collapse
 
savagepixie profile image
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, '')
Collapse
 
peterlau profile image
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))
Collapse
 
raymperry profile image
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($_)
    }
}