Skip to main content
  1. Documentation/

Algorithms - Complete Guide

··23 mins· loading · loading · · ·
Back-End Front-End
Adrien D'acunto
Author
Adrien D’acunto
Table of Contents

Algorithmics
#

An algorithm is used to describe in an intelligible manner the necessary steps to accomplish a task. It allows you to clearly explain the solution ideas to a problem, independently of any programming language. Thanks to the algorithm, the developer can follow the steps defined in a precise order to achieve the expected result.

It must be:

  • Understandable by a human person
  • Precise enough to be translated into a programming language

Basic Principles
#

An algorithm is a compromise between “natural language” and “computer language”, presenting the necessary steps to solve a clearly stated problem.

General Structure
#

Header #

The header describes the general information of the algorithm and contains information such as:

  • Name of the algorithm: title of the algorithm (for example: “Calculate the average”)
  • Objective: Clear description of the purpose of the algorithm (for example: “Calculate the average of exam grades”)
  • Data: the known data of the algorithm
  • Result: what the algorithm must produce as output
  • Principle: Principle(s) used in the algorithm

Body of the Algorithm
#

A body, the algorithm itself, is the set of finite operations necessary to obtain the stated result. The body is delimited by the reserved words: Begin … End

Example
#

Algorithm: AddIntegers
Role: Add two integers and store the result
Data: two known integers
Result: Storage of the sum of the two integer values
Begin
VAR result: INTEGER
result ← 5 + 3
End

In this example, we use two defined values (5 and 3) to perform the operation.

Variables and Constants
#

Definition of a Variable
#

A variable is a “label” intended to identify a space in the machine’s memory. In this space, you can store information that is “variable” over time.

It is defined with:

  • The reserved word: VAR
  • A name (identifier of the variable)
  • A type: the set of values accepted by the defined variable (Integer, Real, String, Character, Boolean, …)
  • And, optionally, a value: a value that will be stored in the memory of the device executing the final code

You define a variable when your algorithm requires you to keep AND modify information throughout the various operations.

The memory space allocated to this variable is therefore accessible:

  • In reading
  • In writing
VAR my_variable: INTEGER // Definition of space in memory
my_variable ← 5 // Assignment of value 5 to the variable
my_variable ← my_variable * 2 // Operation on the variable

At the end of the algorithm, the memory space defined by “my_variable” will therefore be worth 10 (5 x 2)

Definition of a Constant
#

A constant is also a space in memory, but unlike a variable, the value of a constant is defined at the moment of its declaration and cannot be modified during program execution.

It is therefore accessible only for:

  • Reading
CONST MY_CONSTANT: REAL ← 3.14116 // PI

There are “natively” constants in algorithmics:

  • PI which represents the famous value used in geometry. You can use the native PI constant in an algorithm.

You define a constant when you want to ensure that the value of this constant cannot be “mutated” during the execution of your algorithm and thus strengthen consistency during execution.

Summary
#

Keyword Description Assignment mandatory? Example
VAR Declares a variable No VAR counter
CONST Declares a constant Yes CONST PI ← 3.15

You can use pseudo-constants like PI or E (fixed values used as references).

Typing
#

When you define a variable or constant, you must imperatively associate a type with it. The type is the “family” of values that this variable can accept. For example, if you define the following variable:

VAR my_variable: INTEGER

The following operation is therefore impossible:

my_variable ← "Hello World"

On the other hand, if you define the following variable:

VAR my_variable: STRING

The following operation is possible:

my_variable ← "Hello World"

Alphanumeric Types
#

Alphanumeric types are the simplest types to define. They are defined by their family of values and their size.

Type Family of values Size (bytes) Examples
String Character strings N “Hello World”, “Hello”, “World”
Character Characters 1 “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”, “J”, “K”, “L”, “M”, “N”, “O”, “P”, “Q”, “R”, “S”, “T”, “U”, “V”, “W”, “X”, “Y”, “Z”

Certain “internal” functions and operations are applicable to these algorithmic types:

  • LEN(string): will return the length of the character string
  • SUCC(char): will return the character following the character passed as a parameter
  • PRED(char): will return the character preceding the character passed as a parameter

Numeric Types
#

Numeric types are types that allow you to store numeric values. They are defined by their family of values and their size.

Type Family of values Size (bytes) Examples
Integer Whole integers 4 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Real Real numbers 8 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0

