Refine Algorithm Thinking

Algorithms govern every process in this worldor most. Anything which follows a pre-defined sequence of rules is fueled by algorithms.

In computer science, an algorithm is a formal and mathematical set of instructions that are processed by computer programs to solve problems. The real world requires innovative algorithms for solving problems.

“If you can write “hello world” you can change the world” Raghu Venkatesh

Throughout our academic journey, algorithms are mostly taught and learned with the aim to pass technical interviews. We often hear that some of the algorithms we learn are never used in real lifenot entirely true.

The most advanced algorithms in the technology ecosystem are often based on a collection of these simple algorithms. We interact with these algorithms daily and they make our lives easier.

For example, Google Search utilizes a collection of algorithms to serve accurate search results. Netflix is famed for its personalized movie recommendation system.

Designing an algorithm requires specialized skills that each developer should learn. In this article, we have discussed various tips to help you develop effective algorithms and solve real-world problems. 

Let’s go.

. . .

1. Understanding the Problem Statement

Understanding the Structure of Data

“Programming isn’t about what you know; it’s about what you can figure out.” Chris Pine, Learn to Program

Every computer program and software application starts with gathering requirements. The aim is to capture all possible system information. Business development managers, system analysts, or developers are responsible for requirement gathering. They try to understand the complexity of the task based on its objectives.

In a software program, the complexity depends on various factors like business logic, technical expertise, revenue model, and performance goals, etc. Each factor highly impacts the solution.

Based on requirements and intuition, a problem statement is strategically defined. It requires a lot of thinking, discussion, and brainstorming among the development teams. Initially, the problem is defined on a high level in simple words. Further complexities are added as the process is refined.

The team identifies the scope of the program, code challenges, technical details, limitations, and a probable solution to formulate an efficient problem statement. Solving the problem becomes harder if the problem is not understood accurately. If the developers implement the problem with faulty understandings, the project is doomed.

For example, if you are asked to implement a complex mathematical formula in a financial software application, it is better to first understand the formula and its relevant terms. A slight error in implementation can incite financial disaster.

“Think twice, code once.” Waseem Latif

. . .

2. Figure Out Sample Inputs and Expected Outputs

Simple Input and Expected Output

“Programming is usually taught by examples.” Waseem Latif

Examples help us understand the world around us. While scientists crave to formalize theories, examples make them believable and understandable.

Similarly, programming requirements can be difficult to comprehend but examples make them easy. A program can have many possible input-output combinations. Identifying some of them can greatly increase our understanding of the entire system.

For example, if you are asked to check a palindrome word or number, it is better to figure out a few palindromes as examples. If you are asked to apply an encryption-decryption scheme for security, having input-output samples can improve task understanding.

. . .

3. Divide the Problem Into Small Chunks

Splitting the data

“When it comes to writing code, the number one most important skill is how to keep a tangle of features from collapsing under the weight of its own complexity.” James Hague

Software applications are huge. They can have hundreds of features with thousands of lines of code that cannot be managed by a single person. The key to building successful programs is to break the problem into small parts.

Applications are broken down into modules which are further broken down into individual functions. Each function solves one particular problem. Within the function, the problem can be divided into various parts.

Good algorithms are built using simple steps. Each step contributes towards solving the problem. Divide and conquer algorithms are classical examples of dividing a problem into various sub-problems. The sub-problems are solved first and their outputs are collectively used to solve bigger problems.

“Programming is breaking of one big impossible task into several very small possible tasks.” Jazzwant

. . .

4. Explore Important Existing Algorithms for Inspiration

In software development, many of the commonly used algorithms and techniques are available by default. The open-source community has also worked for decades to build repositories of advanced algorithmic techniques.

As a developer, you must always remain curious to explore the next big breakthrough. Every day researchers and industry veterans are developing massive Artificial Intelligence and Machine Learning algorithms like BERT and GPT-3. But as a novice, you can stick with exploring basic algorithms that are built into most programming languages.

