코딩 공부/코딩테스트

자바스크립트 코딩테스트 입문 (23)

천서리 2023. 6. 7. 18:58
QUOTE THE DAY

“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”

- 이글슨 (Eagleson)
반응형

코딩테스트 입문 Day 23 배열, 정렬, 문자열

출처 : https://programmers.co.kr/

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


특이한 정렬

문제

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

 

제한사항

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

 

입출력 예

numlist n result
[1, 2, 3, 4, 5, 6] 4 [4, 5, 3, 6, 2, 1]
[10000,20,36,47,40,6,10,7000] 3 [36, 40, 20, 47, 10, 6, 7000, 10000]

 

입출력 예 설명

 

입출력 예 #1

  • 4에서 가까운 순으로 [4, 5, 3, 6, 2, 1]을 return합니다.
  • 3과 5는 거리가 같으므로 더 큰 5가 앞에 와야 합니다.
  • 2와 6은 거리가 같으므로 더 큰 6이 앞에 와야 합니다.

입출력 예 #2

  • 30에서 가까운 순으로 [36, 40, 20, 47, 10, 6, 7000, 10000]을 return합니다.
  • 20과 40은 거리가 같으므로 더 큰 40이 앞에 와야 합니다.

 

solution.js

function solution(numlist, n) {
  const distances = numlist.map((num) => [Math.abs(num - n), num]);
  
  distances.sort((a, b) => a[0] - b[0]);
  
  distances.sort((a, b) => {
    if (a[0] === b[0]) {
      return b[1] - a[1];
    }
    return a[0] - b[0];
  });
  
  const sortedNumlist = distances.map((pair) => pair[1]);
  return sortedNumlist;
}
  1. numlist의 각 원소와 n 사이의 거리와 원소를 쌍으로 묶어 distances 배열에 저장합니다. 이를 위해 map 함수를 사용하며, distances 배열의 각 요소는 [거리, 원소] 형태의 배열입니다.
  2. distances 배열을 거리를 기준으로 오름차순으로 정렬합니다. sort 함수를 사용하며, 정렬에는 비교 함수가 필요한데, a[0] - b[0]를 반환하여 거리를 비교합니다.
  3. 거리가 같은 경우, 원소를 비교하여 더 큰 수가 앞에 오도록 정렬합니다. 이를 위해 sort 함수를 다시 사용하며, 비교 함수는 다음과 같이 작성됩니다:
    • 만약 a[0]과 b[0]가 같다면, b[1] - a[1]를 반환하여 원소를 비교합니다. 이로써 거리가 같을 경우에는 더 큰 수가 앞에 오도록 정렬됩니다.
    • 그렇지 않은 경우, 앞서 정렬한 거리를 유지합니다.
  4. 정렬된 원소들을 sortedNumlist 배열에 담아 반환합니다. 이를 위해 map 함수를 사용하여 distances 배열에서 원소만 추출합니다.

등수 매기기

문제

영어 점수와 수학 점수의 평균 점수를 기준으로 학생들의 등수를 매기려고 합니다. 영어 점수와 수학 점수를 담은 2차원 정수 배열 score가 주어질 때, 영어 점수와 수학 점수의 평균을 기준으로 매긴 등수를 담은 배열을 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 0 ≤ score[0], score[1] ≤ 100
  • 1 ≤ score의 길이 ≤ 10
  • score의 원소 길이는 2입니다.
  • score는 중복된 원소를 갖지 않습니다.

 

입출력 예

score result
[[80, 70], [90, 50], [40, 70], [50, 80]] [1, 2, 4, 3]
[[80, 70], [70, 80], [30, 50], [90, 100], [100, 90], [100, 100], [10, 30]] [4, 4, 6, 2, 2, 1, 7]

 

입출력 예 설명

 

입출력 예 #1

  • 평균은 각각 75, 70, 55, 65 이므로 등수를 매겨 [1, 2, 4, 3]을 return합니다.

입출력 예 #2

  • 평균은 각각 75, 75, 40, 95, 95, 100, 20 이므로 [4, 4, 6, 2, 2, 1, 7] 을 return합니다.
  • 공동 2등이 두 명, 공동 4등이 2명 이므로 3등과 5등은 없습니다.

 

solution.js

