Skip to content

[9019-DSLR] struct vs class #8

@soo941226

Description

@soo941226

저희가 이전에 이야기 나누기를 struct내부에서 mutating이 너무 빈번히 일어나면 차라리 class가 더 빠르다 라고 결론을 지었던 내용이 있었는데요

이번에 DSLR을 풀면서 이게 또 반드시 그런 건 아닌가? 하는 생각이 들어서 기록을 위해 남겨놓습니다. 스위프트를 참 알다가도 모르겠네요 ㅋㅋ

문제는 큐를 struct로 구현하는지 class로 구현하는지에 따라 시간이 굉장히 많이 차이가 나고, 특히 struct가 더 빨랐습니다. struct로 구현하게 되면 큐의 enqueue과 dequeue가 mutating이 붙어야만 하기 때문에 기존의 결론처럼 오히려 class로 구현하는 것보다 느리지 않을까 싶었는데, 반대로 훨씬 빠르네요.

로직에 문제가 있는 건지 제 눈으로는 파악이 잘안되어서 아래에 제가 구현한 코드도 함께 남겨놓습니다~

typealias DSLR = (_ n: Int) -> Int

func D(_ n: Int) -> Int {
    return (2 * n) % 10000
}

func S(_ n: Int) -> Int {
    return n == 0 ? 9999 : n-1
}

func L(_ n: Int) -> Int {
    let pulledN = (n % 1000) * 10
    let last = n / 1000
    return pulledN + last
}

func R(_ n: Int) -> Int {
    let pushedN = n / 10
    let first = (n % 10) * 1000
    return first + pushedN
}

let directions: [(DSLR, String)] = [
    (D, "D"),
    (S, "S"),
    (L, "L"),
    (R, "R")
]

if let inputLength = readLine().flatMap(Int.init) {
    var result = ""

    for _ in 0..<inputLength {
        guard let input = readLine()?
                .split(separator: " ")
                .compactMap({ Int($0) }) else {
                    break
                }

        let startNumber = input[0], targetNumber = input[1]

        var queue = Queue<(number: Int, flag: String)>()
        queue.enqueue((number: startNumber, flag: ""))

        var everVisitied = Array(repeating: false, count: 10000)
        everVisitied[startNumber] = true

        var inProgress = true
        while inProgress {
            guard let (number, currentFlag) = queue.dequeue() else { break }

            for (dslr, flag) in directions {
                let number = dslr(number)

                if everVisitied[number] {
                    continue
                }

                let flag = currentFlag + flag
                if number == targetNumber {
                    result += flag + "\n"
                    inProgress = false
                    break
                } else {
                    everVisitied[number] = true
                    queue.enqueue((number: number, flag: flag))
                }
            }
        }
    }

    print(result)
}

// MARK: - struct queue
struct Queue<Element> {
    private var list = [Element]()
    private var index = 0

    var isEmpty: Bool {
        return index >= list.count
    }

    mutating func enqueue(_ element: Element) {
        list.append(element)
    }

    mutating func dequeue() -> Element? {
        if isEmpty {
            return nil
        }

        defer {
            index += 1
        }

        return list[index]
    }
}

// MARK: - class queue
//class Queue<Element> {
//    private var list = [Element]()
//    private var index = 0
//
//    var isEmpty: Bool {
//        return index >= list.count
//    }
//
//    func enqueue(_ element: Element) {
//        list.append(element)
//    }
//
//    func dequeue() -> Element? {
//        if isEmpty {
//            return nil
//        }
//
//        defer {
//            index += 1
//        }
//
//        return list[index]
//    }
//}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions