Algorithm/문제풀이 Python

프로그래머스 레벨2 - 카카오인턴 2020 수식최대화

nauni 2020. 12. 31. 21:08

문제 주소

 

programmers.co.kr/learn/courses/30/lessons/67257

 

코딩테스트 연습 - 수식 최대화

IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과

programmers.co.kr

내 풀이

 

from itertools import permutations

def solution(expression):
    answer = 0
    operators = ["+","-","*"]
    expList = [expression[0]]
    # 숫자부분이랑 연산부분으로 파싱해서 리스트로 만들기
    for i in range(1,len(expression)) :
        if expression[i] not in operators and expList[-1] not in operators:
            expList[-1] += expression[i]
            continue
        expList.append(expression[i])
    # 모든 우선순위 조합에 대해 확인
    for priority in list(permutations(operators,3)):
        newExpList = expList[:]
        for operator in priority:
            while True:
                if operator in newExpList:
                    index = newExpList.index(operator)
                    calculated = eval(newExpList[index-1]+newExpList[index]+newExpList[index+1])
                    newExpList[index+1] = str(calculated)
                    del newExpList[index-1:index+1]
                else:
                    break
        answer = max(answer,abs(int(newExpList[0])))
    return answer

 

ㅠㅠ 오늘 꽤 오랜시간동안 풀었다ㅠㅠ 처음에는 정규표현식으로 파싱을 시도했다가 10+2+3 이런식으로 같은 기호가 연속으로 나오는 부분이 처리가 안 되었다. 이 부분을 아래처럼 while 문을 돌면서 같은 연산에 대해 처리하게 했더니 연산해서 - 값이 되는 부분이 처리가 안 되었다.

while True:
   regex = r"\d+" + re.escape(priority[i]) + r"\d+"
   calculation = re.findall(regex, newExpression)
   if len(calculation) == 0 :
       break
   for cal in calculation :
       newExpression = newExpression.replace(cal, str(eval(cal)))

-100+30 의 결과가 -(100+30) 으로 계산되어서 통과가 안 되었다..ㅠㅠ 결국 돌고 돌다가 풀이처럼 배열로 값을 저장하고 연산의 앞 뒤 문자를 가져와서 계산한 결과를 다시 넣어주는 방식으로 했다.

 

다른사람 풀이

 

나와 비슷한 방식의 풀이지만 좀 더 깔끔하게 처리한 풀이도 있었다. 이 풀이를 보면서 좀 더 간결하게 for 문을 정리하는 방식을 연습해야겠다는 생각을 했다. 사실 시간의 차이는 크게 없을 수도 있겠으나 가독성이 훨씬 좋아진다고 생각한다. 리스트 내부 한 줄짜리 for문으로 정리하는 연습을 하면 좋겠다. (\D)를 사용해서 정규표현식의 그룹핑을 하는 방식도 있는 듯 싶다.

 

 

계산하는 재귀함수를 만들어서 처리한 풀이도 있었다. 재귀함수는 구현이 어렵게 느껴지는 편인데 재귀함수로 푼 풀이가 좀 인상깊었다. 재귀함수로 구현한 것은 우선순위 조합이 (*,+,-) 로 주어진다면 실제 계산되는 조합은 - > + >* 로 뒤에부터 리턴되서 계산되고 마지막에 합쳐서 답을 주는 형식인 것 같았다. join 메서드는 잘 사용을 안 하게 되는데 문자열을 합치는 연산을 할 때 생각할 수 있도록 해야겠다. 재귀함수는 확실히 종료조건과 기존 연산과 결합하는 방식을 잘 생각해 낼 수 있다면 편리하게 사용 가능할 것 같았다.

 

정리

 

생각보다 너무 오랫동안 풀어서 앞으로 알고리즘 문제를 꾸준히 풀려면 시간을 정하고 풀어야 겠다는 생각을 했다.😥 카카오 문제는 항상 생각보다 너무 까다롭다ㅠㅠ 그래도 오늘 풀어서 다행이다.. 여전히 문자열에서 숫자를 분리해 내는 것은 어렵게 느껴졌다.

 

정규표현식을 사용하는 건 조건이 까다로우면 어렵다고 생각이 들었고, 문자열 자체로 파싱하고 계산까지 하는 문제에는 좀 적합하지 않을 수도 있겠다는 생각이 들었다.

 

정규표현식에서 변수를 사용하는 방식, eval 메소드에 대해 새롭게 알 수 있었다.