반응형

2019 카카오 개발자 겨울 인턴십 문제입니다.

문제풀이

1. 정규표현식에서 '.'은 모든 문자 1개를 의미합니다. 따라서 banned_id의 모든 '*'을 '.'으로 바꾼 후 이를 컴파일러로 사용합니다.

2. user_id의 아이디 하나 u가 banned_id의 하나 b에 해당되기 위해서는 b로 만든 컴파일러에 u가 걸리고, b와 u의 길이가 같아야합니다. 저는 정규표현식의 match를 활용하였는데, match를 활용하면 'a.b'로 만든 컴파일러에 'aabb' 또한 매칭되므로 두번째 조건이 필요합니다.

3. 2 과정을 통해 모든 b에 해당하는 u의 리스트를 만듭니다.

user_id banned_id
["frodo", "fradi", "crodo", "abc123", "frodoc"] ["fr*d*", "abc1**"]

이 예를 사용하면 3의 결과는 다음과 같습니다.

{0: ['frodo', 'fradi'], 1: ['abc123']}

여기서 key값인 숫자는 b의 index입니다.

4. 3의 결과인 dictionary를 dfs 하여 최종 결과를 만들어냅니다.

 

*말로는 설명이 잘 안되어 아래 코드에서 자세히 다시 설명하겠습니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import re
 
def solution(user_id, banned_id):
    # 가능한 제재id
    global answer
    answer = []
    # key : banned_id의 id의 index, value : 아래의 checked
    candidate = {}
    for i, b in enumerate(banned_id):
        # re.sub를 활용하여 b의 모든 *을 .으로 변환
        checker = re.compile(re.sub('\*','.',b))
        # banned_id 중 하나인 b에 매칭되는 user_id
        checked = []
        for u in user_id:
            # match가 안되면 결과가 None으로 두번째 조건 만족x
            if len(u) == len(b) and checker.match(u):
                checked.append(u)
        candidate[i] = checked
    # candidate를 활용하여 dfs
    for x in candidate[0]:
        dfs([x],candidate,len(banned_id))
 
    return len(answer)
 
'''
selected는 list로 selected[i]는 candidate[i]의 원소 중 하나. 즉 i번째 banned_id에 매칭되는 user_id 중 하나.
n은 banned_id의 길이.
dfs의 탈출 조건은 selected에 들어있는 원소의 수가 n이 되는 것이다.
'''
def dfs(selected,candidate, n):
    # 탈출조건
    if len(selected) == n:
        global answer
        # 중복을 제거하기 위해 selected를 정렬한 후 비교
        tmp = sorted(selected)
        if tmp not in answer:
            answer.append(tmp)
        return ;
    '''
    <selected의 원소 수가 n이 아닌 경우.>
    selected의 원소 수는 다음 banned_id의 index를 의미한다.
    ex) selected에 한개가 들어있으면 banned_id[1](banned_id의 두번째 요소)에 매칭되는 user_id의 집합인 
        candidate[1]의 원소 중 하나를 selected에 넣는다.
    '''
    for x in candidate[len(selected)]:
        if x not in selected:
            dfs(selected+[x],candidate,n)
 
cs

문제링크

 

코딩테스트 연습 - 불량 사용자

개발팀 내에서 이벤트 개발을 담당하고 있는 무지는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량

programmers.co.kr

 

반응형
반응형

2018 카카오 블라인드 채용 문제입니다.

문제풀이

먼저, LRU 알고리즘 : 새로운 페이지가 등장했을 때, 가장 오래전에 사용된 페이지를 캐시에서 삭제합니다.

즉, 캐시 사이즈가 2이고, 캐시에 t=1일 때 A, t=2일 때 B가 들어오면, A와 B는 캐시가 비어있으므로 그냥 캐시에 추가합니다. t=3 일 때 C가 등장한다면, 가장 오래전에 사용된 A를 캐시에서 제거하고 C를 캐시에 추가합니다.

=> 큐 자료구조를 활용합니다.

