├── .github └── workflows │ └── pr_alert.yml ├── .gitignore ├── BOARDCOVER ├── BOARDCOVER_chrisjune.py ├── BOARDCOVER_chrisjune_2.py ├── README.md ├── boardcover_brownbear.py ├── boardcover_hyewoneee.py └── boardcover_yoonnoon.py ├── CLIMBING └── climbing_jimin.py ├── CLIMBING_STAIRS ├── __init__.py ├── climbing_stairs_brownbear.py ├── climbing_stairs_chrisjune.py ├── climbing_stairs_jonnung.go ├── climbing_stairs_jonnung.py ├── climbing_stairs_yoonnoon.py └── climging_stairs_hyewoneee.py ├── FENCE ├── README.md ├── fence_americanomin.py ├── fence_brownbear.py ├── fence_chrisjune.py ├── fence_chrisjune_re.py ├── fence_hyewoneee.py ├── fence_jonnung.py ├── fence_yoonnoon.py └── test_fence_chrisjune.py ├── IS_SUBSEQUENCE └── is_subsequence_chrisjune.py ├── JUMPGAME ├── README.md ├── jumpgame_brownbear.py ├── jumpgame_chrisjune.py ├── jumpgame_hyewoneee.py ├── jumpgame_jonnung.py ├── jumpgame_leejimin.py └── jumpgame_yoonnoon.py ├── JUMPGAME2 ├── jumpgame2_chrisjune.py ├── jumpgame2_jonnung.py └── jumpgame_2_yoonnoon.py ├── JUMPGAMEII └── jump_game_ll_brownbear.py ├── LIS ├── README.md ├── lis_chrisjune.py ├── lis_hyewoneee.py ├── lis_jimin.py ├── lis_jonnung.go ├── lis_jonnung.py └── lis_yoonnoon.py ├── LONGEST_PALINDROMIC_SUBSTRING ├── README.md ├── longest_palindromic_substring_chrisjune.py ├── longest_palindromic_substring_yoonnoon.py └── lps_jonnung.py ├── MAXIMUM_SUBARRAY ├── __init__.py ├── maximum_subarray_brownbear.py ├── maximum_subarray_hyewoneee.py ├── maximum_subarray_jonnung.py ├── maximum_subarray_leejimin.py ├── maximum_subarray_yoonnoon.py └── maxium_subarray_chrisjune.py ├── PICNIC ├── PICNIC_chirsjune_2.py ├── PICNIC_chrisjune.py ├── README.md ├── picnic_americanomin.py ├── picnic_brownbear.py ├── picnic_hyewoneee.py ├── picnic_jonnung.py └── picnic_yoonnoon.py ├── QUADTREE ├── README.md ├── quadtree_brownbear.py ├── quadtree_chrisjune.py ├── quadtree_hyewoneee.py ├── quadtree_jonnung.py └── quadtree_yoonnoon.py ├── README.md ├── TRIANGLEPATH ├── README.md └── trianglepath_chrisjune.py ├── WILDCARD ├── README.md ├── wildcard_chrisjune.py ├── wildcard_chrisjune_re.py ├── wildcard_hyewoneee.py ├── wildcard_jimin.py ├── wildcard_jonnung.py └── wildcard_yoonnoon.py └── tests ├── CLIMBING_STAIRS └── test_climbing_stairs.py ├── FENCE ├── test_fence_americanomin.py └── test_fence_jonnung.py ├── JUMPGAME └── test_jumpgame_jonnung.py ├── JUMPGAME2 └── test_jumpgame2_jonnung.py ├── LIS └── test_lis_jonnung.py ├── LONGEST_PALINDROMIC_SUBSTRING └── test_lps_jonnung.py ├── MAXIMUM_SUBARRAY └── test_maximum_subarray.py └── QUADTREE └── test_quadtree_jonnung.py /.github/workflows/pr_alert.yml: -------------------------------------------------------------------------------- 1 | name: PR Alert 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | pr_alert: 7 | name: PR Alert 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Send Message 11 | uses: jonnung/29rithm_algospot_pr_alert@master 12 | env: 13 | WEBHOOK_URL: "https://bot.29cm.co.kr/slack/message/" 14 | PULL_REQUEST_NUMBER : ${{ github.event.pull_request.number }} 15 | PULL_REQUEST_TITLE : ${{ github.event.pull_request.title }} 16 | PULL_REQUEST_AUTHOR_NAME : ${{ github.event.pull_request.user.login }} 17 | PULL_REQUEST_AUTHOR_ICON_URL : ${{ github.event.pull_request.user.avatar_url }} 18 | PULL_REQUEST_URL : ${{ github.event.pull_request.html_url }} 19 | PULL_REQUEST_BODY : ${{ github.event.pull_request.body }} 20 | with: 21 | channel_id: "GQLD2ESAJ" 22 | id: send_message 23 | - name: Echo it works 24 | run: echo "It works!" 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | .pytest_cache 4 | .vscode 5 | Pipfile* -------------------------------------------------------------------------------- /BOARDCOVER/BOARDCOVER_chrisjune.py: -------------------------------------------------------------------------------- 1 | # BOARDCOVER 2 | cards = [[(0, 0), (1, 0), (0, 1)], [(0, 0), (1, 0), (1, 1)], [(0, 0), (0, 1), (1, 1)], [(0, 0), (1, 0), (1, -1)]] 3 | board = [] 4 | 5 | 6 | def count_board(blank_count): 7 | global count 8 | 9 | if blank_count % 3 != 0: 10 | return 11 | 12 | # find first index 13 | first_free = (-1, -1) 14 | for row in range(len(board)): 15 | for col in range(len(board[0])): 16 | if board[row][col] == 0: 17 | first_free = (row, col) 18 | break 19 | if first_free != (-1, -1): 20 | break 21 | 22 | if first_free == (-1, -1): 23 | count += 1 24 | return 25 | 26 | # put card on board 27 | for card in cards: 28 | if covered(first_free, card, 1): 29 | count_board(blank_count - 3) 30 | covered(first_free, card, -1) 31 | 32 | 33 | def covered(location, card, action): 34 | result = True 35 | for ele in card: 36 | row = location[0] + ele[0] 37 | col = location[1] + ele[1] 38 | if row < 0 or row >= len(board) or col < 0 or col >= len(board[0]): 39 | result = False 40 | continue 41 | if board[row][col] == 1: 42 | result = False 43 | board[row][col] += action 44 | return result 45 | 46 | 47 | if __name__ == '__main__': 48 | global count 49 | cases = int(input()) 50 | for case in range(cases): 51 | board = [] 52 | count = 0 53 | blank_count = 0 54 | size = list(map(int, input().split())) 55 | height, width = size[0], size[1] 56 | for row in range(height): 57 | new_row = [int(i.replace('#', '1').replace('.', '0')) for i in input()] 58 | board.append(new_row) 59 | blank_count += new_row.count(0) 60 | count_board(blank_count) 61 | print(count) 62 | -------------------------------------------------------------------------------- /BOARDCOVER/BOARDCOVER_chrisjune_2.py: -------------------------------------------------------------------------------- 1 | # H x W의 카드로 덮는다 2 | # 문제는, 카드마다 모양이 다르기 때문에 뒷셀의 카드를 먼저 덮은경우 중복으로 세게 된다. 3 | # 따라서 카드놓는 셀을 선택할 순서를 정해놓으면 앞에서 뒤로, 뒤에서 앞으로 세는 것을 막을 수 있다. 4 | # 그 셀을 선택하는 기준을 가장 윗쪽 오른쪽부터 찾아내고, 그 셀에 카드를 대어보고 맞으면 5 | # 재귀를 태운다. 6 | 7 | # 또 문제는, 카드를 놓을 수 없던 경우 놓았던 카드를 ㄱ자를 놓고 ㄴ자 모양의 다른 카드도 놓아야하기 때문에 8 | # 카드를 놓을 수 있는 경우에는 재귀 함수 이후에 카드를 떼는 로직이 필요하고, 9 | # 카드를 놓을 수 없는 경우에는 재귀를 태우지 않아야 한다. 10 | 11 | cards = [ 12 | [(0, 0), (0, 1), (1, 1)], 13 | [(0, 0), (1, 0), (1, 1)], 14 | [(0, 0), (1, 0), (1, -1)], 15 | [(0, 0), (1, 0), (0, 1)] 16 | ] 17 | 18 | 19 | def counter(board): 20 | first = (-1, -1) 21 | for row in range(len(board)): 22 | for col in range(len(board[0])): 23 | if board[row][col] == 0: 24 | first = (row, col) 25 | break 26 | if first != (-1, -1): 27 | break 28 | if first == (-1, -1): 29 | return 1 30 | 31 | count = 0 32 | for card in cards: 33 | if covered(card, board, first, 1): 34 | count += counter(board) 35 | covered(card, board, first, -1) 36 | return count 37 | 38 | 39 | # 카드가 겹치는 것과 무관하게 일단 카드를 올린다고 판단해야, rollback할 때 편하다 40 | def covered(card, board, index, direction): 41 | result = True 42 | for idx in card: 43 | new_row = index[0] + idx[0] 44 | new_col = index[1] + idx[1] 45 | if new_row < 0 or new_col < 0 or new_row >= len(board) or new_col >= len(board[0]): 46 | result = False 47 | continue 48 | if board[new_row][new_col] != 0: 49 | result = False 50 | board[new_row][new_col] += direction 51 | return result 52 | 53 | 54 | if __name__ == '__main__': 55 | for case in range(int(input())): 56 | board = [] 57 | info = [int(i) for i in input().split()] 58 | for i in range(info[0]): 59 | board.append([1 if i == '#' else 0 for i in list(input())]) 60 | print(counter(board)) 61 | -------------------------------------------------------------------------------- /BOARDCOVER/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/BOARDCOVER 2 | -------------------------------------------------------------------------------- /BOARDCOVER/boardcover_brownbear.py: -------------------------------------------------------------------------------- 1 | """ 2 | 흰 칸 3칸 짜리인 L자로 모든 판을 덮는 수 (회전 가능) 3 | 4 | 테스트 케이스 5 | 행 열 (H W) (1 <= H,W <= 20) 6 | 다음 H 줄에 W 수 만큼 # 과 . 7 | #은 검은 칸, .은 흰 칸 8 | 총 흰 칸의 수는 50을 넘지 않음 9 | 3 10 | 3 7 11 | #.....# 12 | #.....# 13 | ##...## 14 | 3 7 15 | #.....# 16 | #.....# 17 | ##..### 18 | 8 10 19 | ########## 20 | #........# 21 | #........# 22 | #........# 23 | #........# 24 | #........# 25 | #........# 26 | ########## 27 | 28 | 결과 29 | 0 30 | 2 31 | 1514 32 | """ 33 | 34 | 35 | """ 36 | 3칸짜리 L 모양을 탐색하는 방법은 총 8가지다 37 | - 알파벳 순서로 탐색을 진행한다 38 | - 탐색 순서는 오른쪽, 아래, 왼쪽 39 | - 위에서부터 진행하므로 위로 올라가는 길을 찾을 필요는 없다 40 | 41 | 1. 42 | a b 43 | c 44 | 45 | 2. 46 | a b 47 | c 48 | 49 | 3. 50 | a 51 | b c 52 | 53 | # 현재 행,열의 인덱스에서 오른쪽 한 칸이 막힌 의미 54 | 4. 55 | a 56 | c b 57 | 58 | : 59 | 위에서 찾은 방법으로 진행하면서 색칠한다. 60 | 61 | 62 | pseudo code 63 | 64 | global 색칠된 2차원배열[행H][열W] : #은 True, .은 False로 변경 65 | global cnt 66 | 67 | def run(현재 행 인덱스: i, 현재 열 인덱스: j): 68 | if j > W: 69 | run(i, 0) 70 | if i > H: 71 | if 색칠된 2차원배열[행H][열W] 의 모든 값이 True인 경우: 72 | cnt += 1 73 | 74 | # 위 케이스 1번 확인 75 | if not (색칠된 2차원배열[i][j] and 색칠된 2차원배열[i][j+1] and 색칠된 2차원배열[i+1][j+1]): 76 | 색칠된 2차원배열[i][j], 색칠된 2차원배열[i][j+1], 색칠된 2차원배열[i+1][j+1] = True 77 | run(i, j + 2) 78 | # 위 케이스 2번 확인 79 | if not (색칠된 2차원배열[i][j] and 색칠된 2차원배열[i][j+1] and 색칠된 2차원배열[i+1][j]): 80 | 색칠된 2차원배열[i][j], 색칠된 2차원배열[i][j+1], 색칠된 2차원배열[i+1][j] = True 81 | run(i, j + 2) 82 | # 위 케이스 3번 확인 83 | if not (색칠된 2차원배열[i][j] and 색칠된 2차원배열[i+1][j] and 색칠된 2차원배열[i+1][j+1]): 84 | 색칠된 2차원배열[i][j], 색칠된 2차원배열[i+1][j], 색칠된 2차원배열[i+1][j+1] = True 85 | run(i, j + 1) 86 | # 위 케이스 4번 확인 87 | if not (색칠된 2차원배열[i][j] and 색칠된 2차원배열[i+1][j] and 색칠된 2차원배열[i+1][j-1]): 88 | 색칠된 2차원배열[i][j], 색칠된 2차원배열[i+1][j], 색칠된 2차원배열[i+1][j-1] = True 89 | run(i, j + 2) 90 | 91 | return cnt 92 | 93 | 94 | """ 95 | 96 | 97 | def is_success(board): 98 | for b in board: 99 | if False in b: 100 | return False 101 | return True 102 | 103 | 104 | def run(i, j): 105 | global cnt 106 | if j >= W: 107 | run(i + 1, 0) 108 | 109 | if i >= H: 110 | if is_success(board): 111 | cnt += 1 112 | 113 | if i + 1 < H and j + 1 < W and not (board[i][j] or board[i][j + 1] or board[i + 1][j + 1]): 114 | board[i][j] = board[i][j + 1] = board[i + 1][j + 1] = True 115 | run(i, j + 2) 116 | board[i][j] = board[i][j + 1] = board[i + 1][j + 1] = False 117 | if i + 1 < H and j + 1 < W and not (board[i][j] or board[i][j + 1] or board[i + 1][j]): 118 | board[i][j] = board[i][j + 1] = board[i + 1][j] = True 119 | run(i, j + 2) 120 | board[i][j] = board[i][j + 1] = board[i + 1][j] = False 121 | if i + 1 < H and j + 1 < W and not (board[i][j] or board[i + 1][j] or board[i + 1][j + 1]): 122 | board[i][j] = board[i + 1][j] = board[i + 1][j + 1] = True 123 | run(i, j + 1) 124 | board[i][j] = board[i + 1][j] = board[i + 1][j + 1] = False 125 | if i + 1 < H and j < W and -1 < j - 1 and not (board[i][j] or board[i + 1][j] or board[i + 1][j - 1]): 126 | board[i][j] = board[i + 1][j] = board[i + 1][j - 1] = True 127 | run(i, j + 1) 128 | board[i][j] = board[i + 1][j] = board[i + 1][j - 1] = False 129 | if i < H and j < W and board[i][j]: 130 | run(i, j + 1) 131 | return cnt 132 | 133 | 134 | for _ in range(int(input())): 135 | H, W = map(int, input().split(' ')) 136 | board = [[s == '#' for s in input()] for _ in range(H)] 137 | cnt = 0 138 | print(run(0, 0)) 139 | 140 | -------------------------------------------------------------------------------- /BOARDCOVER/boardcover_hyewoneee.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/29rithm/algospot/3b4c671d089b58e49a558573b4e05abb80de04d8/BOARDCOVER/boardcover_hyewoneee.py -------------------------------------------------------------------------------- /BOARDCOVER/boardcover_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class BoardCover: 5 | def __init__(self, n, m): 6 | self.n = n 7 | self.m = m 8 | self.count = 0 9 | 10 | def get_lu(self, idx, board): 11 | """ 12 | ##.## 13 | #..## 14 | ##### 15 | ##### 16 | """ 17 | if idx // self.m == 0: 18 | return None 19 | if idx % self.m == 0: 20 | return None 21 | if board[idx - 1] == '#' or board[idx - self.m] == '#': 22 | return None 23 | return idx, idx - 1, idx - self.m 24 | 25 | def get_rd(self, idx, board): 26 | """ 27 | ##### 28 | ##..# 29 | ##.## 30 | ##### 31 | """ 32 | if idx // self.m == self.n - 1: 33 | return None 34 | if idx % self.m == self.m - 1: 35 | return None 36 | if board[idx + 1] == '#' or board[idx + self.m] == '#': 37 | return None 38 | return idx, idx + 1, idx + self.m 39 | 40 | def get_ru(self, idx, board): 41 | """ 42 | ##.## 43 | ##..# 44 | ##### 45 | ##### 46 | """ 47 | if idx // self.m == 0: 48 | return None 49 | if idx % self.m == self.m - 1: 50 | return None 51 | if board[idx + 1] == '#' or board[idx - self.m] == '#': 52 | return None 53 | return idx, idx + 1, idx - self.m 54 | 55 | def get_ld(self, idx, board): 56 | """ 57 | ##### 58 | #..## 59 | ##.## 60 | ##### 61 | """ 62 | if idx // self.m == self.n - 1: 63 | return None 64 | if idx % self.m == 0: 65 | return None 66 | if board[idx - 1] == '#' or board[idx + self.m] == '#': 67 | return None 68 | return idx, idx - 1, idx + self.m 69 | 70 | def solution(self, _data): 71 | board = '' 72 | for line in _data: 73 | board += line 74 | if board.count('.') % 3 != 0: 75 | return 0 76 | 77 | indices = [idx for idx in range(len(board)) if board[idx] == '.'] 78 | self.search(list(board), indices) 79 | 80 | return self.count 81 | 82 | def search(self, board, indices): 83 | if board.count('.') == 0: 84 | self.count += 1 85 | return 86 | 87 | node = None 88 | for idx in indices: 89 | if board[idx] == '.': 90 | if not node: 91 | node = idx 92 | candidates = [self.get_rd(idx, board), 93 | self.get_ru(idx, board), 94 | self.get_lu(idx, board), 95 | self.get_ld(idx, board)] 96 | 97 | for element in candidates: 98 | if element and node in element: 99 | for _ in element: 100 | board[_] = '#' 101 | self.search(board, indices) 102 | for _ in element: 103 | board[_] = '.' 104 | 105 | 106 | if __name__ == '__main__': 107 | tc = input() 108 | 109 | for i in range(int(tc)): 110 | nm = input().split(' ') 111 | data = (input() for row in range(int(nm[0]))) 112 | print(BoardCover(n=int(nm[0]), m=int(nm[1])).solution(data)) 113 | 114 | 115 | class Test(unittest.TestCase): 116 | 117 | def test(self): 118 | n = 3 119 | m = 12 120 | data = ( 121 | '####....###.', 122 | '#..#....##..', 123 | '##.#....####', 124 | ) 125 | self.assertEqual(BoardCover(n, m).solution(data), 4) 126 | 127 | def test_case1(self): 128 | n = 3 129 | m = 7 130 | data = ( 131 | '#.....#', 132 | '#.....#', 133 | '##...##', 134 | ) 135 | self.assertEqual(BoardCover(n, m).solution(data), 0) 136 | 137 | def test_case2(self): 138 | n = 3 139 | m = 7 140 | data = ( 141 | '#.....#', 142 | '#.....#', 143 | '##..###', 144 | ) 145 | self.assertEqual(BoardCover(n, m).solution(data), 2) 146 | 147 | def test_case3(self): 148 | n = 8 149 | m = 10 150 | data = ( 151 | '##########', 152 | '#........#', 153 | '#........#', 154 | '#........#', 155 | '#........#', 156 | '#........#', 157 | '#........#', 158 | '##########', 159 | ) 160 | self.assertEqual(BoardCover(n, m).solution(data), 1514) 161 | -------------------------------------------------------------------------------- /CLIMBING/climbing_jimin.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.climb_history = {1: 1, 2: 2} 4 | 5 | def climbStairs(self, n: int) -> int: 6 | if n <= 1: 7 | return n 8 | 9 | return self._climb_combination(n) 10 | 11 | def _climb_combination(self, n): 12 | if not n in self.climb_history: 13 | self.climb_history[n] = self._climb_combination(n-1) + self._climb_combination(n-2) 14 | 15 | return self.climb_history[n] 16 | 17 | if __name__ == '__main__': 18 | assert Solution().climbStairs(1) == 1 19 | assert Solution().climbStairs(2) == 2 20 | assert Solution().climbStairs(3) == 3 21 | assert Solution().climbStairs(4) == 5 22 | assert Solution().climbStairs(5) == 8 23 | assert Solution().climbStairs(6) == 13 24 | -------------------------------------------------------------------------------- /CLIMBING_STAIRS/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/29rithm/algospot/3b4c671d089b58e49a558573b4e05abb80de04d8/CLIMBING_STAIRS/__init__.py -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climbing_stairs_brownbear.py: -------------------------------------------------------------------------------- 1 | """ 2 | input: 1 3 | 1 4 | 5 | 6 | input: 2 7 | 1 1 8 | 2 9 | 10 | input: 3 11 | 1 1 1 12 | 2 1 13 | 1 2 14 | 15 | input: 4 16 | 1 1 1 1 17 | 2 1 1 18 | 1 2 1 19 | 1 1 2 20 | 2 2 21 | 22 | input: 5 23 | 1 1 1 1 1 24 | 2 1 1 1 25 | 1 2 1 1 26 | 1 1 2 1 27 | 1 1 1 2 28 | 2 2 1 29 | 2 1 2 30 | 1 2 2 31 | 32 | input: 6 33 | 1 1 1 1 1 1 34 | 2 1 1 1 1 35 | 1 2 1 1 1 36 | 1 1 2 1 1 37 | 1 1 1 2 1 38 | 1 1 1 1 2 39 | 2 2 1 1 40 | 2 1 2 1 41 | 2 1 1 2 42 | 1 2 2 1 43 | 1 2 1 2 44 | 1 1 2 2 45 | 2 2 2 46 | 47 | input: 7 48 | 1 1 1 1 1 1 1 49 | 2 1 1 1 1 1 50 | 1 2 1 1 1 1 51 | 1 1 2 1 1 1 52 | 1 1 1 2 1 1 53 | 1 1 1 1 2 1 54 | 1 1 1 1 1 2 55 | 2 2 1 1 1 56 | 2 1 2 1 1 57 | 2 1 1 2 1 58 | 2 1 1 1 2 59 | 1 2 2 1 1 60 | 1 2 1 2 1 61 | 1 2 1 1 2 62 | 1 1 2 2 1 63 | 1 1 2 1 2 64 | 1 1 1 2 2 65 | 2 2 2 1 66 | 2 2 1 2 67 | 2 1 2 2 68 | 1 2 2 2 69 | 70 | 피보나치의 수 71 | """ 72 | 73 | 74 | class Solution: 75 | def climbStairs(self, n: int) -> int: 76 | prev = 1 77 | next = 0 78 | sum = 0 79 | for _ in range(n + 1): 80 | sum = prev + next 81 | prev = next 82 | next = sum 83 | 84 | return sum -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climbing_stairs_chrisjune.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | cache = [] 3 | 4 | def climbStairs(self, n: int) -> int: 5 | if not self.cache: 6 | self.cache = [0 for _ in range(n+1)] 7 | 8 | if n in [0, 1]: 9 | return 1 10 | 11 | if self.cache[n]: 12 | return self.cache[n] 13 | 14 | self.cache[n] = self.climbStairs(n-1) + self.climbStairs(n-2) 15 | return self.cache[n] 16 | 17 | 18 | if __name__ == '__main__': 19 | assert Solution().climbStairs(2) == 2 20 | assert Solution().climbStairs(3) == 3 21 | -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climbing_stairs_jonnung.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func climbStairs(n int) int { 8 | if n == 0 { 9 | return 0 10 | } 11 | 12 | mem := make([]int, n) 13 | for i := 0; i < n; i++ { 14 | if i < 3 { 15 | mem[i] = i + 1 16 | } else { 17 | mem[i] = mem[i-1] + mem[i-2] 18 | } 19 | } 20 | return mem[n-1] 21 | } 22 | 23 | func TestClimbStairs(t *testing.T) { 24 | var tests = []struct { 25 | input, output int 26 | }{ 27 | {0, 0}, 28 | {1, 1}, 29 | {2, 2}, 30 | {3, 3}, 31 | {4, 5}, 32 | {5, 8}, 33 | {6, 13}, 34 | } 35 | 36 | for _, tc := range tests { 37 | result := climbStairs(tc.input) 38 | if result != tc.output { 39 | t.Errorf("got %d, expect %d", result, tc.output) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climbing_stairs_jonnung.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def climbStairs(self, n: int) -> int: 3 | mem = [0 for _ in range(n)] 4 | for i in range(n): 5 | mem[i] = mem[i-1] + mem[i-2] if i > 1 else i + 1 6 | return mem[n-1] if n > 0 else 0 7 | 8 | 9 | class FullSearchSolution: 10 | def recv(self, current, prev, goal): 11 | temp_sum = current + prev 12 | if temp_sum == goal: 13 | self.count += 1 14 | 15 | if temp_sum < goal: 16 | self.recv(1, temp_sum, goal) 17 | self.recv(2, temp_sum, goal) 18 | 19 | def climbStairs(self, n: int) -> int: 20 | self.count = 0 21 | self.recv(1, 0, n) 22 | self.recv(2, 0, n) 23 | return self.count -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climbing_stairs_yoonnoon.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/climbing-stairs/ 3 | """ 4 | import unittest 5 | 6 | 7 | class Solution: 8 | """ 9 | Runtime: 20 ms, faster than 96.68% of Python3 online submissions for Climbing Stairs. 10 | Memory Usage: 12.8 MB, less than 100.00% of Python3 online submissions for Climbing Stairs. 11 | """ 12 | def climbStairs(self, n: int) -> int: 13 | dp = {} 14 | for i in range(n): 15 | dp[i] = dp[i-1] + dp[i-2] if i > 1 else (1 if i == 0 else 2) 16 | return dp[n-1] 17 | 18 | 19 | class TestCase(unittest.TestCase): 20 | 21 | def testcase_1(self): 22 | n = 2 23 | output = 2 24 | self.assertEqual(Solution().climbStairs(n), output) 25 | 26 | def testcase_2(self): 27 | n = 3 28 | output = 3 29 | self.assertEqual(Solution().climbStairs(n), output) 30 | 31 | def testcase_3(self): 32 | n = 45 33 | output = 1836311903 34 | self.assertEqual(Solution().climbStairs(n), output) -------------------------------------------------------------------------------- /CLIMBING_STAIRS/climging_stairs_hyewoneee.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def climbStairs(self, n: int) -> int: 3 | res = [0 for i in range(n + 1)] 4 | res[0], res[1], = 1, 1 5 | for i in range(2, n+1): 6 | res[i] = res[i - 2] + res[i - 1] 7 | return res[n] 8 | -------------------------------------------------------------------------------- /FENCE/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/FENCE 2 | -------------------------------------------------------------------------------- /FENCE/fence_americanomin.py: -------------------------------------------------------------------------------- 1 | def get_width_block(index, fence): 2 | right_index = index + 1 3 | left_index = index - 1 4 | left_block = 0 5 | right_block = 0 6 | while True: 7 | if right_index > len(fence) - 1: 8 | break 9 | 10 | if fence[index] <= fence[right_index]: 11 | right_index += 1 12 | right_block += 1 13 | else: 14 | break 15 | 16 | while True: 17 | if left_index < 0: 18 | break 19 | 20 | if fence[index] <= fence[left_index]: 21 | left_index -= 1 22 | left_block += 1 23 | else: 24 | break 25 | 26 | return right_block, left_block 27 | 28 | 29 | def get_max_square_measure(fence): 30 | max_square_measure = 0 31 | calculated_height = {} 32 | 33 | for i, i_height in enumerate(fence): 34 | calculated_square_measure = calculated_height.get(i_height) 35 | 36 | if ( 37 | calculated_square_measure 38 | and i > 0 39 | and i in range(*calculated_square_measure) 40 | ): 41 | continue 42 | 43 | right_block, left_block = get_width_block(i, fence) 44 | 45 | square_measure = i_height * (1 + right_block + left_block) 46 | calculated_height[i_height] = [i - left_block, i + right_block] 47 | 48 | if square_measure > max_square_measure: 49 | max_square_measure = square_measure 50 | 51 | return max_square_measure 52 | 53 | 54 | if __name__ == "__main__": 55 | tc = input() 56 | result_list = [] 57 | for i in range(int(tc)): 58 | width = int(input()) 59 | fence = [int(height) for height in input().split(" ")] 60 | result_list.append(get_max_square_measure(fence)) 61 | 62 | for result in result_list: 63 | print(result) 64 | -------------------------------------------------------------------------------- /FENCE/fence_brownbear.py: -------------------------------------------------------------------------------- 1 | """ 2 | 연속된 판자를 자르는데 가장 큰 넓이를 가진 직사각형의 크기를 구하기 3 | - 각 판자의 넓이는 1 고정 4 | 5 | C: tc 반복횟수 , N: 판자의 수, H: 판자의 높이 6 | 7 | 8 | 7 9 | 7 1 5 9 6 7 3 10 | 11 | 20 12 | 13 | 7 14 | 1 4 4 4 4 1 1 15 | 16 | 16 17 | 18 | 4 19 | 1 8 2 2 20 | 21 | 8 22 | """ 23 | """ 24 | 1 <= N <= 20000 25 | 0 <= H <= 10000 26 | 27 | 판자의 수가 20000개이므로 재귀로 푼다면 스택오버플로우가 날 가능성이 있음 28 | 만약 nested loop이 발생했을 때, 20000 * 10000의 케이스에서 3초가 넘을 수 있음 29 | - 로컬에서 테스트 했을 때, for 20000 * 10000 진행 시 약 16초 소요 30 | 31 | 정렬해서 풀 수가 없음 32 | 33 | 7 : 7 34 | 1 : 7 35 | 5 : 7 36 | 9 : 10 37 | 6 : 15 38 | 7 : 20 39 | 3 : 20 40 | > 20 41 | 42 | 43 | """ 44 | 45 | 46 | # 시간초과 47 | # def run(left, right): 48 | # if left == right: 49 | # return h[left] 50 | # mid = (left + right) // 2 51 | # ret = max(run(left, mid), run(mid+1, right)) 52 | # 53 | # lower, higher = mid, mid + 1 54 | # height = min(h[lower], h[higher]) 55 | # ret = max(ret, height * 2) 56 | # 57 | # while left < lower or higher < right: 58 | # if higher < right and (lower == left or h[higher + 1] > h[lower - 1]): 59 | # higher += 1 60 | # height = min(height, h[higher]) 61 | # else: 62 | # lower -= 1 63 | # height = min(height, h[lower]) 64 | # ret = max(ret, height * (higher - lower + 1)) 65 | # return com(height, ret, left, lower, higher, right) 66 | # 67 | # def com(height, ret, left, lower, higher, right): 68 | # if not (left < lower or higher < right): 69 | # return ret 70 | # if higher < right and (lower == left or h[higher + 1] > h[lower - 1]): 71 | # higher += 1 72 | # height = min(height, h[higher]) 73 | # else: 74 | # lower -= 1 75 | # height = min(height, h[lower]) 76 | # ret = max(ret, height * (higher - lower + 1)) 77 | # return com(height, ret, left, lower, higher, right) 78 | # 79 | # 80 | 81 | 82 | # 83 | # def run(fences, n): 84 | # def inner(max_area, new_index): 85 | # while stack and stack[-1][1] >= fence: 86 | # max_area = max(max_area, stack[-1][1] * (i - stack[-1][0])) 87 | # new_index = stack.pop()[0] 88 | # return (max_area, new_index) 89 | # 90 | # max_area = 0 91 | # stack = [] 92 | # for i, fence in enumerate(fences): 93 | # max_area, range_i = inner(max_area, i) 94 | # stack.append((range_i, fence)) 95 | # 96 | # max_area, new_index = inner(max_area, n) 97 | # return max_area 98 | # 99 | # 100 | # if __name__ == '__main__': 101 | # test_case = 1 102 | # for case in range(test_case): 103 | # n = 7 104 | # fences = list(map(int, '7 1 5 9 6 7 3'.split(' '))) 105 | # print(run(fences, n)) 106 | 107 | 108 | # 시간초과 109 | # def run(left, right): 110 | # if left == right: 111 | # return h[left] 112 | # mid = (left + right) // 2 113 | # ret = max(run(left, mid), run(mid+1, right)) 114 | # 115 | # lower, higher = mid, mid + 1 116 | # height = min(h[lower], h[higher]) 117 | # ret = max(ret, height * 2) 118 | # while left < lower or higher < right: 119 | # if higher < right and (lower == left or h[higher + 1] > h[lower - 1]): 120 | # higher += 1 121 | # height = min(height, h[higher]) 122 | # else: 123 | # lower -= 1 124 | # height = min(height, h[lower]) 125 | # ret = max(ret, height * (higher - lower + 1)) 126 | # 127 | # return ret 128 | # 129 | # for i in range(int(input())): 130 | # n = int(input()) 131 | # h = list(map(int, input().split())) 132 | # print(run(0, n-1)) 133 | 134 | 135 | def run(): 136 | def inner(area, index): 137 | while stack and stack[-1][1] >= fence: 138 | area = max(area, stack[-1][1] * (i - stack[-1][0])) 139 | index = stack.pop()[0] 140 | return area, index 141 | 142 | max_area = 0 143 | stack = [] 144 | for i, fence in enumerate(fences): 145 | max_area, rear = inner(max_area, i) 146 | stack.append((rear, fence)) 147 | 148 | return max_area 149 | 150 | 151 | if __name__ == '__main__': 152 | for case in range(int(input())): 153 | n = int(input()) 154 | fences = list(map(int, input().split(' '))) 155 | fences.append(0) 156 | print(run()) 157 | -------------------------------------------------------------------------------- /FENCE/fence_chrisjune.py: -------------------------------------------------------------------------------- 1 | def counter(fences): 2 | if len(fences) == 1: 3 | return fences[0] 4 | 5 | mid = len(fences)//2 6 | 7 | left = mid-1 8 | right = mid 9 | height = min(fences[left], fences[right]) 10 | size = height * 2 11 | while 0 < left or right < len(fences)-1: 12 | if right < len(fences)-1 and (left==0 or fences[left-1] < fences[right+1]): 13 | right+=1 14 | height = min(height, fences[right]) 15 | else: 16 | left-=1 17 | height = min(height, fences[left]) 18 | size = max(size, height * (right-left+1)) 19 | mid_size = size 20 | 21 | single = max(counter(fences[:mid]), counter(fences[mid:])) 22 | return max(mid_size, single) 23 | 24 | if __name__ == '__main__': 25 | for c in range(int(input())): 26 | fence_count = int(input()) 27 | print(counter([int(i) for i in input().split()])) -------------------------------------------------------------------------------- /FENCE/fence_chrisjune_re.py: -------------------------------------------------------------------------------- 1 | # 7.4 fence 2 | # 잘라낼 수 있는 최대 크기의 판자의 크기를 구하시오 3 | # 제한 1초, 64MB의 메모리 4 | # 입력 50케이스, 각 20000개 판자길이, 높이 10000이하 5 | # for-loop로 돌면 총 2억 6 | 7 | # 아이디어를 떠올리자 8 | # 분할정복은 기본적으로 절반씩 나눌 때 nlogn의 속도로 하게됨 9 | # 한번 서치하는 부분은 가운데를 끼고 검색하는것 나머지는 재귀문제가됨 10 | # 가운데를 낀다는 의미는 무조건 두개를 포함하는 것 11 | 12 | # 분할 정복을 어떻게 접근할 것인가? 13 | # 가운데를 기준으로 왼쪽, 오른쪽, 가운데를 포함한 양쪽 14 | # 왼쪽, 오른쪽 부분은 분할재귀를 호출하면 된다 15 | # 문제가 되는 부분은 가운데를 포함한 부분일 것이다. 16 | 17 | 18 | def fence(board): 19 | if len(board) <= 1: 20 | return board[0] 21 | mid = len(board) // 2 22 | left = mid - 1 23 | right = mid 24 | total_size = min(board[left], board[right]) * 2 25 | while 0 < left or right < len(board) - 1: 26 | if right < len(board) - 1 and (left == 0 or board[left - 1] <= board[right + 1]): 27 | right += 1 28 | else: 29 | left -= 1 30 | total_size = max(total_size, min(board[left:right + 1]) * (right - left + 1)) 31 | return max(total_size, fence(board[:mid]), fence(board[mid:])) 32 | 33 | 34 | if __name__ == '__main__': 35 | # board = [7, 1, 5, 9, 6, 7, 3] 36 | # assert fence(board) == 20 37 | # board = [1,4,4,4,4,1,1] 38 | # assert fence(board) == 16 39 | # board = [1,8,2,2] 40 | # assert fence(board) == 8 41 | for _ in range(int(input())): 42 | total_input = int(input()) 43 | board = [] 44 | for _ in range(total_input): 45 | board.append(int(input())) 46 | print(fence(board)) 47 | -------------------------------------------------------------------------------- /FENCE/fence_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def Fence(fence_list): 2 | max_rectangle = 0 3 | 4 | for i in range(len(fence_list)): 5 | height = fence_list[i] 6 | rectangle = height 7 | for j in range(i-1, -1, -1): 8 | if height <= fence_list[j]: 9 | rectangle += height 10 | else: 11 | break 12 | for j in range(i+1, len(fence_list)): 13 | if height <= fence_list[j]: 14 | rectangle += height 15 | else: 16 | break 17 | if max_rectangle < rectangle: 18 | max_rectangle = rectangle 19 | return max_rectangle 20 | 21 | if __name__ == '__main__': 22 | import sys 23 | case = sys.stdin.readline() 24 | 25 | if int(case) > 50: 26 | raise print('테스트 케이스는 50번을 넘길 수 없다.') 27 | 28 | for tc in range(int(case)): 29 | max_height = 0 30 | fence_num = input() 31 | height = input().split(' ') 32 | print(Fence([int(i) for i in height])) 33 | -------------------------------------------------------------------------------- /FENCE/fence_jonnung.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def calculate_rectangle_size(width, boards): 5 | max_rectangle_size = 0 6 | same_heights_indies = defaultdict(list) 7 | 8 | for i, v in enumerate(boards): 9 | height = v 10 | 11 | if v == 0: 12 | continue 13 | 14 | if i in same_heights_indies[v]: 15 | continue 16 | 17 | right_width_index = left_width_index = i 18 | for j in range(i+1, width): 19 | if v <= boards[j]: 20 | if v == boards[j]: 21 | same_heights_indies[v].append(j) 22 | else: 23 | right_width_index = j - 1 24 | break 25 | 26 | for k in range(i-1, -1, -1): 27 | if v <= boards[k]: 28 | if v == boards[k]: 29 | same_heights_indies[v].append(k) 30 | else: 31 | left_width_index = k + 1 32 | break 33 | 34 | rectangle_size = ((right_width_index - left_width_index) + 1) * height 35 | if rectangle_size > max_rectangle_size: 36 | max_rectangle_size = rectangle_size 37 | 38 | return max_rectangle_size 39 | 40 | 41 | if __name__ == '__main__': 42 | import sys 43 | 44 | rl = lambda: sys.stdin.readline() 45 | c = int(rl()) 46 | for _ in range(c): 47 | n = int(rl()) 48 | boards = list(map(int, rl().split())) 49 | print(calculate_rectangle_size(n, boards)) 50 | -------------------------------------------------------------------------------- /FENCE/fence_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class FenceElement: 5 | 6 | def __init__(self, start, height): 7 | self.start = start 8 | self.height = height 9 | 10 | def get_area(self, end): 11 | return (end-self.start) * self.height 12 | 13 | __slots__ = ('start', 'height',) 14 | 15 | 16 | class Fence: 17 | 18 | def __init__(self, _n, _data): 19 | self.n = _n 20 | self.data = _data 21 | self.stack = [] 22 | self.max = 0 23 | 24 | def solution(self): 25 | prev = -1 26 | for idx in range(self.n): 27 | height = self.data[idx] 28 | 29 | if prev > height: 30 | back = 0 31 | while True: 32 | e = self.stack[-1] 33 | if e.height > height: 34 | e = self.stack.pop(-1) 35 | back, candidate = e.start, e.get_area(idx) 36 | self.max = candidate if candidate > self.max else self.max 37 | if not self.stack: 38 | self.stack.append(FenceElement(e.start, height)) 39 | break 40 | else: 41 | if e.height < height: 42 | self.stack.append(FenceElement(back, height)) 43 | break 44 | elif prev < height: 45 | self.stack.append(FenceElement(idx, height)) 46 | 47 | prev = height 48 | 49 | for e in self.stack: 50 | candidate = e.get_area(self.n) 51 | self.max = candidate if candidate > self.max else self.max 52 | 53 | return self.max 54 | 55 | __slots__ = ('n', 'data', 'stack', 'max',) 56 | 57 | 58 | def main(): 59 | tc = input() 60 | 61 | for i in range(int(tc)): 62 | n = int(input()) 63 | data = [int(i) for i in input().split(' ')] 64 | print(Fence(n, data).solution()) 65 | 66 | 67 | if __name__ == '__main__': 68 | main() 69 | 70 | 71 | class Test(unittest.TestCase): 72 | 73 | def test_case1(self): 74 | test_data = [7, 1, 5, 9, 6, 7, 3, 3, 3, 3, 3, 3] 75 | test_n = len(test_data) 76 | self.assertEqual(Fence(test_n, test_data).solution(), 30) 77 | 78 | def test_case2(self): 79 | test_data = [1, 4, 4, 4, 4, 1, 1] 80 | test_n = len(test_data) 81 | self.assertEqual(Fence(test_n, test_data).solution(), 16) 82 | 83 | def test_case3(self): 84 | test_data = [1, 8, 2, 2] 85 | test_n = len(test_data) 86 | self.assertEqual(Fence(test_n, test_data).solution(), 8) 87 | 88 | def test_case4(self): 89 | test_data = [5, 4, 3, 2, 1, 99] 90 | test_n = len(test_data) 91 | self.assertEqual(Fence(test_n, test_data).solution(), 99) 92 | -------------------------------------------------------------------------------- /FENCE/test_fence_chrisjune.py: -------------------------------------------------------------------------------- 1 | from FENCE.fence_chrisjune import counter 2 | 3 | assert counter([7,1,5,9,6,7,3]) == 20 4 | assert counter([1,4,4,4,4,1,1]) == 16 5 | assert counter([1,8,2,2]) == 8 6 | assert counter([2,2]) == 4 7 | assert counter([1,3]) == 3 8 | assert counter([1,4,1,5,4,4,4]) == 16 -------------------------------------------------------------------------------- /IS_SUBSEQUENCE/is_subsequence_chrisjune.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSubsequence(self, s: str, t: str) -> bool: 3 | for target in t: 4 | if len(s) and target == s[0]: 5 | s = s[1:] 6 | if len(s): 7 | return False 8 | return True 9 | 10 | 11 | if __name__ == '__main__': 12 | assert Solution().isSubsequence('abc', 'ahbgdc') 13 | assert not Solution().isSubsequence('axc', 'ahbgdc') 14 | -------------------------------------------------------------------------------- /JUMPGAME/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/JUMPGAME 2 | -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_brownbear.py: -------------------------------------------------------------------------------- 1 | def run(i, j): 2 | # 인덱스가 도착지점이면 True 반환. 배열에 직접 접근하는 것보다 변수와 비교하는게 조금 더 빠른거 같음 3 | if i == n - 1 and j == n - 1: 4 | return True 5 | 6 | is_end = False 7 | tile = int(board[i][j]) 8 | # 오른쪽, 아래쪽 순으로 진행하기 때문에 한 번 방문한 타일은 이미 경우의 수를 전부 계산했기 때문에 건너 뛴다. - *이거 안 하면 시간초과* 9 | if tile != -1: 10 | if not is_end and j + tile < n: 11 | is_end = run(i, j + tile) 12 | if not is_end and i + tile < n: 13 | is_end = run(i + tile, j) 14 | # 오른쪽, 아래쪽까지 전부 이동한 상태면 현재 타일을 방문했다는 표시로 -1로 변경 15 | board[i][j] = -1 16 | return is_end 17 | 18 | 19 | if __name__ == '__main__': 20 | for _ in range(int(input())): 21 | n = int(input()) 22 | # 1차원 배열일 땐, list(map(int, 배열))로 먼저 형변환을 진행하는 것이 비교할 때마다 형변환을 진행하는 것보다 조금 더 빠르지만 23 | # 2차원 배열의 경우, 비교할 때마다 형변환을 하는 것이 map()을 사용해 미리 형변환을 하는 것보다 30% 이상 빠르다. 24 | # **정정** 2차원 배열을 전부 다 탐색할 때는, 형변환을 먼저 한 것이 조금 더 빠름. -> 전체 탐색이 아닌 경우는, 비교할 때마다 형변환 하는게 더 효율적 25 | board = [input().split() for _ in range(n)] 26 | print('YES' if run(0, 0) else 'NO') 27 | -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_chrisjune.py: -------------------------------------------------------------------------------- 1 | # JUMP 2 | # 일단 재귀적으로 본문제를 작은 부분부터 떼어내고 3 | # 나머지 부분은 모두 메모이제이션으로 확인해보자 4 | # 우선 특정 셀에서 갈 수 있는 곳은 두곳밖에 없다 5 | # jump(i,j) 라는 문제가 jump(i+board[i][j],j) , jump(i,j+board[i][j]) 6 | # 이런식의 가지치기 문제가 되고 마지막에 도달할 수 있게 되면 return 끝을 내면 된다 7 | 8 | # 기저문제, 더한 값이 밖으로 나가면 false 9 | # 기저문제, 더한 값이 마지막 셀에 들어오면 true 10 | 11 | # 마지막으로 연산이 반복되는 부분을 메모이제이션을 활용하여 이미 지난 곳을 12 | # 가지 않도록처리해준다 13 | board = [] 14 | blocked = [] 15 | def jump(row, col): 16 | if row >= len(board) or col >= len(board[0]): 17 | return False 18 | 19 | if blocked[row][col]==1: 20 | return False 21 | 22 | this = board[row][col] 23 | if this == 0: 24 | return True 25 | 26 | if jump(row, col+this) or jump(row+this, col): 27 | return True 28 | else: 29 | blocked[row][col] = 1 30 | 31 | return False 32 | 33 | if __name__ == '__main__': 34 | for c in range(int(input())): 35 | board = [] 36 | blocked = [] 37 | n = int(input()) 38 | for _ in range(n): 39 | board.append([int(i) for i in input().split()]) 40 | blocked.append([0] * n) 41 | print('YES' if jump(0,0) else 'NO') 42 | 43 | # board = [[1, 1, 1], [1, 1, 1], [1, 1, 0]] 44 | # blocked = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 45 | # assert jump(0,0) == True 46 | # 47 | # board = [[2, 3, 2], [3, 3, 3], [3, 3, 0]] 48 | # blocked = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 49 | # assert jump(0,0) == True 50 | # 51 | # board = [[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,2],[1,1,1,2,0]] 52 | # blocked = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]] 53 | # assert jump(0, 0) == False 54 | # 55 | # blocked = [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] 56 | # board = [[2,5,1,6,1,4,1],[6,1,1,2,2,9,3],[7,2,3,2,1,3,1],[1,1,3,1,7,1,2],[4,1,2,3,4,1,2],[3,3,1,2,3,4,1],[1,5,2,9,4,7,0]] 57 | # assert jump(0,0) == True 58 | # 59 | # blocked = [[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,0]] 60 | # board = [[2,5,1,6,1,4,1],[6,1,1,2,2,9,3],[7,2,3,2,1,3,1],[1,1,3,1,7,1,2],[4,1,2,3,4,1,3],[3,3,1,2,3,4,1],[1,5,2,9,4,7,0]] 61 | # assert jump(0,0) == False 62 | # print('Success') -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def JumpGame(i, j): 2 | if i == int(game_count)-1 and j == int(game_count) -1: 3 | return True 4 | if i > int(game_count) -1 or j > int(game_count) -1: 5 | return False 6 | if ret[i][j] == -1: 7 | return False 8 | game = game_list[i][j] 9 | ret[i][j] = -1 10 | 11 | return JumpGame(i, game+j ) or JumpGame(i+game, j) 12 | 13 | if __name__ == '__main__': 14 | import sys 15 | case = sys.stdin.readline() 16 | 17 | if int(case) > 50: 18 | raise print('테스트 케이스는 50번을 넘길 수 없다.') 19 | 20 | for tc in range(int(case)): 21 | game_list = [] 22 | ret = [] 23 | game_count = input() 24 | for count in range(int(game_count)): 25 | game_list.append([int(i) for i in input().split(' ')]) 26 | ret.append([0] * int(game_count)) 27 | 28 | print('YES' if JumpGame(0,0) else 'NO') 29 | -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_jonnung.py: -------------------------------------------------------------------------------- 1 | 2 | class JumpGame: 3 | def __init__(self, width, game_board): 4 | self.reachable = False 5 | self.width = width 6 | self.game_board = game_board 7 | self.jump_history = [[0 for _ in range(width)] for _ in range(width)] 8 | 9 | def check_movable(self, i, j): 10 | move_distance = self.game_board[i][j] 11 | down_movable = i + move_distance < self.width 12 | right_movable = j + move_distance < self.width 13 | return down_movable, right_movable 14 | 15 | def right(self, i, j): 16 | move_distance = self.game_board[i][j] 17 | return i, j + move_distance 18 | 19 | def down(self, i, j): 20 | move_distance = self.game_board[i][j] 21 | return i + move_distance, j 22 | 23 | def jump(self, i=0, j=0): 24 | if i == j == self.width - 1: 25 | self.reachable = True 26 | return True 27 | 28 | if self.reachable: 29 | return True 30 | 31 | if i >= self.width or j >= self.width: 32 | return False 33 | 34 | if self.jump_history[i][j] != 0: 35 | return self.jump_history[i][j] 36 | 37 | down_movable, right_movable = self.check_movable(i, j) 38 | down_result = False 39 | right_result = False 40 | 41 | if down_movable: 42 | next_down_position = self.down(i, j) 43 | down_result = self.jump(*next_down_position) 44 | 45 | if right_movable: 46 | next_right_position = self.right(i, j) 47 | right_result = self.jump(*next_right_position) 48 | 49 | self.jump_history[i][j] = down_result or right_result 50 | return self.jump_history[i][j] 51 | 52 | 53 | if __name__ == '__main__': 54 | import sys 55 | 56 | rl = lambda: sys.stdin.readline() 57 | 58 | c = int(rl()) 59 | 60 | for _ in range(c): 61 | n = int(rl()) 62 | game_board = [] 63 | for _ in range(n): 64 | game_board.append(list(map(int, rl().split()))) 65 | 66 | jg = JumpGame(n, game_board) 67 | jg.jump() 68 | print("YES" if jg.reachable else "NO") 69 | -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_leejimin.py: -------------------------------------------------------------------------------- 1 | memorize_jump_history = {} 2 | 3 | 4 | def has_jump_way(point, game_board): 5 | global memorize_jump_history 6 | 7 | y_point = point[0] 8 | x_point = point[1] 9 | 10 | memorize_key = ":".join(map(str, point)) 11 | 12 | if memorize_key in memorize_jump_history: 13 | return memorize_jump_history[memorize_key] 14 | 15 | if (y_point > max_y_point) or (x_point > max_x_point): 16 | return False 17 | 18 | point_value = game_board[y_point][x_point] 19 | 20 | if point_value == 0: 21 | return True 22 | 23 | right_point = (y_point, x_point + point_value) 24 | right_memorize_key = ":".join(map(str, right_point)) 25 | if has_jump_way(right_point, game_board): 26 | memorize_jump_history[right_memorize_key] = True 27 | return True 28 | else: 29 | memorize_jump_history[right_memorize_key] = False 30 | 31 | down_point = (y_point + point_value, x_point) 32 | down_memorize_key = ":".join(map(str, down_point)) 33 | if has_jump_way(down_point, game_board): 34 | memorize_jump_history[down_memorize_key] = True 35 | return True 36 | else: 37 | memorize_jump_history[down_memorize_key] = False 38 | return False 39 | 40 | return False 41 | 42 | 43 | if __name__ == "__main__": 44 | tc = input() 45 | result_list = [] 46 | 47 | for i in range(int(tc)): 48 | memorize_jump_history = {} 49 | board_list = [] 50 | board_height = int(input()) 51 | 52 | for _ in range(board_height): 53 | board = [int(height) for height in input().split(" ")] 54 | board_list.append(board) 55 | 56 | max_y_point = board_height - 1 57 | max_x_point = len(board_list[0]) - 1 58 | 59 | result_list.append(has_jump_way((0, 0), board_list)) 60 | 61 | for result in result_list: 62 | if result: 63 | print("YES") 64 | else: 65 | print("NO") 66 | -------------------------------------------------------------------------------- /JUMPGAME/jumpgame_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class JumpGame: 5 | 6 | def __init__(self, _n, _data): 7 | self.n = _n 8 | self.data = _data 9 | self.is_arrive = False 10 | self.visit_memo = set() 11 | 12 | def solution(self): 13 | self.move(0, 0) 14 | return "YES" if self.is_arrive else "NO" 15 | 16 | def move(self, row, col): 17 | if row >= self.n or col >= self.n or (row, col) in self.visit_memo: 18 | return 19 | 20 | _next = self.data[row][col] 21 | if _next == 0: 22 | self.is_arrive = True 23 | 24 | if not self.is_arrive: 25 | self.move(row, col+_next) 26 | 27 | if not self.is_arrive: 28 | self.move(row+_next, col) 29 | 30 | if not self.is_arrive: 31 | self.visit_memo.add((row, col)) 32 | 33 | 34 | def main(): 35 | tc = input() 36 | 37 | for i in range(int(tc)): 38 | n = int(input()) 39 | data = [] 40 | for j in range(n): 41 | data.insert(j, [int(e) for e in input().split(' ')]) 42 | print(JumpGame(n, data).solution()) 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | 48 | 49 | class Test(unittest.TestCase): 50 | 51 | def test_main(self): 52 | main() 53 | 54 | def test_case1(self): 55 | n = 7 56 | data = [ 57 | [2, 5, 1, 6, 1, 4, 1], 58 | [6, 1, 1, 2, 2, 9 ,3], 59 | [7, 2, 3, 2, 1, 3, 1], 60 | [1, 1, 3, 1, 7, 1, 2], 61 | [4, 1, 2, 3, 4, 1, 2], 62 | [3, 3, 1, 2, 3, 4, 1], 63 | [1, 5, 2, 9, 4, 7, 0] 64 | ] 65 | self.assertEqual(JumpGame(n, data).solution(), "YES") 66 | 67 | def test_case2(self): 68 | n = 7 69 | data = [ 70 | [2, 5, 1, 6, 1, 4, 1], 71 | [6, 1, 1, 2, 2, 9, 3], 72 | [7, 2, 3, 2, 1, 3, 1], 73 | [1, 1, 3, 1, 7, 1, 2], 74 | [4, 1, 2, 3, 4, 1, 3], 75 | [3, 3, 1, 2, 3, 4, 1], 76 | [1, 5, 2, 9, 4, 7, 0] 77 | ] 78 | self.assertEqual(JumpGame(n, data).solution(), "NO") 79 | 80 | def test_case2(self): 81 | n = 5 82 | data = [ 83 | [1, 1, 2, 3, 3], 84 | [1, 1, 1, 3, 3], 85 | [2, 1, 1, 3, 3], 86 | [1, 2, 2, 3, 3], 87 | [1, 3, 3, 3, 0] 88 | ] 89 | self.assertEqual(JumpGame(n, data).solution(), "YES") -------------------------------------------------------------------------------- /JUMPGAME2/jumpgame2_chrisjune.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.jumpcnt = 0 4 | self.result = [] 5 | 6 | def jump(self, nums: list) -> int: 7 | if len(nums) <= 1: 8 | self.result.append(self.jumpcnt) 9 | return min(self.result) 10 | 11 | first = nums[0] 12 | if first == 0: 13 | return 14 | 15 | for i in range(first): 16 | self.jumpcnt += 1 17 | self.jump(nums[i + 1:]) 18 | self.jumpcnt -= 1 19 | return min(self.result) 20 | 21 | 22 | if __name__ == '__main__': 23 | assert Solution().jump([2, 3, 1, 1, 4]) == 2 24 | assert Solution().jump([0]) == 0 25 | assert Solution().jump([1, 2]) == 1 26 | assert Solution().jump([2,3,0,1,4]) == 2 27 | assert Solution().jump([5,9,3,2,1,0,2,3,3,1,0,0]) == 6 28 | assert Solution().jump([1,1,1,1,1,1]) == 5 29 | -------------------------------------------------------------------------------- /JUMPGAME2/jumpgame2_jonnung.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | class Solution: 4 | minimum_steps = 0 5 | def jump(self, nums): 6 | length = len(nums) 7 | 8 | if len(Counter(nums).keys()) == 1: 9 | return length - 1 10 | 11 | if length == 1: 12 | return 0 13 | 14 | if length == 2: 15 | return 1 16 | 17 | destination = length - 1 18 | current_step = destination - 1 19 | widest_stride = current_step 20 | while widest_stride > 0: 21 | if current_step + nums[current_step] >= destination: 22 | widest_stride = current_step 23 | 24 | current_step -= 1 25 | if current_step < 0: 26 | destination = widest_stride 27 | current_step = widest_stride - 1 28 | self.minimum_steps += 1 29 | return self.minimum_steps 30 | -------------------------------------------------------------------------------- /JUMPGAME2/jumpgame_2_yoonnoon.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/jump-game-ii/ 3 | """ 4 | import unittest 5 | from typing import List 6 | 7 | 8 | class Solution: 9 | 10 | def jump_dynamic_programming(self, nums: List[int]) -> int: 11 | """ 12 | Time Limit Exceed( 90/92 pass ) 13 | """ 14 | dp = [0 for _ in range(len(nums))] 15 | for i in range(len(nums)): 16 | candidate = [dp[j]+1 for j in range(i) if nums[j] - (i-j) >= 0] 17 | dp[i] = min(candidate) if candidate else 0 18 | return dp[-1] 19 | 20 | def jump(self, nums: List[int]) -> int: 21 | """ 22 | Runtime: 108 ms, faster than 35.42% of Python3 online submissions for Jump Game II. 23 | Memory Usage: 14.9 MB, less than 8.33% of Python3 online submissions for Jump Game II. 24 | """ 25 | 26 | stack = [] 27 | for i in range(len(nums) - 1): 28 | if i + nums[i] >= len(nums)-1: 29 | stack.append(-1) 30 | break 31 | 32 | else: 33 | if stack and i < stack[-1]: 34 | continue 35 | 36 | next_position = 0 37 | for j in range(i, i+nums[i]+1): 38 | next_position = j if j + nums[j] > next_position + nums[next_position] else next_position 39 | stack.append(next_position) 40 | 41 | return len(stack) 42 | 43 | 44 | class TestCase(unittest.TestCase): 45 | 46 | def testcase_1(self): 47 | nums = [2, 3, 1, 1, 4] 48 | output = 2 49 | self.assertEqual(Solution().jump(nums), output) 50 | 51 | def testcase_2(self): 52 | nums = [1 for _ in range(10000)] 53 | output = 9999 54 | self.assertEqual(Solution().jump(nums), output) 55 | 56 | def testcase_3(self): 57 | nums = [2, 3, 1, 1, 4] 58 | output = 2 59 | self.assertEqual(Solution().jump_dynamic_programming(nums), output) 60 | 61 | def testcase_4(self): 62 | nums = [1 for _ in range(10000)] 63 | output = 9999 64 | self.assertEqual(Solution().jump_dynamic_programming(nums), output) 65 | -------------------------------------------------------------------------------- /JUMPGAMEII/jump_game_ll_brownbear.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def jump(self, nums: List[int]) -> int: 3 | index = 0 4 | cnt = 1 5 | length = len(nums) - 1 6 | if not length: 7 | return 0 8 | # 현재 인덱스와 값의 합이 길이가 넘으면 종료 9 | while length > index + nums[index]: 10 | max_value = 0 11 | max_index = 0 12 | for i in range(1, nums[index] + 1): 13 | # 이동할 수 있는 값에 현재 인덱스 위치인 가중치를 더함 14 | selectable = nums[index + i] + i 15 | # 최대 값이 같은 경우, 인덱스가 더 뒤에 존재할 수도 있어 equal인 경우도 포함 16 | if max_value <= selectable: 17 | max_value = selectable 18 | max_index = i 19 | index = index + max_index 20 | cnt += 1 21 | 22 | return cnt 23 | -------------------------------------------------------------------------------- /LIS/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/LIS 2 | 3 | -------------------------------------------------------------------------------- /LIS/lis_chrisjune.py: -------------------------------------------------------------------------------- 1 | # LIS = Longest Increasing Sequence 2 | # 순 증가하는 수열을 나타낸다. 다시말하여 왼쪽에서 오른쪽으로 증가하는 숫자의 나열을 나타낸다 3 | # 해당 문제에서는 숫자리스트가 주어지고, 리스트에서 순증가하는 수열의 최대개수를 반환하는 함수를 푸는 것이다 4 | 5 | # [5,6,7,8,1,2,3] -> 4를 반환하는 것이다 6 | # TC50, 입력이 500개이기 때문에 500*500*50 7 | 8 | # def lis(seq): 9 | # maxcnt = 0 10 | # for i in range(len(seq)): 11 | # cnt = 1 12 | # for j in range(i+1, len(seq)): 13 | # first = seq[i] 14 | # second = seq[j] 15 | # if first < second: 16 | # cnt += 1 17 | # maxcnt = max(maxcnt, cnt) 18 | # return maxcnt 19 | 20 | 21 | def lis(seq): 22 | # 가운데를 포함한 녀석들을 계산 23 | if len(seq) <= 1: 24 | return 1 25 | mid = len(seq) // 2 26 | left = mid - 1 27 | right = mid 28 | max_len = 2 if seq[left] < seq[right] else 1 29 | l = left 30 | r = right 31 | 32 | while (0 < left or right < len(seq) - 1): 33 | if right < len(seq) - 1 and (left == 0 or seq[left - 1] < seq[right + 1]): 34 | if seq[r] < seq[right+1]: 35 | max_len += 1 36 | r += 1 37 | right += 1 38 | else: 39 | if seq[left-1] < seq[l]: 40 | max_len += 1 41 | l -= 1 42 | left -= 1 43 | # 가운데를 뺀 왼쪽 44 | return max(max_len, lis(seq[:mid]), lis(seq[mid:])) 45 | 46 | 47 | # if __name__ == '__main__': 48 | # for _ in range(int(input())): 49 | # count = int(input()) 50 | # seq = [int(i) for i in input().split()] 51 | # print(lis(seq)) 52 | if __name__ == '__main__': 53 | assert lis([1, 2, 3, 4]) == 4 54 | print(lis([1,2,3,9,4,5,6])) 55 | print(lis([5,6,7,8,1,2,3,4])) 56 | assert lis([5,6,7,8,1,2,3,4]) == 4 57 | assert lis([9,1,2,3,4]) == 4 58 | assert lis([2, 5, 6, 1, 2]) == 3 59 | assert lis([9, 1, 3, 7, 5, 6, 20]) == 5 60 | -------------------------------------------------------------------------------- /LIS/lis_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def lis(subsequence): 2 | if not subsequence: 3 | return print(len(blank)) 4 | if len(subsequence) == 1: 5 | if blank: 6 | if blank[-1] < subsequence[0]: 7 | blank.append(subsequence[0]) 8 | elif(subsequence[0] < subsequence[1]): 9 | if not blank: 10 | blank.append(subsequence[1]) 11 | subsequence.pop() 12 | lis(subsequence) 13 | if __name__ == '__main__': 14 | import sys 15 | test_case = sys.stdin.readline() 16 | for tc in range(int(test_case)): 17 | blank = [] 18 | num = input() 19 | subsequence = input().split(' ') 20 | case_list = [int(i) for i in subsequence] 21 | print(lis(case_list)) 22 | -------------------------------------------------------------------------------- /LIS/lis_jimin.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self._max_length = 0 4 | self._searched_numbers = set() 5 | 6 | def lengthOfLIS(self, nums): 7 | self._search_lis(nums) 8 | return self._max_length 9 | 10 | def _search_lis(self, sequence_data): 11 | if len(sequence_data) == 1 or self._is_increasing_subsequence(sequence_data): 12 | candiate_cnt = len(set(sequence_data)) 13 | 14 | if candiate_cnt > self._max_length: 15 | self._max_length = candiate_cnt 16 | 17 | return sequence_data 18 | 19 | for index in range(len(sequence_data)): 20 | if index >= (len(sequence_data)-1): 21 | continue 22 | 23 | if sequence_data[index] == sequence_data[index+1]: 24 | sequence_data.pop(index) 25 | 26 | if self._is_decreasing_subsequence(sequence_data): 27 | if not self._max_length: 28 | self._max_length = 1 29 | 30 | return sequence_data 31 | 32 | for index, number in enumerate(sequence_data): 33 | sequence_data.pop(index) 34 | search_numbers = " ".join(map(str, sequence_data)) 35 | 36 | if search_numbers in self._searched_numbers: 37 | self._searched_numbers.add(search_numbers) 38 | sequence_data.insert(index, number) 39 | continue 40 | 41 | self._searched_numbers.add(search_numbers) 42 | self._search_lis(sequence_data) 43 | sequence_data.insert(index, number) 44 | 45 | return sequence_data 46 | 47 | def _is_increasing_subsequence(self, sequence_data): 48 | for index in range(len(sequence_data)): 49 | if index == 0: 50 | continue 51 | 52 | if sequence_data[index] < sequence_data[index - 1]: 53 | return False 54 | 55 | return True 56 | 57 | def _is_decreasing_subsequence(self, sequence_data): 58 | """ 59 | 내림차순 순열으로만 구성되어 있는가? 60 | """ 61 | if len(sequence_data) == 1: 62 | return False 63 | 64 | for index in range(len(sequence_data)): 65 | if index == 0: 66 | continue 67 | 68 | if sequence_data[index] >= sequence_data[index - 1]: 69 | return False 70 | 71 | return True 72 | 73 | if __name__ == '__main__': 74 | max_lis_cnt = 0 75 | searched_numbers = set() 76 | 77 | for case in range(int(input())): 78 | subsequence_cnt = int(input()) 79 | subsequence = input() 80 | result = Solution().lengthOfLIS(subsequence.split(' ')) 81 | print(print) 82 | 83 | # assert Solution().lengthOfLIS([2, 1]) == 1 84 | # assert Solution().lengthOfLIS([2, 2]) == 1 85 | # assert Solution().lengthOfLIS([2, 1, 3]) == 2 86 | # assert Solution().lengthOfLIS([1, 2, 3, 4]) == 4 87 | # assert Solution().lengthOfLIS([5, 4, 3, 2, 1, 6, 7, 8]) == 4 88 | # assert Solution().lengthOfLIS([5, 6, 7, 8, 1, 2, 3, 4]) == 4 89 | # assert Solution().lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18]) == 4 90 | -------------------------------------------------------------------------------- /LIS/lis_jonnung.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "bufio" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func max(arr []int64) int64 { 12 | max := int64(0) 13 | for _, v := range arr { 14 | if v > max { 15 | max = v 16 | } 17 | } 18 | 19 | return max 20 | } 21 | 22 | 23 | func solution(size int64, seqc []int64) { 24 | var mem [500]int64 25 | 26 | for m := int64(0); m < size; m++ { 27 | mem[m] = 1 28 | } 29 | 30 | for i := int64(1); i < size; i++ { 31 | for j := int64(0); j < i; j++ { 32 | if seqc[i] > seqc[j] { 33 | compare := [2]int64{mem[i], mem[j] + 1} 34 | mem[i] = max(compare[:]) 35 | } 36 | } 37 | } 38 | 39 | fmt.Println(max(mem[:size])) 40 | } 41 | 42 | 43 | func main() { 44 | var c, n int64 45 | var v string 46 | var sequence []int64 47 | 48 | input := bufio.NewScanner(os.Stdin) 49 | 50 | // TC 개수 입력 51 | input.Scan() 52 | c, _ = strconv.ParseInt(input.Text(), 0, 64) 53 | 54 | for i := int64(0); i < c; i++ { 55 | // 원소 개수 입력 56 | input.Scan() 57 | n, _ = strconv.ParseInt(input.Text(), 0, 64) 58 | 59 | // 길이가 n인 수열 입력 60 | input.Scan() 61 | v = input.Text() 62 | values := strings.Fields(v) 63 | sequence = make([]int64, len(values)) 64 | for j, num := range values { 65 | intNum, _ := strconv.Atoi(num) 66 | sequence[j] = int64(intNum) 67 | } 68 | 69 | solution(n, sequence) 70 | } 71 | } -------------------------------------------------------------------------------- /LIS/lis_jonnung.py: -------------------------------------------------------------------------------- 1 | """ 2 | yoonnoon님의 `LISv2`로 해결(외워버림) 3 | """ 4 | def lis_solution(sequence): 5 | length = len(sequence) 6 | memo = [1 for _ in range(length)] 7 | for i in range(1, length): 8 | for j in range(i): 9 | if sequence[i] > sequence[j]: 10 | memo[i] = max(memo[i], memo[j] + 1) 11 | 12 | return max(memo) 13 | 14 | 15 | if __name__ == '__main__': 16 | import sys 17 | 18 | rl = lambda: sys.stdin.readline() 19 | 20 | c = int(rl()) 21 | 22 | for _ in range(c): 23 | n = int(rl()) 24 | v = list(map(int, rl().split())) 25 | print(lis_solution(v)) -------------------------------------------------------------------------------- /LIS/lis_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import bisect 4 | 5 | 6 | class LISv3: 7 | 8 | def __init__(self, n, data): 9 | self.n = n 10 | self.data = data 11 | self.q = [] 12 | 13 | def solution(self): 14 | for n in self.data: 15 | if not self.q or n > self.q[-1]: 16 | self.q.append(n) 17 | else: 18 | index = bisect.bisect_left(self.q, n) 19 | self.q[index] = n 20 | return len(self.q) 21 | 22 | 23 | class LISv2: 24 | def __init__(self, n, data): 25 | self.n = n 26 | self.data = data 27 | 28 | def solution(self): 29 | if self.n == 0: 30 | return 0 31 | elif self.n == 1: 32 | return 1 33 | 34 | dp = [1 for i in range(self.n)] 35 | for i in range(1, self.n): 36 | for j in range(i): 37 | if self.data[i] > self.data[j]: 38 | dp[i] = max(dp[i], dp[j] + 1) 39 | 40 | res = max(dp) 41 | return res 42 | 43 | 44 | class LISv1: 45 | def __init__(self, n, data): 46 | self.n = n 47 | self.data = data 48 | self.memo = {} 49 | 50 | def solution(self): 51 | _max = 0 52 | for i in range(self.n): 53 | _max = max(self.search_or_cache(i), _max) 54 | return _max 55 | 56 | def search_or_cache(self, i): 57 | return self.memo[i] if i in self.memo else self.search(i) 58 | 59 | def search(self, base): 60 | _max = 0 61 | for i in range(base + 1, self.n): 62 | if self.data[i] > self.data[base]: 63 | _max = max(self.search_or_cache(i), _max) 64 | 65 | self.memo[base] = _max + 1 66 | return self.memo[base] 67 | 68 | 69 | def main(): 70 | tc = input() 71 | 72 | for i in range(int(tc)): 73 | n = int(input()) 74 | data = [int(v) for v in input().split(' ')] 75 | print(LISv1(n, data).solution()) 76 | print(LISv2(n, data).solution()) 77 | print(LISv3(n, data).solution()) 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | 83 | 84 | class Test(unittest.TestCase): 85 | 86 | def test_case1(self): 87 | n = 4 88 | data = [1, 2, 3, 4] 89 | self.assertEqual(LISv1(n, data).solution(), 4) 90 | self.assertEqual(LISv2(n, data).solution(), 4) 91 | self.assertEqual(LISv3(n, data).solution(), 4) 92 | 93 | def test_case2(self): 94 | n = 10 95 | data = [5, 4, 3, 2, 3, 4, 1, 6, 7, 8] 96 | self.assertEqual(LISv1(n, data).solution(), 6) 97 | self.assertEqual(LISv2(n, data).solution(), 6) 98 | self.assertEqual(LISv3(n, data).solution(), 6) 99 | 100 | def test_case3(self): 101 | n = 8 102 | data = [5, 6, 7, 8, 1, 2, 3, 4] 103 | self.assertEqual(LISv1(n, data).solution(), 4) 104 | self.assertEqual(LISv2(n, data).solution(), 4) 105 | self.assertEqual(LISv3(n, data).solution(), 4) 106 | 107 | def test_case4(self): 108 | n = 8 109 | data = [10, 9, 2, 5, 3, 7, 101, 18] 110 | self.assertEqual(LISv1(n, data).solution(), 4) 111 | self.assertEqual(LISv2(n, data).solution(), 4) 112 | self.assertEqual(LISv3(n, data).solution(), 4) 113 | 114 | def test_case5(self): 115 | n = 7 116 | data = [9, 1, 3, 7, 5, 6, 20] 117 | self.assertEqual(LISv1(n, data).solution(), 5) 118 | self.assertEqual(LISv2(n, data).solution(), 5) 119 | self.assertEqual(LISv3(n, data).solution(), 5) 120 | 121 | 122 | class TrianglePath: 123 | 124 | def __init__(self, n, data): 125 | self.n = n 126 | self.data = data 127 | self.memo = dict() 128 | 129 | def solution(self): 130 | for row in range(self.n): 131 | for idx in range(len(self.data[row])): 132 | upper = self.memo[(row-1, idx)] + self.data[row][idx] if row > 0 and idx < len(self.data[row-1]) else self.data[row][idx] 133 | lupper = self.memo[(row-1, idx-1)] + self.data[row][idx] if row > 0 and idx > 0 else self.data[row][idx] 134 | 135 | self.memo[(row, idx)] = max(upper, lupper) 136 | 137 | return max(self.memo.values()) 138 | 139 | 140 | def main_triangle_path(): 141 | tc = input() 142 | 143 | for i in range(int(tc)): 144 | n = int(input()) 145 | data = [] 146 | for j in range(n): 147 | data.append([int(v) for v in input().split(' ')]) 148 | print(TrianglePath(n, data).solution()) 149 | 150 | 151 | if __name__ == '__main__': 152 | main_triangle_path() 153 | 154 | 155 | class TestTrianglePath(unittest.TestCase): 156 | 157 | def test_main(self): 158 | main_triangle_path() 159 | 160 | def test_case1(self): 161 | n = 5 162 | data = [ 163 | [6], 164 | [1, 2], 165 | [3, 7, 4], 166 | [9, 4, 1, 7], 167 | [2, 7, 5, 9, 4] 168 | ] 169 | self.assertEqual(TrianglePath(n, data).solution(), 28) 170 | 171 | def test_case2(self): 172 | n = 5 173 | data = [ 174 | [1], 175 | [2, 4], 176 | [8, 16, 8], 177 | [32, 64, 32, 64], 178 | [128, 256, 128, 256, 128] 179 | ] 180 | self.assertEqual(TrianglePath(n, data).solution(), 341) 181 | -------------------------------------------------------------------------------- /LONGEST_PALINDROMIC_SUBSTRING/README.md: -------------------------------------------------------------------------------- 1 | # Longest Palindromic Substring 2 | 3 | https://leetcode.com/problems/longest-palindromic-substring/ 4 | -------------------------------------------------------------------------------- /LONGEST_PALINDROMIC_SUBSTRING/longest_palindromic_substring_chrisjune.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPalindrome(self, s: str) -> str: 3 | max_result = '' 4 | for i in range(len(s)): 5 | max_result = max(max_result, self.calculate(s, i, i + 1), self.calculate(s, i,i), key=lambda x:len(x)) 6 | return max_result 7 | 8 | def calculate(self, s, left, right): 9 | l, r = 0, 0 10 | while 0 <= left and right <=len(s) - 1: 11 | if s[left] == s[right]: 12 | l, r = left, right 13 | left -= 1 14 | right += 1 15 | continue 16 | else: 17 | break 18 | return s[l: r+1] 19 | 20 | 21 | 22 | if __name__ == '__main__': 23 | # assert Solution().longestPalindrome('aba') == 'aba' 24 | assert Solution().longestPalindrome('xaba') == 'aba' 25 | assert Solution().longestPalindrome('xxaba') == 'aba' 26 | assert Solution().longestPalindrome('abax') == 'aba' 27 | assert Solution().longestPalindrome('abaxx') == 'aba' 28 | assert Solution().longestPalindrome('racecar') == 'racecar' 29 | assert Solution().longestPalindrome('cbbd') == 'bb' 30 | -------------------------------------------------------------------------------- /LONGEST_PALINDROMIC_SUBSTRING/longest_palindromic_substring_yoonnoon.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/longest-palindromic-substring/ 3 | """ 4 | import unittest 5 | 6 | 7 | class Solution: 8 | """ 9 | Runtime: 924 ms, faster than 85.15% of Python3 online submissions for Longest Palindromic Substring. 10 | Memory Usage: 13.8 MB, less than 22.69% of Python3 online submissions for Longest Palindromic Substring. 11 | """ 12 | def longestPalindrome(self, s: str) -> str: 13 | if not s and len(s) == 1: 14 | return s 15 | 16 | dp = dict() 17 | for i, value in enumerate(s): 18 | candidates = list(value) 19 | 20 | dp_start_position = i - len(dp[i-1]) if i > 0 else -1 21 | 22 | if dp_start_position > 0: 23 | if s[dp_start_position-1] == value: 24 | dp[i] = s[dp_start_position-1:i+1] 25 | continue 26 | 27 | for j in range(len(s[dp_start_position:i+1])): 28 | if is_palindromic_string(s[dp_start_position+j:i+1]): 29 | candidates.append(s[dp_start_position+j:i+1]) 30 | break 31 | 32 | dp[i] = elected(candidates) 33 | 34 | return elected(dp.values()) 35 | 36 | 37 | def is_palindromic_string(s): 38 | if len(s) < 2: 39 | return True 40 | 41 | if s[0] == s[-1]: 42 | return is_palindromic_string(s[1:len(s)-1]) 43 | 44 | 45 | def elected(candidates): 46 | temp = '' 47 | for element in candidates: 48 | temp = element if len(element) > len(temp) else temp 49 | return temp 50 | 51 | 52 | class TestCase(unittest.TestCase): 53 | def test_case_1(self): 54 | s = "babad" 55 | output = ("bab", "aba") 56 | self.assertIn(Solution().longestPalindrome(s), output) 57 | 58 | def test_case_2(self): 59 | s = "cbbc" 60 | output = ("cbbc") 61 | self.assertIn(Solution().longestPalindrome(s), output) 62 | -------------------------------------------------------------------------------- /LONGEST_PALINDROMIC_SUBSTRING/lps_jonnung.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPalindrome(self, s: str) -> str: 3 | size = len(s) 4 | if size <= 1: 5 | return s 6 | 7 | if size == 2: 8 | if s[0] == s[1]: 9 | return s 10 | return s[0] 11 | 12 | max_str = "" 13 | for i in range(size): 14 | # abb 15 | l, r = i, i 16 | while l > 0 and r < size-1: 17 | l, r = l-1, r+1 18 | if s[l] == s[r]: 19 | new_max_str = s[l:r+1] 20 | if len(new_max_str) > len(max_str): 21 | max_str = new_max_str 22 | else: 23 | break 24 | 25 | for i in range(size): 26 | l, r = i, i+1 27 | if r < size and s[l] == s[r]: 28 | new_max_str = s[l:r+1] 29 | if len(new_max_str) > len(max_str): 30 | max_str = new_max_str 31 | else: 32 | continue 33 | 34 | while l > 0 and r < size-1: 35 | l, r = l-1, r+1 36 | if s[l] == s[r]: 37 | new_max_str = s[l:r+1] 38 | if len(new_max_str) > len(max_str): 39 | max_str = new_max_str 40 | else: 41 | break 42 | 43 | if max_str == "": 44 | return s[0] 45 | 46 | return max_str 47 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/29rithm/algospot/3b4c671d089b58e49a558573b4e05abb80de04d8/MAXIMUM_SUBARRAY/__init__.py -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maximum_subarray_brownbear.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums): 3 | sequence_sum = 0 4 | max_sum = -9999999999999 5 | 6 | for num in nums: 7 | if sequence_sum < 0: 8 | sequence_sum = num 9 | else: 10 | sequence_sum += num 11 | 12 | if sequence_sum > max_sum: 13 | max_sum = sequence_sum 14 | 15 | return max_sum 16 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maximum_subarray_hyewoneee.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.result_list = [] 4 | 5 | def maxSubArray(self, nums: List[int]) -> int: 6 | score = [] 7 | 8 | results=0 9 | if len(nums) == 1: 10 | if not self.result_list: 11 | return nums[0] 12 | self.result_list.append(nums[0]) 13 | return max(self.result_list) 14 | 15 | for i in range(len(nums)): 16 | if not score: 17 | score.append(nums[i]) 18 | else: 19 | score.append(score[-1] + nums[i]) 20 | if i+1 == len(nums): 21 | max_num = max(score) 22 | index = score.index(max_num) + 1 23 | for i in nums[:index]: 24 | results += i 25 | if results == max_num: 26 | self.result_list.append(results) 27 | nums.pop(0) 28 | return self.maxSubArray(nums) 29 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maximum_subarray_jonnung.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums): 3 | size = len(nums) 4 | 5 | current_max = global_max = nums[0] 6 | 7 | for i in range(1, size): 8 | current_max = max(nums[i], nums[i] + current_max) 9 | if current_max > global_max: 10 | global_max = current_max 11 | 12 | return global_max 13 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maximum_subarray_leejimin.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums): 3 | sub_array_sum = [] 4 | max_sum = None 5 | total_count = len(nums) 6 | if total_count == 1: 7 | return sum(nums) 8 | 9 | for i in range(total_count): 10 | sub_array_sum.append(nums[i]) 11 | if max_sum is None or nums[i] > max_sum: 12 | max_sum = nums[i] 13 | 14 | if i == total_count - 1: 15 | continue 16 | 17 | for j in range(i+1, len(nums)): 18 | sub_array = nums[i: j+1] 19 | sub_sum = sum(sub_array) 20 | if max_sum is None or sub_sum > max_sum: 21 | max_sum = sub_sum 22 | return max_sum 23 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maximum_subarray_yoonnoon.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/maximum-subarray/ 3 | """ 4 | import unittest 5 | 6 | from typing import List 7 | 8 | 9 | class Solution: 10 | 11 | def maxSubArray(self, nums: List[int]) -> int: 12 | """ 13 | My submissions 14 | 15 | Time complexity: O(n) 16 | runtime: 80 ms 17 | memory: 13.2 MB 18 | """ 19 | dp = [0 for i in nums] 20 | for i, value in enumerate(nums, 0): 21 | dp[i] = value if i == 0 or dp[i-1] < 0 else dp[i-1] + value 22 | return max(dp) 23 | 24 | 25 | class TestCase(unittest.TestCase): 26 | 27 | def test_case_1(self): 28 | nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] 29 | output = 6 30 | self.assertEqual(Solution().maxSubArray(nums), output) 31 | -------------------------------------------------------------------------------- /MAXIMUM_SUBARRAY/maxium_subarray_chrisjune.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # Divide & Conquer 3 | def maxSubArray(self, nums): 4 | if not nums: 5 | return float('-inf') 6 | 7 | if len(nums) <= 1: 8 | return nums[0] 9 | 10 | mid = len(nums) // 2 11 | 12 | p_sum = 0 13 | left_max = 0 14 | for i in range(mid - 1, 0 - 1, -1): 15 | p_sum += nums[i] 16 | left_max = max(left_max, p_sum) 17 | 18 | p_sum = 0 19 | right_max = 0 20 | for i in range(mid + 1, len(nums), 1): 21 | p_sum += nums[i] 22 | right_max = max(right_max, p_sum) 23 | 24 | mid_max = left_max + right_max + nums[mid] 25 | 26 | return max(mid_max, self.maxSubArray(nums[:mid]), self.maxSubArray(nums[mid + 1:])) 27 | 28 | # DP 29 | def maxSubArray2(self, nums): 30 | total = nums[0] 31 | partial_sum = nums[0] 32 | for i in range(1, len(nums)): 33 | partial_sum = max(partial_sum + nums[i], nums[i]) 34 | total = max(total, partial_sum) 35 | return total 36 | 37 | 38 | if __name__ == '__main__': 39 | assert (Solution().maxSubArray([1])) == 1 40 | assert (Solution().maxSubArray([1, 2])) == 3 41 | assert (Solution().maxSubArray([1, -2, 2])) == 2 42 | assert (Solution().maxSubArray([-3, -2, -2, -3])) == -2 43 | assert (Solution().maxSubArray([-2, 3, 0, 2, -2, 3])) == 6 44 | assert (Solution().maxSubArray([-2, 3, 0, 2, -2, 3])) == 6 45 | assert (Solution().maxSubArray([3, 1, -2, 2, 2, 1, -2, -3])) == 7 46 | assert (Solution().maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])) == 6 47 | assert (Solution().maxSubArray([5, 8, -8, 5, -4, 2, 1, 9, 2, -8, 8, 3, -4, -5])) == 23 48 | -------------------------------------------------------------------------------- /PICNIC/PICNIC_chirsjune_2.py: -------------------------------------------------------------------------------- 1 | # 1. 두명씩 짝을 짓는다 2 | # 2. 친구여부를 확인하고 짝을 지어준다. 3 | # 3. 일부만 짝이 아니어도 다른 방법으로 판단한다 4 | 5 | # 친구:1,2,3,4 / 짝: (1,2), (3,4) 와 (2,1), (3,4)는 동일하다 6 | # 차이는 친구를 맺어줄때 7 | # 중복없이 짝을 맺는 방법은 받은 친구리스트에서 제일 작은 번호를 뽑고 8 | # 나머지 친구들을 for로 친구를 맺어준다. 그리고 나머지 친구리스트는 재귀호출 9 | 10 | pairs = [] 11 | 12 | def count_pair(students): 13 | if not students: 14 | return 1 15 | first = students[0] 16 | other = students[1:] 17 | 18 | count = 0 19 | for idx in range(len(other)): 20 | pair = other.pop(idx) 21 | 22 | # 친구 관계이면 재귀태우고 아니면 바로 롤백 23 | if [first, pair] in pairs: 24 | count += count_pair(other) 25 | other.insert(idx, pair) 26 | return count 27 | 28 | if __name__ == '__main__': 29 | for case in range(int(input())): 30 | info = input().split() 31 | students = int(info[0]) 32 | 33 | pair_input = input().split() 34 | pairs = [sorted([int(pair_input[i]), int(pair_input[i+1])]) for i in range(0, len(pair_input), 2)] 35 | print(count_pair([i for i in range(students)])) 36 | 37 | 38 | -------------------------------------------------------------------------------- /PICNIC/PICNIC_chrisjune.py: -------------------------------------------------------------------------------- 1 | pair_list = None 2 | 3 | n = 0 4 | are_friends = [] 5 | 6 | 7 | def count_pairs(taken): 8 | first_free = -1 9 | for i in range(n): 10 | if not taken[i]: 11 | first_free = i 12 | break 13 | 14 | if first_free < 0: 15 | return 1 16 | 17 | ret = 0 18 | 19 | for pair_with in range(first_free + 1, n): 20 | if not taken[pair_with] and is_friend([first_free, pair_with], pair_list): 21 | taken[first_free] = taken[pair_with] = True 22 | ret += count_pairs(taken) 23 | taken[first_free] = taken[pair_with] = False 24 | return ret 25 | 26 | def is_friend(pair, pair_list): 27 | for i in range(0, len(pair_list), 2): 28 | if (pair[0], pair[1]) == (pair_list[i], pair_list[i + 1]) or \ 29 | (pair[0], pair[1]) == (pair_list[i + 1], pair_list[i]): 30 | return True 31 | return False 32 | 33 | 34 | # Main 35 | if __name__ == '__main__': 36 | for case in range(int(input())): 37 | info = list(map(int, input().split())) 38 | # 4 39 | n = info[0] 40 | students = [False for i in range(n)] 41 | # 6 42 | pair_count = info[1] 43 | pair_list = list(map(int, input().split())) 44 | print(count_pairs(students)) 45 | -------------------------------------------------------------------------------- /PICNIC/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/PICNIC 2 | -------------------------------------------------------------------------------- /PICNIC/picnic_americanomin.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import sys 3 | 4 | 5 | def populate_pairs(student_list, relation_set): 6 | if len(student_list) < 1: 7 | return [] 8 | 9 | total_friend_pairs = [] 10 | copied_student_list = copy.deepcopy(student_list) 11 | first_student = copied_student_list.pop() 12 | 13 | for copied_student in copied_student_list: 14 | if first_student>copied_student: 15 | one_pair = f"{copied_student}:{first_student}" 16 | else: 17 | one_pair = f"{first_student}:{copied_student}" 18 | 19 | if not one_pair in relation_set: 20 | continue 21 | 22 | nested_student_list = copy.deepcopy(copied_student_list) 23 | nested_student_list.remove(copied_student) 24 | combinations = populate_pairs(nested_student_list, relation_set) 25 | 26 | if combinations: 27 | for combination in combinations: 28 | combination.add(one_pair) 29 | total_friend_pairs.append(combination) 30 | else: 31 | data = set() 32 | data.add(one_pair) 33 | total_friend_pairs.append(data) 34 | 35 | return total_friend_pairs 36 | 37 | 38 | def picnic(friends_meta_info, friends_relations): 39 | friends_meta_info = [ meta for meta in friends_meta_info.split(' ') if meta] 40 | friends_relations = [ relation for relation in friends_relations.split(' ') if relation] 41 | relation_set = set() 42 | 43 | for i, student in enumerate(friends_relations): 44 | if i % 2 != 0 or len(friends_relations) - 1 == i: 45 | continue 46 | key_element = friends_relations[i:i + 2] 47 | key_element.sort() 48 | relation_key = ':'.join(key_element) 49 | relation_set.add(relation_key) 50 | 51 | friends_count = int(friends_meta_info[0]) 52 | friends_count = int(friends_meta_info[0]) 53 | 54 | student_list = [a for a in range(friends_count)] 55 | pairs = populate_pairs(student_list, relation_set) 56 | 57 | return pairs 58 | 59 | if __name__ == '__main__': 60 | rl = lambda : sys.stdin.readline() 61 | test_case_count = int(rl()) 62 | 63 | result = [] 64 | for i in range(test_case_count): 65 | first_line = rl().rstrip().lstrip() 66 | second_line = rl().rstrip().lstrip() 67 | print(len(picnic(first_line, second_line))) 68 | -------------------------------------------------------------------------------- /PICNIC/picnic_brownbear.py: -------------------------------------------------------------------------------- 1 | """ 2 | 테스트 케이스 수 (C <= 50) 3 | 4 | (학생의 수, 친구 쌍의 수) 5 | 6 | (0,1), (1,2), (2,3), (3,0), (0,2), (1,3) 7 | 8 | 1. (0,1), (2,3) 9 | 2. (1,2), (3,0) 10 | 3. (0,2), (1,3) 11 | 12 | 13 | 14 | 0 1 0 2 1 2 1 3 1 4 2 3 2 4 3 4 3 5 4 5 15 | 16 | 17 | * 학생의 수는 무조건 짝수 18 | * 학생은 2명 이상 10명 이하 19 | """ 20 | 21 | def pair_find(students): 22 | if not students: 23 | return 1 24 | 25 | target = students.pop(0) 26 | count = 0 27 | 28 | for student in friends_list[target]: 29 | if student in students: 30 | cp_students = students.copy() 31 | cp_students.remove(student) 32 | count += pair_find(cp_students) 33 | return count 34 | 35 | 36 | if __name__ == '__main__': 37 | # 여기서 가정은 학생의 숫자는 0부터 10까지 순서대로 있다는 가정 38 | for _ in range(int(input())): 39 | friends_cnt = int(input().split()[0]) 40 | friends_set = list(map(int, input().split())) 41 | friends_list = [[] for _ in range(friends_cnt)] 42 | 43 | for i in range(0, len(friends_set), 2): 44 | index = friends_set[i] 45 | value = friends_set[i+1] 46 | if index > value: 47 | index, value = value, index 48 | friends_list[index].append(value) 49 | 50 | print(pair_find(list(range(friends_cnt)))) 51 | -------------------------------------------------------------------------------- /PICNIC/picnic_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def picnic(num, case_list): 2 | friend_list=[] 3 | next_list=[] 4 | result_list = [] 5 | while True: 6 | if not case_list: 7 | if num == 2: 8 | return 1 9 | return len(result_list) 10 | 11 | for case in case_list: 12 | compare_list = [] 13 | if not friend_list: 14 | friend_list.append(case) 15 | for friend in range(len(friend_list)): 16 | boolean = True 17 | if (friend_list[friend][0] not in case) and (friend_list[friend][1] not in case): 18 | if case > friend_list[-1]: 19 | boolean = False 20 | else: 21 | boolean = True 22 | try_num = friend 23 | compare_list.append(boolean) 24 | if compare_list.count(False) == len(compare_list): 25 | friend_list.append(case) 26 | if [case[0], case[1]+1] in case_list: 27 | next_list.append([case[0], case[1]+1]) 28 | if len(friend_list) * 2 == num: 29 | if 0 in friend_list[0]: 30 | result_list.append(friend_list) 31 | 32 | if next_list: 33 | friend_list = friend_list[0:try_num] 34 | friend_list.append(next_list[0]) 35 | next_list.pop(0) 36 | try_num = 0 37 | else: 38 | friend_list = [] 39 | next_list = [] 40 | case_list.pop(0) 41 | 42 | if __name__ == '__main__': 43 | import sys 44 | test_case = sys.stdin.readline() 45 | case_list = [] 46 | friend_num = 2 47 | for tc in range(int(test_case)): 48 | n, m = tuple(map(int, sys.stdin.readline().split())) 49 | student_list = list(map(int, sys.stdin.readline().split())) 50 | for i in range((len(student_list) + friend_num - 1) // friend_num): 51 | set_student = student_list[i * friend_num:(i + 1) * friend_num] 52 | if set_student[0] < set_student[1]: 53 | case_list.append([set_student[0], set_student[1]]) 54 | else: 55 | case_list.append([set_student[1], set_student[0]]) 56 | case_list.sort() 57 | print(picnic(n, case_list)) 58 | -------------------------------------------------------------------------------- /PICNIC/picnic_jonnung.py: -------------------------------------------------------------------------------- 1 | def matching_friend(students, already=0): 2 | global estimate_count 3 | global friendship 4 | 5 | for first in students: 6 | if first < already: 7 | continue 8 | 9 | for second in students: 10 | if first >= second: 11 | continue 12 | 13 | if (first, second) in friendship: 14 | remain_students = students[:] 15 | remain_students.remove(first) 16 | remain_students.remove(second) 17 | 18 | if len(remain_students) > 0: 19 | matching_friend(remain_students, first) 20 | else: 21 | estimate_count += 1 22 | 23 | 24 | if __name__ == "__main__": 25 | import sys 26 | for tc in range(int(sys.stdin.readline())): 27 | # 표준 입력 처리 28 | n, m = tuple(map(int, sys.stdin.readline().split())) 29 | friendship_list = list(map(int, sys.stdin.readline().split())) 30 | friendship_list_odd = [friendship_list[x] for x in range(0, len(friendship_list), 2)] 31 | friendship_list_even = [friendship_list[x] for x in range(1, len(friendship_list), 2)] 32 | friendship = [tuple(sorted(x)) for x in zip(friendship_list_odd, friendship_list_even)] 33 | 34 | # 경우의 수(전역 변수) 35 | estimate_count = 0 36 | 37 | # 메인 함수 38 | matching_friend(list(range(n))) 39 | 40 | # 결과 출력 41 | print(estimate_count) 42 | -------------------------------------------------------------------------------- /PICNIC/picnic_yoonnoon.py: -------------------------------------------------------------------------------- 1 | def solution(input1, input2): 2 | nm = input1.split(' ') 3 | data = input2.split(' ') 4 | 5 | if int(nm[1]) == 0: 6 | return 0 7 | 8 | q = [set(data[count * 2:count * 2 + 2]) for count in range(int(nm[1]))] 9 | 10 | def get_accumulated_data(position): 11 | memo = [q[position]] 12 | 13 | if position == 0: 14 | return memo 15 | else: 16 | prior = get_accumulated_data(position - 1) 17 | memo.extend([element for element in 18 | [x.union(q[position]) for x in prior if len(x.intersection(q[position])) == 0] if 19 | len(element) % 2 == 0]) 20 | memo.extend(prior) 21 | return memo 22 | 23 | return len([case for case in get_accumulated_data(len(q) - 1) if len(case) == int(nm[0])]) 24 | 25 | 26 | test_case_count = input().rstrip().lstrip() 27 | for i in range(int(test_case_count)): 28 | first_line = input().rstrip().lstrip() 29 | second_line = input().rstrip().lstrip() 30 | 31 | print(solution(input1=first_line, input2=second_line)) 32 | -------------------------------------------------------------------------------- /QUADTREE/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/QUADTREE 2 | -------------------------------------------------------------------------------- /QUADTREE/quadtree_brownbear.py: -------------------------------------------------------------------------------- 1 | """ 2 | 주어진 공간을 항상 4개로 분할 / 재귀적으로 표현 3 | 2^n x 2^n 크기 4 | 5 | - 모든 픽셀이 검은색이면 크기와 상관없이 b 6 | - 모든 픽셀이 흰색이면 크기와 상관없이 w 7 | - 모든 색이 아니라면, 가로 세로 각각 2등분해 4개의 조각으로 쪼갬. 8 | x(왼쪽 위 부분의 압축 결과)(오른쪽 위 부분의 압축 결과)(왼쪽 아래 부분의 압축 결과)(오른쪽 아래 부분의 압축 결과)가 됩니다. 9 | 예를 들어 그림 (a)의 왼쪽 위 4분면은 xwwwb로 압축됩니다. 10 | 11 | 주어진 문재를 상하 뒤집어서 다시 출력 12 | 주어지는 문자열은 1000개 이하 13 | """ 14 | 15 | """ 16 | 0<= N < 20 17 | 만약 N이 4면 18 | 2^4 x 2^4 = 16 x 16 행렬. 19 | 1. 16 X 16 행렬을 가로, 세로 나눠 크기가 8 x 8 인 사사분면으로 만듦 20 | 2. 위에서 만든 사사분면에서 w(모두 흰색), b(모두 검정), x(흰색, 검정 혼합)을 셈 21 | 3. x인 부분을 찾아 가로, 세로로 나눠 크기가 4 x 4인 사사분면으로 만듦 22 | 4. 위에서 만든 사사분면에서 w(모두 흰색), b(모두 검정), x(흰색, 검정 혼합)을 셈 23 | 5. x인 부분을 찾아 가로, 세로로 나눠 크기가 2 x 2인 사사분면으로 만듦 24 | 6. 위에서 만든 사사분면에서 w(모두 흰색), b(모두 검정), x(흰색, 검정 혼합)을 셈 25 | 7. x인 부분을 찾아 가로, 세로로 나눠 크기가 1 x 1인 사사분면으로 만듦 26 | 8. 위에서 만든 사사분면에서 w(모두 흰색), b(모두 검정)을 셈 27 | 8-1. 여기서는 1 x 1이기 때문에 x(흰색, 검정 혼합)가 나올 수 없음 28 | 29 | 30 | 그래프의 탐색 순서는 VLR (preorder) 31 | 루트노드는 x 고정 32 | 33 | 상하 뒤집는 건 모든 사사분면에 적용 34 | 35 | 쿼드트리 구성 후, 상하 반전된 걸 읽는 순서는 3,4,1,2 36 | 37 | 받은 문자열 중 첫 번째 x는 생략 (루트노드) 38 | 39 | 들어온 데이터는 아래와 같이 꾸민다. 40 | xwbbw: 41 | [w,b,b,w] 42 | 43 | 상하 뒤집으면 3,4,1,2 순으로 읽어서 아래와 같이 쓴다. 44 | [b,w,w,b] 45 | 46 | xbwxwbbwb: 47 | [b,w,(x,(w,b,b,w)),b] 48 | 상하 뒤집으면 3,4,1,2 순으로 읽어서 아래와 같이 쓴다. 49 | [(x,(b,w,w,b)),b,b,w] 50 | 51 | pseudo code 52 | 53 | # 함수 make(i): 54 | # t = s[i] 55 | # if t == 'x': 56 | # pass 57 | # 58 | # origin.append(t) 59 | 60 | 함수 make(s): 61 | (x,(s)) 62 | 63 | # 주어진 값을 먼저 위 형식으로 만든다. 64 | 65 | origin = [] 66 | 67 | is_inner = False 68 | a = ('x',()) 69 | for s in 원본데이터: 70 | if is_inner: 71 | make(s) 72 | elif s != 'x' and not is_inner: 73 | origin.append(s) 74 | else: 75 | is_inner = True 76 | 77 | 78 | 79 | # 트리를 구현해서?? 80 | class Tree: 81 | 82 | r = [[],[],[],[]] 83 | 84 | 85 | """ 86 | 87 | 88 | def read(r, i): 89 | if i == 5: 90 | return 91 | target = r[orders[i]] 92 | if isinstance(target, list): 93 | read(target, 0) 94 | else: 95 | result.append(target) 96 | read(r, i + 1) 97 | 98 | 99 | if __name__ == '__main__': 100 | orders = [0, 3, 4, 1, 2] 101 | for _ in range(int(input())): 102 | tc = input() 103 | result = [] 104 | tree = [] 105 | 106 | if len(tc) == 1: 107 | print(tc) 108 | continue 109 | 110 | # 뒤에서 부터 세주면서 subtree를 구성 111 | # 루트 노드는 빼고 세야 쿼드트리 형태를 이룰 수 있음 112 | for i in range(len(tc) - 1, 0, -1): 113 | node = tc[i] 114 | if node != 'x': 115 | tree.append(node) 116 | continue 117 | # 쿼드트리이므로 들어온 순으로 4개를 뽑아서 tree를 구성해줌 118 | subtree = tree[-1:-5:-1] 119 | # 부모 노드인 x를 붙여줌 120 | subtree.insert(0, node) 121 | del tree[-1:-5:-1] 122 | tree.append(subtree) 123 | # 루트노드를 제외하고 최하단 리프노드부터 세었으므로 가장 마지막에 루트노드인 x를 추가 124 | tree.append('x') 125 | tree.reverse() 126 | 127 | read(tree, 0) 128 | print(''.join(result)) 129 | -------------------------------------------------------------------------------- /QUADTREE/quadtree_chrisjune.py: -------------------------------------------------------------------------------- 1 | # QUADTREE 2 | # 실질적으로 자리를 바꾸는 문제임 3 | # x1234 -> x3412형태 4 | # x12x12344 -> xx3412412 5 | # 가장 작은 형태인 x1234를 뒤집어서 반환하게한다 6 | 7 | 8 | string = None 9 | recursived = False 10 | 11 | 12 | def flip(): 13 | # 재귀로 시작한 것인지 판단하기 위한 변수 14 | global recursived 15 | if recursived: 16 | first = 'x' 17 | recursived = False 18 | else: 19 | # 재귀로 시작한게 아니라면 입력 문자열에서 첫번째를 읽는다 20 | first = next(string) 21 | 22 | # 만약 첫 문자가 x로 시작하지 않으면 볼 필요없이 그대로반환 23 | if first != 'x': 24 | return first 25 | 26 | # 여기서부턴 x1234의 형태가 된다 27 | # x도 결과문자에 포함해야하기 때문에 append 28 | swap = [] 29 | swap.append(first) 30 | try: 31 | while True: 32 | # 입력받은 문자열이 얼마나 긴지 모르기 때문에 판단여부를 swap할 대상리스트가 33 | # 총 [x,1,2,3,4] 5개가 되면 끝낸다 34 | if len(swap) == 5: 35 | break 36 | 37 | # 여기선 x 이후의 문자가 되는데 38 | # 다시 x가 등장하면 재귀를 호출하여 부분문제를 풀도록하고 39 | # 숫자가 등장하면 x,1,2,3,4의 문자열이기 때문에 swap에 모두 넣어준다 40 | target = next(string) 41 | if target == 'x': 42 | recursived = True 43 | swap.append(flip()) 44 | else: 45 | swap.append(target) 46 | except StopIteration: 47 | pass 48 | 49 | # x1234 -> x3412로 되도록 순서변경해준다 50 | swap[1], swap[2], swap[3], swap[4] = swap[3], swap[4], swap[1], swap[2] 51 | return ''.join(swap) 52 | 53 | 54 | if __name__ == '__main__': 55 | for case in range(int(input())): 56 | string = iter(input()) 57 | print(flip()) 58 | -------------------------------------------------------------------------------- /QUADTREE/quadtree_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def QuadList(data_list): 2 | set_list = [] 3 | while True: 4 | try: 5 | char = next(data_list) 6 | if char == 'x': 7 | set_list.append(QuadList(data_list)) 8 | else: 9 | set_list.append(char) 10 | if len(set_list) == 4: 11 | return set_list 12 | except StopIteration: 13 | return set_list[0] 14 | 15 | def QuadTree(data): 16 | if len(data) == 1: 17 | print(data[0]) 18 | tree_list = data 19 | for i in range(len(data)): 20 | if isinstance(data[i], list): 21 | tree_list[i] = QuadTree(data[i]) 22 | return 'x' + data[2] + data[3] + data[0] + data[1] 23 | 24 | if __name__ == '__main__': 25 | import sys 26 | case = sys.stdin.readline() 27 | if int(case) > 50: 28 | raise print('테스트 케이스는 50번을 넘길 수 없다.') 29 | for tc in range(int(case)): 30 | quad_list = [] 31 | input_list = input() 32 | if input_list == 'w' or input_list == 'b': 33 | print(input_list) 34 | else: 35 | for i in input_list: 36 | quad_list.append(i) 37 | print(QuadTree(QuadList(iter(quad_list)))) 38 | -------------------------------------------------------------------------------- /QUADTREE/quadtree_jonnung.py: -------------------------------------------------------------------------------- 1 | def split_squad(compressed_str_iter): 2 | ret = [] 3 | while True: 4 | try: 5 | char = next(compressed_str_iter) 6 | if char == "x": 7 | ret.append(split_squad(compressed_str_iter)) 8 | else: 9 | ret.append(char) 10 | 11 | if len(ret) == 4: 12 | return ret 13 | except StopIteration: 14 | return ret[0] 15 | 16 | 17 | def change_up_down(decompress_list): 18 | if len(decompress_list) == 1: 19 | return decompress_list[0] 20 | 21 | copied_decompress_list = decompress_list[:] 22 | for i, v in enumerate(copied_decompress_list): 23 | if isinstance(v, list): 24 | copied_decompress_list[i] = change_up_down(v) 25 | 26 | decompress_list[0], decompress_list[1] = copied_decompress_list[2], copied_decompress_list[3] 27 | decompress_list[2], decompress_list[3] = copied_decompress_list[0], copied_decompress_list[1] 28 | 29 | return "x" + "".join(decompress_list) 30 | 31 | 32 | if __name__ == "__main__": 33 | import sys 34 | rl = lambda: sys.stdin.readline() 35 | c = int(rl()) 36 | for _ in range(c): 37 | print(change_up_down(split_squad(iter(rl())))) -------------------------------------------------------------------------------- /QUADTREE/quadtree_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, _value): 6 | self.value = _value 7 | self.child = [None, None, None, None] 8 | 9 | def __str__(self): 10 | return self.value + str(self.child[2]) + str(self.child[3]) + str(self.child[0]) + str(self.child[1]) 11 | 12 | 13 | class QuadTree: 14 | 15 | def __init__(self, _data): 16 | self.data = _data 17 | self.temp = list(self.data) 18 | self.root = None 19 | 20 | def solution(self): 21 | if self.data.startswith('x'): 22 | self.root = TreeNode(self.temp.pop(0)) 23 | self.make_tree(self.root) 24 | else: 25 | return self.data 26 | 27 | return str(self.root) 28 | 29 | def make_tree(self, tree): 30 | for idx in range(len(tree.child)): 31 | c = self.temp.pop(0) 32 | if c == 'x': 33 | tree.child[idx] = TreeNode(c) 34 | self.make_tree(tree.child[idx]) 35 | else: 36 | tree.child[idx] = c 37 | 38 | 39 | if __name__ == '__main__': 40 | tc = input() 41 | 42 | for i in range(int(tc)): 43 | data = input() 44 | print(QuadTree(data).solution()) 45 | 46 | 47 | class Test(unittest.TestCase): 48 | 49 | def test_case1(self): 50 | test_data = 'w' 51 | self.assertEqual(QuadTree(test_data).solution(), 'w') 52 | 53 | def test_case2(self): 54 | test_data = 'xbwwb' 55 | self.assertEqual(QuadTree(test_data).solution(), 'xwbbw') 56 | 57 | def test_case3(self): 58 | test_data = 'xbwxwbbwb' 59 | self.assertEqual(QuadTree(test_data).solution(), 'xxbwwbbbw') 60 | 61 | def test_case4(self): 62 | test_data = 'xxwwwbxwxwbbbwwxxxwwbbbwwwwbb' 63 | self.assertEqual(QuadTree(test_data).solution(), 'xxwbxwwxbbwwbwbxwbwwxwwwxbbwb') 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 이구리즘 - 알고리즘 문제 해결 스터디 2 | ---- 3 | ## 스터디 계획 4 | - 구종만의 [알고리즘 문제 해결 전략](https://book.algospot.com/) 책으로 진행하는 알고리즘 문제 해결 오프라인 스터디 5 | - 매주 목요일 저녁 6시 6 | - "알고리즘 문제 해결 전략" 챕터 순서대로 문제 1개 선택해서 [algospot.com](https://algospot.com/)~을 통해 제출~ 또는 [leetcode](https://leetcode.com/)에서 유사한 문제를 선정 7 | - 프로그래밍 언어는 자유롭게 선택 가능 8 | - 먼저 [이 스터디 저장소](https://github.com/29rithm/algospot)를 Fork한 뒤 그 저장소를 Clone 9 | - 문제 해결 소스코드는 `{문제 영문명}_{Github 계정명}.{확장자}` 형식으로 저장 후 Fork한 저장소로 Push 10 | - 그 다음 개인 저장소(origin)에서 스터디 저장소(upstream)으로 Pull Request 작성 11 | 12 | ## COC (Code of Conduct, 행동 지침) 13 | 1. 알고리즘 문제 해결에만 집착하지 않고, 원리와 패턴을 익히는 데 목적을 둔다. 14 | 2. 절대 풀지 못할 것 같은 문제는 적당한 시점에 포기하고, 다른 사람의 풀이를 통해 영감을 얻고 배우자. 15 | 3. 지금 풀지 못한 문제라도 언젠가 풀게 될 수 있다는 자신감을 갖자. 16 | 4. 꾸준한 훈련을 통해 알고리즘 문제 해결 뇌근육을 키우자. 17 | 5. 문제가 잘 풀리지 않는다고 스스로 비하하지 않는다. 18 | 6. 다른 사람이 어려움을 겪고 있을 때는 용기를 줄 수 있는 따뜻한 말 한마디를 건넨다. 19 | 7. 다른 사람의 코드나 문제 해결 방식을 비난하지 않는다. 20 | 21 | ## 스케줄 및 알고리즘 문제 22 | ##### 2019-11-21 23 | - [PICNIC](https://algospot.com/judge/problem/read/PICNIC) 24 | ##### 2019-12-05 25 | - [BOARDCOVER](https://algospot.com/judge/problem/read/BOARDCOVER) 26 | ##### 2019-12-12 27 | - [QUADTREE](https://algospot.com/judge/problem/read/QUADTREE) 28 | ##### 2019-12-19 29 | - [FENCE](https://algospot.com/judge/problem/read/FENCE) 30 | ##### 2019-12-26 31 | - [JUMPGAME](https://algospot.com/judge/problem/read/JUMPGAME) 32 | ##### 2020-01-02 33 | - [WILDCARD](https://algospot.com/judge/problem/read/WILDCARD) 34 | ##### 2020-01-16 35 | - [LIS](https://algospot.com/judge/problem/read/LIS) 36 | ##### 2020-01-30 37 | - ~QUANTIZATION~ [maximum-subarray](https://leetcode.com/problems/maximum-subarray/) 38 | ##### 2020-02-06 39 | - [LONGEST_PALINDROMIC_SUBSTRING](https://leetcode.com/problems/longest-palindromic-substring/) 40 | ##### 2020-02-13 41 | - [CLIMBING-STAIRS](https://leetcode.com/problems/climbing-stairs/) 42 | ##### 2020-02-20 43 | - ~[IS-SUBSEQUENCE](https://leetcode.com/problems/is-subsequence/)~ 44 | - [JUMP-GAME2](https://leetcode.com/problems/jump-game-ii/) 45 | ##### 2020-02-27 46 | - [GAS-STATION](https://leetcode.com/problems/gas-station/) 47 | -------------------------------------------------------------------------------- /TRIANGLEPATH/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/TRIANGLEPATH 2 | 3 | -------------------------------------------------------------------------------- /TRIANGLEPATH/trianglepath_chrisjune.py: -------------------------------------------------------------------------------- 1 | # 입력은 삼각형이기 때문에 2 | # n번째 줄은 n개의 개수 3 | # n+1번째 줄은 n+1개수라는 것이 확정 4 | # 한번 움직일때마다 아래 또는 아래오른쪽으로 움직인다 5 | # 만약 idx = (r, c) 라면 -> (r+1, c) 또는 (r+1, c+1)이라는 의미이다 6 | # 이 형태로 부분문제를 만든다 7 | 8 | triangle = [] 9 | cache = [] 10 | 11 | 12 | def sum_triangle(r, c): 13 | if r >= len(triangle) or c >= len(triangle): 14 | return 0 15 | if cache[r][c] != -1: 16 | return cache[r][c] 17 | 18 | sum = 0 19 | sum += triangle[r][c] 20 | max_value = max(sum_triangle(r + 1, c), sum_triangle(r + 1, c + 1)) 21 | sum += max_value 22 | cache[r][c] = sum 23 | return sum 24 | 25 | 26 | if __name__ == '__main__': 27 | for _ in range(int(input())): 28 | rows = int(input()) 29 | triangle = [] 30 | cache = [] 31 | for i in range(rows): 32 | row = [int(i) for i in input().split()] 33 | triangle.append(row) 34 | cache.append([-1 for i in range(len(row))]) 35 | print(sum_triangle(0, 0)) 36 | -------------------------------------------------------------------------------- /WILDCARD/README.md: -------------------------------------------------------------------------------- 1 | https://algospot.com/judge/problem/read/WILDCARD 2 | 3 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_chrisjune.py: -------------------------------------------------------------------------------- 1 | # * 이 문제가 된다 2 | # so*me*bo*dy 3 | # so* me* bo* dy 4 | # 이렇게 네 개로 쪼개버리고 5 | # * 을 만났을 때 부분문제로 처리한다 6 | # ab fg 7 | # ab cdefg 8 | 9 | def check_match(pattern, string): 10 | idx = 0 11 | while idx < len(pattern) and idx < len(string) and ((pattern[idx] == string[idx]) or pattern[idx] == '?'): 12 | idx += 1 13 | 14 | if idx == len(pattern): 15 | return idx == len(string) 16 | 17 | if pattern[idx] == '*': 18 | for i in range(len(string)-idx+1): 19 | if(check_match(pattern[idx+1:], string[idx+i:])): 20 | return True 21 | return False 22 | 23 | if __name__ == '__main__': 24 | for _ in range(int(input())): 25 | pattern = input() 26 | for case in range(int(input())): 27 | string = input() 28 | result = check_match(pattern, string) 29 | if result: 30 | print(string) 31 | 32 | # if __name__ == '__main__': 33 | # assert check_match('he?p', 'help') 34 | # assert check_match('?e?p', 'help') 35 | # assert not check_match('he?p', 'helpp') 36 | # assert check_match('*p', 'help') 37 | # assert check_match('h*', 'help') 38 | # assert check_match('h*p', 'help') 39 | # assert check_match('*l*', 'help') 40 | # assert check_match('*p*', 'help') 41 | # assert check_match('*p*', 'papa') 42 | # assert not check_match('*p*', 'hello') 43 | 44 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_chrisjune_re.py: -------------------------------------------------------------------------------- 1 | # 8.2 wildcard 2 | # * = 0글자 이상 3 | # ? = 1글자 4 | # 패턴과 패턴으로 검색할 수 있는 대상들이 주어지고 그 대상중 맞는 것만 반환 5 | # 입력 C <= 10, 패턴, 대상들 <=50 6 | # 패턴 = 알파벳, 대소문자, 숫자, *, ? 7 | # 파일명 알파벳, 대소문자, 숫자, 문자열길이 <=100, 공백미포함 8 | def search(pattern, file): 9 | idx = 0 10 | while idx < len(pattern) and idx < len(file) and (pattern[idx] == '?' or pattern[idx] == file[idx]): 11 | idx += 1 12 | 13 | # 종료됨, 종료된 사유에 따라서 로직을 처리 14 | if idx == len(pattern): 15 | return idx == len(file) 16 | 17 | if pattern[idx] == '*': 18 | for i in range(len(file)-idx+1): 19 | if search(pattern[idx+1:], file[idx+i:]): 20 | return True 21 | return False 22 | 23 | if __name__ == '__main__': 24 | pattern = 'he?p' 25 | file = 'help' 26 | assert search(pattern, file) 27 | file = 'heap' 28 | assert search(pattern, file) 29 | file = 'helpp' 30 | assert not search(pattern, file) 31 | 32 | pattern = '*p*' 33 | file = 'help' 34 | assert search(pattern, file) 35 | file = 'papa' 36 | assert search(pattern, file) 37 | file = 'hello' 38 | assert search(pattern, file) 39 | 40 | # for _ in range(int(input())): 41 | # pattern = input() 42 | # ret = [] 43 | # for f in range(int(input())): 44 | # file = input() 45 | # if search(pattern, file): 46 | # ret.append(file) 47 | # ret.sort() 48 | # print(ret) 49 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_hyewoneee.py: -------------------------------------------------------------------------------- 1 | def wild_card(pattern, name_list): 2 | import re 3 | result = [] 4 | mark_pattern = pattern.replace('?', '.') 5 | reg_pattern = mark_pattern.replace('*', '.*') 6 | reg_pattern += '$' 7 | re = re.compile(reg_pattern) 8 | for s in name_list: 9 | match = re.match(s) 10 | if match: 11 | result.append(match.group()) 12 | result.sort() 13 | return '\n'.join(result) 14 | 15 | if __name__ == '__main__': 16 | import sys 17 | test_case = sys.stdin.readline() 18 | 19 | for tc in range(int(test_case)): 20 | pattern = input() 21 | name_count = input() 22 | name_list = [] 23 | for nc in range(int(name_count)): 24 | name_list.append(input()) 25 | print(wild_card(pattern, name_list)) 26 | 27 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_jimin.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | def check_wildcard(wildcard_regex, search_text_list): 4 | cleaned_regex = wildcard_regex.replace('?', '.') 5 | cleaned_regex = cleaned_regex.replace('*', '.*') 6 | regrex = re.compile(cleaned_regex) 7 | 8 | confimed_text_list = [] 9 | 10 | for search_text in search_text_list: 11 | matched_data = regrex.findall(search_text) 12 | 13 | if matched_data and len(matched_data[0]) == len(search_text): 14 | confimed_text_list.append(search_text) 15 | 16 | confimed_text_list.sort() 17 | return confimed_text_list 18 | 19 | 20 | if __name__ == "__main__": 21 | for problem_count in range(int(input())): 22 | board = [] 23 | blocked = [] 24 | wildcard_regex = input().strip() 25 | target_text_count = int(input()) 26 | 27 | target_text_list = [input() for _ in range(target_text_count)] 28 | results = check_wildcard(wildcard_regex, target_text_list) 29 | 30 | for result in results: 31 | print(result) 32 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_jonnung.py: -------------------------------------------------------------------------------- 1 | def match(pattern, filename): 2 | index = 0 3 | 4 | while True: 5 | if index == len(pattern) and index == len(filename): 6 | return True 7 | 8 | if index == len(pattern) and len(filename) > 0: 9 | return False 10 | 11 | if pattern[index] != "*": 12 | if pattern[index] == "?" or pattern[index] == filename[index]: 13 | index += 1 14 | continue 15 | else: 16 | return False 17 | else: 18 | if index == len(filename): 19 | return True 20 | 21 | if pattern[index + 1] == "*": 22 | index += 1 23 | continue 24 | 25 | for right in range(len(filename[index:])): 26 | next_pattern = pattern[index + 1:] 27 | 28 | if not next_pattern: 29 | return True 30 | 31 | temp_filename = filename[index + right:] 32 | if match(next_pattern, temp_filename): 33 | return True 34 | 35 | return False 36 | 37 | if __name__ == "__main__": 38 | import sys 39 | 40 | rl = lambda: sys.stdin.readline() 41 | c = int(rl()) 42 | for _ in range(c): 43 | w = str(rl()).strip() 44 | n = int(rl()) 45 | matched = [] 46 | for _ in range(n): 47 | filename = str(rl()).strip() 48 | if match(w, filename): 49 | matched.append(filename) 50 | for result in sorted(matched): 51 | print(result) 52 | 53 | -------------------------------------------------------------------------------- /WILDCARD/wildcard_yoonnoon.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class Wildcard: 5 | def __init__(self, regex): 6 | self.regex = regex 7 | self.asterisk_count = self.regex.count('*') 8 | 9 | def solution(self, data): 10 | data.sort() 11 | return [string for string in data 12 | if len(string) >= len(self.regex)-self.asterisk_count 13 | and self.is_match(self.regex, string, False)] 14 | 15 | def is_match(self, regex, string, asterisk): 16 | if not asterisk and not regex and string: 17 | return False 18 | 19 | if asterisk and not regex and string: 20 | return True 21 | 22 | if not regex and not string: 23 | return True 24 | 25 | if regex[0] == '*': 26 | return self.is_match(regex[1:], string, True) 27 | else: 28 | if not string: 29 | return False 30 | 31 | if asterisk: 32 | idx = -1 33 | for i in range(len(string)): 34 | if regex[0] == '?': 35 | if self.is_match(regex[1::], string[1+i::], False): 36 | return True 37 | else: 38 | if i > idx: 39 | idx = string.find(regex[0], i) 40 | if idx > -1: 41 | if self.is_match(regex[1::], string[idx+1::], False): 42 | return True 43 | else: 44 | return False 45 | return False 46 | else: 47 | return self.is_match(regex[1:], string[1:], False) \ 48 | if regex[0] == string[0] or regex[0] == '?' else False 49 | 50 | 51 | def main(): 52 | tc = input() 53 | 54 | for i in range(int(tc)): 55 | regex = input() 56 | data = [] 57 | for j in range(int(input())): 58 | data.insert(j, input()) 59 | 60 | results = Wildcard(regex).solution(data) 61 | for i in results: 62 | print(i) 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | 68 | 69 | class Test(unittest.TestCase): 70 | 71 | def test_main(self): 72 | main() 73 | 74 | def test_case1(self): 75 | regex = 'he?p' 76 | data = ['help', 'heap', 'helpp'] 77 | self.assertEqual(Wildcard(regex).solution(data), ['heap', 'help']) 78 | 79 | def test_case2(self): 80 | regex = '*p*' 81 | data = ['help', 'papa', 'hello'] 82 | self.assertEqual(Wildcard(regex).solution(data), ['help', 'papa']) 83 | -------------------------------------------------------------------------------- /tests/CLIMBING_STAIRS/test_climbing_stairs.py: -------------------------------------------------------------------------------- 1 | from CLIMBING_STAIRS.climbing_stairs_jonnung import Solution 2 | 3 | 4 | def test_climbling_stairs_testcase(): 5 | tc = [ 6 | (2, 2), 7 | (3, 3), 8 | (4, 5), 9 | (5, 8), 10 | (6, 13), 11 | ] 12 | 13 | solution = Solution() 14 | for input, output in tc: 15 | assert solution.climbStairs(input) == output 16 | -------------------------------------------------------------------------------- /tests/FENCE/test_fence_americanomin.py: -------------------------------------------------------------------------------- 1 | from FENCE.fence_americanomin import get_max_square_measure 2 | 3 | 4 | def test__get_max_square_measure_case_1(): 5 | fence = [7, 1, 5, 9, 6, 7, 3] 6 | assert 20 == get_max_square_measure(fence) 7 | 8 | 9 | def test__get_max_square_measure_case_2(): 10 | fence = [1, 4, 4, 4, 4, 1, 1] 11 | assert 16 == get_max_square_measure(fence) 12 | 13 | 14 | def test__get_max_square_measure_case_3(): 15 | fence = [1, 8, 2, 2] 16 | assert 8 == get_max_square_measure(fence) 17 | 18 | 19 | def test__get_max_square_measure_case_4(): 20 | fence = [2, 2] 21 | assert 4 == get_max_square_measure(fence) 22 | 23 | 24 | def test__get_max_square_measure_case_5(): 25 | fence = [1, 3] 26 | assert 3 == get_max_square_measure(fence) 27 | 28 | 29 | def test__get_max_square_measure_case_6(): 30 | fence = [1, 4, 1, 5, 4, 4, 4] 31 | assert 16 == get_max_square_measure(fence) 32 | -------------------------------------------------------------------------------- /tests/FENCE/test_fence_jonnung.py: -------------------------------------------------------------------------------- 1 | from FENCE.fence_jonnung import calculate_rectangle_size 2 | 3 | 4 | def test__현재_위치_양옆으로_현재_높이보다_작을때까지_너비를_계산한다(): 5 | # arrange 6 | fence1 = [1, 4, 4, 4, 4, 1, 1] 7 | rectangle_size1 = calculate_rectangle_size(len(fence1), fence1) 8 | 9 | fence2 = [7, 1, 5, 9, 6, 7, 3] 10 | rectangle_size2 = calculate_rectangle_size(len(fence2), fence2) 11 | 12 | fence3 = [1, 8, 2, 2] 13 | rectangle_size3 = calculate_rectangle_size(len(fence3), fence3) 14 | 15 | # assert 16 | assert rectangle_size1 == 16 17 | assert rectangle_size2 == 20 18 | assert rectangle_size3 == 8 19 | -------------------------------------------------------------------------------- /tests/JUMPGAME/test_jumpgame_jonnung.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from JUMPGAME.jumpgame_jonnung import JumpGame 4 | 5 | 6 | @pytest.fixture 7 | def case1(): 8 | return [ 9 | [1, 1], 10 | [1, 0], 11 | ] 12 | 13 | 14 | @pytest.fixture 15 | def case2(): 16 | return [ 17 | [1, 1, 2], 18 | [1, 2, 3], 19 | [2, 4, 0], 20 | ] 21 | 22 | 23 | @pytest.fixture 24 | def case3(): 25 | return [ 26 | [2, 5, 1, 6, 1, 4, 1], 27 | [6, 1, 1, 2, 2, 9, 3], 28 | [7, 2, 3, 2, 1, 3, 1], 29 | [1, 1, 3, 1, 7, 1, 2], 30 | [4, 1, 2, 3, 4, 1, 2], 31 | [3, 3, 1, 2, 3, 4, 1], 32 | [1, 5, 2, 9, 4, 7, 0], 33 | ] 34 | 35 | 36 | @pytest.fixture 37 | def case4(): 38 | return [ 39 | [2, 5, 1, 6, 1, 4, 1], 40 | [6, 1, 1, 2, 2, 9, 3], 41 | [7, 2, 3, 2, 1, 3, 1], 42 | [1, 1, 3, 1, 7, 1, 2], 43 | [4, 1, 2, 3, 4, 1, 3], 44 | [3, 3, 1, 2, 3, 4, 1], 45 | [1, 5, 2, 9, 4, 7, 0], 46 | ] 47 | 48 | 49 | def test__주어진_위치에서_오른쪽_아래쪽으로_이동할_수_있는지_확인(case1): 50 | jg1 = JumpGame(2, case1) 51 | jg2 = JumpGame(2, case1) 52 | 53 | jg1_down, jg1_right = jg1.check_movable(0, 0) 54 | jg2_down, jg2_right = jg2.check_movable(0, 1) 55 | 56 | assert jg1_down is True 57 | assert jg1_right is True 58 | assert jg2_down is True 59 | assert jg2_right is False 60 | 61 | 62 | def test__주어진_위치에서_오른쪽으로_이동_했을때_값을_알수있다(case2): 63 | jg = JumpGame(3, case2) 64 | assert jg.right(0, 0) == (0, 1) 65 | 66 | 67 | def test__오른쪽으로_이동_했을때_좌표가_최종_목적지이면_참(case2): 68 | jg = JumpGame(3, case2) 69 | assert jg.right(2, 0) == (2, 2) 70 | 71 | 72 | def test__끝까지_갈_수_있는_방법이_존재한다(case2, case3): 73 | jg1 = JumpGame(3, case2) 74 | assert jg1.jump() is True 75 | 76 | jg2 = JumpGame(7, case3) 77 | assert jg2.jump() is True 78 | 79 | def test__끝까지_갈_수_있는_방법이_존재하지_않는다(case4): 80 | jg3 = JumpGame(7, case4) 81 | assert jg3.jump() is False 82 | -------------------------------------------------------------------------------- /tests/JUMPGAME2/test_jumpgame2_jonnung.py: -------------------------------------------------------------------------------- 1 | from JUMPGAME2.jumpgame2_jonnung import Solution 2 | 3 | 4 | def test_jumpgame2_default_testcase(): 5 | tc = [2, 3, 1, 1, 4] 6 | 7 | solution = Solution() 8 | result = solution.jump(tc) 9 | 10 | assert result == 2 11 | 12 | 13 | def test_jumpgame2_basic1_testcase(): 14 | tc = [0] 15 | solution = Solution() 16 | result = solution.jump(tc) 17 | 18 | assert result == 0 19 | 20 | 21 | def test_jumpgame2_basic2_testcase(): 22 | tc = [1, 2, 3] 23 | solution = Solution() 24 | result = solution.jump(tc) 25 | 26 | assert result == 2 27 | 28 | 29 | def test_jumpgame2_basic3_testcase(): 30 | tc = [3, 2, 1] 31 | solution = Solution() 32 | result = solution.jump(tc) 33 | 34 | assert result == 1 35 | 36 | 37 | def test_jumpgame2_basic4_testcase(): 38 | tc = [1, 2] 39 | solution = Solution() 40 | result = solution.jump(tc) 41 | 42 | assert result == 1 43 | 44 | 45 | def test_jumpgame2_basic5_testcase(): 46 | tc = [1, 2, 0, 1] 47 | solution = Solution() 48 | result = solution.jump(tc) 49 | 50 | assert result == 2 51 | 52 | 53 | def test_jumpgame2_large_testcase(): 54 | tc = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] 55 | 56 | solution = Solution() 57 | result = solution.jump(tc) 58 | 59 | assert result == 24999 -------------------------------------------------------------------------------- /tests/LIS/test_lis_jonnung.py: -------------------------------------------------------------------------------- 1 | from LIS.lis_jonnung import lis_solution 2 | 3 | 4 | def test_lis_solution(): 5 | tc1 = [1, 2, 3, 4] 6 | tc2 = [5, 4, 3, 2, 1, 6, 7, 8] 7 | tc3 = [5, 6, 7, 8, 1, 2, 3, 4] 8 | 9 | assert lis_solution(tc1) == 4 10 | assert lis_solution(tc2) == 4 11 | assert lis_solution(tc3) == 4 -------------------------------------------------------------------------------- /tests/LONGEST_PALINDROMIC_SUBSTRING/test_lps_jonnung.py: -------------------------------------------------------------------------------- 1 | from LONGEST_PALINDROMIC_SUBSTRING.lps_jonnung import Solution 2 | 3 | 4 | def test_lps_default_testcase(): 5 | tc = [ 6 | ("babad", "bab"), 7 | ("cbbd", "bb"), 8 | ] 9 | 10 | solution = Solution() 11 | for input, output in tc: 12 | assert solution.longestPalindrome(input) == output 13 | 14 | 15 | def test_lps_base_case(): 16 | tc = "a" 17 | assert Solution().longestPalindrome(tc) == "a" 18 | 19 | 20 | def test_lps_no_palindronmic(): 21 | tc = "ab" 22 | assert Solution().longestPalindrome(tc) == "a" 23 | 24 | 25 | def test_lps_empty_string(): 26 | tc = "" 27 | assert Solution().longestPalindrome(tc) == "" 28 | 29 | 30 | def test_lps_twice_equal(): 31 | tc = "bb" 32 | assert Solution().longestPalindrome(tc) == "bb" 33 | 34 | 35 | def test_lps_all_equal(): 36 | tc = "aaaa" 37 | assert Solution().longestPalindrome(tc) == "aaaa" 38 | 39 | 40 | def test_lps_abcba(): 41 | tc = "abcba" 42 | assert Solution().longestPalindrome(tc) == "abcba" 43 | 44 | 45 | def test_lps_abb(): 46 | tc = "abb" 47 | assert Solution().longestPalindrome(tc) == "bb" 48 | 49 | 50 | def test_lps_abcda(): 51 | tc = "abcda" 52 | assert Solution().longestPalindrome(tc) == "a" 53 | 54 | def test_lps_aaabaaaa(): 55 | tc = "aaabaaaa" 56 | assert Solution().longestPalindrome(tc) == "aaabaaa" -------------------------------------------------------------------------------- /tests/MAXIMUM_SUBARRAY/test_maximum_subarray.py: -------------------------------------------------------------------------------- 1 | from MAXIMUM_SUBARRAY.maximum_subarray_jonnung import Solution 2 | 3 | 4 | def test_max_subarray_base_case(): 5 | input = [1] 6 | result = Solution().maxSubArray(input) 7 | assert result == 1 8 | 9 | def test_max_subarray_leetcode_tc(): 10 | input = [-2, 1, -3, 4, -1, 2, 1, -5, 4] 11 | result = Solution().maxSubArray(input) 12 | assert result == 6 13 | 14 | def test_max_subarray_length_two(): 15 | input = [-2, 1] 16 | result = Solution().maxSubArray(input) 17 | assert result == 1 18 | 19 | def test_max_subarray_length_one(): 20 | input = [-1] 21 | result = Solution().maxSubArray(input) 22 | assert result == -1 23 | 24 | def test_max_subarray_length_three(): 25 | input = [1, -1, 1] 26 | result = Solution().maxSubArray(input) 27 | assert result == 1 -------------------------------------------------------------------------------- /tests/QUADTREE/test_quadtree_jonnung.py: -------------------------------------------------------------------------------- 1 | from QUADTREE.quadtree_jonnung import split_squad, change_up_down 2 | 3 | 4 | def test__문자열에_w와_b로_분류해서_각각을_요소로_갖는_리스트를_만든다(): 5 | case1 = "w" 6 | case2 = "xwbbb" 7 | 8 | expected_result1 = "w" 9 | expected_result2 = ["w", "b", "b", "b"] 10 | 11 | result1 = split_squad(iter(case1)) 12 | result2 = split_squad(iter(case2)) 13 | 14 | assert result1 == expected_result1 15 | assert result2 == expected_result2 16 | 17 | 18 | def test__문자열이_x로_시작하면_다음에_나오는_문자들은_길이가_4인_리스트에_담긴다(): 19 | case1 = "xwbxwbwbw" 20 | case2 = "xxwwwbxwxwbbbwwxxxwwbbbwwwwbb" 21 | 22 | expected_result1 = ["w", "b", ["w", "b", "w", "b"], "w"] 23 | expected_result2 = [["w", "w", "w", "b"], ["w", ["w", "b", "b" ,"b"], "w", "w"], [[["w", "w", "b", "b"], "b", "w", "w"], "w", "w", "b"], "b"] 24 | 25 | result1 = split_squad(iter(case1)) 26 | result2 = split_squad(iter(case2)) 27 | 28 | assert result1 == expected_result1 29 | assert result2 == expected_result2 30 | 31 | 32 | def test__분해된_리스트에서_첫번째두번째와_세번째네번째_순서를_바꿔_결합한_문자열을_반환한다(): 33 | case0 = ["b"] 34 | case1 = ["w", "b", "b", "b"] 35 | case2 = ["b", "w", ["w", "b", "b", "w"], "b"] 36 | case3 = [["w", "w", "w", "b"], ["w", ["w", "b", "b" ,"b"], "w", "w"], [[["w", "w", "b", "b"], "b", "w", "w"], "w", "w", "b"], "b"] 37 | 38 | expected_result0 = "b" 39 | expected_result1 = "xbbwb" 40 | expected_result2 = "xxbwwbbbw" 41 | expected_result3 = "xxwbxwwxbbwwbwbxwbwwxwwwxbbwb" 42 | 43 | result0 = change_up_down(case0) 44 | result1 = change_up_down(case1) 45 | result2 = change_up_down(case2) 46 | result3 = change_up_down(case3) 47 | 48 | assert result0 == expected_result0 49 | assert result1 == expected_result1 50 | assert result2 == expected_result2 51 | assert result3 == expected_result3 52 | --------------------------------------------------------------------------------