파이썬 알고리즘 : 다리를 지나는 트럭

2024년 3월 18일 알고리즘 문제풀이 문제 다리를 지나는 트럭 난이도 Lv.2 코드 1차 42.9점 / 100점 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from collections import deque def solution(bridge_length, weight, truck_weights): answer = 0 # 다리를 표현하기 위한 덱 in_bridge = deque() # 다리의 길이와 트럭의 위치를 표현하기 위해 트럭이 없는 곳은 0인 원소로 채운다. for _ in range(bridge_length): in_bridge.append(0) for truck in truck_weights: # 현재 다리에 지금 주목하는 트럭이 올라가면 무게 제한을 초과할 경우 # 가장 끝에 있는 원소를 빼낸다. 트럭일 수도, 빈 값(0)일 수도 있다. # 0번 인덱스가 빠지고 하나가 추가되기 때문에 모든 원소들의 index는 1씩 줄어든다. # 따라서 다리 위의 모든 트럭이 1칸 움직이는 것을 의미한다. while sum(in_bridge)+truck > weight: outgoing_truck = in_bridge.popleft() in_bridge.append(0) answer += 1 # 만약 실제로 트럭이 빠졌다면, 이와 동시에 새로운 트럭이 올라올 수 있다. # 새로운 트럭이 올라오는 행위는 동시에 일어나므로 시간이 흐르지 않은것으로 치기 위해 뺸다. if outgoing_truck: answer -= 1 # 다리에 새로운 트럭이 올라올 수 있다면 올려준다. if sum(in_bridge)+truck <= weight: # 잘못된 부분: 위에서 동시에 올라온다고 해놓고 여기서 또 하나의 트럭을 빼주었다. 여기서 오답이 발생 in_bridge.popleft() in_bridge.append(truck) answer += 1 # 모든 트럭을 다리 위에 올렸더라도, 도착까지 계산해야 한다. # 가장 도착지에서 먼 트럭이 도착지까지 걸리는 시간을 더해준다. for i in range(len(in_bridge)-1,-1,-1): if in_bridge[i]: answer += (i+1) break return answer 덱을 이용해야겠다는 생각은 보자마자 들었다. 배열에서 한 쪽으론 트럭을 빼내야 하고 한 쪽으론 집어 넣어야 해서 입구와 출구가 정해져있는 덱이 유리하겠다고 생각했다. 덱의 길이를 항상 bridge_length 만큼으로 유지하기 위해 항상 빈 곳은 0의 값을 채워 넣어 주었다. 다리의 길이가 1이 아니기 때문에, 다리 위에서 트럭이 움직일 떄도 시간이 흐르기 때문이다. 시간이 흐를 때마다 0번 index 값을 빼주고(popleft), 맨 뒤에 새로운 값을 삽입하면(append) 다리 위에 있는 모든 트럭의 index는 1씩 감소하게 된다. 따라서 1칸 씩 전진한 셈이 된다. 현재 트럭의 위치를 index로 설정하기 위해선 트럭이 있지 않은 공간을 0으로 설정하는 것은 내가 생각해도 잘한 것 같다. 특히나, 이렇게 하면 다리 길이보다 더 많은 트럭이 올라올 일은 걱정하지 않아도 된다. ...

2024년 3월 19일 · 5 분 · 배준수

프린이

Today I Learend 날짜 2024년 3월 19일 화요일 내용 모달로 기능 추가하기 우리 서비스를 삭제하려면 Shopify 의 shop admin 쪽에서 처리하면 된다. 하지만 이와 별도로 우리 서비스 내에서도 자체적으로 삭제 버튼을 만들기로 했다. 이와 관련된 로직은 아마 내일 처리할 예정이니 내일 TIL에 담길 듯 하다. 오늘은 프론트쪽에서의 기능 구현을 우선으로 했다. 삭제 전 이유에 대한 데이터를 모달을 이용해서 수집해야 한다. 기존 계획으론 모달에서 고객이 선택하고 입력한 데이터를 수집한다. 유저가 확인버튼을 누를 경우 삭제 요청과 함께 이 데이터를 서버로 보낸다. 서버에선 데이터는 저장하고 삭제 로직을 시작한다 모달이 종료된다.. 만약 취소버튼을 누를 경우 그냥 2~3번 과정 없이 모달창을 종료한다. 의 순서로 구성했다. 프론트는 아직 너무 허접한 수준이라 조언을 받았는데, 우리 서비스에서 특별한 예외 케이스가 아니면 모달에서 요청을 보내도록 처리하지 않았다. 모달이 닫히고 기존에 위치해 있던 페이지에서 요청을 보내야 한다. 따라서 ...

