[프로그래머스] 할인 행사

이찬혁·2024년 5월 7일

알고리즘

목록 보기
57/72

프로그래머스 Lv2 - 할인 행사 문제

프로그래머스 레벨 2 할인 행사 문제를 풀이했다.

문제 내용 및 입출력 예를 보면서 총 몇 번을 반복해야할까 고민하다가
할인 제품의 총 개수(discount의 길이) - 구매해야하는 제품의 총 개수(want의 요소들의 합) + 1
의 공식을 발견하여 하기 흐름과 같이 풀이했다.

  1. 맵(key: 제품명, value: 제품 개수) 및 구매해야하는 제품의 총 개수 초기화
  2. 첫번째 반복문에서 loopCnt - total + 1만큼 반복
  3. 2-1 내부 반복문에서 해당하는 제품의 개수 카운트를 1씩 감소
  4. 2-2 내부 반복문에서 사지못한(value가 0초과인) 제품이 있는지 판별
  5. 다 살 수 있다면 정답 변수 1증가

중간에 for (int j = i; j < total + i; j++) 반복문의 조건에 오탈자가 있어 효율성도 떨어지고 계속 통과하지 못하였다.. 로깅 결과 계속 0번째 인덱스부터 반복하길래 다시 확인해보니 for (int j = 0; j < total + i; j++)으로 되어있었고 그래서 원래라면 다 사지 못 할 제품들도 다 살 수 있게되어 정답보다 더 큰 숫자들이 나오고, 중첩 반복문도 더 반복을 하게되니 효율성도 떨어지게 되었다.
코딩 테스트 때 오탈자 조심하자..!(사실 오탈자보단 오탈자로 인한 오류가 정확하겠다 ㅎ)

DiscountEvent.java

package com.example.Programmers.Lv2;

import java.util.HashMap;
import java.util.Map;

/**
 * 프로그래머스 Lv2 - 할인 행사
 */
public class DiscountEvent {
    public int solution(String[] want, int[] number, String[] discount) {
        int answer = 0;
        int loopCnt = discount.length;
        int total = 0;
        Map<String, Integer> wantMap = new HashMap<>();

        // 맵 및 제품 총 개수 초기화
        for (int i = 0; i < want.length; i++) {
            wantMap.put(want[i], number[i]);
            total += number[i];
        }

        // loopCnt - total + 1만큼 반복(제품 개수가 discount 길이 중 몇 번 반복할 수 있는지)
        for (int i = 0; i < loopCnt - total + 1; i++) {
            // 반복문에서 원본 맵 유지를 위해 생성자를 통한 복사
            Map<String, Integer> copyMap = new HashMap<String, Integer>(wantMap);
            for (int j = i; j < total + i; j++) {
                // 제한된 길이만큼 반복하면서 구매할 수 있으면(키가 존재하면) 카운트 - 1
                if (copyMap.containsKey(discount[j])) {
                    copyMap.replace(discount[j], copyMap.get(discount[j]) - 1);
                }
            }
            // 전체 제품 다 살 수 있는지 판별하는 변수
            boolean isAllDiscount = true;
            // 맵을 순회하며 못 산 제품이 있는지(0보다 큰지) 판별
            for (Map.Entry<String, Integer> m : copyMap.entrySet()) {
                if (m.getValue() > 0) {
                    isAllDiscount = false;
                }
            }
            if (isAllDiscount) {
                answer += 1;
            }
        }

        return answer;
    }
}

DiscountEventTest.java

package com.example.Programmers.Lv2;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class DiscountEventTest {
    @Test
    public void testDiscountEvent() {
        DiscountEvent d = new DiscountEvent();

        int result1 = d.solution(new String[] { "banana", "apple", "rice", "pork", "pot" }, new int[] { 3, 2, 2, 2, 1 },
                new String[] { "chicken", "apple", "apple", "banana", "rice", "apple", "pork", "banana", "pork", "rice",
                        "pot", "banana", "apple", "banana" });
        int result2 = d.solution(new String[] { "apple" }, new int[] { 10 }, new String[] { "banana", "banana",
                "banana", "banana", "banana", "banana", "banana", "banana", "banana", "banana" });

        assertEquals(3, result1);
        assertEquals(0, result2);
    }
}
profile
나의 개발로그

0개의 댓글