FrontEnd/프로그래머스

[JS] 자물쇠와 열쇠

728x90

배열을 다룰 줄알아야 하는 문제였다.

 

1. 배열을 회전시키며 4가지 경우를 검사한다.

2. 2 * key.length + lock.length - 2만큼의 배열을 만든다.

 

2번과 같은 확장배열을 만들어야 key를 움직여가며 자물쇠와 키를 맞춰놓는것이 편하다.

 

만약 예제라면 아래와 같은 7*7 확장배열을 만들고 lock의 정보를 저장한다. (빈칸은 0이라 생각하자.

 

             
             
    1 1 1    
    1 1      
    1   1    
             
             

 

 

아래처럼 자물쇠와 키를 순회하며 검사한다. 이때, key의값을 그냥 넣는것이 아닌 더해져서 넣어야 후에 돌기와 돌기가 만난것을 검사할 수 있다.

             
1            
  1 2 1 1    
    1 1      
    1   1    
             
             

 

             
  1          
    2 2 1    
    1 1      
    1   1    
             
             

 

 

             
    1        
    1 2 2    
    1 1      
    1   1    
             
             

 

 

             
      1      
    1 1 2 1  
    1 1      
    1   1    
             
             

 

 

.... 반복

 

 

3. 자물쇠와 key가 일치하는 것은 가운데의 lock배열의 크기만 검사해서 모두 1이라면 열리는 상태인 것이다.

 

 

function solution(key, lock) {
    const kLen = key.length
    const lLen = lock.length

    
    //key 배열을 시계방향 1회회전
    const rotateKeyRight = ary => {
       const ret = [...Array(kLen)].map(_ => Array(kLen).fill(0))
       for (let i = 0;i<kLen;i++){
           for(let j=0;j<kLen;j++){
               ret[j][kLen-i-1] = ary[i][j]
           }
       }
       return ret
    }
    
    //key,자물쇠를 맞춰보기위한 확장배열
    const extendLock = [...Array(2*kLen+lLen-1)].map(_ => Array(2*kLen+lLen-1).fill(0))
    for(let i = 0 ; i < lLen;i++){
        for (let j = 0 ; j < lLen ; j++){
            extendLock[i+kLen-1][j+kLen-1] = lock[i][j]
        }
    }
    
    //자물쇠가 열리는지 체크
    const openLock = (extendLock,key,addR,addC) => {
        const tmp = [...Array(2*kLen+lLen-1)].map((_,idx)=>[...extendLock[idx]])
        
        for (let i = 0 ; i < kLen ; i++){
            for (let j = 0 ; j < kLen ; j++){
                tmp[addR+i][addC+j] += key[i][j]
            }
        }
        
        
        
        for (let i = kLen-1 ; i < lLen+kLen-1 ;i++){
            for (let j = kLen-1 ; j < lLen+kLen-1 ; j++){
                if (tmp[i][j]!==1) return false
            }
        }
        
        return true
        
    }
    
    
    for(let i =0 ; i < 4 ; i++){
        for (let i = 0 ; i < kLen+lLen-1 ; i++){
            for (let j = 0 ; j < kLen+lLen-1 ; j++){
                if (openLock(extendLock,key,i,j)) return true
            }
        }
        key = rotateKeyRight(key)
    }
   
   return false
}
728x90

'FrontEnd > 프로그래머스' 카테고리의 다른 글

[JS] 가장 먼 노드  (0) 2023.12.27
[JS] 순위  (0) 2023.12.26
[JS] 외벽 점검  (1) 2023.12.21
[JS] 블록 이동하기  (0) 2023.12.20
[JS] 징검다리 건너기  (0) 2023.12.19