아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.
이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
N은 1 이상 9 이하입니다.
number는 1 이상 32,000 이하입니다.
수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다.
최솟값이 8보다 크면 -1을 return 합니다.
N | number | return |
---|---|---|
5 | 12 | 4 |
2 | 11 | 3 |
i
개의 N으로 이루어진 숫자들의 모음은j
개의 N으로 이루어진 사칙연산 결과 모음과i-j
개의 N으로 이루어진 모음의 조합으로 이루어져 있다고 생각하고 문제에 접근해보겠습니다.(1=<j<4
) N
이 number
와 같다면 N
하나만 필요하므로 1
을 리턴하고 dp
는 list를 값으로 가지는 딕셔너리로 지정해둡니다.dp[i]
는 i개의 N으로 이루어진 사칙연산의 결과값들의 list입니다. if N == number:
return 1
dp = collections.defaultdict(list)
dp[1].append(N)
33
, 555
같이 N이 사칙연산없이 이어붙어진 형태의 수들을 처리해줍니다. for i in range(2,9):
dp[i].append(int(str(N)*i))
dp[j]
의 요소들과dp[i-j]
를 사칙연산한 결과를 순서대로 dp[i]
에 넣어줍니다.extend
와 map, lambda
로 각 사친연산의 결과를 한번에 처리합니다.try
,except
처리해줍니다.number
가 존재한다면 i
를 리턴합니다.i=8
까지 탐색했음에도 일치하는 결과값이 없다면 -1을 리턴합니다. for i in range(2,9):
dp[i].append(int(str(N)*i))
for j in range(1,5):
# dp[i]는 dp[i-j]와 dp[j]의 조합
for d_i in dp[i-j]:
dp[i].extend(list(map(lambda x:x+d_i, dp[j])))
dp[i].extend(list(map(lambda x:x-d_i, dp[j])))
dp[i].extend(list(map(lambda x:x*d_i, dp[j])))
try:
dp[i].extend(list(map(lambda x:x//d_i, dp[j])))
except:
continue
if number in dp[i]:
return i
return -1
import collections
def solution(N, number):
if N == number:
return 1
dp = collections.defaultdict(list)
dp[1].append(N)
for i in range(2,9):
dp[i].append(int(str(N)*i))
for j in range(1,5):
# dp[i]는 dp[i-j]와 dp[j]의 조합
for d_i in dp[i-j]:
dp[i].extend(list(map(lambda x:x+d_i, dp[j])))
dp[i].extend(list(map(lambda x:x-d_i, dp[j])))
dp[i].extend(list(map(lambda x:x*d_i, dp[j])))
try:
dp[i].extend(list(map(lambda x:x//d_i, dp[j])))
except:
continue
if number in dp[i]:
return i
return -1