BACKGROUND: I teach a C++ course with 300 students where the grade is based on programming assignments. We use automatic tools to assess the assignment correctness (using many unit-tests), code quality (using
clang-tidy), and to check plagiarism. In addition, the students present some of their solutions to the lecturer or TA in an online interview, and are graded by six quality criteria: organization, testing, correctness, efficiency, readability, and safety (I used recommendations from here for the rubric).
Last year, while I was interviewing students, I noticed a paradoxical phoenomenon: about half the students wrote perfect code (100% in all rubrics), and they all used very similar ideas - similar tricks, algorithms, etc. While the solutions were not entirely identical (so I cannot blame them for plagiarism), I was quite convinced that some of them shared their ideas with others. On the other hand, about half the students wrote mediocre code (60-70% in most rubrics), and their work was very different than others - I was quite convinced that they did all the work by themselves.
It turned out that I gave a lower grade to students who did all work by themselves, than to students who (probably) consulted other students and used their ideas. My grading scheme does not properly encourage students to do original work. Note that the course guidelines do not forbid students to consult each other. But, I still want to encourage students to make the best effort to solve the homework by themselves.
QUESTION: how can I design a grading scheme for programming exercises, which simultaneously encourage both quality and originality?