알고리즘/풀었지만 다시 보기
프로그래머스 [Lv. 3] [PCCP 기출문제] 4번 / 수식 복원하기 {언어 : Python}
스위태니
2024. 9. 12. 16:37
728x90
문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/340210
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
정답 코드
def isValid(number, notation):
for n in number:
if int(n) >= notation:
return False
return True
def changeNotation(number, notation):
newNumber = ""
while number > 0:
newNumber += str(number%notation)
number //= notation
if newNumber:
return int(newNumber[::-1])
return 0
def solution(expressions):
# bi, tetra, quater, penta, hexa, hepta, octa, nona
notations = [num for num in range(2, 10)]
intersections = set(notations)
dictExpressions = dict()
expKeys = []
for expression in expressions:
a, oper, b, equal, c = expression.split()
validNotations = set()
values = [0 for _ in range(10)] # 계산을 편하게 하기 위해서
if c.isdigit():
notC = int(c)
for notation in notations:
if isValid(c, notation) and isValid(a, notation) and isValid(b, notation):
notA = int(a, notation)
notB = int(b, notation)
tmp = 0
if oper == "+":
tmp = changeNotation(notA + notB, notation)
values[notation] = tmp
else:
tmp = changeNotation(notA - notB, notation)
values[notation] = tmp
if tmp == int(c):
validNotations.add(notation)
else:
for notation in notations:
if isValid(a, notation) and isValid(b, notation):
notA = int(a, notation)
notB = int(b, notation)
tmp = 0
if oper == "+":
tmp = changeNotation(notA + notB, notation)
values[notation] = tmp
else:
tmp = changeNotation(notA - notB, notation)
values[notation] = tmp
validNotations.add(notation)
expKeys.append(expression)
intersections = intersections.intersection(validNotations)
# expression자체를 키로 써서 dictionary에 저장
dictExpressions[expression] = values
listInter = sorted(list(intersections))
lenL = len(listInter)
answer = []
for ek in expKeys:
values = dictExpressions[ek]
val = values[listInter[0]]
a, oper, b, equal, c = ek.split()
isSame = True
result = str(val)
if lenL > 1:
for idx in range(1, lenL):
if val == values[listInter[idx]]:
continue
else:
result = "?"
break
answer.append(f"{a} {oper} {b} = {result}")
return answer
풀이 방법
- 진법별 계산 저장:
- 각 수식에 대해 모든 진법(2부터 9까지)으로 계산하여 결과를 저장한다.
- 예를 들어 34 + 56 = X라는 수식이 있다면, 34는 5진법부터 9진법까지 유효하고, 56은 7진법부터 9진법까지 유효하다고 가정한다.
- 진법 유효성 검사:
- 각 수식을 각 진법으로 변환하여 계산한 결과를 저장한다.
- 이때 결과를 저장하기 위해 길이가 10인 배열(values)을 사용한다.
- 배열의 인덱스는 진법을 의미하며, 예를 들어 values[7]는 7진법에서의 계산 결과를 의미한다.
- 예를 들어 values = [0, 0, 0, 0, 0, 0, 0, 66, 74, 82]일 수 있다.
- 유효 진법 찾기:
- 각 수식의 유효 진법을 찾기 위해 수식에서의 계산 결과가 주어진 결과와 일치하는지 확인한다.
- 예를 들어 34 + 56 = X의 결과가 실제 X와 같다면, 그 진법은 유효한 진법으로 간주된다.
- 모든 유효 진법들의 교집합을 구하여 유효한 진법을 점차 좁혀나간다.
- 교집합 계산:
- 가능한 진법들의 교집합을 계속해서 구한다.
- 예를 들어 {1, 2, 3}과 {2, 3}이 있을 때 교집합은 {2, 3}이 되고, 여기에 {3}과의 교집합을 구하면 {3}이 된다.
- 이렇게 해서 최종적으로 유효한 진법을 구한다.
- 결과 계산 및 출력:
- 유효한 진법들로 계산한 결과를 사용하여 수식의 결과를 도출한다.
- 결과가 일관되면 그 값을 출력하고, 일관되지 않으면 ?를 출력한다.
느낀점
- 좀 더 깔끔하게 풀 수는 없었을까 생각해보면서 다른 언어로 리팩토링을 해보면 좋을 것 같다.
728x90