Programmers: Javascript 문제풀이(17-24번)

너겟·2022년 5월 16일
0
post-thumbnail

Programmers_coding test

프로그래머스에서 자바스크립트 알고리즘을 풀어볼 수 있다!

17번) 문자열 다루기 기본

17번 문제 풀러가기!

문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다.

조건:
s는 길이 1 이상, 길이 8 이하인 문자열입니다.

입출력 예:

풀이:
정말 여러가지 방법으로 해봤는데 계속 조금씩 틀려서 결국 해설을 찾아봤다. 문제는 여러가지였는데,
첫번째는 "문자열의 각 문자가 모두 숫자로되어있는지 확인 하는 것이므로 정수만 가능하다." 즉, "소수는 안된다."

두번째로 잘못한 부분은, &&를 이용해서 조건을 여러개 명시해 주어야 할때는 조건끼리 괄호로 묶어야 한다는 것.

세번째는 자바스크립트 정규문법!
참고한 링크!

/^\d+$/ : 숫자만 입력가능하다는 뜻!

function solution(s) {
    return (s.length === 4|| s.length === 6) && /^[0-9]+$/.test(s);
}

사실 정규식을 이용하면 다음과 같은 풀이도 가능하다:

function alpha_string46(s){
  var regex = /^\d{6}$|^\d{4}$/;
  return regex.test(s);
}

note

짚고 넘어가야 할 이 아이들의 차이:

isNaN

이 문제에서 요구하는 것처럼 우리가 원하는 '숫자'를 찾아내기엔 무리가 있다.
숫자가 아닌 값도 true로 걸리는 등... 원하는 답을 명확히 찾기 어렵다.
실제로 '0.5'라는 소수를 isNaN로 확인해보았을때 false로 나온다.

Number

ex) '0.5' === 0.5
해당 문자열의 숫자를 있는 그대로 출력한다.
문자열 내에 숫자 말고도 문자가 섞여있으면 무조건 NaN로 나온다.

parseInt

ex) '0.5' === 0
소수를 출력해도 해당 소수점은 다 자르고 정수만 나온다.
문자열 내에 숫자 말고도 문자가 섞여있어도 숫자만 그대로 출력해주는 기능이 있다.

결론: isNaN, Number를 사용하면 틀리고 parseInt를 사용해야 한다.
참고한 링크

18번) 서울에서 김서방 찾기

18번 문제 풀러가기!

String형 배열 seoul의 element중 "Kim"의 위치 x를 찾아, "김서방은 x에 있다"는 String을 반환하는 함수, solution을 완성하세요. seoul에 "Kim"은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.

조건:

  • seoul은 길이 1 이상, 1000 이하인 배열입니다.
  • seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.
  • "Kim"은 반드시 seoul 안에 포함되어 있습니다.

입출력 예:

풀이:

function solution(seoul) {
    for (let i=0;i<seoul.length;i++) {
        if (seoul[i] === "Kim") {
        return "김서방은 " + i + "에 있다"
        }
    }
}

note
더 간단한 좋은 풀이가 있었다!
indexOf 함수를 써서 kim의 위치를 찾을 수 있다.

return "김서방은 " + seoul.indexOf('Kim') + "에 있다";

indexOf 더 알아보러 가기!

19번) 수박수박수박수박수박수?

19번 문제 풀러가기!

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.

조건:
n은 길이 10,000이하인 자연수입니다.

입출력 예:

풀이:

function solution(n) {
    let subak = ""
    for (let i=1;i<=n;i++) {
        if(i%2 === 1) {
            subak += "수"
        } else {
            subak += "박"
        }
    }
    return subak
}

20번) 완주하지 못한 선수

20번 문제 풀러가기!

단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

조건:

  • 마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

입출력 예:

풀이:
일단 뭔가 한 명만 완주를 못했다는 스토리 자체가 조금 서글프다...! 다 완주했으면 좋았을 것을..

participant라는 array안에 completion array의 element들이 다 들어가 있기 때문에 나는 반복문을 돌려서 participant array 에 completion array의 element 들이 include/match 안된 케이스를 찾을거다.

처음 풀이:
여기서 잘못된 점은 이름이 반복될 수 있는 것을 고려하지 않았다.

function solution(participant, completion) {
    for (let i=0;i<participant.length;i++) {        
        if  (completion.includes(participant[i])===false) {
            return participant[i]
        }        
    }
}

그럼 includes되는 것을 하나씩 리스트에서 delete해보자!

2번째 풀이:
이상하게도 일부 작동이 안된다.

function solution(participant, completion) {
    for (let i=0;i<completion.length;i++) {        
        let a = participant.includes(completion[i]); 
        participant.pop(a);
        
    }
    return participant[0];
}

찾아보니 map함수를 이용한 전혀 새로운 접근이 있었다!

21번) 이상한 문자 만들기

