취업 및 이직 준비/코딩테스트 준비

프로그래머스 코딩 기초 트레이닝 Python Day16 ~ Day25

code2772 2025. 2. 11. 17:23
728x90
반응형

DAY16 문자열

 

대문자로 바꾸기

def solution(myString):
   return myString.upper()

테스트:

print(solution("aBcDeFg"))# "ABCDEFG"
print(solution("AAA"))# "AAA"

설명:

  • upper() 메서드는 문자열의 모든 알파벳을 대문자로 변환
  • 이미 대문자인 경우는 그대로 유지됨

 

소문자로 바꾸기

def solution(myString):
   return myString.lower()

테스트:

print(solution("aBcDeFg"))# "abcdefg"
print(solution("aaa"))# "aaa"

설명:

  • lower() 메서드는 문자열의 모든 알파벳을 소문자로 변환
  • 이미 소문자인 경우는 그대로 유지됨

 

배열에서 문자열 대소문자 변환하기

def solution(strArr):
   return [s.lower() if i % 2 == 0 else s.upper()
           for i, s in enumerate(strArr)]

또는 더 명시적으로:

def solution(strArr):
    result = []
    for i in range(len(strArr)):
        if i % 2 == 0:# 짝수 인덱스
            result.append(strArr[i].lower())
        else:# 홀수 인덱스
            result.append(strArr[i].upper())
    return result

테스트:

print(solution(["AAA","BBB","CCC","DDD"]))# ["aaa","BBB","ccc","DDD"]
print(solution(["aBc","AbC"]))# ["abc","ABC"]

설명:

  1. 배열의 각 원소를 인덱스와 함께 순회
  2. 짝수 인덱스(0, 2, ...)의 문자열은 소문자로 변환
  3. 홀수 인덱스(1, 3, ...)의 문자열은 대문자로 변환
  4. 변환된 문자열들을 새 배열에 저장하여 반환

 

A 강조하기

def solution(myString):
# 전체 문자열을 소문자로 변환 후 'a'만 대문자로 변환
   return myString.lower().replace('a', 'A')

테스트:

print(solution("abstract algebra"))# "AbstrAct AlgebrA"
print(solution("PrOgRaMmErS"))# "progrAmmers"

설명:

  1. 문자열을 소문자로 변환:
    • lower() 메서드로 모든 문자를 소문자로 만듦
    • PrOgRaMmErS -> programmers
  2. 'a'를 'A'로 변환:
    • replace('a', 'A')로 모든 'a'를 'A'로 변경
    • programmers -> progrAmmers

이 두 작업을 메서드 체이닝으로 한 번에 처리합니다

 

특정한 문자를 대문자로 바꾸기

def solution(my_string, alp):
   return my_string.replace(alp, alp.upper())

테스트:

print(solution("programmers", "p"))# "Programmers"
print(solution("lowercase", "x"))# "lowercase"

설명:

  1. replace(old, new) 메서드 사용:
    • old: 찾을 문자열(alp)
    • new: 바꿀 문자열(alp.upper())
  2. 예시:
    • "programmers"에서 "p"를 "P"로 변경 → "Programmers"
    • "lowercase"에서 "x"를 찾았으나 없으므로 그대로 반환
  3. alp.upper()는 입력된 소문자를 대문자로 변환:
    • "p" → "P"
    • "x" → "X"

 

DAY17 문자열

 

특정 문자열로 끝나는 가장 긴 부분

def solution(myString, pat):
# pat의 마지막 등장 위치를 찾음
   last_idx = myString.rindex(pat)

# 처음부터 pat이 끝나는 위치까지 자름
   return myString[:last_idx + len(pat)]

테스트:

print(solution("AbCdEFG", "dE"))# "AbCdE"
print(solution("AAAAaaaa", "a"))# "AAAAaaaa"

설명:

  1. rindex() 메서드 사용:
    • 문자열에서 pat가 마지막으로 등장하는 위치를 찾음
    • AbCdEFG에서 "dE"는 3번 인덱스에서 마지막으로 등장
  2. 슬라이싱:
    • 처음(0)부터 (pat가 끝나는 위치)까지 문자열을 자름
    • last_idx + len(pat)는 pat의 마지막 문자까지 포함하기 위함

예시 동작:

  • "AbCdEFG", "dE":
    • "dE"의 마지막 위치: 3
    • 슬라이싱: 0부터 3+2(pat의 길이)까지
    • 결과: "AbCdE"

 

문자열이 몇 번 등장하는지 세기

def solution(myString, pat):
   count = 0
   for i in range(len(myString) - len(pat) + 1):
       if myString[i:i+len(pat)] == pat:
           count += 1
   return count

또는 더 간단하게:

def solution(myString, pat):
    return myString.count(pat)

테스트:

print(solution("banana", "ana"))# 2
print(solution("aaaa", "aa"))# 3

설명:

  1. 첫 번째 방법:
    • 문자열을 순회하면서 각 위치에서 pat 길이만큼의 부분 문자열을 확인
    • pat과 일치하면 count 증가
  2. 두 번째 방법:
    • 문자열의 count() 메서드를 사용하여 pat의 등장 횟수를 직접 계산

예시 동작 (banana, ana):

  • ban[ana] -> 첫 번째 발견
  • ban[ana]na -> 두 번째 발견
  • 총 2회 발견

 

ad 제거하기

def solution(strArr):
# "ad"를 포함하지 않는 문자열만 필터링
   return [s for s in strArr if "ad" not in s]

테스트:

print(solution(["and","notad","abcd"]))# ["and","abcd"]
print(solution(["there","are","no","a","ds"]))# ["there","are","no","a","ds"]

설명:

  1. 리스트 컴프리헨션 사용:
    • strArr의 각 문자열(s)에 대해
    • "ad" not in s로 "ad" 포함 여부 확인
    • 포함하지 않는 문자열만 선택
  2. 더 명시적인 방법:
def solution(strArr):
    result = []
    for s in strArr:
        if "ad" not in s:
            result.append(s)
    return result

두 방식 모두 동일한 결과를 반환하지만, 첫 번째 방법이 더 파이썬스럽고 간결합니다.

 

공백으로 구분하기 1

def solution(my_string):
   return my_string.split()

테스트:

print(solution("i love you"))# ["i", "love", "you"]
print(solution("programmers"))# ["programmers"]

