How can I help my students to think algorithmically?

I teach 13-14 year old boys an "Introduction to Computer Science" course. For most of them, it is their first structured coding experience.

Before we even touch an IDE, I have them walk through problems like this:

Devise an algorithm that calculates a user’s paycheque.

The program will begin by welcoming the user.
It will then ask the user to input their hours worked.
It will then ask them to input their rate of pay.
It will then calculate their total pay. You may assume no deductions due to taxes, fees, dues, etc... The program will then exit with an appropriate exit message.

The correct answer usually looks something like this:

Begin
print welcome
input hours
input rate
pay = hours * rate
print pay
print goodbye
End


A progression to flowcharts then follows.

I guess what I'm asking the group is "How do you teach students of this age and ability to think algorithmically?". I've been teaching C.S. to this age group and ability level for about 15 years or so now. I find that the problem statement/algorithm/flowchart model is about 95% effective. I'd estimate that only 5% of the students that I encounter can't break the problem statement/pseudocode barrier. I'm always looking to solve this problem so any constructive criticism this group can offer is greatly appreciated. Even age appropriate resources would be deeply helpful.

• I don't see how flow charts help. As for as I can see, they are a legacy from before we worked out how to create compilers (This could also be said for pseudo code, however I think that pseudo code is of use when learning your first programming language). Around the time of the first compiler there was a paper “goto considered harmful”, flowcharts are full of gotos, and are harmful. Jun 15 '17 at 18:06
• @richard I start teaching about flowcharts and algorithms and programming in general by saying: "CPUs can only do 5 things - fetch, store, arithmetic, compare, branch." This has always been true, and as far as I can tell, always will (until we emulate neurons or develop quantum computing). So, flowcharts are actually the most accurate translation of a high-level language algorithm in to what will happen when the program is run. Knowledge is power. It makes clear that languages (roughly 400 commonly used ones these days) are only a convenience between the mind and the hardware.
– user737
Jun 16 '17 at 13:42
• Maybe the problem isn't so much the logic and structured flow as I hear from reading your comments, but really the parsing and translation of terms for each statement. Jun 16 '17 at 14:12
• @nocomprende I agree that when teaching low-level programming then flow charts could be useful. I disagree about the 5 things (compare is arithmetic), there for there are 4 thinks (also logic is arithmetic and arithmetic is logic). You could also condense fetch and store into move, now there are only 3 things. This is the von-noumen architecture (harvard as well). There are however other architectures. Jun 16 '17 at 16:03
• Agreed with other users that using common tasks (sandwich, brushing, etc..) is better. I use shoe tying. Yours is too broad a scope. The site interaction you describe does stuff out of scope from the original description ("Devise an algorithm that calculates a user’s paycheque"). An algorithm is not welcome messages and exit messages. Tying your shoes doesn't include picking shoes to coordinate with your outfit from the closet. Making a sandwich doesn't mean harvesting the grain to make bread. Jun 17 '17 at 3:33

Rather than giving them processes to model algorithmically, have them start coming up with algorithms for everyday activities. Here is the formal assignment I have students complete: CS50 AP - Everyday Algorithms.

They begin with a simple pseudocode example:

1   look out the window
2   if it is raining outside
3      put on your rain boots
5   go outside


After they get comfortable with pseudocode, students write their own simple algorithm:

Okay, now you’ve learned a lot about algorithms and pseudocode. Perhaps we should try writing a few—three, to be precise. First, write up algorithms (both in sentence form and in pseudocode) for how to:

• brush one’s teeth

• eat an orange

Next, think of something that you do every day or nearly every day. Write an algorithm in sentence form and in pseudocode for how to do the thing you’re thinking of.

Students will take more ownership and may understand it new ways if they are coming up with the processes to model based on something important to them. While your example certainly works well, what about students for whom getting a paycheck is unfamiliar territory? You want to use a student's prior knowledge to your advantage, so the focus is solely on the algorithm, not the algorithm and some other idea.

