코드 처리하기, 등차수열의 특정한 항만 더하기, 주사위게임2, 원소들의 곱과 합, 이어 붙인 수

1. 코드 처리하기

  • 문자열 code가 주어집니다.

code를 앞에서부터 읽으면서 만약 문자가 “1”이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다.

mode는 0과 1이 있으며, idx를 0 부터 code의 길이 - 1 까지 1씩 키워나가면서 code[idx]의 값에 따라 다음과 같이 행동합니다.

  • mode가 0일 때
    • code[idx]가 “1”이 아니면 idx가 짝수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다.
    • code[idx]가 “1”이면 mode를 0에서 1로 바꿉니다.
  • mode가 1일 때
    • code[idx]가 “1”이 아니면 idx가 홀수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다.
    • code[idx]가 “1”이면 mode를 1에서 0으로 바꿉니다.

문자열 code를 통해 만들어진 문자열 ret를 return 하는 solution 함수를 완성해 주세요.

단, 시작할 때 mode는 0이며, return 하려는 ret가 만약 빈 문자열이라면 대신 “EMPTY”를 return 합니다.

  • 1 ≤ code의 길이 ≤ 100,000
  • code는 알파벳 소문자 또는 “1”로 이루어진 문자열입니다.
code result
“abc1abc1abc” “acbac”
  • code의 각 인덱스 i에 따라 다음과 같이 mode와 ret가 변합니다.
i code[i] mode ret
0 “a” 0 “a”
1 “b” 0 “a”
2 “c” 0 “ac”
3 “1” 1 “ac”
4 “a” 1 “ac”
5 “b” 1 “acb”
6 “c” 1 “acb”
7 “1” 0 “acb”
8 “a” 0 “acba”
9 “b” 0 “acba”
10 “c” 0 “acbac”
  • 따라서 “acbac”를 return 합니다.
1
2
3
def solution(code):
    answer = ''
    return answer
  • code 라는 인자로 abc1abc1abc 가 입력되면 이를 조건에 따라 mode를 바꿔가면서 문자열 출력값을 바꿔 ret 라는 출력값으로 저장되어야 함
  • mode가 바꾸는 기준은 code에 입력된 문자열로 기본값은 0이며 code[idx] 가 1일때 mode가 1로 바뀐다.
  • mode가 0일 때 출력조건
    • code[idx] 의 문자가 숫자가 아닌 알파뱃이면서, idx가 짝수일때만 ret의 맨뒤에 code[idx] . 즉, abc1abc1abcn 번째 idx의 문자열을 append
    • code[idx] 의 문자가 1 인 경우 mode를 0에서 1로 변환
  • mode 가 1일 때 출력조건
    • code[idx] 의 문자가 숫자가 아닌 알파뱃이면서, idx가 홀수일때만 ret의 맨뒤에 code[idx] . 즉, abc1abc1abcn 번째 idx의 문자열을 append
    • code[idx] 의 문자가 1 인 경우 mode를 1에서 0으로 변환
  • return 하려는 ret가 비어있으면 “EMPTY”를 출력해야 함
  • ret = ' 'mode = 0 으로 기본 값을 설정
  • code를 iteration하고 idx를 추출하여 판단하도록 for문 설정
  • mode가 0일때와 1일때의 로직이 다르게 작동해야 함
  • 조건문으로 code[idx] 가 “1” 인지 아닌지를 최우선적으로 판별
    • 이 값에 따라 mode가 계속 바뀌어야 하기 때문
  • code[idx] 가 “1” 이 아닌 경우 mode 값을 0으로 설정하고 필요한 작업을 설정
    • code[idx] 가 “1”이라면 mode값을 1로 설정하고 pass
    • idx가 짝수이면 code[idx]ret에 append
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def solution(code):
    ret = ''  # 결과를 저장할 빈 문자열
    mode = 0  # 초기 모드는 0
    
    # 코드의 길이만큼 반복
    for idx in range(len(code)):
        char = code[idx]  # 현재 문자
        # 모드가 0일 때
        if mode == 0:
            # idx가 짝수이고, 문자가 "1"이 아니면 ret에 추가
            if idx % 2 == 0:
                ret += char
            # 문자가 "1"이면 모드 변경
            if char == '1':
                mode = 1
        # 모드가 1일 때
        else:
            # idx가 홀수이면 ret에 추가
            if idx % 2 != 0:
                ret += char
            # 문자가 "1"이면 모드 변경
            if char == '1':
                mode = 0

    # ret가 빈 문자열이면 "EMPTY" 반환
    return ret if ret else "EMPTY"

