Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9019-DSLR] struct vs class #8

Open
soo941226 opened this issue Feb 20, 2022 · 0 comments
Open

[9019-DSLR] struct vs class #8

soo941226 opened this issue Feb 20, 2022 · 0 comments

Comments

@soo941226
Copy link
Collaborator

저희가 이전에 이야기 나누기를 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]
//    }
//}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant