ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 로또의 최고 순위와 최저 순위
    코딩 테스트/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]};
        }
    }
    반응형
Designed by Tistory.