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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

처음에는 딕셔너리를 만들어 선물을 준 사람과 받은 사람관의 관계를 나타내고, 각 사람의 [준 선물/ 받은 선물 / 선물 지수]를 저장할 딕셔너리를 생성했다.

이후 서로간의 관계에 따라 다음달에 받을 선물을 확인하는 로직을 작성하던 중, 내가 받았을 때와 받지 않았을 때의 관계를 찾는것이 너무 어려웠다.

def solution(friends, gifts):
    answer = {x:0 for x in friends}
    gifts_to_friends = {x:{} for x in friends}
    gifts_count = {x:[0,0,0] for x in friends}
    for i in gifts:
        give, take = i.split()
        gifts_count[take][1] += 1 # 받은 선물 카운팅
        if take in gifts_to_friends[give]:
            gifts_to_friends[give][take] += 1 # 선물 전달 내역 기록
            gifts_count[give][0] += 1 # 준 선물 카운팅
        else:
            gifts_to_friends[give][take] = 1
            gifts_count[give][0] += 1
            
    for name in gifts_count:  #선물 지수 구하기
        gifts_count[name][2] = gifts_count[name][0] - gifts_count[name][1]
            
    print(gifts_to_friends)
    print(gifts_count)
    
    for giving_name in gifts_to_friends:
        for friend in friends:
            if giving_name != friend: #자신인 경우 제외
                if gifts_to_friends[giving_name]: # 내가 선물을 준 사람이 있다면 
                    for taking_name in gifts_to_friends[giving_name]: #여기까지는 ok
                        if giving_name in gifts_to_friends[taking_name]: #상대도 나에게 주었다면
                            if gifts_to_friends[giving_name][taking_name] > gifts_to_friends[taking_name][giving_name]:
                                answer[giving_name]+=1
                            elif gifts_to_friends[giving_name][taking_name] == gifts_to_friends[taking_name][giving_name]:
                                if gifts_count[giving_name][2] > gifts_count[taking_name][2]:
                                    answer[giving_name]+=1
                    
    
    return max(answer.values())

 

나는 자신인 경우를 제외하였지만, 또 다시 어떤 관계에 대해 계산하는 문제가 있었다.

이 문제는 enumerate를 활용해 index 슬라이싱을 활용해 해결하였다.

 

관계가 없는 상황을 계산하는 것이 어려웠다. 이 문제는 딕셔너리 메서드 중 .get()메서드를 통해 해결했다.

.get() 메서드는 키를 지정해주고 그 키에대한 값이 있다면 반환해주고, 없다면 특정 값을 지정해 반환할 수 있다.

def solution(friends, gifts):
    answer = {x:0 for x in friends}
    gifts_to_friends = {x:{} for x in friends}
    gifts_count = {x:[0,0,0] for x in friends}
    for i in gifts:
        give, take = i.split()
        gifts_count[take][1] += 1 # 받은 선물 카운팅
        if take in gifts_to_friends[give]:
            gifts_to_friends[give][take] += 1 # 선물 전달 내역 기록
        else:
            gifts_to_friends[give][take] = 1
        gifts_count[give][0] += 1 # 준 선물 카운팅
            
    for name in gifts_count:  #선물 지수 구하기
        gifts_count[name][2] = gifts_count[name][0] - gifts_count[name][1]
            
    # print(gifts_to_friends)
    # print(gifts_count)
    
    for i, giving_name in enumerate(friends):
        for j, taking_name in enumerate(friends[i+1:], i+1): # 나를 제외 / 이전에 확인한 것은 제외
            if giving_name != taking_name:
                give_count = gifts_to_friends[giving_name].get(taking_name, 0) # .get()메서드 / 딕셔너리에서 해당 키의 값이 있다면 반환, 없다면 반환할 값을 지정 가능
                take_count = gifts_to_friends[taking_name].get(giving_name, 0)
                
                if give_count > take_count:
                    answer[giving_name] += 1
                elif give_count < take_count:
                    answer[taking_name] += 1
                else:  # 선물을 주고받은 기록이 없거나 수가 같은 경우
                    if gifts_count[giving_name][2] > gifts_count[taking_name][2]:
                        answer[giving_name] += 1
                    elif gifts_count[giving_name][2] < gifts_count[taking_name][2]:
                        answer[taking_name] += 1
                    
    
    return max(answer.values())

이렇게 해당 문제를 풀이했다.

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

이 문제는 간단한 수식을 통해 해결할 수 있을거라 생각했다.

def solution(diffs, times, limit):
    time_prev = [(times[x-1]+times[x]) for x in range(1, len(times))]
    time_prev = [times[0]] + time_prev
    # print(time_prev)
    time = 10**15 + 1
    level = 0
    while (time > limit):
        time = 0
        level += 1
        for i in range(len(diffs)):
            if time > limit:
                break
                
            if diffs[i] <= level:
                time += times[i]
                # print('if문')
                # print(level, time)
            else:
                time += time_prev[i] * (diffs[i] - level) + times[i]
                # print('level :', level)
                # print("else문 itme :", time)
        
        
    return level

다음과 같이 수식을 활용해 풀었으나 시간 초과 오류가 발생했다.

수가 커지면서 너무 많은 반복을 해서 그런거 같다.

반복 횟수를 줄여야 한다는 생각을 하였고 이진 탐색을 통해 횟수를 줄일 수 있다고 생각했다.

 

Left, Right를 지정해주고 가운데 지점부터 확인하면서 Left, Right를 초기화 해준다.

def solution(diffs, times, limit):
    time_prev = [(times[x-1]+times[x]) for x in range(1, len(times))] # time_prev를 미리 계산
    time_prev = [times[0]] + time_prev # 첫 번째값 대입

    left, right = 1, max(diffs) # 이진 탐색을 위한 index 지정
    while left <= right: # lift > right라면 그 지점이 최초로 time <= limit인 부분
        level = (left + right) // 2 # 중간 지점 확인(정수형)
        time = 0
        for i in range(len(diffs)):
            if time > limit: # 시간초과 발생시 다음 탐색
                break
            
            time += times[i] # 기본적으로 times[i]를 더해주기 때문에 지정 
            if diffs[i] > level: # 숙련도가 낮을 경우 시간 추가
                time += (diffs[i] - level) * time_prev[i]

        if time <= limit: # 시간이 리미트를 넘어서지 않은 경우 오른쪽 지점을 변경
            right = level - 1
        else:
            left = level + 1
    
    return left

https://school.programmers.co.kr/learn/courses/30/lessons/132265?language=python3

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

이 문제를 처음 접했을 때는 인덱스 슬라이싱을 먼저 떠올렸다.

그래서 for 문을 돌리며 인덱스를 기준으로 left와 right를 자르고 len(), set()을 통하여 포함되어 있는 토핑 갯수를 확인하였다.

그러나 시간초과 문제를 직면하였다.

 

그 다음에는 deque를 활용해서 큐 자료구조를 활용하였다.

최대한 연산을 줄이고 길이를 나타내는 변수(check, count)를 만들어서 비교하였다.

절반만 맞고, 절반은 시간초과가 떴다.

from collections import deque

def solution(topping):
    answer = 0
    check = len(set(topping))
    count = 0
    dq1 = deque()
    dq2 = deque(topping)

    for i in topping:
        dq2.popleft()
        if (not i in dq1):
            dq1.append(i)
            count += 1

        if (not i in dq2):
            check -= 1
        
        if (count < check):
            continue
        elif (count > check):
            break
        else:
            answer += 1
    return answer
    
topping = [1, 2, 1, 3, 1, 4, 1, 2]

print(solution(topping))

 

가장 마지막 방식으로는 딕셔너리를 활요해 문제를 풀었다.

확실히 딕셔너리로 풀었을 때 가장 시간이 단축되었다.

문제의 형태에 따라 좋은 방식을 선택한다면 풀이하는 시간을 많이 줄일 수 있다.

주석 부분은 처음에는 사용했지만, 없어도 문제가 풀리기 때문에 주석처리 했다.

처음에 이 코드를 이해하려면 필요하기에 남겨두었다.

