참고로, 시뮬레이션 결과 확인하실 때
개발자도구 열고 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