본문 바로가기
AI/Coding_Test

Day 15) 프로그래머스 파이썬 조건 변환과 반복문 5문제 풀

by 거대웅 TitanBear 2026. 7. 23.

Programmers Coding Test · Day 15 · Python

Day 15
조건 변환과 반복문 5문제 풀이

정수 나눗셈, 이전 상태와 다음 상태 비교, 중첩 반복문, 문자열 대소문자 통일까지 직접 작성한 코드의 흐름을 따라 정리했습니다.

이번 문제들은 조건식 자체보다 값의 자료형, 반복문 안팎의 들여쓰기, 현재 상태와 다음 상태의 비교를 정확하게 다루는 연습이었다. 특히 배열이 더 이상 변하지 않을 때까지 반복하는 문제는 한 번의 변환을 만드는 코드와 멈추는 시점을 나누어 생각하는 것이 핵심이었다.

오늘의 핵심 /는 실수를 만들고 //는 몫을 만든다. 배열 변환을 반복할 때는 기존 배열과 새 배열을 비교하고, 값이 아니라 인덱스가 필요한 반복인지도 먼저 판단한다.

문제 및 공식 링크

프로그래머스 코딩 기초 트레이닝 Day 15
순서문제핵심 개념
1조건에 맞게 수열 변환하기 1조건 분기, //
2조건에 맞게 수열 변환하기 2상태 비교, while
31로 만들기중첩 반복문, 몫 나눗셈
4길이에 따른 연산합, 곱, 조건부 표현식
5원하는 문자열 찾기문자열 메서드, in

1. 조건에 맞게 수열 변환하기 1

각 원소가 50 이상인 짝수라면 2로 나누고, 50 미만인 홀수라면 2를 곱하는 문제다. 나머지 원소는 그대로 둔다.

처음 작성한 코드

def solution(arr):
    answer = []

    for num in arr:
        if num >= 50 and num % 2 == 0:
            answer.append(num / 2)
        elif num <= 50 and num % 2 != 0:
            answer.append(num * 2)
        else:
            answer.append(num)

    return answer

세 갈래로 나누어 결과를 새 리스트에 넣는 전체 흐름은 정확했다. 다만 첫 번째 조건의 나눗셈 기호 하나 때문에 반환값의 자료형이 달라진다.

1
/는 일반 나눗셈이다50 / 2의 결과는 25.0이다. 문제는 정수 배열을 요구하므로 실수가 섞이지 않도록 해야 한다.
2
지문대로 num < 50이라고 적는다50은 짝수라 두 번째 조건에서 실제 결과는 같지만, 문제의 조건이 50보다 작은 홀수이므로 < 50이 더 정확하고 읽기 쉽다.

수정한 기본 풀이

