[프로그래머스 | 파이썬 / 자바스크립트] 안전지대(코딩테스트 입문/ level 0)

2023. 2. 22. 14:10·Problem Solving/프로그래머스
문제

https://school.programmers.co.kr/learn/courses/30/lessons/120866?language=python3 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

🐍파이썬
더보기

❌ 실패한 코드

def solution(board):
    newlist = [[i,j] for i in range(len(board)) for j in range(len(board[i])) if board[i][j] == 1]
    answer = len(newlist)
    for n in newlist:
        for i in [-1, 0, 1]:
            for j in [-1, 0, 1]:
                if n[0]+i < len(board[0]) and n[1]+j < len(board[1]):
                    if board[n[0]+i][n[1]+j] == 0:
                        board[n[0]+i][n[1]+j] = 1
                        answer += 1
    return len(board[0])**2 - answer

  • 7번 라인 0 <= 바운더리 설정하지 않아서
    • 테스트케이스 1번 오류 발생
    • 테스트9 런타임에러 발생
def solution(board):
    newlist = [[i,j] for i in range(len(board)) for j in range(len(board[i])) if board[i][j] == 1]
    answer = len(newlist)
    for n in newlist:
        for i in [-1, 0, 1]:
            for j in [-1, 0, 1]:
                if 0 <= n[0]+i < len(board) and 0 <= n[1]+j < len(board):
                    if board[n[0]+i][n[1]+j] == 0:
                        board[n[0]+i][n[1]+j] = 1
                        answer += 1
    return len(board)**2 - answer

1️⃣ newlist에 지뢰의 위치를 저장한다.

2️⃣ answer에는 안전지대가 아닌 지역의 갯수를 저장한다. 따라서 newlist에서 구한 지뢰의 갯수를 넣어 answer을 초기화해준다. 

3️⃣ 지뢰의 위, 아래, 좌우, 대각선의 좌표를 이중 for문으로 돌며 각 좌표를 방문한다.

i = -1 -> j = -1, 0, 1 ☞ 위/왼쪽대각선, 위, 위/오른쪽대각선

i = 0 -> j = -1, 0, 1 ☞  좌, 지뢰, 우

i = 1 -> j = -1, 0, 1 ☞  아래/왼쪽대각선, 아래, 아래/왼쪽대각선

---총 9회 반복한다.

4️⃣ 지뢰의 위, 아래, 좌우, 대각선 좌표가 배열의 바운더리를 벗어난 경우 방문하지 않게 하기 위해 0 <= n[0]+i < len(board) and 0 <= n[1]+j < len(board) 조건을 추가한다.

5️⃣ 각 좌표를 방문하면서 안전지대 표시를 1(비안전지대)로 바꾸고 그때마다 안전지대가 아닌 지역을 카운팅하기 위해 answer에 1을 더해준다.

6️⃣ 모든 좌표 방문이 끝났다면 전체 배열 길이에서 비안전지대 갯수를 빼서 안전지대 갯수를 구한다.


def solution(board):
    newlist = [[i,j] for i in range(len(board)) for j in range(len(board[i])) if board[i][j]==1]
    answer = len(newlist)
    x_arr = [-1, -1, -1, 0, 0, 1, 1, 1]
    y_arr = [-1, 0, 1, -1, 1, -1, 0, 1]
    for x, y in newlist:
        for i in range(8):
            new_x = x + x_arr[i]
            new_y = y + y_arr[i]
            if 0 <= new_x < len(board) and 0 <= new_y < len(board):
                if board[new_x][new_y] == 0:
                    board[new_x][new_y] = 1
                    answer += 1
    return len(board)**2 - answer

1️⃣ newlist에 지뢰의 위치를 저장한다.

2️⃣ answer에는 안전지대가 아닌 지역의 갯수를 저장한다. 따라서 newlist에서 구한 지뢰의 갯수를 넣어 answer을 초기화해준다. 

