본문 바로가기
유용한기술

python 로또 번호 추출기 2탄

by DuncanKim 2022. 5. 15.
728x90

python으로 로또 추출기를 만든지 한 달 넘게 지났다.

자바로 했던 것을 파이썬으로 옮겨 놓는 것이 1탄이었다면, 무식했던 방법을 새로운 정렬 알고리즘을 통해 다시 만들어보고자 한다.

 

기존의 코드의 단점은 1000만 개 이상의 번호를 만들면 과도한 시간이 걸리는 것이었다.

2022.04.18 - [프로그래밍/재미있는 코딩놀이] - python 로또 번호 생성기

 

그래서 최근에 배운 계수정렬을 활용하면 딕셔너리를 활용하지 않고 충분히 많이 만들어진 로또 번호를 6개 골라낼 수 있을 것 같았다.

왜냐하면 계수 정렬에 필요한 리스트의 크기가 45이면 충분했기 때문이다. 메모리 용량도 그렇게 많이 잡아먹지 않고, 빠르게 연산할 수 있다고 생각했다.

 

바로 실행에 옮겼다.

 

** 기존 코드

import random

print("이번주 번호는 다음과 같습니다.")

# 5번의 게임을 반복하는 반복문
for h in range(5):

# loop 숫자 만큼의 랜덤 번호를 생성함.
    loop = int(10000000)
    randomlist = list()
    for i in range(loop):
        c = int(random.random()*45)
        randomlist.append(c)

# 0~44의 숫자가 생성된 횟수를 센 딕셔너리 생성(key = 번호 / value = 생성된 횟수)
    countlist = dict()
    for j in range(44):
        countlist[j] = randomlist.count(j)

# 생성된 횟수를 value를 기준으로 내림차순 정렬함(람다 사용)
    arraylist = list()
    arraylist = sorted(countlist.items(), key=lambda x: x[1], reverse=True)

# 리스트 안에 튜플 쌍으로 (key, value) 가 들어가있음.
# 앞에서 6번째 까지의 arraylist에 들어가있는 k번째 튜플의 0번째 값
# 즉 countlist의 key값(로또 번호)만을 출력하며 recommendlist에 삽입
# randomlist에서 만들어진 로또 번호는 0~44이므로 36번째 라인에서 + 1 함

    recommendlist = list()
    for k in range(6):
        recommendlist.append(arraylist[k][0]+1)
    
    recommendlist.sort()
    print("%d번째 게임 추천 번호 : " %(h+1), end="")
    print(recommendlist)

 

** 새 코드

import random

print("이번주 번호는 다음과 같습니다.")

# 5번의 게임을 반복하는 반복문
for h in range(5): # 5천원 어치의 게임을 한다고 치자. 전체 반복은 5회 해야 한다.

# 0~44까지 번호가 나온 횟수를 담을 리스트 선언
    randomlist = [0 for i in range(0, 45)]
# loop 숫자 만큼의 랜덤 번호를 생성함.
    loop = 100000000 # 1억 회의 루프를 돌면서 랜덤 번호 생성
    for i in range(loop):
        c = int(random.random()*45) # 1개의 번호 생성
        randomlist[c] += 1  # c는 랜덤리스트의 인덱스로 활용가능. 나온 횟수를 1 증가시킴 

    recommendlist = [] # 각 게임별 추천 숫자를 담는 리스트
    for k in range(6): # 게임 당 6개의 번호를 뽑아야 된다.
        a = max(randomlist) # random 리스트 중 가장 큰 값
        b = randomlist.index(a) # random 리스트 중 가장 큰 값의 인덱스
        randomlist[b] = 0 # b의 인덱스를 활용하여 값을 가장 적게 만들어 버리고
        recommendlist.append(b+1) # 추천리스트에 b+1한 값을 넣는다(로또 숫자는 1~45이기 때문)

    recommendlist.sort() # 번호를 오름차순으로 정렬한다.
    print("%d번째 게임 추천 번호 : " %(h+1), end="")
    print(recommendlist)

 

비슷한 듯 하면서도 비슷하지 않다. 리스트 만을 활용하여 모든 것을 해결하였다.

리스트 컴프리헨션을 적절히 써가면서 코드의 길이를 줄이기도 한다.

 

더 큰 차이는 수행시간이다.

새로운 코드는 출력이 끝나기 까지 8.0초, 기존 코드는 19.7초가 걸린다.

2.46배 정도의 성능 향상이 있었다. 그래서 1억번까지 루프를 돌려도 3분이 넘게 걸리지 않고 1분 20초 정도로 끝나버린다.

 

뿌듯.

728x90

댓글