코딩테스트 연습 - 수식 최대화
IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과
programmers.co.kr
해결 과정
리스트 조작으로 인해 시간 소요 생각보다 많이 됐던 문제.
string 으로 주어진 식에 대해서 조작하는 과정이 있는 문제다.
근데 다른 풀이 보니 더 간단하게 푼 풀이가 많은 것 같아서 참고해보자.
생각의 흐름
1. 연산자 뽑기
2. 연산자로 가능한 순열 뽑기 (가짓수는 최대 6개이므로 전부다 계산하는 문제구나)
3. 계산해주는 함수 만들기 (이 부분 좀 더 쉽게 할 수 없을까)
3-1. 이를 위해 연산자, 피연산자로 분리된 리스트 만들기
4. 계산 결과 값 중 가장 최댓값 뽑기
나의 풀이
from itertools import permutations
def calculate(elements, operators): # operates == ('*', '-', '+')
all_elements = elements
result = 0
for operator in operators:
while len(all_elements) != 1:
for i, element in enumerate(all_elements):
if element == operator:
a = all_elements[i-1]
b = all_elements[i+1]
if operator == "*":
all_elements.insert(
i+2, a * b)
elif operator == "-":
all_elements.insert(
i+2, a - b)
elif operator == "+":
all_elements.insert(
i+2, a + b)
del all_elements[i-1]
del all_elements[i-1]
del all_elements[i-1]
break
if operator not in all_elements:
break
result = all_elements[0]
return result
def solution(expression):
answer = 0
# 연산자 뽑기
operators = []
elements = []
last_operator_index = -1
for index, value in enumerate(expression):
if value == "-" or value == "*" or value == "+":
operators.append(value)
elements.append(int(expression[last_operator_index + 1:index]))
elements.append(value)
last_operator_index = index
elements.append(int(expression[last_operator_index + 1:]))
operators = list(set(operators))
operator_combi = list(permutations(operators, len(operators)))
# 계산해서 최댓값 뽑기
candidates = [abs(calculate(elements[:], i)) for i in operator_combi]
answer = max(candidates)
return answer
다른 풀이
def solution(expression):
operations = [('+', '-', '*'),('+', '*', '-'),('-', '+', '*'),('-', '*', '+'),('*', '+', '-'),('*', '-', '+')]
answer = []
for op in operations:
a = op[0]
b = op[1]
temp_list = []
for e in expression.split(a):
temp = [f"({i})" for i in e.split(b)]
temp_list.append(f'({b.join(temp)})')
answer.append(abs(eval(a.join(temp_list))))
return max(answer)
음 이건 생각하기 어려운 풀이인 듯. 디버깅 하면서 어떤 원리인지 파악했다.
eval() 함수를 쓸 건데, 아예 연산자 우선순위 별로 괄호를 쳐서 통째로 eval() 함수에 넣는 풀이이다.
가령
계산할 식 => 100-200*300-500+20
1) 연산자 우선순위 => ('+', '-', '*')
((100)-(200*300)-(500))+((20))
2) 연산자 우선순위 => ('+', '*', '-')
((100-200)*(300-500))+((20))
import re
from itertools import permutations
def solution(expression):
#1
op = [x for x in ['*','+','-'] if x in expression]
op = [list(y) for y in permutations(op)]
ex = re.split(r'(\D)',expression)
#2
a = []
for x in op:
_ex = ex[:]
for y in x:
while y in _ex:
tmp = _ex.index(y)
_ex[tmp-1] = str(eval(_ex[tmp-1]+_ex[tmp]+_ex[tmp+1]))
_ex = _ex[:tmp]+_ex[tmp+2:]
a.append(_ex[-1])
#3
return max(abs(int(x)) for x in a)
re를 알았다면 조금 더 간결하게 작성할 수 있는 코드.
이게 그나마 이해하기 용이한 코드.
IDEA
python의 mutable 객체
python의 list는 mutable(가변) 객체이다. call by reference처럼 동작한다. list를 매개변수로 넘겨줄 때, 그 리스트 자체가 바뀌게 되므로 원본 list를 바꾸고 싶지 않는 경우에는 list[:] 이런 식으로 새로운 변수를 넘겨주거나 새로운 변수를 재정의 해줘야 한다.
eval(expression)
'100*200' -> 20000 이런 결과를 바로 얻고 싶을 때 eval() 함수를 사용할 수 있다.
import re, 정규표현식
'100*200-300' 이 문자열을 ['100', '*', '200', '-', '300'] 이렇게 쪼개서 리스트에 저장하고 싶을 때 re.split을 사용할 수 있다.
'Coding Test > 문제 풀이' 카테고리의 다른 글
[문제 풀이] 여행경로 (0) | 2022.03.03 |
---|---|
[문제 풀이] 더 맵게 (0) | 2022.03.02 |
[문제 풀이] 거리두기 확인하기 (0) | 2022.02.24 |
[문제 풀이] 큰 수 만들기 (0) | 2022.02.17 |
[문제 풀이] 체육복 (0) | 2022.02.16 |