diff --git a/README.md b/README.md index 6bd0a05..9817d6c 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,35 @@ Just trying to learn Typescript and improve my problem solving skills. I am also trying to incorporate testing, documentation and a better GIT control. +Checkout my [Notion](https://mohitjain.notion.site/Coding-Challenges-af9b8197a438447e9b455ab9e010f9a2?pvs=4) where I share how I tackled these challenges, along with my learnings. + ## Structure - `src` - Contains all the source code - `tests` - Contains all the test files +## Challenges + +1. [Write your own wc tool](src/1/) +2. [Write your own JSON parser](src/2/) +3. [Write Your Own Compression Tool](src/3/) +4. [Write Your Own cut Tool](src/4/) +5. [Write You Own Load Balancer](src/5/) +6. [Write Your Own Sort Tool](src/6/) +7. [Write Your Own Calculator](src/7/) +8. [Write Your Own Redis Server](src/8/) +9. [Write your own grep](src/9/) +10. [Write Your Own uniq Tool](src/10/) +11. [Write Your Own Web Server](src/11/) +12. [Write Your Own URL Shortener](https://github.com/jainmohit2001/short-url) +13. [Write Your Own diff Tool](src/13/) +14. [Write Your Own Shell](src/14/) +15. [Write Your Own cat Tool](src/15/) +16. [Write Your Own IRC Client](src/16/) +17. [Write Your Own Memcached Server](src/17/) +18. [Write Your Own Spotify Client](https://github.com/jainmohit2001/spotify-client) +19. [Write Your Own Discord Bot](src/19/) + ## Installation The following command will build all the .ts files present in `src` folder into a new `build` folder. diff --git a/src/1/README.md b/src/1/README.md new file mode 100644 index 0000000..a4fc4f1 --- /dev/null +++ b/src/1/README.md @@ -0,0 +1,40 @@ +# Challenge 1 - Write your own wc tool + +This challenge corresponds to the first part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-wc. + +## Description + +The WC tool is written in `wc.ts` file and the `index.ts` is the command line version of the tool. The tool is used to count the number of words, lines, bytes and characters in a file/stdin. + +Check out [this](https://www.notion.so/mohitjain/1-Write-Your-Own-wc-Tool-b289bb2362c14778880029633b76033b) Notion page to understand how I approached this challenge. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +npx ts-node index.ts [option] filename +``` + +The following options are supported: + +- `-w`: prints the number of words in the file +- `-l`: prints the number of lines in the file +- `-c`: prints the number of bytes in the file +- `-m`: prints the number of characters in the file + +The tool can also be used in stdin mode as follows: + +```bash +cat filename | npx ts-node index.ts [option] +``` + +## Run tests + +To run the tests for the WC tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/1/ +``` + +The tests are located in the `tests/1/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/10/README.md b/src/10/README.md new file mode 100644 index 0000000..8c7c41f --- /dev/null +++ b/src/10/README.md @@ -0,0 +1,42 @@ +# Challenge 10 - Write Your Own uniq Tool + +This challenge corresponds to the tenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-uniq. + +## Description + +The uniq tool is written in `uniq.ts` file and the `uniq.index.ts` is the command line version of the tool. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +# Using input file +npx ts-node uniq.index.ts [-option] + +# Using standard input +cat filename | npx ts-node uniq.index.ts [-option] - + +# Using output with input file +npx ts-node uniq.index.ts [-option] + +# Using output with standard input +cat filename | npx ts-node uniq.index.ts [-option] - +``` + +The following options are supported: + +- `-c` or `--count`: prefix lines by the number of occurrences +- `-d` or `--repeated`: only print duplicate lines +- `-u`: only print unique lines +- `-`: read from standard input + +## Run tests + +To run the tests for the uniq tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/10/ +``` + +The tests are located in the `tests/10/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/11/README.md b/src/11/README.md new file mode 100644 index 0000000..2c9cb38 --- /dev/null +++ b/src/11/README.md @@ -0,0 +1,52 @@ +# Challenge 11 - Write Your Own Web Server + +This challenge corresponds to the eleventh part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-webserver. + +## Description + +The web server API implementation is inspired from (express)[https://www.npmjs.com/package/express]. +The webserver is a basic implementation and a subpart of the express framework. +It current handles only GET requests and supports responses and file responses. +The webserver is able to handle the case when the callback to a GET function throws an error, by sending a 500 response. + +- `webserver.ts`: Contains the implementation of the web server, implemented using the `net` module of Node.js. It exposes `startServer`, `stopServer` and `get` methods to start, stop and handle GET requests respectively. +- `index.ts`: A simple example of how to use the web server and serve a HTML file. +- `request.ts`: A simple implementation of the request object that is passed to the callback of the `get` method. +- `status_codes.ts`: Contains the supported status codes and their corresponding messages that are used in the response. + +## Usage + +You can directly import the HttpServer class from the `webserver.ts` file and use it as follows: + +```typescript +import { HttpServer } from './webserver'; + +// Create a new instance of the HttpServer class with +const HOST = '127.0.0.1'; +const PORT = 8000; +const debug = false; +const webServer = new HttpServer(HOST, PORT, debug); + +// Handle GET requests +webServer.get('/', (req) => { + res.send('Hello World!'); +}); + +// Serve a HTML file +webServer.get('/index.html', (req) => { + req.sendFile('path/to/index.html'); +}); + +// Start the server +webServer.startServer(); +``` + +## Run tests + +To run the tests for the webserver, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/11/ +``` + +The tests are located in the `tests/11/` directory. diff --git a/src/13/README.md b/src/13/README.md new file mode 100644 index 0000000..baba47b --- /dev/null +++ b/src/13/README.md @@ -0,0 +1,28 @@ +# Challenge 13 - Write Your Own diff Tool + +This challenge corresponds to the thirteenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-diff. + +## Description + +The diff tool is written in `diff.ts` file and the `diff.index.ts` is the command line version of the tool. +The diff tool is build using the Longest common subsequence (LCS) problem. We first find the LCS of a pair of strings and extend that to a pair of array of strings. +While finding LCS we also store information about the insertions and deletions required to convert one string to another and use that information to print the differences between the two strings. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +# Using input file +npx ts-node diff.index.ts +``` + +## Run tests + +To run the tests for the diff tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/13/ +``` + +The tests are located in the `tests/13/` directory. diff --git a/src/14/README.md b/src/14/README.md new file mode 100644 index 0000000..fd515b6 --- /dev/null +++ b/src/14/README.md @@ -0,0 +1,34 @@ +# Challenge 14 - Write Your Own Shell + +This challenge corresponds to the fourteenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-shell. + +## Description + +As the name suggests, here we try to build a simple shell using the `child_process` module of Node.js. +The shell supports all the commands (including piped commands) that are available in any standard LINUX shell. + +Apart from the builtin commands - `cd`, `pwd`, `exit`, `history` are executed by spawning a new process and passing all the relevant arguments provided by the user. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +npx ts-node shell.ts +``` + +All the executed commands are stored in a file in the home directory of the user with the name `.ccsh_history`. You can then use the `history` command to see the previously executed commands. + +To exit the shell, use the `exit` command. + +The `pwd` and `cd` command support is implemented using the inbuilt `cwd()` and `chdir()` function exposed by the process module. + +## Run tests + +To run the tests for the shell tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/14/ +``` + +The tests are located in the `tests/14/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/15/README.md b/src/15/README.md new file mode 100644 index 0000000..e7bafc0 --- /dev/null +++ b/src/15/README.md @@ -0,0 +1,35 @@ +# Challenge 15 - Write Your Own cat Tool + +This challenge corresponds to the fifteenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-cat. + +## Description + +The cat utility reads files sequentially, writing them to the standard output. +The file operands are processed in command-line order. If file is a single dash (`-`) or absent, cat reads from the standard input. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +# Using file +npx ts-node cat.ts [-option] [filename] + +# Using stdin +cat test.txt | npx ts-node cat.ts [-option] +``` + +The following options are supported: + +- `-n`: number the lines are they are printed out +- `-b`: number the lines excluding blank lines + +## Run tests + +To run the tests for the cat tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/15/ +``` + +The tests are located in the `tests/15/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/16/README.md b/src/16/README.md new file mode 100644 index 0000000..d585132 --- /dev/null +++ b/src/16/README.md @@ -0,0 +1,119 @@ +# Challenge 16 - Write Your Own IRC Client + +This challenge corresponds to the sixteenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-irc. + +## Table of contents + +- [Description](#description) +- [Usage](#usage) +- [Run tests](#run-tests) +- [TODOs](#todos) + +## Description + +The IRC client is written using the `net` module of Node.js. +You can find more about the IRC protocol from https://datatracker.ietf.org/doc/html/rfc2812. + +- `command-types.ts`: Command types returned by server and supported by client +- `parser.ts`: A parser class that parses the data sent by server into a more usable message interface +- `types.ts`: All the interface definitions are present in this file +- `utils.ts`: Utility functions used by IRC client +- `irc-client.ts`: The main IRC Client login is written here. +- `irc-client.index.ts`: A command line interface for IRC Client to interact with the server + +The IRC Client supports file based logging via [winston](https://www.npmjs.com/package/winston) + +The following commands are supported by the IRC Client: + +- JOIN +- PART +- NICK +- PRIVMSG +- QUIT + +## Usage + +To use the IRC Client command line interface, you can update the following variables present in `irc-client.index.ts` and use the `ts-node` command to start the client. + +```typescript +const host = 'irc.freenode.net'; +const port = 6667; +const nickName = 'MJ'; // Use you nickname +const fullName = 'Mohit Jain'; // Use your full name +const debug = true; // Enable winston logging +``` + +```bash +npx ts-node irc-client.index.ts +``` + +The following commands are supported by the IRC Client: + +```bash +# Connect to server +client>connect + +# Join a channel +client>/join + +# Leave a channel +client>/part + +# Change your nickname +client>/nick + +# Send a message to a channel +client>/privmsg + +# Quit the IRC Client +client>/quit +``` + +You can also use the IRC Client Class in your own code by importing it from `irc-client.ts`. + +```typescript +import IRCClient from './irc-client'; + +// logger is an instance of winston.Logger otherwise undefined +const client = new IRCClient(host, port, nickName, fullName, debug, logger); + +// Connect the client to the server +await client.connect(); + +// Join a channel +await client.join([{ channel: '#cc' }]); + +// Send message to a channel +client.privateMessage('#cc', 'Hello World!'); + +// Part a channel +await client.part({ channels: ['#cc'], partMessage: 'Bye Bye' }); + +// Update your nickname +await client.nick('MJ'); + +// Quit the server +await client.quit('Bye Bye'); + +// Get details about a channel +const channelDetails = client.getChannelDetails('#cc'); +``` + +You can add listeners to different command types supported by the IRC Client. The client exposes the `on()` method as mentioned in [types.ts](https://github.com/jainmohit2001/coding-challenges/blob/416a47f715fff82964bd8def81c26ab72cfe8978/src/16/types.ts#L189). + +## Run tests + +To run the tests for the IRC Client, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/16/ +``` + +The tests are located in the `tests/16/` directory. + +## TODOs + +- [ ] Add support for multiple channels for JOIN and PART commands. +- [ ] Add command line option support for `irc-client.index.ts`. +- [ ] Separate the command handling from the main IRC client code into more a structured and scalable format. +- [ ] Improve tests. diff --git a/src/17/README.md b/src/17/README.md new file mode 100644 index 0000000..9680591 --- /dev/null +++ b/src/17/README.md @@ -0,0 +1,42 @@ +# Challenge 17 - Write Your Own Memcached Server + +This challenge corresponds to the seventeenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-memcached. + +## Description + +This is a simple implementation of a Memcached server written in Node.js using the `net` module. + +The server supports the following commands: + +- `get`: Get the value corresponding to the provided key +- `set`: Set a key value pair +- `add`: Add a key value pair if not already present +- `replace`: Replace a key value pair if present + +The server also supports the `expTime`, and `noreply` feature. + +The `command.ts` file exports a function that parses the information about the command sent by the client and returns an instance of `MemCommand` class which is used by the server to handle the execution of the command. + +## Usage + +To start the server, use the `ts-node` command: + +```bash +npx ts-node memcached.index.ts -p 11211 +``` + +Or using the node command: + +```bash +node path/to/memcached.index.js -p 11211 +``` + +## Run tests + +To run the tests for the IRC Client, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/17/ +``` + +The tests are located in the `tests/17/` directory. diff --git a/src/19/README.md b/src/19/README.md new file mode 100644 index 0000000..868d2e5 --- /dev/null +++ b/src/19/README.md @@ -0,0 +1,48 @@ +# Challenge 19 - Write Your Own Discord Bot + +This challenge corresponds to the nineteenth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-discord. + +## Description + +This is a simple implementation of a Discord bot written in Node.js using the [discord.js](https://old.discordjs.dev/#/docs/discord.js/main/general/welcome) module. + +The bot supports the following functionalities and slash commands: + +- After the bot is added to a server and hosted, it will send to a `Hello` message sent by the client with the message `Hello `. +- Slash commands: These commands are implemented in the `commands` directory. + + - `add`: This command takes a URL as an argument and adds a new coding challenge to the bot's DB. + - `challenge`: Suggests a random challenge. + - `list`: Lists all the challenges available. + - `quote`: Fetch a random quote using https://dummyjson.com/quotes/random + +More information about the files present in this directory: + +- `challenge.ts`: This file exposes a storage class that is used by the bot to interact with the file based DB. +- `index.ts`: Entry point of the bot. + +## Usage + +Create a `.env` file at the root directory of this repository and add the following environment variables: + +```bash +APP_ID='app-id' +DISCORD_TOKEN='discord-token' +PUBLIC_KEY='public-key' +``` + +To change the above behavior of reading the environment variables, go to `index.ts` and change the following line as per your needs. + +```typescript +config({ path: './.env' }); +``` + +Go to the root directory of this repository and run the following command to start the discord bot: + +```bash +# Using ts-node +npx ts-node ./src/19/index.ts + +# Using node +node ./build/src/19/index.js +``` diff --git a/src/2/README.md b/src/2/README.md new file mode 100644 index 0000000..c43e718 --- /dev/null +++ b/src/2/README.md @@ -0,0 +1,29 @@ +# Challenge 2 - Write your own JSON parser + +This challenge corresponds to the second part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-json-parser. + +## Description + +The JSON parser is written in `json-parser.ts`. The tool is used to parse a given string and returns the equivalent object representation of the string in TypeScript. + +Check out [this](https://www.notion.so/mohitjain/2-Write-Your-Own-JSON-Parser-09795d8ec27c4ee8a55a457f3da99fd2) Notion page to understand how I approached this challenge. + +## Usage + +You can directly import the tool into any TypeScript file as follows: + +```ts +import { JsonParser } from 'path/to/json-parser.ts'; + +const output = new JsonParser(input).parse(); +``` + +## Run tests + +To run the tests for the JSON parser tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/2/ +``` + +The tests are located in the `tests/2/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/3/README.md b/src/3/README.md new file mode 100644 index 0000000..a681d96 --- /dev/null +++ b/src/3/README.md @@ -0,0 +1,43 @@ +# Challenge 3 - Write Your Own Compression Tool + +This challenge corresponds to the third part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-huffman. + +## Description + +This is a command line tool used to compress a given file using the [Huffman coding algorithm](https://en.wikipedia.org/wiki/Huffman_coding). + +- `huffman_tree_node.ts` - This file contains the class definition for the Huffman tree node. Each internal node has a left child, a right child and a weight. Each leaf node has a weight, and a value determining the character. + +- `utils.ts` - This file contains some utility functions used by the Huffman coding algorithm. + +- `huffman.ts` - This file contains the class definition for the Huffman coding algorithm. All the compression and decompression logic is implemented in this file. + +- `index.ts` - This file contains the main function which is the entry point of the command line tool. + +## Usage + +You can use ts-node to run the command line tool as follows + +```bash +# To compress a file +npx ts-node index.ts --compress +``` + +Where the `input-file` corresponds to the file to be compressed and the `output-file` corresponds to the compressed file. + +```bash +# To decompress a file +npx ts-node index.ts --decompress +``` + +Where the `compressed-file` corresponds to the compressed input file and the `output-file` corresponds to the decompressed file. + +## Run tests + +To run the tests for the compression tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/3/ +``` + +The tests are located in the `tests/3/` directory. diff --git a/src/4/README.md b/src/4/README.md new file mode 100644 index 0000000..77c947b --- /dev/null +++ b/src/4/README.md @@ -0,0 +1,49 @@ +# Challenge 4 - Write Your Own cut Tool + +This challenge corresponds to the fourth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-cut. + +## Description + +The CUT tool is written in `cut.ts` file and the `index.ts` is the command line version of the tool. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +# Print out the second field from each line of the file +npx ts-node index.ts -f2 filename +``` + +The cut tool supports the following options: + +- Single Field index support + ```bash + # prints out the first field + npx ts-node index.ts -f1 filename + ``` +- Delimiter support + ```bash + # use delimiter "," to separate fields and print out the first field + npx ts-node index.ts -f1 -d, filename + ``` +- Field list support + ```bash + # prints out the first and second fields + npx ts-node index.ts -f1,2 + ``` +- Standard Input support + ```bash + # prints out the first and second fields from the standard input delimited by "," + cat test.csv | npx ts-node index.ts -d, -f"1 2" + ``` + +## Run tests + +To run the tests for the CUT tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/4/ +``` + +The tests are located in the `tests/4/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/5/README.md b/src/5/README.md new file mode 100644 index 0000000..619a275 --- /dev/null +++ b/src/5/README.md @@ -0,0 +1,56 @@ +# Challenge 5 - Write You Own Load Balancer + +This challenge corresponds to the fifth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-load-balancer. + +## Description + +The aim of this challenge is to write a load balancer that distributes the incoming requests to the registered servers in a Round Robin fashion. + +- `be_details.ts` - contains the class for the BE Server details stored with the Load balancer. +- `be.index.ts` - a command line tool to start a backend server. +- `be.ts` - Contains the backend server implementation. +- `enum.ts` - Contains relevant ENUMs for the SchedulingAlgorithm and the Health of a Backend Server. +- `lb.index.ts` - a command line tool to start the load balancer with ROUND_ROBIN scheduling algorithm. +- `lb.ts` - Contains the load balancer implementation. + +## Usage + +1. First we need to register the BE servers on the LB. To do so, find the private variable `backendServerUrls` and update it with the URLs of the BE servers. + + For the sake of explanation, the BE servers and LB are all hosted on the same machine. The LB is listening on port 80, and the BE servers are listening on port 8080, 8081 and 8082. + +2. Start the load balancer using the command line tool `lb.index.ts` as follows: + + ```bash + # Using node + node path/to/lb.index.js 80 + + # Using ts-node + npx ts-node lb.index.ts 80 + ``` + +3. Start the BE servers using the command line tool `be.index.ts` as follows: + + ```bash + # Using node + node path/to/be.index.js 8081 + + # Using ts-node + npx ts-node be.index.ts 8081 + ``` + +4. Add more BE servers using the above command with different ports. + +5. Start sending requests using any preferred tool (e.g. Postman) to the LB on port 80. The LB will distribute the requests to the BE servers in a Round Robin fashion. + +6. Cross check the **Health Check Mechanism** by stopping one of the BE servers. The LB will stop sending requests to the unhealthy BE server. + +## Run tests + +To run the tests for the Load Balancer, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/5/ +``` + +The tests are located in the `tests/5/` directory. diff --git a/src/6/README.md b/src/6/README.md new file mode 100644 index 0000000..eb82aa9 --- /dev/null +++ b/src/6/README.md @@ -0,0 +1,38 @@ +# Challenge 6 - Write Your Own Sort Tool + +This challenge corresponds to the sixth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-sort. + +## Description + +The SORT tool is written in `sort.ts` file and the `sort.index.ts` is the command line version of the tool to sort data present in a file. +The rest of files correspond to the different types of algorithms used to sort the data. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +npx ts-node sort.index.ts filename [-u] [--algorithm] +``` + +The SORT tool supports the following options: + +- `-u`: Unique. Suppresses duplicate lines. +- `--algorithm`: The algorithm to use to sort the data. The available algorithms are: + + - `--merge-sort`: Merge sort algorithm. + - `--quick-sort`: Quick sort algorithm. + - `--heap-sort`: Heap sort algorithm. + - `--random-sort`: Random sort algorithm. + + If no algorithm is specified, the sorting is done using the inbuilt `sort()` method. + +## Run tests + +To run the tests for the SORT tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/6/ +``` + +The tests are located in the `tests/6/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL). diff --git a/src/7/README.md b/src/7/README.md new file mode 100644 index 0000000..a945ef1 --- /dev/null +++ b/src/7/README.md @@ -0,0 +1,42 @@ +# Challenge 7 - Write Your Own Calculator + +This challenge corresponds to the seventh part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-calculator. + +## Description + +The aim of the challenge is to write a calculator that can perform basic arithmetic operations on numbers (floating point numbers are also supported). +The calculator supports the following operators: + +- `+`: Addition +- `-`: Subtraction +- `*`: Multiplication +- `/`: Division +- `^`: Exponentiation + +The calculator also support parentheses `(` and `)` to group operations. + +No support for functions such as `sin` or `cos` is currently provided. + +**IMP**: The input string should have operators and operands always separated by a space. + +The calculator first converts the input string into a postfix expression using [Shunting Yard algorithm](https://en.wikipedia.org/wiki/Shunting_yard_algorithm#The_algorithm_in_detail), and then evaluates the expression to get the result. It will throw an Error if the input string is invalid. + +## Usage + +You can directly import the Calculator class from the `calculator.ts` file and use it in your code as follows: + +```typescript +import { Calculator } from 'path/to/calculator'; +const str = '1 + 1'; +const value = new Calculator(str).calculate(); // value = 2 +``` + +## Run tests + +To run the tests for the Calculator tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/7/ +``` + +The tests are located in the `tests/7/` directory. diff --git a/src/8/README.md b/src/8/README.md new file mode 100644 index 0000000..dac007d --- /dev/null +++ b/src/8/README.md @@ -0,0 +1,59 @@ +# Challenge 8 - Write Your Own Redis Server + +This challenge corresponds to the eighth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-redis. + +## Description + +The aim of the challenge is to write a basic Redis server that can handle concurrent clients using the [RESP Protocol](https://redis.io/docs/reference/protocol-spec/). + +- `redis_commands.ts`: The commands supported by the server +- `redis_client.ts`: My own class implementation of the Redis client. This is not part of the challenge, but I wanted to implement the client as well. +- `redis_client.index.ts`: Command line version of the Redis client +- `redis_server.ts`: The Redis server implementation +- `redis_server.index.ts`: Command line version of the Redis server +- `redis_serializer.ts`: The serializer used by the Redis server to serialize the data +- `redis_deserializer.ts`: The deserializer used by the Redis server to deserialize the data +- `types.ts`: The different types of objects support by RESP protocol + +## Usage + +To start the Redis server on the default port 6379, run the following command: + +```bash +# Using ts-node +npx ts-node redis_server.index.ts + +# Using node +node path/to/redis_server.index.js +``` + +Afterwards you can connect to the server by starting up a client session using your preferred Redis Client. See Redis CLI(https://redis.io/docs/ui/cli/) to learn more about the Redis command line interface. + +## Benchmark + +I have created my own benchmark tool present in `benchmark.ts`. The code is inspired from the original Redis benchmarking method https://github.com/redis/node-redis/blob/master/benchmark/lib/runner.js. + +To run the benchmark, close all the previous servers and clients and run the following command: + +```bash +npx ts-node benchmark.ts +``` + +The benchmark tool will start the Redis server and perform GET, SET and DEL operations using multiple clients. +The tool has the following parameters that can be changed as per your needs: + +```typescript +const concurrency = 50; // The number of concurrent clients +const times = 100000; // The number of operations per client +const size = 1024; // The size of key and value in bytes +``` + +## Run tests + +To run the tests for the REDIS server, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/8/ +``` + +The tests are located in the `tests/8/` directory. diff --git a/src/9/README.md b/src/9/README.md new file mode 100644 index 0000000..e8c15a0 --- /dev/null +++ b/src/9/README.md @@ -0,0 +1,32 @@ +# Challenge 9 - Write your own grep + +This challenge corresponds to the ninth part of the Coding Challenges series by John Crickett https://codingchallenges.fyi/challenges/challenge-grep. + +## Description + +The GREP tool is written in `grep.ts` file and the `grep.index.ts` is the command line version of the tool. The tool is used to search for a pattern in a file or a directory and print the matching lines. + +The implementation is using the inbuilt `RegExp` class of JavaScript. + +## Usage + +You can use `ts-node` to run the tool as follows: + +```bash +npx ts-node grep.index.ts [-i] [-v] +``` + +The following options are supported: + +- `-i`: case insensitive search +- `-v`: print lines that do not match the pattern + +## Run tests + +To run the tests for the grep tool, go to the root directory of this repository and run the following command: + +```bash +npm run test tests/9/ +``` + +The tests are located in the `tests/9/` directory. All the tests are made for **LINUX** environment only. If you want to run the tests in Windows environment, you can use the Git Bash terminal or Windows Subsystem for Linux (WSL).