728x90

Q. 주어진 array를 주어진 size만큼 잘라서 sub array로 넣어라.

--- Examples
chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]]
chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5], 4) --> [[ 1, 2, 3, 4], [5]]
chunk([1, 2, 3, 4, 5], 10) --> [[ 1, 2, 3, 4, 5]]

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/blob/master/completed_exercises/chunk/index.js

😢 undefined 개념, 배열의 마지막 index를 지정하는 방법 그리고 slice를 활용하는 방법을 몰라서 많이 고민했다.

😊 Solution 1)
주어진 array 값을 for ... of를 통해 element로 하나씩 가져오고, 새로운 chunk array가 비어(undefined)있거나 size만큼 꽉차면 새로운 sub array를 push하고, 그게 아니라면 chunk array의 마지막 index sub array에 element를 push하여 해결한다.

Solution 2)
index를 size만큼 쌓아올리는 index 변수를 선언하여, slice(index, index + size); index += size; 를 while loop안에서 반복해준다. 그렇게하면 주어진 길이만큼 slice하여 sub array로 push할 수 있다.

✔ undefined 이용

!undefined는 true

✔ slice(begin, end)

시작부터 끝 전 index까지 array를 잘라준다.
(자세한 내용은 helper method 카테고리에서 확인 가능하다)

Full Code

function chunk(array, size) {
const chunked = [];
let index = 0;
 
while (index < array.length) {
chunked.push(array.slice(index, index + size));
index += size;
}
 
return chunked;
}
 
// function chunk(array, size) {
// const chunked = [];
//
// for (let element of array) {
// const last = chunked[chunked.length - 1];
//
// if (!last || last.length === size) {
// chunked.push([element]);
// } else {
// last.push(element);
// }
// }
//
// return chunked;
// }
728x90

https://www.acmicpc.net/problem/4344

Code

https://github.com/DasolPark/Algorithm_JavaScript/commit/54592b15a8664302e6d2c812440edabf9b417013

😢 5분 정도 고민하고, 코드로 하나씩 정리해 나가면서 금방 풀 수 있었던 문제

😊 전체 Test Case를 반복할 수 있는 for loop을 가장 바깥에서 돌리고, 중첩 첫 번째 for loop에서 점수를 모두 더해준 후 평균을 구한다. 그리고 중첩 두 번째 for loop에서 평균보다 높은 인원수를 구하고 비율을 계산해주고 출력한다.
평균을 어떻게 구할지, 평균을 넘는 인원은 몇명인지, 비율을 구하는 공식은 무엇인지 먼저 정리하고 풀어나가면 금방 해결할 수 있다.

Full Code

// 1st Solution
 
// For submit
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
 
// For local test
const input = [
'5',
'5 50 50 70 80 100',
'7 100 95 90 80 70 60 50',
'3 70 90 80',
'3 70 90 81',
'9 100 99 98 97 96 95 94 93 91'
];
 
const C = parseInt(input[0]);
 
for (let i = 1; i <= C; i++) {
const NAndGradeArr = input[i].trim().split(' ');
let totalGrade = 0;
let avg = 0;
let counter = 0;
let proportion = 0;
for (let j = 1; j <= parseInt(NAndGradeArr[0]); j++) {
totalGrade += parseInt(NAndGradeArr[j]);
}
 
avg = totalGrade / parseInt(NAndGradeArr[0]);
 
for (let k = 1; k <= parseInt(NAndGradeArr[0]); k++) {
if (parseInt(NAndGradeArr[k]) > avg) {
counter++;
}
}
 
proportion = (counter / parseInt(NAndGradeArr[0])) * 100;
console.log(proportion.toFixed(3) + '%');
}
// 비율 구하는 공식 : 비교량 / 기준량 * 100 (2 / 5 * 100)
 
// other solution (좀 특이해서 참고해보았다)
 
// var a = require('fs')
// .readFileSync('/dev/stdin')
// .toString()
// .match(/[^\r\n]+/g)
// .slice(1),
// b = a.map(function(x) {
// return x.split(' ');
// }),
// c = [],
// e = [];
// for (var i = 0; i <= b.length - 1; i++) {
// c.push(
// b[i].reduce(function(pre, cur) {
// return parseInt(pre) + parseInt(cur);
// }) /
// b[i][0] -
// 1
// );
 