Searching and sorting techniques are the most common algorithms. These simple algorithms have the ability to design powerful software solutions. Exploring them in detail will enable you to understand core programming concepts. Breaking down each loop and conditional statement can help you learn the control flow of any program.

Search AlgorithmsBinary Search, Linear Search

Search algorithms can find data elements from a collection of data. There are many search algorithms available like binary search, linear search, Fibonacci search, breadth-first search, depth-first search, and more. Some are given preference over others based on their time efficiency. Binary search and linear search are the easiest and most commonly used search algorithms.

Sort AlgorithmsInsertion Sort, Bubble Sort

Sorting algorithms are vital for many programming applications. The data must be sorted in ascending or descending order. Data can also be sorted based on data keys and ids. Insertion sort, bubble sort, merge sort, and heap sort, etc are some of the most commonly used sorting algorithms.

If a built-in algorithm is available, always use it in your programming solution to achieve good results. If you try to write each section of the code yourself, you’ll end up with a messy and complicated solution.

. . .

5. Write Pseudocode First

“Some of the best programmings is done on paper, really. Putting it into the computer is just a minor detail.”― Max Kanat-Alexander, Code Simplicity: The Fundamentals of Software

Now that you have grasped the necessary knowledge about the problem and figured out its sample input-outputs, it is time to put your coding abilities to the test.

But wait. You are not going to use a keyboard or write the program on your fancy computer screen.

The best approach for newbie developers is to write the pseudocode first. The pseudocode is a mixture of English language sentences with sprinkles of logical code snippets in between. These are general guidelines or instructions that a computer program must follow to achieve the desired task but in a human-readable format.

At first, the developer must aim to build a high-level algorithm that covers all major requirements. Perform a dry run analysis to improve your understanding of the program control flow and identify the missing links. Repeating this step a few times can churn out sophisticated pseudocodes.

Many developers believe that writing the pseudocode is the biggest challenge in coding. Once you have general high-level instructions, any associate-level developer can convert them into executable code.

. . .

6. Write Simple Code and Generalize It

After refining the pseudocode, it is time to write the actual code.

Code can be written with any programming language in any development environment. Initially, try to cover all fundamental cases. Aim to develop an executable program that can handle all basic input-output combinations.

Prefer simplicity over complexity. But don’t hard code anything. Keep the code generic. Oftentimes, in search of simplicity, developers prefer hard-coding instead of writing dynamic programs as they can be mildly difficult to write at first.

Hard coding is a bad software development practice where the values of the program variables are fixed or static. Like fixing the values of your input array or function parameters. The program will always execute with the same set of variable values that will lead to the same results every time. You do not want your calculator application to always display the same answer regardless of the input calculations. 

It is generally frowned upon in the IT industry as it limits the problem-solving capabilities of the systems. 

“I once generalized from a single data point, and I’ll never do that again!” Carlos Bueno, The Mature Optimization Handbook

. . .

7. Try to Improve Your Algorithmic Creation

Algorithm Creations

Every programming solution ever built has gone through an extensive refinement process. It involves various iterations of code refactoring to remove bad code and bugs.

After writing a simple code, the next step is to add complexity to the program. Detailed requirements are implemented and all edge cases are handled properly.

Good developers also focus on identifying the elements that cannot be improved any further. Oftentimes, clients expect the program to behave in a certain way when it is not possible programmatically. Spotting such exceptions and conveying them to the client is vital to building trust.

Developers must compare different algorithms if there is more than one solution available. If you are using an iterative approach, try the recursive solutions as well. Optimize the algorithm to reduce the time and space complexity. This is a vital step to improve the efficiency of the computer program.

Instead of playing the guessing game, developers must experiment and refrain from always selecting the obvious answer. Create solutions that completely represent the requirements instead of adding more complications.

“Some people, when confronted with a problem, think ‘I know, I’ll use regular expressions.’ Now they have two problems.”― Jamie Zawinski

. . .

8. Find a Suitable Data Structure 

Data Structure

Data structures are vital in programming. As the name suggests, data structures organize the data in our programs. All programming languages have a specific set of data structures built into them. Some of these are:

