Brute Force 연습 ing

이은택·2021년 11월 18일
0

알고리즘

목록 보기
14/15
post-thumbnail

코드잇 Brute Force 문제


1. 카드 뭉치 최대 조합

1차

  • 구현 3분
    def max_product(left_cards, right_cards):
        # 코드를 작성하세요.
        max_value = 0
        for left in left_cards:
            for right in right_cards:
                current_product = left * right
                if max_value < current_product:
                    max_value = current_product
        return max_value
        
    # 테스트
    print(max_product([1, 6, 5], [4, 2, 3]))
    print(max_product([1, -9, 3, 4], [2, 8, 3, 1]))
    print(max_product([-1, -7, 3], [-4, 3, 6]))

다른 풀이 - max()사용

if max_value < current_product:
                max_value = current_product
  • 대신에 내장함수 max() 를 사용해서 대체
  max_value = max(max_value, current_product)


2. 가까운 매장 찾기

1차

  • 구현 20분
# 제곱근 사용을 위한 sqrt 함수
from math import sqrt

# 두 매장의 직선 거리를 계산해 주는 함수
def distance(store1, store2):
    return sqrt((store1[0] - store2[0]) ** 2 + (store1[1] - store2[1]) ** 2)

# 가장 가까운 두 매장을 찾아주는 함수
def closest_pair(coordinates):
    # 여기 코드를 쓰세요
    shortest_points = coordinates[0], coordinates[1] 
    for x_index in range(len(coordinates)-1):
        for y_index in range(x_index + 1, len(coordinates)):
            current_points = [coordinates[x_index], coordinates[y_index]]
            current_dis = distance(coordinates[x_index], coordinates[y_index])
            shortest_dis = distance(shortest_points[0], shortest_points[1])
            if current_dis < shortest_dis:
                shortest_points = current_points
    return shortest_points
# 테스트
test_coordinates = [(2, 3), (12, 30), (40, 50), (5, 1), (12, 10), (3, 4)]
print(closest_pair(test_coordinates))

막힌 부분 및 주의사항

  1. 구상한 것을 노트에 적지 않고 구현함으로써 오는 생각하지도 못한 부분들에 대한 시행착오가 있기 때문에 웬만하면 구상한것을 실제로 적어서 이상이 없는지 확인작업을 해둘것
  2. 출력값을 제대로 인지 하지 않고 두 지점이 아닌 거리로 구했던 것
  3. 이미 작성한 임이의 변수를 수정할때 하나라도 놓치면 연쇄작용으로 복잡하지니 처음 생성시 간결하고 직관적인것을 고려해서 작성 할것


3. 강남역 폭우

1차 실패

  • 구상 15분

2차 실패 - 층마다의 범위 활용

구상 15분

구현 1시간 5분

def trapping_rain(buildings):
    # 코드를 작성하세요
    
    highest_building = sorted(buildings)[-1] # 가장 높은 빌딩 높이
    
    floors_range_dict = {}
    
    rev_bldings_order = buildings.reverse()
    total_rain = 0
    for floor in range(1,highest_building + 1):
        front = 0
        back = 0
        
        
        for f in range(len(buildings)):
            if floor == buildings[f]:
                front = f
                break
        
        for b in range(len(buildings)):
            if floor == buildings[b]:
                back = len(buildings) -1 -b
                break
        
        floor_range = back - front + 1
        
        total_rain += floor_range * floor
            
    sum_bildings_heights = 0
    for blding in buildings:
        sum_bildings_heights += blding
    
    total_rain -= sum_bildings_heights
    
    return total_rain
        
# 테스트
print(trapping_rain([3, 0, 0, 2, 0, 4]))
print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))

3차 풀이중 - 구간마다 오름 내림 활용

구상 25분

구현 1시간 15분

def trapping_rain(buildings):
    # 코드를 작성하세요
    
    # 첫번째 빌딩 시작점 찾기
    first_location = 0
    for first in range(len(buildings)):
        if 0 < buildings[first]:
            first_location = first
            break
    
    total = 0 
    chase_right = first_location
    for left in range(first_location, len(buildings)):
        if left == chase_right:
            for right in range(left + 1, len(buildings)):
                if buildings[left] <= buildings[right]:
                    total += (right - left) * buildings[right]
                    chase_right = right
                    break
                
                elif right == len(buildings) -1:
                    total += buildings[left]
                    print(left)
    
            
                    chase_right = left + 1
                    
                        
        
    return total
            
    
    