Certain “operations” are applicable to numeric types:

  • Addition (+), subtraction (-), multiplication (*), division (/)
  • Integer division: DIV to retrieve the integer part of a division
  • Modulo: MOD retrieving the “remainder” of an integer division
  • Comparison operators: =, >, <, >=, <=, <> or !=

Logical Types
#

Logical types are types that allow you to store logical values. They are defined by their family of values and their size.

Type Family of values Size (bytes) Examples
Boolean True or False 1 TRUE, FALSE

Certain “operations” are applicable to logical types:

  • And (AND), or (OR), not (NOT), exclusive or (XOR) But can use comparison operators: =, >, <, >=, <=, <> or != as well as logical operators: AND, OR, NOT, XOR.

Complex Types
#

You quickly reach saturation when using simple types (string, character, boolean, number). Indeed, if you want for example to calculate an average, you would have to declare n variables of type real, then perform an addition of all these variables and finally divide by the number of grades to obtain this famous average. The work would be long and tedious, and generator of errors. Complex types will provide an effective response to this problem.

The Array Type
#

An array is a collection of data of the same type (including Array as well). An array can be a “finite” set for which you have defined the limits at declaration or not finite, in this case, it becomes a dynamic set.

VAR array: ARRAY[] OF STRING
VAR num_array: ARRAY[0..4] OF INTEGER
VAR array2array: ARRAY[] OF ARRAY[] OF REAL

The first declaration defines an unlimited array that can only contain character strings. The second declaration defines an array of 5 elements. Since the starting index is 0, you will count 0, 1, 2, 3, 4 indices, therefore 5 elements. The last declaration defines an array that will contain an array at each index.

Adding Data to an Array
#

To write data to an array, simply follow the array variable (or constant) with empty brackets.

VAR array: ARRAY[] OF STRING
// Write data to the array
array[] ← "Jean-Luc"
array[] ← "Elsa"
array[] ← "Max"

After execution, the array will therefore have the following form in your machine’s memory:

Index Value
0 “Jean-Luc”
1 “Elsa”
2 “Max”

Reading Data from an Array
#

After filling the data contiguously, you can read information by passing the desired index value between brackets in the array.

...
VAR second: STRING ← array[1]

Replacing Data in an Array
#

To replace data, simply redefine the value at the index in question:

...
array[1] ← "Achraf"

You can use a pseudo-function LEN(array) to retrieve the number of elements in this array.

Operations and Syntax
#

Algorithmics implements a certain number of operations (calculations) to arrive at a result. Operands (variables or constants) are subject to operations (comparison, addition, subtraction, multiplication or division) as well as more specific operations (integer DIVision, MODulo remainder of division), or even logical operations (NOT, OR, AND, XOR…).

Assignment
#

Assignment defines the value of a variable.

The sign = is forbidden for assignment.

We use the sign for assignment.

x ← 5

Operations
#

An operator is a symbol of operation allowing action on a variable (+, -, /, *, AND, OR, DIV, MOD, =, <, >, , , <>, …). An operand is an “entity” (variable, constant or expression) used by an operator. An expression is a combination of the two previous elements, evaluated during algorithm execution and has a value as well as a type.

Comparison allows you to compare two values.

Comparisons always return a boolean. (TRUE or FALSE)

Basic Comparison Operators
#

We use the following signs for comparison:

Operator Meaning Example Result
= Equal to x = y TRUE if x and y are equal
!= Different from x != y TRUE if x is different from y
< Strictly less than x < y TRUE if x is smaller than y
> Strictly greater than x > y TRUE if x is greater than y
<= Less than or equal to x <= y TRUE if x is smaller or equal to y
>= Greater than or equal to x >= y TRUE if x is greater or equal to y

Example of use:

IF grade >= 10 THEN
    display("Admitted")
ELSE
    display("Failed")
ENDIF

Another example:

IF age < 18 THEN
    display("Minor")
ELSE
    display("Adult")
ENDIF

Logical Operations
#

Logical operations allow you to combine logical conditions.

Operator Meaning Example Result
AND Both conditions must be true (x > 0) AND (x < 10) TRUE if x is between 0 and 10
OR At least one condition is true (a = b) OR (a = c) TRUE if a is equal to b or c
NOT Inverts the boolean value NOT(a = b) TRUE if a is different from b
NOR True if none of the conditions is true (A NOR B) TRUE only if A and B are FALSE
XOR True if only one of the two conditions is true (A XOR B) TRUE if A and B are different