1. cities에서 city를 꺼내고 대소문자를 구분하지 않는다고 했으므로 전부 대문자로 변환합니다.

2. queue 자료구조로 cache를 선언합니다. cache의 앞에 있을수록 사용한지 오래된 페이지입니다.

위의 예에서 cache는 [A] -> [A, B] -> [B, C]로 변화합니다.

3-1. city가 cache에 있다면 cache에서 city를 삭제하고 city를 다시 넣어줍니다. answer에는 1을 더해줍니다.

* pop()으로 꺼내지 않고 remove(cache)로 지워야합니다. 여기서 city를 지우는 이유는 city를 가장 최근에 사용된 것으로 바꾸기 위해 cache의 맨 끝에 넣기 위함인데, pop()으로 지우면 cache에서 city가 아니라 가장 오래된 것이 지워집니다.

** cache가 [A, B, C] 일 때, B가 들어오면, cache를 [A, C, B]로 바꾸기 위해 B를 지운 후 다시 넣는 것을 말합니다.

3-2. city가 cache에 없다면 cache의 첫번째 요소를 제거(pop())한 후, city를 cache에 넣어줍니다. answer에는 5를 더해줍니다.

*cache의 크기가 cacheSize보다 작을 때는 첫번째 요소를 제거하지 않고 city를 cache에 넣어주는 작업만 수행합니다.

Python Code 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from collections import deque
 
def solution(cacheSize, cities):
    if cacheSize == 0 : return len(cities) * 5
    answer = 5
    cache = deque([cities[0].upper()])
    for city in cities[1:]:
        c = city.upper()
        if c in cache:
            answer +=1
            cache.remove(c)
            cache.append(c)
        else:
            answer += 5
            cache.append(c)
            if len(cache) > cacheSize:
                cache.popleft()
    
    return answer
cs

Line 4 : cacheSize가 0인 경우에는 cities의 요소 수에 5를 곱해 반환합니다.

Line 6 : cache에 cities의 첫번째 요소를 넣은 채 선언합니다. 따라서 answer 역시 5로 초기화합니다.

Line 9 : city가 cache에 있는 경우입니다.

Line 13 : city가 cache에 없는 경우입니다.

 

문제 링크

 

코딩테스트 연습 - [1차] 캐시