Another essential element I found to getting students to think algorithmically is to model it in all things I do at the start of the year. Everything is a process as follows: input -> algorithm -> output. Let's say I want to take attendance or assign seats. I think out loud with an algorithmic process. My input is an uncounted group of students, and my desired output is a counted group as a means of attendance. Here's the algorithm I use, which I borrow from CS50's first lecture at Yale:

1 stand up and assign yourself the number 1
3 one of the pair should sit down; the other goes back to step 2


The value of this exercise is it gets student moving. Differentiation is essential for teaching students to think in a new way. Get them moving and talking to each other. Make it relevant to their everyday experience.

• This is the exact approach my first programming teacher used on my class. Breaking down "How do you make a peanut-butter and jelly sandwich" in to individual steps is permanently associated with programming for me now. It was immensely helpful. Jun 16 '17 at 19:41

How do you teach students of this age and ability to think algorithmically?

I don't really think there's a silver bullet to this problem. To be able to think algorithmically, you need to solve lots of problems, over and over. Some students will naturally have the ability to be able to describe algorithms without much teaching, but it's not a universal skill, and it comes at different rates for different people.

In an ideal world, adapting the level of difficulty of the algorithms to design would be useful: get an easy algorithm right, and then move on to a harder one, until you get stuck, and then go back down until you master algorithm design for even complex problems. However, that would require a lot of attention to do in person, so to get that level of support, you need an automated solution.

I highly recommend Codewars as a good tool to practice solving simple problems that scale up in difficulty—I had great fun trying some myself a while back.

• A task (kata) is given with instructions, example outputs and (usually) pre-made unit tests.

• You input your solution, test it, then submit. Codewars runs it against (hidden) tests to make sure the solution is valid, and then if so, you gain points.

You can create 'Clans' (perhaps for your class) so a league table is shown—the gamification might be a good motivator for some.

The difficulty of the kata increases as you get better (and harder kata give higher rewards), so the difficulty should ramp up and help students develop their skills.

This, of course, does require students to be relatively comfortable with the syntax of at least one programming language. If you've not taught any of the language itself yet, you probably should do that before you teach algorithmic thinking—a basic handle on how a programming language is used would probably be useful so that students can understand what an algorithm can and can't do.

• See also: Code Golf SE. While I don't expect students to start golfing their code (<shudder>), the sorts of challenges that come up are the ones that are generally good to present. Particularly the ones tagged [kolmogorov-complexity] which is all about expressing something complex as a series of simpler instructions. Algorithms are for finding short cuts by doing the same operation multiple times instead of copy-pasting and why I don't like most of the other answers. Jun 22 '17 at 18:04

I remember a demonstration from early in my first college CS course (this was in 1998, almost 20 years ago!), where the professor brought in a loaf of bread, a butter knife, a jar of peanut butter, and a jar of jelly. He then asked the class to give him instructions to make a peanut butter sandwich, with predictably hilarious results. After we had finally created the first messy sandwich, he had us repeat the exercise, but this time we had to record the steps on the board in advance. Then he followed the steps, again with hilarious results.

The point, of course, was to first teach us that computer will always take things literally, always do exactly what you tell them, and that mistakes early in the process can cause good instructions later on to have bad results. It's important that both the algorithm be correct, and that each instruction that composes the algorithm is correct. It also demonstrated the degree to which we rely on common abstractions and idioms that are often not perfectly represented in the computer.

At the college age, I felt like it was kind of simplistic for us. But for 13-14 year olds this would be perfect.

