Programming with pseudocode
- Formal model of pseudocode
- Types, expressions, and scopes
- Subroutines: contracts, pre- and post-conditions
- Pseudocode Operators and Patterns
- Design and quality standards
- Mini-cheat sheet
- Common mistakes and how to prevent them
- Connection with preparation for the Exam in Computer Science
- Five exercises with detailed solutions
- Pseudocode Author Self-Assessment Checklist
- Security questions
- Conclusion
Pseudocode is a formalized representation of an algorithm in natural language with a minimal set of strict constructs (variables, expressions, branches, loops, subroutines) sufficient for unambiguous human interpretation and easy translation into any programming language. Pseudocode serves as a bridge between the problem and the implementation: it captures the logic and invariants without distracting with the syntactic details of a specific language.
For the Unified State Exam in Computer Science, mastery of pseudocode is a practical skill: it is required for parsing conditions, constructing algorithms, analyzing complexities, proving the correctness of loops, and converting flowcharts into programs.
Formal model of pseudocode
- Algorithm as a tuple
An algorithm in pseudocode is considered a tuple
A = (Σ, V, T, S, R)
Where
- Σ – alphabet of lexemes (identifiers, literals, operators);
- V is a finite subset of identifiers (variables, constants, subroutine names);
- T – type system (integer, real, logical, strings, arrays, records);
- S – a set of correct operators (assignment, if, for, while, subroutine call, return/output/input);
- R – inference relations that define syntax rules and operational semantics.
Execution is the transformation of the memory state M (mapping V → value T) by sequential (or branching) application of operators S according to the rules R.
- Syntactic form
We use a structural indentation style (like Python/CLRS pseudocode). Basic elements:
- Assignment:
- x ← expr
- Condition:
- if cond then
- S1
- otherwise
- S2
- All
- Cycles:
- Bye, cond do S all
- for i from a to b step h do S all
- repeat S until cond
- Subroutines:
- function f(parameters): type
- body
- return value
- end
- Operational semantics (sketch)
- Assignment: evaluate expr in the current environment Env, write the result to x.
- Condition: if cond = true, execute S1, otherwise S2 (if any).
- While loop: predicate iteration – test cond before body; invariant Inv must be true before/after each iteration; variant (decreasing value) ensures termination.
- For loop: syntactic sugar over while with automatic counter change.
- Subroutine: When called, a new local environment is created; parameters are passed by value (default) or by reference (by explicit marking).
Types, expressions, and scopes
- Type system
whole // whole
thing // material
log // boolean
string // strings
array[T] // indexed collection
record {…} // aggregates (if necessary)
Implicit conversions are prohibited: if necessary, write explicitly int(x) or thing(x) explicitly.
- Scope
- Local variables: declared within a subroutine/block, not accessible from outside.
- Global: declared outside all routines (for learning purposes, avoid unless required).
- Shadows: A local name can overlap a global one; it is recommended not to overuse it.
- Subroutine parameters
- sign – transfer by value (copy);
- reference – alias to argument (changes are visible from the outside);
- result – return value; for functions – via return; for procedures – through the parameters via the link.
Subroutines: contracts, pre- and post-conditions
- Contract (Design by Contract)
For each function/procedure, we record:
name(parameter types) → result type
preconditions: P(args) // what must be true at input
postconditions: Q(args, result) // what is guaranteed at the output
Side effects: description (or not)
Example (argmin) :
function argmin(A: array[int]) → entry {value: int, index: int}
prev: |A| ≥ 1
post: A[result.index] = min(A) and this is the first occurrence
- Purity and Determinism
A pure function: the return value is determined only by the parameters, without I/O or changes to external state. In Unified State Exam (USE) problems, we strive for purity.
Pseudocode Operators and Patterns
- Linear design
input n
S ← 0
for i from 1 to n do
S ← S + i
All
conclusion S
- Branching
if x % 2 = 0 then
output “even”
otherwise
output “odd”
All
- Cycles and invariants
Template for proving the correctness of a while cycle:
invariant Inv: … // formulate
// base: Inv true before input
while you do the cond
// assume Inv is true at the start of the iteration
loop body
// prove that Inv is true at the end of the iteration
All
// after exit: Inv and ¬cond → goal proven
Example (finding the minimum):
m ← A[1]; i_min ← 1
for k from 2 to n do
if A[k] < m then
m ← A[k]; i_min ← k
All
All
Invariant: after processing A[1..k]: m = min(A[1..k]), i_min is the index of the first minimum.
- Arrays and processing algorithms
- Single-pass aggregates: sum/min/max/counters.
- Two-pointer method (two indices) for compression/filtering.
- Prefix sums for fast queries over segments:
P[0] ← 0
for i from 1 to n do
P[i] ← P[i−1] + A[i]
All
// sum over [l..r] = P[r] − P[l−1]
- Recursion and divide and conquer
function gcd(a:int, b:int) → int
if b = 0 then return |a|
return gcd(b, a % b)
end
Design and quality standards
- Naming: descriptive names in “snake” or “verbal” style – sum_digits, is_prime, read_count.
- Indents and block structure: each nesting level – +2–4 spaces.
- Comments on the matter: they explain why, but not what.
- Boundaries and extreme cases: n=0, empty arrays, negative values.
- Complexity: indicate time/memory estimate next to the algorithm:
complexity: time Θ(n), memory Θ(1) - Input/output: separate from computational logic – pure functions + I/O wrapper.
- Consistency of style: the same words for the same actions (“input”, “output”, “return”, “all”).
Mini-cheat sheet
Assignment
x ← expression
Condition
if condition then
S1
otherwise
S2
All
Cycles
fulfill the condition for now
body
All
for i from a to b step h do
body
All
repeat
body
while the condition
Subroutine
function f(a:type, b:type) → typeRes
// precondition: …
// postcondition: …
…
return the result
end
Prefix sums
P[0] ← 0
for i from 1 to n do P[i] ← P[i−1] + A[i] all
sum(l, r) = P[r] − P[l−1]
Parameter by reference
procedure swap(reference x:target, reference y:target)
t ← x; x ← y; y ← t
end