2024년 3월 19일 · 2 분 · 배준수

Google Search Console 색인 등록 문제 해결법

Google Search Console 색인 등록 문제 해결법 상황 2023년 5월 27일에 지금의 깃허브 블로그를 처음 시작했다. 어려운 것, 귀찮은 것, 잘 모르는 것 투성이지만 그만큼 배울게 많아질 것이라 생각하며 시작했다. 24년 3월 18일을 기준으로 447개의 게시글을 작성했다! 자주 쓰는 만큼 고퀄리티는 아닌지라 누군가에게 보여주기 민망하지만, 그래도 한명이라도 나의 글로 도움을 받길 바라고 있다. 나 또한 다른 사람들의 글을 보며 그랬으니까. Google search console에 나의 블로그를 등록하고 sitemap.yml 과 robot.txt, feed.xml도 설정해주었다. 방법에 관한 글은 구글에 넘쳐난다. ...

2024년 3월 18일 · 2 분 · 배준수

간간히 유지보수

Today I Learend 날짜 2024년 3월 18일 월요일 내용 아직 스프린트가 끝나지 않았지만, 프론트 쪽 일정이 진행되는 동안 유지보수 작업을 시작했다. 프론트 쪽이 주 작업인데, 기존에 항상 설정되어 있던 placeholder를 서버에서 받은 세팅값이 False일 경우에는 세팅하지 않도록 한다던가, 현재 우리의 소개페이지(랜딩페이지)에 작동안되는 버튼들을 정리하고 다른 URL로 연결하는 간단한 작업들이 었다. 다만 아직 프론트 코드들은 익숙하지 않아서 기존의 구조를 망가뜨리지 않도록 잘 살펴보면서 하긴 했다. 작성된 리뷰를 보여주는 위젯에는 ‘더보기’ 기능이 있다. 말 그대로 내용이 길 경우 일부만 보여주고 모든 내용을 보기 위한 버튼이어야 정상인데 지금은 이미지만 확대된다. 내용은 아무리 길어도 다 출력된다. 이 기능을 정상적으로 되돌려야 한다. 위젯은 HTML로 서버에서 렌더링하여 제공하는데, 여기에 사용되는 더보기 관련 스크립트가 Shopify 프론트 쪽에 구현되어 있는 것 같다. 이게 맞나..? ...

2024년 3월 18일 · 1 분 · 배준수

파이썬 알고리즘 : 캐시

2024년 3월 18일 알고리즘 문제풀이 문제 캐시 난이도 Lv.2 코드 1차 80점 / 100점 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 def solution(cacheSize, cities): answer = 0 if not cacheSize: answer = 5 * len(cities) return answer arr = [] for i in cities: city = i.lower() if len(arr) < cacheSize: answer += 5 arr.append(city) continue if city in arr: answer += 1 arr.remove(city) arr.append(city) continue else: answer += 5 arr.pop(0) arr.append(city) return answer 캐시에 여유공간이 있을 때는 우선적으로 채워주었다. 캐시가 가득 찼을 때, 가장 사용된지 오래된 캐시가 삭제되야 하므로 이에 대한 구별이 필요했다. 따라서 사용한 캐시는 배열에서 삭제후 다시 추가하였다. 이렇게 되면 캐시 배열의 0번 index의 값이 1순위로 삭제될 캐시가 된다. 테스트 케이스가 몇개 있어 실패하였는데, 생각해보니 캐시가 가득 차지 않았을 때도 이미 캐시에 존재하여 추가할 필요가 없는 경우가 있었다. 예를 들어, 첫 번째 두 번쨰 도시가 같다면 내 로직에선 둘 다 캐시에 들어 가버린다. 이 경우를 위해 조건을 추가했다. ...

2024년 3월 18일 · 2 분 · 배준수

scalars의 사용 이유