설명:

  1. split() 메서드 사용:
    • 문자열을 공백을 기준으로 나눔
    • 연속된 공백은 하나로 처리
    • 결과를 리스트로 반환
  2. 예시 동작:
    • "i love you" → ["i", "love", "you"]
    • "programmers" → ["programmers"]

참고: split()과 split(' ')의 차이

  • split(): 연속된 공백을 하나로 처리
  • split(' '): 공백을 정확히 구분

이 문제에서는 "공백 한 개로 구분"이라는 조건이 있으므로 단순 split()을 사용하면 됩니다.

 

공백으로 구분하기 2

def solution(my_string):
   return my_string.split()

테스트:

print(solution(" i    love  you"))# ["i", "love", "you"]
print(solution("    programmers  "))# ["programmers"]

설명:

  1. split() 메서드 사용:
    • 문자열의 앞뒤 공백 제거
    • 연속된 공백을 하나의 구분자로 처리
    • 공백을 기준으로 문자열을 분리하여 리스트로 반환
  2. split() 메서드의 특징:
    • 문자열 앞뒤의 공백 무시
    • 연속된 공백을 하나로 처리
    • 공백으로 구분된 실제 단어만 리스트에 포함
  3. 예시 동작:
    • " i love you"
      1. 앞뒤 공백 제거
      2. 연속된 공백을 하나로 처리
      3. 단어 분리
      4. 결과: ["i", "love", "you"]

 

DAY18 문자열

 

x 사이의 개수

def solution(myString):
# 'x'로 문자열을 나누고 각 부분의 길이를 리스트로 반환
   return [len(part) for part in myString.split('x')]

테스트

print(solution("oxooxoxxox"))# [1, 2, 1, 0, 1, 0]
print(solution("xabcxdefxghi"))# [0, 3, 3, 3]

설명:

  1. split('x') 사용:
    • 문자열을 'x'를 기준으로 나눔
    • 빈 문자열도 포함됨
  2. 리스트 컴프리헨션:
    • 나눠진 각 부분 문자열의 길이를 계산
    • len() 함수로 길이 측정
  3. 예시 동작: "oxooxoxxox" →
    • split('x')로 나누기: ["o", "oo", "o", "", "o", ""]
    • 각 부분의 길이: [1, 2, 1, 0, 1, 0]

 

문자열 잘라서 정렬하기

def solution(myString):
# 'x'로 문자열을 나누고, 빈 문자열을 제거한 후, 정렬
   return sorted(x for x in myString.split('x') if x)

테스트:

print(solution("axbxcxdx"))# ["a", "b", "c", "d"]
print(solution("dxccxbbbxaaaa"))# ["aaaa", "bbb", "cc", "d"]

설명:

  1. split('x'):
    • 문자열을 'x'를 기준으로 나눔
  2. 빈 문자열 제거:
    • if x로 빈 문자열 제외
    • 리스트 컴프리헨션에서 조건 사용
  3. sorted():
    • 나눠진 문자열들을 사전순으로 정렬

예시 동작: "dxccxbbbxaaaa" →

  1. split('x'): ["d", "cc", "bbb", "aaaa"]
  2. 빈 문자열 제거: 같음 (빈 문자열 없음)
  3. 정렬: ["aaaa", "bbb", "cc", "d"]

 

간단한 식 계산하기

def solution(binomial):
# 문자열을 공백으로 분리
   a, op, b = binomial.split()

# 문자열을 정수로 변환
   a = int(a)
   b = int(b)

# 연산자에 따른 계산
   if op == '+':
       return a + b
   elif op == '-':
       return a - b
   else:# op == '*'
       return a * b

테스트:

print(solution("43 + 12"))# 55
print(solution("0 - 7777"))# -7777
print(solution("40000 * 40000"))# 1600000000

설명:

  1. split():
    • 공백을 기준으로 문자열을 3부분으로 나눔
    • a: 첫 번째 숫자
    • op: 연산자
    • b: 두 번째 숫자
  2. int():
    • 문자열로 된 숫자를 정수로 변환
  3. 조건문:
    • 연산자에 따라 다른 연산 수행
    • '+': 덧셈
    • '-': 뺄셈
    • '*': 곱셈

 

문자열 바꿔서 찾기

def solution(myString, pat):
# A와 B를 서로 바꾸기
   converted = myString.replace('A', 'C').replace('B', 'A').replace('C', 'B')

# pat이 변환된 문자열의 부분문자열인지 확인
   return 1 if pat in converted else 0

테스트:

print(solution("ABBAA", "AABB"))# 1
print(solution("ABAB", "ABAB"))# 0

설명:

  1. 문자열 변환:
    • A → B, B → A로 직접 바꾸면 모든 문자가 같은 문자로 바뀌므로
    • 임시 문자 C를 사용하여 3단계로 변환
    • A → C (임시 저장)
    • B → A
    • C → B
  2. 부분 문자열 확인:
    • in 연산자로 pat이 변환된 문자열에 포함되는지 확인
    • 포함되면 1, 아니면 0 반환

예시 동작("ABBAA", "AABB"):

  1. "ABBAA" → "CBBCC" → "CAACC" → "BAABB"
  2. "BAABB"에 "AABB"가 포함됨
  3. 1 반환

 

my_string

def solution(rny_string):
   return rny_string.replace('m', 'rn')

테스트:

print(solution("masterpiece"))# "rnasterpiece"
print(solution("programmers"))# "prograrnrners"
print(solution("jerry"))# "jerry"
print(solution("burn"))# "burn"

설명:

  1. replace() 메서드 사용:
    • 문자열에서 'm'을 찾아서 'rn'으로 교체
    • 'm'이 없으면 원래 문자열 그대로 반환

동작 과정:

  • "masterpiece" → "rnasterpiece" ('m' → 'rn' 교체)
  • "programmers" → "prograrnrners" ('m' → 'rn' 교체)
  • "jerry" → "jerry" ('m'이 없으므로 그대로)
  • "burn" → "burn" ('m'이 없으므로 그대로)

 

DAY19 문자열,리스트(배열)

 

세 개의 구분자

def solution(myStr):
# a, b, c를 구분자로 문자열 분리
   import re

# a, b, c로 분리하고 빈 문자열 제거
   result = [x for x in re.split('[abc]', myStr) if x]