// e.push(
// b[i].slice(1).filter(function(x) {
// return x > c[i];
// })
// );
 
// console.log(((e[i].length / b[i][0]) * 100).toFixed(3) + '%');
// }
728x90

✨ 문자 또는 숫자를 순서대로 정렬할 때 사용하는 helper method

(e.g., strArr.sort() or numArr.sort((a, b) => a - b)) 문자를 sort 할 때, 10이 넘어가는 숫자를 sort할 때, 왼쪽처럼 사용법이 다르다.
Numbers는 Strings으로 변환되기 때문에, Unicode order에 따라 80이 9보다 앞에 위치한다.

💻Example Code

const strArr = [ 'c', 'b', 'a' ];
const numArr = [ 3, 33, 2, 22, 1, 11 ];

console.log( strArr.sort() );
console.log( numArr.sort() ); // For Example
console.log( numArr.sort((a,b) => a - b) );

실행 결과( 2번째 결과는 Number를 그냥 sort() 했을 때 결과이다)

😋 Anagrams(철자 순서를 바꾼 말) Algorithm에서 유용하게 사용 가능하며, 다양한 상황에서 사용 가능하다.

✔ sort((a, b) => a - b)로 숫자가 정렬되는 것을 Test 해보자

const numArr = [ 3, 2, 1, 11, 22 ,33 ];

function compare(a, b) {
console.log('a:'+a);
console.log('b:'+b);
return a - b; }

a가 b보다 작아서 negative가 나오는 경우 a는 b보다 낮은 숫자의 index를 갖고, 0은 변화 없음, 0보다 크면 a는 b보다 높은 index를 갖게 되는 식으로 정렬된다. 아마 선택 정렬(Selection Sort)과 비슷한 방식이 아닐까 생각해본다.

👉 자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

 

Array.prototype.sort()

The sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

developer.mozilla.org

 

'JavaScript > Built-in Method etc.' 카테고리의 다른 글

String.prototype.replace()  (0) 2019.12.29
Object.keys() & Object.values()  (0) 2019.12.29
String.prototype.toLowerCase() & toUpperCase()  (0) 2019.12.28
Array.prototype.includes()  (0) 2019.12.26
Array.prototype.every()  (0) 2019.12.24
728x90

Q. 주어진 2개의 String이 서로 Anagrams인지 확인하라 (Anagram - 철자 순서만 다르고, 같은 개수의 알파벳)
(단, 대문자, 공백 그리고 구두점은 제외한다)

--- Examples
anagrams('rail safety', 'fairy tales') --> True
anagrams('RAIL! SAFETY!', 'fairy tales') --> True
anagrams('Hi there', 'Bye there') --> False

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/2cf4631c1d09e038f0bf9827b710812d078c4023

😢 RegExp, Object.keys().length 스킬을 사용하게 될지 예상하기 힘들었다.

😊 Solution 1)
Map을 생성해주는 function을 만들고, Object.keys().length를 이용해 사용된 철자의 종류가 동일한지 확인하고, for ... in을 이용해 사용된 철자의 개수가 동일한지 확인하여 문제를 해결한다.
Solution 2)
순서를 정렬하는 function을 만들고, 그 결과가 서로 같은지 확인하는 방법을 이용해 문제를 해결한다.

위의 2가지 방법에서 가장 중요한 것은 replace(/[^\w]/g, '')을 이용해 대문자, 공백 그리고 구두점을 제거해주는 것이다.

✔ replace(/[^\w]/g, '')

알파벳 외 문자를 제거한다.

✔ toLowerCase()

대문자를 소문자로 바꿔준다

✔ split('')

String을 separator기준으로 Array로 나눠서 저장해준다

✔ sort()

Array의 순서를 UTF-16 기준으로 정렬해준다

✔ join()

Array를 separator기준으로 String으로 합쳐준다

✔ Object.keys()

Object의 key만 Array 형식으로 받아볼 수 있다. 따라서 옆에 .length를 사용해 길이를 받아볼 수 있다

 

Full Code

function anagrams(stringA, stringB) {
return cleanString(stringA) === cleanString(stringB);
}
 
function cleanString(str) {
return str
.replace(/[^\w]/g, '')
.toLowerCase()
.split('')
.sort()
.join('');
}
 
