파이썬 알고리즘 : 프렌즈4블록

2024년 2월 27일 알고리즘 문제풀이 문제 프렌즈4블록 난이도 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 60 61 62 63 64 65 66 def solution(m, n, board): answer = 0 # 시계방향으로 90도 회전하는 함수 # 따라서 n x m 인 배열이 된다. # 블록의 추락도 아래가 아닌 왼쪽으로 발생해야 한다. arr = [[] for _ in range(n)] for k in range(n): for i in range(m-1,-1,-1): arr[k].append(board[i][k]) # 점을 기준으로 오른쪽, 아래, 오른쪽 아래가 모두 동일한지 확인하는 함수 def check(a,b): result = False tmp = arr[a][b] if arr[a+1][b] == tmp and arr[a][b+1] == tmp and arr[a+1][b+1] == tmp: result = True return result # 점을 기준으로 오른쪽, 아래, 오른쪽 아래 4개를 지우는 함수. # 지워지는 블록이 다른 곳과 겹칠 경우를 대비하여, 실제 지워진 갯수를 계산하여 반환 def delete(a,b): result = 0 if arr[a][b] != '0': arr[a][b] = '0' result += 1 if arr[a+1][b] != '0': arr[a+1][b] = '0' result += 1 if arr[a][b+1] != '0': arr[a][b+1] = '0' result += 1 if arr[a+1][b+1] != '0': arr[a+1][b+1] = '0' result += 1 return result # 90도 회전하였기 때문에, 왼쪽으로 블록이 떨어지는 함수 구현 # 각 행마다, 비어있는 열을 발견할 경우 오른쪽을 탐색하여 떨어질 블록을 찾아 바꿔준다. # 한 칸씩 떨어뜨리면, 여러 블록을 떨어뜨리는 경우가 복잡해진다. def fall(): for i in range(n): for j in range(m): if arr[i][j] == '0': for k in range(j+1,m): if arr[i][k] != '0': arr[i][j] = arr[i][k] arr[i][k] = '0' break # '0'이 아니라는 조건을 추가하지 않으면 무한루프가 실행된다. while True: delete_list = [] for i in range(n-1): # 여기가 1,m 이면 테스트 5가 실패함 for j in range(m-1): if arr[i][j] != '0' and check(i,j): delete_list.append([i,j]) if not delete_list: break for a,b in delete_list: tmp = delete(a,b) answer += tmp fall() return answer 겁나 힘들게 풀었다… 기존에는 위와 같이 풀되, 90도로 회전하지 않았다. 이떄 발생하는 어려움은 블록을 부수고 떨어뜨리는 것을 구현하기 힘들었다. 위에서 아래로 떨어뜨릴 경우 같은 열이지만 다른 행인 원소들간의 비교가 이루어져야 한다. 위 각주에서도 말했지만 한 칸씩 옮길 경우 2개가 같이 떨어질 떄나, 여러 칸을 떨어뜨리는 경우의 수는 상당히 복잡하기 때문에 구현이 힘들었다. 추락을 같은 List 안에서 발생하도록 하면 훨씬 편해질 것이라고 생각해서 배열을 90도 회전하였다. ...

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

파이썬 알고리즘 : 크레인 인형뽑기 게임

2024년 2월 26일 알고리즘 문제풀이 문제 크레인 인형뽑기 게임 난이도 Lv.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 27 28 29 30 def solution(board, moves): n = len(board) stk = [] answer = 0 # 열에서 가장 위에 있는 인형을 찾는 함수 # 찾으면 board에서 0으로 바꾸고 반환 def first_target(row): for i in range(n): if board[i][row]: result = board[i][row] board[i][row] = 0 break else: result = False return result # 인형이 있을 때, 이미 들어있는 인형과 동일하면 2개 제거, 아니면 추가 for x in moves: row = x-1 tmp = first_target(row) if tmp: if stk: if stk[-1] == tmp: stk.pop() answer += 2 continue stk.append(tmp) return answer

2024년 2월 26일 · 1 분 · 배준수

파이썬 알고리즘 : 짝지어 제거하기

