SkillAgentSearch skills...

Lifty

Lifty - The Elevator

Install / Use

/learn @dabeaz/Lifty
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Lifty - The Elevator

Author: David Beazley (https://www.dabeaz.com)
Source: https://github.com/dabeaz/lifty

Copyright (C) 2025

Graydon decides that he's going to go visit his friend Fletcher. He arrives at his apartment building and gets in the elevator. However, instead of a typical building directory, the following puzzler is posted:

Baker, Cooper, Fletcher, Miller, and Smith live here. They each live on a different floor. Baker does not live on the top floor. Cooper does not live on the bottom floor. Fletcher does not live on either the top or the bottom floor. Miller lives on a higher floor than does Cooper. Smith does not live on a floor adjacent to Fletcher. Fletcher does not live on a floor adjacent to Cooper.

"Ah, hell, what kind of madness is this?" he mumbles. After turning over all of the solutions in his mind before arriving at the correct floor, he pushes the elevator button only to find that the elevator software has crashed.

"It's ridiculous," he thought, "that we computer people can't even make an elevator that works without crashing!" Indeed. How hard could it be? An elevator goes up and down. Doors open and close. Maybe it's kind of like a glorified toaster.

Overview

An elevator is an object from everyday experience that most people would claim to "understand." However, elevators are surprisingly devious. Thus, an elevator makes a great problem domain for all sorts of computer science problems involving algorithms, design, testing, systems, formal verification, software engineering, and more.

What you'll find here is a simulator of elevator hardware with none of the brains of elevator control. It's intended use is as an educational tool. Thus, think of it as an empty canvas for exploring various kinds of programming projects involving elevators (see the "Ideas" section at the end for possible projects).

The simulator models an elevator system consisting of a single car in a five-floor building. It's nothing fancy--the image below gives you a visual reference for the setup.

The hardware has the following features:

  • A single elevator car.
  • A motor that makes the car go up and down.
  • A door that can open and close.
  • A button panel inside the car.
  • Up buttons on floors 1-4.
  • Down buttons on floors 2-5.
  • Indicator lights on each floor that can show a direction.
  • A three-position key-switch to enable different "modes."

Certain elevator features such door open/close buttons are ommitted in the interest of simplicity (sic).

You can control the elevator by typing commands in the terminal or by sending network messages. The simulator can also report real-time events to a separate control program via the network.

The Simulator

The simulator is implemented in a file lifty.rs. This is a single-file Rust project with no dependencies. Compile it to create the lifty program:

bash % rustc lifty.rs

If you run it, you'll get output like this:

bash % ./lifty
Welcome!  I'm Lifty--a simulated elevator in a 5-floor building.

I'm just hardware, but you can press my buttons
(type below and hit return):

    Pn  - Floor n button on panel inside car
    Un  - Up button on floor n
    Dn  - Down button on floor n

If something goes wrong, I'll crash and you'll have to call
maintenance to restart the elevator control program.

[ FLOOR 1 | CLOSED     -- | P:----- | U:----- | D:----- ] :

The elevator is stopped on the first floor with the door closed. You can type commands after the :. Try pressing a few buttons by typing "P2", "U3", and "D5" separately. The output should change to the following:

[ FLOOR 1 | CLOSED   -- | P:----- | U:----- | D:----- ] : P2
[ FLOOR 1 | CLOSED   -- | P:-2--- | U:----- | D:----- ] : U3
[ FLOOR 1 | CLOSED   -- | P:-2--- | U:--3-- | D:----- ] : D5
[ FLOOR 1 | CLOSED   -- | P:-2--- | U:--3-- | D:----5 ] :

Here, the hardware has recorded some button presses (imagine that the buttons are now illuminated as in an actual elevator). However, there are no brains built into the simulator. Literally nothing happens. You can instruct the hardware to do things though. Try opening the door by typing "DO". You'll see the elevator status show "OPENING" for a few seconds before changing to "OPEN". The output will look like this:

[ FLOOR 1 | CLOSED   -- | P:-2--- | U:--3-- | D:----5 ] : DO
[ FLOOR 1 | OPENING  -- | P:-2--- | U:--3-- | D:----5 ] : 
[ FLOOR 1 | OPEN     -- | P:-2--- | U:--3-- | D:----5 ] :

Try closing the door by typing "DC". You should see the elevator status show "CLOSING" for a few seconds before finally changing to "CLOSED". Although the output is basic, the elevator is dynamic, has internal timing, and will change its state automatically (updating the output as needed). It might look weird to see all of the state changes printed in order, but you'll appreciate this feature when it comes to explaining what's happening or for debugging.

Try typing "MU" to have the elevator start moving up. You should see the floor slowly increment about every 3-4 seconds. Eventually the elevator will crash with a message like this:

[ FLOOR 1 | CLOSED   -- | P:-2--- | U:--3-- | D:----5 ] : MU
[ FLOOR 1 | UP       -- | P:-2--- | U:--3-- | D:----5 ] :
[ FLOOR 2 | UP       -- | P:-2--- | U:--3-- | D:----5 ] :
[ FLOOR 3 | UP       -- | P:-2--- | U:--3-- | D:----5 ] :
[ FLOOR 4 | UP       -- | P:-2--- | U:--3-- | D:----5 ] :
[ FLOOR 5 | UP       -- | P:-2--- | U:--3-- | D:----5 ] :
CRASH! : Hit the roof!
[ FLOOR 5 | CRASH    -- | P:-2--- | U:--3-- | D:----5 ] :

Again, the hardware is dumb. The elevator did not stop at any floor and just slammed into the top of the building. Once crashed, the elevator stays crashed and won't respond to any future commands until you issue a reset (R).

Giving the elevator bad combinations of commands will also cause it to crash. For example, telling it to open the doors and then move.

[ FLOOR 5 | CRASH    -- | P:-2--- | U:--3-- | D:----5 ] : R
[ FLOOR 1 | CLOSED   -- | P:----- | U:----- | D:----- ] : DO
[ FLOOR 1 | OPENING  -- | P:----- | U:----- | D:----- ] : 
[ FLOOR 1 | OPEN     -- | P:----- | U:----- | D:----- ] : MU

CRASH! : motor command received while doors open
[ FLOOR 1 | CRASH    -- | P:----- | U:----- | D:----- ] :

The simulator is pretty sensitive to timing related issues and various modal errors. For example, if you tried to open the doors twice:

[ FLOOR 5 | CRASH    -- | P:-2--- | U:--3-- | D:----5 ] : R
[ FLOOR 1 | CLOSED   -- | P:----- | U:----- | D:----- ] : DO
[ FLOOR 1 | OPENING  -- | P:----- | U:----- | D:----- ] : 
[ FLOOR 1 | OPEN     -- | P:----- | U:----- | D:----- ] : DO

CRASH! : door already open
[ FLOOR 1 | CRASH    -- | P:----- | U:----- | D:----- ] : 

Remote Access

Although the above example involved typing commands at the terminal, the simulator can also receive commands over the network using a UDP socket. Start the lifty program in a separate terminal window. Now, go to a different terminal and start Python (which provides a good environment for interactive experimentation). Try the following example:

>>> from socket import *
>>> sock = socket(AF_INET, SOCK_DGRAM)
>>> sock.bind(('localhost', 11000))
>>> sock.sendto(b'R', ('localhost', 10000))
1
>>> sock.sendto(b'DO', ('localhost', 10000))
2
>>>

The Lifty program should be showing an elevator with the door open like this:

[ FLOOR 1 | CRASH    -- | P:----- | U:----- | D:----- ] : recv: R
[ FLOOR 1 | CLOSED   -- | P:----- | U:----- | D:----- ] : recv: DO
[ FLOOR 1 | OPENING  -- | P:----- | U:----- | D:----- ] :
[ FLOOR 1 | OPEN     -- | P:----- | U:----- | D:----- ] :

Any command that can be typed at the prompt can also be sent to Lifty via a socket. All commands received in this way will be printed, but prefaced by a "recv:" to indicate that they were received over the network.

Events

Lifty also generates certain events that get sent to a control program. In the same Python example above, type the following to receive an event:

>>> sock.recvfrom(100)
(b'O1', ('127.0.0.1', 50903))
>>> 

You'll immediately see an "O1" event. This is something the simulator sent when the doors finished opening. Now, type this in Python:

>>> sock.recvfrom(100)
... blocked (waiting)

Python will be blocked waiting for a message. Go the Lifty prompt and type "DC" to close the doors. Lifty will briefly display "CLOSING" before shifting to "CLOSED" like this:

[ FLOOR 1 | OPEN     -- | P:----- | U:----- | D:----- ] : DC
[ FLOOR 1 | CLOSING  -- | P:----- | U:----- | D:----- ] :
[ FLOOR 1 | CLOSED   -- | P:----- | U:----- | D:----- ] :

The Python program should have now returned with a message like this:

>>> sock.recvfrom(100)
(b'C1', ('127.0.0.1', 50903))
>>>

The "C1" event means that the doors just closed on floor 1. Put the Python program into a loop like this:

>>> while True:
...     print(sock.recvfrom(100))
...

Now, type "MU" into the Lifty program to turn the motor on. You should see the following appear in the Python terminal before the elevator crashes into the roof:

>>> while True:
...     print(sock.recvfrom(100))
...
(b'A2', ('127.0.0.1', 50903))
(b'A3', ('127.0.0.1', 50903))
(b'A4', ('127.0.0.1', 50903))
(b'A5', ('127.0.0.1', 50903))

These are events indicating that the elevator is approaching a new floor. Again, the elevator is pretty dumb. It will keep moving unless you tell it to stop. Here's a modified Python example that illustrates stopping on the 4th floor:

>>> while True:
...     msg, _ = sock.recvfrom(100)
...     if msg == b'A4':
...         sock.sendto(b'S', ('localhost', 10000))
..
View on GitHub
GitHub Stars54
CategoryDevelopment
Updated2mo ago
Forks2

Languages

Rust

Security Score

80/100

Audited on Jan 29, 2026

No findings