[TIL #33] 마법의 엘리베이터

2024. 11. 20. 17:55·Camp/T.I.L.

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
'Camp/T.I.L.' 카테고리의 다른 글
  • [TIL #35] 데드락에 죽다 살다
  • [TIL #34] Docker 및 Docker Compose 올려보기
  • [TIL #32] 자바스크립트와 싱글톤
  • [TIL #31] 상태 업데이트의 벽
BVM
BVM
  • BVM
    E:\
    BVM
  • 전체
    오늘
    어제
    • 분류 전체보기 (168)
      • Thoughts (14)
      • Study (69)
        • Japanese (3)
        • C++ & C# (46)
        • Javascript (3)
        • Python (14)
        • Others (3)
      • Play (1)
        • Battlefield (1)
      • Others (11)
      • Camp (73)
        • T.I.L. (57)
        • Temp (1)
        • Standard (10)
        • Challenge (3)
        • Project (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 본 블로그 개설의 목적
  • 인기 글

  • 태그

    FF14
    C++
    OSI
    Server
    JS
    포인터
    암호화
    Asio
    네트워크 프로그래밍
    c#
    스타필드
    discord
    boost
    7계층
    IOCP
    Selenium
    서버
    로깅
    Network
    클라우드
    Python
    discord py
    db
    bot
    cloudtype
    베데스다
    프로그래머스
    docker
    Dalamud
    네트워크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
BVM
[TIL #33] 마법의 엘리베이터
상단으로

티스토리툴바