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

프로그래머스 코딩 기초 트레이닝 Python Day6 ~ Day15출처

code2772 2025. 2. 10. 13:36
728x90
반응형

DAY6 조건문 반복문

 

마지막 두 원소

def solution(num_list):
# 마지막 원소와 그 전 원소 비교
    if num_list[-1] > num_list[-2]:
# 마지막 원소가 더 크면 그 차이를 추가
        num_list.append(num_list[-1] - num_list[-2])
    else:
# 마지막 원소가 더 크지 않으면 마지막 원소의 두 배를 추가
        num_list.append(num_list[-1] * 2)

    return num_list

설명:

  1. 리스트의 마지막 원소와 그 전 원소 비교:
    • num_list[-1]은 마지막 원소
    • num_list[-2]는 마지막에서 두 번째 원소
  2. 조건에 따른 값 추가:
    • 마지막 원소가 더 크면: 두 원소의 차이를 추가
    • 마지막 원소가 더 크지 않으면: 마지막 원소의 2배를 추가

테스트 케이스:

print(solution([2, 1, 6]))# [2, 1, 6, 5]
print(solution([5, 2, 1, 7, 5]))# [5, 2, 1, 7, 5, 10]

또는 리스트 슬라이싱을 사용하여 더 간단하게 작성할 수도 있습니다:

def solution(num_list):
    return num_list + [num_list[-1] - num_list[-2] if num_list[-1] > num_list[-2] else num_list[-1] * 2]

 

수 조작하기 1

def solution(n, control):
# 각 문자에 대한 동작을 딕셔너리로 정의
    actions = {
        'w': 1,
        's': -1,
        'd': 10,
        'a': -10
    }

# control의 각 문자에 대해 해당하는 값을 n에 더함
    for c in control:
        n += actions[c]

    return n

또는 더 간단하게:

python
Copy
def solution(n, control):
    return n + control.count('w') - control.count('s') + 10*control.count('d') - 10*control.count('a')

설명:

  1. 첫 번째 방법:
    • 각 문자에 대한 동작을 딕셔너리로 정의
    • control 문자열을 순회하며 각 문자에 해당하는 값을 n에 더함
  2. 두 번째 방법:
    • 각 문자의 등장 횟수를 count()로 세어서
    • 한 번에 계산
    • w는 +1, s는 -1, d는 +10, a는 -10

테스트 케이스:

print(solution(0, "wsdawsdassw"))# -1

두 방식 모두 같은 결과를 도출하며, 제한사항(-100,000 ≤ n ≤ 100,000, 1 ≤ control의 길이 ≤ 100,000)을 만족합니다.

 

수 조작하기 2

def solution(numLog):
    result = ''

# 각 차이값에 대응하는 조작 문자를 딕셔너리로 정의
    operations = {
        1: 'w',# 1 증가
        -1: 's',# 1 감소
        10: 'd',# 10 증가
        -10: 'a'# 10 감소
    }

# 연속된 두 수의 차이를 확인하여 해당하는 조작 문자 추가
    for i in range(1, len(numLog)):
        diff = numLog[i] - numLog[i-1]
        result += operations[diff]

    return result

설명:

  1. 결과 문자열 초기화:
    • 빈 문자열로 시작
  2. 조작 매핑 정의:
    • 1 → 'w
    • 1 → 's'
    • 10 → 'd'
    • 10 → 'a'
  3. 숫자 배열 순회:
    • 연속된 두 수의 차이 계산
    • 차이값에 해당하는 조작 문자를 결과에 추가

테스트 케이스:

print(solution([0, 1, 0, 10, 0, 1, 0, 10, 0, -1, -2, -1]))# "wsdawsdassw"

더 간단한 버전으로도 작성할 수 있습니다:

def solution(numLog):
    return ''.join(['w' if n==1 else 's' if n==-1 else 'd' if n==10 else 'a'
                   for n in [b-a for a, b in zip(numLog, numLog[1:])]])

 

수열과 구간 쿼리 3

def solution(arr, queries):
# 각 쿼리에 대해 위치 교환 수행
    for i, j in queries:
# 두 원소의 위치 교환
        arr[i], arr[j] = arr[j], arr[i]

    return arr

설명:

  1. queries 순회:
    • 각 쿼리에서 i, j 값을 추출
  2. 위치 교환:
    • 파이썬의 다중 할당을 사용하여 두 원소의 위치를 교환
    • arr[i], arr[j] = arr[j], arr[i]

테스트 케이스:

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

또는 임시 변수를 사용하여 더 명시적으로 작성할 수도 있습니다:

def solution(arr, queries):
    for i, j in queries:
# 임시 변수를 사용한 교환
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

    return arr

 

수열과 구간 쿼리

def solution(arr, queries):
    result = []

    for s, e, k in queries:
# 범위 내에서 k보다 큰 값들만 필터링
        filtered = [x for x in arr[s:e+1] if x > k]