Example of use:

IF (age >= 18) AND (nationality = "FR") THEN
    display("Registration possible")
ELSE
    display("Refused")
ENDIF
IF NOT(isValid) THEN
    display("Input error")
ENDIF
IF (grade >= 10) XOR (bonus = TRUE) THEN
    display("Makeup accepted")
ENDIF

Warning
#

An operator cannot be applied to different types:

VAR test: Boolean ← TRUE
VAR result ← "Hello" + test

However, in some cases, this rule can be waived:

VAR name: String ← "Marie"
VAR result ← "Hello" + name

In this case, the “+” operator plays the role of a concatenation operator. This is also the case if you concatenate a string and a number:

VAR result: STRING ← name + " " + 3.25

result will be worth: “Marie 3.25”

Input / Output
#

In general, an algorithm takes into account data “entering” (user input, data reading, etc.) and allows “writing” to the output device:

name: String
name ← read()
write("Hello " + name)

Conditional Instructions
#

You often have to opt for a series of treatments, depending on the evaluation of an expression:

Algorithmics allows you to handle conditions:

VAR data: Real ← read()
IF data < 0 THEN
    data ← data * -1
ENDIF
write(data)

The ELSE instruction is optional.

Case Treatment
#

It is sometimes necessary to compare a value to several others. When paying for a shopping “cart”, you offer the user several payment methods => card, transfer, check, mandate, …

This problem can be easily expressed by the CASE instruction:

CASE paymentMethod VALUES
    'card': 
        WRITE("Payment by card accepted.")
    'transfer': 
        WRITE("Payment by transfer accepted.")
    'check': 
        WRITE("Payment by check accepted.")
    'mandate': 
        WRITE("Payment by mandate accepted.")
OTHER:
        WRITE("Payment method not recognized.")
ENDCASE

Loops
#

It often happens that it is necessary to process a series of instructions several times in a row, on a finite set.

For the set of 10 glasses on the table, you must fill them.

On a set whose limit you don’t know: as long as there is sun, I enjoy the beach.

In the first case, we speak of unconditional repetitions, and of conditional repetitions in the other.

Unconditional Repetitions
#

The FOR loop allows you to repeat a series of instructions a “known” number of times:

FOR var: Integer GOING FROM startValue TO endValue STEP inc
END FOR
array: Array ← [125, 201, 302, 5, 15, 12]
FOR index: Integer FROM 0 TO 5 STEP 1
    display(array[index] * 2)
END FOR

This loop will go through each element of the array one by one and display the value multiplied by two at each occurrence: 250 402 604 10 30 24

array: Array ← [125, 201, 302, 5, 15, 12]
index: Integer ← 0
REPEAT
    display(array[index] * 2)
    index ← index + 1
UNTIL index = 6

Once again, the result will be identical, however:

  • The loop will be executed systematically at least once

  • The exit condition is evaluated at the end of the loop, which explains the value 6 instead of 5 at the end of the algorithm

FOR can also be used like this:

FOR EACH integer IN integers

Conditional Repetitions
#

A conditional repetition will execute the instructions while a condition is satisfied, or until a condition is satisfied. In the first case “while”, the instructions may not be executed, if the upstream condition is not satisfied. In the second case, the instructions will be executed at least once.

The WHILE loop allows you to execute an instruction while a condition is satisfied. If you need to make change from a given amount and a sum provided:

amount: Integer ← 15
sum: Integer ← read()
toReturn: Integer ← sum - amount
WHILE toReturn > 0
    toReturn ← toReturn - 1
END WHILE
array: Array ← [125, 201, 302, 5, 15, 12]
index: Integer ← 0
WHILE index < 5
    display(array[index] * 2)
    index ← index + 1
END WHILE

The result of this algorithm is the same as before.

Note however that in this case:

  • If you forget to initialize the index to a value less than the number of elements in the array, the loop may not be executed

  • You must increment the index value yourself

At execution:

index: 0 => display 250, index: 1 index: 1 => display 402, index: 2 index: 2 => display 604, index: 3 index: 3 => display 10, index: 4 index: 4 => display 30, index: 5 index: 5 => display 24, index: 6

=> Loop exit

Warning
#

Poorly formed loops can lead to “dead loops”, that is, loops that never stop, leading to application crashes.

FOR i: Integer FROM 0 TO 10 STEP 1
    display("index: " + index)
    index ← index - 1