1. Arrays: 

Arrays can be one-dimensional, two-dimensional arrays, up to n-dimensional. They store numbers and text elements in contiguous (neighboring) memory locations.

2. Stacks: 

A stack can contain any data type based on the Last In First Out (LIFO) principle. Stacks are used in memory management processes.

3. Queues: 

Similar to stacks, Queues can store data based on the First In First Out (FIFO) principle. Scheduling applications and processes in computer systems use queues as their primary data structure.

4. Linked Lists: 

Linked lists are objects or data elements connected in a sequence. They have high flexibility in storage capabilities as compared to arrays.

5. Trees:

Trees contain data nodes that are linked to each other in a hierarchical structure. There is a root node at the top which grows downwards into child nodes and so on. The file explorer system for any computer applies the tree data structure.

6. Graphs:

Graphs are network-based data structures that are a collection of vertices or nodes joined by edges.

Developers should pay special attention while selecting a data structure for an algorithm. The choice of data structure can affect the performance of the entire system.

. . .

9. Problem Solving via Design Patterns

Design Patterns

In programming, code repetition tells a lot about your abilities as a coder. If the code is repeated, it becomes rigid. Code changes become expensive as the same changes must be applied everywhere.

This is where design patterns come in handy.

A design pattern is a code template that can reduce code repetition. It provides a solution to commonly occurring software design problems. Every developer must learn to implement design patterns in their algorithms.

Design patterns are of three types: creational patterns, structural patterns, and behavioral patterns. They are proven solutions for recurring software problems.

. . .

10. Practice Maketh a Man Developer Perfect

Developer Perfect

“Take time to learn the closest thing that we have to a SUPERPOWER – Code” Sharen Eddings

Coding is a superpower. If you have it, you can do wonders with it. The entire digital ecosystem runs on codes written by developers.

But writing code is a challenging task. It requires a certain level of wisdom and intellect. Developers must build their coding skills through practice.

Only with sheer determination and hard work, the developers can improve their programming abilities. With practice, they can start to think more intuitively for solving problems. 

If you want to achieve greatness in the field of programming, you must have the courage to put in the required amount of effort.

. . .

Concluding Thoughts

“Everybody in this country should learn to program a computer because it teaches you how to think” Steve Jobs

Novice developers often show symptoms of Imposter Syndrome. They doubt their abilities to write code. Overcoming the fear of failure is hard. Identify your flaws to embrace them and overcome your imposter syndrome. 

Know that you are not the only one experiencing this and seek guidance from people who have made it big in the IT industry.

We believe that everyone can write algorithms to solve complex problems. As with any other aspect of life, it requires time, energy, passion, dedication, and hard work.

THE END

References

  1. https://www.google.com/search/about/
  2. https://netflixtechblog.com/netflix-recommendations-beyond-the-5-stars-part-1-55838468f429
  3. https://examples.yourdictionary.com/palindrome-examples.html
  4. https://www.khanacademy.org/computing/computer-science/algorithms/merge-sort/a/divide-and-conquer-algorithms
  5. https://ai.googleblog.com/2018/11/open-sourcing-bert-state-of-art-pre.html
  6. https://openai.com/blog/gpt-3-apps/
  7. https://www.altexsoft.com/blog/engineering/code-refactoring-best-practices-when-and-when-not-to-do-it/
  8. https://dzone.com/articles/what-is-design-pattern
Newsletter
Our newsletter

Become A Better Programmer In Just 15 Minutes🎯

Subscribe to my newsletter for valuable insights on thriving as a software engineer, helping you excel in your career.

Morshed
Software Engineer

Morshed Alam

I'm the creator of Savvy Programmer, a blog for programmers to level up their skills and advance their career. Through this blog, I'll be your guide in your programming journey no matter how far into it you are!

Table of Contents

Newsletter

Newsletter
Our Newsletter

Become A Better Programmer In Just 15 Minutes🎯

Subscribe to my newsletter for valuable insights on thriving as a software engineer, helping you excel in your career.

Copyright © | 2022 Savvy Programmer