What is an Algorithm and how does it differ from a Program?

An algorithm is a set of step-by-step instructions that define how a task should be performed. In programming, algorithms are fundamental as they define the logic that computers must follow to solve specific problems.

A program is the implementation of one or more algorithms in a specific programming language. While an algorithm can be represented in many ways, a program is a concrete artifact that can be executed by a computer.

Parts of an Algorithm

  1. Input: The data that is entered into the algorithm.
  2. Process: The operations that are performed on the input data.
  3. Output: The result obtained after processing the data.

Characteristics of an Algorithm

  1. Sequential: The instructions are executed one after another.
  2. Precise: Each instruction must be clear and unambiguous.
  3. Ordered: The instructions must be in a specific order.
  4. Finite: The algorithm must have an end after a finite number of steps.
  5. Defined: Each step must be defined and effective.

What are the quality measures that an Algorithm must meet

  1. Efficiency: It is when it performs its task in the shortest possible time or using the least amount of resources. Efficiency is generally measured in terms of execution time and memory usage.
  2. Effectiveness: When it achieves its goal or solves the problem for which it was designed. An effective algorithm produces correct and complete results.
  3. Readability: An algorithm is readable when it is easy to understand for an external programmer. Readability is improved with good coding style, the use of comments, and the choice of descriptive names for variables and functions.
  4. Reusability: It is reusable when it can be used in different contexts without the need to make significant changes. Code reuse reduces development time and improves code maintainability.
  5. Adaptability: It is when it can be easily modified to handle new situations or requirements. An adaptable algorithm is flexible and can handle changes in the problem requirements.
  6. Portability: When it can be run on different platforms or operating systems without the need to make significant changes. Portability is important to ensure that the algorithm can be used on a wide range of systems.

It is important to clarify that an algorithm that is efficient is effective, as it performs its task in the shortest possible time or using the least amount of resources, which implies that it is achieving its goal. However, an algorithm can be effective (achieve its goal) without being efficient if, for example, it uses more time or resources than necessary to perform its task.

How is an algorithm created?

  1. Define the problem: Before starting to write an algorithm, we must clearly understand the problem we are trying to solve.
  2. Identify the inputs and outputs: We must determine what data is needed to solve the problem (inputs) and what results we expect to obtain (outputs).
  3. Design the logic of the algorithm: At this point, abstraction becomes a crucial tool. Abstraction allows us to identify and extract the essential data to solve the problem and discard everything that does not contribute to the solution. This allows us to simplify the problem, eliminating unnecessary details and reducing it to its most manageable components. In this way, abstraction helps us handle even the most complex problems in a more efficient and effective way.
  4. Write the algorithm: Once we have designed the logic, we can start writing the algorithm, making sure that each step is clear, precise, and ordered.
  5. Test the algorithm: Finally, we must test the algorithm to ensure that it produces the expected results.

What is a Programming Language?

Abstraction becomes an essential tool for understanding and designing efficient algorithms, but in order to develop the programs that computers can execute we need the so-called programming languages.

Programming languages are tools that we use to write instructions that computers can understand and execute. They are like the bridge between humans and machines, allowing us to communicate our ideas and problem solutions in a way that a computer can carry out.

There are many programming languages, each with its own rules (syntax) and particular uses. Some are more suitable for specific tasks, while others are more versatile. Programming languages are essential for implementing algorithms into executable programs.

What are the components of a Programming Language?

  1. Lexicon: It is the set of symbols or basic elements that can be used in a language. These can be identifiers, constants, operators, instructions, among others.
  2. Syntax: It refers to the structure and format that instructions written in a programming language must follow. It is like the grammar of programming, where each command and element must be in the right place and follow the rules established by the language.
  3. Semantics: It refers to the meaning of the instructions written in a programming language. While syntax focuses on the way instructions are written, semantics focuses on what those instructions actually do and how they interact with each other.

High-Level vs Low-Level Programming Languages

Programming languages can be classified into two main categories: high-level languages and low-level languages.

High-Level Programming Languages

