LEARNING · STAGE 00 · PROGRAMMING BASICS

How a Programmer Thinks

There won't be a single line of code in this lesson. Instead, there's one chest with a combination lock that needs to be opened without any lockpick. It's interesting to watch how you yourself, from scratch, arrive at the same patterns of thinking programmers use — not just one pattern, but several at once, often quite unlike each other.

01What You'll Learn

  • Two different, equally legitimate ways to make a computer find a solution — brute force and reasoning based on constraints
  • How a human plan for solving a problem turns into an algorithm — a precise step-by-step procedure — even before any programming language appears
  • Eight different lenses through which you can look at a stuck problem — not a "do this, then this, then this" recipe, but a set of perspectives you have to choose between
  • Why "sit down and start writing code right away" is almost never the first step — and why even a knowingly clumsy plan is better than no plan at all

02Why This Comes Before Syntax

The previous lesson introduced statements and expressions — the building blocks of the language. But blocks alone don't build anything: knowing what an if is doesn't mean you'll be able to apply it to a specific unfamiliar problem on the first try. Between "I know the words of the language" and "I can solve a problem" lies a separate skill that is rarely explained explicitly — because by the time a programmer gains experience, this skill works on autopilot and they no longer think about it themselves. Here it's easier to isolate and demonstrate it without syntax — syntax, the first time around, draws too much attention to itself.

03The Chest with Three Dials

In a game you might someday build, there's a treasure chest. The lock on it consists of three rotating dials, each with digits from 0 to 9. That makes a thousand possible combinations, and trying them all by hand would mean standing at the chest for a very, very long time. On the wall nearby is a faded inscription left by someone long ago:

  1. The sum of all three digits is 12.
  2. The first digit is exactly twice the third.
  3. The second digit is odd.

Before reading further, it's worth pausing — but not on the question "what is the chest's code." On a different one: if the code were being searched for not by you, but by a mindless machine that can't "just see" the answer and can only carry out precise instructions one after another — what would you tell it to do? A computer can't guess. It needs a procedure that can be executed mechanically, step by step, without any real understanding of what a chest, a code, or a treasure is.

04Two Ways to Make a Computer Find the Code

There isn't one good answer here, but two — and both are honest. Below are both in turn, not just the shorter one.

Method A: brute force. The computer doesn't need to understand anything about the sum, parity, or the relationship between the digits as a unified system — it only needs to be able to check three separate facts about one combination and repeat that check a thousand times in a row. Here is that procedure, laid out so it can be executed without thinking at all:

  1. Take the next unchecked combination, starting with 0-0-0.
  2. Check: is the sum of the three digits equal to 12?
  3. If yes — check: is the first digit equal to twice the third?
  4. If yes — check: is the second digit odd?
  5. If all three checks pass — remember this combination as a suitable one.
  6. If any check fails — discard the combination and return to step 1 with the next one.
  7. Repeat until all combinations from 000 to 999 have been exhausted.

A thousand repetitions for a human turning dials by hand is pure torture. For a machine that can repeat the same thing without irritation or fatigue, it's less than a second of work. Method A isn't clever, but it's easy to explain and easy to verify: there's simply nowhere to make a mistake, because it requires no guesses, only patience. It's not a "wrong" algorithm — it's a working algorithm with a specific cost: it pays with time where thought could have been.

Method B: narrow the search space by reasoning. Since we're not a mindless machine, but humans with limited patience, it makes sense to look for a way not to blindly try a thousand options, but to first take a closer look at the clues themselves — they're clearly not given for nothing, but precisely so that an exhaustive search of this size wouldn't be needed at all.

Let's translate the condition from human language into a language that's more convenient to work with — let's denote the digits with letters. Let the first digit be A, the second B, the third C. Then the three clues from the wall turn into three equations: A + B + C = 12, A = 2 × C, and "B is odd." The condition hasn't become shorter, but now it can be worked with in pieces, rather than holding a long sentence entirely in your head.

Which of the three equations should you start with? Not the first one — it ties all three letters together at once and by itself barely narrows anything down. You should start with the "tightest" condition — the one that most strictly limits the choices. A = 2 × C is the most suitable: if C is an ordinary digit from 0 to 9, then A, being twice as large, cannot be greater than 9 — which means C cannot be greater than 4 at all. One equation just cut the range for C from ten options to five (0, 1, 2, 3, 4) — and at the same time immediately determined A for each of them: 0, 2, 4, 6, or 8.