• Please do not remove the parenthetical about the date. The remark isn't just a side-note; it shows that the demo had staying power on impressionable young minds. Jun 16 '17 at 15:11
• Quite right, my apologies. Jun 16 '17 at 15:16
• I did almost exactly this lesson for years, but I added a computer program into the mix - I created a PB&J simulator, with a syntax and a set of instructions. They had to open and close drawers with their two hands, take out plates, knives, etc... I pasted their "code" into my simulator, and if the end result was a sandwich, they were allowed to actually make it only following their own instructions. There were some peanut-buttery hands in that classroom ;-)
– Ben I.
Jun 16 '17 at 15:20
• I was going to recommend this. The younger the children the better it works. However, it's important not to focus too much on funny failures (as is tempting to do) if your doing this to start stressing algorithms in general. Make sure to try to act like a computer, including simply failing to do anything for some invalid input (rather then doing the wrong thing). if someone uses poor english syntax give them a syntax error. if someone tells you something too general tell them you don't now that method/keyword, try to focus on a small set of 'predefined' API calls you understand. Jun 19 '17 at 16:24
• Oh, also make sure you ask about peanut allergies ahead of time!! or maybe just be on the safe side and stick with a jelly sandwich. Jun 19 '17 at 16:25

Thinking algorithmically isn't always natural. In an algorithm, you're going to write down everything the computer is going to, then hit "go" and step away for a few microseconds while the computer does it. In most of our lives, there's more back-and-forth in our interactions, so it takes a while to get used to thinking in this one-pass approach.

Something I think would be helpful is an origami game. It's really hard, but an excellent introduction to thinking like this. The game works like this:

1. Teams are split into two groups (minimum team size of 2, obviously)
2. One group is given a folded origami creation and pictoral instructions on how to make it.
3. That group must create written (not pictural) instructions to make the object.
4. Those instructions are then given to the second half of the team, who have to create the orgami from those instructions. They do not get to see the pictorial instructions nor what the final product should look like.

A few rounds through that will quickly teach them what works and what doesn't.

It also makes you really appreciate your debugger!

The problem as described is simply translation from one firm of words to another, so in some senses, students may not really grasp what you are asking for. I think a more important thing to ask for is to construct algorithms from a less structured problem.

A flow chart is just another way to write the algorithm, not really a progression - and not necessarily useful.

I suspect one major challenge with thinking algorithmically is the ability to break down the problem into the right number of steps, with those steps at the right level of abstraction. People often tend to focus on either the parts that they know, or the parts that they don't know.

An approach that may help is successive refinement where you try to sub-divide the problem in small steps. Inputs and outputs being an obvious thing to try first. The aim is to avoid getting stuck in the minute details, or blocked on a part that you don't know where to begin. Progress on one area will often give some ideas about how to solve another.

I'm a bit confused by your question. Your exercise seems to involve some combination of…

