붕대 감기
어떤 게임에는 붕대 감기라는 기술이 있습니다.
붕대 감기는 t초 동안 붕대를 감으면서 1초마다 x만큼의 체력을 회복합니다. t초 연속으로 붕대를 감는 데 성공한다면 y만큼의 체력을 추가로 회복합니다. 게임 캐릭터에는 최대 체력이 존재해 현재 체력이 최대 체력보다 커지는 것은 불가능합니다.
기술을 쓰는 도중 몬스터에게 공격을 당하면 기술이 취소되고, 공격을 당하는 순간에는 체력을 회복할 수 없습니다. 몬스터에게 공격당해 기술이 취소당하거나 기술이 끝나면 그 즉시 붕대 감기를 다시 사용하며, 연속 성공 시간이 0으로 초기화됩니다.
몬스터의 공격을 받으면 정해진 피해량만큼 현재 체력이 줄어듭니다. 이때, 현재 체력이 0 이하가 되면 캐릭터가 죽으며 더 이상 체력을 회복할 수 없습니다.
당신은 붕대감기 기술의 정보, 캐릭터가 가진 최대 체력과 몬스터의 공격 패턴이 주어질 때 캐릭터가 끝까지 생존할 수 있는지 궁금합니다.
붕대 감기 기술의 시전 시간, 1초당 회복량, 추가 회복량을 담은 1차원 정수 배열 bandage와 최대 체력을 의미하는 정수 health, 몬스터의 공격 시간과 피해량을 담은 2차원 정수 배열 attacks가 매개변수로 주어집니다. 모든 공격이 끝난 직후 남은 체력을 return 하도록 solution 함수를 완성해 주세요. 만약 몬스터의 공격을 받고 캐릭터의 체력이 0 이하가 되어 죽는다면 -1을 return 해주세요.
입출력 예
function solution(bandage, health, attacks) {
var answer = health;
let bandageTime = bandage[0];
let bandageHeal = bandage[1];
let bandageFull = bandage[2];
let healCombo = 1;
let attackCount = 0;
for (let i = 0; i <= attacks[attacks.length-1][0]; i++) {
if (i === attacks[attackCount][0]) {
answer -= attacks[attackCount][1];
attackCount ++;
healCombo = 1;
if (answer <= 0) {
return -1;
}
}
else if (answer < health) {
if (healCombo === bandageTime) {
answer += (bandageHeal + bandageFull);
healCombo = 1;
}
else {
answer += bandageHeal;
healCombo ++;
}
if (answer > health) {
answer = health;
}
}
}
return answer;
}
- 먼저 어떤 방식으로 풀지 정해야 했는데
첫 번째 방법으로는 입출력 예 처럼 시간을 0초부터 1초씩 흐르게 하며 해당 시간마다 공격 또는 회복이 발생하도록 하는 방법이고
두 번째 방법은 attacks 배열을 반복문으로 순차적으로 돌며 공격을 당한 후 다음 공격까지의 여유 시간동안 회복되는 양을 계산하여 회복시키는 방법이 있었다.
좀 더 효율적인 로직은 두 번째 방법이긴 하나 어떤 식으로 로직을 짜야할지 바로 감이 오질 않아 일단은 첫 번째 방법으로 구성했다.
(첫 번째 방법으로는 시간 초과가 발생할 줄 알았는데 에러는 발생하지 않았다...)
- 먼저 가독성을 위해 붕대의 옵션들을 따로 변수에 지정하고 연속으로 붕대를 감은 횟수를 알기 위해 healCombo, 그리고 공격의 배열을 돌기 위한 attackCount를 선언했다.
붕대를 감으면 healCombo가 1씩 증가하고 붕대를 감는 최대 시간인 bandageTime과 동일해지면 bandageFull만큼 추가로 회복하는 방식이다.
그리고 반복문으로 돌고 있는 시간(초=i)이 attacks의 0번 인덱스와 동일해지면 공격을 당하고 attackCount를 1 증가시켜 다음 attacks 인덱스를 보게된다.
- 반복문 내용의 순서도 중요한데
공격 확인 및 공격 > 현재 체력과 최대 체력 확인 및 체력 회복 > 최대 체력 초과시 체력 재설정
순서로 구성했다.