본문 바로가기
Algorithm

[프로그래머스] Lv1. 바탕화면 정리 - Javascript

by 리코더@typing4life 2023. 3. 5.

# 문제

  • 컴퓨터 바탕화면에 있는 파일들을 삭제하려고 한다
  • 바탕화면은 각 칸이 정사각형인 격자판
  • 상태를 나타낸 문자열 배열 wallpaper 가 주어지고, 파일들은 각 격자칸에 위치한다
  • 격자판은 가장 왼쪽 위를 (0, 0) 으로 시작해 (세로 좌표, 가로 좌표)로 표현
  • 빈칸은 ., 파일이 있는 칸은 # 값을 가짐
  • 최소한의 이동거리를 갖는 한 번의 드래그로 모든 파일을 선택하고자 한다. 이 때 드래그의 시작점과 끝점을 담은 정수 배열을 반환

# 정의

  • "점 S에서 점 E로 드래그한다"라는 표현은 격자점 S(lux, luy)에서 마우스 클릭 후 격자점 E(rdx, rdy)에서 떼는 행동을 의미한다.
  • 드래그 한 거리는 | rdx - lux | + | rdy - luy | 로 정의

# 제한사항

  • 1 <= wallpaper의 길이 <= 50
  • 1 <= wallpaper[i]의 길이 <= 50. wallpaper의 모든 원소의 길이는 동일함
  • wallpaper[i][j]는 바탕화면에서 i + 1j + 1열에 해당하는 칸의 상태를 나타냄
  • wallpaper은 "#" 또는 "."의 값만 가짐
  • 바탕화면에는 적어도 하나의 파일이 있음
  • lux < rdx, luy < rdy

# 입출력 예

  • wallpaper: [".#...", "..#..", "...#."]
    result: [0, 1, 3, 4]
  • wallpaper: ["..........", ".....#....", "......##..", "...##.....", "....#....."]
    result: [1, 3, 5, 8]
  • wallpaper: [".##...##.", "#..#.#..#", "#...#...#", ".#.....#.", "..#...#..", "...#.#...", "....#...."]
    result: [0, 0, 7, 9]
  • wallpaper: ["..", "#."]
    result: [1, 0, 2, 1]

# 풀이

문제에서 '드래그 한 거리'를 드래그에 포함되는 범위를 사각형으로 바라봤을 때 가로 길이 + 세로 길이로 정의되어 있다.

바꿔 말하면 드래그 범위 안에 모든 파일을 담을 수 있는 가장 작은 사각형을 구하라는 문제로 해석할 수 있다.

때문에 파일 위치들을 Point: { x: number, y: number}로 표현했을 때 반환해야할 값은 [x 최솟값, y 최솟값, x+1 최댓값, y+1 최댓값] 이다.

여기서 x + 1y + 1 인 이유는 각 인덱스가 파일 아이콘의 왼쪽 상단을 가리키고 있는데, 드래그 범위 안에 들어오기 위해서는 x와 y 모두 1씩 올려야 하기 때문이다.

코드는 다음과 같다.

// input: string[]
// output: ({ x: number, y: number} | null)[]
// 정의: 파일이 존재할 경우 해당 위치를 Point 형식으로 변환
function convert2Point(wallpaper) {
    return wallpaper.map((row, rowIndex) =>
        [...row].map((el, colIndex) => {
            if(el === '#') {
                return { x: rowIndex, y: colIndex };
            }
            return null;
        })
    )
}

// input: string[]
// output: { x: number, y: number }[]
// 정의: 비어있는 데이터를 필터링 후 Point 배열 반환
function getDraggablePoints(wallpaper) {
    return convert2Point(wallpaper)
        .flatMap(el => el)
        .filter(el => el);
}


// input: string[]
// output: number[]
// 정의: 드래그가 가능한 포인트들을 구한 뒤 답을 반환
function solution(wallpaper) {
    const points = getDraggablePoints(wallpaper);
    return [
        Math.min(...points.map(({ x }) => x)),
        Math.min(...points.map(({ y }) => y)),
        Math.max(...points.map(({ x }) => x + 1)),
        Math.max(...points.map(({ y }) => y + 1)),
    ];
}
반응형

댓글