# 테스트
solution(code) 

# 출력값 : "acb1ac"
  • code[idx] 에서 추출되는 “1” 은 mode를 바꾸는 기준점으로서만 작동해야함.
  • 바꿔 말하자면 “1”은 짝수,홀수번째 조건에 해당 되어도 ret에는 추가가 되지 않아야 함
  • 인지하고 있는 내용이었지만 코드에 이러한 처리를 하도록 하지 않음
  • mode별 조건문에서 ret에 문자열을 추가하는 조건에 “1”이 아닌 경우를 and조건으로 추가해야 함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def solution(code):
    ret = ''  # 결과를 저장할 빈 문자열
    mode = 0  # 초기 모드는 0
    
    # 코드의 길이만큼 반복
    for idx in range(len(code)):
        char = code[idx]  # 현재 문자
        
        # 모드가 0일 때
        if mode == 0:
            # idx가 짝수이고, 문자가 "1"이 아니면 ret에 추가
            if idx % 2 == 0 and char != '1':
                ret += char
            # 문자가 "1"이면 모드 변경
            elif char == '1':
                mode = 1
        # 모드가 1일 때
        else:
            # idx가 홀수이면 ret에 추가
            if idx % 2 != 0 and char != '1':
                ret += char
            # 문자가 "1"이면 모드 변경
            elif char == '1':
                mode = 0
                
    # ret가 빈 문자열이면 "EMPTY" 반환
    return ret if ret else "EMPTY"

# 테스트
print(solution("abc1abc1abc"))  # 출력: "acbac"
1
2
3
4
테스트 1
입력값 	"abc1abc1abc"
기댓값 	"acbac"
실행 결과 	테스트를 통과하였습니다.
  • 문자열을 처리하는 다양한 방법과 조건문, 반복문을 이해해야하고, 데이터 타입에 대한 이해가 있어야 풀 수 있는 문제
  • 이전까지 풀던 문제보다 문제가 너무 길고 서술이 많아서 처음에 좀 당황했는데, 막상 정리하고 보니 로직이 명확해서 상대적으로 풀기 어려운 문제는 아니었다.
  • 복잡한 문제를 보면 겁먹지 말고 한줄 한줄 로직을 정리해서 풀어나가야 겠다.

2. 등차수열의 특정한 항만 더하기

  • 두 정수 ad와 길이가 n인 boolean 배열 included가 주어집니다. 첫째항이 a, 공차가 d인 등차수열에서 included[i]가 i + 1항을 의미할 때, 이 등차수열의 1항부터 n항까지 included가 true인 항들만 더한 값을 return 하는 solution 함수를 작성해 주세요.
  • 1 ≤ a ≤ 100
  • 1 ≤ d ≤ 100
  • 1 ≤ included의 길이 ≤ 100
  • included에는 true가 적어도 하나 존재합니다.
