programmers ) coding test 6

Yeonn·2024년 5월 9일
0

coding test

목록 보기
6/13
post-thumbnail

✔️ 코딩테스트 입문

✅ check

  • switch
  • arr.map()
  • get()
  • has()
  • toFixed()
  • arr.sort()
  • parseInt()

🌿 외계어 사전

🌱 문제 설명

PROGRAMMERS-962 행성에 불시착한 우주비행사 머쓱이는 외계행성의 언어를 공부하려고 합니다. 알파벳이 담긴 배열 spell과 외계어 사전 dic이 매개변수로 주어집니다. spell에 담긴 알파벳을 한번씩만 모두 사용한 단어가 dic에 존재한다면 1, 존재하지 않는다면 2를 return하도록 solution 함수를 완성해주세요.

🌱 제한 사항

  • spell과 dic의 원소는 알파벳 소문자로만 이루어져있습니다.
  • 2 ≤ spell의 크기 ≤ 10
  • spell의 원소의 길이는 1입니다.
  • 1 ≤ dic의 크기 ≤ 10
  • 1 ≤ dic의 원소의 길이 ≤ 10
  • spell의 원소를 모두 사용해 단어를 만들어야 합니다.
  • spell의 원소를 모두 사용해 만들 수 있는 단어는 dic에 두 개 이상 존재하지 않습니다.
  • dic과 spell 모두 중복된 원소를 갖지 않습니다.

🌱 입출력 예

spelldicresult
["p", "o", "s"]["sod", "eocd", "qixm", "adio", "soo"]2
["z", "d", "x"]["def", "dww", "dzx", "loveaw"]1
["s", "o", "m", "d"]["moos", "dzx", "smm", "sunmmo", "som"]2

🌱 내 코드

const solution = (spell, dic) => {
  const sortedSpell = [...spell].sort().join('');
  let lettersForDic = [];
  let count = 0;
  
  dic.forEach((el) => {
    lettersForDic.push(el.split('').sort().join(''));
  });
  
  lettersForDic.forEach(el => el === sortedSpell ? count ++ : '')
  
  return count === 0 ? 2 : 1
}

🌱 다른 사람 풀이

function solution(p, d) {
    return d.some(s => p.sort().toString() == [...s].sort().toString()) ? 1 : 2;
}

📍arr.some()
배열 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 한번이라도 참이면 true, 모두 거짓이면 false를 반환, 호출한 배열이 빈 배열인 경우 언제나 false를 반환



🌿 캐릭터의 좌표

🌱 문제 설명

머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.

[0, 0]은 board의 정 중앙에 위치합니다. 예를 들어 board의 가로 크기가 9라면 캐릭터는 왼쪽으로 최대 [-4, 0]까지 오른쪽으로 최대 [4, 0]까지 이동할 수 있습니다.

🌱 제한 사항

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 ≤ keyinput의 길이 ≤ 50
  • 1 ≤ board[0] ≤ 99
  • 1 ≤ board[1] ≤ 99
  • keyinput은 항상 up, down, left, right만 주어집니다.

🌱 입출력 예

keyinputboardresult
["left", "right", "up", "right", "right"][11, 11][2, 1]
["down", "down", "down", "down", "down"][7, 9][0, -4]

🌱 내 코드

const solution = (keyinput, board) => {
  let location = [0, 0];
  
  for(let i = 0; i < keyinput.length; i ++){
    if(keyinput[i] === 'left' && location[0]-1 >= -board[0]/2 ){
      location[0] --;
    };
    if(keyinput[i] === 'right'&& location[0]+1 <= board[0]/2) {
      location[0] ++;
    }
    if(keyinput[i] === 'up' && location[1]+1 <= board[1]/2) {
      location[1] ++;
    }
    if(keyinput[i] === 'down' && location[1]-1 >= -board[1]/2 ) {
      location[1] --;
    }
  }
  
  Math.abs(location[0]) > Math.floor(board[0] / 2) ? 
	location[0] = Math.floor(board[0] / 2) : location[0];
  Math.abs(location[1]) > Math.floor(board[1] / 2) ?
    location[1] = Math.floor(board[1] / 2) : location[1];
  
  return location;
}

📍 Math.abs()

  • 인수로 전달된 숫자의 절대값 반환
  • 절대값: 반드시 0 또는 양수

📍 Math.floor()
인수로 전달된 숫자의 소수점 이하를 내림한 정수를 반환( ceil 반대 ! )

