https://school.programmers.co.kr/learn/courses/30/lessons/148653
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
모듈러 뺑뺑이 돌리는 문제.
접근법은 명확한데, 특정 테스트 케이스를 통과하지 못해서 평소보다 많은 시간을 투자했다.
먼저 첫 접근부터.
// 음수층은 없음
// 하지만 음수층이 있는 것 처럼 생각 가능
// 모듈러 지옥
function solution(storey) {
let total = 0;
let carry = 0;
while (storey > 0) {
let digit = (storey % 10) + carry; // 현재 자릿수 + 캐리
if (digit <= 5) {
total += digit; // -1 버튼을 digit번 누름
carry = 0; // 캐리 초기화
} else {
total += (10 - digit);
carry = 1; // 다음 자릿수로 캐리
}
storey = Math.floor(storey / 10); // 다음 자릿수로 이동
}
if (carry === 1) {
total += 1; // 남아있는 캐리 처리
}
return total;
}
솔직히 이거면 문제가 없어야 한다고 생각했다.
하지만 문제가 있었고...
당장 질문하기로 가서 유사한 문제를 찾아보자.
아하...
기존 코드대로라면 5를 더하고 20을 더하고 500을 빼기 때문에 12가 나온다.
여기서 필요한 건 다음 자릿수가 5 이상인지도 고려하는 것이다.
445였다면 그냥 5를 빼고, 그다음 자릿수도 5 이하이기 때문에 빼는 흐름이 됐을 것이다.
하지만 8로 5보다 크기 때문에 이 점도 고려가 되어야 한다.
그리고 다음의 설명도 많은 도움이 됐다.
사실 같은 말을 하고 있는 것과 같다.
이 점을 반영하면 다음과 같은 결과가 나온다.
function solution(storey) {
let answer = 0;
while (storey !== 0) {
let current = storey % 10; // 현재 자릿수
let next = Math.floor((storey % 100) / 10); // 다음 자릿수
if (current > 5) {
// 현재 자릿수가 5보다 크면 위로 올라가는 게 이득
answer += (10 - current);
storey += (10 - current);
} else if (current === 5 && next >= 5) {
// 현재 자릿수가 5이고 다음 자릿수가 5 이상이면 위로 올라가는 게 이득
answer += 5;
storey += 5;
} else {
// 그 외의 경우는 아래로 내려가는 게 이득
answer += current;
}
// 다음 자릿수로 이동
storey = Math.floor(storey / 10);
}
return answer;
}
층수가 1억 이하기 때문에 큰 부하가 걸리진 않는다.
아무리 문제의 스토리텔링이라도 그렇지 이건 머리에 문제가 있는 게 아닌가?
다른 사람은 어떻게 풀었는지도 함 봐줘야 한다.
그 해법은 다음과 같았다.
function solution(storey) {
// 기저 조건: 5 미만이면 그대로 반환
if (storey < 5) return storey;
// 현재 자릿수의 값 구하기
const r = storey % 10;
// 현재 자릿수를 제외한 나머지 숫자
const m = (storey - r) / 10;
// 두 가지 선택지 중 최소값 반환:
// 1. 아래로 내려가기: 현재 자릿수(r)만큼 내려가고 나머지 숫자(m)에 대해 재귀
// 2. 위로 올라가기: (10-r)만큼 올라가고 다음 숫자(m+1)에 대해 재귀
return Math.min(r + solution(m), 10 - r + solution(m + 1));
}
매우 간결한 코드다.
제한 사항은 1억이기 때문에 스택이 터질 일도 없다.
``Math.min()``을 통한 분기도 아까의 설명글에서 설명했던 그대로다.
프로그래머스는 가독성이 나빠도 코드가 짧기만 하면 추앙하는 이상한 사람들이 많은데,
이러한 진짜 간결하고 흐름이 보이는 코드가 좋은 코드가 아닐까.
'Camp > T.I.L.' 카테고리의 다른 글
[TIL #35] 데드락에 죽다 살다 (0) | 2024.12.15 |
---|---|
[TIL #34] Docker 및 Docker Compose 올려보기 (0) | 2024.12.03 |
[TIL #32] 자바스크립트와 싱글톤 (0) | 2024.11.18 |
[TIL #31] 상태 업데이트의 벽 (0) | 2024.10.31 |
[TIL #30] 모의 면접을 준비하며 (0) | 2024.10.30 |