Solution to coding-challenge-backend-c (Patrick Desmarais)

The approach can be decomposed into three steps: parsing query string parameters, parsing TSV 
file, and returning sorted suggestions.


# Flow in code

Code has been added in a new "src" folder and tests have been added in the "test" folder.

At the entry point to "/suggestions", the root "/app.js" script delegates the retrieval of 
suggestions to "/src/suggestions.js".

First, the query string parameters are parsed in "/src/suggestions.js". Once parsed, those 
parameters are handed over to "/src/parse.js".

Second, "/src/parse.js" efficiently reads "data/cities...tsv" to find cities that meet the 
criteria. Lines are efficiently extracted from each file chunk to be triaged and stored 
in a "/src/model/Suggestions.js" model object.

Third, once the parsing is done, the "/src/model/Suggestions.js" model object takes 
advantage of the "/src/model/SuggestedCity.js" and "/src/model/City.js" model objects 
within its collection of valid cities to return a sorted list of suggestions.


# Solution Details


## Parsing results

When reading the input file, each chunk is analyzed to find new-line characters. Hence, 
each line can be parsed before waiting for all chunks to arrive and be accumulated in 
memory. The field values of interest are stored, and some partial score value is 
pre-computed before waiting for the next chunk.

Note that one could argue that the file only weighs 1.2MB, and keeping all lines in 
memory could achieve better performance under a heavy number of "/suggestions" 
requests.

Furthermore, the use of a database for storing each line could really help to achieve 
better performance.

Nevertheless, this approach provides an interesting performance for the purpose of 
this challenge.


## String search and comparison

The approach chosen to find matching results was to use a simple regular expression 
with the query string parameter value for "q". Regular-expression-specific characters 
are escaped and special French characters are replaced to create a more normalized 
string suited for a case-insensitive comparison.

Since only Canada and the United States figure in the input data, only special 
characters from the French language like "é", "è", etc. are being replaced by 
their ASCII counterparts both in the query string parameter value for "q" and 
from the input data.

Note that this replacement of special characters should be reviewed when including 
more languages with new input files (from other world regions for example).


## Scores

The score is computed based on the Haversine formula to find the distance between 
two points given their latitude and longitude. The final score is computed based 
on the relative distance to the highest distance between the input latitude and 
longitude and the latitude and longitude of the matching city names.

To further enhance the score, and give more meaningful results, the score could 
be reviewed to use an approximate string matching algorithm.


# Challenge Review

The challenge was very interesting. As I was familiar with Node.js and had hardware 
compatible to the Get Started section, I could arrive at a simple solution after 
the first day.

I thought I could come up with a solution in five hours, but this estimation did not 
take into account the problematic with special characters in French and other edge 
cases. Furthermore, I did not take into acount the learning of Heroku. With code 
enhancements for better maintenance and some unit tests to cover the main cases, I 
ended up with 12.75 hours of work.

If I had to start over, I would have taken the time to set up WebStorm to help 
with debugging, and take a better approach to meet the challenge requirements using 
a test-driven approach to development.