END FOR
index: Integer ← 0
WHILE index < 5
    input: String ← read()
END WHILE

Arrays
#

Arrays can be thought of as collections, sets of information.

In an array, the information is “indexed”, in other words, each value in the collection is associated with a numeric “label” that gives its position in the array.

An array is declared in algorithmics as follows:

array: Array ← [15, 23, 201]

Access to the elements of an array is done by reference to the indices, the index of the value in question is passed between brackets:

aValue: Integer ← array[1]

An array is considered part of the family of “iterables”. An “iterable” is a variable that you can loop over:

oneArray: Array ← [15, 3, 20, 18, 1, 6]
FOR index: Integer FROM 0 TO 5 STEP 1
    display(oneArray[index])
END FOR

Algorithmic “functions” help handle loops: length(oneArray) returns the number of elements of the variable “oneArray”.

Using the LEN(array) function it is possible to rework the previous example in another way:

oneArray: Array ← [15, 3, 20, 18, 1, 6]
FOR index: Integer FROM 0 TO LEN(oneArray) - 1 STEP 1
    display(oneArray[index])
END FOR

Note the use of LEN(oneArray) - 1 in the loop. Indeed, there are 6 elements in the array but the index varies from 0 to 5.

Multidimensional Arrays
#

An array can have multiple “dimensions”, in other words, each element of an array can itself be an array.

To be able to display the contents of an array with n dimensions, it is therefore necessary to nest n loops:

oneArray: Array ← [[1,2],[3,4],[5,6], [7,8],[9,10], [11,12]]
FOR index: Integer FROM 0 TO LEN(oneArray) - 1 STEP 1
    FOR subIndex: Integer FROM 0 TO LEN(oneArray[index]) - 1 STEP 1
        display(oneArray[index][subIndex])
    END FOR
END FOR

Access to an element of an array with multiple dimensions is done as follows: oneArray[1][0] will allow you to access the value “4” (first index of the array present at index 1).

Structures
#

Definition of a Structure
#

A structure is a complex data type that groups several fields (or attributes) of different types under the same name. It allows you to make an algorithm more readable, organized, and closer to object-oriented programming (OOP).

You can see a structure as the equivalent of a simplified “object”, without the concepts of inheritance or encapsulation.

The benefit of the structure is to:

  • Make the code more readable and intelligible

  • Avoid multidimensional arrays that are difficult to understand

  • Be able to logically group information that belongs together

  • Possibility of adding internal functions (methods), which operate on the data of the structure

Example of a Structure
#

A structure is defined by the following syntax:

STRUCTURE Student
    BEGIN
        VAR name: STRING
        VAR firstName: STRING
    END
END STRUCTURE

This structure allows you to store information about a student (name and first name).

Usage:

CONST jl: Student
jl.name ← "Aubert"
jl.firstName ← "Jean-Luc"

Structures Containing an Array of Another Structure
#

A structure can contain an array of another structure type. Example: a student has multiple grades.

STRUCTURE Grade
    BEGIN
        VAR subject: STRING
        VAR grade: INTEGER
    END
END STRUCTURE

Then you enrich the Student structure:

STRUCTURE Student
    BEGIN
        VAR name: STRING
        VAR firstName: STRING
        VAR grades: Array(Grade)
    END
END STRUCTURE

Adding Internal Functions
#

A structure can also contain a function that acts on its own data (like an object method).

STRUCTURE Student
    BEGIN
        VAR name: STRING
        VAR firstName: STRING
        VAR grades: Array(Grade)
        
        FUNCTION general_avg(): REAL
            BEGIN
                VAR gradeSum: INTEGER ← 0
                FOR EACH the_grade IN THIS.grades DO
                    gradeSum ← gradeSum + the_grade.grade
                END FOR
                RETURN gradeSum / LEN(THIS.grades)
            END
        END FUNCTION
    END
END STRUCTURE

Note:

  • THIS designates the current instance (like this or self in other languages).
  • We return the average of the student’s grades.

Complete Example of Use
#

VAR one_grade: Grade
one_grade.subject ← "Algorithms"
one_grade.grade ← 15

CONST jl: Student
jl.name ← "Aubert"
jl.firstName ← "Jean-Luc"
jl.grades[] ← one_grade    // Adding the first grade

one_grade.subject ← "Algorithms"
one_grade.grade ← 9
jl.grades[] ← one_grade    // Adding the second grade

