본문 바로가기
Coding Test/JavaScript

[Javascript] (프로그래머스 level 2) 캐시

by Chaedie 2022. 11. 22.
728x90

[Javascript] (프로그래머스 level 2) 캐시

💡 구글에 Javascript 풀이가 많이 없거나, 배운 점이 있으면 포스팅합니다.

내 풀이

function solution(cacheSize, cities) {

    let time = 0;
    const cache = [];

    const isFull = () => cache.length >= cacheSize;
    const isCached = (city) => cache.indexOf(city) !== -1;

    const cacheHitTime = () => time += 1;
    const cacheHit = (city) => {
        const indexOfCachedData = cache.indexOf(city)
        cache.splice(indexOfCachedData, 1);
        cache.push(city)
    }

    const cacheMissTime = () => time += 5;
    const cacheMiss = (city) => {
        if (isFull()){
            cache.shift()
            cache.push(city)    
        } else {
            cache.push(city)
        }
    }

    if( cacheSize === 0) {
        return cities.length * 5;
    }

    for (let city of cities) {
        city = city.toLowerCase();
        if (isCached(city)) {
            cacheHitTime();
            cacheHit(city);
        } else {
            cacheMissTime();
            cacheMiss(city);
        }
    }

    return time
}

LRU캐시를 Queue를 활용해 hit가 되면 앞순위로 넣어주는 형식으로 만들었다.

if-else를 엄청나게 거친 뒤 완성했더니 코드가 보기가 어렵다는 생각에 함수로 모두 묶어주었는데, 이 또한 굉장히 더럽다는 생각을 하게 되었다.

클래스로 한번 묶어봐야겠다. 코딩테스트에서 의미 있는 행동은 아닐지 모르지만. 한번 해보면서 클래스로 묶는 연습을 해봐야겠다.

테스트 케이스 7번, 17번

문제를 다 풀고 나서 테케 7, 17에서 계속 걸렸었다. 이럴 때는 예외케이스를 생각해야하는데, 주어진 샘플 케이스에서 cachesize0일때를 이미 주어서 문제가 없다고 생각했었다. 하지만 cachesize가 0일때는 모두 cacheMiss라는걸 감안해서 배열사이즈 * 5를 해서 return 했더니 테케가 문제없이 해결되었다.

클래스로 묶은 풀이

function solution(cacheSize, cities) {
    let time = 0;
    const cache = new Cache(cacheSize)

    if(cacheSize === 0) return cities.length * 5;

    for (let city of cities) {
        city = city.toLowerCase();
        if (cache.isCached(city)) {
            time += 1;
            cache.cacheHit(city);
        } else {
            time += 5;
            cache.cacheMiss(city);
        }
    }

    return time
}

class Cache {
    cache = [];
    constructor(cacheSize) {
        this.cacheSize = cacheSize;
    }

    isFull = () => this.cache.length >= this.cacheSize;
    isCached = (city) => this.cache.indexOf(city) !== -1;

    cacheHit = (city) => {
        const indexOfCachedData = this.cache.indexOf(city)
        this.cache.splice(indexOfCachedData, 1);
        this.cache.push(city)
    }

    cacheMiss = (city) => {
        if (this.isFull()){
            this.cache.shift()
            this.cache.push(city)    
        } else {
            this.cache.push(city)
        }
    }
}

이렇게 클래스로 묶는 행위가 코테에서 의미있는 행동은 아닐수도 있지만… 그냥 이게 더 깔끔한거 같다. ㅎㅎ

배운 점, 느낀 점

기업과제를 하면서 캐싱을 간단히 직접 구현해본 적이 있는데, 그 땐 단순히 Expired Time을 만들어서 new Date()보다 expired Time이 지났으면 새로 API 콜하는 형태로 했었습니다. 코테 준비를 하면서 캐싱에 LRU알고리즘을 적용해보니 더 재밌네요 ㅎㅎ 재밌는것과 더해서 알고리즘이라는것들이 어려운 것도 있겠지만 간단한 아이디어들의 집합이라는 생각도 듭니다. 이런 간단한 아이디어들이 모여서 OS를 구성하고, 컴퓨터를 구성한다는게 신기하네요! 더 많이 배우고 싶네요 ㅎㅎ 

댓글