-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 숫자를 순 우리말 수사로 변환하거나 수 관형사로 변환하는 함수를 추가 (#201)
* feat: 상수 추가 * feat: 수사 추가 * test: susa에 대한 테스트케이스 추가 * feat: 테스트케이스를 통과하도록 수정 * feat: 에 대한 문서 추가 * feat: 에서 를 export 하도록 수정 * refactor: 변할 수 있는 변수 선언인 let보다는 최대한 const를 사용 * feat: 정수가 아닌 경우에 대한 예외처리를 추가하고 분기를 탈 확률이 가장 낮은 조건을 뒤로 배치 * test: 정수가 아닌 값에 대한 테스트케이스 추가 * refactor: let이 사용되던 부분을 동일하게 제거 * Create itchy-nails-bake.md --------- Co-authored-by: 박찬혁 <[email protected]>
- Loading branch information
1 parent
506d0fc
commit 56db7f0
Showing
7 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"es-hangul": patch | ||
--- | ||
|
||
feat: 숫자를 순 우리말 수사로 변환하거나 수 관형사로 변환하는 함수를 추가 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
title: susa | ||
--- | ||
|
||
# susa | ||
|
||
Convert numbers to native Korean numeral words or numeral determiners. The given number is valid when it is greater than 0 and less than or equal to 100. | ||
|
||
```typescript | ||
function susa( | ||
// Number to convert | ||
num: number, | ||
// Whether to use numeral determiners | ||
classifier?: boolean | ||
): string; | ||
``` | ||
|
||
## Examples | ||
|
||
```typescript | ||
susa(1); // '하나' | ||
susa(2); // '둘' | ||
susa(11); // '열하나' | ||
susa(21); // '스물하나' | ||
susa(99); // '아흔아홉' | ||
susa(100); // '백' | ||
|
||
susa(1, true); // '한' | ||
susa(2, true); // '두' | ||
susa(11, true); // '열한' | ||
susa(20, true); // '스무' | ||
susa(21, true); // '스물한' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
title: susa | ||
--- | ||
|
||
# susa | ||
|
||
숫자를 순 우리말 [수사](https://ko.dict.naver.com/#/entry/koko/d0ce2b674cae4b44b9028f648dd458b0)로 변환하거나 [수 관형사](https://ko.dict.naver.com/#/entry/koko/c513782b82554ff499c80ec616c5b611)로 변환합니다. 주어진 숫자가 0보다 크고 100 이하일 때 유효합니다. | ||
|
||
```typescript | ||
function susa( | ||
// 변환할 숫자 | ||
num: number, | ||
// 수 관형사를 사용할지 여부 | ||
classifier?: boolean | ||
): string; | ||
``` | ||
|
||
## Examples | ||
|
||
```typescript | ||
susa(1); // '하나' | ||
susa(2); // '둘' | ||
susa(11); // '열하나' | ||
susa(21); // '스물하나' | ||
susa(99); // '아흔아홉' | ||
susa(100); // '백' | ||
|
||
susa(1, true); // '한' | ||
susa(2, true); // '두' | ||
susa(11, true); // '열한' | ||
susa(20, true); // '스무' | ||
susa(21, true); // '스물한' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { susa } from './susa'; | ||
|
||
describe('susa', () => { | ||
const validNumbers = [ | ||
{ num: 1, word: '하나', classifier: '한' }, | ||
{ num: 2, word: '둘', classifier: '두' }, | ||
{ num: 3, word: '셋', classifier: '세' }, | ||
{ num: 4, word: '넷', classifier: '네' }, | ||
{ num: 5, word: '다섯', classifier: '다섯' }, | ||
{ num: 6, word: '여섯', classifier: '여섯' }, | ||
{ num: 7, word: '일곱', classifier: '일곱' }, | ||
{ num: 8, word: '여덟', classifier: '여덟' }, | ||
{ num: 9, word: '아홉', classifier: '아홉' }, | ||
{ num: 10, word: '열', classifier: '열' }, | ||
{ num: 11, word: '열하나', classifier: '열한' }, | ||
{ num: 12, word: '열둘', classifier: '열두' }, | ||
{ num: 20, word: '스물', classifier: '스무' }, | ||
{ num: 21, word: '스물하나', classifier: '스물한' }, | ||
{ num: 30, word: '서른', classifier: '서른' }, | ||
{ num: 99, word: '아흔아홉', classifier: '아흔아홉' }, | ||
{ num: 100, word: '백', classifier: '백' }, | ||
]; | ||
|
||
const invalidNumbers = [0, -1, 101, 1.1, -1.1, Infinity, -Infinity, NaN]; | ||
|
||
validNumbers.forEach(({ num, word, classifier }) => { | ||
it(`${num} - 순 우리말 수사로 바꿔 반환해야 한다.`, () => { | ||
expect(susa(num, false)).toBe(word); | ||
}); | ||
|
||
it(`${num} - 순 우리말 수 관형사가 있다면 수 관형사로 없다면 수사로 반환해야 한다.`, () => { | ||
expect(susa(num, true)).toBe(classifier); | ||
}); | ||
}); | ||
|
||
invalidNumbers.forEach(num => { | ||
it(`유효하지 않은 숫자 ${num}에 대해 오류를 발생시켜야 한다.`, () => { | ||
expect(() => susa(num, false)).toThrow('지원하지 않는 숫자입니다.'); | ||
expect(() => susa(num, true)).toThrow('지원하지 않는 숫자입니다.'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { SUSA_MAP, SUSA_CLASSIFIER_MAP } from './constants'; | ||
import { hasProperty } from './utils'; | ||
|
||
export function susa(num: number, classifier?: boolean): string { | ||
validateNumber(num); | ||
return classifier ? getClassifierWord(num) : getNumberWord(num); | ||
} | ||
|
||
function getClassifierWord(num: number): string { | ||
if (num === 20) { | ||
return SUSA_CLASSIFIER_MAP[num]; | ||
} | ||
|
||
const tens = Math.floor(num / 10) * 10; | ||
const ones = num % 10; | ||
|
||
const tensWord = hasProperty(SUSA_MAP, tens) ? SUSA_MAP[tens] : ''; | ||
|
||
if (ones === 0) { | ||
return tensWord; | ||
} | ||
|
||
if (hasProperty(SUSA_CLASSIFIER_MAP, ones)) { | ||
const onesWord = SUSA_CLASSIFIER_MAP[ones]; | ||
|
||
return `${tensWord}${onesWord}`; | ||
} | ||
|
||
if (hasProperty(SUSA_MAP, ones)) { | ||
const onesWord = SUSA_MAP[ones]; | ||
|
||
return `${tensWord}${onesWord}`; | ||
} | ||
|
||
// `susa`에서` `validateNumber` 하기 때문에 도달할 수 없는 분기입니다. 타입 추론을 위해 에러를 던져줍니다. | ||
throw new Error('지원하지 않는 숫자입니다.'); | ||
} | ||
|
||
function validateNumber(num: number): void { | ||
if (Number.isNaN(num) || num <= 0 || num > 100 || !Number.isInteger(num) || !Number.isFinite(num)) { | ||
throw new Error('지원하지 않는 숫자입니다.'); | ||
} | ||
} | ||
|
||
function getNumberWord(num: number): string { | ||
if (num === 100) { | ||
return SUSA_MAP[100]; | ||
} | ||
|
||
const tens = Math.floor(num / 10) * 10; | ||
const ones = num % 10; | ||
|
||
const tensWord = hasProperty(SUSA_MAP, tens) ? SUSA_MAP[tens] : ''; | ||
const onesWord = hasProperty(SUSA_MAP, ones) ? SUSA_MAP[ones] : ''; | ||
|
||
return `${tensWord}${onesWord}`; | ||
} |