Learning to Think Algorithmically

In order to solve a given problem in programming, a sequence of instructions is followed to get the desired result. This is basically what an algorithm is. It is something that is dealt with quite frequently as a programmer to break down complicated tasks into simple steps, and also something that I never knew that I would have to be using quite frequently.


artturi-jalli-g5_rxRjvKmg-unsplash.jpg

Photo by Artturi Jalli on Unsplash

As a beginner, using algorithms is something that I had no idea that I would be using quite often in programming.

You might be wondering, "How have you been coding then if you don't describe what you want your program to do?"

Good question.

What I always did was:

  1. Look at problem
  2. Write code
  3. The end

And that always worked out

Source

It always worked for most of the beginning part, but as time passed, my genius strategy started to become obsolete. Most of the time, I would be stuck on programming problems because I didn't know how to start, and I would just be blindly following tutorials without thinking of what is going on.

After searching for answers to why I find it hard to code, I found that I had been doing it wrong from the very beginning. As a programmer, I am supposed to "think like a programmer" which is basically using algorithms to describe what you want your program to do.

After thinking about this for a while, I realized that I was creating code without knowing the steps it should take and hoping it does something. Kind of like shooting a gun into a random direction and hoping it hits any random object.

So, I decided to use my newly found skill to solve some problems on CodeWars. The question I attempted was one called "Count IP Addresses" which went like:

Given two different IP addresses, find the number of hosts between the two IP addresses.

This wasn't exactly how the question went, but it was something like this.

At first, I was just staring blankly at the question while my monkey brain was trying to understand what on earth was going on.

Stared at the screen like this for like 5 minutes. Source

After staring at the screen mindlessly, I decided to pull myself together and start working.

I thought about the steps of how the program would solve the problem and made an algorithm from there. This was what I came up with at first:

1. Convert IP address to decimal values
2. Subtract decimal value of first IP address from the second one
3. Give result
4. Do orange justice 

After looking at the problem again, I realized that the IP addresses were actually strings (I don't know how I didn't notice that) and I felt my algorithm wasn't concise enough.

To begin with, I never knew how to convert an IP address into a decimal value. So, I spent some time trying to guess how to do it (which failed of course). After multiple attempts, I gave up and searched online for how to do this. It turns out that for each number in the address, you multiply it by decreasing powers of 255 from right to left. So, for instance if we have an IP address like 20.0.10.38, we will get something like:

20.0.10.38 -> 20*(255^3) + 0*(255^2) + 10*(255^1) + 38*(255^0) = Whatever this sums up to

With this newfound knowledge, it was time to update the algorithm for my program.

1. Extract numbers from the IP addresses
2. Store extracted numbers into a list
3. Convert extracted numbers from 'str' to 'int'
4. Loop through the starting and ending IP address values and multiply with decreasing power values of 255 and add them together (IDK exactly how to say this)
5. Subtract the decimal value of the starting IP address from the ending one
6. Return result
7. Play Fortnite or something

With that out of the way, it was time to start coding. For this, I will be using Python.

The first thing was to get the numbers from the IP address. I managed to do that with no problem at all.

start_ip = start.split(".")
end_ip = end.split(".")

What this does is that it separates the IP address after every '.' and appends the numbers into a list. So, from the sample IP address that I used earlier, it will be separated like:

20.0.10.38 -> ["20", "0", "10", "38"]

The numbers have been gotten from the address, but they are still strings. So, arithmetic operations can't be performed on them yet. The next step is to change the numbers from strings to integers.

int_start_ip = map(int, start_ip)
int_end_ip = map(int, end_ip)

To be honest, I'm kind of proud of how I changed them here. This is my first time using this function and I felt like a genius when I used it lol.

