1) 문제

 클릭▼


    2-1) 코드

      (내 코드)


    2-2) 코드 & 코드 설명

      (개인적으로 좋아하는 코드)

 

 

for i, j, k in commands:
	answer.append(list(sorted(array[i-1:j]))[k-1])

     # commands 에서 i, j, k 를 출력해보자.

     # 이해하기 쉽게 i,  j, k 를 하나씩 출력해보자.

     # answer.append(list(sorted(array[i-1:j]))[k-1]) 를 쪼개서 살펴보면 우선 array를 [k-1:j] 로 슬라이싱                     해서 출력해보자.

     # i-1로 하는 이유는 인덱스는 0부터 시작하므로 array = [1, 5, 2, 6, 3, 7, 4] 에서 2번째 숫자는 5이고                           인덱스로 나타면 array[1]의 위치이기 때문에 i-1로 슬라이싱 한다.                                                                         # j는 -1을 하지 않는 이유는 슬라이싱 할때 만약 array[1:5] 라면 밑에 그림과 같이array 1번째 ~ 4번째                          까지 출력되기 때문에 j에는 -1을 할 필요가 없다.

     # sorted() 함수는 숫자를 순서대로 정렬해주는 함수이다.

     # 슬라이싱한 리스트에서 [k-1] 번째 숫자를 출력한다. i와 마찬가지로 -1을 해준다.

     # 위의 출력 결과를 좀 더 쉽게 설명하면 슬라이싱해서 sorted() 한 결과 [2, 3, 5, 6]를  apple 변수에 넣고                      apple의 [k-1]번째 즉, apple[2]의 결과를 출력하라는 의미이다.

 

1) 문제

클릭▼


2) 문제 설명 (이진법 계산)

 

 

# 이진법(二進法, binary)은 두 개의 숫자(0과 1)만을 이용하는 수 체계이다. 컴퓨터는 수를 표현할 때 두 가지

   수로 표현하는데 그것이 바로 0과 1이며, 이렇게 0과 1만으로 수를 표현하는 것을 ‘이진수’라고 한다. 

# ↑위에 그림을 보면 공백을 0, '#'을 1로 나타내서 지도 옆에 2진수로(01001, 10100.. ) 나타내고 그 숫자를

    10진수로 변환 한 값을 나타내고 있다.

# 우리가 일상생활에서 읽는 수를 10진수인데 위에 문제에서 2진수 값을 10진수를 변환 한 것이다. 즉, 2진수 

는 10진수로 변환하면 9이다.

 

2진수 -> 10진수 변환방법은?

# 2진수는 오른쪽에서 왼쪽으로 나타낸다.

 

 

# 예를 들어 01001 이라면 1이 있는 자리의 숫자만 더해서 계산하면 8+1 = 9가 된다.

 

 

# 동일한 방법으로 10100 은 16+4 = 20이 되고 11100은 16+8+4 = 28이 된다

 

 


3) 코드

('좋아요' 수 제일 많은 풀이)

 

 


4) 코드 설명

① answer = [ ]

# 결과를 넣어서 출력할 빈 리스트 answer를 만들어 준다.

② for i, j in zip(arr1, arr2):

# zip() 함수는 동일한 개수(arr1와 arr2의 길이가 같다.)로 이루어진 자료형을 묶어 주는 역할을 한다.

  여러 개의 iterable 객체를 받은 후 자료형 들을 묶어서 튜플 형태로 출력해준다. 

# iterable 이란 반복 가능하다는 뜻인데 한번에 하나씩 자료를 반환할 수 있는 파이썬 객체이다. 

  간단히 말해 for문으로 그 값을 출력 할 수 있는 것을 의미하며 리스트, 튜플, 딕셔너리 등을 말한다.

 

 

 

 

# ↑위의 결과를 보면 리스트 arr1과 리스트 arr2를 zip 함수로 묶어서 리스트 arr1의 요소를 i로,

   리스트 arr2의 요소를 j로 해서 print(i, j)를 하면 각 list의 동일한 index 끼리 짝지어서 출력된다.

 

③ a12 = str(bin(i|j)[2:])

 

# bin() 함수는 10진수 숫자를 2진수(binary)로 변환해주는 함수이다.

# 예를들어 10진수 숫자 28을 bin() 함수에 넣어서 출력을 하면 '0b11100'이 된다.

# 여기서 '0b'는 2진수를 뜻한다. ( '0o' = 8진수, '0x' = 16진수 )

# 우리는 '0b'를 뺀 11100만 사용하니 [2:] 즉, 인덱스 2번째 부터 사용한다. (인덱스는 0부터 시작)

 

 

 

 

# bin(i|j) 여기서 의 의미는 논리 연산자(logical operator) OR을 의미한다.

# OR두 비트 a, b 중 하나라도 1 이면 결과는 1이고 a, b 둘다 0 일때만 0이다.

# 그림을 보면 더 쉽게 이해가 된다.

 

 

 

 

# 그럼 bin(i|j) 의 연산은 우선 i, j를 2진수로 변환한 후 i, j를 OR 연산 시킨다. 

 

 

 

 

# 연산 방법을 보면 arr1의 첫번째 요소인 46을 bin()을 사용하여 2진수로 변환하면 101110 = bin(i)이 된다.

# arr2의 첫번빼 요소인 27을 bin()을 사용하여 2진수로 변환하면 11011 = bin(j) 이 된다.

# 그 다음 OR 연산으로 이 두 이진수를 오른쪽 정렬하여 bin(i), bin(j)중 하나라도 1이 있으면 1을 반환한다.

# 숫자가 없다면(빈칸) 두 비트 중 하나라도 1이 있으면 1을 반환하고 아니면 0을 반환한다.

 

 

