[프로그래머스] 기능개발: math.ceil 대체 수식

2024. 10. 5. 15:05·TIL
반응형

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

풀이1

def solution(progresses, speeds):
    answer = []
    days_left = [(100 - progresses[i] + speeds[i] -1) // speeds[i] for i in range(len(progresses))]
   
    day = days_left[0]
    cnt = 1
    
    for d in days_left[1:]: 
        if d <= day:
            cnt += 1
        else:
            answer.append(cnt)
            day = d
            cnt = 1
    
    answer.append(cnt)
    return answer

 

시간복잡도는 days_left 구할때 O(n), for문에서 O(n)

-> O(n)

zip을 이용해서 progresses랑 speeds를 한번에 돌면서 하고싶었는데

어떻게할지 모르겠음+문제 조건에서 리스트 길이가 100 이하래서

그냥 새로운 리스트 days_left를 따로 만들어서 풀었다

다른풀이1

from math import ceil

def solution(progresses, speeds):
    answer = []
    max_duration = ceil((100 - progresses[0]) / speeds[0])
    count = 0
    
    for progress, speed in zip(progresses, speeds):
        duration = ceil((100 - progress) / speed)
        # duration = -(-(100 - progress) // speed)
        if max_duration < duration:
            answer.append(count)
            count = 0
            max_duration = duration
        count += 1
    
    if count > 0:
        answer.append(count)
    
    return answer

 

처음에 풀려던 의도대로 해결한 풀이법

다른풀이2

def solution(progresses, speeds):
    Q = []
    for p, s in zip(progresses, speeds):
        days_left = (100 - p + s - 1) // s  # 남은 일수 계산 (올림 효과)
        if not Q or Q[-1][0] < days_left:
            Q.append([days_left, 1])  # 새로운 배포 그룹 시작
        else:
            Q[-1][1] += 1  # 같은 배포 그룹에 포함
    return [q[1] for q in Q]

 

zip() 이용한 풀이

2차원리스트 활용

비교: 이전 코드와의 차이점

  1. 첫 번째 코드 (기존 코드):
    • 각 작업이 완료될 일수를 계산한 후, 다시 한 번 순회하여 배포 가능한 작업들을 그룹화합니다.
    • 시간 복잡도는 O(n)입니다.
  2. 두 번째 코드 (새 코드):
    • zip을 이용해 한 번의 순회만으로 남은 일수 계산과 그룹화를 동시에 처리합니다.
    • 시간 복잡도는 O(n)입니다.

어떤 코드가 더 나은가?

  • 가독성: 첫 번째 코드는 각 단계를 명확히 나눠서 처리합니다. 첫 번째 코드는 각 작업의 완료 일수를 먼저 계산하고, 그 이후에 배포 가능 여부를 판단하는 구조라서 이해하기 쉽습니다. 반면, 두 번째 코드는 한 번의 루프에서 모든 것을 처리하기 때문에 다소 복잡하게 느껴질 수 있습니다.
  • 성능: 두 코드는 모두 시간 복잡도가 O(n)으로 동일하므로, 입력 크기 n에 따른 성능 차이는 크지 않습니다. 하지만 두 번째 코드는 그룹화를 계산하는 과정을 반복해서 처리하지 않고, 한 번의 루프에서 모든 것을 해결하므로 약간 더 효율적입니다.

결론

  • 첫 번째 코드는 가독성이 좋고, 직관적으로 단계별로 문제를 해결하는 방식입니다.
  • 두 번째 코드는 한 번의 루프에서 작업을 처리하므로, 효율성이 조금 더 뛰어납니다. 단, 가독성 측면에서 약간 불리할 수 있습니다.

따라서, 두 번째 코드가 미세하게 더 효율적일 수 있지만, 코드의 명확성과 유지보수성을 고려하면 프로젝트 상황에 따라 두 코드 중 선택할 수 있습니다.

 

math.ceil

원래 math.ceil()함수를 사용해서 풀었는데 챗지피티가 다른 방법을 알려주었다

# import math
# math.ceil((x - p) / s)

# 대신 아래 식으로 쓸 수 있다

(x - p + s - 1) // s

 

  • 함수 호출 비용: math.ceil은 Python에서 함수를 호출하는 것이므로, 함수 호출에 대한 오버헤드가 발생합니다. 이 오버헤드는 특히 반복문 안에서 호출할 경우 성능에 영향을 미칠 수 있습니다.
  • 산술 연산: 반면, (x - p + s - 1) // s는 단순한 산술 연산이므로, 계산이 더 빠르게 수행됩니다. 이 방식은 일반적으로 상수 시간 O(1)로 처리됩니다.

 

또 -((p - 100) // s)로 푸는 방법도 있었는데 가독성과 미미한 성능의 차이에서 모두(x-p+s-1)//s가 낫다고 한다.

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'TIL' 카테고리의 다른 글

[프로그래머스] 예산: O(n^2) -> O(n log n)  (1) 2024.10.05
[프로그래머스] 큰 수 만들기: 문자열보다 리스트 사용하기  (0) 2024.10.03
[프로그래머스/SQL] 가격이 제일 비싼 식품의 정보 출력하기: 정렬 vs 서브쿼리  (0) 2024.07.26
NestJS | TypeORM: entity 정의(soft delete, 추상클래스)  (0) 2022.11.21
NestJS | @nestjs/config 패키지를 활용한 환경변수 관리 -> db연결  (0) 2022.11.21
'TIL' 카테고리의 다른 글
  • [프로그래머스] 예산: O(n^2) -> O(n log n)
  • [프로그래머스] 큰 수 만들기: 문자열보다 리스트 사용하기
  • [프로그래머스/SQL] 가격이 제일 비싼 식품의 정보 출력하기: 정렬 vs 서브쿼리
  • NestJS | TypeORM: entity 정의(soft delete, 추상클래스)
이라후
이라후
  • 이라후
    화이팅
    이라후
  • 전체
    오늘
    어제
    • 분류 전체보기 (133)
      • TIL (23)
      • 기타 (26)
      • Python (14)
      • Django (10)
      • JavaScript (8)
      • git & GitHub (8)
      • Web (10)
      • Go (3)
      • wecode (31)
  • 반응형
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
이라후
[프로그래머스] 기능개발: math.ceil 대체 수식
상단으로

티스토리툴바