1. Requirements gathering: what are the inputs, outputs, and formulas?
2. Translating the requirements to a conceptual model
3. Translating the conceptual model to pseudocode
4. Translating the pseudocode to code
5. Translating the pseudocode or code back to a flowchart (Why? In decades of programming experience, I've almost never found flowcharts to be useful. If anything, they encourage an if-then-goto mentality, which is the opposite of what you want to aim for.)

It's not clear from your question which parts of the exercise are provided to the students as givens, and which parts you expect the students to perform.

In any case, "Devise an algorithm that calculates a user’s paycheque" is much too open-ended a question for a beginner! All of those steps expect students to produce some output starting from a blank slate, which can be intimidating.

Furthermore, I'm not convinced that this exercise teaches useful computer science concepts. It may be a useful demonstration of what programmers do, but that's not quite the same thing.

As an alternative, I suggest giving exercises where the inputs, outputs, and expected behaviour are obvious. The correctness of the response should be easily testable.

For kids, you could try Code Combat or Code.org's exercises. Some of the exercises can be done in visual programming environments using drag-and-drop blocks (like Scratch or Snap), eliminating the fear that some students encounter when asked to write something starting with an empty screen. If you're looking for more "traditional" programming environments, you could try Karel exercises, which have been ported to a variety of programming languages. These exercises all encourage students to develop algorithms — mainly to move characters on a board in a specified pattern. In contrast to your open-ended exercise, these are highly guided activities, which gradually increase in difficulty.

Once students have mastered the concept of developing algorithms to solve problems with extremely well specified inputs and outputs, then they can be asked to apply those ideas to real-life problems, where the inputs are not fixed, the scope is unclear, and requirements are negotiable.

• This is a beautiful answer. Very well thought out. Welcome to CSE! I hope we hear more from you.
– Ben I.
Jun 17 '17 at 1:44

Since all the other great answers are all given, let me mention a minor one. Lateral thinking Puzzles are good for this. They help to teach children to think in a different manner by themselves and encourage general problem solving.

However, they can be used to teach one important part of algorithms, the need for rigor in your statements, if one chooses to go that route. Pick some of the easier lateral thinking puzzles, but threaten to answer questions exactly as a computer will.

You find that many times people ask questions different then they intend to. They phrase things wrong, or they hear one answer but assume you meant something else. If you are very very exact in your answering you can make a puzzle hard to solve simply because people interpert your answers very different from what you literally said.

I would also include things like "does not computer" for questions that aren't well phrased, some 'standard' ammusing response to questions that are not yes or no questions. etc. Most importantly, remember in your head some examples where you can see the children misunderstood your answers or made ralse presumptions. Then after a puzzle is solved show them their mistakes and explain to them how they lacked rigour in their questions and how that lead to confusion, it's a good analogy for how you need to approach computers that are 100% literal and do exactly what you told them to, but not always what you meant for them to do.

This works best with "false assumpiton" puzzles that are written in such a way as to trick people into assuming something about the premis that wasn't said. for example:

• use a pronoun to refer to someone who is also refered to by name, so they presume two people are relevant instead of one person refered to in two ways (aliasing!)
• Any puzzle that doesn't use humans as the premise, "Tom killed Jerry but no one cared, why?", because Tom and Jerry are a cat and mouse.
• Trick someone by confusing sex, talk about "Alice and Kris" doing something where people presume Kris is male and the puzzle the mystery is obvious if one realizes Kris is female.
• Other presumptions that are false. Maybe Alice and Kris went out on a date together, they saw a movie and then went out to eat, but after the dinner Kris refused to pay for Alice dinner and left immediately without giving Kris a ride back home. He proceed to complain about how horrible his date was to everyone the next day at school. Alice wasn't upset by any of this, why not?", turns out their both female and on a double date, Alice's dinner and ride home was provided by the boy she was dating and isn't offended that Kris didn't like the boy she dated.

This sort of questions teach the children to learn to check their presumptions and how to ask properly rigorous questions to verify information, even get's them into the mindset needed to debug broken code by knowing what to ask to narrow down a problem.

I've used these sort of things to prepare young kids for the mindset required for programming, but these were kids I was mentoring and spent a bit of time with. It takes a little time to do a puzzle with kids, and while I found they helped me to communicate programming ideas I don't know if they provide so much benefit as to warrant class time spent on them? If nothing else these could be good things to do during 'dead' time, before class officially starts, on the bus during a field trip, while waiting outside during a fire alarm, etc to entertain kids while sneaking in some extra training.

Sounds like you've tried everything already, but here are some suggestions:

• Use a scenario / problem that every student can relate to

Most of my lower ability 13-14 year old boys don't have much experience of wages, tax and jobs. Writing an algorithm for making a perfect cup of tea doesn't do much for them either. Drawing a flow chart for how to irritate a teacher and comparing it to how to get a merit / positive / reward / whatever the equivalent in your school is always a memorable lesson.

• Give them lots of practice at understanding pseudocode before asking them to write it

Getting students to physically act out instructions can be time consuming and patronising but can also be really helpful for students struggling to visualise the sequence. Getting students to take turns giving instructions to sort numbers (bits of paper stuck to a wall) is a good way of doing this. Alternatively, you can set some challenges like this so students can work through the process of following instructions, ideally with instant feedback if they get each one right.

• Give them broken algorithms to fix

This works really nicely as a team activity. First, students work in pairs to diagnose and fix problems in algorithms you give them and then they design algorithms for each other with some obvious mistakes. The mistakes could be using the wrong symbols in a flowchart (leading to a discussion about syntax errors), writing a statement that doesn't really make sense (leading to a discussion about needing crystal clear, unambiguous instructions) or writing an instruction that's just plain wrong (leading to a discussion about logical errors)

• One thing that helps in my experience (albeit with older students) is to give a pseudo-code cheat-sheet and insist that the problem has to be solved only using the building blocks on the sheet. In particular, you must insist that anything that is not on the list must be written using the building blocks.

So if at some point they need to fill an array with something, there is no magical "fill the array" step. The students have to first define it in terms of increment, for loops, or whatever you have in the pseudo-language. And that is the hard part. What do you allow in your pseudo-code? Side effects? Functions vs Procedure? By-value, and by-reference parameter passing? It all depends.

• One way to reach the point where you can actually write pseudo-code, is to start from slightly more general problem statements, then refine it in smaller steps, and then again, until you arrive toward something that is pseudo-code. In your example I would start the exercise by asking just "Devise an algorithm that calculates a user’s paycheque based on the hourly rate and the number of hours."

I would let the student work collectively while guiding them and only let them do the actual last step (English -> pseudo-code) individually. And gradually help them less and less. For instance a student might say "oh you multiply early rate by number of hours and done". Yes but where do you get the rate and hours from? "Huh? Maybe I need to read them from somewhere or ask the user". And what do you do with the result ? "Oh yes that's right I have to display it" etc... And then when you have all the bits, put them in order and express them using pseudo-language.

I just finished up 8th grade.

I took an Intro to Engineering/Robotics class as an elective this past semester. I have programmed (mainly in Python 3) before this class, and I was mainly excited for the Robotics part. When we started, the teacher talked to us about how the computer takes things very literally, etc, etc, and then - he had us pretend he was the robot. So he told us to "program" him to get to the door. Someone forgot to tell him to turn, so he literally walked into a wall. Another person got him too close to the door, so when someone else told him to lift up his arm - hit the door. So he walked us through that.

Then he gave us very simple exercises - turn the motor on at such and such speed for this time, and then stop it, and had us write out the pseudo code, check it with him, and then turn it into regular code, and so on. As the problems got more complex, the pseudo code got more and more important. One problem, the full solution's code was much more complex, and so he had most people do it an easier way, but he let me try the full solution, so I worked on it, and he had me diagram a part up on the whiteboard for him, and so on, and it worked.

I guess the point is, give an illustration - like the PB&J one that seems to be popular, or this one, and then emphasize pseudocode as they solve simple problems, and eventually, as the problems get more complex, it will serve them well. The key is to have them do tons of programming, and eventually it will come more naturally.

Another idea is to do a form of code golf - have people come up with solutions, pick a slower/longer solution, and encourage ideas to make it more efficient, and so on, until you have a much more ideal piece of code.

• Welcome to CSE! You are very articulate young lady. I hope we hear more from you as you continue to learn about computer science. :)
– Ben I.
Jun 17 '17 at 15:19