# k보다 큰 값이 있으면 최솟값을, 없으면 -1을 추가
        result.append(min(filtered) if filtered else -1)

    return result

설명:

  1. 결과 배열 초기화:
    • 빈 리스트로 시작
  2. 각 쿼리 처리:
    • s, e, k 값 추출
    • arr[s:e+1]로 해당 범위의 값들 선택
    • k보다 큰 값들만 필터링
  3. 결과 계산:
    • 필터링된 값이 있으면 그 중 최솟값을 추가
    • 필터링된 값이 없으면 -1을 추가

테스트 케이스:

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

또는 더 명시적으로 작성할 수도 있습니다:

def solution(arr, queries):
    result = []

    for s, e, k in queries:
        min_val = float('inf')# 초기값을 무한대로 설정

# 범위 내 값들을 순회하며 k보다 큰 최솟값 찾기
        for i in range(s, e + 1):
            if arr[i] > k:
                min_val = min(min_val, arr[i])

# k보다 큰 값을 찾았으면 그 값을, 못 찾았으면 -1을 추가
        result.append(min_val if min_val != float('inf') else -1)

    return result

두 방식 모두 같은 결과를 도출하며, 제한사항을 만족합니다. 첫 번째 방법이 더 파이썬스럽고 간결하지만, 두 번째 방법이 메모리 사용 면에서 더 효율적일 수 있습니다.

 

DAY7 반복문

 

수열과 구관 쿼리

def solution(arr, queries):
    for s, e, k in queries:
# k가 0인 경우 처리 (0으로 나누기 방지)
        if k == 0:
            continue

# 범위 내에서 k의 배수 인덱스의 값 증가
        for i in range(s, e + 1):
            if i % k == 0:# i가 k의 배수인 경우
                arr[i] += 1

    return arr

설명:

  1. queries 순회:
    • 각 쿼리에서 s(시작), e(끝), k(배수) 값 추출
  2. 범위 내 값 처리:
    • s부터 e까지의 인덱스 순회
    • 각 인덱스 i가 k의 배수인지 확인
    • k의 배수이면 arr[i]의 값을 1 증가

테스트 케이스:

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

또는 리스트 컴프리헨션을 사용하여 더 파이썬스럽게 작성할 수도 있습니다:

def solution(arr, queries):
    for s, e, k in queries:
        if k != 0:# 0으로 나누기 방지
            arr = [val + 1 if s <= i <= e and i % k == 0 else val
                  for i, val in enumerate(arr)]
    return arr

두 방식 모두 같은 결과를 도출하며, 제한사항을 만족합니다. 첫 번째 방법이 더 직관적이고 이해하기 쉽습니다.

 

배열 만들기

def solution(l, r):
    result = []

# l부터 r까지 순회하면서 각 숫자 확인
    for num in range(l, r + 1):
# 숫자를 문자열로 변환하여 각 자리수 확인
        if all(digit in '05' for digit in str(num)):
            result.append(num)

# 조건을 만족하는 숫자가 없으면 [-1] 반환
    return result if result else [-1]

설명:

  1. 결과를 저장할 빈 리스트 생성
  2. l부터 r까지 각 숫자 검사:
  3. for num in range(l, r + 1): str_num = str(num)# 숫자를 문자열로 변환
  4. 각 숫자의 모든 자리수가 0 또는 5인지 확인:
  5. if all(digit in '05' for digit in str(num)): # all()은 모든 조건이 True일 때만 True 반환# digit in '05'는 각 자리수가 '0' 또는 '5'인지 확인
  6. 조건을 만족하면 결과 리스트에 추가:
  7. result.append(num)

테스트:

print(solution(5, 555))# [5, 50, 55, 500, 505, 550, 555]
print(solution(10, 20))# [-1]

또는 더 효율적인 방법으로 작성할 수 있습니다:

def solution(l, r):
    result = []

# 이진수 활용: 0과 5만 사용하여 숫자 생성
    for i in range(len(str(r))):
        for j in range(2**i):
# 이진수를 0과 5로 변환
            num = int(bin(j)[2:].replace('1', '5').replace('0', '0'))
            if l <= num <= r:
                result.append(num)

    return sorted(result) if result else [-1]

 

카운트업

range(start, end)는 start부터 end-1까지의 숫자를 생성

def solution(start_num, end_num):
    return list(range(start_num, end_num + 1))

설명:

  1. range(start_num, end_num + 1)를 사용하여 시작 숫자부터 끝 숫자까지의 연속된 숫자 생성
  2. list()를 사용하여 range 객체를 리스트로 변환

또는 리스트 컴프리헨션을 사용할 수도 있습니다:

def solution(start_num, end_num):
    return [i for i in range(start_num, end_num + 1)]

 

콜라츠 수열

