문제
어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.
내 코드
s = []
def finds(n):
for i in range(1, int(n) + 1):
x = list(map(int, str(i)))[1:]
y = list(map(int, str(i)))[:-1]
gap = set(map(lambda x,y:x-y, x, y))
if len(gap) == 1 or len(gap) == 0:
s.append(i)
n = input()
finds(n)
print(len(s))
과정
별다른 방법이 생각나지 않았기 때문에 입력받은 n 이하의 자연수 중 한수를 하나하나 찾는 방법을 선택했다.
1) 자릿수 분리 및 공차 계산을 위한 리스트 슬라이싱
저번 셀프 넘버 문제를 풀 때와 다르게, map을 이용해 숫자의 자릿수를 분리했다. input()으로 입력받는 값은 문자열로 취급되기 때문에 정수로 사용해야 할 때와 문자열로 사용해야 할 때를 잘 구분해 형변환을 해줬다.
나는 반복문을 돌며 앞 인덱스와의 차를 계산하는 것이 아니라 길이가 동일한 리스트 두 개를 만들어 공차를 한 번에 계산하고 싶었기 때문에 x, y 두 개의 리스트를 만들었다. 각각 자릿수 리스트에서 첫 번째 요소가 빠진 리스트와 마지막 요소가 빠진 리스트다.
2) 람다 함수를 이용해 공차를 계산한 후 set에 넣기
최근에 자주 썼던 JS에는 익명 함수라는 개념이 있다. 예전에 들었던 수업에서 파이썬의 익명 함수에 관한 내용을 배웠던 기억이 있어서 이 문제에 적용해 봤다. 앞서 만든 리스트 x, y의 각 요소를 순회하며 차를 계산하도록 함수를 작성했는데, 리스트를 두 개 만든 것이 이 과정을 위해서였다.
이렇게 계산한 공차는 gap이라는 set에 집어넣었다. python에서 set은 순서가 없으며, 중복된 요소가 없다는 특징이 있다. 바로 이 점을 이용해서 해당 숫자가 한수인지를 판별했다.
3) gap의 길이를 계산해 한수 판별
gap의 길이가 1일 경우 모든 자릿수 간의 차가 동일하다는 의미다. 단, 한 자릿수의 경우 gap의 길이가 0이기 때문에 이 경우까지 포함해 한수 여부를 판별한 후 전역 리스트 s에 한수를 추가했다.
...
저번 문제를 풀 때는 기본적인 문법만 이용해 문제를 해결하려고 했었지만 이번에는 보다 다양한 개념(set, map 등)을 활용하려고 노력했다. 최선의 방법은 아닐 수 있지만 단순 반복문보다는 효율적인 것 같아 뿌듯하다.
'Algorithm' 카테고리의 다른 글
[1018] 체스판 다시 칠하기 - Python (0) | 2022.01.26 |
---|---|
[1004] 어린 왕자 - Python (0) | 2022.01.24 |
[9461] 파도반 수열 - Python (0) | 2022.01.24 |
[11729] 하노이 탑 - Python (2) | 2022.01.23 |
[4673] 셀프 넘버 - Python (1) | 2022.01.20 |