3 [Jeju, Pangyo, Seoul, NewYork, LA, Jeju, Pangyo, Seoul, NewYork, LA] 50 3 [Jeju, Pangyo, Seoul, Jeju, Pangyo, Seoul, Jeju, Pangyo, Seoul] 21 2 [Jeju, Pangyo, Seoul, NewYork, LA, SanFrancisco, Seoul, Rome, Paris, Jeju, NewYork, Rome] 60 5 [Jeju, Pangyo, S

programmers.co.kr

 

반응형
반응형

2019 카카오 개발자 겨울 인턴십 문제입니다.

문제풀이

1. 문제가 잘 이해가 안되는데, 예로 [2,1,3,4]를 설명하면 다음과 같다.

[2,1,3,4]는 {{2},{2,1},{2,1,3},{2,1,3,4}}로 쓸 수 있는데, 이 집합의 순서를 아래와 같이

{{2,1},{2,1,3},{2},{2,1,3,4}} 등으로 바꿀 경우, 이 집합을 통해 [2,1,3,4]를 맞추는 문제이다.

2. 집합의 각 요소를 살펴보면, 2가 4번, 1이 3번, 3이 2번, 4가 1번 등장하는 것을 볼 수 있다.

즉, 많이 순서대로 앞에 위치하는 요소가 된다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
def solution(s):
    s = s[2:-2]
    co = {}
    for tuple in s.split('},{') :
        for t in tuple.split(','):
            tmp = int(t)
            if tmp in co:
                co[tmp] = co[tmp] + 1
            else:
                co[tmp] = 1
    return sorted(list(co.keys()), key = lambda x : co[x], reverse = True)
cs

Line 4 : 각 집합을 꺼냅니다.

Line 5 : 각 집합의 요소를 꺼내 int로 변환해줍니다(Line 6).

Line 3, 7 - 10 : co는 각 요소가 key, 등장하는 횟수가 value인 딕셔너리 자료구조입니다.

Line 11 : co의 key들을 등장 횟수를 기준으로 정렬하여 리스트로 반환합니다.

 

문제링크

 

코딩테스트 연습 - 튜플

"{{2},{2,1},{2,1,3},{2,1,3,4}}" [2, 1, 3, 4] "{{1,2,3},{2,1},{1,2,4,3},{2}}" [2, 1, 3, 4] "{{4,2,3},{3},{2,3,4,1},{2,3}}" [3, 2, 4, 1]

programmers.co.kr

 

반응형
반응형

 

2018 KAKAO BLIND RECRUITMENT 3차 문제입니다.

 

문제 풀이

1. 0부터 차례대로 n진수로 변환합니다.

2. n진수로 변환한 수를 q에 넣어줍니다.

3. q에 들어간 요소의 수가 게임 참가자의 수 m보다 크게되면 answer에 큐의 p번째 요소(튜브의 순서)를 넣어주고 q에서 m개의 요소를 제거하여 줍니다.

4. 1 ~3의 과정을 answer의 길이가 t가 될 때까지 반복해줍니다.

 

* 단계1에서 0부터 계속 n진수로 바꾸는 것을, 0에 계속 1씩 더해가는 방식으로 수정하면 더 빠를 것 같습니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from collections import deque
= "0123456789ABCDEF"
 
def convert(n, base):
    q, r = divmod(n, base)
    if q == 0:
        return T[r]
    else:
        return convert(q, base) + T[r]
 
def solution(n, t, m, p):
    q= deque()
    answer = ''
    
    #말해야할 숫자
    i = 0
    while len(answer) < t:
        c = convert(i,n)
        
        for s in list(c):
            q.append(s)
            
        while len(q) > m:
            answer+= q[p-1]
            for _ in range(m):
                q.popleft()
        i += 1
    return answer
cs

Line 4 : 숫자 n을 base 진수로 변환시켜주는 함수입니다. 재귀식으로 수행됩니다.

결과

 

테스트 20 통과 (2.07ms, 10.1MB)
테스트 21 통과 (8.82ms, 10.2MB)
테스트 22 통과 (4.58ms, 10.2MB)
테스트 23 통과 (12.77ms, 10.2MB)
테스트 24 통과 (20.17ms, 10.2MB)
테스트 25 통과 (15.09ms, 10.2MB)
테스트 26 통과 (5.53ms, 10.3MB)

두번째 풀이

위의 풀이에 *로 써놓은 것을 구현한 코드입니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from collections import deque
 
class Num():
    def __init__(self, base):
        self.num = [0]
        self.T = list("0123456789ABCDEF")
        self.base = base
    def add(self):
        self.addOne(1)
    def addOne(self,depth):
        if depth > len(self.num):
            self.num = [1+ self.num
            return ;
        if self.num[-depth] == self.base-1:
            self.num[-depth] = 0
            self.addOne(depth+1)
        else:
            self.num[-depth] += 1
    def getNum(self):
        return [self.T[x] for x in self.num]
    
def solution(n, t, m, p):
    q= deque()
    answer = ''
    
    #말해야할 숫자
    num = Num(n)
    while len(answer) < t:
        
        for s in num.getNum():
            q.append(s)
            
        while len(q) > m:
            answer+= q[p-1]
            for _ in range(m):
                q.popleft()
        num.add()
    return answer
cs

 

Line 3: Num 클래스는 n진수이며 처음에  num 변수는 [0]로 초기화됩니다.

Line 8 : Num 클래스의 add 메소드는 num 변수에 1을 더하는 메소드로 addNum이라는 메소드를 통해 실행됩니다.

Line 10 : addNum은 depth 자릿수의 숫자에 1을 더하는 것으로, 수가 가득차는 경우(10진수의 경우 9에 1을 더해 10이 되는 경우)에는 depth 자릿수의 숫자는 0으로 하고 depth+1번째 자릿수에 1을 더하게 됩니다.

결과

테스트 20 통과 (2.17ms, 10.3MB)
테스트 21 통과 (8.86ms, 10.4MB)
테스트 22 통과 (4.44ms, 10.2MB)
테스트 23 통과 (11.55ms, 10.2MB)
테스트 24 통과 (14.63ms, 10.3MB)
테스트 25 통과 (11.84ms, 10.3MB)
테스트 26 통과 (6.06ms, 10.3MB)

테스트 24번을 기준으로 앞의 풀이보다 약 5ms 빨라진 것을 볼 수 있습니다.

문제 링크

 

코딩테스트 연습 - [3차] n진수 게임

N진수 게임 튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다. 숫자를 0

programmers.co.kr

 

반응형
반응형

문제 풀이

1. GROUP BY 를 통해 각 이름의 개수를 세어줍니다.

2. 개수가 2개 이상인 이름만 출력합니다.

* 이름이 NULL인 것이 함정입니다.

Oracle Code

1
2
3
4
5
6
7
SELECT X.NAME, X.COUNT
FROM(SELECT NAME, COUNT(*) COUNT
    FROM ANIMAL_INS
    WHERE NAME IS NOT NULL
    GROUP BY NAME) X
WHERE X.COUNT > 1
ORDER BY X.NAME
cs

문제 링크

 

코딩테스트 연습 - 동명 동물 수 찾기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

반응형
반응형

문제 풀이

1. 요거트가 담긴 바구니의 카트 아이디 중 우유가 담긴 바구니를 찾는다.

Oracle Code

1
2
3
4
5
6
SELECT DISTINCT X.CART_ID
FROM (SELECT CART_ID 
    FROM CART_PRODUCTS
    WHERE NAME = 'Yogurt') X, CART_PRODUCTS Y
WHERE Y.NAME = 'Milk' AND X.CART_ID = Y.CART_ID
ORDER BY X.CART_ID;
cs

Line 2~4 : 요거트가 담긴 바구니의 카트 아이디를 구한다.

Line 5 : 우유가 담긴 바구니의 카트 아이디 중 요거트가 담긴 바구니의 카트 아이디와 같은 것을 찾아 반환한다.

문제링크

 

코딩테스트 연습 - 우유와 요거트가 담긴 장바구니

CART_PRODUCTS 테이블은 장바구니에 담긴 상품 정보를 담은 테이블입니다. CART_PRODUCTS 테이블의 구조는 다음과 같으며, ID, CART_ID, NAME, PRICE는 각각 테이블의 아이디, 장바구니의 아이디, 상품 종류, 가

programmers.co.kr

 

반응형
반응형

2020 KAKAO BLIND RECRUITMENT 문제

위의 카카오 공식 해설을 참조하시면 좋을 것 같습니다.

 

문제 풀이

1. 압축하는 글자 수는 1개부터 글자수의 절반까지만 하면 됩니다.

2. 압축 글자 수를 num이라 할 때, 첫 문자열의 위치를 i, 다음 문자열의 위치를 j라 하면 s[i:i+num]와 s[j:j+num]을 비교하며 같으면 j를 j+num으로 고쳐주며 같은 단어의 수를 세어줍니다.

3. 다른 경우에는 정답 문자열에 같은 단어의 숫자 + s[i:i+num]을 더해줍니다.

4. 위의 과정을 반복한 후, 남은 문자열을 더해줍니다. (xxxxi를 압축하는 경우, 위의 과정을 반복하면 2xx가 되고, 남는 i를 더해 2xxi를 완성합니다.)

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def solution(s):
    answer = len(s)
    for i in range(1,len(s)//2+1):
        tmp = compress(i,s)
        answer = min(answer,tmp)
    return answer
 
 
def compress(num,s):
    ans = ''
    i = 0
    j = num
    cnt = 1
    while i<len(s):
        if s[i:i+num] == s[j:j+num]:
            cnt += 1
            j += num
            if j + num > len(s):
                ans = ans + str(cnt) + s[i:i+num] if cnt != 1 else ans + s[i:i+num]
                ans += s[j:]
                break
        else:
            ans = ans + str(cnt) + s[i:i+num] if cnt != 1 else ans + s[i:i+num]
            i = j
            j += num
            cnt=1
            
    return len(ans)
cs

Line 3 : 압축은 1개부터 문자열의 절반까지만 수행합니다.

Line 11 : i는 기준 문자열의 시작점입니다.

Line 12 : j는 비교할 문자열의 시작점입니다. 처음에는 s[0:num]과 s[num:num+num]을 비교하게 됩니다.

Line 13 : cnt는 기준 문자열이 반복되는 횟수입니다. 반복되는 문자열이 없는 경우에는 1이 됩니다.

Line 14 : 기준 문자열의 시작점이 문자열보다 커지면 중단합니다.

Line 15 : 기준 문자열이 반복되면 cnt에 1을 더해주고, j에 num을 더해 다음 문자열을 기준 문자열과 비교합니다.

Line 19 : cnt가 1인 경우에는 쓰지 않습니다.

Line 20 : 위의 과정4인 남는 문자열을 씁니다.

 

문제 링크

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 어피치는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자

programmers.co.kr

 

반응형
반응형

문제 풀이

1. 달팽이는 아래방향, 오른쪽 방향, 대각선(왼쪽 위) 방향 이 세가지를 번갈아 움직입니다.

  - 따라서 방향을 바꿀 때마다 check 변수에 1씩 더해주며, check mod 3이 방향이 됩니다.

2. 편의상 정사각형에서 움직인다고 생각하고 풀었습니다.

3. 아래로 움직일 때의 경우의 수를 생각해보면 다음과 같습니다.

  3-1) 끝까지 왔거나, 아래 방향의 칸이 0이 아닌 경우 : 방향을 오른쪽으로 바꾼 후, 오른쪽으로 한칸 움직인 후, 해당 칸을 현재 값으로 바꿔줍니다..

  3-2) 아래 방향의 칸의 값이 0인 경우 : 아래로 이동 후, 아래 칸의 값을 현재 값으로 바꿔줍니다.

4. 3의 과정을 오른쪽 방향, 대각선 방향에 대해서도 구현해 줍니다.

5. 밑변의 길이가 n일 때, 총 칸의 수 tot(n)은 다음의 재귀식으로 나타낼 수 있습니다.

  tot(n) = tot(n-1) + 1 , tot(1) = 1

  예를 들어, n=2일 때의 칸의 수는 tot(1) + 2 = 3이고, n=3일 때의 칸의 수는 tot(3) = tot(2) + 3 = 6입니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def solution(n):
    direction = ['down','right','diagonal']
    check = 0
    answer = []
    square = [[0 for i in range(n)] for j in range(n)]
    i,j = 0,0
    square[j][i] = 1
    tot = sum(i for i in range(1,n+1))
    for s in range(2,tot+1):
        d = direction[check%3]
        if d == 'down':
            if j+1==or square[j+1][i] != 0:
                check += 1
                square[j][i+1= s
                i += 1
            else:
                square[j+1][i] = s
                j += 1
        elif d == 'right':
            if i+1 == n or square[j][i+1!= 0 :
                check += 1
                square[j-1][i-1= s
                j-=1
                i-=1
            else :
                square[j][i+1= s
                i += 1
        else :
            if square[j-1][i-1!= 0:
                check +=1
                square[j+1][i] = s
                j += 1
            else :
                square[j-1][i-1= s
                j -= 1
                i -= 1
    for i,v in enumerate(square):
        answer += v[:i+1]
    return answer
 
 
cs

 

Line 8 : 과정 5의 재귀식을 표현한 값입니다.

Line 37 : 사각형에서 필요한 부분만 잘라 answer에 붙여줍니다.

문제 링크

 

코딩테스트 연습 - 삼각 달팽이

5 [1,2,12,3,13,11,4,14,15,10,5,6,7,8,9] 6 [1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]

programmers.co.kr

 

반응형

+ Recent posts