All that remains is to substitute each of these five pairs into the first equation and check the third. Since A + B + C = 12, then B = 12 − A − C, and since A is always twice C, then B = 12 − 3 × C. Let's go through all five values of C in order, without skipping anything:

CA = 2×CB = 12 − 3×CB odd?
0012fails — 12 is not a single digit
129passes — code 2 9 1
246even — fails
363passes — code 6 3 3
480even — fails

Out of the thousand possible combinations, exactly two remain: 2-9-1 and 6-3-3. Both perfectly fit all three clues simultaneously — the inscription on the wall doesn't name a single code; it simply didn't anticipate that someone would honestly write out the conditions step by step instead of immediately trying everything by hand.

Notice that both methods carry the task through to completion, and both are legitimate algorithms — not one correct one and one "for the lazy." Method A requires almost no thought, but requires a thousand checks. Method B requires a few minutes of reasoning, but reduces the work to two checks. Which one to choose depends on what you have more of at the moment: machine time or time to think. This same choice — trading computation for reasoning or vice versa — will come up again in the course when we talk about how some ways of solving the same problem are faster than others.

05From a Human Plan to an Algorithm

Method B above was described as reasoning — with all the "whys" and accompanying explanations. But if you extract only the actions themselves from it and discard the explanations, you get this:

  1. Denote the unknowns with letters: A, B, C — instead of "first, second, third digit."
  2. Write down all three clues as equations: A + B + C = 12, A = 2 × C, "B is odd."
  3. From the three equations, choose the one that most strictly limits the range of one variable — here it's A = 2 × C.
  4. Iterate only over the values of C allowed by this equation (0, 1, 2, 3, 4) — not all ten digits.
  5. For each value of C, compute A and B using the formulas and check the remaining condition — the oddness of B.
  6. Collect all values of C that passed the check — these are the solution candidates.
  7. Check the remaining candidates physically, on the actual lock.

This is no longer a story about numbers — it's an algorithm: a precise, finite sequence of steps that can be handed to someone else (or something else) and produce the same result every time. A computer doesn't understand what a "chest" or a "clue on the wall" is — but it perfectly understands a step-by-step instruction like "for each value of C from 0 to 4, compute…". In a few lessons, variables, conditions, and loops will appear — the very building blocks with which this plan will be written in C++. The plan itself won't change a single step — only the language it's written in will change: from Russian to code.

06Several Different Lenses on Programmer Thinking

So far, the lesson has followed one path of thinking — the path to solving this specific chest problem. But reducing programmer thinking to a single recipe would be a lie: it's more of a set of different lenses through which you can look at a stuck problem, and an experienced programmer doesn't go through them in order from top to bottom, but tries out which one fits right now — sometimes two lenses even suggest opposite moves. Below are eight such lenses, each with an example different from the chest, so it's clear: these aren't tricks for solving this particular puzzle, but habits of thinking that transfer anywhere.

1. A plan — even a knowingly clumsy one — is better than no plan at all. Method A from the previous section, trying all thousand combinations, is a bad plan by the standards of a human too lazy to turn dials a thousand times. But it's still a plan: it answers the question "what to do right now" at any moment, and that's the only thing that makes a plan a plan. The absence of a plan looks different: sitting down in front of a problem, trying something at random a couple of times, getting distracted, coming back, trying again — with no way of telling how much work has already been done and how much is left. Even a knowingly inefficient plan gives you something chaotic poking never does: the ability to stop in the middle and know exactly where you are.

2. The condition can be retold in your own words — and it's not wasted time, it's part of the work. The chest problem could have been formulated differently — for example, "on how many of the thousand codes does the clue author's trap hold" — and that would sound like pure brute force. But once the three clues were retold as three equations, the problem became a problem about the intersection of allowed values, with a completely different set of tools. Retelling also works in the other direction: sometimes, in trying to reformulate a problem, you discover you're asking for help with the wrong part — for example, looking for a way to speed up a function that actually shouldn't be called as often as it currently is.

3. Split the problem — holding everything in your head at once is more expensive than it seems. The three chest conditions weren't checked simultaneously, but one by one: first A = 2 × C cut down the list of options, then the sum was checked for the remaining five pairs, and only at the end — parity. Merging all three checks into one multi-story condition would be technically possible, but holding three interdependent requirements in your head at once and not mixing anything up is harder than going through them one at a time. A task that looks like one big step on paper almost always hides several smaller ones inside, which are easier to solve separately.