For this next step, I was feeling a little bit adventurous. I wanted to see if it would be possible to multiply the numbers in the IP address while the power of 256 decreases using a for loop (I still don't know how to express this statement). Doubted this would work so I wanted to make sure by letting it print out the loop variables.

for x,y in int_start_ip, range(1, len(int_start_ip) + 1):
    print({0} + {1}.format(x,y))

...and it didn't

Yep, didn't work.jpg

Turns out it was because of the map function that I used. I always knew there would be some sort of a catch to it.

Anyways, after some thinking, I decided to change my plan of action

for x in int_start_ip:
    power = 3
    total_start += x * pow(256, power)
    power -= 1

for y in int_end_ip:
    power = 3
    total_end += y * pow(256, power)
    power -= 1

between = total_end - total_start
return between

After everything, I started thinking "everything is all done" and "I've got this" expecting to see "Test passed", but NOPE.

epic fail.jpg

It turns out that every time the for loop runs, the power of 256 gets reset back to 3 instead of decreasing by one.

I spent some time thinking of how to handle this issue and finally found a way to fix it. It wasn't the best method out there, but it works.

power = 3
while power != -1:
    for x in int_start_ip:
        total_start += x * pow(256, power)
        power -= 1
    
power = 3
while power != -1:
    for y in int_end_ip:
        total_end += y * pow(256, power)
        power -= 1
    
between = total_end - total_start
return between 

Joining everything together, this is the final result.

def ips_between(start, end):
    start_ip = start.split(".")
    end_ip = end.split(".")
    
    int_start_ip = map(int, start_ip)
    int_end_ip = map(int, end_ip)
    
    total_start = 0
    total_end = 0
    between = 0
    
    power = 3
    while power != -1:
        for x in int_start_ip:
            total_start += x * pow(256, power)
            power -= 1
    
    power = 3
    while power != -1:
        for y in int_end_ip:
            total_end += y * pow(256, power)
            power -= 1
    
    between = total_end - total_start
    return between 

After submitting it again, it got accepted. Great :)

it works.jpg

The program took 606 milliseconds to run. I'm not sure if that's a good thing or not.

And yes, I'm aware that my code is not the best looking one out there but if it works, it works.

When you submit your code, the CodeWars website allows you to have a look at other peoples' coding solutions. I found out that someone was able to solve the question using 3 lines of code. It took me an hour to solve this problem. And this is the code:

from ipaddress import ip_address

def ips_between(start, end):
    return int(ip_address(end)) - int(ip_address(start))

...and now, I'm just disappointed....

7848c2160135eb558ba3b3429c07a184disappointed-bald-man-standing-disappointed-cricket-fan-meme.jpg

Source

But it was also cool though, I was also able to learn about different ways that this problem can be approached.


I randomly thought of sharing a bit of programming progress. I don't know if this will become like a programming series or something. I also hope that I will be able to get good at this in the future.

Well, that's all for now and thanks for reading.

Sort:  

I found out that someone was able to solve the question using 3 lines of code.

😂 I always hate when that happens. I will solve a problem with over 10 lines of code but I will go to the solution section and see someone solving the same problem with just one line of code. That actually encouraged me to always think of the shortest way to solve a problem, but sometimes the shortest way is not actually the fastest

Yeah lol.
I've even started trying to see if I can do that too but it's kinda difficult to squeeze an entire algorithm into one line of code. But I believe I'll get there someday.
Also, thanks for reading :)

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support. 
 

Congratulations @sidkay588! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s):

You received more than 1500 upvotes.
Your next target is to reach 1750 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

Our Hive Power Delegations to the August PUM Winners
Feedback from the September 1st Hive Power Up Day
Hive Power Up Month Challenge 2022-08 - Winners List

The thing about Python (and Javascript) is that, for most things you are thinking to do it yourself... High chance someone had did something that you can import instead :) but solving it yourself is still good, though. So you'll know how it actually works and learn the idea behind IP addresses.

If you dig deeper, you might also find out that IP addresses are actually just 32-bit integers chopped into 4 sections in terms of bits. With this knowledge, you can do the conversion of IP addresses to integers without using multiplication or powers at all :) (probably not even using the '+' operation!) The rabbit hole only goes deeper from here, hehe.