캐릭터 이동 시에 바로 범위 조건을 체크하지 않고 마지막에 체크하기 때문에 오류 가능성이 있고 switch문 보다 가독성이 떨어진다...

🌱 다른 사람 풀이

function solution(keyinput, board) {
    let res = [0,0];
    for (let p of keyinput) {
        switch(p){
            case 'left': if (-res[0] < board[0]/2-1) res[0]--; break;
            case 'right': if (res[0] < board[0]/2-1) res[0]++; break;
            case 'up': if (res[1] < board[1]/2-1) res[1]++; break;
            case 'down': if (-res[1] < board[1]/2-1) res[1]--; break;
        }
    }
    return res;
}

📍 switch
주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case 문으로 이동, default 는 optional

switch ( 표현식 ){
	case 표현식 1:
		switch 문의 표현식과 표현식1이 일치될 경우 실행될 코드;
		break;
	case 표현식 2:
		switch 문의 표현식과 표현식2이 일치될 경우 실행될 코드;
		break;
	default:
		switch 문의 표현식과 일치하는 case 가 없을 때 실행될 코드;
}


🌿 로그인 성공?

🌱 문제 설명

머쓱이는 프로그래머스에 로그인하려고 합니다. 머쓱이가 입력한 아이디와 패스워드가 담긴 배열 id_pw와 회원들의 정보가 담긴 2차원 배열 db가 주어질 때, 다음과 같이 로그인 성공, 실패에 따른 메시지를 return하도록 solution 함수를 완성해주세요.

아이디와 비밀번호가 모두 일치하는 회원정보가 있으면 "login"을 return합니다.
로그인이 실패했을 때 아이디가 일치하는 회원이 없다면 “fail”를, 아이디는 일치하지만 비밀번호가 일치하는 회원이 없다면 “wrong pw”를 return 합니다.

🌱 제한 사항

  • 회원들의 아이디는 문자열입니다.
  • 회원들의 아이디는 알파벳 소문자와 숫자로만 이루어져 있습니다.
  • 회원들의 패스워드는 숫자로 구성된 문자열입니다.
  • 회원들의 비밀번호는 같을 수 있지만 아이디는 같을 수 없습니다.
  • id_pw의 길이는 2입니다.
  • id_pw와 db의 원소는 [아이디, 패스워드] 형태입니다.
  • 1 ≤ 아이디의 길이 ≤ 15
  • 1 ≤ 비밀번호의 길이 ≤ 6
  • 1 ≤ db의 길이 ≤ 10
  • db의 원소의 길이는 2입니다.

🌱 입출력 예

id_pwdbresult
["meosseugi", "1234"][["rardss", "123"], ["yyoom", "1234"], ["meosseugi", "1234"]]"login"
["programmer01", "15789"][["programmer02", "111111"], ["programmer00", "134"], ["programmer01", "1145"]]"wrong pw"
["rabbit04", "98761"][["jaja11", "98761"], ["krong0313", "29440"], ["rabbit00", "111333"]]"fail"

🌱 내 코드

const solution = (id_pw, db) => {
  // 구조 분해 할당
  const [id, pw] = id_pw;
  
  for( let i = 0; i < db.length; i ++ ){
    if( id === db[i][0] && pw === db[i][1]) return 'login';
    else if( id === db[i][0] && pw !== db[i][1]) return 'wrong pw';
  }
  return 'fail'
}

🌱 다른 사람 풀이

function solution(id_pw, db) {
    const [ userId, userPw ] = id_pw;
        //for 문 안에도 구조분해 할당을 활용 !!
    for (const [ dbId, dbPw ] of db) {
        if (userId === dbId && userPw === dbPw) return "login";
        else if (userId === dbId && userPw !== dbPw) return "wrong pw";
    }
    return "fail";
}

// map 활용 🌸🌸🌸
function solution(id_pw, db) {
  const [id, pw] = id_pw;
  const map = new Map(db);
  return map.has(id) ? (map.get(id) === pw ? 'login' : 'wrong pw') : 'fail';
}

📍 arr.map()

  • 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출하고 이 콜백 함수의 반환값들로 구성된 새로운 배열을 반환( 원본 배열 : 반환 배열 = 1 : 1 매핑 )
  • 원본 배열 변경 X

📍 .has()
객체에 특정 요소가 있는지 확인하여 불리언 값 반환

