Programming, in the end, comes down to writing a set of instructions. But the effort that has to be put in to write those few lines of codes sometimes can be overwhelming. Because, there are design issues, deadline issues, trade-offs between quality and time in hand, and many more issues.
The easiest part of programming in my view would be taking user inputs, and showing final program outputs. Luckily, many programs in the world do just about that - take the user input, process the data by applying well known operations through well known libraries and tools and show final output. An example of this easy life of programming can be: A simple database application which used to be developed through VB6 during the late 90's and early 2000's. Now a days, the more elegant form is .NET to do the same things. As long as our programming boundary bounds itself only to the simple well known stuff (e.g., addition, deletion, update, simple queries, etc. in case of database apps), I think we can call it programming, but not programming problem solving.
So, what can be a programming challenge in the database application I mentioned above? If the same application could provide undo/redo feature for addition/deletion/editing of rows, then some of us would have a programming problem in hand and henceforth faced with a programming challenge. Why I gave the database related example is I find myself a novice in database stuff and providing undo/redo feature (or state maintenance) in a database app is something I am not familiar with. That is why it is a programming problem for me. This is not something I see in a day to day database application and I am dealing with something I am not comfortable with.
Probably if you are experienced and have enough knowledge about design, then you could fit the problem into a pattern and you would have overcome the first challenge. Fitting into the proper pattern can be a fascination aspect in some cases, but it shouldn't be the toughest challenge.
In the above problem, If I decide to follow the command pattern (well known for undo redo features), maybe I have done the job well. But the real challenge begins after that. If I know that I should follow command pattern (I am not suggesting it's the best pattern for the undo redo stuff in a database), the real hurdle is - what variables to declare, what should be done in the command execute method, what states and bookmarks should be saved and how to write the unexecute method of the command class. Here the noticeable aspect is, the databases and their purposes vary from application to application, and this is where the uniqueness, talent and the insight of the programmer will come into play. The solution depends upon the project, its complexity, context and obviously the deadline.
In short, to me, a programming problem is a challenge that rises because of the uniqueness and context of the project. The solutions to the problems vary from project to project and here-in lies the challenge of programming. Basic skeletons to solve most programming problems in the world, up to now, exist. It's the programmer's job to tweak the skeleton, fit it according to the project demand, and give the solution a unique look. The more you gain knowledge, experience and skill, the easier is to tweak the skeleton.
And of-course, there are genius people who come up with new theories and new outlook to problem solving (thus creating new skeletons), but they are very few in numbers.
Yes, you can make life easier for a programmer by providing frameworks and library, but you cannot make the programming problems of a programmer easier... Solving the problems is where the art(!) of programming resides.