본문 바로가기

알고리즘 & 문제풀이

프로그래머스 - L2 예상 대진표

설계

짝수인 경우 자신의 값 - 1 과 대결하고, 홀수인 경우 자신의 값 + 1과 대결

다음 라운드 배정 받는 수는 자신의 값 / 2 올림

위 규칙을 반복하여 대결 번호가 겹치는 경우 break 및 반환

git : 예상 대진표

문제 : https://school.programmers.co.kr/learn/courses/30/lessons/12985


문제 풀이

frontOpponent 은 frontNumber의 상대 번호, backOpponent은 backNumber의 상대 번호

if(frontOpponent == backNumber) 인 경우 a, b가 대결하게 되는 경우 이므로, break

그렇지 않은 경우는 다음 라운드시 배정받는 번호를 부여 및 라운드 수를 올린다.

import Foundation
// 홀수는 n + 1이랑 붙게되고
// 짝수는 n - 1이랑 붙게됨
// N : 인원 수 / 부전승 x
// answer : 몇 번재 라운드에서 붙는가
func solution(_ n:Int, _ a:Int, _ b:Int) -> Int
{
    var answer = 1
    var frontNumber = a < b ? a : b
    var backNumber = a > b ? a : b

    while(true) {
        let frontOpponent = frontNumber % 2 == 0 ? frontNumber - 1 : frontNumber + 1
        let backOpponent = backNumber % 2 == 0 ? backNumber - 1 : backNumber + 1
        if(frontOpponent == backNumber) {
            break
        }
        frontNumber = Int(ceil(Double(frontNumber) / 2))
        backNumber = Int(ceil(Double(backOpponent) / 2))
        answer += 1
    }

    return answer
}

만약 앱 개발 내 로직이였다면, 잘못 된 전달인자의 전달 등등 다양한 이유로 무한루프를 돌 가능성이 있으므로 n 인원이 n^m 이니까 m을 구해서 for문으로 동작한다든지 하는게 좋을거 같습니다!

다른 사람 풀이 분석

프로그래머스 -

import Foundation

func solution(_ n:Int, _ a:Int, _ b:Int) -> Int
{
    var answer = 0
    var nextA = a
    var nextB = b

    repeat {
        nextA = (nextA + 1) / 2
        nextB = (nextB + 1) / 2
        answer += 1
    } while nextA != nextB

    return answer
}

다음 라운드 배정 번호가 같으면 전 라운드에서 대결을 한거니.. 이 방법이 더 심플합니다!

와..

정리

while의 사용은 유의하셔야합니다.