📍 .get(key)
반환값: 명시된 키와 연관된 요소, value 혹은 Map 객체에서 해당 키를 찾을 수 없는 경우 undefined
key: Map 객체에서 반환받을 요소의 키



🌿 유한소수 판별하기

🌱 문제 설명

소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.

🌱 제한 사항

  • a, b는 정수
  • 0 < a ≤ 1,000
  • 0 < b ≤ 1,000

🌱 입출력 예

abresult
7201
11221
12212

🌱 내 코드

const solution = (a, b) => {
  let dividerB = [];
  
  for( let i = a; i >= 1; i --){
    if( a % i === 0 && b % i === 0 ){
      a = a / i;
      b = b / i;
    }
  }

  for( let i = 2; i <= b; i++ ){
    if( b % i === 0 ){
      i % 2 !== 0 && i %5 !== 0 ? dividerB.push(i) : '';
      b = b / i;
    }
  }
  
  const answer = [...new Set(dividerB)]
  
  return answer.length !== 0 ? 2 : 1
}

🌱 다른 사람 풀이

function solution(a, b) {
    let n = 1;
    for (let i = 1; i <= Math.min(a,b); i++) {
        if (a%i===0 && b%i===0) n = i;
    }

    b/=n;
    while (b%2===0) b/=2;
    while (b%5===0) b/=5;

    return b === 1 ? 1 : 2;   
}

function solution(a, b) {
    return Number((a/b).toFixed(10)) == a/b ? 1 : 2
}

📍 numObj.toFixed([digits]);

  • 반환값: 고정 소수점 표기법을 사용하여 나타낸 수를 문자열로 바꾼 값
  • digits(optional): 소수점 뒤에 나타날 자릿수. 0 이상 20 이하의 값을 사용할 수 있으며, 구현체에 따라 더 넓은 범위의 값을 지원 가능. 생략시 0

🌿 특이한 정렬

🌱 문제 설명

정수 n을 기준으로 n과 가까운 수부터 정렬하려고 합니다. 이때 n으로부터의 거리가 같다면 더 큰 수를 앞에 오도록 배치합니다. 정수가 담긴 배열 numlist와 정수 n이 주어질 때 numlist의 원소를 n으로부터 가까운 순서대로 정렬한 배열을 return하도록 solution 함수를 완성해주세요.

🌱 제한 사항

  • 1 ≤ n ≤ 10,000
  • 1 ≤ numlist의 원소 ≤ 10,000
  • 1 ≤ numlist의 길이 ≤ 100
  • numlist는 중복된 원소를 갖지 않습니다.

🌱 입출력 예

numlistnresult
[1, 2, 3, 4, 5, 6]4[4, 5, 3, 6, 2, 1]
[10000,20,36,47,40,6,10,7000]30[36, 40, 20, 47, 10, 6, 7000, 10000]

🌱 내 코드

const solution = (numlist, n) => {
  let differObj = {};
  let resultObj = {};
  
  numlist.map(el => differObj[el] = Math.abs(n - el));
  const rank = [...new Set(Object.values(differObj))].sort((a, b) => a - b);
  
  rank.map(el => {
    let nums = [];
    
    for( key in differObj ){  
      if( el === differObj[key] ){
        nums.push(parseInt(key));
        resultObj[el] = nums.sort((a, b) => b - a);
      }
    }
  })
  
  const result = Object.values(resultObj)
  
  return result.flat()
}

🌱 다른 사람 풀이

function solution(numlist, n) {
  return numlist.sort((a, b) => Math.abs(a - n) - Math.abs(b - n) || b - a);
}

📍 arr.sort([compareFunction])

  • compareFunction(Optional)
    정렬 순서를 정의하는 함수. 생략 시 배열은 오름차순 정렬
  • 배열의 요소를 정렬하여 정렬된 배열을 반환, 기본값: 오름차순( ascending )
  • 문자열 오름차순: string.sort() / 숫자 오름차순: number.sort((a, b) => a - b)
  • arr.sort((a, b) => diff1 || diff2)
    : diff 1 이 해당할 경우 diff 1 기준 정렬, 해당하지 않을 경우 diff 2 기준 정렬


🌿 다항식 더하기

🌱 문제 설명

한 개 이상의 항의 합으로 이루어진 식을 다항식이라고 합니다. 다항식을 계산할 때는 동류항끼리 계산해 정리합니다. 덧셈으로 이루어진 다항식 polynomial이 매개변수로 주어질 때, 동류항끼리 더한 결괏값을 문자열로 return 하도록 solution 함수를 완성해보세요. 같은 식이라면 가장 짧은 수식을 return 합니다.

