1️⃣ 문제 설명

코딩테스트 연습 - [1차] 프렌즈4블록

스크린샷 2022-07-13 오후 11.29.52.png

스크린샷 2022-07-13 오후 11.30.14.png

스크린샷 2022-07-13 오후 11.30.32.png


2️⃣ 풀이

//1. 첫 배치가 주어졌을 때 , 지워지는 블록이 모두 몇 개인지 판단
//높이 m, 폭 n, 판의 배치 정보 board
//2x2 형태로 4개가 붙어어있을 경우 블록들이 사라지면서 점수 추가

//2. 2x2 블록 지우기
//for 문을 돌면서 자기와 +1 인덱스의 값이 같다면, 밑의 줄과 비교
//2x2까지 같다면 바로 지우지 않고, 해당 인덱스만 추출하여 배열에 넣자
//마지막 배치까지 검사한 후 배열의 인덱스들 찾아서 빈 칸으로 치환

//3. 칸 내리기
//이것도 for 문을 돌며 아래 열부터 검사
//자기가 빈 칸이고 윗 열들 중 빈칸이 아닌 칸이 있으면 처음 만나는 블록을 자기 칸으로 옮기기
//반복

//이걸 2x2가 없을 때 까지 반복

//4. 점수 계산
//결국 마지막 보드에서 지워진 칸의 총 개수가 문제가 원하는 정답

3️⃣ 나의 코드

function solution(m, n, board) {
	let arr = board.map((v) => v.split(""));
	let idx = [];

	//4. 이 과정을 2x2 블록이 없을 때 까지 반복
	while (true) {
		//1. 2x2가 되는 블록을 찾아 idx에 넣기
		for (let i = 0; i < m - 1; i++) {
			for (let j = 0; j < n - 1; j++) {
				if (
					//빈 칸 끼리 4칸이 모여 지워지면 안됨
					arr[i][j] !== " " &&
					arr[i][j] === arr[i][j + 1] &&
					arr[i][j] === arr[i + 1][j] &&
					arr[i][j] === arr[i + 1][j + 1]
				) {
					idx.push([i, j]);
				}
			}
		}

		//5. 2x2 조건에 맞는 블록이 없을 경우 정답 산출
		if (!idx.length) {
			let answer = 0;
			arr.forEach((i) =>
				i.forEach((v) => {
					if (v === " ") answer++;
				})
			);
			return answer;
		}

		//2. idx배열을 돌며 2x2로 지워지는 블록들을 공백으로 치환
		idx.forEach(([i, j]) => {
			arr[i][j] = " ";
			arr[i][j + 1] = " ";
			arr[i + 1][j] = " ";
			arr[i + 1][j + 1] = " ";
		});
		idx = [];

		//3. 빈 칸 메꾸기
		for (let i = m - 1; i > 0; i--) {
			for (let j = 0; j < n; j++) {
				if (arr[i][j] === " ") {
					//i만 증가시켜서 빈칸이 아닌 칸을 발견하면 끌어오기
					for (let k = i - 1; k >= 0; k--) {
						if (arr[k][j] !== " ") {
							arr[i][j] = arr[k][j];
							arr[k][j] = " ";
							break;
						}
					}
				}
			}
		}
	}
}

4️⃣ 마무리

풀릴듯 말듯 해서 시간을 많이 쓴 문제다

풀이를 생각하는 데엔 오래 걸리지 않았는데, 이걸 구현하는 과정이 생각보다 복잡했다

결과적으로 풀긴 했지만 삼중 For문을 도는게 맞을까..?

다른 사람들의 풀이를 보며 더 나은 부분을 참고해야겠다