🔒 문제
https://codingdojang.com/scode/514?answer=17578
일련의 숫자가 있고, 이 숫자는 1씩 증가, 또는 감소한다. n번째의 숫자가 있을 시에, 이 숫자가 7의 배수(7, 14, 21,...)거나 7이란 숫자를 포함할 시에 (7, 17, 27,...) 방향을 바꾼다.
즉, 다음과 같이 숫자는 진행한다.
1,2,3,4,5,6,[7],6,5,4,3,2,1,[0],1,2,[3],2,1,0,[-1],0,1
(첫 번째 7은 7번째, 두번째 0은 14번째, 세번째 3은 17번째, 네번째 -1은 21번째)
이와 같은 pingpong(x)의 함수를 작성하라. 예시의 인풋과 아웃풋은 다음과 같다.
pingpong(8) = 6
pingpong(22) = 0
pingpong(68) = 2
pingpong(100) = 2
심화학습
위 문제에 다음과 같은 제약을 추가하여 다시 풀어보자.
- For Loop 또는 Array를 쓰지 말 것
- Assignment를 쓰지 말 것, 즉, 변수 할당을 하지 말 것.
- String을 쓰지 말 것
🔓 풀이
🔑 문제 해결 / 코드
"""
2. 핑퐁 게임 (반드시 Python으로 작성할 것)
일련의 숫자가 있고, 이 숫자는 1씩 증가, 또는 감소한다. N 번째의 숫자가 있을 시에,
이 숫자가 7의 배수(7, 14, 21)이거나 7이란 숫자를 포함할 시에 (7, 17, 27) 방향을 바꾼다.
즉, 1, 2, 3, 4, 5, 6, [7], 6, 5, 4, 3, 2, 1, [0], 1, 2, [3], 2, 1, 0, [-1], 0, 1
과 같이 숫자는 진행한다. (첫번째 7은 7번째, 두번째 0은 14번째, 세번째 3은 17번째, 네번째 -1은 21번째)
다음의 제약 하에 pingpong(x)의 함수를 작성하라. 예시의 인풋과 아웃풋은 다음과 같다.
pingpong(8) = 6
pingpong(22)=0
pingpong(68)=2
pingpong(100)=2
@@@@ 주의사항 @@@
- For Loop / While 또는 Array를 쓰지 말 것
- Assignment 를 쓰지 말 것. 즉, 변수 할당을 하지 말 것.
- 스트링을 쓰지 말 것.
"""
"""
- 비고 -
기본적으로는 1씩 더하지만 7의 배수 or 7이 들어간 수를 만나면 1씩 빼는 재귀함수
n = 0
m = 1
n += m // 기본
m = m * -1
n += m
# 주어지는 정수의 범위가 정해져있지 않아서 정수의 자릿수에 따라 조건이 바뀌게 만들어봤는데
python에서는 최대 재귀 깊이가 1,000으로 정해져 있어서 RecursionError에러 발생
사용 가능한 정수 범위 ( N <= 997 )
"""
import math
# x 목표 반복 횟수, y 현재 반복 횟수, z 상태(+ or -), a 결과, b 현재 반복 횟수의 자릿수
def recursive(x, y, z, a, b):
# 재귀함수 종료 조건 // 목표 반복 횟수와 현재 반복 횟수가 일치하면 종료
if x == y:
# 지금까지 더하거나 뺀 결과 리턴
return a
# 7의 배수인 경우
if y % 7 == 0:
# 조건 충족 시 상태를 반대로 바꿔주고 결과도 바뀐 상태 반영
return recursive(x, y+1, -z, a-z, int(math.log10(y+1)))
# 끝자리가 7인경우
elif y % 10 == 7:
return recursive(x, y+1, -z, a-z, int(math.log10(y+1)))
# 자릿수가 0보다 클때 // 반복 횟수가 10 이상인 경우
elif b > 0:
# 자릿수가 1: 80 > n >= 70, 2: 800 > n % 1000 >= 700
if (8*(10**b)) > y % (10*(10**b)) >= (7*(10**b)):
return recursive(x, y+1, -z, a-z, int(math.log10(y+1)))
# 조건 미충족 시 상태변환 x, 결과에 그대로 반영
return recursive(x, y+1, z, a+z, int(math.log10(y+1)))
# 사용 가능한 정수 범위 ( N <= 997 )
def pingpong(x):
if x < 1:
return 0
return recursive(x, 1, 1, 1, int(math.log10(1)))
answer_dict = {8: 6, 22: 0, 68: 2, 100: 2}
for i in answer_dict:
answer = pingpong(i)
if answer == answer_dict[i]:
print(f"answer: {answer} 정답")
else:
print(f"answer: {answer} 오답")
print(pingpong(997))
💉 피드백
주어지는 정수 N의 범위가 정해져 있지 않아서 N의 크기(자릿수)에 따라 조건문 범위를 조절하려고 머리를 쥐어짰는데 python에서 최대 재귀 깊이는 1000까지여서 쓸데없는 고민이었다.
그래도 math 모듈의 log10(x) 함수를 배울 수 있어서 다행
위 코드에서는 1000이 아닌 997을 초과한 정수를 입력하면 에러가 뜨는데 pingpong 함수가 다른 함수를 호출해서 그런 거다.
'알고리즘' 카테고리의 다른 글
[프로그래머스] 예산_Python level1 (0) | 2022.05.20 |
---|---|
[프로그래머스] 3진법 뒤집기_Python level1 (0) | 2022.05.19 |
[기술 테스트 과제] poker hands_python (0) | 2022.05.09 |
[프로그래머스] 실패율_python (0) | 2022.05.02 |
[프로그래머스] 약수의 개수와 덧셈_Python (0) | 2022.05.02 |