def solution(topping):
    answer = 0
    left_dic = {}
    right_dic = {}
    left_len = 0
    right_len = 0

    for d in set(topping):
        right_dic[d] = 0
        right_len += 1
    
    for i in topping:
        right_dic[i] += 1
        
    for j in topping:
        
        if (not j in left_dic):
            left_dic[j] = 0
            left_len += 1
        
        # left_dic[j] += 1
        right_dic[j] -= 1
        
        if right_dic[j] == 0:
            # del right_dic[j]
            right_len -= 1
            
        if (left_len < right_len):
            continue
        elif (left_len > right_len):
            break
        else:
            answer+=1
    
    return answer
    
topping = [1, 2, 1, 3, 1, 4, 1, 2]

print(solution(topping))

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

 

프로그래머스

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

programmers.co.kr

 

처음 이 문제를 풀이할 때 전체 할인률을 [10, 20, 30, 40]으로 각각 지정하여 플러스 이용자가 가장 많은 할인률을 확인한 뒤, 그 범위 안에서 좁혀 나갈 생각을 하였다.

그러나 문제를 풀이하면서 전체의 결과를 다 확인해야 된다는 것을 확인하였다.

그래서 모든 할인률을 확인하기 위해 중복 순열을 사용하였다.

from itertools import product 

