[ 팁 ] 2019 카카오 블라인드 공채 2차 오프라인 - Elevator --- ③ 코드

金弘均·2021년 10월 15일
0

Tip

목록 보기
6/6
post-thumbnail
  • 서버 돌리는 중...

  • 시뮬레이션 결과 확인하는 중...

참고로, 시뮬레이션 결과 확인하실 때
개발자도구 열고 console 창에서

let btn = document.querySelector('#ts')
let timer = setInterval(function() { btn.setUp(); show(btn.value); }, 1000)

clearInterval(timer)  <= 도중에 멈추고 싶을 때 입력

위 명령어를 입력하시면 보다 쉽게 엘레베이터의 움직임을 확인하실 수 있습니다!


  • 핵심 로직

2019 카카오 블라인드 공채 2차 오프라인 코딩 테스트 문제 해설
Collective control 과 유사하지만
내 경우는 좀더 로직을 간단히 하기 위해
엘레베이터가 가려던 방향에 승객이 없더라도
일단 맨 아래층 또는 위층에 도달한뒤
방향을 바꾸는 전략을 택했다.

가는 도중에 엘레베이터에 타려는 승객이 생길수도 있으니
그렇게 나쁘지 않은 전략같고
짧은 시간내에 로직을 작성할 수 있어
괜찮은 trade-off 라고 생각한다.

(그리고 라이언 타워에서 1897 timestamp 를 기록한다!!!)

def get_commands(verbose=False):
    with open('settings.json', 'r') as json_file:
        settings = json.load(json_file)
        token = settings['token']

    with open('condition.json', 'r') as json_file:
        condition = json.load(json_file)
        timestamp = condition['timestamp']
        elevator_directions = condition['elevator_directions']

    pprint(f'timestamp: {timestamp}, token: {token}')

    oncalls_data = api.get_oncalls()
    calls = {}
    for call in oncalls_data['calls']:
        id = call['id']
        calls[id] = Call(**call)
    elevators = {}
    for elevator in oncalls_data['elevators']:
        id = elevator['id']
        passengers = []
        for call in elevator.pop('passengers'):
            passengers.append(Call(**call))
        direction = elevator_directions[id]['direction']
        elevators[id] = Elevator(**elevator, passengers=passengers, direction=direction)

    if verbose:
        pprint(calls)
        pprint(elevators)

    bldg_floors = defaultdict(deque)
    for id, call in calls.items():
        bldg_floors[call.start].append(call)

    if verbose:
        pprint(bldg_floors)

    commands = []
    for id, elevator in elevators.items():
        command = None
        call_ids = []
        exit_ids = [call.id for call in list(filter(lambda _call: _call.end == elevator.floor, elevator.passengers))]
        bldg_floor = bldg_floors[elevator.floor]

        if elevator.status == STOPPED:
            if exit_ids:  # 내릴 사람들이 있을 때
                command = OPEN
            elif bldg_floor and len(elevator.passengers) < MAX_PASSENGERS:  # 기다리는 사람들이 있고 태울 수 있을 때
                command = OPEN
            else:  # 이번 층에서는 볼일 없으니 가던 길 감
                command = elevator.direction
        elif elevator.status == OPENED:
            if exit_ids:  # 내릴 사람들이 있을 때
                command = EXIT
                call_ids = exit_ids
            elif bldg_floor and len(elevator.passengers) < MAX_PASSENGERS:  # 기다리는 사람들이 있고 태울 수 있을 때
                command = ENTER
                while bldg_floor and len(elevator.passengers) < MAX_PASSENGERS:
                    call = bldg_floor.popleft()
                    call_ids.append(call.id)
                    elevator.passengers.append(call)
            else:  # 이번 층에서는 볼일 다 봤으니 문 닫음
                command = CLOSE
        elif elevator.status == UPWARD:
            if exit_ids:  # 내릴 사람들이 있을 때
                command = STOP
            elif bldg_floor:  # 기다리는 사람들이 있을 때
                command = STOP
            elif elevator.floor == MAX_FLOORS:  # 꼭대기 층에 도착했을 때
                command = STOP
                condition['elevator_directions'][elevator.id]['direction'] = DOWN
                with open('condition.json', 'w') as json_file:
                    json.dump(condition, json_file, indent=4)
            else:  # 가던 길 감
                command = UP
        elif elevator.status == DOWNWARD:
            if exit_ids:  # 내릴 사람들이 있을 때
                command = STOP
            elif bldg_floor:  # 기다리는 사람들이 있을 때
                command = STOP
            elif elevator.floor == 1:  # 1 층에 도착했을 때
                command = STOP
                condition['elevator_directions'][elevator.id]['direction'] = UP
                with open('condition.json', 'w') as json_file:
                    json.dump(condition, json_file, indent=4)
            else:  # 가던 길 감
                command = DOWN

        if command in [ENTER, EXIT]:
            command = {'elevator_id': elevator.id, 'command': command, 'call_ids': call_ids}
        else:
            command = {'elevator_id': elevator.id, 'command': command}
        commands.append(command)

    pprint(commands)
    return commands

profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글