wanna be dev 🧑‍💻

Cool 하고 Sick한 개발자가 되고 싶은 uzun입니다

A.K.A. Kick-snare, hyjhyj0901, h_uz99 solvedac-logo

Problem Solving/BOJ

[BOJ][S4] 덱 - 10866 (Kotlin)

Kick_snare 2023. 4. 24. 22:18
728x90

[Silver IV] 덱 - 10866

문제 링크

 

10866번: 덱

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net

분류

자료 구조, 덱

문제 설명

정수를 저장하는 덱(Deque)를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 여덟 가지이다.

  • push_front X: 정수 X를 덱의 앞에 넣는다.
  • push_back X: 정수 X를 덱의 뒤에 넣는다.
  • pop_front: 덱의 가장 앞에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • pop_back: 덱의 가장 뒤에 있는 수를 빼고, 그 수를 출력한다. 만약, 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 덱에 들어있는 정수의 개수를 출력한다.
  • empty: 덱이 비어있으면 1을, 아니면 0을 출력한다.
  • front: 덱의 가장 앞에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • back: 덱의 가장 뒤에 있는 정수를 출력한다. 만약 덱에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

풀이

일반적 풀이

private fun readInt() = readln().toInt()

fun main() {
    val sb = StringBuffer()
    val dq = ArrayDeque<Int>()
    val n = readInt()
    for(i in 0 until n) {
        val inputs = readln().split(' ')
        when(inputs[0]) {
            "pop_front" -> sb.append(dq.removeFirstOrNull() ?: -1)
            "pop_back" -> sb.append(dq.removeLastOrNull() ?: -1)
            "size" -> sb.append(dq.size)
            "empty" -> sb.append(if(dq.isEmpty()) 1 else 0)
            "front" -> sb.append(dq.firstOrNull() ?: -1)
            "back" -> sb.append(dq.lastOrNull() ?: -1)
            else -> {
                val x = inputs[1].toInt()
                when(inputs.first()) {
                    "push_front" -> dq.addFirst(x)
                    "push_back" -> dq.addLast(x)
                }
                continue
            }
        }
        sb.append("\n")
    }
    println(sb)
}

그냥 큐를 구현하면 되는 문제.

Kotlin Collection에 존재하는 ArrayDeque을 사용하여 문제를 구현하였는데, 이것 저것 유용한 메서드를 제공해줘서 편하긴 한데 다른 코드들을 보니 Java.util 에서 LinkedList 불러와서 구현해놓은게 더 빠르더라.

처음에는 그냥 println으로 출력했는데, 계속 시간초과가 나길레 다른 코드 참고하니 StringBuilder , StringBuffer등을 활용하는 것을 보고 위와 같이 수정했다. 꽤나 유의미한 속도 차이가 있는 듯하다.

확실히 백준 플랫폼을 활용하니까 직접적인 구현부 보다 입출력하는데 신경을 써야하는 부분이 존재하는 것 같다.

숏코딩

풀다보니까 코드 사이즈를 더 작게 줄일 수 있지 않을까 하고 이것저것 손대보니 시작했다. 그러다가 나온것이 아래의 코드.

fun main() {
    val sb = StringBuilder()
    val dq = ArrayDeque<String>()
    repeat(readln().toInt()) {
        val cmd = readln().split(' ')
        when (cmd[0]) {
            "push_front" -> dq.addFirst(cmd[1])
            "push_back" -> dq.addLast(cmd[1])
            "pop_front" -> dq.removeFirstOrNull()
            "pop_back" -> dq.removeLastOrNull()
            "empty" -> if (dq.isEmpty()) 1 else 0
            "front" -> dq.firstOrNull()
            "back" -> dq.lastOrNull()
            "size" -> dq.size
            else -> {}
        }.let { if(it !is Unit) sb.appendLine(it ?: "-1") }
    }
    print(sb)
}

숏코딩이다 보니 좋은 가독성 좋은 코드라고는 하기 힘들다.

when express문에는 반환 값이 AnyUnitString, Int가 썪여들어온다. Unit이 아닐때 ("push_front", "push_back" 외) let 함수를 이용해 stringBuilder에 더해준다. elvis operator를 이용해 null 값 시 "-1" 처리

코틀린으로 푸는 사람이 없어서 그런가 난독화 한것도 아닌데 2등 먹었다. 굳

728x90