def solution(users, emoticons):
    # users : n명의 구매 기준을 담은 2차원 정수 배열 [비율, 가격]
    # emoticons :m개의 정가를 담은 1차원 정수 배열
    for i in users:
        if i[0]%10 != 0:
            i[0] = ((i[0] // 10) + 1)*10 

    sales = list(product([10, 20, 30, 40], repeat = len(emoticons)))
    
    best_param = [0,0,0] #가장 값이 좋은 plus_user, sum_cost, sales값
    for sale in sales:
        plus_user = 0
        sum_cost = 0
       
        for user in users:
            cost = 0
            for j in range(len(emoticons)):
                if user[0] <= sale[j]:
                    cost += (emoticons[j] * (1-(sale[j] / 100)) )

            if user[1] <= cost:
                plus_user += 1
                cost = 0
            sum_cost += cost
        
        if (best_param[0] < plus_user):
            best_param[0] = plus_user
            best_param[1] = sum_cost
            best_param[2] = sale
        elif(best_param[0] == plus_user):
            if (best_param[1] <= sum_cost):
                best_param[1] = sum_cost
                best_param[2] = sale
    
    answer = [best_param[0], int(best_param[1])]

    return answer

 

돌아가는 원리를 파악하고 싶다면 아래의 코드를 실행해 보기를 추천한다.

단 원리를 파악할 때 먼저 2명의 users를 확인하길 바란다.

from itertools import product 

def solution(users, emoticons):
    # users : n명의 구매 기준을 담은 2차원 정수 배열 [비율, 가격]
    # emoticons :m개의 정가를 담은 1차원 정수 배열
    for i in users:
        if i[0]%10 != 0:
            i[0] = ((i[0] // 10) + 1)*10 

    sales = list(product([10, 20, 30, 40], repeat = len(emoticons)))
    print(sales)
    
    best_param = [0,0,0] #가장 값이 좋은 plus_user, sum_cost, sales값
    for sale in sales:
        plus_user = 0
        sum_cost = 0
        print('sale =',sale)
        for user in users:
            cost = 0
            for j in range(len(emoticons)):
                if user[0] <= sale[j]:
                    cost += (emoticons[j] * (1-(sale[j] / 100)) )

            print('cost =', cost)
            if user[1] <= cost:
                plus_user += 1
                cost = 0
            sum_cost += cost
        
        if (best_param[0] < plus_user):
            best_param[0] = plus_user
            best_param[1] = sum_cost
            best_param[2] = sale
        elif(best_param[0] == plus_user):
            if (best_param[1] <= sum_cost):
                best_param[1] = sum_cost
                best_param[2] = sale

        print('플러스 이용자 =',plus_user, '최종금액 =',sum_cost)
        print('result =', best_param[0], best_param[1])
        print('='*30)
    
    answer = [best_param[0], int(best_param[1])]
    print('best_param =', best_param[2])
    
    
    return answer

# users = [[40, 2900], [23, 10000], [11, 5200], [5, 5900], [40, 3100], [27, 9200], [32, 6900]]
# emoticons = [1300, 1500, 1600, 4900]

users = [[40, 10000], [25, 10000]]
emoticons = [7000, 9000]
print(solution(users, emoticons))

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

 

프로그래머스

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

programmers.co.kr

 

처음 코드는 다음과 같다.

개인적은 dfs(깊이 우선 탐색) 보다 bfs(너비 우선 탐색)의 방식이 나한테 잘 맞는다고 생각했다.

그러나 이 코드에서는 시간 초과가 떴는데, 문제점을 살펴본 결과 pop(0)의 과정에서 n개의 모든 원소를 확인하여 빼기때문에 시간 복잡도는 O(n)이라고 한다.

만약 depue의 자료형이라면 popleft()을 활용해 O(1)의 시간복잡도로 문제를 풀이할 수 있다.

def solution(numbers, target):
    answer = 0
    q = []
    n = len(numbers)
    q.append([numbers[0],0])
    q.append([-(numbers[0]), 0])
    while q:
        num, index = q.pop(0)
        index += 1
        if index != n:
            q.append([num + numbers[index], index])
            q.append([num - numbers[index], index])
        else:
            if num == target:
                answer += 1
    return answer

 

from collections import deque를 선언하고

popleft() 함수를 활용해 다음과 같이 수정했다.

from collections import deque
def solution(numbers, target):
    answer = 0
    q = deque()
    n = len(numbers)
    q.append([numbers[0],0])
    q.append([-(numbers[0]), 0])
    while q:
        num, index = q.popleft()
        index += 1
        if index != n:
            q.append([num + numbers[index], index])
            q.append([num - numbers[index], index])
        else:
            if num == target:
                answer += 1
    return answer

LV2 > 연습문제 > 뒤에 있는 큰 수 찾기

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

 

프로그래머스

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

programmers.co.kr

 

 

def check(index, arr):
    len_arr = len(arr)
    max_n = 0
    for j in range(index, len_arr):
        if j <= len_arr-2:
            if arr[index] < max(arr[index : j+2]):
                return max(arr[index : j+2])
        else:
            return -1
    

def solution(numbers):
    answer = []
    max_n = max(numbers)
    for i in range(len(numbers)):
        if (i == (len(numbers)-1)) or (numbers[i] == max_n):
            answer.append(-1)
        elif numbers[i] < numbers[i+1]:
            answer.append(numbers[i+1])
        elif numbers[i] >= numbers[i+1]:
            answer.append(check(i, numbers))
            
    return answer

 

10번 ~ 22번 문제 시간초과

 

 

def check(index, arr, n):
    len_arr = len(arr)
    max_n = 0
    if index+n <= len_arr:
        if arr[index] < max(arr[index : index+n]):
            return max(arr[index : index+n])
        else:
            return check(index, arr, n+1)
    else:
        return -1
    

def solution(numbers):
    answer = []
    max_n = max(numbers)
    for i in range(len(numbers)):
        if (i == (len(numbers)-1)) or (numbers[i] == max_n):
            answer.append(-1)
        elif numbers[i] < numbers[i+1]:
            answer.append(numbers[i+1])
        
            
        elif numbers[i] >= numbers[i+1]:
            answer.append(check(i, numbers, 1))
    return answer

 

6번 ~ 22번 문제 시간초과

재귀가 더 시간을 많이 잡아먹음

구조적인 문제가 분명

 

마지막으로 구조는 그대로 가져가고

tru / except문을 활용해보았다.

def solution(numbers):
    answer = []
    max_n = max(numbers)
    for i in range(len(numbers)):
        if (i == (len(numbers)-1)) or (numbers[i] == max_n):
            answer.append(-1)
        elif numbers[i] < numbers[i+1]:
            answer.append(numbers[i+1])
        else:
            for k in range(1, len(numbers[i:])+1):
                try:
                    # print("try문 들어옴")
                    # print(i, numbers[i], k)
                    if numbers[i:].index(numbers[i]+k) >= 0:
                        answer.append(numbers[i]+k)
                        # print(answer)
                        check = 1
                        break
                except:
                    check = 0
                    continue
                    
            if check == 0:
                answer.append(-1)
                    
                
        
    return answer

 

잘못된 부분이 있는지 실패가 많이 떴다.

결국 찾아보고 stack 자료구조를 활용해 뒤에서부터 비교하는 방법으로 많이 풀이한 것을 알았다.

그래서 다음과 같이 풀이했다.

이 풀이에서 가장 중요한 부분은 앞에서 부터 비교하던걸 뒤에서 부터 비교하는 거라 생각한다.

앞에서 비교할 때는 내 다음것을 고려해야 되지만, 뒤로 비교하면 나보다 작다면 적용해주고 나보다 크다면 없애면 된다!

 

def solution(numbers):
    n = len(numbers)
    answer = [-1] * n  # 정답을 -1로 초기화
    stack = []  # 스택을 초기화

    for i in range(n - 1, -1, -1):  # 배열을 오른쪽에서 왼쪽으로 순회
        # 현재 숫자보다 작은 숫자는 스택에서 제거
        while stack and stack[-1] <= numbers[i]:
            stack.pop()
        
        # 스택이 비어 있지 않다면 스택의 맨 위가 '뒤에 있는 큰 수'
        if stack:
            answer[i] = stack[-1]
        
        # 현재 숫자를 스택에 추가
        stack.append(numbers[i])

    return answer

 

 

만약 이해하기 어렵다면 다음 print문을 같이 사용하면 좋을거 같다.

def solution(numbers):
    n = len(numbers)
    answer = [-1] * n  # 정답을 -1로 초기화
    stack = []  # 스택을 초기화

    for i in range(n - 1, -1, -1):  # 배열을 오른쪽에서 왼쪽으로 순회
        # 현재 숫자보다 작은 숫자는 스택에서 제거
        print('index = ', i, 'stack =',stack, 'numbers =', numbers[i])
        while stack and stack[-1] <= numbers[i]:
            stack.pop()
            print('stack pop')
        
        # 스택이 비어 있지 않다면 스택의 맨 위가 '뒤에 있는 큰 수'
        if stack:
            answer[i] = stack[-1]
        
        # 현재 숫자를 스택에 추가
        stack.append(numbers[i])
        print('answer - ',answer)
        print('stack =',stack)
        
    
    return answer

프로그래머스 > 완전탐색 > 소수찾기

 

프로그래머스

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

programmers.co.kr

 

소수를 만들기 위한 조합을 만들고 소수의 수를 count해 출력하는 문제이다.

 

초기에 코드를 짜다 자체적으로 7자리의 수의 모든 조합을 만드는 것은 힘들다 생각해 itertools의 permutauions를 사용하였다.

from itertools import permutations

def solution(numbers):
    L = list(numbers)
    per = []
    answer=0
    for i in range(1,len(L)+1):
        per += list(map(''.join,permutations(L,i))) 
        
    per = list(map(int, per))
    per = list(set(per))
    per.sort()
    #print(per)
    
    for i in per:
        check = True
        if (i == 1) or (i == 0):
            continue 
        elif i == 2:
            answer += 1
        else:
            for j in range(2, i):
                if ((i / j) == (i//j)):
                    print(i, j, i/j, i//j)
                    check = False
                    break
                else:
                    check = True
        
        if check == True:
            answer+=1
    return answer

print(solution('130'))

 

if ((i / j) == (i//j)):의 경우 비효율적이라 생각이되어 if i%j ==0: 으로 수정하였다.

테스트케이스는 성공했지만 정답제출시 통과하지 못해 다시 오류가 나는 부분을 찾아다녔다.

오류가 난 부분은 2를 예외처리할 때 answer += 1이라 해주었는데 check값은 True기 때문에 마지막 if 문에서 결국 +1이 더 되었다.

이를 해결하기 위해 다음과 같이 수정하였다.

 

from itertools import permutations

def solution(numbers):
    L = list(numbers)
    per = []
    answer=0
    for i in range(1,len(L)+1):
        per += list(map(''.join,permutations(L,i))) #(모든 경우의 조합찾기)
        
    per = list(map(int, per)) # int형 자료로 변환
    per = list(set(per)) # 중복제거
    per.sort() #정렬
    print(per)
    
    for i in per:
        check = True
        if (i == 1) or (i == 0):
            continue 
        elif i == 2:
            # answer += 1 #문제가 된 부분
            check = True
        else:
            for j in range(2, i):
                if (i % j == 0): #소수인지 아닌지 확인
                    check = False
                    break #소수라면 멈추고 다음 for문 진행
                else:
                    check = True
        
        if check == True: #소수라면 answer에 +1
            answer+=1
    return answer

 

이제 불 필요한 부분을 없애고 최적화를 해보겠다.

from itertools import permutations
def prime_check(i): #소수 판별을 함수화 / return하여 bool 값을 저장
    if (i == 1) or (i == 0):
        return False
    elif i == 2:
        return True
    else:
        for j in range(2, i):
            if (i % j == 0):
                return False
    return True

def solution(numbers):
    L = list(numbers)
    per = []
    answer=0
    for i in range(1,len(L)+1):
        per += list(map(''.join,permutations(L,i))) 
        
    per = sorted(set(map(int, per))) # int형 변형, 중복제거, 정렬을 한줄로 처리(계산 시간이 소폭 줄어듬)
    
    for i in per:
        if prime_check(i) == True:
            answer+=1
    return answer

 

다음과 같이 마무리하였다.

[프로그래머스] > 완전탐색 >모의고사

 

프로그래머스

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

programmers.co.kr

 

해당 문제는 패턴을 활용하고 index를 어떻게 구분짓는지 달렸다고 생각했다.

초기 코드는 정말 index를 일정하게 맞추는데 초점을 두었다.

def solution(answers):
    answer = []
    case1 = [1, 2, 3, 4, 5]
    case2 = [2, 1, 2, 3, 2, 4, 2, 5]
    case3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    count = [0, 0, 0]
    c1, c2, c3 = 0, 0, 0
    
    for i in range(len(answers)):
        
        
        if c1 >= len(case1):
            c1 = 0
            if case1[c1] == answers[i]:
                count[0]+=1
        else:
            if case1[c1] == answers[i]:
                count[0]+=1
                
        # print(c1)
        if c2 >= len(case2):
            c2 = 0
            if case2[c2] == answers[i]:
                count[1]+=1
        else:
            if case2[c2] == answers[i]:
                count[1]+=1
                
                
        if c3 >= len(case3):
            c3 = 0
            if case3[c3] == answers[i]:
                count[2]+=1
        else:
            if case3[c3] == answers[i]:
                count[2]+=1
        c1+=1
        c2+=1
        c3+=1
        # print(f"{i+1}회 완료")
    # print(count)
    
    for k in range(1, 4):
        if count[k-1] == max(count):
            answer.append(k)
    
            
        
    return answer
L = [1, 2, 3, 4, 5, 1, 3, 5, 2, 4]
print(solution(L))

 

이 코드에서 가장 비효율적인 것은 c1, c2, c3의 변수들을 계속 증가시키고 0으로 초기화 해주는 부분에 있다.

i % len(case1) 같은 코드를 활용하면 패턴 길이에 따라 달라지는 몫을 얻고 원하는 index값을 얻을 수 있다.

그럼으로 불필요한 c1, c2, c3변수를 삭제하고 코드를 간소화 했다.

for문에서 조건문을 넣으면서 if count[k-1] == max(count): 이런 방식으로 코딩해 조건문이 실행될 때마다 count 리스트의

최대값을 계속 계산했다. 변수에 할당하여 재사용 하는 방식으로 간소하지만 번거로운 작업을 줄일 수 있다.

def solution(answers):
    answer = []
    case1 = [1, 2, 3, 4, 5]
    case2 = [2, 1, 2, 3, 2, 4, 2, 5]
    case3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    count = [0, 0, 0]
    
    for i in range(len(answers)):
        if case1[i % len(case1)] == answers[i]:
            count[0] += 1
        if case2[i % len(case2)] == answers[i]:
            count[1] += 1
        if case3[i % len(case3)] == answers[i]:
            count[2] += 1
    
    
    max_count = max(count)  # max(count)를 한 번만 계산
    for k in range(1, 4):
        if count[k - 1] == max_count:
            answer.append(k)

    return answer

# 테스트 코드
L = [1, 2, 3, 4, 5, 1, 3, 5, 2, 4]
print(solution(L))

 

완전탐색 > 최소직사각형

 

프로그래머스

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

programmers.co.kr

 

명함을 돌릴 수 있어 가로와 세로의 구분은 의미가 없다 생각했다.

해당 문제에 데이터는 2차원 데이터로 구성되어 있다.

각 리스트를 확인했을 때 큰 값과 작은 값을 구분하여 저장하고,

각 무리에서 가장 큰 값을 곱해주면 풀리는 문제라고 생각했다.

초기 코드는 다음과 같다.

def solution(sizes):
    firstMax = [] #리스트 안에 있는 것 중 큰것
    secondMax = [] #리스트 안에 있는 것 중 작은것
    answer = 0
    
    for i in range(len(sizes)):
        if (sizes[i][0] >= sizes[i][1]):
            firstMax.append(sizes[i][0])
            secondMax.append(sizes[i][1])
        else:
            firstMax.append(sizes[i][1])
            secondMax.append(sizes[i][0])
    answer = max(firstMax) * max(secondMax)
    
    return answer

L = [[60, 50], [30, 70], [60, 30], [80, 40]]
print(solution(L))

 

코드의 줄을 줄이고 최적화 할 수 있는 부분이 많다 생각했다.

우선 굳이 range를 쓰지 않아도 된다 생각하여 수정해보았다.

def solution(sizes):
    firstMax = [] #리스트 안에 있는 것 중 큰것
    secondMax = [] #리스트 안에 있는 것 중 작은것
    answer = 0
    # print(len(sizes))
    for i, j in sizes:
        if (i >= j): 
            firstMax.append(i)
            secondMax.append(j)
        else:
            firstMax.append(j)
            secondMax.append(i)
    answer = max(firstMax) * max(secondMax)
    
    return answer

L = [[60, 50], [30, 70], [60, 30], [80, 40]]
print(solution(L))

 

for문을 활용해 새로운 리스트 값들을 더해주는건 리스트 컴프리헨션을 활용하면 줄일 수 있다.

  • max([i if i>= j  else j for i, j in sizes ])

다음과 같은 코드로 변경하면 코드의 길이를 줄일 뿐 아니라 더 빠른 속도로 값을 구할 수 있다.

def solution(sizes):
    firstMax = 0 #리스트 안에 있는 것 중 큰것
    secondMax = 0 #리스트 안에 있는 것 중 작은것
    answer = 0
    
    firstMax = max([i if i>= j  else j for i, j in sizes ])
    secondMax = max([i if i<= j  else j for i, j in sizes ])
    answer = firstMax * secondMax
    
    return answer

L = [[60, 50], [30, 70], [60, 30], [80, 40]]
print(solution(L))

 

불필요하게 대입대는 변수들을 없애주면 코드의 길이가 확 줄어든다.

def solution(sizes):   
    return (max([i if i>= j  else j for i, j in sizes ]) * max([i if i<= j  else j for i, j in sizes ]))

L = [[60, 50], [30, 70], [60, 30], [80, 40]]
print(solution(L))

 

나는 리스트의 컴프리헨션 문법중 if else를 사용하였지만 간단하게 max()와 min()를 활용하여 풀이한 사람이 있다.

return max(max(x) for x in sizes) * max(min(x) for x in sizes)

 

  • (max(x) for x in sizes)

위 코드의 자료형이 무엇인지 확인해봤는데 제너레이터(generator)라고 한다.

리스트와는 다른 형태의 자료형이라 어떤 점에서 좋은가 확인해았다.

 

<제너레이터의 장점>

  • 메모리 효율적: 모든 값을 한꺼번에 메모리에 저장하지 않고, 필요할 때 계산하여 반환하기 때문에 대용량 데이터를 처리할 때 유용합니다.

데이터 처리에서 메모리를 효율적으로 사용할 수 있다는 장점이 있었다.

+ Recent posts