def solution(n):
    result = [n]# 초기값 n을 포함한 수열

    while n != 1:# n이 1이 될 때까지 반복
        if n % 2 == 0:# 짝수일 경우
            n = n // 2
        else:# 홀수일 경우
            n = 3 * n + 1
        result.append(n)

    return result

설명:

  1. 초기화:
    • result 리스트에 시작값 n을 먼저 추가
  2. 반복 과정:
    • n이 1이 될 때까지 반복
    • n이 짝수면 2로 나눔
    • n이 홀수면 3을 곱하고 1을 더함
    • 각 단계의 결과를 result에 추가

테스트 케이스:

print(solution(10))# [10, 5, 16, 8, 4, 2, 1]

각 단계별로 어떻게 진행되는지 보면:

10 (짝수) → 10 ÷ 2 = 5
5 (홀수) → 3 × 5 + 1 = 16
16 (짝수) → 16 ÷ 2 = 8
8 (짝수) → 8 ÷ 2 = 4
4 (짝수) → 4 ÷ 2 = 2
2 (짝수) → 2 ÷ 2 = 1

 

배열 만들기

def solution(arr):
    stk = []# 빈 스택으로 시작
    i = 0# 인덱스 초기값

    while i < len(arr):
# stk가 비어있는 경우
        if not stk:
            stk.append(arr[i])
            i += 1

# stk의 마지막 원소가 arr[i]보다 작은 경우
        elif stk[-1] < arr[i]:
            stk.append(arr[i])
            i += 1

# stk의 마지막 원소가 arr[i]보다 크거나 같은 경우
        else:
            stk.pop()

    return stk

과정을 자세히 설명하면:

예시: arr = [1, 4, 2, 5, 3]

  1. 첫 번째 반복 (i=0):
    • stk는 비어있음
    • arr[0]=1을 stk에 추가
    • stk = [1]
  2. 두 번째 반복 (i=1):
    • stk[-1]=1 < arr[1]=4
    • 4를 stk에 추가
    • stk = [1, 4]
  3. 세 번째 반복 (i=2):
    • stk[-1]=4 > arr[2]=2
    • 4를 stk에서 제거
    • stk = [1, 2]
  4. 네 번째 반복 (i=3):
    • stk[-1]=2 < arr[3]=5
    • 5를 stk에 추가
    • stk = [1, 2, 5]
  5. 마지막 반복 (i=4):
    • stk[-1]=5 > arr[4]=3
    • 5를 stk에서 제거
    • stk = [1, 2, 3]

최종 결과: [1, 2, 3]

 

DAY8 조건문 문자열

 

간단한 논리연산자

def solution(x1, x2, x3, x4):
    return (x1 or x2) and (x3 or x4)

설명:

  1. x1 or x2: 첫 번째 괄호의 OR 연산
  2. x3 or x4: 두 번째 괄호의 OR 연산
  3. 두 결과를 AND 연산

파이썬에서:

  • OR 연산은 or 키워드 사용
  • AND 연산은 and 키워드 사용

 

주사위 게임

def solution(a, b, c, d):
# 각 숫자의 등장 횟수를 딕셔너리로 저장
   counts = {}
   for num in [a, b, c, d]:
       counts[num] = counts.get(num, 0) + 1

# 등장 횟수별로 분류
   if len(counts) == 1:# 모두 같은 경우
       p = list(counts.keys())[0]
       return 1111 * p

   elif len(counts) == 2:# 두 종류의 숫자가 나온 경우
       nums = list(counts.items())# (숫자, 등장횟수) 튜플의 리스트
       if 3 in counts.values():# 3:1로 나뉜 경우
           p = next(num for num, count in nums if count == 3)
           q = next(num for num, count in nums if count == 1)
           return (10 * p + q) ** 2
       else:# 2:2로 나뉜 경우
           p, q = nums[0][0], nums[1][0]
           return (p + q) * abs(p - q)

   elif len(counts) == 3:# 세 종류의 숫자가 나온 경우# 2개인 숫자를 찾고, 나머지 1개씩인 숫자들을 곱함
       p = next(num for num, count in counts.items() if count == 2)
       q, r = [num for num, count in counts.items() if count == 1]
       return q * r

   else:# 모두 다른 경우
       return min(counts.keys())

설명:

  1. 숫자의 등장 횟수를 딕셔너리에 저장:
    • key: 주사위 숫자
    • value: 등장 횟수
  2. 등장한 숫자의 종류 수(len(counts))에 따라 다른 로직 적용: a) len(counts) == 1인 경우:

b) len(counts) == 2인 경우:

c) len(counts) == 3인 경우:

d) len(counts) == 4인 경우: - 모두 같은 숫자 (예: 2,2,2,2) - 1111 × p 반환 - 3:1로 나뉜 경우 (예: 4,4,4,1) - (10 × p + q)² 반환 - 2:2로 나뉜 경우 (예: 6,6,3,3) - (p + q) × |p - q| 반환 - 2:1:1로 나뉜 경우 (예: 2,2,5,6) - q × r 반환 - 모두 다른 경우 - 최솟값 반환

 

