본문 바로가기

프로그래머스 - LV 0- 1일차 복습 본문

코딩테스트/프로그래머스 LV.0

프로그래머스 - LV 0- 1일차 복습

jaegomhoji 2024. 6. 4. 00:07

문제 1. 두 수의 차 

정수 num1과 num2가 주어질 때, num1에서 num2를 뺀 값을 return하도록 soltuion 함수를 완성해주세요.

제한사항
-50000 ≤ num1 ≤ 50000
-50000 ≤ num2 ≤ 50000

 

def solution(num1, num2):
    answer = (lambda num1, num2 : num1 - num2)(num1, num2)
    return answer

 

lambda 를 사용해서 간결하게 표현할 수 있다. 들어가는 수는 순서대로이다. 

(lambda x,y : x-y)(num1,num2)가 더 나은 코드. 

solution(2,1) # 1 

 

 

문제 2. 두 수의 곱 

정수 num1, num2가 매개변수 주어집니다. num1과 num2를 곱한 값을 return 하도록 solution 함수를 완성해주세요.

제한사항
0 ≤ num1 ≤ 100
0 ≤ num2 ≤ 100

 

def solution(num1:int, num2:int)->int:
    answer = num1 * num2
    return answer

 

solution(3,4) # 12

 

위와 마찬가지로, lambda를 사용하면 

def solution(num1:int, num2:int)->int:
    answer = (lambda x,y : x*y)(num1, num2)
    return answer

 

문제 3. 몫 구하기

정수 num1, num2가 매개변수로 주어질 때, num1을 num2로 나눈 몫을 return 하도록 solution 함수를 완성해주세요.

제한사항
0 < num1 ≤ 100
0 < num2 ≤ 100

 

def solution(num1, num2):
    assert num1 * num2 !=0
    answer = num1//num2
    return answer

사실 제한 사항을 잘 읽어보면, 주어진 변수 두 개 모두 0 초과라서 assert문은 필요가 없다. 그냥 사용해봄.

solution(3,2) # 1

 

문제 4. 숫자 비교하기

정수 num1과 num2가 매개변수로 주어집니다. 두 수가 같으면 1 다르면 -1을 retrun하도록 solution 함수를 완성해주세요.

제한사항
0 ≤ num1 ≤ 10,000
0 ≤ num2 ≤ 10,000
def solution(num1, num2):
    return 1 if num1==num2 else -1

굉장히 직관적인 파이썬의 one-line 코딩. 역시 보기 너무 좋다. 

 

문제 5. 나머지 구하기

정수 num1, num2가 매개변수로 주어질 때, num1를 num2로 나눈 나머지를 return 하도록 solution 함수를 완성해주세요.

 

간단하고 빠른 버전 O(1)

def solution1(num1, num2):
    answer = num1%num2
    return answer

 

느리고 안좋은 버전. O(n)

이런 문제에서는 while이나 for등의 조건문은 최대한 안쓰는 것이 좋다.

수가 커지니 time.time() 으로 10초 이상 차이 나기도 함. 

 

시간 복잡도 차이가 명확하다. 

def solution2(num1, num2):
    #return num1%num2
    while num1 >= num2:
        num1 -= num2
    return num1

 

 

문제 6. 나이 구하기 

머쓱이는 선생님이 몇 년도에 태어났는지 궁금해졌습니다.
2022년 기준 선생님의 나이 age가 주어질 때, 선생님의 출생 연도를 return 하는 solution 함수를 완성해주세요

0 < age ≤ 120
나이는 태어난 연도에 1살이며 매년 1월 1일마다 1살씩 증가합니다.

 

def solution(age):
    """
    태어난 해에 1살임.
    2022년도 기준으로 2022년도 출생은,
    2022 - 2022 = 0 이지만 +1 살임.
    따라서 현재연도+1이 되어야 함.
    """
    answer = 2023 - age 
    return answer

 

문제 7. 두 수의 합 

# 두 수의 합
정수 num1과 num2가 주어질 때, num1과 num2의 합을 return하도록 soltuion 함수를 완성해주세요.

