Do.

2022 KAKAO BLIND RECRUITMENT - 양궁대회 본문

Algorithm

2022 KAKAO BLIND RECRUITMENT - 양궁대회

Hey_Hen 2022. 3. 18. 11:44

https://programmers.co.kr/learn/courses/30/lessons/92342

 

코딩테스트 연습 - 양궁대회

문제 설명 카카오배 양궁대회가 열렸습니다. 라이언은 저번 카카오배 양궁대회 우승자이고 이번 대회에도 결승전까지 올라왔습니다. 결승전 상대는 어피치입니다. 카카오배 양궁대회 운영위원

programmers.co.kr

 

- 너무 무식하게 접근했는데, 다른 사람 풀이보고 공부해야 겠다.

- 기본적으로 bfs 접근 방식이니, 라이언의 info를 set형태로 visited를 체크하면 속도는 좀 올라갈듯.

 

import Foundation
let scoreBoard = [10,9,8,7,6,5,4,3,2,1,0]

struct Queue {
  var leftStack: [Game] = []
  var rightStack: [Game] = []
  var appeachInfo: [Int] = []
  var maxScoreGame: [Int] = [-1]
  var maxScore: Int = -1

  var count: Int {
    leftStack.count + rightStack.count
  }

  mutating func enqueue(_ element: Game) {
    leftStack.append(element)
    maxScoreCalculating(element.info)
  }

  mutating private func maxScoreCalculating(_ lyonGame: [Int]) {
    let (appeahScore, lyonScore) = scoreCalculating(appeachInfo, lyonGame)
    let scoreDifference = lyonScore - appeahScore
    if scoreDifference > 0,
        maxScore < scoreDifference {
      maxScore = scoreDifference
      maxScoreGame = lyonGame
    } else if scoreDifference > 0, maxScore == scoreDifference {

      for (previous, new) in zip(maxScoreGame, lyonGame).reversed() {
        if new > previous {
          maxScoreGame = lyonGame
          return
        } else if new < previous {
          return
        }
      }
    }
  }

  mutating func dequeue() -> Game? {
    if rightStack.isEmpty {
      rightStack = leftStack.reversed()
      leftStack.removeAll()
    }
    return rightStack.popLast()
  }

  func scoreCalculating(_ appeach: [Int], _ lyon: [Int]) -> (appeach: Int, lyon: Int) {
    var appeachTotalScore = 0
    var lyonTotalScore = 0

    for (index, (appeachArrow, lyonArrow)) in zip(appeach, lyon).enumerated() {
      if appeachArrow != 0 && appeachArrow >= lyonArrow {
        appeachTotalScore += scoreBoard[index]
      } else if lyonArrow != 0 {
        lyonTotalScore += scoreBoard[index]
      }
    }
    return (appeachTotalScore, lyonTotalScore)
  }
}

struct Game {

  var remainArrow: Int
  var info: [Int] = .init(repeating: 0, count: 11)
  var index: Int = 0

  mutating func shot(_ amountOfArrow: Int) {
    defer {
      index += 1
    }

    guard remainArrow >= amountOfArrow,
            amountOfArrow > 0 else {
      info[index] = index == 10 ? remainArrow : 0
      return
    }
    info[index] = amountOfArrow
    remainArrow -= amountOfArrow
    return
  }

  init(remainArrow: Int) {
    self.remainArrow = remainArrow
  }

  init(game: Game) {
    self.remainArrow = game.remainArrow
    self.info = game.info
    self.index = game.index
  }
}

func solution(_ n:Int, _ info:[Int]) -> [Int] {
  var queue = Queue()
  queue.appeachInfo = info
  queue.enqueue(Game(remainArrow: n))
  for arrow in info {
    for _ in 0..<queue.count {
      guard let element = queue.dequeue() else { break }

      var shot = Game(game: element)
      var dontShot = Game(game: element)

      shot.shot(arrow + 1)
      dontShot.shot(0)

      queue.enqueue(shot)
      queue.enqueue(dontShot)
    }
  }
  return queue.maxScoreGame
}
Comments