개발자 톡

연습문제 톡 [HSAT 3회 정기 코딩 인증평가 기출] 교차로

JS

등록일
2024-11-12 20:00:46
조회수
58
작성자
vavoya6324



class CrossRoadsSystem {
    constructor(typeCount) {
        this.system = []
        this.typeList = Array.from({length: typeCount}, (_, i) => i)
        this.record = []
        this.error = false
        this.typeList.forEach(type => {
            this.system[type] = {
                waiting: [],
                index: 0
            }
        })
    }


    /**
     *
     * @param time 기록될 시간
     * @returns {number} 0 -> 교착 상태, 1 -> 정상, 2 -> 차량 없음
     */
    process(time) {
        // 이전 작업에서 이미 교차가 발생. 이후 작업 불가
        if (this.error) {
            return 0
        }

        let count = 0
        let isNull = true
        const passType = []
        this.typeList.forEach(type => {
            const checkType = (type + 3) % this.typeList.length
            // 현재 검사 중인 타입(도로)에 차가 대기 중이면
            const carIndex = this.system[type].waiting[this.system[type].index]
            if (carIndex !== undefined) {
                const carIndex2 = this.system[checkType].waiting[this.system[checkType].index]
                // 근데 도로를 통과할 조건이 아니면? 우선순위가 더 높은 도로에 차가 대기 중이면?
                if (carIndex2 !== undefined) {
                    // 해당 도로는 time에 차가 못지나감
                    count++

                }
                // 해당 도로는 time에 차가 통과 가능
                else {
                    // 통과 가능한 차량 기록
                    this.record[carIndex] = +time
                    // 통과한 교차로 기록. 나중에 시간 업로드
                    passType.push(type)
                }
                isNull = false
            }
        })
        // 통과한 교차로 index 증가
        passType.forEach(type => {
            this.system[type].index++
        })


        // time 에 그 어떤 차량도 교차로를 통과하지 못했다.
        if (count === this.typeList.length) {
            this.error = true
            // 현재 대기 중인 차량들 전부 -1 처리
            this.processError()
            return 0
        }
        // 대기 중인 차량이 없다
        if (isNull) {
            return 2
        }
        // 정상 처리
        return 1
    }

    add(type, index) {
        // process 에서 에러가 발생하면, 이후 추가 차량은 즉시 에러 처리
        if (this.error) {
            this.record[index] = -1
        }
        else {
            this.system[type].waiting.push(index)
        }
    }

    processError() {
        this.system.forEach(type => {
            const list = type.waiting
            while(list[type.index]) {
                const carIndex = list[type.index]
                this.record[carIndex] = -1
                type.index++
            }
        })
    }

    getRecord() {
        return this.record
    }
}

// 입력처리
const fs = require('fs')
const input = fs.readFileSync('input.txt', 'utf8')
    .trim()
    .split(/\n+/)

const line = input.slice(1).map(time_roadType => time_roadType.split(' '))
const roadTypeOfTime = {}
line.forEach((time_roadType, index) => {
    const [time, roadType] = time_roadType
    let typeNum = 0
    // 나중에 (... + 1) % 4 로 간섭 판단할 것이기에
    if (roadType === 'A') typeNum = 0
    else if (roadType === 'B') typeNum = 1
    else if (roadType === 'C') typeNum = 2
    else if (roadType === 'D') typeNum = 3
    if (!(time in roadTypeOfTime)) {
        roadTypeOfTime[time] = [[], [], [], []]
    }
    roadTypeOfTime[time][typeNum].push(index)
})

const crossRoadsSystem = new CrossRoadsSystem(4)

const timeList = Object.keys(roadTypeOfTime)
let currentTime = -1

for (let i = 0 ; i < timeList.length; i++) {
    const time = timeList[i]
    const nextTIme = timeList[i + 1]
    // 현재 시간 초기화
    currentTime = +time
    roadTypeOfTime[time].forEach((carList, type) => {
        carList.forEach(carIndex => {
            crossRoadsSystem.add(type, carIndex)
        })
    })

    // 현재 시간에 빠져 나간 차량들
    // 다음 차량 추가 시간 까지 처리, 더 이상 차량 추가가 없으면 계속 진행
    while (currentTime < nextTIme || nextTIme === undefined) {
        const result = crossRoadsSystem.process(currentTime)

        // 교착
        if (result === 0) {
            // 더이상 진행이 불가하니 탈출
            break
        }
        // 차량 없음
        else if (result === 2) {
            // 작업할 대기 차량이 없으니 탈출
            break
        }
        // 정상 처리
        else {

        }
        currentTime++
    }


}
console.log(crossRoadsSystem.getRecord().join('\n'))

/*
키(초)를 읽으면서
waiting에 넣기


배열 읽기
초1, 초2
초1를 현재 초로 기록
waiting에 타입별로 index를 배열에 저장


초를 1씩 증가시키면서 차량 보내기, 앞을 pop시키면 좋은데 시간이 오래 걸리니 i 를 증가 시키는걸로


 */
#[HSAT_3회_정기_코딩_인증평가_기출]_교차로
#js

이 카테고리의 톡 더보기