# 결과가 빈 배열이면 ["EMPTY"] 반환
   return result if result else ["EMPTY"]

테스트:

print(solution("baconlettucetomato"))# ["onlettu", "etom", "to"]
print(solution("abcd"))# ["d"]
print(solution("cabab"))# ["EMPTY"]

설명:

  1. re.split() 사용:
    • '[abc]': a 또는 b 또는 c를 의미하는 정규표현식
    • 이 구분자들로 문자열을 분리
  2. 리스트 컴프리헨션:
    • 분리된 결과에서 빈 문자열 제거
    • if x로 빈 문자열 필터링
  3. 결과 처리:
    • 필터링된 결과가 있으면 그대로 반환
    • 빈 배열이면 ["EMPTY"] 반환

예시 동작:

  • "baconlettucetomato" →
    1. 'b'로 분리: ["", "aconlettucetomato"]
    2. 'a'로 분리: ["", "", "conlettucetom", "to"]
    3. 'c'로 분리: ["", "", "", "onlettu", "etom", "to"]
    4. 빈 문자열 제거: ["onlettu", "etom", "to"]

 

배열의 원소만큼 추가하기

def solution(arr):
   X = []# 빈 배열 초기화

# arr의 각 원소에 대해
   for a in arr:
# a를 a번 반복하여 X에 추가
       X.extend([a] * a)

   return X

테스트:

print(solution([5, 1, 4]))# [5, 5, 5, 5, 5, 1, 4, 4, 4, 4]
print(solution([6, 6]))# [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]
print(solution([1]))# [1]

설명:

  1. 빈 배열 X 생성:
    • 결과를 저장할 빈 리스트 생성
  2. arr의 각 원소 처리:
    • 각 원소 a에 대해
    • [a] * a로 a를 a번 반복한 리스트 생성
    • extend()로 X에 추가

예시 동작 ([5, 1, 4]):

  1. a = 5: X += [5, 5, 5, 5, 5]
  2. a = 1: X += [1]
  3. a = 4: X += [4, 4, 4, 4]
  4. 최종 결과: [5, 5, 5, 5, 5, 1, 4, 4, 4, 4]

 

빈 배열에 추가, 삭제하기

def solution(arr, flag):
   X = []# 빈 배열 초기화

   for i in range(len(arr)):
       if flag[i]:
# True인 경우: arr[i]를 arr[i] * 2번 추가
           X.extend([arr[i]] * (arr[i] * 2))
       else:
# False인 경우: 마지막 arr[i]개의 원소 제거
           X = X[:-arr[i]]

   return X

테스트:

print(solution([3, 2, 4, 1, 3], [True, False, True, False, False]))
# [3, 3, 3, 3, 4, 4, 4, 4]

설명:

  1. 빈 배열 X 생성
  2. arr와 flag를 동시에 순회하며 처리:
    • flag[i]가 True일 때:
      • arr[i]를 arr[i] * 2번 반복하여 X에 추가
      • extend()와 리스트 곱셈 연산 사용
    • flag[i]가 False일 때:
      • X의 마지막 arr[i]개의 원소 제거
      • 슬라이싱 사용 X[:-arr[i]]

예시 진행 과정:

  1. i=0: arr[0]=3, flag[0]=True
    • X += [3, 3, 3, 3, 3, 3]
  2. i=1: arr[1]=2, flag[1]=False
    • X = X[:-2]
    • X = [3, 3, 3, 3]
  3. i=2: arr[2]=4, flag[2]=True
    • X += [4, 4, 4, 4, 4, 4, 4, 4]
  4. i=3: arr[3]=1, flag[3]=False
    • X = X[:-1]
  5. i=4: arr[4]=3, flag[4]=False
    • X = X[:-3]

최종 결과: [3, 3, 3, 3, 4, 4, 4, 4]

 

배열 만들기6

def solution(arr):
   stk = []# 빈 스택 초기화

   for num in arr:
# 스택이 비어있으면 현재 숫자 추가
       if not stk:
           stk.append(num)

# 스택의 마지막 원소와 현재 숫자가 같으면 pop
       elif stk[-1] == num:
           stk.pop()

# 스택의 마지막 원소와 현재 숫자가 다르면 push
       else:
           stk.append(num)

# 스택이 비어있으면 [-1] 반환, 아니면 스택 반환
   return stk if stk else [-1]

테스트:

print(solution([0, 1, 1, 1, 0]))# [0, 1, 0]
print(solution([0, 1, 0, 1, 0]))# [0, 1, 0, 1, 0]
print(solution([0, 1, 1, 0]))# [-1]

예시 동작 ([0, 1, 1, 1, 0]):

  1. num = 0: stk = [0]
  2. num = 1: stk = [0, 1]
  3. num = 1: stk = [0] (pop)
  4. num = 1: stk = [0, 1]
  5. num = 0: stk = [0, 1, 0]

각 숫자를 처리할 때:

  • 스택이 비어있으면 숫자 추가
  • 스택의 마지막 숫자와 같으면 제거
  • 스택의 마지막 숫자와 다르면 추가

 

무작위로 K개의 수 뽑기

def solution(arr, k):
# 중복을 제거하고 순서를 유지하기 위해 딕셔너리 사용
   result = []
   seen = set()

# arr를 순회하면서 새로운 숫자만 추가
   for num in arr:
       if num not in seen and len(result) < k:
           result.append(num)
           seen.add(num)

# k개가 될 때까지 -1 추가
   while len(result) < k:
       result.append(-1)

   return result

테스트:

print(solution([0, 1, 1, 2, 2, 3], 3))# [0, 1, 2]
print(solution([0, 1, 1, 1, 1], 4))# [0, 1, -1, -1]

설명:

  1. 중복 제거 및 순서 유지:
    • result: 결과를 저장할 리스트
    • seen: 이미 등장한 숫자를 저장할 set
  2. 배열 생성 과정:
    • arr의 각 숫자에 대해:
      • 새로운 숫자이고 (num not in seen)
      • result의 길이가 k보다 작은 경우에만 추가
  3. 길이 조정:
    • result의 길이가 k보다 작으면
    • k개가 될 때까지 -1 추가

예시 동작:

[0, 1, 1, 2, 2, 3], k=3:
1. 0: result=[0], seen={0}
2. 1: result=[0,1], seen={0,1}
3. 1: 이미 있음, 건너뜀
4. 2: result=[0,1,2], seen={0,1,2}
5. k개 채움, 종료