Even though it can be complicated, recursion gives a great algorithmic view of problems. I have seen quite a few students start to think in an algorithmic way after I introduce recursion (just very simple problems such as printing the individual characters of a string. I'll refer to this exercise as an example task throughout the answer).

This gives them the basic idea of what thinking in an algorithmic way means. I go with them every step of the way, and make sure that they all understand exactly what's going on.

Then, I go on to saying that the core of algorithmic thinking is breaking a problem into smaller problems that are very similar to one another (sort of like doing an operation on a tree; you preform on a node, and then on it's children, and so on).

Usually I find it useful to have a classroom discussion on how one deals with big problems/tasks. I lead them to the conclusion that they need to break it into smaller problems, conceptually, before they can write a code that tackles the big problems. This gets the notion of treating problems as a collection of easy tasks that are solved one at a time in a similar manner.

After saying this, I remind them the small recursive task from the beginning. All the program does is print the first letter of the given string. That's easy to the point of ridiculous.

This way, the students understand that algorithmic thinking is just breaking a problem into smaller problems that they know how to solve. A part of algorithmic thinking is turning the input into a form or structure that they can handle in an easy way. This is shown in the example task by turning a string, which is a bit more complex than a single character, into a single character. This is the process of simplification of the problem, which is essential in algorithmic thinking.

From students' feedback, this method works very well. In fact some students start searching (pun intended) for search algorithms and they quickly find and use alpha-beta pruning, minmax and others. They really get the idea of thinking algorithmically.

• Explain by saying: use your smarts to turn a problem in to a series of steps an idiot could do.
– user737
Jun 16 '17 at 13:55
• @nocomprende that's really non constructive for the students Jun 16 '17 at 13:56
• ' 'I was agreeing with you. ' '
– user737
Jun 16 '17 at 13:58

So far in my career, when I have a student who just doesn't seem to get it (and there is no obvious discernible cause) it very often comes down to one of two problems.

The first is mutability, which I wrote a little piece about here. Kids who can't easily trace how values will change need explicit practice in this concept before they will really be able to follow what is going on in imperative languages, and it can take a surprising amount of practice to help them to really get it. The fact that it's so easy to describe is disarming, because we think they get it. And the kind of extremely simple code that we might use to determine understanding often doesn't trigger the kinds of incorrect responses that would naturally call teachers to action. However, as soon as the code itself starts gaining any complexity, having a cloudy notion of mutability is a game-stopper, pure and simple.

The second is simple motivation. For the kids who aren't so quick with CS at the start, not being willing to put extra thought and effort into the topic halts their growth. I don't have a lot of generalized insight into how to fix this one. When I have unmotivated kids, they mostly just kind of muddle through.

• I have never understood why we don't let kids make up their own minds about what they want to study. Wouldn't it be great to have a room full of people who really want to be there? Why do we force people to learn things that they either are not going to be good at, or have no current interest in? Oops, reaching my question mark limit for the day...
– user737
Jun 16 '17 at 13:51
• It's the right question, and I agree with you. I try to give free choice in labs when I can, but sometimes kids stick with it past add/drop, and then you are all stuck with each other.
– Ben I.
Jun 16 '17 at 13:55

The biggest problem is moving students to a difficult algorithm before they have mileage with simple ones. The best way I've found is

a. Go over the classic small algorithms, especially array and string based. - e.g. find the sum, min, max, do a swap.

b. give students many small algorithmic problems to solve. I use the exercises at codingbat.com which were written Nick Parlante, a lecturer at Stanford. I give a lot of level 1 problems, and can usually get them to level 2 near the end of the semester.

Another thing I do is, every lab has a prelab consisting of a bunch of code interspersed with print statements, asking "What does this code print?" I believe that tracing code strengthens students' algorithmic thinking as well.

Finally, homework assignments before the lab with code tracing and writing code snippets also help students a lot.

Do you know about the initiative called Scratch?

It's a visual and algorithmical language, it can be useful as an introductory subject for your students.

In scratch you can visually build loops, conditionals, functions, and return events, it's a whole language that is more approachable to beginners, and maybe might incite more their inquisitive nature.

It helps by literally making them shape visually an algorithm or program, they could also share it with fellow students and get other's code from the community, it also has some fun features such as running a loop to play sounds or images.

It's also used briefly in CS50: Introduction to Computer Science from Harvard.

You might want to give it a try, it could help your students, especially since they are so young.

• Welcome to CSE! We're very glad to have you here. This answer needs a little work, though. How will this help OP's students to think algorithmically?
– Ben I.
Jun 16 '17 at 20:55
• In scratch you can visually build loops, conditionals, functions, and return events, it's a whole language that is more approachable to beginners, and maybe might incite more their inquisitive nature. It helps by literally making them shape visually an algorithm or program, they could also share it with fellow students and get other "code" from the community, it also has some fun features such as running a loop to play sounds or images. Jun 16 '17 at 20:58
• Good improvements. Keeping the quality of the questions and answers high here is a really big deal, because it's what makes the whole enterprise worthwhile. I hope to keep seeing you around the site!
– Ben I.
Jun 16 '17 at 21:00

Here's an enlightening blog post about teaching programming to elementary school age children. They started without any computers at all by "programming" the teacher to walk from one corner of the class to the other using few simple commands. They then proceeded to use the Turtle Roy online programming environment which works like the Logo programming language and teaches you to think algorithmically, with visual results that are immediately visible.

• This is a good answer, but if you can add details about how Turtle Roy teaches you to think algorithmically, it would really make this into a great answer. Jun 17 '17 at 8:54
• Also, welcome to CSE!
– Ben I.
Jun 17 '17 at 15:19
1. Practice. Thinking algorithmically is a skill, and skills develop with focused practice over time. All of the relevant-to-life examples in previous answers are forms of practice that will result in some skills transfer to computer algorithms and also maintain student interest. You could add some basic mathematical algorithms that students know to the pool of practice exercises. Work through the algorithms for addition and subtraction and translate them into pseudocode. Something like "sort a deck of cards" is perhaps an ideal example because sorting is something that people sometimes do in real life and also something that we actually program computers to do (unlike "make a PB&J" or "perform addition in base 10").

Practice exercises should be assessed by the teacher and used to help identify areas where students are having conceptual difficulties with the material.

You can also give students a simple algorithm for debugging their code, which both reinforces algorithm following and also teaches the separate valuable skill of debugging their code. Steps could include "read the error message", "check for syntax errors", "google the error message", "explain your problem out loud to a rubber duck", etc.

2. Teach subskills. "Thinking algorithmically" is a huge skill with many subskills. Break algorithmic thinking into its subskills and teach them individually:

• Identify inputs and outputs.
• Identify repetition/repeatable steps.
• Identify success and failure conditions.
• Identify problems that lend themselves to an algorithmic solution and reframe problems in ways that clarify what the algorithm needs to do.
• Select and employ an algorithmic strategy to attempt to solve a problem.
• Test potential solutions on a number of datasets.

Learning and practicing these subskills explicitly will help to ensure that students are thinking and communicating very clearly about the problems they are trying to solve an the methods they are trying to use. This clear thought and communication is really the only way that students have a hope of understanding more complicated and abstract problems and solutions.

3. Teach strategies. Iteration and recursion, divide-and-conquer, dynamic programming, greedy algorithms. I found a power point presentation with some basic algorithm types and simple examples that demonstrate those types, many of which could be adapted for students at that age level. For example, the four-color map algorithm could actually be done by students on paper, and can be a lot of fun (I've used the four-color theorem in lessons before and the kids loved it); the counting money algorithm (make a certain amount of money with the least number of coins and bills) could also be very accessible and relevant for students.

Algorithmic thinking can perhaps best be taught completely apart from coding in the classes given programming language(s).

I might have one student tell another student how to solve a fairly easy problem on a whiteboard, but only communicating one step at a time using a constrained set of commands, for instance only one input, one arithmetic operation step, or one saved result at a time. Maybe have the algorithm developer write out the steps while the operator student is out of the room, them have the operator come back into the room and execute the written algorithm on the whiteboard.

One example might be averaging N numbers, where student A writes an algorithm, student B later provides the numbers one at a time, then student C uses the algorithm to compute a result, while the class watches.