④ a12 = a12.rjust(n,'0')

 

# rjust() 는 숫자를 오른쪽으로 정렬 시키는 함수이다.

# rjust(전체 자리 숫자, 공백이 있을 경우 공백을 채울 텍스트) 로 정의한다.

# rjust(n,'0')는 n 길이만큼 공백에 '0' 을 채워 넣으라는 뜻이다.

# OR 연산 후 a12를 출력해보자.

 

 

 

# 위의 출력 결과를 보면 길이가 맞지 않은것을 볼 수 있다.

   (1, 2, 3, 6번째는 길이가 6인데, 4, 5번째 결과는 길이가 5)

 

 

 

# 위의 결과에서 보듯 n이 6이므로 길이를 모두 6으로 맞추고 공백은 '0'으로 채우고 오른쪽 정렬을 했다.

 

⑤  a12=a12.replace('1','#')
     a12=a12.replace('0',' ')

# replace() 는 특정값을 다른값으로 바꿔주는 함수이다.

# replace("찾을문자열", "바꿀문자열")로 정의한다.

# replace('1',#') 문자열에서 1을 찾아 '#'으로 바꾸고, replace('0',' ') 문자열에서 0을 찾아 공백으로 바꾼다.

 

⑥ answer.append(a12)

# a12의 결과 값을 append() 메소드를 사용하여 리스트 answer에 추가한다.

# 그다음 return answer 하여 정답을 출력한다.

1) 문제

클릭▼


2) 코드

 (개인적으로 좋아하는 다른 사람 코드)

출처 : https://velog.io/@fftl/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B1%B0%EB%A6%AC%EB%91%90%EA%B8%B0-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0-%ED%8C%8C%EC%9D%B4%EC%8D%AC 

 

def solution(places):
    answer = []
    for p in places:
        key = False
        nowArr = []
        for n in p:
            nowArr.append(list(n))
        for i in range(5):
            if key:
                break;
            for j in range(5):
                if key:
                    break;
                if nowArr[i][j] == "P":
                    if i+1<5:
                        if nowArr[i+1][j] == "P":
                            key = True;
                            break;
                        elif nowArr[i+1][j] == "O":
                            if i+2<5:
                                if nowArr[i+2][j] == "P":
                                    key = True;
                                    break;
                    if j+1<5:
                        if nowArr[i][j+1] == "P":
                            key = True;
                            break;
                        if nowArr[i][j+1] == "O":
                            if j+2<5:
                                if nowArr[i][j+2] == "P":
                                    key = True;
                                    break;
                    if i+1<5 and j+1<5:
                            if nowArr[i+1][j+1] == "P" and (nowArr[i+1][j] == "O" or nowArr[i][j+1] == "O"):
                                key = True;
                                break;
                    if i+1<5 and j-1>=0:
                            if nowArr[i+1][j-1] == "P" and (nowArr[i+1][j] == "O" or nowArr[i][j-1] == "O"):
                                key = True;
                                break;
        if key:
            answer.append(0);
        else:
            answer.append(1);
                                             
    return answer

3) 결과


3) 코드 설명

    for p in places:
        key = False
        nowArr = []
        for n in p:
            nowArr.append(list(n))

 

- key는 거리두기가 지켜지지 않음을 확인하면 바로 반복을 멈추기 위해 사용되고 처음에는 False로 둔다. 

  ( key = True는 거리두기가 지켜지고 있지 않다. key = False 거리두기가 잘 지켜지고 있다. )

- places의 요소를 하나씩 꺼내보면 아래의 결과가 나온다.

 

 

 

 

- p의 요소를 하나씩 꺼내서 nowArr에 넣고 결과를 출력하면 아래와 같이 나온다. 

 

 

 

- 하지만 우리는 알파벳 하나씩을 사용해야 하기때문에 리스트 형식으로 nowArr에 넣어야 한다.

 

 

- 그럼 첫번째 줄 부터 matrix 형태로 나타내보자.

 

 

 

 

        for i in range(5):
            if key:
                break;
            for j in range(5):
                if key:
                    break;

 

- i = 0, 1, 2, 3, 4 그리고 j = 0, 1, 2, 3, 4 를 사용하면 for문을 돌린다

- 만약에 key가 있다면 ( key = True ) break를 하라고 했지만 현재는 False 이므로 for문을 돌린다.

 

                if nowArr[i][j] == "P":
                    if i+1<5:
                        if nowArr[i+1][j] == "P":
                            key = True;
                            break;
                        elif nowArr[i+1][j] == "O":
                            if i+2<5:
                                if nowArr[i+2][j] == "P":
                                    key = True;
                                    break;
                    if j+1<5:
                        if nowArr[i][j+1] == "P":
                            key = True;
                            break;
                        if nowArr[i][j+1] == "O":
                            if j+2<5:
                                if nowArr[i][j+2] == "P":
                                    key = True;
                                    break;
                    if i+1<5 and j+1<5:
                            if nowArr[i+1][j+1] == "P" and (nowArr[i+1][j] == "O" or nowArr[i][j+1] == "O"):
                                key = True;
                                break;
                    if i+1<5 and j-1>=0:
                            if nowArr[i+1][j-1] == "P" and (nowArr[i+1][j] == "O" or nowArr[i][j-1] == "O"):
                                key = True;
                                break;

 

 

- if nowArr[i][j] == "P" 이면 그 뒤로 오는 for문을 돌린다.

- i = 0, j = 0 을 넣고 nowArr[0][0] 값을 확인한다.

 

 

 

 

 

 

- 위의 표와 같이 nowArr[0][0] 값은 "P" 이다. 그럼 i = 0, j = 0 을 가지고 for문을 돌린다.

 

 

 

 