// function anagrams(stringA, stringB) {
// const aCharMap = buildCharMap(stringA);
// const bCharMap = buildCharMap(stringB);
//
// if (Object.keys(aCharMap).length !== Object.keys(bCharMap).length) {
// return false;
// }
//
// for (let char in aCharMap) {
// if (aCharMap[char] !== bCharMap[char]) {
// return false;
// }
// }
//
// return true;
// }
//
// function buildCharMap(str) {
// const charMap = {};
//
// for (let char of str.replace(/[^\w]/g, '').toLowerCase()) {
// charMap[char] = charMap[char] + 1 || 1;
// }
//
// return charMap;
// }
728x90

https://www.acmicpc.net/problem/8958

Code

https://github.com/DasolPark/Algorithm_JavaScript/commit/f1fa3910361f1978f2443cba1df1b851b055da38

😢 이번 문제는 꽤나 고민을 했다. 첫 풀이 때는, 중첩 for loop을 2번이나 써서 '1. 점수를 얻어내고 2. 점수를 계산하여' 출력 하였다. 
하지만 2번째 풀이에서(위의 코드)는 중첩 for loop 한 번으로 점수를 얻음과 동시에 출력하였다. 중첩 for loop을 한 개나 없앴다는 것에 만족한다. 대략 30분 정도 걸렸던 것 같다. 혼자 못 풀 문제는 아니었다.

😊 첫 번째 for {}안에 점수를 표시할 counter와 점수를 더할 eachSum을 선언하였다. 그리고 두 번째 for {}안에서 배열의 해당 index가 O라면 counter를 증가하며 eachSum에 계속 더하였고, X라면 counter가 다시 1로 시작하도록 초기화하였다.
두 번째 for {}이 끝난 후 한 줄의 OX점수를 합한 eachSum을 출력해주었다.

Full Code

 

// 1st Solution (submitted)
 
// const fs = require('fs');
// const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
 
// For local test
 
const input = [
'5',
'OOXXOXXOOO',
'OOXXOOXXOO',
'OXOXOXOXOXOXOX',
'OOOOOOOOOO',
'OOOOXOOOOXOOOOX'
];
 
// 2nd Solution
 
const N = parseInt(input[0]);
 
for (let i = 1; i <= N; i++) {
let counter = 1;
let eachSum = 0;
for (let j = 0; j < input[i].length; j++) {
if (input[i][j] === 'O') {
eachSum += counter;
counter++;
} else {
counter = 1;
}
}
console.log(eachSum);
}
 
// 1st Solution
 
// const N = parseInt(input[0]);
// const result = [];
// let idx = 0;
 
// for (let i = 1; i <= N; i++) {
// let counter = 0;
// for (let j = 0; j < input[i].length; j++) {
// if (input[i][j] === 'O') {
// counter++;
// result.push(counter);
// } else {
// counter = 0;
// result.push(counter);
// }
// }
// }
 
// for (let i = 1; i <= N; i++) {
// let eachSum = 0;
// for (let j = 0; j < input[i].length; j++) {
// eachSum += result[idx];
// idx++;
// }
// console.log(eachSum);
// }
 
// other solution
 
// const N = parseInt(input[0]);
 
// for (let i = 0; i < N; i++) {
// let eachO = String(input[i + 1]).split('X');
// let sum = 0;
// for (let j = 0; j < eachO.length; j++) {
// for (let k = 1; k <= String(eachO[j]).length; k++) {
// sum += k;
// }
// }
// console.log(sum);
// }
728x90

Q. 주어진 Number가 3의 배수일 때는 'fizz', 5의 배수일 때는 'buzz', 3과 5의 배수일 때는 'fizzbuzz'를 출력하라.
(그 외 경우는 숫자로 출력)

--- Example
fizzBuzz(5);
1
2
fizz
4
buzz

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/4bee15d5862145024c21049efb37aeddc7c4ebd0

😢 classic for loop, %연산, &&(and)연산, if else 제어문으로 쉽게 해결 가능하다.

😊 주어진 n까지 for문을 반복하고, 숫자가 증가할 때마다 if else 구문으로 배수를 파악하여 출력하면 된다.
if else구문으로 작성할 때는 해당 조건이 true일 때, 그 구문만 실행하고 다시 for문이 반복된다는 것을 명심하자.

✔ &&(and)연산

양쪽의 결과가 모두 true일 때, 결과는 true
(||(or)연산은 둘 중에 하나만 true여도, 결과는 true)

