본문 바로가기
알고리즘/프로그래머스

[프로그래머스] Lv.2 예상 대진표 문제

by 줍 2024. 4. 11.

1. 처음에 x - y > 1 조건만 적어서 반절 정도만 통과하는걸 보고 혹시나 했는데, 문제에 x가 y보다 작다는 조건이 없었다. 그래서 x > y인 경우와 y > x인 경우로 나누어주었지만 여전히 네 케이스는 실패였다. 반례는 바로 4번과 5번처럼 인접한 번호끼리 여러번 게임을 하는 경우이다. 그래서 x / 2 == y / 2 조건을 추가하여 범위를 넓혀주었다. 수정 후 통과는 했지만 ,,, 코드가 다소 중복되고 맘에 들지 않았다.

func solution(_ n:Int, _ a:Int, _ b:Int) -> Int {
    var answer = 1
    var (x, y) = (a, b)
    if x > y {
        while x - y > 1 || x / 2 == y / 2 {
            x = (x + 1) / 2
            y = (y + 1) / 2
            answer += 1
        }
    } else {
        while y - x > 1 || x / 2 == y / 2 {
            x = (x + 1) / 2
            y = (y + 1) / 2
            answer += 1
        }
    }
    return answer
}

 

2. 두번째 풀이

생각해보니 x, y의 대소관계를 따질 필요가 없어서 이렇게 바꾸어주었다.

func solution(_ n:Int, _ a:Int, _ b:Int) -> Int {
    var answer = 1
    var (x, y) = (a, b)
    while (x + 1) / 2 != (y + 1) / 2 {
        x = (x + 1) / 2
        y = (y + 1) / 2
        answer += 1
    }
    return answer
}

 

3. 다른 사람의 풀이에서 발견한 풀이

논리는 같지만 repeat-while 문을 사용해서 흐름이 자연스럽고 코드 중복도 더욱 줄었다. repeat-while 문은 들어는 봤지만 써볼 생각은 못해봤는데, 이런식으로 잘 쓸 수 있을 것 같다!

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
}