문제 풀이/프로그래머스

2020 KAKAO BLIND RECRUITMENT / 자물쇠와 열쇠

음악​ 2024. 12. 20. 22:17

https://school.programmers.co.kr/learn/courses/30/lessons/60059

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

function solution(key, lock) {
    const holeString = analyzeLock(lock);
    let currentKey = null;
    
    for (let i = 0; i < 4; i++) {
        currentKey = currentKey ? rotate(currentKey) : key;
        if (tryOpen(currentKey, lock, holeString)) {
            return true;
        }
    }

    return false;
}

const analyzeLock = (lock) => {
    const holes = [];
    
    lock.forEach((row, rowIdx) => {
        row.forEach((col, colIdx) => {
            if (col !== 0) {
                return;
            }
            holes.push([rowIdx, colIdx]);
        });
    });
    
    return holes.toString();
}

const analyzeKey = (key) => {
    const blocks = [];
    
    key.forEach((row, rowIdx) => {
        row.forEach((col, colIdx) => {
            if (col !== 1) {
                return;
            }
            blocks.push([rowIdx, colIdx]);
        });
    });
    
    return blocks;
}

const rotate = (square) => {
    const length = square.length;
    const newSquare = Array.from({length}, () => new Array(length).fill());
    
    square.forEach((row, rowIdx) => {
        row.forEach((col, colIdx) => newSquare[colIdx][length - rowIdx - 1] = col);
    })
    
    return newSquare;
}

const tryOpen = (key, lock, holeString) => {
    const keyRowLength = key.length
    const keyColLength = key[0].length;
    const lockRowLength = lock.length
    const lockColLength = lock[0].length;
    const keyBlocks = analyzeKey(key);
    
    for (let rowOffset = -keyRowLength + 1; rowOffset < lockRowLength; rowOffset++) {
        for (let colOffset = -keyColLength + 1; colOffset < lockColLength; colOffset++) {
            const blocks = [];
            keyBlocks.forEach(keyBlock => {
                const row = keyBlock[0] + rowOffset;
                const col = keyBlock[1] + colOffset;
                if (row < 0 || col < 0 || row >= lock.length || col >= lock[row].length) {
                    return;
                }
                blocks.push([row, col]);
            });
            if (blocks.toString() === holeString) {
                return true;
            }
        }
    }
    
    return false;
}