- 위에 그림에서 을 보면 0 + 1 < 5 가 성립하므로 로 간다.

- 의 결과를 보면 nowArr[0+1][0] 는 "P"가 아니므로 elif로 간다.

- 의 결과를 보면  nowArr[0+1][0] == "O" 이므로 로 간다.

- 에서 0 + 2 < 5가 성립하지만 nowArr[0+2][0] 은 "P" 가 아니라 "O" 이므로 key는 바뀌지 않고 False 이다.

 

 

 

 

- 위에 그림에서을 보면 0 + 1 < 5 가 성립하므로 로 간다.

- 의 결과를 보면 nowArr[0][0+1] 는 "P"가 아니므로 로 간다.

- 의 결과를 보면  nowArr[0][0+1] == "O" 이므로 로 간다.

- 에서 0 + 2 < 5가 성립하므로 nowArr[0][0+2] 은 "P" 가 아니라 "O" 이므로 key는 바뀌지 않고 False 이다.

 

 

 

- 위에 그림에서 을 보면 i = 0, j = 0 이므로 0 + 1 < 5, 0 + 1 < 5가 성립한다. 으로 간다. 

- 을 보면 nowArr[0+1][0+1]의 값이 "P"가 아니므로 로 간다. 

- 에서 0 + 1 < 5 and 0 -1 >= 0 이 성립하지 않으므로 로 가지 않는다. 

- key는 바뀌지 않고 False 이다.

★★

- 사실 ⑨ ~ ⑫ 코드는 좌측 제일 밑 부분과 우측 제일 밑 부분을 위한 코드이다. (밑에 노란색 부분)

 

 

 

- 예를들어 ↓ 리스트의 녹색 부분을 보면 nowArr[3][3] == "P" 이고 대각선으로 nowArr[4][4] == "P" 이므로 

  거리두기가 지켜지지 않았다.

 

 

 

- 자 그럼 i = 3, j = 3으로 for문을 돌려보자.

 

 

 

 

- 위에 그림에서 을 보면 3 + 1 < 5 가 성립하므로 로 간다.

- 의 결과를 보면 nowArr[3+1][3] 는 "P"가 아니므로  elif로 간다.

- 의 결과를 보면  nowArr[3+1][3] == "O" 이므로 로 간다.

- 에서 3 + 2 < 5가 성립하지 않으므로 밑에 if문이 돌아가지 않고 key는 바뀌지 않고 False 이다.

 

 

 

 

- 위에 그림에서 을 보면 3 + 1 < 5 가 성립하므로 로 간다.

- 의 결과를 보면 nowArr[3][3+1] 는 "P"가 아니므로 로 간다.

- 의 결과를 보면  nowArr[3][3+1] == "O" 이므로 로 간다.

- 에서 3 + 2 < 5가 성립하지 않으므로 밑에 if문이 돌아가지 않고 key는 바뀌지 않고 False 이다.

- 여기까지만 보면 이 리스트가 거리두기가 지켜지지 않고 있다는것을 찾아 낼 수가 없다.

 

 

 

 

- 위에 그림에서 을 보면 3 + 1 < 5, 3 + 1 < 5가 성립한다. 으로 간다. 

- 을 보면 nowArr[3+1][3+1]의 값이 "P"이고  nowArr[3+1][3] == "O", nowArr[3][3+1] == "O" 이므로

   여기서 key = True로 바뀌면서 break가 걸렸다. 

 

- 그럼 이제 i = 0, j = 0일때는 끝나고 i = 0, j = 1 부터 다시 보도록 하자.

 

 

 

- i = 0, j = 4 일때 "P" 이므로 i = 0, j = 4 을 이용하여 계산해보자.

 

 

 

 

- 위에 그림에서 을 보면 0 + 1 < 5 가 성립하므로 로 간다.

- 의 결과를 보면 nowArr[0+1][4] 는 "P"가 아니므로  elif로 간다.

- 의 결과를 보면  nowArr[0+1][4] 는 "O" 이므로 로 가지않는다.

- key는 바뀌지 않고 False 이다.

 

 

 

 

- 위에 그림에서 을 보면 j = 4 이므로 4 + 1 < 5 가 성립하지 않아 ⑧ 로 가지 않는다.

- key는 바뀌지 않고 False 이다.

 

 

 

 

- 위에 그림에서 을 보면 j = 4 이므로 4 + 1 < 5가 성립되지 않는다. 으로 가지않고 로 간다. 

- ⑪ 에서 0 + 1 < 5 and 4 -1 >= 0 이 성립하므로 로 간다.

- 의 결과를 보면 nowAr[i+1][j-1]의 값이 "P" 가 아니므로 key는 바뀌지 않고 False 이다.

 

 

1) 문제

클릭▼


2) 코드

 (개인적으로 좋아하는 다른 사람 코드)

 

 

 


3) 코드 설명

① reserve_only = list(set(reserve) - set(lost))                                                                    lost_only = list(set(lost) - set(reserve))

   

- set() 함수는 집합이란 의미로 중복되지 않은 원소(unique)를 반환한다. 

 

 

- 문제로 다시 돌아가서 제한사항을 보면 중복되는 번호가 없다고 나와 있기에 set() 함수를 사용하여 중복되는    원소를 제거한다.

 

  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.

- reserve와 lost는 중복된 숫자가 없으므로 set(reserve)와 set(lost)를 출력하면 그 숫자 그대로 나온다.

 

 

- 그 다음 reserve_only 와 lost_only를 출력해보자.

- reserve와 lost 둘다 중복되는 숫자가 없으므로 set(reserve) - set(lost) = set(reserve) 가 출력되고

  set(lost) - set(reserve) = set(lost)가 출력된다.

- list 형식으로 변수에 넣어줬으니 list로 출력된다.

 

 

