You say they copy the intelligent students, so first watch https://www.ted.com/talks/carol_dweck_the_power_of_believing_that_you_can_improve?language=en
Then stop with the sumative assessment (Stop grading them). Encourage mistakes: I just heard of a company that has a mistakes wall. They seed it with a few famous quotes about mistakes. Then the leaders (teachers) add some and sign them. If others (students) add to the wall, then the first ones are praised (and awarded prizes), until it becomes the norm.
Help them to get in a situation where they are making small changes, making many small errors, experimenting, learning from feedback as the program runs. Give them code to change. Encourage small changes. Encourage testing after every change.
Before teaching programming languages, teach them how to program, and before that teach them how to solve problems: That is start unplugged.
Get them to do every problem manually. Teach them to think like a computer. Get them to solve problems like they are a stupid robot.
Then get them to document what they have done. As a set of steps. Get them to test it. Get them to ask their peers to test it. Show them how to test it. Get them to debug/fix it. Show them that you make mistakes. Show them how you fix your own mistakes.
Then when it is working, show them how to translate it, into the chosen programming language.