a d included result
3 4 [true, false, false, true, true] 37
7 1 [false, false, false, true, false, false, false] 10
  • 입출력 예 #1

    예제 1번은 a와 d가 각각 3, 4이고 included의 길이가 5입니다. 이를 표로 나타내면 다음과 같습니다.

      1항 2항 3항 4항 5항
    등차수열 3 7 11 15 19
    included true false false true true

    따라서 true에 해당하는 1항, 4항, 5항을 더한 3 + 15 + 19 = 37을 return 합니다.

  • 입출력 예 #2

    예제 2번은 a와 d가 각각 7, 1이고 included의 길이가 7입니다. 이를 표로 나타내면 다음과 같습니다.

      1항 2항 3항 4항 5항 6항 7항
    등차수열 7 8 9 10 11 12 13
    included false false false true false false false

    따라서 4항만 true이므로 10을 return 합니다.

1
2
3
def solution(a, d, included):
    answer = 0
    return answer
  • 첫항이 a 공차가 d 인 등차수열을 구현해야 하며, 이중에 입력된 included 라는 list에서 True 인 idx에 해당되는 등차수열 값만 추출해서 더한 뒤 return해야 함
  • 첫항이 a 공차가 d 인 등차수열을 구한다.
  • included에서 True인 idx를 찾고 이 idx를 활용해 등차수열의 값이 담긴 list에서 값을 추출한다.
  • 추출된 값을 하나의 변수에 append하며 sum한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def solution(a, d, included):
    
    # 등차수열 생성 함수
    def arithmetic_sequence(a, d, n):
        return [a + i * d for i in range(n)]
    
    # included와 등차수열의 길이 통일
    n = len(included)
    
    # 등차수열 생성
    sequence = arithmetic_sequence(a, d, n)
    
    # 등차수열의 합을 저장할 변수 (정수로 초기화)
    answer = 0
    
    # included 길이만큼 순회
    for idx in range(len(included)):
        # included가 True이면, 같은 idx의 등차수열 값을 추출해서 더함
        if included[idx]:
            answer += sequence[idx]
    
    return answer
1
2
3
4
5
6
7
8
테스트 1
입력값 	3, 4, [true, false, false, true, true]
기댓값 	37
실행 결과 	테스트를 통과하였습니다.
테스트 2
입력값 	7, 1, [false, false, false, true, false, false, false]
기댓값 	10
실행 결과 	테스트를 통과하였습니다.
  • 반복문, 배열, 조건문, 함수 등을 복합적으로 활용해야지만 풀 수 있는 문제였다.
  • 특히 등차수열에 대한 개념과 이를 구현하는 방법을 알지 못하면 풀 수가 없는 문제

3. 주사위 게임 2

  • 1부터 6까지 숫자가 적힌 주사위가 세 개 있습니다. 세 주사위를 굴렸을 때 나온 숫자를 각각 abc라고 했을 때 얻는 점수는 다음과 같습니다.
    • 세 숫자가 모두 다르다면 a + b + c 점을 얻습니다.
    • 세 숫자 중 어느 두 숫자는 같고 나머지 다른 숫자는 다르다면 $(a + b + c) \times (a^2 + b^2 + c^2)$ 점을 얻습니다.
  • 세 숫자가 모두 같다면 $(a + b + c) \times (a^2 + b^2 + c^2) \times (a^3 + b^3 + c^3)$점을 얻습니다.
  • 세 정수 abc가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.
  • abc는 1이상 6이하의 정수입니다.
a b c result
2 6 1 9
5 3 3 473
4 4 4 110592
  • 입출력 예 #1
    • 예제 1번에서 세 주사위 숫자가 모두 다르므로 2 + 6 + 1 = 9점을 얻습니다. 따라서 9를 return 합니다.
  • 입출력 예 #2
    • 예제 2번에서 두 주사위 숫자만 같으므로 $(5 + 3 + 3) \times (5^2 + 3^2 + 3^2) = 11 \times 43 = 473$ 점을 얻습니다. 따라서 473을 return 합니다.
  • 입출력 예 #3
    • 예제 3번에서 세 주사위 숫자가 모두 같으므로 $(4 + 4 + 4) \times (4^2 + 4^2 + 4^2 ) \times (4^3 + 4^3 + 4^3) = 12 \times 48 \times 192 = 110,592$ 점을 얻습니다. 따라서 110592를 return 합니다.