②  reserve_only.sort()

- reserve_only를 올림차순으로 정렬한다.

- 예를들어 reserve = [5,1,3] 을 sort() 사용하여 출력 하였다.

 

 

- 순서대로 [1, 3, 5]로 출력 되었다.

for reserve in reserve_only: 
          front = reserve - 1 
          back = reserve + 1 

 

- 현재 reserve_only에는 [1, 3, 5]가 들어있고 여기에서 요소를 하나씩 꺼내 reserve에 넣은 다음 -1을 해서      front에 넣고 +1을 해서 back에 넣는다.

- for문을 돌려서 front와 back을 출력해보자.

- [1, 3, 5] 에 -1씩 하면 front는 0, 2, 4가 나오고 +1씩 하면 back은 2, 4, 6이 나온다.

 

 

④  if front in lost_only: 
            lost_only.remove(front) 
      elif back in lost_only: 
            lost_only.remove(back)

- 만약 lost_only에 front의 요소가 들어있으면 lost_only에서 그 요소를 remove 해라.

- 만약 lost_only에 back의 요소가 들어있으면 lost_only에서 그 요소를 remove 해라.

- 현재 lost_only 에는 [2, 4]가 들어있고, front는 0, 2, 4 그리고 back에는 2, 4, 6이 들어있다.

- front에 들어있는 요소 2, 4가 lost_only에 들어있으니 두 요소 다 remove 된다.

- 그럼 lost_only에는 아무 요소도 들어있지 않다.

⑤  return n - len(lost_only) 

- n에서 lost_only의 길이 만큼 뺀 결과를 return 해라.

- n = 5 이고, lost_only에는 아무것도 들어있지 않으므로 5 - 0 은 5가 출력된다. 

 


4) 참조

https://coding-grandpa.tistory.com/100

1) 문제

2) 코드

 ('좋아요' 수 제일 많은 풀이)

2) 코드 설명

① bonus = {'S' : 1, 'D' : 2, 'T' : 3}                                                                                                              option = {'' : 1, '*' : 2, '#' : -1}

 - bonus 변수에 딕셔너리로 'S'는 1제곱 이므로 1, 'D'는 2제곱 이므로 2, 'T'는 3제곱 이므로 3을 넣는다.

 - option 변수에 딕셔너리로 ' ' 즉, 아무것도 없을땐 1, '*' 일때 2(두배), '#' 일때 -1(마이너스) 넣는다. 

② p = re.compile('(\d+)([SDT])([*#]?)')

- re 모듈은 정규표현식을 사용할때 쓰는 모듈이다. 

정규표현식(정규식)이란 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 형식 언어이다.

  복잡한 문자열의 검색과 치환을 위해 사용되며, 문자열을 처리하는 모든 곳에서 사용된다.

- 정규표현식을 사용하기 위해 re 모듈을 import 한다.

- 다양한 정규 표현식이 있지만 이 문제에 사용할 기본 표현식만 살펴보자. 

- 참고로 Wd \d와 같은 표현이다. 

 

 

- 그럼 다트 게임 문제의 정규표현식을 보자.             

                             

 

- p = re.compile('검색할문자열') 를 통해서 정규표현식을 컴파일하고, 컴파일된 패턴 객체(p)를 이용하여

  이 객체가 가지고 있는 메서드를 통해 작업을 수행할 수 있다.

- re.compile('(\d+)([SDT])([*#]?)') 에서 ( ) 을 사용하면 그룹이 지어진다.

③ dart = p.findall(dartResult)

- findall() 은 정규식과 매치되는 모든 문자열을 리스트형식으로 리턴한다.

- p.findall(dartResult) 로 dartResult 안에 있는 정규식과 매치되는 문자열을 찾아서 dart 변수에 넣는다.

- dartResult = "1S2D*3T" 와 dartResult = "1D2T#10S" 을 사용해서 dart를 출력해보면 이렇게 된다.

 

 

