비밀지도

비밀지도

네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

  1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 “공백”(” ”) 또는 “벽”(”#”) 두 종류로 이루어져 있다.
  2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 “지도 1”과 “지도 2”라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
  3. “지도 1”과 “지도 2”는 각각 정수 배열로 암호화되어 있다.
  4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

secret map

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식

입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1arr2가 들어온다.

  • 1 ≦ n ≦ 16
  • arr1arr2는 길이 n인 정수 배열로 주어진다.
  • 정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 1을 만족한다.

출력 형식

원래의 비밀지도를 해독하여 '#'공백으로 구성된 문자열 배열로 출력하라.

입출력 예제

매개변수
n 5
arr1 [9, 20, 28, 18, 11]
arr2 [30, 1, 21, 17, 28]
출력 ["#####","# # #", "### #", "# ##", "#####"]
매개변수
n 6
arr1 [46, 33, 33 ,22, 31, 50]
arr2 [27 ,56, 19, 14, 14, 10]
출력 ["######", "### #", "## ##", " #### ", " #####", "### # "]
```python
def solution(n, arr1, arr2):
# 들어오는 숫자 배열을 2진법으로 표현하는 방법, 비트 쉬프팅 가능?
# 매 값마다 뒤로 돌려서 비트쉬프팅 하고, 값을 비교하면 된다. 
# 나온 값음 문자열로 맨 처음에 항상 집어 넣으면 된다. 
wall = '#'
white = ' '
# print("사이즈 : ", n)
# print("지도 1 : ", arr1)
# print("지도 2 : ", arr2)

map1 = [0] * n
map2 = [0] * n
answer = [""] * n 

for i in range(n):
    # print (i)
    first = bin(arr1[i])[2:] # 0x1
    second = bin(arr2[i])[2:]
    if len(first) == n:
        map1[i] = first
    else : 
        while len(first) != n: 
            first = '0' + first
            map1[i] = first
    if len(second) == n:
        map2[i] = second
    else : 
        while len(second) != n:
            second = '0' + second
            map2[i] = second
    
for i in range(n):
    # print(i)
    for j in range(n - 1, -1, -1):
        # print(j)
        if map1[i][j] == '0' and map2[i][j] == '0':
            answer[i] = white + answer[i]
        else:
            answer[i] = wall + answer[i]
return answer

```python
# 다른 사람 풀이1
def solution(n, arr1, arr2):
    answer = []
    for i,j in zip(arr1,arr2):
        a12 = str(bin(i|j)[2:])
        a12=a12.rjust(n,'0')
        a12=a12.replace('1','#')
        a12=a12.replace('0',' ')
        answer.append(a12)
    return answer
# 다른 사람 풀이2
import re

def solution(n, arr1, arr2):
    answer = ["#"]*n
    for i in range(0, n):
        answer[i] = str(bin(arr1[i]|arr2[i]))[2:]
        answer[i] = re.sub('1', '#', '0'*(n-len(answer[i]))+answer[i])
        answer[i] = re.sub('0', ' ', answer[i])
    return answer

숫자 문자열과 영단어

문제 설명

img1.png

네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

  • 1478 → “one4seveneight”
  • 234567 → “23four5six7”
  • 10203 → “1zerotwozero3”

이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

숫자 영단어
0 zero
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine

제한사항
  • 1 ≤ s의 길이 ≤ 50
  • s가 “zero” 또는 “0”으로 시작하는 경우는 주어지지 않습니다.
  • return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.

입출력 예
s result
"one4seveneight" 1478
"23four5six7" 234567
"2three45sixseven" 234567
"123" 123

입출력 예 설명

입출력 예 #1

  • 문제 예시와 같습니다.

입출력 예 #2

  • 문제 예시와 같습니다.

입출력 예 #3

  • “three”는 3, “six”는 6, “seven”은 7에 대응되기 때문에 정답은 입출력 예 #2와 같은 234567이 됩니다.
  • 입출력 예 #2와 #3과 같이 같은 정답을 가리키는 문자열이 여러 가지가 나올 수 있습니다.

입출력 예 #4

  • s에는 영단어로 바뀐 부분이 없습니다.

제한시간 안내
  • 정확성 테스트 : 10초
# 내가 푼 방법 
def solution(s):
    answer = 0
    
    # 일부 자리수 영단어로 바뀜 
    # 문자열 제공, 원래 숫자를 return 하는 솔루션 만들기
    
    # 길이만큼 돈다 
    # 해당 위치가 숫자인지, 문자인지 파악한다 
    # 해당 위치가 숫자라면 기존값에 곱하기 10을 한 뒤 더하기 해준다. 
    # 해당 위치가 숫자가 아니라면, 그 값의 영단어를 탐색한 뒤, 위치까지를 점프를 하고, 기존 값에 대해 수정한다. 
    
    num_dict = {
        "zero": 0,
        "one": 1,
        "two": 2,
        "three": 3,
        "four": 4,
        "five": 5,
        "six": 6,
        "seven": 7,
        "eight": 8,
        "nine": 9
    }
    
    word = ""
    
    def addNumber(answer, number):
        answer = answer * 10 + number
        return answer 
        
    def wordLmit(word, number):
        if (len(word) > number):
            word = word[number:]
        else:
            word = ""
        return word
    
    for char in s:
        if char.isdigit():
            while len(word) != 0:
                if (word[0] == 'z'):
                    word = wordLmit(word, 4)
                    answer = addNumber(answer, num_dict["zero"])
                elif (word[0] == 'o'):
                    word = wordLmit(word, 3)
                    answer = addNumber(answer, num_dict["one"])
                elif (word[0] == 't'):
                    if word[1] == 'w':
                        word = wordLmit(word, 3)
                        answer = addNumber(answer, num_dict["two"])
                    else:
                        word = wordLmit(word, 5)
                        answer = addNumber(answer, num_dict["three"])
                elif (word[0] == 'f'):
                    if word[1] == 'o':
                        answer = addNumber(answer, num_dict["four"])
                    else:
                        answer = addNumber(answer, num_dict["five"])
                    word = wordLmit(word, 4)
                elif (word[0] == 's'):
                    if word[1] == 'i':
                        word = wordLmit(word, 3)   
                        answer = addNumber(answer, num_dict["six"])
                    else: 
                        word = wordLmit(word, 5)
                        answer = addNumber(answer, num_dict["seven"])
                elif (word[0] == 'e'):
                    word = wordLmit(word, 5)
                    answer = addNumber(answer, num_dict["eight"])
                else : # nine
                    word = wordLmit(word, 4)
                    answer = addNumber(answer, num_dict["nine"])
            answer = addNumber(answer, int(char))
        else:
            word = word + char
            
    if len(word) != 0:
        while len(word) != 0:
            if (word[0] == 'z'):
                word = wordLmit(word, 4)
                answer = addNumber(answer, num_dict["zero"])
            elif (word[0] == 'o'):
                word = wordLmit(word, 3)
                answer = addNumber(answer, num_dict["one"])
            elif (word[0] == 't'):
                if word[1] == 'w':
                    word = wordLmit(word, 3)
                    answer = addNumber(answer, num_dict["two"])
                else:
                    word = wordLmit(word, 5)
                    answer = addNumber(answer, num_dict["three"])
            elif (word[0] == 'f'):
                if word[1] == 'o':
                    answer = addNumber(answer, num_dict["four"])
                else:
                    answer = addNumber(answer, num_dict["five"])
                word = wordLmit(word, 4)
            elif (word[0] == 's'):
                if word[1] == 'i':
                    word = wordLmit(word, 3)   
                    answer = addNumber(answer, num_dict["six"])
                else: 
                    word = wordLmit(word, 5)
                    answer = addNumber(answer, num_dict["seven"])
            elif (word[0] == 'e'):
                word = wordLmit(word, 5)
                answer = addNumber(answer, num_dict["eight"])
            else : # nine
                word = wordLmit(word, 4)
                answer = addNumber(answer, num_dict["nine"])
    
    return answer
# 다른 사람 방법
num_dic = {"zero":"0", "one":"1", "two":"2", "three":"3", "four":"4", "five":"5", "six":"6", "seven":"7", "eight":"8", "nine":"9"}

def solution(s):
    answer = s
    for key, value in num_dic.items():
        answer = answer.replace(key, value)
    return int(answer)

신규 아이디 추천

문제 설명

카카오에 입사한 신입 개발자 네오는 “카카오계정개발팀”에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. “네오”에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.

  • 아이디의 길이는 3자 이상 15자 이하여야 합니다.
  • 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
  • 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.

“네오”는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

예를 들어, new_id 값이 ”…!@BaT#*..y.abcdefghijklm” 라면, 위 7단계를 거치고 나면 new_id는 아래와 같이 변경됩니다.

1단계 대문자 ‘B’와 ‘T’가 소문자 ‘b’와 ‘t’로 바뀌었습니다.
"...!@BaT#*..y.abcdefghijklm" → "...!@bat#*..y.abcdefghijklm"

2단계 ’!’, ’@’, ’#’, ’*’ 문자가 제거되었습니다.
"...!@bat#*..y.abcdefghijklm" → "...bat..y.abcdefghijklm"

3단계 ’…’와 ’..’ 가 ’.’로 바뀌었습니다.
"...bat..y.abcdefghijklm" → ".bat.y.abcdefghijklm"

4단계 아이디의 처음에 위치한 ’.’가 제거되었습니다.
".bat.y.abcdefghijklm" → "bat.y.abcdefghijklm"

5단계 아이디가 빈 문자열이 아니므로 변화가 없습니다.
"bat.y.abcdefghijklm" → "bat.y.abcdefghijklm"

6단계 아이디의 길이가 16자 이상이므로, 처음 15자를 제외한 나머지 문자들이 제거되었습니다.
"bat.y.abcdefghijklm" → "bat.y.abcdefghi"

7단계 아이디의 길이가 2자 이하가 아니므로 변화가 없습니다.
"bat.y.abcdefghi" → "bat.y.abcdefghi"

따라서 신규 유저가 입력한 new_id가 ”…!@BaT#*..y.abcdefghijklm”일 때, 네오의 프로그램이 추천하는 새로운 아이디는 “bat.y.abcdefghi” 입니다.


[문제]

신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, “네오”가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.

[제한사항]

new_id는 길이 1 이상 1,000 이하인 문자열입니다.
new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.


[입출력 예]
no new_id result
예1 "...!@BaT#*..y.abcdefghijklm" "bat.y.abcdefghi"
예2 "z-+.^." "z--"
예3 "=.=" "aaa"
예4 "123_.def" "123_.def"
예5 "abcdefghijklmn.p" "abcdefghijklmn"
입출력 예에 대한 설명

입출력 예 #1
문제의 예시와 같습니다.

입출력 예 #2
7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.

1단계 변화 없습니다.
2단계 "z-+.^." → "z-.."
3단계 "z-.." → "z-."
4단계 "z-." → "z-"
5단계 변화 없습니다.
6단계 변화 없습니다.
7단계 "z-" → "z--"

입출력 예 #3
7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.

1단계 변화 없습니다.
2단계 "=.=" → "."
3단계 변화 없습니다.
4단계 "." → "" (new_id가 빈 문자열이 되었습니다.)
5단계 "" → "a"
6단계 변화 없습니다.
7단계 "a" → "aaa"

입출력 예 #4
1단계에서 7단계까지 거치는 동안 new_id(“123_.def”)는 변하지 않습니다. 즉, new_id가 처음부터 카카오의 아이디 규칙에 맞습니다.

입출력 예 #5
1단계 변화 없습니다.
2단계 변화 없습니다.
3단계 변화 없습니다.
4단계 변화 없습니다.
5단계 변화 없습니다.
6단계 "abcdefghijklmn.p" → "abcdefghijklmn." → "abcdefghijklmn"
7단계 변화 없습니다.

# 내 풀이 방식
import re

def solution(new_id):
    answer = new_id
    # 1
    if len(answer) != 0:
        answer = answer.lower()
    # print("1 : ",answer)
    # 2
    if len(answer) != 0:
        answer = re.sub("[^a-zA-Z0-9_.-]", "", answer)
    # print("2 : ",answer)
    # 3
    if len(answer) != 0:
        while ".." in answer:
            answer = answer.replace("..", ".")
    # print("3 : ",answer)
    # # 4 
    if len(answer) != 0:
        if answer[0] == '.':
            answer = answer[1:]
        if len(answer) > 0 and answer[-1] == '.':
            answer = answer[0:len(answer)-1]
    # print("4 : ",answer)
    # # 5
    if len(answer) == 0:
        answer = "a"
    # print("5 : ",answer)
    # # 6
    if len(answer) != 0:
        if len(answer) >= 16:
            answer = answer[0:15]
            if  answer[14] == '.':
                answer = answer[0:14]
    # print("6 : ",answer)
    # # 7
    if len(answer) != 0:
        if len(answer) <= 2:
            while len(answer) < 3:
                answer = answer + answer[-1]
    # print("7 : ",answer)

    
    return answer
# 남이 푼 방법 1 - 정규식 마스터 
import re

def solution(new_id):
    st = new_id
    st = st.lower()
    st = re.sub('[^a-z0-9\-_.]', '', st)
    st = re.sub('\.+', '.', st)
    st = re.sub('^[.]|[.]$', '', st)
    st = 'a' if len(st) == 0 else st[:15]
    st = re.sub('^[.]|[.]$', '', st)
    st = st if len(st) > 2 else st + "".join([st[-1] for i in range(3-len(st))])
    return st

# 남이 푼 방법 2 - 컴프리헨션 마스터 
def solution(new_id):
    answer = ''
    # 1
    new_id = new_id.lower()
    # 2
    for c in new_id:
        if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
            answer += c
    # 3
    while '..' in answer:
        answer = answer.replace('..', '.')
    # 4
    if answer[0] == '.':
        answer = answer[1:] if len(answer) > 1 else '.'
    if answer[-1] == '.':
        answer = answer[:-1]
    # 5
    if answer == '':
        answer = 'a'
    # 6
    if len(answer) > 15:
        answer = answer[:15]
        if answer[-1] == '.':
            answer = answer[:-1]
    # 7
    while len(answer) < 3:
        answer += answer[-1]
    return answer

가장 많이 받은 선물

문제 설명

선물을 직접 전하기 힘들 때 카카오톡 선물하기 기능을 이용해 축하 선물을 보낼 수 있습니다. 당신의 친구들이 이번 달까지 선물을 주고받은 기록을 바탕으로 다음 달에 누가 선물을 많이 받을지 예측하려고 합니다.

  • 두 사람이 선물을 주고받은 기록이 있다면, 이번 달까지 두 사람 사이에 더 많은 선물을 준 사람이 다음 달에 선물을 하나 받습니다.
    • 예를 들어 A가 B에게 선물을 5번 줬고, B가 A에게 선물을 3번 줬다면 다음 달엔 A가 B에게 선물을 하나 받습니다.
  • 두 사람이 선물을 주고받은 기록이 하나도 없거나 주고받은 수가 같다면, 선물 지수가 더 큰 사람이 선물 지수가 더 작은 사람에게 선물을 하나 받습니다.
    • 선물 지수는 이번 달까지 자신이 친구들에게 준 선물의 수에서 받은 선물의 수를 뺀 값입니다.
    • 예를 들어 A가 친구들에게 준 선물이 3개고 받은 선물이 10개라면 A의 선물 지수는 -7입니다. B가 친구들에게 준 선물이 3개고 받은 선물이 2개라면 B의 선물 지수는 1입니다. 만약 A와 B가 선물을 주고받은 적이 없거나 정확히 같은 수로 선물을 주고받았다면, 다음 달엔 B가 A에게 선물을 하나 받습니다.
    • 만약 두 사람의 선물 지수도 같다면 다음 달에 선물을 주고받지 않습니다.

위에서 설명한 규칙대로 다음 달에 선물을 주고받을 때, 당신은 선물을 가장 많이 받을 친구가 받을 선물의 수를 알고 싶습니다.

친구들의 이름을 담은 1차원 문자열 배열 friends 이번 달까지 친구들이 주고받은 선물 기록을 담은 1차원 문자열 배열 gifts가 매개변수로 주어집니다. 이때, 다음달에 가장 많은 선물을 받는 친구가 받을 선물의 수를 return 하도록 solution 함수를 완성해 주세요.


제한사항
  • 2 ≤ friends의 길이 = 친구들의 수 ≤ 50
    • friends의 원소는 친구의 이름을 의미하는 알파벳 소문자로 이루어진 길이가 10 이하인 문자열입니다.
    • 이름이 같은 친구는 없습니다.
  • 1 ≤ gifts의 길이 ≤ 10,000
    • gifts의 원소는 "A B"형태의 문자열입니다. A는 선물을 준 친구의 이름을 B는 선물을 받은 친구의 이름을 의미하며 공백 하나로 구분됩니다.
    • A와 B는 friends의 원소이며 A와 B가 같은 이름인 경우는 존재하지 않습니다.

입출력 예
friends gifts result
[“muzi”, “ryan”, “frodo”, “neo”] [“muzi frodo”, “muzi frodo”, “ryan muzi”, “ryan muzi”, “ryan muzi”, “frodo muzi”, “frodo ryan”, “neo muzi”] 2
[“joy”, “brad”, “alessandro”, “conan”, “david”] [“alessandro brad”, “alessandro joy”, “alessandro conan”, “david alessandro”, “alessandro david”] 4
[“a”, “b”, “c”] [“a b”, “b a”, “c a”, “a c”, “a c”, “c a”] 0

입출력 예 설명

입출력 예 #1

주고받은 선물과 선물 지수를 표로 나타내면 다음과 같습니다.

↓준 사람 \ 받은 사람→ muzi ryan frodo neo
muzi - 0 2 0
ryan 3 - 0 0
frodo 1 1 - 0
neo 1 0 0 -
이름 준 선물 받은 선물 선물 지수
muzi 2 5 -3
ryan 3 1 2
frodo 2 2 0
neo 1 0 1

muzi는 선물을 더 많이 줬던 frodo에게서 선물을 하나 받습니다.
ryan은 선물을 더 많이 줬던 muzi에게서 선물을 하나 받고, 선물을 주고받지 않았던 neo보다 선물 지수가 커 선물을 하나 받습니다.
frodo는 선물을 더 많이 줬던 ryan에게 선물을 하나 받습니다.
neo는 선물을 더 많이 줬던 muzi에게서 선물을 하나 받고, 선물을 주고받지 않았던 frodo보다 선물 지수가 커 선물을 하나 받습니다.

다음달에 가장 선물을 많이 받는 사람은 ryan과 neo이고 2개의 선물을 받습니다. 따라서 2를 return 해야 합니다.

입출력 예 #2

주고받은 선물과 선물 지수를 표로 나타내면 다음과 같습니다.

↓준 사람 \ 받은 사람→ joy brad alessandro conan david
joy - 0 0 0 0
brad 0 - 0 0 0
alessandro 1 1 - 1 1
conan 0 0 0 - 0
david 0 0 1 0 -
이름 준 선물 받은 선물 선물 지수
joy 0 1 -1
brad 0 1 -1
alessandro 4 1 3
conan 0 1 -1
david 1 1 0

alessandro가 선물을 더 많이 줬던 joybradconan에게서 선물을 3개 받습니다. 선물을 하나씩 주고받은 david보다 선물 지수가 커 선물을 하나 받습니다.
david는 선물을 주고받지 않았던 joybradconan보다 선물 지수가 커 다음 달에 선물을 3개 받습니다.
joybradconan은 선물을 받지 못합니다.

다음달에 가장 선물을 많이 받는 사람은 alessandro이고 4개의 선물을 받습니다. 따라서 4를 return 해야 합니다.

입출력 예 #3

a와 ba와 cb와 c 사이에 서로 선물을 주고받은 수도 같고 세 사람의 선물 지수도 0으로 같아 다음 달엔 아무도 선물을 받지 못합니다. 따라서 0을 return 해야 합니다.

# 내가 푼 방식 
def solution(friends, gifts):
    friendsList = {string: i for i, string, in enumerate(friends, start=0)}
    
    oldGiftList = [[0 for _ in range(len(friends))] for _ in range(len(friends))] 
    newGiftList = [[0 for _ in range(len(friends))] for _ in range(len(friends))] 
    giftLevel = [[0 for _ in range(3)] for _ in range(len(friends))]
    newGiftLevel = [[0 for _ in range(3)] for _ in range(len(friends))]
    
    for takeOver in gifts:
        names = takeOver.split()
        oldGiftList[friendsList[names[0]]][friendsList[names[1]]] += 1
    
    # 준선물 / 받은 선물
    for receiver in friendsList:
        for sender in friendsList:
            if receiver == sender:
                continue
            else:
                r = friendsList[receiver]
                s = friendsList[sender]
                giftLevel[s][0] += oldGiftList[s][r]
                giftLevel[r][1] += oldGiftList[s][r]
                
    for man in friendsList:
        target = friendsList[man]
        giftLevel[target][2] = giftLevel[target][0] - giftLevel[target][1]

    for sender in friendsList:
        for receiver in friendsList:    
            if receiver == sender:
                continue
            else:
                s = friendsList[sender]
                r = friendsList[receiver]
                A = oldGiftList[s][r]
                B = oldGiftList[r][s]
                if (A != 0 or B != 0) and (A != B) :
                    if (A < B):
                        newGiftList[s][r] += 1
                elif A == B or (A == 0 and B == 0):
                    if giftLevel[s][2] < giftLevel[r][2]:
                        newGiftList[s][r] += 1
                newGiftLevel[s][0] += newGiftList[s][r]
                newGiftLevel[r][1] += newGiftList[s][r]
                


    def printL(str, target, number):
        print(str, " : ")
        for i in range(number):
            print(target[i])
        
    # printL("old List", oldGiftList, len(friends))
    # printL("gift Level", giftLevel, len(friends))
    # printL("new List", newGiftList, len(friends))
    # printL("new gift Level",newGiftLevel, len(friends))
    
    answer = newGiftLevel[0][1]
    
    for i in range(1, len(friendsList) ):
        answer = max(answer, newGiftLevel[i][1])
    
    
#     문자열 딕셔너리에서 찾아내는 방법
#     value = friendsList[friends[2]]
#     print(value)
    
    # A -> B , B -> A 많은 방향성과 반대로 줘야함 
    # 주고 받은 기록 0, 수가 같으면 선물 지수가 큰 쪽이 선물 지수 작은쪽에서 줌 
        # 선물지수 = 자신이 친구들에게 준 선물의 수 - 받은 선물의 수 뺀값
        # 선물 지수가 서로 같으면 -> 선물 안줌
    # 다음달 선물 가장 많이 받을 사람을 알고 싶다. 
    
    # 1) 전체 선물 횟수를 나타내는 이차원 배열 구성
    # 2) 선물 지수 계산
    # 3) 전체 선물 횟수를 돌면서, 조건식을 확인하여 미래의 경우를 지정
    # 4) 미래의 경우중 가장 큰 값으로 받는 경우를 확인
    return answer