Write, delete, write, delete, write
I know nobody writes code by hand anymore, but BEAR with me.
Everybody in software engineering knows the DRY1 principle. We've also come to terms with DRY being harmful when YAGNI2. As long as there's a SSOT3, there should be three instances of duplication before you attempt a refactor.
These are all good ideas worthy of their ubiquity. However, implementing them effectively requires future sight: a sense of when YAGNI, understanding the flow of data so you can ensure SSOT, and - of course - having a solution which meets your requirements.
What if I told you I had cracked time travel? That would be lying. However, there are many future universes tucked away in my git reflog. You see, ever since I started programming, I built up a habit of implementing the exact same thing multiple times. There is a graveyard of 200 perfectly good OpenGL sprite batching implementations. For every REST API endpoint that I implemented at PostGrid, there are 4 versions of it that never saw the light of day (or when it's crunch time, at least 2). It's not that these implementations were incorrect - they just didn't feel right.
The first implementation is just for exploring the problem space: I'll probably end up writing something complex, or slow, or both. Once I have a feel for the problem, I delete. Unencumbered by my freshman solution, I can begin with the end in mind. "I'm probably not going to need that", "ah yes the widgets are always multitudinous so there's no point processing them one at a time", etc etc. That's when the fun begins. I've probably overcorrected in my second solution. Perhaps there is essential complexity in the problem that can't be willed away. Or maybe the requirements themselves are wrong, and I've proven as much by implementing them twice and running into the same roadblocks. I delete again.
Now, it's finally time to write the solution.