Today I Learend 날짜 2024년 3월 15일 금요일 내용 scalars()의 역할 PostgreSQL에서 데이터를 가져올 떄 다음과 같은 형식을 사용했었다. 1 2 stmt = select(models.Product).where(models.Product.title != "가짜") result = db.execute(stmt).scalars().all() scalars()를 왜 써야하는지 모르는 채, 그냥 기존 코드가 그렇길래 써왔었다. 오늘 위젯 렌더링을 구현하는 과정에서 jinja2 템플릿을 이용해 위젯 HTML에 상품들의 목록을 넣어줬지만 해당 값의 필드들을 참조할 수 없었다. 1 2 3 4 5 stmt = select(models.ListDesignerProduct) .where(models.ListDesigerProduct.list_designer_widget_id == 1) result = db.execute(stmt).all() for product in result: logging.info(product.id) 이런식으로 작성되어 있었다. 이때 저 result를 직접 로깅해보니 row라고 나오면서 내부 필드를 참조할 수 없다고 오류가 발생했다. ...

2024년 3월 15일 · 1 분 · 배준수

파이썬 알고리즘 : 체육복

2024년 3월 15일 알고리즘 문제풀이 문제 체육복 난이도 Lv.1 코드 1차 93.3점 / 100점 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def solution(n, lost, reserve): lost.sort() reserve.sort() arr = set() for loser in lost: if loser in reserve: reserve.remove(loser) continue if loser - 1 in reserve: reserve.remove(loser - 1) elif loser + 1 in reserve: reserve.remove(loser + 1) else: arr.add(loser) return n - len(arr) 2개의 테스트 케이스에서 오답처리 되었다. 생각해보니 이렇게 작성할 경우 여벌이 있었으나 도둑맞은 사람의 것을 다른사람에게 빌려주게 될 수도 있다는 생각이 들었다. 따라서 우선, 여벌이 있었으나 도둑 맞아 더이상 빌려줄 여력이 없으며 다른 사람의 것도 필요 없는 사람을 제외하도록 수정했다. ...

2024년 3월 15일 · 2 분 · 배준수

메일 발송에 필요한 데이터 수집

Today I Learend 날짜 2024년 3월 14일 목요일 내용 의사소통 오류 이번 스프린트에서 내가 데이터베이스 구조를 설계했다. List Desiger에서 위젯은 다수의 상품을 들고 있게 되고 각 상품은 가공된 데이터(최근 구매자, 재고 등)를 갖고 있어야 한다. 기존에 상품과 관련된 데이터 형식을 변경하는 건 당연히 말도 안되는 소리니 위젯에서 사용할 상품의 데이터 형식을 ListDesigerProduct로 만들었다. 내가 이 테이블을 만든 목적은 위젯에서 표시될 데이터를 담아두기 위해서고, 기존에 상품이 가지고 있는 데이터(이름, 가격, sohpify내에서의 고유 ID 등)은 관계를 통해 JOIN으로 해결할 수 있을거라고 생각했다. ...

2024년 3월 14일 · 2 분 · 배준수

파이썬 알고리즘 : 음양 더하기

2024년 3월 14일 알고리즘 문제풀이 문제 음양 더하기 난이도 Lv.1 코드 1 2 3 4 5 6 7 8 def solution(absolutes, signs): answer = 0 for i in range(len(signs)): if signs[i]: answer += absolutes[i] else: answer -= absolutes[i] return answer

2024년 3월 14일 · 1 분 · 배준수

메일 발송에 필요한 데이터 수집

Today I Learend 날짜 2024년 3월 13일 수요일 내용 주간 성과 메일 약 2달 전에 각 스토어에게 주간 작성되거나 import된 리뷰 수에 대한 메일을 보내는 Task를 진행했었다. 이와 비슷하게, 새롭게 생긴 List Designer 기능의 성과를 담은 메일을 매 주 전송해야 한다. 필요한 데이터는 위젯의 클릭 수와 위젯 내 상품의 매출. 위젯의 클릭 수 데이터를 어떻게 저장할 것인지 잠깐 고민했다. 클릭 이벤트가 발생할 때마다 테이블에 레코드를 하나 씩 추가하는 방법이 있는데, 우리 서비스에서 방문자 수를 체크하는 방식이 이렇게 구현되어 있다. 다른 방법은, 각 위젯의 데이터 테이블에 필드를 하나 추가하는 것이다. ...

2024년 3월 13일 · 2 분 · 배준수