- (숫자)([SDT])([*#]?) 이렇게 배열이 되어야 하니 "1S2D*3T" 순서대로 출력하면

 

 

- [('1', 'S', ' '), ('2', 'D', '*'), ('3', 'T', ' ')] 한줄씩 리스트의 요소로 해서 출력된다.

- 1과 S 다음에 *, # 없이 바로 숫자 2가 나오므로 그 자리는 공백으로 둔다.

- 마찬가지로 "1D2T#10S" 출력해보면 다음과 같이 된다.

 

 

- [('1', 'D', ' '), ('2', 'T', '#'), ('10', 'S', ' ')] 출력 되는데 마지막 요소 ('10', 'S', ' ') 가 1, 0 이 아닌 10으로 출력 되는

  이유는 \d 는 0 - 9 까지의 숫자인데 뒤에 +가 붙어서 하나 이상의 연결된 숫자이므로 10이 된다.

 

 갑자기 궁금해졌다.

  • ([*#]?) 에서 ? 없이 출력을 하면 어떻게 될까?
  •  dartResult에 [SDT]가 아닌 다른 문자가 포함되어 있다면 어떻게 출력될까?
  •  dartResult 값 앞의 두자리 즉, "1D2T#10S" 의 앞에 두자리를 바꿔서 "D12T#10S" 출력하면 어떻게 될까?
  •  대문자 대신 소문자를 사용하면 즉, "1D2T#10S" 를 "1d2T#10S" 로 바꾸면 어떻게 출력이 될까?

 ▼ 궁금하다면 클릭

더보기

(1) ([*#]?) 에서 없이 출력을 하면 어떻게 될까?

 

 

- 보는 바와 같이 ([*#]?) 에서 없이 출력을 하면 '#' 포함되어 있는 요소만 출력된다.

- 는 정규식 표현으로 '있거나 없거나' 이기 때문에 가 포함되면 *, # 이 없는 요소도 출력 된다.

 

 

 

(2) dartResult에 [SDT]가 아닌 다른 문자가 포함되어 있다면 어떻게 출력될까?

 

 

- 보는 바와 같이 'A' 라는 문자는 p 즉, [SDT] 에 포함되어 있지 않다.

- 그렇기 때문에 'A' 문자가 포함된 요소(↓표에서 노란색 부분)는 출력되지 않는다.

 

 

 

- 또 다른 예로 숫자가 있어야 할 자리에 'A' 가 포함 되어있다. 그 행은 출력되지 않는다.

 

 

 

 

 

(3) dartResult 값 앞의 두자리 즉, "1D2T#10S" 의 앞에 두자리를 바꿔서 "D12T#10S" 출력하면 어떻게 될까?

 

 

- ↑와 같이 두번째 출력을 보면 (숫자)([SDT])([*#]?) 순이 되어야 하는데 숫자 없이 문자('D') 가 먼저 나와서

  출력되지 않고 그 뒤에 숫자 12부터 순서대로 배열에 맞춰서 출력되었다.

  

 

 

 

 

(4) 대문자 대신 소문자를 사용하면 즉, "1D2T#10S" 를 "1d2T#10S" 로 바꾸면 어떻게 출력이 될까?

 

 

위의 결과 같이 소문자가 포함된 행은 출력되지 않았다. 즉, 소문자, 대문자는 구분해줘야 한다.

 

for i in range(len(dart)):                                                                                                                          if dart[i][2] == '*' and i > 0:                                                                                                                      dart[i-1] *= 2                                                                                                                                 dart[i] = int(dart[i][0]) ** bonus[dart[i][1]] * option[dart[i][2]]

 

- len(dart) = 3 이고 for i in range(len(dart)) 하면 i 는 0, 1, 2 이다. 

                                                                                      

 

- if dart[i][2] == '*' and i > 0 에서 dart[a][b]는      =>

 

 

 

- dart의 요소를 하나씩 출력해보면 ↓밑에 처럼 나온다.

- dart[0][2]와 dart[2][2]는 ' ' 이므로 아무것도 출력 되지 않는다.

 

 

- 다시 문제로 돌아가서 if dart[i][2] == '*' 즉, dart[0][2], dart[1][2], dart[2][2] 에 '*' 이 있으면서 i > 0 이면      dart[i-1] *= 2 즉, 앞 점수에 2배를 해준다.

  (i가 0보다 커야하는 이유는 '*'이 나오면 해당 점수와 바로 앞 점수를 2배 (dart[i-1] *= 2) 해줘야 하는데

  i가 0이거나 그보다 작으면 마이너스 인덱스가 나오므로 (dart[0-1] = dart[-1]), i가 0보다 커야한다.

 

- dart[i][2] 에 '*' 있으면 2배를 해준 다음에, 없으면 바로 그 다음줄로 넘어가서

  dart[i] = int(dart[i][0]) ** bonus[dart[i][1]] * option[dart[i][2]] 실행한다. 

 

- 문제를 그림으로 보자.

- 우선 dartResult = "1S2D*3T" 를 넣고 dart를 프린트 한 결과이다.

 

 

- 나온 결과를 알아보기 쉽게 표로 나타냈다.

 

 

- 위의 결과를 참조하여 코드를 실행해보자.

 

 

- 위의 표에서 보면 dart[1][2] == '*' 이고 i 가 1 즉, i > 0 이므로 바로 앞, dart[0] = 1 이던 값이 2배가 되서

  2가 된것을 확인할 수 있다. (위 표의 초록색 부분)

- 최종 결과는 37이 나온다.

- 다른 예시 

  ▼ 클릭

 

1) 문제

클릭▼

 

2) 코드

 

 

3) 코드 설명

 

내적이란 각 a와 b의 같은 index의 수를 곱한 것들의 합입니다.

         (a[1] * b[1]) + (a[2] * b[2]) + ...

return sum([x*y for x, y in zip(a,b)])

# zip() 함수는 동일한 개수로 이루어진 자료형을 묶어 주는 역할을 한다.

  여러 개의 iterable 객체를 받은 후 자료형 들을 묶어서 튜플 형태로 출력해준다. 

# iterable 이란 반복 가능하다는 뜻인데 한번에 하나씩 자료를 반환할 수 있는 파이썬 객체이다. 

  간단히 말해 for문으로 그 값을 출력 할 수 있는 것을 의미하며 리스트, 튜플, 딕셔너리 등을 말한다.

 

 

# ↑위의 결과를 보면 list a와 list b를 zip 함수로 묶어서

    list a의 요소를 x로, list b의 요소를 y로 해서 print(x, y)를 하면

    각 list의 동일한 index 끼리 짝지어서 출력된다.

# x와 y를 곱해서 출력하면 ↓밑에 처럼 나오고 이 숫자들을 다 더해서(sum) 결과를 return 한다.

 

 

# 즉, (-3) + (-2) + 0 + 8 = 3이 return 된다.

1) 문제

클릭▼


2) 코드

 ('좋아요' 수 제일 많은 풀이)

 

 


2) 코드 설명

① rank = [6, 6, 5, 4, 3, 2, 1]

 

# 로또의 순위는 1등부터 6등까지 있다. 

 

 

# 여기서 일치하는 개수를 계산하여 그 개수와 맞는 인덱스 값을 출력 하려고 한다. 

# rank = [6, 6, 5, 4, 3, 2, 1] 는 rank = [6위, 6위, 5위, 4위, 3위, 2위, 1위] 의미한다.

 

 

일치하는 개수가 0이면 rank[0] = 6(순위)을 출력하고, 맞은 개수가 6이면 rank[6] = 1(순위)을 출력하게

   만들었다.

② cnt_0 = lottos.count(0)

 

# lottos 안에 0의 개수를 찾아서 cnt_0에 넣는다.

# 0의 개수를 찾는 이유는 알아볼 수 없는 번호가 '0' 이기 때문에 최고 순위를 구할때 '0'이 모두 win_nums의    숫자 중 하나라고 생각하고 0의 개수를 구한 다음 그것을 lottos와 win_nums의 일치하는 숫자의 개수에

  더해줘서 최고 순위를 구한다.

# count() 함수는 문자열 안에서 찾고 싶은 문자의 개수를 찾아주는 함수이다. 

# 예를들어 lottos.count(0) 이렇게 출력하면 lottos 안에 0이 몇개인지 찾아준다.

# lottos 안에 0이 2개가 있으므로↓ 2개가 출력되는 걸 확인할 수 있다.

 

③ ans = 0

# 맞은 개수를 담을 ans 변수를 만들고 먼저 0으로 초기화 시킨다

for x in win_nums:                                                                                                                  if x in lottos:                                                                                                                            ans += 1

 

# win_nums 안의 요소를 하나씩 뽑아 x 넣고 만약 x가 lottos 안에 있으면 ans에 1씩 더해준다.

return rank[cnt_0 + ans],rank[ans]

# 결과로 최고 순위 최저 순위를 출력해야 한다.

# 최고 순위 rank[cnt_0 + ans] = rank[0의 개수 + ans의 값]을 의미.

# 최저 순위 rank[ans] = rank[ans의 값]을 의미.

 

 

# ↑위와같이 cnt_0 = 2, ans = 2 이므로 최고 순위 rank[2+2] = rank[4], 최저 순위 rank[2]가 된다. 

# rank[4] = 3, rank[2] = 5 이므로 답은 (3, 5)이다.

 

 

# 다른 예로 lottos = [0, 0, 0, 0, 0, 0] 와 win_nums = [38, 19, 20, 40, 15, 25] 넣어서 출력하면

 

 

# cnt_0 = 6, ans = 0 이므로 최고 순위는 rank[6+0] = rank[6], 최저 순위는 rank[0] 이고 답은 (1, 6) 이다.

 

1) 문제 설명

↓ 클릭


2) 코드

 ('좋아요' 수 제일 많은 풀이)


3) 코드 설명

① stacklist = [ ]

 # 인형들을 담아 줄 리스트 변수를 만든다

 answer = 0     

 # 터져서 없어질 인형의 개수를 계산할 변수를 만들고 0으로 초기화를 한다.

③ board = [[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] 

 # 매트릭스는 ↓이게 기본이고 (row, column) 이렇게 나타낸다.  

 

 

 # board를 매트릭스로 출력하면 인덱스 0번째부터 밑으로, 즉↓ 이렇게 된다.

 

 

# 그럼 문제로 돌아가서 5 x 5 격자에 board 리스트를 입력하면 결과는 이렇게 된다.

   이제 위에서 크레인으로 인형(숫자)을 하나씩 뽑을 거다

 

   

 for move in moves:                                                                                                          for i in range(len(board)):                                                                                                  if board[i][move-1] != 0:                                                                                                      stacklist.append(board[i][move-1])                                                                              board[i][move-1] = 0

  

# moves = [1,5,3,5,1,2,1,4]인데 여기서 하나를 꺼내, 즉 첫번째 1을 꺼내면 move = 1이 되고   

   len(board) = 5 이므로 range(len(board) 즉, i 는 순차적으로 0, 1, 2, 3, 4 이다.

   if board[i][move-1] != 0에서 move = 1i = 0, 1, 2, 3, 4 를 순차적으로 대입하면

   board[0][1-1], board[1][1-1], board[2][1-1],  board[3][1-1],  board[4][1-1]

   즉, board[0][0] = 0, board[1][0] = 0, board[2][0] = 0, board[3][0] = 4, board[4][0] = 3 이다.

   여기서 "if board[i][move-1] != 0 즉, 값이 0이 아니라면" 이므로 board[3][0] 값인 4를 stacklist에 넣는다. 

   그 자리(board[3][0])의 값을 0으로 만들어준다. 

 

 

 

# 두번째는 move = 5 가 되고, i는 똑같이 0, 1, 2, 3, 4 이므로 board[0][5-1], board[1][5-1]... 

   board[1][4] = 3 이므로(0이 아니므로) 3을 stacklist에 넣고 그자리를  0으로 만들어 준다. 

 

 

 

# 동일한 방법으로 move = 3, move = 5를 하면 stacklist에 1, 1이 들어가고 숫자를 뽑은 자리는 0이 된다.

 

 

 

if len(stacklist) > 1:
         if stacklist[-1] == stacklist[-2]:
                 stacklist.pop(-1)
                 stacklist.pop(-1)                                                                                                                 
answer += 2

 

# stacklist의 길이가 1보다 크다면, 그리고 stacklist의 맨 위에 숫자랑 맨 위에서 두번째 숫자가 같다면,

  stacklist[-1] == stacklist[-2], pop을 사용해서 같은 숫자 두개를 터트리고 answer에 터트린 숫자만큼(2개)    더해라.

  즉, 위에 보면 stacklist에 4, 3, 1, 1이 들어있고 제일 마지막(제일 위에 2개)에 들어 온 두 숫자 (1하고 1)이

  같으므로 터트리고 4, 3이 남는다. 그리고 동일한 방법으로 계속 진행한다.

 

# 다음에 move = 1 을 하면 staklist에 3이 들어가게 되고 3이 들어간 자리는 0으로 만들어 준다.

 

 

 

# stacklist 바구니를 보니 맨위의 숫자 3, 위에서 두번째 숫자 3이 같으므로, stacklist[-1] == stacklist[-2]

   두 숫자를 터트리고 answer에 2개를 더해준다. 그리고 stacklist 바구니에는 4가 남는다.

 

# 그 다음으로 move = 2를 하면 stacklist 바구니에 board[2][1] 자리에 있는 숫자 2가 들어가고 move = 1을    하면 이미 board[0][0] ~ board[4][0]은 다 0 이므로 뽑을 인형이 없다. 그래서 넘어가고 마지막 move = 4를    하면 stacklist 바구니에 board[3][3] 자리에 있는 숫자 4가 들어간다.

 

 

 

 

# 우리가 터뜨린 숫자는 4개 이므로 answer를 출력하면 4개가 나오는 것을 확인할 수 있다.

 


4) 주의점 ( break문 )

# 이 문제를 풀면서 제일 어려웠던 부분은 break 문의 위치였다.

# break의 위치에 따라 결과가 달라지는데 그 부분을 살펴보기로 했다.

 

 

 

# break 문이 마지막 if문 뒤에 붙으면 answer의 결과는 8이다.

 

# moves 에서 첫번째 요소 1를 꺼내 i에 넣고 j는 range(len(board)) 즉, 0, 1, 2, 3, 4를 순서대로 넣고 위에서    인형(숫자)을 집어올려 stacklist 바구니에 넣는다. 0이 아닌 숫자만 바구니에 넣는 것이므로 stacklist에는

  4하고 3이 들어가고 그 자리는 0이 된다

 

 

 

 

 

# moves의 두번째 요소 2를 i 넣고 동일하게 계산하면 ↓밑에 처럼 나오고 인형(숫자)를 위에서 부터

  집어 올려서 stacklist 바구니에 넣으면 제일 위에 있는 0은 안되고 3이 들어간다. 3이 들어가는 즉시

  맨위의 숫자 3과 맨위에서 두번째 숫자 3이 같으므로 터트려져 버린다. 

 

 

answer = 2

 

 

 

 

 

 

 

# 여기서 break 문이 걸리고 끝이나고 for문으로 다시 돌아가서 moves의 그 다음 요소를 넣고 계산한다.

 

# if len(stacklist) > 1:

      if stacklist[-1] == stacklist[-2] : 

            stacklist.pop(-1)

            stacklist.pop(-1)

            answer += 2

            break

 

이므로 2번 pop 해서 3이 터트려지고 answer에 2개 더해졌으니 break 되고 다시 for문으로 돌아가게 되는거다. stacklist 바구니에 숫자 3만 들어갔으니 그 자리만 0으로 바뀌게 된다.

 

 

 

 

# moves의 세번째 요소 3을 i에 넣고 동일하게 계산하면 ↓처럼 나오고 위에서부터 인형(숫자)를 집어올려

   1, 5, 4, 1 순서대로 stacklist 바구니에 집어 넣는다. 그리고 그 자리는 0으로 바뀌게 된다.

 

 

 

 

 

 

# moves의 네번째 요소 5를 i에 넣고 동일하게 계산하면 ↓처럼 나오고 위에서부터 인형(숫자)를 집어올려

  1, 2, 1 순서대로 stacklist 바구니에 집어 넣으면 되는데 1을 넣으면 stacklist[-1] 숫자 1이랑 stacklist[-2]

  숫자 1이 같으므로 터트려진다.

  터트려지면서 answer에 2개 더해지고 break 문을 만나 다시 for문으로 돌아간다.  그리고 숫자 1의 자리는

  0으로 바뀐다.

 

   

    answer = 4

 

 

 

 

 

 

 

 

 # moves의 다섯번째 요소 1를 i에 넣고 계산하면 ↓처럼 나오는데 그림과 같이 이미 모든 값이 0으로 바뀌었     으므로 아무런 작업없이 for 문으로 돌아간다.

 

 

 

 

# moves의 여섯번째 요소 2를 i에 넣고 동일하게 계산하면 ↓처럼 나오고 위에서부터 인형(숫자)를 집어올려      2, 2, 5 순서대로 stacklist 바구니에 집어 넣으면 되는데 2 넣고 2를 넣으면 stacklist[-1] == stacklist[-2]

  이므로 2가 터트려진 터트려지면서 answer에 2개 더해지고 break 문을 만나서 다시 for문으로 돌아간다.  

  숫자 2의 자리는 0으로 바뀐다.

 

 

   answer = 6

 

 

 

 

 

 

 

 

 

# moves의 일곱번째 요소 1를 i에 넣고 계산하면 아까와 같이 이미 모든 값이 0으로 바뀌었으므로 아무 작업도 없이 for문으로 돌아가서 마지막 요소 4를 i에 넣고 동일하게 계산한다.  위에서부터 인형(숫자)를 집어올려 4, 3 순서대로 stacklist 바구니에 집어 넣으면 되는데 4를 넣으면 stacklist[-1] == stacklist[-2] 이므로 4가 터트려진다. 터트려지면서 answer에 2개 더해지고 break 문을 만나고 for 문이 다 돌았으므로 if문에서 나온다. 그리고 숫자 4의 자리는 0으로 바뀐다.

 

 

 

   answer = 8

 

 

 

 

 

# break 문이 마지막 if 문에 걸리면 이러한 과정을 거쳐서 answer = 8 이 된다.

1) 문제 설명

2) 코드

    ('좋아요' 수 제일 많은 풀이)

3) 코드 설명