4. Start with the piece that's already clear — the rest will follow. In the chest analysis, the clearest piece wasn't a guess, but boring mechanics — substituting five values of C into ready-made formulas. It was precisely this, once done, that immediately showed which of the options were even worth checking further, and provided a foothold for the next step. Programmers stuck in front of a big unfamiliar task often waste time precisely because they try to understand the hardest part right away — instead of first doing the part whose solution is already obvious and seeing what it suggests.

5. Shrink the problem — temporarily remove part of the difficulty to free your head for the rest. If there had been only one clue on the wall — "the sum is 12" — the problem would be solved differently: you'd have to honestly go through all combinations where the digits add up to 12, and there aren't one or five of those, but several dozen. Working through such a reduced version first — not because it's needed in itself, but to understand how brute force works at all before adding the remaining conditions to it — is a legitimate working technique, not a surrender to the full problem.

6. Look for where this problem has already appeared in different clothing. Behind the computational essence of the chest problem is a question that arises constantly in programming under completely different decorations: "there are several numbers related to each other and a set of constraints on them — which combinations are allowed." The same question will come up when you need to pick a character's starting attributes so that their sum doesn't exceed a point budget, or to place items into limited-size cells. The form of the problem changes, but the inner skeleton doesn't; recognizing that skeleton through different decorations is the slowest skill to build of all the ones on this list, because it requires an already accumulated store of solved problems to compare a new one against.

7. Check by experiment, not by guesswork. At the end of the chest analysis, there were two remaining candidates, and checking them on the real lock isn't a shot in the dark, but a controlled experiment: it was known in advance exactly what was being checked and why there were exactly two candidates, not a hundred. A real guess would look different — turning dials without counting how many options were even left and where those particular digits came from. The difference between an experiment and a guess isn't in the result, but in whether you know in advance exactly what should happen if the hypothesis is correct.

8. Frustration is a signal to stop and change the angle, not to work harder. If at the "which equation to start with" moment the reader kept pushing head-on — trying options one by one manually, getting irritated that there are too many numbers — the right answer wouldn't be to "try harder" on the same path, but to stop and ask: which of the three conditions is the tightest anyway? Irritation with a problem almost always means not "the problem is too hard," but "the chosen angle of attack is wrong." Noticing that and switching to one of the lenses above is almost always faster than stubbornly continuing to push in the same direction.

These eight lenses aren't a checklist and aren't a sequence of "do this, then this, then this" steps: sometimes they suggest opposite moves (split the problem or simplify it entirely?), and choosing between them is already part of thinking, not something that can be computed in advance with a formula. The more different problems get solved over the course, the faster your hand will reach for the right lens, rather than all of them at once.

07Lessons Learned

  • Trying all 1000 combinations isn't a shameful algorithm, but a perfectly legitimate one; it just pays with time where reasoning pays with mental effort.
  • Not all three clues are equally useful as a starting point — you should start with the one that most strongly narrows the space of options.
  • Human reasoning, if you extract only the actions from it and remove the "why" explanations, turns into an algorithm — a precise step-by-step procedure that can then be written in any programming language.
  • A problem doesn't have to have a single formally correct answer on paper (both codes satisfy the condition) — sometimes the solution is found only at the last step, by physical verification.
  • "How a programmer thinks" isn't one recipe, but eight different, sometimes contradictory angles of view on a stuck problem.

08Check Yourself

Below are questions of different types: not just "what is this," but also "why," "what will happen," "explain in your own words." For each question, it's worth first covering the answer with your hand and thinking on your own — the answer opens separately, it won't run away.

Definition
What makes a sequence of steps an algorithm, rather than just a hand-wavy explanation?
Show explanation

Method B in section 05 shows this directly: once the actions were extracted from the reasoning and the "whys" removed, an algorithm emerged — a procedure that can be handed to someone (or something) else and produce the same result every time, even without understanding what a "chest" or a "clue" is. Length has nothing to do with it — Method A (brute force) is also an algorithm, even though it's explained in one sentence and executed in a thousand steps.