WRITE(jl.general_avg())  // Displays JL's general average

The array jl.grades contains:

{"Algorithms", 15}, {"Algorithms", 9}

and jl.general_avg() will return 12.

Once you have a list of students, you can calculate the overall average:

CONST class: Array(Student)
VAR gradeSum: INTEGER ← 0
VAR gradeCount: INTEGER ← 0

FOR EACH student IN class DO
    FOR EACH the_grade IN student.grades DO
        gradeSum ← gradeSum + the_grade.grade
        gradeCount ← gradeCount + 1
    END FOR
END FOR

CONST generalAverage: REAL ← gradeSum / gradeCount
WRITE("Class general average: ", generalAverage)

Functions
#

In algorithmics, you can use “virtual” functions:

  • read() is a function capable of retrieving information coming from the “outside world” (keyboard input, result of an SQL query, information from another part of code…).

  • write(message: String) is a function capable of producing “output” to the “outside world” (screen, printer, …) of information.

  • LEN(array: Array) returns the number of elements of an array.

We don’t need to know how these instructions work but just to know what they do. We often speak of “black boxes”. These functions have no real existence. They are just there to make it easier to write algorithms.

A function can be considered as an autonomous “program”, whose purpose is to process a series of instructions and return a result.

Imagine that you need to create an algorithm that adds the values present in two separate arrays (of the same size), and places the result of the addition in a third array.

One possible solution would be as follows:

firstValues: Array ← [5, 10, 15, 20]
secondValues: Array ← [3, 5, 7, 9]
results: Array
FOR index: Integer FROM 0 TO LEN(firstValues) - 1 STEP 1
    results[] ← firstValues[index] + secondValues[index]
END FOR

Upon reflection, it turns out that you must not add but multiply, you must review your loop to change the operator with the risk of having to change again to return to the previous state.

To avoid risks, you can therefore write two functions:

  • One that will handle adding two values and returning the result

  • Another that will handle multiplying these two values and returning the result

FUNCTION add(value1: Integer, value2: Integer): Integer
    RETURN value1 + value2
END FUNCTION

FUNCTION multiply(value1: Integer, value2: Integer): Integer
    RETURN value1 * value2
END FUNCTION

These two functions “accept” as input two “parameters” (value1 and value2) which will be filled at the function call with the values provided.

Finally, it is therefore possible to “refactor” the algorithm as follows:

firstValues: Array ← [5, 10, 15, 20]
secondValues: Array ← [3, 5, 7, 9]
results: Array
FOR index: Integer FROM 0 TO LEN(firstValues) - 1 STEP 1
    results[] ← add(firstValues[index], secondValues[index])
END FOR


firstValues: Array ← [5, 10, 15, 20]
secondValues: Array ← [3, 5, 7, 9]
results: Array
FOR index: Integer FROM 0 TO LEN(firstValues) - 1 STEP 1
    results[] ← multiply(firstValues[index], secondValues[index])
END FOR

A function can call another function.

FUNCTION chooseOperation(value1: Integer, value2: Integer, isAddition: Boolean): Integer
    IF isAddition = TRUE THEN
        RETURN add(value1, value2)
    ELSE
        RETURN multiply(value1, value2)
    END IF
END FUNCTION
FUNCTION add(value1, value2): Integer
    RETURN value1 + value2
END FUNCTION

FUNCTION multiply(value1, value2): Integer
    RETURN value1 * value2
END FUNCTION

The code can therefore be refactored again:

firstValues: Array ← [5, 10, 15, 20]
secondValues: Array ← [3, 5, 7, 9]
results: Array
FOR index: Integer FROM 0 TO LEN(firstValues) - 1 STEP 1
    results[] ← chooseOperation(firstValues[index], secondValues[index], TRUE)
END FOR

A function can also call itself. Such a function is said to be “recursive”. “Recursive” functions can be risky if exit conditions are poorly evaluated, but extremely useful. By going back to the multidimensional array, you can very well “display” all the content in a single loop.

FUNCTION dump(array: Array)
    FOR index: Integer FROM 1 TO LEN(array) - 1 STEP 1
        IF array[index] IS Array THEN
            dump(array[index])
        ELSE
            display(array[index])
        END IF
    END FOR
END FUNCTION

IS is used here to determine the “type” of the data array[index].

oneArray: Array ← [[1,2],[3,4],[5,6], [7,8],[9,10], [11,12]]
dump(oneArray)

