슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
실패율은 다음과 같이 정의한다.
전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.
1
이상 500
이하의 자연수이다.1
이상 200,000
이하이다.stages에는 1이상 N+1
이하의 자연수가 담겨있다.
N + 1
은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.0
으로 정의한다.N | stages | result |
---|---|---|
5 | [2, 1, 2, 6, 2, 4, 3, 3] | [3,4,2,1,5] |
4 | [4,4,4,4,4] | [4,1,2,3] |
function solution(N, stages) {
let tot = stages.length
const answer = []
const arr = new Array(N)
arr.fill(0)
for (const v of stages) {
if ( v <= N ) arr[v-1]++
}
for (let i=0; i<arr.length; i++){
let fail_rate = 0
if (tot !== 0 && arr[i] !== 0) {
fail_rate = arr[i] / tot
tot -= arr[i]
}
answer.push({stage: i+1, fail: fail_rate})
}
return answer.sort((a,b) => {
if (a.fail === b.fail ) return a.stage - b.stage
return b.fail - a.fail
}).map(v => v.stage)
}
임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다. n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.
n | return |
---|---|
121 | 144 |
3 | -1 |
function solution(n) {
const v = n ** (1/2)
if (v > 0 && v % 1 === 0) return (v+1) ** 2
else return -1
}
Math.sqrt(number)
: number의 제곱근을 반환한다.
Math.pow(number, count)
: number의 count 제곱을 반환한다.
Number.isInteger(number)
: number가 정수 인지 체크한다.
신입사원 어피치는 카카오톡으로 전송되는 메시지를 압축하여 전송 효율을 높이는 업무를 맡게 되었다. 메시지를 압축하더라도 전달되는 정보가 바뀌어서는 안 되므로, 압축 전의 정보를 완벽하게 복원 가능한 무손실 압축 알고리즘을 구현하기로 했다.
어피치는 여러 압축 알고리즘 중에서 성능이 좋고 구현이 간단한 LZW(Lempel–Ziv–Welch) 압축을 구현하기로 했다. LZW 압축은 1983년 발표된 알고리즘으로, 이미지 파일 포맷인 GIF 등 다양한 응용에서 사용되었다.
LZW 압축은 다음 과정을 거친다.
w
를 찾는다.w
에 해당하는 사전의 색인 번호를 출력하고, 입력에서 w
를 제거한다.c
), w+c
에 해당하는 단어를 사전에 등록한다.압축 알고리즘이 영문 대문자만 처리한다고 할 때, 사전은 다음과 같이 초기화된다. 사전의 색인 번호는 정수값으로 주어지며, 1부터 시작한다고 하자.
색인 번호 | 1 | 2 | 3 | … | 24 | 25 | 26 |
---|---|---|---|---|---|---|---|
단어 | A | B | C | … | X | Y | Z |
예를 들어 입력으로 KAKAO
가 들어온다고 하자.
KAKAO
의 첫 글자 K
는 등록되어 있으나, 두 번째 글자까지인 KA
는 없으므로, 첫 글자 K
에 해당하는 색인 번호 11을 출력하고, 다음 글자인 A
를 포함한 KA
를 사전에 27 번째로 등록한다.A
는 사전에 있으나, 세 번째 글자까지인 AK
는 사전에 없으므로, A
의 색인 번호 1을 출력하고, AK
를 사전에 28 번째로 등록한다.KA
가 사전에 있으므로, KA
에 해당하는 색인 번호 27을 출력하고, 다음 글자 O
를 포함한 KAO
를 29 번째로 등록한다.O
에 해당하는 색인 번호 15를 출력한다.현재 입력(w) | 다음 글자(c) | 출력 | 사전 추가(w+c) |
---|---|---|---|
K | A | 11 | 27: KA |
A | K | 1 | 28: AK |
KA | O | 27 | 29: KAO |
O | 15 |
이 과정을 거쳐 다섯 글자의 문장 KAKAO
가 4개의 색인 번호 [11, 1, 27, 15]로 압축된다.
입력으로 TOBEORNOTTOBEORTOBEORNOT
가 들어오면 다음과 같이 압축이 진행된다.
현재 입력(w) | 다음 글자(c) | 출력 | 사전 추가(w+c) |
---|---|---|---|
T | O | 20 | 27: TO |
O | B | 15 | 28: OB |
B | E | 2 | 29: BE |
E | O | 5 | 30: EO |
O | R | 15 | 31: OR |
R | N | 18 | 32: RN |
N | O | 14 | 33: NO |
O | T | 15 | 34: OT |
T | T | 20 | 35: TT |
TO | B | 27 | 36: TOB |
BE | O | 29 | 37: BEO |
OR | T | 31 | 38: ORT |
TOB | E | 36 | 39: TOBE |
EO | R | 30 | 40: EOR |
RN | O | 32 | 41: RNO |
OT | 34 |
입력으로 영문 대문자로만 이뤄진 문자열 msg
가 주어진다. msg
의 길이는 1 글자 이상, 1000 글자 이하이다.
주어진 문자열을 압축한 후의 사전 색인 번호를 배열로 출력하라.
msg | answer |
---|---|
KAKAO |
[11, 1, 27, 15] |
TOBEORNOTTOBEORTOBEORNOT |
[20, 15, 2, 5, 15, 18, 14, 15, 20, 27, 29, 31, 36, 30, 32, 34] |
ABABABABABABABAB |
[1, 2, 27, 29, 28, 31, 30] |
function solution(msg) {
var answer = [];
const alphaMap = new Map()
for (let i=65; i<=90; i++) alphaMap.set(String.fromCharCode(i),i-64)
let i = 0;
let last = 27
while (i<msg.length){
let cnt = 1;
while (i+cnt <= msg.length){
const cur = msg.slice(i,i+cnt);
if (!alphaMap.has(cur)){
const prev = msg.slice(i, i+cnt-1);
answer.push(alphaMap.get(prev));
alphaMap.set(cur, last);
last += 1;
break;
}
else if(i+cnt === msg.length){
answer.push(alphaMap.get(cur))
}
cnt += 1
}
i += cnt - 1
}
return answer;
}
String.fromCharCode(num)
num에 맞는 아스키코드 문자 return