✔ %연산

나머지는 구하는 연산, 3%3의 결과는? 0(나머지가 없음)

Full Code

function fizzBuzz(n) {
for (let i = 1; i <= n; i++) {
// Is the number a multiple of 3 and 5?
if (i % 3 === 0 && i % 5 === 0) {
console.log('fizzbuzz');
// Is the number a multiple of 3?
} else if (i % 3 === 0) {
console.log('fizz');
// Is the number a multiple of 5?
} else if (i % 5 === 0) {
console.log('buzz');
} else {
console.log(i);
}
}
}
728x90

Q. 주어진 string에서 가장 많이 쓰인 char를 찾아서 출력하라.

--- Examples
maxChar("abcccccccd") === "c"
maxChar("apple 1231111") === "1"

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/8db5e8446c13282c8bc305ef53d0ccbedf9bd607

😢 Object를 만드는 방법에 익숙하지 않았는데, 이번 기회를 통해 익숙해질 수 있었다.
마찬가지로, for ... of와 for ... in을 사용하는 것도 익숙해질 수 있었다.

😊 Map(Object)을 만들어서 각 문자(key)의 빈도수(value)를 저장하고, 최대값(max)을 구하여, 가장 많이 쓰인 문자(maxChar)를 출력하는 방식으로 해결하면 된다.

✔ object map

object는 key와 value를 가지고 있다. arr[1] = 'a'; 처럼 배열에 저장하듯 객체를 저장하면 된다.
charMap[char] = charMap[char] ? charMap[char] + 1 : 1;
charMap object에 해당 char가 있으면 +1, 없으면 1로 key와 value를 선언해준다.

✔ for ... of

for( let char of str ) {} 처럼 입력값으로 받은 str의 character를 순서대로 하나씩 가져와 loop을 실행하는 for loop이다.
classic for loop처럼 index를 하나하나 지정해줘야하는 번거로움을 없앨 수 있다.(오타 발생 사전 제거에 유용함)

✔ for ... in

for( let char in charMap ) {} 처럼 charMap object의 key를 순서대로 하나씩 가져와 loop을 실행하는 for loop이다.
객체(object)를 loop하고 싶을 때 사용할 수 있다.

 

Full Code

 

function maxChar(str) {
const charMap = {};
let max = 0;
let maxChar = '';
 
for (let char of str) {
if (charMap[char]) {
charMap[char]++;
} else {
charMap[char] = 1;
}
}
 
for (let char in charMap) {
if (charMap[char] > max) {
max = charMap[char];
maxChar = char;
}
}
 
return maxChar;
}
728x90

Q. 주어진 string의 회문 구조를 파악하고, 맞으면 true 틀리면 false를 return하라.

--- Examples
palindrome("abba") === true
palindrome("abcdefg") === false

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/efd69d6b976fab583958556518cf5b3162275d67
https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/efd69d6b976fab583958556518cf5b3162275d67

😢 reverse int and string에서 배웠던 Skill로도 충분했지만, 다른 방법을 적용해보고 싶었다.

😊 every()를 이용하여 주어진 string argument를 검사하는 방식을 배울 수 있었다.

✔ Array.prototype.every()

every() 괄호 안에 test function을 작성하여, 해당 array값을 이용해 test할 수 있다.
위의 소스코드에서는 char === str[str.length - i - 1]을 이용하여 맨 앞과 맨 뒤의 값을 하나씩 이동하며 비교하였다.
자세한 every() 사용법은 helper methods category에서 다루도록 하겠다.

Full Code

function palindrome(str) {
return str.split('').every((char, i) => {
return char === str[str.length - i - 1];
});
}
 
// function palindrome(str) {
// let reversed = str
// .split('')
// .reverse()
// .join();
// return str === reversed;
// }
728x90

Q. 주어진 integer를 정반대로 뒤바꾸고 return하라.

--- Examples
reverseInt(15) === 51
reverseInt(981) === 189
reverseInt(500) === 5
reverseInt(-15) === -51
reverseInt(-90) === -9

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/ccd99f2e87c5836d5e0b22793caf882e652d9529
https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/ccd99f2e87c5836d5e0b22793caf882e652d9529
https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/ccd99f2e87c5836d5e0b22793caf882e652d9529

