문제
수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다.
리모컨에는 버튼이 0부터 9까지 숫자, +와 -가 있다. +를 누르면 현재 보고있는 채널에서 +1된 채널로 이동하고, -를 누르면 -1된 채널로 이동한다. 채널 0에서 -를 누른 경우에는 채널이 변하지 않고, 채널은 무한대 만큼 있다.
수빈이가 지금 이동하려고 하는 채널은 N이다. 어떤 버튼이 고장났는지 주어졌을 때, 채널 N으로 이동하기 위해서 버튼을 최소 몇 번 눌러야하는지 구하는 프로그램을 작성하시오.
수빈이가 지금 보고 있는 채널은 100번이다.
아이디어
- 주어진 리모컨 버튼(+, - 제외)으로 목표하는 채널 L과 가장 가까운 숫자 E로 가야 한다.
- 목표하는 채널의 자릿수가 5자리 숫자라면, 4~6자리수 숫자 중, 목표 숫자와 가장 가까운 숫자 E를 찾는다. 이때 E는 주어진 버튼으로 만들 수 있는 중복순열 중 하나이다.
- {(E의 길이) + (L-E)}, 즉 숫자 버튼과 +, - 버튼을 조합해서 E로 도달하는 경우와 오직 +, -버튼만 이용해서 E로 도달하는 수 중 더 짧은 숫자를 출력한다.
코드
from itertools import product
obj=input()
x = input()
wr = ""
if x != "0":
wr=input()
wrecks=[a for a in wr.strip().split()]
buttons=[str(a) for a in range(10) if str(a) not in wrecks]
target_len=range(max(1,len(obj)-1),len(obj)+2)
obj=int(obj)
tick=abs(100-obj)
nearest=100
for l in target_len:
p=[int("".join(a)) for a in product(buttons, repeat=l)]
for k in p:
if abs(k-obj)<abs(nearest-obj):
nearest=k
tick=min(abs(obj-nearest)+len(str(nearest)), tick)
print(tick)