이전 포스팅에선 C#과 파이썬에서 random 클래스 사용과 고려해야 할 점에 대해 살펴봤다. 이번에는 셔플링(shuffling; 카드섞기) 기법에 대해 다루도록 한다.
Contents
1. Array in C# and List in Python
2. random in C# and Python
3. Shuffling
4. Shuffling in Python
5. Lottery
3. Shuffling
셔플링 혹은 카드섞기 기법은 다음과 같은 절차를 거친다.
1) 뽑기 원하는 항목으로 채운 배열 혹은 리스트를 준비한다.
2) 배열 또는 리스트 인덱스 범위에 드는 두 난수를 얻는다.
3) 두 인덱스에 해당하는 요소를 교환한다.
4) 위 2), 3) 과정을 지정된 회수만큼 반복한다.
위 과정을 그림으로 설명하겠다. 1에서 6까지 6장의 카드가 있고, 흰색과 검은색 주사위가 아래 그림과 같이 있다고 하자. 흰색과 검은색 두 주사위를 각각 굴려 나온 숫자 위치에 있는 카드를 서로 교환한다. (물론 두 주사위를 굴리는 것은 독립실행이다.)
두 주사위를 굴렸더니 각각 3과 1이 나왔다. 그래서 첫 번째 위치에 있는 카드와 세 번째 위치에 있는 카드를 뽑아 자리를 교체했다.
다시 두 주사위를 굴렸더니 이번에는 각각 4와 2가 나왔다. 앞에서 시행한 바와 같이 두 카드 자리를 교체했다.
마지막으로 두 주사위를 굴렸더니 이번에는 두 주사위 모두 1이 나왔다. 첫 번째 카드를 뽑았다 다시 넣었다. (혹은 첫 번째 자리에 카드를 첫 번째 카드 자리와 교체 했다.)
위 과정을 시행 후 3장의 카드를 맨 위에서 차례로 꺼내면, 원래 1, 2, 3이었던 카드가 3, 4, 1 (혹은 정렬을 시행하면 1, 3, 4) 가 된다. 이를 카드 섞기 기법이라 한다.
C# 코드로 이를 작성하자면 우선 1부터 45까지 든 배열과 난수 발생을 위한 Random 클래스의 인스턴스가 필요로 하다.
아래 그림과 같이 private scope을 가지도록 int 형 배열과 Random 클래스 인스턴스를 선언했다.
난수 발생 메소드는 배열 인덱스에 맞춰, 0에서 44 범위에서 int 형 난수 하나를 얻도록 했고(Random 클래스의 Next(min, max) 메소드로 얻는 난수 N은 min ≤ N < max 범위를 가지는 임의의 정수이다.) 배열 요소간 교환(swap) 메소드는 다음과 같이 작성했다. (이 포스팅에서 작성한 C# 코드는 Console App. 이므로 private scope 변수 및 메소드를 static으로 선언했다.)
이후 프로그램 시작 지점 void Main(string[] args)에서 루프를 시행 후 인덱스 0에서 5까지 6개 숫자를 추출하면 된다. 여기서는 보너스 번호가 6번째 숫자임을 감안하고 첫 5개 숫자를 정렬해 결과를 보여주도록 했다.
실행 결과는 다음과 같다.
파이썬에서는 random 클래스에서 제공하는 메소드만으로 위와 같은 카드 섞기 기법을 이용할 수 있지만 이 포스팅에선 우선 위 C# 코드와 같은 방식으로 코드를 작성하겠다.
random 클래스를 불러오고, 1부터 45까지 연속된 정수를 포함한 리스트를 하나 생성 했다.
난수 발생 메소드(rollDice)와 배열 요소 교환 메소드(swapDeck)은 아래와 같이 작성했다. 파이썬의 경우 기존 프로그래밍 언어와 달리 메소드 결과를 1개 이상 복수로 리턴 할 수 있다. rollDice() 메소드에서 return 구문 다음에 두 개 리턴 값을 돌려주며 이를 받기 위해선 a, b = rollDice() 형태로 받아주면 된다.
100회 루프를 시행 후 얻은 결과를 얻는 코드를 아래에 나타내었다. 파이썬의 리스트에서 list[:6] 으로 콜론 후 숫자는 리턴 할 인자 개수를 의미한다. 예를 들어 인덱스 1에서 시작해서 10개 값을 얻고자 하면 list[1:10] 이라하면 인덱스 1부터 10까지 10개 값을 리턴한다.
아래 코드에서 result = lottoDeck[:5]는 lottoDeck 리스트의 인덱스 0부터 시작하는 5개 요소 값을 result에 할당 하란 뜻이다. 이를 list.sort() 메소드를 통해 소팅 후 result 리스트와 lottoDeck[5] 값을 쉘에서 나타내도록 했다.(파이썬 쉘에서는 변수 명을 기입하면 값이 표시된다.)
혹은 result.append(lottoDeck[5]) 를 해서 result 리스트에 lottoDeck[5] 값을 추가 할 수도 있다.
다음 포스트에선 카드 섞기 기법을 파이썬 random 클래스가 제공하는 메소드로 더 쉽게 접근토록 한다.
댓글 없음:
댓글 쓰기