문제
말썽꾸러기 김코딩은 오늘도 장난을 치다가 조별 발표 순서가 담긴 통을 쏟고 말았습니다.
선생님께서는 미리 모든 발표 순서의 경우의 수를 저장해 놓았지만 김코딩의 버릇을 고치기 위해 문제를 내겠다고 말씀하셨습니다.
김코딩은 모든 조별 발표 순서에 대한 경우의 수를 차례대로 구한 뒤, 선생님께서 숫자를 말하면 그 순서에 맞는 경우의 수를 말해야 하고, 발표 순서를 말하면 이 발표순서가 몇번째 경우의 수인지를 대답해야 합니다.
총 학생의 수 N과 선생님이 말하는 k가 주어질 때, 김코딩이 정답을 말 할 수 있게 올바른 리턴 값을 구하세요.
모든 경우의 수가 담긴 배열은 번호가 작을수록 앞에 위치한다고 가정합니다.
ex) N = 3일경우, [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
주의사항
k가 Number 일 때, k번째 배열을 리턴합니다.
ex) n이 3이고 k가 3일 경우
모든 경우의 수를 2차원 배열에 담는다면 [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]이 되고,
반환하는 값은 [2, 3, 1]이 됩니다.
k가 Array일 때, 몇 번째인지를 리턴합니다. (0 <= index 입니다.) ex) n이 3이고 k가 [2, 3, 1]일 경우
모든 경우의 수를 2차원 배열에 담는다면 [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]이 되고,
반환하는 값은 3이 됩니다.
입출력 예시
let output = orderOfPresentation(3, 3);
console.log(output); // [2,3,1]
let output = orderOfPresentation(3, [2, 3, 1]);
console.log(output); // 3
code
function orderOfPresentation(n, k) {
const permutator = (inputArr) => {
let result = [];
const permute = (arr, m = []) => {
if (arr.length === 0) {
result.push(m)
} else {
for (let i = 0; i < arr.length; i++) {
let curr = arr.slice();
let next = curr.splice(i, 1);
permute(curr.slice(), m.concat(next))
}
}
}
permute(inputArr)
return result;
}
let arr = []
for (let i = 1; i <= n; i++) {
arr.push(i)
}
let result = permutator(arr)
if(Array.isArray(k)) {
return result.indexOfForArrays(k)
}
return result[k];
}
Array.prototype.indexOfForArrays = function(search) {
let searchJson = JSON.stringify(search);
let arrJson = this.map(JSON.stringify);
return arrJson.indexOf(searchJson);
};
문제
평범한 블랙잭 게임이 질린 김코딩은 박해커에게 게임룰을 변형하여 새로운 카드 놀이를 해 볼 것을 제안합니다. 새로운 룰은 다음과 같습니다.
카드를 여러장 받아 그 중 3장의 카드를 고르는데, 그 3장에 적힌 숫자의 합은 소수여야 한다. 받아든 카드로 만들 수 있는 소수의 개수는 몇 개인가?
주의사항
입출력 예시
let output = boringBlackjack([1, 2, 3, 4]);
console.log(output); // 1
let output = boringBlackjack([2, 3, 4, 8, 13]);
console.log(output); // 3
code
function boringBlackjack(cards) {
let count = 0;
for (let i = 0; i < cards.length; i++) {
for (let j = i+1; j < cards.length; j++) {
for (let k = j+1; k < cards.length; k++) {
if (check(cards[i] + cards[j] + cards[k])) {
count++;
}
}
}
}
return count;
}
}
// 소수 판별 함수
function isPrime (n) {
let len = parseInt(Math.sqrt(n));
for (let i = 2; i < len; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}
문제
오늘은 빼빼로 데이입니다. 한 회사의 팀장은 출근길에 아몬드 빼빼로 A 개와 누드 빼빼로 N 개를 구매하여 아침 일찍 출근길에 나섰습니다.
팀장은 자신보다 먼저 출근해있는 직원들에게 빼빼로를 모두 나누어 주려고 합니다. 단, 직원들이 서로 같은 개수의 빼빼로를 받지 못하면 시기 질투할 수 있으므로 직원들에게 같은 개수를 나누어 주어야 하며, 한 가지 종류의 빼빼로만 받는 경우가 없어야 합니다.
회사에 도착하기 전이기 때문에 이미 출근해 있는 직원들이 몇 명인지 모르는 상황입니다. 예를 들어, 팀장이 아몬드 빼빼로를 4개, 누드 빼빼로를 8개를 구매 했다면, 다음과 같이 세 가지 방법으로 나누어 줄 수 있습니다.
여러분이 직원 수에 따라 빼빼로를 나누어 주는 방법을 구하는 솔루션을 제공해 주세요.
출력
[빼빼로를 받게 되는 직원의 수, 나누어 주는 아몬드 빼빼로의 수, 나누어 주는 누드 빼빼로의 수]
입출력 예시
let A = 4;
let N = 8;
let output = divideChocolateStick(A, N);
console.log(output)
// [[1, 4, 8], [4, 1, 2], [2, 2, 4]] 또는,
// [[1, 4, 8], [2, 2, 4], [4, 1, 2]]
// 순서는 상관없습니다
i
가 최대공약수와 나누어 떨어지면 약수로 간주하고 값을 저장한다.i
를 나눴을 때, i가 아니라면 제곱근이 아닌 경우.
code
function divideChocolateStick(A, N) {
let result = [];
let check = gcd(Math.max(A, N), Math.min(A, N));
let len = parseInt(Math.sqrt(check));
for (let i = 1; i <= len; i++) {
if (check % i === 0) {
result.push(i, A / i, N / i);
// 제곱근 보다 작은 수
// 최대 공약수를 제곱근이 아닌 수로 나눠주면 제곱근 보다 큰 수를 구할 수 있다.
if (i !== check / i) {
let x = check / i;
result.push(x, A / x, N / x)
}
}
}
return result;
}
// 유클리드 호제법
function gcd (maxNum, minNum) {
return maxNum % minNum === 0 ? minNum : gcd(minNum, maxNum % minNum);
}
오늘 풀었던 조합과 최대공약수 문제는 그럭저럭 할만 하다고 느꼈다. 그러나 순열은 아직도 많이 어렵다 ㅜㅜ
내일은 이머시브 온 뒤로 첫 H.A 테스트 시험을 보는 날이다. 이머시브에서는 3주마다 테스트 과정을 보는데 내 실력 체크를 할 수있는 기회라고 생각한다.
이번에는 알고리즘을 풀기 위한 자료구조를 공부했기 때문에, 알고리즘 위주로 H.A 시험문제가 나올 것으로 예상된다.
잘 풀렸으면 좋겠다..
👊 내일의 TIW(today I Will)
H.A 시험