The thing that taught me the most about solving problems was doing a bunch of autograded systems programming assignments, and reading about how other people went about doing the assignments
I developed this mindset (note this is for writing code for an autograder that no one else will read, it isn't going into a long term codebase):
- only do the bare minimum necessary to satisfy all criteria
- ignore any bloat that people suggest unless it's part of the shortest cost path
- figure out one way of doing something and just reuse it so that you can use the mental energy elsewhere
- reread the instructions so many times that you can mentally "see" all the logic before the first line gets written
- try to work in long bursts over a short term as opposed to short bursts over a long term because context switching is too expensive