본문 바로가기
Problem Solving/프로그래머스

[프로그래머스 | 파이썬 / 자바스크립트] 할인 행사(연습문제/ level 2)

by 청량리 물냉면 2023. 2. 23.
반응형
문제

https://school.programmers.co.kr/learn/courses/30/lessons/131127

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

🐍파이썬
def solution(want, number, discount):
    answer = 0
    #원하는 품목이 모두 있는지 확인
    for i, j in zip(want, number):
        if j > discount.count(i):
            return 0
    for k in range(len(discount)-9):
        check = 0
        for i, j in zip(want, number):
            # k ~ k+10일 안에 원하는 품목이 존재하지 않는 경우, k+1 진행
            if j > discount[k:k+10].count(i):
                check = 0
                break
            check = 1
        answer += check
    return answer

1️⃣ zip()을 이용해 discount 전체에 원하는 품목이 모두 있는지 체크하고, 원하는 상품의 재고가 없다면 바로 0을 리턴하여 종료한다. 

2️⃣ 행사기간에 원하는 상품을 구매할 수 있다면, 10일 간의 행사기간에 모든 물건을 살 수 있는지 확인한다. discount 배열을 10개씩 끊어서 확인.

3️⃣ 10일 간 물건을 구매할 수 없는 경우 check flag = 0으로 지정한 뒤 break하여 일수를 하루 옮긴 '다음 10일'을 체크한다.

4️⃣ 10일 간 물건을 구매할 수 있는 경우에는  check flag = 1

5️⃣ k+1하기 전, 저장해 둔 체크 플래그 값을 answer 변수에 더한다.(물건을 살 수 있는 경우 1, 살 수 없는 경우 0)

더보기

    #원하는 품목이 모두 있는지 확인
    for i, j in zip(want, number):
        if j > discount.count(i):
            return 0

 

이 코드는 없애도 동작이 되기는 하는데, 문제의 테스트 케이스 2번을 보고 우선 넣기는 했다.

시간 복잡도는 때에 따라 달라진다.

원하는 품목이 모두 있는지 체크하는 코드를 넣은 경우
체크코드를 넣지 않은 경우

 

 

다른 풀이 방법

from collections import Counter
def solution(want, number, discount):
    answer = 0
    dic = {}
    for i in range(len(want)):
        dic[want[i]] = number[i]
    for i in range(len(discount)-9):
        if dic == Counter(discount[i:i+10]): 
            answer += 1
    return answer

1️⃣ dic에 {"banana": 3, "rice":2, ...}와 같이 원하는 품목과 갯수를 저장

2️⃣ Counter() 클래스를 사용한 결과값과 dic의 결과값이 동일한 경우 10일간 원하는 물건을 살 수 있다는 뜻이기 때문에 answer += 1

dic과 Counter(discount[0:10])의 값은 아래와 같다.

    ...
    for i in range(len(discount)-9):
    # dic = {'banana': 3, 'apple': 2, 'rice': 2, 'pork': 2, 'pot': 1}
    # Counter(discount[0:10]) = Counter({'banana': 3, 'apple': 2, 'rice': 2, 'pork': 2, 'pot': 1})
        if dic == Counter(discount[i:i+10]):
            answer += 1
    ...

Counter(discount[i:i+10])의 나머지도 동일하게 동작한다.

 

❗ 참고

Counter() 클래스

중복된 원소가 들어있는 배열을 매개변수로 넘기면 각 원소가 몇 개 들어있는지 저장된 객체를 얻을 수 있다.

Counter(["hi", "hey", "hi", "hi", "hello", "hey"])
// Counter({'hi': 3, 'hey': 2, 'hello': 1})

출처: https://www.daleseo.com/python-collections-counter/

 

파이썬 collections 모듈의 Counter 사용법

Engineering Blog by Dale Seo

www.daleseo.com

 

 

🐥자바스크립트
function solution(want, number, discount) {
    var answer = 0;
    let dic = {};
    for(let i = 0; i < want.length; i++){
        dic[want[i]] = number[i];
    }
    for(let i = 0; i <= discount.length - 10; i++){
        let check = 0;
        for(let key in dic){
            if(dic[key] > discount.slice(i, i+10).filter((el)=> el === key).length){
                check = 0;
                break;
            }
            check = 1;
        }
        answer += check;
    }
    return answer;
}

파이썬 <다른 풀이 방법>의 dictionary 사용과 스스로 푼 문제의 flag 사용법을 합쳐서 풀어보았다.

for문을 더 많이 돌게 되어 시간 효율성은 좋지 않다...

 

 

다른 풀이 방법

function solution(want, number, discount) {
    let count = 0;
    for (let i = 0; i < discount.length - 9; i++) {
        const slice = discount.slice(i, i+10);
        let flag = true;
        for (let j = 0; j < want.length; j++) {
            if (slice.filter(item => item === want[j]).length !== number[j]) {
                flag = false;
                break;
            }
        }
        if (flag) count += 1;
    }
    return count;
}

 

 

 

 

 

 

 

반응형