이번 글에서는 파이썬을 이용해 두 통화 사이의 환율을 계산하는 프로그램을 만들어 보겠습니다. 문제는 다음과 같이 정의할 수 있습니다.
세 개의 배열 curr_a, curr_b, conv_rate가 주어집니다. curr_a와 curr_b에는 통화 이름들이 들어 있고, conv_rate에는 각 통화 쌍의 변환 비율이 저장되어 있습니다. 즉, conv_rate[i]는 curr_a[i]에서 curr_b[i]로 바꿀 때 적용되는 환율입니다.
여기에 출발 통화 src와 도착 통화 dest가 추가로 주어지면, src에서 dest까지의 최종 환율을 구해야 합니다. 만약 경로를 통해 환율을 계산하는 것이 불가능하다면 0(또는 -1)을 반환합니다.
문제 예시
예를 들어 다음과 같은 입력이 주어졌다고 가정해 봅시다.
- src = "INR" (인도 루피)
- dest = "JPY" (일본 엔)
- curr_a = ["INR", "GBP", "EUR"]
- curr_b = ["GBP", "EUR", "JPY"]
- conv_rate = [0.009, 1.17, 129.67]
이 경우 INR → GBP → EUR → JPY 경로를 따라 환율을 곱하면 결과는 1.3654250999999997이 됩니다.
해결 알고리즘
이 문제는 그래프 탐색과 유사한 방식으로 해결할 수 있습니다. 각 통화를 노드로, 환율을 간선의 가중치로 생각하고, 출발점부터 도착점까지 곱셈 경로를 찾으면 됩니다. 단계별 절차는 다음과 같습니다.
- 기본값이 0인 맵(temp)을 생성합니다.
- temp[src] := 1 로 설정합니다. (출발 통화의 초기값은 1)
- 반복 횟수 i := 0, 플래그 p := True로 초기화합니다.
- p가 참이고 i가 temp의 크기 이하인 동안 반복합니다.
- p := False로 설정합니다.
- curr_a, curr_b, conv_rate의 모든 조합(x, y, z)에 대해 다음을 검사합니다.
- 만약 temp[x] * z > temp[y]라면:
- temp[y] := temp[x] * z 로 갱신합니다.
- p := True로 설정하여 반복을 계속합니다.
- 만약 temp[x] * z > temp[y]라면:
- i := i + 1 로 반복 횟수를 늘립니다.
- i가 temp의 크기 이하이면 temp[dest] 값을 반환합니다.
- 그렇지 않으면 -1을 반환합니다. (환율을 구할 수 없음)
이 방식은 벨먼-포드(Bellman-Ford) 알고리즘의 아이디어와 유사합니다. 더 큰 값이 나올 때마다 갱신을 반복하면서 최적의 환율 경로를 찾아내는 것입니다.
파이썬 구현 예제
실제 동작을 이해하기 위해 아래 코드를 살펴보겠습니다.
from collections import defaultdict
def solve(src, dest, curr_a, curr_b, conv_rate):
temp = defaultdict(int)
temp[src] = 1
i = 0
p = True
while p and i <= len(temp):
p = False
for x, y, z in zip(curr_a, curr_b, conv_rate):
if temp[x] * z > temp[y]:
temp[y] = temp[x] * z
p = True
i += 1
return temp[dest] if i <= len(temp) else -1
print(solve("INR", "JPY", ["INR", "GBP", "EUR"], ["GBP", "EUR", "JPY"], [0.009, 1.17, 129.67]))입력
"INR", "JPY", ["INR", "GBP", "EUR"], ["GBP", "EUR", "JPY"], [0.009, 1.17, 129.67]
출력
1.3654251
코드 설명
defaultdict(int)를 사용하면 아직 등록되지 않은 통화에 접근할 때 자동으로 0이 반환되므로 별도의 초기화 작업이 필요 없습니다. zip() 함수는 세 개의 리스트를 병렬로 순회하며 각 통화 쌍과 해당 환율을 한 번에 가져오는 역할을 합니다.
while 루프 내부에서는 더 유리한 환율 경로를 발견할 때마다 값을 갱신하고, 갱신이 더 이상 일어나지 않으면(p가 False인 상태로 유지되면) 반복을 종료합니다. 이렇게 하면 여러 통화를 거쳐 가는 복합 환율도 정확하게 계산할 수 있습니다.
이 알고리즘은 통화 수가 n개일 때 최악의 경우 O(n × E)의 시간 복잡도를 가지며, 여기서 E는 주어진 환율 정보(간선)의 개수입니다. 실무에서는 환율 데이터를 그래프로 구성한 뒤 BFS, DFS 또는 벨먼-포드 알고리즘을 활용해 유사한 방식으로 환율 변환 문제를 해결합니다.