① answer = [0] * len(id_list)

 

# answer 변수에 id_list 갯수 만큼의 0이 있는 리스트를 넣어주었다.

 

 

② reports = { x : 0 for x in id_list}

 

# dictionary = { key : values }

# id_list의 muzi, frodo, apeach, neo를 순차적으로 x로 뽑아서 딕셔너리의 key로 만들고 values는 다 0으로 한다.

# answer 와 reports를 print 하면 ↓ 이렇게 나온다.

 

 

③ for r in set(report):

       reports[r.split()[1]] += 1

 

# set 함수는 집합으로 만들어 주는 함수 즉, 중복된 숫자를 제거할때 사용하는 함수이다.

# ↓의 예를 보면 list = [2, 5, 4, 7, 12, 4, 31, 22, 5, 5, 2, 31] 이렇게 2, 4, 5, 31 중복되어 리스트에 들어있다.

    set 함수를 사용하여 list를 print 하면 중복된 숫자가 한번만 출력되는 것을 확인할 수 있다.

 

 

# set(report) 에서 요소를 하나씩 꺼내서 split 함수를 사용하여 공백을 기준으로 split 한다.

# 공백을 기준으로 split 하면 "muzi frodo" 이렇게 되어 있는게 "muzi", "frodo" 이렇게 둘로 나눠지게 되고 "muzi" 가

  [0]번째 "frodo" 가 [1]번째가 된다.