# 테스트
# print(trapping_rain([3, 0, 0, 2, 0, 4]))
print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))

주석

    # 코드를 작성하세요
    
    # 첫번째 빌딩 시작점 찾기
    first_location = 0
    for first in range(len(buildings)):
        if 0 < buildings[first]:
            first_location = first
            break
    # 빌딩 + 빗물 구하기
    total = 0 
    chase_right = first_location # 다음 sub빌딩 범위 첫번째 위치 구하기
    for left in range(first_location, len(buildings)): # 빌딩 시작점 부터 빌딩 끝 지점 
        if left == chase_right: # 🤔left가 sub빌딩 시작점과 일치할때만 실행
            for right in range(left + 1, len(buildings)): # sub빌딩의 끝지점 구하기
                if buildings[left] <= buildings[right]: # sub빌딩의 끝지점이 시작점의 높이와 같거나 클 경우에 실행 
                    total += (right - left) * buildings[left] # sub직사각형 넓이구하기
            
                    chase_right = right # 다음 sub빌딩의 시작점을 구하기 위해 저장
                    break  # sub빌딩을 이용한 사격형 넓이 구했으니 다음 sub빌딩을 구하기 위해 forloop를 break 해준다
                elif  right == len(buildings) -1:
                    total += buildings[left]
                    chase_right = left + 1   
                
                
                
    # 빌딩 높이 합 구하기
    sum_blding = 0
    for i in buildings:
        sum_blding += i
    print(sum_blding)
    
    
    total_rain = total - sum_blding     
    return total
            
    
    
# 테스트
# print(trapping_rain([3, 0, 0, 2, 0, 4]))
print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))

❗4차 - 위치별 빗물 구하기(답안 참고)

힌트

출처: 코드잇

  1. 현재 인덱스의 왼쪽에서 가장 높은 건물의 높이를 구한다
  2. 현재 인덱스의 오른쪽에서 가장 높은 건물의 높이를 구한다
  3. 그 중 더 낮은 건물의 높이를 구한다
  4. 그 높이에서 현재 인덱스에 있는 건물의 높이를 뺀다

구현

  • 구현 30분
    def trapping_rain(buildings):
        # 코드를 작성하세요
        
        # 시작과 끝의 빌딩 위치 구하기 
        start = 0
        end = 0
        for s in range(len(buildings)):
            if 0 < buildings[s]:
                start = s
                break
        for e in range(len(buildings)):
            if buildings[e] != 0:
                end = e
        
        # 각 위치의 빗물 구하기
        rain = 0
        for i in range(start+1, end): # 시작과 끝위치의 빌딩은 빗물이 없으니 범위에서 제외
            left_max = max(buildings[:i])
            right_max  = max(buildings[i+1:])
            low_height = min(left_max, right_max)
            if buildings[i] < low_height:
                rain += low_height - buildings[i]
        
        return rain
    # 테스트
    print(trapping_rain([3, 0, 0, 2, 0, 4]))
    print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))

✨느낀점

  1. 각 코드들에 대한 데이트 타입이나 뜻을 잘못 해석하고 풀이 할때 오류가 생긴다. 자잘한 실수라고 치부 할 수 있으나 이 자잘한 실수가 나중에는 몇시간이 될 수 있으니 항상 부분단위로 print를 써서 올바르게 구현 했는지 체크 하는 습관을 들이자
  2. 내 머리속에 없는 문제 해결방법 일 수도 있다. 내 머리속에서 나오는 문제풀이 방법에 한해 얼마나 오래 걸리든 시도는 다해보고 나서 어떻게 풀어야될지 감이 전혀 오지 않을때(약 1시간) 힌트나 답안을 참고하자 스스로 생각하고 시행착오를 겪는 과정에서 창의적인 생각과 모방이아닌 스스로 해결하는 능력을 기르면 시간이 허락하는 한 장기적으로 이득이 될것이라고 생각이 되기 때문
  3. 구상을 명확히 하는 것 즉 문제해결 방법을 정확히 생각해내는 능력이 중요하다.
  4. 구상을 하되 더 명확히 해두어야 코드로 구현시 구상을 하는 것에 있어 즉시 구상하고 구현하는 일이 줄어 들기 때문에 오류를 범할 일이 줄어든다. 따라서 문제해결 방법을 명확히 해두고 구현을 시작하는 것이 좋다.
profile
도전!

0개의 댓글