알고리즘∙코테

[프로그래머스 Lv.1] 다트게임

예스코치 2023. 7. 18. 00:18

[1차] 다트 게임

레벨: 1
출처: 2018 KAKAO BLIND RECRUITMENT

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

 

프로그래머스

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

programmers.co.kr

 

문제 풀이


  1. Single, Double, Triple 영역이 존재하고, 각각 1제곱, 2제곱, 3제곱으로 계산된다
    ✅ 제곱 함수 pow 사용
  2. 옵션으로 스타상(*), 아차상(#)이 존재하고, 특히 스타상은 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다
    ✅ 바로 전의 점수에도 접근해야 하므로 스택(LIFO) 자료구조 활용
  3. 입력으로 주어지는 문자열을 하나하나 접근할 경우, 한 자리 숫자는 괜찮지만 10의 경우 처리가 번거로움
    ✅ 입력 형식이 점수|보너스|[옵션] 이므로 split을 사용해서 숫자와 문자 구분

 

나의 풀이


import Foundation

func solution(_ dartResult:String) -> Int {

    let numberList = dartResult.split(whereSeparator: {$0.isNumber == false}).map{Int($0)!}
    let letterList = dartResult.split(whereSeparator: {$0.isNumber})
    let sdtDictionary: [Character: Double] = ["S": 1, "D": 2, "T": 3]

    var stack: [Int] = []

    for i in 0...2 {
        var score = Double(numberList[i])
        for item in letterList[i] {
            if let num = sdtDictionary[item] {
                stack.append(Int(pow(score, num)))
                continue
            }
            let cur = stack.removeLast()
            if item == "*" {
                if let prev = stack.popLast() {
                    stack.append(prev * 2)
                }
                stack.append(cur * 2)
            } else {
                stack.append(cur * -1)
            }
        }
    }
    return stack.reduce(0) {$0 + $1}
}

 

다른 사람의 풀이


func solution(_ dartResult: String) -> Int {

        let numberList = dartResult.split(whereSeparator: {$0.isLetter || $0 == "#" || $0 == "*"})
        let letterList = dartResult.split(whereSeparator: {$0.isNumber})

        var totalScore = 0

        for (i, (number, letter)) in zip(numberList, letterList).enumerated() {
            var score = 0
            if let number = Int(number) {
                score = letter.contains("D") ? number * number : letter.contains("T") ? number * number * number : number
            }
            if letter.contains("*") {
                score *= 2
            } else if letter.contains("#") {
                score = -score
            }
            if i != 2 {
                if letterList[i + 1].contains("*") {
                    score *= 2
                }
            }
            totalScore += score
        }
        return totalScore
}

 

  • zip : 두 개의 시퀀스로 구성된 것을 가지고 시퀀스 쌍을 만듬
    • zip 함수가 반환한 인스턴스에서 i번째 쌍(ith pair)의 요소는 각 시퀀스의 i번째 요소
    • 두 시퀀스의 길이가 다를 경우, 짧은 시퀀스에 맞춰서 나옴

 

https://developer.apple.com/documentation/swift/zip(_:_:) 

 

zip(_:_:) | Apple Developer Documentation

Creates a sequence of pairs built out of two underlying sequences.

developer.apple.com

 

zip 예제코드


let words = ["one", "two", "three", "four"]
let numbers = 1...4


for (word, number) in zip(words, numbers) {
    print("\(word): \(number)")
}
// Prints "one: 1"
// Prints "two: 2"
// Prints "three: 3"
// Prints "four: 4"

// enumerated를 추가하면??

for (i, (word, number)) in zip(words, numbers).enumerated() {
	print("\(i)번째 조합: \(word), \(number)")
}
// Prints "0번째 조합: one, 1"
// Prints "1번째 조합: two, 2"
// Prints "2번째 조합: three, 3"
// Prints "3번째 조합: four, 4"