-50,000 ≤ num1 ≤ 50,000
-50,000 ≤ num2 ≤ 50,000

 

쉬운 버전

def solution(num1, num2):
    answer = num1 + num2
    return answer

 

입력 튜플로 받아서 람다로 전부 더하기 

solution=lambda *x:sum(x)

 

문제 8. 배열의 평균 값 

정수 배열 numbers가 매개변수로 주어집니다. numbers의 원소의 평균값을 return하도록 solution 함수를 완성해주세요.

0 ≤ numbers의 원소 ≤ 1,000
1 ≤ numbers의 길이 ≤ 100
정답의 소수 부분이 .0 또는 .5인 경우만 입력으로 주어집니다.

 

def solution1(numbers):
    answer =0
    for x in numbers:
        answer += x
    answer /= len(numbers)
    return answer
solution([89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]) # 94 

 

이 방법 말고도, 

import numpy as np 

np.mean([array])도 가능하다 

 

이 방법도 가능하다. ( 숫자가 정렬되어 있고, 간격이 같아서 )

def solution2(numbers):
    num_len = len(numbers)
    answer = (numbers[0]+numbers[-1]) * (num_len /2)
    answer /= num_len
   
    if len(numbers) %2 !=0:
        answer = numbers[int((num_len -1) / 2)]

    return answer

 

10억 단위 이상으로 연산을 시키면, for문 O(n) 이 아래 index로 바로 접근하는 O(1)보다 2.5초 이상 느렸다.

 

문제 9. 각도기

각에서 0도 초과 90도 미만은 예각, 90도는 직각, 90도 초과 180도 미만은 둔각 180도는 평각으로 분류합니다.
각 angle이 매개변수로 주어질 때
예각일 때 1, 직각일 때 2, 둔각일 때 3, 평각일 때 4를 return하도록 solution 함수를 완성해주세요.

예각 : 0 < angle < 90
직각 : angle = 90
둔각 : 90 < angle < 180
평각 : angle = 180

제한사항
0 < angle ≤ 180
angle은 정수입니다

 

