├── .DS_Store ├── .gitignore ├── LICENSE ├── README.md └── src ├── .DS_Store ├── leetcode ├── .DS_Store └── Top_100_Liked_Questions │ ├── .DS_Store │ ├── 104_Maximum Depth of Binary Tree.py │ ├── 136_Single Number.py │ ├── 206_Reverse Linked List.py │ ├── 226_Invert Binary Tree.py │ ├── 338_Counting Bits.py │ ├── 347_Top K Frequent Elements.py │ ├── 406_Queue Reconstruction by Height.py │ ├── 46_Permutations.py │ ├── 617_Merge Two Binary Trees.py │ ├── 647_Palindromic Substrings.py │ ├── 739_Daily Temperatures.py │ ├── 78_Subsets.py │ └── 94_Binary Tree Inorder Traversal.py ├── 동적계획법(Dynamic Programming) ├── Level_3_N으로 표현.py ├── Level_3_정수 삼각형.py ├── Level_3_타일 장식물.py └── README.md ├── 스택_큐 ├── Level_2_기능개발.py ├── Level_2_다리를 지나는 트럭.py ├── Level_2_쇠막대기.py ├── Level_2_주식가격.py ├── Level_2_탑.py ├── Level_2_프린터.py └── README.md ├── 완전탐색 ├── Level_1_모의고사.py ├── Level_2_소수찾기.py ├── Level_2_숫자야구.py ├── Level_2_카펫.py └── README.md ├── 정렬 ├── Level_1_k번째 수.py ├── Level_2_H-Index.py ├── Level_2_가장 큰 수.py └── README.md ├── 탐욕법(Greedy) ├── Level_1_체육복.py ├── Level_2_구명보트.py ├── Level_2_조이스틱.py ├── Level_2_큰 수 만들기.py ├── Level_3_단속카메라.py ├── Level_3_섬 연결하기.py ├── Level_3_저울.py └── README.md ├── 해시 ├── Level_1_완주하지못한선수.py ├── Level_2_위장.py ├── Level_2_전화번호부.py ├── Level_3_베스트앨범.py └── README.md └── 힙(Heap) ├── Level_2_더 맵게.py ├── Level_2_라면공장.py ├── Level_3_디스크 컨트롤러.py ├── Level_3_이중우선순위큐.py └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taki0112/coding_interview/06b61646c3fafb63ac74b1170a4d0a77f02231a0/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Junho Kim (1993.01.12) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # coding_interview **(in progress)** 2 | Programmers coding interview in Korean (***2018.11.21*** ~ ) 3 | 4 | ## Problems 5 | ### Junior 6 | * [해시](https://github.com/taki0112/coding_practice/tree/master/src/%ED%95%B4%EC%8B%9C) **(End)** 7 | * [스택/큐](https://github.com/taki0112/coding_practice/tree/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90) **(End)** 8 | * [힙(Heap)](https://github.com/taki0112/coding_practice/tree/master/src/%ED%9E%99(Heap)) **(End)** 9 | * [정렬](https://github.com/taki0112/coding_practice/tree/master/src/%EC%A0%95%EB%A0%AC) **(End)** 10 | * [완전탐색](https://github.com/taki0112/coding_practice/tree/master/src/%EC%99%84%EC%A0%84%ED%83%90%EC%83%89) **(End)** 11 | * [탐욕법(Greedy)](https://github.com/taki0112/coding_practice/tree/master/src/%ED%83%90%EC%9A%95%EB%B2%95(Greedy)) **(End)** 12 | * [동적계획법(Dynamic Programming)](https://github.com/taki0112/coding_interview/tree/master/src/동적계획법(Dynamic%20Programming)) 13 | * 깊이/너비 우선 탐색(DFS/BFS) 14 | * 이분탐색 15 | 16 | ### Senior 17 | * Will be soon 18 | 19 | ## Reference 20 | * [프로그래머스](https://programmers.co.kr/learn/challenges) 21 | 22 | ## Author 23 | Junho Kim 24 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taki0112/coding_interview/06b61646c3fafb63ac74b1170a4d0a77f02231a0/src/.DS_Store -------------------------------------------------------------------------------- /src/leetcode/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taki0112/coding_interview/06b61646c3fafb63ac74b1170a4d0a77f02231a0/src/leetcode/.DS_Store -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taki0112/coding_interview/06b61646c3fafb63ac74b1170a4d0a77f02231a0/src/leetcode/Top_100_Liked_Questions/.DS_Store -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/104_Maximum Depth of Binary Tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def maxDepth(self, root: TreeNode, depth=0) -> int: 10 | if root == None: 11 | return depth 12 | 13 | x = max(self.maxDepth(root.left, depth + 1), self.maxDepth(root.right, depth + 1)) 14 | 15 | return x 16 | -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/136_Single Number.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Solution: 4 | def singleNumber(self, nums: List[int]) -> int: 5 | x = defaultdict(int) 6 | 7 | for n in nums: 8 | x[n] += 1 9 | 10 | for k, v in x.items(): 11 | if v == 1: 12 | return k -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/206_Reverse Linked List.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution: 8 | def reverseList(self, head: ListNode) -> ListNode: 9 | prev_node = None 10 | curr_node = head 11 | 12 | while curr_node: 13 | next_node = curr_node.next 14 | curr_node.next = prev_node 15 | prev_node = curr_node 16 | curr_node = next_node 17 | 18 | head = prev_node 19 | return head 20 | 21 | -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/226_Invert Binary Tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def invertTree(self, root: TreeNode) -> TreeNode: 10 | if root == None: 11 | return None 12 | 13 | root.left, root.right = self.invertTree(root.right), self.invertTree(root.left) 14 | 15 | return root -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/338_Counting Bits.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | class Solution: 3 | def countBits(self, num): 4 | x = [] 5 | for i in range(num+1): 6 | binary_num = format(i, 'b') 7 | binary_dict = Counter(binary_num) 8 | one_num = binary_dict['1'] 9 | 10 | x.append(one_num) 11 | 12 | return x -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/347_Top K Frequent Elements.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | class Solution: 4 | def topKFrequent(self, nums: List[int], k: int) -> List[int]: 5 | count_nums = Counter(nums) 6 | most_nums = count_nums.most_common(k) 7 | 8 | x = [] 9 | 10 | for n in most_nums: 11 | x.append(n[0]) 12 | 13 | return x -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/406_Queue Reconstruction by Height.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reconstructQueue(self, people): 3 | people = sorted(people, key=lambda x: (-x[0], x[1])) 4 | x = [] 5 | for person in people: 6 | x.insert(person[1], person) 7 | 8 | return x 9 | -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/46_Permutations.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | class Solution: 4 | def permute(self, nums: List[int]) -> List[List[int]]: 5 | return list(permutations(nums)) -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/617_Merge Two Binary Trees.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/merge-two-binary-trees/ 2 | # 617. Merge Two Binary Trees 3 | 4 | # Definition for a binary tree node. 5 | # class TreeNode: 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.left = None 9 | # self.right = None 10 | 11 | class Solution: 12 | def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: 13 | if t1 is None: 14 | return t2 15 | if t2 is None: 16 | return t1 17 | 18 | t1.val += t2.val 19 | t1.left = self.mergeTrees(t1.left, t2.left) 20 | t1.right = self.mergeTrees(t1.right, t2.right) 21 | 22 | return t1 -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/647_Palindromic Substrings.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countSubstrings(self, s: str) -> int: 3 | s_len = len(s) 4 | p_num = 0 5 | 6 | for i in range(s_len): 7 | for j in range(i, s_len): 8 | split_s = s[i:j + 1] 9 | if self.check_palindromic(split_s): 10 | p_num += 1 11 | 12 | return p_num 13 | 14 | def check_palindromic(self, s): 15 | if s == s[::-1]: 16 | return True 17 | else: 18 | return False 19 | -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/739_Daily Temperatures.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def dailyTemperatures(self, T): 3 | x, stack = [0] * len(T), [] 4 | for i in range(len(T)): 5 | while stack and T[stack[-1]] < T[i]: 6 | x[stack.pop()] = i - stack[-1] 7 | stack.append(i) 8 | return x -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/78_Subsets.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsets(self, nums: List[int]) -> List[List[int]]: 3 | output = [[]] 4 | 5 | for num in nums: 6 | output += [curr + [num] for curr in output] 7 | 8 | return output -------------------------------------------------------------------------------- /src/leetcode/Top_100_Liked_Questions/94_Binary Tree Inorder Traversal.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | # Left -> Root -> Right 9 | class Solution: 10 | def inorderTraversal(self, root: TreeNode) -> List[int]: 11 | x = [] 12 | self.solver(root, x) 13 | return x 14 | 15 | def solver(self, root, x): 16 | if root: 17 | self.solver(root.left, x) 18 | x.append(root.val) 19 | self.solver(root.right, x) 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/동적계획법(Dynamic Programming)/Level_3_N으로 표현.py: -------------------------------------------------------------------------------- 1 | def solution(N, number): 2 | num_set = [] 3 | 4 | 5 | num_set.append([N]) 6 | for i in range(2, 9) : 7 | lst = [int(str(N)*i)] 8 | 9 | max_num = int(i / 2) 10 | 11 | for X_index in range(0, max_num) : 12 | Y_index = i - X_index - 2 13 | 14 | X = num_set[X_index] 15 | Y = num_set[Y_index] 16 | 17 | for x in X : 18 | for y in Y : 19 | lst.append(x + y) 20 | lst.append(x - y) 21 | lst.append(y - x) 22 | lst.append(x * y) 23 | 24 | if x != 0 : 25 | lst.append(int(y / x)) 26 | if y != 0 : 27 | lst.append(int(x / y)) 28 | 29 | if number in set(lst) : 30 | return i 31 | 32 | num_set.append(lst) 33 | 34 | return -1 35 | 36 | 37 | N = 5 38 | number = 12 39 | 40 | x = solution(N, number) 41 | print(x) -------------------------------------------------------------------------------- /src/동적계획법(Dynamic Programming)/Level_3_정수 삼각형.py: -------------------------------------------------------------------------------- 1 | def solution(triangle): 2 | for i in range(1, len(triangle)): 3 | for j in range(i+1): 4 | if j == 0: 5 | triangle[i][j] += triangle[i-1][j] 6 | elif j == i: 7 | triangle[i][j] += triangle[i-1][j-1] 8 | else: 9 | triangle[i][j] += max(triangle[i-1][j], triangle[i-1][j-1]) 10 | 11 | return max(triangle[-1]) 12 | 13 | triangle = [[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] 14 | 15 | x = solution(triangle) 16 | print(x) -------------------------------------------------------------------------------- /src/동적계획법(Dynamic Programming)/Level_3_타일 장식물.py: -------------------------------------------------------------------------------- 1 | def solution(N): 2 | 3 | x = [1, 1] 4 | 5 | for i in range(2, N): 6 | x.append(x[i - 1] + x[i - 2]) 7 | 8 | answer = ((x[N-1] + x[N-2]) + (x[N-2] + x[N-3])) * 2 9 | 10 | return answer 11 | 12 | x = solution(6) 13 | print(x) -------------------------------------------------------------------------------- /src/동적계획법(Dynamic Programming)/README.md: -------------------------------------------------------------------------------- 1 | # 동적계획법 2 | * [Level 3 N으로 표현](#Level-3-N으로-표현) 3 | * [Level 3 타일 장식물](#Level-3-타일-장식물) 4 | * [Level 3 정수 삼각형](#Level-3-정수-삼각형) 5 | 6 | --- 7 | 8 | ## Level 3 N으로 표현 9 | ``` 10 | 아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다. 11 | 12 | 12 = 5 + 5 + (5 / 5) + (5 / 5) 13 | 12 = 55 / 5 + 5 / 5 14 | 12 = (55 + 5) / 5 15 | 16 | 5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다. 17 | 18 | 이처럼 숫자 N과 number가 주어질 때, 19 | N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요. 20 | ``` 21 | 22 | ### 제한사항 23 | * N은 1 이상 9 이하입니다. 24 | * number는 1 이상 32,000 이하입니다. 25 | * 수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다. 26 | * 최솟값이 8보다 크면 -1을 return 합니다. 27 | 28 | ### 입출력 예 29 | N | number | return | 30 | :---: | :---: | :---: | 31 | 5 | 12 | 4 32 | 2 | 11 | 3 33 | 34 | ### 입출력 예 설명 35 | * 예제 1 36 | * 문제에 나온 예와 같습니다. 37 | * 예제 2 38 | * `11 = 22 / 2`와 같이 2를 3번만 사용하여 표현할 수 있습니다. 39 | 40 | ### [Code](https://github.com/taki0112/coding_interview/blob/master/src/동적계획법(Dynamic%20Programming)/Level_3_N으로%20표현.py) / [위로](#동적계획법) 41 | 42 | --- 43 | 44 | ## Level 3 타일 장식물 45 | ``` 46 | 대구 달성공원에 놀러 온 지수는 최근에 새로 만든 타일 장식물을 보게 되었다. 47 | 타일 장식물은 정사각형 타일을 붙여 만든 형태였는데, 48 | 한 변이 1인 정사각형 타일부터 시작하여 마치 앵무조개의 나선 모양처럼 점점 큰 타일을 붙인 형태였다. 49 | 타일 장식물의 일부를 그리면 다음과 같다. 50 | ``` 51 | 52 | ![img](https://grepp-programmers.s3.amazonaws.com/files/production/3e31bedd54/fcc48066-e72f-45c8-af03-e4360b58b589.png) 53 | 54 | ``` 55 | 그림에서 타일에 적힌 수는 각 타일의 한 변의 길이를 나타낸다. 56 | 타일 장식물을 구성하는 정사각형 타일 한 변의 길이를 안쪽 타일부터 시작하여 차례로 적으면 다음과 같다. 57 | [1, 1, 2, 3, 5, 8, .] 58 | 지수는 문득 이러한 타일들로 구성되는 큰 직사각형의 둘레가 궁금해졌다. 59 | 예를 들어, 처음 다섯 개의 타일이 구성하는 직사각형(위에서 빨간색으로 표시한 직사각형)의 둘레는 26이다. 60 | 61 | 타일의 개수 N이 주어질 때, N개의 타일로 구성된 직사각형의 둘레를 return 하도록 solution 함수를 작성하시오. 62 | ``` 63 | 64 | ### 제한 사항 65 | * N은 1 이상 80 이하인 자연수이다. 66 | 67 | ### 입출력 예 68 | N | return | 69 | :---: | :---: | 70 | 5 | 26 71 | 6 | 42 72 | 73 | ### [Code](https://github.com/taki0112/coding_interview/blob/master/src/동적계획법(Dynamic%20Programming)/Level_3_타일%20장식물.py) / [위로](#동적계획법) 74 | 75 | --- 76 | 77 | ## Level 3 정수 삼각형 78 | ![img](https://grepp-programmers.s3.amazonaws.com/files/production/97ec02cc39/296a0863-a418-431d-9e8c-e57f7a9722ac.png) 79 | 80 | ``` 81 | 위와 같은 삼각형의 꼭대기에서 바닥까지 이어지는 경로 중, 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 합니다. 82 | 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능합니다. 83 | 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능합니다. 84 | 85 | 삼각형의 정보가 담긴 배열 triangle이 매개변수로 주어질 때, 86 | 거쳐간 숫자의 최댓값을 return 하도록 solution 함수를 완성하세요. 87 | ``` 88 | 89 | ### 제한사항 90 | * 삼각형의 높이는 1 이상 500 이하입니다. 91 | * 삼각형을 이루고 있는 숫자는 0 이상 9,999 이하의 정수입니다. 92 | 93 | ### triangle 입출력 예 94 | N | return | 95 | :---: | :---: | 96 | [[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] | 30 97 | 98 | ### [Code](https://github.com/taki0112/coding_interview/blob/master/src/동적계획법(Dynamic%20Programming)/Level_3_정수%20삼각형.py) / [위로](#동적계획법) 99 | 100 | --- 101 | -------------------------------------------------------------------------------- /src/스택_큐/Level_2_기능개발.py: -------------------------------------------------------------------------------- 1 | from math import ceil 2 | 3 | def solution(progresses, speeds): 4 | answer = [] 5 | 6 | max_time = ceil((100 - progresses[0]) / speeds[0]) 7 | n = 1 8 | 9 | for i in range(1, len(progresses)) : 10 | time = ceil((100 - progresses[i]) / speeds[i]) 11 | 12 | if max_time < time : 13 | answer.append(n) 14 | 15 | n = 1 16 | max_time = time 17 | else : 18 | n += 1 19 | 20 | answer.append(n) 21 | 22 | return answer 23 | 24 | 25 | progresses = [93,30,55] 26 | speeds = [1,30,5] 27 | 28 | x = solution(progresses, speeds) 29 | print(x) -------------------------------------------------------------------------------- /src/스택_큐/Level_2_다리를 지나는 트럭.py: -------------------------------------------------------------------------------- 1 | def solution(bridge_length, weight, truck_weights): 2 | q = [0]*bridge_length 3 | answer = 0 4 | while q: 5 | answer += 1 # 시작했으므로 1초씩 더함 6 | q.pop(0) # 트럭이 지나감 7 | if truck_weights: 8 | if sum(q) + truck_weights[0] <= weight: # 다리에 있는 트럭의 무게와 대기 중인 트럭의 무게가 제한 무게보다 작거나 같다면 9 | q.append(truck_weights.pop(0)) # 다리에 트럭 올림 10 | else: 11 | q.append(0) # 중량 초과면 트럭 안올림 12 | return answer 13 | 14 | 15 | bridge_length = 2 16 | weight = 10 17 | truck_weights = [7, 4, 5, 6] 18 | 19 | x = solution(bridge_length, weight, truck_weights) 20 | print(x) -------------------------------------------------------------------------------- /src/스택_큐/Level_2_쇠막대기.py: -------------------------------------------------------------------------------- 1 | def solution(arrangement): 2 | answer = 0 3 | left_bracket = [] 4 | before = '' 5 | for bracket in arrangement : 6 | 7 | if bracket is '(' : 8 | left_bracket.append(bracket) 9 | else : 10 | left_bracket.pop(-1) 11 | 12 | if before is '(' : 13 | answer += len(left_bracket) 14 | else : 15 | answer += 1 16 | before = bracket 17 | return answer 18 | 19 | arrangement = "(((()(()()))(())()))(()())" 20 | x = solution(arrangement) 21 | print(x) -------------------------------------------------------------------------------- /src/스택_큐/Level_2_주식가격.py: -------------------------------------------------------------------------------- 1 | def solution(prices): 2 | answer = [] 3 | 4 | for i in range(len(prices) - 1) : 5 | for j in range(i+1, len(prices)) : 6 | if prices[i] > prices[j] : 7 | answer.append(j - i) 8 | break 9 | else : 10 | answer.append(len(prices) - 1 - i) 11 | else : 12 | answer.append(0) 13 | return answer 14 | 15 | prices = [498,501,470,489] 16 | x = solution(prices) 17 | print(x) -------------------------------------------------------------------------------- /src/스택_큐/Level_2_탑.py: -------------------------------------------------------------------------------- 1 | def solution(heights): 2 | answer = [0]*len(heights) 3 | 4 | for x in range(len(heights)-1, 0, -1): 5 | for y in range(x-1, -1, -1): 6 | if heights[x] < heights[y]: 7 | answer[x] = y+1 8 | break 9 | return answer 10 | 11 | 12 | heights = [1,5,3,6,7,6,5] 13 | x = solution(heights) 14 | print(x) -------------------------------------------------------------------------------- /src/스택_큐/Level_2_프린터.py: -------------------------------------------------------------------------------- 1 | def solution(priorities, location): 2 | answer = 0 3 | search, c = sorted(priorities, reverse=True), 0 4 | while True: 5 | for i, priority in enumerate(priorities): 6 | s = search[c] 7 | if priority == s: 8 | c += 1 9 | answer += 1 10 | if i == location: 11 | break 12 | else: 13 | continue 14 | break 15 | 16 | return answer 17 | 18 | priorities = [1, 1, 9, 1, 1, 1] 19 | location = 0 20 | 21 | x = solution(priorities, location) 22 | print(x) 23 | -------------------------------------------------------------------------------- /src/스택_큐/README.md: -------------------------------------------------------------------------------- 1 | # 스택_큐 2 | * [Level 2 쇠막대기](#Level-2-쇠막대기) 3 | * [Level 2 프린터](#Level-2-프린터) 4 | * [Level 2 다리를 지나는 트럭](#Level-2-다리를-지나는-트럭) 5 | * [Level 2 기능개발](#Level-2-기능개발) 6 | * [Level 2 탑](#Level-2-탑) 7 | * [Level 2 주식가격](#Level-2-주식가격) 8 | 9 | --- 10 | 11 | ## Level 2 쇠막대기 12 | ``` 13 | 여러 개의 쇠막대기를 레이저로 절단하려고 합니다. 14 | 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자릅니다. 15 | 쇠막대기와 레이저의 배치는 다음 조건을 만족합니다. 16 | 17 | - 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있습니다. 18 | - 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓습니다. 19 | - 각 쇠막대기를 자르는 레이저는 적어도 하나 존재합니다. 20 | - 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않습니다. 21 | 22 | 아래 그림은 위 조건을 만족하는 예를 보여줍니다. 23 | 수평으로 그려진 굵은 실선은 쇠막대기이고, 점은 레이저의 위치, 수직으로 그려진 점선 화살표는 레이저의 발사 방향입니다. 24 | ``` 25 | ![img_1](https://grepp-programmers.s3.amazonaws.com/files/ybm/dbd166625b/d3ae656b-bb7b-421c-9f74-fa9ea800b860.png) 26 | ``` 27 | 이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있습니다. 28 | 29 | (a) 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 '()'으로 표현합니다. 또한 모든 '()'는 반드시 레이저를 표현합니다. 30 | (b) 쇠막대기의 왼쪽 끝은 여는 괄호 '('로, 오른쪽 끝은 닫힌 괄호 ')'로 표현됩니다. 31 | 32 | 위 예의 괄호 표현은 그림 위에 주어져 있습니다. 33 | 쇠막대기는 레이저에 의해 몇 개의 조각으로 잘리는데, 34 | 위 예에서 가장 위에 있는 두 개의 쇠막대기는 각각 3개와 2개의 조각으로 잘리고, 35 | 이와 같은 방식으로 주어진 쇠막대기들은 총 17개의 조각으로 잘립니다. 36 | 37 | 쇠막대기와 레이저의 배치를 표현한 문자열 arrangement가 매개변수로 주어질 때, 38 | 잘린 쇠막대기 조각의 총 개수를 return 하도록 solution 함수를 작성해주세요. 39 | ``` 40 | 41 | ### 제한사항 42 | * arrangement의 길이는 최대 100,000입니다. 43 | * arrangement의 여는 괄호와 닫는 괄호는 항상 쌍을 이룹니다. 44 | 45 | ### 입출력 예 46 | arrangement | return | 47 | :---: | :---: | 48 | "()(((()())(())()))(())" | 17 49 | 50 | ### 입출력 예 설명 51 | 문제에 나온 예와 같습니다. 52 | 53 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%EC%87%A0%EB%A7%89%EB%8C%80%EA%B8%B0.py) / [위로](#스택_큐) 54 | 55 | --- 56 | 57 | ## Level 2 프린터 58 | 59 | ``` 60 | 일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 61 | 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 62 | 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다. 63 | 64 | 1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다. 65 | 2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다. 66 | 3. 그렇지 않으면 J를 인쇄합니다. 67 | 68 | 예를 들어, 4개의 문서(A, B, C, D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다. 69 | 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다. 70 | 71 | 현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와, 72 | 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 73 | 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요. 74 | ``` 75 | ### 제한사항 76 | * 현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다. 77 | * 인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다. 78 | * location은 0 이상 (현재 대기목록에 있는 작업 수 - 1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다. 79 | 80 | ### 입출력 예 81 | priorities | location | return | 82 | :---: | :---: | :---: | 83 | [2, 1, 3, 2] | 2 | 1 84 | [1, 1, 9, 1, 1, 1] | 0 | 5 85 | 86 | ### 입출력 예 설명 87 | * 예제 1 88 | * 문제에 나온 예와 같습니다. 89 | 90 | * 예제 2 91 | * 6개의 문서(A, B, C, D, E, F)가 인쇄 대기목록에 있고 중요도가 1 1 9 1 1 1 이므로 C D E F A B 순으로 인쇄합니다. 92 | 93 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%ED%94%84%EB%A6%B0%ED%84%B0.py) / [위로](#스택_큐) 94 | 95 | --- 96 | ## Level 2 쇠막대기 97 | ``` 98 | 여러 개의 쇠막대기를 레이저로 절단하려고 합니다. 99 | 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자릅니다. 100 | 쇠막대기와 레이저의 배치는 다음 조건을 만족합니다. 101 | 102 | - 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있습니다. 103 | - 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓습니다. 104 | - 각 쇠막대기를 자르는 레이저는 적어도 하나 존재합니다. 105 | - 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않습니다. 106 | 107 | 아래 그림은 위 조건을 만족하는 예를 보여줍니다. 108 | 수평으로 그려진 굵은 실선은 쇠막대기이고, 점은 레이저의 위치, 수직으로 그려진 점선 화살표는 레이저의 발사 방향입니다. 109 | ``` 110 | ![img_1](https://grepp-programmers.s3.amazonaws.com/files/ybm/dbd166625b/d3ae656b-bb7b-421c-9f74-fa9ea800b860.png) 111 | ``` 112 | 이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있습니다. 113 | 114 | (a) 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 '()'으로 표현합니다. 또한 모든 '()'는 반드시 레이저를 표현합니다. 115 | (b) 쇠막대기의 왼쪽 끝은 여는 괄호 '('로, 오른쪽 끝은 닫힌 괄호 ')'로 표현됩니다. 116 | 117 | 위 예의 괄호 표현은 그림 위에 주어져 있습니다. 118 | 쇠막대기는 레이저에 의해 몇 개의 조각으로 잘리는데, 119 | 위 예에서 가장 위에 있는 두 개의 쇠막대기는 각각 3개와 2개의 조각으로 잘리고, 120 | 이와 같은 방식으로 주어진 쇠막대기들은 총 17개의 조각으로 잘립니다. 121 | 122 | 쇠막대기와 레이저의 배치를 표현한 문자열 arrangement가 매개변수로 주어질 때, 123 | 잘린 쇠막대기 조각의 총 개수를 return 하도록 solution 함수를 작성해주세요. 124 | ``` 125 | 126 | ### 제한사항 127 | * arrangement의 길이는 최대 100,000입니다. 128 | * arrangement의 여는 괄호와 닫는 괄호는 항상 쌍을 이룹니다. 129 | 130 | ### 입출력 예 131 | arrangement | return | 132 | :---: | :---: | 133 | "()(((()())(())()))(())" | 17 134 | 135 | ### 입출력 예 설명 136 | 문제에 나온 예와 같습니다. 137 | 138 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%EC%87%A0%EB%A7%89%EB%8C%80%EA%B8%B0.py) / [위로](#스택_큐) 139 | 140 | --- 141 | 142 | ## Level 2 다리를 지나는 트럭 143 | 144 | ``` 145 | 트럭 여러 대가 강을 가로지르는 일 차선 다리를 정해진 순으로 건너려 합니다. 146 | 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 147 | 트럭은 1초에 1만큼 움직이며, 다리 길이는 bridge_length이고 다리는 무게 weight까지 견딥니다. 148 | ※ 트럭이 다리에 완전히 오르지 않은 경우, 이 트럭의 무게는 고려하지 않습니다. 149 | 150 | 예를 들어, 길이가 2대까지, 무게 10kg까지 견디는 다리가 있습니다. 151 | 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다. 152 | ``` 153 | 경과 시간 | 다리를 지난 트럭 | 다리를 건너는 트럭 | 대기 트럭 154 | :---: | :---: | :---: | :---: | 155 | 0 | [] | [] | [7,4,5,6] 156 | 1~2 | [] | [7] | [4,5,6] 157 | 3 | [7] | [4] | [5,6] 158 | 4 | [7] | [4,5] | [6] 159 | 5 | [7,4] | [5] | [6] 160 | 6~7 | [7,4,5] | [6] | [] 161 | 8 | [7,4,5,6] | [] | [] 162 | 163 | ``` 164 | 따라서, 모든 트럭이 다리를 지나려면 최소 8초가 걸립니다. 165 | 166 | solution 함수의 매개변수로 다리 길이 bridge_length, 다리가 견딜 수 있는 무게 weight, 트럭별 무게 truck_weights가 주어집니다. 167 | 이때 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 return 하도록 solution 함수를 완성하세요. 168 | ``` 169 | ### 제한 조건 170 | * bridge_length는 1 이상 10,000 이하입니다. 171 | * weight는 1 이상 10,000 이하입니다. 172 | * truck_weights의 길이는 1 이상 10,000 이하입니다. 173 | * 모든 트럭의 무게는 1 이상 weight 이하입니다. 174 | 175 | ### 입출력 예 176 | bridge_length | weight | truck_weights | return 177 | :---: | :---: | :---: | :---: | 178 | 2 | 10 | [7,4,5,6] | 8 179 | 100 | 100 | [10] | 101 180 | 100 | 100 | [10,10,10,10,10,10,10,10,10,10] | 110 181 | 182 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%EB%8B%A4%EB%A6%AC%EB%A5%BC%20%EC%A7%80%EB%82%98%EB%8A%94%20%ED%8A%B8%EB%9F%AD.py) / [위로](#스택_큐) 183 | 184 | --- 185 | 186 | ## Level 2 기능개발 187 | ``` 188 | 프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 189 | 190 | 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 191 | 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다. 192 | 193 | 먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 194 | 각 작업의 개발 속도가 적힌 정수 배열 speeds가 195 | 주어질 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요. 196 | ``` 197 | 198 | ### 제한 사항 199 | * 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다. 200 | * 작업 진도는 100 미만의 자연수입니다. 201 | * 작업 속도는 100 이하의 자연수입니다. 202 | * 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다. 203 | 204 | ### 입출력 예 205 | progresses | speeds | return | 206 | :---: | :---: | :---: | 207 | [93,30,55] | [1,30,5] | [2,1] 208 | 209 | ### 입출력 예 설명 210 | * 첫 번째 기능은 93% 완료되어 있고 하루에 1%씩 작업이 가능하므로 7일간 작업 후 배포가 가능합니다. 211 | * 두 번째 기능은 30%가 완료되어 있고 하루에 30%씩 작업이 가능하므로 3일간 작업 후 배포가 가능합니다. 212 | * 하지만 이전 첫 번째 기능이 아직 완성된 상태가 아니기 때문에 첫 번째 기능이 배포되는 7일째 배포됩니다. 213 | * 세 번째 기능은 55%가 완료되어 있고 하루에 5%씩 작업이 가능하므로 9일간 작업 후 배포가 가능합니다. 214 | * 따라서 7일째에 2개의 기능, 9일째에 1개의 기능이 배포됩니다. 215 | 216 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%EA%B8%B0%EB%8A%A5%EA%B0%9C%EB%B0%9C.py) / [위로](#스택_큐) 217 | 218 | --- 219 | ## Level 2 탑 220 | ``` 221 | 수평 직선에 높이가 서로 다른 탑 N대를 세웠습니다. 222 | 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다. 223 | 발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한, 한 번 수신된 신호는 다른 탑으로 송신되지 않습니다. 224 | 225 | 예를 들어 높이가 6, 9, 5, 7, 4인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 226 | 그러면, 탑은 다음과 같이 신호를 주고받습니다. 227 | 높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑이 수신하고, 228 | 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이, 229 | 높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신합니다. 230 | 높이가 9인 두 번째 탑과 높이가 6인 첫 번째 탑이 보낸 레이저 신호는 어떤 탑에서도 수신할 수 없습니다. 231 | 232 | 맨 왼쪽부터 순서대로 탑의 높이를 담은 배열 heights가 매개변수로 주어질 때 233 | 각 탑이 쏜 신호를 어느 탑에서 받았는지 기록한 배열을 return 하도록 solution 함수를 작성해주세요. 234 | 235 | ``` 236 | 237 | ### 제한 사항 238 | * heights는 길이 2 이상 100 이하인 정수 배열입니다. 239 | * 모든 탑의 높이는 1 이상 100 이하입니다. 240 | * 신호를 수신하는 탑이 없으면 0으로 표시합니다. 241 | 242 | ### 입출력 예 243 | heights | return | 244 | :---: | :---: | 245 | [6,9,5,7,4] | [0,0,2,2,4] 246 | [3,9,9,3,5,7,2] | [0,0,0,3,3,3,6] 247 | [1,5,3,6,7,6,5] | [0,0,2,0,0,5,6] 248 | 249 | ### 입출력 예 설명 250 | * 입출력 예 1 251 | * 앞서 설명한 예와 같습니다. 252 | 253 | * 입출력 예 2 254 | * [1,2,3] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다. 255 | * [4,5,6] 번째 탑이 쏜 신호는 3번째 탑이 수신합니다. 256 | * [7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다. 257 | 258 | * 입출력 예 3 259 | * [1,2,4,5] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다. 260 | * [3] 번째 탑이 쏜 신호는 2번째 탑이 수신합니다. 261 | * [6] 번째 탑이 쏜 신호는 5번째 탑이 수신합니다. 262 | * [7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다. 263 | 264 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%ED%83%91.py) / [위로](#스택_큐) 265 | 266 | --- 267 | 268 | ## Level 2 주식가격 269 | ``` 270 | 초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 271 | 가격이 유지된 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요. 272 | ``` 273 | 274 | ### 제한사항 275 | * prices의 각 가격은 1 이상 10,000 이하인 자연수입니다. 276 | * prices의 길이는 2 이상 100,000 이하입니다. 277 | 278 | ### 입출력 예 279 | prices | return | 280 | :---: | :---: | 281 | [498,501,470,489] | [2,1,1,0] 282 | 283 | ### 입출력 예 설명 284 | * 1초 시점의 ₩498은 2초간 가격을 유지하고, 3초 시점에 ₩470으로 떨어졌습니다. 285 | * 2초 시점의 ₩501은 1초간 가격을 유지하고, 3초 시점에 ₩470으로 떨어졌습니다. 286 | * 3초 시점의 ₩470은 최종 시점까지 총 1초간 가격이 떨어지지 않았습니다. 287 | * 4초 시점의 ₩489은 최종 시점까지 총 0초간 가격이 떨어지지 않았습니다. 288 | 289 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%8A%A4%ED%83%9D_%ED%81%90/Level_2_%EC%A3%BC%EC%8B%9D%EA%B0%80%EA%B2%A9.py) / [위로](#스택_큐) 290 | -------------------------------------------------------------------------------- /src/완전탐색/Level_1_모의고사.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | def solution(answers): 4 | answer = [] 5 | one = [1, 2, 3, 4, 5] 6 | two = [2, 1, 2, 3, 2, 4, 2, 5] 7 | three = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5] 8 | 9 | x = defaultdict(int) 10 | 11 | max_score = 0 12 | for i in range(len(answers)) : 13 | ans = answers[i] 14 | one_ans = one[i % len(one)] 15 | two_ans = two[i % len(two)] 16 | three_ans = three[i % len(three)] 17 | 18 | if ans == one_ans : 19 | x[1] += 1 20 | 21 | if max_score < x[1] : 22 | max_score = x[1] 23 | 24 | if ans == two_ans : 25 | x[2] += 1 26 | 27 | if max_score < x[2] : 28 | max_score = x[2] 29 | 30 | if ans == three_ans : 31 | x[3] += 1 32 | 33 | if max_score < x[3] : 34 | max_score = x[3] 35 | 36 | 37 | for key, value in x.items() : 38 | if max_score == value : 39 | answer.append(key) 40 | 41 | answer.sort() 42 | 43 | return answer 44 | 45 | answers = [1, 3, 2, 4, 2] 46 | 47 | x = solution(answers) 48 | print(x) -------------------------------------------------------------------------------- /src/완전탐색/Level_2_소수찾기.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | def solution(numbers): 4 | answer = 0 5 | candidates, num_set = [], set() 6 | digits = [digit for digit in numbers] 7 | 8 | for i in range(1, len(numbers)+1): 9 | candidates += [*list(permutations(digits, i))] 10 | 11 | for candidate in candidates: 12 | num_set.add(int(''.join(map(str, candidate)))) 13 | 14 | for num in num_set: 15 | if is_prime(num): 16 | answer += 1 17 | 18 | return answer 19 | 20 | def is_prime(number): 21 | if number == 0 or number == 1: 22 | return False 23 | 24 | for i in range(2, number//2 + 1): 25 | if (number/i) == (number//i): 26 | return False 27 | 28 | return True 29 | 30 | numbers = "011" 31 | x = solution(numbers) 32 | print(x) -------------------------------------------------------------------------------- /src/완전탐색/Level_2_숫자야구.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | def get_strike_ball(number, candidate_number): 4 | strike = 0 5 | ball = 0 6 | 7 | number_difference = [] 8 | candidate_difference = [] 9 | 10 | for i in range(3): 11 | if number[i] == candidate_number[i]: 12 | strike += 1 13 | else: 14 | number_difference.append(number[i]) 15 | candidate_difference.append(candidate_number[i]) 16 | 17 | for num in candidate_difference: 18 | if num in number_difference: 19 | ball += 1 20 | 21 | return strike, ball 22 | 23 | 24 | def solution(baseball): 25 | candidate = list(permutations([1, 2, 3, 4, 5, 6, 7, 8, 9], 3)) 26 | 27 | x = [] 28 | 29 | for example in baseball: 30 | 31 | number = [int(i) for i in str(example[0])] 32 | strike_ball = (example[1], example[2]) 33 | 34 | for candidate_number in candidate: 35 | if get_strike_ball(number, candidate_number) == strike_ball: 36 | x.append(candidate_number) 37 | 38 | candidate = x 39 | x = [] 40 | 41 | return len(candidate) 42 | 43 | baseball = [[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] 44 | 45 | x = solution(baseball) 46 | print(x) -------------------------------------------------------------------------------- /src/완전탐색/Level_2_카펫.py: -------------------------------------------------------------------------------- 1 | def solution(brown, red): 2 | size = brown + red 3 | answer = [] 4 | 5 | x = [] 6 | 7 | for n in range(1, size+1) : 8 | if size % n == 0 : 9 | if n >= size // n : 10 | x.append([n, size // n]) 11 | 12 | 13 | for candidate in x : 14 | height, width = candidate[0], candidate[1] 15 | 16 | if (height - 2) * (width - 2) == red and (height + width)*2 - 4 == brown : 17 | answer = [height, width] 18 | 19 | return answer 20 | 21 | brown = 24 22 | red = 24 23 | 24 | x = solution(brown, red) 25 | print(x) -------------------------------------------------------------------------------- /src/완전탐색/README.md: -------------------------------------------------------------------------------- 1 | # 완전탐색 2 | * [Level 1 모의고사](#Level-1-모의고사) 3 | * [Level 2 소수찾기](#Level-2-소수찾기) 4 | * [Level 2 숫자야구](#Level-2-숫자야구) 5 | * [Level 2 카펫](#Level-2-카펫) 6 | 7 | --- 8 | ## Level 1 모의고사 9 | ``` 10 | 수포자는 수학을 포기한 사람의 준말입니다. 11 | 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 12 | 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다. 13 | 14 | 1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ... 15 | 2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ... 16 | 3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ... 17 | 18 | 1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 19 | 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요. 20 | ``` 21 | 22 | ### 제한 조건 23 | * 시험은 최대 10,000 문제로 구성되어있습니다. 24 | * 문제의 정답은 1, 2, 3, 4, 5중 하나입니다. 25 | * 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요. 26 | 27 | ### 입출력 예 28 | answers | return | 29 | :---: | :---: | 30 | [1,2,3,4,5] | [1] 31 | [1,3,2,4,2] | [1,2,3] 32 | 33 | ### 입출력 예 설명 34 | * 입출력 예 1 35 | * 수포자 1은 모든 문제를 맞혔습니다. 36 | * 수포자 2는 모든 문제를 틀렸습니다. 37 | * 수포자 3은 모든 문제를 틀렸습니다. 38 | * 따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다. 39 | 40 | * 입출력 예 2 41 | * 수포자 1은 [1, 4]번 문제를 맞혔습니다. 42 | * 수포자 2는 다섯 번째 문제를 맞혔습니다. 43 | 44 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%99%84%EC%A0%84%ED%83%90%EC%83%89/Level_1_%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC.py) / [위로](#완전탐색) 45 | 46 | --- 47 | 48 | ## Level 2 소수찾기 49 | ``` 50 | 한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 51 | 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 52 | 53 | 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 54 | 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요. 55 | ``` 56 | 57 | ### 제한사항 58 | * numbers는 길이 1 이상 7 이하인 문자열입니다. 59 | * numbers는 0~9까지 숫자만으로 이루어져 있습니다. 60 | * 013은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다. 61 | 62 | ### 입출력 예 63 | answers | return | 64 | :---: | :---: | 65 | "17" | 3 66 | "011" | 2 67 | 68 | ### 입출력 예 설명 69 | * 예제 1 70 | * [1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다. 71 | 72 | * 예제 2 73 | * [0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다. 74 | * 11과 011은 같은 숫자로 취급합니다. 75 | 76 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%99%84%EC%A0%84%ED%83%90%EC%83%89/Level_2_%EC%86%8C%EC%88%98%EC%B0%BE%EA%B8%B0.py) / [위로](#완전탐색) 77 | 78 | --- 79 | 80 | ## Level 2 숫자야구 81 | ``` 82 | 숫자 야구 게임이란 2명이 서로가 생각한 숫자를 맞추는 게임입니다. 83 | 84 | 각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다. 85 | 그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다. 86 | 87 | * 숫자는 맞지만, 위치가 틀렸을 때는 볼 88 | * 숫자와 위치가 모두 맞을 때는 스트라이크 89 | * 숫자와 위치가 모두 틀렸을 때는 아웃 90 | 91 | 예를 들어, 아래의 경우가 있으면 92 | 93 | A : 123 94 | B : 1스트라이크 1볼. 95 | A : 356 96 | B : 1스트라이크 0볼. 97 | A : 327 98 | B : 2스트라이크 0볼. 99 | A : 489 100 | B : 0스트라이크 1볼. 101 | 102 | 이때 가능한 답은 324와 328 두 가지입니다. 103 | 104 | 질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때, 105 | 가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요. 106 | 107 | ``` 108 | 109 | ### 제한사항 110 | * 질문의 수는 1 이상 100 이하의 자연수입니다. 111 | * baseball의 각 행은 [세 자리의 수, 스트라이크의 수, 볼의 수] 를 담고 있습니다. 112 | 113 | ### 입출력 예 114 | baseball | return | 115 | :---: | :---: | 116 | [[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] | 2 117 | 118 | ### 입출력 예 설명 119 | * 문제에 나온 예와 같습니다. 120 | 121 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%99%84%EC%A0%84%ED%83%90%EC%83%89/Level_2_%EC%88%AB%EC%9E%90%EC%95%BC%EA%B5%AC.py) / [위로](#완전탐색) 122 | 123 | --- 124 | 125 | ## Level 2 카펫 126 | ``` 127 | Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 빨간색으로 칠해져 있고 모서리는 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다. 128 | ``` 129 | 130 | ![image](https://grepp-programmers.s3.amazonaws.com/files/ybm/7c94563a35/2ff27ac9-97d0-43a9-9cf8-a344b8e7912e.png) 131 | 132 | ``` 133 | Leo는 집으로 돌아와서 아까 본 카펫의 빨간색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다. 134 | 135 | Leo가 본 카펫에서 갈색 격자의 수 brown, 빨간색 격자의 수 red가 매개변수로 주어질 때 136 | 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요. 137 | ``` 138 | 139 | ### 제한사항 140 | * 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다. 141 | * 빨간색 격자의 수 red는 1 이상 2,000,000 이하인 자연수입니다. 142 | * 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다. 143 | 144 | ### 입출력 예 145 | brown | red | return | 146 | :---: | :---: | :---: | 147 | 10 | 2 | [4, 3] 148 | 8 | 1 | [3, 3] 149 | 24 | 24 | [8, 6] 150 | 151 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%99%84%EC%A0%84%ED%83%90%EC%83%89/Level_2_%EC%B9%B4%ED%8E%AB.py) / [위로](#완전탐색) 152 | -------------------------------------------------------------------------------- /src/정렬/Level_1_k번째 수.py: -------------------------------------------------------------------------------- 1 | def solution(array, commands): 2 | answer = [] 3 | for command in commands : 4 | start_index = command[0] - 1 5 | end_index = command[1] 6 | find_index = command[2] - 1 7 | 8 | x = array[start_index : end_index] 9 | x.sort() 10 | answer.append(x[find_index]) 11 | return answer 12 | 13 | array = [1, 5, 2, 6, 3, 7, 4] 14 | commands = [[2, 5, 3], [4, 4, 1], [1, 7, 3]] 15 | 16 | x = solution(array, commands) 17 | print(x) -------------------------------------------------------------------------------- /src/정렬/Level_2_H-Index.py: -------------------------------------------------------------------------------- 1 | def solution(citations): 2 | citations.sort(reverse=True) 3 | 4 | for i in range(len(citations)) : 5 | if citations[i] < i+1 : 6 | return i 7 | else : 8 | return len(citations) 9 | 10 | citations = [3, 0, 6, 1, 5] 11 | x = solution(citations) 12 | 13 | print(x) -------------------------------------------------------------------------------- /src/정렬/Level_2_가장 큰 수.py: -------------------------------------------------------------------------------- 1 | 2 | def solution(numbers): 3 | numbers = list(map(str, numbers)) 4 | max_len = max([len(x) for x in numbers]) 5 | numbers.sort(key=lambda x: x*max_len, reverse=True) 6 | return str(int(''.join(numbers))) 7 | 8 | 9 | numbers = [9, 95, 9, 82, 9, 813] 10 | x = solution(numbers) 11 | 12 | print(x) -------------------------------------------------------------------------------- /src/정렬/README.md: -------------------------------------------------------------------------------- 1 | # 정렬 2 | * [Level 1 k번째 수](#Level-1-k번째-수) 3 | * [Level 2 가장 큰 수](#Level-2-가장-큰-수) 4 | * [Level 2 H-Index](#Level-2-H-Index) 5 | 6 | --- 7 | 8 | ## Level 1 k번째 수 9 | ``` 10 | 배열 array의 i번째 숫자부터 j번째 숫자까지 자르고 정렬했을 때, k번째에 있는 수를 구하려 합니다. 11 | 12 | 예를 들어 array가 [1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면 13 | 14 | 1. array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]입니다. 15 | 2. 1에서 나온 배열을 정렬하면 [2, 3, 5, 6]입니다. 16 | 3. 2에서 나온 배열의 3번째 숫자는 5입니다. 17 | 18 | 배열 array, [i, j, k]를 원소로 가진 2차원 배열 commands가 매개변수로 주어질 때, 19 | commands의 모든 원소에 대해 앞서 설명한 연산을 적용했을 때 나온 결과를 배열에 담아 return 하도록 solution 함수를 작성해주세요. 20 | ``` 21 | 22 | ### 제한사항 23 | * array의 길이는 1 이상 100 이하입니다. 24 | * array의 각 원소는 1 이상 100 이하입니다. 25 | * commands의 길이는 1 이상 50 이하입니다. 26 | * commands의 각 원소는 길이가 3입니다. 27 | 28 | ### 입출력 예 29 | array | commands | return | 30 | :---: | :---: | :---: | 31 | [1, 5, 2, 6, 3, 7, 4] | [[2, 5, 3], [4, 4, 1], [1, 7, 3]] | [5, 6, 3] 32 | 33 | ### 입출력 예 설명 34 | * [1, 5, 2, 6, 3, 7, 4]를 2번째부터 5번째까지 자른 후 정렬합니다. [2, 3, 5, 6]의 세 번째 숫자는 5입니다. 35 | * [1, 5, 2, 6, 3, 7, 4]를 4번째부터 4번째까지 자른 후 정렬합니다. [6]의 첫 번째 숫자는 6입니다. 36 | * [1, 5, 2, 6, 3, 7, 4]를 1번째부터 7번째까지 자릅니다. [1, 2, 3, 4, 5, 6, 7]의 세 번째 숫자는 3입니다. 37 | 38 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%A0%95%EB%A0%AC/Level_1_k%EB%B2%88%EC%A7%B8%20%EC%88%98.py) / [위로](#정렬) 39 | 40 | --- 41 | 42 | ## Level 2 가장 큰 수 43 | ``` 44 | 0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요. 45 | 46 | 예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 47 | 이중 가장 큰 수는 6210입니다. 48 | 49 | 0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 50 | 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요. 51 | ``` 52 | 53 | ### 제한 사항 54 | * numbers의 길이는 1 이상 100,000 이하입니다. 55 | * numbers의 원소는 0 이상 1,000 이하입니다. 56 | * 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다. 57 | 58 | ### 입출력 예 59 | numbers | return | 60 | :---: | :---: | 61 | [6, 10, 2] | "6210" 62 | [3, 30, 34, 5, 9] | "9534330" 63 | 64 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%A0%95%EB%A0%AC/Level_2_%EA%B0%80%EC%9E%A5%20%ED%81%B0%20%EC%88%98.py) / [위로](#정렬) 65 | 66 | --- 67 | 68 | ## Level 2 H-Index 69 | ``` 70 | H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 71 | 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 72 | 위키백과1에 따르면, H-Index는 다음과 같이 구합니다. 73 | 74 | 어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 75 | 나머지 논문이 h번 이하 인용되었다면, h가 이 과학자의 H-Index입니다. 76 | 77 | 어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 78 | 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요. 79 | ``` 80 | 81 | ### 제한사항 82 | * 과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다. 83 | * 논문별 인용 횟수는 0회 이상 10,000회 이하입니다. 84 | 85 | ### 입출력 예 86 | citations | return 87 | :---: | :---: | 88 | [3, 0, 6, 1, 5] | 3 89 | 90 | ### 입출력 예 설명 91 | * 이 과학자가 발표한 논문의 수는 5편이고, 그중 3편의 논문은 3회 이상 인용되었습니다. 92 | * 그리고 나머지 2편의 논문은 3회 이하 인용되었기 때문에 이 과학자의 H-Index는 3입니다. 93 | 94 | 95 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%EC%A0%95%EB%A0%AC/Level_2_H-Index.py) / [위로](#정렬) 96 | -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_1_체육복.py: -------------------------------------------------------------------------------- 1 | def solution(n, lost, reserve): 2 | _reserve = [r for r in reserve if r not in lost] 3 | _lost = [l for l in lost if l not in reserve] 4 | 5 | 6 | for r in _reserve: 7 | f = r - 1 8 | b = r + 1 9 | 10 | if f in _lost: 11 | _lost.remove(f) 12 | elif b in _lost: 13 | _lost.remove(b) 14 | 15 | x = n - len(_lost) 16 | 17 | return x 18 | 19 | n = 5 20 | lost = [2, 4] 21 | reserve = [3] 22 | 23 | x = solution(n, lost, reserve) 24 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_2_구명보트.py: -------------------------------------------------------------------------------- 1 | def solution(people, limit): 2 | people.sort() 3 | num_people = len(people) 4 | 5 | light = 0 6 | heavy = num_people - 1 7 | 8 | pair = 0 9 | 10 | while light < heavy : 11 | 12 | if people[light] + people[heavy] <= limit: 13 | 14 | pair += 1 15 | light, heavy = light + 1, heavy - 1 16 | 17 | else: 18 | heavy -= 1 19 | 20 | return num_people-pair 21 | 22 | 23 | 24 | people = [70, 50, 80, 50] 25 | 26 | limit = 100 27 | 28 | x = solution(people, limit) 29 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_2_조이스틱.py: -------------------------------------------------------------------------------- 1 | def solution(name): 2 | updown = list(range(14)) + list(range(12,0,-1)) 3 | 4 | updown = {chr(65+k):v for k, v in enumerate(updown)} 5 | 6 | name = [updown[x] for x in name] 7 | 8 | right = 0 9 | left = 0 10 | 11 | for i in range(len(name)-1): 12 | if name[1+i] != 0: 13 | break 14 | right += 1 15 | 16 | for i in range(len(name)-1): 17 | if name[-i-1] != 0: 18 | break 19 | left -= 1 20 | 21 | return sum(name) + len(name) - 1 - max(left, right) 22 | 23 | name = 'JAZ' 24 | 25 | x = solution(name) 26 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_2_큰 수 만들기.py: -------------------------------------------------------------------------------- 1 | def solution(number, k): 2 | start = 0 3 | 4 | for i in range(k) : 5 | 6 | isEnd = True 7 | for j in range(start, len(number) - 1) : 8 | 9 | if number[j] < number[j + 1] : 10 | number = number[ : j] + number[j + 1 : ] 11 | isEnd = False 12 | if j > 0 : 13 | start = j - 1 14 | else : 15 | start = 0 16 | break 17 | 18 | if isEnd == True : 19 | number = number[ : -1] 20 | start = j - 1 21 | 22 | return number 23 | 24 | 25 | number = "4177252841" 26 | k = 4 27 | 28 | x = solution(number, k) 29 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_3_단속카메라.py: -------------------------------------------------------------------------------- 1 | 2 | def solution(routes): 3 | routes.sort() #진입점 기준 오름차순 정렬 4 | length = len(routes) 5 | count = 0 #실제 카메라 설치 개수 6 | cam = [0]*length #각 구간에 카메라가 커버되는지, 1이면 카메라 커버됨 7 | camera = 0 #진입점 기준으로 설치된 카메라 위치 8 | 9 | for i in range(length-1, -1, -1): #진입점이 가장 큰 구간부터 진입점이 작은 구간까지 1개씩 이동 10 | if cam[i] == 0: #카메라가 커버 못하는 구간이라면 11 | camera = routes[i][0]#현 진입점을 카메라 설치 위치로 12 | count += 1 #카메라 1개 설치 13 | for j in range(i, -1, -1): #진입점(camera) 하나를 기준으로 삼고 매 구간의 진출점(routes[j][1])과 비교 14 | if cam[j] == 0 and routes[j][1] >= camera:#카메라가 커버 못하면서 이전 진입점(camera)이 현재 진출점보다 작거나 같다면 15 | cam[j] = 1 #이전 진입점에 설치된 카메라가 현 구간을 커버함 16 | 17 | return count 18 | 19 | 20 | 21 | routes = [[-20,15], [-14,-5], [-18,-13], [-5,-3]] 22 | x = solution(routes) 23 | 24 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_3_섬 연결하기.py: -------------------------------------------------------------------------------- 1 | parent={}#각 노드의 부모 2 | rank={}#트리의 노드 수 3 | 4 | def make_set(v):#각 노드를 집합으로 만들기 5 | parent[v]=v#일단 부모는 자기 자신 6 | rank[v]=0# 7 | 8 | def findRoot(v): 9 | if parent[v]!=v:#부모가 자기 자신이 아니면 10 | parent[v]=findRoot(parent[v])#최상위의 부모로 갱신 11 | return parent[v]#부모가 자기 자신이라면 최상위이므로 반환 12 | 13 | def union(r1,r2): 14 | if r1!=r2:#루트값이 서로 다르면 다른 집합임 15 | if rank[r1]>rank[r2]:#노드 수가 적은 집합의 루트가 노드 수가 많은 집합의 루트로 변경됨 16 | parent[r2]=r1 17 | else: 18 | parent[r1]=r2 19 | if rank[r1]==rank[r2]:#집합의 개수가 같다면 20 | rank[r2]+=1# r1이 속한 집합의 부모 루트가 r2로 변경되었으므로 r2의 개수를 더 많다고 해주기 21 | 22 | def solution(n,costs): 23 | for i in range(n):#모든 노드에 대해 집합화 24 | make_set(i) 25 | mst=[]#최소 비용 신장(spanning) 트리 26 | s=0#최소 비용 누적을 위한 변수 27 | costs=sorted(costs,key=lambda costs:costs[2])#비용 기준으로 정렬 28 | for j in costs: 29 | v,u,w=j# v=노드1 u=노드2 w=비용 30 | r1=findRoot(v)#노드 v에 대한 루트 31 | r2=findRoot(u) 32 | if r1!=r2:#노드의 루트가 다르면 33 | union(r1,r2)#두 노드 중 하나의 집합 수가 많은 집합에 넣기 34 | s+=w 35 | mst.append(j) 36 | return s #최단거리 37 | # return mst #최단거리를 만들기 위해 선택된 노드,간선,비용들 38 | 39 | n = 4 40 | costs = [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] 41 | 42 | x = solution(n, costs) 43 | print(x) 44 | -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/Level_3_저울.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def solution(weight): 4 | weight.sort() 5 | 6 | answer = 1 7 | 8 | for w in weight: 9 | 10 | if answer < w: 11 | break 12 | 13 | answer += w 14 | 15 | return answer 16 | 17 | 18 | weight = [3, 1, 6, 2, 7, 30, 1] 19 | 20 | 21 | x = solution(weight) 22 | print(x) -------------------------------------------------------------------------------- /src/탐욕법(Greedy)/README.md: -------------------------------------------------------------------------------- 1 | # 탐욕법_Greedy 2 | * [Level 1 체육복](#Level-1-체육복) 3 | * [Level 2 조이스틱](#Level-2-조이스틱) 4 | * [Level 2 큰 수 만들기](#Level-2-큰-수-만들기) 5 | * [Level 2 구명보트](#Level-2-구명보트) 6 | * [Level 3 섬 연결하기](#Level-3-섬-연결하기) 7 | * [Level 3 단속카메라](#Level-3-단속카메라) 8 | * [Level 3 저울](#Level-3-저울) 9 | 10 | --- 11 | 12 | ## Level 1 체육복 13 | ``` 14 | 점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 15 | 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 16 | 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 17 | 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 18 | 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다. 19 | 20 | 전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 21 | 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요. 22 | ``` 23 | 24 | ### 제한사항 25 | * 전체 학생의 수는 2명 이상 30명 이하입니다. 26 | * 체육복을 도난당한 학생의 수는 2명 이상 n명 이하이고 중복되는 번호는 없습니다. 27 | * 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다. 28 | * 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다. 29 | * 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 30 | * 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다. 31 | 32 | ### 입출력 예 33 | n | lost | reserve | return | 34 | :---: | :---: | :---: | :---: | 35 | 5 | [2, 4] | [1, 3, 5] | 5 36 | 5 | [2, 4] | [3] | 4 37 | 3 | [3] | [1] | 2 38 | 39 | ### 입출력 예 설명 40 | * 1번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 41 | * 학생 5명이 체육수업을 들을 수 있습니다. 42 | * 3번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 43 | * 학생 4명이 체육수업을 들을 수 있습니다. 44 | 45 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%83%90%EC%9A%95%EB%B2%95(Greedy)/Level_1_%EC%B2%B4%EC%9C%A1%EB%B3%B5.py) / [위로](#탐욕법_Greedy) 46 | 47 | --- 48 | 49 | ## Level 2 조이스틱 50 | ``` 51 | 조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. 52 | ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 53 | 54 | 조이스틱을 각 방향으로 움직이면 아래와 같습니다. 55 | ``` 56 | 57 | ▲ - 다음 알파벳 58 | 59 | ▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로) 60 | 61 | ◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서) 62 | 63 | ▶ - 커서를 오른쪽으로 이동 64 | 65 | ``` 66 | 예를 들어 아래의 방법으로 JAZ를 만들 수 있습니다. 67 | ``` 68 | * 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다. 69 | * 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다. 70 | * 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다. 71 | * 따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다. 72 | 73 | ``` 74 | 만들고자 하는 이름 name이 매개변수로 주어질 때, 75 | 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요. 76 | ``` 77 | 78 | ### 제한 사항 79 | * name은 알파벳 대문자로만 이루어져 있습니다. 80 | * name의 길이는 1 이상 20 이하입니다. 81 | 82 | ### 입출력 예 83 | name | return | 84 | :---: | :---: | 85 | "JEROEN" | 56 86 | "JAN" | 23 87 | 88 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%83%90%EC%9A%95%EB%B2%95(Greedy)/Level_2_%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1.py) / [위로](#탐욕법_Greedy) 89 | 90 | --- 91 | 92 | ## Level 2 큰 수 만들기 93 | ``` 94 | 어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다. 95 | 96 | 예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 97 | 이 중 가장 큰 숫자는 94 입니다. 98 | 99 | 문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. 100 | number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요. 101 | ``` 102 | 103 | ### 제한 조건 104 | * number는 1자리 이상, 1,000,000자리 이하인 숫자입니다. 105 | * k는 1 이상 `number의 자릿수` 미만인 자연수입니다. 106 | 107 | 108 | ### 입출력 예 109 | number | k | return 110 | :---: | :---: | :---: | 111 | "1924" | 2 | "94" 112 | "1231234" | 3 | "3234" 113 | "4177252841" | 4 | "775841" 114 | 115 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%83%90%EC%9A%95%EB%B2%95(Greedy)/Level_2_%ED%81%B0%20%EC%88%98%20%EB%A7%8C%EB%93%A4%EA%B8%B0.py) / [위로](#탐욕법_Greedy) 116 | 117 | --- 118 | 119 | ## Level 2 구명보트 120 | ``` 121 | 무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 122 | 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다. 123 | 124 | 예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 125 | 구명보트의 무게 제한이 100kg이라면 126 | 2번째 사람과 4번째 사람은 같이 탈 수 있지만 127 | 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다. 128 | 129 | 구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다. 130 | 131 | 사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 132 | 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요. 133 | ``` 134 | 135 | ### 제한사항 136 | * 무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다. 137 | * 각 사람의 몸무게는 40kg 이상 240kg 이하입니다. 138 | * 구명보트의 무게 제한은 40kg 이상 240kg 이하입니다. 139 | * 구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다. 140 | 141 | ### 입출력 예 142 | people | limit | return 143 | :---: | :---: | :---: | 144 | [70, 50, 80, 50] | 100 | 3 145 | [70, 80, 50] | 100 | 3 146 | 147 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%83%90%EC%9A%95%EB%B2%95(Greedy)/Level_2_%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8.py) / [위로](#탐욕법_Greedy) 148 | 149 | --- 150 | 151 | ## Level 3 섬 연결하기 152 | ``` 153 | n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 154 | 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요. 155 | 156 | 다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 157 | 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다. 158 | ``` 159 | ### 제한사항 160 | * 섬의 개수 n은 1 이상 100 이하입니다. 161 | * costs의 길이는 `((n-1) * n) / 2`이하입니다. 162 | * 임의의 i에 대해, costs[i][0] 와 costs[i] [1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i] [2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다. 163 | * 같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다. 164 | * 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다. 165 | * 연결할 수 없는 섬은 주어지지 않습니다. 166 | 167 | ### 입출력 예 168 | n | costs | return 169 | :---: | :---: | :---: | 170 | n | [[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]] | 4 171 | 172 | ### 입출력 예 설명 173 | ``` 174 | costs를 그림으로 표현하면 다음과 같으며, 이때 초록색 경로로 연결하는 것이 가장 적은 비용으로 모두를 통행할 수 있도록 만드는 방법입니다. 175 | ``` 176 | ![img](https://grepp-programmers.s3.amazonaws.com/files/production/13e2952057/f2746a8c-527c-4451-9a73-42129911fe17.png) 177 | 178 | 179 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/탐욕법(Greedy)/Level_3_섬%20연결하기.py) / [위로](#탐욕법_Greedy) 180 | 181 | --- 182 | 183 | ## Level 3 단속카메라 184 | ``` 185 | 고속도로를 이동하는 모든 차량이 고속도로를 이용하면서 단속용 카메라를 한 번은 만나도록 카메라를 설치하려고 합니다. 186 | 187 | 고속도로를 이동하는 차량의 경로 routes가 매개변수로 주어질 때, 188 | 모든 차량이 한 번은 단속용 카메라를 만나도록 하려면 최소 몇 대의 카메라를 설치해야 하는지를 return 하도록 solution 함수를 완성하세요. 189 | ``` 190 | 191 | ### 제한사항 192 | * 차량의 대수는 1대 이상 10,000대 이하입니다. 193 | * routes에는 차량의 이동 경로가 포함되어 있으며 194 | * routes[i][0]에는 i번째 차량이 고속도로에 진입한 지점 195 | * routes[i][1]에는 i번째 차량이 고속도로에서 나간 지점이 적혀 있습니다. 196 | * 차량의 진입/진출 지점에 카메라가 설치되어 있어도 카메라를 만난것으로 간주합니다. 197 | * 차량의 진입 지점, 진출 지점은 -30,000 이상 30,000 이하입니다. 198 | 199 | ### 입출력 예 200 | routes | return 201 | :---: | :---: | 202 | [[-20, 15], [-14, -5], [-18, -13], [-5, -3]] | 2 203 | 204 | ### 입출력 예 설명 205 | * -5 지점에 카메라를 설치하면 두 번째, 네 번째 차량이 카메라를 만납니다. 206 | * -15 지점에 카메라를 설치하면 첫 번째, 세 번째 차량이 카메라를 만납니다. 207 | 208 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/탐욕법(Greedy)/Level_3_단속카메라.py) / [위로](#탐욕법_Greedy) 209 | 210 | --- 211 | 212 | ## Level 3 저울 213 | ``` 214 | 하나의 양팔 저울을 이용하여 물건의 무게를 측정하려고 합니다. 215 | 이 저울의 양팔의 끝에는 물건이나 추를 올려놓는 접시가 달려 있고, 양팔의 길이는 같습니다. 216 | 또한, 저울의 한쪽에는 저울추들만 놓을 수 있고, 다른 쪽에는 무게를 측정하려는 물건만 올려놓을 수 있습니다. 217 | ``` 218 | 219 | ![img](https://grepp-programmers.s3.amazonaws.com/files/production/f73e61d4de/f4abf5ff-1956-4e49-bd4a-d3d24619bbf0.png) 220 | 221 | ``` 222 | 저울추가 담긴 배열 weight가 매개변수로 주어질 때, 223 | 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값을 return 하도록 solution 함수를 작성해주세요. 224 | 225 | 예를 들어, 무게가 각각 [3, 1, 6, 2, 7, 30, 1]인 7개의 저울추를 주어졌을 때, 226 | 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값은 21입니다. 227 | ``` 228 | 229 | ### 제한 사항 230 | * 저울추의 개수는 1개 이상 10,000개 이하입니다. 231 | * 각 추의 무게는 1 이상 1,000,000 이하입니다. 232 | 233 | ### 입출력 예 234 | weight | return 235 | :---: | :---: | 236 | [3, 1, 6, 2, 7, 30, 1] | 21 237 | 238 | ### 입출력 예 설명 239 | * 문제에 나온 예와 같습니다. 240 | 241 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/탐욕법(Greedy)/Level_3_저울.py) / [위로](#탐욕법_Greedy) 242 | -------------------------------------------------------------------------------- /src/해시/Level_1_완주하지못한선수.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | def solution(participant, completion): 4 | answer = Counter(participant) - Counter(completion) 5 | return list(answer.keys())[0] 6 | 7 | 8 | participant = ['mislav', 'stanko', 'mislav', 'ana'] 9 | completion = ['stanko', 'ana', 'mislav'] 10 | 11 | x = solution(participant, completion) 12 | print(x) 13 | 14 | -------------------------------------------------------------------------------- /src/해시/Level_2_위장.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | def solution(clothes): 4 | num_clothes_kind = Counter([kind for name, kind in clothes]) 5 | 6 | x = [ num + 1 for num in num_clothes_kind.values() ] 7 | answer = 1 8 | 9 | for x_i in x : 10 | answer *= x_i 11 | answer -= 1 12 | 13 | return answer 14 | 15 | clothes = [['yellow_hat', 'headgear'], ['blue_sunglasses', 'eyewear'], ['green_turban', 'headgear']] 16 | x = solution(clothes) 17 | print(x) -------------------------------------------------------------------------------- /src/해시/Level_2_전화번호부.py: -------------------------------------------------------------------------------- 1 | def solution(phoneBook): 2 | phoneBook = sorted(phoneBook) 3 | 4 | 5 | for p1, p2 in zip(phoneBook, phoneBook[1:]): 6 | if p2.startswith(p1): 7 | return False 8 | return True 9 | 10 | phone_book = ['12','123','1235','567','88'] 11 | x = solution(phone_book) 12 | print(x) -------------------------------------------------------------------------------- /src/해시/Level_3_베스트앨범.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | def sort_by_value(x) : 4 | sort_x = {} 5 | for key, value in sorted(x.items(), key=lambda x : x[1], reverse=True) : 6 | sort_x[key] = value 7 | 8 | return sort_x 9 | 10 | def solution(genres, plays): 11 | answer = [] 12 | total_num = len(genres) 13 | genres_dict = defaultdict(int) 14 | genres_index_dict = {} 15 | 16 | for i in range(total_num) : 17 | genres_dict[genres[i]] += plays[i] 18 | genres_index_dict[genres[i] + '_' + str(i)] = plays[i] 19 | 20 | genres_dict = sort_by_value(genres_dict) 21 | genres_index_dict = sort_by_value(genres_index_dict) 22 | 23 | for k in genres_dict.keys() : 24 | limit_song = 0 25 | for key, value in genres_index_dict.items() : 26 | if k in key : 27 | answer.append(int(key.split('_')[-1])) 28 | limit_song += 1 29 | if limit_song >= 2 : 30 | break 31 | 32 | return answer 33 | 34 | genres = ['classic', 'pop', 'classic', 'classic', 'pop'] 35 | plays = [500, 600, 150, 800, 2500] 36 | 37 | x = solution(genres, plays) 38 | print(x) -------------------------------------------------------------------------------- /src/해시/README.md: -------------------------------------------------------------------------------- 1 | # 해시 2 | * [Level 1 완주하지 못한 선수](#Level-1-완주하지-못한-선수) 3 | * [Level 2 전화번호 목록](#Level-2-전화번호-목록) 4 | * [Level 2 위장](#Level-2-위장) 5 | * [Level 3 베스트앨범](#Level-3-베스트앨범) 6 | 7 | --- 8 | 9 | ## Level 1 완주하지 못한 선수 10 | ``` 11 | 수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 12 | 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 13 | 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요. 14 | ``` 15 | 16 | ### 제한사항 17 | * 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다. 18 | * completion의 길이는 participant의 길이보다 1 작습니다. 19 | * 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다. 20 | * 참가자 중에는 동명이인이 있을 수 있습니다. 21 | 22 | ### 입출력 예 23 | participant | completion | return | 24 | :---: | :---: | :---: | 25 | ["leo", "kiki", "eden"] | ["eden", "kiki"] | "leo" 26 | ["marina", "josipa", "nikola", "vinko", "filipa"] | ["josipa", "filipa", "marina", "nikola"] | "vinko" 27 | ["mislav", "stanko", "mislav", "ana"] | ["stanko", "ana", "mislav"] | "mislav" 28 | 29 | ### 입출력 예 설명 30 | * 예제 1 31 | * **leo**는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다. 32 | 33 | * 예제 2 34 | * **vinko**는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다. 35 | 36 | * 예제 3 37 | * **mislav**는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다. 38 | 39 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%95%B4%EC%8B%9C/Level_1_%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80%EB%AA%BB%ED%95%9C%EC%84%A0%EC%88%98.py) / [위로](#해시) 40 | --- 41 | 42 | ## Level 2 전화번호 목록 43 | ``` 44 | 전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다. 45 | 전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다. 46 | 47 | 구조대 : 119 48 | 박준영 : 97 674 223 49 | 지영석 : 11 9552 4421 50 | 51 | 전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 52 | 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요. 53 | ``` 54 | 55 | ### 제한 사항 56 | * phone_book의 길이는 1 이상 1,000,000 이하입니다. 57 | * 각 전화번호의 길이는 1 이상 20 이하입니다. 58 | 59 | ### 입출력 예제 60 | phone_book | return | 61 | :---: | :---: | 62 | ["119", "97674223", "1195524421"] | false 63 | ["123", "456", "789"] | true 64 | ["12", "123", "1235", "567", "88"] | false 65 | 66 | ### 입출력 예 설명 67 | * 입출력 예 1 68 | * 앞에서 설명한 예와 같습니다. 69 | 70 | * 입출력 예 2 71 | * 한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다. 72 | 73 | * 입출력 예 3 74 | * 첫 번째 전화번호, “12”가 두 번째 전화번호 “123”의 접두사입니다. 따라서 답은 false입니다. 75 | 76 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%95%B4%EC%8B%9C/Level_2_%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8%EB%B6%80.py) / [위로](#해시) 77 | --- 78 | 79 | ## Level 2 위장 80 | ``` 81 | 스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다. 82 | 83 | 예를 들어 스파이가 가진 옷이 아래와 같고 84 | 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 85 | 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다. 86 | 87 | 종류 | 이름 88 | 얼굴 | 동그란 안경, 검정 선글라스 89 | 상의 | 파란색 티셔츠 90 | 하의 | 청바지 91 | 겉옷 | 긴 코트 92 | 93 | 스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요. 94 | ``` 95 | 96 | ### 제한사항 97 | * clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다. 98 | * 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다. 99 | * 같은 이름을 가진 의상은 존재하지 않습니다. 100 | * clothes의 모든 원소는 문자열로 이루어져 있습니다. 101 | * 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다. 102 | * 스파이는 하루에 최소 한 개의 의상은 입습니다. 103 | 104 | ### 입출력 예 105 | * 예제 1 106 | * headgear에 해당하는 의상이 yellow_hat, green_turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다. 107 | ``` 108 | 1. yellow_hat 109 | 2. blue_sunglasses 110 | 3. green_turban 111 | 4. yellow_hat + blue_sunglasses 112 | 5. green_turban + blue_sunglasses 113 | ``` 114 | 115 | * 예제 2 116 | * face에 해당하는 의상이 crow_mask, blue_sunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다. 117 | ``` 118 | 1. crow_mask 119 | 2. blue_sunglasses 120 | 3. smoky_makeup 121 | ``` 122 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%95%B4%EC%8B%9C/Level_2_%EC%9C%84%EC%9E%A5.py) / [위로](#해시) 123 | 124 | --- 125 | 126 | ## Level 3 베스트앨범 127 | ``` 128 | 스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 129 | 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 130 | 131 | 1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다. 132 | 2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다. 133 | 3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다. 134 | 135 | 노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 136 | 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요. 137 | ``` 138 | 139 | ### 제한사항 140 | * genres[i]는 고유번호가 i인 노래의 장르입니다. 141 | * plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다. 142 | * genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다. 143 | * 장르 종류는 100개 미만입니다. 144 | * 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다. 145 | * 모든 장르는 재생된 횟수가 다릅니다. 146 | 147 | ### 입출력 예 148 | genres | plays | return | 149 | :---: | :---: | :---: | 150 | ["classic", "pop", "classic", "classic", "pop"] | [500, 600, 150, 800, 2500] | [4, 1, 3, 0] 151 | 152 | ### 입출력 예 설명 153 | * classic 장르는 1,450회 재생되었으며, classic 노래는 다음과 같습니다. 154 | * 고유 번호 3: 800회 재생 155 | * 고유 번호 0: 500회 재생 156 | * 고유 번호 2: 150회 재생 157 | 158 | * pop 장르는 3,100회 재생되었으며, pop 노래는 다음과 같습니다. 159 | * 고유 번호 4: 2,500회 재생 160 | * 고유 번호 1: 600회 재생 161 | * 따라서 pop 장르의 [4, 1]번 노래를 먼저, classic 장르의 [3, 0]번 노래를 그다음에 수록합니다. 162 | 163 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%95%B4%EC%8B%9C/Level_3_%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94.py) / [위로](#해시) 164 | -------------------------------------------------------------------------------- /src/힙(Heap)/Level_2_더 맵게.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | def solution(scoville, K): 4 | answer = 0 5 | heapq.heapify(scoville) 6 | 7 | while True : 8 | if scoville[0] >= K: 9 | return answer 10 | elif len(scoville) == 1: 11 | return -1 12 | 13 | t1 = heapq.heappop(scoville) 14 | t2 = heapq.heappop(scoville) 15 | 16 | heapq.heappush(scoville, t1 + 2*t2) 17 | answer += 1 18 | 19 | scoville = [9, 1, 2, 3, 10, 12] 20 | K = 7 21 | x = solution(scoville, K) 22 | print(x) 23 | -------------------------------------------------------------------------------- /src/힙(Heap)/Level_2_라면공장.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | def solution(stock, dates, supplies, k): 4 | answer, start = 0, 0 5 | x = [] 6 | n = len(dates) 7 | 8 | while stock < k: 9 | for i in range(start, n): 10 | if dates[i] <= stock: 11 | heapq.heappush(x, -supplies[i]) 12 | else: 13 | start = i 14 | break 15 | answer += 1 16 | stock += -heapq.heappop(x) 17 | 18 | return answer -------------------------------------------------------------------------------- /src/힙(Heap)/Level_3_디스크 컨트롤러.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | def solution(jobs): 4 | pool = [] 5 | 6 | elapsted_t = 0 7 | current_t = 0 8 | initial_t = 0 9 | 10 | n = len(jobs) 11 | 12 | heapq.heapify(pool) 13 | 14 | jobs = sorted(jobs, key=lambda x: x[0]) 15 | 16 | while jobs or pool : 17 | while jobs : 18 | if current_t >= jobs[0][0]: 19 | st, et = jobs.pop(0) 20 | initial_t += st 21 | heapq.heappush(pool, et) 22 | 23 | else: 24 | break 25 | 26 | if pool : 27 | et = heapq.heappop(pool) 28 | current_t += et 29 | elapsted_t += current_t 30 | 31 | else: 32 | current_t = jobs[0][0] 33 | 34 | answer = (elapsted_t-initial_t) // n 35 | 36 | return answer 37 | 38 | 39 | jobs = [[1, 9], [0, 3], [2, 6]] 40 | 41 | x = solution(jobs) 42 | print(x) -------------------------------------------------------------------------------- /src/힙(Heap)/Level_3_이중우선순위큐.py: -------------------------------------------------------------------------------- 1 | def solution(operations): 2 | x = [] 3 | for op in operations : 4 | order, num = op.split()[0], int(op.split()[1]) 5 | 6 | if order == 'I' : 7 | x.append(num) 8 | if order == 'D' : 9 | try : 10 | if num == 1 : 11 | x.remove(max(x)) 12 | if num == -1 : 13 | x.remove(min(x)) 14 | except ValueError : 15 | continue 16 | 17 | if not x : 18 | answer = [0, 0] 19 | else : 20 | answer = [max(x), min(x)] 21 | 22 | return answer 23 | 24 | 25 | operations = ["I 7", "I 5", "I -5", "D -1"] 26 | # operations = ["I 7", "D 1", "D 1", "D -1"] 27 | x = solution(operations) 28 | 29 | print(x) -------------------------------------------------------------------------------- /src/힙(Heap)/README.md: -------------------------------------------------------------------------------- 1 | # 힙_Heap 2 | * [Level 2 더 맵게](#Level-2-더-맵게) 3 | * [Level 2 라면공장](#Level-2-라면공장) 4 | * [Level 3 디스크 컨트롤러](#Level-3-디스크-컨트롤러) 5 | * [Level 3 이중우선순위큐](#Level-3-이중우선순위큐) 6 | 7 | --- 8 | 9 | ## Level 2 더 맵게 10 | ``` 11 | 매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 12 | 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다. 13 | ``` 14 | 15 | * 섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2) 16 | 17 | ``` 18 | Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다. 19 | Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 20 | 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요. 21 | ``` 22 | 23 | ### 제한 사항 24 | * scoville의 길이는 1 이상 1,000,000 이하입니다. 25 | * K는 0 이상 1,000,000,000 이하입니다. 26 | * scoville의 원소는 각각 0 이상 1,000,000 이하입니다. 27 | * 모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return 합니다. 28 | 29 | ### 입출력 예 30 | scoville | K | return | 31 | :---: | :---: | :---: | 32 | [1, 2, 3, 9, 10, 12] | 7 | 2 33 | 34 | ### 입출력 예 설명 35 | * 스코빌 지수가 1인 음식과 2인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다. 36 | * 새로운 음식의 스코빌 지수 = 1 + (2 * 2) = 5 37 | * 가진 음식의 스코빌 지수 = [5, 3, 9, 10, 12] 38 | 39 | * 스코빌 지수가 3인 음식과 5인 음식을 섞으면 음식의 스코빌 지수가 아래와 같이 됩니다. 40 | * 새로운 음식의 스코빌 지수 = 3 + (5 * 2) = 13 41 | * 가진 음식의 스코빌 지수 = [13, 9, 10, 12] 42 | 43 | * 모든 음식의 스코빌 지수가 7 이상이 되었고 이때 섞은 횟수는 2회입니다. 44 | 45 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%9E%99(Heap)/Level_2_%EB%8D%94%20%EB%A7%B5%EA%B2%8C.py) / [위로](#힙_Heap) 46 | 47 | --- 48 | 49 | ## Level 2 라면공장 50 | ``` 51 | 라면 공장에서는 하루에 밀가루를 1톤씩 사용합니다. 52 | 원래 밀가루를 공급받던 공장의 고장으로 앞으로 k일 이후에야 밀가루를 공급받을 수 있기 때문에 해외 공장에서 밀가루를 수입해야 합니다. 53 | 해외 공장에서는 향후 밀가루를 공급할 수 있는 날짜와 수량을 알려주었고, 54 | 라면 공장에서는 운송비를 줄이기 위해 최소한의 횟수로 밀가루를 공급받고 싶습니다. 55 | 56 | 현재 공장에 남아있는 밀가루 수량 stock, 57 | 밀가루 공급 일정(dates), 58 | 해당 시점에 공급 가능한 밀가루 수량(supplies), 59 | 원래 공장으로부터 공급받을 수 있는 시점 k가 주어질 때, 60 | 밀가루가 떨어지지 않고 공장을 운영하기 위해서 최소한 몇 번 해외 공장으로부터 밀가루를 공급받아야 하는지를 return 하도록 solution 함수를 완성하세요. 61 | 62 | dates[i]에는 i번째 공급 가능일이 들어있으며, amounts[i]에는 dates[i] 날짜에 공급 가능한 밀가루 수량이 들어 있습니다. 63 | ``` 64 | 65 | ### 제한사항 66 | * stock에 있는 밀가루는 오늘(0일 이후)부터 사용됩니다. 67 | * stock과 k는 2 이상 100,000 이하입니다. 68 | * dates의 각 원소는 1 이상 k 이하입니다. 69 | * supplies의 각 원소는 1 이상 1,000 이하입니다. 70 | * dates와 supplies의 길이는 1 이상 20,000 이하입니다. 71 | * k일 째에는 밀가루가 충분히 공급되기 때문에 k-1일에 사용할 수량까지만 확보하면 됩니다. 72 | * dates에 들어있는 날짜는 오름차순 정렬되어 있습니다. 73 | * dates에 들어있는 날짜에 공급되는 밀가루는 작업 시작 전 새벽에 공급되는 것을 기준으로 합니다. 74 | * 예를 들어 9일째에 밀가루가 바닥나더라도, 10일째에 공급받으면 10일째에는 공장을 운영할 수 있습니다. 75 | * 밀가루가 바닥나는 경우는 주어지지 않습니다. 76 | 77 | ### 입출력 예 78 | stock | dates | supplies | k | result | 79 | :---: | :---: | :---: | :---: | :---: | 80 | 4 | [4,10,15] | [20,5,10] | 30 | 2 81 | 82 | ### 입출력 예 설명 83 | * 현재 밀가루가 4톤 남아 있기 때문에 오늘과 1일 후~3일 후까지 사용하고 나면 모든 밀가루를 다 사용합니다. 84 | * 따라서 4일 후에는 반드시 밀가루를 공급받아야 합니다. 85 | * 4일째 공급받고 나면 15일 이후 아침에는 9톤의 밀가루가 남아있게 되고, 86 | * 이때 10톤을 더 공급받으면 19톤이 남아있게 됩니다. 87 | * 15일 이후부터 29일 이후까지 필요한 밀가루는 15톤이므로 더 이상의 공급은 필요 없습니다. 88 | * 따라서 총 2회의 밀가루를 공급받으면 됩니다. 89 | 90 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%9E%99(Heap)/Level_2_%EB%9D%BC%EB%A9%B4%EA%B3%B5%EC%9E%A5.py) / [위로](#힙_Heap) 91 | 92 | --- 93 | 94 | ## Level 3 디스크 컨트롤러 95 | ``` 96 | 하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 97 | 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 98 | 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다. 99 | 100 | 예를들어 101 | - 0ms 시점에 3ms가 소요되는 A작업 요청 102 | - 1ms 시점에 9ms가 소요되는 B작업 요청 103 | - 2ms 시점에 6ms가 소요되는 C작업 요청 104 | 105 | 와 같은 요청이 들어왔습니다. 이를 그림으로 표현하면 아래와 같습니다. 106 | ``` 107 | ![example_1](https://grepp-programmers.s3.amazonaws.com/files/production/b68eb5cec6/38dc6a53-2d21-4c72-90ac-f059729c51d5.png) 108 | ``` 109 | 한 번에 하나의 요청만을 수행할 수 있기 때문에 각각의 작업을 요청받은 순서대로 처리하면 다음과 같이 처리 됩니다. 110 | ``` 111 | ![example_2](https://grepp-programmers.s3.amazonaws.com/files/production/5e677b4646/90b91fde-cac4-42c1-98b8-8f8431c52dcf.png) 112 | ``` 113 | - A: 3ms 시점에 작업 완료 (요청에서 종료까지 : 3ms) 114 | - B: 1ms부터 대기하다가, 3ms 시점에 작업을 시작해서 12ms 시점에 작업 완료(요청에서 종료까지 : 11ms) 115 | - C: 2ms부터 대기하다가, 12ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 16ms) 116 | 117 | 이 때 각 작업의 요청부터 종료까지 걸린 시간의 평균은 10ms(= (3 + 11 + 16) / 3)가 됩니다. 118 | 119 | 하지만 A → C → B 순서대로 처리하면 120 | ``` 121 | 122 | ![example_3](https://grepp-programmers.s3.amazonaws.com/files/production/9eb7c5a6f1/a6cff04d-86bb-4b5b-98bf-6359158940ac.png) 123 | ``` 124 | - A: 3ms 시점에 작업 완료(요청에서 종료까지 : 3ms) 125 | - C: 2ms부터 대기하다가, 3ms 시점에 작업을 시작해서 9ms 시점에 작업 완료(요청에서 종료까지 : 7ms) 126 | - B: 1ms부터 대기하다가, 9ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 17ms) 127 | 128 | 이렇게 A → C → B의 순서로 처리하면 각 작업의 요청부터 종료까지 걸린 시간의 평균은 9ms(= (3 + 7 + 17) / 3)가 됩니다. 129 | 130 | 각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 131 | 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마가 되는지 return 하도록 solution 함수를 작성해주세요. 132 | (단, 소수점 이하의 수는 버립니다) 133 | ``` 134 | 135 | ### 제한 사항 136 | * jobs의 길이는 1 이상 500 이하입니다. 137 | * jobs의 각 행은 하나의 작업에 대한 [작업이 요청되는 시점, 작업의 소요시간] 입니다. 138 | * 각 작업에 대해 작업이 요청되는 시간은 0 이상 1,000 이하입니다. 139 | * 각 작업에 대해 작업의 소요시간은 1 이상 1,000 이하입니다. 140 | * 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다. 141 | 142 | ### 입출력 예 143 | jobs | return | 144 | :---: | :---: | 145 | [[0, 3], [1, 9], [2, 6]] | 9 146 | 147 | ### 입출력 예 설명 148 | * 문제에 주어진 예와 같습니다. 149 | * 0ms 시점에 3ms 걸리는 작업 요청이 들어옵니다. 150 | * 1ms 시점에 9ms 걸리는 작업 요청이 들어옵니다. 151 | * 2ms 시점에 6ms 걸리는 작업 요청이 들어옵니다. 152 | 153 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%9E%99(Heap)/Level_3_%EB%94%94%EC%8A%A4%ED%81%AC%20%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC.py) / [위로](#힙_Heap) 154 | 155 | --- 156 | 157 | ## Level 3 이중우선순위큐 158 | ``` 159 | 이중 우선순위 큐는 다음 연산을 할 수 있는 자료구조를 말합니다. 160 | ``` 161 | 명령어 | 수신 탑(높이) | 162 | :---: | :---: | 163 | I 숫자 | 큐에 주어진 숫자를 삽입합니다. 164 | D 1 | 큐에서 최댓값을 삭제합니다. 165 | D -1 | 큐에서 최솟값을 삭제합니다. 166 | 167 | ``` 168 | 이중 우선순위 큐가 할 연산 operations가 매개변수로 주어질 때, 169 | 모든 연산을 처리한 후 큐가 비어있으면 [0,0] 170 | 비어있지 않으면 [최댓값, 최솟값]을 return 하도록 solution 함수를 구현해주세요. 171 | ``` 172 | 173 | ### 제한사항 174 | * operations는 길이가 1 이상 1,000,000 이하인 문자열 배열입니다. 175 | * operations의 원소는 큐가 수행할 연산을 나타냅니다. 176 | * 원소는 “명령어 데이터” 형식으로 주어집니다.- 최댓값/최솟값을 삭제하는 연산에서 최댓값/최솟값이 둘 이상인 경우, 하나만 삭제합니다. 177 | * 빈 큐에 데이터를 삭제하라는 연산이 주어질 경우, 해당 연산은 무시합니다. 178 | 179 | ### 입출력 예 180 | operations | return | 181 | :---: | :---: | 182 | ["I 16","D 1"] | 0,0] 183 | ["I 7,"I 5","I -5","D -1"] | [7,5] 184 | 185 | ### 입출력 예 설명 186 | * 16을 삽입 후 최댓값을 삭제합니다. 비어있으므로 [0,0]을 반환합니다. 187 | * 7,5,-5를 삽입 후 최솟값을 삭제합니다. 최대값 7, 최소값 5를 반환합니다. 188 | 189 | ### [Code](https://github.com/taki0112/coding_practice/blob/master/src/%ED%9E%99(Heap)/Level_3_%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90.py) / [위로](#힙_Heap) 190 | --------------------------------------------------------------------------------