문제 개요
밴디지(붕대) 시스템을 구현하는 문제로, 다음과 같은 요소들이 있다:
bandage: [연속 성공 시간, 초당 회복량, 추가 회복량]health: 최대 체력attacks: 공격 정보 배열 [[시간, 데미지], ...]
핵심 로직
- 공격이 있으면 데미지를 받고 연속 성공 카운트 리셋
- 공격이 없으면 초당 회복량만큼 체력 회복
- 연속 성공 시간을 달성하면 추가 회복량을 받음
- 체력이 0 이하가 되면 -1 반환
내가 놓친 핵심 포인트
잘못된 이해
if (hp + hpsec <= health) {
hp += hpsec;
}잘못된 생각: "체력이 최대치보다 낮을 때만 회복해야 한다"
올바른 이해
hp = Math.min(hp + hpsec, health);올바른 로직: "항상 회복하되, 최대치를 초과하지 않도록 제한한다"
문제가 된 케이스
예시 1: 정상 케이스
- 현재 체력: 90, 최대 체력: 100, 회복량: 10
- 기존 로직:
90 + 10 <= 100→ true → 회복 (맞음)
예시 2: 문제 케이스
- 현재 체력: 95, 최대 체력: 100, 회복량: 10
- 기존 로직:
95 + 10 <= 100→ false → 회복 안함 (틀림) - 수정 로직:
Math.min(95 + 10, 100)→ 100 → 올바르게 회복 (맞음)
교훈
1. 조건문의 의미를 정확히 파악하기
hp + hpsec <= health는 "회복 후에도 최대치를 넘지 않는다"는 의미- 하지만 이는 "회복을 시도할지 말지"를 결정하는 조건이 아님
2. 체력 회복의 올바른 로직
- 체력이 부족하면 회복을 시도
- 단, 최대치를 초과하지 않도록 제한
Math.min()을 사용하면 이 두 조건을 모두 만족
3. 엣지 케이스 고려
- 체력이 거의 최대치에 가까울 때의 동작
- 회복량이 남은 체력보다 클 때의 동작
최종 코드
function solution(bandage, health, attacks) {
let maxAttackTime = attacks[attacks.length - 1][0];
let attackInfo = {};
attacks.forEach((el) => {
attackInfo[el[0]] = el[1];
});
let seqCnt = 0;
let [seqChk, hpsec, addHp] = bandage;
let hp = health;
for (let i = 1; i <= maxAttackTime; i++) {
if (attackInfo[i] !== undefined) {
seqCnt = 0;
hp -= attackInfo[i];
if (hp <= 0) {
hp = -1;
break;
}
} else {
seqCnt += 1;
hp = Math.min(hp + hpsec, health); // 핵심 수정!
if (seqCnt >= seqChk) {
if (hp + addHp <= health) {
hp += addHp;
}
seqCnt = 0;
}
}
}
return hp;
}결론
간단해 보이는 조건문이지만, 실제로는 체력 회복의 근본적인 로직을 잘못 이해했던 것이 문제였다. 항상 엣지 케이스와 경계값을 고려해야 한다는 교훈을 얻었다.
'일반 스터디 > 코딩 테스트' 카테고리의 다른 글
| [프로그래머스] 110 옮기기 (0) | 2025.10.07 |
|---|---|
| [프로그래머스] 도넛과 막대그래프 (0) | 2025.10.07 |
| [프로그래머스] 스타 수열 (0) | 2025.10.06 |
| [프로그래머스] 양궁대회 (0) | 2025.10.06 |
| [프로그래머스] 메뉴 리뉴얼 (0) | 2025.10.05 |
댓글