# 문제

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.

수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 그리고, 가장 빠른 시간으로 찾는 방법이 몇 가지 인지 구하는 프로그램을 작성하시오.

# 입력

첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.

# 출력

첫째 줄에 수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.

둘째 줄에는 가장 빠른 시간으로 수빈이가 동생을 찾는 방법의 수를 출력한다.

# 풀이

  1. trace 기법 (prev[next] = current) 기억하기
  2. 최대범위가 10만이 아닌 20만이어야 함. 수빈이의 첫 좌표가 10만이지 그 이후로 움직이는 좌표는 범위가 특정되지 않는다.
import Foundation

struct Queue<T> {
    var head = 0
    var array: [T?] = []

    var count: Int {
        return array.count - head
    }

    var isEmpty: Bool {
        return count == 0
    }

    mutating func enqueue(_ element: T) {
        array.append(element)
    }

    mutating func dequeue() -> T? {
        guard head < array.count,
              let element = array[head] else { return nil }

        array[head] = nil
        head += 1

        let percentage = Double(head) / Double(array.count)
        if percentage > 0.25 && array.count > 50 {
            array.removeFirst(head)
            head = 0
        }

        return element
    }

    var front: T? {
        if isEmpty {
            return nil
        } else {
            return array[head]
        }
    }
}

let nk = readLine()!.split(separator: " ").map { Int($0)! }; let n = nk[0]; let k = nk[1]
var visited: [Int] = .init(repeating: 0, count: 200004)
var prev: [Int] = .init(repeating: 0, count: 200004)
var ret = 0
var q = Queue<Int>()
q.enqueue(n)
visited[n] = 1

while(!q.isEmpty) {
    guard let current = q.front else { break }
    _ = q.dequeue()

    if current == k {
        ret = visited[k]
        break
    }

    for next in [current + 1, current - 1, current * 2] {
        if next < 0 || next >= 200004 || visited[next] != 0 {
            continue
        }

        visited[next] = visited[current] + 1
        q.enqueue(next)
        prev[next] = current
    }
}
print(ret - 1)

var next = k
var lists: [Int] = []

while(next != n) {
    lists.append(next)
    next = prev[next]
}
lists.append(n)
lists.reverse()

lists.forEach { print($0, terminator:  " " )}