[kata][python] 한수 구하기
- 3 mins1보다 크고 N보다 작거나 같은 정수중에 한수가 몇개인지 구하기
출처: 백준 알고리즘 1065번 문제
일단 원문의 문제를 그대로 옮기면 다음과 같다.
“어떤 양의 정수 X의 자리수가 등차수열을 이룬다면, 그 수를 한수라고 한다.
등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다.
N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나 같은 한수의 개수를 출력하는 프로그램을 작성하시오.”
난 처음에 문제 자체가 잘 이해가 안됐었다.
일단 한수의 정의부터 확실히 알아야하는데,
예를들어 123이라는 숫자가 있다면 1,2,3이 공차가 +1인 등차수열을 이루므로 이는 한수이다.
630 이라는 숫자도 6,3,0이 공차가 -3인 등차수열을 이루므로 한수이다.
그럼 세 자리수 이상의 숫자에서 한수가 무엇인지 찾아내는 방법은 알겠는데,
한 자리수와 두 자리 숫자의 경우는 어떻게 따져봐야할까?
한자리 숫자와 두자리 숫자는 무조건 한수이다.
1~9는 비교대상이 없으므로 그냥 한수로 치고,
11~99도 항상 두 개의 숫자로만 비교하므로 한수로 친다.
예를들어 11은 공차가 0인 등차수열, 13은 동차가 2인 등차수열, 82는 공차가 -6인 등차수열이다.
입력
110
출력
99
110보다 작은 자연수중에 1부터 99까지는 무조건 한수이므로 일단 한수는 99개다.
그리고 100부터 110 사이의 자연수중에 한수는 존재하지 않으므로 출력값은 그대로 99가 된 것이다.
내 풀이
1 # -*- coding: utf-8 -*-
2
3 import sys
4
5 N = int(sys.stdin.readline())
6 han = 0
7
8 def is_han(num):
9 num = str(num)
10 return True if (int(num[1]) - int(num[0])) == (int(num[2]) - int(num[1])) else False
11
12
13 for i in range(N):
14 if i+1 < 100:
15 han += 1
16 elif is_han(i+1):
17 han += 1
18
19 print(han)
5번쨰 라인에서 숫자를 받고, 6번째 라인에서 한수의 갯수를 카운팅할 변수를 0으로 초기화했다.
8번째 줄에 한수 여부를 검증하는 함수를 정의했다.
입력값이 1000보다 작은 정수라는 제한조건이 있어서 세 자리 수에 대한 처리만 해주었다.
(두 번쨰 자리수와 첫 번쨰 자리수의 차이)가 (세 번쨰 자리수와 두 번쨰 자리수의 차이)와 (같다면), 한수로 간주해 True를 반환했다.
13번째 줄에서 입력받은 정수 N만큼 iteration을 돌렸다.
파이썬의 인덱스가 0부터 시작하므로, i에 1을 더해서 비교했다.
우선 1부터 99까지는 무조건 한수로 취급하므로 변수에 1씩 더해주었다.
그리고 그 이외의 숫자(세자리수)에 앞서 정의한 함수를 적용시켜 한수 여부를 판별했다.
다른사람 풀이
print(sum(i//100+i%10==i//10%10*2 or i<100 for i in range(1,int(input())+1)))
입력받은 숫자만큼 for문을 돌며,
1의자리수와 100의자리수를 더한 값이 10의자리수에 2를 곱한 값과 같다면 True,
혹은 i가 100보다 작다면 True를 반환했다.
마지막으로 True를 모두 더해서 한수의 총 갯수를 구했다. (True는 숫자 1로 취급된다)
분석
정답을 맞춘 사람들의 코드를 하나하나 살펴보다가, 매우 인상적인 코드가 있어서 가져왔다.
물론 가독성이 좋은 코드는 아니라고 생각하지만, 이해하는데 크게 무리는 없는 수준인 것 같다.
입력받은 숫자를 for문 돌면서, i가 100보다 작으면 True를 반환하는 것은 그렇다 쳐도,
세자리수 등차수열에서 첫번째 자리와 세번쨰 자리수를 더한 값이 두 번째 자리수에 2를 곱한것과 같다라는 것을 활용한 접근방법이 신선했다.
그리고 일단 한줄로 처리한 것이 뭔가 상당히 cool해 보였다;;