글자 이어붙이기

def solution(my_string, index_list):
    return ''.join(my_string[i] for i in index_list)

설명:

  1. index_list의 각 인덱스를 사용하여 my_string에서 해당 위치의 문자를 추출
  2. join()을 사용하여 추출된 문자들을 하나의 문자열로 연결

또는 더 명시적으로 작성할 수도 있습니다:

def solution(my_string, index_list):
    result = ''
    for index in index_list:
        result += my_string[index]
    return result

 

9로 나눈 나머지

def solution(number):
# 각 자리 숫자의 합 계산
    digit_sum = sum(int(digit) for digit in number)

# 9로 나눈 나머지 반환
    return digit_sum % 9

설명:

  1. 문자열의 각 자리 숫자를 정수로 변환하여 합계 계산:
    • number의 각 문자(digit)를 i()로 변환
    • sum()으로 모든 숫자의 합 계산
  2. 합계를 9로 나눈 나머지 반환:
    • digit_sum % 9

테스트 케이스:

print(solution("123"))# 6 (1+2+3 = 6)
print(solution("78720646226947352489"))# 2 (7+8+7+...+9 = 101, 101 % 9 = 2)

또는 더 간단하게 한 줄로도 작성할 수 있습니다:

def solution(number):
    return sum(int(digit) for digit in number) % 9

이 코드는 제한사항을 모두 만족하며, 문제에서 설명한 수학적 성질을 이용하여 정확한 결과를 반환합니다.

 

문자열 여러번 뒤집기

def solution(my_string, queries):
# 문자열을 리스트로 변환 (문자열은 불변이므로)
    str_list = list(my_string)

# 각 쿼리 처리
    for s, e in queries:
# s부터 e까지의 부분을 뒤집기
        str_list[s:e+1] = str_list[s:e+1][::-1]

# 리스트를 다시 문자열로 변환
    return ''.join(str_list)

설명:

  1. 문자열을 리스트로 변환:
    • 문자열은 불변이므로 수정 가능한 리스트로 변환
  2. 각 쿼리 처리:
    • queries의 각 원소 [s, e]에 대해
    • s부터 e까지의 부분 문자열을 뒤집기
    • [::-1]은 시퀀스를 뒤집는 파이썬의 슬라이싱 문법
  3. 결과 반환:
    • 수정된 리스트를 join()으로 문자열로 변환

테스트:

print(solution("rermgorpsam", [[2, 3], [0, 7], [5, 9], [6, 10]]))
# "programmers"# 단계별 변화# "rermgorpsam" (초기)# "remrgorpsam" (첫 번째 쿼리 후)# "progrmersam" (두 번째 쿼리 후)# "prograsremm" (세 번째 쿼리 후)# "programmers" (마지막 쿼리 후)

또 다른 방법으로는:

def solution(my_string, queries):
    result = my_string
    for s, e in queries:
# 문자열을 세 부분으로 나누어 처리
        result = result[:s] + result[s:e+1][::-1] + result[e+1:]
    return result

 

DAY9 문자열

 

배열 만들기

def solution(intStrs, k, s, l):
   result = []

   for str_num in intStrs:
# s 인덱스부터 l 길이만큼 잘라서 정수로 변환
       num = int(str_num[s:s+l])

# k보다 큰 경우만 결과에 추가
       if num > k:
           result.append(num)

   return result

설명:

  • intStrs의 각 문자열에서 s부터 s+l까지 부분문자열 추출
  • 추출한 문자열을 정수로 변환
  • k보다 큰 경우만 결과 배열에 추가

 

부분 문자열 잘라서 문자열 만들기

def solution(my_strings, parts):
   return ''.join(s[start:end+1] for s, (start, end) in zip(my_strings, parts))

같은 작업을 더 명시적으로 표현하면:

def solution(my_strings, parts):
    result = ''
    for i in range(len(my_strings)):
        s = my_strings[i]
        start, end = parts[i]
        result += s[start:end+1]
    return result

동작 설명:

  • my_strings의 각 문자열에서 parts에 지정된 범위의 부분 문자열을 추출
  • 추출된 부분 문자열들을 순서대로 이어붙임

테스트:

print(solution(
    ["progressive", "hamburger", "hammer", "ahocorasick"],
    [[0, 4], [1, 2], [3, 5], [7, 7]]
))# "pr

 

문자열 뒤의 N글자

def solution(my_string, n):
   return my_string[-n:]

또는 더 명시적으로:

def solution(my_string, n):
    length = len(my_string)
    return my_string[length-n:]

 

접미사 배열

def solution(my_string):
# 모든 접미사 생성 및 정렬
   suffixes = [my_string[i:] for i in range(len(my_string))]
   return sorted(suffixes)

