개발자 톡

연습문제 톡 [HSAT 1회 정기 코딩 인증평가 기출] 로봇이 지나간 경로

JS

등록일
2024-11-16 16:16:06
조회수
105
작성자
vavoya6324

최소한의 명령어 라는건 의미가 없는게 아닐까 싶네요.


const fs = require('fs');
const input = fs.readFileSync('input.txt', 'utf8').trim().split(/\n+/);
const [H, W] = input[0].split(/\s+/).map(Number)
const map = input.slice(1).map(line => line.split('').map(v => {
    // 방문 했으면 true, 아니면 false 로 변환
    return v === '#'
}))

const top = 1
const left = 3
const right = 4
const bottom = 2

function findStart() {
    for (let h = 0; h < H; h++) {
        for (let w = 0; w < W; w++) {
            // 방문한 지점이고
            if (map[h][w]) {
                // 상하좌우 확인
                let count = 0
                if (map[h][w+1]) count++
                if (map[h][w-1]) count++
                if (map[h+1] && map[h+1][w]) count++
                if (map[h-1] && map[h-1][w]) count++

                // 시작 또는 마지막 지점을 찾음
                if (count === 1) {
                    return [h, w]
                }
            }
        }
    }
}

function findEnd(startPosition) {
    // 일단 마지막 지점을 찾을 때 까지 무한 반복
    // 0 방향 업승ㅁ
    // 1 상, 2 하, 3 좌, 4 우
    let arrow = 0
    let instructionStack = []

    while (true) {
        let [x, y] = startPosition
        // 현재 위치에서 상하좌우 어디로 갔는지 확인
        // 오른쪽에 있나. 근데 <- 진입해온거면 안됨
        if (map[x][y+1] && arrow !== left) {
            // 일단 이동 방향만 기록. 회전은 나중에
            instructionStack.push(right)
            arrow = right
            startPosition = [x, y+2]
        }
        // 아니면 왼쪽
        else if (map[x][y-1] && arrow !== right) {
            instructionStack.push(left)
            arrow = left
            startPosition = [x, y-2]
        }
        // 아니면 위?
        else if (map[x-1] && map[x-1][y] && arrow !== bottom) {
            instructionStack.push(top)
            arrow = top
            startPosition = [x-2, y]
        }
        // 그것도 아니면 아래?
        else if (map[x+1] && map[x+1][y] && arrow !== top) {
            instructionStack.push(bottom)
            arrow = bottom
            startPosition = [x+2, y]
        }
        // 이것은 끝이라는 것
        else {
            break
        }
    }
    return instructionStack
}

function getTurnA(prevArrow, newArrow) {
    // 오른쪽 회전
    if (
        (prevArrow === right && newArrow === bottom) ||
        (prevArrow === left && newArrow === top) ||
        (prevArrow === top && newArrow === right) ||
        (prevArrow === bottom && newArrow === left)
    ) {
        return 'RA'
    }

    // 왼쪽
    if (
        (prevArrow === right && newArrow === top) ||
        (prevArrow === left && newArrow === bottom) ||
        (prevArrow === top && newArrow === left) ||
        (prevArrow === bottom && newArrow === right)
    ) {
        return 'LA'
    }

    return 'A'
}

function getFinalInstruction(instructionStack) {
    let prevArrow = 0
    let startArrow = ''
    const finalInstructionStack = []
    for (let i = 0; i < instructionStack.length; i++) {
        const instruction = instructionStack[i]
        // 시작 부분이면
        if (prevArrow === 0) {
            prevArrow = instruction
            if (instruction === left) {
                startArrow = '<'
            }
            else if (instruction === right) {
                startArrow = '>'
            }
            else if (instruction === top) {
                startArrow = '^'
            }
            else if (instruction === bottom) {
                startArrow = 'v'
            }
            finalInstructionStack.push('A')
            continue
        }
        finalInstructionStack.push(getTurnA(prevArrow, instruction))
        prevArrow = instruction

    }

    return [startArrow, finalInstructionStack]
}

// 시작지점 찾고
const startPosition = findStart()
// 움직이는 방향 찾고
const instructionStack = findEnd(startPosition)
// 최종 명령어로 정리하고
const finalIstruction = getFinalInstruction(instructionStack)


console.log(startPosition.map(v => v+1).join(' '))
console.log(finalIstruction[0])
console.log(finalIstruction[1].join(''))


/*
# 입력 분석
H, W 는 높이 너비
# 은 사수가 방문한 위치. 최소 3개.
. 은 방문 안한 위치. 방문? room 도어 ㅋㅋ
빅인트 없음

# 출력
1. 처음 로봇 위치
2. 처음 로봇 방향
3. 명령어

# 문제 분석
최소한의 명령어로 목표 달성해야함.
보니깐 +2 하면서 지나간 곳도 방문으로 치는 듯
그렇다면 로봇은 상하좌우로 이어진 #을 그리게 된다.
십자가 형태는 없음. 재방문을 안하기에.

일단 무조건 2칸 씩 이니깐, 이동하는 지점은 2x2 격자로 정리됨
특정 지점에서 상하좌우 중에 #과 만나는건 최대 2개, 시작과 마지막 지점은 무조건 1개
시작과 마지막 지점은 절대 #과 만나는 지점이 2개가 될 수 없다.

따라서 시작 지점을 찾은 다음에, 그냥 #을 따라서 이동하면 기록하면됨



 */
#[HSAT_1회_정기_코딩_인증평가_기출]_로봇이_지나간_경로
#js

이 카테고리의 톡 더보기