The result of calling the “dump(oneArray)” function will give: 1 2 3 4 … 11

Comments
#

Comments are instructions that are not executed.

To insert a comment, simply add REM in front of the text to comment.

// is also a shortcut for REM.

Example:

REM This is a comment
// This is also a comment

Error Handling
#

There is no try/catch in algorithmics. If needed, you can simply mention in a comment the error handling that could be considered.

Example:

REM If the input is invalid, restart reading

Pseudo Methods
#

Pseudo-methods are instructions that allow you to simulate methods (actions) to describe a behavior.

add(element)
remove(element)

These pseudo-methods are symbolic and serve to make the code more readable.

Exercises
#

Exercise 1
#

Algorithm: Make Change Role: Distribution of a change return in currency by type of bill and/or coin Result: Obtain the number of 100 bills, 50, 20, 10, 5 and the number of 2 euro coins

BEGIN
    CONST PRODUCT_PRICE: INTEGER ← 75
    CONST SUM_GIVEN: INTEGER ← 100
    CONST TO_RETURN: INTEGER ← SUM_GIVEN - PRODUCT_PRICE

    VAR bill100, remainder100, bill50, remainder50, bill20, remainder20, bill10, remainder10, bill5, remainder5, coin2, remainder2: INTEGER ← 0

    // Processing for 100 bills
    bill100 ← TO_RETURN DIV 100 // In this case 0
    remainder100 ← TO_RETURN MOD 100 // In this case 25 / 100 => 0.25 so 25

    // Processing for 50 bills
    bill50 ← remainder100 DIV 50 // In this case 0
    remainder50 ← remainder100 MOD 50 // In this case 25 / 50 => 25

    // Processing for 20 bills
    bill20 ← remainder50 DIV 20 // In this case 25 / 20 => 1
    remainder20 ← remainder50 MOD 20 // In this case 5 / 20 => 5

    // Processing for 10 bills
    bill10 ← remainder20 DIV 10 // In this case 5 / 10 => 0
    remainder10 ← remainder20 MOD 10 // In this case 5

    // Processing for 5 bills
    bill5 ← remainder10 DIV 5 // In this case 1
    remainder5 ← remainder10 MOD 5 // In this case 0

    // Process 2 euro coins
    coin2 ← remainder5 DIV 2 // In this case 0
    remainder2 ← remainder5 MOD 2 // In this case 0
END

Exercise 2
#

CONST integers ← [5, 8, 3, 12, 13, 25, 2]
  1. How many even values are in the array?

  2. Copy the odd values into a new array.

  3. Determine the largest value in the original array.

  4. Calculate the average of the array values.

  5. Determine the factorial of the array.

VAR counter: Integer
FOR VAR i: Integer FROM 0 TO LEN(integers) - 1 STEP 1
    IF integers[i] MOD 2 = 0 THEN
        counter ← counter + 1
    END IF
END FOR
VAR array: ARRAY[INTEGER] ← []
FOR VAR i: INTEGER FROM 0 TO LEN(integers) - 1 STEP 1
    IF integers[i] MOD 2 = 1 THEN
        array[] ← integers[i]
    END IF
END FOR
VAR max_value: INTEGER ← integers[0]
FOR VAR i: INTEGER FROM 1 TO LEN(integers) - 1 STEP 1
    IF integers[i] > max_value THEN
        max_value ← integers[i]
    END IF
END FOR
VAR average: REAL
VAR total_values: INTEGER
FOR VAR i: INTEGER FROM 0 TO LEN(integers) - 1 STEP 1
    total_values ← total_values + integers[i]
END FOR
average ← total_values / LEN(integers)
VAR factorial: INTEGER ← 1
FOR EACH integer IN integers DO
    factorial ← factorial * integer
END FOR

Exercise 3
#

A class is composed of “n” students. During training, grades by subject are given to each student: algorithms, design, SQL. Each subject is subject to 2 to 3 evaluations marked from 0 to 10.

The pedagogical manager wishes to have the following information:

  • General average of the class for all subjects combined
  • Averages distributed by subjects for the entire promotion
  • Averages by subject for each student
  • General average for each student

You will have to define:

  • The structure(s) for storing information
  • Develop the necessary algorithms to solve the requirements
  • Validate the algorithms with a simple test set