이상한 문제 만들기

문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.

조건:

  • 문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.
  • 첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.

입출력 예:

풀이:
생각보다 엄청 복잡했다. 먼저 white space를 구분지어 split한 다음 반복문을 두번이나 써줬다.

function solution(s) {
    var answer = '';
    let newarray = s.split (' ')
    let newstring = ''; 
    for (let i=0;i<newarray.length;i++) {
        newarray[i] += ' '
        for (let j=0;j<newarray[i].length;j++) {
            if (j%2 === 0) {                
                newstring += newarray[i].charAt(j).toUpperCase()
            } else {
                newstring += newarray[i].charAt(j).toLowerCase()
            }  
        }
    } return newstring.substr(0,newstring.length-1);
}

다른 사람의 풀이를 보니 한줄로도 가능했다!
그런데 사실 다른 풀이가 전혀 이해가 안되는 상황... 조금 더 들여다볼것!
다른 풀이

note
join 함수 사용법

22번) 자릿수 더하기

22번 문제 풀러가기!

자연수 N이 주어지면, N의 각 자릿수의 합을 구해서 return 하는 solution 함수를 만들어 주세요.
예를들어 N = 123이면 1 + 2 + 3 = 6을 return 하면 됩니다.

*조건:**

  • N의 범위 : 100,000,000 이하의 자연수

입출력 예:

풀이:
숫자를 string으로 바꿔서 그걸 다시 split을 사용해 하나씩 분리시켜준 다음 reduce를 사용해서 모두 더해준다.

function solution(n) {
    let num = n.toString();
    let arr = num.split('');
    let result = arr.reduce((acc, cur) => acc += Number(cur),0);
    return result
}

note
number, string, array내에 있는 element 등의 개념과 서로가 어떤 속성을 가지고 있는지를 다잡는 문제이다.

23번) 자연수 뒤집기

23번 문제 풀러가기!

자연수 n을 뒤집어 각 자리 숫자를 원소로 가지는 배열 형태로 리턴해주세요. 예를들어 n이 12345이면 [5,4,3,2,1]을 리턴합니다.

입출력 예:

풀이:
앞선 22번 문제에서 사용한 것들을 그대로 가져오면 된다. 먼저 자연수를 string으로 만든 다음, split하고 내림차순으로 배열하면 된다.
한가지 추가로 주의할 점은, return값이 자연수로 나와야한다. 그래서 마지막에 map을 사용해서 array내 모든 elements를 number()을 이용해서 자연수로 바꿔줬다.

처음 제출한 답안:

function solution(n) {
    let arr = n.toString().split('')
    let sudo= arr.sort(function(a,b) {
        return b - a
    });
    
    return answer = sudo.map(x => Number(x))
}

하지만 작동하지 않아서 조건을 다시 읽어봤더니, 내림차순으로 배열하는게 아니고 그냥 반대로 돌리는 거였다....(예시만 보지말고 설명을 잘 읽어보자!!!)
그래서 reverse order in array를 찾아봤더니 arr.reverse()라는 강력한 기능이 있었다! 정답은:

function solution(n) {
    let arr = n.toString().split('')
    let sudo= arr.reverse()
    
    return answer = sudo.map(x => Number(x))
}

note
강력한 map기능을 잘 활용해보자!
map 사용예시:

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

24번) 정수 내림차순으로 배치하기

24번 문제 풀러가기!

함수 solution은 정수 n을 매개변수로 입력받습니다. n의 각 자릿수를 큰것부터 작은 순으로 정렬한 새로운 정수를 리턴해주세요. 예를들어 n이 118372면 873211을 리턴하면 됩니다.

조건:
n은 1이상 8000000000 이하인 자연수입니다.

입출력 예:

풀이:
앗 이건 23번에서 내가 잘못 풀었던 방법으로 풀면 되는 문제이다!

function solution(n) {
    let arr = n.toString().split('')
    let sudo = arr.sort(function(a,b) {
        return b - a
    });
    
    return answer = Number(sudo.reduce((acc, cur) => acc += (cur)))
}

깔끔하게 줄인 다른 사람의 풀이:

function solution(n) {
    // 문자풀이
    return parseInt((n+"").split("").sort().reverse().join(""));
}

note
다른 사람의 풀이로 알게된 것:

  • n + "" 를 하면 자연수가 string이 되는 것.
  • sort()를 쓰고 reverse()를 쓰면 굳이 내림차순으로 다시 배열하지 안해도 되는 것.
  • 그냥 string을 합치면 되서 join을 쓰면 더 간단하다는 점.
profile
꾸준하게 하는 법을 배우는 중입니다!

1개의 댓글

comment-user-thumbnail
2022년 5월 16일

썸네일이 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
정리 잘 하셨네요!! 참고하러 자주 오겠습니다 ^^7

답글 달기