3️⃣ x_arr과 y_arr에는 방문해야 할 x, y 좌표를 각각 저장했다. 순서대로 위/왼쪽대각선, 위, 위/오른쪽대각선, 좌, 우, 아래/왼쪽대각선, 아래, 아래/왼쪽대각선 이다. (지뢰를 0,0으로 표시했을 때를 기준으로 한다.)

4️⃣ 현재 지뢰의 좌표에 x_arr과 y_arr 배열의 좌표를 더한 뒤 지뢰를 기준으로 8개의 좌표를 순서대로 방문한다.

5️⃣ 지뢰의 위, 아래, 좌우, 대각선 좌표가 배열의 바운더리를 벗어난 경우 방문하지 않게 하기 위해 0 <= n[0]+i < len(board) and 0 <= n[1]+j < len(board) 조건을 추가한다.

6️⃣ 좌표를 방문하면서 안전지대 표시를 1(비안전지대)로 바꾸고 그때마다 안전지대가 아닌 지역을 카운팅하기 위해 answer에 1을 더해준다.

7️⃣ 모든 좌표 방문이 끝났다면 전체 배열 길이에서 비안전지대 갯수를 빼서 안전지대 갯수를 구한다.

 

 

다른 풀이 방법

def solution(board):
    n = len(board)
    danger = set()
    for i, row in enumerate(board):
        for j, x in enumerate(row):
            if not x:
                continue
            danger.update((i+di, j+dj) for di in [-1,0,1] for dj in [-1, 0, 1])
    return n*n - sum(0 <= i < n and 0 <= j < n for i, j in danger)

enumerate의 i, j 부분은 각 원소의 인덱스이다.

enumerate를 통해 for문을 돌면서 지뢰의 위치를 찾아 좌표를 더해 비안전지대를 체크하는 것까지 한 번에 수행하고 있다. 바운더리 계산없이 우선 비안전지대를 체크한 뒤 추후 바운더리 체크 조건에 해당하는 값만 sum()으로 합해서 전체 board길이에서 빼주었다.


def solution(board):
    answer = 0
    for col in range(len(board)):
        for row in range(len(board[col])):
            if board[row][col] == 1:
                for j in range(max(col-1,0),min(col+2,len(board))):
                    for i in range(max(row-1,0),min(row+2,len(board))):
                        if board[i][j] == 1:
                            continue
                        board[i][j] = -1
    for i in board:
        answer += i.count(0)
    return answer

바운더리 처리를 min, max로 진행했다.

 

 

🐥자바스크립트
function solution(board) {
    let arr = [];
    for (let i = 0; i < board[0].length; i++){
        for (let j = 0; j < board[0].length; j++){
            if (board[i][j] === 1){
                arr.push([i,j]);
            }
        }
    }
    let answer = arr.length;
    for (let k of arr){
        for (let l of [-1, 0, 1]){
            for (let m of [-1, 0, 1]){
                if ((0 <= (k[0]+l) && (k[0]+l) < board[0].length) && (0 <= (k[1]+m) && (k[1]+m) < board[0].length)){
                    if (board[k[0]+l][k[1]+m] === 0){
                        board[k[0]+l][k[1]+m] = 1
                        answer++;
                    }
                }
            }
        }
    }
    return board.length ** 2 - answer;
}

* 파이썬 1번 풀이와 동일하게 풀었다.

1️⃣ newlist에 지뢰의 위치를 저장한다.

2️⃣ answer에는 안전지대가 아닌 지역의 갯수를 저장한다. 따라서 newlist에서 구한 지뢰의 갯수를 넣어 answer을 초기화해준다. 

3️⃣ 지뢰의 위, 아래, 좌우, 대각선의 좌표를 이중 for문으로 돌며 각 좌표를 방문한다.

i = -1 -> j = -1, 0, 1 ☞ 위/왼쪽대각선, 위, 위/오른쪽대각선

i = 0 -> j = -1, 0, 1 ☞  좌, 지뢰, 우

i = 1 -> j = -1, 0, 1 ☞  아래/왼쪽대각선, 아래, 아래/왼쪽대각선

---총 9회 반복한다.

