파이썬 알고리즘 : H-Index

2024년 5월 13일 알고리즘 문제풀이 문제 H-Index 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def solution(citations): answer = 0 left = 0 right = 10000 while left <= right: cnt = 0 mid = (left+right)//2 for i in citations: if i >= mid: cnt += 1 if cnt < mid: right = mid -1 else: left = mid +1 answer = (left+right)//2 return answer 가능한 값 중 최솟값 혹은 최댓값을 찾는 문제는 이제 자연스레 이진탐색이 떠오른다. ...

2024년 5월 13일 · 1 분 · 배준수

두 앱의 공통 진입점 파악

Today I Learned 날짜 2024년 5월 10일 금요일 내용 프로덕트바리언트 가격 리스트디자이너 위젯에서 할인 전후 가격이 바뀌어서 나타나고 있었다. 알고보니 쇼피파이에서 보내는 데이터 상으로 compare_at_price가 할인 전 가격(높은 가격)이고 price가 할인 후 가격(낮은 가격)인데 바꾸어서 데이터로 저장하고 있었다. 애초에 변수 이름을 좀 알아보기 쉽게 짓지 거참.. 온보딩 앱 두개가 하나의 시작점을 지니도록 처리하려니 신경써야 할 부분이 한 두개가 아니다. 예를 들어, 어떤 계정이 3개의 스토어에 우리 서비스를 설치했다고 가정해보자. A 샵은 알파플러스만 사용하고, B 샵은 브라우저 부스터만 사용, C 샵은 둘 다 사용한다. 계정은 두 서비스를 다 사용한다는 변수를 프론트에게 제공하고 있고, 세션에 저장된다. 그럼 각 샵은 어떻게 처리해야할까? 어드민 페이지에서 A샵이나 B샵을 선택하면 그 샵이 설치한 앱(A샵은 알파플러스, B샵은 브라우저 부스터)에만 접근하도록 해주어야 한다. C샵은 둘 다 접근할 수 있어야 한다. 로그인 시점에 이 정보가 프론트에게 주어져야 한다. 이런 부분이 한두 개가 아니다.. 기존 알파플러스 서비스를 망가뜨리지 않고 새로운 앱을 합치다 보니 머리가 너무 복잡하다ㅏㅏㅏㅏㅏㅏ…. ...

2024년 5월 10일 · 1 분 · 배준수

파이썬 알고리즘 : 덧칠하기

2024년 5월 10일 알고리즘 문제풀이 문제 덧칠하기 난이도 Lv.1 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from heapq import heappop, heappush def solution(n, m, section): answer = 0 arr = [] for x in section: heappush(arr,x) idx = heappop(arr) end = idx + m -1 cnt = 1 while arr: if arr[0] <= end: heappop(arr) continue else: idx = heappop(arr) end = idx + m -1 cnt += 1 return cnt 최소힙을 사용하는 아이디어가 금방 떠올라서 쉽게 풀었다. ...

2024년 5월 10일 · 1 분 · 배준수

2앱 체제 구현

Today I Learned 날짜 2024년 5월 9일 목요일 내용 샵 디테일 수정 새로운 브라우즈 부스터 앱에서 사용할 샵 테이블을 별도로 생성했었다. 이 앱에 앞으로 다양한 서비스가 추가될 테지만, 우선은 필요한 최소한으로 구현하는게 좋다고 클린 아키텍처에서 배웠다. 알파플러스 앱에선 쇼피파이에서 보내주는 데이터는 샵 테이블에, 우리 서비스에서 사용하기 위해 필요한 정보들을 담는데는 샵 디테일 테이블을 사용한다. 우선 브라우저 부스터 앱은 샵 디태일을 별도로 만들지지 않았다. 배운대로 했다는 뿌듯함을 느꼈다. 브라우저 부스터 앱을 설치해도, 알파플러스와 동일한 온보딩 및 회원가입 과정을 겪어야 해서 샵 데이테일 테이블이 필요하다는 것을 꺠달았다. 바로 샵 디테일을 만들었다. 난 생각의 범위가 참 좁다. ...

2024년 5월 9일 · 2 분 · 배준수

파이썬 알고리즘 : two-sum

2024년 5월 9일 알고리즘 문제풀이 문제 two-sum 난이도 Easy 코드 1차시도 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 class Solution: def twoSum(self, nums, target: int): board = dict() idx_arr = dict() answer = [] for i in range(len(nums)): if nums[i] not in board: board[nums[i]] = 1 else: board[nums[i]] += 1 for i in range(len(nums)): if nums[i] not in idx_arr: idx_arr[nums[i]] = [i] else: idx_arr[nums[i]].append(i) for i in range(-target,target+1,1): if i in board and target-i in board: if i != target-i: answer = [idx_arr[i][0],idx_arr[target-i][0]] break else: if board[i] >= 2: answer = [idx_arr[i][0], idx_arr[i][1]] break return answer 다 조회하면 시간이 초과될 것 같아, dictionary를 이용하려 했다. target이 0일 떈 조합을 찾는 반복문이 제대로 작동하지 않아 오답처리되었다. ...

2024년 5월 9일 · 1 분 · 배준수

Shopify Session 설치