1
2
3
def solution(a, b, c):
    answer = 0
		return answer
  • 조건문과 비교연산자를 활용해서 각 조건에 맞는 수식을 작성하는 것이 필요
  • 3개의 경우에 대한 조건문을 각각 작성
1
2
3
4
5
6
7
8
9
10
11
12
def solution(a, b, c):
    answer = 0
    # 모든 숫자가 다른 경우
    if a != b and b != c and a != c:
        answer = a + b + c
    # 두 숫자가 같고 다른 하나는 다른 경우
    elif a == b or a == c or b == c:
        answer = (a+b+c) * (a**2 + b**2 + c**2)
    # 모든 숫자가 같은 경우
    else:
        answer = (a+b+c) * (a**2 + b**2 + c**2) * (a**3 + b**3 + c**3)
    return answer
  • else 조건인 a == b == c 가 구조상 절대 실행될 수가 없는 구조 이기 때문
    • a == b == c 인 경우 2번째 조건문인 a==b or a == c or b == c 를 만족해서 else 문으로 넘어가기전에 2번째 조건문을 실행하게 됨
  • 따라서 조건문의 순서를 바꿀 필요가 있음
1
2
3
4
5
6
7
8
9
10
11
12
def solution(a, b, c):
    answer = 0
    # 모든 숫자가 같은 경우
    if a == b == c:
        answer = (a+b+c) * (a**2 + b**2 + c**2) * (a**3 + b**3 + c**3)
    # 2개의 숫자는 같은데 나머지 하나는 다른 경우
    elif a == b or a == c or b == c:
        answer = (a+b+c) * (a**2 + b**2 + c**2)
    # 3개의 숫자가 모두 다른 경우
    else:
        answer = a + b + c
    return answer
1
2
3
4
5
6
7
8
9
10
11
12
테스트 1
입력값 	2, 6, 1
기댓값 	9
실행 결과 	테스트를 통과하였습니다.
테스트 2
입력값 	5, 3, 3
기댓값 	473
실행 결과 	테스트를 통과하였습니다.
테스트 3
입력값 	4, 4, 4
기댓값 	110592
실행 결과 	테스트를 통과하였습니다.
  • 처음에 문제를 쉽게 보고 개별 건에 대한 조건문만 작성하면 된다고 생각했는데 이게 오답의 원인
  • 이러한 비교연산자 문제에서 if~elif 형태로 작성하게 되면 작성이 되는 순서도 중요하다는 점을 알게 되었음

4. 원소들의 곱과 합

  • 정수가 담긴 리스트 num_list가 주어질 때, 모든 원소들의 곱이 모든 원소들의 합의 제곱보다 작으면 1을 크면 0을 return하도록 solution 함수를 완성해주세요.
  • 2 ≤ num_list의 길이 ≤ 10
  • 1 ≤ num_list의 원소 ≤ 9


num_list result
[3, 4, 5, 2, 1] 1
[5, 7, 8, 3] 0
  • 입출력 예 #1
    • 모든 원소의 곱은 120, 합의 제곱은 225이므로 1을 return합니다.
  • 입출력 예 #2
    • 모든 원소의 곱은 840, 합의 제곱은 529이므로 0을 return합니다.
