GithubHelp home page GithubHelp logo

anagram's Introduction

README

Thank you for taking the time to review my Ibotta Dev Project. I appreciate your consideration.

Getting Started

Clone the repository

Clone the repository:

git clone https://github.com/PlanetEfficacy/anagram.git

Setup the database

The project is to build an API that allows fast searches for anagrams.

Create the database:

rake db:create

Execute database migration:

rake db:migrate

The schema for this migration is

create_table "words", force: :cascade do |t|
  t.string   "value"
  t.string   "alphabetize"
  t.datetime "created_at",  null: false
  t.datetime "updated_at",  null: false
end

Import seed data:

As per the project instructions: Ingesting the file doesn’t need to be fast, and you can store as much data in memory as you like. Running the seed file takes a while. The time comes from loading each word as well as its alphabetized form into the database. A word's alphabetized form is derived by:

  1. splitting the word by character
  2. sorting the characters alphabetically
  3. joining the split word back together

It is more performant to query the database for anagrams once we include both the word's value (text) and its alphabetized form in our word record since the heavy lifting part of the anagram algorithm is done up front upon running the db seed and upon the subsequent creation of words.

Seed your database with the following command:

rake db:seed

Run the test suite:

This project has 100% test coverage according to the SimpleCov gem. I followed a strict TDD methodology when writing this code. My approach was to rigorously test at the unit level. I wrote request specs that checked for proper routing, but use mocks and stubs because I trust my unit tests and this makes the suite overall more performant. The exception to this approach is the spec/requests/words_spec.rb test, which creates database records. The entire suite of 40 examples runs on my machine consistently under 1.5 seconds. To run the test suite type:

rspec

A secondary test file, provided in the instructions for this project, can be run from the root of the project with the following command. The project must be running on localhost:3000 prior to running this command. Also, DO NOT run this test once you have seeded the database as one of the tests will check an endpoint that will delete the entire database.

Caution, do not run this command without commenting out the delete all test once you have seeded your database

ruby anagram_test.rb

Start the development server:

rails server

Functionality

POST /words.json

Takes a JSON array of English-language words and adds them to the corpus (data store)

The following curl command will add words to the corpus

curl --request POST \
  --url http://localhost:3000/words.json \
  --header 'cache-control: no-cache' \
  --header 'content-type: application/json' \
  --data '{ "words": ["read", "dear", "dare"] }'

and return:

[
    {
        "id": 236538,
        "value": "read",
        "alphabetize": "ader",
        "created_at": "2017-02-16T21:44:46.919Z",
        "updated_at": "2017-02-16T21:44:46.919Z"
    },
    {
        "id": 236539,
        "value": "dear",
        "alphabetize": "ader",
        "created_at": "2017-02-16T21:44:46.924Z",
        "updated_at": "2017-02-16T21:44:46.924Z"
    },
    {
        "id": 236540,
        "value": "dare",
        "alphabetize": "ader",
        "created_at": "2017-02-16T21:44:46.929Z",
        "updated_at": "2017-02-16T21:44:46.929Z"
    }
]

GET /anagrams/:word.json

Returns a JSON array of English-language words that are anagrams of the word passed in the URL.

The following curl command will get all of the anagrams of a given word:

curl --request GET \
  --url http://localhost:3000/anagrams/read.json \
  --header 'cache-control: no-cache'

and returns:

{
  "anagrams": [
    "dear",
    "dare"
  ]
}

The endpoint supports an optional query param that indicates the maximum number of results to return. The following command will limit the query to 1 anagram.

curl --request GET \
  --url 'http://localhost:3000/anagrams/read.json?limit=1' \
  --header 'cache-control: no-cache'

The above request returns:

{
  "anagrams": [
    "dear"
  ]
}

DELETE /words/:word.json

Deletes a single word from the data store.

curl -i -X DELETE http://localhost:3000/words/read.json

and returns:

HTTP/1.1 200 OK

DELETE /words.json

Deletes all contents of the data store.

curl -i -X DELETE http://localhost:3000/words.json

and returns:

HTTP/1.1 204 No Content

Optional Functionality

In addition to the above base functionality the following features have also been implemented.

GET /word-count

Returns a count of words in the corpus and min/max/median/average word length.

curl --request GET --url 'http://localhost:3000/word-count'

and returns:

{
  "count": 3,
  "min": 4,
  "max": 4,
  "median": 4.0,
  "average": 4.0
}

Optional proper noun scope

All of the following GET requests can be scoped to exclude proper nouns from the corpus.

curl --request GET --url 'http://localhost:3000/anagrams/:word.json?proper=false'
curl --request GET --url 'http://localhost:3000/word-count?proper=false'
curl --request GET --url 'http://localhost:3000/most-anagrams?proper=false'
curl --request GET --url 'http://localhost:3000/group-anagrams?proper=false'

GET /most-anagrams

Returns the words with the most anagrams.

curl --request GET --url 'http://localhost:3000/most-anagrams'

and returns:

{
  "anagrams": ["read","dear","dare"]
}

GET /check-anagrams

Returns true if the provided word pair are anagrams of each other.

curl --request GET --url 'http://localhost:3000/check-anagrams?anagrams=read,dare'

and returns:

{
  "words": ["read","dare"],
  "anagram": true
}

GET /group-anagrams

Returns all anagram groups of size >= x

curl --request GET --url 'http://localhost:3000/group-anagrams?size=2'

and returns:

{
  "anagram_groups": [["read","dear","dare"]]
}

Note, the nested array in the above example connotes a set of anagram words. If the corpus contains multiple sets of anagram words, the above array would have an equivalent number of child elements.

DELETE /anagrams/:word.json

Deletes the given word as well as all of its anagrams.

curl --request DELETE --url 'http://localhost:3000/anagrams/read.json'

and returns:

HTTP/1.1 204 No Content

Notes

If I was to continue developing this project, I might consider:

  • Using raw sql to create the alphabetize attribute instead of the after_create method I have implemented in the word.rb model.
  • Adding word length limits / maximums in each query. For example find all anagrams of words with length 10.

Thank You

Thank you very much for your time and consideration.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.