Most problems in computer science and software engineering are amenable to minimum viable solutions. You implement the simplest and fastest approach that satisfies the requirements. You don’t gold-plate or prematurely optimize, because You Aren’t Gonna Need It. When new requirements emerge, you incrementally adapt your implementation to meet them.
I often take this approach, and strive to be pragmatic. I can churn out code quickly when I need to. That said, in some situations incremental evolution is counter-productive. You have to commit to fundamental design choices up front, and the cost of changing them later is prohibitive. Developing non-trivial database schemas or ontologies is often like that, for example. I find those problems that require big-picture design and long-term thinking play to my strengths, and I enjoy working on them.
Similarly, I am drawn to problems where the user appreciates the difference between the minimum viable solution and a more involved one. Some graphical user interfaces are like this. So are systems where performance matters. You can create the initial solution quickly, and that’s useful as a working prototype and a tool for gathering feedback. But the difference between the prototype and a great finished product is a lot of detail work.
Not everyone wants to do that work, or thinks it’s worthwhile. Once the minimal solution is done they’re ready to move on. Most of the software engineers I’ve known were like that. Moving on when “good enough” is good enough is certainly better than gold-plating, but there are times when going further makes a big difference. When I’m mentoring students and junior colleagues I encourage them to think carefully about which parts of a problem are worth putting more effort into, and which not. In a world where most people are rushing to do the next thing, we should cultivate an awareness of quality as well as quantity.