🌱 제한 사항

  • 0 < polynomial에 있는 수 < 100
  • polynomial에 변수는 'x'만 존재합니다.
  • polynomial은 양의 정수, 공백, ‘x’, ‘+'로 이루어져 있습니다.
  • 항과 연산기호 사이에는 항상 공백이 존재합니다.
  • 공백은 연속되지 않으며 시작이나 끝에는 공백이 없습니다.
  • 하나의 항에서 변수가 숫자 앞에 오는 경우는 없습니다.
  • " + 3xx + + x7 + "와 같은 잘못된 입력은 주어지지 않습니다.
  • 0으로 시작하는 수는 없습니다.
  • 문자와 숫자 사이의 곱하기는 생략합니다.
  • polynomial에는 일차 항과 상수항만 존재합니다.
  • 계수 1은 생략합니다.
  • 결괏값에 상수항은 마지막에 둡니다.
  • 0 < polynomial의 길이 < 50

🌱 입출력 예

polynomialresult
"3x + 7 + x""4x + 7"
"x + x + x""3x"

🌱 내 코드

const solution = (polynomial) => {
  const arr = polynomial.split(" ");
  let xNum = 0;
  let num = 0;
  let result = '';

  for( let i = 0; i < arr.length; i ++){
    if( arr[i].split('').includes('x') && arr[i].length > 1) xNum += parseInt(arr[i].replace('x', ''));
    if( arr[i].split('').includes('x') && arr[i].length === 1) xNum += 1;
    if( isNaN(arr[i]) === false ) num += parseInt(arr[i]);
  }
  
  const x = () => {
    if(xNum === 0 ) return '';
    if(xNum === 1 ) return 'x';
    if(xNum > 1 ) return `${xNum}x`
  }
  
  const number = () => {
    if( num === 0 ) return '';
    if( num > 0 ) return `${num}`
  }
  
  return x() !== '' && number() !== '' ? `${x()} + ${number()}` : x() !== '' ? `${x()}` : `${number()}`;
}

🌱 다른 사람 풀이

function solution(polynomial) {
    const arr = polynomial.split(" + ");
    const xNum = arr
      .filter(n => n.includes("x"))
      .map(n => n.replace('x', '') || '1')
      .reduce((acc, cur) => acc + parseInt(cur, 10), 0);
    const num = arr
  	  .filter(n => !isNaN(n))
      .reduce((acc, cur) => acc + parseInt(cur, 10), 0); // cur, 10: 십진법 의미

    let answer = [];
    if(xNum) answer.push(`${xNum === 1 ? "" : xNum}x`);
    if(num) answer.push(num);

    return answer.join(" + ");
}

🌸 Number.parseInt(string, radix)

  • string: 파싱할 값. 문자열이 아닐 경우 ToString 추상 연산을 사용해 문자열로 변환. 문자열의 선행 공백은 무시.
  • radix(Optional): string의 진수를 나타내는 2부터 36까지의 정수
    ( radix를 생략하거나 0을 지정한 경우, string이 0x 또는 0X로 시작하는 경우 16을 지정한 것으로 취급하고, 그 외의 경우 10으로 취급한다 )


🌿 최빈값 구하기

🌱 문제 설명

최빈값은 주어진 값 중에서 가장 자주 나오는 값을 의미합니다. 정수 배열 array가 매개변수로 주어질 때, 최빈값을 return 하도록 solution 함수를 완성해보세요. 최빈값이 여러 개면 -1을 return 합니다.

🌱 제한 사항

  • 0 < array의 길이 < 100
  • 0 ≤ array의 원소 < 1000

🌱 입출력 예

arrayresult
[1, 2, 3, 3, 3, 4]3
[1, 1, 2, 2]-1
[1]1

🌱 내 코드

const solution = (array) => {
  let frequentNums = {};
  let frequentNum = [];
  
  array.forEach(el => {
    frequentNums[el] ?  frequentNums[el] ++ : frequentNums[el] = 1
  });
  
  for( key in frequentNums ){
    if( frequentNums[key] === Math.max(...Object.values(frequentNums)) ) frequentNum.push(key)
  }
  
  return frequentNum.length === 1 ? parseInt(frequentNum) : -1
}

🌸 객체를 활용해 같은 빈도를 가진 숫자를 찾는다 !


0개의 댓글