Rails developer by day, snowboard ski patroller by powder days

That Question That Turned My Brain into a 404 Error Ah yes, the moment when my brain decided to take an unexpected vacation during an interview. The question was simple (at least in hindsight): “Can you design an in-memory object that efficiently determines whether a value can be converted to another type?” At that moment,…

Written by

×

Aha! Interview question

That Question That Turned My Brain into a 404 Error

Ah yes, the moment when my brain decided to take an unexpected vacation during an interview. The question was simple (at least in hindsight):

“Can you design an in-memory object that efficiently determines whether a value can be converted to another type?”

At that moment, my brain cells collectively agreed to pack their bags, leaving me in complete silence—an interview power move I did not intend to make.

So, let’s rewind and break it down.

The Ask (Which I Didn’t Quite Get at the Time)

Clients can request that certain form fields be converted to specific types. We don’t care about how the actual conversion happens (that’s a backend magic trick for later). We just need to check, at lightning speed, if the conversion is possible.

This means we need:
1. A configuration stored in memory
2. A way to check if a conversion from type Atype B is possible
3. Bonus: If type A can convert to type C, which can then convert to type B, we should still say “yes!”

Sounds reasonable, right? Yeah… my interview self didn’t think so.

Interviewer’s Hint (Which I Still Didn’t Get)

The interviewer tried to nudge me in the right direction by showing an example:

add_to_config :date_time, [:string, :text]

Translation: “Hey, just store this mapping somewhere!”

Still, I stared at them like they had just spoken in Parseltongue.

Then they showed me this empty object:

CONFIG = {}

And that’s when I realized—oh, we’re just building a fancy lookup table! Hashes can be used to do what is being asked.

The Lightbulb Moment (After the Interview, Of Course 🙃)

Once I sat back and processed everything, the solution clicked:

Step 1: Create the Configuration

CONFIG = {}

def add_to_config(type, conversions)
CONFIG[type] = conversions
end

add_to_config :date_time, [:string, :text]
add_to_config :text, [:string, :email, :phone_number, :num]
add_to_config :string, [:text, :email, :phone_number, :num]
add_to_config :int, [:string, :boolean]

This results in a nicely structured lookup table

{
:date_time => [:string, :text],
:text => [:string, :email, :phone_number, :num],
:string => [:text, :email, :phone_number, :num],
:int => [:string, :boolean]
}

Now we can check direct conversions, but what about indirect ones?

Step 2: Implement Recursive Checking

Since a type can sometimes be converted in multiple steps (like numintboolean), we need to traverse our configuration recursively:

def can_convert?(type, target, visited = {})
return false if visited[type] # Avoid infinite loops
return true if CONFIG[type]&.include?(target)

visited[type] = true # Mark as visited

CONFIG[type]&.any? { |value| can_convert?(value.to_sym, target, visited) } || false
end

How it works:
1. First, check if the direct conversion exists.
2. If not, go on a little journey through all possible paths.
3. If a path leads to the target, return true.
4. If we get lost in the recursion woods, return false.

Voilà! Now It Works

Now we can confidently answer questions like:

can_convert?(:num, :string)  # true (num → string)
can_convert?(:num, :boolean) # true (num → int → boolean)
can_convert?(:text, :phone_number) # true (text → phone_number)
can_convert?(:boolean, :string) # false (no path exists)

Had I pieced this together during the interview, my brain wouldn’t have ghosted me. But hey, better late than never, right? 😆

Graph Reachability

If you have been reading up on algorithms our problem is graph reachability:

  • Each type is a node
  • Each conversion is a directed edge
  • The question is: “Can I reach target from type?”

This is a classic use case for Depth-First Search (DFS), which is why the recursive solution works well.

Leave a comment