1
2
3
def solution(num_list):
    answer = 0
    return answer
  • 하드 코딩으로 풀자면 list내의 모든 원소를 연산하는 방법과 비교연산자 개념을 이용해 풀이하는 문제
  • 좀 더 쉽게 접근하자면 numpy의 np.prod를 응용하거나 reduce 를 이용해서 풀 수 도 있음
    • np.prod : 배열의 모든 요소의 곱을 계산하는 numpy 내장 함수
    • reduce : functools 모듈의 내장함수로 주어진 함수와 리스트(또는 순회가능한 객체)를 입력받아 리스트의 요소를 왼쪽에서 오른쪽으로 누적하면서 함수를 적용하는 내장함수
      • 여기서는 operator의 mul 기능을 이용해 num_list 배열내의 인자들을 왼쪽부터 오른쪽 방향으로 누적하면서 곱셈 연산을 하는
  • for문으로 list내의 원소를 iteration하며 곱을 직접 계산
  • sum을 이용해 list내 모든 원소의 합을 구한뒤 제곱근 계산
  • 두 값을 비교해서 0 또는 1을 출력
  • 하드코딩 방식으로 작성해서 풀어본 뒤 나머지 2가지 방법으로도 풀어보기
1
2
3
4
5
6
7
8
9
10
11
def solution(num_list):
    # 모든 요소의 곱을 계산
    product_of_elements = 1
    for num in num_list:
        product_of_elements *= num
    
    # 모든 요소의 합을 계산
    sum_of_elements = sum(num_list)
    
    # 합의 제곱과 모든 요소의 곱을 비교
    return 1 if product_of_elements < sum_of_elements ** 2 else 0
  • 파이썬의 numpy와 reduce를 활용해서 다양한 방법으로 풀어보기
    • 모든 요소의 곱을 계산하는 부분을 좀 더 간결하게 할 수 있음
1
2
3
4
5
6
7
# numpy로 푸는 버전
import numpy as np

def solution(num_list):
    product_of_elements = np.prod(num_list)  # 모든 요소의 곱
    sum_of_elements = np.sum(num_list)  # 모든 요소의 합
    return 1 if product_of_elements < sum_of_elements ** 2 else 0  # 모든 요소의 합의 제곱과 모든 요소의 곱을 비교
1
2
3
4
5
6
7
8
# reduce로 푸는 버전
from functools import reduce
import operator

def solution(num_list):
    product_of_elements = reduce(operator.mul, num_list, 1)  # 모든 요소의 곱
    sum_of_elements = sum(num_list)  # 모든 요소의 합의 제곱
    return 1 if product_of_elements < sum_of_elements ** 2 else 0  # 모든 요소의 합의 제곱과 모든 요소의 곱을 비교
1
2
3
4
5
6
7
8
테스트 1
입력값 	[3, 4, 5, 2, 1]
기댓값 	1
실행 결과 	테스트를 통과하였습니다.
테스트 2
입력값 	[5, 7, 8, 3]
기댓값 	0
실행 결과 	테스트를 통과하였습니다.
  • 조건에 따른 연산을 할 수 있다면 어렵지 않게 풀 수 있는 문제
  • 하드코딩으로 하는 방법외에 다른 방법도 있을 수 있음을 배움

5. 이어 붙인 수

  • 정수가 담긴 리스트 num_list가 주어집니다. num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 함수를 완성해주세요.
  • 2 ≤ num_list의 길이 ≤ 10
  • 1 ≤ num_list의 원소 ≤ 9
  • num_list에는 적어도 한 개씩의 짝수와 홀수가 있습니다.
num_list result
[3, 4, 5, 2, 1] 393
[5, 7, 8, 3] 581
  • 입출력 예 #1
    • 홀수만 이어 붙인 수는 351이고 짝수만 이어 붙인 수는 42입니다. 두 수의 합은 393입니다.
  • 입출력 예 #2
    • 홀수만 이어 붙인 수는 573이고 짝수만 이어 붙인 수는 8입니다. 두 수의 합은 581입니다.
