프로그래머스 카펫
문제 설명
Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.

Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.
Leo가 본 카펫에서 갈색 격자의 수 brown, 노란색 격자의 수 yellow가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.
[제한사항]
- 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
- 노란색 격자의 수 yellow는 1 이상 2,000,000 이하인 자연수입니다.
- 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.
[입출력 예]
| brown | yellow | return |
|---|
| 10 | 2 | [4, 3] |
| 8 | 1 | [3, 3] |
| 24 | 24 | [8, 6] |
문제 해석하기
- brown이 10개이고 yellow가 2이면 가운데가 2이고 나머지 테두리 한 줄 부분이 모두 brown이라는 뜻이다.
- 그러면 가로(4) + 세로(3)라고 판단할 수 있다.
- yellow를 바탕으로 2이면, 가로 길이는 결국 yellow + 양쪽으로 +2가 되는것이고 가로는 위 아래 2개가 있기 때문에 (yellow+2)*2라는 것을 알수 있다.
- 세로의 경우 yellow가 2인 경우 사진 처럼 가로로 누워서 2개가 연결되어있다고 생각하면, 세로 부분으로는 1이 위 아래로 2개 있다고 생각하면된다.
- 다른 예시를 바탕으로 가로 세로를 한번 더 확인해본다.
- yellow가 1이면, 하나만 있는 것이므로, (yellow+2)*2를 통해서 위 아래 가로 길이의 합이 6임을 알 수 있다.
- 또한, 세로의 길이도 yellow가 1이므로 1+1+1로 3임을 알 수 있다.
- 결론적으로 brown의 총 개수는 8이 된다.
- 가로와 세로 길이를 출력해야 하기 때문에, 가로 길이는 (yellow+2), 세로 길이는 1이지만 위의 2개를 포함해서 3개 라는 식으로 적어주면 된다.
- 마지막으로, 24,24 관련해서 확인해보는데 위와는 다르게 생각해야 된다는점을 확인했다.
- 무조건적으로 세로는 3이고, 가로 길이로 brown 개수를 판단하려했지만, 세로의 길이가 항상 3은 아니라는 것을 간과했다.
- 따라서, 이 문제를 해결하기 위해서는 yellow를 소인수 분해해서 가로와 세로를 구해야한다는 점을 깨달았다.
이런식으로 일단 기초 베이스를 쌓고 어떻게 구현해나갈지 생각해보았다.
규칙은 yellow를 기준으로 하고 있다.
- yellow의 가로 길이(
w)와 세로 길이(h)의 모든 조합이 필요하다. 이때, w와 h는 yellow를 소인수 분해한 결과이다.
- yellow의 가로와 세로에 각각 2를 더하면 전체 카펫의 가로 길이와 세로 길이가 된다.
- 해당 내용을 가지고 총 brown과 yellow 개수를 확인하며 검증이 가능하다
- 카펫의 가로 길이는 세로 길이와 같거나 더 길어야 한다. 따라서, 이를 만족하는 조합만 반환하도록 한다.
def solution(brown, yellow):
for h in range(1, int(yellow**0.5) + 1):
if yellow % h == 0:
w = yellow // h
total_width = w + 2
total_height = h + 2
if total_width * total_height - yellow == brown:
return [total_width, total_height]
오늘의 회고
예시를 하나씩 확인하면서 문제를 해결해나가는 과정에서 예외가 항상 발생하는 것을 알 수 있다. 이 예외를 놓치지 않고 찾아서 새로운 방식으로 코드를 작성하는 것이 가장 중요하다는 것을 다시 한번 느낄 수 있었다.