설명:

  1. 문자열의 0부터 끝까지 각 인덱스에서 시작하는 접미사를 생성
  2. 생성된 접미사들을 사전순으로 정렬

테스트:

print(solution("banana"))
# ["a", "ana", "anana", "banana", "na", "nana"]

print(solution("programmers"))
# ["ammers", "ers", "grammers",

 

접미사인지 확인하기

def solution(my_string, is_suffix):
# is_suffix가 my_string의 끝부분과 일치하는지 확인
   if len(is_suffix) > len(my_string):
       return 0
   return 1 if my_string.endswith(is_suffix) else 0

또는:

def solution(my_string, is_suffix):
    return int(my_string[-len(is_suffix):] == is_suffix) if len(is_suffix) <= len(my_string) else 0

테스트:

print(solution("banana", "ana"))# 1
print(solution("banana", "nan"))# 0
print(solution("banana", "wxyz"))# 0
print(solution("banana", "abanana"))# 0

 

DAY10 문자열

 

문자열의 앞의 n글자

def solution(my_string, n):
   return my_string[:n]

테스트:

print(solution("ProgrammerS123", 11))# "ProgrammerS"
print(solution("He110W0r1d", 5))# "He110"

 

접두사인지 확인하기

def solution(my_string, is_prefix):
# is_prefix가 my_string의 시작 부분과 일치하는지 확인
   if len(is_prefix) > len(my_string):
       return 0
   return 1 if my_string.startswith(is_prefix) else 0

테스트:

print(solution("banana", "ban"))# 1
print(solution("banana", "nan"))# 0
print(solution("banana", "abcd"))# 0
print(solution("banana", "bananan"))# 0

 

문자열 뒤집기

def solution(my_string, s, e):
# 문자열을 세 부분으로 나누어 처리
   return my_string[:s] + my_string[s:e+1][::-1] + my_string[e+1:]

또는 리스트를 사용하는 방법:

def solution(my_string, s, e):
# 문자열을 리스트로 변환
    string_list = list(my_string)

# s부터 e까지 부분을 뒤집기
    string_list[s:e+1] = string_list[s:e+1][::-1]

# 리스트를 다시 문자열로 변환
    return ''.join(string_list)

테스트:

print(solution("Progra21Sremm3", 6, 12))# "ProgrammerS123"
print(solution("Stanley1yelnatS", 4, 10))# "Stanley1yelnatS"

 

세로 읽기

def solution(my_string, m, c):
   return my_string[c-1::m]

더 명시적인 버전:

def solution(my_string, m, c):
# 문자열을 m 길이로 나누어 c번째 문자만 추출
    result = ''
    for i in range(c-1, len(my_string), m):
        result += my_string[i]
    return result

테스트:

print(solution("ihrhbakrfpndopljhygc", 4, 2))# "happy"
print(solution("programmers", 1, 1))

 

qr code

def solution(q, r, code):
   return ''.join(c for i, c in enumerate(code) if i % q == r)

테스트:

print(solution(3, 1, "qjnwezgrpirldywt"))# "jerry"
print(solution(1, 0, "programmers"))# "programmers"

설명:

  • 문자열의 각 인덱스를 q로 나눈 나머지가 r과 일치하는 문자만 선택
  • 선택된 문자들을 순서대로 이어붙여 반환

 

DAY11 리스트 배열

 

문자 개수 새기

def solution(my_string):
# 길이 52의 배열 초기화 (A-Z, a-z)
   result = [0] * 52

   for char in my_string:
       if char.isupper():
# 대문자인 경우 (A=65, 인덱스 0부터)
           result[ord(char) - 65] += 1
       else:
# 소문자인 경우 (a=97, 인덱스 26부터)
           result[ord(char) - 97 + 26] += 1

   return result

테스트:

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

 

배열 만들기1

def solution(n, k):
   return [i for i in range(k, n + 1, k)]

  • range() 함수의 구조:
    • 첫 번째 인자 k: 시작 값
    • 두 번째 인자 n + 1: 끝 값 (이 값은 포함되지 않음)
    • 세 번째 인자 k: 간격(step)
  • [i for i in ...] 리스트 컴프리헨션:
    • i는 range에서 생성되는 각 숫자를 임시로 저장하는 변수
    • range가 생성하는 각 숫자가 순서대로 i에 할당됨

또는:

def solution(n, k):
    return list(range(k, n + 1, k))

테스트:

print(solution(10, 3))# [3, 6, 9]
print(solution(15, 5))# [5, 10, 15]

 

글자 지우기

def solution(my_string, indices):
# indices를 제외한 위치의 문자들만 가져와서 새 문자열 생성
   return ''.join(char for i, char in enumerate(my_string) if i not in indices)

또는:

def solution(my_string, indices):
# 문자열을 리스트로 변환
    string_list = list(my_string)

# indices에 해당하는 위치의 문자 제거
    for i in sorted(indices, reverse=True):
        string_list.pop(i)