Today I Learned 날짜 2024년 5월 8일 수요일 내용 Shopify session 새로 추가될 앱을 같은 서버에 만들었다. 앱이 설치되는 방식은 대략 다음과 같다. 쇼피파이에 설정해둔 우리 서버의 엔드포인트로 요청이 들어오면(/shopify) 우리 서버는 shopify_session을 이용해 허용 URL을 만들고 redirect시킨다. 앱을 설치하는 고객은 앱이 요청하는 권한(고객 데이터 접근, 주문 데이터 접근 등등)에 대해 확인하고 허가하는 창으로 안내되고, 허용하면 다시 우리 서버로 요청이 넘어온다. 이후로 온보딩 플로우로 넘어가든, 로그인으로 넘어가든 우리 코드대로 처리된다. ...

2024년 5월 8일 · 2 분 · 배준수

데이터베이스 개선작업 시작

Today I Learned 날짜 2024년 5월 7일 화요일 내용 데이터베이스 개선 지난주에 이어 데이터베이스를 개선하고 있는데, 예상치 못한 부분에서 신경쓸 거리가 많다. 예를 들어, 서비스에 가입할 때 항상 Shop테이블을 기준으로 구현되어 있다. 이 부분의 로직도 다른 예외처리를 두어야 한다. 그리고 리뷰서버에선 Redis를 이용해 샵의 정보를 불러오는데 새로 만든 앱의 샵은 Redis에서 정보를 찾을 수 없다. 우선은 Shop_id로 Shop 서버에서 정보를 가져오는 함수를 만들어 처리하고 있다. 점차 두번째 앱에서 처리해야할 정보나 범위가 많아진다면 Redis에 두번째 앱의 shop들에 대한 정보를 추가해주야 한다. ...

2024년 5월 7일 · 1 분 · 배준수

파이썬 알고리즘 : 괄호 변환

2024년 5월 7일 알고리즘 문제풀이 문제 괄호 변환 난이도 Lv.2 코드 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 from collections import Counter # 균형잡힌 괄후 문자열인지 확인하는 함수 def check_balance(k): arr = Counter(k) if arr['('] == arr[')']: return True return False # 올바른 괄호 문자열인지 확인하는 함수 def check_right(k): while '()' in k: arr = list(k) for i in range(len(k)-1): if arr[i] == '(' and arr[i+1] == ')': arr[i] = arr[i+1] = '' k = ''.join(arr) if not len(k): return True return False # 변환과정을 나타내는 함수 def process(x): # 1단계 if not x: return x # 2단계 for i in range(1,len(x)+1): tmp = x[:i] if check_balance(tmp): break u = tmp v = x[i:] # 3단계 if check_right(u): # 3-1단계 return u + process(v) # 4단계 else: # 4-1, 4-2, 4-3단계 new = '(' + process(v) + ')' arr = [] # 4-4단계 for i in range(1,len(u)-1): if u[i] == '(': arr.append(')') else: arr.append('(') new += ''.join(arr) # 4-5단계 return new def solution(p): answer = '' u = '' answer = process(p) return answer 카카오는 시키는대로 하면 된다. ...

2024년 5월 7일 · 2 분 · 배준수

파이썬 알고리즘 : 별 찍기 - 10

2024년 5월 6일 알고리즘 문제풀이 문제 별 찍기 - 10 난이도 골드 5 코드 길이가 3인 정사각형에서 가운데만 비어있는 형태로 반복하여 쌓이게 된다. 정사각형을 9등분하여 가운데에만 제외하고 8개를 복사해준다고 생각했다. 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 import sys n = int(sys.stdin.readline()) board = [[' ' for _ in range(n)] for _ in range(n)] # 재귀함수 정의 def main(num:int): # 사각형이 최소크기면 if num == 3: for i in range(3): for j in range(3): # 가운데(좌표 1,1)를 제외하고 *을 그려준다. if i != 1 or j != 1: board[i][j] = '*' return # 3등분하여 재귀를 반복 p = num//3 main(p) for i in range(0, num, p): for j in range(0, num, p): # 가운데가 아닐 때를 제외하곤 똑같은 모양을 넣어준다. if i != p or j != p: for x in range(p): board[i+x][j:j+p] = board[x][:p] # 함수 실행 main(n) # 결과 출력 for i in range(n): for j in range(n): print(board[i][j], end='') print() 출처 : TaxFree ...

2024년 5월 6일 · 1 분 · 배준수

데이터베이스 테이블 계층 변경하기

Today I Learned 날짜 2024년 5월 3일 금요일 내용 DB구조에 대해 열심히 고민했다. 우리 서비스는 애초에 앱을 여러개 낼 계획이 없었기 떄문에 Shopify에서 받은 스토어 정보를 Shop 테이블에 저장하고 이 테이블을 중심으로 모든 로직이 이루어진다. 가장 최상위 테이블 역할을 한다. 알파리뷰 서비스에 가입한 계정에 관한 테이블인 ShopAdminAccount가 같은 계층에 있어 서로 참조할 수 있는 테이블이긴 하지만, 그외의 모든 데이터는 결국 Shop을 기준으로 정규화가 이루어져 있다. 따라서 서비스 삭제도 이 Shop을 삭제하면 이와 연관된 모든 테이블이 삭제된다(일부 남는 테이블과 리뷰서버 쪽도 처리하긴 해야 하지만…). ...

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