Skip to content

Commit 0285dd4

Browse files
committed
programmers.co.kr 코딩테스트 연습_동적계획법(Dynamic Programming)_N으로 표현
문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/42895
1 parent e809d16 commit 0285dd4

File tree

2 files changed

+118
-0
lines changed
  • programmers.co.kr 코딩테스트 연습_동적계획법(Dynamic Programming)_N으로 표현

2 files changed

+118
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import copy
2+
from collections import defaultdict
3+
from typing import List, Dict
4+
5+
6+
def solution(N: int, number: int):
7+
# X / N 의 값이 number의 최소값이 될 수 있음
8+
# 따라서, number * N + 1 이 dp의 최소 길이
9+
l = number * N + 1
10+
dp: List[int] = [9] * l
11+
12+
dp[N] = 1
13+
dp[1] = min(dp[1], 2) # N/N, N이 1인 경우도 고려해서, min()이 필요함
14+
15+
# NN, NNN등의 숫자 처리필요함
16+
str = '{:d}'.format(N)
17+
cntN = 1
18+
19+
while int(str) <= l:
20+
dp[int(str)] = min(dp[int(str)], cntN)
21+
str += '{:d}'.format(N)
22+
cntN += 1
23+
24+
def do_plus():
25+
for i in range(l - 1, 0, -1):
26+
if dp[i] <= 8 and 1 <= i + N < l:
27+
dp[i + N] = min(dp[i + N], dp[i] + 1)
28+
29+
def do_multiply():
30+
for i in range(l - 1, 0, -1):
31+
if dp[i] <= 8 and 1 <= i * N < l:
32+
dp[i * N] = min(dp[i * N], dp[i] + 1)
33+
34+
def do_minus():
35+
for i in range(1, l):
36+
if dp[i] <= 8 and 1 <= i - N < l:
37+
dp[i - N] = min(dp[i - N], dp[i] + 1)
38+
39+
def do_divide():
40+
for i in range(1, l):
41+
if dp[i] <= 8 and 1 <= i // N < l:
42+
dp[i // N] = min(dp[i // N], dp[i] + 1)
43+
44+
for _ in range(8):
45+
do_plus()
46+
do_multiply()
47+
do_minus()
48+
do_divide()
49+
50+
dict: Dict = defaultdict(lambda: 9)
51+
52+
for i in range(1, l):
53+
if dp[i] > 8:
54+
continue
55+
else:
56+
dict[i] = dp[i]
57+
58+
dict_local: Dict = copy.deepcopy(dict)
59+
li = list(dict.keys())
60+
lj = list(dict.keys())
61+
li.sort()
62+
lj.sort()
63+
64+
for i in li:
65+
for j in lj:
66+
if i == j:
67+
continue
68+
69+
vs = [i + j, i * j, i // j, i - j,
70+
j + i, j * i, j // i, j - i]
71+
for v in vs:
72+
if 1 <= v < l:
73+
dict_local[v] = min(dict_local[v], dict[i] + dict[j])
74+
if dict_local[v] > 8:
75+
del dict_local[v]
76+
77+
dict = dict_local
78+
79+
if dict[number] > 8:
80+
return -1
81+
82+
return dict[number]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from unittest import TestCase
2+
from main import solution
3+
4+
5+
class Test(TestCase):
6+
def test1_solution(self):
7+
self.assertEqual(4, solution(5, 12))
8+
9+
def test2_solution(self):
10+
self.assertEqual(3, solution(2, 11))
11+
12+
def testa_solution(self):
13+
self.assertEqual(-1, solution(5, 31168))
14+
15+
# https://school.programmers.co.kr/questions/30926
16+
# 4, 31
17+
# (4 + 4) * 4 - (4 / 4)
18+
def test_a1_solution(self):
19+
self.assertEqual(5, solution(4, 31))
20+
21+
# https://school.programmers.co.kr/questions/56476
22+
def test_b1_solution(self):
23+
self.assertEqual(4, solution(1, 121))
24+
25+
def test_b2_solution(self):
26+
self.assertEqual(4, solution(5, 3025))
27+
28+
def test_b3_solution(self):
29+
self.assertEqual(5, solution(5, 3125))
30+
31+
# def test_b4_solution(self):
32+
# self.assertEqual(2, solution(9, 0))
33+
34+
# https://school.programmers.co.kr/questions/43922
35+
def test_c1_solution(self):
36+
self.assertEqual(3, solution(6, 5))

0 commit comments

Comments
 (0)