These languages are designed to be easily understandable by humans. They are abstract, which means they are quite far from machine code. High-level languages use a syntax that is similar to English and are easier to learn and use. Examples of high-level languages include Python, Ruby, Java, and C++.

  • Advantages: They are easier to learn and write, which allows programmers to be more productive. In addition, they are portable, which means that the same code can be run on different types of machines.
  • Disadvantages: Due to their high level of abstraction, they can be less efficient and slower in execution compared to low-level languages.

Low-Level Programming Languages

These languages are closer to the hardware and use a syntax that is more difficult to understand for humans. Low-level languages allow more direct control over what the machine does. Examples of low-level languages are machine language and assembly language.

  • Advantages: They allow more detailed control of the hardware and can be faster and more efficient in execution.
  • Disadvantages: They are more difficult to learn and write, and the code is not portable, which means that the code written for a specific machine or operating system may not work on another.

Compiled Languages vs Interpreted Languages

Compiled Languages

These are languages that require a “translation” step from the source code to machine language that the processor can execute. Examples of compiled languages are C, C++, Rust, Go, among others.

To do this, it is necessary to compile the code using a program called a compiler. In general, the source language is a high-level language and the object language is a low-level language, such as assembly or machine code.

The operation of a compiler can be divided into several fundamental stages:

  1. Lexical Analysis: This is the first phase in which the compiler scans the source code. This process is performed from left to right, character by character, and groups these characters into tokens.
  2. Syntax Analysis: This phase consists of discovering the structure of the code. It determines whether a text follows the expected format or not.
  3. Semantic Analysis: This phase validates whether the constructed syntactic tree agrees with the rules of the formal language.
  4. Intermediate Code Generation: After having performed the semantic analysis, the compiler generates an intermediate code between the source code and the target machine code.
  5. Code Optimization: This phase performs an optimization of the generated intermediate code.
  6. Object Code Generation: This is the last phase of the compilation process, where the final code is generated in the object language.

Interpreted Languages

An interpreted programming language is one whose source code is not completely translated to machine language before it is executed, but is interpreted and executed line by line as the program runs. This has its advantages, such as portability and ease of debugging.

The interpretation process involves several stages:

  1. Reading the Code: The interpreter reads the source code line by line.
  2. Creating an Internal Representation of the Code: The interpreter creates an internal representation of the code.
  3. Interpreting the Code in Real Time: The interpreter interprets the code in real time.
  4. Generating Results: The interpreter generates the results.

It is important to mention that each time an interpreted program is run, the interpreter reads and executes the code, which can result in a slower execution speed compared to compiled languages.

What is Data?

Data are raw facts that on their own may not make sense. However, when these data are processed, organized, structured, or presented in a given context, they become useful information. Therefore, we can say that data plus interpretation and context give us valuable Information.

Data Types

Elementary

Elementary data types are the most basic building blocks of programming. These include:

  1. Booleans (bool): These are truth values, that is, true or false.
  2. Characters (char): These are individual letters, numbers, or symbols. For example, ‘a’, ‘Z’, ‘3’, ‘$’ are characters.
  3. Integers (int): These are numbers without decimals. For example, 5, -3, 0 are integers.
  4. Floating Point (float): These are numbers with decimals. For example, 3.14, -0.01 are floating point numbers.
  5. Text Strings (string): These are sequences of characters. For example, “Hello World” is a text string.
  6. Enumerated (enum): These are data types that consist of a set of constant values. Each constant value in an enumerated has an associated index that starts from 0. For example, the days of the week (Monday=0, Tuesday=1, etc.) can be an enumerated data type. You can reference a value of the enumerated using its name or its index, and you will get the other. For example, if you have the day “Monday”, you can get its index 0, and vice versa.
  7. Double Precision (double): These are numbers with decimals that have a greater precision than float type. For example, 3.141592653589793 is a double precision number.

Structured

Structured data types are more complex and are used to organize and store collections of data. These include:

  1. Homogeneous Data: These are those that contain the same type of data. For example arrays, are collections of elements of the same type. An array of integers can contain [1, 2, 3, 4, 5].
  2. Heterogeneous Data: These are those that can contain different types of data. For example:
    1. Files: These are sets of data stored on the hard drive that can contain different types of data, such as text, numbers, images, etc.
    2. Records: These are structures that can contain different types of data. For example, a student record can contain his name (text string), age (integer), and grades (array of numbers).

