Such is modern computing: everything simple is made too complicated because it's easy to fiddle with; everything complicated stays complicated because it's hard to fix.
Ugly programs are like ugly suspension bridges: they're much more liable to collapse than pretty ones, because the way humans (especially engineer-humans) perceive beauty is intimately related to our ability to process and understand complexity. A language that makes it hard to write elegant code makes it hard to write good code.
Constraints are advantages in disguise. Limited resources force you to make do with what you've got. There's no room for waste. And that forces you to be creative.
It comes from saying no to 1,000 things to make sure we don't get on the wrong track or try to do too much.
The cleaner and nicer the program, the faster it's going to run. And if it doesn't, it'll be easy to make it fast.
It's okay to figure out murder mysteries, but you shouldn't need to figure out code. You should be able to read it.
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Don't waste your time typing up that long visionary tome; no one's going to read it. Take consolation in the fact that if you give your product enough room to grow itself, in the end it won't resemble anything you wrote about anyway.
A design is "simple" if it follows these rules: Runs all the tests; Contains no duplication; Expresses the intent of the programmer; Minimizes the number of classes and methods.
A program is portable to the extent that it can be easily moved to a new computing environment with much less effort than would be required to write it afresh.
If you're willing to restrict the flexibility of your approach, you can almost always do something better.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.