4️⃣ 지뢰의 위, 아래, 좌우, 대각선 좌표가 배열의 바운더리를 벗어난 경우 방문하지 않게 하기 위해 (0 <= (k[0]+l) && (k[0]+l) < board[0].length) && (0 <= (k[1]+m) && (k[1]+m) < board[0].length) 조건을 추가한다.

5️⃣ 각 좌표를 방문하면서 안전지대 표시를 1(비안전지대)로 바꾸고 그때마다 안전지대가 아닌 지역을 카운팅하기 위해 answer에 1을 더해준다.

6️⃣ 모든 좌표 방문이 끝났다면 전체 배열 길이에서 비안전지대 갯수를 빼서 안전지대 갯수를 구한다.

 

 

다른 풀이 방법

function solution(board) {
    let outside = [[-1,0], [-1,-1], [-1,1], [0,-1],[0,1],[1,0], [1,-1], [1,1]];
    let safezone = 0;

    board.forEach((row, y, self) => row.forEach((it, x) => {
        if (it === 1) return false;
        return outside.some(([oy, ox]) => !!self[oy + y]?.[ox + x]) ? false : safezone++;
    }));
    return safezone;
}

이중 forEach문, !!, ?. 사용.

?.부분이 이해가 안 간다...

 

💫 참고

❗ forEach()

형태: arr.forEach((처리할 현재 요소, 처리할 현재 요소의 인덱스, forEach를 호출한 배열) => {각 요소에 대해 실행할 함수})

출처: https://tinyurl.com/2zucpb7r

 

Array.prototype.forEach() - JavaScript | MDN

forEach() 메서드는 주어진 함수를 배열 요소 각각에 대해 실행합니다.

developer.mozilla.org

❗❗ some()

배열 안의 요소가 주어진 판별 함수를 적어도 하나라도 통과하면 true 그렇지 않으면 false를 반환한다.

callbak 함수는 3가지 인자를 갖는다.

  • element 처리할 배열 내 현재 요소
  • index 처리할 현재 요소의 인덱스
  • array some()을 호출한 배열

❗❗❗ 느낌표 두개 (Double Exclamation Operation)

object를 boolean 형으로 변환하는 연산자

[undefined, "", 0] 일 경우 결과는 false, 그 외의 결과는 모두 true

  • !! 0 –> false
  • !! null –> false
  • !! undefined –> false
  • !! 48 –> true
  • !! “hello” –> true
  • !! [1, 2, 3] –> true

출처: https://www.codingem.com/javascript-double-exclamation-operator/

 

The Double Exclamation Operator (!!) in JavaScript - codingem.com

JavaScript double exclamation operator (!!) converts any object to a boolean value. For example !!0 --> false and !!1 --> true.

www.codingem.com

❗❗❗❗ ?. (optional chaining)

  • 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근하기 위한 문법 ☞ 즉, 존재하지 않는 요소(null, undefined)에 접근해 정보를 가져오려 할 때 오류가 발생하는 문제를 해결하기 위한 문법
  • ?.'앞’의 평가 대상이 undefined나 null이면 평가를 멈추고 undefined를 반환
//기존 방법
let nestedProp = obj.first && obj.first.second;
//optional chaining
let nestedProp = obj.first?.second;
  • obj.first?.second : obj.first가 존재하면 obj.first.second을 반환, 그렇지 않으면 undefined를 반환함

출처

https://tinyurl.com/2jtfrshr

 

Optional chaining - JavaScript | MDN

optional chaining 연산자 (?.) 는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있다.

developer.mozilla.org

https://ko.javascript.info/optional-chaining

 

옵셔널 체이닝 '?.'

 

ko.javascript.info


function solution(b) {
    const directions = [[0,0],[0,1],[0,-1],[1,1],[1,0],[1,-1],[-1,-1],[-1,0],[-1,1]]
    let bombSet = new Set();

    for(let i = 0; i < b.length; i++) {
        for(let j = 0; j < b[i].length; j++) {
            if(b[i][j] == 1) {
                directions.forEach(el => {
                    let [nextX, nextY] = el;
                    [nextX, nextY] = [i+nextX, j+nextY];
                    if(nextX >= 0 && nextX < b.length && nextY >= 0 && nextY < b[i].length) {
                        bombSet.add(nextX+' '+nextY);
                    }
                })
            }
        }
    }
    return b.length * b[0].length - bombSet.size;
}
저작자표시 비영리 변경금지 (새창열림)

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