// =====================
// Initial Data
// =====================
CONST Students: ARRAY(ARRAY) ← [
    [1, "Denis", "Alibert"],
    [2, "Alice", "Villers"],
    [3, "Cedric", "Da Silva"]
]

CONST Subjects: ARRAY(ARRAY) ← [
    [1, "SQL"],
    [2, "Algorithms"],
    [3, "Design"]
]

CONST Grades: ARRAY(ARRAY) ← [
    [1, 2, 5],
    [1, 2, 7],
    [1, 3, 4],
    [2, 1, 10],
    [2, 3, 10],
    [2, 3, 8],
    [2, 2, 10],
    [3, 3, 10],
    [3, 2, 7],
    [3, 3, 5]
]

// =====================
// Output Variables
// =====================
VAR AverageBySubjectStudent: ARRAY(ARRAY) ← [] // [studentId, subjectId, average]
VAR GeneralAverageStudent: ARRAY(ARRAY) ← []   // [studentId, average]
VAR AverageBySubjectPromo: ARRAY(ARRAY) ← []   // [subjectId, average]
VAR GeneralAverageClass: REAL ← 0

// =====================
// Calculate averages by subject and by student
// =====================
FOR VAR e: INTEGER FROM 0 TO LEN(Students) - 1 STEP 1 DO
    FOR VAR m: INTEGER FROM 0 TO LEN(Subjects) - 1 STEP 1 DO
        VAR gradeSum: REAL ← 0
        VAR counter: INTEGER ← 0
        
        FOR VAR n: INTEGER FROM 0 TO LEN(Grades) - 1 STEP 1 DO
            IF Grades[n][0] = Students[e][0] AND Grades[n][1] = Subjects[m][0] THEN
                gradeSum ← gradeSum + Grades[n][2]
                counter ← counter + 1
            END IF
        END FOR
        
        IF counter > 0 THEN
            VAR subjectAverage: REAL ← gradeSum / counter
            ADD [Students[e][0], Subjects[m][0], subjectAverage] IN AverageBySubjectStudent
        END IF
    END FOR
END FOR

// =====================
// General average per student
// =====================
FOR VAR e: INTEGER FROM 0 TO LEN(Students) - 1 STEP 1 DO
    VAR averageSum: REAL ← 0
    VAR counter: INTEGER ← 0
    
    FOR VAR n: INTEGER FROM 0 TO LEN(AverageBySubjectStudent) - 1 STEP 1 DO
        IF AverageBySubjectStudent[n][0] = Students[e][0] THEN
            averageSum ← averageSum + AverageBySubjectStudent[n][2]
            counter ← counter + 1
        END IF
    END FOR
    
    IF counter > 0 THEN
        VAR generalAverage: REAL ← averageSum / counter
        ADD [Students[e][0], generalAverage] IN GeneralAverageStudent
    END IF
END FOR

// =====================
// Averages by subject for the entire promotion
// =====================
FOR VAR m: INTEGER FROM 0 TO LEN(Subjects) - 1 STEP 1 DO
    VAR averageSum: REAL ← 0
    VAR counter: INTEGER ← 0
    
    FOR VAR n: INTEGER FROM 0 TO LEN(AverageBySubjectStudent) - 1 STEP 1 DO
        IF AverageBySubjectStudent[n][1] = Subjects[m][0] THEN
            averageSum ← averageSum + AverageBySubjectStudent[n][2]
            counter ← counter + 1
        END IF
    END FOR
    
    IF counter > 0 THEN
        VAR promoAverage: REAL ← averageSum / counter
        ADD [Subjects[m][0], promoAverage] IN AverageBySubjectPromo
    END IF
END FOR

// =====================
// General average of the class
// =====================
VAR generalSum: REAL ← 0
VAR studentCount: INTEGER ← 0

FOR VAR i: INTEGER FROM 0 TO LEN(GeneralAverageStudent) - 1 STEP 1 DO
    generalSum ← generalSum + GeneralAverageStudent[i][1]
    studentCount ← studentCount + 1
END FOR

IF studentCount > 0 THEN
    GeneralAverageClass ← generalSum / studentCount
END IF

Resources
#

Related

How Databases Work - Complete Guide
··23 mins· loading · loading
Back-End
API Cookies
··4 mins· loading · loading
API
Firefox
·1 min· loading · loading
Docker
Gitea
·2 mins· loading · loading
Docker
Jellyfin
·1 min· loading · loading
Docker Media
Myspeed
·1 min· loading · loading
Docker