2024년 2월 23일 알고리즘 문제풀이 문제 짝지어 제거하기 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def solution(s): arr = list(s) stk = [] for i in range(len(s)): if not stk: stk.append(arr[i]) continue else: if stk[-1] == arr[i]: stk.pop() else: stk.append(arr[i]) if not stk: answer = 1 else: answer = 0 return answer

2024년 2월 23일 · 1 분 · 배준수

파이썬 알고리즘 : 정수 내림차순으로 배치하기

2024년 2월 22일 알고리즘 문제풀이 문제 정수 내림차순으로 배치하기 난이도 Lv.1 코드 1 2 3 4 5 6 7 def solution(n): arr = list(str(n)) map(int,arr) arr.sort(reverse=True) map(str,arr) answer = ''.join(arr) return int(answer)

2024년 2월 22일 · 1 분 · 배준수

삭제한 Store의 API에 접근할 수 없는 이유

Today I Learned 날짜 2024년 2월 14일 수요일 내용 안돼 앱을 삭제한 shop의 메타필드와 테마 내 에셋을 삭제하는 Task를 진행중이다. 문제가 되는 부분을 정리하자면 app이 삭제되면 웹훅 시그널이 도착하는데, 이 때 shopify API로 메타필드나 에셋에 접근하면 access token으로 인해 401이 뜬다. 메타필드와 asset에 접근하는 다른 커맨드를 이용해 잘 작동되는게 확인된 access_token을 삭제해도 마찬가지로 aceess_token으로 인해 401이 뜬다. 열심히 구글링하는 과정에서 다음 링크를 발견했다. 요약하면, “app/uninstalled”라는 topic의 웹훅이 도착했을 떄는 이미 우리 app이 삭제된 이후기 떄문에 access token이 무효화되어 스토어의 에셋이나 메타필드에 접근할 수 없다는 것. 무려 Shopify 파트너의 답변이라… 그렇다면 알파리뷰를 삭제한 store의 스니펫을 위해 API로 전송한 데이터를 삭제할 수 있는 방법이 없다. 그리고 shopify 개발자 포럼을 확인해보니 이 문제를 나만 겪는게 아닌가보다. ...

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

rich snippet 위치 찾기

# Today I Learned ## 날짜 2024년 2월 13일 화요일 ## 내용 ### 왤까? 저번주부터 진행하던 Task는 고객이 서비스를 설치할 당시 생성된 데이터들 중 우리 서버에 있는 것과 Shopify에 저장해둔 것을 찾아 삭제해야 한다. 고객이 서비스를 삭제할 때 발생하는 일련의 과정은 웹훅으로 구현되어 있다. 내 로컬에서 태스크를 진행하기 위해 테스트 서버와 로컬에 웹훅을 설치해 열심히 구현했다. 저번 TIL에 있었던 metafields나 asset이 여기에 해당된다. 생성될 때의 함수를 보고 반대로 했다. 내가 지워야할 데이터는 구글에 rich snippet을 제공하기 위해 생성되었던 것들인데, 탐색해서 삭제하는 로직을 완성했다. 문제를 겪는 부분이 있고, 분명 발생해야 할 문제인데 그렇지 않은 부분도 있다. 우선, 설치를 삭제한 shop의 테마를 shopify에서 조회하는데 자꾸 실패한다. 이미 작성된 다른 커맨드를 이용해 테마를 조회할 떄는 잘 나오는데 왜 여기서만 문제가 될까? 같은 함수를 사용하는데.. 삭제해야할 테마가 존재하지 않는다면 그냥 넘어가도록 로직을 설정할지, 무언가 잘못된 부분이 있는지 아직 확신이 서지 않는다. 왜 안될까? 두번쨰로, 테마의 asset을 다루는 API는 Shopify에 예외적인 상황임을 알려 승인받지 않는다면 더 이상 지원하지 않는다. 우리 서비스는 승인을 받았지만, 실서버만 적용되기 때문에 테스트서버에선 asset API가 작동되지 않을 것이라고 조언을 받았었다. 이 과정을 어떻게 처리해야할지 참 고민이 많았는데 아직까지 나타나지 않고 있다. 왜 될까? ## 회고 긴 연휴 끝이라 집중을 잘 못할까 걱정했는데 기우였다. 휴식이 최고.

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

