일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 코테공부
- 리액트 공부정리
- 코딩테스트공부
- 프로그래머스파이썬
- 우박수열 정적분 파이썬
- 백준 DP 문제풀이
- 우박수열 파이썬
- 노마드코더 리액트 노트정리
- 노마드코더리액트
- 리액트 훅
- 2022카카오코테
- 17677 파이썬
- PostgreSQL
- 노마드코더 리액트
- 방금그곡 파이썬
- 프로그래머스 방금그곡
- 뉴스 클러스터링 파이썬
- 프로그래머스
- 코테 공부
- 백준문제풀이
- 프로그래머스 17677
- 리액트공부
- 백준 타일링 문제
- 프로그래머스 134239 파이썬
- 프로그래머스 우박수열
- 노마드코더
- 리액트 독학
- 프로그래머스 카카오코테
- 카카오코테
- 프로그래머스 17683 파이썬
- Today
- Total
My Develop Log
[프로그래머스] (연습문제) - 134239 우박수열 정적분 본문
문제 설명
콜라츠 추측이란 로타르 콜라츠(Lothar Collatz)가 1937년에 제기한 추측으로 모든 자연수 n에 대해 다음 작업을 반복하면 항상 1로 만들 수 있다는 추측입니다.
1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2.결과로 나온 수가 1보다 크다면 1번 작업을 반복합니다.
예를 들어 주어진 수가 5 라면 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒2 ⇒ 1 이되어 총 5번만에 1이 됩니다.
수가 커졌다 작아지기를 반복하는 모습이 비구름에서 빗방울이 오르락내리락하며 우박이 되는 모습과 비슷하다고 하여 우박수 또는 우박수열로 불리기도 합니다. 현재 이 추측이 참인지 거짓인지 증명되지 않았지만 약 1해까지의 수에서 반례가 없음이 밝혀져 있습니다.
은지는 우박수열을 좌표 평면 위에 꺾은선 그래프로 나타내보려고 합니다. 초항이 K인 우박수열이 있다면, x = 0일때 y = K이고 다음 우박수는 x = 1에 표시합니다. 이런 식으로 우박수가 1이 될 때까지 점들을 찍고 인접한 점들끼리 직선으로 연결하면 다음과 같이 꺾은선 그래프를 만들 수 있습니다.
은지는 이렇게 만든 꺾은선 그래프를 정적분 해보고 싶어졌습니다. x에 대한 어떤 범위 [a, b]가 주어진다면 이 범위에 대한 정적분 결과는 꺾은선 그래프와 x = a, x = b, y = 0 으로 둘러 쌓인 공간의 면적과 같습니다. 은지는 이것을 우박수열 정적분이라고 정의하였고 다양한 구간에 대해서 우박수열 정적분을 해보려고 합니다.
단, 우박수열 그래프의 가로축 길이를 미리 알 수 없기 때문에 구간의 시작은 음이 아닌 정수, 구간의 끝은 양이 아닌 정수로 표현합니다. 이는 각각 꺾은선 그래프가 시작하는 점과 끝나는 점의 x좌표에 대한 상대적인 오프셋을 의미합니다.
예를 들어, 5를 초항으로 하는 우박수열은 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒ 2 ⇒ 1 입니다. 이를 좌표 평면으로 옮기면 (0, 5), (1, 16), (2, 8), (3, 4), (4, 2), (5, 1) 에 점이 찍히고 점들을 연결하면 꺾은선 그래프가 나옵니다. 이를 [0,0] 구간에 대해 정적분 한다면 전체 구간에 대한 정적분이며, [1,-2] 구간에 대해 정적분 한다면 1 ≤ x ≤ 3인 구간에 대한 정적분입니다.
우박수의 초항 k와, 정적분을 구하는 구간들의 목록 ranges가 주어졌을 때 정적분의 결과 목록을 return 하도록 solution을 완성해주세요. 단, 주어진 구간의 시작점이 끝점보다 커서 유효하지 않은 구간이 주어질 수 있으며 이때의 정적분 결과는 -1로 정의합니다.
제한사항
- 2 ≤ k ≤ 10,000
- 1 ≤ ranges의 길이 ≤ 10,000
- 주어진 모든 입력에 대해 정적분의 결과는 227 을 넘지 않습니다.
- 본 문제는 정답에 실수형이 포함되는 문제입니다. 입출력 예의 소수 부분 .0이 코드 실행 버튼 클릭 후 나타나는 결괏값, 기댓값 표시와 다를 수 있습니다.
입출력 예
k | ranges | result |
5 | [[0,0],[0,-1],[2,-3],[3,-3]] | [33.0,31.5,0.0,-1.0] |
입출력 예 설명
입출력 예 #1
5로 시작하는 우박수열은 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒ 2 ⇒ 1 입니다. 그래프에서 꺾이는 지점을 경계로 5개의 구역으로 나눠보면 각각의 구간 넓이는 10.5, 12, 6, 3, 1.5 입니다.
문제 풀이
위에 문제를 해결하기 위해서
1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2.결과로 나온 수가 1보다 크다면 1번 작업을 반복합니다.
공식에 맞게 다음과 같이 함수를 만들어준다.
def checkSuyol(x):
xyData=[x]
while x>1:
if x % 2 == 0:
x/=2
else:
x=x*3+1
xyData.append(x)
return xyData
이후, 정적분을 구하려면 구간의 넓이를 구하면 되므로 규칙성을 찾아보면 다음과 같다.
이 규칙을 바탕으로 범위를 나눠주는 것이 관건인데 범위를 나눌때 문제를 이해하지 못해 시간을 많이 지체했다..⭐️
정적분 즉, 넓이를 구할 때, 좌측 x좌표가 우측 x좌표보다 클 경우 -1을 반환해야 한다.
예를 들면, k=6, range=[6, -3]이라 했을 때, [0+6, 8-3] = [6, 5]가 된다. 좌측 x가, 우측 x보다 크기 때문에 이때는 -1을 반환해야 한다.
코드로 조건을 통해 작성하면 다음과 같다.
if checkRange[0]+abs(checkRange[1])>len(xyData)-1:
total=-1.0
그 외에는 다음과 같이 범위를 처리해 주었다.
else:
for i in range(checkRange[0],len(xyData)+checkRange[1]-1):
total+=(xyData[i+1]-xyData[i])/2
total+=xyData[i]
다음 핵심 내용들을 바탕으로 종합해서 작성한 코드는 다음과 같다.
def checkSuyol(x):
xyData=[x]
while x>1:
if x % 2 == 0:
x/=2
else:
x=x*3+1
xyData.append(x)
return xyData
def solution(k, ranges):
answer = []
xyData=checkSuyol(k)
for checkRange in ranges:
total=0
if checkRange[0]+abs(checkRange[1])>len(xyData)-1:
total=-1.0
else:
for i in range(checkRange[0],len(xyData)+checkRange[1]-1):
total+=(xyData[i+1]-xyData[i])/2
total+=xyData[i]
answer.append(total)
return answer
print(solution(5,[[0,0],[0,-1],[2,-3],[3,-3]]),[33.0,31.5,0.0,-1.0])
Reference
https://school.programmers.co.kr/learn/courses/30/lessons/134239
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
'코테 공부 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] (2018 KAKAO BLIND RECRUITMENT) - 17683 [3차] 방금그곡 (0) | 2023.05.22 |
---|---|
[프로그래머스] 17677 [1차] 뉴스 클러스터링 (0) | 2023.04.25 |
[프로그래머스] 154539 뒤에 있는 큰 수 찾기 (0) | 2023.04.21 |
[프로그래머스] 155651 호텔 대실 (0) | 2023.04.12 |
[프로그래머스] 81301 숫자 문자열과 영단어 (0) | 2023.04.11 |