I have a couple puzzles that I have given myself over the years. I thought I'd share them and hopefully see what others may have done as self assigned programming exercises.
One I've used for a very long time, and have done in at least four or five different languages, is an elevator simulator. It has multiple parts; elevator, the building that they're in, people that need to go places, and others things depending on how complicated you want to make it.
The elevator must be able to go from and to a specific number of floors. It might not start at the ground floor. It might not go to the top floor. It can only hold so many people. It takes time to go from floor to floor.
The building can have more than one elevator. It must have more than one floor (else the elevator to nowhere).
The people have to first enter the building. They have to choose a destination floor. They have to fit on the elevator. They have to get on and off.
One thing also needed is a controller/simulator to create the building, and then start feeding people to it. Each person in the building needs to be tracked and controlled and randomly be given places to go.
That's the "hard" stuff. The fun stuff, for me anyway, is trying to optimize the logic that the elevators use to move people the most efficiently. I always assume a single controller controlling all elevators, so they always know what the others are doing and what's needed.
Two of my breakthroughs that gave the highest building throughput, were giving elevators a staging floor to go to when there was no work, and allowing multiple floor button pushes to let the elevator know how many people want a specific floor.
The staging floor is best with a larger building with more elevators. If there's nobody needing a ride, and each elevator goes to a different floor spread evenly among the floors to wait, then there is always a fairly close elevator when someone needs a ride. They get picked up quickly.
The multiple pushes is basically just a count of how many people on the elevator need a certain floor. That is, if there are 10 people needing the 20th floor, and one person needing the 15th floor, you get better overall throughput by passing the 15th floor on the way up to let the 10 people off, then going back down to let the one person off. Yeah, not very fair to that person, but that gets a larger number of people to their destination quicker. The problem with this in real life is that once people learn the logic being used, there's nothing to stop that one person from pushing their button 100 times to get preferential treatment.
There are variations I've added, for things like express elevators and elevators getting stuck.
I first played with this puzzle in BASIC. A few other scripting and interpreted languages were tried. The C version ended up being pretty cool. Java was by far the easiest to write and became the most fun to play with.
So, what kind of programming exercises to you give yourself? Or do you?