[프로그래머스] [PCCP 기출문제] 1번 / 붕대 감기(javascript)

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/250137?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

확인 내용

1. 1초 마다 bandage[1]만큼 회복

2. 연속 성공 시 bandage[2]만큼 회복

3. attacks 배열의 순서 [공격 시간(초), 피해량]  


 

코드 로직

1. attacks의 모든 공격이 끝나면 연산 종료이므로 마지막 공격의 시간 확인

2. 초당 현재 회복량과 연속 성공여부를 확인

3. 연속 성공 시 추가 회복 체력량 연산

4. 마지막 공격의 종료 시점에서 현재 회복량 return

 

 

변수

second : 현재 시간 0
lastSec : 마지막 공격의 초
nowHealth : 현재 체력 
recoverytime : 회복 연속 성공 확인하는 변수

함수 

addHealth : 추가 체력 회복량을 합산할 때 사용

*** 최대 체력보단 클 수 없음

isAttack : 현재 시간(초)가 공격하는 시간인지 확인 후 공격력 return

lastAttackSec : 마지막 공격 시간(초) 확인 함수 

 

 

중요!!! 

1. 연속 성공 확인하는 방법이 초마다 +1을 하지만 공격을 받으면 0으로 초기화해야 합니다.

2. 추가 체력을 더할 때 최대 체력을 넘지 않아야 합니다.

3. 현재 체력이 0 이하일 경우는 -1을 리턴해야 합니다.

 

 

최종 코드

// bandage :  [시전 시간(t), 초당 회복량(x), 추가 회복량(y)]  
// attacks : [[공격 시간, 피해량]... ]
function solution(bandage, health, attacks) {
    // 최대 체력보다 커지는 것 X
    // 현재 체력이 0이하가되면 끝 = return -1
    // attacks : 2초일 때 공격, 9초일 때 공격 ..
    // attacks가 모두 끝나면 return
    let second = 0
    let lastSec = lastAttackSec(attacks); // 몇초까지 돌려야 하나
    let nowHealth = health // 체력 확인 
    let recoverytime = 0 // 회복 연속 성공 변수

    // 마지막 공격을 받고 남은 체력을 return
    for (var i=0; i<lastSec+1; i++){
        // 현재 공격 시간인지 확인
        if (isAttack(i) === 0) {
            recoverytime = recoverytime + 1
            nowHealth = addHealth(nowHealth, bandage[1])
        }else {
            // 회복 실패
            recoverytime = 0
            nowHealth -= isAttack(i)
        }

        // 연속으로 체력 회복 성공 시 
        if(recoverytime === bandage[0]) {
            nowHealth = addHealth(nowHealth, bandage[2])
            recoverytime = 0
        }

        // 현재 체력 값 확인
        if (nowHealth <= 0) {
            nowHealth =-1
            break;
        }
    }
    return nowHealth;


	// 체력 추가할 때 
    function addHealth(now, stamina){
        now += stamina
        if(now > health) now = health
        return now
    }
    // 배열에서 공격하는지 확인 후 공격력 return, 공격이 아니면 0 return 
    function isAttack(sec){
        for (var i=0; i<attacks.length; i++){
            if(sec === attacks[i][0]) return attacks[i][1]
        }
        return 0
    }
    // 마지막 공격 시간 확인
    function lastAttackSec(attacks){
        let lastSec = 0;

        attacks.forEach((attack) =>{
            lastSec = attack[0] > lastSec ? attack[0] : lastSec
        })
        return lastSec
    }
}

 

 

마무리

이 코드는 0초부터 공격 마지막 시점까지 체력량을 확인하는 코드입니다.

조금 더 생각해보고 초를 기준이 아니라 attacks를 기준으로 하면 더 짧게 작성할 수 있습니다.

attack에 초까지 나와있기 때문에 규칙성을 파악하고 연산하는 코드를 작성할 수 있습니다.

hint : for of 문법을 사용!

 

더보기
function solution(bandage, health, attacks) {
  let currHealth = health;
  let currTime = 0;

  for (let [attackTime, damage] of attacks) {
    let diffTime = attackTime - currTime - 1;
    currHealth += diffTime * bandage[1] + Math.floor(diffTime / bandage[0]) * bandage[2];

    if (currHealth > health) currHealth = health;
    currHealth -= damage;
    if (currHealth <= 0) return -1;
    currTime = attackTime;
  }

  return currHealth;

https://enai.tistory.com/63

728x90