def solution(angle):
    answer = (angle // 90) * 2 + (angle % 90 > 0) * 1
    return answer

 

90도로 나눈 몫은 ( 0,1,2 ) * 2 -> ( 0, 2, 4 )로 바로 답. 

나머지가 있다면 True 일때 1, False일 때 0.

 

문제 10. 짝수의 합 

정수 n이 주어질 때, n이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.
0 < n ≤ 1000

 

3가지로 풀어봤다. 

 

1. 정직한 답. 

def solution(n):
    answer = 0
    for nums in range(1,n+1):
        if nums % 2 == 0:
            answer += nums
    return answer

 

 

2. list comprehension. 간결하고 직관적인 답. 

def solution(n):
    return sum([i for i in range(2, n + 1, 2)])

 

3. DP풀면서 썼던 memoization 사용. 복습. 어쨌든 점화식으로 표현 가능하니까 이렇게 풀 수 있다. 

i번째 배열의 항은 = i-1번째 배열의 항 + 2*i 이다. 

def solution(n):
    # n이 2 이하일 경우 바로 끝 
    if n < 2:
        return 0

    arr = [0] * (n // 2 + 1) # 짝수니까 배열은 반만 만들어도 된다. 
    arr[0] = 0 # 0번째 , 1번째는 미리 할당해놓는다. 
    arr[1] = 2

    for k in range(2, n // 2 + 1): # 2부터 끝까지 가자~ 
        arr[k] = arr[k - 1] + 2 * k # 점화식 

    return arr[n // 2]

 

문제 11. 양꼬치 

 

문제 12. 두 수의 나눗셈

정수 num1과 num2가 매개변수로 주어질 때,
num1을 num2로 나눈 값에 1,000을 곱한 후 정수 부분을 return

0 < num1 ≤ 100
0 < num2 ≤ 100

 

def solution(num1, num2):
    return int((num1/num2)*1000)

 

문제 13. 중복된 숫자 개수

정수가 담긴 배열 array와 정수 n이 매개변수로 주어질 때,
array에 n이 몇 개 있는 지를 return 하도록 solution 함수를 완성해보세요.

 

노가다

def solution(array:list, n:int)->int:
    cnt = 0
    for num in array:
        if num == n:
            cnt += 1
    return cnt

 

쉬운 길 

def solution(array, n):
    return array.count(n)

 

 

문제 14. 머쓱이보다 키 큰 사람 

머쓱이는 학교에서 키 순으로 줄을 설 때 몇 번째로 서야 하는지 궁금해졌습니다.
머쓱이네 반 친구들의 키가 담긴 정수 배열 array와 머쓱이의 키 height가 매개변수로 주어질 때,
머쓱이보다 키 큰 사람 수를 return 하도록 solution 함수를 완성해보세요.

1 ≤ array의 길이 ≤ 100
1 ≤ height ≤ 200
1 ≤ array의 원소 ≤ 200

 

array.sort()를 사용할 수 있었던 이유는, 배열의 길이가 100보다 작기 때문이다. 

O(n log n )을 해도 무방했음. 

def solution(array:list, height:int)->int:
    """
    정렬을 한 뒤, 처음으로 머쓱이보다 키 큰 사람이 나오는 인덱스를 찾고,

    전체 길이에서 빼주면 구할 수 있음

    """
    n = 0
    array.sort()

    while n < len:
        if array[n] > height:
            break
        n += 1
   
    answer = len(array) - n  
    return answer

 

def solution(array, height):
    """
    정렬을 하지 않는게 O(n) 임.
    정렬을 하면 O(n log n) 이다.

    작은 n 값에서는 O(n log n)과 O(n)의 차이가 크지 않을 수 있습니다.
    큰 n 값에서는 O(n log n)이 O(n)보다 더 큰 시간이 소요됩니다.
   
    n = 10인 경우, log(10) ≈ 2.3 따라서 n log n ≈ 10 * 2.3 = 23 , n log n(23) > n(10)
    n = 100인 경우, log(100) ≈ 4.6 따라서 n log n ≈ 100 * 4.6 = 460 , n log n (460) > n (100)
    n = 1000인 경우, log(1000) ≈ 6.9 따라서 n log n ≈ 1000 * 6.9 = 6900

    """
    return sum(1 for a in array if a > height)

array가 100까지기 때문에, 사실 100부터도 n log n > n 이지만, 큰 차이가 없었던 것이다. 

더 효율적으로 짜는 코드는 for문을 이용한 O(n)으로, 위와 같다. 

 

문제 15. 중앙값 구하기 

마찬가지로, array가 홀수이고 100보다 적은 경우 

다음과 같이 구할 수 있다. 

def solution(array):
    """
    정렬 후, 홀수라서
    중앙의 인덱스만 구하면 된다.

    힌트는 array의 길이가 < 100.

    만약 array의 길이가 > 10000 이상이었으면?
    """
    array.sort()
    return array[len(array)//2]

만약 array가 일정 크기 이상이라면, quick select 알고리즘으로 풀도록 하자. 

# 퀵 셀렉트 방식
https://devraphy.tistory.com/372 # 이 블로그 참고하기 

 

문제 16. 짝수는 싫어요

정수 n이 매개변수로 주어질 때,
n 이하의 홀수가 오름차순으로 담긴 배열을 return하도록
solution 함수를 완성해주세요.

1 ≤ n ≤ 100

 

1부터 2씩 증가시키면서 배열에 넣기

def solution(n):
    arr = []

    for i in range(1,n+1,2):
        arr.append(i)

    return arr

 

 

문제 17. 피자 나눠 먹기 1  

머쓱이네 피자가게는 피자를 일곱 조각으로 잘라 줍니다. 피자를 나눠먹을 사람의 수 n이 주어질 때,
모든 사람이 피자를 한 조각 이상 먹기 위해 필요한 피자의 수를 return 하는 solution 함수를 완성해보세요.

 

인원수/피자조각으로 몇 판이 필요한지 계산하고,  나머지가 있으면 1판을 더 더해준다. 

def solution(n):
    return n // 7 + ( 1 if n%7 > 0 else 0 )

 

GPT발 코드도 재밌다. 1명이어도 1판을 먹어야 되기 떄문에 ( n+6 = 7 )으로 1이 되게 해줬다.  

def solution(n):
 
    return (n+6) // 7

 

문제 18. 옷가게 할인 받기 

머쓱이네 옷가게는 10만 원 이상 사면 5%, 30만 원 이상 사면 10%, 50만 원 이상 사면 20%를 할인해줍니다.
구매한 옷의 가격 price가 주어질 때, 지불해야 할 금액을 return 하도록 solution 함수를 완성해보세요.

10 ≤ price ≤ 1,000,000
price는 10원 단위로(1의 자리가 0) 주어집니다.
소수점 이하를 버린 정수를 return합니다.

 

노가다 코드 

def solution(price):
    if price >= 500000:
        price *= 0.80

    elif price >= 300000:
        price *= 0.90

    elif price >= 100000:
        price *= 0.95
   
    return int(price)

 

# 결제가격 : 할인율의 형태로 얼마를 구매했을때 어느정도 할인받을 수 있는지 문제에 맞게 가독성이 좋아진 코드. 

# 내림차순으로 정렬을 해줘야 종료 시점이 알맞게 된다. 

# 일부러 딕셔너리를 큰 값부터 작은 값 찾으면 return하면서 종료되도록 정렬함.
def solution(price):
    discount_rates = {500000: 0.8, 300000: 0.9, 100000: 0.95, 0: 1}
 
   # dic.items()로 key 와 value를 받는다.
    for discount_price, discount_rate in discount_rates.items():
        # 만약 결제 가격이 할인가격의 key보다 같거나 크다면 ( 그 이상의 할인율이 적용되어야 한다 ) 
        if price >= discount_price:
       # 할인요금을 계산하여 반환하면서 종료. 
            return int(price * discount_rate)

 

문제 19. 아이스 아메리카노 , 특이사항 없음

def solution(money):
    return [ money // 5500 , money % 5500 ]

 

문제 20. 개미군단.

개미 군단이 사냥을 나가려고 합니다.
개미군단은 사냥감의 체력에 딱 맞는 병력을 데리고 나가려고 합니다.
장군개미는 5의 공격력을, 병정개미는 3의 공격력을 일개미는 1의 공격력을 가지고 있습니다.

예를 들어 체력 23의 여치를 사냥하려고 할 때, 일개미 23마리를 데리고 가도 되지만,
장군개미 네 마리와 병정개미 한 마리를 데리고 간다면 더 적은 병력으로 사냥할 수 있습니다.
사냥감의 체력 hp가 매개변수로 주어질 때,
사냥감의 체력에 딱 맞게 최소한의 병력을 구성하려면
몇 마리의 개미가 필요한지를 return하도록 solution 함수를 완성해주세요.

hp는 자연수입니다.
0 ≤ hp ≤ 1000

 

for + while문의 형태로 그리디 알고리즘을 사용해도 되는 문제이다. 동전 문제 ( 동전을 가장 적게 가져가려는 ~ )  

주어진 자원에서 양적으로 최소의 자원만 할당할 수 있을지에 관한 문제들이 비슷한 형태. 

def solution(hp):
    """
    # 딱 맞게 최소한의 병력
    # 그리디 알고리즘 , 동전 문제
    """
    ant_cnt = 0
    ant_attk = [5,3,1] # 순서는 내림차순 정렬되어야 한다. 

    for ants in ant_attk:
        much = (hp//ants) # 최대한 계산할 수 있는 만큼 큰 단위부터 계산, 몫 = 몇 마리인지.
        hp -= much*ants # 현재 피에서 까준다. 
        ant_cnt += much # 개미 수를 합산해준다.
 
    return ant_cnt

 

solution(999) # 201 
Comments