코딩 테스트/Level 1
로또의 최고 순위와 최저 순위
컴닥
2021. 5. 3. 16:35
반응형
로또의 최고 순위와 최저 순위
2021 Dev-Matching: 웹 백엔드 개발자(상반기)
736명 완료
programmers.co.kr/learn/courses/30/lessons/77484
코딩테스트 연습 - 로또의 최고 순위와 최저 순위
로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호
programmers.co.kr
파이썬
def solution(lottos, win_nums):
zero, match = 0, 0
for num in lottos:
if num == 0:
zero += 1
elif num in win_nums:
match += 1
return [min(6, 7 - match - zero), min(6, 7 - match)]
리스트보다 딕셔너리나 셋(집합)의 검색이 더 빠릅니다.
파이썬의 딕셔너리와 셋은 해시 알고리듬으로 작성되어 있습니다.
def solution(lottos, win_nums):
zero, match, win_nums = 0, 0, set(win_nums)
for num in lottos:
if num == 0:
zero += 1
elif num in win_nums:
match += 1
return [min(6, 7 - match - zero), min(6, 7 - match)]
golang
func solution(lottos []int, win_nums []int) []int {
zero, match := 0, 0
count := make(map[int]bool)
prize := []int{6, 6, 5, 4, 3, 2, 1}
for _, v := range win_nums {
count[v] = true
}
for _, v := range lottos {
if v == 0 {
zero++
} else if count[v] {
match++
}
}
return []int{prize[zero+match], prize[match]}
}
Java
정직하게...
class Solution {
public int[] solution(int[] lottos, int[] win_nums) {
var win_count = 0;
var zero_count = 0;
for (int lotto : lottos) {
if (find(win_nums, lotto)) {
win_count++;
} else if (lotto == 0) {
zero_count++;
}
}
return new int[]{prize(zero_count + win_count), prize(win_count)};
}
boolean find(int[] numbers, int num) {
for (var each : numbers) {
if (each == num) {
return true;
}
}
return false;
}
int prize(int num) {
return (num > 1) ? 7 - num : 6;
}
}
해시 셋을 이용했습니다.
루프를 반복하지 않으니 속도도 향상되고,
코드량도 줍니다.
class Solution {
public int[] solution(int[] lottos, int[] win_nums) {
var win_count = 0;
var zero_count = 0;
var winNumSet = new HashSet<Integer>();
for (var each: win_nums) winNumSet.add(each);
for (int lotto : lottos) {
if (winNumSet.contains(lotto)) {
win_count++;
} else if (lotto == 0) {
zero_count++;
}
}
return new int[]{prize(zero_count + win_count), prize(win_count)};
}
int prize(int num) {
return (num > 1) ? 7 - num : 6;
}
}
45개의 결과를 검색하기 위해 해시를 사용하는 것은 메모리의 낭비입니다.
다이렉트 어드레스 테이블(?)을 직접 구현하는 게 더 좋습니다.
import java.util.Arrays;
class Solution {
public int[] solution(int[] lottos, int[] win_nums) {
var win_count = 0;
var zero_count = 0;
var winNumTable = new Boolean[46];
Arrays.fill(winNumTable, false);
for (var each : win_nums) winNumTable[each] = true;
for (int lotto : lottos) {
if (winNumTable[lotto]) {
win_count++;
} else if (lotto == 0) {
zero_count++;
}
}
return new int[]{prize(zero_count + win_count), prize(win_count)};
}
int prize(int num) {
return (num > 1) ? 7 - num : 6;
}
}
등수 계산 함수도 array로 대체하였습니다.
위 과 같은 원리입니다.
import java.util.Arrays;
class Solution {
public int[] solution(int[] lottos, int[] win_nums) {
var win_count = 0;
var zero_count = 0;
var winNumTable = new Boolean[46];
// array를 이용해 함수 하나를 줄일 수 있습니다.
var prizeTable = new int[]{6, 6, 5, 4, 3, 2, 1};
// 검색 시 null 에러 방지를 위해, false로 채워주었습니다.
Arrays.fill(winNumTable, false);
// winNumTable의 인덱스에 로또 번호를 넣으면 당첨 여부를 바로 알 수 있습니다.
// prizeTable과 같은 원리입니다.
for (var each : win_nums) winNumTable[each] = true;
for (int lotto : lottos) {
if (winNumTable[lotto]) {
win_count++;
} else if (lotto == 0) {
zero_count++;
}
}
return new int[]{prizeTable[zero_count + win_count], prizeTable[win_count]};
}
}
반응형