[0, 1, 1, 1, 1], k=4:
1. 0: result=[0], seen={0}
2. 1: result=[0,1], seen={0,1}
3. 나머지는 중복, -1 추가
4. result=[0,1,-1,-1]

 

DAY20 함수 (메서드)

 

배열의 길이를 2의 거듭제곱으로 만들기

def solution(arr):
# 현재 배열 길이
   length = len(arr)

# 필요한 2의 거듭제곱 크기 찾기
   target_length = 1
   while target_length < length:
       target_length *= 2

# 필요한 만큼 0 추가
   return arr + [0] * (target_length - length)

테스트:

print(solution([1, 2, 3, 4, 5, 6]))# [1, 2, 3, 4, 5, 6, 0, 0]
print(solution([58, 172, 746, 89]))# [58, 172, 746, 89]

설명:

  1. 2의 거듭제곱 찾기:
    • 1부터 시작해서 2를 곱해가며
    • arr의 길이보다 크거나 같은 첫 번째 2의 거듭제곱 찾기
  2. 필요한 0의 개수 계산:
    • target_length - length
    • 예: 길이 6인 경우, 8(2³)까지 채우려면 2개의 0 필요

예시 동작:

python
Copy[1, 2, 3, 4, 5, 6]:
- 길이: 6
- 다음 2의 거듭제곱: 8 (2³)
- 필요한 0의 개수: 8 - 6 = 2
- 결과: [1, 2, 3, 4, 5, 6, 0, 0]

[58, 172, 746, 89]:
- 길이: 4
- 이미 2의 거듭제곱 (2²)
- 추가 0 불필요
- 결과: [58, 172, 746, 89]

 

배열 비교하기

def solution(arr1, arr2):
# 길이 비교
   if len(arr1) != len(arr2):
       return 1 if len(arr1) > len(arr2) else -1

# 합계 비교
   sum1 = sum(arr1)
   sum2 = sum(arr2)

   if sum1 != sum2:
       return 1 if sum1 > sum2 else -1

# 길이도 같고 합도 같으면 0
   return 0

테스트:

print(solution([49, 13], [70, 11, 2]))# -1
print(solution([100, 17, 84, 1], [55, 12, 65, 36]))# 1
print(solution([1, 2, 3, 4, 5], [3, 3, 3, 3, 3]))# 0

설명:

  1. 길이 비교:
    • arr1과 arr2의 길이가 다르면
    • 더 긴 쪽이 큰 것
    • arr1이 더 길면 1, arr2가 더 길면 -1 반환
  2. 합계 비교 (길이가 같을 때):
    • 각 배열의 모든 원소 합 계산
    • sum1 > sum2이면 1
    • sum1 < sum2이면 -1
  3. 같은 경우:
    • 길이도 같고 합도 같으면 0 반환

 

문자열 묶기

def solution(strArr):
# 길이별로 문자열 개수를 저장할 딕셔너리
   length_count = {}

# 각 문자열의 길이를 카운트
   for s in strArr:
       length = len(s)
       length_count[length] = length_count.get(length, 0) + 1

# 가장 많은 개수를 가진 그룹의 크기 반환
   return max(length_count.values())

테스트:

print(solution(["a","bc","d","efg","hi"]))# 2

설명:

  1. 딕셔너리 사용:
    • key: 문자열 길이
    • value: 해당 길이를 가진 문자열의 개수
  2. 카운팅:
    • 각 문자열의 길이를 계산
    • 딕셔너리에서 해당 길이의 카운트 증가
    • length_count.get(length, 0)로 없는 길이는 0으로 초기화
  3. 최대값 반환:
    • values()로 모든 카운트 값을 가져옴
    • max()로 가장 큰 값 반환

예시 동작:

["a","bc","d","efg","hi"]:
1. 길이별 카운트:
   - 길이 1: 2개 ("a", "d")
   - 길이 2: 2개 ("bc", "hi")
   - 길이 3: 1개 ("efg")

2. length_count = {1: 2, 2: 2, 3: 1}

3. max(length_count.values()) = 2

 

배열의 길이에 따라 다른 연산하기

def solution(arr, n):
# arr의 길이가 홀수인 경우: 짝수 인덱스에 n 더하기# arr의 길이가 짝수인 경우: 홀수 인덱스에 n 더하기
   for i in range(len(arr)):
       if len(arr) % 2 == 1:# 홀수 길이
           if i % 2 == 0:# 짝수 인덱스
               arr[i] += n
       else:# 짝수 길이
           if i % 2 == 1:# 홀수 인덱스
               arr[i] += n
   return arr

또는 리스트 컴프리헨션을 사용하여:

def solution(arr, n):
    return [x + n if (len(arr) % 2 == i % 2) else x for i, x in enumerate(arr)]

테스트:

python
Copyprint(solution([49, 12, 100, 276, 33], 27))# [76, 12, 127, 276, 60]
print(solution([444, 555, 666, 777], 100))# [444, 655, 666, 877]

예시 동작:

  1. [49, 12, 100, 276, 33], n=27 (길이 5, 홀수):
    • 짝수 인덱스(0, 2, 4)에 27 더하기
    • [49+27, 12, 100+27, 276, 33+27]
    • [76, 12, 127, 276, 60]
  2. [444, 555, 666, 777], n=100 (길이 4, 짝수):
    • 홀수 인덱스(1, 3)에 100 더하기
    • [444, 555+100, 666, 777+100]
    • [444, 655, 666, 877]

 

뒤에서 5등까지지

def solution(num_list):
# 리스트 정렬 후 앞에서 5개 반환
   return sorted(num_list)[:5]

테스트:

print(solution([12, 4, 15, 46, 38, 1, 14]))# [1, 4, 12, 14, 15]

설명:

  1. sorted() 함수로 리스트를 오름차순 정렬
  2. 슬라이싱 [:5]로 앞에서 5개 원소만 선택
  3. 결과 반환

예시 진행 과정:

[12, 4, 15, 46, 38, 1, 14]
-> 정렬: [1, 4, 12, 14, 15, 38, 46]
-> 5개 선택: [1, 4, 12, 14, 15]

 

DAY21 함수 (메서드)

 

뒤에서 5등 위로