😢 정반대로 바꾸는 것은 문제가 없었으나, 부호를 살리는 것과 다시 num type 으로 바꾸는 것에 대해서 어떻게 효율적으로 코드를 작성할 수 있을지 조금 고민을 했다.

😊 Math.sign()을 이용해 깔끔하게 부호를 살릴 수 있었고, Reverse String에서 쓰던 Skill들을 그대로 사용하였다.
그 외에 추가된 Skill은 toString(), parseInt()가 있다.

✔ Math.sign()

Math.sign()를 이용해 해당 변수의 부호를 알아내고 활용할 수 있다.
위의 소스코드에서 보면 알 수 있듯, arguments로 들어오는 n의 부호를 마지막에 곱해주어 해당 -(negative)를 다시 살려주었다.

✔ Number.prototype.toString()

처음에 들어오는 arguments가 number type이므로 reverse()를 이용할 것이라면 toString()으로 반드시 변환해줘야 한다.
그리고 reverse()를 사용하기 전에 split()사용하여 array로 반드시 변환해줘야 한다. Array.prototype.reverse()이기 때문이다.

✔ Global.parseInt()

string과 array를 이용해 number를 뒤바꾸어 주었으니, 최종값은 parseInt()를 이용해 number type으로 변환해야 한다.

Full Code

function reverseInt(n) {
let reversed = n
.toString()
.split('')
.reverse()
.join('');
return parseInt(reversed) * Math.sign(n);
}
 
// function reverseInt(n) {
// let rev = '';
 
// for (let num of n.toString()) {
// rev = num + rev;
// }
 
// return Math.sign(n) * parseInt(rev);
// }
 
// function reverseInt(n) {
// return (
// Math.sign(n) *
// parseInt(
// n
// .toString()
// .split('')
// .reduce((rev, num) => (rev = num + rev))
// )
// );
// }
728x90

Q. 주어진 string을 정반대로 뒤바꾸고 return하라.

--- Examples
reverse('apple') === 'leppa'
reverse('hello') === 'olleh'
reverse('Greetings!') === '!sgniteerG'

Code

https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/9cc55eac880eb89db3649ea8e440a311caa4ef48
https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/3437f358a612996ee0baa02a8ff2e1f5a414ef3c
https://github.com/DasolPark/Algorithm_DataStructure_JavaScript-Stephen-/commit/198f985e17d687765d99ee0bc31f739c587b4a50

😢 reverse() helper를 이용하여 쉽게 해결할 수 있지만, 다른 방법으로도 풀 수 있는 것이 중요하다.

😊 평소 자주 사용하지 않았던, for of loop와 reduce를 이용하여 쉽게 해결할 수 있었다.

 String.prototype.split()

split() 의 괄호 안에 separator를 지정하여 string을 array로 변환할 수 있다.

✔ Array.prototype.reverse()

method명 그대로 array의 순서를 정반대로 뒤바꿀 수 있다.
따라서 해당 값이 array가 아니라면, split('')을 이용해 array로 변경해주는 것이 중요하다.

Array.prototype.join()

join() 의 괄호 안에 separator를 지정하여 array를 string으로 변환할 수 있다.

Array.prototype.reduce()

reduce() 의 괄호 안에 reducer function을 작성하여 array 값을 다룰 수 있다. 
간단히 설명하자면, 첫 번째 arguments는 accumulator, 두 번째 arguments는 currentValue이며,
위의 3번째 소스코드처럼 rev에 char를 하나씩 계속 더하는 방식으로 결과를 도출해냈다.
자세한 내용은 helper methods category에서 다루도록 하겠다.

✔ for ... of

classic for loop 보다 fancy한 for loop이다.
for(let value of array){} 형식으로 사용하며, array의 첫 번째 값부터 마지막 값까지 순서대로 value에 전달한다.
평소 classic for loop을 이용하면 index 선언 순서가 헷갈리거나 오타가 발생할 수 있는데, 그것을 방지하는 것에 좋다.
다른 category에서 더 자세히 다루어 보겠다.

Full Code

function reverse(str) {
return str.split('').reduce((rev, char) => char + rev, '');
}
 
// function reverse(str) {
// return str
// .split('')
// .reverse()
// .join('');
// }
 
// function reverse(str) {
// let reversed = '';
 
// for (let character of str) {
// reversed = character + reversed;
// }
 
// return reversed;
// }

+ Recent posts