TIL 11일차 - Javascript 코딩 테스트 풀이 답안 정리(2)

박찬웅·2023년 2월 16일
0

항해99

목록 보기
16/105

23년 2월 16일

  • 모든 문제의 출처는 프로그래머 스쿨에서 가져왔으며, 아래 적은 코드들의 답은 되도록 스스로 풀려고 생각했으나, 모르는 것들은 팀원들과 같이 풀거나, 기술매니저님한테 도움을 받았습니다.

12. 부족한 금액 계산하기

부족한 금액 계산하기 문제 푸는 곳
해답 및 설명

function solution(price, money, count) {
    var answer = 0;
    var result = 0;
    result = money - (count * (price + price * count) / 2); // 등차수열 이용
    if (result >= 0) {
        answer = 0; 
    } else {
        answer = -result;
    }
    return answer;
}

이 문제 같은 경우에는 예전에 고등학교 수학때 배웠던 등차수열 공식을 이용을 하였다. s = a(r+l)/2 를 생각하면 되었는데 초항(r)은 price이고, 마지막 항(l)은 price와 count를 곱한 수, 공차(a)는 count 라고 보면 된다. 따라서 money에서 등차수열 값을 빼면 음수가 나오게 된다. 다만 돈이 남아 있었을 경우에는 0으로 출력해야 했기 때문에 if문을 사용해서 돈이 남으면 0으로 출력하고, 그 반대로라면 부호를 바꿔주면 되었다.

13. 2016년

2016년 문제 푸는 곳
해답 및 설명

function solution(a, b) {
    var week = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']; // 배열로 요일 정의
    var dayOfWeek = week[new Date(2016, a-1, b).getDay()]; // Date 함수 공식을 이용
    // a-1하는 이유는 월은, 0~11까지 로 나타내기 때문에 1을 감소해야 정확한 값이 뜬다.
    return dayOfWeek;
}

날짜 요일을 표시 하는 것 같은 경우에는 처음에 갈피를 잡지 못하였다. 그런데 구글링으로 찾아 본 결과 자바스크립트 중 함수 메소드 중에 날짜를 표현하는 것과 요일을 나타내는 정의된 함수가 있었다. new Date(년, 월, 일)로 날짜를 표시 하면 오늘의 날짜를 표현 할수 있다. 다만 주의 할 점은 가운데 월은 0~11로 출력이 되는 구조라서 a-1로 해야 정확한 달이 지정이 된다고 한다. 일은 그대로 1부터 출력이 되서 그대로 b로 나타내면 된다.
요일 또한 getDay 함수를 이용하면 0부터 6까지 로 표현이 가능하지만, 숫자로만 뜨기 때문에 이걸 배열로 나타나게 하기 위해서 week 함수로 리스트를 정의를 해줘야 정확한 값이 출력이 된다.
본인 같은 경우엔 date 메소드로 이용해서 풀었지만, 정석으로 for문과 if문만 가지고 풀수도 있는데, 이런 경우에는 각 월과 일마다 리스트를 선언해야 하기에 번거로운 편이다.

14. 나누어 떨어진 숫자 배열

나누어 떨어진 숫자 배열 문제 푸는 곳
해답 및 설명

function solution(arr, divisor) {
    var answer = []
    // 나누어 떨어진 숫자만 배열 추가
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] % divisor === 0) {
            answer.push(arr[i]);
        }
    }
    // 오름 차순 정렬, for문 밖으로 실행해야 정상 출력됨
    answer.sort(function(a, b) {return a - b}); 
    // 나눌 숫자가 없어 길이 값이 0이면 -1을 추가
    if (answer.length === 0) {
        answer.push(-1);
    } 
    return answer;
}