def solution(num_list):
# 리스트 정렬 후 앞의 5개를 제외한 나머지 반환
   return sorted(num_list)[5:]

 

전국 대회 선발 고사

def solution(rank, attendance):
# 참가 가능한 학생들의 (등수, 학생번호) 리스트 생성
   available = [(r, i) for i, r in enumerate(rank) if attendance[i]]

# 등수 기준으로 정렬
   available.sort()

# 상위 3명의 학생 번호 추출
   a, b, c = [student_num for _, student_num in available[:3]]

# 계산식 적용
   return 10000 * a + 100 * b + c

테스트:

print(solution([3, 7, 2, 5, 4, 6, 1], [false, true, true, true, true, false, false]))# 20403
print(solution([1, 2, 3], [true, true, true]))# 102
print(solution([6, 1, 5, 2, 3, 4], [true, false, true, false, false, true]))# 50200

설명:

  1. 참가 가능한 학생 필터링:
    • enumerate(rank)로 등수와 학생번호 연결
    • attendance가 True인 학생만 선택
    • (등수, 학생번호) 형태로 저장
  2. 정렬:
    • 등수(첫 번째 요소)를 기준으로 정렬
    • 오름차순 정렬되므로 등수가 높은 순서대로 정렬됨
  3. 상위 3명 선택:
    • 정렬된 리스트에서 앞에서 3명 선택
    • 학생 번호만 추출
  4. 결과 계산:
    • 10000 * a + 100 * b + c 공식 적용

예시:

rank = [3, 7, 2, 5, 4, 6, 1]
attendance = [false, true, true, true, true, false, false]

1. 참가 가능한 학생: [(3,0), (7,1), (2,2), (5,3), (4,4)]
2. 등수순 정렬: [(2,2), (4,4), (3,3)]
3. 상위 3명: a=2, b=4, c=3
4. 결과: 10000*2 + 100*4 + 3 = 20403

 

정수 부분

def solution(flo):
   return int(flo)

 

문자열 정수의 합

def solution(num_str):
# 문자열의 각 문자를 정수로 변환하여 합계 계산
   return sum(int(digit) for digit in num_str)

다른 방법:

def solution(num_str):
    return sum(map(int, num_str))

테스트:

print(solution("123456789"))# 45
print(solution("1000000"))# 1

설명:

  1. 첫 번째 방법:
    • 문자열의 각 문자(digit)를 순회
    • int()로 각 문자를 정수로 변환
    • sum()으로 모든 숫자의 합 계산
  2. 두 번째 방법:
    • map(int, num_str)로 모든 문자를 한번에 정수로 변환
    • sum()으로 합계 계산

두 방법 모두 동일한 결과를 반환합니다.

 

문자열을 정수로 변환하기

def solution(n_str):
return int(n_str)

 

DAY22 함수(메서드), 조건문 활용

 

0떼기

def solution(n_str):
# 왼쪽의 0을 제거하기 위해 int로 변환 후 다시 str로 변환
   return str(int(n_str))

또는 문자열 메서드를 사용하여:

def solution(n_str):
    return n_str.lstrip('0')

테스트:

print(solution("0010"))# "10"
print(solution("854020"))# "854020"

설명:

  1. 첫 번째 방법 (int-str 변환):
    • int()로 변환하면 자동으로 앞의 0이 제거됨
    • 다시 str()로 문자열 변환
  2. 두 번째 방법 (lstrip):
    • lstrip('0')은 문자열 왼쪽의 '0'을 모두 제거
    • 오른쪽이나 중간의 0은 유지됨

두 방법 모두 같은 결과를 반환하며, 제한사항을 만족합니다.

 

두수의 합

def solution(a, b):
# 두 문자열을 정수로 변환하여 더한 후 다시 문자열로 변환
   return str(int(a) + int(b))

테스트:

print(solution("582", "734"))# "1316"
print(solution("18446744073709551615", "287346502836570928366"))# "305793246910280479981"
print(solution("0", "0"))# "0"

설명:

  1. 문자열을 정수로 변환:
    • int(a), int(b)로 각 문자열을 정수로 변환
    • 파이썬은 매우 큰 정수도 자동으로 처리 가능
  2. 덧셈 수행:
    • 변환된 정수들을 더함
  3. 결과를 문자열로 변환:
    • str()을 사용하여 계산 결과를 다시 문자열로 변환

주의사항:

  • 매우 큰 숫자도 처리할 수 있어야 함
  • 파이썬은 큰 정수를 자동으로 처리하므로 별도의 처리가 필요없음
  • 결과가 항상 문자열이어야 함

 

문자열로 변환

def solution(n):
   return str(n)

테스트:

print(solution(123))# "123"
print(solution(2573))# "2573"

설명:

  • str() 함수를 사용하여 정수를 문자열로 변환
  • 파이썬의 str() 함수는 어떤 타입의 값이든 문자열로 변환 가능
  • 정수를 문자열로 변환할 때 가장 간단하고 직관적인 방법

 

배열의 원소 삭제하기

def solution(arr, delete_list):
# delete_list의 원소를 제외한 arr의 원소만 선택
   return [x for x in arr if x not in delete_list]

또는 filter를 사용하여:

def solution(arr, delete_list):
    return list(filter(lambda x: x not in delete_list, arr))

테스트:

print(solution([293, 1000, 395, 678, 94], [94, 777, 104, 1000, 1, 12]))
# [293, 395, 678]

print(solution([110, 66, 439, 785, 1], [377, 823, 119, 43]))
# [110, 66, 439, 785, 1]

설명:

  1. 리스트 컴프리헨션 방식:
    • arr의 각 원소 x에 대해
    • x not in delete_list 조건을 만족하는 원소만 선택
    • 원래 순서 유지됨
  2. filter 방식:
    • filter 함수로 조건에 맞는 원소만 선택
    • lambda로 조건 함수 정의
    • list()로 결과를 리스트로 변환

두 방법 모두 동일한 결과를 반환하며, arr의 원래 순서를 유지합니다.

 

부분 문자열인지 확인하기

def solution(my_string, target):
# target이 my_string의 부분 문자열인지 확인
   return 1 if target in my_string else 0

테스트:

python
Copprint(solution("banana", "ana"))# 1
print(solution("banana", "wxyz"))# 0

설명:

  1. in 연산자 사용:
    • 문자열의 부분 문자열 여부를 확인
    • target이 my_string에 있으면 True, 없으면 False 반환
  2. 조건부 표현식(삼항 연산자):
    • 결과가 True면 1 반환
    • 결과가 False면 0 반환

또는 더 명시적으로:

def solution(my_string, target):
    if target in my_string:
        return 1
    return 0

두 방법 모두 같은 결과를 반환하며, 제한사항을 만족합니다.

 

DAY23 조건문 활용

 

부분 문자열

def solution(str1, str2):
# str1이 str2의 부분 문자열인지 확인
   return 1 if str1 in str2 else 0

테스트:

print(solution("abc", "aabcc"))# 1
print(solution("tbt", "tbbttb"))# 0

설명:

  1. in 연산자 사용하여 부분 문자열 확인
    • str1이 str2 안에 연속된 문자열로 존재하는지 검사
    • 있으면 True, 없으면 False 반환
  2. 조건부 표현식으로 결과 변환
    • True면 1 반환
    • False면 0 반환

더 명시적인 버전:

def solution(str1, str2):
    if str1 in str2:
        return 1
    return 0

예시 동작:

"abc" in "aabcc":
- "aabcc" 안에 "abc"가 연속된 부분 문자열로 존재
- 따라서 1 반환

"tbt" in "tbbttb":
- "tbbttb" 안에 "tbt"가 연속된 부분 문자열로 존재하지 않음
- 따라서 0 반환

 

꼬리 문자열

def solution(str_list, ex):
# ex를 포함하지 않는 문자열만 선택하여 연결
   return ''.join(s for s in str_list if ex not in s)

테스트:

print(solution(["abc", "def", "ghi"], "ef"))# "abcghi"
print(solution(["abc", "bbc", "cbc"], "c"))# ""

설명:

  1. 리스트 컴프리헨션을 사용하여 필터링:
    • str_list의 각 문자열 s에 대해
    • ex not in s 조건으로 ex를 포함하지 않는 문자열만 선택
  2. join() 메서드로 문자열 결합:
    • 선택된 문자열들을 빈 문자열('')로 연결
    • 결과 문자열 반환

또는 더 명시적인 버전:

def solution(str_list, ex):
    result = ''
    for s in str_list:
        if ex not in s:
            result += s
    return result

예시 동작:

["abc", "def", "ghi"], ex="ef":
1. "abc" - "ef" 없음 -> 포함
2. "def" - "ef" 있음 -> 제외
3. "ghi" - "ef" 없음 -> 포함
결과: "abcghi"

["abc", "bbc", "cbc"], ex="c":
1. "abc" - "c" 있음 -> 제외
2. "bbc" - "c" 있음 -> 제외
3. "cbc" - "c" 있음 -> 제외
결과: ""

 

정수 찾기

def solution(num_list, n):
# n이 num_list에 있으면 1, 없으면 0 반환
   return 1 if n in num_list else 0

테스트:

print(solution([1, 2, 3, 4, 5], 3))# 1
print(solution([15, 98, 23, 2, 15], 20))# 0

설명:

  1. in 연산자 사용:
    • num_list 안에 n이 있는지 확인
    • 있으면 True, 없으면 False 반환
  2. 조건부 표현식으로 1 또는 0 반환:
    • True면 1 반환
    • False면 0 반환

더 명시적인 버전:

python
Copydef solution(num_list, n):
    if n in num_list:
        return 1
    return 0

두 방법 모두 같은 결과를 반환하며, 제한사항을 만족합니다.

 

주사위 게임1

def solution(a, b):
# 두 수가 모두 홀수인 경우
   if a % 2 == 1 and b % 2 == 1:
       return a**2 + b**2

# 하나만 홀수인 경우
   elif a % 2 == 1 or b % 2 == 1:
       return 2 * (a + b)

# 둘 다 홀수가 아닌 경우 (짝수)
   else:
       return abs(a - b)

테스트:

print(solution(3, 5))# 34 (둘 다 홀수: 3² + 5² = 34)
print(solution(6, 1))# 14 (하나만 홀수: 2 * (6 + 1) = 14)
print(solution(2, 4))# 2  (둘 다 짝수: |2 - 4| = 2)

설명:

  1. 두 수가 모두 홀수인 경우:
    • a % 2 == 1 and b % 2 == 1로 판별
    • a의 제곱과 b의 제곱의 합 반환
  2. 하나만 홀수인 경우:
    • a % 2 == 1 or b % 2 == 1로 판별
    • (a + b)의 2배 반환
  3. 둘 다 홀수가 아닌 경우:
    • abs()로 두 수의 차의 절대값 반환

각 조건을 순차적으로 확인하여 해당하는 계산을 수행합니다.

 

날짜 비교하기

def solution(date1, date2):
# 각 날짜를 숫자로 변환하여 비교
   d1 = date1[0] * 10000 + date1[1] * 100 + date1[2]
   d2 = date2[0] * 10000 + date2[1] * 100 + date2[2]

# date1이 더 앞선 날짜면 1, 아니면 0 반환
   return 1 if d1 < d2 else 0

다른 방식:

def solution(date1, date2):
# 리스트 직접 비교
    return 1 if date1 < date2 else 0

테스트:

print(solution([2021, 12, 28], [2021, 12, 29]))# 1
print(solution([1024, 10, 24], [1024, 10, 24]))# 0

설명:

  1. 첫 번째 방법:
    • 날짜를 하나의 숫자로 변환하여 비교
    • 연도는 10000을 곱하고, 월은 100을 곱함
    • 예: 2021년 12월 28일 → 20211228
  2. 두 번째 방법:
    • 파이썬의 리스트 비교 기능 사용
    • 첫 요소부터 순서대로 비교
    • 더 작은 값이 나오면 해당 리스트가 더 앞선 날짜

두 방법 모두 같은 결과를 반환하며, 제한사항을 만족합니다

 

DAY24 조건문 활용, 반복문 활용, 이차원 리스트(배열)

 

커피 신부름

def solution(order):
   total = 0

   for drink in order:
# 아메리카노 케이스 (4500원)
       if 'americano' in drink or drink == 'anything':
           total += 4500
# 카페라테 케이스 (5000원)
       elif 'cafelatte' in drink:
           total += 5000

   return total

테스트:

print(solution(["cafelatte", "americanoice", "hotcafelatte", "anything"]))# 19000
print(solution(["americanoice", "americano", "iceamericano"]))# 13500

설명:

  1. 각 주문을 순회하면서:
    • 'americano'가 포함되거나 'anything'이면 4500원 추가
    • 'cafelatte'가 포함되면 5000원 추가
    • 온도는 가격에 영향을 주지 않음
  2. 가격 계산 규칙:
    • 아메리카노: 4500원
      • iceamericano, americanoice
      • hotamericano, americanohot
      • americano
      • anything
    • 카페라테: 5000원
      • icecafelatte, cafelatteice
      • hotcafelatte, cafelattehot
      • cafelatte
  3. 주의사항:
    • 'anything'은 차가운 아메리카노로 처리
    • 온도 표시 없는 음료는 차가운 것으로 처리
    • 온도에 관계없이 같은 가격 적용

 

그림확대

def solution(picture, k):
   result = []

# 각 행을 k배 확대
   for row in picture:
# 각 문자를 k번 반복하여 새로운 행 생성
       expanded_row = ''.join(char * k for char in row)
# 같은 행을 k번 반복하여 결과에 추가
       for _ in range(k):
           result.append(expanded_row)

   return result

테스트:

print(solution([".xx...xx.", "x..x.x..x", "x...x...x", ".x.....x.", "..x...x..", "...x.x...", "....x...."], 2))
print(solution(["x.x", ".x.", "x.x"], 3))

설명:

  1. 가로 확대:
    • 각 문자를 k번 반복
    • 예: 'x' → 'xxx' (k=3)
    # 한 행의 가로 확대 예시
    row = ".x"
    expanded_row = ''.join(char * k for char in row)# k=3이면 "...xxx"
    
    
  2. 세로 확대:
    • 확대된 각 행을 k번 반복
    python
    Coy# 세로 확대 예시
    for _ in range(k):
        result.append(expanded_row)
    
    
  3. 예시 실행 과정 (k=3):
원본:     확대 후:
"x.x""xxx...xxx"
         "xxx...xxx"
         "xxx...xxx"
".x.""...xxx..."
         "...xxx..."
         "...xxx..."
"x.x""xxx...xxx"
         "xxx...xxx"
         "xxx...xxx"

이 코드는 이미지를 k배 확대하면서 각 픽셀('.' 또는 'x')을 k×k 크기로 확대합니다.

 

조건에 맞게 수열변기3

def solution(arr, k):
# k가 홀수면 곱셈, 짝수면 덧셈
   return [x * k if k % 2 == 1 else x + k for x in arr]

또는 더 명시적으로:

def solution(arr, k):
    result = 
# k가 홀수인지 확인
    if k % 2 == 1:
# 홀수면 곱하기
        for x in arr:
            result.append(x * k)
    else:
# 짝수면 더하기
        for x in arr:
            result.append(x + k)
    return result

테스트:

print(solution([1, 2, 3, 100, 99, 98], 3))# [3, 6, 9, 300, 297, 294]
print(solution([1, 2, 3, 100, 99, 98], 2))# [3, 4, 5, 102, 101, 100]

설명:

  1. k가 홀수인지 확인:
    • k % 2 == 1로 홀수 판별
  2. 배열의 각 원소 처리:
    • 홀수면 원소에 k를 곱함
    • 짝수면 원소에 k를 더함
  3. 처리된 원소를 포함하는 새 배열 반환

 

I로 만들기

def solution(myString):
    return ''.join('l' if c < 'l' else c for c in myString)
# join으로 'l','l' ll 이런식으로 연결해준다.

또는 문자열의 replace 메서드를 사용하여:

def solution(myString):
# a부터 k까지의 모든 문자를 'l'로 변경
    for c in 'abcdefghijk':
        myString = myString.replace(c, 'l')
    return myString

테스트:

print(solution("abcdevwxyz"))# "lllllvwxyz"
print(solution("jjnnllkkmm"))# "llnnllllmm"

설명:

  1. 첫 번째 방법:
    • 문자열의 각 문자를 순회
    • 각 문자가 'l'보다 작으면 'l'로 변경, 아니면 그대로 유지
    • join()으로 결과 문자들을 하나의 문자열로 결합
  2. 두 번째 방법:
    • 'l'보다 앞서는 모든 문자(a부터 k까지)에 대해
    • replace() 메서드를 사용하여 'l'로 변경

파이썬에서 문자열 비교는 사전순으로 이루어지므로, 'a' < 'l'은 True가 됩니다.

 

특별한 이차원 배열1

def solution(n):
    return [[1 if i == j else 0 for j in range(n)] for i in range(n)]

  1. 이중 반복문 사용:
def solution(n):
    arr = []
    for i in range(n):
        row = []
        for j in range(n):
            if i == j:
                row.append(1)
            else:
                row.append(
        arr.append(row)
    return arr

  1. 0으로 초기화 후 대각선만 1로 설정:
python
Copy
def solution(n):
    arr = [[0] * n for _ in range(n)]
    for i in range(n):
        arr[i][i] = 1
    return arr

테스트:

python
Copy
print(solution(3))# [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
print(solution(1))# [[1]]

설명:

  1. 첫 번째 방법:
    • 이중 리스트 컴프리헨션 사용
    • i와 j가 같으면 1, 다르면 0
  2. 두 번째 방법:
    • 이중 반복문으로 각 위치 확인
    • 행과 열 인덱스가 같으면 1, 다르면 0
  3. 세 번째 방법:
    • 먼저 모든 원소를 0으로 초기화
    • 대각선 위치(i==j)만 1로 설정

모든 방법이 같은 결과를 반환하며, 제한사항을 만족합니다.

 

DAY25 이차원 리스트(배열)

 

정수를 나선형으로 배치하기

def solution(n):
# n x n 크기의 2차원 배열 생성 및 0으로 초기화
   arr = [[0] * n for _ in range(n)]

# 진행 방향 - 오른쪽, 아래쪽, 왼쪽, 위쪽 순서
   dx = [0, 1, 0, -1]# 행 이동
   dy = [1, 0, -1, 0]# 열 이동

   x, y = 0, 0# 시작 위치
   direction = 0# 시작 방향 (오른쪽)

# 1부터 n^2까지 숫자 채우기
   for i in range(1, n*n + 1):
       arr[x][y] = i

# 다음 위치 계산
       nx = x + dx[direction]
       ny = y + dy[direction]

# 방향 전환이 필요한 경우# 배열을 벗어나거나 이미 숫자가 채워진 경우
       if (nx < 0 or nx >= n or ny < 0 or ny >= n or arr[nx][ny] != 0):
           direction = (direction + 1) % 4# 다음 방향으로 전환
           nx = x + dx[direction]
           ny = y + dy[direction]

       x, y = nx, ny# 위치 이동

   return arr

테스트:

print(solution(4))
# [[1, 2, 3, 4],#  [12, 13, 14, 5],#  [11, 16, 15, 6],#  [10, 9, 8, 7]]

print(solution(5))
# [[1, 2, 3, 4, 5],#  [16, 17, 18, 19, 6],#  [15, 24, 25, 20, 7],#  [14, 23, 22, 21, 8],#  [13, 12, 11, 10, 9]]

설명:

  1. 배열 초기화:
    • n x n 크기의 2차원 배열을 0으로 초기화
  2. 방향 설정:
    • dx, dy 배열로 4가지 방향(오른쪽, 아래쪽, 왼쪽, 위쪽) 정의
    • direction 변수로 현재 진행 방향 관리
  3. 숫자 채우기:
    • 1부터 n^2까지 순서대로 숫자 채움
    • 현재 방향으로 진행하다가 벽이나 이미 채워진 칸을 만나면 방향 전환
  4. 방향 전환 조건:
    • 배열 범위를 벗어날 때
    • 이미 숫자가 채워진 칸에 도달할 때
    • 방향은 시계 방향으로 90도씩 회전

이렇게 하면 시계방향으로 돌면서 나선형으로 숫자가 채워집니다.

특별한 이차원 배열

def solution(arr):
    n = len(arr)

# 모든 원소 쌍을 
    for i in range(n):
        for j in range(n):
            if arr[i][j] != arr[j][i]:
                return 0

    return 1

최적화된 버전:

def solution(arr):
    n = len(arr)

# 절반만 비교 (대각선 위쪽만)
    for i in range(n):
        for j in range(i + 1, n):# i보다 큰 j에 대해서만 검사
            if arr[i][j] != arr[j][i]:
                return 0

    return 1

테스트:

print(solution([[5, 192, 33], [192, 72, 95], [33, 95, 999]]))# 1
print(solution([[19, 498, 258, 587], [63, 93, 7, 754],
                [258, 7, 1000, 723], [587, 754, 723, 81]]))# 0

설명:

  1. 첫 번째 방법:
    • 모든 원소 쌍을 비교
    • arr[i][j]와 arr[j][i]가 다른 경우가 있으면 0 반환
    • 모든 쌍이 같으면 1 반환
  2. 두 번째 방법 (최적화):
    • 대각선을 기준으로 위쪽 영역만 검사
    • 대칭이므로 절반만 검사해도 충분
    • j는 i+1부터 시작하여 중복 검사 방지

두 방법 모두 같은 결과를 반환하지만, 두 번째 방법이 더 효율적입니다.

  • 첫 번째 방법: n² 번 비교
  • 두 번째 방법: n(n-1)/2 번 비교

정사각형으로 만들기

def solution(arr):
   rows = len(arr)# 행의 수
   cols = len(arr[0])# 열의 수
   target = max(rows, cols)# 목표 크기

   if rows > cols:# 행이 더 많은 경우# 각 행에 0 추가
       for i in range(rows):
           arr[i].extend([0] * (target - cols))

   elif cols > rows:# 열이 더 많은 경우# 새로운 행 추가
       for _ in range(target - rows):
           arr.append([0] * cols)

   return arr

테스트:

python
Copy
print(solution([[572, 22, 37], [287, 726, 384], [85, 137, 292], [487, 13, 876]]))
# [[572, 22, 37, 0], [287, 726, 384, 0], [85, 137, 292, 0], [487, 13, 876, 0]]

print(solution([[57, 192, 534, 2], [9, 345, 192, 999]]))
# [[57, 192, 534, 2], [9, 345, 192, 999], [0, 0, 0, 0], [0, 0, 0, 0]]

print(solution([[1, 2], [3, 4]]))
# [[1, 2], [3, 4]]

설명:

  1. 크기 확인:
    • 현재 행과 열의 수 확인
    • 목표 크기를 행과 열 중 큰 값으로 설정
  2. 행이 더 많은 경우:
    • 각 행의 끝에 0을 추가
    • extend() 메서드로 필요한 만큼의 0을 추가
  3. 열이 더 많은 경우:
    • 새로운 행(모두 0으로 구성)을 추가
    • append() 메서드로 0으로 채워진 행 추가
  4. 행과 열이 같은 경우:
    • 추가 작업 없이 원래 배열 반환

주의사항:

  • 행과 열의 길이를 같게 만들어야 함
  • 새로 추가되는 값은 모두 0이어야 함
  • 원본 배열의 값은 보존되어야 함

이차원 배열 대각선 순회하기

def solution(board, k):
# i + j <= k를 만족하는 원소들의 합 계산
   total = 0
   for i in range(len(board)):
       for j in range(len(board[0])):
           if i + j <= k:
               total += board[i][j]
   return total

또는 리스트 컴프리헨션을 사용하여:

def solution(board, k):
    return sum(board[i][j]
              for i in range(len(board))
              for j in range(len(board[0]))
              if i + j <= k)

테스트:

board = [[0, 1, 2],
         [1, 2, 3],
         [2, 3, 4],
         [3, 4, 5]]
k = 2
print(solution(board, k))# 8

설명:

  1. 2차원 배열 순회:
    • i는 행 인덱스 (0부터 board의 길이-1까지)
    • j는 열 인덱스 (0부터 board[0]의 길이-1까지)
  2. 조건 확인:
    • i + j가 k 이하인 경우만 처리
  3. 합계 계산:
    • 조건을 만족하는 원소들의 합을 누적

예시 동작 (k=2):

[0,1,2]    * 표시는 i+j <= 2인 위치
[1,2,3]    [*,*,*]
[2,3,4]    [*,*,_]
[3,4,5]    [*,_,_]
           [_,_,_]

합계: 0 + 1 + 2 + 1 + 2 + 2 = 8

반응형