다항식 더하기

2024. 8. 18. 18:00코딩테스트 입문

https://school.programmers.co.kr/learn/courses/30/lessons/120863

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 설명
한 개 이상의 항의 합으로 이루어진 식을 다항식이라고 합니다. 다항식을 계산할 때는 동류항끼리 계산해 정리합니다. 덧셈으로 이루어진 다항식 polynomial이 매개변수로 주어질 때, 동류항끼리 더한 결괏값을 문자열로 return 하도록 solution 함수를 완성해보세요. 같은 식이라면 가장 짧은 수식을 return 합니다.


제한사항

  • 0 < polynomial에 있는 수 < 100
  • polynomial에 변수는 'x'만 존재합니다.
  • polynomial은 양의 정수, 공백, ‘x’, ‘+'로 이루어져 있습니다.
  • 항과 연산기호 사이에는 항상 공백이 존재합니다.
  • 공백은 연속되지 않으며 시작이나 끝에는 공백이 없습니다.
  • 하나의 항에서 변수가 숫자 앞에 오는 경우는 없습니다.
  • " + 3xx + + x7 + "와 같은 잘못된 입력은 주어지지 않습니다.
  • 0으로 시작하는 수는 없습니다.
  • 문자와 숫자 사이의 곱하기는 생략합니다.
  • polynomial에는 일차 항과 상수항만 존재합니다.
  • 계수 1은 생략합니다.
  • 결괏값에 상수항은 마지막에 둡니다.
  • 0 < polynomial의 길이 < 50

입출력 예

polynomial result
"3x + 7 + x" "4x + 7"
"x + x + x" "3x"

입출력 예 설명
입출력 예 #1

  • "3x + 7 + x"에서 동류항끼리 더하면 "4x + 7"입니다.

입출력 예 #2

  • "x + x + x"에서 동류항끼리 더하면 "3x"입니다.

처음 문제를 보고 이 정도 문제가 입문 난이도에서 나온다고? 라는 생각이 들었습니다.

막상 풀어보니까 그렇게 어려운 문제는 아닌데, 고려할 경우의 수가 좀 많은 문제입니다.

 

제가 생각하는 문제 풀이의 핵심은 다음과 같습니다.

1. 변수항과 상수항을 어떻게 분리할 것인가?

2. 변수항의 계수들을 어떻게 더해줄 것인가?

3. 정답식을 어떻게 만들 것인가?

 

일단 문제에서 공백을 기준으로 문자열이 주어지기 때문에, 공백을 기준으로 나누는 split() 함수를 사용할 수 있습니다.

그러면 이제 + 기호가 거슬리는데, 이 기호는 replace로 먼저 처리를 해준다면 깔끔하게 변수항과 상수항으로 분리할 수 있습니다.

# 다항식으로부터 원소를 추출합니다
elements = polynomial.replace('+', '').split()

 

그 다음은 이제 계수를 더해주는 부분입니다.

상수항 부분은 딱히 신경 쓸 게 없는게, 애초에 정수로 형변환만 해주면 알아서 연산되기 때문입니다.

변수항 계수는 nx의 형태로 되어 있는데, n = 1일 경우에는 x로 생략할 수 있습니다.

이를 해결하기 위해서 split(x) 로 n과 x를 나눠주고, 나눈 결과가 비어 있다면 n = 1이라고 유추할 수 있습니다.

# 변수항, 상수항 초기화
var, con = 0, 0
# 모든 원소를 탐색합니다
for e in elements:
    # 변수항일 경우
    if 'x' in e:
        # e를 x 기준으로 분리합니다.
        num = e.split('x')[0]
        # 해당 값이 정수일 때
        if num.isdigit():
            # int로 형변환해서 더해줍니다.
            var += int(num)
        # 정수형이 아닐 경우 = 1이 생략된 경우
        else:
            # 1을 더해줍니다.
            var += 1
    # 상수항일 경우
    else:
        # int로 형변환해서 더해줍니다.
        con += int(e)

 