What is the Casting Process?

In programming, we often find ourselves in situations where we need to work with data that are not of the type we need. Casting, also known as casting or type casting, is a process in programming where we convert a variable from one data type to another. This is useful when we want to perform operations that require a specific data type.

There are two main types of casting:

  1. Implicit Casting: This occurs when the compiler automatically converts one data type to another without the need for the programmer to explicitly specify the conversion. For example, if you try to add an integer with a floating point number, the compiler will automatically convert the integer to a floating point number before performing the sum.
  2. Explicit Casting: This occurs when the programmer explicitly specifies the conversion of one data type to another. This is done using the casting syntax. For example, in C++, if you have a variable of type double and you want to convert it to int, you can do it in the following way: int myVariable = (int)myDouble;.

It is important to note that not all data types can be converted to other data types. Some conversions can lead to data loss, such as when we convert a floating point number to an integer, where the decimal part is discarded.

Operators in Programming

Once we have our data, whether elementary or structured, we need a way to manipulate them to solve problems and create useful programs. This is where operators come in.

An operator in programming is a symbol that tells the compiler or interpreter to perform specific mathematical, logical, and relational operations. Operators are used to manipulate data and variables in programs. Some common examples of operators include +, -, *, /, and =. Each operator has a specific function and the operation it performs depends on the type of data with which it is used.

Types of Operators

It is important to mention that operators have an order of priority that determines the order in which operations are performed in an expression. The operators discussed below are ordered by their priority, with arithmetic operators having the highest priority and assignment operators having the lowest priority.

It should be clarified that before all these operators, the parentheses (()) have the highest priority (priority 0). This means that any operation within the parentheses will be performed before any other operation. In addition, operations at the same level will be performed from left to right.

1) Arithmetic Operators

These operators are used to perform mathematical operations. They return a numeric value that can be an integer or a floating point number, depending on the operands.

  • pow: This is the power function. It raises the first value to the power of the second value.
  • *: This is the multiplication operator. It multiplies two values.
  • /: This is the division operator. It divides the value on the left by the value on the right.
  • %: This is the modulo operator. It returns the remainder of the division of the value on the left by the value on the right.
  • +: This is the addition operator. It adds two values.
  • -: This is the subtraction operator. It subtracts the value on the right from the value on the left.
  • ++: This is the increment operator. It increases the value of the variable by one.
  • --: This is the decrement operator. It decreases the value of the variable by one.

2) Comparison Operators

These operators are used to compare two values. They always return a boolean value (true or false).

  • <: This is the less than operator. It returns true if the value on the left is less than the value on the right.
  • <=: This is the less than or equal to operator. It returns true if the value on the left is less than or equal to the value on the right.
  • >: This is the greater than operator. It returns true if the value on the left is greater than the value on the right.
  • >=: This is the greater than or equal to operator. It returns true if the value on the left is greater than or equal to the value on the right.
  • ==: This is the equality operator. It returns true if the two values are equal.
  • !=: This is the inequality operator. It returns true if the two values are not equal.

3) Logical Operators

These operators are used to perform logical operations. They return a boolean value (true or false).

  • &&: This is the logical AND operator. It returns true if both operands are true.
  • ||: This is the logical OR operator. It returns true if at least one of the operands is true.

4) Assignment Operators

These operators are used to assign a new value to a variable. The data type they return depends on the data type of the operands.

  • =: This is the assignment operator. It assigns the value on the right to the variable on the left.
  • +=: This is the addition and assignment operator. It adds the value on the right to the value on the left and assigns the result to the variable on the left.
  • -=: This is the subtraction and assignment operator. It subtracts the value on the right from the value on the left and assigns the result to the variable on the left.
  • *=: This is the multiplication and assignment operator. It multiplies the value on the left by the value on the right and assigns the result to the variable on the left.
  • /=: This is the division and assignment operator. It divides the value on the left by the value on the right and assigns the result to the variable on the left.
  • %=: This is the modulo and assignment operator. It takes the modulo of the value on the left by the value on the right and assigns the result to the variable on the left.
  • &=: This is the AND and assignment operator. It performs a bitwise AND operation on the value on the left with the value on the right and assigns the result to the variable on the left.