몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 3] [PCCP 기출문제] 4번 / 수식 복원하기 {언어 : Python} 본문

알고리즘/풀었지만 다시 보기

프로그래머스 [Lv. 3] [PCCP 기출문제] 4번 / 수식 복원하기 {언어 : Python}

스위태니 2024. 9. 12. 16:37

문제 링크

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

풀이 방법

  1. 진법별 계산 저장:
    • 각 수식에 대해 모든 진법(2부터 9까지)으로 계산하여 결과를 저장한다.
    • 예를 들어 34 + 56 = X라는 수식이 있다면, 34는 5진법부터 9진법까지 유효하고, 56은 7진법부터 9진법까지 유효하다고 가정한다.
  2. 진법 유효성 검사:
    • 각 수식을 각 진법으로 변환하여 계산한 결과를 저장한다.
    • 이때 결과를 저장하기 위해 길이가 10인 배열(values)을 사용한다.
    • 배열의 인덱스는 진법을 의미하며, 예를 들어 values[7]는 7진법에서의 계산 결과를 의미한다.
    • 예를 들어 values = [0, 0, 0, 0, 0, 0, 0, 66, 74, 82]일 수 있다.
  3. 유효 진법 찾기:
    • 각 수식의 유효 진법을 찾기 위해 수식에서의 계산 결과가 주어진 결과와 일치하는지 확인한다.
    • 예를 들어 34 + 56 = X의 결과가 실제 X와 같다면, 그 진법은 유효한 진법으로 간주된다.
    • 모든 유효 진법들의 교집합을 구하여 유효한 진법을 점차 좁혀나간다.
  4. 교집합 계산:
    • 가능한 진법들의 교집합을 계속해서 구한다.
    • 예를 들어 {1, 2, 3}과 {2, 3}이 있을 때 교집합은 {2, 3}이 되고, 여기에 {3}과의 교집합을 구하면 {3}이 된다.
    • 이렇게 해서 최종적으로 유효한 진법을 구한다.
  5. 결과 계산 및 출력:
    • 유효한 진법들로 계산한 결과를 사용하여 수식의 결과를 도출한다.
    • 결과가 일관되면 그 값을 출력하고, 일관되지 않으면 ?를 출력한다.

느낀점

  • 좀 더 깔끔하게 풀 수는 없었을까 생각해보면서 다른 언어로 리팩토링을 해보면 좋을 것 같다.