function solution(arr) {
let answer = [];
arr.forEach((ele) => {
for (let i = 0;i<ele;i++){
answer.push(ele)
}
})
return answer;
}
반복문을 조금 더 줄이고 예쁘게 구성할 수 있는 방법이 없을까.
짜잔!
function solution(arr) {
let answer = [];
arr.forEach((ele) => {
answer.push(...Array(ele).fill(ele))
})
return answer;
}
python의 List comprehension처럼
특정 원소로 초기화하는 배열을 만들 때, Array(_갯수).fill(_채우고 싶은 수)
로 쓰면 될 것 같다.
function solution(arr) {
let answer = [];
arr.forEach((ele) => {
answer.push(...Array.from({length: ele}, _ => ele))
})
return answer;
}
코드1 | 코드2 | 코드3 | |
---|---|---|---|
평균 시간 | 0.207ms | 0.118ms | 0.359ms |
평균 메모리 | 34.925MB | 35.031MB | 34.931MB |
최고 시간 | 0.91ms | 0.31ms | 1.11ms |
최저 시간 | 0.04ms | 0.04ms | 0.07ms |
최고 메모리 | 37.4MB | 37.8MB | 37.5MB |
최저 메모리 | 33.5MB | 33.5MB | 33.5MB |
시간 표준 편차 | 0.188 | 0.034 | 0.280 |
메모리 표준 편차 | 19.345 | 21.057 | 20.462 |
결과적으로 코드2가 시간 효율성이 가장 높다.
즉, 배열 초기화에서 더 효율적인 것은Array.from()
메서드보다Array.fill()
이다.
const text = `테스트 결과 copy and paste`
const testCount = text.split('테스트').length-1
let time = []
let memory = []
text.split('통과 (').forEach((ele, idx) => {
if(idx == 0) return
let value = ele.split(')')[0].split(', ')
time.push(parseFloat(value[0].slice(0, 4)))
memory.push(parseFloat(value[1].slice(0, 4)))
})
const getAverage = (data) => (data.reduce((a, b) => a+b)/testCount).toFixed(3)
const averageTime = getAverage(time)
const averageMemory = getAverage(memory)
const getStandardDeviation = (data, average) => ((data.reduce((a, b) => a + (b-average)**2))/testCount**(1/2)).toFixed(3)
const SDT = getStandardDeviation(time, averageTime)
const SDM = getStandardDeviation(memory, averageMemory)
console.log(`평균 시간: ${averageTime}ms`)
console.log(`평균 메모리: ${averageMemory}MB`)
console.log(`최고 시간: ${Math.max(...time)}ms`)
console.log(`최저 시간: ${Math.min(...time)}ms`)
console.log(`최고 메모리: ${Math.max(...memory)}MB`)
console.log(`최저 메모리: ${Math.min(...memory)}MB`)
console.log(`시간 표준 편차: ${SDT}`)
console.log(`메모리 표준 편차: ${SDM}`)
사용 방법 예시
text에 프로그래머스 코드 실행 결과를 그대로 드래그에서 복사한 것을 붙여넣기 하면 된다!
function solution(arr, n) {
arrLength = arr.length
let answer = arr.map((ele, idx) => {
if (arrLength % 2 == 0 ){
if (idx % 2 == 1){
return ele += n
}
} else {
if (idx % 2 == 0) {
return ele += n
}
}
return ele
});
return answer;
}
조건문의 가독성을 조금 더 올리고 코드를 줄일 수 있는 방법이 없을까
function solution(arr, n) {
arrLength = arr.length
let answer = arr.map((ele, idx) => {
if (arrLength % 2 == 0 & idx % 2 == 1) return ele += n
if (arrLength % 2 == 1 & idx % 2 == 0) return ele += n
return ele
});
return answer;
}
흠... 아직도 마음에 썩 들진 않는다...
function solution(l, r) {
var answer = [];
let start = l.toString().length;
let end = r.toString().length;
let possibleNum = Array(7).fill([])
possibleNum[0] = []
possibleNum[1] = [0, 5]
for (let i = start;i<=end;i++){
if (possibleNum[i].length > 0) continue
let result5 = possibleNum[i-1].map((ele) => parseInt('5'+ele.toString()))
let result50 = possibleNum[i-2].map((ele) => parseInt('50'+ele.toString()))
possibleNum[i] = result5.concat(result50)
}
let allNum = [].concat.apply([], possibleNum).sort((a, b) => a-b)
let filteredNum = allNum.filter((v) => l<=v & v<=r)
answer = filteredNum.length > 0 ? filteredNum : [-1]
return answer
}
유사 DP로 풀려고 했으나 틀렸다.
곰곰히 생각해 보니 이 코드는 50005인 경우, 즉 메모이제이션으로 참고하는 앞 수가 5일 때 000...05
으로 조합되지 않아서 커버가 되지 않는다.
그래서 갈아엎고 다른 방법으로 도전했다.
function solution(l, r) {
var answer = [];
let possible = []
let end = r.toString().length
for (let i = 1;i<2**end;i++){
possible.push(i.toString(2))
}
fiveOrZero = possible.map((ele)=> ele*5)
answer = fiveOrZero.filter((ele) => l<=ele & ele<=r)
answer = answer.length > 0 ? answer: [-1]
return answer
}
Lv.0인데 거의 1시간을 잡았다... 허어...
결국 0과 5만 쓰이는 숫자를 만드는 것이니 이진법으로 키워드를 돌려 접근했더니 정답!
오늘 스터디로 푼 문제인데, 완전탐색 + 정규표현식으로 풀이한 결과와 비교해본다.
이진법 | 완전탐색 + 정규표현식 | |
---|---|---|
평균 시간 | 3.502ms | 14.742ms |
평균 메모리 | 33.650MB | 37.850MB |
최고 시간 | 4.27ms | 94.6ms |
최저 시간 | 3.16ms | 0.18ms |
최고 메모리 | 33.8MB | 52.7MB |
최저 메모리 | 33.6MB | 33.5MB |
시간 표준 편차 | 1.005 | 2708.405 |
메모리 표준 편차 | 7.188 | 111.008 |
확실히... 완전탐색으로 하면 극단적인 데이터에서 굉장한 결과가 갑자기 나온다.
여기서 드는 의문!
과연 시간과 메모리의 편차가 크지 않은 것이 좋은 알고리즘인가?
즉, 시간 표준 편차와 메모리 표준 편차가 작을 수록 좋은 알고리즘인가?
function solution(arr, query) {
let answer = arr
query.forEach((queryIdx, idx) => {
if (idx % 2 == 0){
answer = answer.slice(0, queryIdx+1)
} else {
answer = answer.slice(-(answer.length-queryIdx))
}
})
return answer;
}
코딩 기초 트레이닝 중에서 정답률이 2번째로 낮은 친구여서 긴장했지만
별거 없었던 문제였다.
function solution(arr, query) {
let answer = arr
query.forEach((queryIdx, idx) => {
let start = idx % 2 == 0 ? 0: queryIdx
let end = idx % 2 == 0 ? queryIdx+1:answer.length
answer = answer.slice(start, end)
})
return answer;
}
시간을 따졌을 때 개선 코드가 조금 더 빠른 경우가 있었는데, 아주 미미한 차이라 비교하는 것이 무의미할 정도이다.
조건문이 살짝 가독성이 떨어져서 삼항 연산자로 한 번 더 수정하여 개선시켰다.