문제 이해하기
(x, y) 형태로 표현되는 여러 개의 쌍이 주어졌다고 가정해 보겠습니다. 여기서 x는 해당 수의 진법(base)을 의미하고, y는 실제 숫자 값을 나타냅니다. 서로 다른 진법으로 표현되었지만 실제로는 같은 값을 가지는 쌍들이 목록 속에 존재할 수 있으며, 우리는 주어진 쌍들 중에서 값이 일치하는 경우가 몇 개인지 확인해야 합니다. 단, 입력에는 중복된 쌍이 포함될 수 있고, 유효하지 않은 진법과 숫자의 조합도 섞여 있을 수 있습니다.
예를 들어 입력이 num_inputs = 2, input_arr = [(10, 15), (8, 17)]이라면 출력은 1이 됩니다.
num_inputs는 입력의 개수를 지정하고, input_arr는 숫자 쌍들의 목록입니다. 두 쌍을 자세히 살펴보면, 10진수(밑이 10)로 표현한 15는 8진수(밑이 8)로 표현한 17과 완전히 같은 값입니다. 따라서 일치하는 경우가 하나뿐이므로 출력값으로 1을 반환하게 됩니다.
해결 접근 방법
이 문제를 해결하기 위해 다음 단계를 따릅니다.
- arr_len에 input_arr의 크기를 저장합니다.
- 정수 값을 저장하는 새로운 딕셔너리 temp_dict를 생성합니다.
- i를 0부터 num_inputs까지 반복하면서 다음 작업을 수행합니다.
- num_base에 input_arr의 i번째 쌍에서 첫 번째 값(진법)을 문자열 형태로 저장합니다.
- num_val에 두 번째 값(숫자)을 문자열 형태로 저장합니다.
- int(num_val, int(num_base))를 통해 해당 수를 10진수 정수로 변환한 뒤, temp_dict에서 그 값의 등장 횟수를 1 증가시킵니다.
- cnt를 0으로 초기화합니다.
- temp_dict의 모든 값(value)에 대해 cnt에 value * ((value - 1) // 2)를 더합니다. 이는 동일한 값이 value개 있을 때 서로 다른 두 쌍을 뽑는 조합의 개수, 즉 valueC2를 계산하는 공식입니다.
- cnt를 반환합니다.
예제 코드
아래 구현 예제를 통해 더 잘 이해할 수 있습니다.
from collections import defaultdict
def solve(num_inputs, input_arr):
arr_len = len(input_arr)
temp_dict = defaultdict(int)
for i in range(num_inputs):
num_base, num_val = str(input_arr[i][0]), str(input_arr[i][1])
temp_dict[int(num_val, int(num_base))] += 1
cnt = 0
for value in temp_dict.values():
cnt += value*(value - 1)//2
return cnt
print(solve(2, [(10, 15), (8, 17)]))입력
2, [(10, 15), (8, 17)]
출력
1
코드 설명
이 코드의 핵심은 Python 내장 함수 int()의 두 번째 인자입니다. int(문자열, 진법) 형태로 호출하면 해당 진법으로 표현된 숫자 문자열을 10진수 정수로 손쉽게 변환할 수 있습니다. 예를 들어 int('17', 8)은 8진수 17을 10진수로 바꾸어 15를 반환하므로, int('15', 10)의 결과와 동일해집니다.
collections 모듈의 defaultdict(int)를 사용하면 아직 존재하지 않는 키에 접근하더라도 자동으로 0으로 초기화되기 때문에, 별도의 키 존재 여부 검사 없이 간결하게 등장 횟수를 누적할 수 있습니다. 마지막으로 각 값의 등장 횟수 n에 대해 n * (n - 1) // 2를 모두 더하면, 서로 다른 진법 표기이지만 같은 값을 나타내는 쌍의 총 개수를 구할 수 있습니다.