class Solution {
static int pad;
public boolean solution(int[][] key, int[][] lock) {
pad = key.length-1;
for(int dx = 0; dx<pad+lock.length; dx++){
// 행에서 움직이는방향
for(int dy = 0; dy <pad+lock.length; dy++){
// 열에서 움직이는 방향
for(int r = 0; r<4; r++){
int[][] bigLock = new int[lock.length+key.length*2][lock.length+key.length*2];
// 확장된 자물쇠 만들기
for(int i=0; i<lock.length; i++){
for(int j=0; j<lock.length; j++){
bigLock[pad+i][pad+j] = lock[i][j];
}
}
match(bigLock,key,dx,dy,r);
if(check(bigLock,lock.length)) return true;
}
}
}
return false;
}
public void match(int[][]bigLock , int key[][],int x,int y, int r){
int keySize = key.length;
for(int i=0; i<key.length; i++){
for(int j=0; j<key.length; j++){
switch(r){
case 0:
bigLock[x+i][y+j] += key[i][j];
break;
case 1:
// 90도 회전시 행과 열의 관계
bigLock[x+i][y+j] += key[j][keySize-1-i];
break;
case 2:
// 180도 회전시 행과 열의 관계
bigLock[x+i][y+j] += key[keySize-1-i][keySize-1-j];
break;
case 3:
bigLock[x+i][y+j] += key[keySize-1-j][i];
break;
}
}
}
}
/**
열쇠가 들어 맞는 경우는 0+1, 1+0 뿐이므로
돌기와 돌기 => 1+1=2, 홈과 홈 => 0+0 => 0이 자물쇠에 있다면
맞지 않는 것
*/
public boolean check(int[][] bigLock, int lockSize){
for(int i=0; i<lockSize; i++){
for(int j=0; j<lockSize; j++){
if(bigLock[pad+i][pad+j] != 1) return false;
}
}
return true;
}
}
2차원 배열 회전
class Solution {
public boolean solution(int[][] key, int[][] lock) {
int padSize = key.length -1;
int newSize = padSize*2 + lock.length;
int[][] newLock = new int[newSize][newSize];
int zeroToFill = 0;
// 키를 움직이면서 비교하기 위한 확장 배열 만들기
for(int i=0; i<lock.length; i++){
for(int j=0; j<lock.length; j++){
newLock[padSize+i][padSize+j] = lock[i][j];
// 채워야할 구멍수 파악
if(lock[i][j]==0) zeroToFill++;
}
}
// 키 이동 시켜가며 끼워보기 -> 키의 왼쪽 가장위 [0][0] 원소부터 비교 시작한다.
for(int x=0; x<padSize+lock.length; x++){
for(int y=0; y<padSize+lock.length; y++){
// 키 돌려가며 꼽아보기
for(int r =0; r<4; r++){
int[][] curKey = rotated(key,r,key.length);
int fitCnt =0;
for(int i=0; i<key.length; i++){
boolean flag = false;
for(int j=0; j<key.length; j++){
// 자물쇠 밖에서 비교하는 경우는 무시한다.
if((x+i)>padSize+lock.length-1 || (y+j)>padSize+lock.length-1
|| (x+i)<padSize || (y+j)<padSize) continue;
int curKeyVal = curKey[i][j];
int curLockVal = newLock[x+i][y+j];
if(curKeyVal+curLockVal !=1){
flag = true;
break;
}
else{
if(curLockVal == 0) fitCnt++;
}
}
if(flag) break;
}
if(fitCnt == zeroToFill) return true;
}
}
}
return false;
}
public int[][] rotated(int[][] raw,int rot,int size){
if(rot==0) return raw;
int[][] tmp = new int[size][size];
if(rot == 1){
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
tmp[i][j] = raw[size-1-j][i];
}
}
}else if(rot == 2){
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
tmp[i][j] = raw[size-1-i][size-1-j];
}
}
}else{
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
tmp[i][j] = raw[j][size-1-i];
}
}
}
return tmp;
}
}