팬디지털 수(Pandigital Number)란?
수학에서 팬디지털 수란 주어진 진법(base)에서 그 수의 유효 숫자들 가운데 해당 진법에서 사용되는 모든 숫자가 적어도 한 번씩 포함된 정수를 말합니다.
다시 말해, 어떤 진법에서 쓸 수 있는 숫자를 하나도 빠짐없이 모두 사용해 만든 정수가 바로 팬디지털 수입니다. 예를 들어 10진법에서 1234567890은 0부터 9까지 모든 숫자를 한 번씩 사용했으므로 대표적인 팬디지털 수입니다.
또한 0을 제외한 나머지 숫자를 모두 사용한 수는 '제로리스 팬디지털(zeroless pandigital)' 수라고 부릅니다.
문제 해결 접근 방식
- 숫자와 진법을 입력받습니다.
- 진법이 2 미만이거나 10을 초과하면 프로그램을 종료하고, 그렇지 않으면 해당 숫자가 팬디지털 수인지 검사합니다.
- 정수형 함수 is_pandigital(long long n, int base)는 숫자와 진법을 입력으로 받아 팬디지털 여부를 판별합니다.
- 숫자에 포함된 모든 자릿수를 세어 각 숫자의 등장 횟수를 증가시킵니다.
- 모든 자릿수를 순회하면서 한 번도 등장하지 않은 숫자가 있으면 false를 반환합니다.
- 정수형 함수 is_zeroless_pandigital(long long n, int base)는 숫자와 진법을 입력받아 0이 없는 팬디지털 여부를 확인합니다.
- 모든 자릿수를 순회하며 비어 있는 숫자가 발견되면 0을 반환합니다.
- 마지막으로 check_number(long long number, int base) 함수는 주어진 숫자가 해당 진법에서 유효한지 검사하여 유효하면 1, 그렇지 않으면 0을 반환합니다.
예제 코드
#include <iostream>
#include <cstring>
using namespace std;
int is_pandigital(long long number, int base);
int is_zeroless_pandigital(long long number, int base);
int check_number(long long number, int base);
int main(){
long long number;
int base;
cout << "Enter a number: ";
cin >> number;
cout << "Enter base(min:2 to max-10): ";
cin >> base;
if(base < 2 || base > 10){
return 1;
}
if(check_number(number, base)){
if(is_pandigital(number, base)){
cout << number << " is a pandigital number in base " << base << endl;
}else{
cout << number << " is not a pandigital number in base " << base << endl;
}
if(is_zeroless_pandigital(number, base)){
cout << number << " is a zeroless pandigital number in base " << base << endl;
}else{
cout << number << " is not a zeroless pandigital number in base " << base << endl;
}
}else{
cout << number << " is not a valid number in base " << base << endl;
}
return 0;
}
/* 숫자가 팬디지털 수인지 검사하는 함수 */
int is_pandigital(long long number, int base){
/* 모든 자릿수의 개수를 저장할 배열 */
int digits[10], i;
memset(digits, 0, sizeof(int)*10);
/* 숫자의 각 자릿수마다 카운트를 1씩 증가 */
while(number > 0){
int digit = number % 10;
++digits[digit];
number /= 10;
}
/* 모든 자릿수를 순회하며 비어 있는 숫자가 있으면 false 반환 */
for(i = 0; i < base; ++i)
if(digits[i] == 0)
return 0;
/* 비어 있는 숫자가 없으면 true 반환 */
return 1;
}
/* 0이 없는 팬디지털 수인지 검사하는 함수 */
int is_zeroless_pandigital(long long number, int base){
int digits[10], i;
memset(digits, 0, sizeof(int)*10);
while(number > 0){
int digit = number % 10;
if(digit == 0) return 0;
++digits[digit];
number /= 10;
}
for(i = 1; i < base; ++i)
if(digits[i] == 0)
return 0;
return 1;
}
/* 주어진 숫자가 해당 진법에서 유효한지 검사하는 함수 */
int check_number(long long number, int base){
while(number > 0){
int digit = number % 10;
if(digit > base - 1) return 0;
number /= 10;
}
return 1;
}
실행 결과
위 코드를 실행하면 다음과 같은 출력을 얻을 수 있습니다. 진법 범위를 벗어나는 자릿수가 포함된 숫자를 입력하면 유효하지 않은 숫자로 처리됩니다.
Enter a number: 45
Enter base(min:2 to max-10):3
45 is not a valid number in base 3.