# 리스트를 다시 문자열로 변환
    return ''.join(string_list)

예시:

print(solution("apporoograpemmemprs", [1, 16, 6, 15, 0, 10, 11, 3]))
# "programmers"

카운트 다운

def solution(start_num, end_num):
   return list(range(start_num, end_num - 1, -1))

테스트:

print(solution(10, 3))# [10, 9, 8, 7, 6, 5, 4, 3]

range(start, stop, step) 설명:

  • start: 시작값 (10)
  • stop: 끝값-1 (3-1=2, 포함되지 않음)
  • step: -1 (감소)

 

가까운 1 찾기

def solution(arr, idx):
   for i in range(idx, len(arr)):
       if arr[i] == 1:
           return i
   return -1

또는 더 간단하게:

def solution(arr, idx):
    try:
        return idx + arr[idx:].index(1)
    except ValueError:
        return -1

테스트:

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

 

DAY12 리스트 배열2

 

리스트 자르기

def solution(n, slicer, num_list):
   a, b, c = slicer

   if n == 1:
       return num_list[:b+1]
   elif n == 2:
       return num_list[a:]
   elif n == 3:
       return num_list[a:b+1]
   else:# n == 4
       return num_list[a:b+1:c]

테스트:

print(solution(3, [1, 5, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9]))# [2, 3, 4, 5, 6]
print(solution(4, [1, 5, 2], [1, 2, 3, 4, 5, 6, 7, 8, 9]))# [2, 4, 6]

 

첫 번째로 나오는 음수

def solution(num_list):
   for i, num in enumerate(num_list):
       if num < 0:
           return i
   return -1

또는:

def solution(num_list):
    try:
        return next(i for i, num in enumerate(num_list) if num < 0)
    except StopIteration:
        return -1

테스트:

print(solution([12, 4, 15, 46, 38, -2, 15]))# 5
print(solution([13, 22, 53, 24, 15, 6]))# -1

 

배열 만들기 3

def solution(arr, intervals):
   a1, b1 = intervals[0]
   a2, b2 = intervals[1]
   return arr[a1:b1+1] + arr[a2:b2+1]

테스트:

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

 

2의 영역

def solution(arr):
# 2의 위치 찾기
   indices = [i for i, num in enumerate(arr) if num == 2]

# 2가 없으면 [-1] 반환
   if not indices:
       return [-1]

# 첫 2와 마지막 2 사이의 부분 배열 반환
   return arr[indices[0]:indices[-1] + 1]

테스트:

print(solution([1, 2, 1, 4, 5, 2, 9]))# [2, 1, 4, 5, 2]
print(solution([1, 2, 1]))# [2]
print(solution([1, 1, 1]))# [-1]
print(solution([1, 2, 1, 2, 1, 10, 2, 1]))# [2, 1, 2, 1, 10, 2]

 

배열 조작하기

def solution(arr, query):
   for i, q in enumerate(query):
       if i % 2 == 0:# 짝수 인덱스
           arr = arr[:q + 1]# 뒷부분 자르기
       else:# 홀수 인덱스
           arr = arr[q:]# 앞부분 자르기
   return arr

테스트:

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

예시 실행 과정:

  1. q=4 (짝수 인덱스): [0,1,2,3,4] 남음
  2. q=1 (홀수 인덱스): [1,2,3,4] 남음
  3. q=2 (짝수 인덱스): [1,2,3] 남음

 

DAY13 리스트(배열)

 

n 번째 원소부터

def solution(num_list, n):
   return num_list[n-1:]

테스트:

print(solution([2, 1, 6], 3))# [6]
print(solution([5, 2, 1, 7, 5], 2))# [2, 1, 7, 5]

  • n-1 인덱스부터 마지막까지 슬라이싱
  • n이 1부터 시작하므로 n-1로 인덱스 조정

 

순서 바꾸기

def solution(num_list, n):
   return num_list[n:] + num_list[:n]

테스트:

print(solution([2, 1, 6], 1))# [1, 6, 2]
print(solution([5, 2, 1, 7, 5], 3))# [7, 5, 5, 2, 1]

리스트 슬라이싱으로:

  1. num_list[n:] : n번째 이후 원소들
  2. num_list[:n] : n번째까지의 원소들
  3. 두 부분을 + 연산자로 연결

 

왼쪽 오른쪽

def solution(str_list):
   for i, s in enumerate(str_list):
       if s == "l":
           return str_list[:i]
       if s == "r":
           return str_list[i+1:]
   return []

테스트:

print(solution(["u", "u", "l", "r"]))# ["u", "u"]
print(solution(["l"]))# []

 

n번째 원소까지

def solution(num_list, n):
   return num_list[:n]

테스트:

print(solution([2, 1, 6], 1))# [2]
print(solution([5, 2, 1, 7, 5], 3))# [5, 2, 1]

 

n 개 간격의 원소들

def solution(num_list, n):
   return num_list[::n]

테스트:

print(solution([4, 2, 6, 1, 7, 6], 2))# [4, 6, 7]
print(solution([4, 2, 6, 1, 7, 6], 4))# [4, 7]

[::n]은 리스트를 n 간격으로 슬라이싱합니다.

 

DAY14 리스트(배열)

 

홀수 vs 짝수

def solution(num_list):
# 홀수 번째(인덱스로는 0, 2, 4...) 원소들의 합
   odd_sum = sum(num_list[::2])

# 짝수 번째(인덱스로는 1, 3, 5...) 원소들의 합
   even_sum = sum(num_list[1::2])

# 더 큰 값 반환
   return max(odd_sum, even_sum)

테스트:

print(solution([4, 2, 6, 1, 7, 6]))# 17
print(solution([-1, 2, 5, 6, 3]))# 8

다른 방법:

def solution(num_list):
# 인덱스로 직접 접근하여 계산
    odd_sum = sum(x for i, x in enumerate(num_list) if i % 2 == 0)
    even_sum = sum(x for i, x in enumerate(num_list) if i % 2 == 1)
    return max(odd_sum, even_sum)

 

5명씩

def solution(names):
   return names[::5]

테스트:

print(solution(["nami", "ahri", "jayce", "garen", "ivern", "vex", "jinx"]))
# ["nami", "vex"]

설명:

  1. names[::5]는 리스트를 5개 간격으로 슬라이싱합니다:
    • 첫 번째 그룹(0~4)의 첫 번째 이름
    • 두 번째 그룹(5~9)의 첫 번째 이름
    • 이런 식으로 계속...
  2. 예시에서:
    • 첫 번째 그룹: ["nami", "ahri", "jayce", "garen", "ivern"]
    • 두 번째 그룹: ["vex", "jinx"]
    • 각 그룹의 첫 번째 이름: ["nami", "vex"]

 

할 일 목록

def solution(todo_list, finished):
# finished가 False인 인덱스의 todo_list 항목만 필터링
   return [task for task, is_done in zip(todo_list, finished) if not is_done]

또는 더 명시적으로:

python
Copydef solution(todo_list, finished):
    result = []
    for i in range(len(todo_list)):
        if not finished[i]:# 아직 완료하지 못한 일
            result.append(todo_list[i])
    return result

테스트:

print(solution(
    ["problemsolving", "practiceguitar", "swim", "studygraph"],
    [True, False, True, False]
))
# ["practiceguitar", "studygraph"]

설명:

  1. todo_list와 finished 배열을 동시에 순회하면서
  2. finished가 False인 항목(아직 완료하지 못한 일)만 선택하여
  3. 새로운 배열에 담아 반환

 

N보다 커질 떄까지 더하기

def solution(numbers, n):
   total = 0
   for num in numbers:
       total += num
       if total > n:
           return total
   return total

또는 더 파이썬스럽게:

def solution(numbers, n):
    sum_numbers = 0
    return next(sum_numbers := sum_numbers + x for x in numbers if (sum_numbers := sum_numbers + x) > n)

테스트:

print(solution([34, 5, 71, 29, 100, 34], 123))# 139
print(solution([58, 44, 27, 10, 100], 139))# 239

설명:

  1. 첫 번째 방법:
    • 합계를 저장할 변수(total) 초기화
    • 숫자를 하나씩 더해가면서
    • n보다 커지는 순간의 합계 반환
  2. 예시 실행 과정 ([34, 5, 71, 29, 100, 34], n=123):
  3. 34 -> sum = 34 +5 -> sum = 39 +71 -> sum = 110 +29 -> sum = 139 > 123, 따라서 139 반환

 

수열과 구간 쿼리1

def solution(arr, queries):
# 각 쿼리마다 처리
   for s, e in queries:
# s부터 e까지의 인덱스에 1씩 더하기
       for i in range(s, e + 1):
           arr[i] += 1
   return arr

테스트:

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

단계별 실행 과정:

초기: [0, 1, 2, 3, 4]

[0, 1] 쿼리 처리:
- 인덱스 0, 11 더하기
- [1, 2, 2, 3, 4]

[1, 2] 쿼리 처리:
- 인덱스 1, 21 더하기
- [1, 3, 3, 3, 4]

[2, 3] 쿼리 처리:
- 인덱스 2, 31 더하기
- [1, 3, 4, 4, 4]

 

DAY15 리스트 배열, 문자열

 

조건에 맞게 수욜 변환하기1

def solution(arr):
   result = []
   for num in arr:
# 50 이상이고 짝수인 경우
       if num >= 50 and num % 2 == 0:
           result.append(num // 2)
# 50 미만이고 홀수인 경우
       elif num < 50 and num % 2 == 1:
           result.append(num * 2)
# 그 외의 경우는 그대로 유지
       else:
           result.append(num)
   return result

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

def solution(arr):
    return [num // 2 if num >= 50 and num % 2 == 0 else
            num * 2 if num < 50 and num % 2 == 1 else
            num for num in arr]

테스트:

print(solution([1, 2, 3, 100, 99, 98]))# [2, 2, 6, 50, 99, 49]

각 단계별 설명:

  1. 1: 50 미만 홀수 → 2
  2. 2: 조건 해당 없음 → 2
  3. 3: 50 미만 홀수 → 6
  4. 100: 50 이상 짝수 → 50
  5. 99: 조건 해당 없음 → 99
  6. 98: 50 이상 짝수 → 49

 

조건에 맞게 수욜 변환하기2

def transform_array(arr):
# 주어진 조건에 따라 배열 변환
   return [num // 2 if num >= 50 and num % 2 == 0 else
           num * 2 + 1 if num < 50 and num % 2 == 1 else
           num for num in arr]

def solution(arr):
   count = 0
   prev_arr = arr

   while True:
# 배열 변환
       new_arr = transform_array(prev_arr)

# 이전 배열과 새로운 배열이 동일한지 확인
       if new_arr == prev_arr:
           return count

       count += 1
       prev_arr = new_arr

테스트:

print(solution([1, 2, 3, 100, 99, 98]))# 5

설명:

  1. transform_array 함수:
    • 50이상 짝수: 2로 나누기
    • 50미만 홀수: 2를 곱하고 1을 더하기
    • 그 외: 그대로 유지
  2. solution 함수:
    • 배열이 변하지 않을 때까지 반복
    • 이전 배열과 새 배열이 같으면 반복 횟수 반환
    • count로 반복 횟수 추적

예시 실행 과정:

[1, 2, 3, 100, 99, 98][3, 2, 7, 50, 99, 49][7, 2, 15, 25, 99, 99][15, 2, 31, 51, 99, 99][31, 2, 63, 51, 99, 99][63, 2, 63, 51, 99, 99][63, 2, 63, 51, 99, 99] (동일함 - 5회 반복)

 

1로 만들기

def count_operations(num):
# 1이면 0을 반환 (연산 필요 없음)
   if num == 1:
       return 0

# 짝수면 2로 나누고, 홀수면 1을 빼고 2로 나눔
   if num % 2 == 0:
       return 1 + count_operations(num // 2)
   else:
       return 1 + count_operations((num - 1) // 2)
def solution(num_list):
# 각 숫자별로 필요한 연산 횟수의 합을 반환
   return sum(count_operations(num) for num in num_list)

테스트:

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

설명:

  1. count_operations 함수:
    • 재귀적으로 각 숫자를 1로 만드는데 필요한 연산 횟수 계산
    • 1이면 0 반환 (기저 사례)
    • 짝수면 2로 나누기
    • 홀수면 1 빼고 2로 나누기
    • 각 단계마다 1씩 더함 (연산 횟수)
  2. solution 함수:
    • 리스트의 각 숫자에 대해 count_operations 실행
    • 모든 연산 횟수의 합 반환

예시 실행 과정:

  • 12: 12→6→3→1 (3번)
  • 4: 4→2→1 (2번)
  • 15: 15→7→3→1 (3번)
  • 1: 1 (0번)
  • 14: 14→7→3→1 (3번) 총 11번의 연산 필요

 

길이에 따른 연산

def solution(num_list):
# 리스트 길이가 11 이상이면 합, 10 이하면 곱
   if len(num_list) >= 11:
       return sum(num_list)
   else:
       result = 1
       for num in num_list:
           result *= num
       return result

또는 더 간단하게:

from math import prod

def solution(num_list):
    return sum(num_list) if len(num_list) >= 11 else prod(num_list)

테스트:

print(solution([3, 4, 5, 2, 5, 4, 6, 7, 3, 7, 2, 2, 1]))# 51
print(solution([2, 3, 4, 5]))

 

원하는 문자열 찾기

def solution(myString, pat):
# 대소문자 구분을 없애기 위해 모두 소문자로 변환
   myString = myString.lower()
   pat = pat.lower()

# pat이 myString의 부분 문자열인지 확인
   return 1 if pat in myString else 0

또는 한 줄로:

def solution(myString, pat):
    return int(pat.lower() in myString.lower())

테스트:

print(solution("AbCdEfG", "aBc"))# 1
print(solution("aaAA", "aaaaa"))# 0

설명:

  1. 대소문자 구분을 없애기 위해 두 문자열을 모두 소문자로 변환
  2. in 연산자를 사용하여 pat이 myString의 부분 문자열인지 확인
  3. 결과를 정수(1 또는 0)로 반환

예시 동작:

  • "AbCdEfG" -> "abcdefg"
  • "aBc" -> "abc"
  • "abc"가 "abcdefg"에 있으므로 1 반환
반응형