# [1]번째만 뽑아서 그 이름만큼 더해서 합계를 낸다 ( += 1 의미 ) 

 

# ↓의 예를 보면 딕셔너리로 철수, 민수, 영희의 시험점수를 입력하였다.

# 민수의 점수를 알고싶다면 scores["민수"] 로 점수를 읽을 수 있고 83점이던 민수의 점수를 88점으로 변경하려면

   scores["민수"] = 88  이렇게 가능하다.

 

 

# reports[r.split()[1]] += 1 도 동일한 방법으로 reports["muzi"] += 1, reports["frodo"] += 1, report["neo"] += 1

   reports["apeach"] 이렇게 하나씩 카운트하여 합계를 나타낸 것을 넣으라는 것이다.

 

 

# ↑ 위를 보면 report에서 요소를 하나씩 꺼내서 split 한 다음에 [1]번째 이름에 카운트를 해서 합계를 낸 것이다.

# 첫번째 결과를 보면 report 에서 "muzi frodo"가 꺼내졌고, [1]번째인 frodo를 +1 해줬다.

   { 'muzi' : 0, 'frodo' : 1, 'peach' : 0, 'neo' : 0 }

# 두번째 결과를 보면 report 에서 "muzi neo"가 꺼내졌고, [1]번째인 neo를 +1 해줬고 첫번째 결과의 frodo는 그대로

   1이다.

  { 'muzi' : 0, 'frodo' : 1, 'peach' : 0, 'neo' : 1 }