Shopify API

Today I Learned 날짜 2024년 2월 7일 수요일 내용 새로 시작한 Task에 대해 파악하는데 하루 종일 썼다. 내가 등록한 ECS Task가 5일동안 작동하지 않았는데, 로그나 apm.capture에 아무것도 안떴다. 다시 작동하니까 아무 문제 없이 잘 되는데 이유를 모르겠다. 그냥 해프닝이길.. Shopify에서 정보 받아오기 메타필드(metafield) 그동안 잘 보지 않았던 부분이라 정확한 개념을 우선 파악했다. Shopify에는 스토어에 대한 정보를 저장하여 매번 서버에서 가져오지 않고 프론트에서 동적으로 출력하는데 사용할 수 있다. 데이터를 메타필드에 저장한다. ...

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

스프린트 준비

Today I Learned 날짜 2024년 2월 6일 화요일 내용 많은 것을 하진 못했다. weekly review report email은 잘 작동했지만 1가지 오류가 발생했다. 실서버 데이터 중 잘못된 데이터가 있어 그 샵의 시간대를 찾지 못했다. 어제 미처 추가하지 못한 부분이라 해당 부분에 대한 예외처리 코드를 추가했다. 당장 급한 Task는 없다고 생각해 테스트 코드를 작성하려고 했다. 이번에 만든 기능들에 대한 유닛테스트 코드를 작성해두고 싶었다. 2달? 정도 전 내가 이미 있던 테스트들이 고장나있던 상태라 고쳤는데 1가지 오류가 발생했다. 모든 타입의 위젯을 생성해보는 테스트였는데 특정 타입에서 item_per_page 라는 속성이 없어 발생한 문제였다. 각 위젯별로 위젯에 보여줄 아이템의 갯수를 설정할 수 있는데 GALLERY_GRID_TEMPLATE 타입에는 설정할 수 없다. 내가 파악하기론, GALLERY_GID 라는 위젯 안에 들어가는 템플릿이기 때문이다. 따라서 위젯을 생성하는 함수에서는 처리하지 않는 타입이라 오류가 발생했다. 제외 이유를 각주에 추가하고 테스트 케이스에서 제외했다. ...

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

예외 처리

Today I Learned 날짜 2024년 2월 5일 월요일 내용 이전에 진행했던 Task들을 마무리했다. 로컬에서는 문제없이 작동한다는 것을 확인했기 떄문에, 테스트 서버에서 확인이 필요했다. logging문으로 구체적인 예외 메시지를 확인할 수 있었는데, 특정 데이터가 None일 때 오류가 발생했다. 오류가 난 필드는 shop이 꼭 가지고 있어야 하는 데이터였기 때문에 이상했다. 테스트 서버의 데이터베이스를 확인해보니 모든 필드의 값이 None으로 되어있는 뜬금없는 데이터가 들어있었다. 그 레코드 하나를 지우면 해결될 일이지만, 실제 서버에서 이런일이 발생했다면 저 뜬금없는 레코드 하나때문에 작동을 안하고, 찾을려고 이리저리 뒤져볼 모습을 생각하니 해프닝으로 넘어갈 일은 아니라고 생각했다. ...

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

효율성에 매몰되지 않기

Today I Learned 날짜 2024년 2월 2일 금요일 내용 삼지선다 나름 기가 막힌 아이디어가 떠올라서, 어제의 Task를 처리했다. 내가 달성해야 할 구현 목표는 다음과 같다. 구글 스프레드시트에 있는 데이터는 기존 행에 새로운 값을 덮어써준다. 구글 스프레드시트에 없지만 2024년 2월 이후 가입했거나, 기존에 가입했으나 새로 AI 서비스를 이용하게 된 고객의 데이터는 새로운 행에 추가해준다. 서비스에서 탈퇴해 데이터가 없어졌을 떈 스프레드시트에서도 삭제한다. 추가된 데이터를 한번 정제해서 쓰면 되니 굳이 API가 완벽하게 정리된 데이터를 만들 필요는 없다고 하셨지만 뭔가 놓치고 있다는 느낌이 자꾸 들어 기존의 걸림돌을 되짚어봤다. ...

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