마지막으로 정답식을 만드는 과정입니다.

일단 정답식의 기본 형태는 nx + m 형태지만, n = 0이거나 n = 1일 때 문제가 발생합니다.

n = 0 이면 m은 앞의 + 기호가 생략되어야 하고, n = 1 이면 1을 생략해서 x + m 형태로 만들어줘야 합니다.

# 정답식 처리
answer = ''
# 변수항이 있을 때
if var != 0:
    # 변수항이 1이면 1은 생략합니다.
    if var == 1:
        answer += f"x"
    # 변수항이 1 이상이면 {var}x 형태로 만들어줍니다.
    else:
        answer += f"{var}x"
# 상수항이 있을 때
if con != 0:
    # 변수항이 없다면 + 기호는 생략합니다.
    if var == 0:
        answer += f"{con}"
    # 변수항이 있다면 + 기호를 추가합니다.
    else:
        answer += f" + {con}"

경우를 나누어 정답식을 만들어 주었습니다.

 

최종 코드는 다음과 같습니다.

def solution(polynomial):
    # 다항식으로부터 원소를 추출합니다
    elements = polynomial.replace('+', '').split()
    # 변수항, 상수항 초기화
    var, con = 0, 0
    # 모든 원소를 탐색합니다
    for e in elements:
        # 변수항일 경우
        if 'x' in e:
            # e를 x 기준으로 분리합니다.
            num = e.split('x')[0]
            # 해당 값이 정수일 때
            if num.isdigit():
                # int로 형변환해서 더해줍니다.
                var += int(num)
            # 정수형이 아닐 경우 = 1이 생략된 경우
            else:
                # 1을 더해줍니다.
                var += 1
        # 상수항일 경우
        else:
            # int로 형변환해서 더해줍니다.
            con += int(e)
            
    # 정답식 처리
    answer = ''
    # 변수항이 있을 때
    if var != 0:
        # 변수항이 1이면 1은 생략합니다.
        if var == 1:
            answer += f"x"
        # 변수항이 1 이상이면 {var}x 형태로 만들어줍니다.
        else:
            answer += f"{var}x"
    # 상수항이 있을 때
    if con != 0:
        # 변수항이 없다면 + 기호는 생략합니다.
        if var == 0:
            answer += f"{con}"
        # 변수항이 있다면 + 기호를 추가합니다.
        else:
            answer += f" + {con}"
    return answer

 

코드가 중구난방이죠? 그래서 이 코드를 기반으로 좀 더 가독성 좋게 코드를 작성해보았습니다.

def solution(polynomial):
    # 변수 계수, 상수 계수를 초기화합니다.
    var, con = 0, 0
    # ' + '을 기준으로 변수항, 상수항을 나눕니다.
    for term in polynomial.split(' + '):
        # 변수항에 속한다면
        if 'x' in term:
            # x 전까지의 숫자를 var에 추가한다.
            # 숫자가 없다면(1이 생략된 경우) var에 1을 추가한다.
            var += int(term[:-1]) if term[:-1].isdigit() else 1
        else:
            con += int(term)

    # 정답식을 생성합니다.
    if var and con: # var, con 모두 값이 0보다 크다면
        # var이 2 이상이면 var을, 1이면 생략한다.
        return f"{var if var > 1 else ''}x + {con}"
    elif var: # var만 0보다 크다면 (con이 0이라면 생략)
        # var이 2 이상이면 var을, 1이면 생략한다.
        return f"{var if var > 1 else ''}x"
    else: # con만 0보다 크다면 (var이 0이라면 생략)
        # con만 반환한다.
        return f"{con}"

가독성이 좀 더 올라갔습니다.

'코딩테스트 입문' 카테고리의 다른 글

안전지대  (0) 2024.08.20
숨어있는 숫자의 덧셈 (2)  (0) 2024.08.19
최댓값 만들기 (2)  (0) 2024.08.17
캐릭터의 좌표  (0) 2024.08.16
직사각형 넓이 구하기  (0) 2024.08.15