거꾸로 숫자(Upside Down Numbers)란?
숫자를 180도 회전했을 때 원래 값 그대로 유지되는 수를 '거꾸로 숫자(Upside Down Numbers)'라고 합니다.
대표적인 예로 9116과 69가 있으며, 두 숫자 모두 거꾸로 뒤집어도 동일하게 읽힙니다.
자릿수별 회전 규칙은 다음과 같습니다.
- 0 → 0, 1 → 1, 8 → 8 : 회전해도 그대로 유지됩니다.
- 6 → 9, 9 → 6 : 서로 뒤바뀌며 회전됩니다.
- 2, 3, 4, 5, 7 : 회전 시 유효한 숫자가 되지 않으므로 거꾸로 숫자에 포함될 수 없습니다.
문제 정의
두 개의 숫자로 이루어진 범위 배열을 입력받아, 해당 범위 안에 속하는 모든 거꾸로 숫자의 개수를 반환하는 JavaScript 함수를 작성해야 합니다.
구현 코드
다음은 위 문제를 해결한 코드입니다 −
const range = [5, 125];
const flipNum = (number) => {
const upsideDownDigits = [0, 1, -99, -99, -99, -99, 9, -99, 8, 6];
let reverseNumArr = String(number)
.split('')
.map(val => Number(val))
.reverse();
let flipDigitsNumArr = reverseNumArr.map(val => upsideDownDigits[val]);
if (flipDigitsNumArr.includes(-99)) {
return false;
}
let flipDigitsNum = Number(
flipDigitsNumArr.reduce((accum, curr) => accum + String(curr))
);
return flipDigitsNum === number;
};
const countUpsideDown = ([lowNum, highNum]) => {
let uDNums = 0;
for (let counter = lowNum; counter <= highNum; counter++) {
uDNums += flipNum(counter) === true;
}
return uDNums;
};
console.log(countUpsideDown(range));
코드 동작 방식
핵심 로직을 단계별로 살펴보겠습니다.
- flipNum(number) : 하나의 숫자가 거꾸로 숫자인지 판별하는 헬퍼 함수입니다.
- upsideDownDigits 배열은 각 자릿수(인덱스)가 회전 후 어떤 숫자로 바뀌는지를 저장하며, 유효하지 않은 자릿수(2, 3, 4, 5, 7)는 -99로 표시합니다.
- 입력 숫자를 문자열로 변환해 배열로 분리한 뒤 순서를 뒤집습니다. 180도 회전 시 자릿수 순서가 역전되기 때문입니다.
- 뒤집힌 각 자릿수를 회전된 값으로 매핑하고, -99가 포함되어 있으면 즉시 false를 반환합니다.
- 매핑 결과를 다시 숫자로 조합해 원래 숫자와 비교하며, 일치하면 true를 반환합니다.
- countUpsideDown([lowNum, highNum])은 범위의 시작부터 끝까지 모든 숫자를 순회하면서 flipNum의 결과가 true인 경우만 카운트해 반환합니다.
출력 결과
7
범위 [5, 125]에 속하는 거꾸로 숫자는 8, 11, 69, 88, 96, 101, 111로 총 7개입니다.