Swift) 2020 카카오 인턴십 - 수식 최대화

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

 

프로그래머스

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

programmers.co.kr

경우의 수, DFS, 구현 문제. 가장 고민을 많이 했던 것은 우선순위를 적용한 계산을 어떻게 할 것인지 고민을 많이 했다. 

내가 푼 방식은 연산자와 숫자를 각각 나눠서 배열에 담고, 우선순위를 for문으로 돌아서 연산자 우선순위가 높은것을 먼저 계산하고 숫자 배열에 이를 적용하고 계산한 숫자는 제거하는 방식으로 구현했다. 

import Foundation

var solutionAnswer: Int64 = 0

enum Operator: Int {
    case plus = 0
    case multi
    case minus
    
    func calculate (_ num1: Int64, _ num2: Int64) -> Int64 {
        switch self {
            case .plus:
                return num1+num2
            case .multi:
                return num1*num2
            case .minus:
                return num1-num2
        }
    }
}

var priority: [Operator] = [.plus, .multi, .minus]
var isVisited: [Bool] = [false, false, false]

func calculateExpression (_ expression: String) -> Int64 {
    var numberList = expression.components(separatedBy: ["*","-","+"]).map {Int64($0)!}
    var operatorList = getOperator(expression)
    
    for prior in priority {
        while let index = operatorList.firstIndex(of: prior) {
            numberList[index] = prior.calculate(numberList[index], numberList[index+1])
            numberList.remove(at: index+1)
            operatorList.remove(at: index)
        }
    }
    return abs(numberList[0])
}

func operatorColaborationDFS(_ depth: Int, _ operatorS: Operator, _ expression: String) {
    priority[depth] = operatorS
    if depth == 2 {
        //수식 연산 수행
        solutionAnswer = max(calculateExpression(expression), solutionAnswer)
        return
    }
    
    for i in 0..<3 {
        let nextOperator = Operator(rawValue:i)!
        if isVisited[nextOperator.rawValue] {
            continue
        }
        isVisited[i] = true
        operatorColaborationDFS(depth+1, nextOperator, expression)
        isVisited[i] = false
    }
}

func getOperator(_ expression: String) -> [Operator] {
    var answer: [Operator] = []
    for i in Array(expression) {
        if !i.isNumber {
            if i == "+" {
                answer.append(.plus)
            } else if i == "*" {
                answer.append(.multi)
            } else if i == "-" {
                answer.append(.minus)
            }
        }
    }
    return answer
}

func solution(_ expression:String) -> Int64 {
    for i in 0..<3 {
        isVisited[i] = true
        operatorColaborationDFS(0, Operator(rawValue: i)!, expression)
        isVisited[i] = false
    }
    
    return solutionAnswer
}