As I was preparing to move to Canada, I was fortunate enough to receive a coding assignment from a frontend position in Vancouver that I had applied for.
This post is a reflection on what I learned while working through that assignment.
Have you heard of WER (Word Error Rate)? WER is a metric used to evaluate speech recognition systems at the word level. It measures how different a hypothesis sentence is from a reference sentence based on the minimum number of operations required to transform one into the other.
The operations are:
The formula itself is simple:
WER = (S + D + I) / N
S: Substitutions
D: Deletions
I: Insertions
N: Number of words in the reference sentence
However, the assignment was not simply about calculating a WER score.
The requirements were:
In my previous work experience, the organization was large enough to have a dedicated BFF (Backend for Frontend) layer. Most complex sorting or algorithmic logic was handled on the server side. As a frontend developer, my primary responsibility was to present already processed data.
This assignment was different. I had to directly implement the DP-based Edit Distance (Levenshtein) algorithm and use its result to satisfy the UI requirements. Edit Distance itself is a well-known algorithm and it can be implemented almost instantly with AI assistance these days.
But the key challenge here was not writing the algorithm.
For me, frontend development is about translating logic into user experience.
To animate the transformation process correctly, I had to truly understand the algorithm and connect it to the UI layer.
At first, I could not intuitively understand why a delete operation comes from dp[i-1][j].
It felt as if something had already been deleted.
So I went back and redefined the meaning of the DP table.
dp[i][j]represents the minimum number of operations required to transform the firstiwords of the reference into the firstjwords of the hypothesis.
With this definition, the transitions became clearer:
dp[i-1][j] → previous state if the current cell results from a deletiondp[i][j-1] → previous state if it results from an insertiondp[i-1][j-1] → previous state if it results from a substitution or a matchIt became much clearer when visualized in a DP table:
![]()
Another important realization was that the DP table stores only the minimum cost. It does not store which operation was chosen. To compute the counts of insertions, deletions, and substitutions, and to animate the exact sequence of transformations, I needed to backtrack along the minimum-cost path.
This meant a 2D DP table was structurally necessary. Only after fully understanding this process did the animation logic start to make sense.
In the end, the real challenge was not the DP algorithm itself, but state design.
The calculation phase was an algorithmic problem.
The animation phase was a state modeling problem.
Questions I had to answer included:
The computation happens instantly and the user experience unfolds over time.
Recognizing this difference allowed me to separate the pure algorithm from the UI concerns and approach the animation as a state management problem.
This assignment was not just about calculating WER. It was my first experience deeply understanding an internal algorithm and translating it into something visible and experiential for users.
Below is the live demo for reference: Live Demo
![]()