function solution(score) {
  const averages = score.map((s, idx) => [((s[0] + s[1]) / 2), idx]);
  
  averages.sort((a, b) => b[0] - a[0]);
  
  const result = [];
  let rank = 1;
  for (let i = 0; i < averages.length; i++) {
    if (i > 0 && averages[i][0] < averages[i - 1][0]) {
      rank = i + 1;
    }
    result[averages[i][1]] = rank;
  }
  
  return result;
}
  1. score 배열의 각 요소는 [과목1 점수, 과목2 점수] 형태로 구성되어 있습니다. 이를 기반으로 각 학생의 평균 점수와 인덱스를 쌍으로 묶어 averages 배열에 저장합니다. map 함수를 사용하여 각 요소를 [평균 점수, 인덱스] 형태의 배열로 변환합니다.
  2. averages 배열을 평균 점수를 기준으로 내림차순으로 정렬합니다. sort 함수를 사용하며, 비교 함수는 b[0] - a[0]를 반환하여 평균 점수를 비교합니다.
  3. 등수를 매기면서 결과 배열에 등수를 저장합니다. 빈 배열인 result를 초기화하고, rank 변수를 1로 초기화합니다. 반복문을 통해 averages 배열을 순회하면서 등수를 계산하고 result 배열에 저장합니다.
    • 만약 현재 요소의 평균 점수가 바로 이전 요소의 평균 점수보다 작다면, rank를 현재 인덱스에 1을 더한 값으로 업데이트합니다. 이는 이전 학생들과 평균 점수가 다르므로 등수를 증가시킵니다.
    • result 배열의 인덱스로는 해당 학생의 인덱스를 사용하며, 평균 점수가 높은 학생부터 순서대로 등수가 저장됩니다.
  4. 최종적으로 result 배열을 반환합니다. 이 배열은 각 학생의 등수가 저장되어 있습니다.

옹알이 (1)

문제

머쓱이는 태어난 지 6개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음을 최대 한 번씩 사용해 조합한(이어 붙인) 발음밖에 하지 못합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return하도록 solution 함수를 완성해주세요.

 

제한사항 

  • 1 ≤ babbling의 길이 ≤ 100
  • 1 ≤ babbling[i]의 길이 ≤ 15
  • babbling의 각 문자열에서 "aya", "ye", "woo", "ma"는 각각 최대 한 번씩만 등장합니다.
    • 즉, 각 문자열의 가능한 모든 부분 문자열 중에서 "aya", "ye", "woo", "ma"가 한 번씩만 등장합니다.
  • 문자열은 알파벳 소문자로만 이루어져 있습니다.

 

입출력 예

babbling result
["aya", "yee", "u", "maa", "wyeoo"] 1
["ayaye", "uuuma", "ye", "yemawoo", "ayaa"] 3

 

입출력 예 설명

 

입출력 예 #1

  • ["aya", "yee", "u", "maa", "wyeoo"]에서 발음할 수 있는 것은 "aya"뿐입니다. 따라서 1을 return합니다.

입출력 예 #2

  • ["ayaye", "uuuma", "ye", "yemawoo", "ayaa"]에서 발음할 수 있는 것은 "aya" + "ye" = "ayaye", "ye", "ye" + "ma" + "woo" = "yemawoo"로 3개입니다. 따라서 3을 return합니다.

유의 사항

  • 네 가지를 붙여 만들 수 있는 발음 이외에는 어떤 발음도 할 수 없는 것으로 규정합니다. 예를 들어 "woowo"는 "woo"는 발음할 수 있지만 "wo"를 발음할 수 없기 때문에 할 수 없는 발음입니다.

 

solution.js

