Oops, All Code!/🤯 Oops, My Algorithm!

- ̗̀ෆෆ ̖́ 01. 기본 입출력에 관한 예제

밍동망동 2024. 6. 28. 21:30

문자열 겹쳐쓰기

 

문자열 my_string, overwrite_string과 정수 s가 주어집니다.

문자열 my_string의 인덱스 s부터 overwirte_string의 길이만큼을

문자열 overwirte_string으로 바꾼 문자열을 return하는 solution 함수를 작성해 주세요.

 

mySolution

function solution(my_string, overwrite_string, s) {
    var answer = '';
    part_one = my_string.slice(0, s);
    part_two = my_string.slice(s+overwrite_string.length);
    const result = [part_one, overwrite_string, part_two];
    answer = result.join('');
    return answer;
}

 

코드가 깔끔하지 않다.
slice로 나누어 합치기 전, 합치는 부분, 합치고 난 후 세 분야로 뺐는데 조금 더 깔끔한 방법이 있을 것 같다.

 

 


 

 

split 문자열을 특정 구분자로 나누어 배열로 반환   문자열만 가능
slice 새로운 문자열 또는 배열로 반환
원본은 변경되지 않음
원본은 변경되지 않음 문자열 또는 배열
splice 배열의 요소를 추가, 제거 또는 교체
원본 배열이 변경
원본 배열이 변경 배열만 가능

 


 

초기 코드 오답

function solution(price) {
    var discount = 0;
    var final_price = 0;
    
    if (price >= 500000) {
        discount = 0.2;
    } else if (price >= 300000) {
        discount = 0.1;
    } else if (price >= 100000) {
        discount = 0.05;
    } else {
        discount = 0;
    }
    
    final_price = price - (price * discount);
    
    return final_price;
}

 

오답의 원인

보통 수식에서 소수점 따위의 문제로 정수 취급이 이상했을 것 같음.

final_price = Math.floor(final_price);

 

다른 사람의 풀이

const discounts = [
    [500000, 20],
    [300000, 10],
    [100000,  5],
];

const solution = (price) => {
    for (const discount of discounts)
        if (price >= discount[0])
            return Math.floor(price - price * discount[1] / 100);
    return price;
}

 

2차원 배열과 화살표 함수를 사용해 특정 조건에 맞는 할인율을 적용함.

배열을 사용했기 때문에, 유지보수성이 향상되었음.

 

동적으로 할인 조건을 설정할 수 있다는 부분이 유연했음.

따라서 특정 조건마다 달라지는 경우 배열을 떠올림으로써 유지보수성을 늘릴 수 있을 것으로 판단됨.


나의 코드

function solution(array, height) {
    let answer = 0;
    
    for(let i=0; i<array.length; i++){
        if(array[i]>height){
            answer++;
        }
    }
    
    return answer;
}

 

의문점

 

초기의 코드는 answer을 초기화해주지 않았다.

let answer;

null로 판단되기에, 0으로 초기화했더니 해결되었다.

이유를 생각해보았는데 초기화되지 않은 경우 undefined로 연산되면

undefined에 ++연산자를 대입하면 나는 알아서 타입 추론할 것으로 예상했는데,

NaN(Not-a-Number) 취급을 당한 것이다.

 

타입 추론에 대한 잘못된 생각을 바로잡을 수 있었다.

 

다른 사람의 코드

function solution(array, height) {
    var answer = array.filter(item => item > height);
    return answer.length;
}

 

filter를 이용해 조건에 맞는 요소들만 추출했음.

조금 더 직관적이라고 판단됨.

 

더 나아가

 

전체 배열을 순회하면서 같은 연산을 하는거니까 map을 사용할 수 있지 않을까 생각해봤다.

하지만, map은 배열을 순회해 새로운 배열을 만드는거니까

초기 목적에 어울리지 않는다고 판단해 forEach 연산자를 떠올렸다.

function solution(array, height) {
    let count = 0;

array.forEach(item => {
        if (item > height) {
            count++;
        }
    });

    return count;
}

 

좋은 판단 방식이라 생각했는데 완성한 코드를 보니

역시 filter 메소드가 훨씬 더 간결하고 직관적이라는 생각이 들었다.


 

체력에 맞게 최소한의 병력을 구축하라는 문제

최소한이라는 키워드가 눈에 들어와 조금 더 고민되었다.

 

0단계는 입출력만 다룬다고 생각했는데, 뭔가 처음으로 마주한 코테스러운 단어였다.

 

생각보다 오래 고민하였는데 어렵게 생각할 필요 없이

장군, 병정, 일 순으로 강력하기 때문에 최소한의 병력을 구축하기 위해

장군부터 최대한 채우고, 병정, 일 순으로 계산하면 된다고 생각했다.

 

나의 코드

function solution(hp) {
    const generalAnt = 5; 
    const soldierAnt = 3; 
    const workerAnt = 1;  

    let generalCount = 0;
    let soldierCount = 0;
    let workerCount = 0;

    generalCount = Math.floor(hp / generalAnt);
    hp = hp % generalAnt; 

    soldierCount = Math.floor(hp / soldierAnt);
    hp = hp % soldierAnt; 

    workerCount = hp;

    return generalCount + soldierCount + workerCount;
}

 

다른 사람의 코드

function solution(hp) {
    return Math.floor(hp/5)+Math.floor((hp%5)/3)+(hp%5)%3;
}

생각 이상으로 간단하여 놀라운데 핵심 로직은 전부 맞았다.

직관력을 덜더라도 변수를 조금 덜 사용하고, 짧게 작성하는 생각을 들여야겠다.