A bad habit of mine is jumping into a problem and trying to get a final & complete solution first time.
This means that I often get bogged down in the finer details and corner-cases before even the most significant functionality is complete because I am trying to deliver a gold-plated, perfect, thought-of-everything solution the first time.
I've found time and time again that it really helps to take a step back, acknowledge to yourself and/or others that there will be TODOs, and start building up the core functionality piece-by-piece starting from the fundamentals and working your way up to the details & corner-cases.
That might mean you play around with a few approaches for an hour, pick one and then commit once, or it might mean that you go through many refactorings and commits over a period of days or weeks.
Whatever approach you take, I've found the feel-good factor/reassurance of having working-code but with known TODOs really helps keep me going and avoids me getting irritated/burnt-out fighting with problems before I've got anything working.
It is not going to be perfect first time, but "mighty oaks from little acorns grow" as they say.
tl;dr - get the fundamentals working first, refactor later to handle the edge-cases or make it sophisticated/elegant.