Why it matters
In Method B, the reasoning didn't start with the first clue on the wall (A + B + C = 12), but with the equation A = 2 × C. Why start there, instead of going in order from top to bottom?
Show explanation

Section 04 explains this explicitly: you should start with the "tightest" condition — the one that most strictly limits the choices. A = 2 × C immediately reduced the range of C from ten digits to five (0–4) and at the same time determined A for each. Had you started with the first equation in order, you would have had to go through noticeably more pairs before applying the remaining conditions.

Predict the result
Imagine someone starts substituting pairs of A and C into A + B + C = 12 at random, without narrowing the range using the equation A = 2 × C first. What will most likely happen?
Show explanation

This isn't the same as a full brute force of all 1000 combinations (option d) — the sum of three digits already on its own greatly reduces the search space compared to a full brute force. But there are noticeably more than five pairs satisfying only A + B + C = 12 — checking them without narrowing via A = 2 × C would take more steps than the final five pairs in the table in section 04. The order of applying conditions changes the amount of work, even if the final answer doesn't depend on it.

Explain in your own words
A programmer gets stuck on a problem, keeps trying the same approach in circles, and gets irritated that there are too many options to try by hand. Based on the eight lenses from section 06, what should be done first?
Show explanation

Lens 8 in section 06 says this directly: irritation with a problem almost always means not "the problem is too hard," but "the chosen angle of attack is wrong." The right answer is not to "try harder" on the same path, but to stop and ask which condition or which lens (splitting, simplifying, finding the tightest constraint) would fit better right now.

09Mental Warm-up

No code, just something to think about — the same patterns of thinking, applied to new material:

Warm-up 1: your own tight clue

Recall any everyday problem with several conditions at once (what to cook for dinner from what's in the fridge; how to seat guests at the table so no one quarrels) — and try to find the "tightest" condition in it, the one you should start with, rather than going in the order the conditions came to mind.

Warm-up 2: brute force or reasoning

Imagine the task "find in a phone book of 500 contacts the one person whose number ends in three specific digits." Describe method A (brute force) for it and think about whether method B even exists here — reasoning that would narrow the search faster than checking all 500 contacts in a row. Not every problem has a clever method B — sometimes honest brute force is the best you can do.

Warm-up 3: where would you start

Later in the course, a character program will appear that you'll be assembling piece by piece from lesson to lesson — it starts in the very next lesson. Without looking ahead: if you needed to store and display the attributes of a game character, which single attribute would you start with first and why? Keep your answer in mind — it will be compared with how it's done in the next lesson.

10What You Can Do Now

There wasn't a single line of code here, but that's exactly why it's easier to see the skill separately from the syntax it's usually wrapped in:

  • You can name two different legitimate algorithms for the same problem — brute force and reasoning based on constraints — and explain what each one pays for the other's savings.
  • You can turn human reasoning into a step-by-step plan with all the "whys" removed and only the actions left — that is, into an algorithm, and not just an explanation.
  • You can notice that the order in which conditions are listed doesn't have to be the order in which they should be applied — and start not with the first condition, but with the one that most strongly narrows the choices.
  • You can recognize at least one of the eight thinking lenses in someone else's, non-toy context — in a compiler error message, in a bug hunt, in an unfamiliar .lab-task problem — and not only where it's specially demonstrated on the chest.

11In Short

  • One problem can have several legitimate solution algorithms — brute force and reasoning based on constraints — and the choice between them depends on what you have more of: machine time or time to think.
  • A human plan, if you remove the explanations and leave only the actions, is already an algorithm; the code will come later, but the sequence of steps itself won't change.
  • When you have several constraints, start with the tightest one — the one that most strongly narrows the space of options.
  • Programmer thinking isn't one recipe, but a set of eight different lenses (plan, retelling, splitting, starting with what's clear, simplifying, analogy, experiment, dealing with frustration), between which you have to choose anew for each new problem.
🎮 How does this relate to Unreal Engine?

The same sequence of moves — reformulate, find the tightest constraint, break it into steps, check what remains by hand — is exactly what happens when debugging a mysterious bug in Blueprint or C++: first you reduce the reproduction to a minimal case (you simplify the condition), then you check assumptions one by one instead of guessing about the whole system at once (you break it into steps), and only at the end do you actually run it and see what happens (experiment). None of these moves is specific to any particular engine API — that's exactly why they won't become obsolete along with the next version of Unreal.