문제 설명
저는 IT 벤처 캐피털 회사를 운영하고 있습니다.
Ryan은 우승자에게 상품을 제공하는 연례 내부 해커톤을 개최합니다.
이전 콘테스트와 달리 다음과 같은 방식으로 우승자에게 수여되는 상금을 결정하려고 합니다.
해커톤의 모든 참가자에게는 숫자와 세 개의 산술 문자(+, -, *)로 구성된 산술 공식이 제공됩니다.
참가자는 전달된 수식에 포함된 연산자의 우선 순위를 자유롭게 재정의하여 만들 수 있는 가장 큰 숫자를 제출해야 합니다.
그러나 새로운 연산자 우선 순위를 정의할 때 동일한 순위의 연산자가 있을 수 없습니다.
다시 말해서, + > – > * 또는 – > * > + 예를 들어 연산자 우선 순위를 정의할 수 있습니다.
+,* > – 또는 * > 둘 이상의 연산자가 + 및 -와 같이 동일한 순위를 갖도록 연산자 우선 순위를 정의할 수 없습니다.
식에 두 개의 연산자가 포함된 경우 정의할 수 있는 연산자 우선 순위의 가능한 조합은 2!
= 2, 연산자가 3개면 3!
= 6개의 조합이 가능합니다.
계산 결과가 음수일 경우 그 숫자의 절대값을 환산하여 제출하며, 가장 큰 숫자를 제출한 참가자를 우승자로 선정하고, 우승자가 제출한 숫자를 당첨금으로 지급 .
예를 들어, 참가자들 사이 Neo가 다음 수식을 전달한다고 가정합니다.
“100-200*300-500+20”
일반적으로 덧셈과 뺄셈은 수학과 전산학에서 약속한 연산자 우선순위에 따라 동등하며, 곱셈은 덧셈과 뺄셈보다 우선순위가 높습니다.
* > +,- 우선 순위가 정의됩니다.
게임의 규칙에 따라 + > – > * 또는 – > * > + 예를 들어 연산자 우선 순위를 정의할 수 있습니다.
+,* > – 또는 * > +,- 다음과 같이 두 개 이상의 연산자가 동일한 순위를 갖도록 연산자 우선 순위를 정의할 수 없습니다.
수식에 3개의 연산자가 있는 경우 가능한 연산자 우선 순위 조합은 3!
= 6, 여기서 + > – > * 연산자 우선 순위를 로 설정하면 결과 값은 22,000원입니다.
반면에 * > + > – 연산자 우선 순위가 설정되면 수식의 결과 값은 -60,420이지만 규칙에 따라 우승 상금은 절대 값인 60,420원입니다.
참가자에 대한 수식이 포함된 문자열 표현식을 인수로 주어 승리 시 얻을 수 있는 최대 상금을 반환하는 솔버 기능을 완성합니다.
한계
- expression은 길이가 3 이상 100 이하인 문자열입니다.
- 표현식은 적절한 중위 표기법(연산의 두 대상 사이에 연산자 기호를 사용하는 방법)으로 표현되는 표현식으로 숫자와 3개의 연산자(+, -, *)로만 구성되며 공백이나 괄호는 사용하지 않습니다.
유효하지 않은 표현식은 입력으로 제공되지 않습니다.
- 다시 말해서, “402+-561*”과 같은 유효하지 않은 수식은 올바른 중위 표기법이 아니기 때문에 제공되지 않습니다.
- 다시 말해서, “402+-561*”과 같은 유효하지 않은 수식은 올바른 중위 표기법이 아니기 때문에 제공되지 않습니다.
- 식의 피연산자는 0에서 999 사이의 숫자입니다.
- 다시 말해서, “100-2145*458+12″와 같이 피연산자가 999개 이상인 표현식은 입력으로 제공되지 않습니다.
- “-56+100″과 같이 피연산자가 음수인 표현식도 입력으로 제공되지 않습니다.
- 다시 말해서, “100-2145*458+12″와 같이 피연산자가 999개 이상인 표현식은 입력으로 제공되지 않습니다.
- 식에는 하나 이상의 연산자가 포함됩니다.
- 연산자 우선 순위가 적용되는 방식에 관계없이 식의 중간 평가 및 최종 결과의 절대값은 263입니다.
– 1 이하를 입력합니다. - 같은 연산자 사이에서는 전자가 우선합니다.
입력 및 출력 예
표현하다 | 결과 |
“100-200*300-500+20” | 60420 |
“50*6-3*2” | 300 |
솔루션.py
이 문제를 해결하기 전에 평가 기능에 대해 알아보기필요합니다.
eval(expression) 함수란 무엇입니까?
매개변수로 받기 연산식(산술식이 포함된 문자열)을 실행하여 계산된 숫자를 반환하는 함수보지 않았다.
예를 들어 eval(“100+400”)을 실행하면 문자열로 받은 “100+400″을 평가하고 500을 반환합니다.
eval("100+400") // 500
문제를 풀다
- 인수 set(re.findall(“\D”, expression)) 로 받은 표현식에 포함된 연산자만 반복 없이 추출합니다.
- 추출된 연산자는 우선 순위 연산자 순열과 순열 함수의 조합을 만드는 데 사용됩니다.
- dfs 알고리즘을 통해 생성된 우선 순위 연산자 순열과 조합을 차례로 순회하여 절대값이 가장 큰 숫자를 반환합니다.
정답 코드
import re
from itertools import permutations
def solution(expression):
answer = 0
operator = set(re.findall("\D", expression)) # expression에 포함된 연산자만을 추출 (중복x)
priorities_operators = list(permutations(operator, len(operator)))
for priorities in priorities_operators:
evaluated_val = int(dfs(expression, priorities, 0))
answer = max(answer, abs(evaluated_val))
return answer
def dfs(expression, priorities, depth):
if depth == len(priorities) - 1:
return str(eval(expression))
oper = priorities(depth)
print(expression.split(oper))
evaluated = eval(
oper.join(
(dfs(e, priorities, depth = depth + 1) for e in expression.split(oper))
)
)
return str(evaluated)
먼저 순열의 경우할 것이다.