우기의 알 블로그 저자 한승욱이라고 합니다.
스스로 알을 깨고 나오는 새처럼
언젠가 알을 깨고 온전한 나 자신이 되었을 때, 그때를 기다리며 제 속에서 솟아 나오는 것을 글로써 표현하고자 합니다.
'개발 기술블로그'를 위주로 저 한승욱의 다양한 관심사, 생각, 철학 등을 포스팅합니다.
stock =4
dates =[4,10,15]
supplies =[20,5,10]
k =30# 다음과 같이 입력값이 들어온다면,# 현재 재고가 4개 있습니다. 그리고 정상적으로 돌아오는 날은 30일까지입니다.# 즉, 26개의 공급량을 사와야 합니다!# 그러면 제일 최소한으로 26개를 가져오려면? supplies 에서 20, 10 을 가져오면 되겠죠?# 그래서 이 경우의 최소 공급 횟수는 2 입니다!
stock =4
dates =[4,10,15]
supplies =[20,15,10]
k =30# 이 때! 다음과 같이 입력값이 들어온다면 어떻게 해야 할까요?# supplies 에서 20, 15를 가져오는게 가장 최고의 상황입니다!# 즉, 4일과 10일에 공급량을 가져오는 게 좋습니다!
주의할 점: 그냥 제일 큰 값만 가지고 와서 넣으면 안된다. 재고가 다 떨어지기 전에 한번이라도
공급을 받아야 하기때문이다. 재고가 바닥나는 시점 이전까지 받을 수 있는 라면 중 제일 많은 라면을 받는 것이 목표이다.
현재 재고의 상태에 따라 최곳값을 받아야 한다.(동적으로 변경), 두번째로 제일 많은 값만
가져가면 된다.
데이터를 넣을 때마다 최댓값을 동적으로 변경시키며 최소/최댓값을 바로 꺼낼 수 있는 자료구조가
필요하기에 '힙' 자료구조를 쓰면 된다.
stock이 k보다 많아야지 정상적으로 시도가 가능하다.
# 정답import heapq
ramen_stock =4
supply_dates =[4,10,15]
supply_supplies =[20,5,10]
supply_recover_k =30defget_minimum_count_of_overseas_supply(stock, dates, supplies, k):
answer =0
current_day_index =0# 오늘이 며칠인지에 따라서 가지고 올 수 있는 supply 수가 다르기에
max_heap =[]# 현재 공급량이 떨어지지 않는 선에서 가장 많은 공급량을 가지고 올 수 있게while stock < k:# date를 기준으로 반복. 왜냐면 지금 내가 재고가 바닥난 상황인지 아닌지를 알기 위함for date_index inrange(current_day_index,len(dates)):if dates[date_index]<= stock:# 현재 스톡이 4고 요일이 10이면 10 < 4라서 조건이 안 맞기에
heapq.heappush(max_heap,-supplies[date_index])else:
current_day_index = date_index
break
answer +=1
stock +=-heapq.heappop(max_heap)return answer
print(get_minimum_count_of_overseas_supply(ramen_stock, supply_dates, supply_supplies, supply_recover_k))
샤오미 로봇 청소기
r, c, d =7,4,0
room_map =[[1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,1,1,1,1,0,1],[1,0,0,1,1,0,0,0,0,1],[1,0,1,1,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1]]
# 코드 스니펫
current_r, current_c, current_d =7,4,0
current_room_map =[[1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,1,1,1,1,0,1],[1,0,0,1,1,0,0,0,0,1],[1,0,1,1,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1]]defget_count_of_departments_cleaned_by_robot_vacuum(r, c, d, room_map):return# 57 가 출력되어야 합니다!print(get_count_of_departments_cleaned_by_robot_vacuum(current_r, current_c, current_d, current_room_map))
모든 칸을 탐색해야 하기에 전부 탐색하고 모든 칸을 탐색해야하기에 BFS를 활용하는 것이다.
현재 위치를 청소한다 - 청소하는 곳의 정보를 기록
2차원 배열이라 visited를 쓰지 않고 배열에 표시
0 은 청소하지 않은 장소
1은 청소하지 못하는 장소
2는 청소한 장소로 표시 함으로써 정보를 기록
현재 위치에서 현재 방향을 기준으로 왼쪽 방향부터 차례대로 탐색을 진행한다.
방향 개념이 필요하기에 배열 내에서 방향을 표시하기로함
북쪽으로 가면 로우가 -1 컬럼은 0
동쪽으로 가면 로우 0 컬럼 1
남쪽으로 가면 로우 1 컬럼 0
서쪽으로 가면 로우 0 컬럼 -1
dr과 dc라는 변수에 담음
dr = [-1, 0, 1, 0]
dc = [0, 1, 0, -1]
왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면 그 방향으로 회전하고 다음 한칸을 전진하고 1번부터 진행
회전 개념이 필요함
dr, dc에서 북:0, 동:1, 남:2, 서:3
북쪽에서 왼쪽 회전 서: 0 → 3
동쪽에서 왼쪽 회전 북: 1 → 0
남쪽에서 왼쪽 회전 동: 2 → 1
서쪽에서 왼쪽 회전 남: 3 → 2
get_d_index_when_rotate_to_left() 함수를 구현. 3을 더한다음에 %4
왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.
현재 본 방향에서 청소할 곳이 없다면 다시 왼쪽으로 회전하라는 의미
모든 방향이 청소가 되어있거나 벽인 경우에는 바라보는 방향을 유지한채로 한 칸 후진을 하고 2번으로 돌아간다.
모든 방향이 청소되어 있다면 뒤로 한칸 후진
북 뒤로 돌면 남: 0 → 2
동 뒤로 돌면 서: 1 → 3
남 뒤로 돌면 북: 2 → 0
서 뒤로 돌면 동: 3 → 1
함수 구현. 2를 더한 다음에 %4
네 방향 모두 청소가 이미 되어있거나 벽이면서 뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다.
우리가 마지막으로 반환해줘야 하는 것은 청소한 칸의 갯수. count_of_departments_cleaned 변수.
# 정답
current_r, current_c, current_d =7,4,0
current_room_map =[[1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,1,1,1,1,0,1],[1,0,0,1,1,0,0,0,0,1],[1,0,1,1,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,1,1,0,1],[1,0,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1]]
dr =[-1,0,1,0]
dc =[0,1,0,-1]defget_d_index_when_rotate_to_left(d):return(d+3)%4defget_d_index_when_go_back(d):return(d+2)%4defget_count_of_departments_cleaned_by_robot_vacuum(r, c, d, room_map):
n =len(room_map)
m =len(room_map[0])
count_of_departments_cleaned =1# 맨처음 칸은 청소했다고 침
room_map[r][c]=2
queue =list([[r, c, d]])# 현재 위치와 방향을 전부 기록해놓고 어떻게 탐색할지 고민이 필요하기에 r,c,d 저장while queue:
r, c, d = queue.pop(0)
temp_d = d # 방향은 계속 돌릴 것이기에 임시 변수for i inrange(4):
temp_d = get_d_index_when_rotate_to_left(temp_d)
new_r, new_c = r + dr[temp_d], c + dc[temp_d]if0<= new_r < n and0<= new_c < m and current_room_map[new_r][new_c]==0:
count_of_departments_cleaned +=1
room_map[new_r][new_c]=2
queue.append([new_r, new_c, temp_d])breakelif i ==3:
new_r, new_c = r + dr[get_d_index_when_go_back(temp_d)], c + dc[get_d_index_when_go_back(temp_d)]
queue.append([new_r, new_c, temp_d])if current_room_map[new_r][new_c]==1:return count_of_departments_cleaned
return count_of_departments_cleaned
# 57 가 출력되어야 합니다!print(get_count_of_departments_cleaned_by_robot_vacuum(current_r, current_c, current_d, current_room_map))
알고리즘 4주차 - 숙제
농심 라면 공장
주의할 점: 그냥 제일 큰 값만 가지고 와서 넣으면 안된다. 재고가 다 떨어지기 전에 한번이라도 공급을 받아야 하기때문이다. 재고가 바닥나는 시점 이전까지 받을 수 있는 라면 중 제일 많은 라면을 받는 것이 목표이다.
현재 재고의 상태에 따라 최곳값을 받아야 한다.(동적으로 변경), 두번째로 제일 많은 값만 가져가면 된다.
데이터를 넣을 때마다 최댓값을 동적으로 변경시키며 최소/최댓값을 바로 꺼낼 수 있는 자료구조가 필요하기에 '힙' 자료구조를 쓰면 된다.
stock이 k보다 많아야지 정상적으로 시도가 가능하다.
샤오미 로봇 청소기
모든 칸을 탐색해야 하기에 전부 탐색하고 모든 칸을 탐색해야하기에 BFS를 활용하는 것이다.
CGV 극장 좌석 자리 구하기
[1, 2, 3, 4, 5, 6, 7, 8, 9]에서 4와 7이 고정되어 있을때 앉을 수 있는 여러 가지의 가능한 개수에 대해 알아보는 문제
1 2 3
5 6
8 9
를 어떻게 마음껏 옮겨서 만들 수 있는 모든 경우의 수
좌석 [1, 2]: [1, 2], [2, 1] → 2개
좌석 [1, 2, 3]: [1, 2, 3], [2, 1, 3], [1, 3, 2] → 3개 # [3, 2, 1]은 3도 두 자리 옮기고 1도 두자리 옮기니 말이 안됨
좌석 [1, 2, 3, 4]: → 5개
...
피보나치 수열과 비슷한 것을 확인 가능
다른 점은 F(2) = 2, F(3) = 3 인점
그렇다면 왜 피보나치 수열일까?
총 좌석의 자리가 i개 있다고 가정하면
그리고 각 독립적인 값에 대해서 곱의 법칙을 적용해주면 전체 경우의 수.
4와 7이 고정되어 있으므로
1 2 3 F(3) = 3
5 6 F(2) = 2
8, 9 F(2) = 2
3 * 2 * 2 = 12가 모든 가지의 경우의 수
'기술개발 > Algorithm' 카테고리의 다른 글