[Kotlin] 중복 없는 N자리 숫자 만들기

RID·2024년 4월 29일
0

Kotlin

목록 보기
2/3

오늘 간단하게 Kotlin을 활용한 숫자야구 게임을 만들다가 중복된 숫자 없는 n자리 숫자를 만드는 함수를 작성하게 되었다. 해당 문제에서는 자리수가 적어 상관이 없겠지만 자리수가 많아지는 경우에 어떻게 하면 비교적 효율적으로 작성할 수 있을 지 고민해보았다.

1. 매 자리수마다 중복 체크하기

가장 쉽게 떠오르는 방법은 다음과 같다.
1. 0~9까지의 수 중 하나를 랜덤으로 고른다.
2. 다음 자리 수 역시 랜덤으로 고르고 앞의 자리 수와 겹치는 경우 겹치지 않을 때 까지 랜덤 뽑기를 반복한다.
3. n자리가 될 때 까지 이를 반복한다.

val n = 10
val arr : MutableList<Int> = mutableListOf()

for(i in 0..n-1){
	while(true){
    	val randomNum = (0 until n).random()
        if(!arr.contains(randomNum)) {
         	arr.add(randomNum)
            break
        }
    }
}

2. 중복 없이 생성되어 있는 배열을 조작하기

두 번째 방법의 흐름은 다음과 같다.
1. 0~9까지의 숫자를 하나씩 담고 있는 배열을 생성하기
2. 배열의 인덱스 두 개를 랜덤으로 골라 두 숫자의 위치를 Swap
3. 2의 과정을 충분히 반복
4. 배열의 앞 n개의 원소만 가져오기

val numList = mutableListOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
val repeatNum = 100
val n = 8
repeat(repeatNum){
    val index1 = numList.indices.random()
    val index2 = numList.indices.random()
    val temp = numList[index1]
    numList[index1] = numList[index2]
    numList[index2] = temp
}
val result = numList.subList(0,n)

3. 결과


두 가지 방식 중 두 번째 방법을 채택하여 프로젝트에 활용하였다. 사실 10자리 숫자까지 만드는 데에 큰 차이가 나지는 않을 것 같다고 생각했다.

하지만 measureNanoTime 함수를 활용해 동작 시간을 비교해보니 다음과 같은 결과가 나왔다.

1번 방식 : 65730μs
2번 방식 : 3270μs 

여러 번 시도 해 보았지만 대부분 약 20배 정도의 시간 차이를 보여주었다.
물론 2번 방식의 repeatNum 횟수를 늘려주면 그만큼 시간이 늘어나겠지만 이정도면 충분하다고 판단했다.

앞으로 중복 없는 n 자리 숫자 생성 시 2번과 같은 방식을 사용해보자.

0개의 댓글