def solution(arr):
    answer = []

    for num in arr:
        if num >= 50 and num % 2 == 0:
            answer.append(num // 2)
        elif num < 50 and num % 2 != 0:
            answer.append(num * 2)
        else:
            answer.append(num)

    return answer

리스트 컴프리헨션 풀이

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

한 줄로 줄일 수는 있지만 조건이 세 갈래라면 처음에는 일반 for문 풀이가 더 읽기 쉽다. 공식 예제 [1, 2, 3, 100, 99, 98][2, 2, 6, 50, 99, 49]가 된다.

2. 조건에 맞게 수열 변환하기 2

첫 번째 문제의 조건과 비슷하지만, 50 미만인 홀수는 2를 곱한 뒤 1을 더하고, 배열이 더 이상 변하지 않을 때까지 이 작업을 반복한다. 문제의 arr(x)는 함수 호출 문법이 아니라 “x번 변환한 배열”을 뜻하는 수학 표기다.

처음 떠올린 흐름과 막힌 지점

def solution(arr):
    arr(x)

    while arr(x) = arr(x + 1):
        for num in arr:
            if num >= 50 and num % 2 == 0:
                arr = num // 2
            elif num <= 50 and num != 2:
                arr = num * 2 + 1

    return arr
1
수학 표기와 코드 문법은 다르다arr(x)는 문제 설명의 표기다. 파이썬에서 리스트 뒤에 괄호를 붙이면 함수를 호출하려는 것으로 해석된다.
2
배열 전체를 숫자로 덮어쓰면 안 된다변환한 원소는 새 리스트에 하나씩 모아야 한다. arr = num // 2는 리스트를 숫자 하나로 바꿔 버린다.
3
홀수는 num % 2 != 0으로 확인한다num % 2 != 2는 나머지가 0 또는 1인 모든 정수에 대해 참이 된다. 50 미만의 짝수까지 잘못 변환하는 원인이다.

시간 초과가 난 이유: 들여쓰기

새 배열을 만든 뒤의 if old == new, 배열 교체, 카운트 증가가 while문 바깥에 있으면 반복문은 탈출 조건을 절대 만나지 못한다. 파이썬에서는 들여쓰기가 코드 블록의 소속을 결정하므로 이 세 줄도 반드시 while 안에 있어야 한다.

내가 완성한 풀이

def solution(arr):
    answer = 0
    old = arr

    while True:
        new = []

        for i in old:
            if i >= 50 and i % 2 == 0:
                new.append(i // 2)
            elif i < 50 and i % 2 == 1:
                new.append(i * 2 + 1)
            else:
                new.append(i)

        if old == new:
            break

        old = new
        answer += 1

    return answer

이 풀이는 정답이다. 처음에는 i / 2 뒤에 int(i)를 씌워 정수로 바꾸는 방식도 가능했지만, 조건상 나누는 수는 짝수이므로 처음부터 i // 2를 쓰는 편이 더 직접적이다.

break를 만나면 answer가 0인 것 아닌가? 아니다. answer += 1은 배열이 실제로 바뀌었을 때만 실행된다. 처음부터 변하지 않으면 0에서 바로 멈추는 것이 맞고, 예를 들어 [100]은 [100] → [50] → [25] → [51]로 세 번 바뀐 뒤 [51]에서 멈추므로 3을 반환한다.

검산: 공식 예제 [1, 2, 3, 100, 99, 98]은 다섯 번 변환한 배열과 여섯 번 변환한 배열이 같아지므로 5를 반환한다.

3. 1로 만들기

리스트의 각 정수를 1이 될 때까지 반으로 줄이고, 필요한 나누기 연산 횟수의 총합을 구하는 문제다. 짝수는 반으로 나누고, 홀수는 1을 뺀 뒤 반으로 나눈다.

처음 시도에서 보완할 점

def solution(num_list):
    answer = 0

    while True:
        num = 0
        for i in num_list:
            if i % 2 == 0:
                num = i // 2
            else:
                num = (i - 1) // 2

        if num == 1:
            return answer

num 하나에 계산 결과를 넣으면 반복할 때마다 앞의 값이 덮어써져 마지막 원소만 남는다. 이 문제는 배열 전체를 한꺼번에 새 배열로 바꾸기보다, 원소 하나를 꺼내서 1이 될 때까지 처리하는 구조가 자연스럽다.

내 풀이

def solution(num_list):
    answer = 0

    for n in num_list:
        while n != 1:
            n //= 2
            answer += 1

    return answer

이 코드는 양의 정수라는 문제 조건에서 정확하다. 홀수 n에 대해 n // 2(n - 1) // 2와 같으므로 짝수와 홀수를 따로 나눌 필요가 없다.

///의 차이 소수점까지 정확한 나눗셈이 필요하면 /를 쓴다. 예를 들어 5 / 2는 2.5다. 반대로 이번 문제처럼 소수점 아래를 버리고 정수 몫만 필요하면 //를 사용한다. 5 // 2는 2다.

검산: [12, 4, 15, 1, 14]에서는 각각 3, 2, 3, 0, 3번이 필요해 총 11을 반환한다.

4. 길이에 따른 연산

리스트 길이가 11 이상이면 모든 원소의 합을, 10 이하이면 모든 원소의 곱을 반환하는 문제다.

내 풀이

def solution(num_list):
    answer = 1

    if len(num_list) > 10:
        answer = sum(num_list)
    else:
        for i in num_list:
            answer *= i

    return answer

이 풀이는 정답이다. 곱셈의 초기값을 1로 둔 점이 중요하다. 0으로 시작하면 어떤 수를 곱해도 0이 된다. len(num_list) > 10은 “길이가 11 이상”과 같은 뜻이다.

math.prod()와 조건부 표현식

from math import prod


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

작성한 한 줄 풀이도 정답이다. 다만 from math import prod와 함수 정의는 서로 다른 문장이므로 반드시 줄을 나누어 적는다. 조건부 표현식은 참일 때 값 if 조건 else 거짓일 때 값 순서로 읽으면 된다.

검산: 길이가 13인 공식 예제는 합계 51을, [2, 3, 4, 5]는 곱 120을 반환한다.

5. 원하는 문자열 찾기

대소문자를 구분하지 않고 myString 안에 pat이 연속된 부분 문자열로 존재하는지 확인하는 문제다.

처음 시도

def solution(myString, pat):
    my_string = super(myString)
    pat = super(pat)

    if pat in my_string:
        return 1
    else:
        return 0

pat in my_string이라는 포함 여부 검사 방향은 정확했다. 다만 super()는 부모 클래스 관련 기능이고, 문자열을 통일하는 메서드가 아니다.

수정한 기본 풀이

def solution(myString, pat):
    my_string = myString.lower()
    pat = pat.lower()

    if pat in my_string:
        return 1

    return 0

lower()는 문자열 뒤에 점을 붙여 호출하는 메서드다. 두 문자열을 모두 소문자로 통일한 뒤 in으로 검사하면 대소문자를 구분하지 않는 비교가 된다.

내가 줄인 한 줄 풀이

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

이 코드도 정답이다. in의 결과는 True 또는 False이고, 파이썬에서 int(True)는 1, int(False)는 0이다.

검산: "AbCdEfG""aBc"은 1을, "aaAA""aaaaa"는 0을 반환한다.

실수 방지 체크리스트

정수 결과가 필요한 나눗셈에는 //를 사용한다.
홀수 조건은 num % 2 != 0 또는 num % 2 == 1로 쓴다.
반복 종료 조건, 상태 갱신, 카운트 증가가 모두 while 블록 안에 있는지 확인한다.
리스트 전체를 숫자 하나로 덮어쓰지 않고, 필요하면 새 리스트에 값을 모은다.
곱셈 누적 변수의 시작값은 1이다.
문자열 전용 기능은 myString.lower()처럼 점 표기법으로 호출한다.

같이 보면 좋은 자료

1
파이썬 공식 문서: 숫자형과 연산/, //, 나머지 연산의 의미를 확인할 수 있다.
2
파이썬 공식 문서: math.prod()반복 가능한 객체의 모든 원소를 곱하는 표준 함수다.
3
파이썬 공식 문서: str.lower()문자열을 소문자로 통일하는 메서드와 문자열 검색을 복습할 수 있다.
마무리

이번 문제에서 가장 크게 남은 포인트는 “반복할 때 무엇을 비교하고, 언제 카운트를 올릴 것인가”였다. 수열 변환 문제는 새 배열을 만든 뒤 이전 배열과 다를 때만 횟수를 증가시키면 되고, 1로 만들기는 각 숫자 하나를 끝까지 처리하면 된다. 문제의 수학적 설명을 그대로 코드에 옮기기보다, 현재 값과 다음 값이라는 프로그램의 흐름으로 바꾸어 생각하면 복잡한 반복문도 훨씬 선명해진다.