# 세번째 결과를 보면 report 에서 "apeach frodo"가 꺼내졌고, [1]번째인 frodo를 +1 해줘서 frodo가 2가 되었다.

  { 'muzi' : 0, 'frodo' : 2, 'peach' : 0, 'neo' : 1 }

# 네번째 결과를 보면 report 에서 "apeach muzi"가 꺼내졌고, [1]번째인 muzi를 +1 해줬다.

  { 'muzi' : 1, 'frodo' : 2, 'peach' : 0, 'neo' : 1 }

# 마지막으로 report 에서 "frodo neo"가 꺼내졌고, [1]번째인 neo를 +1 해줘서 neo는 2가 되었다.

  { 'muzi' : 1, 'frodo' : 2, 'peach' : 0, 'neo' : 2 }

# report 에서 꺼내는 순서는 랜덤이기에 ("apeach neo" 가 먼저 꺼내질 수 도 있다.) 마지막 결과만 빼고 1-4번째 결과는

   바뀔수도 있다. 

 

# print의 위치를 for문 열에 맞춰서 출력을 하면 제일 마지막 결과만 출력이 된다. ↓ 참조.

 

 

 

 

④ for r in set(report):

       if reports[r.split()[1]] >= k:

          answer[id_list.index(r.split()[0])] += 1

 

# set(report) 에서 요소를 하나씩 꺼내서 reports[r.split()[1]] 값, 즉  { 'muzi' : 1, 'frodo' : 2, 'peach' : 0, 'neo' : 2 }

  중에서 k 보다 크거나 같으면 (이 문제에서는 k = 2 이므로 frodo와 neo가 해당된다)

   answer[id_list.index(r.split()[0]] += 1 이렇게 한다.

# 밑에 ↓ 결과에서 보면 알 수 있듯이 id_list.index("neo")를 출력하면 리스트에서 "neo"의 위치를 반환한다.

# 리스트는 0부터 시작하므로 "neo"는 id_list의 3번째에 위치해 있다.

 

 

# id_list.index(r.split()[0])는 "muzi frodo" 여기서 [0]번째 즉, muzi를 얘기하는 것이므로 [1]번째에 

  frodo 와 neo를 가지고 있는 요소를 찾고 그 요소의 [0]번째 이름을 찾아서 그 인덱스 자리에 +1을 하라는 말이다

# 다시말해 report = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"] 에서 frodo 와 

   neo를 [1]번째에 가지고 있는 요소는 "muzi frodo", "apeach frodo", "frodo neo", "muzi neo"이다. 이 요소들의

   [0]번째 즉, muzi, apeach, frodo, muzi를 id_list에서 찾아서 이름에 맞는 자리에 +1 씩 해주라는 의미이다.

# id_list = "muzi", "frodo", "apeach", "neo" 순 이므로 muzi = 2, frodo = 1, apeach = 1, neo = 0 이고 이것을 출력하면

   그 순서에 맞게 [2, 1, 1, 0] 이 나오는 것이다.

 

 

 

 

 

 

 

+ Recent posts