코딩테스트/프로그래머스
[프로그래머스] 입문 Day 8 배열, 구현, 수학 (Javascript)
꼽파
2023. 12. 19. 13:41
배열 자르기
문제 설명
- 정수 배열 numbers와 정수 num1, num2가 매개변수로 주어질 때, numbers의 num1번 째 인덱스부터 num2번째 인덱스까지 자른 정수 배열을 return 하도록 solution 함수를 완성해보세요.
제한사항
- 2 ≤ numbers의 길이 ≤ 30
- 0 ≤ numbers의 원소 ≤ 1,000
- 0 ≤num1 < num2 < numbers의 길이
입출력 예
numbers | num1 | num2 | result |
[1, 2, 3, 4, 5] | 1 | 3 | [2, 3, 4] |
[1, 3, 5] | 1 | 2 | [3, 5] |
풀이 1
주어진 범위에 해당하는 원소들을 for 반복문으로 추출해서 새로운 배열에 추가
function solution(numbers, num1, num2) {
var answer = [];
// 배열 원소 자르기
for (i = num1; i <= num2; i++) {
answer.push(numbers[i])
}
return answer;
}
풀이 2
slice 메소드 이용
function solution(numbers, num1, num2) {
// num1부터 num2까지 (num2 + 1 미만)
return numbers.slice(num1, num2 + 1)
}
풀이 3
splice 메소드 이용
function solution(numbers, num1, num2) {
// 시작 인덱스, 추출할 요소 개수, (추가할 값)
// num1부터 num2까지 개수 = num2 - num1 + 1
return numbers.splice(num1, num2 - num1 + 1)
}
주의할 점
- 배열 자르기는 기본적으로 slice와 splice를 활용할 수 있음.
외계행성의 나이
문제 설명
- 우주여행을 하던 머쓱이는 엔진 고장으로 PROGRAMMERS-962 행성에 불시착하게 됐습니다. 입국심사에서 나이를 말해야 하는데, PROGRAMMERS-962 행성에서는 나이를 알파벳으로 말하고 있습니다. a는 0, b는 1, c는 2, ..., j는 9입니다. 예를 들어 23살은 cd, 51살은 fb로 표현합니다. 나이 age가 매개변수로 주어질 때 PROGRAMMER-962식 나이를 return하도록 solution 함수를 완성해주세요.
제한사항
- age는 자연수입니다.
- age ≤ 1,000
- PROGRAMMERS-962 행성은 알파벳 소문자만 사용합니다.
입출력 예
age | result |
23 | "cd" |
51 | "fb" |
100 | "baa" |
풀이 1
숫자의 각 자릿수를 map으로 인덱싱
function solution(age) {
var answer = '';
// map에 알파벳의 기호와 인덱스 쌍을 넣기
const alpha = "abcdefghijklmnopqrstuvwxyz";
const m = new Map();
for (i = 0; i < alpha.length; i++) {
m.set(i, alpha[i])
}
// age를 10으로 나눈 나머지를 저장
// 해당 나머지 값이 key(인덱스) 중 있으면 해당 value(알파벳) 반환
// value 값은 str에 넣기
while (age >= 1) {
const remainder = age % 10
if (m.has(remainder)) {
answer = m.get(remainder) + answer;
}
age = Math.floor(age / 10);
}
return answer;
}
function solution(age) {
var answer = '';
// map에 알파벳의 기호와 인덱스 쌍을 넣기
const alpha = "abcdefghij";
const m = new Map();
for (i = 0; i < alpha.length; i++) {
m.set(i, alpha[i])
}
// 각 숫자를 알파벳으로 매핑하여 answer에 추가
String(age).split("").forEach(digit => {
// 각 자리의 숫자를 정수로 변환하여 인덱스로 활용
const index = Number(digit);
// 매핑된 알파벳을 answer에 추가
answer += m.get(index);
});
return answer;
}
풀이 2
map과 join을 활용
function solution(age) {
// 각 숫자가 0부터 9까지 숫자에 해당되게끔
// a는 = "abcdefghij"라는 문자열에서 a의 인덱스값
return age
.toString() // "23"
.split("") // ["2", "3"]
.map((v) => "abcdefghij"[v]) // "2"는 "abcdefghij"[2] = c
.join(""); // "23" (문자열)
}
풀이 3
배열에 맞는 문자 출력
function solution(age) {
var alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
var answer = "";
age = age.toString();
// 한글자씩 for문으로 순회
// 배열에서 해당 숫자에 해당하는 알파벳 넣어주기
for(let i = 0; i < age.length; i++){
answer += alphabet[i];
}
return answer;
}
주의할 점
- 풀이1은 내가 푼 방법인데, map을 활용하긴 했지만 뭔가 복잡해보인다. 내가 풀었나 싶을 정도임.
- 문제는 이해하기 쉽지만 구현하는 것이 꽤 까다롭다.
진료순서 정하기
문제 설명
- 외과의사 머쓱이는 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다. 정수 배열 emergency가 매개변수로 주어질 때 응급도가 높은 순서대로 진료 순서를 정한 배열을 return하도록 solution 함수를 완성해주세요.
제한사항
- 중복된 원소는 없습니다.
- 1 ≤ emergency의 길이 ≤ 10
- 1 ≤ emergency의 원소 ≤ 100
입출력 예
emergency | result |
[3, 76, 24] | [3, 1, 2] |
[1, 2, 3, 4, 5, 6, 7] | [7, 6, 5, 4, 3, 2, 1] |
[30, 10, 23, 6, 100] | [2, 4, 3, 5, 1] |
풀이 1
Map을 통해 정렬된 배열의 각 원소와 해당 원소의 원래 인덱스를 매핑
function solution(emergency) {
var answer = []; // 정답을 반환할 배열
// emergency를 내림차순으로 정렬
// 주의 : const sorted_e = emergency.sort로 쓰면 emergency가 변경됨.
const sorted_e = [...emergency].sort((a, b) => (b - a)) // [ 76, 24, 3 ]
// 해당 배열의 인덱스를 추출하여 map에 원소, 인덱스 넣기
let m = new Map();
for (let i = 0; i < sorted_e.length; i++) {
m.set(sorted_e[i], i + 1)
}
// Map(3) { 76 => 1, 24 => 2, 3 => 3 }
// emergency 원소를 순회
// map의 키 값과 같다면 해당 value를 반환하도록 함
for (num of emergency) { // [3, 76, 24]
if (m.has(num)) {
answer.push(m.get(num))
}
}
return answer;
}
풀이 2
sort와 map을 활용한 간단한 풀이
function solution(emergency) {
var answer = []; // 정답을 반환할 배열
// emergency를 내림차순으로 정렬
// 주의 : const sorted_e = emergency.sort로 쓰면 emergency가 변경됨.
const sorted_e = emergency.slice().sort((a, b) => b - a);
// emergency 배열의 모든 원소는 sorted_e의 인덱스 값 + 1
return emergency.map(a => sorted_e.indexOf(a) + 1);
}
주의할 점
- 자료구조 map과 배열에 쓰는 메서드 map이 헷갈림.
- 자료구조와 메서드에 대한 이해가 부족해서 풀이가 복잡해지는 듯 싶음.
순서쌍의 개수
문제 설명
- 순서쌍이란 두 개의 숫자를 순서를 정하여 짝지어 나타낸 쌍으로 (a, b)로 표기합니다. 자연수 n이 매개변수로 주어질 때 두 숫자의 곱이 n인 자연수 순서쌍의 개수를 return하도록 solution 함수를 완성해주세요.
제한사항
- 1 ≤ n ≤ 1,000,000
입출력 예
n | result |
20 | 6 |
100 | 9 |
풀이 1
순서쌍의 개수를 구하라고 했으니, 약수의 개수를 출력하면 됨.
function solution(n) {
var count = 0; // 순서쌍의 개수
for (i = 1; i <= n; i++){
if (n % i == 0) {
count += 1
}
}
return count;
}
풀이 2
풀이 1과 원리가 같으나, 제곱근을 사용해서 확인해야할 범위를 줄임
function solution(n) {
let answer = 0;
// n의 제곱근까지만 순회함.
// 약수의 개수는 2개씩 증가하도록 함.
for (let i = 1; i < Math.sqrt(n); i++)
if (n % i === 0) answer += 2;
// 만약 완전제곱수인 경우는 (ex. 6 * 6 = 36) 약수의 개수에 1을 더함.
return Number.isInteger(Math.sqrt(n)) ? answer + 1 : answer;
}
어떤 수의 약수를 찾을 때 그 수의 제곱근보다 큰 약수를 찾을 필요가 없음.
ex. 36의 약수 : 1, 2, 3, 4, 6, 12, 36
여기서 6 * 6 = 36이므로 36의 제곱근인 6까지 찾으면 나머지 약수의 개수를 찾을 수 있음.
그러므로 특정 수의 제곱근까지만 for문으로 순회함.
주의할 점
- 순서쌍의 개수를 구하라고 해서 위처럼 약수의 개수를 출력하는 것이 가능했음.
- 만약 '순서쌍을 구하시오'라고 했으면?
순서쌍 구하기
function solution(n) {
let pairs = [];
for (let i = 1; i <= n; i++) {
if (n % i === 0) {
pairs.push([i, n / i]);
}
}
return pairs;
}
// Example
console.log(solution(20));
// [ [ 1, 20 ], [ 2, 10 ], [ 4, 5 ], [ 5, 4 ], [ 10, 2 ], [ 20, 1 ] ]
순서쌍 중에서 순서와 무관하게 값이 중복되는 것을 제외하고 싶은 경우
function solution(n) {
let pairs = [];
// for문으로 제곱근까지만 순회
for (let i = 1; i <= Math.sqrt(n); i++) {
if (n % i === 0) {
pairs.push([i, n / i]);
}
}
return pairs;
}
// Example
console.log(solution(20)); // [ [ 1, 20 ], [ 2, 10 ], [ 4, 5 ] ]
console.log(solution(36)); // [ [ 1, 36 ], [ 2, 18 ], [ 3, 12 ], [ 4, 9 ], [ 6, 6 ] ]
자바스크립트에서 (,)을 쓰면 튜플이 생성되는 게 아님.
소괄호 () 안에 ,를 사용하면 그냥 뒤의 값으로 평가됨.
function solution(n) {
let pairs = [];
for (let i = 1; i <= n; i++) {
if (n % i === 0) {
pairs.push((i, n / i)); // n / i 만 나옴
}
}
return pairs;
}
// Example
console.log(solution(20));
// [ 20, 10, 5, 4, 2, 1 ]
728x90