Logic Building Before DSA
Six phases of problems that need no data structure you have not met — just conditions, loops, recursion and a list. The rung between syntax and algorithms.
Why Logic Before Data Structures
Most people who stall on their first DSA problem do not lack knowledge of arrays. They lack the habit of turning a sentence into steps. You can recite what a hash map is and still freeze at "find the first non-repeating character", because the gap is not the structure — it is the reasoning that decides to use one.
This page is the rung between knowing your language's syntax and starting Big-O. Six phases, each one a small set of problems that can be solved with nothing but conditions, loops, recursion and a list. No data structure you have not met yet, no algorithm names — just the thinking.
The Dry Run — Your Most Useful Tool
A dry run is tracing your code by hand, one line at a time, writing down what every variable holds after each step. It is the single technique that separates people who debug quickly from people who guess.
def mystery(n): total = 0 while n > 0: total = total + (n % 10) n = n // 10 return total mystery(472)
Now the trace table. One row per pass, one column per variable:
| Pass | n at start | n % 10 | total after | n after |
|---|---|---|---|---|
| 1 | 472 | 2 | 0 + 2 = 2 | 47 |
| 2 | 47 | 7 | 2 + 7 = 9 | 4 |
| 3 | 4 | 4 | 9 + 4 = 13 | 0 |
| — | 0 | loop ends | 13 | — |
Three rows and the function names itself: it sums the digits. You now also know the loop runs once per digit, which is the beginning of complexity analysis without the vocabulary.
Two habits worth forming alongside it. Pseudocode first: write the steps in plain language, then translate. And know your edge cases before you start — zero, one element, empty input, negatives, duplicates, the largest value. Most failed submissions are correct logic meeting an input the author never considered.
Phase 1 — Conditions & Boolean Logic
Goal: make a decision correctly, including when several conditions interact.
What you are practising: relational operators, and / or / not, nested conditions, ordering your checks so the first true branch is the right one.
# Wrong: 95 prints "Pass", because the first true branch wins if score >= 40: print("Pass") elif score >= 75: print("Distinction") # Right: test the narrowest condition first if score >= 75: print("Distinction") elif score >= 40: print("Pass")
Work through these:
- Print whether a number is positive, negative or zero — three outcomes, not two.
- Decide whether a year is a leap year. The rule has three parts and most people get the century case wrong.
- Take three numbers and print the largest, without using a built-in max.
- Classify a character as uppercase, lowercase, digit or symbol.
- Given three side lengths, decide whether they form a triangle, and if so whether it is equilateral, isosceles or scalene.
- Given a temperature and whether it is raining, decide between four clothing recommendations. Write the conditions so no input falls through with no answer.
Phase 2 — Loops & Patterns
Goal: repeat work deliberately, and know how many times the body will run before you press run.
What you are practising: for and while, accumulator variables, nested loops, break and continue, and reading a loop by its invariant.
total = 0 # start from the identity for d in digits: total = total + d # one step per item print(total)
A nested loop is not twice the work — it is the work squared. Two loops over the same n items run n² times, which is why a pattern that prints instantly for 10 rows crawls at 10,000.
Work through these:
- Print the multiplication table for a number, then for every number to 10 — the second is the first inside another loop.
- Sum the digits of a number, then reverse it. Both are the same loop with a different accumulator.
- Decide whether a number is prime. Then find every prime below 100. Stop the inner loop as soon as you know the answer.
- Print a right triangle of stars, then a pyramid. Work out the spaces before the stars on paper first.
- Compute a factorial with a loop, then the first n Fibonacci numbers.
- Given a series of inputs ending in zero, report the count, sum, largest and smallest in a single pass.
Phase 3 — Recursion
Goal: solve a problem by describing it in terms of a smaller version of itself.
What you are practising: the base case, the recursive step, trusting the call, and seeing the call stack unwind.
def factorial(n): if n <= 1: return 1 # base case: the smallest problem, answered directly return n * factorial(n - 1) # recursive step: assume it works for n-1
Work through these:
- Factorial and the nth Fibonacci number. Then trace how many calls Fibonacci makes for n = 6, and see why it explodes.
- Sum the digits of a number recursively — the same problem as Phase 2, now without a loop.
- Reverse a string recursively.
- Decide whether a string is a palindrome, comparing the outermost characters and recursing inward.
- Compute the greatest common divisor with Euclid's rule: gcd(a, b) = gcd(b, a mod b).
- Print every subset of a small list. Draw the decision tree before writing it — include this element or not.
Phase 4 — Arrays
Goal: reason about a collection: visit it, measure it, rearrange it.
What you are practising: traversal, running maximum and minimum, counting occurrences, two indexes moving through one list, in-place changes.
largest = items[0] # never start from 0 — negatives break that for x in items[1:]: if x > largest: largest = x
Work through these:
- Find the largest and smallest value in one pass, not two.
- Find the second largest. The obvious approach fails on duplicates — decide what you want it to do first.
- Count how many times each value occurs.
- Reverse a list in place, using two indexes that move toward each other.
- Move every zero to the end while keeping the order of the rest.
- Find the elements that appear in both of two lists, and then those in one but not the other.
Phase 5 — Strings
Goal: treat text as a sequence you can measure and rebuild.
What you are practising: indexing and slicing, character classification, building a result piece by piece, comparing two strings.
A string is an array whose elements happen to be characters — every Phase 4 pattern applies. What changes is that in most languages strings are immutable, so "modifying" one means building a new one.
result = "" for ch in text: if ch not in "aeiou": result = result + ch # a new string each time — fine here, O(n^2) at scale
Work through these:
- Count the vowels, consonants, digits and spaces in a sentence.
- Reverse the words in a sentence without reversing the letters inside them.
- Decide whether a string is a palindrome, ignoring case and punctuation.
- Find the first character that does not repeat.
- Decide whether two strings are anagrams, without using a built-in counter.
- Compress a string so that "aaabbc" becomes "a3b2c1", and leave it unchanged when compression would make it longer.
Phase 6 — Mixed Challenges
Goal: choose the approach yourself, with no chapter heading telling you which tool to reach for.
What you are practising: everything above, combined — this is what a real interview question feels like.
Solve these without deciding in advance which phase they belong to. That choice is the skill.
Work through these:
- Given student marks, report how many passed, the average, and the highest scorer.
- Validate a password: minimum length, at least one uppercase, one digit and one symbol. Report which rule failed, not just true or false.
- Print the frequency of each digit in a number.
- Count the prime numbers in a list.
- Print every palindromic word in a sentence.
- Given a list of daily temperatures, find the longest run of consecutive rising days.
When You Are Ready for DSA
You are ready when you can read a problem, describe the steps aloud, name the edge cases, and trace your solution on paper before running it. Not when you have solved all thirty-six — when the process feels routine.
From here, Big-O Notation gives you the language for the cost you have already been feeling, and Arrays & Strings starts the patterns proper. The DSA roadmap lays out the full order.
Quick Quiz
Five questions on the habits, not the syntax.
if score >= 40: "Pass" elif score >= 75: "Distinction" — what does 95 print?largest = 0 a bug?