function solution(babbling) {
  var answer = 0;
  const regex = /^(aya|ye|woo|ma)+$/;

  babbling.forEach(word => {
    if (regex.test(word)) answer++;  
  })

  return answer;
}
  1. answer 변수를 0으로 초기화합니다. 이 변수는 유효한 단어의 개수를 세기 위해 사용됩니다.
  2. 정규표현식 regex를 정의합니다. 이 정규표현식은 문자열이 "aya", "ye", "woo", "ma" 중 하나의 단어로 이루어져 있는지를 검사합니다. ^는 문자열의 시작을 의미하며, (aya|ye|woo|ma)는 "aya", "ye", "woo", "ma" 중 하나의 패턴을 의미합니다. +는 해당 패턴이 하나 이상 반복되는 것을 의미하며, $는 문자열의 끝을 의미합니다.
  3. babbling 배열을 순회하면서 각 단어를 검사합니다. forEach 메서드를 사용하여 배열의 각 요소에 대해 반복합니다.
  4. 각 단어에 대해 정규표현식 regex를 사용하여 검사합니다. test 메서드를 사용하여 정규표현식과 단어를 비교하고, 매칭되면 조건문이 실행됩니다.
  5. 조건문 내부에서 answer 변수를 증가시킵니다. 이는 유효한 단어를 발견했을 때만 카운트하기 위한 것입니다.
  6. 반복이 끝나면 최종적으로 answer 값을 반환합니다. 이 값은 유효한 단어의 개수입니다.

로그인 성공?

문제

머쓱이는 프로그래머스에 로그인하려고 합니다. 머쓱이가 입력한 아이디와 패스워드가 담긴 배열 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_pw db result
["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"

 

입출력 예 설명

 

입출력 예 #1

  • db에 같은 정보의 계정이 있으므로 "login"을 return합니다.

입출력 예 #2

  • db에 아이디는 같지만 패스워드가 다른 계정이 있으므로 "wrong pw"를 return합니다.

입출력 예 #3

  • db에 아이디가 맞는 계정이 없으므로 "fail"을 return합니다.

 

solution.js

function solution(id_pw, db) {
  const [inputId, inputPw] = id_pw;
  
  let loginResult = "fail";
  let idMatch = false;
  
  for (let i = 0; i < db.length; i++) {
    const [dbId, dbPw] = db[i];
    
    if (dbId === inputId) {
      idMatch = true;
      
      if (dbPw === inputPw) {
        loginResult = "login";
        break;
      } else {
        loginResult = "wrong pw";
      }
    }
  }
  
  if (!idMatch) {
    loginResult = "fail";
  }
  
  return loginResult;
}
  1. id_pw 배열에서 첫 번째 요소를 inputId 변수에, 두 번째 요소를 inputPw 변수에 할당합니다. 이를 위해 배열 비구조화 할당을 사용합니다.
  2. loginResult 변수를 "fail"로 초기화합니다. 이 변수는 로그인 결과를 나타내는 문자열입니다. idMatch 변수를 false로 초기화합니다. 이 변수는 입력된 아이디와 일치하는 데이터베이스의 아이디가 있는지 여부를 나타내는 불리언 값입니다.
  3. 반복문을 통해 db 배열을 순회합니다. for 문을 사용하며, 반복문 변수 i는 0부터 db 배열의 길이보다 작을 때까지 증가합니다.
  4. 각 반복마다 db 배열의 요소를 [dbId, dbPw] 변수에 할당합니다. 이를 위해 배열 비구조화 할당을 사용합니다.
  5. 입력된 아이디 inputId와 데이터베이스의 아이디 dbId를 비교합니다. 만약 일치한다면, idMatch 변수를 true로 설정합니다. 이는 입력된 아이디와 일치하는 데이터베이스의 아이디가 있는 경우를 나타냅니다.
  6. 아이디가 일치하는 경우, 입력된 비밀번호 inputPw와 데이터베이스의 비밀번호 dbPw를 비교합니다. 비밀번호가 일치한다면, loginResult 변수를 "login"으로 설정하고 반복문을 종료합니다. 비밀번호가 일치하지 않는 경우, loginResult 변수를 "wrong pw"로 설정합니다.
  7. 반복문이 끝난 후, idMatch가 여전히 false라면 입력된 아이디와 일치하는 데이터베이스의 아이디가 없는 경우입니다. 이 경우 loginResult 변수를 "fail"로 설정합니다.
  8. 최종적으로 loginResult 값을 반환합니다. 이 값은 로그인 결과를 나타내는 문자열입니다.

즉, 이 함수는 입력된 아이디와 비밀번호를 데이터베이스의 아이디와 비밀번호와 비교하여 로그인 결과를 반환합니다. 로그인 성공 시 "login", 비밀번호가 틀렸을 때 "wrong pw", 입력된 아이디와 일치하는 데이터베이스의 아이디가 없을 때 "fail"을 반환합니다.

반응형
Adventure Time - BMO