In my earlier post, we saw what a T-Nut is. We also said, moving along, we are gonna be cracking a lot of those.
But how does one go about it? What follows, is a step by step guideline, to cracking a T-Nut.
Jump over here, for the cheat sheet.
The Thought Train
Any problem solving is like cracking a nut. So, we are gonna use the allegory of literally chewing on an unknown fruit and careen our way to the seed/t-nut at the centre.
Remember, just like in a fruit, the T-Nut as a seed, is shrouded in edible pericarps and non-edible epicarps.
As we march towards the T-Nut, we need to cull the epicarp and swallow the pericarp.
So, how do we do it? Shall we start off with a step by step guideline?
Sounds good. As we stroll ahead, we can revisit and regroup if something doesn’t seem to fit the bill. Chalo, let’s begin then.
Step 1 - Cull the epicarp
Why cull ?
This is an unknown fruit. Before we begin cracking the nut in it, let’s make sure we understand or at least roughly gauge the nut.
Is it a groundnut, peanut or a walnut?
And what about the fruit concealing it?
What’s its size, texture, and so on…
Basically, let’s ask ourselves, if we truly understand the problem we are trying to solve.
Once we know the kind of fruit and nut we are dealing with, cracking it is just a hammer away.
Now, why wouldn’t we understand the problem?
What could be stopping us?
It could be the distance from the problem, distance from the T-Nut, that’s making it harder, don’t you think?
So, let’s try to get closer to the T-Nut.
To do that, let’s first set aside the epicarp veiling the fruit.
What's an epicarp ?
The epicarp typically, is a seemingly useless, unrelated information, masking the problem.
As you wander into the real world, be it in your corporate environment, or your personal life, rarely is someone going to hand us the problem - like, reverse a linked list.
Almost Never.
It is up to us to identify the problem, which is more often than not, in hiding.
What does culling mean ?
Culling the epicarp is the process of isolating the problem statement we are trying to address, from the other verbal gibberish that shrouds it.
Sometimes, just isolating the epicarp, can almost get you to the solution.
An typical example
Still doesn’t ring a bell?
Try this example and get back.
Synopsis
Putting things together, the typical approach to cull the epicarp would be as below
- Simplify the problem statement
Let’s jot down the naïve problem statement that we can atleast vaguely comprehend - Extract the buzz words
Let’s pull out all the jargons and buzz words that hit on us and try to connect them together
Step 2 - Take the first bite
Where do we begin ?
More often than not, culling the epicarp, WILL NOT hand us the solution. It does better the visibility of the fruit and nut though… But it aint over till the fat lady sings.
So what do we do next? Even after culling the epicarp, the T-Nut is still not visible to the naked eye.
We are still far from it. We need to get closer.
Well, since ‘Hunger’ knows no barriers, for one option, we can bite our way through to it.
But our first bites are always calculative right? We always prefer to bite the juicy side, or at least what we think is juicy.
What's so juicy?
Juicy here, is a metaphor, for a problem area which we know to address with ease. Something that we are comfortable with… Something the looks tasty…
So for the next bite, we will look at the fruit from an angle where it seems palatable and then take that out first. Basically, make the problem more colorful and exciting.
What's taking the bite ?
Taking a bite, is a process of collecting data points.
It's about gathering enough information to stride towards a goal.
In short, it's devising a strategy towards the solution.
However, taking the first bite is the process of looking at the problem statement through the lens of something that we already know. More like, transforming it to a problem variety that we have already conquered before. That should be our first strategy towards the solution.
Apart from the invaluable psychological edge that it boosts, it gives us a path to start walking towards a goal.
Synopsis
The typical approach of taking the first bite would be
- Visual Representation
Make it more colorful, vivid and exciting.
Create a visual representation of the problem. - Relatable Examples
Ensure to take relatable examples. If we have never seen such a problem, let’s try to draw parallels with the real world.
If we have seen similar problems, let’s try to keep it as close to our earlier problem as possible. - Analyze the Input Output Samples
Begin by analysing the input and output samples and see if we can catch some rhythm. Catch some logic.
Try to see if we can guess the output, seeing the input. That’s where we would want to start. - Solve it mentally
Let our “pristine brain” take centre stage. Go with the flow and mentally solve it.
We can work the logic around it later.
Step 3 - Chew and swallow the bite
Chew on the bite
When we chew on a tasty fruit, we generally focus on the aspects of the fruit that we like.
Its sweetness, juice, color, etc
On similar lines, as we chew on our initial bite, let’s focus on the prime aspects of the problem, and the key take aways. Let’s genuinely feel the bite we just took and carve out a solution of sorts.
Let it flow through
Just like letting a bite flow through your esophagus and smoothly into the bowels,
let’s get some logic to flow through the disparate dots and help connect them.
Create a mindmap and visually connect the dots available through buzz words, problem statement, naive logic, etc.
Chewing & Swallowing thus, is synonymous to
analysis, logic formulation and retrospection.
In short, a logical, feedback driven manifestation of our strategy.
You can do this mentally, scribble on paper or start hacking some code.
Whatever you do, remember to retrospect.
Retrospect to see if the dots connect and take you in the right direction.
Try not to force a solution though… let it be smooth
The way we swallow greatly influences the next bites we would take. Try not to make it hard for ourselves to take subsequent bites.
Synopsis
The typical process of chewing on and swallowing the bite would be as below
- Identify the edge cases
Re look at the samples and try to identify some anomalies or edge cases, apparent in the samples provided. - Create a logical flow
Begin with naïve “pristine brain” approach and see if you can convert that to a programmable logic or a logical diagram. Make tweaks in the thinking if need be. - Retrospect
Let’s keep asking ourselves if we are going towards the goal with our current approach.
Moving fast is useless, if we are moving in the wrong direction.
If the approach seems complicated, let’s give it some rest and try something else.
Note
More often than not, you will be unable to transform the “pristine brain” methodology to a logical flow.
This is because the “pristine brain” works very differently than the “logical brain”.
Just because you solved something mentally, doesn’t always mean you can write a program for it. It is for this reason, that we get stuck most of times when we try to pen something down.
In the software world,
Now do you see why interviewers insist on us to write code?
This is not to test our syntax strength
but to identify some pitfalls in our reasoning.
But remember, our pristine brain is extremely adaptable. The more of such problems we solve, the more efficient it will become in working with these types of constraints. And for this reason, we will be cracking a lot of such T-Nuts.
Another word of caution.
While, the logical brain always looks for constraints, the pristine brain always ignores it, if it isn’t explicit. “Pristine Brain” only cares about getting to the goal, however that is. So it is important we present the problem with all constraints emphasized, through the “Logical Counterpart” if you want to force some logical thinking.
This will seem a little hard and unnatural initially but we’ll get used to this style of stating a problem as we crack more T-Nuts.
Step 4 - Take more bites
To bite or not to bite
Alright, we’ve kind of got the flavour of the fruit as we chewed it.
If we liked what we bit, let’s take similar bites and get to the T-Nut.
If we didn’t like the taste of the bite, let’s pick the next juicy spot.
Adapt to Change
Sometimes, our initial approaches may not be the right one.
What we thought was the juicy side, may not turn out to be so.
In the event of which, let’s change the approach and look for another juicy side until we find the sweet spot. Even if this means that we’ve to change our visual representation to suit the newer approach… So be it.
This is the crux of problem solving.
Never hold on to a solution. We should be able to learn from our approach and let it go when situation demands. Don’t hold on too tight onto anything
Law of conservation of thought
Believe in the law of conservation of thought
"Your thinking and effort cannot be destroyed.
It will manifest itself some way or the other, into action."
Yup, believe in it.
Our thoughts will manifest itself into action and turn out fruitful. Let’s keep moving forward.
Step 5 - Swallow the next bite
Repeat Step-3
As just stated, as we move along, we can either choose to take similar bites and narrow down on the solution or take a divergent path.
With each bite, as we try out a new solution path or optimise the current one,
let’s sculpt out a sustainable, workable logic as we swallow.
And more importantly, let’s remember to retrospect.
Let’s retrospect and evaluate the approach and check if this is taking us towards the goal. Because if not, we may need to start over.
The earlier we re-route from an ineffective path, the better, so feedback is key.
So remember the cycle
Bite -> Swallow -> Retrospect
Step 6 - Optimize the final bites
Working with constraints
As we keep gnawing our way through, we are nibbling away the fruit that we have got to work with.
On one hand, we are getting closer to the T-Nut at the centre and are probably just a bite away from cracking it open.
But, on the other hand, we still want to crack it right.
Just try to recollect how our bites change, as we reach the finishing stages of devouring a fruit.
We substitute intense, prodigious bites with smaller, calculated chunks. We basically cover the areas of the fruit, we had left behind or ignored.
Litmus Test
On similar lines, the functional core of our solution to the T-Nut might be in place (or it may seem so), but it’s time to address the remnants.
Let’s try to move away from the straight forward scenarios and test some complicated ones. Let’s verify that our logic is fault proof and profound.
Try out the edge cases, empty input and invalid input scenarios and ensure all of these are handled gracefully.
Let’s put our logic through a litmus test and ensure it doesn’t go bonkers!!!
Sometimes, the edge cases can highlight a major flaw in our reasoning..
and guess what, because of that, we may need to start all over again.
In those cases, remember… to let go… Don’t hold on.
Just drop the fruit, pick up a new one and start gnawing your way through.
We have the appetite don’t we? Then why worry?
NFRs (Non Functional Requirements)
In software terminologies, such requirements, which are outside the scope of the functional core but still as important and relevant as the core functionality, are termed as “Non Functional Requirements”, or in short, NFRs.
NFRs are key requirements these days, because as Engineers we are keen on efficiently using the resources we have at our disposal.
But similar to our fruit analogy, engineers always choose to bite these at the end.
Typical examples include security aspects, performance, scalability, usability, etc.
This could be the stage where we critically evaluate our strategy’s “Time Complexity” and “Space Complexity”
Thus "Optimizing Final Bites" is the process of addressing the NFRs
and the non-straightforward scenarios, more so called the edge cases.
Step 7 - Perpetual Optimization
Last but not least, optimization is a perpetual process! There is always room for improvement.
For quite a few reasons, we would have to optimize our current solution.
Letting Go
Many a times, the way we chose to approach the problem, might take us off course and lead to a lot a difficulties. And only deep down the thought process, we may realise we are going astray.
But, we would have worked on it so much, that we would be in denial to accept that this approach is not the right one. So we may still go ahead and tweak the solution and see if it fits.
Remember what I said before? Don’t hold on too tight, let go.
Choose an alternative path and move on. Believe in the law of conservation of thought.
Turn around and go full throttle… All over again!
Necessity is the mother of invention
Not surprisingly, this is not the only form or need of optimization.
There are times when a perfectly working solution needs to be improvised, well, because it’s not good enough any more.
For one, the solution might not have been designed for this workload and for these access patterns.
Or may be, as time progressed, the problem core became a frequently used service so there is pressing need to make it more efficient.
Take search engines for eg.
During the earlier days, people would patiently wait, even for a minute, for any online search to display results, because manually scurrying pages would obviously take longer.
But today, we’ve become so edgy. We expect search results to return in a jiffy and are intolerant to anything above a few seconds.
Times have changed, the need has changed, so its time to optimize.
But remember,
There is nothing wrong with the older search algorithms. They did their job in their era.
They are just not relevant any more.
In these times, we will have to start all over with new emphasized constraints and redo the above steps.
Well if you haven’t guessed already, almost always, if our current solution doesn’t fit the bill and we need to restart, it would be because of the NFRs.
Performance is a key requirement nowadays, so when we set out to solve a problem, let’s understand the non-functional constraints thoroughly as well.
And remember,
Necessity is the mother of invention.
That adage is not just for the lazy gooses but also for the smart squirrels.
Don’t over engineer. Don’t over optimise. Do only what ever is needed.
First get to the goal and then, keep getting better.
That’s an elaborate guide we have here. Let’s take a case study to understand the above approach.
Let’s start with this simple Little B T-Nut of reversing a list.
Once we are done cracking the T-Nut, we’ll revisit and see if we can simply the approach.
All righty, its’ road to El Dorado then!!
For a shorter concise version of the above, refer the quick guide