[프로그래머스 | 파이썬 / 자바스크립트] 모음제거(코딩테스트 입문/ level 0)  (0) 2023.02.22
[프로그래머스 | 파이썬 / 자바스크립트] 둘만의 암호(연습문제/ level 1)  (0) 2023.02.22
[프로그래머스 | 파이썬 / 자바스크립트] 순서쌍의 개수(코딩테스트 입문/ level 0)  (0) 2023.02.22
[프로그래머스 | 파이썬 / 자바스크립트] 자릿수 더하기(코딩테스트 입문/ level 0)  (0) 2023.02.21
[프로그래머스 | 파이썬 / 자바스크립트] n의 배수 고르기(코딩테스트 입문/ level 0)  (2) 2023.02.21
[프로그래머스 | 파이썬 / 자바스크립트] 최댓값 만들기 (2)(코딩테스트 입문/ level 0)  (0) 2023.02.21
'Problem Solving/프로그래머스' 카테고리의 다른 글
  • [프로그래머스 | 파이썬 / 자바스크립트] 둘만의 암호(연습문제/ level 1)
  • [프로그래머스 | 파이썬 / 자바스크립트] 순서쌍의 개수(코딩테스트 입문/ level 0)
  • [프로그래머스 | 파이썬 / 자바스크립트] 자릿수 더하기(코딩테스트 입문/ level 0)
  • [프로그래머스 | 파이썬 / 자바스크립트] n의 배수 고르기(코딩테스트 입문/ level 0)
청량리 물냉면
청량리 물냉면
프로그래밍 공부를 하고 있습니다. 공부 내용 정리 겸 정보 공유를 목적으로 합니다.
  • 청량리 물냉면
    노력중인 블로그
    청량리 물냉면
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 프로그래밍
        • Programming
        • C | C++
        • Java
        • Python
      • 웹 프로그래밍
        • HTML | CSS
        • JavaScript | TypeScript
        • React
        • Vue.js
        • Next.js
        • Spring & Spring Boot
        • JSP & Servlet
        • DB
      • 웹 프로젝트
        • 웹 프로젝트
        • 🥨스낵몰
        • 👨‍👨‍👧‍👧소셜 가계부
        • 🌜꿈 일기장
        • 🔮포트폴리오 사이트
        • 🏃‍♂️팀 프로젝트: 일정관리 프로그램
        • 📈팀 프로젝트: AI기반 주식 분석 플랫폼
        • 😺Just Meow It: 고양이의 조언
      • 앱 프로그래밍
        • Flutter
        • Kotlin
      • Problem Solving
        • 백준
        • 프로그래머스
        • SWEA
      • Computer Science
        • 알고리즘
        • 컴퓨터 네트워크
        • 이산수학
      • Developer
        • 후기
        • 자료정리
        • 취업 | 취준
        • 웹개발 교육 프로그램
        • TIL
  • 블로그 메뉴

    • 홈
    • Github
  • 공지사항

    • 프로그래밍 공부 중😊
  • 인기 글

  • 태그

    d3
    컴퓨터네트워크
    프로젝트
    Next.js
    파이썬
    프로그래머스
    spring boot
    SWEA
    블로그 제작
    클론 프로젝트
    포트폴리오
    웹사이트
    백준
    플러터
    구현
    bfs
    자바
    Jiraynor Programming
    뉴렉처
    타입스크립트
    React
    mysql
    ZeroCho
    알고리즘
    자바스크립트
    공식문서
    강의내용정리
    리액트
    AWS
    Til
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
청량리 물냉면
[프로그래머스 | 파이썬 / 자바스크립트] 안전지대(코딩테스트 입문/ level 0)
상단으로

티스토리툴바