각 배열의 하나마다 나머지가 0일때 그떄만 출력하기 위해서 if문 조건을 사용하였고, 나머지가 0이면 push함수로 해당하는 배열 리스트만 추가하였다. 그리고 숫자 크기대로 오름차순을 정렬 하기 위해서 오름차순 정렬하는 방식인 공식인 sort(function(a, b) {return a - b}를 이용하였다. 마지막으로 나눌 숫자가 없어서 아무것도 출력 하지 않았다면 -1을 push하면 되었다.
문제 접근 자체는 어렵지 않았다. 다만 숫자 크기대로 오름차순을 정렬 해야하는 위치가 가장 헷갈렸던 문제였다. for문으로 전부 수행하고 난 뒤에 정렬을 해야 정확하게 구현이 된다고 한다는 것을 알게 되었다.

15. 내적

내적 문제 푸는 곳
해답 및 설명

function solution(a, b) {
    var answer = 0;
    for (let i = 0; i < a.length; i++) {
        answer += a[i]*b[i] // 두 배열의 같은 위치의 합
    }
    return answer;
}

문제 자체는 아주 쉬웠다. 각각의 배열의 곱을 하고 그 나온 값을 모두 더 하면 되면 끝이였다.

16. 문자열 내 p와 y의 개수

문자열 내 p와 y의 개수 문제 푸는 곳
해답 및 설명

function solution(s){
    let p = 0, y = 0;
    s = s.toLowerCase(); // 소문자로 통합
  
    for (let i = 0; i < s.length; i++) {
        if (s[i] === 'p') {
            p += 1; // 문자열 p의 개수
        } else if (s[i] === 'y') {
            y += 1; // 문자열 y의 개수
        }
    }
    return p === y ? true : false // 삼항 연산자로 판별
}

우선 p와 y의 개수를 찾기 위해 p와 y 변수를 선언하였다. 또한 대문자와 소문자를 둘 중 하나로 통일하면 더 정리하기 쉬워지기 때문에 본인 같은 경우에는 소문자로 통일하는 함수인 toLowerCase 함수를 이용하였다. 그리고 나서 if문과 else if문으로 문자열의 p와 y의 개수를 찾는 조건문을 만들고 이후에 삼항 연산자로 p와 y 변수의 값이 동일하면 true, 아니면 false를 출력하게 만들었다.

17. 문자열 다루기 기본

문자열 다루기 기본 문제 푸는 곳
해답 및 설명

function solution(s) {
    let answer = parseInt(s); // 문자열을 숫자로 변환
  	// 길이가 4 혹은 6이면서, 숫자여야 하는 조건식
    if ((s.length === 4 || s.length === 6) && s == answer) {
        answer = true;
    } else {
        answer = false;
    }
    return answer;
}

먼저 문자열을 숫자로 변환하는 함수인 parseInt 함수를 이용하였다. 이러면 숫자로 바뀌게 된다. 문제에서는 s의 길이가 4이거나 6이여야 하기 때문이 ||(or)를 사용하였고, 아까 s를 문자여에서 숫자로 바꿨기 때문에 여야한다는 조건문을 만들면 되었다.
사실 이문제 접근하는 방식은 파악하는 것은 문제 없었다. 다만 s === answer 으로 조건을 세우면 모두 false가 나왔었다. ===는 현재 생긴 모습이 문자열인지 숫자인지까지 엄격하게 구분했기 때문에 false가 나왔었다 그래서 그냥 숫자만 일치하면 되는 ==을 써야 정상적으로 true가 나왔다.

18. 서울에서 김서방 찾기

서울에서 김서방 찾기 문제 푸는 곳
해답 및 설명

function solution(seoul) {
    return `김서방은 ${seoul.indexOf('Kim')}에 있다` ;
}

배열에서 특정한 값을 찾는 함수인 indexOf 함수를 이용하면 되었다. 그리고 예전에 웹개발 종합반에서 배웠던 것을 기억하면 크롤링 한 것의 결과를 출력하기 위해서 백틱과 ${}를 이용하면 이렇게 바로 return 반환하면 바로 출력이 가능했다.

19. 수박수박수박수박수박수?

수박수박수박수박수박수? 문제 푸는 곳
해답 및 설명

function solution(n) {
    var answer = '';
    for (let i = 0; i < n; i++) {
        if (i % 2 === 0) {
            answer += '수';
        } else {
            answer += '박';
        }
    }
    return answer;
}

for문으로 출력하는 범위를 정하고, 나머지가 0일때 문자열 '수' 출력, 아니면 '박' 출력하면 간단했다.

20. 완주하지 못한 선수

완주하지 못한 선수 문제 푸는 곳
해답 및 설명

function solution(participant, completion) {
    let answer = '';
    
    participant.sort(); // 참가자 배열 정렬
    completion.sort(); // 완주자 배열 정렬
    // 두 배열의 i번째와 비교 해서 불일치
    for (let i = 0; i < participant.length; i++) {
        if (participant[i] !== completion[i]) {
            answer = participant[i];
            return answer; 
        }
    }
}

먼저 참가자 배열과 완주자 배열 모두 sort 메소드 함수를 이용해서 사전적으로 정렬을 하였다. 그러고 나서 모든 마라톤 선수 중 한명만 완주 못한다는 전제가 있기 때문에, 정렬이 된 두 배열을 비교하면서 참가자 배열 기준으로 순회를 하면서 다른 사람이 나오면 그 참가자를 반환하면 되었다. 그리고 for문 안에다 반환을 해야 정상적으로 나왔다. for문 밖으로 나가서 출력을 하게 되면 동명이인의 문제 때문인지 틀린다고 한다.

ps. 사실 이 문제는 혼자서 노력은 물론, 팀원들이랑도 같이 끙끙 맸지만 2시간 동안 끝내 풀지 못해서 결국 인터넷에서 먼저 푸신 분의 답안들을 미리 보고 이 중에서 가장 이해하기 쉬운 코드를 가져와서 답안을 적었고 이 코드가 어떻게 돌아가는지 이해하였다. 이 문제 한정으로는 다른문제는 정확성만 뿐만이 아니라 효율성까지도 테스트를 한다. 그래서 만약 이중 리스트로 돌리면 사용성에서 실패가 뜨기 때문에 레벨1 답지 않은 문제였던것 같았다. 따라서 오늘 유이하게 풀지 못한 문제 중 하나였다.

21. 이상한 문자 만들기

링크텍스트
해답 및 설명

function solution(s) {
    let answer = '';
    let words = s.split(' '); // 공백을 기준으로 단어 쪼개기
    // 이중 for문을 활용
    for (let i = 0; i < words.length; i++) {
        for (let j = 0; j < words[i].length; j++) {
            if(j % 2 === 0) {
                answer += words[i][j].toUpperCase(); // 짝수번째에 대문자 표현
            } else {
                answer += words[i][j].toLowerCase(); // 홀수번째에 소문자 표현
            }
        }
        // 각 단어가 끝났을 때 공백칸 출력
        if (i < words.length - 1) {
            answer += ' ';
        }
    }
    return answer;
}

우선 변수 하나를 추가 더 선언 해서 split 함수를 통해 공백을 기준으로 잘라 배열을 만들었다. 그런 다음에 for문을 돌려서 단어의 길이만큼 돌리고 그리고 한번 더 for문을 돌려서 그 단어의 철자 기준으로 돌려서 이중 for문을 작성했다. 그런 다음에 짝수번째 철자에는 대문자로 변환하는 toUpperCase를 사용했고, 반대면 소문자로 변환하는 toLowerCase을 사용했다. 이렇게 끝나면 단어가 쭉 붙어 있는 상태로 나열 되어있기 때문에 공백을 다시 추가하기 위해서 각 단어가 끝났을때 공백을 추가하는 작업을 하면 끝났다.

ps. 이 문제도 20번과 함께 끝내 풀지 못하고 다른 사람의 답안을 보고 이해한 문제였다. 우선 이중 for문 표현하는 것이 정말로 까다로웠고, 마지막에 공백을 추가하기 위한 식을 나타내지 못하였고, 그걸 알아도 왜 2번째 for문이 끝난 바로 뒤에다 적어야 하는 건지에 대해서 정말로 이해하기 어려웠던 부분이였다.

22. 자릿수 더하기

자리숫 더하기 문제 푸는 곳

function solution(n) {
    var answer = 0;
    let number = n.toString(); // 숫자를 문자열로 전환
    
    for (let i = 0; i < number.length; i++) {
        answer += parseInt(number[i]); // 문자열을 숫자로 전환

    }
    
    
    return answer;
}

우선 정수를 그냥 쪼갤 수 없기 때문에 tostring문을 써서 숫자를 문자열로 바꿨다. 그런 다음에 for문을 돌려서 각 자리수 마다 더하는 식을 구해야 하는데 지금 정의 된 것이 문자열 이기 때문에 parseInt를 사용해서 다시 숫자로 전환을 하면 되었다. 문자열로 바꿔서 구한 뒤에 다시 숫자로 변환해야 하는 조금 상당히 깊게 생각을 해야 풀수 있었던 문제였다.

알게 된 점

어제에 이어서 오늘도 계속해서 알고리즘 문제를 풀게 되었다. 어제부터 느낀 건데 확실히 이중 for문 작성에서 많이 애를 많이 타는 느낌을 받았었다. 그래도 어제랑은 다르게 잘 모를때는 중간에 콘솔에 찍어보면서 한번 풀어보려고 노력을 하였다. 특히나 오늘 같은 경우에는 2문제 정도는 아예 못풀고 결국엔 인터넷에서 올라온 다른 분들의 해답을 보고 이게 어떻게 굴러갔는지 이해하려고 노력을 했고, 한 문제를 너무 오래는 잡지 말고 모를때는 다른 사람의 답을 보고 그 코드가 어떻게 굴러갔는지 이해 하는 것도 괜찮은 방법인 것을 알게 되었다. 아직 이틀밖에 하지 못해서 여전히 부족한 점은 많은 것 같기도 한다. 내가 적은 코드들을 보면서 복습도 하고, 자주 쓰는 몇몇 메소드 함수들도 익숙하는데 힘을 써야 할 것 같다.

앞으로 계획

내일정도면 이번주의 목표치인 28문제를 다 풀 것 같아 보인다. 하지만 향해 커리큐럼이 그렇듯 28문제 다 풀면, 이거보다 난이도 더 높은 추가문제들도 준비 되어 있으니, 시간이 남으면 그것도 한번 풀어보고, 지금까지 푼 것도 복습해보는 시간을 가져 볼 예정이다. 월요일에 코딩테스트 시험이 있으므로 남은 기간도 화이팅이다.

profile
향해 13기 node.js 백앤드

0개의 댓글