Common mistakes and how to prevent them
- Vague language: mixing colloquial and coded phrases – → ambiguity. Solution: use a fixed vocabulary of constructions.
- No invariants: the loop is written, but its correctness is unclear. Solution: formulate Inv and the termination variant.
- Index confusion : 0- and 1-indexing. Solution: declare the agreement at the beginning and follow it.
- Mixing I/O and computation: a function prints its result instead of returning it. Solution: Separate output from logic.
- Undefined edge cases: empty inputs. Solution: explicit preconditions/processing branches.
- Ambiguous parameters: does the argument change? Solution: mark ref/value.
- Lack of complexity estimation: It is difficult to justify the choice of the solution. Solution: write asymptotics.
Connection with preparation for the Exam in Computer Science
- Algorithmization: Pseudocode is the standard form of answer in programming/flowchart problems.
- Invariants and proofs: The while loop with a formal invariant is a frequent check of understanding.
- Structuring: translation from flowchart to pseudocode and back.
- Difficulty: Specifying Θ(n), Θ(log n) increases the parsing score.
- Working with arrays and strings: one-pass aggregate patterns, prefixes, two pointers.
- Features: return value, contract, no side effects – makes it easier to check automatically.
Five exercises with detailed solutions
Exercise 1. Formal invariant for the sum and number of positive
Problem: Write pseudocode that returns the sum of positive elements and their number for the array A[1..n], and prove its correctness using a loop invariant.
Solution (pseudocode):
function sum_pos(A: array[int]) → entry {S:int, K:int}
req: |A| ≥ 0
S ← 0; K ← 0
for i from 1 to |A| do
if A[i] > 0 then
S ← S + A[i]
K ← K + 1
All
All
return {S, K}
end
Invariant after step i:
S = sum of positive integers from A[1..i], K = their number. Base: i=0 – true. Transition: at i+1, either add A[i+1] and 1, or not; properties are preserved. After i=n, we obtain the required result.
Exercise 2. Argmin with the first entry
Condition. Implement pseudocode for the argmin(A) function (minimum and index of first occurrence). Provide preconditions/postconditions.
Solution:
function argmin(A: array[int]) → entry {value:int, index:int}
prev: |A| ≥ 1
m ← A[1]; i_min ← 1
for k from 2 to |A| do
if A[k] < m then
m ← A[k]; i_min ← k
All
All
post: A[i_min] = m and ∀j< i_min: A[j] ≥ m
return {m, i_min}
end
Complexity: time Θ(n), memory Θ(1).
Exercise 3. Prefix sums and queries over segments
Problem: Given an array A[1..n], answer q queries for “sum of elements on [l..r]”. Provide pseudocode with preprocessing and complexity estimates.
Solution:
procedure build_prefix(A: array[int], ref P: array[int])
P[0] ← 0
for i from 1 to |A| do
P[i] ← P[i−1] + A[i]
All
end
function range_sum(P: array[int], l:int, r:int) → int
return P[r] − P[l−1]
end
Complexity: preprocessing Θ(n), one query – Θ(1), memory Θ(n).
Exercise 4. Two pointers: filtering odd numbers
Condition: Compress the array in place, leaving only the odd elements at the beginning, preserving the order. Return the new length.
Solution:
procedure compact_odds(ref A: array[int]) → int
write ← 1
to read from 1 to |A| do
if A[read] % 2 ≠ 0 then
A[write] ← A[read]
write ← write + 1
All
All
return write – 1
end
Invariant: before each iteration, A[1..write−1] are the original odd ones in the same order. Complexity Θ(n).
Exercise 5. Proof of loop correctness: Finding the subarray with the maximum sum (Kadane)
Condition. Write Kadane’s pseudocode (meaning and bounds) and justify the correctness of the step.
Solution:
function max_subarray(A: array[int]) → entry {best:int, l: int, r: int}
req: |A| ≥ 1
cur ← A[1]; best ← A[1]
start ← 1; l ← 1; r ← 1
for j from 2 to |A| do
if A[j] ≥ cur + A[j] then
cur ← A[j]
start ← j
otherwise
cur ← cur + A[j]
All
if (cur > best) or (cur = best and (j − start < r − l)) then
best ← cur; l ← start; r ← j
All
All
return {best, l, r}
end
Invariant: cur is the maximum of the sums of subarrays ending in j; best is the maximum over all positions < j. The step is correct because the best sum ending in j either starts at j or continues the optimum at j−1.
Pseudocode Author Self-Assessment Checklist
- The contract of subroutines (pre/post conditions) is formulated.
- Invariants and variants of cycles are defined.
- Array boundaries and indexing conventions are clearly defined.
- Pure computational logic vs I/O is highlighted.
- Time/memory difficulties are assessed.
- Extreme cases (empty, negative, equal) are handled.
- A consistent style is used (lexemes, indents, keywords).
Security questions
- What are the advantages of pseudocode over flowcharts and concrete language?
- Formulate an invariant for the minimum search algorithm and explain its role.
- How do “by-value” and “by-reference” parameters differ in pseudocode semantics?
- Why is it important to separate I/O from pure functions?
- What is the asymptotic behavior of prefix sums in preprocessing and queries?
Conclusion
Pseudocode is a discipline of precise thinking: it makes an algorithm independent of language syntax, emphasizes invariants and complexity, removes ambiguity, and simplifies verification. For the computer science Exam, mastering pseudocode speeds up the process from an idea to a correct solution, improves the quality of argumentation, and reduces the risk of errors at boundaries and in loops. Master the suggested templates, follow the checklist, and work through the exercises—and your pseudocode will become a reliable support for solving any exam problems.
Explore More IT Terms
#
A
- A Guide to SQL Query Formatting
- A/B testing
- Agile
- Algorithm complexity in 5 minutes
- Algorithms and Data Structures in C#
- An overview of the C # programming language
- An overview of the Python programming language
- Anaconda Python
- Android
- Android App Bundle
- Android SDK
- Angular
- Ansible
- Apache
- Apache Airflow
- Apache Kafka
- Apache Tomcat
- App Store
- AppCode
- Array-based stack
- ArrayList
- ASCII
- ASP.NET
- Assembly Language Lessons
B
C
D
- Data Analytics: applications of data analysis in companies
- Data Engineer - Who is it, what does a data engineer do, and an overview of the profession
- Data modeling: what it is, types, and process steps.
- Data preprocessing: a complete guide for beginners and professionals.
- Data structure
- Data structures
- Defining Aliases
- Defining Arrays
- Deque
- Developing a Website from Scratch
- Digital data: understand the importance of this asset for businesses.
- Doubly linked lists
E
F
H
- Handling errors and exceptions
- How to effectively organize your workflow
- How to Learn Java: Tips for Beginner Developers
- How to Learn PHP: A Beginner's Guide
- How to Use S3 Storage in Kubernetes with CSI
- HTML
- HTML and CSS: Definition, Application, and Operating Principles
- HTML and CSS. Layout from Scratch: What to Learn, Where to Learn, and How Long Will It Take?
- HTML Frame Structure
- HTML Link Formatting
I
- if..else construction
- Inheritance in Java: A Complete Guide to Principles and Implementation
- Inserting an Image
- Interactive Python Tutorial – Learn Programming from Scratch
- Interview Problem: Finding a Deleted Element in O(N)
- Interview Scare: The FizzBuzz Challenge
- Introduction to C++
- Introduction to Machine Learning
- Introduction to programming languages
- IT Specialist Resume (CV)
J
K
M
O
P
- PHP lessons
- Private DNS server and its configuration
- Programmer's Dictionary
- Programming with pseudocode
- Python Code Formatting Guide: PEP8
- Python for data analysis: how to do it and main libraries
- Python Lessons
- Python Superstar: 5 Ways to Use the * Operator
- Python vs. Julia: Should You Replace Python with Julia?
S
- SFML Graphics Library Tutorials
- SQL commands: see what they are, what the main ones are + examples
- SQL Interview Questions and Tasks
- SQL Lessons
- SQL Stored Procedures
- SQL Syntactic Sugar: The COALESCE Function
- Stack
- Start in analytics: Python or R
- Statistical analysis: importance for decision making.
- String formatting in Python
- Swift Lessons
- switch/match construct
T
W
- What are databases, and why do they need DBMS and SQL?
- What do Linux distributions consist of?
- What is .NET and what is it used for?
- What is a GPU in a computer, in simple terms?
- What is Big Data? Introduction, Types, Characteristics, and Examples
- What is Golang and what is it used for?
- What is Haskell and what is it used for?
- What is Kotlin and what is it used for?
- What is Linux? The History of Linux
- What is machine learning, and how does it work?
- What is Power BI: everything about the data analytics software
- What is the C++ programming language?
- What is the OSI Model: A Complete Explanation of the Seven Layers and Their Role in Networking
- Where to start learning the C programming language?
- Which Linux distribution should you choose? A Linux distribution overview