1
2
3
def solution(num_list):
    answer = 0
    return answer
  • 홀수와 짝수를 구분하는 방법과 조건문, 산술연산자등을 응용해서 풀이하는 문제
  • 이어붙인다는 개념이 int 형태의 숫자를 이어 붙이는 것이 아니고 str 형태의 숫자를 이어 붙이는 것
  • 두 변수를 합할때는 int 로서 합해야 함
  • 하드 코딩으로 푼다면 for문으로 list를 순환하면서 나머지를 이용해 홀수와 짝수를 구분하고, 조건문에 따라 각각 별개의 변수(even, odd)에 담은뒤
  • return할때 int로 변환해서 덧셈 연산하여 return
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def solution(num_list):
    # 홀수와 짝수를 도출할 변수 초기화
    even = ''
    odd = ''
    
    # num_list를 순회하며 홀짝 구분
    for num in num_list:
        # 짝수인 경우
        if num % 2 == 0:
            even += str(num) # even 변수에 문자로 변환하여 append
        # 홀수인 경우
        else:
            odd += str(num) # odd 변수에 문자로 변환하여 append
    return int(even) + int(odd) # 두 변수의 합 return
  • 좀 더 간결하게 코드를 작성하는 방법을 적용해보고 싶었음
  • 개념을 찾다보니 lambda를 적용해서 풀어낼 수 있을 것 같았음
    • list내에서 주어진 조건을 만족하는 것만 return하는 filter() 함수와
    • 개별적으로 return되는 값들을 모아 다시 배열로 만들어 주는 map() 함수
    • 그리고 이러한 결과들을 연결해주는 join() 함수를 응용하면 풀 수 있음
1
2
3
4
5
6
7
def solution(num_list):
    even = ''.join(map(str, filter(lambda x: x % 2 == 0, num_list))) # 짝수만 추출해서 이어 붙이기
    odd = ''.join(map(str, filter(lambda x: x % 2 != 0, num_list))) # 홀수만 추출해서 이어 붙이기
    
		# 짝수와 홀수의 합 return
		# even과 odd가 빈 문자열일 경우를 고려해 if even and odd else int(even or odd) 부분을 넣음
    return int(even) + int(odd) if even and odd else int(even or odd)
  • 입력된 함수의 가장 우측부터 좌측방향으로 한단계씩 연산되며 진행(filter → map → join)
  • filter 함수 : 주어진 함수의 조건을 만족하는 요소만 걸러내어 반환 (1 단계)
    • lambda x: x % 2 == 0 : num_list의 개별 인자 x가 짝수인지 확인하는 lambda 함수
    • lambda x: x % 2 != 0 : num_list의 개별 인자 x가 홀수인지 확인하는 lambda 함수
    • num_list[3, 4, 2, 5, 1]이라면, 짝수는 [4, 2] 를 반환하고 홀수는 [3, 5, 1] 을 반환
  • map 함수 : 주어진 함수를 적용해서 새로운 리스트(정확히는 iterator) 생성하는 함수로 여기서는 lambda 함수의 결과를 적용 (2단계)
    • map(str, [4, 2]) 가 입력되어 입력된 [4, 2] 의 각 요소에 str()이 적용되어 ['4', '2'] 가 return
    • map(str, [3, 5, 1]) 가 입력되어 [3, 5, 1] 의 각 요소에 str()이 적용되어 ['3', '5', '1'] 가 return
  • join 함수 : 문자열 리스트를 하나의 문자열로 연결하는 함수 (3단계)
    • ''.join(['4','2']) 가 되어서 문자열 '42' 를 return
    • ''.join(['3', '5', '1']) 가 되어서 문자열 '351' 를 return
  • 각각 연산된 결과(even , odd ) 를 int 로 변환하여 덧셈한뒤 return
1
2
3
4
5
6
7
8
테스트 1
입력값 	[3, 4, 5, 2, 1]
기댓값 	393
실행 결과 	테스트를 통과하였습니다.
테스트 2
입력값 	[5, 7, 8, 3]
기댓값 	581
실행 결과 	테스트를 통과하였습니다.
  • 간단하게 풀려고 하면 그리 어려운 문제는 아니었던 것 같은데, 생소한 개념인 lambda나 다른 함수들을 복합적으로 적용하려고 하니까 조금 어려운 문제가 되어 버렸다.


댓글남기기