[Coding Study]

프로그래머스 Study 5주차

jjinyeok 2023. 7. 9. 00:11

개인정보 수집 유효기간 - 2023 KAKAO BLIND RECRUITMENT, Level1

# 날짜 ➔ integer
def solution(today, terms, privacies):
    
    answer = []
    
    year, month, day = map(int, today.split('.'))
    today = year * 12 * 28 + month * 28 + day
    
    terms_dic = {}
    for temp in terms:
        term, month = temp.split()
        terms_dic[term] = int(month) * 28
        
    for idx, temp in enumerate(privacies):
        date, term = temp.split()
        year, month, day = map(int, date.split('.'))
        expired_date = year * 12 * 28 + month * 28 + day + terms_dic[term]
        
        if expired_date <= today:
            answer.append(idx + 1)
    
    return answer

1. 개인정보 수집일자를 정수로 변환한다.

    1.1) 모든 달은 28일까지 있다고 가정합니다. → 정수형 날짜 = 12 * 28 * year + 28 * month + day

2. 마찬가지 방법으로 유효기간도 정수로 변환한다.

3. 개인정보 수집일자와 유효기간을 비교하며 정답을 구한다.

 

이모티콘 할인행사 - 2023 KAKAO BLIND RECRUITMENT, Level2

from itertools import product

def solution(users, emoticons):
    # answers: 정답, n: 사용자 수, m: 이모티콘 수
    answers, n, m = [], len(users), len(emoticons)
    
    # discount_rates: emoticons에 대한 할인율 리스트
    discount_rates = list(product([10, 20, 30, 40], repeat=m))
    
    for discount_rate in discount_rates:
        prices = [] # prices: 할인율을 적용한 이모티콘 가격
        for i in range(m):
            prices.append(emoticons[i] * (100 - discount_rate[i]) // 100)
        
        # total_subscriber_yn: 모든 사용자 가입여부, total_user_price: 모든 사용자 이모티콘 구매금액
        total_subscriber_yn, total_user_price = 0, 0
        for user_discout_rate, user_limit_price in users:
            
            # subscriber_yn: 가입여부, user_price: 이모티콘 구매금액
            subscriber_yn, user_price = 0, 0
            for j in range(m):
                if discount_rate[j] >= user_discout_rate:
                    user_price += prices[j]
            if user_price >= user_limit_price:
                subscriber_yn, user_price = 1, 0
            total_subscriber_yn += subscriber_yn
            total_user_price += user_price
        
        answers.append((total_subscriber_yn, total_user_price))

    # 정렬: total_subscriber_yn DESC, total_user_price DESC
    answers.sort(key=lambda x: (-x[0], -x[1]))
    
    return answers[0]

1. 이모티콘 할인율에 대한 모든 경우의 수를 저장한다.

2. 각각의 할인율에 대해 이모티콘 가격을 저장한다.

3. 모든 사용자에 대해 가입여부와 이모티콘 구매금액을 저장한다. (정답이 되는 모든 경우이다.)

4. 그 중 가입여부가 가장 많고, 이모티콘 구매금액이 가장 많은 경우가 정답이다.

 

표현 가능한 이진트리 - 2023 KAKAO BLIND RECRUITMENT, Level3

from math import sqrt
from collections import deque

'''
@parmas: 10진수 숫자
@return: 포화이진트리 문자열
'''
def make_binary_number(number):    
    # 1. 10진수 → 2진수 문자열
    binary_number = bin(number)[2: ]
    # 2. 포화이진트리 세팅을 위한 자리수 세팅
    digit_number = 1
    while True:
        if len(binary_number) <= digit_number - 1:
            break
        digit_number = digit_number * 2
    # 3. 포화이진트리
    binary_number = '0' * (digit_number - 1 - len(binary_number)) + binary_number
    return binary_number
    

def solution(numbers):
    answer = [0 for _ in range(len(numbers))]
    
    for idx, number in enumerate(numbers):
        binary_number = make_binary_number(number)
                
        root = len(binary_number) // 2
        visited = [False for _ in range(len(binary_number))]
        q = deque()
        
        if binary_number[root] == '1':        
            visited[root] = True
            q.append((root, 0, len(binary_number))) #(루트노드, 시작점, 끝점)
        
        while q:
            root, start, end = q.popleft()
            
            left_node = (root - 1 + start) // 2
            if 0 <= left_node < root and binary_number[left_node] == '1':
                q.append((left_node, start, root - 1))
                visited[left_node] = True
            elif left_node == root and binary_number[left_node] == '1':
                visited[left_node] = True
                
            right_node = (root + 1 + end) // 2
            if root < right_node < len(binary_number) and binary_number[right_node] == '1':
                q.append((right_node, root + 1, end))
                visited[right_node] = True
            elif right_node == root and binary_number[right_node] == '1':
                visited[right_node] = True

        check = True
        for i in range(len(binary_number)):
            if binary_number[i] == '1' and visited[i] == False:
                check = False
                break
        if check:
            answer[idx] = 1
    
    return answer

1. 숫자를 포화 이진트리 문자열로 바꾸는 함수를 만든다.

    1.1) 2진수 이진트리 문자열로 만든다

    1.2) 자리수를 계산하여 포화 이진트리 문자열로 만든다.

2. 포화 이진트리 문자열을 BFS와 이진탐색 기법을 활용하여 이진트리 가능 여부를 계산한다.

 

미로 탈출 명령어 - 2023 KAKAO BLIND RECRUITMENT, Level3 - Fail

from collections import deque

def solution(n, m, x, y, r, c, k):
    answers, answer = [], 'impossible'
    
    q = deque([('', (x, y))]) # 경로, 위치
    
    while q:
        route, location =  q.popleft()
        
        if len(route) < k:
            if location[1] - 1 > 0:
                q.append((route + 'l', (location[0], location[1] - 1)))
            if location[1] + 1 <= m:
                q.append((route + 'r', (location[0], location[1] + 1)))
            if location[0] - 1 > 0:
                q.append((route + 'u', (location[0] - 1, location[1])))
            if location[0] + 1 <= n:
                q.append((route + 'd', (location[0] + 1, location[1])))
        elif len(route) == k and location[0] == r and location[1] == c:
            answers.append(route)
    
    if len(answers) > 0:
        answers.sort()
        answer = answers[0]
        
    return answer

1. 경로와 위치를 저장하며 BFS를 돌린다.

    1.1) 간단한 방법이니 만큼 정확도는 100%일 것이다.

2. 시간초과로 실패했다.