diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 70c43d3475..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,28 +0,0 @@ -root = true - -[*] -tab_width = 2 -indent_size = 2 -charset = utf-8 -end_of_line = lf -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.txt] -indent_size = false - -[test/fast/Listing versions/Running 'nvm ls' calls into nvm_alias] -indent_size = false - -[test/fast/Listing versions/Running 'nvm ls --no-alias' does not call into nvm_alias] -indent_size = false - -[test/fast/Unit tests/mocks/**] -insert_final_newline = off - -[test/**/.urchin*] -insert_final_newline = off - -[Makefile] -indent_style = tab diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..a83a1d5831 --- /dev/null +++ b/.env.production @@ -0,0 +1,3 @@ +ALGOLIA_APP_ID=O6OT9G9U8Z +ALGOLIA_API_KEY=b0cb3d390176e1ff4bd1ecb12fc15730 +ALGOLIA_INDEX_NAME=XXX \ No newline at end of file diff --git a/.github/workflows/azure-staticwebapp.yml b/.github/workflows/azure-staticwebapp.yml new file mode 100644 index 0000000000..99bde11984 --- /dev/null +++ b/.github/workflows/azure-staticwebapp.yml @@ -0,0 +1,72 @@ +# This workflow will build and push a web application to an Azure Static Web App when you change your code. +# +# This workflow assumes you have already created the target Azure Static Web App. +# For instructions see https://docs.microsoft.com/azure/static-web-apps/get-started-portal?tabs=vanilla-javascript +# +# To configure this workflow: +# +# 1. Set up a secret in your repository named AZURE_STATIC_WEB_APPS_API_TOKEN with the value of your Static Web Apps deployment token. +# For instructions on obtaining the deployment token see: https://docs.microsoft.com/azure/static-web-apps/deployment-token-management +# +# 3. Change the values for the APP_LOCATION, API_LOCATION and APP_ARTIFACT_LOCATION, AZURE_STATIC_WEB_APPS_API_TOKEN environment variables (below). +# For instructions on setting up the appropriate configuration values go to https://docs.microsoft.com/azure/static-web-apps/front-end-frameworks +name: Deploy web app to Azure Static Web Apps + +on: + push: + branches: + - "master" + pull_request: + types: [opened, synchronize, reopened, closed] + branches: + - "master" + +# Environment variables available to all jobs and steps in this workflow +env: + APP_LOCATION: "/" # location of your client code + API_LOCATION: "api" # location of your api source code - optional + APP_ARTIFACT_LOCATION: "build" # location of client code build output + AZURE_STATIC_WEB_APPS_API_TOKEN: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} # secret containing deployment token for your static web app + +permissions: + contents: read + +jobs: + build_and_deploy_job: + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: write # for Azure/static-web-apps-deploy to comment on PRs + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ env.AZURE_STATIC_WEB_APPS_API_TOKEN }} # secret containing api token for app + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments) + action: "upload" + ###### Repository/Build Configurations - These values can be configured to match you app requirements. ###### + # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig + app_location: ${{ env.APP_LOCATION }} + api_location: ${{ env.API_LOCATION }} + app_artifact_location: ${{ env.APP_ARTIFACT_LOCATION }} + ###### End of Repository/Build Configurations ###### + + close_pull_request_job: + permissions: + contents: none + if: github.event_name == 'pull_request' && github.event.action == 'closed' + runs-on: ubuntu-latest + name: Close Pull Request Job + steps: + - name: Close Pull Request + id: closepullrequest + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ env.AZURE_STATIC_WEB_APPS_API_TOKEN }} # secret containing api token for app + action: "close" diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 70932bf142..845a2eb570 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -9,6 +9,7 @@ name: Labeler on: [pull_request] jobs: +<<<<<<< HEAD label: runs-on: ubuntu-latest permissions: @@ -19,3 +20,16 @@ jobs: - uses: actions/labeler@v2 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' +======= + label: + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" +>>>>>>> master diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..2144002d13 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,26 @@ +on: push +name: Build Gatsby Site +jobs: + build: + name: Build Gatsby Site + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Build Gatsby Site + uses: jzweifel/gatsby-cli-github-action@master + with: + gatsby-arg: build +on: push +name: Build Gatsby Site in Subdirectory +jobs: + build: + name: Build Gatsby Site + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Build Gatsby Site + uses: jzweifel/gatsby-cli-github-action@master + env: + GATSBY_PROJECT_PATH: "./" + with: + gatsby-arg: build diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml new file mode 100644 index 0000000000..de2dbe9453 --- /dev/null +++ b/.github/workflows/makefile.yml @@ -0,0 +1,27 @@ +name: Generate Documentation + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Github Action genshdoc + id: action-genshdoc + uses: vargiuscuola/genshdoc@master + - name: genshdoc result + run: echo "The result of genshdoc Action was ${{ steps.action-genshdoc.outputs.result }}" + - name: Commit files + run: | + echo ${{ github.ref }} + git add . + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git commit -m "CI: Automated build push" -a | exit 0 + - name: Push changes + if: github.ref == 'refs/heads/master' + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000000..b80d85d364 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,52 @@ +# Sample workflow for building and deploying a Gatsby site to GitHub Pages +# +# To get started with Gatsby see: https://www.gatsbyjs.com/docs/quick-start/ +# +name: Deploy Gatsby site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +# Default to bash +defaults: + run: + shell: bash + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/package.json" ]; then + echo "::set-output name=manager::npm" + echo "::set-output name=command::ci" + exit 0 + else + echo "Unable to determine packager manager" + exit 1 + fi + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: "14" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..62452f8e94 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "25 1 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "Stale issue message" + stale-pr-message: "Stale pull request message" + stale-issue-label: "no-issue-activity" + stale-pr-label: "no-pr-activity" diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml new file mode 100644 index 0000000000..acee01e2b2 --- /dev/null +++ b/.github/workflows/super-linter.yml @@ -0,0 +1,29 @@ +# This workflow executes several linters on changed files based on languages used in your code base whenever +# you push a code or open a pull request. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/github/super-linter +name: Lint Code Base + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] +jobs: + run-lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + # Full git history is needed to get a proper list of changed files within `super-linter` + fetch-depth: 0 + + - name: Lint Code Base + uses: github/super-linter@v4 + env: + VALIDATE_ALL_CODEBASE: false + DEFAULT_BRANCH: "master" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index de010e39bd..e79440f493 100644 --- a/.gitignore +++ b/.gitignore @@ -77,8 +77,12 @@ typings/ # gatsby files +<<<<<<< HEAD # .cache/ # public +======= + +>>>>>>> master # Mac files .DS_Store @@ -91,8 +95,13 @@ yarn-error.log .yarn-integrity node_modules/ +public/ +.cache/ +<<<<<<< HEAD .package-lock.json *.cache *public src/pages/docs/tools/Archive.md +======= +>>>>>>> master diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 0000000000..579ceb2f87 --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,4 @@ + +FROM gitpod/workspace-full + +RUN npm -g install gatsby-dev-cli diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 1f609ed928..0000000000 --- a/.markdownlint.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "default": true, - "MD026/":false, - "MD013": false, - "MD033":false, - "MD02":false, - "MD024":false, - "MD030":false, - "MD022":false, - "MD001":false, - "MD003":false, - "MD029": false, - "MD007": { "indent": 4 }, - "no-hard-tabs": false -} diff --git a/.node-version b/.node-version new file mode 100644 index 0000000000..654afc8e19 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +14.7.0 diff --git a/docs/content/cheat-sheets/react-cheatsheet.md b/.npmignore similarity index 100% rename from docs/content/cheat-sheets/react-cheatsheet.md rename to .npmignore diff --git a/.npmrc b/.npmrc index 3ce2c41f93..5d35b284eb 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -{ "engines" : { "node" : ">=0.15" } } +{ "engines" : { "node" : ">=0.14" } } diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json index 9551807b01..4871108954 100644 --- a/.vscode/PythonImportHelper-v2-Completion.json +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -1,8 +1,6 @@ -[ - { - "label": "Flask", - "importPath": "flask", - "description": "flask", +[{ + "label": "argparse", + "kind": 6, "isExtraImport": true, "detail": "flask", "documentation": {} diff --git a/HelloNetlifyGraph.md b/HelloNetlifyGraph.md deleted file mode 100644 index 5524b8df7f..0000000000 --- a/HelloNetlifyGraph.md +++ /dev/null @@ -1 +0,0 @@ -Thank you for checking out Netlify Graph, we hope you like it! \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index b42dc482c2..0000000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Bryan C Guner - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..8ff8459161 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,40 @@ +# License Agreement +##### Version 1.02 (02/14/2019) + +This Single Project License Agreement (**“Agreement”**) is between you and Stackbit Inc., a Delaware corporation (“Stackbit”) and governs Your right to use the website project including website theme and other media content (the "Project") obtained from or generated using our services available at www.stackbit.com (the "Services"). By clicking on the “Create Account” button (or any similar button) that is presented to you at the time of sign-up or by using the Site to generate a Project, you indicate that you agree to the terms and conditions of this Agreement. If You are accepting this Agreement on behalf of Your employer or other organization, You are agreeing to these terms for the entity and You represent and warrant that You have authority to bind such entity (party bound to this Agreement is referred to as “You”). + +1. **Definitions**. The capitalized terms shall have the meaning given in the relevant paragraph where such term is defined. In addition, the following terms shall have the meaning set forth below. + + **“Client"** means the person or entity whose website you are designing if you are a web developer, web designer, agency or a marketing agent. + + **“Theme”** means the website theme made available on the Site and generated using the Services, in HTML/JS/CSS electronic source code format together with any related developer documentation. + + **“Project”** means any work that includes a Theme or that is derived from or is a ‘derivative work’ of a Theme, as such terms are used under the United States Copyright Act of 1976, as amended. + +2. **License**. Subject to the terms and conditions of this Agreement, Stackbit hereby grants you a perpetual, non-exclusive, non-transferable, non-sublicensable limited license to use, modify, and display the Theme only as incorporated in a single Project as set forth in Section 3 below. All rights not granted herein are expressly reserved by Stackbit. + +3. **Permitted Use** + + You may use the Theme as it is incorporated into a single Project, either your own Project or the Project of your Client, and You may make modifications to the Theme necessary to fit the requirements of the Project provided that the Project and the use of the Project by You or the Client remains subject to this Agreement. You will own the Project you create, but Stackbit retains all right, title and interest in and to the Theme and other media content that are incorporated in your Project. You must retain and include all copyright notices and the terms of this License without modification in the files of the Project. You and Client must use the Project in compliance with all applicable federal, state and local laws, rules and regulations. + +4. **Prohibited Uses** + + You may not, and shall not permit anyone else to, use the Project or do anything with the Project that is not expressly permitted by this Agreement, including, but not limited to, the following strictly prohibited uses: + + 1. resell, sublicense or other transfer the Project or the Theme or other components thereof or your rights to use the Theme as set forth herein or otherwise make available or allows a person to access or reproduce the Theme as an electronic file, except in connection with the single Project and subject to Section 3 above; + + 2. Use, reproduce or display the Theme or Project in any manner that competitive with the Services or our business (e.g. inclusion as part of an online website builder service, or distribution outside the Services such as on a Theme/themes marketplace or a "freebies" website); + + 3. Use, reproduce or display of the Theme in a fashion that we consider as, or under applicable law is considered, pornographic, obscene, immoral, infringing, defamatory or libelous; and + + 4. Use or display of the Theme in an electronic format that enables it to be downloaded or distributed in any file sharing arrangement. + +5. **Ownership**. Stackbit shall retain and own all right, title and interest, including but not limited to copyright, patent, trade secret and all other intellectual property rights, in and to the Themes. You shall own all right, title and interest, including but not limited to copyright, patent, trade secret and all other intellectual property rights, in and to the Project, subject to Stackbit’s ownership of the Theme and the terms of this license agreement. + +6. **Term and Termination**. This Agreement shall commence on the deployment of a Project through Stackbit’s Services to a repository (such as for example to Github) and continue indefinitely until it is terminated in accordance with Section 6. Stackbit may terminate this Agreement if You breach the Agreement and such breach remains uncured for 15 days following Your receipt of written notice from Stackbit. You may terminate this Agreement for convenience and without cause at any time immediately upon written notice to Stackbit. Upon termination of this Agreement for any reason, You and your Client shall a) cease all use of the Theme and the Project b) destroy or delete all copies and archives of the Theme, Projects, and accompanying materials, and c) if requested, confirm to Stackbit in writing that you have complied with these requirements. Any provisions of this Agreement which expressly or by implication are intended to survive its termination will survive and continue to bind the parties. + +7. **Warranty and Disclaimer**. THE SERVICES, SITE, THEME, PROJECT AND ALL CONTENT AVAILABLE THROUGH THE SITE ARE OFFERED “AS IS” AND WITHOUT WARRANTY, AND STACKBIT MAKES NO REPRESENTATION OR WARRANTY OF ANY KIND, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY DISCLAIMS ALL WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE. + +8. **Limitation of Liability**. Stackbit’s aggregate liability for all claims, losses, liabilities or damages in connection with this Services, Theme, Project or this Agreement or its subject matter, whether as a result of breach of contract, tort (including negligence) or otherwise, regardless of the theory of liability asserted, is limited to no more than the total amount of fees paid to Stackbit under this Agreement, or $100, whichever is greater. In addition, Stackbit will not be liable in any event for lost profits, consequential, indirect, punitive, exemplary or special damages. + +9. **General**. This Agreement shall be governed by the law of the State of California, without reference to conflict of laws principles. The United Nations Convention on contracts for the International Sales of Goods shall not apply. This Agreement, together with the Stackbit Terms of Service at www.stackbit.com/tos/ represents the entire agreement between the parties with regard to the subject matter thereof and supersedes any prior understandings, proposals or agreements concerning the same subject matter. If any provision of this Agreement is found to be unenforceable or invalid, the remainder of such provision shall be enforced to the maximum extent permitted by law. No amendment or modification of this Agreement shall be valid or binding unless in a writing signed by representatives of both parties. You may not assign this Agreement without Stackbit’s prior written consent. Any attempted assignment in violation of this shall be null and void. This Agreement shall be binding upon and inure to the benefit of the parties hereto and their respective permitted successors and assigns. Any notice required or permitted to be given by either party under this Agreement shall be in writing and may be sent via an active Services account dashboard or shall be personally delivered or sent by commercial courier service, or by first class mail (certified or registered if available), or by telecopy confirmed by first class mail (registered or certified if available), to the other party at its address set forth below, or such new address as may from time-to-time be supplied hereunder by the parties hereto. diff --git a/README.md b/README.md index 354a04ea98..ec86fc5869 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ --- +<<<<<<< HEAD +======= +### [CHANGELOG](./CHANGELOG.md) +>>>>>>> master @@ -25,11 +29,15 @@
[![Netlify Status](https://api.netlify.com/api/v1/badges/a1b7ee1a-11a7-4bd2-a341-2260656e216f/deploy-status)](https://app.netlify.com/sites/bgoonz-blog/deploys)[![CodeFactor](https://www.codefactor.io/repository/github/bgoonz/bgoonz_blog_2.0/badge)](https://www.codefactor.io/repository/github/bgoonz/bgoonz_blog_2.0) - ![GitHub visitors](https://visitor-badge-reloaded.herokuapp.com/badge?page_id=bgoonz.visitor.badge.reloaded&color=00bbbb&style=for-the-badge&logo=github) +[![Deploy Gatsby site to Pages](https://github.com/DUKE42web/BGOONZ_BLOG_2.0/actions/workflows/pa7ges.yml/badge.svg?branch=master&event=deployment)](https://github.com/DUKE42web/BGOONZ_BLOG_2.0/actions/workflows/pa7ges.yml) +[![Lint Code Base](https://github.com/bgoonz/BGOONZ_BLOG_2.0/actions/workflows/super-linter.yml/badge.svg)](https://github.com/bgoonz/BGOONZ_BLOG_2.0/actions/workflows/super-linter.yml) + +[![Deploy Gatsby site to Pages](https://github.com/bgoonz/BGOONZ_BLOG_2.0/actions/workflows/pages.yml/badge.svg)](https://github.com/bgoonz/BGOONZ_BLOG_2.0/actions/workflows/pages.yml) --- +<<<<<<< HEAD ![preview](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/blog-preview.png?raw=true) @@ -39,9 +47,375 @@ ![Foo](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/Screenshot%202022-03-30%20at%2012-37-24%20Website%20Speed%20Test%20Tool%20-%20Testmysite.io%20by%20Netlify.png?raw=true)
+======= +#### Branch Deploys + +##### [Preview](https://preview--bgoonz-blog.netlify.app/) + +##### [local](https://local--bgoonz-blog.netlify.app/) + +##### []() + +##### []() + +##### []() + +##### []() + +##### []() + +##### []() + +docky src/components/**/*.js --watch "src/components/**/*.js","./README.md" --ignore "src/components/**/index.js" + +--- + +### Table Of Contents + +- [Bgoonz Blog Readme](#bgoonz-blog-readme) + - [⇨WEBSITE🗺️⇦](#website️) + - [CHANGELOG](#changelog) + - [⇨WEBSITE🗺️⇦ ⇨**Cloudfare-Backup**⇦ ⇨**search**⇦ ⇨**Backup Repo Deploy**⇦ ⇨**Github pages**⇦ ⇨**Go To Site Wiki**⇦ ⇨**Gatsby Cloud Version**⇦ ⇨**Vercel Version**⇦ ⇨**Cloudfare-Domain**⇦ ⇨**gh-pages**⇦ ⇨**backup netlify deploy**⇦](#website️-cloudfare-backup-search-backup-repo-deploy-github-pages-go-to-site-wiki-gatsby-cloud-version-vercel-version-cloudfare-domain-gh-pages-backup-netlify-deploy) + - [Repos](#repos) + - [⇨Privacy policy⇦](#privacy-policy) + - [](#) + - [Branch Deploys](#branch-deploys) + - [Preview](#preview) + - [local](#local) + - [](#-1) + - [](#-2) + - [](#-3) + - [](#-4) + - [](#-5) + - [](#-6) + - [Table Of Contents](#table-of-contents) + - [](#-7) + - [Useful Commands (internal use)](#useful-commands-internal-use) + - [Stable Points](#stable-points) + - [Links To Remember:](#links-to-remember) + - [Web Dev Setup](#web-dev-setup) + - [Basic Web Development Environment Setup](#basic-web-development-environment-setup) + - [Basic Web Development Environment Setup](#basic-web-development-environment-setup-1) + - [Windows Subsystem for Linux (WSL) and Ubuntu](#windows-subsystem-for-linux-wsl-and-ubuntu) + - [Test if you have Ubuntu installed by typing "Ubuntu" in the search box in the bottom app bar that reads "Type here to search". If you see a search result that reads **"Ubuntu 20.04 LTS"** with "App" under it, then you have it installed.](#test-if-you-have-ubuntu-installed-by-typing-ubuntu-in-the-search-box-in-the-bottom-app-bar-that-reads-type-here-to-search-if-you-see-a-search-result-that-reads-ubuntu-2004-lts-with-app-under-it-then-you-have-it-installed) + - [Git](#git) + - [Google Chrome](#google-chrome) + - [Node.js](#nodejs) + - [Unzip](#unzip) + - [Python 3](#python-3) + - [Note about WSL](#note-about-wsl) + - [Some other common instillations](#some-other-common-instillations) + - [](#-8) + - [Documentation Commands:](#documentation-commands) + - [documentation build src/components/ActionLink.js -f md\> ./notes/ActionLink.md](#documentation-build-srccomponentsactionlinkjs---f-md-notesactionlinkmd) + - [Blog Content:](#blog-content) + - [Bash Cheat Sheet (MY COMMANDS)](#bash-cheat-sheet-my-commands) + - [1. Remove spaces from file and folder names and then remove numbers from files and folder names](#1-remove-spaces-from-file-and-folder-names-and-then-remove-numbers-from-files-and-folder-names) + - [Description: need to : `sudo apt install rename`](#description-need-to--sudo-apt-install-rename) + - [code](#code) + - [2. Download Website Using Wget](#2-download-website-using-wget) + - [Description](#description) + - [code](#code-1) + - [3. Clean Out Messy Git Repo](#3-clean-out-messy-git-repo) + - [Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders](#description-recursively-removes-git-related-folders-as-well-as-internal-use-files--attributions-in-addition-to-empty-folders) + - [code](#code-2) + - [4. clone all of a user's git repositories](#4-clone-all-of-a-users-git-repositories) + - [Description: clone all of a user or organization's git repositories](#description-clone-all-of-a-user-or-organizations-git-repositories) + - [code](#code-3) + - [Generalized](#generalized) + - [Clone all Git User](#clone-all-git-user) + - [Clone all Git Organization](#clone-all-git-organization) + - [5. Git Workflow](#5-git-workflow) + - [Description](#description-1) + - [code](#code-4) + - [6. Recursive Unzip In Place](#6-recursive-unzip-in-place) + - [Description: recursively unzips folders and then deletes the zip file by the same name](#description-recursively-unzips-folders-and-then-deletes-the-zip-file-by-the-same-name) + - [code](#code-5) + - [7. git pull keeping local changes](#7-git-pull-keeping-local-changes) + - [Description](#description-2) + - [code](#code-6) + - [8. Prettier Code Formatter](#8-prettier-code-formatter) + - [Description](#description-3) + - [code](#code-7) + - [9. Pandoc](#9-pandoc) + - [Description](#description-4) + - [code](#code-8) + - [10. Gitpod Installs](#10-gitpod-installs) + - [Description](#description-5) + - [code](#code-9) + - [11. Repo Utils Package](#11-repo-utils-package) + - [Description: my standard repo utis package](#description-my-standard-repo-utis-package) + - [code](#code-10) + - [12. Unix Tree Package Usage](#12-unix-tree-package-usage) + - [Description](#description-6) + - [code](#code-11) + - [13. Find \& Replace string in file \& folder names recursively](#13-find--replace-string-in-file--folder-names-recursively) + - [Description](#description-7) + - [code](#code-12) + - [14. Remove double extensions](#14-remove-double-extensions) + - [Description](#description-8) + - [code](#code-13) + - [15. Truncate folder names down to 12 characters](#15-truncate-folder-names-down-to-12-characters) + - [Description: Truncate folder names down to 12 characters](#description-truncate-folder-names-down-to-12-characters) + - [code](#code-14) + - [16.Appendir.js](#16appendirjs) + - [Description: combine the contents of every file in the contaning directory](#description-combine-the-contents-of-every-file-in-the-contaning-directory) + - [code](#code-15) + - [17. Replace space in filename with underscore](#17-replace-space-in-filename-with-underscore) + - [Description: followed by replace `'#' with '_'` in directory name](#description-followed-by-replace--with-_-in-directory-name) + - [code](#code-16) + - [18. Filter \& delete files by name and extension](#18-filter--delete-files-by-name-and-extension) + - [Description](#description-9) + - [code](#code-17) + - [19. Remove lines containing string](#19-remove-lines-containing-string) + - [Description](#description-10) + - [code](#code-18) + - [20. Remove duplicate lines from a text file](#20-remove-duplicate-lines-from-a-text-file) + - [Description](#description-11) + - [code](#code-19) + - [21. Remove lines containing string](#21-remove-lines-containing-string) + - [Description](#description-12) + - [code](#code-20) + - [22. Zip directory excluding .git and node\_modules all the way down (Linux)](#22-zip-directory-excluding-git-and-node_modules-all-the-way-down-linux) + - [Descriptio: zip up an entire git directory](#descriptio-zip-up-an-entire-git-directory) + - [code](#code-21) + - [23. Delete files containing a certain string](#23-delete-files-containing-a-certain-string) + - [Description](#description-13) + - [code](#code-22) + - [24 Generate sitemap](#24-generate-sitemap) + - [Description](#description-14) + - [code](#code-23) + - [25. Index of Iframes](#25-index-of-iframes) + - [Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags](#description-creates-an-indexhtml-file-that-contains-all-the-files-in-the-working-directory-or-any-of-its-sub-folders-as-iframes-instead-of-anchor-tags) + - [code](#code-24) + - [26. Filter Corrupted Git Repo For Troublesome File](#26-filter-corrupted-git-repo-for-troublesome-file) + - [Description](#description-15) + - [code](#code-25) + - [27. OVERWRITE LOCAL CHANGES](#27-overwrite-local-changes) + - [Description](#description-16) + - [code](#code-26) + - [28. Remove Submodules](#28-remove-submodules) + - [Description: To remove a submodule you need to](#description-to-remove-a-submodule-you-need-to) + - [code](#code-27) + - [29. GET GISTS](#29-get-gists) + - [Description](#description-17) + - [code](#code-28) + - [30. Remove Remote OriginL](#30-remove-remote-originl) + - [Description](#description-18) + - [code](#code-29) + - [31. just clone .git folder](#31-just-clone-git-folder) + - [Description](#description-19) + - [code](#code-30) + - [32. Undo recent pull request](#32-undo-recent-pull-request) + - [Description](#description-20) + - [code](#code-31) + - [33. Lebab](#33-lebab) + - [Description: ES5 --\> ES6](#description-es5----es6) + - [code](#code-32) + - [34. Troubleshoot Ubuntu Input/Output Error](#34-troubleshoot-ubuntu-inputoutput-error) + - [Description: Open Powershell as Administrator](#description-open-powershell-as-administrator) + - [code](#code-33) + - [35. Export Medium as Markdown](#35-export-medium-as-markdown) + - [Description](#description-21) + - [code](#code-34) + - [36. Delete files in violation of a given size range (100MB for git)](#36-delete-files-in-violation-of-a-given-size-range-100mb-for-git) + - [Description](#description-22) + - [code](#code-35) + - [37. download all links of given file type](#37-download-all-links-of-given-file-type) + - [Description](#description-23) + - [code](#code-36) + - [38. Kill all node processes](#38-kill-all-node-processes) + - [Description](#description-24) + - [code](#code-37) + - [39. Remove string from file names recursively](#39-remove-string-from-file-names-recursively) + - [Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories](#description-in-the-example-below-i-am-using-this-command-to-remove-the-string--master-from-all-file-names-in-the-working-directory-and-all-of-its-sub-directories) + - [code](#code-38) + - [40. Remove spaces from file and folder names recursively](#40-remove-spaces-from-file-and-folder-names-recursively) + - [Description: replaces spaces in file and folder names with an `_` underscore](#description-replaces-spaces-in-file-and-folder-names-with-an-_-underscore) + - [code](#code-39) + - [41. Zip Each subdirectories in a given directory into their own zip file](#41-zip-each-subdirectories-in-a-given-directory-into-their-own-zip-file) + - [Description](#description-25) + - [code](#code-40) + - [91. Unzip PowerShell](#91-unzip-powershell) + - [Description](#description-26) + - [code](#code-41) + - [92. return to bash from zsh](#92-return-to-bash-from-zsh) + - [Description](#description-27) + - [code](#code-42) + - [93. Symbolic Link](#93-symbolic-link) + - [Description: to working directory](#description-to-working-directory) + - [code](#code-43) + - [94. auto generate readme](#94-auto-generate-readme) + - [Description: rename existing readme to blueprint.md](#description-rename-existing-readme-to-blueprintmd) + - [code](#code-44) + - [95. Log into postgres](#95-log-into-postgres) + - [Description](#description-28) + - [code](#code-45) + - [96. URL To Subscribe To YouTube Channel](#96-url-to-subscribe-to-youtube-channel) + - [| JavaScript libraries | Lodash ; Dojo ; core-js ; jQuery |](#-javascript-libraries--lodash--dojo--core-js--jquery-------------------------) + - [96. URL To Subscribe To YouTube Channel](#96-url-to-subscribe-to-youtube-channel-1) + - [Description](#description-29) + - [code](#code-46) + - [97. Embed Repl.it In Medium Post](#97-embed-replit-in-medium-post) + - [code](#code-47) + - [98 rRmove text target="parent" from files called right.html](#98-rrmove-text-targetparent-from-files-called-righthtml) + - [Description](#description-30) + - [code](#code-48) + - [99. Cheat Sheet](#99-cheat-sheet) + - [Description](#description-31) + - [code](#code-49) + - [Find](#find) + - [To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG)](#to-find-files-by-case-insensitive-extension-ex-jpg-jpg-jpg) + - [To find directories](#to-find-directories) + - [To find files](#to-find-files) + - [To find files by octal permission](#to-find-files-by-octal-permission) + - [To find files with setuid bit set](#to-find-files-with-setuid-bit-set) + - [To find files with extension '.txt' and remove them](#to-find-files-with-extension-txt-and-remove-them) + - [To find files with extension '.txt' and look for a string into them](#to-find-files-with-extension-txt-and-look-for-a-string-into-them) + - [To find files with size bigger than 5 Mebibyte and sort them by size](#to-find-files-with-size-bigger-than-5-mebibyte-and-sort-them-by-size) + - [To find files bigger than 2 Megabyte and list them](#to-find-files-bigger-than-2-megabyte-and-list-them) + - [To find files modified more than 7 days ago and list file information](#to-find-files-modified-more-than-7-days-ago-and-list-file-information) + - [To find symlinks owned by a user and list file information](#to-find-symlinks-owned-by-a-user-and-list-file-information) + - [To search for and delete empty directories](#to-search-for-and-delete-empty-directories) + - [To search for directories named build at a max depth of 2 directories](#to-search-for-directories-named-build-at-a-max-depth-of-2-directories) + - [To search all files who are not in .git directory](#to-search-all-files-who-are-not-in-git-directory) + - [To find all files that have the same node (hard link) as MY\_FILE\_HERE](#to-find-all-files-that-have-the-same-node-hard-link-as-my_file_here) + - [To find all files in the current directory and modify their permissions](#to-find-all-files-in-the-current-directory-and-modify-their-permissions) + - [find . -type f -exec chmod 644 {} ;](#find---type-f--exec-chmod-644--) + - [](#-9) + - [Wiki Nav](#wiki-nav) + - [Dependencies](#dependencies) + - [](#-10) + - [Docs Structure](#docs-structure) + - [SITEMAP](#sitemap) + - [](#-11) +- [](#-12) + - [🚀 Quick start](#-quick-start) + - [🧐 What's inside?](#-whats-inside) + - [🎓 Learning Gatsby](#-learning-gatsby) + - [💫 Deploy](#-deploy) + - [](#-13) + - [Gatsby With Netlify CMS](#gatsby-with-netlify-cms) + - [Prerequisites](#prerequisites) + - [Set up a Netlify CMS-managed Gatsby site in 5 steps](#set-up-a-netlify-cms-managed-gatsby-site-in-5-steps) + - [Step 1](#step-1) + - [Step 2](#step-2) + - [Step 3](#step-3) + - [Customizing your site](#customizing-your-site) + - [Step 4](#step-4) + - [Step 5](#step-5) + - [Benefits of Netlify CMS, GitHub, and Netlify Workflow](#benefits-of-netlify-cms-github-and-netlify-workflow) + - [You can learn more about Netlify CMS and how to configure it further in the Netlify CMS documentation](#you-can-learn-more-about-netlify-cms-and-how-to-configure-it-further-in-the-netlify-cms-documentation) + - [Gatsby Project Structure | Gatsby](#gatsby-project-structure--gatsby) + - [The file/folder structure described above reflects Gatsby-specific files and folders. Since Gatsby sites are also React apps, it's common to use standard React code organization patterns such as folders like `/components` and `/utils` inside `/src`. The React docs have more information on a typical React app folder structure.](#the-filefolder-structure-described-above-reflects-gatsby-specific-files-and-folders-since-gatsby-sites-are-also-react-apps-its-common-to-use-standard-react-code-organization-patterns-such-as-folders-like-components-and-utils-inside-src-the-react-docs-have-more-information-on-a-typical-react-app-folder-structure) + - [Layout Components | Gatsby](#layout-components--gatsby) + - [Excerpt](#excerpt) + - [Adding Markdown Pages | Gatsby](#adding-markdown-pages--gatsby) + - [](#-14) + - [Overview](#overview) + - [Syntax](#syntax) + - [Parameters](#parameters) + - [Return value](#return-value) + - [Example](#example) + - [Explanation](#explanation) + - [Output](#output) + - [Technoloy](#technoloy) + - [](#-15) + - [SOURCECODE](#sourcecode) + - [Overview](#overview-1) + - [Syntax](#syntax-1) + - [Parameters](#parameters-1) + - [Return value](#return-value-1) + - [Example](#example-1) + - [Explanation](#explanation-1) + - [Output](#output-1) + - [Source Code](#source-code) + - [Component Structure](#component-structure) + - [Table of Contents](#table-of-contents-1) + - [getPage](#getpage) + - [Parameters](#parameters-2) + - [getPageByFilePath](#getpagebyfilepath) + - [Parameters](#parameters-3) + - [getPages](#getpages) + - [Parameters](#parameters-4) + - [Examples](#examples) + +![preview](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/blog-may-2022.png?raw=true) +--- + +## Useful Commands (internal use) + +```bash +npm i @stackbit/gatsby-plugin-menus babel-runtime chokidar classnames fs-extra gatsby gatsby-image gatsby-plugin-netlify gatsby-plugin-netlify-cms gatsby-plugin-sass gatsby-plugin-react-helmet gatsby-plugin-typescript --legacy-peer-deps +git checkout 307a5cd # check out the commit that you want to reset to +git checkout -b fixy # create a branch named fixy to do the work +git merge -s ours master # merge master's history without changing any files +git checkout master # switch back to master +git merge fixy # and merge in the fixed branch +git push # done, no need to force push! +``` + +--- + +## Stable Points + +- [stable 8-13-2021](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/0c09a707f4bfddd974a31d97a4f8d716f1858ef8) or [or maybe](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/68fba78e36fffcf21288ea0e90e1075bf31b2a82) +- [Stable September 11](https://github.com/side-projects-42/BGOONZ_BLOG_2.0) +- [October Stable](https://github.com/Web-Dev-Collaborative/october-stable) +- [November 2021 stable](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/9ae5da5813cc9b48d2a57c84cd32cf4309078524) +- [Late November Stable](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/40ecc95f000a848710c39e166961b8da7fca306b) +- [December](https://github.com/bgoonz/BGOONZ_BLOG_2.0/tree/fc4a6ba1d61a3ef0b893cc5a44e41672547a3cc6) +- [Late December](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/848a8505eece492bfd9856eb63bd4acbee8bced6) +- [Late Febuary](https://deploy-preview-1697--bgoonz-blog.netlify.app/) +- [Late January](https://github.com/bgoonz/BGOONZ_BLOG_2.0/pull/1447) +- [Good stable point](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/90f70928a145c8a784899baf62efc2a0d5697bf4) +- [Stable March 13th 2022](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/c3f30229ac3dcd19ff54798227ce065c216e0c11) +- [Stable March 13th 2022](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/99db7b97282d7190556b2a1b1ac61d6d9c67f970) +[netlify-deploy-preview](https://deploy-preview-2280--bgoonz-blog.netlify.app/docs/tools/) +- [May fix](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/736d38cdcdd3692d6a3bf1d5485ac2b0a3824d02) + +- [Syntax hilighting working most recent](https://github.com/bgoonz/BGOONZ_BLOG_2.0/tree/db4d36067c1483c079389f1bd0e456c473c56710) +- [FINALLY FIXED](https://62b5863dd06870000889c5cf--bgoonz-blog.netlify.app/) + +- [Good deploy early Aug](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/a6bb13adf39305b7292a88bb1b37bb4bb2e5e76c) + +--- + +### Links To Remember: + + +- [Algolia Search UI](https://www.algolia.com/interface-demos/6ed0c3de-f9e4-4cc8-a7b2-c6c7c979cc5e) +- [Most recent stable commit](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/2448c20614bfef5491240d7da5b5e5873db8b586) +- [sitemap](https://www.xml-sitemaps.com/download/bgoonz-blog.netlify.app-ee43723d7/sitemap.xml?view=1) +- [initial commit](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/e8f12effd461b560b366ee0bde5231f2c1ce0a4c) +- [Static Html Version](https://github.com/Archive-42/bgoonz-blog-static) +- [commit pages](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commits/master?after=496dfce7e627bc81c80f7c0b5c41ecf420500b4a+34&branch=master) +- [alt blog contact page](https://bgoonz-blog-v3-0.netlify.app/contact/) +- [Resource Archive](https://resourcerepo2.netlify.app/) +- [starter](https://codesandbox.io/s/ecstatic-wozniak-gj31v?autoresize=1&expanddevtools=1&fontsize=12&hidenavigation=1&theme=dark) +- [Instant Search Demo](https://codesandbox.io/s/magical-davinci-l4hq6) +- [midway-commit](https://github.com/bgoonz/BGOONZ_BLOG_2.0/tree/92d88002bebcde66b47d8109222ac62c64fa9909) +- [blog2.0 backups](https://gist.github.com/bgoonz/68203bca236305d93d75e87533c7e8b8) +- [backup repo](https://github.com/bgoonz/BGOONZ_BLOG_2.0) +- [Bookmark website](https://github.com/side-projects-42/superb-celery) +- [stable stackbit](https://github.com/bgoonz/BGOONZ_BLOG_2.0/commit/69a617bbce1113e65390d90e0085be422e7f23e1) +- [repl.it for questions](https://comments-3.bgoonz.repl.co/) +- [rotate pages](https://random-static-html-deploys.netlify.app/rotate.html) +- [More widgets](https://webdevhub-1.disqus.com/) + + + + + +--- + +## Web Dev Setup +>>>>>>> master +
+<<<<<<< HEAD Bash Commands ## My Commands @@ -51,15 +425,27 @@ # To find files by case-insensitive extension (ex: .jpg, .jpg, .jpG) find . -iname "\*.jpg" +======= + + +Web Dev Setup + +## Basic Web Development Environment Setup +>>>>>>> master # To find directories +<<<<<<< HEAD find . -type d # To find files +======= +### Basic Web Development Environment Setup +>>>>>>> master find . -type f +<<<<<<< HEAD # To find files by octal permission find . -type f -perm 777 @@ -128,34 +514,173 @@ find . -name "* *" -type f | rename 's/ /_/g' ```sh ```sh -find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +======= +
-find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +![Web Dev Setup](https://cdn-images-1.medium.com/max/800/0*aqKP1drNHmNm34zz.jpg) -for i in *.html; do mv "$i" "${i%-*}.html"; done +
-for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done +###### Test if you have Ubuntu installed by typing "Ubuntu" in the search box in the bottom app bar that reads "Type here to search". If you see a search result that reads **"Ubuntu 20.04 LTS"** with "App" under it, then you have it installed. +``` +1. In the application search box in the bottom bar, type "PowerShell" to find the application named "Windows PowerShell" +2. Right-click on "Windows PowerShell" and choose "Run as administrator" from the popup menu +3. In the blue PowerShell window, type the following: `Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux` +4. Restart your computer +5. In the application search box in the bottom bar, type "Store" to find the application named "Microsoft Store" +6. Click "Microsoft Store" +7. Click the "Search" button in the upper-right corner of the window +8. Type in "Ubuntu" +9. Click "Run Linux on Windows (Get the apps)" +10. Click the orange tile labeled **"Ubuntu"** Note that there are 3 versions in the Microsoft Store… you want the one just entitled 'Ubuntu' +11. Click "Install" +12. After it downloads, click "Launch" +13. If you get the option, pin the application to the task bar. Otherwise, right-click on the orange Ubuntu icon in the task bar and choose "Pin to taskbar" +14. When prompted to "Enter new UNIX username", type your first name with no spaces +15. When prompted, enter and retype a password for this UNIX user (it can be the same as your Windows password) +16. Confirm your installation by typing the command `whoami 'as in who-am-i'`followed by Enter at the prompt (it should print your first name) +17. You need to update your packages, so type `sudo apt update` (if prompted for your password, enter it) +18. You need to upgrade your packages, so type `sudo apt upgrade` (if prompted for your password, enter it) +``` +### Git +Git comes with Ubuntu, so there's nothing to install. However, you should configure it using the following instructions. +Open an Ubuntu terminal if you don't have one open already. +1. > You need to configure Git, so type `git config --global user.name "Your Name"` with replacing "Your Name" with your real name. +2. > You need to configure Git, so type `git config --global user.email your@email.com` with replacing "your@email.com" with your real email. +**Note: if you want git to remember your login credentials type:** + git config --global credential.helper store +### Google Chrome +Test if you have Chrome installed by typing "Chrome" in the search box in the bottom app bar that reads "Type here to search". If you see a search result that reads "Chrome" with "App" under it, then you have it installed. Otherwise, follow these instructions to install Google Chrome. +### Node.js +Test if you have Node.js installed by opening an Ubuntu terminal and typing `node --version`. If it reports "Command 'node' not found", then you need to follow these directions. +1. > In the Ubuntu terminal, type `sudo apt update` and press Enter +2. > In the Ubuntu terminal, type `sudo apt install build-essential` and press Enter +3. > In the Ubuntu terminal, type `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash` and press Enter +4. > In the Ubuntu terminal, type `. ./.bashrc` and press Enter +5. > In the Ubuntu terminal, type `nvm install --lts` and press Enter +6. > Confirm that **node** is installed by typing `node --version` and seeing it print something that is not "Command not found"! +### Unzip +You will often have to download a zip file and unzip it. It is easier to do this from the command line. So we need to install a linux unzip utility. +In the Ubuntu terminal type: `sudo apt install unzip` and press Enter +Mocha.js +Test if you have Mocha.js installed by opening an Ubuntu terminal and typing `which mocha`. If it prints a path, then you're good. Otherwise, if it prints nothing, install Mocha.js by typing `npm install -g mocha`. +### Python 3 +Ubuntu does not come with Python 3. Install it using the command `sudo apt install python3`. Test it by typing `python3 --version` and seeing it print a number. +### Note about WSL +As of the time of writing of this document, WSL has an issue renaming or deleting files if Visual Studio Code is open. So before doing any linux commands which manipulate files, make sure you **close** Visual Studio Code before running those commands in the Ubuntu terminal. +### Some other common instillations +```bash + # Installing build essentials + sudo apt-get install -y build-essential libssl-dev + # Nodejs and NVM + curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash + source ~/.profile + sudo nvm install 7.10.0 + sudo nvm use 7.10.0 + node -v + #nodemon + sudo npm install -g nodemon + sudo npm install -g loopback-cli + # Forever to run nodejs scripts forever + sudo npm install forever -g + # Git - a version control system + sudo apt-get update + sudo apt-get install -y git xclip + # Grunt - an automated task runner + sudo npm install -g grunt-cli + # Bower - a dependency manager + sudo npm install -g bower + # Yeoman - for generators + sudo npm install -g yo + # maven + sudo apt-get install maven -y + # Gulp - an automated task runner + sudo npm install -g gulp-cli + # Angular FullStack - My favorite MEAN boilerplate (MEAN = MongoDB, Express, Angularjs, Nodejs) + sudo npm install -g generator-angular-fullstack + # Vim, Curl, Python - Some random useful stuff + sudo apt-get install -y vim curl python-software-properties + sudo apt-get install -y python-dev, python-pip + sudo apt-get install -y libkrb5-dev + # Installing JDK and JRE + sudo apt-get install -y default-jre + sudo apt-get install -y default-jdk + # Archive Extractors + sudo apt-get install -y unace unrar zip unzip p7zip-full p7zip-rar sharutils rar uudeview mpack arj cabextract file-roller + # FileZilla - a FTP client + sudo apt-get install -y filezilla +``` +
+--- +### Documentation Commands: +documentation build src/components/DocsMenu.js -f md> ./notes/DocsMenu.md +documentation build src/components/Footer.js -f md> ./notes/Footer.md +documentation build src/components/Header.js -f md> ./notes/Header.md +documentation build src/components/index.js -f md> ./notes/index.md +documentation build src/components/SectionContent.js -f md> ./notes/SectionContent.md +documentation build src/components/SectionDocs.js -f md> ./notes/SectionDocs.md +documentation build src/components/SectionHero.js -f md> ./notes/SectionHero.md +documentation build src/components/CtaButtons.js -f md> ./notes/CtaButtons.md +documentation build src/components/DocsSubmenu.js -f md> ./notes/DocsSubmenu.md +documentation build src/components/FormField.js -f md> ./notes/FormField.md +documentation build src/components/Icon.js -f md> ./notes/Icon.md +documentation build src/components/Layout.js -f md> ./notes/Layout.md +documentation build src/components/SectionCta.js -f md> ./notes/SectionCta.md +documentation build src/components/SectionGrid.js -f md> ./notes/SectionGrid.md +documentation build src/components/Submenu.js -f md> ./notes/Submenu.md +documentation build src/components/ActionLink.js -f md> ./notes/ActionLink.md +--- +## Blog Content: +--- +--- +## Bash Cheat Sheet (MY COMMANDS) + +
+ + + Bash Cheat Sheet (MY COMMANDS) + +## 1. Remove spaces from file and folder names and then remove numbers from files and folder names +### Description: need to : `sudo apt install rename` +> Notes: Issue when renaming file without numbers collides with existing file name... +###### code +```bash +find . -name "* *" -type d | rename 's/ /_/g' +find . -name "* *" -type f | rename 's/ /_/g' +``` +```bash +```bash +>>>>>>> master +find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +for i in*.html; do mv "$i" "${i%-*}.html"; done +for i in*.*; do mv "$i" "${i%-*}.${i##*.}"; done --- +<<<<<<< HEAD ## Description: combine the contents of every file in the contaning directory. > Notes: this includes the contents of the file it's self... ## # code: +======= +### Description: combine the contents of every file in the contaning directory. +>Notes: this includes the contents of the file it's self... +###### code: +>>>>>>> master ```js //APPEND-DIR.js const fs = require('fs'); let cat = require('child_process') - .execSync('cat *') +.execSync('cat*') .toString('UTF-8'); fs.writeFile('output.md', cat, err => { if (err) throw err; }); - ``` - --- +<<<<<<< HEAD # 2. Download Website Using Wget @@ -167,11 +692,17 @@ fs.writeFile('output.md', cat, err => { ```sh +======= +## 2. Download Website Using Wget +### Description +> Notes: ==> sudo apt install wget +###### code +```bash +>>>>>>> master wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/ - ``` - --- +<<<<<<< HEAD # 3. Clean Out Messy Git Repo @@ -183,15 +714,19 @@ wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e ro ```sh +======= +## 3. Clean Out Messy Git Repo +### Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders +> Notes: To clear up clutter in repositories that only get used on your local machine. +###### code +```bash +>>>>>>> master find . -empty -type d -print -delete - find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + - find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + - ``` - --- +<<<<<<< HEAD # 4. clone all of a user's git repositories @@ -205,37 +740,53 @@ find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.tx ```sh +======= +## 4. clone all of a user's git repositories +### Description: clone all of a user or organization's git repositories +> Notes: +###### code +## Generalized +```bash +>>>>>>> master CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone ``` +<<<<<<< HEAD # Clone all Git User ```sh +======= +## Clone all Git User +```bash +>>>>>>> master CNTX={users}; NAME={bgoonz}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone - ``` +<<<<<<< HEAD # Clone all Git Organization ```sh +======= +## Clone all Git Organization +```bash +>>>>>>> master CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone - ``` - --- +<<<<<<< HEAD # 5. Git Workflow @@ -244,43 +795,65 @@ curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=m ## ## code ```sh +======= +## 5. Git Workflow +### Description +###### code +```bash +>>>>>>> master git pull git init git add . git commit -m"update" git push -u origin master ``` +<<<<<<< HEAD ```sh +======= +```bash +>>>>>>> master git init git add . git commit -m"update" git push -u origin main ``` +<<<<<<< HEAD ```sh +======= +```bash +>>>>>>> master git init git add . git commit -m"update" git push -u origin bryan-guner ``` +<<<<<<< HEAD ```sh +======= +```bash +>>>>>>> master git init git add . git commit -m"update" git push -u origin gh-pages ``` +<<<<<<< HEAD ```sh +======= +```bash +>>>>>>> master git init git add . git commit -m"update" git push -u origin preview ``` - --- +<<<<<<< HEAD # 6. Recursive Unzip In Place @@ -292,13 +865,18 @@ git push -u origin preview ```sh +======= +## 6. Recursive Unzip In Place +### Description: recursively unzips folders and then deletes the zip file by the same name +> Notes: +###### code +```bash +>>>>>>> master find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; - find . -name "*.zip" -type f -print -delete - ``` - --- +<<<<<<< HEAD # 7. git pull keeping local changes @@ -310,13 +888,19 @@ find . -name "*.zip" -type f -print -delete ```sh +======= +## 7. git pull keeping local changes +### Description +> Notes: +###### code +```bash +>>>>>>> master git stash git pull git stash pop - ``` - --- +<<<<<<< HEAD # 8. Prettier Code Formatter @@ -328,13 +912,18 @@ git stash pop ```sh +======= +## 8. Prettier Code Formatter +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo npm i prettier -g - prettier --write . - ``` - --- +<<<<<<< HEAD # 9. Pandoc @@ -346,15 +935,19 @@ prettier --write . ```sh +======= +## 9. Pandoc +### Description +> Notes: +###### code +```bash +>>>>>>> master find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; - find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \; - find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \; - ``` - --- +<<<<<<< HEAD # 10. Gitpod Installs @@ -365,6 +958,13 @@ find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' { ## ## code ```sh +======= +## 10. Gitpod Installs +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo apt install tree sudo apt install pandoc -y sudo apt install rename -y @@ -373,17 +973,19 @@ sudo apt install wget -y npm i lebab -g npm i prettier -g npm i npm-recursive-install -g - ``` +<<<<<<< HEAD ```sh +======= +```bash +>>>>>>> master black . - prettier --write . npm-recursive-install ``` - --- +<<<<<<< HEAD # 11. Repo Utils Package @@ -394,11 +996,17 @@ npm-recursive-install ## ## code ```sh +======= +## 11. Repo Utils Package +### Description: my standard repo utis package +> Notes: +###### code +```bash +>>>>>>> master npm i @bgoonz11/repoutils - ``` - --- +<<<<<<< HEAD # 12. Unix Tree Package Usage @@ -409,9 +1017,16 @@ npm i @bgoonz11/repoutils ## ## code ```sh +======= +## 12. Unix Tree Package Usage +### Description +> Notes: +###### code +```bash +>>>>>>> master tree -d -I 'node_modules' - tree -I 'node_modules' +<<<<<<< HEAD tree -f -I 'node_modules' > TREE.md @@ -423,9 +1038,16 @@ tree -f -I 'node_modules' -d > TREE.md tree -f > README.md +======= +tree -f -I 'node_modules' >TREE.md +tree -f -L 2 >README.md +tree -f -I 'node_modules' >listing-path.md +tree -f -I 'node_modules' -d >TREE.md +tree -f >README.md +>>>>>>> master ``` - --- +<<<<<<< HEAD # 13. Find & Replace string in file & folder names recursively @@ -437,23 +1059,23 @@ tree -f > README.md ```sh +======= +## 13. Find & Replace string in file & folder names recursively +### Description +> Notes: +###### code +```bash +>>>>>>> master find . -type f -exec rename 's/string1/string2/g' {} + - find . -type d -exec rename 's/-master//g' {} + - find . -type f -exec rename 's/\.download//g' {} + - find . -type d -exec rename 's/-main//g' {} + - -rename 's/\.js\.download$/.js/' *.js\.download - +rename 's/\.js\.download$/.js/'*.js\.download rename 's/\.html\.markdown$/.md/' *.html\.markdown - find . -type d -exec rename 's/es6//g' {} + - ``` - --- +<<<<<<< HEAD # 14. Remove double extensions @@ -467,35 +1089,46 @@ find . -type d -exec rename 's/es6//g' {} + #!/bin/bash for file in *.md.md +======= +## 14. Remove double extensions +### Description +> Notes: +###### code +```bash +# !/bin/bash +for file in*.md.md +>>>>>>> master do mv "${file}" "${file%.md}" done - -#!/bin/bash - +# !/bin/bash for file in *.html.html do mv "${file}" "${file%.html}" done ``` +<<<<<<< HEAD ```sh #!/bin/bash for file in *.html.png +======= +```bash +# !/bin/bash +for file in*.html.png +>>>>>>> master do mv "${file}" "${file%.png}" done - for file in *.jpg.jpg do mv "${file}" "${file%.png}" done - ``` - --- +<<<<<<< HEAD # 15. Truncate folder names down to 12 characters @@ -507,11 +1140,17 @@ done ```sh +======= +## 15. Truncate folder names down to 12 characters +### Description: Truncate folder names down to 12 characters +> Notes: Truncate folder names down to 12 characters +###### code +```bash +>>>>>>> master for d in ./*; do mv $d ${d:0:12}; done - ``` - --- +<<<<<<< HEAD # 16.Appendir.js @@ -521,6 +1160,12 @@ for d in ./*; do mv $d ${d:0:12}; done ## ## code +======= +## 16.Appendir.js +### Description: combine the contents of every file in the contaning directory +> Notes: this includes the contents of the file it's self... +###### code +>>>>>>> master ```js //APPEND-DIR.js const fs = require('fs'); @@ -529,8 +1174,8 @@ fs.writeFile('output.md', cat, (err) => { if (err) throw err; }); ``` - --- +<<<<<<< HEAD # 17. Replace space in filename with underscore @@ -541,13 +1186,18 @@ fs.writeFile('output.md', cat, (err) => { ## ## code ```sh +======= +## 17. Replace space in filename with underscore +### Description: followed by replace `'#' with '_'` in directory name +> Notes: Can be re-purposed to find and replace any set of strings in file or folder names. +###### code +```bash +>>>>>>> master find . -name "* *" -type f | rename 's/_//g' - find . -name "* *" -type d | rename 's/#/_/g' - ``` - --- +<<<<<<< HEAD # 18. Filter & delete files by name and extension @@ -558,23 +1208,23 @@ find . -name "* *" -type d | rename 's/#/_/g' ## ## code ```sh +======= +## 18. Filter & delete files by name and extension +### Description +> Notes: +###### code +```bash +>>>>>>> master find . -name '.bin' -type d -prune -exec rm -rf '{}' + - find . -name '*.html' -type d -prune -exec rm -rf '{}' + - find . -name 'nav-index' -type d -prune -exec rm -rf '{}' + - find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + - find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' + - find . -name 'right.html' -type f -prune -exec rm -rf '{}' + - find . -name 'left.html' -type f -prune -exec rm -rf '{}' + - ``` - --- +<<<<<<< HEAD # 19. Remove lines containing string @@ -584,45 +1234,58 @@ find . -name 'left.html' -type f -prune -exec rm -rf '{}' + ```sh +======= +## 19. Remove lines containing string +### Description +> Notes: Remove lines not containing `'.js'` +```bash +>>>>>>> master sudo sed -i '/\.js/!d' ./*scrap2.md - ``` +<<<<<<< HEAD ## ## code ```sh +======= +###### code +```bash +>>>>>>> master sudo sed -i '/githubusercontent/d' ./*sandbox.md - sudo sed -i '/githubusercontent/d' ./*scrap2.md - sudo sed -i '/github\.com/d' ./*out.md - sudo sed -i '/author/d' ./* - ``` - --- +<<<<<<< HEAD # 20. Remove duplicate lines from a text file ## Description +======= +## 20. Remove duplicate lines from a text file +### Description +>>>>>>> master > Notes: > //...syntax of uniq...// > $uniq [OPTION] [INPUT[OUTPUT]] > The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn't specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn't specified then uniq writes to the standard output. - Now, let's understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq. +<<<<<<< HEAD ## ## code ```sh +======= +###### code +```bash +>>>>>>> master sudo apt install uniq uniq -u input.txt output.txt - ``` - --- +<<<<<<< HEAD # 21. Remove lines containing string @@ -633,34 +1296,34 @@ uniq -u input.txt output.txt ## ## code ```sh +======= +## 21. Remove lines containing string +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo sed -i '/githubusercontent/d' ./*sandbox.md - sudo sed -i '/githubusercontent/d' ./*scrap2.md - sudo sed -i '/github\.com/d' ./*out.md - --- title: add_days tags: date,intermediate firstSeen: 2020-10-28T16:19:04+02:00 lastUpdated: 2020-10-28T16:19:04+02:00 --- - sudo sed -i '/title:/d' ./*output.md sudo sed -i '/firstSeen/d' ./*output.md sudo sed -i '/lastUpdated/d' ./*output.md sudo sed -i '/tags:/d' ./*output.md - sudo sed -i '/badstring/d' ./* - sudo sed -i '/stargazers/d' ./repo.txt sudo sed -i '/node_modules/d' ./index.html sudo sed -i '/right\.html/d' ./index.html sudo sed -i '/right\.html/d' ./right.html - ``` - --- +<<<<<<< HEAD # 22. Zip directory excluding .git and node_modules all the way down (Linux) @@ -673,10 +1336,18 @@ sudo sed -i '/right\.html/d' ./right.html ```sh #!/bin/bash +======= +## 22. Zip directory excluding .git and node_modules all the way down (Linux) +### Descriptio: zip up an entire git directory +> Notes: +###### code +```bash +# !/bin/bash +>>>>>>> master TSTAMP=`date '+%Y%m%d-%H%M%S'` zip -r $1.$TSTAMP.zip $1 -x "**.git/*" -x "**node_modules/*" `shift; echo $@;` - printf "\nCreated: $1.$TSTAMP.zip\n" +<<<<<<< HEAD # usage: # - zipdir thedir @@ -685,9 +1356,16 @@ printf "\nCreated: $1.$TSTAMP.zip\n" # if in windows/git-bash, add 'zip' command this way: # https://stackoverflow.com/a/55749636/1482990 +======= +## usage: +## - zipdir thedir +## - zip thedir -x "anotherexcludedsubdir" (important the double quotes to prevent glob expansion) +## if in windows/git-bash, add 'zip' command this way: +## https://stackoverflow.com/a/55749636/1482990 +>>>>>>> master ``` - --- +<<<<<<< HEAD # 23. Delete files containing a certain string @@ -699,12 +1377,19 @@ printf "\nCreated: $1.$TSTAMP.zip\n" ```sh find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh +======= +## 23. Delete files containing a certain string +### Description +> Notes: +###### code +```bash +find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh +>>>>>>> master vi doit.sh // check for murphy and his law source doit.sh - ``` - --- +<<<<<<< HEAD # 24 @@ -937,21 +1622,187 @@ cmd $listing --sort=extension > > $html ```sh +======= +## 24 Generate sitemap +### Description +> Notes: bash command to auto generate sitemap.html which will list all files contained within parent directory. +###### code +```bash +# !/bin/sh +## find ./ | grep -i "\.*$" >files +find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files +listing="files" +out="" +html="sitemap.html" +out="basename $out.html" +html="sitemap.html" +cmd() { + echo ' ' + echo '' + echo '' + echo ' ' + echo ' ' + echo '' + echo ' ' + echo ' ' + echo " directory " + echo '' + echo '' + echo "" + echo '' + echo '' + echo '' + echo "" + # continue with the HTML stuff + echo "" + echo "" + echo "
    " + awk '{print "
  • ",$1," 
  • "}' $listing + # awk '{print "
  • "}; + # {print " ",$1,"
  •  "}' \ $listing + echo "" + echo "
" + echo "" + echo "" +} +cmd $listing --sort=extension >>$html +``` +--- +## 25. Index of Iframes +### Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags +> Notes: Useful Follow up Code: +```bash +``` +###### code +```bash +# !/bin/sh +## find ./ | grep -i "\.*$" >files +find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files +listing="files" +out="" +html="index.html" +out="basename $out.html" +html="index.html" +cmd() { + echo ' ' + echo '' + echo '' + echo ' ' + echo ' ' + echo '' + echo ' ' + echo ' ' + echo " directory " + echo "" + echo '' + echo '' + echo '' + echo "" + # continue with the HTML stuff + echo "" + echo "" + echo "
    " + awk '{print ""}' $listing + # awk '{print "
  • "}; + # {print " ",$1,"
  •  "}' \ $listing + echo "" + echo "
" + echo "" + echo "" +} +cmd $listing --sort=extension >>$html +``` +--- +## 26. Filter Corrupted Git Repo For Troublesome File +### Description +> Notes: +###### code +```bash +>>>>>>> master git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD - ``` - --- +<<<<<<< HEAD # 27. OVERWRITE LOCAL CHANGES ## Description +======= +## 27. OVERWRITE LOCAL CHANGES +### Description +>>>>>>> master Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected. - > Notes: > First, run a fetch to update all origin/ refs to latest: +<<<<<<< HEAD ## ## code @@ -971,19 +1822,35 @@ git reset --hard origin/ # git fetch downloads the latest from remote without trying to merge or rebase anything. # Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master +======= +###### code +```bash +git fetch --all +## Backup your current branch: +git branch backup-master +## Then, you have two options: +git reset --hard origin/master +## OR If you are on some other branch: +git reset --hard origin/ +## Explanation: +## git fetch downloads the latest from remote without trying to merge or rebase anything. +## Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master +>>>>>>> master git fetch --all git reset --hard origin/master - ``` - --- +<<<<<<< HEAD # 28. Remove Submodules ## Description: To remove a submodule you need to +======= +## 28. Remove Submodules +### Description: To remove a submodule you need to +>>>>>>> master > Notes: - > Delete the relevant section from the .gitmodules file. > Stage the .gitmodules changes git add .gitmodules > Delete the relevant section from .git/config. @@ -991,14 +1858,19 @@ git reset --hard origin/master > Run rm -rf .git/modules/path_to_submodule (no trailing slash). > Commit git commit -m "Removed submodule " > Delete the now untracked submodule files rm -rf path_to_submodule +<<<<<<< HEAD ## ## code ```sh +======= +###### code +```bash +>>>>>>> master git submodule deinit ``` - --- +<<<<<<< HEAD # 29. GET GISTS @@ -1009,19 +1881,21 @@ git submodule deinit ## ## code ```sh +======= +## 29. GET GISTS +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo apt install wget - wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget - wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget - wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget - wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget - ``` - --- +<<<<<<< HEAD # 30. Remove Remote OriginL @@ -1033,11 +1907,17 @@ wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F ```sh +======= +## 30. Remove Remote OriginL +### Description +> Notes: +###### code +```bash +>>>>>>> master git remote remove origin - ``` - --- +<<<<<<< HEAD # 31. just clone .git folder @@ -1049,11 +1929,17 @@ git remote remove origin ```sh +======= +## 31. just clone .git folder +### Description +> Notes: +###### code +```bash +>>>>>>> master git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git - ``` - --- +<<<<<<< HEAD # 32. Undo recent pull request @@ -1065,11 +1951,17 @@ git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-We ```sh +======= +## 32. Undo recent pull request +### Description +> Notes: +###### code +```bash +>>>>>>> master git reset --hard master@{"10 minutes ago"} - ``` - --- +<<<<<<< HEAD # 33. Lebab @@ -1082,6 +1974,14 @@ git reset --hard master@{"10 minutes ago"} ```sh # Safe: +======= +## 33. Lebab +### Description: ES5 --> ES6 +> Notes: +###### code +```bash +## Safe: +>>>>>>> master lebab --replace ./ --transform arrow lebab --replace ./ --transform arrow-return lebab --replace ./ --transform for-of @@ -1091,9 +1991,13 @@ git reset --hard master@{"10 minutes ago"} lebab --replace ./ --transform obj-method lebab --replace ./ --transform obj-shorthand lebab --replace ./ --transform multi-var +<<<<<<< HEAD # ALL: +======= +## ALL: +>>>>>>> master lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow @@ -1123,10 +2027,9 @@ lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param lebab --replace ./ --transform includes - ``` - --- +<<<<<<< HEAD # 34. Troubleshoot Ubuntu Input/Output Error @@ -1136,15 +2039,18 @@ lebab --replace ./ --transform includes ## ## code +======= +## 34. Troubleshoot Ubuntu Input/Output Error +### Description: Open Powershell as Administrator +> Notes: +###### code +>>>>>>> master ```ps1 - wsl.exe --shutdown - Get-Service LxssManager | Restart-Service - ``` - --- +<<<<<<< HEAD # 35. Export Medium as Markdown @@ -1159,9 +2065,18 @@ npm i mediumexporter -g mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 > ds.md +======= +## 35. Export Medium as Markdown +### Description +> Notes: +###### code +```bash +npm i mediumexporter -g +mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md +>>>>>>> master ``` - --- +<<<<<<< HEAD # 36. Delete files in violation of a given size range (100MB for git) @@ -1173,13 +2088,18 @@ mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascrip ```sh +======= +## 36. Delete files in violation of a given size range (100MB for git) +### Description +> Notes: +###### code +```bash +>>>>>>> master find . -size +75M -a -print -a -exec rm -f {} \; - find . -size +98M -a -print -a -exec rm -f {} \; - ``` - --- +<<<<<<< HEAD # 37. download all links of given file type @@ -1191,11 +2111,17 @@ find . -size +98M -a -print -a -exec rm -f {} \; ```sh +======= +## 37. download all links of given file type +### Description +> Notes: +###### code +```bash +>>>>>>> master wget -r -A.pdf https://overapi.com/git - ``` - --- +<<<<<<< HEAD # 38. Kill all node processes @@ -1206,11 +2132,17 @@ wget -r -A.pdf https://overapi.com/git ## ## code ```sh +======= +## 38. Kill all node processes +### Description +> Notes: +###### code +```bash +>>>>>>> master killall -s KILL node - ``` - --- +<<<<<<< HEAD # 39. Remove string from file names recursively @@ -1221,20 +2153,31 @@ killall -s KILL node ```sh find -type f -exec sed -i 's/ / /g' {} + +======= +## 39. Remove string from file names recursively +### Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories +###### code +```bash +find -type f -exec sed -i 's///g' {} + +>>>>>>> master find . -type f -exec rename 's/-master//g' {} + - ``` +<<<<<<< HEAD > Notes: The same could be done for folder names by changing the _-type f_ flag (for file) to a _-type d_ flag (for directory) ```sh find -type d -exec sed -i 's/ / /g' {} + +======= +> Notes: The same could be done for folder names by changing the*-type f*flag (for file) to a*-type d*flag (for directory) +```bash +find -type d -exec sed -i 's///g' {} + +>>>>>>> master find . -type d -exec rename 's/-master//g' {} + - ``` - --- +<<<<<<< HEAD # 40. Remove spaces from file and folder names recursively @@ -1246,11 +2189,18 @@ find . -type d -exec rename 's/-master//g' {} + ```sh +======= +## 40. Remove spaces from file and folder names recursively +### Description: replaces spaces in file and folder names with an `_` underscore +> Notes: need to run `sudo apt install rename` to use this command +###### code +```bash +>>>>>>> master find . -name "* *" -type d | rename 's/ /_/g' find . -name "* *" -type f | rename 's/ /_/g' ``` - --- +<<<<<<< HEAD # 41. Zip Each subdirectories in a given directory into their own zip file @@ -1263,9 +2213,17 @@ find . -name "* *" -type f | rename 's/ /_/g' ```sh for i in */; do zip -r "${i%/}.zip" "$i"; done +======= +## 41. Zip Each subdirectories in a given directory into their own zip file +### Description +> Notes: +###### code +```bash +for i in*/; do zip -r "${i%/}.zip" "$i"; done +>>>>>>> master ``` - --- +<<<<<<< HEAD # 90 @@ -1277,30 +2235,35 @@ for i in */; do zip -r "${i%/}.zip" "$i"; done ## ## code +======= +## 91. Unzip PowerShell +### Description +> Notes: +###### code +>>>>>>> master ```ps1 - PARAM ( [string] $ZipFilesPath = "./", [string] $UnzipPath = "./RESULT" ) - $Shell = New-Object -com Shell.Application $Location = $Shell.NameSpace($UnzipPath) - $ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP - $progress = 1 foreach ($ZipFile in $ZipFiles) { - Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" +Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1))* 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" $ZipFolder = $Shell.NameSpace($ZipFile.fullname) +<<<<<<< HEAD $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - http://msdn.microsoft.com/en-us/library/bb787866%28VS.85%29.aspx +======= + $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - https://msdn.microsoft.com/library/bb787866%28VS.85%29.aspx +>>>>>>> master $progress++ } - ``` - --- +<<<<<<< HEAD # 92. return to bash from zsh @@ -1311,11 +2274,17 @@ foreach ($ZipFile in $ZipFiles) { ## ## code ```sh +======= +## 92. return to bash from zsh +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo apt --purge remove zsh - ``` - --- +<<<<<<< HEAD # 93. Symbolic Link @@ -1327,13 +2296,18 @@ foreach ($ZipFile in $ZipFiles) { ```sh +======= +## 93. Symbolic Link +### Description: to working directory +> Notes: +###### code +```bash +>>>>>>> master ln -s "$(pwd)" ~/NameOfLink - ln -s "$(pwd)" ~/Downloads - ``` - --- +<<<<<<< HEAD # 94. auto generate readme @@ -1345,11 +2319,17 @@ ln -s "$(pwd)" ~/Downloads ```sh +======= +## 94. auto generate readme +### Description: rename existing readme to blueprint.md +> Notes: +###### code +```bash +>>>>>>> master npx @appnest/readme generate - ``` - --- +<<<<<<< HEAD # 95. Log into postgres @@ -1360,13 +2340,23 @@ npx @appnest/readme generate ## ## code ```sh +======= +## 95. Log into postgres +### Description +> Notes: +###### code +```bash +>>>>>>> master sudo -u postgres psql ``` - --- +<<<<<<< HEAD ## Technologies Used +======= +## 96. URL To Subscribe To YouTube Channel +>>>>>>> master | URL | | |----------------------|----------------------------------------------------------| | Miscellaneous | webpack ; Prism | @@ -1381,6 +2371,7 @@ sudo -u postgres psql | Tag managers | Google Tag Manager | | Live chat | Smartsupp ; LiveChat : Mesibo API | | JavaScript libraries | Lodash ; Dojo ; core-js ; jQuery | +<<<<<<< HEAD @@ -1388,37 +2379,41 @@ sudo -u postgres psql # 96. URL To Subscribe To YouTube Channel +======= +--- +## 96. URL To Subscribe To YouTube Channel +>>>>>>> master ## Description - > Notes: +<<<<<<< HEAD ## ## code +======= +###### code +>>>>>>> master ```txt - https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1 - ``` - --- +<<<<<<< HEAD # 97. Embed Repl.it In Medium Post ## ## code +======= +## 97. Embed Repl.it In Medium Post +###### code +>>>>>>> master ```txt - https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - https://repl.it/@bgoonz/node-db1-project?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - https://repl.it/@bgoonz/interview-prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - https://repl.it/@bgoonz/Database-Prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - ``` - --- +<<<<<<< HEAD # 98 @@ -1430,19 +2425,474 @@ https://repl.it/@bgoonz/Database-Prac?lite=true&referrer=https%3A%2F%2Fbryan ```sh +======= +## 98 rRmove text target="parent" from files called right.html +### Description +> Notes: +###### code +```bash +>>>>>>> master find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + - -find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + - +find . -name*right.html -type f -exec sed -i 's/target="_parent"//g' {} + ``` +<<<<<<< HEAD +======= +## 99. Cheat Sheet +### Description +> Notes: +###### code +```bash +# !/bin/bash +revert +## SHORTCUTS and HISTORY +CTRL+A # move to beginning of line +CTRL+B # moves backward one character +CTRL+C # halts the current command +CTRL+D # deletes one character backward or logs out of current session, similar to exit +CTRL+E # moves to end of line +CTRL+F # moves forward one character +CTRL+G # aborts the current editing command and ring the terminal bell +CTRL+H # deletes one character under cursor (same as DELETE) +CTRL+J # same as RETURN +CTRL+K # deletes (kill) forward to end of line +CTRL+L # clears screen and redisplay the line +CTRL+M # same as RETURN +CTRL+N # next line in command history +CTRL+O # same as RETURN, then displays next line in history file +CTRL+P # previous line in command history +CTRL+Q # resumes suspended shell output +CTRL+R # searches backward +CTRL+S # searches forward or suspends shell output +CTRL+T # transposes two characters +CTRL+U # kills backward from point to the beginning of line +CTRL+V # makes the next character typed verbatim +CTRL+W # kills the word behind the cursor +CTRL+X # lists the possible filename completions of the current word +CTRL+Y # retrieves (yank) last item killed +CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background +ALT+B # moves backward one word +ALT+D # deletes next word +ALT+F # moves forward one word +ALT+H # deletes one character backward +ALT+T # transposes two words +ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. +ALT+U # capitalizes every character from the current cursor position to the end of the word +ALT+L # uncapitalizes every character from the current cursor position to the end of the word +ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. +ALT+R # reverts any changes to a command you've pulled from your history if you've edited it. +ALT+? # list possible completions to what is typed +ALT+^ # expand line to most recent match from history +CTRL+X then ( # start recording a keyboard macro +CTRL+X then ) # finish recording keyboard macro +CTRL+X then E # recall last recorded keyboard macro +CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands +BACKSPACE # deletes one character backward +DELETE # deletes one character under cursor +history # shows command line history +!! # repeats the last command +! # refers to command line 'n' +! # refers to command starting with 'string' +exit # logs out of current session +## BASH BASICS +env # displays all environment variables +echo $SHELL # displays the shell you're using +echo $BASH_VERSION # displays bash version +bash # if you want to use bash (type exit to go back to your previously opened shell) +whereis bash # locates the binary, source and manual-page for a command +which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) +clear # clears content on window (hide displayed lines) +## FILE COMMANDS +ls # lists your files in current directory, ls to print files in a specific directory +ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified +ls -a # lists all files in 'long format', including hidden files (name beginning with '.') +ln -s # creates symbolic link to file +readlink # shows where a symbolic links points to +tree # show directories and subdirectories in easilly readable file tree +mc # terminal file explorer (alternative to ncdu) +touch # creates or updates (edit) your file +mktemp -t # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) +cat # prints file raw content (will not be interpreted) +any_command > # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) +more # shows the first part of a file (move with space and type q to quit) +head # outputs the first lines of file (default: 10 lines) +tail # outputs the last lines of file (useful with -f option) (default: 10 lines) +vim # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist +mv # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) +cp # copies a file +rm # removes a file +find . -name # searches for a file or a directory in the current directory and all its sub-directories by its name +diff # compares files, and shows where they differ +wc # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations +sort # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. +sort -t -k # sorts the contents on specific sort key field starting from 1, using the field separator t. +rev # reverse string characters (hello becomes olleh) +chmod -options # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) +gzip # compresses files using gzip algorithm +gunzip # uncompresses files compressed by gzip +gzcat # lets you look at gzipped file without actually having to gunzip it +lpr # prints the file +lpq # checks out the printer queue +lprm # removes something from the printer queue +genscript # converts plain text files into postscript for printing and gives you some options for formatting +dvips # prints .dvi files (i.e. files produced by LaTeX) +grep # looks for the string in the files +grep -r # search recursively for pattern in directory +head -n file_name | tail +n # Print nth line from file. +head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines. +## DIRECTORY COMMANDS +mkdir # makes a new directory +rmdir # remove an empty directory +rmdir -rf # remove a non-empty directory +mv # rename a directory from to +cd # changes to home +cd .. # changes to the parent directory +cd # changes directory +cp -r # copy into including sub-directories +pwd # tells you where you currently are +cd ~ # changes to home. +cd - # changes to previous working directory +## SSH, SYSTEM INFO & NETWORK COMMANDS +ssh user@host # connects to host as user +ssh -p user@host # connects to host on specified port as user +ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login +whoami # returns your username +passwd # lets you change your password +quota -v # shows what your disk quota is +date # shows the current date and time +cal # shows the month's calendar +uptime # shows current uptime +w # displays whois online +finger # displays information about user +uname -a # shows kernel information +man # shows the manual for specified command +df # shows disk usage +du # shows the disk usage of the files and directories in filename (du -s give only a total) +last # lists your last logins +ps -u yourusername # lists your processes +kill # kills the processes with the ID you gave +killall # kill all processes with the name +top # displays your currently active processes +lsof # lists open files +bg # lists stopped or background jobs ; resume a stopped job in the background +fg # brings the most recent job in the foreground +fg # brings job to the foreground +ping # pings host and outputs results +whois # gets whois information for domain +dig # gets DNS information for domain +dig -x # reverses lookup host +wget # downloads file +time # report time consumed by command execution +## VARIABLES +varname=value # defines a variable +varname=value command # defines a variable to be in the environment of a particular subprocess +echo $varname # checks a variable's value +echo $$ # prints process ID of the current shell +echo $! # prints process ID of the most recently invoked background job +echo $? # displays the exit status of the last command +read # reads a string from the input and assigns it to a variable +read -p "prompt" # same as above but outputs a prompt to ask user for value +column -t # display info in pretty columns (often used with pipe) +let = # performs mathematical calculation using operators like +, -, *, /, % +export VARNAME=value # defines an environment variable (will be available in subprocesses) +array[0]=valA # how to define an array +array[1]=valB +array[2]=valC +array=([2]=valC [0]=valA [1]=valB) # another way +array=(valA valB valC) # and another +${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed +${#array[i]} # to find out the length of any element in the array +${#array[@]} # to find out how many values there are in the array +declare -a # the variables are treated as arrays +declare -f # uses function names only +declare -F # displays function names without definitions +declare -i # the variables are treated as integers +declare -r # makes the variables read-only +declare -x # marks the variables for export via the environment +${varname:-word} # if varname exists and isn't null, return its value; otherwise return word +${varname:word} # if varname exists and isn't null, return its value; otherwise return word +${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value +${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script +${varname:+word} # if varname exists and isn't null, return word; otherwise return null +${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters +${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest +${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest +${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest +${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest +${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced +${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced +${#varname} # returns the length of the value of the variable as a character string +*(patternlist) # matches zero or more occurrences of the given patterns ++(patternlist) # matches one or more occurrences of the given patterns +?(patternlist) # matches zero or one occurrence of the given patterns +@(patternlist) # matches exactly one of the given patterns +!(patternlist) # matches anything except one of the given patterns +$(UNIX command) # command substitution: runs the command and returns standard output +## FUNCTIONS +## The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth. +## $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters. +function functname() { + shell commands +} +unset -f functname # deletes a function definition +declare -f # displays all defined functions in your login session +## FLOW CONTROLS +statement1 && statement2 # and operator +statement1 || statement2 # or operator +-a # and operator inside a test conditional expression +-o # or operator inside a test conditional expression +## STRINGS +str1 == str2 # str1 matches str2 +str1 != str2 # str1 does not match str2 +str1 < str2 # str1 is less than str2 (alphabetically) +str1 > str2 # str1 is greater than str2 (alphabetically) +str1 \> str2 # str1 is sorted after str2 +str1 \< str2 # str1 is sorted before str2 +-n str1 # str1 is not null (has length greater than 0) +-z str1 # str1 is null (has length 0) +## FILES +-a file # file exists or its compilation is successful +-d file # file exists and is a directory +-e file # file exists; same -a +-f file # file exists and is a regular file (i.e., not a directory or other special type of file) +-r file # you have read permission +-s file # file exists and is not empty +-w file # your have write permission +-x file # you have execute permission on file, or directory search permission if it is a directory +-N file # file was modified since it was last read +-O file # you own file +-G file # file's group ID matches yours (or one of yours, if you are in multiple groups) +file1 -nt file2 # file1 is newer than file2 +file1 -ot file2 # file1 is older than file2 +## NUMBERS +-lt # less than +-le # less than or equal +-eq # equal +-ge # greater than or equal +-gt # greater than +-ne # not equal +if condition +then + statements +[elif condition + then statements...] +[else + statements] +fi +for x in {1..10} +do + statements +done +for name [in list] +do + statements that can use $name +done +for (( initialisation ; ending condition ; update )) +do + statements... +done +case expression in + pattern1 ) + statements ;; + pattern2 ) + statements ;; +esac +select name [in list] +do + statements that can use $name +done +while condition; do + statements +done +until condition; do + statements +done +## COMMAND-LINE PROCESSING CYCLE +## The default order for command lookup is functions, followed by built-ins, with scripts and executables last. +## There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`. +command # removes alias and function lookup. Only built-ins and commands found in the search path are executed +builtin # looks up only built-in commands, ignoring functions and commands found in PATH +enable # enables and disables shell built-ins +eval # takes arguments and run them through the command-line processing steps all over again +## INPUT/OUTPUT REDIRECTORS +cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 +< file # takes standard input from file +> file # directs standard output to file +>> file # directs standard output to file; append to file if it already exists +>|file # forces standard output to file even if noclobber is set +n>|file # forces output to file from file descriptor n even if noclobber is set +<> file # uses file as both standard input and standard output +n<>file # uses file as both input and output for file descriptor n +n>file # directs file descriptor n to file +n>file # directs file description n to file; append to file if it already exists +n>& # duplicates standard output to file descriptor n +n<& # duplicates standard input from file descriptor n +n>&m # file descriptor n is made to be a copy of the output file descriptor +n<&m # file descriptor n is made to be a copy of the input file descriptor +&>file # directs standard output and standard error to file +<&- # closes the standard input +>&- # closes the standard output +n>&- # closes the ouput from file descriptor n +n<&- # closes the input from file descripor n +|tee # output command to both terminal and a file (-a to append to file) +## PROCESS HANDLING +## To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y. +## This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal. +## Of course, to interrupt a job, type CTRL+C. +myCommand & # runs job in the background and prompts back the shell +jobs # lists all jobs (use with -l to see associated PID) +fg # brings a background job into the foreground +fg %+ # brings most recently invoked background job +fg %- # brings second most recently invoked background job +fg %N # brings job number N +fg %string # brings job whose command begins with string +fg %?string # brings job whose command contains string +kill -l # returns a list of all signals on the system, by name and number +kill PID # terminates process with specified PID +kill -s SIGKILL 4500 # sends a signal to force or terminate the process +kill -15 913 # Ending PID 913 process with signal 15 (TERM) +kill %1 # Where %1 is the number of job as read from 'jobs' command. +ps # prints a line of information about the current running login shell and any processes running under it +ps -a # selects all processes with a tty except session leaders +trap cmd sig1 sig2 # executes a command when a signal is received by the script +trap "" sig1 sig2 # ignores that signals +trap - sig1 sig2 # resets the action taken when the signal is received to the default +disown # removes the process from the list of jobs +wait # waits until all background jobs have finished +sleep # wait # of seconds before continuing +pv # display progress bar for data handling commands. often used with pipe like |pv +yes # give yes response everytime an input is requested from script/process +## TIPS & TRICKS +## set an alias +cd; nano .bash_profile +> alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile +## to quickly go to a specific directory +cd; nano .bashrc +> shopt -s cdable_vars +> export websites="/Users/mac/Documents/websites" +source .bashrc +cd $websites +## DEBUGGING SHELL PROGRAMS +bash -n scriptname # don't run commands; check for syntax errors only +set -o noexec # alternative (set option in script) +bash -v scriptname # echo commands before running them +set -o verbose # alternative (set option in script) +bash -x scriptname # echo commands after command-line processing +set -o xtrace # alternative (set option in script) +trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits +function errtrap { + es=$? + echo "ERROR line $1: Command exited with status $es." +} +trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status +function dbgtrap { + echo "badvar is $badvar" +} +trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script +## ...section of code in which the problem occurs... +trap - DEBUG # turn off the DEBUG trap +function returntrap { + echo "A return occurred" +} +trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing +## COLORS AND BACKGROUNDS +## note: \e or \x1B also work instead of \033 +## Reset +Color_Off='\033[0m' # Text Reset +## Regular Colors +Black='\033[0;30m' # Black +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Blue='\033[0;34m' # Blue +Purple='\033[0;35m' # Purple +Cyan='\033[0;36m' # Cyan +White='\033[0;97m' # White +## Additional colors +LGrey='\033[0;37m' # Ligth Gray +DGrey='\033[0;90m' # Dark Gray +LRed='\033[0;91m' # Ligth Red +LGreen='\033[0;92m' # Ligth Green +LYellow='\033[0;93m'# Ligth Yellow +LBlue='\033[0;94m' # Ligth Blue +LPurple='\033[0;95m'# Light Purple +LCyan='\033[0;96m' # Ligth Cyan +## Bold +BBlack='\033[1;30m' # Black +BRed='\033[1;31m' # Red +BGreen='\033[1;32m' # Green +BYellow='\033[1;33m'# Yellow +BBlue='\033[1;34m' # Blue +BPurple='\033[1;35m'# Purple +BCyan='\033[1;36m' # Cyan +BWhite='\033[1;37m' # White +## Underline +UBlack='\033[4;30m' # Black +URed='\033[4;31m' # Red +UGreen='\033[4;32m' # Green +UYellow='\033[4;33m'# Yellow +UBlue='\033[4;34m' # Blue +UPurple='\033[4;35m'# Purple +UCyan='\033[4;36m' # Cyan +UWhite='\033[4;37m' # White +## Background +On_Black='\033[40m' # Black +On_Red='\033[41m' # Red +On_Green='\033[42m' # Green +On_Yellow='\033[43m'# Yellow +On_Blue='\033[44m' # Blue +On_Purple='\033[45m'# Purple +On_Cyan='\033[46m' # Cyan +On_White='\033[47m' # White +## Example of usage +echo -e "${Green}This is GREEN text${Color_Off} and normal text" +echo -e "${Red}${On_White}This is Red test on White background${Color_Off}" +## option -e is mandatory, it enable interpretation of backslash escapes +printf "${Red} This is red \n" +``` +
+> +#### Find +## To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG) +find . -iname "\*.jpg" +## To find directories +find . -type d +## To find files +find . -type f +## To find files by octal permission +find . -type f -perm 777 +## To find files with setuid bit set +find . -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l +## To find files with extension '.txt' and remove them +find ./path/ -name '\*.txt' -exec rm '{}' \; +## To find files with extension '.txt' and look for a string into them +find ./path/ -name '\*.txt' | xargs grep 'string' +## To find files with size bigger than 5 Mebibyte and sort them by size +find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z +## To find files bigger than 2 Megabyte and list them +find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }' +## To find files modified more than 7 days ago and list file information +find . -type f -mtime +7d -ls +## To find symlinks owned by a user and list file information +find . -type l -user -ls +## To search for and delete empty directories +find . -type d -empty -exec rmdir {} \; +## To search for directories named build at a max depth of 2 directories +find . -maxdepth 2 -name build -type d +## To search all files who are not in .git directory +find . ! -iwholename '*.git*' -type f +## To find all files that have the same node (hard link) as MY_FILE_HERE +find . -type f -samefile MY_FILE_HERE 2>/dev/null +## To find all files in the current directory and modify their permissions +find . -type f -exec chmod 644 {} \; +--- +>>>>>>> master - --- - ![Preview](https://i.imgur.com/nieW1vp.png) - ## Wiki Nav +<<<<<<< HEAD - [Home](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) - [add copy to code blocks.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/add-copy-to-code-blocks.md) @@ -1479,116 +2929,110 @@ find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + - [web archive.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/web-archive.md) - [wordpress vs headless cms.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/wordpress-vs-headless-cms.md) +======= +- [Home](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) +- [add copy to code blocks.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/add-copy-to-code-blocks.md) +- [Add site search w algolia.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Add-site-search-w-algolia.md) +- [adding mailing list.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/adding-mailing-list.md) +- [Adding search 2 gatsby site.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Adding-search-2-gatsby-site.md) +- [awesome.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/awesome.md) +- [broken links.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/broken-links.md) +- [configure custom domain.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/configure-custom-domain.md) +- [contentauthoring.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/contentauthoring.md) +- [full text search w lunar.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/full-text-search-w-lunar.md) +- [inject 4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject-4.md) +- [inject3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject3.md) +- [inject4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject4.md) +- [injected content part2.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-content-part2.md) +- [injected js part4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-js-part4.md) +- [injected part3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-part3.md) +- [links 2 embed.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-2-embed.md) +- [links to remember](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-to-remember) +- [Netlify Injected Content](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Netlify-Injected-Content) +- [old version of index.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/old-version-of-index.md) +- [optimize vscode.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/optimize-vscode.md) +- [possibly useful snippets.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/possibly-useful-snippets.md) +- [privacy policy.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/privacy-policy.md) +- [random stuff.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random-stuff.md) +- [random.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random.md) +- [ref type](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/ref-type) +- [SEO.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/SEO.md) +- [stable points.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/stable-points.md) +- [tech used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/tech-used.md) +- [Technologies Used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Technologies-Used.md) +- [THINGS TO EMBED.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/THINGS-TO-EMBED.md) +- [validation report.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/validation-report.md) +- [web archive.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/web-archive.md) +- [wordpress vs headless cms.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/wordpress-vs-headless-cms.md) +>>>>>>> master --- - ## Dependencies
- Click to expand! + + Click to expand! [![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-search `^ 4.10.3` - [![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-common `4.10.5` - ![@ghost**](https://avatars.githubusercontent.com/u/10137?s=40&v=4)@algolia/requester-common `4.10.5` - [![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/transporter `4.10.5` - [![@stackbit**](https://avatars.githubusercontent.com/u/38996451?s=40&v=4)](https://github.com/stackbit)[stackbit / gatsby-plugin-menus](https://github.com/stackbit/gatsby-plugin-menus)@stackbit/gatsby-plugin-menus `0.0.4` - [![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest)babel-jest `^ 24.7.1` - [![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby)babel-preset-gatsby `^ 0.1.11` - [![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby) `^ 2.5.0` - [![@keyz**](https://avatars.githubusercontent.com/u/2268452?s=40&u=c3f56fe1d943474ffe4577a82ad79c1a79d7eb6e&v=4)](https://github.com/keyz)[keyz / identity-obj-proxy](https://github.com/keyz/identity-obj-proxy) `^ 3.0.0` - [![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest) `^ 24.7.1` - [![@lodash**](https://avatars.githubusercontent.com/u/2565403?s=40&v=4)](https://github.com/lodash)[lodash / lodash](https://github.com/lodash/lodash) `^ 4.17.11` - [![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / react](https://github.com/facebook/react)react-test-renderer `^ 16.8.6` - [![@getkirby-v2**](https://avatars.githubusercontent.com/u/6985611?s=40&v=4)](https://github.com/getkirby-v2)[getkirby-v2 / algolia-plugin](https://github.com/getkirby-v2/algolia-plugin)algolia `0.0.0` - [![@ecomfe**](https://avatars.githubusercontent.com/u/2268460?s=40&v=4)](https://github.com/ecomfe)[ecomfe / babel-runtime](https://github.com/ecomfe/babel-runtime) `6.26.0` - [![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / chokidar](https://github.com/paulmillr/chokidar) `3.4.0` - [![@DefinitelyTyped**](https://avatars.githubusercontent.com/u/3637556?s=40&v=4)](https://github.com/DefinitelyTyped)[DefinitelyTyped / DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)@types/node `^ 13` - [![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / anymatch](https://github.com/micromatch/anymatch) `~ 3.1.1` - [![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / braces](https://github.com/micromatch/braces) `~ 3.0.2` - [![@chaijs**](https://avatars.githubusercontent.com/u/1515293?s=40&v=4)](https://github.com/chaijs)[chaijs / chai](https://github.com/chaijs/chai) `^ 4.2` - [![@microsoft**](https://avatars.githubusercontent.com/u/6154722?s=40&v=4)](https://github.com/microsoft)[microsoft / dtslint](https://github.com/microsoft/dtslint) `^ 3.3.0` - [![@eslint**](https://avatars.githubusercontent.com/u/6019716?s=40&v=4)](https://github.com/eslint)[eslint / eslint](https://github.com/eslint/eslint) `^ 6.6.0` - [![@fsevents**](https://avatars.githubusercontent.com/u/48760001?s=40&v=4)](https://github.com/fsevents)[fsevents / fsevents](https://github.com/fsevents/fsevents) `~ 2.1.2` - [![@gulpjs**](https://avatars.githubusercontent.com/u/6200624?s=40&v=4)](https://github.com/gulpjs)[gulpjs / glob-parent](https://github.com/gulpjs/glob-parent) `~ 5.1.0` - [![@sindresorhus**](https://avatars.githubusercontent.com/u/170270?s=40&u=34acd557a042ac478d273a4621570cadb6b0bd89&v=4)](https://github.com/sindresorhus)[sindresorhus / is-binary-path](https://github.com/sindresorhus/is-binary-path) `~ 2.1.0` - [![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / is-glob](https://github.com/micromatch/is-glob) `~ 4.0.1` - [![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 7.0.0` - [![@jonschlinkert**](https://avatars.githubusercontent.com/u/383994?s=40&u=335f06277f72722162e89bd5516849f2e82f37cf&v=4)](https://github.com/jonschlinkert)[jonschlinkert / normalize-path](https://github.com/jonschlinkert/normalize-path) `~ 3.0.0` - [![@istanbuljs**](https://avatars.githubusercontent.com/u/13523395?s=40&v=4)](https://github.com/istanbuljs)[istanbuljs / nyc](https://github.com/istanbuljs/nyc) `^ 15.0.0` - [![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / readdirp](https://github.com/paulmillr/readdirp) `~ 3.4.0` - [![@isaacs**](https://avatars.githubusercontent.com/u/9287?s=40&u=60a280618307ae965cadbe52da4baa7e351c848c&v=4)](https://github.com/isaacs)[isaacs / rimraf](https://github.com/isaacs/rimraf) `^ 3.0.0` - [![@sinonjs**](https://avatars.githubusercontent.com/u/6570253?s=40&v=4)](https://github.com/sinonjs)[sinonjs / sinon](https://github.com/sinonjs/sinon) `^ 9.0.1` - [![@domenic**](https://avatars.githubusercontent.com/u/617481?s=40&v=4)](https://github.com/domenic)[domenic / sinon-chai](https://github.com/domenic/sinon-chai) `^ 3.3.0` - [![@anodynos**](https://avatars.githubusercontent.com/u/856453?s=40&v=4)](https://github.com/anodynos)[anodynos / upath](https://github.com/anodynos/upath) `^ 1.2.0` - [![@JedWatson**](https://avatars.githubusercontent.com/u/872310?s=40&u=9548676d01f104232ee42e5ac0d985db77e6a5a4&v=4)](https://github.com/JedWatson)[JedWatson / classnames](https://github.com/JedWatson/classnames) `2.2.6` - [![@bestiejs**](https://avatars.githubusercontent.com/u/802850?s=40&v=4)](https://github.com/bestiejs)[bestiejs / benchmark.js](https://github.com/bestiejs/benchmark.js)benchmark `^ 1.0.0` - [![@browserify**](https://avatars.githubusercontent.com/u/6320506?s=40&v=4)](https://github.com/browserify)[browserify / browserify](https://github.com/browserify/browserify) `^ 14.1.0` - [![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 2.1.0` - [![@jeromedecoster**](https://avatars.githubusercontent.com/u/158071?s=40&u=470a733fdc34a9fedab18ae4cf5109d2ea357425&v=4)](https://github.com/jeromedecoster)[jeromedecoster / opn-cli](https://github.com/jeromedecoster/opn-cli) `^ 3.1.0` - [![@documentationjs**](https://avatars.githubusercontent.com/u/11415556?s=40&v=4)](https://github.com/documentationjs)[documentationjs / documentation](https://github.com/documentationjs/documentation) `^ 13.2.5` - [![@babel**](https://avatars.githubusercontent.com/u/9637642?s=40&v=4)](https://github.com/babel)[babel / babel](https://github.com/babel/babel)@babel/core `7.12.3` - [Cloudfare-Backup](https://bgoonz-blog-2-0.pages.dev/) ↞↠ Search Website: [search](https://www.algolia.com/realtime-search-demo/web-dev-resource-hub-9e6b8aa8-6106-44c5-9f59-ff3f9531abd4) ↞↠ [Backup Repo Deploy](https://bgoonzblog20-backup.netlify.app/#gsc.tab=0) ↞↠ [Github pages](https://bgoonz.github.io/BGOONZ_BLOG_2.0/) ↞↠ [Go To Site Wiki](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) -
- --- - ## Docs Structure
- Docs Structure + + Docs Structure ``` ├── blog │ ├── 300-react-questions.md @@ -1815,10 +3259,9 @@ find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + ├── readme.md ├── showcase.md └── tree.md - 23 directories, 202 files - ``` +<<<<<<< HEAD # SITEMAP @@ -2212,52 +3655,258 @@ find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + ## [**🌍⇒docs/tutorials/google-lighthouse-cli🗺️**](https://bgoonz-blog.netlify.app/docs/tutorials/google-lighthouse-cli) +======= +## SITEMAP +[**🌍⇒https://bgoonz-blog.netlify.app/🗺️**](https://bgoonz-blog.netlify.app/) +[**🌍⇒blog🗺️**](https://bgoonz-blog.netlify.app/blog) +[**🌍⇒docs🗺️**](https://bgoonz-blog.netlify.app/docs) +[**🌍⇒readme🗺️**](https://bgoonz-blog.netlify.app/readme) +[**🌍⇒review🗺️**](https://bgoonz-blog.netlify.app/review) +[**🌍⇒showcase🗺️**](https://bgoonz-blog.netlify.app/showcase) +[**🌍⇒blog/awesome-graphql🗺️**](https://bgoonz-blog.netlify.app/blog/awesome-graphql) +[**🌍⇒blog/big-o-complexity🗺️**](https://bgoonz-blog.netlify.app/blog/big-o-complexity) +[**🌍⇒blog/blog-archive🗺️**](https://bgoonz-blog.netlify.app/blog/blog-archive) +[**🌍⇒blog/blogwcomments🗺️**](https://bgoonz-blog.netlify.app/blog/blogwcomments) +[**🌍⇒blog/data-structures🗺️**](https://bgoonz-blog.netlify.app/blog/data-structures) +[**🌍⇒blog/flow-control-in-python🗺️**](https://bgoonz-blog.netlify.app/blog/flow-control-in-python) +[**🌍⇒blog/functions-in-python🗺️**](https://bgoonz-blog.netlify.app/blog/functions-in-python) +[**🌍⇒blog/git-gateway🗺️**](https://bgoonz-blog.netlify.app/blog/git-gateway) +[**🌍⇒blog/interview-questions-js🗺️**](https://bgoonz-blog.netlify.app/blog/interview-questions-js) +[**🌍⇒blog/media-queries-explained🗺️**](https://bgoonz-blog.netlify.app/blog/media-queries-explained) +[**🌍⇒blog/my-medium🗺️**](https://bgoonz-blog.netlify.app/blog/my-medium) +[**🌍⇒blog/netlify-cms🗺️**](https://bgoonz-blog.netlify.app/blog/netlify-cms) +[**🌍⇒blog/platform-docs🗺️**](https://bgoonz-blog.netlify.app/blog/platform-docs) +[**🌍⇒blog/python-for-js-dev🗺️**](https://bgoonz-blog.netlify.app/blog/python-for-js-dev) +[**🌍⇒blog/python-resources🗺️**](https://bgoonz-blog.netlify.app/blog/python-resources) +[**🌍⇒blog/web-dev-trends🗺️**](https://bgoonz-blog.netlify.app/blog/web-dev-trends) +[**🌍⇒blog/web-scraping🗺️**](https://bgoonz-blog.netlify.app/blog/web-scraping) +[**🌍⇒docs/about🗺️**](https://bgoonz-blog.netlify.app/docs/about) +[**🌍⇒docs/articles🗺️**](https://bgoonz-blog.netlify.app/docs/articles) +[**🌍⇒docs/audio🗺️**](https://bgoonz-blog.netlify.app/docs/audio) +[**🌍⇒docs/career🗺️**](https://bgoonz-blog.netlify.app/docs/career) +[**🌍⇒docs/community🗺️**](https://bgoonz-blog.netlify.app/docs/community) +[**🌍⇒docs/content🗺️**](https://bgoonz-blog.netlify.app/docs/content) +[**🌍⇒docs/docs🗺️**](https://bgoonz-blog.netlify.app/docs/docs) +[**🌍⇒docs/faq🗺️**](https://bgoonz-blog.netlify.app/docs/faq) +[**🌍⇒docs/gallery🗺️**](https://bgoonz-blog.netlify.app/docs/gallery) +[**🌍⇒docs/interact🗺️**](https://bgoonz-blog.netlify.app/docs/interact) +[**🌍⇒docs/javascript🗺️**](https://bgoonz-blog.netlify.app/docs/javascript) +[**🌍⇒docs/leetcode🗺️**](https://bgoonz-blog.netlify.app/docs/leetcode) +[**🌍⇒docs/other-content🗺️**](https://bgoonz-blog.netlify.app/docs/other-content) +[**🌍⇒docs/privacy-policy🗺️**](https://bgoonz-blog.netlify.app/docs/privacy-policy) +[**🌍⇒docs/projects🗺️**](https://bgoonz-blog.netlify.app/docs/projects) +[**🌍⇒docs/python🗺️**](https://bgoonz-blog.netlify.app/docs/python) +[**🌍⇒docs/quick-reference🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference) +[**🌍⇒docs/react🗺️**](https://bgoonz-blog.netlify.app/docs/react) +[**🌍⇒docs/reference🗺️**](https://bgoonz-blog.netlify.app/docs/reference) +[**🌍⇒docs/search🗺️**](https://bgoonz-blog.netlify.app/docs/search) +[**🌍⇒docs/sitemap🗺️**](https://bgoonz-blog.netlify.app/docs/sitemap) +[**🌍⇒docs/tools🗺️**](https://bgoonz-blog.netlify.app/docs/tools) +[**🌍⇒docs/tutorials🗺️**](https://bgoonz-blog.netlify.app/docs/tutorials) +[**🌍⇒docs/about/eng-portfolio🗺️**](https://bgoonz-blog.netlify.app/docs/about/eng-portfolio) +[**🌍⇒docs/about/ideas-for-this-website🗺️**](https://bgoonz-blog.netlify.app/docs/about/ideas-for-this-website) +[**🌍⇒docs/about/intrests🗺️**](https://bgoonz-blog.netlify.app/docs/about/intrests) +[**🌍⇒docs/about/interview🗺️**](https://bgoonz-blog.netlify.app/docs/about/interview) +[**🌍⇒docs/about/resume🗺️**](https://bgoonz-blog.netlify.app/docs/about/resume) +[**🌍⇒docs/articles/basic-web-dev🗺️**](https://bgoonz-blog.netlify.app/docs/articles/basic-web-dev) +[**🌍⇒docs/articles/buffers🗺️**](https://bgoonz-blog.netlify.app/docs/articles/buffers) +[**🌍⇒docs/articles/dev-dep🗺️**](https://bgoonz-blog.netlify.app/docs/articles/dev-dep) +[**🌍⇒docs/articles/event-loop🗺️**](https://bgoonz-blog.netlify.app/docs/articles/event-loop) +[**🌍⇒docs/articles/fs-module🗺️**](https://bgoonz-blog.netlify.app/docs/articles/fs-module) +[**🌍⇒docs/articles/how-the-web-works🗺️**](https://bgoonz-blog.netlify.app/docs/articles/how-the-web-works) +[**🌍⇒docs/articles/http🗺️**](https://bgoonz-blog.netlify.app/docs/articles/http) +[**🌍⇒docs/articles/install🗺️**](https://bgoonz-blog.netlify.app/docs/articles/install) +[**🌍⇒docs/articles/intro🗺️**](https://bgoonz-blog.netlify.app/docs/articles/intro) +[**🌍⇒docs/articles/media-queries-no-more🗺️**](https://bgoonz-blog.netlify.app/docs/articles/media-queries-no-more) +[**🌍⇒docs/articles/module-exports🗺️**](https://bgoonz-blog.netlify.app/docs/articles/module-exports) +[**🌍⇒docs/articles/nextjs🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nextjs) +[**🌍⇒docs/articles/node-api-express🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-api-express) +[**🌍⇒docs/articles/node-cli-args🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-cli-args) +[**🌍⇒docs/articles/node-common-modules🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-common-modules) +[**🌍⇒docs/articles/node-env-variables🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-env-variables) +[**🌍⇒docs/articles/node-js-language🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-js-language) +[**🌍⇒docs/articles/node-package-manager🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-package-manager) +[**🌍⇒docs/articles/node-repl🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-repl) +[**🌍⇒docs/articles/node-run-cli🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-run-cli) +[**🌍⇒docs/articles/nodejs🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nodejs) +[**🌍⇒docs/articles/nodevsbrowser🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nodevsbrowser) +[**🌍⇒docs/articles/npm🗺️**](https://bgoonz-blog.netlify.app/docs/articles/npm) +[**🌍⇒docs/articles/npx🗺️**](https://bgoonz-blog.netlify.app/docs/articles/npx) +[**🌍⇒docs/articles/os-module🗺️**](https://bgoonz-blog.netlify.app/docs/articles/os-module) +[**🌍⇒docs/articles/package-lock🗺️**](https://bgoonz-blog.netlify.app/docs/articles/package-lock) +[**🌍⇒docs/articles/reading-files🗺️**](https://bgoonz-blog.netlify.app/docs/articles/reading-files) +[**🌍⇒docs/articles/semantic🗺️**](https://bgoonz-blog.netlify.app/docs/articles/semantic) +[**🌍⇒docs/articles/semantic-html🗺️**](https://bgoonz-blog.netlify.app/docs/articles/semantic-html) +[**🌍⇒docs/articles/the-uniform-resource-locator-(url)🗺️**]() +[**🌍⇒docs/articles/understanding-firebase🗺️**](https://bgoonz-blog.netlify.app/docs/articles/understanding-firebase) +[**🌍⇒docs/articles/v8🗺️**](https://bgoonz-blog.netlify.app/docs/articles/v8) +[**🌍⇒docs/articles/web-standards-checklist🗺️**](https://bgoonz-blog.netlify.app/docs/articles/web-standards-checklist) +[**🌍⇒docs/articles/webdev-tools🗺️**](https://bgoonz-blog.netlify.app/docs/articles/webdev-tools) +[**🌍⇒docs/articles/write-2-json-with-python🗺️**](https://bgoonz-blog.netlify.app/docs/articles/write-2-json-with-python) +[**🌍⇒docs/articles/writing-files🗺️**](https://bgoonz-blog.netlify.app/docs/articles/writing-files) +[**🌍⇒docs/audio/audio🗺️**](https://bgoonz-blog.netlify.app/docs/audio/audio) +[**🌍⇒docs/audio/audio-feature-extraction🗺️**](https://bgoonz-blog.netlify.app/docs/audio/audio-feature-extraction) +[**🌍⇒docs/audio/dfft🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dfft) +[**🌍⇒docs/audio/discrete-fft🗺️**](https://bgoonz-blog.netlify.app/docs/audio/discrete-fft) +[**🌍⇒docs/audio/dtw-python-explained🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dtw-python-explained) +[**🌍⇒docs/audio/dynamic-time-warping🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dynamic-time-warping) +[**🌍⇒docs/audio/web-audio-api🗺️**](https://bgoonz-blog.netlify.app/docs/audio/web-audio-api) +[**🌍⇒docs/career/confidence🗺️**](https://bgoonz-blog.netlify.app/docs/career/confidence) +[**🌍⇒docs/career/dev-interview🗺️**](https://bgoonz-blog.netlify.app/docs/career/dev-interview) +[**🌍⇒docs/career/interview-dos-n-donts🗺️**](https://bgoonz-blog.netlify.app/docs/career/interview-dos-n-donts) +[**🌍⇒docs/career/job-boards🗺️**](https://bgoonz-blog.netlify.app/docs/career/job-boards) +[**🌍⇒docs/community/an-open-letter-2-future-developers🗺️**](https://bgoonz-blog.netlify.app/docs/community/an-open-letter-2-future-developers) +[**🌍⇒docs/community/video-chat🗺️**](https://bgoonz-blog.netlify.app/docs/community/video-chat) +[**🌍⇒docs/content/algo🗺️**](https://bgoonz-blog.netlify.app/docs/content/algo) +[**🌍⇒docs/content/archive🗺️**](https://bgoonz-blog.netlify.app/docs/content/archive) +[**🌍⇒docs/content/data-structures-algo🗺️**](https://bgoonz-blog.netlify.app/docs/content/data-structures-algo) +[**🌍⇒docs/content/gatsby-Queries-Mutations🗺️**](https://bgoonz-blog.netlify.app/docs/content/gatsby-Queries-Mutations) +[**🌍⇒docs/content/history-api🗺️**](https://bgoonz-blog.netlify.app/docs/content/history-api) +[**🌍⇒docs/content/projects🗺️**](https://bgoonz-blog.netlify.app/docs/content/projects) +[**🌍⇒docs/content/recent-projects🗺️**](https://bgoonz-blog.netlify.app/docs/content/recent-projects) +[**🌍⇒docs/content/trouble-shooting🗺️**](https://bgoonz-blog.netlify.app/docs/content/trouble-shooting) +[**🌍⇒docs/docs/appendix🗺️**](https://bgoonz-blog.netlify.app/docs/docs/appendix) +[**🌍⇒docs/docs/bash🗺️**](https://bgoonz-blog.netlify.app/docs/docs/bash) +[**🌍⇒docs/docs/content🗺️**](https://bgoonz-blog.netlify.app/docs/docs/content) +[**🌍⇒docs/docs/css🗺️**](https://bgoonz-blog.netlify.app/docs/docs/css) +[**🌍⇒docs/docs/data-structures-docs🗺️**](https://bgoonz-blog.netlify.app/docs/docs/data-structures-docs) +[**🌍⇒docs/docs/git-reference🗺️**](https://bgoonz-blog.netlify.app/docs/docs/git-reference) +[**🌍⇒docs/docs/git-repos🗺️**](https://bgoonz-blog.netlify.app/docs/docs/git-repos) +[**🌍⇒docs/docs/html-spec🗺️**](https://bgoonz-blog.netlify.app/docs/docs/html-spec) +[**🌍⇒docs/docs/markdown🗺️**](https://bgoonz-blog.netlify.app/docs/docs/markdown) +[**🌍⇒docs/docs/no-whiteboarding🗺️**](https://bgoonz-blog.netlify.app/docs/docs/no-whiteboarding) +[**🌍⇒docs/docs/node-docs-complete🗺️**](https://bgoonz-blog.netlify.app/docs/docs/node-docs-complete) +[**🌍⇒docs/docs/node-docs-full🗺️**](https://bgoonz-blog.netlify.app/docs/docs/node-docs-full) +[**🌍⇒docs/docs/regex-in-js🗺️**](https://bgoonz-blog.netlify.app/docs/docs/regex-in-js) +[**🌍⇒docs/docs/sitemap🗺️**](https://bgoonz-blog.netlify.app/docs/docs/sitemap) +[**🌍⇒docs/faq/contact🗺️**](https://bgoonz-blog.netlify.app/docs/faq/contact) +[**🌍⇒docs/faq/plug-ins🗺️**](https://bgoonz-blog.netlify.app/docs/faq/plug-ins) +[**🌍⇒docs/interact/callstack-visual🗺️**](https://bgoonz-blog.netlify.app/docs/interact/callstack-visual) +[**🌍⇒docs/interact/clock🗺️**](https://bgoonz-blog.netlify.app/docs/interact/clock) +[**🌍⇒docs/interact/jupyter-notebooks🗺️**](https://bgoonz-blog.netlify.app/docs/interact/jupyter-notebooks) +[**🌍⇒docs/interact/other-sites🗺️**](https://bgoonz-blog.netlify.app/docs/interact/other-sites) +[**🌍⇒docs/interact/video-chat🗺️**](https://bgoonz-blog.netlify.app/docs/interact/video-chat) +[**🌍⇒docs/javascript/arrow-functions🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/arrow-functions) +[**🌍⇒docs/javascript/await-keyword🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/await-keyword) +[**🌍⇒docs/javascript/bigo🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/bigo) +[**🌍⇒docs/javascript/clean-code🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/clean-code) +[**🌍⇒docs/javascript/constructor-functions🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/constructor-functions) +[**🌍⇒docs/javascript/promises🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/promises) +[**🌍⇒docs/javascript/review🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/review) +[**🌍⇒docs/javascript/this-is-about-this🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/this-is-about-this) +[**🌍⇒docs/projects/medium-links🗺️**](https://bgoonz-blog.netlify.app/docs/projects/medium-links) +[**🌍⇒docs/projects/my-websites🗺️**](https://bgoonz-blog.netlify.app/docs/projects/my-websites) +[**🌍⇒docs/python/at-length🗺️**](https://bgoonz-blog.netlify.app/docs/python/at-length) +[**🌍⇒docs/python/basics🗺️**](https://bgoonz-blog.netlify.app/docs/python/basics) +[**🌍⇒docs/python/cheat-sheet🗺️**](https://bgoonz-blog.netlify.app/docs/python/cheat-sheet) +[**🌍⇒docs/python/comprehensive-guide🗺️**](https://bgoonz-blog.netlify.app/docs/python/comprehensive-guide) +[**🌍⇒docs/python/examples🗺️**](https://bgoonz-blog.netlify.app/docs/python/examples) +[**🌍⇒docs/python/flow-control🗺️**](https://bgoonz-blog.netlify.app/docs/python/flow-control) +[**🌍⇒docs/python/functions🗺️**](https://bgoonz-blog.netlify.app/docs/python/functions) +[**🌍⇒docs/python/google-sheets-api🗺️**](https://bgoonz-blog.netlify.app/docs/python/google-sheets-api) +[**🌍⇒docs/python/intro-for-js-devs🗺️**](https://bgoonz-blog.netlify.app/docs/python/intro-for-js-devs) +[**🌍⇒docs/python/python-ds🗺️**](https://bgoonz-blog.netlify.app/docs/python/python-ds) +[**🌍⇒docs/python/snippets🗺️**](https://bgoonz-blog.netlify.app/docs/python/snippets) +[**🌍⇒docs/quick-reference/Emmet🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/Emmet) +[**🌍⇒docs/quick-reference/all-emojis🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/all-emojis) +[**🌍⇒docs/quick-reference/create-react-app🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/create-react-app) +[**🌍⇒docs/quick-reference/git-bash🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/git-bash) +[**🌍⇒docs/quick-reference/git-tricks🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/git-tricks) +[**🌍⇒docs/quick-reference/google-firebase🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/google-firebase) +[**🌍⇒docs/quick-reference/heroku-error-codes🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/heroku-error-codes) +[**🌍⇒docs/quick-reference/installation🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/installation) +[**🌍⇒docs/quick-reference/markdown-dropdowns🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/markdown-dropdowns) +[**🌍⇒docs/quick-reference/minifiction🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/minifiction) +[**🌍⇒docs/quick-reference/new-repo-instructions🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/new-repo-instructions) +[**🌍⇒docs/quick-reference/psql-setup🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/psql-setup) +[**🌍⇒docs/quick-reference/pull-request-rubric🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/pull-request-rubric) +[**🌍⇒docs/quick-reference/quick-links🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/quick-links) +[**🌍⇒docs/quick-reference/topRepos🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/topRepos) +[**🌍⇒docs/quick-reference/understanding-path🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/understanding-path) +[**🌍⇒docs/quick-reference/vscode-themes🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/vscode-themes) +[**🌍⇒docs/react/cheatsheet🗺️**](https://bgoonz-blog.netlify.app/docs/react/cheatsheet) +[**🌍⇒docs/react/createReactApp🗺️**](https://bgoonz-blog.netlify.app/docs/react/createReactApp) +[**🌍⇒docs/react/demo🗺️**](https://bgoonz-blog.netlify.app/docs/react/demo) +[**🌍⇒docs/react/jsx🗺️**](https://bgoonz-blog.netlify.app/docs/react/jsx) +[**🌍⇒docs/react/react-docs🗺️**](https://bgoonz-blog.netlify.app/docs/react/react-docs) +[**🌍⇒docs/react/react-in-depth🗺️**](https://bgoonz-blog.netlify.app/docs/react/react-in-depth) +[**🌍⇒docs/react/react2🗺️**](https://bgoonz-blog.netlify.app/docs/react/react2) +[**🌍⇒docs/react/render-elements🗺️**](https://bgoonz-blog.netlify.app/docs/react/render-elements) +[**🌍⇒docs/reference/awesome-lists🗺️**](https://bgoonz-blog.netlify.app/docs/reference/awesome-lists) +[**🌍⇒docs/reference/awesome-static🗺️**](https://bgoonz-blog.netlify.app/docs/reference/awesome-static) +[**🌍⇒docs/reference/bookmarks🗺️**](https://bgoonz-blog.netlify.app/docs/reference/bookmarks) +[**🌍⇒docs/reference/embed-the-web🗺️**](https://bgoonz-blog.netlify.app/docs/reference/embed-the-web) +[**🌍⇒docs/reference/github-search🗺️**](https://bgoonz-blog.netlify.app/docs/reference/github-search) +[**🌍⇒docs/reference/how-2-reinstall-npm🗺️**](https://bgoonz-blog.netlify.app/docs/reference/how-2-reinstall-npm) +[**🌍⇒docs/reference/how-to-kill-a-process🗺️**](https://bgoonz-blog.netlify.app/docs/reference/how-to-kill-a-process) +[**🌍⇒docs/reference/installing-node🗺️**](https://bgoonz-blog.netlify.app/docs/reference/installing-node) +[**🌍⇒docs/reference/intro-to-nodejs🗺️**](https://bgoonz-blog.netlify.app/docs/reference/intro-to-nodejs) +[**🌍⇒docs/reference/notes-template🗺️**](https://bgoonz-blog.netlify.app/docs/reference/notes-template) +[**🌍⇒docs/reference/psql🗺️**](https://bgoonz-blog.netlify.app/docs/reference/psql) +[**🌍⇒docs/reference/resources🗺️**](https://bgoonz-blog.netlify.app/docs/reference/resources) +[**🌍⇒docs/reference/vscode🗺️**](https://bgoonz-blog.netlify.app/docs/reference/vscode) +[**🌍⇒docs/reference/web-api's🗺️**](https://bgoonz-blog.netlify.app/docs/reference/web-api's) +[**🌍⇒docs/tools/data-structures🗺️**](https://bgoonz-blog.netlify.app/docs/tools/data-structures) +[**🌍⇒docs/tools/dev-utilities🗺️**](https://bgoonz-blog.netlify.app/docs/tools/dev-utilities) +[**🌍⇒docs/tools/google-cloud🗺️**](https://bgoonz-blog.netlify.app/docs/tools/google-cloud) +[**🌍⇒docs/tools/markdown-html🗺️**](https://bgoonz-blog.netlify.app/docs/tools/markdown-html) +[**🌍⇒docs/tools/more-tools🗺️**](https://bgoonz-blog.netlify.app/docs/tools/more-tools) +[**🌍⇒docs/tutorials/google-lighthouse-cli🗺️**](https://bgoonz-blog.netlify.app/docs/tutorials/google-lighthouse-cli) +>>>>>>> master
- --- - --- - ---
+ + ↞↠ Getting Started With GatsbyJS ↞↠ # - --- - ## 🚀 Quick start - 1. **Create a Gatsby site.** - Use the Gatsby CLI to create a new site, specifying the default starter. +<<<<<<< HEAD ```shell # create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default ``` +======= +```bashell + # create a new Gatsby site using the default starter + gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default +``` +>>>>>>> master 1. **Start developing.** - Navigate into your new site's directory and start it up. +<<<<<<< HEAD ```shell cd my-default-starter/ gatsby develop ``` +======= +```bashell + cd my-default-starter/ + gatsby develop +``` +>>>>>>> master 1. **Open the source code and start editing!** - Your site is now running at `http://localhost:8000`! +<<<<<<< HEAD _Note: You'll also see a second link:_`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.com/tutorial/part-five/#introducing-graphiql)._ +======= + *Note: You'll also see a second link:*`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.com/tutorial/part-five/#introducing-graphiql)._ +>>>>>>> master Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time! - ## 🧐 What's inside? - A quick look at the top-level files and directories you'll see in a Gatsby project. - . ├── node_modules ├── src @@ -2271,44 +3920,35 @@ A quick look at the top-level files and directories you'll see in a Gatsby proje ├── package-lock.json ├── package.json └── README.md - 1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed. - 2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for "source code". - 3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for. - 4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent. - 5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.com/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser. - 6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the [config docs](https://www.gatsbyjs.com/docs/gatsby-config/) for more detail). - 7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.com/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. - 8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering. - 9. **`LICENSE`**: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. - 10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won't change this file directly).** - 11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. - 12. **`README.md`**: A text file containing useful reference information about your project. - ## 🎓 Learning Gatsby - Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.com/). Here are some places to start: +<<<<<<< HEAD - **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby**](https://www.gatsbyjs.com/tutorial/).\*\* It starts with zero assumptions about your level of ability and walks through every step of the process. - - **To dive straight into code samples, head [to our documentation**](https://www.gatsbyjs.com/docs/).\*\* In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar. +======= +- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby**](https://www.gatsbyjs.com/tutorial/).\*\* It starts with zero assumptions about your level of ability and walks through every step of the process. +- +- **To dive straight into code samples, head [to our documentation**](https://www.gatsbyjs.com/docs/).\*\* In particular, check out the *Guides*, *API Reference*, and *Advanced Tutorials* sections in the sidebar. +>>>>>>> master ## 💫 Deploy - [![Deploy to Netlify**](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/BGOONZ_BLOG_2.0.git) - [![Deploy with Vercel**](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/BGOONZ_BLOG_2.0.git) +<<<<<<< HEAD @@ -2316,15 +3956,71 @@ Looking for more guidance? Full documentation for Gatsby lives [on the website]( # Gatsby Project Structure | Gatsby +======= +--- +### Gatsby With Netlify CMS +This tutorial will use [gatsby-personal-starter-blog](https://github.com/thomaswang/gatsby-personal-starter-blog), a Gatsby starter based on the official [gatsby-starter-blog](/starters/gatsbyjs/gatsby-starter-blog/). The differences are that `gatsby-personal-starter-blog` is configured to run the blog on a subdirectory, `/blog`, and comes pre-installed with [Netlify CMS](https://www.netlifycms.org/) for content editing. It also adds VS Code highlighting for code blocks. +## Prerequisites +- A GitHub account +- The [Gatsby CLI](/docs/reference/gatsby-cli/) installed +## Set up a Netlify CMS-managed Gatsby site in 5 steps +### Step 1 +Open your Terminal and run the following command from the Gatsby CLI to create a new Gatsby site using [gatsby-personal-starter-blog](https://github.com/thomaswang/gatsby-personal-starter-blog). +```shell +gatsby new [your-project-name] https://github.com/thomaswangio/gatsby-personal-starter-blog +``` +### Step 2 +Once the Gatsby site is finished installing all the packages and dependencies, you can now go into the directory and run the site locally. +```shell +cd [your-project-name] +gatsby develop +``` +Now you can go to `http://localhost:8000` to see your new site, but what's extra cool is that Netlify CMS is pre-installed and you can access it at `http://localhost:8000/admin` +A CMS, or content management system, is useful because you can add content like blog posts from a dashboard on your site, instead of having to add posts manually with Markdown. However, you'll likely want to be able to access the CMS from a deployed website, not just locally. For that, you'll need to deploy to Netlify through GitHub, set up continuous deployment, and do a few configurations. You'll go over this in [Step-5](#step-5). +### Step 3 +Open the project in your code editor and open `static/admin/config.yml`. Replace `your-username/your-repo-name` with your GitHub username and project name. This step is important for managing and deploying the Netlify CMS interface. +```diff +backend: +- name: test-repo ++ name: github ++ repo: your-username/your-repo-name +``` +#### Customizing your site +Head into `gatsby-config.js` and you can edit your siteMetadata, add a Google Analytics tracking ID, and your app icon/favicon. Test out the edits for the deployed build by quitting the development server and running `gatsby build && gatsby serve`. +You'll likely also want to edit the `README.md` and `package.json` files to include your own project details. +### Step 4 +Open [github.com](https://github.com) and create a new repository, with the same name as your project. Push your new Gatsby site's code to GitHub using the following Terminal commands: +```shell +git init +git add . +git commit -m "initial commit" +git remote add origin https://github.com/[your-username]/[your-repo-name].git +git push -u origin master +``` +Then, open [app.netlify.com](https://app.netlify.com) and add a "New site from Git". Choose your newly created repo and click on "Deploy site" with the default deployment settings. +> *Note: if you don't see the correct repo listed, you may need to install or reconfigure the Netlify app on GitHub.* +![Netlify Dashboard for Creating a new site](netlify-dashboard.png) +### Step 5 +To make sure that Netlify CMS has access to your GitHub repo, you need to set up an OAuth application on GitHub. The instructions for that are here: [Netlify's Using an Authorization Provider](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider). +For the "Homepage URL" – you can use your Netlify subdomain, `[name-of-your-site].netlify.com`, or you can use a custom domain. To customize the subdomain, look for the "Edit site name" field under "Domain Management" for your project on the [Netlify app](https://app.netlify.com). To connect your Netlify site to your custom domain instead, see [Netlify’s instructions on custom domains](https://www.netlify.com/docs/custom-domains/). +Once you've configured an authentication provider then you'll be able to use Netlify CMS at your deployed site to add new posts. +![Netlify and GitHub Authorization](https://cdn.netlify.com/67edd5b656c432888d736cd40125cb61376905bb/c1cba/img/docs/github-oauth-config.png) +Copy the credentials of your new app listed on [GitHub OAuth Apps](https://github.com/settings/developers) and install a new auth provider on Netlify using them. +![Setting up access control](netlify-install-oauth-provider.png) +#### Benefits of Netlify CMS, GitHub, and Netlify Workflow +Congrats! Now that Netlify CMS is successfully configured to your project, every time you add a new post, the content will be stored in your repository and versioned on GitHub because Netlify CMS is Git-based. Also, thanks to [Netlify's Continuous Deployment](https://www.netlify.com/docs/continuous-deployment/), a new version will be deployed every time you add or edit a post. +You can learn more about Netlify CMS and how to configure it further in the [Netlify CMS documentation](https://www.netlifycms.org/docs/intro/) +--- +--- +## Gatsby Project Structure | Gatsby +>>>>>>> master > ## Excerpt > > Inside a Gatsby project, you may see some or all of the following folders and files: Folders /.cache Automatically generated. This folder… - --- - Inside a Gatsby project, you may see some or all of the following folders and files: - ``` +<<<<<<< HEAD /|-- /.cache|-- /plugins|-- /public|-- /src |-- /api |-- /pages |-- /templates |-- html.js|-- /static|-- gatsby-config.js|-- gatsby-node.js|-- gatsby-ssr.js|-- gatsby-browser.js ``` @@ -2351,19 +4047,56 @@ Inside a Gatsby project, you may see some or all of the following folders and fi ## [](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#miscellaneous)Miscellaneous +======= +/| +-- /.cache +|-- /plugins +|-- /public +|-- /src +|-- /api +|-- /pages +|-- /templates +|-- html.js +|-- /static +|-- gatsby-config.js +|-- gatsby-node.js +|-- gatsby-ssr.js +|-- gatsby-browser.js +``` +[Folders](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#folders) +- **`/.cache`** *Automatically generated.* This folder is an internal cache created automatically by Gatsby. The files inside this folder are not meant for modification. Should be added to the `.gitignore` file if not added already. +- **`/plugins`** This folder hosts any project-specific ("local") plugins that aren't published as an `npm` package. Check out the [plugin docs](https://www.gatsbyjs.com/docs/plugins/) for more detail. +- **`/public`** *Automatically generated.* The output of the build process will be exposed inside this folder. Should be added to the `.gitignore` file if not added already. +- **`/src`** This directory will contain all of the code related to what you will see on the frontend of your site (what you see in the browser), like your site header, or a page template. "src" is a convention for "source code". + - **`/api`** JavaScript and TypeScript files under `src/api` become functions automatically with paths based on their file name. Check out the [functions guide](https://www.gatsbyjs.com/docs/reference/functions/) for more detail. + - **`/pages`** Components under `src/pages` become pages automatically with paths based on their file name. Check out the [pages recipes](https://www.gatsbyjs.com/docs/recipes/pages-layouts) for more detail. + - **`/templates`** Contains templates for programmatically creating pages. Check out the [templates docs](https://www.gatsbyjs.com/docs/conceptual/building-with-components/#page-template-components) for more detail. + - **`html.js`** For custom configuration of default `.cache/default_html.js`. Check out the [custom HTML docs](https://www.gatsbyjs.com/docs/custom-html/) for more detail. +- **`/static`** If you put a file into the static folder, it will not be processed by webpack. Instead it will be copied into the public folder untouched. Check out the [assets docs](https://www.gatsbyjs.com/docs/how-to/images-and-media/static-folder/#adding-assets-outside-of-the-module-system) for more detail. +[Files](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#files) +- **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/) (if any). These allow customization/extension of default Gatsby settings affecting the browser. +- **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. Check out the [config docs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-config/) for more detail. +- **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby node APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. +- **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/) (if any). These allow customization of default Gatsby settings affecting server-side rendering. +[Misc](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#miscellaneous) +[Misc](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#miscellaneous) +>>>>>>> master The file/folder structure described above reflects Gatsby-specific files and folders. Since Gatsby sites are also React apps, it's common to use standard React code organization patterns such as folders like `/components` and `/utils` inside `/src`. The [React docs](https://reactjs.org/docs/faq-structure.html) have more information on a typical React app folder structure. - --- +<<<<<<< HEAD # Layout Components | Gatsby > ## Excerpt > +======= +#### Layout Components | Gatsby +## Excerpt +>>>>>>> master > In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from… - --- - In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from unmounting. +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#gatsbys-approach-to-layouts)Gatsby's approach to layouts @@ -2375,49 +4108,59 @@ Layout components are for sections of your site that you want to share across mu ## [](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-create-layout-components)How to create layout components +======= +[Gatsby's approach to layouts](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#gatsbys-approach-to-layouts) +Gatsby does not, by default, automatically apply layouts to pages (there are, however, ways to do so which will be covered in a later section). Instead, Gatsby follows React's compositional model of importing and using components. This makes it possible to create multiple levels of layouts, e.g. a global header and footer, and then on some pages, a sidebar menu. It also makes it possible to pass data between layout and page components. +[What are layout components?](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#what-are-layout-components) +Layout components are for sections of your site that you want to share across multiple pages. For example, Gatsby sites will commonly have a layout component with a shared header and footer. Other common things to add to layouts are a sidebar and/or navigation menu. On this page for example, the header at the top is part of gatsbyjs.com's layout component. +[How to create layout components](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-create-layout-components) +>>>>>>> master It is recommended to create your layout components alongside the rest of your components (e.g. into `src/components/`). - Here is an example of a very basic layout component at `src/components/layout.js`: - ``` import React from "react"export default function Layout({ children }) { return (
{children}
)} ``` +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-import-and-add-layout-components-to-pages)How to import and add layout components to pages +======= +[](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-import-and-add-layout-components-to-pages)How to import and add layout components to pages +>>>>>>> master If you want to apply a layout to a page, you will need to include the `Layout` component and wrap your page in it. For example, here is how you would apply your layout to the front page: - ``` import React from "react"import Layout from "../components/layout"export default function Home() { return (

I'm in a layout!

);} ``` - Repeat for every page and template that needs this layout. +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-prevent-layout-components-from-unmounting)How to prevent layout components from unmounting +======= +[How to prevent layout components from unmounting](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-prevent-layout-components-from-unmounting) +>>>>>>> master As mentioned earlier, Gatsby does not, by default, automatically wrap pages in a layout component. The "top level" component is the page itself. As a result, when the "top level" component changes between pages, React will re-render all children. This means that shared components like navigations will unmount and remount. This will break CSS transitions or React state within those shared components. - If you need to set a wrapper component around page components that won't get unmounted on page changes, use the **`wrapPageElement`** [browser API](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/#wrapPageElement) and the [SSR equivalent](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/#wrapPageElement). - Alternatively, you can prevent your layout component from unmounting by using [gatsby-plugin-layout](https://www.gatsbyjs.com/plugins/gatsby-plugin-layout/), which implements the `wrapPageElement` APIs for you. +<<<<<<< HEAD # Adding Markdown Pages | Gatsby +======= +## Adding Markdown Pages | Gatsby +>>>>>>> master > ## Excerpt > > Gatsby can use Markdown files to create pages in your site. > You add plugins to read and understand folders with Markdown files and from them… - --- - Gatsby can use Markdown files to create pages in your site. You add plugins to read and understand folders with Markdown files and from them create pages automatically. - Here are the steps Gatsby follows for making this happen. - 1. Read files into Gatsby from the filesystem 2. Transform Markdown to HTML and [frontmatter](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#frontmatter-for-metadata-in-markdown-files) to data 3. Add a Markdown file 4. Create a Collection Route component for the Markdown files +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#read-files-into-gatsby-from-the-filesystem)Read files into Gatsby from the filesystem @@ -2429,13 +4172,32 @@ Use the plugin [`gatsby-source-filesystem`](https://www.gatsbyjs.com/plugins/gat ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#add-plugin)Add plugin +======= +[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#read-files-into-gatsby-from-the-filesystem)Read files into Gatsby from the filesystem +Use the plugin [`gatsby-source-filesystem`](https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#gatsby-source-filesystem) to read files. +[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#install)Install +`npm install gatsby-source-filesystem` +[Add Plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#add-plugin)Add plugin +>>>>>>> master Open `gatsby-config.js` to add the `gatsby-source-filesystem` plugin. The `path` option is how you set the directory to search for files. - ``` +<<<<<<< HEAD module.exports = { siteMetadata: { title: "My Gatsby Site", }, plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `markdown-pages`, path: `${__dirname}/src/markdown-pages`, }, }, ],} +======= +module.exports = { siteMetadata: { + title: "My Gatsby Site", }, +plugins: [ { + resolve: `gatsby-source-filesystem`, +options: { + name: `markdown-pages`, + path: `${__dirname}/src/markdown-pages`, +}, + }, +],} +>>>>>>> master ``` - Completing the above step means that you've "sourced" the Markdown files from the filesystem. You can now "transform" the Markdown to HTML and the YAML frontmatter to JSON. +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#transform-markdown-to-html-and-frontmatter-to-data-using-gatsby-transformer-remark)Transform Markdown to HTML and frontmatter to data using `gatsby-transformer-remark` @@ -2447,9 +4209,16 @@ You'll use the plugin [`gatsby-transformer-remark`](https://www.gatsbyjs.com/plu ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#configure-plugin)Configure plugin +======= +[Transform Markdown to HTML and frontmatter to data using `gatsby-transformer-remark`](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#transform-markdown-to-html-and-frontmatter-to-data-using-gatsby-transformer-remark) +You'll use the plugin [`gatsby-transformer-remark`](https://www.gatsbyjs.com/plugins/gatsby-transformer-remark/) to recognize files which are Markdown and read their content. The plugin will convert the frontmatter metadata part of your Markdown files as `frontmatter` and the content part as HTML. +[Install transformer plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#install-transformer-plugin) +`npm install gatsby-transformer-remark` +[Configure plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#configure-plugin) +>>>>>>> master Add this to `gatsby-config.js` after the previously added `gatsby-source-filesystem`. - ``` +<<<<<<< HEAD module.exports = { siteMetadata: { title: "My Gatsby Site", }, plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `markdown-pages`, path: `${__dirname}/src/markdown-pages`, }, }, `gatsby-transformer-remark`, ],} ``` @@ -2459,56 +4228,138 @@ Create a folder in the `/src` directory of your Gatsby application called `markd ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#frontmatter-for-metadata-in-markdown-files)Frontmatter for metadata in Markdown files +======= +module.exports = { siteMetadata: { + title: "My Gatsby Site", }, +plugins: [ { + resolve: `gatsby-source-filesystem`, +options: { + name: `markdown-pages`, + path: `${__dirname}/src/markdown-pages`, +}, + }, + `gatsby-transformer-remark`, ], +} +``` +[Add a Markdown file](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#add-a-markdown-file) +Create a folder in the `/src` directory of your Gatsby application called `markdown-pages`. Now create a Markdown file inside it with the name `post-1.md`. +[Frontmatter for metadata in Markdown files](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#frontmatter-for-metadata-in-markdown-files) +>>>>>>> master When you create a Markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called "frontmatter" and is denoted by the triple dashes at the start and end of the block. This block will be parsed by `gatsby-transformer-remark` as YAML. You can then query the data through the GraphQL API from your React components. - src/markdown-pages/post-1.md - ``` ---slug: "/blog/my-first-post"date: "2019-05-04"title: "My first blog post"--- ``` - What is important in this step is the key pair `slug`. The value that is assigned to the key `slug` is used in order to navigate to your post. +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#create-a-collection-route-for-the-markdown-files)Create a Collection Route for the Markdown files +======= +[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#create-a-collection-route-for-the-markdown-files)Create a Collection Route for the Markdown files +>>>>>>> master Create `src/pages/{MarkdownRemark.frontmatter__slug}.js` and add the following code: - src/pages/{MarkdownRemark.frontmatter\_\_slug}.js - ``` +<<<<<<< HEAD import React from "react"import { graphql } from "gatsby"export default function Template({ data, }) { const { markdownRemark } = data const { frontmatter, html } = markdownRemark return (

{frontmatter.title}

{frontmatter.date}

)}export const pageQuery = graphql` query($id: String!) { markdownRemark(id: { eq: $id }) { html frontmatter { date(formatString: "MMMM DD, YYYY") slug title } } }` +======= +import React from "react" +import { graphql } from "gatsby"export default function Template({ data, }) { const { markdownRemark } = data const { frontmatter, html } = markdownRemark return (

{frontmatter.title}

{frontmatter.date}

)}export const pageQuery = graphql` query($id: String!) { markdownRemark(id: { + eq: $id }) { html frontmatter { date(formatString: "MMMM DD, YYYY") slug title } } }` +>>>>>>> master ``` - Two things are important in the file above: - 1. A GraphQL query is made in the second half of the file to get the Markdown data. Gatsby has automagically given you all the Markdown metadata and HTML in this query's result. - **Note: To learn more about GraphQL, consider this [excellent resource](https://www.howtographql.com/)** - 2. The result of the query is injected by Gatsby into the component as the `data` prop. `props.data.markdownRemark` is the property that has all the details of the Markdown file. - Next you could create a page component at `src/pages/blog/index.js` to serve as a listing page for all your blog posts. - This should get you started on some basic Markdown functionality in your Gatsby site. You can further customize the frontmatter and the component file to get desired effects! - For more information, have a look in the working example `using-markdown-pages`. You can find it in the [Gatsby examples section](https://github.com/gatsbyjs/gatsby/tree/master/examples). +<<<<<<< HEAD ## [](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#other-tutorials)Other tutorials +======= +[Other tutorials](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#other-tutorials) +>>>>>>> master
- --- +<<<<<<< HEAD # Technoloy +======= +### Overview +The **`_.get()` method** in Lodash retrieves the object’s value at a specific path. +If the value is not present at the object’s specific path, it will be resolved as `undefined`. This method will return the default value if specified in such a case. +### Syntax +```js +_.get(object, path, defaultValue) +``` +### Parameters +This method accepts the following parameters: +- **`object`**: The object in which the given path will be queried. +- **`path`**: The path used to retrieve the value from the object. +- **`defaultValue`**: The default value that will be returned for resolved values that are undefined. +### Return value +This method will return the value at the specified path if found. Otherwise, it will return the default value if specified. +### Example +Let’s look at an example of the `_.get()` method in the code snippet below: +### Explanation +In the HTML tab: +- **Line 5**: We import the `lodash` script. +In the JavaScript tab: +- **Lines 2 to 15**: We create an object to perform a query. +- **Line 18**: We define a variable `collegeYopPath` to get the value. +- **Lines 19**: We use the `_.get()` method and pass the `object`, `collegeYopPath`, and a default value as parameters. +- **Line 22**: We define a variable `falsyPath` to get the value. +- **Lines 23**: We use the `_.get()` method and pass the `object`, `falsyPath` and a `default value` as parameters. +### Output +- The `_.get()` method at **line 19** contains a valid path, and therefore the expression is resolved, and `2021` is printed on the console. +- The `_.get()` method at **Line 23** contains an invalid path, and therefore the expression is resolved as `undefined`. +## Technoloy +>>>>>>> master ![tech-stack](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/madewith.png?raw=true) - --- +<<<<<<< HEAD # SOURCECODE +======= +## SOURCECODE +--- +### Overview +The **`_.get()` method** in Lodash retrieves the object’s value at a specific path. +If the value is not present at the object’s specific path, it will be resolved as `undefined`. This method will return the default value if specified in such a case. +### Syntax +```js +_.get(object, path, defaultValue) +``` +### Parameters +This method accepts the following parameters: +- **`object`**: The object in which the given path will be queried. +- **`path`**: The path used to retrieve the value from the object. +- **`defaultValue`**: The default value that will be returned for resolved values that are undefined. +### Return value +This method will return the value at the specified path if found. Otherwise, it will return the default value if specified. +### Example +Let’s look at an example of the `_.get()` method in the code snippet below: +### Explanation +In the HTML tab: +- **Line 5**: We import the `lodash` script. +In the JavaScript tab: +- **Lines 2 to 15**: We create an object to perform a query. +- **Line 18**: We define a variable `collegeYopPath` to get the value. +- **Lines 19**: We use the `_.get()` method and pass the `object`, `collegeYopPath`, and a default value as parameters. +- **Line 22**: We define a variable `falsyPath` to get the value. +- **Lines 23**: We use the `_.get()` method and pass the `object`, `falsyPath` and a `default value` as parameters. +### Output +- The `_.get()` method at **line 19** contains a valid path, and therefore the expression is resolved, and `2021` is printed on the console. +- The `_.get()` method at **Line 23** contains an invalid path, and therefore the expression is resolved as `undefined`. +--- +>>>>>>> master ``` - bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components @@ -2651,18 +4502,21 @@ bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js - 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ ``` - --- +<<<<<<< HEAD # Source Code +======= +## Source Code +>>>>>>> master
- Folder Structure (src) + + Folder Structure (src) ``` . ├── Combined_____-_____Doc.md @@ -2969,17 +4823,21 @@ bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ ├── toStyleObj.js ├── toUrl.js └── withPrefix.js - 32 directories, 272 files ``` -
+ + Click To See Component Sourcecode +<<<<<<< HEAD # Component Structure +======= +## Component Structure +>>>>>>> master ``` . ├── ActionLink.js @@ -3001,18 +4859,17 @@ bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ ├── Submenu.js ├── global.css └── index.js - ``` - --- - ```js import React from 'react'; import _ from 'lodash'; +<<<<<<< HEAD +======= +>>>>>>> master import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; - export default class ActionLink extends React.Component { render() { let action = _.get(this.props, 'action', null); @@ -3031,7 +4888,7 @@ export default class ActionLink extends React.Component { 'button-icon': _.get(action, 'style', null) === 'icon' })} > - {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon_class', null) ? ( + {_.get(action, 'style', null) === 'icon' &&_.get(action, 'icon_class', null) ? ( {_.get(action, 'label', null)} @@ -3044,19 +4901,76 @@ export default class ActionLink extends React.Component { } } ``` - --- +<<<<<<< HEAD ```js import React from 'react'; import _ from 'lodash'; +======= +### Table of Contents +- [getPage][1] + - [Parameters][2] +- [getPageByFilePath][3] + - [Parameters][4] +- [getPages][5] + - [Parameters][6] + - [Examples][7] +## getPage +Get the page at the provided `urlPath`. +### Parameters +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `urlPath` **[string][9]** The url path to find the page by +Returns **[Object][10]** +## getPageByFilePath +Get the page at the provided `filePath`. +### Parameters +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `filePath` **[string][9]** The file path to find the page by +Returns **[Object][10]** +## getPages +Get all the pages located under the provided `urlPath`, not including the +index page. I.e.: All pages having their URLs start with `urlPath` excluding +the page having its URL equal to `urlPath`. +### Parameters +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `urlPath` **[string][9]** The url path to filter pages by +### Examples +```javascript +pages => [ + {url: '/'}, + {url: '/about'}, + {url: '/posts'}, + {url: '/posts/hello'}, + {url: '/posts/world'} +] +getPages(pages, /posts') +=> [ + {url: '/posts/hello'}, + {url: '/posts/world'} +] +``` +Returns **[Array][8]** +[1]: #getpage +[2]: #parameters +[3]: #getpagebyfilepath +[4]: #parameters-1 +[5]: #getpages +[6]: #parameters-2 +[7]: #examples +[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array +[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object +```js +import React from 'react'; +import_ from 'lodash'; +>>>>>>> master import { Link, withPrefix, classNames } from '../utils'; - export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); - return _.map(actions, (action, action_idx) => ( +return_.map(actions, (action, action_idx) => ( {_.get(action, 'label', null)} @@ -3077,20 +4991,21 @@ export default class CtaButtons extends React.Component { } } ``` - --- - ```js import React from 'react'; +<<<<<<< HEAD import _ from 'lodash'; +======= +import_ from 'lodash'; +>>>>>>> master import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; - export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); - let page = _.get(this.props, 'page', null); +let page =_.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( @@ -3104,7 +5019,7 @@ export default class DocsMenu extends React.Component {
- - - ---- -### Documentation Commands: - -documentation build src/components/DocsMenu.js -f md> ./notes/DocsMenu.md -documentation build src/components/Footer.js -f md> ./notes/Footer.md -documentation build src/components/Header.js -f md> ./notes/Header.md -documentation build src/components/index.js -f md> ./notes/index.md -documentation build src/components/SectionContent.js -f md> ./notes/SectionContent.md -documentation build src/components/SectionDocs.js -f md> ./notes/SectionDocs.md -documentation build src/components/SectionHero.js -f md> ./notes/SectionHero.md -documentation build src/components/CtaButtons.js -f md> ./notes/CtaButtons.md -documentation build src/components/DocsSubmenu.js -f md> ./notes/DocsSubmenu.md -documentation build src/components/FormField.js -f md> ./notes/FormField.md -documentation build src/components/Icon.js -f md> ./notes/Icon.md -documentation build src/components/Layout.js -f md> ./notes/Layout.md -documentation build src/components/SectionCta.js -f md> ./notes/SectionCta.md -documentation build src/components/SectionGrid.js -f md> ./notes/SectionGrid.md -documentation build src/components/Submenu.js -f md> ./notes/Submenu.md -documentation build src/components/ActionLink.js -f md> ./notes/ActionLink.md - - - - ---- - -## Blog Content: - - - - - ---- - - - ---- - -## Bash Cheat Sheet (MY COMMANDS) - - - - - -
- - Bash Cheat Sheet (MY COMMANDS) Notes: Issue when renaming file without numbers collides with existing file name... - -###### code - -```bash -find . -name "* *" -type d | rename 's/ /_/g' -find . -name "* *" -type f | rename 's/ /_/g' -``` - -```bash - -```bash -find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh - -find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh - -for i in *.html; do mv "$i" "${i%-*}.html"; done - -for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done - ---- -### Description: combine the contents of every file in the contaning directory. - ->Notes: this includes the contents of the file it's self... - -###### code: - -```js -//APPEND-DIR.js -const fs = require('fs'); -let cat = require('child_process') - .execSync('cat *') - .toString('UTF-8'); -fs.writeFile('output.md', cat, err => { - if (err) throw err; -}); - -``` - ---- - -## 2. Download Website Using Wget - -### Description - -> Notes: ==> sudo apt install wget - -###### code - -```bash - -wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/ - -``` - ---- - -## 3. Clean Out Messy Git Repo - -### Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders - -> Notes: To clear up clutter in repositories that only get used on your local machine. - -###### code - -```bash - -find . -empty -type d -print -delete - -find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + - -find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + - -``` - ---- - -## 4. clone all of a user's git repositories - -### Description: clone all of a user or organization's git repositories - -> Notes: - -###### code - -## Generalized - -```bash - -CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 -curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" | - grep -e 'git_url*' | - cut -d \" -f 4 | - xargs -L1 git clone -``` - -## Clone all Git User - -```bash -CNTX={users}; NAME={bgoonz}; PAGE=1 -curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | - grep -e 'git_url*' | - cut -d \" -f 4 | - xargs -L1 git clone - -``` - -## Clone all Git Organization - -```bash - -CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1 -curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | - grep -e 'git_url*' | - cut -d \" -f 4 | - xargs -L1 git clone - -``` - ---- - -## 5. Git Workflow - -### Description - -###### code - -```bash -git pull -git init -git add . -git commit -m"update" -git push -u origin master -``` - -```bash -git init -git add . -git commit -m"update" -git push -u origin main -``` - -```bash - -git init -git add . -git commit -m"update" -git push -u origin bryan-guner -``` - -```bash -git init -git add . -git commit -m"update" -git push -u origin gh-pages -``` - -```bash -git init -git add . -git commit -m"update" -git push -u origin preview -``` - ---- - -## 6. Recursive Unzip In Place - -### Description: recursively unzips folders and then deletes the zip file by the same name - -> Notes: - -###### code - -```bash - -find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; - -find . -name "*.zip" -type f -print -delete - -``` - ---- - -## 7. git pull keeping local changes - -### Description - -> Notes: - -###### code - -```bash - -git stash -git pull -git stash pop - -``` - ---- - -## 8. Prettier Code Formatter - -### Description - -> Notes: - -###### code - -```bash - -sudo npm i prettier -g - -prettier --write . - -``` - ---- - -## 9. Pandoc - -### Description - -> Notes: - -###### code - -```bash - -find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; - -find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \; - -find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \; - -``` - ---- - -## 10. Gitpod Installs - -### Description - -> Notes: - -###### code - -```bash -sudo apt install tree -sudo apt install pandoc -y -sudo apt install rename -y -sudo apt install black -y -sudo apt install wget -y -npm i lebab -g -npm i prettier -g -npm i npm-recursive-install -g - -``` - -```bash -black . - -prettier --write . -npm-recursive-install -``` - ---- - -## 11. Repo Utils Package - -### Description: my standard repo utis package - -> Notes: - -###### code - -```bash -npm i @bgoonz11/repoutils - -``` - ---- - -## 12. Unix Tree Package Usage - -### Description - -> Notes: - -###### code - -```bash -tree -d -I 'node_modules' - -tree -I 'node_modules' - -tree -f -I 'node_modules' >TREE.md - -tree -f -L 2 >README.md - -tree -f -I 'node_modules' >listing-path.md - -tree -f -I 'node_modules' -d >TREE.md - -tree -f >README.md - -``` - ---- - -## 13. Find & Replace string in file & folder names recursively - -### Description - -> Notes: - -###### code - -```bash - -find . -type f -exec rename 's/string1/string2/g' {} + - -find . -type d -exec rename 's/-master//g' {} + - -find . -type f -exec rename 's/\.download//g' {} + - -find . -type d -exec rename 's/-main//g' {} + - -rename 's/\.js\.download$/.js/' *.js\.download - -rename 's/\.html\.markdown$/.md/' *.html\.markdown - -find . -type d -exec rename 's/es6//g' {} + - -``` - ---- - -## 14. Remove double extensions - -### Description - -> Notes: - -###### code - -```bash -#!/bin/bash - -for file in *.md.md -do - mv "${file}" "${file%.md}" -done - -#!/bin/bash - -for file in *.html.html -do - mv "${file}" "${file%.html}" -done -``` - -```bash - -#!/bin/bash - -for file in *.html.png -do - mv "${file}" "${file%.png}" -done - -for file in *.jpg.jpg -do - mv "${file}" "${file%.png}" -done - -``` - ---- - -## 15. Truncate folder names down to 12 characters - -### Description: Truncate folder names down to 12 characters - -> Notes: Truncate folder names down to 12 characters - -###### code - -```bash - -for d in ./*; do mv $d ${d:0:12}; done - -``` - ---- - -## 16.Appendir.js - -### Description: combine the contents of every file in the contaning directory - -> Notes: this includes the contents of the file it's self... - -###### code - -```js -//APPEND-DIR.js -const fs = require('fs'); -let cat = require('child_process').execSync('cat *').toString('UTF-8'); -fs.writeFile('output.md', cat, (err) => { - if (err) throw err; -}); -``` - ---- - -## 17. Replace space in filename with underscore - -### Description: followed by replace `'#' with '_'` in directory name - -> Notes: Can be re-purposed to find and replace any set of strings in file or folder names. - -###### code - -```bash -find . -name "* *" -type f | rename 's/_//g' - -find . -name "* *" -type d | rename 's/#/_/g' - -``` - ---- - -## 18. Filter & delete files by name and extension - -### Description - -> Notes: - -###### code - -```bash -find . -name '.bin' -type d -prune -exec rm -rf '{}' + - -find . -name '*.html' -type d -prune -exec rm -rf '{}' + - -find . -name 'nav-index' -type d -prune -exec rm -rf '{}' + - -find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + - -find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' + - -find . -name 'right.html' -type f -prune -exec rm -rf '{}' + - -find . -name 'left.html' -type f -prune -exec rm -rf '{}' + - -``` - ---- - -## 19. Remove lines containing string - -### Description - -> Notes: Remove lines not containing `'.js'` - -```bash - -sudo sed -i '/\.js/!d' ./*scrap2.md - -``` - -###### code - -```bash -sudo sed -i '/githubusercontent/d' ./*sandbox.md - -sudo sed -i '/githubusercontent/d' ./*scrap2.md - -sudo sed -i '/github\.com/d' ./*out.md - -sudo sed -i '/author/d' ./* - -``` - ---- - -## 20. Remove duplicate lines from a text file - -### Description - -> Notes: -> //...syntax of uniq...// -> $uniq [OPTION] [INPUT[OUTPUT]] -> The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn't specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn't specified then uniq writes to the standard output. - -Now, let's understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq. - -###### code - -```bash -sudo apt install uniq -uniq -u input.txt output.txt - -``` - ---- - -## 21. Remove lines containing string - -### Description - -> Notes: - -###### code - -```bash -sudo sed -i '/githubusercontent/d' ./*sandbox.md - -sudo sed -i '/githubusercontent/d' ./*scrap2.md - -sudo sed -i '/github\.com/d' ./*out.md - ---- -title: add_days -tags: date,intermediate -firstSeen: 2020-10-28T16:19:04+02:00 -lastUpdated: 2020-10-28T16:19:04+02:00 ---- - -sudo sed -i '/title:/d' ./*output.md -sudo sed -i '/firstSeen/d' ./*output.md -sudo sed -i '/lastUpdated/d' ./*output.md -sudo sed -i '/tags:/d' ./*output.md - -sudo sed -i '/badstring/d' ./* - -sudo sed -i '/stargazers/d' ./repo.txt -sudo sed -i '/node_modules/d' ./index.html -sudo sed -i '/right\.html/d' ./index.html -sudo sed -i '/right\.html/d' ./right.html - -``` - ---- - -## 22. Zip directory excluding .git and node_modules all the way down (Linux) - -### Descriptio: zip up an entire git directory - -> Notes: - -###### code - -```bash - -#!/bin/bash -TSTAMP=`date '+%Y%m%d-%H%M%S'` -zip -r $1.$TSTAMP.zip $1 -x "**.git/*" -x "**node_modules/*" `shift; echo $@;` - -printf "\nCreated: $1.$TSTAMP.zip\n" - -## usage: -## - zipdir thedir -## - zip thedir -x "anotherexcludedsubdir" (important the double quotes to prevent glob expansion) - -## if in windows/git-bash, add 'zip' command this way: -## https://stackoverflow.com/a/55749636/1482990 - -``` - ---- - -## 23. Delete files containing a certain string - -### Description - -> Notes: - -###### code - -```bash -find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh -vi doit.sh // check for murphy and his law -source doit.sh - -``` - ---- - -## 24 Generate sitemap - -### Description - -> Notes: bash command to auto generate sitemap.html which will list all files contained within parent directory. - -###### code - -```bash - -#!/bin/sh - -## find ./ | grep -i "\.*$" >files -find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files -listing="files" - -out="" - -html="sitemap.html" -out="basename $out.html" -html="sitemap.html" -cmd() { - - echo ' ' - echo '' - echo '' - - echo ' ' - - echo ' ' - echo '' - echo ' ' - echo ' ' - - echo " directory " - echo '' - echo '' - echo "" - echo '' - echo '' - - echo '' - - echo "" - - # continue with the HTML stuff - - echo "" - - echo "" - - echo "
    " - - awk '{print "
  • ",$1," 
  • "}' $listing - - # awk '{print "
  • "}; - - # {print " ",$1,"
  •  "}' \ $listing - - echo "" - - echo "
" - - echo "" - - echo "" - -} - -cmd $listing --sort=extension >>$html - -``` - ---- - -## 25. Index of Iframes - -### Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags - -> Notes: Useful Follow up Code: - -```bash - -``` - -###### code - -```bash - -#!/bin/sh - -## find ./ | grep -i "\.*$" >files -find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files -listing="files" - -out="" - -html="index.html" -out="basename $out.html" -html="index.html" -cmd() { - - echo ' ' - echo '' - echo '' - - echo ' ' - - echo ' ' - echo '' - echo ' ' - echo ' ' - - echo " directory " - - echo "" - echo '' - echo '' - - echo '' - - echo "" - - # continue with the HTML stuff - - echo "" - - echo "" - - echo "
    " - - awk '{print ""}' $listing - - # awk '{print "
  • "}; - - # {print " ",$1,"
  •  "}' \ $listing - - echo "" - - echo "
" - - echo "" - - echo "" - -} - -cmd $listing --sort=extension >>$html - -``` - ---- - -## 26. Filter Corrupted Git Repo For Troublesome File - -### Description - -> Notes: - -###### code - -```bash - -git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD - -``` - ---- - -## 27. OVERWRITE LOCAL CHANGES - -### Description - -Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] -If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected. - -> Notes: -> First, run a fetch to update all origin/ refs to latest: - -###### code - -```bash - -git fetch --all -## Backup your current branch: - -git branch backup-master -## Then, you have two options: - -git reset --hard origin/master -## OR If you are on some other branch: - -git reset --hard origin/ -## Explanation: -## git fetch downloads the latest from remote without trying to merge or rebase anything. - -## Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master -git fetch --all -git reset --hard origin/master - -``` - ---- - -## 28. Remove Submodules - -### Description: To remove a submodule you need to - -> Notes: - -> Delete the relevant section from the .gitmodules file. -> Stage the .gitmodules changes git add .gitmodules -> Delete the relevant section from .git/config. -> Run git rm --cached path_to_submodule (no trailing slash). -> Run rm -rf .git/modules/path_to_submodule (no trailing slash). -> Commit git commit -m "Removed submodule " -> Delete the now untracked submodule files rm -rf path_to_submodule - -###### code - -```bash -git submodule deinit -``` - ---- - -## 29. GET GISTS - -### Description - -> Notes: - -###### code - -```bash -sudo apt install wget - -wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget - -wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget - -wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget - -wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget - -``` - ---- - -## 30. Remove Remote OriginL - -### Description - -> Notes: - -###### code - -```bash - -git remote remove origin - -``` - ---- - -## 31. just clone .git folder - -### Description - -> Notes: - -###### code - -```bash - -git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git - -``` - ---- - -## 32. Undo recent pull request - -### Description - -> Notes: - -###### code - -```bash - -git reset --hard master@{"10 minutes ago"} - -``` - ---- - -## 33. Lebab - -### Description: ES5 --> ES6 - -> Notes: - -###### code - -```bash -## Safe: - - lebab --replace ./ --transform arrow - lebab --replace ./ --transform arrow-return - lebab --replace ./ --transform for-of - lebab --replace ./ --transform for-each - lebab --replace ./ --transform arg-rest - lebab --replace ./ --transform arg-spread - lebab --replace ./ --transform obj-method - lebab --replace ./ --transform obj-shorthand - lebab --replace ./ --transform multi-var - -## ALL: - -lebab --replace ./ --transform obj-method -lebab --replace ./ --transform class -lebab --replace ./ --transform arrow -lebab --replace ./ --transform let -lebab --replace ./ --transform arg-spread -lebab --replace ./ --transform arg-rest -lebab --replace ./ --transform for-each -lebab --replace ./ --transform for-of -lebab --replace ./ --transform commonjs -lebab --replace ./ --transform exponent -lebab --replace ./ --transform multi-var -lebab --replace ./ --transform template -lebab --replace ./ --transform default-param -lebab --replace ./ --transform destruct-param -lebab --replace ./ --transform includes -lebab --replace ./ --transform obj-method -lebab --replace ./ --transform class -lebab --replace ./ --transform arrow -lebab --replace ./ --transform arg-spread -lebab --replace ./ --transform arg-rest -lebab --replace ./ --transform for-each -lebab --replace ./ --transform for-of -lebab --replace ./ --transform commonjs -lebab --replace ./ --transform exponent -lebab --replace ./ --transform multi-var -lebab --replace ./ --transform template -lebab --replace ./ --transform default-param -lebab --replace ./ --transform destruct-param -lebab --replace ./ --transform includes - -``` - ---- - -## 34. Troubleshoot Ubuntu Input/Output Error - -### Description: Open Powershell as Administrator - -> Notes: - -###### code - -```ps1 - - wsl.exe --shutdown - - Get-Service LxssManager | Restart-Service - -``` - ---- - -## 35. Export Medium as Markdown - -### Description - -> Notes: - -###### code - -```bash -npm i mediumexporter -g - -mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md - -``` - ---- - -## 36. Delete files in violation of a given size range (100MB for git) - -### Description - -> Notes: - -###### code - -```bash - -find . -size +75M -a -print -a -exec rm -f {} \; - -find . -size +98M -a -print -a -exec rm -f {} \; - -``` - ---- - -## 37. download all links of given file type - -### Description - -> Notes: - -###### code - -```bash - -wget -r -A.pdf https://overapi.com/git - -``` - ---- - -## 38. Kill all node processes - -### Description - -> Notes: - -###### code - -```bash -killall -s KILL node - -``` - ---- - -## 39. Remove string from file names recursively - -### Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories - -###### code - -```bash -find -type f -exec sed -i 's///g' {} + - -find . -type f -exec rename 's/-master//g' {} + - -``` - -> Notes: The same could be done for folder names by changing the *-type f* flag (for file) to a *-type d* flag (for directory) - -```bash -find -type d -exec sed -i 's///g' {} + - -find . -type d -exec rename 's/-master//g' {} + - -``` - ---- - -## 40. Remove spaces from file and folder names recursively - -### Description: replaces spaces in file and folder names with an `_` underscore - -> Notes: need to run `sudo apt install rename` to use this command - -###### code - -```bash - -find . -name "* *" -type d | rename 's/ /_/g' -find . -name "* *" -type f | rename 's/ /_/g' -``` - ---- - -## 41. Zip Each subdirectories in a given directory into their own zip file - -### Description - -> Notes: - -###### code - -```bash -for i in */; do zip -r "${i%/}.zip" "$i"; done - -``` - ---- - -## 91. Unzip PowerShell - -### Description - -> Notes: - -###### code - -```ps1 - -PARAM ( - [string] $ZipFilesPath = "./", - [string] $UnzipPath = "./RESULT" -) - -$Shell = New-Object -com Shell.Application -$Location = $Shell.NameSpace($UnzipPath) - -$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP - -$progress = 1 -foreach ($ZipFile in $ZipFiles) { - Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" - $ZipFolder = $Shell.NameSpace($ZipFile.fullname) - - $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - https://msdn.microsoft.com/library/bb787866%28VS.85%29.aspx - $progress++ -} - -``` - ---- - -## 92. return to bash from zsh - -### Description - -> Notes: - -###### code - -```bash - sudo apt --purge remove zsh - -``` - ---- - -## 93. Symbolic Link - -### Description: to working directory - -> Notes: - -###### code - -```bash - -ln -s "$(pwd)" ~/NameOfLink - -ln -s "$(pwd)" ~/Downloads - -``` - ---- - -## 94. auto generate readme - -### Description: rename existing readme to blueprint.md - -> Notes: - -###### code - -```bash - -npx @appnest/readme generate - -``` - ---- - -## 95. Log into postgres - -### Description - -> Notes: - -###### code - -```bash -sudo -u postgres psql -``` - ---- - -## 96. URL To Subscribe To YouTube Channel - -| URL | | -| -------------------- | -------------------------------------------------------- | -| Miscellaneous | webpack ; Prism | -| Widgets | Facebook ; AddThis | -| Analytics | Moat ; Google Analytics ; Google Ads Conversion Tracking | -| Comment systems | Facebook API & REPL.it Database | -| Security | Netlify Access | -| Font scripts | Google Font API | -| CDN | Unpkg ; jsDelivr ; jQuery CDN ; Netlify | -| Marketing automation | MailChimp | -| Advertising | Google AdSense | -| Tag managers | Google Tag Manager | -| Live chat | Smartsupp ; LiveChat : Mesibo API | -| JavaScript libraries | Lodash ; Dojo ; core-js ; jQuery | - ---- - -## 96. URL To Subscribe To YouTube Channel - -## Description - -> Notes: - -###### code - -```txt - -https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1 - -``` - ---- - -## 97. Embed Repl.it In Medium Post - -###### code - -```txt - -https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - -https://repl.it/@bgoonz/node-db1-project?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - -https://repl.it/@bgoonz/interview-prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - -https://repl.it/@bgoonz/Database-Prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com - -``` - ---- - -## 98 rRmove text target="parent" from files called right.html - -### Description - -> Notes: - -###### code - -```bash - -find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + - -find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + - -``` - -## 99. Cheat Sheet - -### Description - -> Notes: - -###### code - -```bash -#!/bin/bash -revert -## SHORTCUTS and HISTORY - - -CTRL+A # move to beginning of line -CTRL+B # moves backward one character -CTRL+C # halts the current command -CTRL+D # deletes one character backward or logs out of current session, similar to exit -CTRL+E # moves to end of line -CTRL+F # moves forward one character -CTRL+G # aborts the current editing command and ring the terminal bell -CTRL+H # deletes one character under cursor (same as DELETE) -CTRL+J # same as RETURN -CTRL+K # deletes (kill) forward to end of line -CTRL+L # clears screen and redisplay the line -CTRL+M # same as RETURN -CTRL+N # next line in command history -CTRL+O # same as RETURN, then displays next line in history file -CTRL+P # previous line in command history -CTRL+Q # resumes suspended shell output -CTRL+R # searches backward -CTRL+S # searches forward or suspends shell output -CTRL+T # transposes two characters -CTRL+U # kills backward from point to the beginning of line -CTRL+V # makes the next character typed verbatim -CTRL+W # kills the word behind the cursor -CTRL+X # lists the possible filename completions of the current word -CTRL+Y # retrieves (yank) last item killed -CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background - -ALT+B # moves backward one word -ALT+D # deletes next word -ALT+F # moves forward one word -ALT+H # deletes one character backward -ALT+T # transposes two words -ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. -ALT+U # capitalizes every character from the current cursor position to the end of the word -ALT+L # uncapitalizes every character from the current cursor position to the end of the word -ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. -ALT+R # reverts any changes to a command you've pulled from your history if you've edited it. -ALT+? # list possible completions to what is typed -ALT+^ # expand line to most recent match from history - -CTRL+X then ( # start recording a keyboard macro -CTRL+X then ) # finish recording keyboard macro -CTRL+X then E # recall last recorded keyboard macro -CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands - -BACKSPACE # deletes one character backward -DELETE # deletes one character under cursor - -history # shows command line history -!! # repeats the last command -! # refers to command line 'n' -! # refers to command starting with 'string' - -exit # logs out of current session - - -## BASH BASICS - - -env # displays all environment variables - -echo $SHELL # displays the shell you're using -echo $BASH_VERSION # displays bash version - -bash # if you want to use bash (type exit to go back to your previously opened shell) -whereis bash # locates the binary, source and manual-page for a command -which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) - -clear # clears content on window (hide displayed lines) - - -## FILE COMMANDS - - -ls # lists your files in current directory, ls to print files in a specific directory -ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified -ls -a # lists all files in 'long format', including hidden files (name beginning with '.') -ln -s # creates symbolic link to file -readlink # shows where a symbolic links points to -tree # show directories and subdirectories in easilly readable file tree -mc # terminal file explorer (alternative to ncdu) -touch # creates or updates (edit) your file -mktemp -t # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) -cat # prints file raw content (will not be interpreted) -any_command > # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) -more # shows the first part of a file (move with space and type q to quit) -head # outputs the first lines of file (default: 10 lines) -tail # outputs the last lines of file (useful with -f option) (default: 10 lines) -vim # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist -mv # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) -cp # copies a file -rm # removes a file -find . -name # searches for a file or a directory in the current directory and all its sub-directories by its name -diff # compares files, and shows where they differ -wc # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations -sort # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. -sort -t -k # sorts the contents on specific sort key field starting from 1, using the field separator t. -rev # reverse string characters (hello becomes olleh) -chmod -options # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) -gzip # compresses files using gzip algorithm -gunzip # uncompresses files compressed by gzip -gzcat # lets you look at gzipped file without actually having to gunzip it -lpr # prints the file -lpq # checks out the printer queue -lprm # removes something from the printer queue -genscript # converts plain text files into postscript for printing and gives you some options for formatting -dvips # prints .dvi files (i.e. files produced by LaTeX) -grep # looks for the string in the files -grep -r # search recursively for pattern in directory -head -n file_name | tail +n # Print nth line from file. -head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines. - - -## DIRECTORY COMMANDS - - -mkdir # makes a new directory -rmdir # remove an empty directory -rmdir -rf # remove a non-empty directory -mv # rename a directory from to -cd # changes to home -cd .. # changes to the parent directory -cd # changes directory -cp -r # copy into including sub-directories -pwd # tells you where you currently are -cd ~ # changes to home. -cd - # changes to previous working directory - - -## SSH, SYSTEM INFO & NETWORK COMMANDS - - -ssh user@host # connects to host as user -ssh -p user@host # connects to host on specified port as user -ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login - -whoami # returns your username -passwd # lets you change your password -quota -v # shows what your disk quota is -date # shows the current date and time -cal # shows the month's calendar -uptime # shows current uptime -w # displays whois online -finger # displays information about user -uname -a # shows kernel information -man # shows the manual for specified command -df # shows disk usage -du # shows the disk usage of the files and directories in filename (du -s give only a total) -last # lists your last logins -ps -u yourusername # lists your processes -kill # kills the processes with the ID you gave -killall # kill all processes with the name -top # displays your currently active processes -lsof # lists open files -bg # lists stopped or background jobs ; resume a stopped job in the background -fg # brings the most recent job in the foreground -fg # brings job to the foreground - -ping # pings host and outputs results -whois # gets whois information for domain -dig # gets DNS information for domain -dig -x # reverses lookup host -wget # downloads file - -time # report time consumed by command execution - - -## VARIABLES - - -varname=value # defines a variable -varname=value command # defines a variable to be in the environment of a particular subprocess -echo $varname # checks a variable's value -echo $$ # prints process ID of the current shell -echo $! # prints process ID of the most recently invoked background job -echo $? # displays the exit status of the last command -read # reads a string from the input and assigns it to a variable -read -p "prompt" # same as above but outputs a prompt to ask user for value -column -t # display info in pretty columns (often used with pipe) -let = # performs mathematical calculation using operators like +, -, *, /, % -export VARNAME=value # defines an environment variable (will be available in subprocesses) - -array[0]=valA # how to define an array -array[1]=valB -array[2]=valC -array=([2]=valC [0]=valA [1]=valB) # another way -array=(valA valB valC) # and another - -${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed -${#array[i]} # to find out the length of any element in the array -${#array[@]} # to find out how many values there are in the array - -declare -a # the variables are treated as arrays -declare -f # uses function names only -declare -F # displays function names without definitions -declare -i # the variables are treated as integers -declare -r # makes the variables read-only -declare -x # marks the variables for export via the environment - -${varname:-word} # if varname exists and isn't null, return its value; otherwise return word -${varname:word} # if varname exists and isn't null, return its value; otherwise return word -${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value -${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script -${varname:+word} # if varname exists and isn't null, return word; otherwise return null -${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters - -${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest -${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest -${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest -${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest -${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced -${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced - -${#varname} # returns the length of the value of the variable as a character string - -*(patternlist) # matches zero or more occurrences of the given patterns -+(patternlist) # matches one or more occurrences of the given patterns -?(patternlist) # matches zero or one occurrence of the given patterns -@(patternlist) # matches exactly one of the given patterns -!(patternlist) # matches anything except one of the given patterns - -$(UNIX command) # command substitution: runs the command and returns standard output - - -## FUNCTIONS - - -## The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth. -## $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters. - -function functname() { - shell commands -} - -unset -f functname # deletes a function definition -declare -f # displays all defined functions in your login session - - -## FLOW CONTROLS - - -statement1 && statement2 # and operator -statement1 || statement2 # or operator - --a # and operator inside a test conditional expression --o # or operator inside a test conditional expression - -## STRINGS - -str1 == str2 # str1 matches str2 -str1 != str2 # str1 does not match str2 -str1 < str2 # str1 is less than str2 (alphabetically) -str1 > str2 # str1 is greater than str2 (alphabetically) -str1 \> str2 # str1 is sorted after str2 -str1 \< str2 # str1 is sorted before str2 --n str1 # str1 is not null (has length greater than 0) --z str1 # str1 is null (has length 0) - -## FILES - --a file # file exists or its compilation is successful --d file # file exists and is a directory --e file # file exists; same -a --f file # file exists and is a regular file (i.e., not a directory or other special type of file) --r file # you have read permission --s file # file exists and is not empty --w file # your have write permission --x file # you have execute permission on file, or directory search permission if it is a directory --N file # file was modified since it was last read --O file # you own file --G file # file's group ID matches yours (or one of yours, if you are in multiple groups) -file1 -nt file2 # file1 is newer than file2 -file1 -ot file2 # file1 is older than file2 - -## NUMBERS - --lt # less than --le # less than or equal --eq # equal --ge # greater than or equal --gt # greater than --ne # not equal - -if condition -then - statements -[elif condition - then statements...] -[else - statements] -fi - -for x in {1..10} -do - statements -done - -for name [in list] -do - statements that can use $name -done - -for (( initialisation ; ending condition ; update )) -do - statements... -done - -case expression in - pattern1 ) - statements ;; - pattern2 ) - statements ;; -esac - -select name [in list] -do - statements that can use $name -done - -while condition; do - statements -done - -until condition; do - statements -done - - -## COMMAND-LINE PROCESSING CYCLE - - -## The default order for command lookup is functions, followed by built-ins, with scripts and executables last. -## There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`. - -command # removes alias and function lookup. Only built-ins and commands found in the search path are executed -builtin # looks up only built-in commands, ignoring functions and commands found in PATH -enable # enables and disables shell built-ins - -eval # takes arguments and run them through the command-line processing steps all over again - - -## INPUT/OUTPUT REDIRECTORS - - -cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 -< file # takes standard input from file -> file # directs standard output to file ->> file # directs standard output to file; append to file if it already exists ->|file # forces standard output to file even if noclobber is set -n>|file # forces output to file from file descriptor n even if noclobber is set -<> file # uses file as both standard input and standard output -n<>file # uses file as both input and output for file descriptor n -n>file # directs file descriptor n to file -n>file # directs file description n to file; append to file if it already exists -n>& # duplicates standard output to file descriptor n -n<& # duplicates standard input from file descriptor n -n>&m # file descriptor n is made to be a copy of the output file descriptor -n<&m # file descriptor n is made to be a copy of the input file descriptor -&>file # directs standard output and standard error to file -<&- # closes the standard input ->&- # closes the standard output -n>&- # closes the ouput from file descriptor n -n<&- # closes the input from file descripor n - -|tee # output command to both terminal and a file (-a to append to file) - - -## PROCESS HANDLING - - -## To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y. -## This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal. -## Of course, to interrupt a job, type CTRL+C. - -myCommand & # runs job in the background and prompts back the shell - -jobs # lists all jobs (use with -l to see associated PID) - -fg # brings a background job into the foreground -fg %+ # brings most recently invoked background job -fg %- # brings second most recently invoked background job -fg %N # brings job number N -fg %string # brings job whose command begins with string -fg %?string # brings job whose command contains string - -kill -l # returns a list of all signals on the system, by name and number -kill PID # terminates process with specified PID -kill -s SIGKILL 4500 # sends a signal to force or terminate the process -kill -15 913 # Ending PID 913 process with signal 15 (TERM) -kill %1 # Where %1 is the number of job as read from 'jobs' command. - -ps # prints a line of information about the current running login shell and any processes running under it -ps -a # selects all processes with a tty except session leaders - -trap cmd sig1 sig2 # executes a command when a signal is received by the script -trap "" sig1 sig2 # ignores that signals -trap - sig1 sig2 # resets the action taken when the signal is received to the default - -disown # removes the process from the list of jobs - -wait # waits until all background jobs have finished -sleep # wait # of seconds before continuing - -pv # display progress bar for data handling commands. often used with pipe like |pv -yes # give yes response everytime an input is requested from script/process - - -## TIPS & TRICKS - - -## set an alias -cd; nano .bash_profile -> alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile - -## to quickly go to a specific directory -cd; nano .bashrc -> shopt -s cdable_vars -> export websites="/Users/mac/Documents/websites" - -source .bashrc -cd $websites - - -## DEBUGGING SHELL PROGRAMS - - -bash -n scriptname # don't run commands; check for syntax errors only -set -o noexec # alternative (set option in script) - -bash -v scriptname # echo commands before running them -set -o verbose # alternative (set option in script) - -bash -x scriptname # echo commands after command-line processing -set -o xtrace # alternative (set option in script) - -trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits - -function errtrap { - es=$? - echo "ERROR line $1: Command exited with status $es." -} - -trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status - -function dbgtrap { - echo "badvar is $badvar" -} - -trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script -## ...section of code in which the problem occurs... -trap - DEBUG # turn off the DEBUG trap - -function returntrap { - echo "A return occurred" -} - -trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing - - -## COLORS AND BACKGROUNDS - -## note: \e or \x1B also work instead of \033 -## Reset -Color_Off='\033[0m' # Text Reset - -## Regular Colors -Black='\033[0;30m' # Black -Red='\033[0;31m' # Red -Green='\033[0;32m' # Green -Yellow='\033[0;33m' # Yellow -Blue='\033[0;34m' # Blue -Purple='\033[0;35m' # Purple -Cyan='\033[0;36m' # Cyan -White='\033[0;97m' # White - -## Additional colors -LGrey='\033[0;37m' # Ligth Gray -DGrey='\033[0;90m' # Dark Gray -LRed='\033[0;91m' # Ligth Red -LGreen='\033[0;92m' # Ligth Green -LYellow='\033[0;93m'# Ligth Yellow -LBlue='\033[0;94m' # Ligth Blue -LPurple='\033[0;95m'# Light Purple -LCyan='\033[0;96m' # Ligth Cyan - -## Bold -BBlack='\033[1;30m' # Black -BRed='\033[1;31m' # Red -BGreen='\033[1;32m' # Green -BYellow='\033[1;33m'# Yellow -BBlue='\033[1;34m' # Blue -BPurple='\033[1;35m'# Purple -BCyan='\033[1;36m' # Cyan -BWhite='\033[1;37m' # White - -## Underline -UBlack='\033[4;30m' # Black -URed='\033[4;31m' # Red -UGreen='\033[4;32m' # Green -UYellow='\033[4;33m'# Yellow -UBlue='\033[4;34m' # Blue -UPurple='\033[4;35m'# Purple -UCyan='\033[4;36m' # Cyan -UWhite='\033[4;37m' # White - -## Background -On_Black='\033[40m' # Black -On_Red='\033[41m' # Red -On_Green='\033[42m' # Green -On_Yellow='\033[43m'# Yellow -On_Blue='\033[44m' # Blue -On_Purple='\033[45m'# Purple -On_Cyan='\033[46m' # Cyan -On_White='\033[47m' # White - -## Example of usage -echo -e "${Green}This is GREEN text${Color_Off} and normal text" -echo -e "${Red}${On_White}This is Red test on White background${Color_Off}" -## option -e is mandatory, it enable interpretation of backslash escapes -printf "${Red} This is red \n" - -``` - -
- -> - -#### Find - -## To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG) - -find . -iname "\*.jpg" - -## To find directories - -find . -type d - -## To find files - -find . -type f - -## To find files by octal permission - -find . -type f -perm 777 - -## To find files with setuid bit set - -find . -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l - -## To find files with extension '.txt' and remove them - -find ./path/ -name '\*.txt' -exec rm '{}' \; - -## To find files with extension '.txt' and look for a string into them - -find ./path/ -name '\*.txt' | xargs grep 'string' - -## To find files with size bigger than 5 Mebibyte and sort them by size - -find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z - -## To find files bigger than 2 Megabyte and list them - -find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }' - -## To find files modified more than 7 days ago and list file information - -find . -type f -mtime +7d -ls - -## To find symlinks owned by a user and list file information - -find . -type l -user -ls - -## To search for and delete empty directories - -find . -type d -empty -exec rmdir {} \; - -## To search for directories named build at a max depth of 2 directories - -find . -maxdepth 2 -name build -type d - -## To search all files who are not in .git directory - -find . ! -iwholename '*.git*' -type f - -## To find all files that have the same node (hard link) as MY_FILE_HERE - -find . -type f -samefile MY_FILE_HERE 2>/dev/null - -## To find all files in the current directory and modify their permissions - -find . -type f -exec chmod 644 {} \; - ---- - - - ---- - -![Preview](https://i.imgur.com/nieW1vp.png) - -## Wiki Nav - -- [Home](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) -- [add copy to code blocks.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/add-copy-to-code-blocks.md) -- [Add site search w algolia.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Add-site-search-w-algolia.md) -- [adding mailing list.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/adding-mailing-list.md) -- [Adding search 2 gatsby site.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Adding-search-2-gatsby-site.md) -- [awesome.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/awesome.md) -- [broken links.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/broken-links.md) -- [configure custom domain.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/configure-custom-domain.md) -- [contentauthoring.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/contentauthoring.md) -- [full text search w lunar.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/full-text-search-w-lunar.md) -- [inject 4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject-4.md) -- [inject3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject3.md) -- [inject4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject4.md) -- [injected content part2.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-content-part2.md) -- [injected js part4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-js-part4.md) -- [injected part3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-part3.md) -- [links 2 embed.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-2-embed.md) -- [links to remember](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-to-remember) -- [Netlify Injected Content](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Netlify-Injected-Content) -- [old version of index.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/old-version-of-index.md) -- [optimize vscode.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/optimize-vscode.md) -- [possibly useful snippets.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/possibly-useful-snippets.md) -- [privacy policy.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/privacy-policy.md) -- [random stuff.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random-stuff.md) -- [random.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random.md) -- [ref type](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/ref-type) -- [SEO.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/SEO.md) -- [stable points.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/stable-points.md) -- [tech used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/tech-used.md) -- [Technologies Used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Technologies-Used.md) -- [THINGS TO EMBED.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/THINGS-TO-EMBED.md) -- [validation report.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/validation-report.md) -- [web archive.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/web-archive.md) -- [wordpress vs headless cms.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/wordpress-vs-headless-cms.md) - ---- - -## Dependencies - -
- Click to expand! - -[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-search -`^ 4.10.3` - -[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-common -`4.10.5` - -![@ghost**](https://avatars.githubusercontent.com/u/10137?s=40&v=4)@algolia/requester-common -`4.10.5` - -[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/transporter -`4.10.5` - -[![@stackbit**](https://avatars.githubusercontent.com/u/38996451?s=40&v=4)](https://github.com/stackbit)[stackbit / gatsby-plugin-menus](https://github.com/stackbit/gatsby-plugin-menus)@stackbit/gatsby-plugin-menus -`0.0.4` - -[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest)babel-jest -`^ 24.7.1` - -[![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby)babel-preset-gatsby -`^ 0.1.11` - -[![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby) `^ 2.5.0` - -[![@keyz**](https://avatars.githubusercontent.com/u/2268452?s=40&u=c3f56fe1d943474ffe4577a82ad79c1a79d7eb6e&v=4)](https://github.com/keyz)[keyz / identity-obj-proxy](https://github.com/keyz/identity-obj-proxy) `^ 3.0.0` - -[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest) `^ 24.7.1` - -[![@lodash**](https://avatars.githubusercontent.com/u/2565403?s=40&v=4)](https://github.com/lodash)[lodash / lodash](https://github.com/lodash/lodash) `^ 4.17.11` - -[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / react](https://github.com/facebook/react)react-test-renderer -`^ 16.8.6` - -[![@getkirby-v2**](https://avatars.githubusercontent.com/u/6985611?s=40&v=4)](https://github.com/getkirby-v2)[getkirby-v2 / algolia-plugin](https://github.com/getkirby-v2/algolia-plugin)algolia -`0.0.0` - -[![@ecomfe**](https://avatars.githubusercontent.com/u/2268460?s=40&v=4)](https://github.com/ecomfe)[ecomfe / babel-runtime](https://github.com/ecomfe/babel-runtime) `6.26.0` - -[![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / chokidar](https://github.com/paulmillr/chokidar) `3.4.0` - -[![@DefinitelyTyped**](https://avatars.githubusercontent.com/u/3637556?s=40&v=4)](https://github.com/DefinitelyTyped)[DefinitelyTyped / DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)@types/node -`^ 13` - -[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / anymatch](https://github.com/micromatch/anymatch) `~ 3.1.1` - -[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / braces](https://github.com/micromatch/braces) `~ 3.0.2` - -[![@chaijs**](https://avatars.githubusercontent.com/u/1515293?s=40&v=4)](https://github.com/chaijs)[chaijs / chai](https://github.com/chaijs/chai) `^ 4.2` - -[![@microsoft**](https://avatars.githubusercontent.com/u/6154722?s=40&v=4)](https://github.com/microsoft)[microsoft / dtslint](https://github.com/microsoft/dtslint) `^ 3.3.0` - -[![@eslint**](https://avatars.githubusercontent.com/u/6019716?s=40&v=4)](https://github.com/eslint)[eslint / eslint](https://github.com/eslint/eslint) `^ 6.6.0` - -[![@fsevents**](https://avatars.githubusercontent.com/u/48760001?s=40&v=4)](https://github.com/fsevents)[fsevents / fsevents](https://github.com/fsevents/fsevents) `~ 2.1.2` - -[![@gulpjs**](https://avatars.githubusercontent.com/u/6200624?s=40&v=4)](https://github.com/gulpjs)[gulpjs / glob-parent](https://github.com/gulpjs/glob-parent) `~ 5.1.0` - -[![@sindresorhus**](https://avatars.githubusercontent.com/u/170270?s=40&u=34acd557a042ac478d273a4621570cadb6b0bd89&v=4)](https://github.com/sindresorhus)[sindresorhus / is-binary-path](https://github.com/sindresorhus/is-binary-path) `~ 2.1.0` - -[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / is-glob](https://github.com/micromatch/is-glob) `~ 4.0.1` - -[![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 7.0.0` - -[![@jonschlinkert**](https://avatars.githubusercontent.com/u/383994?s=40&u=335f06277f72722162e89bd5516849f2e82f37cf&v=4)](https://github.com/jonschlinkert)[jonschlinkert / normalize-path](https://github.com/jonschlinkert/normalize-path) `~ 3.0.0` - -[![@istanbuljs**](https://avatars.githubusercontent.com/u/13523395?s=40&v=4)](https://github.com/istanbuljs)[istanbuljs / nyc](https://github.com/istanbuljs/nyc) `^ 15.0.0` - -[![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / readdirp](https://github.com/paulmillr/readdirp) `~ 3.4.0` - -[![@isaacs**](https://avatars.githubusercontent.com/u/9287?s=40&u=60a280618307ae965cadbe52da4baa7e351c848c&v=4)](https://github.com/isaacs)[isaacs / rimraf](https://github.com/isaacs/rimraf) `^ 3.0.0` - -[![@sinonjs**](https://avatars.githubusercontent.com/u/6570253?s=40&v=4)](https://github.com/sinonjs)[sinonjs / sinon](https://github.com/sinonjs/sinon) `^ 9.0.1` - -[![@domenic**](https://avatars.githubusercontent.com/u/617481?s=40&v=4)](https://github.com/domenic)[domenic / sinon-chai](https://github.com/domenic/sinon-chai) `^ 3.3.0` - -[![@anodynos**](https://avatars.githubusercontent.com/u/856453?s=40&v=4)](https://github.com/anodynos)[anodynos / upath](https://github.com/anodynos/upath) `^ 1.2.0` - -[![@JedWatson**](https://avatars.githubusercontent.com/u/872310?s=40&u=9548676d01f104232ee42e5ac0d985db77e6a5a4&v=4)](https://github.com/JedWatson)[JedWatson / classnames](https://github.com/JedWatson/classnames) `2.2.6` - -[![@bestiejs**](https://avatars.githubusercontent.com/u/802850?s=40&v=4)](https://github.com/bestiejs)[bestiejs / benchmark.js](https://github.com/bestiejs/benchmark.js)benchmark -`^ 1.0.0` - -[![@browserify**](https://avatars.githubusercontent.com/u/6320506?s=40&v=4)](https://github.com/browserify)[browserify / browserify](https://github.com/browserify/browserify) `^ 14.1.0` - -[![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 2.1.0` - -[![@jeromedecoster**](https://avatars.githubusercontent.com/u/158071?s=40&u=470a733fdc34a9fedab18ae4cf5109d2ea357425&v=4)](https://github.com/jeromedecoster)[jeromedecoster / opn-cli](https://github.com/jeromedecoster/opn-cli) `^ 3.1.0` - -[![@documentationjs**](https://avatars.githubusercontent.com/u/11415556?s=40&v=4)](https://github.com/documentationjs)[documentationjs / documentation](https://github.com/documentationjs/documentation) `^ 13.2.5` - -[![@babel**](https://avatars.githubusercontent.com/u/9637642?s=40&v=4)](https://github.com/babel)[babel / babel](https://github.com/babel/babel)@babel/core -`7.12.3` - -[Cloudfare-Backup](https://bgoonz-blog-2-0.pages.dev/) ↞↠ Search Website: [search](https://www.algolia.com/realtime-search-demo/web-dev-resource-hub-9e6b8aa8-6106-44c5-9f59-ff3f9531abd4) ↞↠ [Backup Repo Deploy](https://bgoonzblog20-backup.netlify.app/#gsc.tab=0) ↞↠ [Github pages](https://bgoonz.github.io/BGOONZ_BLOG_2.0/) ↞↠ [Go To Site Wiki](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) - -
- ---- - -## Docs Structure - -
- Docs Structure - -``` -├── blog -│ ├── 300-react-questions.md -│ ├── awesome-graphql.md -│ ├── big-o-complexity.md -│ ├── blog-archive.md -│ ├── blogwcomments.md -│ ├── data-structures.md -│ ├── flow-control-in-python.md -│ ├── functions-in-python.md -│ ├── git-gateway.md -│ ├── index.md -│ ├── interview-questions-js.md -│ ├── netlify-cms.md -│ ├── platform-docs.md -│ ├── python-for-js-dev.md -│ ├── python-resources.md -│ ├── web-dev-trends.md -│ └── web-scraping.md -├── docs -│ ├── about -│ │ ├── eng-portfolio.md -│ │ ├── ideas-for-this-website.md -│ │ ├── index.md -│ │ ├── intrests.md -│ │ ├── job-search.md -│ │ └── resume.md -│ ├── articles -│ │ ├── basic-web-dev.md -│ │ ├── buffers.md -│ │ ├── dev-dep.md -│ │ ├── event-loop.md -│ │ ├── fs-module.md -│ │ ├── how-the-web-works.md -│ │ ├── http.md -│ │ ├── index.md -│ │ ├── install.md -│ │ ├── intro.md -│ │ ├── modules.md -│ │ ├── nextjs.md -│ │ ├── node-api-express.md -│ │ ├── node-cli-args.md -│ │ ├── node-common-modules.md -│ │ ├── node-env-variables.md -│ │ ├── node-js-language.md -│ │ ├── node-package-manager.md -│ │ ├── node-repl.md -│ │ ├── node-run-cli.md -│ │ ├── nodejs.md -│ │ ├── nodevsbrowser.md -│ │ ├── npm.md -│ │ ├── npx.md -│ │ ├── os-module.md -│ │ ├── reading-files.md -│ │ ├── semantic-html.md -│ │ ├── semantic.md -│ │ ├── the-uniform-resource-locator-(url).md -│ │ ├── understanding-firebase.md -│ │ ├── v8.md -│ │ ├── web-standards-checklist.md -│ │ ├── webdev-tools.md -│ │ └── writing-files.md -│ ├── audio -│ │ ├── audio-feature-extraction.md -│ │ ├── audio.md -│ │ ├── dfft.md -│ │ ├── discrete-fft.md -│ │ ├── dtw-python-explained.md -│ │ ├── dynamic-time-warping.md -│ │ ├── index.md -│ │ └── web-audio-api.md -│ ├── career -│ │ ├── dev-interview.md -│ │ ├── index.md -│ │ ├── interview-dos-n-donts.md -│ │ └── job-boards.md -│ ├── community -│ │ ├── an-open-letter-2-future-developers.md -│ │ ├── index.md -│ │ └── video-chat.md -│ ├── content -│ │ ├── algo.md -│ │ ├── archive.md -│ │ ├── gatsby-Queries-Mutations.md -│ │ ├── history-api.md -│ │ ├── index.md -│ │ ├── main-projects.md -│ │ └── trouble-shooting.md -│ ├── data-structures -│ │ └── index.md -│ ├── docs -│ │ ├── appendix.md -│ │ ├── art-of-command-line.md -│ │ ├── bash.md -│ │ ├── content.md -│ │ ├── css.md -│ │ ├── data-structures-docs.md -│ │ ├── es-6-features.md -│ │ ├── git-reference.md -│ │ ├── git-repos.md -│ │ ├── html-spec.md -│ │ ├── index.md -│ │ ├── markdown.md -│ │ ├── no-whiteboarding.md -│ │ ├── node-docs-complete.md -│ │ ├── node-docs-full.md -│ │ ├── regex-in-js.md -│ │ └── sitemap.md -│ ├── faq -│ │ ├── contact.md -│ │ ├── index.md -│ │ └── plug-ins.md -│ ├── gists.md -│ ├── index.md -│ ├── interact -│ │ ├── callstack-visual.md -│ │ ├── clock.md -│ │ ├── index.md -│ │ ├── jupyter-notebooks.md -│ │ ├── other-sites.md -│ │ └── video-chat.md -│ ├── interview -│ │ ├── index.md -│ │ ├── job-search-nav.md -│ │ └── review-concepts.md -│ ├── javascript -│ │ ├── arrow-functions.md -│ │ ├── asyncjs.md -│ │ ├── await-keyword.md -│ │ ├── bigo.md -│ │ ├── clean-code.md -│ │ ├── constructor-functions.md -│ │ ├── index.md -│ │ ├── promises.md -│ │ ├── review.md -│ │ └── this-is-about-this.md -│ ├── leetcode -│ │ └── index.md -│ ├── privacy-policy.md -│ ├── projects -│ │ ├── embeded-websites.md -│ │ ├── index.md -│ │ ├── list-of-projects.md -│ │ ├── mini-projects.md -│ │ └── my-websites.md -│ ├── python -│ │ ├── at-length.md -│ │ ├── cheat-sheet.md -│ │ ├── comprehensive-guide.md -│ │ ├── examples.md -│ │ ├── flow-control.md -│ │ ├── functions.md -│ │ ├── google-sheets-api.md -│ │ ├── index.md -│ │ ├── intro-for-js-devs.md -│ │ ├── python-ds.md -│ │ └── snippets.md -│ ├── quick-reference -│ │ ├── Emmet.md -│ │ ├── all-emojis.md -│ │ ├── create-react-app.md -│ │ ├── git-bash.md -│ │ ├── git-tricks.md -│ │ ├── google-firebase.md -│ │ ├── heroku-error-codes.md -│ │ ├── index.md -│ │ ├── installation.md -│ │ ├── markdown-dropdowns.md -│ │ ├── minifiction.md -│ │ ├── new-repo-instructions.md -│ │ ├── psql-setup.md -│ │ ├── pull-request-rubric.md -│ │ ├── quick-links.md -│ │ ├── topRepos.md -│ │ ├── understanding-path.md -│ │ └── vscode-themes.md -│ ├── react -│ │ ├── ajax-n-apis.md -│ │ ├── cheatsheet.md -│ │ ├── createReactApp.md -│ │ ├── demo.md -│ │ ├── dont-use-index-as-keys.md -│ │ ├── index.md -│ │ ├── jsx.md -│ │ ├── react-docs.md -│ │ ├── react-in-depth.md -│ │ ├── react2.md -│ │ └── render-elements.md -│ ├── reference -│ │ ├── awesome-lists.md -│ │ ├── awesome-static.md -│ │ ├── bash-commands.md -│ │ ├── bookmarks.md -│ │ ├── embed-the-web.md -│ │ ├── github-search.md -│ │ ├── google-cloud.md -│ │ ├── how-2-reinstall-npm.md -│ │ ├── how-to-kill-a-process.md -│ │ ├── index.md -│ │ ├── installing-node.md -│ │ ├── intro-to-nodejs.md -│ │ ├── notes-template.md -│ │ ├── psql.md -│ │ ├── resources.md -│ │ ├── vscode.md -│ │ └── web-api's.md -│ ├── search.md -│ ├── sitemap.md -│ ├── tips -│ │ ├── array-methods.md -│ │ ├── index.md -│ │ └── insert-into-array.md -│ ├── tools -│ │ ├── Archive.md -│ │ ├── data-structures.md -│ │ ├── dev-utilities.md -│ │ ├── index.md -│ │ └── markdown-html.md -│ └── tutorials -│ ├── enviorment-setup.md -│ └── index.md -├── index.md -├── privacy-policy.md -├── readme.md -├── showcase.md -└── tree.md - -23 directories, 202 files - -``` - -## SITEMAP - -[**🌍⇒https://bgoonz-blog.netlify.app/🗺️**](https://bgoonz-blog.netlify.app/) - -[**🌍⇒blog🗺️**](https://bgoonz-blog.netlify.app/blog) - -[**🌍⇒docs🗺️**](https://bgoonz-blog.netlify.app/docs) - -[**🌍⇒readme🗺️**](https://bgoonz-blog.netlify.app/readme) - -[**🌍⇒review🗺️**](https://bgoonz-blog.netlify.app/review) - -[**🌍⇒showcase🗺️**](https://bgoonz-blog.netlify.app/showcase) - -[**🌍⇒blog/awesome-graphql🗺️**](https://bgoonz-blog.netlify.app/blog/awesome-graphql) - -[**🌍⇒blog/big-o-complexity🗺️**](https://bgoonz-blog.netlify.app/blog/big-o-complexity) - -[**🌍⇒blog/blog-archive🗺️**](https://bgoonz-blog.netlify.app/blog/blog-archive) - -[**🌍⇒blog/blogwcomments🗺️**](https://bgoonz-blog.netlify.app/blog/blogwcomments) - -[**🌍⇒blog/data-structures🗺️**](https://bgoonz-blog.netlify.app/blog/data-structures) - -[**🌍⇒blog/flow-control-in-python🗺️**](https://bgoonz-blog.netlify.app/blog/flow-control-in-python) - -[**🌍⇒blog/functions-in-python🗺️**](https://bgoonz-blog.netlify.app/blog/functions-in-python) - -[**🌍⇒blog/git-gateway🗺️**](https://bgoonz-blog.netlify.app/blog/git-gateway) - -[**🌍⇒blog/interview-questions-js🗺️**](https://bgoonz-blog.netlify.app/blog/interview-questions-js) - -[**🌍⇒blog/media-queries-explained🗺️**](https://bgoonz-blog.netlify.app/blog/media-queries-explained) - -[**🌍⇒blog/my-medium🗺️**](https://bgoonz-blog.netlify.app/blog/my-medium) - -[**🌍⇒blog/netlify-cms🗺️**](https://bgoonz-blog.netlify.app/blog/netlify-cms) - -[**🌍⇒blog/platform-docs🗺️**](https://bgoonz-blog.netlify.app/blog/platform-docs) - -[**🌍⇒blog/python-for-js-dev🗺️**](https://bgoonz-blog.netlify.app/blog/python-for-js-dev) - -[**🌍⇒blog/python-resources🗺️**](https://bgoonz-blog.netlify.app/blog/python-resources) - -[**🌍⇒blog/web-dev-trends🗺️**](https://bgoonz-blog.netlify.app/blog/web-dev-trends) - -[**🌍⇒blog/web-scraping🗺️**](https://bgoonz-blog.netlify.app/blog/web-scraping) - -[**🌍⇒docs/about🗺️**](https://bgoonz-blog.netlify.app/docs/about) - -[**🌍⇒docs/articles🗺️**](https://bgoonz-blog.netlify.app/docs/articles) - -[**🌍⇒docs/audio🗺️**](https://bgoonz-blog.netlify.app/docs/audio) - -[**🌍⇒docs/career🗺️**](https://bgoonz-blog.netlify.app/docs/career) - -[**🌍⇒docs/community🗺️**](https://bgoonz-blog.netlify.app/docs/community) - -[**🌍⇒docs/content🗺️**](https://bgoonz-blog.netlify.app/docs/content) - -[**🌍⇒docs/docs🗺️**](https://bgoonz-blog.netlify.app/docs/docs) - -[**🌍⇒docs/faq🗺️**](https://bgoonz-blog.netlify.app/docs/faq) - -[**🌍⇒docs/gallery🗺️**](https://bgoonz-blog.netlify.app/docs/gallery) - -[**🌍⇒docs/interact🗺️**](https://bgoonz-blog.netlify.app/docs/interact) - -[**🌍⇒docs/javascript🗺️**](https://bgoonz-blog.netlify.app/docs/javascript) - -[**🌍⇒docs/leetcode🗺️**](https://bgoonz-blog.netlify.app/docs/leetcode) - -[**🌍⇒docs/other-content🗺️**](https://bgoonz-blog.netlify.app/docs/other-content) - -[**🌍⇒docs/privacy-policy🗺️**](https://bgoonz-blog.netlify.app/docs/privacy-policy) - -[**🌍⇒docs/projects🗺️**](https://bgoonz-blog.netlify.app/docs/projects) - -[**🌍⇒docs/python🗺️**](https://bgoonz-blog.netlify.app/docs/python) - -[**🌍⇒docs/quick-reference🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference) - -[**🌍⇒docs/react🗺️**](https://bgoonz-blog.netlify.app/docs/react) - -[**🌍⇒docs/reference🗺️**](https://bgoonz-blog.netlify.app/docs/reference) - -[**🌍⇒docs/search🗺️**](https://bgoonz-blog.netlify.app/docs/search) - -[**🌍⇒docs/sitemap🗺️**](https://bgoonz-blog.netlify.app/docs/sitemap) - -[**🌍⇒docs/tools🗺️**](https://bgoonz-blog.netlify.app/docs/tools) - -[**🌍⇒docs/tutorials🗺️**](https://bgoonz-blog.netlify.app/docs/tutorials) - -[**🌍⇒docs/about/eng-portfolio🗺️**](https://bgoonz-blog.netlify.app/docs/about/eng-portfolio) - -[**🌍⇒docs/about/ideas-for-this-website🗺️**](https://bgoonz-blog.netlify.app/docs/about/ideas-for-this-website) - -[**🌍⇒docs/about/intrests🗺️**](https://bgoonz-blog.netlify.app/docs/about/intrests) - -[**🌍⇒docs/about/interview🗺️**](https://bgoonz-blog.netlify.app/docs/about/interview) - -[**🌍⇒docs/about/resume🗺️**](https://bgoonz-blog.netlify.app/docs/about/resume) - -[**🌍⇒docs/articles/basic-web-dev🗺️**](https://bgoonz-blog.netlify.app/docs/articles/basic-web-dev) - -[**🌍⇒docs/articles/buffers🗺️**](https://bgoonz-blog.netlify.app/docs/articles/buffers) - -[**🌍⇒docs/articles/dev-dep🗺️**](https://bgoonz-blog.netlify.app/docs/articles/dev-dep) - -[**🌍⇒docs/articles/event-loop🗺️**](https://bgoonz-blog.netlify.app/docs/articles/event-loop) - -[**🌍⇒docs/articles/fs-module🗺️**](https://bgoonz-blog.netlify.app/docs/articles/fs-module) - -[**🌍⇒docs/articles/how-the-web-works🗺️**](https://bgoonz-blog.netlify.app/docs/articles/how-the-web-works) - -[**🌍⇒docs/articles/http🗺️**](https://bgoonz-blog.netlify.app/docs/articles/http) - -[**🌍⇒docs/articles/install🗺️**](https://bgoonz-blog.netlify.app/docs/articles/install) - -[**🌍⇒docs/articles/intro🗺️**](https://bgoonz-blog.netlify.app/docs/articles/intro) - -[**🌍⇒docs/articles/media-queries-no-more🗺️**](https://bgoonz-blog.netlify.app/docs/articles/media-queries-no-more) - -[**🌍⇒docs/articles/module-exports🗺️**](https://bgoonz-blog.netlify.app/docs/articles/module-exports) - -[**🌍⇒docs/articles/nextjs🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nextjs) - -[**🌍⇒docs/articles/node-api-express🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-api-express) - -[**🌍⇒docs/articles/node-cli-args🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-cli-args) - -[**🌍⇒docs/articles/node-common-modules🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-common-modules) - -[**🌍⇒docs/articles/node-env-variables🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-env-variables) - -[**🌍⇒docs/articles/node-js-language🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-js-language) - -[**🌍⇒docs/articles/node-package-manager🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-package-manager) - -[**🌍⇒docs/articles/node-repl🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-repl) - -[**🌍⇒docs/articles/node-run-cli🗺️**](https://bgoonz-blog.netlify.app/docs/articles/node-run-cli) - -[**🌍⇒docs/articles/nodejs🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nodejs) - -[**🌍⇒docs/articles/nodevsbrowser🗺️**](https://bgoonz-blog.netlify.app/docs/articles/nodevsbrowser) - -[**🌍⇒docs/articles/npm🗺️**](https://bgoonz-blog.netlify.app/docs/articles/npm) - -[**🌍⇒docs/articles/npx🗺️**](https://bgoonz-blog.netlify.app/docs/articles/npx) - -[**🌍⇒docs/articles/os-module🗺️**](https://bgoonz-blog.netlify.app/docs/articles/os-module) - -[**🌍⇒docs/articles/package-lock🗺️**](https://bgoonz-blog.netlify.app/docs/articles/package-lock) - -[**🌍⇒docs/articles/reading-files🗺️**](https://bgoonz-blog.netlify.app/docs/articles/reading-files) - -[**🌍⇒docs/articles/semantic🗺️**](https://bgoonz-blog.netlify.app/docs/articles/semantic) - -[**🌍⇒docs/articles/semantic-html🗺️**](https://bgoonz-blog.netlify.app/docs/articles/semantic-html) - -[**🌍⇒docs/articles/the-uniform-resource-locator-(url)🗺️**]() - -[**🌍⇒docs/articles/understanding-firebase🗺️**](https://bgoonz-blog.netlify.app/docs/articles/understanding-firebase) - -[**🌍⇒docs/articles/v8🗺️**](https://bgoonz-blog.netlify.app/docs/articles/v8) - -[**🌍⇒docs/articles/web-standards-checklist🗺️**](https://bgoonz-blog.netlify.app/docs/articles/web-standards-checklist) - -[**🌍⇒docs/articles/webdev-tools🗺️**](https://bgoonz-blog.netlify.app/docs/articles/webdev-tools) - -[**🌍⇒docs/articles/write-2-json-with-python🗺️**](https://bgoonz-blog.netlify.app/docs/articles/write-2-json-with-python) - -[**🌍⇒docs/articles/writing-files🗺️**](https://bgoonz-blog.netlify.app/docs/articles/writing-files) - -[**🌍⇒docs/audio/audio🗺️**](https://bgoonz-blog.netlify.app/docs/audio/audio) - -[**🌍⇒docs/audio/audio-feature-extraction🗺️**](https://bgoonz-blog.netlify.app/docs/audio/audio-feature-extraction) - -[**🌍⇒docs/audio/dfft🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dfft) - -[**🌍⇒docs/audio/discrete-fft🗺️**](https://bgoonz-blog.netlify.app/docs/audio/discrete-fft) - -[**🌍⇒docs/audio/dtw-python-explained🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dtw-python-explained) - -[**🌍⇒docs/audio/dynamic-time-warping🗺️**](https://bgoonz-blog.netlify.app/docs/audio/dynamic-time-warping) - -[**🌍⇒docs/audio/web-audio-api🗺️**](https://bgoonz-blog.netlify.app/docs/audio/web-audio-api) - -[**🌍⇒docs/career/confidence🗺️**](https://bgoonz-blog.netlify.app/docs/career/confidence) - -[**🌍⇒docs/career/dev-interview🗺️**](https://bgoonz-blog.netlify.app/docs/career/dev-interview) - -[**🌍⇒docs/career/interview-dos-n-donts🗺️**](https://bgoonz-blog.netlify.app/docs/career/interview-dos-n-donts) - -[**🌍⇒docs/career/job-boards🗺️**](https://bgoonz-blog.netlify.app/docs/career/job-boards) - -[**🌍⇒docs/community/an-open-letter-2-future-developers🗺️**](https://bgoonz-blog.netlify.app/docs/community/an-open-letter-2-future-developers) - -[**🌍⇒docs/community/video-chat🗺️**](https://bgoonz-blog.netlify.app/docs/community/video-chat) - -[**🌍⇒docs/content/algo🗺️**](https://bgoonz-blog.netlify.app/docs/content/algo) - -[**🌍⇒docs/content/archive🗺️**](https://bgoonz-blog.netlify.app/docs/content/archive) - -[**🌍⇒docs/content/data-structures-algo🗺️**](https://bgoonz-blog.netlify.app/docs/content/data-structures-algo) - -[**🌍⇒docs/content/gatsby-Queries-Mutations🗺️**](https://bgoonz-blog.netlify.app/docs/content/gatsby-Queries-Mutations) - -[**🌍⇒docs/content/history-api🗺️**](https://bgoonz-blog.netlify.app/docs/content/history-api) - -[**🌍⇒docs/content/projects🗺️**](https://bgoonz-blog.netlify.app/docs/content/projects) - -[**🌍⇒docs/content/recent-projects🗺️**](https://bgoonz-blog.netlify.app/docs/content/recent-projects) - -[**🌍⇒docs/content/trouble-shooting🗺️**](https://bgoonz-blog.netlify.app/docs/content/trouble-shooting) - -[**🌍⇒docs/docs/appendix🗺️**](https://bgoonz-blog.netlify.app/docs/docs/appendix) - -[**🌍⇒docs/docs/bash🗺️**](https://bgoonz-blog.netlify.app/docs/docs/bash) - -[**🌍⇒docs/docs/content🗺️**](https://bgoonz-blog.netlify.app/docs/docs/content) - -[**🌍⇒docs/docs/css🗺️**](https://bgoonz-blog.netlify.app/docs/docs/css) - -[**🌍⇒docs/docs/data-structures-docs🗺️**](https://bgoonz-blog.netlify.app/docs/docs/data-structures-docs) - -[**🌍⇒docs/docs/git-reference🗺️**](https://bgoonz-blog.netlify.app/docs/docs/git-reference) - -[**🌍⇒docs/docs/git-repos🗺️**](https://bgoonz-blog.netlify.app/docs/docs/git-repos) - -[**🌍⇒docs/docs/html-spec🗺️**](https://bgoonz-blog.netlify.app/docs/docs/html-spec) - -[**🌍⇒docs/docs/markdown🗺️**](https://bgoonz-blog.netlify.app/docs/docs/markdown) - -[**🌍⇒docs/docs/no-whiteboarding🗺️**](https://bgoonz-blog.netlify.app/docs/docs/no-whiteboarding) - -[**🌍⇒docs/docs/node-docs-complete🗺️**](https://bgoonz-blog.netlify.app/docs/docs/node-docs-complete) - -[**🌍⇒docs/docs/node-docs-full🗺️**](https://bgoonz-blog.netlify.app/docs/docs/node-docs-full) - -[**🌍⇒docs/docs/regex-in-js🗺️**](https://bgoonz-blog.netlify.app/docs/docs/regex-in-js) - -[**🌍⇒docs/docs/sitemap🗺️**](https://bgoonz-blog.netlify.app/docs/docs/sitemap) - -[**🌍⇒docs/faq/contact🗺️**](https://bgoonz-blog.netlify.app/docs/faq/contact) - -[**🌍⇒docs/faq/plug-ins🗺️**](https://bgoonz-blog.netlify.app/docs/faq/plug-ins) - -[**🌍⇒docs/interact/callstack-visual🗺️**](https://bgoonz-blog.netlify.app/docs/interact/callstack-visual) - -[**🌍⇒docs/interact/clock🗺️**](https://bgoonz-blog.netlify.app/docs/interact/clock) - -[**🌍⇒docs/interact/jupyter-notebooks🗺️**](https://bgoonz-blog.netlify.app/docs/interact/jupyter-notebooks) - -[**🌍⇒docs/interact/other-sites🗺️**](https://bgoonz-blog.netlify.app/docs/interact/other-sites) - -[**🌍⇒docs/interact/video-chat🗺️**](https://bgoonz-blog.netlify.app/docs/interact/video-chat) - -[**🌍⇒docs/javascript/arrow-functions🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/arrow-functions) - -[**🌍⇒docs/javascript/await-keyword🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/await-keyword) - -[**🌍⇒docs/javascript/bigo🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/bigo) - -[**🌍⇒docs/javascript/clean-code🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/clean-code) - -[**🌍⇒docs/javascript/constructor-functions🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/constructor-functions) - -[**🌍⇒docs/javascript/promises🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/promises) - -[**🌍⇒docs/javascript/review🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/review) - -[**🌍⇒docs/javascript/this-is-about-this🗺️**](https://bgoonz-blog.netlify.app/docs/javascript/this-is-about-this) - -[**🌍⇒docs/projects/medium-links🗺️**](https://bgoonz-blog.netlify.app/docs/projects/medium-links) - -[**🌍⇒docs/projects/my-websites🗺️**](https://bgoonz-blog.netlify.app/docs/projects/my-websites) - -[**🌍⇒docs/python/at-length🗺️**](https://bgoonz-blog.netlify.app/docs/python/at-length) - -[**🌍⇒docs/python/basics🗺️**](https://bgoonz-blog.netlify.app/docs/python/basics) - -[**🌍⇒docs/python/cheat-sheet🗺️**](https://bgoonz-blog.netlify.app/docs/python/cheat-sheet) - -[**🌍⇒docs/python/comprehensive-guide🗺️**](https://bgoonz-blog.netlify.app/docs/python/comprehensive-guide) - -[**🌍⇒docs/python/examples🗺️**](https://bgoonz-blog.netlify.app/docs/python/examples) - -[**🌍⇒docs/python/flow-control🗺️**](https://bgoonz-blog.netlify.app/docs/python/flow-control) - -[**🌍⇒docs/python/functions🗺️**](https://bgoonz-blog.netlify.app/docs/python/functions) - -[**🌍⇒docs/python/google-sheets-api🗺️**](https://bgoonz-blog.netlify.app/docs/python/google-sheets-api) - -[**🌍⇒docs/python/intro-for-js-devs🗺️**](https://bgoonz-blog.netlify.app/docs/python/intro-for-js-devs) - -[**🌍⇒docs/python/python-ds🗺️**](https://bgoonz-blog.netlify.app/docs/python/python-ds) - -[**🌍⇒docs/python/snippets🗺️**](https://bgoonz-blog.netlify.app/docs/python/snippets) - -[**🌍⇒docs/quick-reference/Emmet🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/Emmet) - -[**🌍⇒docs/quick-reference/all-emojis🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/all-emojis) - -[**🌍⇒docs/quick-reference/create-react-app🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/create-react-app) - -[**🌍⇒docs/quick-reference/git-bash🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/git-bash) - -[**🌍⇒docs/quick-reference/git-tricks🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/git-tricks) - -[**🌍⇒docs/quick-reference/google-firebase🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/google-firebase) - -[**🌍⇒docs/quick-reference/heroku-error-codes🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/heroku-error-codes) - -[**🌍⇒docs/quick-reference/installation🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/installation) - -[**🌍⇒docs/quick-reference/markdown-dropdowns🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/markdown-dropdowns) - -[**🌍⇒docs/quick-reference/minifiction🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/minifiction) - -[**🌍⇒docs/quick-reference/new-repo-instructions🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/new-repo-instructions) - -[**🌍⇒docs/quick-reference/psql-setup🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/psql-setup) - -[**🌍⇒docs/quick-reference/pull-request-rubric🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/pull-request-rubric) - -[**🌍⇒docs/quick-reference/quick-links🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/quick-links) - -[**🌍⇒docs/quick-reference/topRepos🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/topRepos) - -[**🌍⇒docs/quick-reference/understanding-path🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/understanding-path) - -[**🌍⇒docs/quick-reference/vscode-themes🗺️**](https://bgoonz-blog.netlify.app/docs/quick-reference/vscode-themes) - -[**🌍⇒docs/react/cheatsheet🗺️**](https://bgoonz-blog.netlify.app/docs/react/cheatsheet) - -[**🌍⇒docs/react/createReactApp🗺️**](https://bgoonz-blog.netlify.app/docs/react/createReactApp) - -[**🌍⇒docs/react/demo🗺️**](https://bgoonz-blog.netlify.app/docs/react/demo) - -[**🌍⇒docs/react/jsx🗺️**](https://bgoonz-blog.netlify.app/docs/react/jsx) - -[**🌍⇒docs/react/react-docs🗺️**](https://bgoonz-blog.netlify.app/docs/react/react-docs) - -[**🌍⇒docs/react/react-in-depth🗺️**](https://bgoonz-blog.netlify.app/docs/react/react-in-depth) - -[**🌍⇒docs/react/react2🗺️**](https://bgoonz-blog.netlify.app/docs/react/react2) - -[**🌍⇒docs/react/render-elements🗺️**](https://bgoonz-blog.netlify.app/docs/react/render-elements) - -[**🌍⇒docs/reference/awesome-lists🗺️**](https://bgoonz-blog.netlify.app/docs/reference/awesome-lists) - -[**🌍⇒docs/reference/awesome-static🗺️**](https://bgoonz-blog.netlify.app/docs/reference/awesome-static) - -[**🌍⇒docs/reference/bookmarks🗺️**](https://bgoonz-blog.netlify.app/docs/reference/bookmarks) - -[**🌍⇒docs/reference/embed-the-web🗺️**](https://bgoonz-blog.netlify.app/docs/reference/embed-the-web) - -[**🌍⇒docs/reference/github-search🗺️**](https://bgoonz-blog.netlify.app/docs/reference/github-search) - -[**🌍⇒docs/reference/how-2-reinstall-npm🗺️**](https://bgoonz-blog.netlify.app/docs/reference/how-2-reinstall-npm) - -[**🌍⇒docs/reference/how-to-kill-a-process🗺️**](https://bgoonz-blog.netlify.app/docs/reference/how-to-kill-a-process) - -[**🌍⇒docs/reference/installing-node🗺️**](https://bgoonz-blog.netlify.app/docs/reference/installing-node) - -[**🌍⇒docs/reference/intro-to-nodejs🗺️**](https://bgoonz-blog.netlify.app/docs/reference/intro-to-nodejs) - -[**🌍⇒docs/reference/notes-template🗺️**](https://bgoonz-blog.netlify.app/docs/reference/notes-template) - -[**🌍⇒docs/reference/psql🗺️**](https://bgoonz-blog.netlify.app/docs/reference/psql) - -[**🌍⇒docs/reference/resources🗺️**](https://bgoonz-blog.netlify.app/docs/reference/resources) - -[**🌍⇒docs/reference/vscode🗺️**](https://bgoonz-blog.netlify.app/docs/reference/vscode) - -[**🌍⇒docs/reference/web-api's🗺️**](https://bgoonz-blog.netlify.app/docs/reference/web-api's) - -[**🌍⇒docs/tools/data-structures🗺️**](https://bgoonz-blog.netlify.app/docs/tools/data-structures) - -[**🌍⇒docs/tools/dev-utilities🗺️**](https://bgoonz-blog.netlify.app/docs/tools/dev-utilities) - -[**🌍⇒docs/tools/google-cloud🗺️**](https://bgoonz-blog.netlify.app/docs/tools/google-cloud) - -[**🌍⇒docs/tools/markdown-html🗺️**](https://bgoonz-blog.netlify.app/docs/tools/markdown-html) - -[**🌍⇒docs/tools/more-tools🗺️**](https://bgoonz-blog.netlify.app/docs/tools/more-tools) - -[**🌍⇒docs/tutorials/google-lighthouse-cli🗺️**](https://bgoonz-blog.netlify.app/docs/tutorials/google-lighthouse-cli) - -
- ---- - ---- - ---- - -
- ↞↠ Getting Started With GatsbyJS ↞↠ -# - ---- - -## 🚀 Quick start - -1. **Create a Gatsby site.** - - Use the Gatsby CLI to create a new site, specifying the default starter. - -```bashell - # create a new Gatsby site using the default starter - gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default -``` - -1. **Start developing.** - - Navigate into your new site's directory and start it up. - -```bashell - cd my-default-starter/ - gatsby develop -``` - -1. **Open the source code and start editing!** - - Your site is now running at `http://localhost:8000`! - - *Note: You'll also see a second link:*`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.com/tutorial/part-five/#introducing-graphiql)._ - - Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time! - -## 🧐 What's inside? - -A quick look at the top-level files and directories you'll see in a Gatsby project. - - . - ├── node_modules - ├── src - ├── .gitignore - ├── .prettierrc - ├── gatsby-browser.js - ├── gatsby-config.js - ├── gatsby-node.js - ├── gatsby-ssr.js - ├── LICENSE - ├── package-lock.json - ├── package.json - └── README.md - -1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed. - -2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for "source code". - -3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for. - -4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent. - -5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.com/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser. - -6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the [config docs](https://www.gatsbyjs.com/docs/gatsby-config/) for more detail). - -7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.com/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. - -8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering. - -9. **`LICENSE`**: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. - -10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won't change this file directly).** - -11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. - -12. **`README.md`**: A text file containing useful reference information about your project. - -## 🎓 Learning Gatsby - -Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.com/). Here are some places to start: - -- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby**](https://www.gatsbyjs.com/tutorial/).\*\* It starts with zero assumptions about your level of ability and walks through every step of the process. -- -- **To dive straight into code samples, head [to our documentation**](https://www.gatsbyjs.com/docs/).\*\* In particular, check out the *Guides*, *API Reference*, and *Advanced Tutorials* sections in the sidebar. - -## 💫 Deploy - -[![Deploy to Netlify**](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/BGOONZ_BLOG_2.0.git) - -[![Deploy with Vercel**](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/BGOONZ_BLOG_2.0.git) - ---- -### Gatsby With Netlify CMS - -This tutorial will use [gatsby-personal-starter-blog](https://github.com/thomaswang/gatsby-personal-starter-blog), a Gatsby starter based on the official [gatsby-starter-blog](/starters/gatsbyjs/gatsby-starter-blog/). The differences are that `gatsby-personal-starter-blog` is configured to run the blog on a subdirectory, `/blog`, and comes pre-installed with [Netlify CMS](https://www.netlifycms.org/) for content editing. It also adds VS Code highlighting for code blocks. - -## Prerequisites - -- A GitHub account -- The [Gatsby CLI](/docs/reference/gatsby-cli/) installed - -## Set up a Netlify CMS-managed Gatsby site in 5 steps - -### Step 1 - -Open your Terminal and run the following command from the Gatsby CLI to create a new Gatsby site using [gatsby-personal-starter-blog](https://github.com/thomaswang/gatsby-personal-starter-blog). - -```shell -gatsby new [your-project-name] https://github.com/thomaswangio/gatsby-personal-starter-blog -``` - -### Step 2 - -Once the Gatsby site is finished installing all the packages and dependencies, you can now go into the directory and run the site locally. - -```shell -cd [your-project-name] -gatsby develop -``` - -Now you can go to `http://localhost:8000` to see your new site, but what's extra cool is that Netlify CMS is pre-installed and you can access it at `http://localhost:8000/admin` - -A CMS, or content management system, is useful because you can add content like blog posts from a dashboard on your site, instead of having to add posts manually with Markdown. However, you'll likely want to be able to access the CMS from a deployed website, not just locally. For that, you'll need to deploy to Netlify through GitHub, set up continuous deployment, and do a few configurations. You'll go over this in [Step-5](#step-5). - -### Step 3 - -Open the project in your code editor and open `static/admin/config.yml`. Replace `your-username/your-repo-name` with your GitHub username and project name. This step is important for managing and deploying the Netlify CMS interface. - -```diff -backend: -- name: test-repo - -+ name: github -+ repo: your-username/your-repo-name -``` - -#### Customizing your site - -Head into `gatsby-config.js` and you can edit your siteMetadata, add a Google Analytics tracking ID, and your app icon/favicon. Test out the edits for the deployed build by quitting the development server and running `gatsby build && gatsby serve`. - -You'll likely also want to edit the `README.md` and `package.json` files to include your own project details. - -### Step 4 - -Open [github.com](https://github.com) and create a new repository, with the same name as your project. Push your new Gatsby site's code to GitHub using the following Terminal commands: - -```shell -git init -git add . -git commit -m "initial commit" -git remote add origin https://github.com/[your-username]/[your-repo-name].git -git push -u origin master -``` - -Then, open [app.netlify.com](https://app.netlify.com) and add a "New site from Git". Choose your newly created repo and click on "Deploy site" with the default deployment settings. - -> *Note: if you don't see the correct repo listed, you may need to install or reconfigure the Netlify app on GitHub.* - -![Netlify Dashboard for Creating a new site](netlify-dashboard.png) - -### Step 5 - -To make sure that Netlify CMS has access to your GitHub repo, you need to set up an OAuth application on GitHub. The instructions for that are here: [Netlify's Using an Authorization Provider](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider). - -For the "Homepage URL" – you can use your Netlify subdomain, `[name-of-your-site].netlify.com`, or you can use a custom domain. To customize the subdomain, look for the "Edit site name" field under "Domain Management" for your project on the [Netlify app](https://app.netlify.com). To connect your Netlify site to your custom domain instead, see [Netlify’s instructions on custom domains](https://www.netlify.com/docs/custom-domains/). - -Once you've configured an authentication provider then you'll be able to use Netlify CMS at your deployed site to add new posts. - -![Netlify and GitHub Authorization](https://cdn.netlify.com/67edd5b656c432888d736cd40125cb61376905bb/c1cba/img/docs/github-oauth-config.png) - -Copy the credentials of your new app listed on [GitHub OAuth Apps](https://github.com/settings/developers) and install a new auth provider on Netlify using them. - -![Setting up access control](netlify-install-oauth-provider.png) - -#### Benefits of Netlify CMS, GitHub, and Netlify Workflow - -Congrats! Now that Netlify CMS is successfully configured to your project, every time you add a new post, the content will be stored in your repository and versioned on GitHub because Netlify CMS is Git-based. Also, thanks to [Netlify's Continuous Deployment](https://www.netlify.com/docs/continuous-deployment/), a new version will be deployed every time you add or edit a post. - -You can learn more about Netlify CMS and how to configure it further in the [Netlify CMS documentation](https://www.netlifycms.org/docs/intro/) ---- - ---- - -## Gatsby Project Structure | Gatsby - -> ## Excerpt -> -> Inside a Gatsby project, you may see some or all of the following folders and files: Folders /.cache Automatically generated. This folder… - ---- - -Inside a Gatsby project, you may see some or all of the following folders and files: - -``` -/| --- /.cache -|-- /plugins -|-- /public -|-- /src -|-- /api -|-- /pages -|-- /templates -|-- html.js -|-- /static -|-- gatsby-config.js -|-- gatsby-node.js -|-- gatsby-ssr.js -|-- gatsby-browser.js -``` - -[Folders](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#folders) - -- **`/.cache`** *Automatically generated.* This folder is an internal cache created automatically by Gatsby. The files inside this folder are not meant for modification. Should be added to the `.gitignore` file if not added already. -- **`/plugins`** This folder hosts any project-specific ("local") plugins that aren't published as an `npm` package. Check out the [plugin docs](https://www.gatsbyjs.com/docs/plugins/) for more detail. -- **`/public`** *Automatically generated.* The output of the build process will be exposed inside this folder. Should be added to the `.gitignore` file if not added already. -- **`/src`** This directory will contain all of the code related to what you will see on the frontend of your site (what you see in the browser), like your site header, or a page template. "src" is a convention for "source code". - - - **`/api`** JavaScript and TypeScript files under `src/api` become functions automatically with paths based on their file name. Check out the [functions guide](https://www.gatsbyjs.com/docs/reference/functions/) for more detail. - - **`/pages`** Components under `src/pages` become pages automatically with paths based on their file name. Check out the [pages recipes](https://www.gatsbyjs.com/docs/recipes/pages-layouts) for more detail. - - **`/templates`** Contains templates for programmatically creating pages. Check out the [templates docs](https://www.gatsbyjs.com/docs/conceptual/building-with-components/#page-template-components) for more detail. - - **`html.js`** For custom configuration of default `.cache/default_html.js`. Check out the [custom HTML docs](https://www.gatsbyjs.com/docs/custom-html/) for more detail. - -- **`/static`** If you put a file into the static folder, it will not be processed by webpack. Instead it will be copied into the public folder untouched. Check out the [assets docs](https://www.gatsbyjs.com/docs/how-to/images-and-media/static-folder/#adding-assets-outside-of-the-module-system) for more detail. - -[Files](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#files) - -- **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/) (if any). These allow customization/extension of default Gatsby settings affecting the browser. -- **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. Check out the [config docs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-config/) for more detail. -- **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby node APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. -- **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/) (if any). These allow customization of default Gatsby settings affecting server-side rendering. - -[Misc](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#miscellaneous) -[Misc](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#miscellaneous) - -The file/folder structure described above reflects Gatsby-specific files and folders. Since Gatsby sites are also React apps, it's common to use standard React code organization patterns such as folders like `/components` and `/utils` inside `/src`. The [React docs](https://reactjs.org/docs/faq-structure.html) have more information on a typical React app folder structure. - ---- - - - - - -#### Layout Components | Gatsby - -## Excerpt - -> In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from… - ---- - -In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from unmounting. - -[Gatsby's approach to layouts](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#gatsbys-approach-to-layouts) - -Gatsby does not, by default, automatically apply layouts to pages (there are, however, ways to do so which will be covered in a later section). Instead, Gatsby follows React's compositional model of importing and using components. This makes it possible to create multiple levels of layouts, e.g. a global header and footer, and then on some pages, a sidebar menu. It also makes it possible to pass data between layout and page components. - -[What are layout components?](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#what-are-layout-components) - -Layout components are for sections of your site that you want to share across multiple pages. For example, Gatsby sites will commonly have a layout component with a shared header and footer. Other common things to add to layouts are a sidebar and/or navigation menu. On this page for example, the header at the top is part of gatsbyjs.com's layout component. - -[How to create layout components](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-create-layout-components) - -It is recommended to create your layout components alongside the rest of your components (e.g. into `src/components/`). - -Here is an example of a very basic layout component at `src/components/layout.js`: - -``` -import React from "react"export default function Layout({ children }) { return (
{children}
)} -``` - -[](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-import-and-add-layout-components-to-pages)How to import and add layout components to pages - -If you want to apply a layout to a page, you will need to include the `Layout` component and wrap your page in it. For example, here is how you would apply your layout to the front page: - -``` -import React from "react"import Layout from "../components/layout"export default function Home() { return (

I'm in a layout!

);} -``` - -Repeat for every page and template that needs this layout. - -[How to prevent layout components from unmounting](https://www.gatsbyjs.com/docs/how-to/routing/layout-components/#how-to-prevent-layout-components-from-unmounting) - -As mentioned earlier, Gatsby does not, by default, automatically wrap pages in a layout component. The "top level" component is the page itself. As a result, when the "top level" component changes between pages, React will re-render all children. This means that shared components like navigations will unmount and remount. This will break CSS transitions or React state within those shared components. - -If you need to set a wrapper component around page components that won't get unmounted on page changes, use the **`wrapPageElement`** [browser API](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/#wrapPageElement) and the [SSR equivalent](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/#wrapPageElement). - -Alternatively, you can prevent your layout component from unmounting by using [gatsby-plugin-layout](https://www.gatsbyjs.com/plugins/gatsby-plugin-layout/), which implements the `wrapPageElement` APIs for you. - -## Adding Markdown Pages | Gatsby - -> ## Excerpt -> -> Gatsby can use Markdown files to create pages in your site. -> You add plugins to read and understand folders with Markdown files and from them… - ---- - -Gatsby can use Markdown files to create pages in your site. You add plugins to read and understand folders with Markdown files and from them create pages automatically. - -Here are the steps Gatsby follows for making this happen. - -1. Read files into Gatsby from the filesystem -2. Transform Markdown to HTML and [frontmatter](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#frontmatter-for-metadata-in-markdown-files) to data -3. Add a Markdown file -4. Create a Collection Route component for the Markdown files - -[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#read-files-into-gatsby-from-the-filesystem)Read files into Gatsby from the filesystem - -Use the plugin [`gatsby-source-filesystem`](https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#gatsby-source-filesystem) to read files. - -[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#install)Install - -`npm install gatsby-source-filesystem` - -[Add Plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#add-plugin)Add plugin - -Open `gatsby-config.js` to add the `gatsby-source-filesystem` plugin. The `path` option is how you set the directory to search for files. - -``` -module.exports = { siteMetadata: { - title: "My Gatsby Site", }, -plugins: [ { - resolve: `gatsby-source-filesystem`, -options: { - name: `markdown-pages`, - path: `${__dirname}/src/markdown-pages`, -}, - }, -],} -``` - -Completing the above step means that you've "sourced" the Markdown files from the filesystem. You can now "transform" the Markdown to HTML and the YAML frontmatter to JSON. - -[Transform Markdown to HTML and frontmatter to data using `gatsby-transformer-remark`](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#transform-markdown-to-html-and-frontmatter-to-data-using-gatsby-transformer-remark) - -You'll use the plugin [`gatsby-transformer-remark`](https://www.gatsbyjs.com/plugins/gatsby-transformer-remark/) to recognize files which are Markdown and read their content. The plugin will convert the frontmatter metadata part of your Markdown files as `frontmatter` and the content part as HTML. - -[Install transformer plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#install-transformer-plugin) - -`npm install gatsby-transformer-remark` - -[Configure plugin](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#configure-plugin) - -Add this to `gatsby-config.js` after the previously added `gatsby-source-filesystem`. - -``` -module.exports = { siteMetadata: { - title: "My Gatsby Site", }, -plugins: [ { - resolve: `gatsby-source-filesystem`, -options: { - name: `markdown-pages`, - path: `${__dirname}/src/markdown-pages`, -}, - }, - `gatsby-transformer-remark`, ], -} -``` - -[Add a Markdown file](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#add-a-markdown-file) - -Create a folder in the `/src` directory of your Gatsby application called `markdown-pages`. Now create a Markdown file inside it with the name `post-1.md`. - -[Frontmatter for metadata in Markdown files](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#frontmatter-for-metadata-in-markdown-files) - -When you create a Markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called "frontmatter" and is denoted by the triple dashes at the start and end of the block. This block will be parsed by `gatsby-transformer-remark` as YAML. You can then query the data through the GraphQL API from your React components. - -src/markdown-pages/post-1.md - -``` ----slug: "/blog/my-first-post"date: "2019-05-04"title: "My first blog post"--- -``` - -What is important in this step is the key pair `slug`. The value that is assigned to the key `slug` is used in order to navigate to your post. - -[](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#create-a-collection-route-for-the-markdown-files)Create a Collection Route for the Markdown files - -Create `src/pages/{MarkdownRemark.frontmatter__slug}.js` and add the following code: - -src/pages/{MarkdownRemark.frontmatter\_\_slug}.js - -``` -import React from "react" -import { graphql } from "gatsby"export default function Template({ data, }) { const { markdownRemark } = data const { frontmatter, html } = markdownRemark return (

{frontmatter.title}

{frontmatter.date}

)}export const pageQuery = graphql` query($id: String!) { markdownRemark(id: { - eq: $id }) { html frontmatter { date(formatString: "MMMM DD, YYYY") slug title } } }` -``` - -Two things are important in the file above: - -1. A GraphQL query is made in the second half of the file to get the Markdown data. Gatsby has automagically given you all the Markdown metadata and HTML in this query's result. - - **Note: To learn more about GraphQL, consider this [excellent resource](https://www.howtographql.com/)** - -2. The result of the query is injected by Gatsby into the component as the `data` prop. `props.data.markdownRemark` is the property that has all the details of the Markdown file. - -Next you could create a page component at `src/pages/blog/index.js` to serve as a listing page for all your blog posts. - -This should get you started on some basic Markdown functionality in your Gatsby site. You can further customize the frontmatter and the component file to get desired effects! - -For more information, have a look in the working example `using-markdown-pages`. You can find it in the [Gatsby examples section](https://github.com/gatsbyjs/gatsby/tree/master/examples). - -[Other tutorials](https://www.gatsbyjs.com/docs/how-to/routing/adding-markdown-pages/#other-tutorials) - -
- ---- - -### Overview - -The **`_.get()` method** in Lodash retrieves the object’s value at a specific path. - -If the value is not present at the object’s specific path, it will be resolved as `undefined`. This method will return the default value if specified in such a case. - -### Syntax - -```js -_.get(object, path, defaultValue) -``` - -### Parameters - -This method accepts the following parameters: - -- **`object`**: The object in which the given path will be queried. -- **`path`**: The path used to retrieve the value from the object. -- **`defaultValue`**: The default value that will be returned for resolved values that are undefined. - -### Return value - -This method will return the value at the specified path if found. Otherwise, it will return the default value if specified. - -### Example - -Let’s look at an example of the `_.get()` method in the code snippet below: - -### Explanation - -In the HTML tab: - -- **Line 5**: We import the `lodash` script. - -In the JavaScript tab: - -- **Lines 2 to 15**: We create an object to perform a query. - -- **Line 18**: We define a variable `collegeYopPath` to get the value. - -- **Lines 19**: We use the `_.get()` method and pass the `object`, `collegeYopPath`, and a default value as parameters. - -- **Line 22**: We define a variable `falsyPath` to get the value. - -- **Lines 23**: We use the `_.get()` method and pass the `object`, `falsyPath` and a `default value` as parameters. - -### Output - -- The `_.get()` method at **line 19** contains a valid path, and therefore the expression is resolved, and `2021` is printed on the console. -- The `_.get()` method at **Line 23** contains an invalid path, and therefore the expression is resolved as `undefined`. - -## Technoloy - -![tech-stack](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/madewith.png?raw=true) - ---- - -## SOURCECODE - ---- - - - -### Overview - -The **`_.get()` method** in Lodash retrieves the object’s value at a specific path. - -If the value is not present at the object’s specific path, it will be resolved as `undefined`. This method will return the default value if specified in such a case. - -### Syntax - -```js -_.get(object, path, defaultValue) -``` - -### Parameters - -This method accepts the following parameters: - -- **`object`**: The object in which the given path will be queried. -- **`path`**: The path used to retrieve the value from the object. -- **`defaultValue`**: The default value that will be returned for resolved values that are undefined. - -### Return value - -This method will return the value at the specified path if found. Otherwise, it will return the default value if specified. - -### Example - -Let’s look at an example of the `_.get()` method in the code snippet below: - -### Explanation - -In the HTML tab: - -- **Line 5**: We import the `lodash` script. - -In the JavaScript tab: - -- **Lines 2 to 15**: We create an object to perform a query. - -- **Line 18**: We define a variable `collegeYopPath` to get the value. - -- **Lines 19**: We use the `_.get()` method and pass the `object`, `collegeYopPath`, and a default value as parameters. - -- **Line 22**: We define a variable `falsyPath` to get the value. - -- **Lines 23**: We use the `_.get()` method and pass the `object`, `falsyPath` and a `default value` as parameters. - -### Output - -- The `_.get()` method at **line 19** contains a valid path, and therefore the expression is resolved, and `2021` is printed on the console. -- The `_.get()` method at **Line 23** contains an invalid path, and therefore the expression is resolved as `undefined`. - - ---- - -``` - -bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f -. -├── ./components -│ ├── ./components/ActionLink.js -│ ├── ./components/CtaButtons.js -│ ├── ./components/DocsMenu.js -│ ├── ./components/DocsSubmenu.js -│ ├── ./components/Footer.js -│ ├── ./components/Header.js -│ ├── ./components/Icon.js -│ ├── ./components/Layout.js -│ ├── ./components/SectionContent.js -│ ├── ./components/SectionCta.js -│ ├── ./components/SectionDocs.js -│ ├── ./components/SectionGrid.js -│ ├── ./components/SectionHero.js -│ ├── ./components/Submenu.js -│ ├── ./components/global.css -│ └── ./components/index.js -├── ./data -│ └── ./data/doc_sections.yml -├── ./hooks -│ └── ./hooks/useScript.js -├── ./html.js -├── ./pages -│ ├── ./pages/blog -│ │ ├── ./pages/blog/blog-archive.md -│ │ ├── ./pages/blog/blogwcomments.md -│ │ ├── ./pages/blog/data-structures.md -│ │ ├── ./pages/blog/index.md -│ │ ├── ./pages/blog/my-medium.md -│ │ ├── ./pages/blog/platform-docs.md -│ │ ├── ./pages/blog/python-for-js-dev.md -│ │ ├── ./pages/blog/python-resources.md -│ │ └── ./pages/blog/web-scraping.md -│ ├── ./pages/docs -│ │ ├── ./pages/docs/about -│ │ │ ├── ./pages/docs/about/index.md -│ │ │ ├── ./pages/docs/about/me.md -│ │ │ ├── ./pages/docs/about/node -│ │ │ │ ├── ./pages/docs/about/node/install.md -│ │ │ │ ├── ./pages/docs/about/node/intro.md -│ │ │ │ ├── ./pages/docs/about/node/nodejs.md -│ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md -│ │ │ │ ├── ./pages/docs/about/node/reading-files.md -│ │ │ │ └── ./pages/docs/about/node/writing-files.md -│ │ │ ├── ./pages/docs/about/npm.md -│ │ │ └── ./pages/docs/about/resume.md -│ │ ├── ./pages/docs/articles -│ │ │ ├── ./pages/docs/articles/algo.md -│ │ │ ├── ./pages/docs/articles/article-compilation.md -│ │ │ ├── ./pages/docs/articles/basic-web-dev.md -│ │ │ ├── ./pages/docs/articles/gists.md -│ │ │ ├── ./pages/docs/articles/index.md -│ │ │ ├── ./pages/docs/articles/install.md -│ │ │ ├── ./pages/docs/articles/intro.md -│ │ │ ├── ./pages/docs/articles/python.md -│ │ │ ├── ./pages/docs/articles/reading-files.md -│ │ │ ├── ./pages/docs/articles/resources.md -│ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md -│ │ │ └── ./pages/docs/articles/writing-files.md -│ │ ├── ./pages/docs/docs -│ │ │ └── ./pages/docs/docs/tools -│ │ │ └── ./pages/docs/docs/tools/file-types.md -│ │ ├── ./pages/docs/faq -│ │ │ ├── ./pages/docs/faq/contact.md -│ │ │ └── ./pages/docs/faq/index.md -│ │ ├── ./pages/docs/gists.md -│ │ ├── ./pages/docs/index.md -│ │ ├── ./pages/docs/interact -│ │ │ ├── ./pages/docs/interact/clock.md -│ │ │ ├── ./pages/docs/interact/index.md -│ │ │ └── ./pages/docs/interact/jupyter-notebooks.md -│ │ ├── ./pages/docs/links -│ │ │ ├── ./pages/docs/links/index.md -│ │ │ ├── ./pages/docs/links/medium-links.md -│ │ │ ├── ./pages/docs/links/my-websites.md -│ │ │ └── ./pages/docs/links/social.md -│ │ ├── ./pages/docs/quick-reference -│ │ │ ├── ./pages/docs/quick-reference/Emmet.md -│ │ │ ├── ./pages/docs/quick-reference/docs.md -│ │ │ ├── ./pages/docs/quick-reference/index.md -│ │ │ ├── ./pages/docs/quick-reference/installation.md -│ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md -│ │ ├── ./pages/docs/react -│ │ │ ├── ./pages/docs/react/createReactApp.md -│ │ │ ├── ./pages/docs/react/index.md -│ │ │ └── ./pages/docs/react/react2.md -│ │ ├── ./pages/docs/react-in-depth.md -│ │ ├── ./pages/docs/sitemap.md -│ │ └── ./pages/docs/tools -│ │ ├── ./pages/docs/tools/index.md -│ │ ├── ./pages/docs/tools/notes-template.md -│ │ ├── ./pages/docs/tools/plug-ins.md -│ │ └── ./pages/docs/tools/vscode.md -│ ├── ./pages/index.md -│ ├── ./pages/notes-template.md -│ ├── ./pages/review.md -│ └── ./pages/showcase.md -├── ./sass -│ ├── ./sass/imports -│ │ ├── ./sass/imports/_animations.scss -│ │ ├── ./sass/imports/_buttons.scss -│ │ ├── ./sass/imports/_docs.scss -│ │ ├── ./sass/imports/_footer.scss -│ │ ├── ./sass/imports/_forms.scss -│ │ ├── ./sass/imports/_functions.scss -│ │ ├── ./sass/imports/_general.scss -│ │ ├── ./sass/imports/_header.scss -│ │ ├── ./sass/imports/_helpers.scss -│ │ ├── ./sass/imports/_icons.scss -│ │ ├── ./sass/imports/_palettes.scss -│ │ ├── ./sass/imports/_posts.scss -│ │ ├── ./sass/imports/_prism.scss -│ │ ├── ./sass/imports/_reset.scss -│ │ ├── ./sass/imports/_sections.scss -│ │ ├── ./sass/imports/_structure.scss -│ │ ├── ./sass/imports/_tables.scss -│ │ └── ./sass/imports/_variables.scss -│ └── ./sass/main.scss -├── ./templates -│ ├── ./templates/advanced.js -│ ├── ./templates/blog.js -│ ├── ./templates/docs.js -│ ├── ./templates/page.js -│ └── ./templates/post.js -└── ./utils - ├── ./utils/attribute.js - ├── ./utils/classNames.js - ├── ./utils/cycler.js - ├── ./utils/getData.js - ├── ./utils/getPage.js - ├── ./utils/getPageByFilePath.js - ├── ./utils/getPages.js - ├── ./utils/htmlToReact.js - ├── ./utils/index.js - ├── ./utils/link.js - ├── ./utils/markdownify.js - ├── ./utils/pathJoin.js - ├── ./utils/toStyleObj.js - ├── ./utils/toUrl.js - └── ./utils/withPrefix.js - -21 directories, 119 files -bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ -``` - ---- - -## Source Code - -
- Folder Structure (src) - -``` -. -├── Combined_____-_____Doc.md -├── components -│ ├── ActionLink.js -│ ├── CtaButtons.js -│ ├── DarkToggle -│ │ ├── index.js -│ │ └── styles.js -│ ├── DocsMenu.js -│ ├── DocsSubmenu.js -│ ├── Footer.js -│ ├── Header.js -│ ├── Icon.js -│ ├── Layout.js -│ ├── SectionContent.js -│ ├── SectionCta.js -│ ├── SectionDocs.js -│ ├── SectionGrid.js -│ ├── SectionHero.js -│ ├── Submenu.js -│ ├── global.css -│ └── index.js -├── data -│ └── doc_sections.yml -├── hooks -│ ├── addScript.js -│ ├── index.js -│ ├── useDarkMode.js -│ ├── useEventListener.js -│ ├── useMediaQuery.js -│ ├── useOnClickOutside.js -│ ├── useQueryParam.js -│ ├── useSize.js -│ └── useStorage.js -├── html.js -├── pages -│ ├── blog -│ │ ├── 300-react-questions.md -│ │ ├── awesome-graphql.md -│ │ ├── big-o-complexity.md -│ │ ├── blog-archive.md -│ │ ├── blogwcomments.md -│ │ ├── data-structures.md -│ │ ├── flow-control-in-python.md -│ │ ├── functions-in-python.md -│ │ ├── git-gateway.md -│ │ ├── index.md -│ │ ├── interview-questions-js.md -│ │ ├── netlify-cms.md -│ │ ├── platform-docs.md -│ │ ├── python-for-js-dev.md -│ │ ├── python-resources.md -│ │ ├── web-dev-trends.md -│ │ └── web-scraping.md -│ ├── docs -│ │ ├── about -│ │ │ ├── eng-portfolio.md -│ │ │ ├── ideas-for-this-website.md -│ │ │ ├── index.md -│ │ │ ├── intrests.md -│ │ │ ├── job-search.md -│ │ │ └── resume.md -│ │ ├── articles -│ │ │ ├── basic-web-dev.md -│ │ │ ├── buffers.md -│ │ │ ├── dev-dep.md -│ │ │ ├── event-loop.md -│ │ │ ├── fs-module.md -│ │ │ ├── how-the-web-works.md -│ │ │ ├── http.md -│ │ │ ├── index.md -│ │ │ ├── install.md -│ │ │ ├── intro.md -│ │ │ ├── modules.md -│ │ │ ├── nextjs.md -│ │ │ ├── node-api-express.md -│ │ │ ├── node-cli-args.md -│ │ │ ├── node-common-modules.md -│ │ │ ├── node-env-variables.md -│ │ │ ├── node-js-language.md -│ │ │ ├── node-package-manager.md -│ │ │ ├── node-repl.md -│ │ │ ├── node-run-cli.md -│ │ │ ├── nodejs.md -│ │ │ ├── nodevsbrowser.md -│ │ │ ├── npm.md -│ │ │ ├── npx.md -│ │ │ ├── os-module.md -│ │ │ ├── reading-files.md -│ │ │ ├── semantic-html.md -│ │ │ ├── semantic.md -│ │ │ ├── the-uniform-resource-locator-(url).md -│ │ │ ├── understanding-firebase.md -│ │ │ ├── v8.md -│ │ │ ├── web-standards-checklist.md -│ │ │ ├── webdev-tools.md -│ │ │ └── writing-files.md -│ │ ├── audio -│ │ │ ├── audio-feature-extraction.md -│ │ │ ├── audio.md -│ │ │ ├── dfft.md -│ │ │ ├── discrete-fft.md -│ │ │ ├── dtw-python-explained.md -│ │ │ ├── dynamic-time-warping.md -│ │ │ ├── index.md -│ │ │ └── web-audio-api.md -│ │ ├── career -│ │ │ ├── dev-interview.md -│ │ │ ├── index.md -│ │ │ ├── interview-dos-n-donts.md -│ │ │ └── job-boards.md -│ │ ├── community -│ │ │ ├── an-open-letter-2-future-developers.md -│ │ │ ├── index.md -│ │ │ └── video-chat.md -│ │ ├── content -│ │ │ ├── algo.md -│ │ │ ├── archive.md -│ │ │ ├── gatsby-Queries-Mutations.md -│ │ │ ├── history-api.md -│ │ │ ├── index.md -│ │ │ ├── main-projects.md -│ │ │ └── trouble-shooting.md -│ │ ├── data-structures -│ │ │ └── index.md -│ │ ├── docs -│ │ │ ├── appendix.md -│ │ │ ├── art-of-command-line.md -│ │ │ ├── bash.md -│ │ │ ├── content.md -│ │ │ ├── css.md -│ │ │ ├── data-structures-docs.md -│ │ │ ├── es-6-features.md -│ │ │ ├── git-reference.md -│ │ │ ├── git-repos.md -│ │ │ ├── html-spec.md -│ │ │ ├── index.md -│ │ │ ├── markdown.md -│ │ │ ├── no-whiteboarding.md -│ │ │ ├── node-docs-complete.md -│ │ │ ├── node-docs-full.md -│ │ │ ├── regex-in-js.md -│ │ │ └── sitemap.md -│ │ ├── faq -│ │ │ ├── contact.md -│ │ │ ├── index.md -│ │ │ └── plug-ins.md -│ │ ├── gists.md -│ │ ├── index.md -│ │ ├── interact -│ │ │ ├── callstack-visual.md -│ │ │ ├── clock.md -│ │ │ ├── index.md -│ │ │ ├── jupyter-notebooks.md -│ │ │ ├── other-sites.md -│ │ │ └── video-chat.md -│ │ ├── interview -│ │ │ ├── index.md -│ │ │ ├── job-search-nav.md -│ │ │ └── review-concepts.md -│ │ ├── javascript -│ │ │ ├── arrow-functions.md -│ │ │ ├── asyncjs.md -│ │ │ ├── await-keyword.md -│ │ │ ├── bigo.md -│ │ │ ├── clean-code.md -│ │ │ ├── constructor-functions.md -│ │ │ ├── index.md -│ │ │ ├── promises.md -│ │ │ ├── review.md -│ │ │ └── this-is-about-this.md -│ │ ├── leetcode -│ │ │ └── index.md -│ │ ├── privacy-policy.md -│ │ ├── projects -│ │ │ ├── embeded-websites.md -│ │ │ ├── index.md -│ │ │ ├── list-of-projects.md -│ │ │ ├── mini-projects.md -│ │ │ └── my-websites.md -│ │ ├── python -│ │ │ ├── at-length.md -│ │ │ ├── cheat-sheet.md -│ │ │ ├── comprehensive-guide.md -│ │ │ ├── examples.md -│ │ │ ├── flow-control.md -│ │ │ ├── functions.md -│ │ │ ├── google-sheets-api.md -│ │ │ ├── index.md -│ │ │ ├── intro-for-js-devs.md -│ │ │ ├── python-ds.md -│ │ │ └── snippets.md -│ │ ├── quick-reference -│ │ │ ├── Emmet.md -│ │ │ ├── all-emojis.md -│ │ │ ├── create-react-app.md -│ │ │ ├── git-bash.md -│ │ │ ├── git-tricks.md -│ │ │ ├── google-firebase.md -│ │ │ ├── heroku-error-codes.md -│ │ │ ├── index.md -│ │ │ ├── installation.md -│ │ │ ├── markdown-dropdowns.md -│ │ │ ├── minifiction.md -│ │ │ ├── new-repo-instructions.md -│ │ │ ├── psql-setup.md -│ │ │ ├── pull-request-rubric.md -│ │ │ ├── quick-links.md -│ │ │ ├── topRepos.md -│ │ │ ├── understanding-path.md -│ │ │ └── vscode-themes.md -│ │ ├── react -│ │ │ ├── ajax-n-apis.md -│ │ │ ├── cheatsheet.md -│ │ │ ├── createReactApp.md -│ │ │ ├── demo.md -│ │ │ ├── dont-use-index-as-keys.md -│ │ │ ├── index.md -│ │ │ ├── jsx.md -│ │ │ ├── react-docs.md -│ │ │ ├── react-in-depth.md -│ │ │ ├── react2.md -│ │ │ └── render-elements.md -│ │ ├── reference -│ │ │ ├── awesome-lists.md -│ │ │ ├── awesome-static.md -│ │ │ ├── bash-commands.md -│ │ │ ├── bookmarks.md -│ │ │ ├── embed-the-web.md -│ │ │ ├── github-search.md -│ │ │ ├── google-cloud.md -│ │ │ ├── how-2-reinstall-npm.md -│ │ │ ├── how-to-kill-a-process.md -│ │ │ ├── index.md -│ │ │ ├── installing-node.md -│ │ │ ├── intro-to-nodejs.md -│ │ │ ├── notes-template.md -│ │ │ ├── psql.md -│ │ │ ├── resources.md -│ │ │ ├── vscode.md -│ │ │ └── web-api's.md -│ │ ├── search.md -│ │ ├── sitemap.md -│ │ ├── tips -│ │ │ ├── array-methods.md -│ │ │ ├── index.md -│ │ │ └── insert-into-array.md -│ │ ├── tools -│ │ │ ├── Archive.md -│ │ │ ├── data-structures.md -│ │ │ ├── dev-utilities.md -│ │ │ ├── index.md -│ │ │ └── markdown-html.md -│ │ └── tutorials -│ │ ├── enviorment-setup.md -│ │ └── index.md -│ ├── index.md -│ ├── privacy-policy.md -│ ├── readme.md -│ └── showcase.md -├── sass -│ ├── imports -│ │ ├── _animations.scss -│ │ ├── _buttons.scss -│ │ ├── _docs.scss -│ │ ├── _footer.scss -│ │ ├── _forms.scss -│ │ ├── _functions.scss -│ │ ├── _general.scss -│ │ ├── _header.scss -│ │ ├── _helpers.scss -│ │ ├── _icons.scss -│ │ ├── _palettes.scss -│ │ ├── _posts.scss -│ │ ├── _prism.scss -│ │ ├── _reset.scss -│ │ ├── _sections.scss -│ │ ├── _structure.scss -│ │ ├── _tables.scss -│ │ └── _variables.scss -│ └── main.scss -├── templates -│ ├── advanced.js -│ ├── blog.js -│ ├── docs.js -│ ├── page.js -│ ├── post.js -│ └── templates.md -└── utils - ├── attribute.js - ├── blm-badge.js - ├── classNames.js - ├── cycler.js - ├── getData.js - ├── getPage.js - ├── getPageByFilePath.js - ├── getPages.js - ├── htmlToReact.js - ├── index.js - ├── link.js - ├── markdownify.js - ├── pathJoin.js - ├── toStyleObj.js - ├── toUrl.js - └── withPrefix.js - -32 directories, 272 files -``` - -
- -
- Click To See Component Sourcecode - -## Component Structure - -``` -. -├── ActionLink.js -├── CtaButtons.js -├── DarkToggle -│ ├── index.js -│ └── styles.js -├── DocsMenu.js -├── DocsSubmenu.js -├── Footer.js -├── Header.js -├── Icon.js -├── Layout.js -├── SectionContent.js -├── SectionCta.js -├── SectionDocs.js -├── SectionGrid.js -├── SectionHero.js -├── Submenu.js -├── global.css -└── index.js - -``` - ---- - -```js -import React from 'react'; -import _ from 'lodash'; - - -import { Link, withPrefix, classNames } from '../utils'; -import Icon from './Icon'; - -export default class ActionLink extends React.Component { - render() { - let action = _.get(this.props, 'action', null); - return ( - - {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon_class', null) ? ( - - - {_.get(action, 'label', null)} - - ) : ( - _.get(action, 'label', null) - )} - - ); - } -} -``` - ---- -### Table of Contents - -- [getPage][1] - - [Parameters][2] -- [getPageByFilePath][3] - - [Parameters][4] -- [getPages][5] - - [Parameters][6] - - [Examples][7] - -## getPage - -Get the page at the provided `urlPath`. - -### Parameters - -- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. -- `urlPath` **[string][9]** The url path to find the page by - -Returns **[Object][10]** - -## getPageByFilePath - -Get the page at the provided `filePath`. - -### Parameters - -- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. -- `filePath` **[string][9]** The file path to find the page by - -Returns **[Object][10]** - -## getPages - -Get all the pages located under the provided `urlPath`, not including the -index page. I.e.: All pages having their URLs start with `urlPath` excluding -the page having its URL equal to `urlPath`. - -### Parameters - -- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. -- `urlPath` **[string][9]** The url path to filter pages by - -### Examples - -```javascript -pages => [ - {url: '/'}, - {url: '/about'}, - {url: '/posts'}, - {url: '/posts/hello'}, - {url: '/posts/world'} -] - -getPages(pages, /posts') -=> [ - {url: '/posts/hello'}, - {url: '/posts/world'} -] -``` - -Returns **[Array][8]** - -[1]: #getpage -[2]: #parameters -[3]: #getpagebyfilepath -[4]: #parameters-1 -[5]: #getpages -[6]: #parameters-2 -[7]: #examples -[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array -[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object - - - -```js -import React from 'react'; -import _ from 'lodash'; - - -import { Link, withPrefix, classNames } from '../utils'; - -export default class CtaButtons extends React.Component { - render() { - let actions = _.get(this.props, 'actions', null); - return _.map(actions, (action, action_idx) => ( - - {_.get(action, 'label', null)} - - )); - } -} -``` - ---- - -```js -import React from 'react'; -import _ from 'lodash'; - - -import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; -import DocsSubmenu from './DocsSubmenu'; - -export default class DocsMenu extends React.Component { - render() { - let site = _.get(this.props, 'site', null); - let page = _.get(this.props, 'page', null); - let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); - let root_page = getPage(this.props.pageContext.pages, root_docs_path); - return ( - - ); - } -} -``` - ---- - -```js -import React from 'react'; -import _ from 'lodash'; - - -import { classNames, Link, withPrefix } from '../utils'; - -export default class DocsSubmenu extends React.Component { - render() { - let child_pages = _.get(this.props, 'child_pages', null); - let page = _.get(this.props, 'page', null); - return ( -
    - {_.map(child_pages, (child_page, child_page_idx) => ( -
  • - {_.get(child_page, 'frontmatter.title', null)} -
  • - ))} -
- ); - } -} -``` - ---- - -```js -import _ from 'lodash'; -import React from 'react'; - -import { htmlToReact } from '../utils'; -import ActionLink from './ActionLink'; -import addScript from './../hooks/addScript'; -const Script = (props) => { - importScript('./../hooks/addScript.js'); -}; -export default class Footer extends React.Component { - render() { - return ( -
-
-
-
- - - -
- - - - - - - - - - -
-
- - - - - - - - -
- - index - - - - sitemap - - - - advanced - -
-
- - - - - - - - - - -
- - search engine - - - by - freefind - - { - - } -
- - Save to PDF - -
-
- -
- -
-

- {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( - {htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))} - )} - {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( - - ))}{' '} -

- {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( -
- {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( - - ))}{' '} -
- )}{' '} -
-
-
- ); - } -} -``` - ---- - -```js -import React from 'react'; -import _ from 'lodash'; - - -import { Link, withPrefix, classNames } from '../utils'; -import ActionLink from './ActionLink'; -import Submenu from './Submenu'; - -export default class Header extends React.Component { - render() { - return ( -
- {/* */} - -
- -
-
-
- {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( -

- - {_.get(this.props, - -

- ) : ( -

- {' '} - WebDevHub - - {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} - -

- )} -
- - {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( - - - - - )} -
-
- - -
- ); - } -} -``` - ---- - -```js -import React from 'react'; -import _ from 'lodash'; - -export default class Icon extends React.Component { - render() { - let icon = _.get(this.props, 'icon', null); - return ( - - {icon === 'dev' ? ( - - ) : icon === 'facebook' ? ( - - ) : icon === 'github' ? ( - - ) : icon === 'instagram' ? ( - - ) : icon === 'linkedin' ? ( - - ) : icon === 'pinterest' ? ( - - ) : icon === 'reddit' ? ( - - ) : icon === 'twitter' ? ( - - ) : icon === 'youtube' ? ( - - ) : ( - icon === 'vimeo' && ( - - ) - )} - - ); - } -} -``` diff --git a/cloudflared.deb b/cloudflared.deb deleted file mode 100644 index 0d15fe6d4c..0000000000 Binary files a/cloudflared.deb and /dev/null differ diff --git a/config.yml b/config.yml new file mode 100644 index 0000000000..11b2be0828 --- /dev/null +++ b/config.yml @@ -0,0 +1,3 @@ +backend: + name: git-gateway + branch: master # Branch to update (optional; defaults to master) \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..9320a43f7d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,3875 @@ +# Bgoonz Blog Readme: + +### [Github Org Link](https://github.com/BGOOONZ-BLOG/) + +## [CHANGELOG](./CHANGELOG.md) + +##### [Cloudfare-Backup](https://bgoonz-blog-2-0.pages.dev/) + +⇨ [search](https://www.algolia.com/realtime-search-demo/web-dev-resource-hub-9e6b8aa8-6106-44c5-9f59-ff3f9531abd4) ⇨ [Backup Repo Deploy](https://bgoonzblog20-backup.netlify.app/#gsc.tab=0) ⇨ [Github pages](https://bgoonz.github.io/BGOONZ_BLOG_2.0/) + +⇨ [Go To Site Wiki](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) ⇨ [Gatsby Cloud Version](https://bgoonzblog20master.gtsb.io/) + +⇨ [Vercel Version](https://bgoonz-blog-2-0.vercel.app/) + +⇨ [Cloudfare-Domain](www.webdevhub.us) ⇨ [gh-pages](https://bgoonz.github.io/BGOONZ_BLOG_2.0/) + +### Repos + +- [Alt Backup](https://github.com/BGOOONZ-BLOG/bgoonz-blog2.0-v-5) +- [Blog Content](https://github.com/bgoonz/MainBlogContent) + +###### [⇨Privacy policy⇦](https://codepen.io/bgoonz/pen/LYLJZrW) + + +![preview](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/blog-may-2022.png?raw=true) + +--- +## Useful Commands (internal use) + +```bash + +npm i @stackbit/gatsby-plugin-menus babel-runtime chokidar classnames fs-extra gatsby gatsby-image gatsby-plugin-netlify gatsby-plugin-netlify-cms gatsby-plugin-sass gatsby-plugin-react-helmet gatsby-plugin-typescript --legacy-peer-deps + +git checkout 307a5cd # check out the commit that you want to reset to +git checkout -b fixy # create a branch named fixy to do the work +git merge -s ours master # merge master's history without changing any files +git checkout master # switch back to master +git merge fixy # and merge in the fixed branch +git push # done, no need to force push! + + + + +![preview](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/blog-may-2022.png?raw=true) + +git checkout 307a5cd # check out the commit that you want to reset to +git checkout -b fixy # create a branch named fixy to do the work +git merge -s ours master # merge master's history without changing any files +git checkout master # switch back to master +git merge fixy # and merge in the fixed branch +git push # done, no need to force push! + + + +``` +npm i @stackbit/gatsby-plugin-menus babel-runtime chokidar classnames fs-extra gatsby gatsby-image gatsby-plugin-netlify gatsby-plugin-netlify-cms gatsby-plugin-sass gatsby-plugin-react-helmet gatsby-plugin-typescript --legacy-peer-deps + +--- + +![Test My Site](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/Screenshot%202022-03-30%20at%2012-37-24%20Website%20Speed%20Test%20Tool%20-%20Testmysite.io%20by%20Netlify.png?raw=true) + +[![gmail](https://img.icons8.com/color/96/000000/gmail.png)](mailto:bryan.guner@gmail.com)[![linkedin](https://img.icons8.com/color/96/000000/linkedin.png) ](https://www.linkedin.com/in/bryan-guner-046199128/) + +
+Web Dev Setup + +[webpack](https://webpack.js.org/) + +## Basic Web Development Environment Setup +Windows Subsystem for Linux (WSL) and Ubuntu + +--- + +![dtw](https://d33wubrfki0l68.cloudfront.net/1111140b3425c2a3e653688cedc52c43af701d30/54d59/images/dtw-algo.jpg) +Artificial neural networks, usually simply called neural networks, are computing systems vaguely inspired by the biological [neural networks](https://github.com/tensorflow/tensorflow) +![neural](/_static/app-assets/neural.PNG) +[NJDEVILS](https://www.allaboutthejersey.com/) + +[Career](/docs/career/) + +[![webdevhub logo](https://d33wubrfki0l68.cloudfront.net/e5662f0d4f3e7730aea1a0faf7ff09ea20184700/83eb0/images/home-button.png)](/) + +Open Menu + +- [Navigation](/docs/sitemap) Sub-menu +- [Docs](/docs) +- [Showcase](/showcase) +- [Contact!](/docs/faq/contact) +- [Python](/docs/python/python-ds) +- [JavaScript](/javascript) +- [Blog](/blog/) + +Sub-menu + +- [Blog-Post-Archive](https://bgoonz.blogspot.com/) + +- [Top Blog Posts](https://blog-w-comments.vercel.app/) + +- [Blog w Comments](/blogWcomments/) + +- [Job Search](/docs/career/) + +Sub-menu + +- [Job Boards](/docs/career/job-boards) +- [Do's and Don'ts of interviews](/interview/dos-and-donts) +- [Career-Tips](https://bgoonz-blog.netlify.app/docs/career/) + +- [Interview Questions](/docs/interview/interview-questions) +- [Archive](/docs/archive) Sub-menu +- [Resource-Archive-Server](https://github.com/bgoonz/Learning-Assets) +- [Bootcamp Resources](https://lambda-resources.netlify.app/) + +- [Web Dev Setup](https://bgoonz-blog.netlify.app/blog/webdev-setup/) + + +- [Top Repos](/docs) +- [MY_DOCS](https://bryan-guner.gitbook.io/my-docs/) + + +--- + +- [WebAudioLab](https://bgoonz.github.io/WebAudioDaw/) + + +- [Condensed -Portfolio](https://bg-portfolio.netlify.app/) + +- [Family Promise Tracker](https://a.familypromiseservicetracker.dev/) + +- [DTW-Guitar-FX-Automation](https://github.com/bgoonz/Revamped-Automatic-Guitar-Effect-Triggering) +- [Embeds Blog](https://bgoonz-blog-v3-0.netlify.app/embeds/) + +- [alt-blogs](https://bgoonz-blog-v3-0.netlify.app/) + +- [Games](https://bgoonz-games.netlify.app/) + +- [Blog Backup](https://bgoonz-blog-v3-0.netlify.app/) + +- [Cover Letter](https://bgoonz-cv.netlify.app/) + +- [Project Centric](https://project-portfolio42.netlify.app/) + +- [Wordpress Blog](https://bgoonz-blog.netlify.app/) + +- [Project Portfolio Gallery](https://project-portfolio42.netlify.app/) + +- [github-stats-website](https://bgoonz.github.io/github-stats-website/) + +- [Admin](https://bgoonz-blog.netlify.app/admin/) + +Sub-menu + +- [Write Docs](https://bgoonz-blog.netlify.app/admin/#/collections/docs) +- [Write Blog](https://bgoonz-blog.netlify.app/admin/#/collections/blog/new) +- [Webmaster](https://bgoonz-blog.netlify.app/admin/#/collections/blog/new) +- [Tools](/docs/tools) Sub-menu +- [Github HTML Previewer](https://githtmlpreview.netlify.app/) + +- [Text Tools](https://devtools42.netlify.app/) + +- [Ternary 2 If Else](https://ternary42.netlify.app/) + +- [Web Dev Utility Tools](/hps://web-dev-utility-tools-bgoonz.netlify.app/) + +- [Setup Checker](https://github.com/bgoonz/web-dev-setup-checker) +- [PotluckPlanner](https://potluck-landing.netlify.app/) + +- [WebDev Quizzes](https://web-dev-interview-prep-quiz-website.netlify.app/) + +- [Github-Advanced-Search](https://github.com/search/advanced) + Close Menu + _🔎_ + Search + +# I am a musician, electrical engineer & web developer + +**Please note that this website is in development and is often broken!** +[](https://www.vagrantup.com/) + +[![gmail](https://img.icons8.com/color/96/000000/gmail.png)](mailto:bryan.guner@gmail.com)[![linkedin](https://img.icons8.com/color/96/000000/linkedin.png) ](https://www.linkedin.com/in/bryan-guner-046199128/) + +```bash +git init +git add . +git commit -m"update" +git push -u origin gh-pages +``` +```bash +git init +git add . +git commit -m"update" +git push -u origin preview +``` + +[](https://webpack.js.org/) + +> Notes: +###### code + +```bash + +![Python](https://img.shields.io/badge/-Python-05122A?style=flat&logo=python) +![HTML](https://img.shields.io/badge/-HTML-05122A?style=flat&logo=HTML5) +![CSS](https://img.shields.io/badge/-CSS-05122A?style=flat&logo=CSS3&logoColor=1572B6) +![JavaScript](https://img.shields.io/badge/-JavaScript-05122A?style=flat&logo=javascript) +![React](https://img.shields.io/badge/-React-05122A?style=flat&logo=react) +![Node.js](https://img.shields.io/badge/-Node.js-05122A?style=flat&logo=node.js) + +![VisualStudioCode](https://img.shields.io/badge/-Visual%20Studio%20Code-05122A?style=flat&logo=visual-studio-code&logoColor=007ACC) +![Docker](https://img.shields.io/badge/-Docker-05122A?style=flat&logo=Docker) +![MongoDB](https://img.shields.io/badge/-MongoDB-05122A?style=flat&logo=mongodb) +![PostgreSQL](https://img.shields.io/badge/-PostgreSQL-05122A?style=flat&logo=postgresql) + +![Git](https://img.shields.io/badge/-Git-05122A?style=flat&logo=git) +![GitHub](https://img.shields.io/badge/-GitHub-05122A?style=flat&logo=github) +![GitLab](https://img.shields.io/badge/-GitLab-05122A?style=flat&logo=gitlab) + +--- + +![](https://d33wubrfki0l68.cloudfront.net/47651cb6f5e64bf9eee581581215e5c456e3968d/83ee4/images/bigo.jpg) + +### [A Quick Guide To Big O](https://bgoonz-blog.netlify.app/docs/ds-algo/big-o/) + +Memoization, Tabulation, and Sorting Algorithms by Example↩ Why is looking at runtime not a reliable method of calculating time↩ complexity? +[View Post](/docs/ds-algo/big-o/) + +![python](https://d33wubrfki0l68.cloudfront.net/4337f190bb60dcd6f83fd5e2ac21502e1cf93f45/16558/images/python-language.jpg) + +### [Python Guide](https://bgoonz-blog.netlify.app/docs/python/python-ds) + +_Python has a built in help function that let's you see a description↩ of the source code without having to navigate to it… "-SickNasty …↩ Autor Unknown" ._ +[View Posts](https://bgoonz-blog.netlify.app/docs/python/python-ds) + +![](https://d33wubrfki0l68.cloudfront.net/1111140b3425c2a3e653688cedc52c43af701d30/54d59/images/dtw-algo.jpg) + +### [Guitar Effects Triggering w DTW](https://github.com/bgoonz/Revamped-Automatic-Guitar-Effect-Triggering) + +[Learn More](/docs/tools) + +![img of dtw](https://d33wubrfki0l68.cloudfront.net/a37b8bc089cdd775711785baf935f9b1c4e732b0/c2294/images/react.gif) + +### [Beginner Guide React](https://bgoonz-blog.netlify.app/docs/react/react2/) + +As I learn to build web applications in React I will blog about it in↩ this series in an attempt to capture the questions that a complete↩ beginner might encounter that a more seasoned developer would take for↩ granted! + +![img of react](https://d33wubrfki0l68.cloudfront.net/f318a0bdc5403fb9b59683b46e3c9ec2d75d2ed2/7de75/images/pleasant-birch.png) + +### [Scope & Closure](https://dev.to/bgoonz/scope-and-context-in-javascript-5cma) + +Scope & Context in JS +The **scope** of a program in JavaScript is the set of variables that are available for use within the program. + +![scope and closure](https://d33wubrfki0l68.cloudfront.net/bc959e2c76edd99401fa7bc07665db54863f5fd2/97e29/images/dtw-slideshow.gif) + +### Web Audio Daw + +PostgreSQL Cheat Sheet, Everything You Need to View Post With VSCode + +- Extensions & Resources, Super Simple Intro To HTML, Understanding↩ Git... etc.... + +## Current Interests + +From github repositories to existential questions. + +![angolia](https://d33wubrfki0l68.cloudfront.net/589475503098710e5f2f3c1a381015f69e6b4760/0be4d/images/neural.png) + +```bash +git init +git add . +git commit -m"update" +git push -u origin gh-pages +``` +```bash +git init +git add . +git commit -m"update" +git push -u origin preview +``` + +[Full Text Search](https://www.algolia.com/) + +![neural networks](https://d33wubrfki0l68.cloudfront.net/589475503098710e5f2f3c1a381015f69e6b4760/0be4d/images/neural.png) + +### [Convolutional Neural Networks](/neural networks) + +> Notes: +###### code + +### [Jamstack](/jamstack) + +##### Why Jamstack Jamstack is the new standard architecture for the + +web. Using Git workflows and modern build tools, pre-rendered content↩ is served to a CDN and made dynamic through APIs and serverless↩ functions. Technologies in the stack include JavaScript frameworks,↩ Static Site Generators, Headless CMSs, and CDNs. + +![event loop](https://d33wubrfki0l68.cloudfront.net/fb22b10eaa16e4ac0690115bf6c6987350d38d4b/13c10/images/eventloop.gif) + +### [Asynchronous JavaScript](/docs/) + +The term **asynchronous** refers to two or more objects or events **not** existing or happening at the same time (or multiple related things happening without waiting for the previous one to complete). In computing, the word "asynchronous" is used in two major contexts. +[Learn More](https://www.allaboutthejersey.com/) + +![nj-devils](/images/njdev-219301cd.jpg) + +### [NJ Devils](https://www.allaboutthejersey.com/) + +# New Jersey Devils Hockey Team + +### (Hockey in general) + +## Team identity + +[![devils](https://upload.wikimedia.org/wikipedia/en/thumb/d/da/OldDevils.png/300px-OldDevils.png)](https://en.wikipedia.org/wiki/File:OldDevils.png) +The old green style jerseys used from 1982 to 1992The jerseys used from 1992 to 2017[Sean Avery](https://en.wikipedia.org/wiki/Sean_Avery) of the [New York Rangers](https://en.wikipedia.org/wiki/New_York_Rangers) attempts to distract Brodeur during the [2008 Stanley Cup playoffs](https://en.wikipedia.org/wiki/2008_Stanley_Cup_playoffs). The playoff series was the fifth to feature the [Devils-Rangers rivalry](https://en.wikipedia.org/wiki/Devils%E2%80%93Rangers_rivalry). +[Learn More](https://www.iter.org/) + +![ITER Reactor](https://d33wubrfki0l68.cloudfront.net/c2ae8fae397ffc059312cb9e84ae23dd4bf774bd/fd765/images/iter.jpg) + +### [ITER Fusion Reactor Experiment (Southern France)](https://www.iter.org/) + +# Break Even Nuclear Fusion Candidate + +In December, researchers at the Joint European Torus (JET) started↩ conducting fusion experiments with tritium — a rare and radioactive↩ isotope of hydrogen. The facility is a one-tenth-volume mock-up of the↩ US\$22-billion ITER project and has the same doughnut-shaped 'tokamak'↩ design — the world's most developed approach to fusion energy. It is↩ the first time since 1997 that researchers have done experiments in a↩ tokamak with any significant amount of tritium. + +## Resume & Portfolio + +![resume](https://d33wubrfki0l68.cloudfront.net/b6e6b09f4479310dff86d8dd7af1b73762484f6a/fea3e/images/image-of-resume.png) + +### [Resume](https://github.com/bgoonz/resume-cv-portfolio-samples/raw/master/2021-resume/bryan-guner-resume-2021.pdf) + +[View In One Drive](https://1drv.ms/b/s!AkGiZ9n9CRDSpLsZsnPtiN7p77vq6A) [Web Version](#) [Download PDF](https://github.com/bgoonz/bgoonz/raw/master/bryan_guner_resume_2021_V9.pdf) + +![portfolio of websites](https://d33wubrfki0l68.cloudfront.net/4e66fa2888421bd225aa811c156362cc0b7d4ebc/ca806/images/portfolio.jpg) + +### Showcase + +![My Projects](/_static/app-assets/lambda-demo1.gif)My Projects! +[Learn More](/showcase) + +## Blog-Archive-And-Mini-Projects + +![animated gif](/images/cool annimation.gif) + +## Latest & Greatest + +## Web Dev Utilitiy Tools + +## Tools Showcase + +![medium](https://d33wubrfki0l68.cloudfront.net/e5828552ff6b5743ed241d9c926e60eb925dde97/8dbbf/images/goals.jpg) + +## Web Audio DA + +[Go To Web Audio Daw](https://mihirbegmusiclab.netlify.app/) + +```bash +tree -d -I 'node_modules' +## Quick Links + +quick links home + +### [About](/docs/about/) + +Web-Dev-Hub is my personal blogand documentation site +[Learn More](/docs/about/) + +### [Articles](/docs/articles/) + +my web development articles +[Learn More](/docs/articles/) + +### [Audio](/docs/audio/) + +Audio Projects and tools / web audio daw +[Learn More](/docs/audio/) + +### [Archive](/docs/archive/) + +more tools that I have created or collaborated on. +[Learn More](/docs/archive/) + +### [Career](/docs/career/) + +Reference materials and descriptions of fundamental concepts as well as visua +[Learn More](/docs/career/) + +### [Community](/docs/community/) + +We'd love it if you participate in the Libris community. Find out how to get connected. +[Learn More](/docs/community/) + +### [Content](/docs/content/) + +[Learn More](/docs/content/) + +### [CSS](/docs/css/) + +[Learn More](/docs/css/) + +### [Docs](/docs/docs/) + +Documentation +[Learn More](/docs/docs/) + +### [Data Structures](/docs/ds-algo/) + +In this section you'll learn how to add syntax highlighting, examples, callouts and much more. +[Learn More](/docs/ds-algo/) + +### [FAQ](/docs/faq/) + +In this section you'll find commonly asked questions regarding the Libris theme. If you have questions, don't hesitate to ask us directly. +[Learn More](/docs/faq/) + +find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + +### + +Learn More + +### [Interact](/docs/interact/) + +Interactive examples and projects +[Learn More](/docs/interact/) + +### [Javascript](/docs/javascript/) + +[Learn More](/docs/javascript/) + +### [JS-Quick-Tips](/docs/js-tips/) + +Javascript articles and docs +[Learn More](/docs/js-tips/) + +### [Leetcode](/docs/leetcode/) + +[Learn More](/docs/leetcode/) + +### [Netlify CMS](/docs/netlify-cms-jamstack/) + +etlify CMS is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflows. +[Learn More](/docs/netlify-cms-jamstack/) + +### [Overflow](/docs/overflow/) + +feel free to try the examples +[Learn More](/docs/overflow/) + +### [Projects](/docs/projects/) + +We'd love it if you participate in the Web-Dev-Hubcommunity. Find out how to get connected. +[Learn More](/docs/projects/) + +### [Python](/docs/python/) + +Python +[Learn More](/docs/python/) + +### [QuickRef](/docs/quick-ref/) + +In this section you'll find basic information about Web-Dev-Hub and how to use it. +[Learn More](/docs/quick-ref/) + +### [React](/docs/react/) + +To make it easy to write documentation in plain Markdown, most React are styled using Markdown elements with few additional CSS classes. +[Learn More](/docs/react/) + +### [Reference](/docs/reference/) + +helpful reference guides +[Learn More](/docs/reference/) + +### [Tips](/docs/tips/) + +lorem-ipsum +[Learn More](/docs/tips/) + +### [Tools](/docs/tools/) + +See some interesting tools developed by the Web-Dev-Hubcommunity to help automate parts of your workflow. +[Learn More](/docs/tools/) + +### [Tutorials](/docs/tutorials/) + +Walkthroughs of various development activities and skills +[Learn More](/docs/tutorials/) + +## Contact + +get in touch! +1 (551) - 254 - 5505 +[Contact](/docs/faq/contact) +[index](https://search.freefind.com/siteindex.html?si=14588965) +[sitemap](https://search.freefind.com/find.html?si=14588965&m=0&p=0) +[advanced](https://search.freefind.com/find.html?si=14588965&pid=a) +[search engine](https://www.freefind.com) [byfreefind](https://www.freefind.com) +[Save to PDF](//pdfcrowd.com/url_to_pdf/?) +[![webdevhub logo](https://d33wubrfki0l68.cloudfront.net/e5662f0d4f3e7730aea1a0faf7ff09ea20184700/6ca0b/images/dgqlkqjtmk.png)](/) + +@bgoonz on almost every platform [BLM](https://random-static-html-deploys.netlify.app/blm.html) +[Twitter](https://twitter.com/bgooonz) [LinkedIn](https://www.linkedin.com/in/bryan-guner-046199128/) + +[GitHub](https://github.com/bgoonz) [Youtube](https://www.youtube.com/channel/UC9-rYyUMsnEBK8G8fCyrXXA) [Instagram](https://www.instagram.com/bgoonz/?hl=en) [dev.to](https://dev.to/bgoonz) + + Bash Commands +## My Commands +## # Find +# To find files by case-insensitive extension (ex: .jpg, .jpg, .jpG) +find . -iname "\*.jpg" +# To find directories +find . -type d +# To find files +find . -type f +# To find files by octal permission +find . -type f -perm 777 +# To find files with setuid bit set +find . -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l +# To find files with extension '.txt' and remove them +find ./path/ -name '\*.txt' -exec rm '{}' \; +# To find files with extension '.txt' and look for a string into them +find ./path/ -name '\*.txt' | xargs grep 'string' +# To find files with size bigger than 5 Mebibyte and sort them by size +find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z +# To find files bigger than 2 Megabyte and list them +find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }' +# To find files modified more than 7 days ago and list file information +find . -type f -mtime +7d -ls +# To find symlinks owned by a user and list file information +find . -type l -user -ls +# To search for and delete empty directories +find . -type d -empty -exec rmdir {} \; +# To search for directories named build at a max depth of 2 directories +find . -maxdepth 2 -name build -type d +# To search all files who are not in .git directory +find . ! -iwholename '_.git_' -type f +# To find all files that have the same node (hard link) as MY_FILE_HERE +find . -type f -samefile MY_FILE_HERE 2> /dev/null +# To find all files in the current directory and modify their permissions +find . -type f -exec chmod 644 {} \; +# 1. Remove spaces from file and folder names and then remove numbers from files and folder names +## Description: need to : `sudo apt install rename` +> Notes: Issue when renaming file without numbers collides with existing file name... +## # code +````console +find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh +for i in *.html; do mv "$i" "${i%-*}.html"; done +for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done +## Description: combine the contents of every file in the contaning directory. +## # code: +let cat = require('child_process') +.execSync('cat *') +.toString('UTF-8'); +fs.writeFile('output.md', cat, err => { +```` +# 2. Download Website Using Wget +> Notes: ==> sudo apt install wget +wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/ +# 3. Clean Out Messy Git Repo +## Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders +> Notes: To clear up clutter in repositories that only get used on your local machine. +find . -empty -type d -print -delete +find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + +find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + +# 4. clone all of a user's git repositories +## Description: clone all of a user or organization's git repositories +# Generalized +CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 +curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" | +# Clone all Git User +CNTX={users}; NAME={bgoonz}; PAGE=1 +# Clone all Git Organization +CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1 +curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | +grep -e 'git_url*' | +cut -d \" -f 4 | +xargs -L1 git clone +# 5. Git Workflow +git push -u origin master +git push -u origin main +git push -u origin bryan-guner +git push -u origin gh-pages +git init +git add . +git commit -m"update" +git push -u origin preview +# 6. Recursive Unzip In Place +## Description: recursively unzips folders and then deletes the zip file by the same name +find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; +find . -name "*.zip" -type f -print -delete +# 7. git pull keeping local changes +git stash +git pull +git stash pop +# 8. Prettier Code Formatter +sudo npm i prettier -g +# 9. Pandoc +find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; +find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \; +find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \; +# 10. Gitpod Installs +sudo apt install tree +sudo apt install pandoc -y +sudo apt install rename -y +sudo apt install black -y +sudo apt install wget -y +npm i lebab -g +npm i prettier -g +npm i npm-recursive-install -g +black . +prettier --write . +npm-recursive-install +# 11. Repo Utils Package +## Description: my standard repo utis package +npm i @bgoonz11/repoutils +# 12. Unix Tree Package Usage +tree -d -I 'node_modules' +tree -I 'node_modules' +tree -f -I 'node_modules' > TREE.md +tree -f -L 2 > README.md +tree -f -I 'node_modules' > listing-path.md +tree -f -I 'node_modules' -d > TREE.md +tree -f > README.md +# 13. Find & Replace string in file & folder names recursively +find . -type f -exec rename 's/string1/string2/g' {} + +find . -type f -exec rename 's/\.download//g' {} + +find . -type d -exec rename 's/-main//g' {} + +rename 's/\.js\.download$/.js/' *.js\.download +rename 's/\.html\.markdown$/.md/' *.html\.markdown +find . -type d -exec rename 's/es6//g' {} + +# 14. Remove double extensions +for file in *.md.md +mv "${file}" "${file%.md}" +for file in *.html.html +mv "${file}" "${file%.html}" +for file in *.html.png +for file in *.jpg.jpg +do +mv "${file}" "${file%.png}" +done +# 15. Truncate folder names down to 12 characters +for d in ./*; do mv $d ${d:0:12}; done +# 16.Appendir.js +## Description: combine the contents of every file in the contaning directory +> Notes: this includes the contents of the file it's self... +//APPEND-DIR.js +const fs = require('fs'); +let cat = require('child_process').execSync('cat *').toString('UTF-8'); +fs.writeFile('output.md', cat, (err) => { +if (err) throw err; +}); +# 17. Replace space in filename with underscore +## Description: followed by replace `'#' with '_'` in directory name +> Notes: Can be re-purposed to find and replace any set of strings in file or folder names. +find . -name "* *" -type f | rename 's/_//g' +find . -name "* *" -type d | rename 's/#/_/g' +# 18. Filter & delete files by name and extension +find . -name '.bin' -type d -prune -exec rm -rf '{}' + +find . -name '*.html' -type d -prune -exec rm -rf '{}' + +find . -name 'nav-index' -type d -prune -exec rm -rf '{}' + +find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + +find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' + +find . -name 'right.html' -type f -prune -exec rm -rf '{}' + +find . -name 'left.html' -type f -prune -exec rm -rf '{}' + +# 19. Remove lines containing string +> Notes: Remove lines not containing `'.js'` +sudo sed -i '/\.js/!d' ./*scrap2.md +sudo sed -i '/author/d' ./* +# 20. Remove duplicate lines from a text file +> //...syntax of uniq...// +> $uniq [OPTION] [INPUT[OUTPUT]] +> The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn't specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn't specified then uniq writes to the standard output. +Now, let's understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq. +sudo apt install uniq +uniq -u input.txt output.txt +# 21. Remove lines containing string +sudo sed -i '/githubusercontent/d' ./*sandbox.md +sudo sed -i '/githubusercontent/d' ./*scrap2.md +sudo sed -i '/github\.com/d' ./*out.md +title: add_days +tags: date,intermediate +firstSeen: 2020-10-28T16:19:04+02:00 +lastUpdated: 2020-10-28T16:19:04+02:00 +sudo sed -i '/title:/d' ./*output.md +sudo sed -i '/firstSeen/d' ./*output.md +sudo sed -i '/lastUpdated/d' ./*output.md +sudo sed -i '/tags:/d' ./*output.md +sudo sed -i '/badstring/d' ./* +sudo sed -i '/stargazers/d' ./repo.txt +sudo sed -i '/node_modules/d' ./index.html +sudo sed -i '/right\.html/d' ./index.html +sudo sed -i '/right\.html/d' ./right.html +# 22. Zip directory excluding .git and node_modules all the way down (Linux) +#!/bin/bash +TSTAMP=`date '+%Y%m%d-%H%M%S'` +zip -r $1.$TSTAMP.zip $1 -x "**.git/*" -x "**node_modules/*" `shift; echo $@;` +printf "\nCreated: $1.$TSTAMP.zip\n" +# usage: +# - zipdir thedir +# - zip thedir -x "**anotherexcludedsubdir/*" (important the double quotes to prevent glob expansion) +# if in windows/git-bash, add 'zip' command this way: +# https://stackoverflow.com/a/55749636/1482990 +# 23. Delete files containing a certain string +find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh +vi doit.sh // check for murphy and his law +source doit.sh +# 24 +html="sitemap.html" +echo ' ' +echo ' ' +awk '{print "
  • ",$1," 
  • "}' $listing +# 25. Index of Iframes +## Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags +> Notes: Useful Follow up Code: + +```bash + +``` + +###### code + +```bash + +#!/bin/sh + +## find ./ | grep -i "\.*$" >files +find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files +listing="files" + +out="" + +html="index.html" +out="basename $out.html" +html="index.html" +cmd() { + + echo ' ' + echo '' + echo '' + + echo ' ' + + echo ' ' + echo '' + echo ' ' + echo ' ' + + echo " directory " + + echo "" + echo '' + echo '' + + echo '' + + echo "" + + # continue with the HTML stuff + + echo "" + + echo "" + + echo "
      " + + awk '{print ""}' $listing + + # awk '{print "
    • "}; + + # {print " ",$1,"
    •  "}' \ $listing + + echo "" + + echo "
    " + + echo "" + + echo "" + +} + +cmd $listing --sort=extension >>$html + +``` + +--- + +## 26. Filter Corrupted Git Repo For Troublesome File + +### Description + +> Notes: + +###### code + +```bash + +git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD + +``` + +--- + +## 27. OVERWRITE LOCAL CHANGES + +### Description + +Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] +If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected. + +> Notes: +> First, run a fetch to update all origin/ refs to latest: + +###### code + +```bash + +git fetch --all +## Backup your current branch: + +git branch backup-master +## Then, you have two options: + +git reset --hard origin/master +## OR If you are on some other branch: + +git reset --hard origin/ +## Explanation: +## git fetch downloads the latest from remote without trying to merge or rebase anything. + +## Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master +git fetch --all +git reset --hard origin/master + +``` + +--- + +## 28. Remove Submodules + +### Description: To remove a submodule you need to + +> Notes: + +> Delete the relevant section from the .gitmodules file. +> Stage the .gitmodules changes git add .gitmodules +> Delete the relevant section from .git/config. +> Run git rm --cached path_to_submodule (no trailing slash). +> Run rm -rf .git/modules/path_to_submodule (no trailing slash). +> Commit git commit -m "Removed submodule " +> Delete the now untracked submodule files rm -rf path_to_submodule + +###### code + +```bash +git submodule deinit +``` + +--- + +## 29. GET GISTS + +### Description + +> Notes: + +###### code + +```bash +sudo apt install wget + +wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget + +wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget + +wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget + +wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget + +``` + +--- + +## 30. Remove Remote OriginL + +### Description + +> Notes: + +###### code + +```bash + +git remote remove origin + +``` + +--- + +## 31. just clone .git folder + +### Description + +> Notes: + +###### code + +```bash + +git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git + +``` + +--- + +## 32. Undo recent pull request + +### Description + +> Notes: + +###### code + +```bash + +git reset --hard master@{"10 minutes ago"} + +``` + +--- + +## 33. Lebab + +### Description: ES5 --> ES6 + +> Notes: + +###### code + +```bash +## Safe: + + lebab --replace ./ --transform arrow + lebab --replace ./ --transform arrow-return + lebab --replace ./ --transform for-of + lebab --replace ./ --transform for-each + lebab --replace ./ --transform arg-rest + lebab --replace ./ --transform arg-spread + lebab --replace ./ --transform obj-method + lebab --replace ./ --transform obj-shorthand + lebab --replace ./ --transform multi-var + +## ALL: + +lebab --replace ./ --transform obj-method +lebab --replace ./ --transform class +lebab --replace ./ --transform arrow +lebab --replace ./ --transform let +lebab --replace ./ --transform arg-spread +lebab --replace ./ --transform arg-rest +lebab --replace ./ --transform for-each +lebab --replace ./ --transform for-of +lebab --replace ./ --transform commonjs +lebab --replace ./ --transform exponent +lebab --replace ./ --transform multi-var +lebab --replace ./ --transform template +lebab --replace ./ --transform default-param +lebab --replace ./ --transform destruct-param +lebab --replace ./ --transform includes +lebab --replace ./ --transform obj-method +lebab --replace ./ --transform class +lebab --replace ./ --transform arrow +lebab --replace ./ --transform arg-spread +lebab --replace ./ --transform arg-rest +lebab --replace ./ --transform for-each +lebab --replace ./ --transform for-of +lebab --replace ./ --transform commonjs +lebab --replace ./ --transform exponent +lebab --replace ./ --transform multi-var +lebab --replace ./ --transform template +lebab --replace ./ --transform default-param +lebab --replace ./ --transform destruct-param +lebab --replace ./ --transform includes + +``` + +--- + +## 34. Troubleshoot Ubuntu Input/Output Error + +### Description: Open Powershell as Administrator + +> Notes: + +###### code + +```ps1 + + wsl.exe --shutdown + + Get-Service LxssManager | Restart-Service + +``` + +--- + +## 35. Export Medium as Markdown + +### Description + +> Notes: + +###### code + +```bash +npm i mediumexporter -g + +mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md + +``` + +--- + +## 36. Delete files in violation of a given size range (100MB for git) + +### Description + +> Notes: + +###### code + +```bash + +find . -size +75M -a -print -a -exec rm -f {} \; + +find . -size +98M -a -print -a -exec rm -f {} \; + +``` + +--- + +## 37. download all links of given file type + +### Description + +> Notes: + +###### code + +```bash + +wget -r -A.pdf https://overapi.com/git + +``` + +--- + +## 38. Kill all node processes + +### Description + +> Notes: + +###### code + +```bash +killall -s KILL node + +``` + +--- + +## 39. Remove string from file names recursively + +### Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories + +###### code + +```bash +find -type f -exec sed -i 's///g' {} + + +find . -type f -exec rename 's/-master//g' {} + + +``` + +> Notes: The same could be done for folder names by changing the *-type f* flag (for file) to a *-type d* flag (for directory) + +```bash +find -type d -exec sed -i 's///g' {} + + +find . -type d -exec rename 's/-master//g' {} + + +``` + +--- + +## 40. Remove spaces from file and folder names recursively + +### Description: replaces spaces in file and folder names with an `_` underscore + +> Notes: need to run `sudo apt install rename` to use this command + +###### code + +```bash + +find . -name "* *" -type d | rename 's/ /_/g' +find . -name "* *" -type f | rename 's/ /_/g' +``` + +--- + +## 41. Zip Each subdirectories in a given directory into their own zip file + +### Description + +> Notes: + +###### code + +```bash +for i in */; do zip -r "${i%/}.zip" "$i"; done + +``` + +--- + +## 91. Unzip PowerShell + +### Description + +> Notes: + +###### code + +```ps1 + +PARAM ( + [string] $ZipFilesPath = "./", + [string] $UnzipPath = "./RESULT" +) + +$Shell = New-Object -com Shell.Application +$Location = $Shell.NameSpace($UnzipPath) + +$ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP + +$progress = 1 +foreach ($ZipFile in $ZipFiles) { + Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" + $ZipFolder = $Shell.NameSpace($ZipFile.fullname) + + $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - https://msdn.microsoft.com/library/bb787866%28VS.85%29.aspx + $progress++ +} + +``` + +--- + +## 92. return to bash from zsh + +### Description + +> Notes: + +###### code + +```bash + sudo apt --purge remove zsh + +``` + +--- + +## 93. Symbolic Link + +### Description: to working directory + +> Notes: + +###### code + +```bash + +ln -s "$(pwd)" ~/NameOfLink + +ln -s "$(pwd)" ~/Downloads + +``` + +--- + +## 94. auto generate readme + +### Description: rename existing readme to blueprint.md + +> Notes: + +###### code + +```bash + +npx @appnest/readme generate + +``` + +--- + +## 95. Log into postgres + +### Description + +> Notes: + +###### code + +```bash +sudo -u postgres psql +``` + +--- + +## 96. URL To Subscribe To YouTube Channel + +| URL | | +| -------------------- | -------------------------------------------------------- | +| Miscellaneous | webpack ; Prism | +| Widgets | Facebook ; AddThis | +| Analytics | Moat ; Google Analytics ; Google Ads Conversion Tracking | +| Comment systems | Facebook API & REPL.it Database | +| Security | Netlify Access | +| Font scripts | Google Font API | +| CDN | Unpkg ; jsDelivr ; jQuery CDN ; Netlify | +| Marketing automation | MailChimp | +| Advertising | Google AdSense | +| Tag managers | Google Tag Manager | +| Live chat | Smartsupp ; LiveChat : Mesibo API | +| JavaScript libraries | Lodash ; Dojo ; core-js ; jQuery | + +--- + +## 96. URL To Subscribe To YouTube Channel + +## Description + +> Notes: + +###### code + +```txt + +https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1 + +``` + +--- + +## 97. Embed Repl.it In Medium Post + +###### code + +```txt + +https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com + +https://repl.it/@bgoonz/node-db1-project?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com + +https://repl.it/@bgoonz/interview-prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com + +https://repl.it/@bgoonz/Database-Prac?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com + +``` + +--- + +## 98 rRmove text target="parent" from files called right.html + +### Description + +> Notes: + +###### code + +```bash + +find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + + +find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + + +``` + +## 99. Cheat Sheet + +### Description + +> Notes: + +###### code + +```bash +#!/bin/bash +revert +## SHORTCUTS and HISTORY + + +CTRL+A # move to beginning of line +CTRL+B # moves backward one character +CTRL+C # halts the current command +CTRL+D # deletes one character backward or logs out of current session, similar to exit +CTRL+E # moves to end of line +CTRL+F # moves forward one character +CTRL+G # aborts the current editing command and ring the terminal bell +CTRL+H # deletes one character under cursor (same as DELETE) +CTRL+J # same as RETURN +CTRL+K # deletes (kill) forward to end of line +CTRL+L # clears screen and redisplay the line +CTRL+M # same as RETURN +CTRL+N # next line in command history +CTRL+O # same as RETURN, then displays next line in history file +CTRL+P # previous line in command history +CTRL+Q # resumes suspended shell output +CTRL+R # searches backward +CTRL+S # searches forward or suspends shell output +CTRL+T # transposes two characters +CTRL+U # kills backward from point to the beginning of line +CTRL+V # makes the next character typed verbatim +CTRL+W # kills the word behind the cursor +CTRL+X # lists the possible filename completions of the current word +CTRL+Y # retrieves (yank) last item killed +CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background + +ALT+B # moves backward one word +ALT+D # deletes next word +ALT+F # moves forward one word +ALT+H # deletes one character backward +ALT+T # transposes two words +ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. +ALT+U # capitalizes every character from the current cursor position to the end of the word +ALT+L # uncapitalizes every character from the current cursor position to the end of the word +ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. +ALT+R # reverts any changes to a command you've pulled from your history if you've edited it. +ALT+? # list possible completions to what is typed +ALT+^ # expand line to most recent match from history + +CTRL+X then ( # start recording a keyboard macro +CTRL+X then ) # finish recording keyboard macro +CTRL+X then E # recall last recorded keyboard macro +CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands + +BACKSPACE # deletes one character backward +DELETE # deletes one character under cursor + +history # shows command line history +!! # repeats the last command +! # refers to command line 'n' +! # refers to command starting with 'string' + +exit # logs out of current session + + +## BASH BASICS + + +env # displays all environment variables + +echo $SHELL # displays the shell you're using +echo $BASH_VERSION # displays bash version + +bash # if you want to use bash (type exit to go back to your previously opened shell) +whereis bash # locates the binary, source and manual-page for a command +which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) + +clear # clears content on window (hide displayed lines) + + +## FILE COMMANDS + + +ls # lists your files in current directory, ls to print files in a specific directory +ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified +ls -a # lists all files in 'long format', including hidden files (name beginning with '.') +ln -s # creates symbolic link to file +readlink # shows where a symbolic links points to +tree # show directories and subdirectories in easilly readable file tree +mc # terminal file explorer (alternative to ncdu) +touch # creates or updates (edit) your file +mktemp -t # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) +cat # prints file raw content (will not be interpreted) +any_command > # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) +more # shows the first part of a file (move with space and type q to quit) +head # outputs the first lines of file (default: 10 lines) +tail # outputs the last lines of file (useful with -f option) (default: 10 lines) +vim # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist +mv # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) +cp # copies a file +rm # removes a file +find . -name # searches for a file or a directory in the current directory and all its sub-directories by its name +diff # compares files, and shows where they differ +wc # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations +sort # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. +sort -t -k # sorts the contents on specific sort key field starting from 1, using the field separator t. +rev # reverse string characters (hello becomes olleh) +chmod -options # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) +gzip # compresses files using gzip algorithm +gunzip # uncompresses files compressed by gzip +gzcat # lets you look at gzipped file without actually having to gunzip it +lpr # prints the file +lpq # checks out the printer queue +lprm # removes something from the printer queue +genscript # converts plain text files into postscript for printing and gives you some options for formatting +dvips # prints .dvi files (i.e. files produced by LaTeX) +grep # looks for the string in the files +grep -r # search recursively for pattern in directory +head -n file_name | tail +n # Print nth line from file. +head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines. + + +## DIRECTORY COMMANDS + + +mkdir # makes a new directory +rmdir # remove an empty directory +rmdir -rf # remove a non-empty directory +mv # rename a directory from to +cd # changes to home +cd .. # changes to the parent directory +cd # changes directory +cp -r # copy into including sub-directories +pwd # tells you where you currently are +cd ~ # changes to home. +cd - # changes to previous working directory + + +## SSH, SYSTEM INFO & NETWORK COMMANDS + + +ssh user@host # connects to host as user +ssh -p user@host # connects to host on specified port as user +ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login + +whoami # returns your username +passwd # lets you change your password +quota -v # shows what your disk quota is +date # shows the current date and time +cal # shows the month's calendar +uptime # shows current uptime +w # displays whois online +finger # displays information about user +uname -a # shows kernel information +man # shows the manual for specified command +df # shows disk usage +du # shows the disk usage of the files and directories in filename (du -s give only a total) +last # lists your last logins +ps -u yourusername # lists your processes +kill # kills the processes with the ID you gave +killall # kill all processes with the name +top # displays your currently active processes +lsof # lists open files +bg # lists stopped or background jobs ; resume a stopped job in the background +fg # brings the most recent job in the foreground +fg # brings job to the foreground + +ping # pings host and outputs results +whois # gets whois information for domain +dig # gets DNS information for domain +dig -x # reverses lookup host +wget # downloads file + +time # report time consumed by command execution + + +## VARIABLES + + +varname=value # defines a variable +varname=value command # defines a variable to be in the environment of a particular subprocess +echo $varname # checks a variable's value +echo $$ # prints process ID of the current shell +echo $! # prints process ID of the most recently invoked background job +echo $? # displays the exit status of the last command +read # reads a string from the input and assigns it to a variable +read -p "prompt" # same as above but outputs a prompt to ask user for value +column -t # display info in pretty columns (often used with pipe) +let = # performs mathematical calculation using operators like +, -, *, /, % +export VARNAME=value # defines an environment variable (will be available in subprocesses) + +array[0]=valA # how to define an array +array[1]=valB +array[2]=valC +array=([2]=valC [0]=valA [1]=valB) # another way +array=(valA valB valC) # and another + +${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed +${#array[i]} # to find out the length of any element in the array +${#array[@]} # to find out how many values there are in the array + +declare -a # the variables are treated as arrays +declare -f # uses function names only +declare -F # displays function names without definitions +declare -i # the variables are treated as integers +declare -r # makes the variables read-only +declare -x # marks the variables for export via the environment + +${varname:-word} # if varname exists and isn't null, return its value; otherwise return word +${varname:word} # if varname exists and isn't null, return its value; otherwise return word +${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value +${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script +${varname:+word} # if varname exists and isn't null, return word; otherwise return null +${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters + +${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest +${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest +${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest +${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest +${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced +${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced + +${#varname} # returns the length of the value of the variable as a character string + +*(patternlist) # matches zero or more occurrences of the given patterns ++(patternlist) # matches one or more occurrences of the given patterns +?(patternlist) # matches zero or one occurrence of the given patterns +@(patternlist) # matches exactly one of the given patterns +!(patternlist) # matches anything except one of the given patterns + +$(UNIX command) # command substitution: runs the command and returns standard output + + +## FUNCTIONS + + +## The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth. +## $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters. + +function functname() { + shell commands +} + +unset -f functname # deletes a function definition +declare -f # displays all defined functions in your login session + + +## FLOW CONTROLS + + +statement1 && statement2 # and operator +statement1 || statement2 # or operator + +-a # and operator inside a test conditional expression +-o # or operator inside a test conditional expression + +## STRINGS + +str1 == str2 # str1 matches str2 +str1 != str2 # str1 does not match str2 +str1 < str2 # str1 is less than str2 (alphabetically) +str1 > str2 # str1 is greater than str2 (alphabetically) +str1 \> str2 # str1 is sorted after str2 +str1 \< str2 # str1 is sorted before str2 +-n str1 # str1 is not null (has length greater than 0) +-z str1 # str1 is null (has length 0) + +## FILES + +-a file # file exists or its compilation is successful +-d file # file exists and is a directory +-e file # file exists; same -a +-f file # file exists and is a regular file (i.e., not a directory or other special type of file) +-r file # you have read permission +-s file # file exists and is not empty +-w file # your have write permission +-x file # you have execute permission on file, or directory search permission if it is a directory +-N file # file was modified since it was last read +-O file # you own file +-G file # file's group ID matches yours (or one of yours, if you are in multiple groups) +file1 -nt file2 # file1 is newer than file2 +file1 -ot file2 # file1 is older than file2 + +## NUMBERS + +-lt # less than +-le # less than or equal +-eq # equal +-ge # greater than or equal +-gt # greater than +-ne # not equal + +if condition +then + statements +[elif condition + then statements...] +[else + statements] +fi + +for x in {1..10} +do + statements +done + +for name [in list] +do + statements that can use $name +done + +for (( initialisation ; ending condition ; update )) +do + statements... +done + +case expression in + pattern1 ) + statements ;; + pattern2 ) + statements ;; +esac + +select name [in list] +do + statements that can use $name +done + +while condition; do + statements +done + +until condition; do + statements +done + + +## COMMAND-LINE PROCESSING CYCLE + + +## The default order for command lookup is functions, followed by built-ins, with scripts and executables last. +## There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`. + +command # removes alias and function lookup. Only built-ins and commands found in the search path are executed +builtin # looks up only built-in commands, ignoring functions and commands found in PATH +enable # enables and disables shell built-ins + +eval # takes arguments and run them through the command-line processing steps all over again + + +## INPUT/OUTPUT REDIRECTORS + + +cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 +< file # takes standard input from file +> file # directs standard output to file +>> file # directs standard output to file; append to file if it already exists +>|file # forces standard output to file even if noclobber is set +n>|file # forces output to file from file descriptor n even if noclobber is set +<> file # uses file as both standard input and standard output +n<>file # uses file as both input and output for file descriptor n +n>file # directs file descriptor n to file +n>file # directs file description n to file; append to file if it already exists +n>& # duplicates standard output to file descriptor n +n<& # duplicates standard input from file descriptor n +n>&m # file descriptor n is made to be a copy of the output file descriptor +n<&m # file descriptor n is made to be a copy of the input file descriptor +&>file # directs standard output and standard error to file +<&- # closes the standard input +>&- # closes the standard output +n>&- # closes the ouput from file descriptor n +n<&- # closes the input from file descripor n + +|tee # output command to both terminal and a file (-a to append to file) + + +## PROCESS HANDLING + + +## To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y. +## This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal. +## Of course, to interrupt a job, type CTRL+C. + +myCommand & # runs job in the background and prompts back the shell + +jobs # lists all jobs (use with -l to see associated PID) + +fg # brings a background job into the foreground +fg %+ # brings most recently invoked background job +fg %- # brings second most recently invoked background job +fg %N # brings job number N +fg %string # brings job whose command begins with string +fg %?string # brings job whose command contains string + +kill -l # returns a list of all signals on the system, by name and number +kill PID # terminates process with specified PID +kill -s SIGKILL 4500 # sends a signal to force or terminate the process +kill -15 913 # Ending PID 913 process with signal 15 (TERM) +kill %1 # Where %1 is the number of job as read from 'jobs' command. + +ps # prints a line of information about the current running login shell and any processes running under it +ps -a # selects all processes with a tty except session leaders + +trap cmd sig1 sig2 # executes a command when a signal is received by the script +trap "" sig1 sig2 # ignores that signals +trap - sig1 sig2 # resets the action taken when the signal is received to the default + +disown # removes the process from the list of jobs + +wait # waits until all background jobs have finished +sleep # wait # of seconds before continuing + +pv # display progress bar for data handling commands. often used with pipe like |pv +yes # give yes response everytime an input is requested from script/process + + +## TIPS & TRICKS + + +## set an alias +cd; nano .bash_profile +> alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile + +## to quickly go to a specific directory +cd; nano .bashrc +> shopt -s cdable_vars +> export websites="/Users/mac/Documents/websites" + +source .bashrc +cd $websites + + +## DEBUGGING SHELL PROGRAMS + + +bash -n scriptname # don't run commands; check for syntax errors only +set -o noexec # alternative (set option in script) + +bash -v scriptname # echo commands before running them +set -o verbose # alternative (set option in script) + +bash -x scriptname # echo commands after command-line processing +set -o xtrace # alternative (set option in script) + +trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits + +function errtrap { + es=$? + echo "ERROR line $1: Command exited with status $es." +} + +trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status + +function dbgtrap { + echo "badvar is $badvar" +} + +trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script +## ...section of code in which the problem occurs... +trap - DEBUG # turn off the DEBUG trap + +function returntrap { + echo "A return occurred" +} + +trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing + + +## COLORS AND BACKGROUNDS + +## note: \e or \x1B also work instead of \033 +## Reset +Color_Off='\033[0m' # Text Reset + +## Regular Colors +Black='\033[0;30m' # Black +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Blue='\033[0;34m' # Blue +Purple='\033[0;35m' # Purple +Cyan='\033[0;36m' # Cyan +White='\033[0;97m' # White + +## Additional colors +LGrey='\033[0;37m' # Ligth Gray +DGrey='\033[0;90m' # Dark Gray +LRed='\033[0;91m' # Ligth Red +LGreen='\033[0;92m' # Ligth Green +LYellow='\033[0;93m'# Ligth Yellow +LBlue='\033[0;94m' # Ligth Blue +LPurple='\033[0;95m'# Light Purple +LCyan='\033[0;96m' # Ligth Cyan + +## Bold +BBlack='\033[1;30m' # Black +BRed='\033[1;31m' # Red +BGreen='\033[1;32m' # Green +BYellow='\033[1;33m'# Yellow +BBlue='\033[1;34m' # Blue +BPurple='\033[1;35m'# Purple +BCyan='\033[1;36m' # Cyan +BWhite='\033[1;37m' # White + +## Underline +UBlack='\033[4;30m' # Black +URed='\033[4;31m' # Red +UGreen='\033[4;32m' # Green +UYellow='\033[4;33m'# Yellow +UBlue='\033[4;34m' # Blue +UPurple='\033[4;35m'# Purple +UCyan='\033[4;36m' # Cyan +UWhite='\033[4;37m' # White + +## Background +On_Black='\033[40m' # Black +On_Red='\033[41m' # Red +On_Green='\033[42m' # Green +On_Yellow='\033[43m'# Yellow +On_Blue='\033[44m' # Blue +On_Purple='\033[45m'# Purple +On_Cyan='\033[46m' # Cyan +On_White='\033[47m' # White + +## Example of usage +echo -e "${Green}This is GREEN text${Color_Off} and normal text" +echo -e "${Red}${On_White}This is Red test on White background${Color_Off}" +## option -e is mandatory, it enable interpretation of backslash escapes +printf "${Red} This is red \n" + +``` + +
    + +> + +#### Find + +## To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG) + +find . -iname "\*.jpg" + +## To find directories + +find . -type d + +## To find files + +find . -type f + +## To find files by octal permission + +find . -type f -perm 777 + +## To find files with setuid bit set + +find . -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l + +## To find files with extension '.txt' and remove them + +find ./path/ -name '\*.txt' -exec rm '{}' \; + +## To find files with extension '.txt' and look for a string into them + +find ./path/ -name '\*.txt' | xargs grep 'string' + +## To find files with size bigger than 5 Mebibyte and sort them by size + +find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z + +## To find files bigger than 2 Megabyte and list them + +find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }' + +## To find files modified more than 7 days ago and list file information + +find . -type f -mtime +7d -ls + +## To find symlinks owned by a user and list file information + +find . -type l -user -ls + +## To search for and delete empty directories + +find . -type d -empty -exec rmdir {} \; + +## To search for directories named build at a max depth of 2 directories + +find . -maxdepth 2 -name build -type d + +## To search all files who are not in .git directory + +find . ! -iwholename '*.git*' -type f + +## To find all files that have the same node (hard link) as MY_FILE_HERE + +find . -type f -samefile MY_FILE_HERE 2>/dev/null + +## To find all files in the current directory and modify their permissions + +find . -type f -exec chmod 644 {} \; + +--- + +
    + +--- + +![Preview](https://i.imgur.com/nieW1vp.png) + + +## Wiki Nav + + +- [Home](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) +- [add copy to code blocks.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/add-copy-to-code-blocks.md) +- [Add site search w algolia.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Add-site-search-w-algolia.md) +- [adding mailing list.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/adding-mailing-list.md) +- [Adding search 2 gatsby site.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Adding-search-2-gatsby-site.md) +- [awesome.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/awesome.md) +- [broken links.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/broken-links.md) +- [configure custom domain.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/configure-custom-domain.md) +- [contentauthoring.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/contentauthoring.md) +- [full text search w lunar.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/full-text-search-w-lunar.md) +- [inject 4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject-4.md) +- [inject3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject3.md) +- [inject4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/inject4.md) +- [injected content part2.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-content-part2.md) +- [injected js part4.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-js-part4.md) +- [injected part3.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/injected-part3.md) +- [links 2 embed.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-2-embed.md) +- [links to remember](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/links-to-remember) +- [Netlify Injected Content](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Netlify-Injected-Content) +- [old version of index.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/old-version-of-index.md) +- [optimize vscode.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/optimize-vscode.md) +- [possibly useful snippets.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/possibly-useful-snippets.md) +- [privacy policy.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/privacy-policy.md) +- [random stuff.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random-stuff.md) +- [random.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/random.md) +- [ref type](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/ref-type) +- [SEO.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/SEO.md) +- [stable points.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/stable-points.md) +- [tech used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/tech-used.md) +- [Technologies Used.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/Technologies-Used.md) +- [THINGS TO EMBED.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/THINGS-TO-EMBED.md) +- [validation report.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/validation-report.md) +- [web archive.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/web-archive.md) +- [wordpress vs headless cms.md](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki/wordpress-vs-headless-cms.md) + + +--- + +## Dependencies + + +
    + Click to expand! + +[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-search +`^ 4.10.3` + +[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/client-common +`4.10.5` + +![@ghost**](https://avatars.githubusercontent.com/u/10137?s=40&v=4)@algolia/requester-common +`4.10.5` + +[![@algolia**](https://avatars.githubusercontent.com/u/2034458?s=40&v=4)](https://github.com/algolia)[algolia / algoliasearch-client-javascript](https://github.com/algolia/algoliasearch-client-javascript)@algolia/transporter +`4.10.5` + +[![@stackbit**](https://avatars.githubusercontent.com/u/38996451?s=40&v=4)](https://github.com/stackbit)[stackbit / gatsby-plugin-menus](https://github.com/stackbit/gatsby-plugin-menus)@stackbit/gatsby-plugin-menus +`0.0.4` + +[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest)babel-jest +`^ 24.7.1` + +[![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby)babel-preset-gatsby +`^ 0.1.11` + +[![@gatsbyjs**](https://avatars.githubusercontent.com/u/12551863?s=40&v=4)](https://github.com/gatsbyjs)[gatsbyjs / gatsby](https://github.com/gatsbyjs/gatsby) `^ 2.5.0` + +[![@keyz**](https://avatars.githubusercontent.com/u/2268452?s=40&u=c3f56fe1d943474ffe4577a82ad79c1a79d7eb6e&v=4)](https://github.com/keyz)[keyz / identity-obj-proxy](https://github.com/keyz/identity-obj-proxy) `^ 3.0.0` + +[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / jest](https://github.com/facebook/jest) `^ 24.7.1` + +[![@lodash**](https://avatars.githubusercontent.com/u/2565403?s=40&v=4)](https://github.com/lodash)[lodash / lodash](https://github.com/lodash/lodash) `^ 4.17.11` + +[![@facebook**](https://avatars.githubusercontent.com/u/69631?s=40&v=4)](https://github.com/facebook)[facebook / react](https://github.com/facebook/react)react-test-renderer +`^ 16.8.6` + +[![@getkirby-v2**](https://avatars.githubusercontent.com/u/6985611?s=40&v=4)](https://github.com/getkirby-v2)[getkirby-v2 / algolia-plugin](https://github.com/getkirby-v2/algolia-plugin)algolia +`0.0.0` + +[![@ecomfe**](https://avatars.githubusercontent.com/u/2268460?s=40&v=4)](https://github.com/ecomfe)[ecomfe / babel-runtime](https://github.com/ecomfe/babel-runtime) `6.26.0` + +[![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / chokidar](https://github.com/paulmillr/chokidar) `3.4.0` + +[![@DefinitelyTyped**](https://avatars.githubusercontent.com/u/3637556?s=40&v=4)](https://github.com/DefinitelyTyped)[DefinitelyTyped / DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)@types/node +`^ 13` + +[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / anymatch](https://github.com/micromatch/anymatch) `~ 3.1.1` + +[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / braces](https://github.com/micromatch/braces) `~ 3.0.2` + +[![@chaijs**](https://avatars.githubusercontent.com/u/1515293?s=40&v=4)](https://github.com/chaijs)[chaijs / chai](https://github.com/chaijs/chai) `^ 4.2` + +[![@microsoft**](https://avatars.githubusercontent.com/u/6154722?s=40&v=4)](https://github.com/microsoft)[microsoft / dtslint](https://github.com/microsoft/dtslint) `^ 3.3.0` + +[![@eslint**](https://avatars.githubusercontent.com/u/6019716?s=40&v=4)](https://github.com/eslint)[eslint / eslint](https://github.com/eslint/eslint) `^ 6.6.0` + +[![@fsevents**](https://avatars.githubusercontent.com/u/48760001?s=40&v=4)](https://github.com/fsevents)[fsevents / fsevents](https://github.com/fsevents/fsevents) `~ 2.1.2` + +[![@gulpjs**](https://avatars.githubusercontent.com/u/6200624?s=40&v=4)](https://github.com/gulpjs)[gulpjs / glob-parent](https://github.com/gulpjs/glob-parent) `~ 5.1.0` + +[![@sindresorhus**](https://avatars.githubusercontent.com/u/170270?s=40&u=34acd557a042ac478d273a4621570cadb6b0bd89&v=4)](https://github.com/sindresorhus)[sindresorhus / is-binary-path](https://github.com/sindresorhus/is-binary-path) `~ 2.1.0` + +[![@micromatch**](https://avatars.githubusercontent.com/u/26890389?s=40&v=4)](https://github.com/micromatch)[micromatch / is-glob](https://github.com/micromatch/is-glob) `~ 4.0.1` + +[![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 7.0.0` + +[![@jonschlinkert**](https://avatars.githubusercontent.com/u/383994?s=40&u=335f06277f72722162e89bd5516849f2e82f37cf&v=4)](https://github.com/jonschlinkert)[jonschlinkert / normalize-path](https://github.com/jonschlinkert/normalize-path) `~ 3.0.0` + +[![@istanbuljs**](https://avatars.githubusercontent.com/u/13523395?s=40&v=4)](https://github.com/istanbuljs)[istanbuljs / nyc](https://github.com/istanbuljs/nyc) `^ 15.0.0` + +[![@paulmillr**](https://avatars.githubusercontent.com/u/574696?s=40&u=7f4396380d73af134b898c8eaf7bb171f448f40f&v=4)](https://github.com/paulmillr)[paulmillr / readdirp](https://github.com/paulmillr/readdirp) `~ 3.4.0` + +[![@isaacs**](https://avatars.githubusercontent.com/u/9287?s=40&u=60a280618307ae965cadbe52da4baa7e351c848c&v=4)](https://github.com/isaacs)[isaacs / rimraf](https://github.com/isaacs/rimraf) `^ 3.0.0` + +[![@sinonjs**](https://avatars.githubusercontent.com/u/6570253?s=40&v=4)](https://github.com/sinonjs)[sinonjs / sinon](https://github.com/sinonjs/sinon) `^ 9.0.1` + +[![@domenic**](https://avatars.githubusercontent.com/u/617481?s=40&v=4)](https://github.com/domenic)[domenic / sinon-chai](https://github.com/domenic/sinon-chai) `^ 3.3.0` + +[![@anodynos**](https://avatars.githubusercontent.com/u/856453?s=40&v=4)](https://github.com/anodynos)[anodynos / upath](https://github.com/anodynos/upath) `^ 1.2.0` + +[![@JedWatson**](https://avatars.githubusercontent.com/u/872310?s=40&u=9548676d01f104232ee42e5ac0d985db77e6a5a4&v=4)](https://github.com/JedWatson)[JedWatson / classnames](https://github.com/JedWatson/classnames) `2.2.6` + +[![@bestiejs**](https://avatars.githubusercontent.com/u/802850?s=40&v=4)](https://github.com/bestiejs)[bestiejs / benchmark.js](https://github.com/bestiejs/benchmark.js)benchmark +`^ 1.0.0` + +[![@browserify**](https://avatars.githubusercontent.com/u/6320506?s=40&v=4)](https://github.com/browserify)[browserify / browserify](https://github.com/browserify/browserify) `^ 14.1.0` + +[![@mochajs**](https://avatars.githubusercontent.com/u/8770005?s=40&v=4)](https://github.com/mochajs)[mochajs / mocha](https://github.com/mochajs/mocha) `^ 2.1.0` + +[![@jeromedecoster**](https://avatars.githubusercontent.com/u/158071?s=40&u=470a733fdc34a9fedab18ae4cf5109d2ea357425&v=4)](https://github.com/jeromedecoster)[jeromedecoster / opn-cli](https://github.com/jeromedecoster/opn-cli) `^ 3.1.0` + +[![@documentationjs**](https://avatars.githubusercontent.com/u/11415556?s=40&v=4)](https://github.com/documentationjs)[documentationjs / documentation](https://github.com/documentationjs/documentation) `^ 13.2.5` + +[![@babel**](https://avatars.githubusercontent.com/u/9637642?s=40&v=4)](https://github.com/babel)[babel / babel](https://github.com/babel/babel)@babel/core +`7.12.3` + +↞↠ Search Website: [search](https://www.algolia.com/realtime-search-demo/web-dev-resource-hub-9e6b8aa8-6106-44c5-9f59-ff3f9531abd4) ↞↠ [Backup Repo Deploy](https://bgoonzblog20-backup.netlify.app/#gsc.tab=0) ↞↠ [Github pages](https://bgoonz.github.io/BGOONZ_BLOG_2.0/) + +↞↠ [Go To Site Wiki](https://github.com/bgoonz/BGOONZ_BLOG_2.0/wiki) + +## Docs Structure + + +
    + Docs Structure + +``` +├── blog +│ ├── 300-react-questions.md +│ ├── awesome-graphql.md +│ ├── big-o-complexity.md +│ ├── blog-archive.md +│ ├── blogwcomments.md +│ ├── data-structures.md +│ ├── flow-control-in-python.md +│ ├── functions-in-python.md +│ ├── git-gateway.md +│ ├── index.md +│ ├── interview-questions-js.md +│ ├── netlify-cms.md +│ ├── platform-docs.md +│ ├── python-for-js-dev.md +│ ├── python-resources.md +│ ├── web-dev-trends.md +│ └── web-scraping.md +├── docs +│ ├── about +│ │ ├── eng-portfolio.md +│ │ ├── ideas-for-this-website.md +│ │ ├── index.md +│ │ ├── intrests.md +│ │ ├── job-search.md +│ │ └── resume.md +│ ├── articles +│ │ ├── basic-web-dev.md +│ │ ├── buffers.md +│ │ ├── dev-dep.md +│ │ ├── event-loop.md +│ │ ├── fs-module.md +│ │ ├── how-the-web-works.md +│ │ ├── http.md +│ │ ├── index.md +│ │ ├── install.md +│ │ ├── intro.md +│ │ ├── modules.md +│ │ ├── nextjs.md +│ │ ├── node-api-express.md +│ │ ├── node-cli-args.md +│ │ ├── node-common-modules.md +│ │ ├── node-env-variables.md +│ │ ├── node-js-language.md +│ │ ├── node-package-manager.md +│ │ ├── node-repl.md +│ │ ├── node-run-cli.md +│ │ ├── nodejs.md +│ │ ├── nodevsbrowser.md +│ │ ├── npm.md +│ │ ├── npx.md +│ │ ├── os-module.md +│ │ ├── reading-files.md +│ │ ├── semantic-html.md +│ │ ├── semantic.md +│ │ ├── the-uniform-resource-locator-(url).md +│ │ ├── understanding-firebase.md +│ │ ├── v8.md +│ │ ├── web-standards-checklist.md +│ │ ├── webdev-tools.md +│ │ └── writing-files.md +│ ├── audio +│ │ ├── audio-feature-extraction.md +│ │ ├── audio.md +│ │ ├── dfft.md +│ │ ├── discrete-fft.md +│ │ ├── dtw-python-explained.md +│ │ ├── dynamic-time-warping.md +│ │ ├── index.md +│ │ └── web-audio-api.md +│ ├── career +│ │ ├── dev-interview.md +│ │ ├── index.md +│ │ ├── interview-dos-n-donts.md +│ │ └── job-boards.md +│ ├── community +│ │ ├── an-open-letter-2-future-developers.md +│ │ ├── index.md +│ │ └── video-chat.md +│ ├── content +│ │ ├── algo.md +│ │ ├── archive.md +│ │ ├── gatsby-Queries-Mutations.md +│ │ ├── history-api.md +│ │ ├── index.md +│ │ ├── main-projects.md +│ │ └── trouble-shooting.md +│ ├── data-structures +│ │ └── index.md +│ ├── docs +│ │ ├── appendix.md +│ │ ├── art-of-command-line.md +│ │ ├── bash.md +│ │ ├── content.md +│ │ ├── css.md +│ │ ├── data-structures-docs.md +│ │ ├── es-6-features.md +│ │ ├── git-reference.md +│ │ ├── git-repos.md +│ │ ├── html-spec.md +│ │ ├── index.md +│ │ ├── markdown.md +│ │ ├── no-whiteboarding.md +│ │ ├── node-docs-complete.md +│ │ ├── node-docs-full.md +│ │ ├── regex-in-js.md +│ │ └── sitemap.md +│ ├── faq +│ │ ├── contact.md +│ │ ├── index.md +│ │ └── plug-ins.md +│ ├── gists.md +│ ├── index.md +│ ├── interact +│ │ ├── callstack-visual.md +│ │ ├── clock.md +│ │ ├── index.md +│ │ ├── jupyter-notebooks.md +│ │ ├── other-sites.md +│ │ └── video-chat.md +│ ├── interview +│ │ ├── index.md +│ │ ├── job-search-nav.md +│ │ └── review-concepts.md +│ ├── javascript +│ │ ├── arrow-functions.md +│ │ ├── asyncjs.md +│ │ ├── await-keyword.md +│ │ ├── bigo.md +│ │ ├── clean-code.md +│ │ ├── constructor-functions.md +│ │ ├── index.md +│ │ ├── promises.md +│ │ ├── review.md +│ │ └── this-is-about-this.md +│ ├── leetcode +│ │ └── index.md +│ ├── privacy-policy.md +│ ├── projects +│ │ ├── embeded-websites.md +│ │ ├── index.md +│ │ ├── list-of-projects.md +│ │ ├── mini-projects.md +│ │ └── my-websites.md +│ ├── python +│ │ ├── at-length.md +│ │ ├── cheat-sheet.md +│ │ ├── comprehensive-guide.md +│ │ ├── examples.md +│ │ ├── flow-control.md +│ │ ├── functions.md +│ │ ├── google-sheets-api.md +│ │ ├── index.md +│ │ ├── intro-for-js-devs.md +│ │ ├── python-ds.md +│ │ └── snippets.md +│ ├── quick-reference +│ │ ├── Emmet.md +│ │ ├── all-emojis.md +│ │ ├── create-react-app.md +│ │ ├── git-bash.md +│ │ ├── git-tricks.md +│ │ ├── google-firebase.md +│ │ ├── heroku-error-codes.md +│ │ ├── index.md +│ │ ├── installation.md +│ │ ├── markdown-dropdowns.md +│ │ ├── minifiction.md +│ │ ├── new-repo-instructions.md +│ │ ├── psql-setup.md +│ │ ├── pull-request-rubric.md +│ │ ├── quick-links.md +│ │ ├── topRepos.md +│ │ ├── understanding-path.md +│ │ └── vscode-themes.md +│ ├── react +│ │ ├── ajax-n-apis.md +│ │ ├── cheatsheet.md +│ │ ├── createReactApp.md +│ │ ├── demo.md +│ │ ├── dont-use-index-as-keys.md +│ │ ├── index.md +│ │ ├── jsx.md +│ │ ├── react-docs.md +│ │ ├── react-in-depth.md +│ │ ├── react2.md +│ │ └── render-elements.md +│ ├── reference +│ │ ├── awesome-lists.md +│ │ ├── awesome-static.md +│ │ ├── bash-commands.md +│ │ ├── bookmarks.md +│ │ ├── embed-the-web.md +│ │ ├── github-search.md +│ │ ├── google-cloud.md +│ │ ├── how-2-reinstall-npm.md +│ │ ├── how-to-kill-a-process.md +│ │ ├── index.md +│ │ ├── installing-node.md +│ │ ├── intro-to-nodejs.md +│ │ ├── notes-template.md +│ │ ├── psql.md +│ │ ├── resources.md +│ │ ├── vscode.md +│ │ └── web-api's.md +│ ├── search.md +│ ├── sitemap.md +│ ├── tips +│ │ ├── array-methods.md +│ │ ├── index.md +│ │ └── insert-into-array.md +│ ├── tools +│ │ ├── Archive.md +│ │ ├── data-structures.md +│ │ ├── dev-utilities.md +│ │ ├── index.md +│ │ └── markdown-html.md +│ └── tutorials +│ ├── enviorment-setup.md +│ └── index.md +├── index.md +├── privacy-policy.md +├── readme.md +├── showcase.md +└── tree.md + +23 directories, 202 files + +``` + +## SITEMAP + +docky ./../src/components/pages/**/*.md \ # specify the components to parse + --watch "./../src/components/**/*.js","./README.md" \ # watch files + --ignore "src/components/**/index.js" \ # ignored files + --use-readme=true + +[**🌍⇒blog🗺️**](https://bgoonz-blog.netlify.app/blog) + +[**🌍⇒docs🗺️**](https://bgoonz-blog.netlify.app/docs) + +[**🌍⇒readme🗺️**](https://bgoonz-blog.netlify.app/readme) + +[**🌍⇒review🗺️**](https://bgoonz-blog.netlify.app/review) + +[**🌍⇒showcase🗺️**](https://bgoonz-blog.netlify.app/showcase) + +``` + +# SITEMAP + +- [https://bgoonz-blog.netlify.app/](https://bgoonz-blog.netlify.app/) + +- [https://bgoonz-blog.netlify.app/admin](https://bgoonz-blog.netlify.app/admin) +- [https://bgoonz-blog.netlify.app/blog](https://bgoonz-blog.netlify.app/blog) +- [https://bgoonz-blog.netlify.app/blog/10-essential-react-interview-questions](https://bgoonz-blog.netlify.app/blog/10-essential-react-interview-questions) +- [https://bgoonz-blog.netlify.app/blog/300-react-questions](https://bgoonz-blog.netlify.app/blog/300-react-questions) +- [https://bgoonz-blog.netlify.app/blog/adding-css-to-your-html](https://bgoonz-blog.netlify.app/blog/adding-css-to-your-html) +- [https://bgoonz-blog.netlify.app/blog/awesome-graphql](https://bgoonz-blog.netlify.app/blog/awesome-graphql) +- [https://bgoonz-blog.netlify.app/blog/beginners-guide-to-python](https://bgoonz-blog.netlify.app/blog/beginners-guide-to-python) +- [https://bgoonz-blog.netlify.app/blog/big-o-complexity](https://bgoonz-blog.netlify.app/blog/big-o-complexity) +- [https://bgoonz-blog.netlify.app/blog/blog-archive](https://bgoonz-blog.netlify.app/blog/blog-archive) +- [https://bgoonz-blog.netlify.app/blog/code-playgrounds-of-2021](https://bgoonz-blog.netlify.app/blog/code-playgrounds-of-2021) +- [https://bgoonz-blog.netlify.app/blog/data-structures](https://bgoonz-blog.netlify.app/blog/data-structures) +- [https://bgoonz-blog.netlify.app/blog/data-structures-algorithms-resources](https://bgoonz-blog.netlify.app/blog/data-structures-algorithms-resources) +- [https://bgoonz-blog.netlify.app/blog/deploy-react-app-to-heroku](https://bgoonz-blog.netlify.app/blog/deploy-react-app-to-heroku) +- [https://bgoonz-blog.netlify.app/blog/embedding-media-in-html](https://bgoonz-blog.netlify.app/blog/embedding-media-in-html) +- [https://bgoonz-blog.netlify.app/blog/eslint-rules](https://bgoonz-blog.netlify.app/blog/eslint-rules) +- [https://bgoonz-blog.netlify.app/blog/event-handeling](https://bgoonz-blog.netlify.app/blog/event-handeling) +- [https://bgoonz-blog.netlify.app/blog/expressjs-apis](https://bgoonz-blog.netlify.app/blog/expressjs-apis) +- [https://bgoonz-blog.netlify.app/blog/file-system-route-api](https://bgoonz-blog.netlify.app/blog/file-system-route-api) +- [https://bgoonz-blog.netlify.app/blog/flow-control-in-python](https://bgoonz-blog.netlify.app/blog/flow-control-in-python) +- [https://bgoonz-blog.netlify.app/blog/front-end-interview-questions-part-2](https://bgoonz-blog.netlify.app/blog/front-end-interview-questions-part-2) +- [https://bgoonz-blog.netlify.app/blog/functions-in-python](https://bgoonz-blog.netlify.app/blog/functions-in-python) +- [https://bgoonz-blog.netlify.app/blog/gatsby-cli](https://bgoonz-blog.netlify.app/blog/gatsby-cli) +- [https://bgoonz-blog.netlify.app/blog/git-gateway](https://bgoonz-blog.netlify.app/blog/git-gateway) +- [https://bgoonz-blog.netlify.app/blog/google-analytics](https://bgoonz-blog.netlify.app/blog/google-analytics) +- [https://bgoonz-blog.netlify.app/blog/grep-in-linuz](https://bgoonz-blog.netlify.app/blog/grep-in-linuz) +- [https://bgoonz-blog.netlify.app/blog/hoisting](https://bgoonz-blog.netlify.app/blog/hoisting) +- [https://bgoonz-blog.netlify.app/blog/htt-requests](https://bgoonz-blog.netlify.app/blog/htt-requests) +- [https://bgoonz-blog.netlify.app/blog/interview-questions-js](https://bgoonz-blog.netlify.app/blog/interview-questions-js) +- [https://bgoonz-blog.netlify.app/blog/interview-questions-js-p2](https://bgoonz-blog.netlify.app/blog/interview-questions-js-p2) +- [https://bgoonz-blog.netlify.app/blog/interview-questions-js-p3](https://bgoonz-blog.netlify.app/blog/interview-questions-js-p3) +- [https://bgoonz-blog.netlify.app/blog/intro-01-data-structures](https://bgoonz-blog.netlify.app/blog/intro-01-data-structures) +- [https://bgoonz-blog.netlify.app/blog/intro-to-markdown](https://bgoonz-blog.netlify.app/blog/intro-to-markdown) +- [https://bgoonz-blog.netlify.app/blog/jsx-in-depth](https://bgoonz-blog.netlify.app/blog/jsx-in-depth) +- [https://bgoonz-blog.netlify.app/blog/netlify-cms](https://bgoonz-blog.netlify.app/blog/netlify-cms) +- [https://bgoonz-blog.netlify.app/blog/passing-arguments-to-a-callback-in-js](https://bgoonz-blog.netlify.app/blog/passing-arguments-to-a-callback-in-js) +- [https://bgoonz-blog.netlify.app/blog/platform-docs](https://bgoonz-blog.netlify.app/blog/platform-docs) +- [https://bgoonz-blog.netlify.app/blog/psql-cheat-sheet](https://bgoonz-blog.netlify.app/blog/psql-cheat-sheet) +- [https://bgoonz-blog.netlify.app/blog/python-for-js-dev](https://bgoonz-blog.netlify.app/blog/python-for-js-dev) +- [https://bgoonz-blog.netlify.app/blog/python-quiz](https://bgoonz-blog.netlify.app/blog/python-quiz) +- [https://bgoonz-blog.netlify.app/blog/python-resources](https://bgoonz-blog.netlify.app/blog/python-resources) +- [https://bgoonz-blog.netlify.app/blog/react-fragments](https://bgoonz-blog.netlify.app/blog/react-fragments) +- [https://bgoonz-blog.netlify.app/blog/react-semantics](https://bgoonz-blog.netlify.app/blog/react-semantics) +- [https://bgoonz-blog.netlify.app/blog/react-state](https://bgoonz-blog.netlify.app/blog/react-state) +- [https://bgoonz-blog.netlify.app/blog/useful-stock-images](https://bgoonz-blog.netlify.app/blog/useful-stock-images) +- [https://bgoonz-blog.netlify.app/blog/using-the-dom](https://bgoonz-blog.netlify.app/blog/using-the-dom) +- [https://bgoonz-blog.netlify.app/blog/vs-code-extensions](https://bgoonz-blog.netlify.app/blog/vs-code-extensions) +- [https://bgoonz-blog.netlify.app/blog/vscode-extensions](https://bgoonz-blog.netlify.app/blog/vscode-extensions) +- [https://bgoonz-blog.netlify.app/blog/web-dev-trends](https://bgoonz-blog.netlify.app/blog/web-dev-trends) +- [https://bgoonz-blog.netlify.app/blog/web-scraping](https://bgoonz-blog.netlify.app/blog/web-scraping) +- [https://bgoonz-blog.netlify.app/blog/webdev-setup](https://bgoonz-blog.netlify.app/blog/webdev-setup) +- [https://bgoonz-blog.netlify.app/blog/what-is-a-redux-reducer](https://bgoonz-blog.netlify.app/blog/what-is-a-redux-reducer) +- [https://bgoonz-blog.netlify.app/blog/wordpress-vs-headless-cms](https://bgoonz-blog.netlify.app/blog/wordpress-vs-headless-cms) +- [https://bgoonz-blog.netlify.app/docs](https://bgoonz-blog.netlify.app/docs) +- [https://bgoonz-blog.netlify.app/docs/about](https://bgoonz-blog.netlify.app/docs/about) +- [https://bgoonz-blog.netlify.app/docs/about/eng-portfolio](https://bgoonz-blog.netlify.app/docs/about/eng-portfolio) +- [https://bgoonz-blog.netlify.app/docs/about/internal-use](https://bgoonz-blog.netlify.app/docs/about/internal-use) +- [https://bgoonz-blog.netlify.app/docs/about/intrests](https://bgoonz-blog.netlify.app/docs/about/intrests) +- [https://bgoonz-blog.netlify.app/docs/about/job-search](https://bgoonz-blog.netlify.app/docs/about/job-search) +- [https://bgoonz-blog.netlify.app/docs/about/readme](https://bgoonz-blog.netlify.app/docs/about/readme) +- [https://bgoonz-blog.netlify.app/docs/about/resume](https://bgoonz-blog.netlify.app/docs/about/resume) +- [https://bgoonz-blog.netlify.app/docs/archive](https://bgoonz-blog.netlify.app/docs/archive) +- [https://bgoonz-blog.netlify.app/docs/archive/embeded-websites](https://bgoonz-blog.netlify.app/docs/archive/embeded-websites) +- [https://bgoonz-blog.netlify.app/docs/articles](https://bgoonz-blog.netlify.app/docs/articles) +- [https://bgoonz-blog.netlify.app/docs/articles/buffers](https://bgoonz-blog.netlify.app/docs/articles/buffers) +- [https://bgoonz-blog.netlify.app/docs/articles/common-modules](https://bgoonz-blog.netlify.app/docs/articles/common-modules) +- [https://bgoonz-blog.netlify.app/docs/articles/dev-dep](https://bgoonz-blog.netlify.app/docs/articles/dev-dep) +- [https://bgoonz-blog.netlify.app/docs/articles/fs-module](https://bgoonz-blog.netlify.app/docs/articles/fs-module) +- [https://bgoonz-blog.netlify.app/docs/articles/how-search-engines-work](https://bgoonz-blog.netlify.app/docs/articles/how-search-engines-work) +- [https://bgoonz-blog.netlify.app/docs/articles/how-the-web-works](https://bgoonz-blog.netlify.app/docs/articles/how-the-web-works) +- [https://bgoonz-blog.netlify.app/docs/articles/intro](https://bgoonz-blog.netlify.app/docs/articles/intro) +- [https://bgoonz-blog.netlify.app/docs/articles/jamstack](https://bgoonz-blog.netlify.app/docs/articles/jamstack) +- [https://bgoonz-blog.netlify.app/docs/articles/nextjs](https://bgoonz-blog.netlify.app/docs/articles/nextjs) +- [https://bgoonz-blog.netlify.app/docs/articles/node-api-express](https://bgoonz-blog.netlify.app/docs/articles/node-api-express) +- [https://bgoonz-blog.netlify.app/docs/articles/npm](https://bgoonz-blog.netlify.app/docs/articles/npm) +- [https://bgoonz-blog.netlify.app/docs/articles/os-module](https://bgoonz-blog.netlify.app/docs/articles/os-module) +- [https://bgoonz-blog.netlify.app/docs/articles/reading-files](https://bgoonz-blog.netlify.app/docs/articles/reading-files) +- [https://bgoonz-blog.netlify.app/docs/articles/semantic](https://bgoonz-blog.netlify.app/docs/articles/semantic) +- [https://bgoonz-blog.netlify.app/docs/articles/semantic-html](https://bgoonz-blog.netlify.app/docs/articles/semantic-html) +- [https://bgoonz-blog.netlify.app/docs/articles/url](https://bgoonz-blog.netlify.app/docs/articles/url) +- [https://bgoonz-blog.netlify.app/docs/articles/web-standards-checklist](https://bgoonz-blog.netlify.app/docs/articles/web-standards-checklist) +- [https://bgoonz-blog.netlify.app/docs/articles/webdev-tools](https://bgoonz-blog.netlify.app/docs/articles/webdev-tools) +- [https://bgoonz-blog.netlify.app/docs/articles/writing-files](https://bgoonz-blog.netlify.app/docs/articles/writing-files) +- [https://bgoonz-blog.netlify.app/docs/audio](https://bgoonz-blog.netlify.app/docs/audio) +- [https://bgoonz-blog.netlify.app/docs/audio/dfft](https://bgoonz-blog.netlify.app/docs/audio/dfft) +- [https://bgoonz-blog.netlify.app/docs/audio/discrete-fft](https://bgoonz-blog.netlify.app/docs/audio/discrete-fft) +- [https://bgoonz-blog.netlify.app/docs/audio/dtw-python-explained](https://bgoonz-blog.netlify.app/docs/audio/dtw-python-explained) +- [https://bgoonz-blog.netlify.app/docs/audio/dynamic-time-warping](https://bgoonz-blog.netlify.app/docs/audio/dynamic-time-warping) +- [https://bgoonz-blog.netlify.app/docs/audio/web-audio-api](https://bgoonz-blog.netlify.app/docs/audio/web-audio-api) +- [https://bgoonz-blog.netlify.app/docs/career](https://bgoonz-blog.netlify.app/docs/career) +- [https://bgoonz-blog.netlify.app/docs/career/job-boards](https://bgoonz-blog.netlify.app/docs/career/job-boards) +- [https://bgoonz-blog.netlify.app/docs/career/my-websites](https://bgoonz-blog.netlify.app/docs/career/my-websites) +- [https://bgoonz-blog.netlify.app/docs/career/projects](https://bgoonz-blog.netlify.app/docs/career/projects) +- [https://bgoonz-blog.netlify.app/docs/community](https://bgoonz-blog.netlify.app/docs/community) +- [https://bgoonz-blog.netlify.app/docs/community/an-open-letter-2-future-developers](https://bgoonz-blog.netlify.app/docs/community/an-open-letter-2-future-developers) +- [https://bgoonz-blog.netlify.app/docs/community/bookmarks](https://bgoonz-blog.netlify.app/docs/community/bookmarks) +- [https://bgoonz-blog.netlify.app/docs/community/video-chat](https://bgoonz-blog.netlify.app/docs/community/video-chat) +- [https://bgoonz-blog.netlify.app/docs/content](https://bgoonz-blog.netlify.app/docs/content) +- [https://bgoonz-blog.netlify.app/docs/content/algo](https://bgoonz-blog.netlify.app/docs/content/algo) +- [https://bgoonz-blog.netlify.app/docs/content/archive](https://bgoonz-blog.netlify.app/docs/content/archive) +- [https://bgoonz-blog.netlify.app/docs/content/data-structures-in-python](https://bgoonz-blog.netlify.app/docs/content/data-structures-in-python) +- [https://bgoonz-blog.netlify.app/docs/content/gatsby-Queries-Mutations](https://bgoonz-blog.netlify.app/docs/content/gatsby-Queries-Mutations) +- [https://bgoonz-blog.netlify.app/docs/content/gists](https://bgoonz-blog.netlify.app/docs/content/gists) +- [https://bgoonz-blog.netlify.app/docs/content/history-api](https://bgoonz-blog.netlify.app/docs/content/history-api) +- [https://bgoonz-blog.netlify.app/docs/content/javascript-examples](https://bgoonz-blog.netlify.app/docs/content/javascript-examples) +- [https://bgoonz-blog.netlify.app/docs/content/main-projects](https://bgoonz-blog.netlify.app/docs/content/main-projects) +- [https://bgoonz-blog.netlify.app/docs/content/native-data-structures-in-js](https://bgoonz-blog.netlify.app/docs/content/native-data-structures-in-js) +- [https://bgoonz-blog.netlify.app/docs/content/trouble-shooting](https://bgoonz-blog.netlify.app/docs/content/trouble-shooting) +- [https://bgoonz-blog.netlify.app/docs/css](https://bgoonz-blog.netlify.app/docs/css) +- [https://bgoonz-blog.netlify.app/docs/css/css-selector-specificity](https://bgoonz-blog.netlify.app/docs/css/css-selector-specificity) +- [https://bgoonz-blog.netlify.app/docs/css/media-querries](https://bgoonz-blog.netlify.app/docs/css/media-querries) +- [https://bgoonz-blog.netlify.app/docs/css/the-box-model](https://bgoonz-blog.netlify.app/docs/css/the-box-model) +- [https://bgoonz-blog.netlify.app/docs/docs](https://bgoonz-blog.netlify.app/docs/docs) +- [https://bgoonz-blog.netlify.app/docs/docs/appendix](https://bgoonz-blog.netlify.app/docs/docs/appendix) +- [https://bgoonz-blog.netlify.app/docs/docs/archive](https://bgoonz-blog.netlify.app/docs/docs/archive) +- [https://bgoonz-blog.netlify.app/docs/docs/bash](https://bgoonz-blog.netlify.app/docs/docs/bash) +- [https://bgoonz-blog.netlify.app/docs/docs/css](https://bgoonz-blog.netlify.app/docs/docs/css) +- [https://bgoonz-blog.netlify.app/docs/docs/git-reference](https://bgoonz-blog.netlify.app/docs/docs/git-reference) +- [https://bgoonz-blog.netlify.app/docs/docs/git-repos](https://bgoonz-blog.netlify.app/docs/docs/git-repos) +- [https://bgoonz-blog.netlify.app/docs/docs/glossary](https://bgoonz-blog.netlify.app/docs/docs/glossary) +- [https://bgoonz-blog.netlify.app/docs/docs/html-tags](https://bgoonz-blog.netlify.app/docs/docs/html-tags) +- [https://bgoonz-blog.netlify.app/docs/docs/markdown](https://bgoonz-blog.netlify.app/docs/docs/markdown) +- [https://bgoonz-blog.netlify.app/docs/docs/no-whiteboarding](https://bgoonz-blog.netlify.app/docs/docs/no-whiteboarding) +- [https://bgoonz-blog.netlify.app/docs/docs/node-docs-complete](https://bgoonz-blog.netlify.app/docs/docs/node-docs-complete) +- [https://bgoonz-blog.netlify.app/docs/docs/privacy-policy](https://bgoonz-blog.netlify.app/docs/docs/privacy-policy) +- [https://bgoonz-blog.netlify.app/docs/docs/regex-in-js](https://bgoonz-blog.netlify.app/docs/docs/regex-in-js) +- [https://bgoonz-blog.netlify.app/docs/docs/sitemap](https://bgoonz-blog.netlify.app/docs/docs/sitemap) +- [https://bgoonz-blog.netlify.app/docs/ds-algo](https://bgoonz-blog.netlify.app/docs/ds-algo) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/big-o](https://bgoonz-blog.netlify.app/docs/ds-algo/big-o) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/data-structures-docs](https://bgoonz-blog.netlify.app/docs/ds-algo/data-structures-docs) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/ds-algo-interview](https://bgoonz-blog.netlify.app/docs/ds-algo/ds-algo-interview) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/ds-by-example](https://bgoonz-blog.netlify.app/docs/ds-algo/ds-by-example) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/ds-overview](https://bgoonz-blog.netlify.app/docs/ds-algo/ds-overview) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/free-code-camp](https://bgoonz-blog.netlify.app/docs/ds-algo/free-code-camp) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/graph](https://bgoonz-blog.netlify.app/docs/ds-algo/graph) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/heaps](https://bgoonz-blog.netlify.app/docs/ds-algo/heaps) +- [https://bgoonz-blog.netlify.app/docs/ds-algo/tree](https://bgoonz-blog.netlify.app/docs/ds-algo/tree) +- [https://bgoonz-blog.netlify.app/docs/faq](https://bgoonz-blog.netlify.app/docs/faq) +- [https://bgoonz-blog.netlify.app/docs/faq/contact](https://bgoonz-blog.netlify.app/docs/faq/contact) +- [https://bgoonz-blog.netlify.app/docs/faq/plug-ins](https://bgoonz-blog.netlify.app/docs/faq/plug-ins) +- [https://bgoonz-blog.netlify.app/docs/fetch-api](https://bgoonz-blog.netlify.app/docs/fetch-api) +- [https://bgoonz-blog.netlify.app/docs/git/git](https://bgoonz-blog.netlify.app/docs/git/git) +- [https://bgoonz-blog.netlify.app/docs/git/git/github-tutorial](https://bgoonz-blog.netlify.app/docs/git/git/github-tutorial) +- [https://bgoonz-blog.netlify.app/docs/interact](https://bgoonz-blog.netlify.app/docs/interact) +- [https://bgoonz-blog.netlify.app/docs/interact/callstack-visual](https://bgoonz-blog.netlify.app/docs/interact/callstack-visual) +- [https://bgoonz-blog.netlify.app/docs/interact/clock](https://bgoonz-blog.netlify.app/docs/interact/clock) +- [https://bgoonz-blog.netlify.app/docs/interact/jupyter-notebooks](https://bgoonz-blog.netlify.app/docs/interact/jupyter-notebooks) +- [https://bgoonz-blog.netlify.app/docs/interact/other-sites](https://bgoonz-blog.netlify.app/docs/interact/other-sites) +- [https://bgoonz-blog.netlify.app/docs/interact/react-testing-library](https://bgoonz-blog.netlify.app/docs/interact/react-testing-library) +- [https://bgoonz-blog.netlify.app/docs/interact/video-chat](https://bgoonz-blog.netlify.app/docs/interact/video-chat) +- [https://bgoonz-blog.netlify.app/docs/javascript](https://bgoonz-blog.netlify.app/docs/javascript) +- [https://bgoonz-blog.netlify.app/docs/javascript/arrow-functions](https://bgoonz-blog.netlify.app/docs/javascript/arrow-functions) +- [https://bgoonz-blog.netlify.app/docs/javascript/asynchronous-javascript-and-xml](https://bgoonz-blog.netlify.app/docs/javascript/asynchronous-javascript-and-xml) +- [https://bgoonz-blog.netlify.app/docs/javascript/asyncjs](https://bgoonz-blog.netlify.app/docs/javascript/asyncjs) +- [https://bgoonz-blog.netlify.app/docs/javascript/await-keyword](https://bgoonz-blog.netlify.app/docs/javascript/await-keyword) +- [https://bgoonz-blog.netlify.app/docs/javascript/bigo](https://bgoonz-blog.netlify.app/docs/javascript/bigo) +- [https://bgoonz-blog.netlify.app/docs/javascript/clean-code](https://bgoonz-blog.netlify.app/docs/javascript/clean-code) +- [https://bgoonz-blog.netlify.app/docs/javascript/constructor-functions](https://bgoonz-blog.netlify.app/docs/javascript/constructor-functions) +- [https://bgoonz-blog.netlify.app/docs/javascript/cs-basics-in-js](https://bgoonz-blog.netlify.app/docs/javascript/cs-basics-in-js) +- [https://bgoonz-blog.netlify.app/docs/javascript/for-loops](https://bgoonz-blog.netlify.app/docs/javascript/for-loops) +- [https://bgoonz-blog.netlify.app/docs/javascript/javascript-resource-table](https://bgoonz-blog.netlify.app/docs/javascript/javascript-resource-table) +- [https://bgoonz-blog.netlify.app/docs/javascript/js-expressions](https://bgoonz-blog.netlify.app/docs/javascript/js-expressions) +- [https://bgoonz-blog.netlify.app/docs/javascript/js-objects](https://bgoonz-blog.netlify.app/docs/javascript/js-objects) +- [https://bgoonz-blog.netlify.app/docs/javascript/part2-pojo](https://bgoonz-blog.netlify.app/docs/javascript/part2-pojo) +- [https://bgoonz-blog.netlify.app/docs/javascript/promises](https://bgoonz-blog.netlify.app/docs/javascript/promises) +- [https://bgoonz-blog.netlify.app/docs/javascript/review](https://bgoonz-blog.netlify.app/docs/javascript/review) +- [https://bgoonz-blog.netlify.app/docs/javascript/snippets](https://bgoonz-blog.netlify.app/docs/javascript/snippets) +- [https://bgoonz-blog.netlify.app/docs/javascript/this-is-about-this](https://bgoonz-blog.netlify.app/docs/javascript/this-is-about-this) +- [https://bgoonz-blog.netlify.app/docs/javascript/variables](https://bgoonz-blog.netlify.app/docs/javascript/variables) +- [https://bgoonz-blog.netlify.app/docs/js-tips](https://bgoonz-blog.netlify.app/docs/js-tips) +- [https://bgoonz-blog.netlify.app/docs/js-tips/abs](https://bgoonz-blog.netlify.app/docs/js-tips/abs) +- [https://bgoonz-blog.netlify.app/docs/js-tips/acos](https://bgoonz-blog.netlify.app/docs/js-tips/acos) +- [https://bgoonz-blog.netlify.app/docs/js-tips/acosh](https://bgoonz-blog.netlify.app/docs/js-tips/acosh) +- [https://bgoonz-blog.netlify.app/docs/js-tips/addition](https://bgoonz-blog.netlify.app/docs/js-tips/addition) +- [https://bgoonz-blog.netlify.app/docs/js-tips/all](https://bgoonz-blog.netlify.app/docs/js-tips/all) +- [https://bgoonz-blog.netlify.app/docs/js-tips/allsettled](https://bgoonz-blog.netlify.app/docs/js-tips/allsettled) +- [https://bgoonz-blog.netlify.app/docs/js-tips/any](https://bgoonz-blog.netlify.app/docs/js-tips/any) +- [https://bgoonz-blog.netlify.app/docs/js-tips/array](https://bgoonz-blog.netlify.app/docs/js-tips/array) +- [https://bgoonz-blog.netlify.app/docs/js-tips/array-methods](https://bgoonz-blog.netlify.app/docs/js-tips/array-methods) +- [https://bgoonz-blog.netlify.app/docs/js-tips/arrow_functions](https://bgoonz-blog.netlify.app/docs/js-tips/arrow_functions) +- [https://bgoonz-blog.netlify.app/docs/js-tips/async_function](https://bgoonz-blog.netlify.app/docs/js-tips/async_function) +- [https://bgoonz-blog.netlify.app/docs/js-tips/bad_radix](https://bgoonz-blog.netlify.app/docs/js-tips/bad_radix) +- [https://bgoonz-blog.netlify.app/docs/js-tips/bind](https://bgoonz-blog.netlify.app/docs/js-tips/bind) +- [https://bgoonz-blog.netlify.app/docs/js-tips/classes](https://bgoonz-blog.netlify.app/docs/js-tips/classes) +- [https://bgoonz-blog.netlify.app/docs/js-tips/concat](https://bgoonz-blog.netlify.app/docs/js-tips/concat) +- [https://bgoonz-blog.netlify.app/docs/js-tips/conditional_operator](https://bgoonz-blog.netlify.app/docs/js-tips/conditional_operator) +- [https://bgoonz-blog.netlify.app/docs/js-tips/const](https://bgoonz-blog.netlify.app/docs/js-tips/const) +- [https://bgoonz-blog.netlify.app/docs/js-tips/create](https://bgoonz-blog.netlify.app/docs/js-tips/create) +- [https://bgoonz-blog.netlify.app/docs/js-tips/date](https://bgoonz-blog.netlify.app/docs/js-tips/date) +- [https://bgoonz-blog.netlify.app/docs/js-tips/eval](https://bgoonz-blog.netlify.app/docs/js-tips/eval) +- [https://bgoonz-blog.netlify.app/docs/js-tips/every](https://bgoonz-blog.netlify.app/docs/js-tips/every) +- [https://bgoonz-blog.netlify.app/docs/js-tips/filter](https://bgoonz-blog.netlify.app/docs/js-tips/filter) +- [https://bgoonz-blog.netlify.app/docs/js-tips/for...of](https://bgoonz-blog.netlify.app/docs/js-tips/for...of) +- [https://bgoonz-blog.netlify.app/docs/js-tips/foreach](https://bgoonz-blog.netlify.app/docs/js-tips/foreach) +- [https://bgoonz-blog.netlify.app/docs/js-tips/functions](https://bgoonz-blog.netlify.app/docs/js-tips/functions) +- [https://bgoonz-blog.netlify.app/docs/js-tips/import](https://bgoonz-blog.netlify.app/docs/js-tips/import) +- [https://bgoonz-blog.netlify.app/docs/js-tips/insert-into-array](https://bgoonz-blog.netlify.app/docs/js-tips/insert-into-array) +- [https://bgoonz-blog.netlify.app/docs/js-tips/map](https://bgoonz-blog.netlify.app/docs/js-tips/map) +- [https://bgoonz-blog.netlify.app/docs/js-tips/object](https://bgoonz-blog.netlify.app/docs/js-tips/object) +- [https://bgoonz-blog.netlify.app/docs/js-tips/reduce](https://bgoonz-blog.netlify.app/docs/js-tips/reduce) +- [https://bgoonz-blog.netlify.app/docs/js-tips/regexp](https://bgoonz-blog.netlify.app/docs/js-tips/regexp) +- [https://bgoonz-blog.netlify.app/docs/js-tips/sort](https://bgoonz-blog.netlify.app/docs/js-tips/sort) +- [https://bgoonz-blog.netlify.app/docs/js-tips/sorting-strings](https://bgoonz-blog.netlify.app/docs/js-tips/sorting-strings) +- [https://bgoonz-blog.netlify.app/docs/js-tips/string](https://bgoonz-blog.netlify.app/docs/js-tips/string) +- [https://bgoonz-blog.netlify.app/docs/js-tips/this](https://bgoonz-blog.netlify.app/docs/js-tips/this) +- [https://bgoonz-blog.netlify.app/docs/js-tips/var](https://bgoonz-blog.netlify.app/docs/js-tips/var) +- [https://bgoonz-blog.netlify.app/docs/leetcode](https://bgoonz-blog.netlify.app/docs/leetcode) +- [https://bgoonz-blog.netlify.app/docs/leetcode/ContaineWitMosWater](https://bgoonz-blog.netlify.app/docs/leetcode/ContaineWitMosWater) +- [https://bgoonz-blog.netlify.app/docs/leetcode/DividTwIntegers](https://bgoonz-blog.netlify.app/docs/leetcode/DividTwIntegers) +- [https://bgoonz-blog.netlify.app/docs/leetcode/GeneratParentheses](https://bgoonz-blog.netlify.app/docs/leetcode/GeneratParentheses) +- [https://bgoonz-blog.netlify.app/docs/leetcode/LetteCombinationoPhonNumber](https://bgoonz-blog.netlify.app/docs/leetcode/LetteCombinationoPhonNumber) +- [https://bgoonz-blog.netlify.app/docs/leetcode/LongesCommoPrefix](https://bgoonz-blog.netlify.app/docs/leetcode/LongesCommoPrefix) +- [https://bgoonz-blog.netlify.app/docs/leetcode/MediaoTwSorteArrays](https://bgoonz-blog.netlify.app/docs/leetcode/MediaoTwSorteArrays) +- [https://bgoonz-blog.netlify.app/docs/leetcode/NexPermutation](https://bgoonz-blog.netlify.app/docs/leetcode/NexPermutation) +- [https://bgoonz-blog.netlify.app/docs/leetcode/PalindromNumber](https://bgoonz-blog.netlify.app/docs/leetcode/PalindromNumber) +- [https://bgoonz-blog.netlify.app/docs/leetcode/RegulaExpressioMatching](https://bgoonz-blog.netlify.app/docs/leetcode/RegulaExpressioMatching) +- [https://bgoonz-blog.netlify.app/docs/leetcode/RemovDuplicatefroSorteArray](https://bgoonz-blog.netlify.app/docs/leetcode/RemovDuplicatefroSorteArray) +- [https://bgoonz-blog.netlify.app/docs/leetcode/RemovNtNodFroEnoList](https://bgoonz-blog.netlify.app/docs/leetcode/RemovNtNodFroEnoList) +- [https://bgoonz-blog.netlify.app/docs/leetcode/RomatInteger](https://bgoonz-blog.netlify.app/docs/leetcode/RomatInteger) +- [https://bgoonz-blog.netlify.app/docs/leetcode/SearciRotateSorteArray](https://bgoonz-blog.netlify.app/docs/leetcode/SearciRotateSorteArray) +- [https://bgoonz-blog.netlify.app/docs/leetcode/StrintIntege(atoi)]() +- [https://bgoonz-blog.netlify.app/docs/leetcode/ValiParentheses](https://bgoonz-blog.netlify.app/docs/leetcode/ValiParentheses) +- [https://bgoonz-blog.netlify.app/docs/leetcode/ZigZaConversion](https://bgoonz-blog.netlify.app/docs/leetcode/ZigZaConversion) +- [https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack](https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack) +- [https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/get-started-with-gatsby](https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/get-started-with-gatsby) +- [https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/jamstack-templates](https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/jamstack-templates) +- [https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/serverlessjs](https://bgoonz-blog.netlify.app/docs/netlify-cms-jamstack/serverlessjs) +- [https://bgoonz-blog.netlify.app/docs/overflow](https://bgoonz-blog.netlify.app/docs/overflow) +- [https://bgoonz-blog.netlify.app/docs/overflow/emmet-cheat-sheet](https://bgoonz-blog.netlify.app/docs/overflow/emmet-cheat-sheet) +- [https://bgoonz-blog.netlify.app/docs/overflow/html-spec](https://bgoonz-blog.netlify.app/docs/overflow/html-spec) +- [https://bgoonz-blog.netlify.app/docs/overflow/http](https://bgoonz-blog.netlify.app/docs/overflow/http) +- [https://bgoonz-blog.netlify.app/docs/overflow/install](https://bgoonz-blog.netlify.app/docs/overflow/install) +- [https://bgoonz-blog.netlify.app/docs/overflow/modules](https://bgoonz-blog.netlify.app/docs/overflow/modules) +- [https://bgoonz-blog.netlify.app/docs/overflow/node-cli-args](https://bgoonz-blog.netlify.app/docs/overflow/node-cli-args) +- [https://bgoonz-blog.netlify.app/docs/overflow/node-js-language](https://bgoonz-blog.netlify.app/docs/overflow/node-js-language) +- [https://bgoonz-blog.netlify.app/docs/overflow/node-package-manager](https://bgoonz-blog.netlify.app/docs/overflow/node-package-manager) +- [https://bgoonz-blog.netlify.app/docs/overflow/node-repl](https://bgoonz-blog.netlify.app/docs/overflow/node-repl) +- [https://bgoonz-blog.netlify.app/docs/overflow/node-run-cli](https://bgoonz-blog.netlify.app/docs/overflow/node-run-cli) +- [https://bgoonz-blog.netlify.app/docs/overflow/nodejs](https://bgoonz-blog.netlify.app/docs/overflow/nodejs) +- [https://bgoonz-blog.netlify.app/docs/overflow/nodevsbrowser](https://bgoonz-blog.netlify.app/docs/overflow/nodevsbrowser) +- [https://bgoonz-blog.netlify.app/docs/overflow/understanding-firebase](https://bgoonz-blog.netlify.app/docs/overflow/understanding-firebase) +- [https://bgoonz-blog.netlify.app/docs/overflow/v8](https://bgoonz-blog.netlify.app/docs/overflow/v8) +- [https://bgoonz-blog.netlify.app/docs/privacy-policy](https://bgoonz-blog.netlify.app/docs/privacy-policy) +- [https://bgoonz-blog.netlify.app/docs/projects](https://bgoonz-blog.netlify.app/docs/projects) +- [https://bgoonz-blog.netlify.app/docs/projects/archive](https://bgoonz-blog.netlify.app/docs/projects/archive) +- [https://bgoonz-blog.netlify.app/docs/projects/archive/embeded-websites](https://bgoonz-blog.netlify.app/docs/projects/archive/embeded-websites) +- [https://bgoonz-blog.netlify.app/docs/projects/links](https://bgoonz-blog.netlify.app/docs/projects/links) +- [https://bgoonz-blog.netlify.app/docs/projects/mini-projects](https://bgoonz-blog.netlify.app/docs/projects/mini-projects) +- [https://bgoonz-blog.netlify.app/docs/projects/mini-projects2](https://bgoonz-blog.netlify.app/docs/projects/mini-projects2) +- [https://bgoonz-blog.netlify.app/docs/projects/recent](https://bgoonz-blog.netlify.app/docs/projects/recent) +- [https://bgoonz-blog.netlify.app/docs/python](https://bgoonz-blog.netlify.app/docs/python) +- [https://bgoonz-blog.netlify.app/docs/python/at-length](https://bgoonz-blog.netlify.app/docs/python/at-length) +- [https://bgoonz-blog.netlify.app/docs/python/cheat-sheet](https://bgoonz-blog.netlify.app/docs/python/cheat-sheet) +- [https://bgoonz-blog.netlify.app/docs/python/comprehensive-guide](https://bgoonz-blog.netlify.app/docs/python/comprehensive-guide) +- [https://bgoonz-blog.netlify.app/docs/python/data-structures-in-python](https://bgoonz-blog.netlify.app/docs/python/data-structures-in-python) +- [https://bgoonz-blog.netlify.app/docs/python/examples](https://bgoonz-blog.netlify.app/docs/python/examples) +- [https://bgoonz-blog.netlify.app/docs/python/flow-control](https://bgoonz-blog.netlify.app/docs/python/flow-control) +- [https://bgoonz-blog.netlify.app/docs/python/functions](https://bgoonz-blog.netlify.app/docs/python/functions) +- [https://bgoonz-blog.netlify.app/docs/python/google-sheets-api](https://bgoonz-blog.netlify.app/docs/python/google-sheets-api) +- [https://bgoonz-blog.netlify.app/docs/python/intro-for-js-devs](https://bgoonz-blog.netlify.app/docs/python/intro-for-js-devs) +- [https://bgoonz-blog.netlify.app/docs/python/python-ds](https://bgoonz-blog.netlify.app/docs/python/python-ds) +- [https://bgoonz-blog.netlify.app/docs/python/python-quiz](https://bgoonz-blog.netlify.app/docs/python/python-quiz) +- [https://bgoonz-blog.netlify.app/docs/python/snippets](https://bgoonz-blog.netlify.app/docs/python/snippets) +- [https://bgoonz-blog.netlify.app/docs/quick-ref](https://bgoonz-blog.netlify.app/docs/quick-ref) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/all-emojis](https://bgoonz-blog.netlify.app/docs/quick-ref/all-emojis) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/create-react-app](https://bgoonz-blog.netlify.app/docs/quick-ref/create-react-app) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/Emmet](https://bgoonz-blog.netlify.app/docs/quick-ref/Emmet) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/fetch](https://bgoonz-blog.netlify.app/docs/quick-ref/fetch) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/general-structured-data-guidelines](https://bgoonz-blog.netlify.app/docs/quick-ref/general-structured-data-guidelines) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/git-bash](https://bgoonz-blog.netlify.app/docs/quick-ref/git-bash) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/git-tricks](https://bgoonz-blog.netlify.app/docs/quick-ref/git-tricks) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/google-firebase](https://bgoonz-blog.netlify.app/docs/quick-ref/google-firebase) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/heroku-error-codes](https://bgoonz-blog.netlify.app/docs/quick-ref/heroku-error-codes) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/installation](https://bgoonz-blog.netlify.app/docs/quick-ref/installation) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/markdown-dropdowns](https://bgoonz-blog.netlify.app/docs/quick-ref/markdown-dropdowns) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/minifiction](https://bgoonz-blog.netlify.app/docs/quick-ref/minifiction) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/new-repo-instructions](https://bgoonz-blog.netlify.app/docs/quick-ref/new-repo-instructions) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/pull-request-rubric](https://bgoonz-blog.netlify.app/docs/quick-ref/pull-request-rubric) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/python-builtin-functions](https://bgoonz-blog.netlify.app/docs/quick-ref/python-builtin-functions) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/quick-links](https://bgoonz-blog.netlify.app/docs/quick-ref/quick-links) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/topRepos](https://bgoonz-blog.netlify.app/docs/quick-ref/topRepos) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/understanding-path](https://bgoonz-blog.netlify.app/docs/quick-ref/understanding-path) +- [https://bgoonz-blog.netlify.app/docs/quick-ref/vscode-themes](https://bgoonz-blog.netlify.app/docs/quick-ref/vscode-themes) +- [https://bgoonz-blog.netlify.app/docs/react](https://bgoonz-blog.netlify.app/docs/react) +- [https://bgoonz-blog.netlify.app/docs/react/accessibility](https://bgoonz-blog.netlify.app/docs/react/accessibility) +- [https://bgoonz-blog.netlify.app/docs/react/ajax-n-apis](https://bgoonz-blog.netlify.app/docs/react/ajax-n-apis) +- [https://bgoonz-blog.netlify.app/docs/react/cheatsheet](https://bgoonz-blog.netlify.app/docs/react/cheatsheet) +- [https://bgoonz-blog.netlify.app/docs/react/complete-react](https://bgoonz-blog.netlify.app/docs/react/complete-react) +- [https://bgoonz-blog.netlify.app/docs/react/createReactApp](https://bgoonz-blog.netlify.app/docs/react/createReactApp) +- [https://bgoonz-blog.netlify.app/docs/react/demo](https://bgoonz-blog.netlify.app/docs/react/demo) +- [https://bgoonz-blog.netlify.app/docs/react/dont-use-index-as-keys](https://bgoonz-blog.netlify.app/docs/react/dont-use-index-as-keys) +- [https://bgoonz-blog.netlify.app/docs/react/higher-order-components](https://bgoonz-blog.netlify.app/docs/react/higher-order-components) +- [https://bgoonz-blog.netlify.app/docs/react/jsx](https://bgoonz-blog.netlify.app/docs/react/jsx) +- [https://bgoonz-blog.netlify.app/docs/react/quiz](https://bgoonz-blog.netlify.app/docs/react/quiz) +- [https://bgoonz-blog.netlify.app/docs/react/react-docs](https://bgoonz-blog.netlify.app/docs/react/react-docs) +- [https://bgoonz-blog.netlify.app/docs/react/react-in-depth](https://bgoonz-blog.netlify.app/docs/react/react-in-depth) +- [https://bgoonz-blog.netlify.app/docs/react/react-patterns-by-usecase](https://bgoonz-blog.netlify.app/docs/react/react-patterns-by-usecase) +- [https://bgoonz-blog.netlify.app/docs/react/react-router](https://bgoonz-blog.netlify.app/docs/react/react-router) +- [https://bgoonz-blog.netlify.app/docs/react/react-study-guide](https://bgoonz-blog.netlify.app/docs/react/react-study-guide) +- [https://bgoonz-blog.netlify.app/docs/react/react2](https://bgoonz-blog.netlify.app/docs/react/react2) +- [https://bgoonz-blog.netlify.app/docs/react/render-elements](https://bgoonz-blog.netlify.app/docs/react/render-elements) +- [https://bgoonz-blog.netlify.app/docs/readme](https://bgoonz-blog.netlify.app/docs/readme) +- [https://bgoonz-blog.netlify.app/docs/reference](https://bgoonz-blog.netlify.app/docs/reference) +- [https://bgoonz-blog.netlify.app/docs/reference/art-of-command-line](https://bgoonz-blog.netlify.app/docs/reference/art-of-command-line) +- [https://bgoonz-blog.netlify.app/docs/reference/awesome-lists](https://bgoonz-blog.netlify.app/docs/reference/awesome-lists) +- [https://bgoonz-blog.netlify.app/docs/reference/awesome-nodejs](https://bgoonz-blog.netlify.app/docs/reference/awesome-nodejs) +- [https://bgoonz-blog.netlify.app/docs/reference/awesome-static](https://bgoonz-blog.netlify.app/docs/reference/awesome-static) +- [https://bgoonz-blog.netlify.app/docs/reference/bash-commands](https://bgoonz-blog.netlify.app/docs/reference/bash-commands) +- [https://bgoonz-blog.netlify.app/docs/reference/bookmarks](https://bgoonz-blog.netlify.app/docs/reference/bookmarks) +- [https://bgoonz-blog.netlify.app/docs/reference/embed-the-web](https://bgoonz-blog.netlify.app/docs/reference/embed-the-web) +- [https://bgoonz-blog.netlify.app/docs/reference/github-resources](https://bgoonz-blog.netlify.app/docs/reference/github-resources) +- [https://bgoonz-blog.netlify.app/docs/reference/github-search](https://bgoonz-blog.netlify.app/docs/reference/github-search) +- [https://bgoonz-blog.netlify.app/docs/reference/google-cloud](https://bgoonz-blog.netlify.app/docs/reference/google-cloud) +- [https://bgoonz-blog.netlify.app/docs/reference/how-2-reinstall-npm](https://bgoonz-blog.netlify.app/docs/reference/how-2-reinstall-npm) +- [https://bgoonz-blog.netlify.app/docs/reference/how-to-kill-a-process](https://bgoonz-blog.netlify.app/docs/reference/how-to-kill-a-process) +- [https://bgoonz-blog.netlify.app/docs/reference/installing-node](https://bgoonz-blog.netlify.app/docs/reference/installing-node) +- [https://bgoonz-blog.netlify.app/docs/reference/intro-to-nodejs](https://bgoonz-blog.netlify.app/docs/reference/intro-to-nodejs) +- [https://bgoonz-blog.netlify.app/docs/reference/markdown-styleguide](https://bgoonz-blog.netlify.app/docs/reference/markdown-styleguide) +- [https://bgoonz-blog.netlify.app/docs/reference/notes-template](https://bgoonz-blog.netlify.app/docs/reference/notes-template) +- [https://bgoonz-blog.netlify.app/docs/reference/psql](https://bgoonz-blog.netlify.app/docs/reference/psql) +- [https://bgoonz-blog.netlify.app/docs/reference/resources](https://bgoonz-blog.netlify.app/docs/reference/resources) +- [https://bgoonz-blog.netlify.app/docs/reference/vscode](https://bgoonz-blog.netlify.app/docs/reference/vscode) +- [https://bgoonz-blog.netlify.app/docs/reference/web-api's](https://bgoonz-blog.netlify.app/docs/reference/web-api's) +- [https://bgoonz-blog.netlify.app/docs/showcase](https://bgoonz-blog.netlify.app/docs/showcase) +- [https://bgoonz-blog.netlify.app/docs/sitemap](https://bgoonz-blog.netlify.app/docs/sitemap) +- [https://bgoonz-blog.netlify.app/docs/tips](https://bgoonz-blog.netlify.app/docs/tips) +- [https://bgoonz-blog.netlify.app/docs/tips/7-tips-to-become-a-better-web-developer](https://bgoonz-blog.netlify.app/docs/tips/7-tips-to-become-a-better-web-developer) +- [https://bgoonz-blog.netlify.app/docs/tips/decrement](https://bgoonz-blog.netlify.app/docs/tips/decrement) +- [https://bgoonz-blog.netlify.app/docs/tips/firebase-hosting](https://bgoonz-blog.netlify.app/docs/tips/firebase-hosting) +- [https://bgoonz-blog.netlify.app/docs/tips/httrack](https://bgoonz-blog.netlify.app/docs/tips/httrack) +- [https://bgoonz-blog.netlify.app/docs/tips/regex-tips](https://bgoonz-blog.netlify.app/docs/tips/regex-tips) +- [https://bgoonz-blog.netlify.app/docs/tips/storybook](https://bgoonz-blog.netlify.app/docs/tips/storybook) +- [https://bgoonz-blog.netlify.app/docs/tips/top-10-money-tips](https://bgoonz-blog.netlify.app/docs/tips/top-10-money-tips) +- [https://bgoonz-blog.netlify.app/docs/tips/ubuntu-setup](https://bgoonz-blog.netlify.app/docs/tips/ubuntu-setup) +- [https://bgoonz-blog.netlify.app/docs/tips/web-accessibility](https://bgoonz-blog.netlify.app/docs/tips/web-accessibility) +- [https://bgoonz-blog.netlify.app/docs/tools](https://bgoonz-blog.netlify.app/docs/tools) +- [https://bgoonz-blog.netlify.app/docs/tools/dev-utilities](https://bgoonz-blog.netlify.app/docs/tools/dev-utilities) +- [https://bgoonz-blog.netlify.app/docs/tools/markdown-html](https://bgoonz-blog.netlify.app/docs/tools/markdown-html) +- [https://bgoonz-blog.netlify.app/docs/tutorials](https://bgoonz-blog.netlify.app/docs/tutorials) +- [https://bgoonz-blog.netlify.app/docs/tutorials/bash](https://bgoonz-blog.netlify.app/docs/tutorials/bash) +- [https://bgoonz-blog.netlify.app/docs/tutorials/bash-commands-my](https://bgoonz-blog.netlify.app/docs/tutorials/bash-commands-my) +- [https://bgoonz-blog.netlify.app/docs/tutorials/get-file-extension](https://bgoonz-blog.netlify.app/docs/tutorials/get-file-extension) +- [https://bgoonz-blog.netlify.app/docs/tutorials/how-2-ubuntu](https://bgoonz-blog.netlify.app/docs/tutorials/how-2-ubuntu) +- [https://bgoonz-blog.netlify.app/docs/tutorials/psql-setup](https://bgoonz-blog.netlify.app/docs/tutorials/psql-setup) +- [https://bgoonz-blog.netlify.app/docs/tutorials/webdev-review](https://bgoonz-blog.netlify.app/docs/tutorials/webdev-review) +- [https://bgoonz-blog.netlify.app/docs/typescript](https://bgoonz-blog.netlify.app/docs/typescript) +- [https://bgoonz-blog.netlify.app/interview-questions-js](https://bgoonz-blog.netlify.app/interview-questions-js) +- [https://bgoonz-blog.netlify.app/readme](https://bgoonz-blog.netlify.app/readme) +- [https://bgoonz-blog.netlify.app/showcase](https://bgoonz-blog.netlify.app/showcase) + ↞↠ Getting Started With GatsbyJS ↞↠ + +# + + + +## Technoloy + +![tech-stack](https://github.com/bgoonz/BGOONZ_BLOG_2.0/blob/master/static/images/madewith.png?raw=true) + +``` +--- + +## SOURCECODE + +--- + + + +### Overview + +The **`_.get()` method** in Lodash retrieves the object’s value at a specific path. + +If the value is not present at the object’s specific path, it will be resolved as `undefined`. This method will return the default value if specified in such a case. + +### Syntax + +```js +_.get(object, path, defaultValue) +``` + +### Parameters + +This method accepts the following parameters: + +- **`object`**: The object in which the given path will be queried. +- **`path`**: The path used to retrieve the value from the object. +- **`defaultValue`**: The default value that will be returned for resolved values that are undefined. + +### Return value + +This method will return the value at the specified path if found. Otherwise, it will return the default value if specified. + +### Example + +Let’s look at an example of the `_.get()` method in the code snippet below: + +### Explanation + +In the HTML tab: + +- **Line 5**: We import the `lodash` script. + +In the JavaScript tab: + +- **Lines 2 to 15**: We create an object to perform a query. + +- **Line 18**: We define a variable `collegeYopPath` to get the value. + +- **Lines 19**: We use the `_.get()` method and pass the `object`, `collegeYopPath`, and a default value as parameters. + +- **Line 22**: We define a variable `falsyPath` to get the value. + +- **Lines 23**: We use the `_.get()` method and pass the `object`, `falsyPath` and a `default value` as parameters. + +### Output + +- The `_.get()` method at **line 19** contains a valid path, and therefore the expression is resolved, and `2021` is printed on the console. +- The `_.get()` method at **Line 23** contains an invalid path, and therefore the expression is resolved as `undefined`. + + +--- + +``` + +bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f +. +├── ./components +│ ├── ./components/ActionLink.js +│ ├── ./components/CtaButtons.js +│ ├── ./components/DocsMenu.js +│ ├── ./components/DocsSubmenu.js +│ ├── ./components/Footer.js +│ ├── ./components/Header.js +│ ├── ./components/Icon.js +│ ├── ./components/Layout.js +│ ├── ./components/SectionContent.js +│ ├── ./components/SectionCta.js +│ ├── ./components/SectionDocs.js +│ ├── ./components/SectionGrid.js +│ ├── ./components/SectionHero.js +│ ├── ./components/Submenu.js +│ ├── ./components/global.css +│ └── ./components/index.js +├── ./data +│ └── ./data/doc_sections.yml +├── ./hooks +│ └── ./hooks/useScript.js +├── ./html.js +├── ./pages +│ ├── ./pages/blog +│ │ ├── ./pages/blog/blog-archive.md +│ │ ├── ./pages/blog/blogwcomments.md +│ │ ├── ./pages/blog/data-structures.md +│ │ ├── ./pages/blog/index.md +│ │ ├── ./pages/blog/my-medium.md +│ │ ├── ./pages/blog/platform-docs.md +│ │ ├── ./pages/blog/python-for-js-dev.md +│ │ ├── ./pages/blog/python-resources.md +│ │ └── ./pages/blog/web-scraping.md +│ ├── ./pages/docs +│ │ ├── ./pages/docs/about +│ │ │ ├── ./pages/docs/about/index.md +│ │ │ ├── ./pages/docs/about/me.md +│ │ │ ├── ./pages/docs/about/node +│ │ │ │ ├── ./pages/docs/about/node/install.md +│ │ │ │ ├── ./pages/docs/about/node/intro.md +│ │ │ │ ├── ./pages/docs/about/node/nodejs.md +│ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md +│ │ │ │ ├── ./pages/docs/about/node/reading-files.md +│ │ │ │ └── ./pages/docs/about/node/writing-files.md +│ │ │ ├── ./pages/docs/about/npm.md +│ │ │ └── ./pages/docs/about/resume.md +│ │ ├── ./pages/docs/articles +│ │ │ ├── ./pages/docs/articles/algo.md +│ │ │ ├── ./pages/docs/articles/article-compilation.md +│ │ │ ├── ./pages/docs/articles/basic-web-dev.md +│ │ │ ├── ./pages/docs/articles/gists.md +│ │ │ ├── ./pages/docs/articles/index.md +│ │ │ ├── ./pages/docs/articles/install.md +│ │ │ ├── ./pages/docs/articles/intro.md +│ │ │ ├── ./pages/docs/articles/python.md +│ │ │ ├── ./pages/docs/articles/reading-files.md +│ │ │ ├── ./pages/docs/articles/resources.md +│ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md +│ │ │ └── ./pages/docs/articles/writing-files.md +│ │ ├── ./pages/docs/docs +│ │ │ └── ./pages/docs/docs/tools +│ │ │ └── ./pages/docs/docs/tools/file-types.md +│ │ ├── ./pages/docs/faq +│ │ │ ├── ./pages/docs/faq/contact.md +│ │ │ └── ./pages/docs/faq/index.md +│ │ ├── ./pages/docs/gists.md +│ │ ├── ./pages/docs/index.md +│ │ ├── ./pages/docs/interact +│ │ │ ├── ./pages/docs/interact/clock.md +│ │ │ ├── ./pages/docs/interact/index.md +│ │ │ └── ./pages/docs/interact/jupyter-notebooks.md +│ │ ├── ./pages/docs/links +│ │ │ ├── ./pages/docs/links/index.md +│ │ │ ├── ./pages/docs/links/medium-links.md +│ │ │ ├── ./pages/docs/links/my-websites.md +│ │ │ └── ./pages/docs/links/social.md +│ │ ├── ./pages/docs/quick-reference +│ │ │ ├── ./pages/docs/quick-reference/Emmet.md +│ │ │ ├── ./pages/docs/quick-reference/docs.md +│ │ │ ├── ./pages/docs/quick-reference/index.md +│ │ │ ├── ./pages/docs/quick-reference/installation.md +│ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md +│ │ ├── ./pages/docs/react +│ │ │ ├── ./pages/docs/react/createReactApp.md +│ │ │ ├── ./pages/docs/react/index.md +│ │ │ └── ./pages/docs/react/react2.md +│ │ ├── ./pages/docs/react-in-depth.md +│ │ ├── ./pages/docs/sitemap.md +│ │ └── ./pages/docs/tools +│ │ ├── ./pages/docs/tools/index.md +│ │ ├── ./pages/docs/tools/notes-template.md +│ │ ├── ./pages/docs/tools/plug-ins.md +│ │ └── ./pages/docs/tools/vscode.md +│ ├── ./pages/index.md +│ ├── ./pages/notes-template.md +│ ├── ./pages/review.md +│ └── ./pages/showcase.md +├── ./sass +│ ├── ./sass/imports +│ │ ├── ./sass/imports/_animations.scss +│ │ ├── ./sass/imports/_buttons.scss +│ │ ├── ./sass/imports/_docs.scss +│ │ ├── ./sass/imports/_footer.scss +│ │ ├── ./sass/imports/_forms.scss +│ │ ├── ./sass/imports/_functions.scss +│ │ ├── ./sass/imports/_general.scss +│ │ ├── ./sass/imports/_header.scss +│ │ ├── ./sass/imports/_helpers.scss +│ │ ├── ./sass/imports/_icons.scss +│ │ ├── ./sass/imports/_palettes.scss +│ │ ├── ./sass/imports/_posts.scss +│ │ ├── ./sass/imports/_prism.scss +│ │ ├── ./sass/imports/_reset.scss +│ │ ├── ./sass/imports/_sections.scss +│ │ ├── ./sass/imports/_structure.scss +│ │ ├── ./sass/imports/_tables.scss +│ │ └── ./sass/imports/_variables.scss +│ └── ./sass/main.scss +├── ./templates +│ ├── ./templates/advanced.js +│ ├── ./templates/blog.js +│ ├── ./templates/docs.js +│ ├── ./templates/page.js +│ └── ./templates/post.js +└── ./utils + ├── ./utils/attribute.js + ├── ./utils/classNames.js + ├── ./utils/cycler.js + ├── ./utils/getData.js + ├── ./utils/getPage.js + ├── ./utils/getPageByFilePath.js + ├── ./utils/getPages.js + ├── ./utils/htmlToReact.js + ├── ./utils/index.js + ├── ./utils/link.js + ├── ./utils/markdownify.js + ├── ./utils/pathJoin.js + ├── ./utils/toStyleObj.js + ├── ./utils/toUrl.js + └── ./utils/withPrefix.js + +21 directories, 119 files +bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ +``` + +--- + +## Source Code + +
    + Folder Structure (src) + +``` +. +├── Combined_____-_____Doc.md +├── components +│ ├── ActionLink.js +│ ├── CtaButtons.js +│ ├── DarkToggle +│ │ ├── index.js +│ │ └── styles.js +│ ├── DocsMenu.js +│ ├── DocsSubmenu.js +│ ├── Footer.js +│ ├── Header.js +│ ├── Icon.js +│ ├── Layout.js +│ ├── SectionContent.js +│ ├── SectionCta.js +│ ├── SectionDocs.js +│ ├── SectionGrid.js +│ ├── SectionHero.js +│ ├── Submenu.js +│ ├── global.css +│ └── index.js +├── data +│ └── doc_sections.yml +├── hooks +│ ├── addScript.js +│ ├── index.js +│ ├── useDarkMode.js +│ ├── useEventListener.js +│ ├── useMediaQuery.js +│ ├── useOnClickOutside.js +│ ├── useQueryParam.js +│ ├── useSize.js +│ └── useStorage.js +├── html.js +├── pages +│ ├── blog +│ │ ├── 300-react-questions.md +│ │ ├── awesome-graphql.md +│ │ ├── big-o-complexity.md +│ │ ├── blog-archive.md +│ │ ├── blogwcomments.md +│ │ ├── data-structures.md +│ │ ├── flow-control-in-python.md +│ │ ├── functions-in-python.md +│ │ ├── git-gateway.md +│ │ ├── index.md +│ │ ├── interview-questions-js.md +│ │ ├── netlify-cms.md +│ │ ├── platform-docs.md +│ │ ├── python-for-js-dev.md +│ │ ├── python-resources.md +│ │ ├── web-dev-trends.md +│ │ └── web-scraping.md +│ ├── docs +│ │ ├── about +│ │ │ ├── eng-portfolio.md +│ │ │ ├── ideas-for-this-website.md +│ │ │ ├── index.md +│ │ │ ├── intrests.md +│ │ │ ├── job-search.md +│ │ │ └── resume.md +│ │ ├── articles +│ │ │ ├── basic-web-dev.md +│ │ │ ├── buffers.md +│ │ │ ├── dev-dep.md +│ │ │ ├── event-loop.md +│ │ │ ├── fs-module.md +│ │ │ ├── how-the-web-works.md +│ │ │ ├── http.md +│ │ │ ├── index.md +│ │ │ ├── install.md +│ │ │ ├── intro.md +│ │ │ ├── modules.md +│ │ │ ├── nextjs.md +│ │ │ ├── node-api-express.md +│ │ │ ├── node-cli-args.md +│ │ │ ├── node-common-modules.md +│ │ │ ├── node-env-variables.md +│ │ │ ├── node-js-language.md +│ │ │ ├── node-package-manager.md +│ │ │ ├── node-repl.md +│ │ │ ├── node-run-cli.md +│ │ │ ├── nodejs.md +│ │ │ ├── nodevsbrowser.md +│ │ │ ├── npm.md +│ │ │ ├── npx.md +│ │ │ ├── os-module.md +│ │ │ ├── reading-files.md +│ │ │ ├── semantic-html.md +│ │ │ ├── semantic.md +│ │ │ ├── the-uniform-resource-locator-(url).md +│ │ │ ├── understanding-firebase.md +│ │ │ ├── v8.md +│ │ │ ├── web-standards-checklist.md +│ │ │ ├── webdev-tools.md +│ │ │ └── writing-files.md +│ │ ├── audio +│ │ │ ├── audio-feature-extraction.md +│ │ │ ├── audio.md +│ │ │ ├── dfft.md +│ │ │ ├── discrete-fft.md +│ │ │ ├── dtw-python-explained.md +│ │ │ ├── dynamic-time-warping.md +│ │ │ ├── index.md +│ │ │ └── web-audio-api.md +│ │ ├── career +│ │ │ ├── dev-interview.md +│ │ │ ├── index.md +│ │ │ ├── interview-dos-n-donts.md +│ │ │ └── job-boards.md +│ │ ├── community +│ │ │ ├── an-open-letter-2-future-developers.md +│ │ │ ├── index.md +│ │ │ └── video-chat.md +│ │ ├── content +│ │ │ ├── algo.md +│ │ │ ├── archive.md +│ │ │ ├── gatsby-Queries-Mutations.md +│ │ │ ├── history-api.md +│ │ │ ├── index.md +│ │ │ ├── main-projects.md +│ │ │ └── trouble-shooting.md +│ │ ├── data-structures +│ │ │ └── index.md +│ │ ├── docs +│ │ │ ├── appendix.md +│ │ │ ├── art-of-command-line.md +│ │ │ ├── bash.md +│ │ │ ├── content.md +│ │ │ ├── css.md +│ │ │ ├── data-structures-docs.md +│ │ │ ├── es-6-features.md +│ │ │ ├── git-reference.md +│ │ │ ├── git-repos.md +│ │ │ ├── html-spec.md +│ │ │ ├── index.md +│ │ │ ├── markdown.md +│ │ │ ├── no-whiteboarding.md +│ │ │ ├── node-docs-complete.md +│ │ │ ├── node-docs-full.md +│ │ │ ├── regex-in-js.md +│ │ │ └── sitemap.md +│ │ ├── faq +│ │ │ ├── contact.md +│ │ │ ├── index.md +│ │ │ └── plug-ins.md +│ │ ├── gists.md +│ │ ├── index.md +│ │ ├── interact +│ │ │ ├── callstack-visual.md +│ │ │ ├── clock.md +│ │ │ ├── index.md +│ │ │ ├── jupyter-notebooks.md +│ │ │ ├── other-sites.md +│ │ │ └── video-chat.md +│ │ ├── interview +│ │ │ ├── index.md +│ │ │ ├── job-search-nav.md +│ │ │ └── review-concepts.md +│ │ ├── javascript +│ │ │ ├── arrow-functions.md +│ │ │ ├── asyncjs.md +│ │ │ ├── await-keyword.md +│ │ │ ├── bigo.md +│ │ │ ├── clean-code.md +│ │ │ ├── constructor-functions.md +│ │ │ ├── index.md +│ │ │ ├── promises.md +│ │ │ ├── review.md +│ │ │ └── this-is-about-this.md +│ │ ├── leetcode +│ │ │ └── index.md +│ │ ├── privacy-policy.md +│ │ ├── projects +│ │ │ ├── embeded-websites.md +│ │ │ ├── index.md +│ │ │ ├── list-of-projects.md +│ │ │ ├── mini-projects.md +│ │ │ └── my-websites.md +│ │ ├── python +│ │ │ ├── at-length.md +│ │ │ ├── cheat-sheet.md +│ │ │ ├── comprehensive-guide.md +│ │ │ ├── examples.md +│ │ │ ├── flow-control.md +│ │ │ ├── functions.md +│ │ │ ├── google-sheets-api.md +│ │ │ ├── index.md +│ │ │ ├── intro-for-js-devs.md +│ │ │ ├── python-ds.md +│ │ │ └── snippets.md +│ │ ├── quick-reference +│ │ │ ├── Emmet.md +│ │ │ ├── all-emojis.md +│ │ │ ├── create-react-app.md +│ │ │ ├── git-bash.md +│ │ │ ├── git-tricks.md +│ │ │ ├── google-firebase.md +│ │ │ ├── heroku-error-codes.md +│ │ │ ├── index.md +│ │ │ ├── installation.md +│ │ │ ├── markdown-dropdowns.md +│ │ │ ├── minifiction.md +│ │ │ ├── new-repo-instructions.md +│ │ │ ├── psql-setup.md +│ │ │ ├── pull-request-rubric.md +│ │ │ ├── quick-links.md +│ │ │ ├── topRepos.md +│ │ │ ├── understanding-path.md +│ │ │ └── vscode-themes.md +│ │ ├── react +│ │ │ ├── ajax-n-apis.md +│ │ │ ├── cheatsheet.md +│ │ │ ├── createReactApp.md +│ │ │ ├── demo.md +│ │ │ ├── dont-use-index-as-keys.md +│ │ │ ├── index.md +│ │ │ ├── jsx.md +│ │ │ ├── react-docs.md +│ │ │ ├── react-in-depth.md +│ │ │ ├── react2.md +│ │ │ └── render-elements.md +│ │ ├── reference +│ │ │ ├── awesome-lists.md +│ │ │ ├── awesome-static.md +│ │ │ ├── bash-commands.md +│ │ │ ├── bookmarks.md +│ │ │ ├── embed-the-web.md +│ │ │ ├── github-search.md +│ │ │ ├── google-cloud.md +│ │ │ ├── how-2-reinstall-npm.md +│ │ │ ├── how-to-kill-a-process.md +│ │ │ ├── index.md +│ │ │ ├── installing-node.md +│ │ │ ├── intro-to-nodejs.md +│ │ │ ├── notes-template.md +│ │ │ ├── psql.md +│ │ │ ├── resources.md +│ │ │ ├── vscode.md +│ │ │ └── web-api's.md +│ │ ├── search.md +│ │ ├── sitemap.md +│ │ ├── tips +│ │ │ ├── array-methods.md +│ │ │ ├── index.md +│ │ │ └── insert-into-array.md +│ │ ├── tools +│ │ │ ├── Archive.md +│ │ │ ├── data-structures.md +│ │ │ ├── dev-utilities.md +│ │ │ ├── index.md +│ │ │ └── markdown-html.md +│ │ └── tutorials +│ │ ├── enviorment-setup.md +│ │ └── index.md +│ ├── index.md +│ ├── privacy-policy.md +│ ├── readme.md +│ └── showcase.md +├── sass +│ ├── imports +│ │ ├── _animations.scss +│ │ ├── _buttons.scss +│ │ ├── _docs.scss +│ │ ├── _footer.scss +│ │ ├── _forms.scss +│ │ ├── _functions.scss +│ │ ├── _general.scss +│ │ ├── _header.scss +│ │ ├── _helpers.scss +│ │ ├── _icons.scss +│ │ ├── _palettes.scss +│ │ ├── _posts.scss +│ │ ├── _prism.scss +│ │ ├── _reset.scss +│ │ ├── _sections.scss +│ │ ├── _structure.scss +│ │ ├── _tables.scss +│ │ └── _variables.scss +│ └── main.scss +├── templates +│ ├── advanced.js +│ ├── blog.js +│ ├── docs.js +│ ├── page.js +│ ├── post.js +│ └── templates.md +└── utils + ├── attribute.js + ├── blm-badge.js + ├── classNames.js + ├── cycler.js + ├── getData.js + ├── getPage.js + ├── getPageByFilePath.js + ├── getPages.js + ├── htmlToReact.js + ├── index.js + ├── link.js + ├── markdownify.js + ├── pathJoin.js + ├── toStyleObj.js + ├── toUrl.js + └── withPrefix.js + +32 directories, 272 files +``` + +
    + +
    + Click To See Component Sourcecode + +## Component Structure + +``` +. +├── ActionLink.js +├── CtaButtons.js +├── DarkToggle +│ ├── index.js +│ └── styles.js +├── DocsMenu.js +├── DocsSubmenu.js +├── Footer.js +├── Header.js +├── Icon.js +├── Layout.js +├── SectionContent.js +├── SectionCta.js +├── SectionDocs.js +├── SectionGrid.js +├── SectionHero.js +├── Submenu.js +├── global.css +└── index.js + +``` + +--- + +```js +import React from 'react'; +import _ from 'lodash'; + + +import { Link, withPrefix, classNames } from '../utils'; +import Icon from './Icon'; + +export default class ActionLink extends React.Component { + render() { + let action = _.get(this.props, 'action', null); + return ( + + {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon_class', null) ? ( + + + {_.get(action, 'label', null)} + + ) : ( + _.get(action, 'label', null) + )} + + ); + } +} +``` + +--- +### Table of Contents + +- [getPage][1] + - [Parameters][2] +- [getPageByFilePath][3] + - [Parameters][4] +- [getPages][5] + - [Parameters][6] + - [Examples][7] + +## getPage + +Get the page at the provided `urlPath`. + +### Parameters + +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `urlPath` **[string][9]** The url path to find the page by + +Returns **[Object][10]** + +## getPageByFilePath + +Get the page at the provided `filePath`. + +### Parameters + +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `filePath` **[string][9]** The file path to find the page by + +Returns **[Object][10]** + +## getPages + +Get all the pages located under the provided `urlPath`, not including the +index page. I.e.: All pages having their URLs start with `urlPath` excluding +the page having its URL equal to `urlPath`. + +### Parameters + +- `pages` **[Array][8]** Array of page objects. All pages must have 'url' field. +- `urlPath` **[string][9]** The url path to filter pages by + +### Examples + +```javascript +pages => [ + {url: '/'}, + {url: '/about'}, + {url: '/posts'}, + {url: '/posts/hello'}, + {url: '/posts/world'} +] + +getPages(pages, /posts') +=> [ + {url: '/posts/hello'}, + {url: '/posts/world'} +] +``` + +Returns **[Array][8]** + +[1]: #getpage +[2]: #parameters +[3]: #getpagebyfilepath +[4]: #parameters-1 +[5]: #getpages +[6]: #parameters-2 +[7]: #examples +[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array +[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object + + + +```js +import React from 'react'; +import _ from 'lodash'; + + +import { Link, withPrefix, classNames } from '../utils'; + +export default class CtaButtons extends React.Component { + render() { + let actions = _.get(this.props, 'actions', null); + return _.map(actions, (action, action_idx) => ( + + {_.get(action, 'label', null)} + + )); + } +} +``` + +--- + +```js +import React from 'react'; +import _ from 'lodash'; + + +import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; +import DocsSubmenu from './DocsSubmenu'; + +export default class DocsMenu extends React.Component { + render() { + let site = _.get(this.props, 'site', null); + let page = _.get(this.props, 'page', null); + let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); + let root_page = getPage(this.props.pageContext.pages, root_docs_path); + return ( + + ); + } +} +``` + +--- + +```js +import React from 'react'; +import _ from 'lodash'; + + +import { classNames, Link, withPrefix } from '../utils'; + +export default class DocsSubmenu extends React.Component { + render() { + let child_pages = _.get(this.props, 'child_pages', null); + let page = _.get(this.props, 'page', null); + return ( +
      + {_.map(child_pages, (child_page, child_page_idx) => ( +
    • + {_.get(child_page, 'frontmatter.title', null)} +
    • + ))} +
    + ); + } +} +``` + +--- + +```js +import _ from 'lodash'; +import React from 'react'; + +import { htmlToReact } from '../utils'; +import ActionLink from './ActionLink'; +import addScript from './../hooks/addScript'; +const Script = (props) => { + importScript('./../hooks/addScript.js'); +}; +export default class Footer extends React.Component { + render() { + return ( +
    +
    +
    +
    + + + +
    + + + + + + + + + + +
    +
    + + + + + + + + +
    + + index + + + + sitemap + + + + advanced + +
    +
    + +
    + + + + + + + +
    +
    + + search engine + + + by + freefind + + { + + } +
    + + Save to PDF + +
    +
    + +
    + +
    +

    + {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( + {htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))} + )} + {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( + + ))}{' '} +

    + {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( +
    + {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( + + ))}{' '} +
    + )}{' '} +
    +
    +
    + ); + } +} +``` + +--- + +```js +import React from 'react'; +import _ from 'lodash'; + + +import { Link, withPrefix, classNames } from '../utils'; +import ActionLink from './ActionLink'; +import Submenu from './Submenu'; + +export default class Header extends React.Component { + render() { + return ( +
    + {/* */} + +
    + +
    +
    +
    + {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( +

    + + {_.get(this.props, + +

    + ) : ( +

    + {' '} + WebDevHub + + {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} + +

    + )} +
    + + {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( + + + + + )} +
    +
    + + +
    + ); + } +} +``` + +--- + +```js +import React from 'react'; +import _ from 'lodash'; + +export default class Icon extends React.Component { + render() { + let icon = _.get(this.props, 'icon', null); + return ( + + {icon === 'dev' ? ( + + ) : icon === 'facebook' ? ( + + ) : icon === 'github' ? ( + + ) : icon === 'instagram' ? ( + + ) : icon === 'linkedin' ? ( + + ) : icon === 'pinterest' ? ( + + ) : icon === 'reddit' ? ( + + ) : icon === 'twitter' ? ( + + ) : icon === 'youtube' ? ( + + ) : ( + icon === 'vimeo' && ( + + ) + )} + + ); + } +} +``` diff --git a/docs/content/DS_ALGO/algorithms/Conversions/ArbitraryBase.js b/docs/content/DS_ALGO/algorithms/Conversions/ArbitraryBase.js deleted file mode 100644 index d66ec555da..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/ArbitraryBase.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Converts a string from one base to other - * @param {string} stringInBaseOne String in input base - * @param {string} baseOneCharacters Character set for the input base - * @param {string} baseTwoCharacters Character set for the output base - * @returns {string} - */ -const convertArbitraryBase = (stringInBaseOne, baseOneCharacters, baseTwoCharacters) => { - if ([stringInBaseOne, baseOneCharacters, baseTwoCharacters].map((arg) => typeof arg).some((type) => type !== 'string')) { - throw new TypeError('Only string arguments are allowed'); - } - [baseOneCharacters, baseTwoCharacters].forEach((baseString) => { - const charactersInBase = [...baseString]; - if (charactersInBase.length !== new Set(charactersInBase).size) { - throw new TypeError('Duplicate characters in character set are not allowed'); - } - }); - const reversedStringOneChars = [...stringInBaseOne].reverse(); - const stringOneBase = baseOneCharacters.length; - let value = 0; - let placeValue = 1; - for (const digit of reversedStringOneChars) { - const digitNumber = baseOneCharacters.indexOf(digit); - if (digitNumber === -1) { - throw new TypeError(`Not a valid character: ${digit}`); - } - value += digitNumber * placeValue; - placeValue *= stringOneBase; - } - let stringInBaseTwo = ''; - const stringTwoBase = baseTwoCharacters.length; - while (value > 0) { - const remainder = value % stringTwoBase; - stringInBaseTwo = baseTwoCharacters.charAt(remainder) + stringInBaseTwo; - value /= stringTwoBase; - } - const baseTwoZero = baseTwoCharacters.charAt(0); - return stringInBaseTwo.replace(new RegExp(`^${baseTwoZero}+`), ''); -}; -export { convertArbitraryBase }; -// > convertArbitraryBase('98', '0123456789', '01234567') -// '142' -// > convertArbitraryBase('98', '0123456789', 'abcdefgh') -// 'bec' -// > convertArbitraryBase('129', '0123456789', '01234567') -// '201' diff --git a/docs/content/DS_ALGO/algorithms/Conversions/ArrayBufferToBase64.js b/docs/content/DS_ALGO/algorithms/Conversions/ArrayBufferToBase64.js deleted file mode 100644 index 820cac189d..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/ArrayBufferToBase64.js +++ /dev/null @@ -1,31 +0,0 @@ -// About base64: https://en.wikipedia.org/wiki/Base64 -/** - * Converts an array of bytes to base64 encoding - * @param {ArrayBuffer} binaryData An ArrayBuffer which represents an array of bytes - * @returns {string} A string containing the base64 encoding of `binaryData` - */ -function bufferToBase64(binaryData) { - // The base64 encoding uses the following set of characters to encode any binary data as text - const base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - // Every 3 bytes translates to 4 base64 characters, if we have less than 3 bytes we must append '=' chars as padding - const padding = 3 - (binaryData.byteLength % 3); - // Create an instance of Uint8Array, to read from the binaryData array buffer - const byteView = new Uint8Array(binaryData); - let result = ''; - // Loop through all bytes in the buffer, in increments of 3 bytes - for (let i = 0; i < byteView.byteLength; i += 3) { - // Get the index for the next 4 base64 chars - const char1 = (byteView[i] & 252) >> 2; - const char2 = ((byteView[i] & 3) << 4) + ((byteView[i + 1] & 240) >> 4); - const char3 = ((byteView[i + 1] & 15) << 2) + ((byteView[i + 2] & 192) >> 6); - const char4 = byteView[i + 2] & 63; - result += base64Table[char1] + base64Table[char2] + base64Table[char3] + base64Table[char4]; - } - // Add padding '=' chars if needed - if (padding !== 3) { - const paddedResult = result.slice(0, result.length - padding) + '='.repeat(padding); - return paddedResult; - } - return result; -} -export { bufferToBase64 }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/Base64ToArrayBuffer.js b/docs/content/DS_ALGO/algorithms/Conversions/Base64ToArrayBuffer.js deleted file mode 100644 index 7bc2299960..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/Base64ToArrayBuffer.js +++ /dev/null @@ -1,40 +0,0 @@ -// About base64: https://en.wikipedia.org/wiki/Base64 -/** - * Converts a base64 string to an array of bytes - * @param {string} b64 A base64 string - * @returns {ArrayBuffer} An ArrayBuffer representing the bytes encoded by the base64 string - */ -function base64ToBuffer(b64) { - // The base64 encoding uses the following set of characters to encode any binary data as text - const base64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - // Find the index of char '=' first occurrence - const paddingIdx = b64.indexOf('='); - // Remove padding chars from base64 string, if there are any - const b64NoPadding = paddingIdx !== -1 ? b64.slice(0, paddingIdx) : b64; - // Calculate the length of the result buffer - const bufferLength = Math.floor((b64NoPadding.length * 6) / 8); - // Create the result buffer - const result = new ArrayBuffer(bufferLength); - // Create an instance of Uint8Array, to write to the `result` buffer - const byteView = new Uint8Array(result); - // Loop through all chars in the base64 string, in increments of 4 chars, and in increments of 3 bytes - for (let i = 0, j = 0; i < b64NoPadding.length; i += 4, j += 3) { - // Get the index of the next 4 base64 chars - const b64Char1 = base64Table.indexOf(b64NoPadding[i]); - const b64Char2 = base64Table.indexOf(b64NoPadding[i + 1]); - let b64Char3 = base64Table.indexOf(b64NoPadding[i + 2]); - let b64Char4 = base64Table.indexOf(b64NoPadding[i + 3]); - // If base64 chars 3 and 4 don't exit, then set them to 0 - if (b64Char3 === -1) b64Char3 = 0; - if (b64Char4 === -1) b64Char4 = 0; - // Calculate the next 3 bytes - const byte1 = (b64Char1 << 2) + ((b64Char2 & 48) >> 4); - const byte2 = ((b64Char2 & 15) << 4) + ((b64Char3 & 60) >> 2); - const byte3 = ((b64Char3 & 3) << 6) + b64Char4; - byteView[j] = byte1; - byteView[j + 1] = byte2; - byteView[j + 2] = byte3; - } - return result; -} -export { base64ToBuffer }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/BinaryToDecimal.js b/docs/content/DS_ALGO/algorithms/Conversions/BinaryToDecimal.js deleted file mode 100644 index 181ab7445f..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/BinaryToDecimal.js +++ /dev/null @@ -1,8 +0,0 @@ -export default function binaryToDecimal(binaryString) { - let decimalNumber = 0; - const binaryDigits = binaryString.split('').reverse(); // Splits the binary number into reversed single digits - binaryDigits.forEach((binaryDigit, index) => { - decimalNumber += binaryDigit * Math.pow(2, index); // Summation of all the decimal converted digits - }); - return decimalNumber; -} diff --git a/docs/content/DS_ALGO/algorithms/Conversions/BinaryToHex.js b/docs/content/DS_ALGO/algorithms/Conversions/BinaryToHex.js deleted file mode 100644 index 90bddde8b7..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/BinaryToHex.js +++ /dev/null @@ -1,68 +0,0 @@ -const pad = (num, padlen) => { - const pad = new Array(1 + padlen).join(0); - return (pad + num).slice(-pad.length); -}; -const hexLookup = (bin) => { - let binary = bin; - if (binary.length < 4) { - binary = pad(binary, 4); - } - switch (binary) { - case '0000': - return '0'; - case '0001': - return '1'; - case '0010': - return '2'; - case '0011': - return '3'; - case '0100': - return '4'; - case '0101': - return '5'; - case '0110': - return '6'; - case '0111': - return '7'; - case '1000': - return '8'; - case '1001': - return '9'; - case '1010': - return 'A'; - case '1011': - return 'B'; - case '1100': - return 'C'; - case '1101': - return 'D'; - case '1110': - return 'E'; - case '1111': - return 'F'; - } -}; -const binaryToHex = (binaryString) => { - /* - Function for convertung Binary to Hex - 1. The conversion will start from Least Significant Digit (LSB) to the Most Significant Bit (MSB). - 2. We divide the bits into sections of 4-bits starting from LSB to MSB. - 3. If the MSB get less than 4 bits, then we pad 0s to the front of it. - For Example: - Binary String = '1001101' - 1. Divide it to 2 parts => ['100', '1101'] - 2. Pad 0s the MSB so it'll be => ['0100', '1101'] - 3. Use the lookup table and merge them, therefore the result is 4D. - */ - let result = ''; - binaryString = binaryString.split(''); - for (let i = binaryString.length - 1; i >= 0; i = i - 4) { - if (i >= 3) { - result += hexLookup(binaryString.slice(i - 3, i + 1).join('')); - } else { - result += hexLookup(binaryString.slice(0, i + 1).join('')); - } - } - return result.split('').reverse().join(''); -}; -export default binaryToHex; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DateDayDifference.js b/docs/content/DS_ALGO/algorithms/Conversions/DateDayDifference.js deleted file mode 100644 index 9359a71151..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DateDayDifference.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - DateDayDifference Method - ------------------------ - DateDayDifference method calculates the number of days between two dates. - Algorithm & Explanation : https://ncalculators.com/time-date/date-difference-calculator.htm -*/ -// Internal method for make calculations easier -const isLeap = (year) => { - if (year % 400 === 0) return true; - else if (year % 100 === 0) return false; - else if (year % 4 === 0) return true; - else return false; -}; -const DateToDay = (dd, mm, yyyy) => { - return Math.floor( - 365 * (yyyy - 1) + (yyyy - 1) / 4 - (yyyy - 1) / 100 + (yyyy - 1) / 400 + dd + (367 * mm - 362) / 12 + (mm <= 2 ? 0 : isLeap(yyyy) ? -1 : -2) - ); -}; -const DateDayDifference = (date1, date2) => { - // firstly, check that both input are string or not. - if (typeof date1 !== 'string' && typeof date2 !== 'string') { - return new TypeError('Argument is not a string.'); - } - // extract the first date - const [firstDateDay, firstDateMonth, firstDateYear] = date1.split('/').map((ele) => Number(ele)); - // extract the second date - const [secondDateDay, secondDateMonth, secondDateYear] = date2.split('/').map((ele) => Number(ele)); - // check the both data are valid or not. - if ( - firstDateDay < 0 || - firstDateDay > 31 || - firstDateMonth > 12 || - firstDateMonth < 0 || - secondDateDay < 0 || - secondDateDay > 31 || - secondDateMonth > 12 || - secondDateMonth < 0 - ) { - return new TypeError('Date is not valid.'); - } - return Math.abs(DateToDay(secondDateDay, secondDateMonth, secondDateYear) - DateToDay(firstDateDay, firstDateMonth, firstDateYear)); -}; -// Example : DateDayDifference('17/08/2002', '10/10/2020') => 6630 -export { DateDayDifference }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DateToDay.js b/docs/content/DS_ALGO/algorithms/Conversions/DateToDay.js deleted file mode 100644 index ac371d4797..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DateToDay.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - DateToDay Method - ---------------- - The DateToDay method takes a date in string format and - returns the name of a day. The approach behind this method - is very simple, we first take a string date and check - whether their date is valid or not, if the date is valid - then we do this But apply the algorithm shown below. The - algorithm shown below gives us the number of the day and - finally converts it to the name of the day. - Algorithm & Explanation : https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html -*/ -// March is taken as the first month of the year. -const calcMonthList = { - 1: 11, - 2: 12, - 3: 1, - 4: 2, - 5: 3, - 6: 4, - 7: 5, - 8: 6, - 9: 7, - 10: 8, - 11: 9, - 12: 10 -}; -// show the week day in a number : Sunday - Saturday => 0 - 6 -const daysNameList = { - // weeks-day - 0: 'Sunday', - 1: 'Monday', - 2: 'Tuesday', - 3: 'Wednesday', - 4: 'Thursday', - 5: 'Friday', - 6: 'Saturday' -}; -const DateToDay = (date) => { - // firstly, check that input is a string or not. - if (typeof date !== 'string') { - return new TypeError('Argument is not a string.'); - } - // extract the date - const [day, month, year] = date.split('/').map((x) => Number(x)); - // check the data are valid or not. - if (day < 0 || day > 31 || month > 12 || month < 0) { - return new TypeError('Date is not valid.'); - } - // divide year to century and yearDigit value. - const yearDigit = year % 100; - const century = Math.floor(year / 100); - // Apply the algorithm shown above - const weekDay = Math.abs( - (day + Math.floor(2.6 * calcMonthList[month] - 0.2) - 2 * century + yearDigit + Math.floor(yearDigit / 4) + Math.floor(century / 4)) % 7 - ); - // return the weekDay name. - return daysNameList[weekDay]; -}; -// Example : DateToDay("18/12/2020") => Friday -export { DateToDay }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToBinary.js b/docs/content/DS_ALGO/algorithms/Conversions/DecimalToBinary.js deleted file mode 100644 index 0a72ba50f2..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToBinary.js +++ /dev/null @@ -1,15 +0,0 @@ -function decimalToBinary(num) { - const bin = []; - while (num > 0) { - bin.unshift(num % 2); - num >>= 1; // basically /= 2 without remainder if any - } - return bin.join(''); -} -export { decimalToBinary }; -// > decimalToBinary(2) -// '10' -// > decimalToBinary(7) -// '111' -// > decimalToBinary(35) -// '100011' diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToHex.js b/docs/content/DS_ALGO/algorithms/Conversions/DecimalToHex.js deleted file mode 100644 index c2c15ee2e3..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToHex.js +++ /dev/null @@ -1,26 +0,0 @@ -function intToHex(num) { - switch (num) { - case 10: - return 'A'; - case 11: - return 'B'; - case 12: - return 'C'; - case 13: - return 'D'; - case 14: - return 'E'; - case 15: - return 'F'; - } - return num; -} -function decimalToHex(num) { - const hexOut = []; - while (num > 15) { - hexOut.unshift(intToHex(num % 16)); - num = Math.floor(num / 16); - } - return intToHex(num) + hexOut.join(''); -} -export { decimalToHex }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToOctal.js b/docs/content/DS_ALGO/algorithms/Conversions/DecimalToOctal.js deleted file mode 100644 index 0861a83593..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToOctal.js +++ /dev/null @@ -1,21 +0,0 @@ -function decimalToOctal(num) { - let oct = 0; - let c = 0; - while (num > 0) { - const r = num % 8; - oct = oct + r * Math.pow(10, c++); - num = Math.floor(num / 8); // basically /= 8 without remainder if any - } - return oct; -} -export { decimalToOctal }; -// > decimalToOctal(2) -// 2 -// > decimalToOctal(8) -// 10 -// > decimalToOctal(65) -// 101 -// > decimalToOctal(216) -// 330 -// > decimalToOctal(512) -// 1000 diff --git a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToRoman.js b/docs/content/DS_ALGO/algorithms/Conversions/DecimalToRoman.js deleted file mode 100644 index 6d4942021a..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/DecimalToRoman.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - Decimal To Roman - This algorithm take decimal number and convert to roman numeral according to standard form (https://en.wikipedia.org/wiki/Roman_numerals#Description) - Algorithm & Explanation : https://www.rapidtables.com/convert/number/how-number-to-roman-numerals.html -*/ -const values = { - M: 1000, - CM: 900, - D: 500, - CD: 400, - C: 100, - XC: 90, - L: 50, - XL: 40, - X: 10, - IX: 9, - V: 5, - IV: 4, - I: 1 -}; -const orders = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; -function decimalToRoman(num) { - let roman = ''; - for (const symbol of orders) { - while (num >= values[symbol]) { - roman += symbol; - num -= values[symbol]; - } - } - return roman; -} -export { decimalToRoman }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/HexToBinary.js b/docs/content/DS_ALGO/algorithms/Conversions/HexToBinary.js deleted file mode 100644 index 63b643cea6..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/HexToBinary.js +++ /dev/null @@ -1,34 +0,0 @@ -const binLookup = (key) => - ({ - 0: '0000', - 1: '0001', - 2: '0010', - 3: '0011', - 4: '0100', - 5: '0101', - 6: '0110', - 7: '0111', - 8: '1000', - 9: '1001', - a: '1010', - b: '1011', - c: '1100', - d: '1101', - e: '1110', - f: '1111' - }[key.toLowerCase()]); // select the binary number by valid hex key with the help javascript object -const hexToBinary = (hexString) => { - if (typeof hexString !== 'string') { - throw new TypeError('Argument is not a string type'); - } - if (/[^\da-f]/gi.test(hexString)) { - throw new Error('Argument is not a valid HEX code!'); - } - /* - Function for converting Hex to Binary - 1. We convert every hexadecimal bit to 4 binary bits - 2. Conversion goes by searching in the lookup table - */ - return hexString.replace(/[0-9a-f]/gi, (lexeme) => binLookup(lexeme)); -}; -export default hexToBinary; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/HexToDecimal.js b/docs/content/DS_ALGO/algorithms/Conversions/HexToDecimal.js deleted file mode 100644 index 861ff86e6a..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/HexToDecimal.js +++ /dev/null @@ -1,28 +0,0 @@ -function hexToInt(hexNum) { - const numArr = hexNum.split(''); // converts number to array - return numArr.map((item, index) => { - switch (item) { - case 'A': - return 10; - case 'B': - return 11; - case 'C': - return 12; - case 'D': - return 13; - case 'E': - return 14; - case 'F': - return 15; - default: - return parseInt(item); - } - }); -} -function hexToDecimal(hexNum) { - const intItemsArr = hexToInt(hexNum); - return intItemsArr.reduce((accumulator, current, index) => { - return accumulator + current * Math.pow(16, intItemsArr.length - (1 + index)); - }, 0); -} -export { hexToInt, hexToDecimal }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/HexToRGB.js b/docs/content/DS_ALGO/algorithms/Conversions/HexToRGB.js deleted file mode 100644 index 1895e2c095..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/HexToRGB.js +++ /dev/null @@ -1,13 +0,0 @@ -function hexStringToRGB(hexString) { - let r = hexString.substring(0, 2); - let g = hexString.substring(2, 4); - let b = hexString.substring(4, 6); - r = parseInt(r, 16); - g = parseInt(g, 16); - b = parseInt(b, 16); - const obj = { r, g, b }; - return obj; -} -export { hexStringToRGB }; -// > hexStringToRGB('ffffff') -// { r: 255, g: 255, b: 255 } diff --git a/docs/content/DS_ALGO/algorithms/Conversions/LowerCaseConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/LowerCaseConversion.js deleted file mode 100644 index d874399e5c..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/LowerCaseConversion.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - Explanation :- a user gives a String (it can be incomplete uppercase or - partial uppercase) and then the program would convert it into a - complete(all characters in lower case) lower case string. The - logic we have used in the following program is: All the upper case - characters (A-Z) has ASCII value ranging from 65 to 90 and their - corresponding lower case characters (a-z) have ASCII values 32 - greater than them. For example ‘A‘ has an ASCII value of 65 - and ‘a‘ has an ASCII value of 97 (65+32). The same applies to other - characters. -*/ -/** - * LowerCaseConversion takes any case-style string and converts it to the lower case-style string. - * @param {String} inputString any case style string - * @returns {String} lower case string - */ -const LowerCaseConversion = (inputString) => { - // Take a string and split it into characters. - const newString = inputString.split('').map((char) => { - // Get a character code by the use charCodeAt method. - const presentCharCode = char.charCodeAt(); - // If the character code lies between 65 to 90 it means they are in the upper case so convert it. - if (presentCharCode >= 65 && presentCharCode <= 90) { - // Convert the case by use of the above explanation. - return String.fromCharCode(presentCharCode + 32); - } - // Else return the characters without any modification. - return char; - }); - // After modification, with the help of the join method, join all the characters and return them. - return newString.join(''); -}; -export { LowerCaseConversion }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/MeterToFeetConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/MeterToFeetConversion.js deleted file mode 100644 index 0074022f6f..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/MeterToFeetConversion.js +++ /dev/null @@ -1,8 +0,0 @@ -// Foot: https://en.wikipedia.org/wiki/Foot_(unit) -const feetToMeter = (feet) => { - return feet * 0.3048; -}; -const meterToFeet = (meter) => { - return meter / 0.3048; -}; -export { feetToMeter, meterToFeet }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/OctToDecimal.js b/docs/content/DS_ALGO/algorithms/Conversions/OctToDecimal.js deleted file mode 100644 index 5f6ab83e6b..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/OctToDecimal.js +++ /dev/null @@ -1,16 +0,0 @@ -function octalToDecimal(num) { - let dec = 0; - let base = 1; - while (num > 0) { - const r = num % 10; - num = Math.floor(num / 10); - dec = dec + r * base; - base = base * 8; - } - return dec; -} -export { octalToDecimal }; -// > octalToDecimal(56) -// 46 -// > octalToDecimal(2365) -// 1269 diff --git a/docs/content/DS_ALGO/algorithms/Conversions/RGBToHex.js b/docs/content/DS_ALGO/algorithms/Conversions/RGBToHex.js deleted file mode 100644 index 7663861c9c..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/RGBToHex.js +++ /dev/null @@ -1,12 +0,0 @@ -function RGBToHex(r, g, b) { - if (typeof r !== 'number' || typeof g !== 'number' || typeof b !== 'number') { - throw new TypeError('argument is not a Number'); - } - const toHex = (n) => (n || '0').toString(16).padStart(2, '0'); - return `#${toHex(r)}${toHex(g)}${toHex(b)}`; -} -export { RGBToHex }; -// > RGBToHex(255, 255, 255) -// '#ffffff' -// > RGBToHex(255, 99, 71) -// '#ff6347' diff --git a/docs/content/DS_ALGO/algorithms/Conversions/RailwayTimeConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/RailwayTimeConversion.js deleted file mode 100644 index 28bcf3a3f3..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/RailwayTimeConversion.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - The time conversion of normalized time to the railway is a simple algorithm - because we know that if the time is in 'AM' value it means they only want - some changes on hours and minutes and if the time in 'PM' it means the only - want some changes in hour value. - Input Format -> 07:05:45PM - Output Format -> 19:05:45 - Problem & Explanation Source : https://www.mathsisfun.com/time.html -*/ -/** - * RailwayTimeConversion method converts normalized time string to Railway time string. - * @param {String} timeString Normalized time string. - * @returns {String} Railway time string. - */ -const RailwayTimeConversion = (timeString) => { - // firstly, check that input is a string or not. - if (typeof timeString !== 'string') { - return new TypeError('Argument is not a string.'); - } - // split the string by ':' character. - const [hour, minute, scondWithShift] = timeString.split(':'); - // split second and shift value. - const [second, shift] = [scondWithShift.substr(0, 2), scondWithShift.substr(2)]; - // convert shifted time to not-shift time(Railway time) by using the above explanation. - if (shift === 'PM') { - if (parseInt(hour) === 12) { - return `${hour}:${minute}:${second}`; - } else { - return `${parseInt(hour) + 12}:${minute}:${second}`; - } - } else { - if (parseInt(hour) === 12) { - return `00:${minute}:${second}`; - } else { - return `${hour}:${minute}:${second}`; - } - } -}; -export { RailwayTimeConversion }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/RgbHsvConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/RgbHsvConversion.js deleted file mode 100644 index d5a50b2c15..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/RgbHsvConversion.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - * The RGB color model is an additive color model in which red, green, and blue light are added - * together in various ways to reproduce a broad array of colors. The name of the model comes from - * the initials of the three additive primary colors, red, green, and blue. Meanwhile, the HSV - * representation models how colors appear under light. In it, colors are represented using three - * components: hue, saturation and (brightness-)value. This file provides functions for converting - * colors from one representation to the other. (description adapted from - * https://en.wikipedia.org/wiki/RGB_color_model and https://en.wikipedia.org/wiki/HSL_and_HSV). - */ -/** - * Conversion from the HSV-representation to the RGB-representation. - * - * @param hue Hue of the color. - * @param saturation Saturation of the color. - * @param value Brightness-value of the color. - * @return The tuple of RGB-components. - */ -export function hsvToRgb(hue, saturation, value) { - if (hue < 0 || hue > 360) { - throw new Error('hue should be between 0 and 360'); - } - if (saturation < 0 || saturation > 1) { - throw new Error('saturation should be between 0 and 1'); - } - if (value < 0 || value > 1) { - throw new Error('value should be between 0 and 1'); - } - const chroma = value * saturation; - const hueSection = hue / 60; - const secondLargestComponent = chroma * (1 - Math.abs((hueSection % 2) - 1)); - const matchValue = value - chroma; - return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent); -} -/** - * Conversion from the RGB-representation to the HSV-representation. - * - * @param red Red-component of the color. - * @param green Green-component of the color. - * @param blue Blue-component of the color. - * @return The tuple of HSV-components. - */ -export function rgbToHsv(red, green, blue) { - if (red < 0 || red > 255) { - throw new Error('red should be between 0 and 255'); - } - if (green < 0 || green > 255) { - throw new Error('green should be between 0 and 255'); - } - if (blue < 0 || blue > 255) { - throw new Error('blue should be between 0 and 255'); - } - const dRed = red / 255; - const dGreen = green / 255; - const dBlue = blue / 255; - const value = Math.max(Math.max(dRed, dGreen), dBlue); - const chroma = value - Math.min(Math.min(dRed, dGreen), dBlue); - const saturation = value === 0 ? 0 : chroma / value; - let hue; - if (chroma === 0) { - hue = 0; - } else if (value === dRed) { - hue = 60 * ((dGreen - dBlue) / chroma); - } else if (value === dGreen) { - hue = 60 * (2 + (dBlue - dRed) / chroma); - } else { - hue = 60 * (4 + (dRed - dGreen) / chroma); - } - hue = (hue + 360) % 360; - return [hue, saturation, value]; -} -export function approximatelyEqualHsv(hsv1, hsv2) { - const bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2; - const bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002; - const bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002; - return bHue && bSaturation && bValue; -} -function getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent) { - function convertToInt(input) { - return Math.round(255 * input); - } - let red; - let green; - let blue; - if (hueSection >= 0 && hueSection <= 1) { - red = convertToInt(chroma + matchValue); - green = convertToInt(secondLargestComponent + matchValue); - blue = convertToInt(matchValue); - } else if (hueSection > 1 && hueSection <= 2) { - red = convertToInt(secondLargestComponent + matchValue); - green = convertToInt(chroma + matchValue); - blue = convertToInt(matchValue); - } else if (hueSection > 2 && hueSection <= 3) { - red = convertToInt(matchValue); - green = convertToInt(chroma + matchValue); - blue = convertToInt(secondLargestComponent + matchValue); - } else if (hueSection > 3 && hueSection <= 4) { - red = convertToInt(matchValue); - green = convertToInt(secondLargestComponent + matchValue); - blue = convertToInt(chroma + matchValue); - } else if (hueSection > 4 && hueSection <= 5) { - red = convertToInt(secondLargestComponent + matchValue); - green = convertToInt(matchValue); - blue = convertToInt(chroma + matchValue); - } else { - red = convertToInt(chroma + matchValue); - green = convertToInt(matchValue); - blue = convertToInt(secondLargestComponent + matchValue); - } - return [red, green, blue]; -} diff --git a/docs/content/DS_ALGO/algorithms/Conversions/RomanToDecimal.js b/docs/content/DS_ALGO/algorithms/Conversions/RomanToDecimal.js deleted file mode 100644 index 076ccbc858..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/RomanToDecimal.js +++ /dev/null @@ -1,28 +0,0 @@ -const values = { - I: 1, - V: 5, - X: 10, - L: 50, - C: 100, - D: 500, - M: 1000 -}; -export function romanToDecimal(romanNumber) { - let prev = ' '; - let sum = 0; - let newPrev = 0; - for (let i = romanNumber.length - 1; i >= 0; i--) { - const c = romanNumber.charAt(i); - if (prev !== ' ') { - newPrev = values[prev] > newPrev ? values[prev] : newPrev; - } - const currentNum = values[c]; - if (currentNum >= newPrev) { - sum += currentNum; - } else { - sum -= currentNum; - } - prev = c; - } - return sum; -} diff --git a/docs/content/DS_ALGO/algorithms/Conversions/TemperatureConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/TemperatureConversion.js deleted file mode 100644 index 67c0351d46..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/TemperatureConversion.js +++ /dev/null @@ -1,96 +0,0 @@ -// This files has functions to convert different temperature units -// Functions take temperature value as a argument and returns corresponding converted value -const celsiusToFahrenheit = (celsius) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - return Math.round((celsius * 9) / 5 + 32); -}; -const celsiusToKelvin = (celsius) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - return Math.round(celsius + 273.15); -}; -const celsiusToRankine = (celsius) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - return Math.round((celsius * 9) / 5 + 491.67); -}; -const fahrenheitToCelsius = (fahrenheit) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - return Math.round(((fahrenheit - 32) * 5) / 9); -}; -const fahrenheitToKelvin = (fahrenheit) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - return Math.round(((fahrenheit - 32) * 5) / 9 + 273.15); -}; -const fahrenheitToRankine = (fahrenheit) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - return Math.round(fahrenheit + 459.67); -}; -const kelvinToCelsius = (kelvin) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - return Math.round(kelvin - 273.15); -}; -const kelvinToFahrenheit = (kelvin) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - return Math.round(((kelvin - 273.15) * 9) / 5 + 32); -}; -const kelvinToRankine = (kelvin) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - return Math.round((kelvin * 9) / 5); -}; -const rankineToCelsius = (rankine) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - // Wikipedia reference: https://en.wikipedia.org/wiki/Celsius - return Math.round(((rankine - 491.67) * 5) / 9); -}; -const rankineToFahrenheit = (rankine) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - // Wikipedia reference: https://en.wikipedia.org/wiki/Fahrenheit - return Math.round(rankine - 459.67); -}; -const rankineToKelvin = (rankine) => { - // Wikipedia reference: https://en.wikipedia.org/wiki/Rankine_scale - // Wikipedia reference: https://en.wikipedia.org/wiki/Kelvin - return Math.round((rankine * 5) / 9); -}; -const reaumurToKelvin = (reaumur) => { - // Reference:- http://www.csgnetwork.com/temp2conv.html - return Math.round(reaumur * 1.25 + 273.15); -}; -const reaumurToFahrenheit = (reaumur) => { - // Reference:- http://www.csgnetwork.com/temp2conv.html - return Math.round(reaumur * 2.25 + 32); -}; -const reaumurToCelsius = (reaumur) => { - // Reference:- http://www.csgnetwork.com/temp2conv.html - return Math.round(reaumur * 1.25); -}; -const reaumurToRankine = (reaumur) => { - // Reference:- http://www.csgnetwork.com/temp2conv.html - return Math.round(reaumur * 2.25 + 32 + 459.67); -}; -export { - celsiusToFahrenheit, - celsiusToKelvin, - celsiusToRankine, - fahrenheitToCelsius, - fahrenheitToKelvin, - fahrenheitToRankine, - kelvinToCelsius, - kelvinToFahrenheit, - kelvinToRankine, - rankineToCelsius, - rankineToFahrenheit, - rankineToKelvin, - reaumurToCelsius, - reaumurToFahrenheit, - reaumurToKelvin, - reaumurToRankine -}; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/TitleCaseConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/TitleCaseConversion.js deleted file mode 100644 index b4a8e6c234..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/TitleCaseConversion.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - Problem statement and Explanation : https://www.codeproject.com/Tips/162540/Letter-Case-Conversion-Algorithms-Title-Case-Toggl. - [Title case](https://en.wikipedia.org/wiki/Title_case) is a style where all words are capitalized. Officially, title case - does not capitalize some words, such as very short words like "a" or "is", but for the purposes of this function, a general approach - is taken where all words are capitalized regardless of length. -*/ -/** - * The titleCaseConversion function converts a string into a title case string. - * @param {string} inputString The input string which can have any types of letter casing. - * @returns {string} A string that is in title case. - */ -const titleCaseConversion = (inputString) => { - if (inputString === '') return ''; - // Extract all space separated string. - const stringCollections = inputString.split(' ').map((word) => { - let firstChar = ''; - // Get the [ASCII](https://en.wikipedia.org/wiki/ASCII) character code by the use charCodeAt method. - const firstCharCode = word[0].charCodeAt(); - // If the ASCII character code lies between 97 to 122 it means they are in the lowercase so convert it. - if (firstCharCode >= 97 && firstCharCode <= 122) { - // Convert the case by use of the above explanation. - firstChar += String.fromCharCode(firstCharCode - 32); - } else { - // Else store the characters without any modification. - firstChar += word[0]; - } - const newWordChar = word - .slice(1) - .split('') - .map((char) => { - // Get the ASCII character code by the use charCodeAt method. - const presentCharCode = char.charCodeAt(); - // If the ASCII character code lies between 65 to 90, it means they are in the uppercase so convert it. - if (presentCharCode >= 65 && presentCharCode <= 90) { - // Convert the case by use of the above explanation. - return String.fromCharCode(presentCharCode + 32); - } - // Else return the characters without any modification. - return char; - }); - // Return the first converted character and remaining character string. - return firstChar + newWordChar.join(''); - }); - // Convert all words in a string and return it. - return stringCollections.join(' '); -}; -export { - titleCaseConversion -}; -titleCaseConversion -}; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/UpperCaseConversion.js b/docs/content/DS_ALGO/algorithms/Conversions/UpperCaseConversion.js deleted file mode 100644 index f4ef74947d..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/UpperCaseConversion.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - Explanation :- A user gives a string (it can be incomplete lowercase or - partially in lowercase) and then the program converts it into a - completely (all characters in uppercase) uppercase string. The - logic we have used in the following program is: All the lowercase - characters (a-z) has [ASCII](https://en.wikipedia.org/wiki/ASCII) value ranging from 97 to 122 and their - corresponding uppercase characters (A-Z) have ASCII values 32 - lesser than them. For example ‘a‘ has an ASCII value of 97 - and ‘A‘ has an ASCII value of 65 (97 - 32). The same applies to other - characters. -*/ -/** - * upperCaseConversion takes any case-style string and converts it to the uppercase-style string. - * @param {string} inputString Any case style string - * @returns {string} Uppercase string - */ -const upperCaseConversion = (inputString) => { - // Take a string and split it into characters. - const newString = inputString.split('').map((char) => { - // Get a character code by the use charCodeAt method. - const presentCharCode = char.charCodeAt(); - // If the character code lies between 97 to 122, it means they are in the lowercase so convert it. - if (presentCharCode >= 97 && presentCharCode <= 122) { - // Convert the case by use of the above explanation. - return String.fromCharCode(presentCharCode - 32); - } - // Else return the characters without any modification. - return char; - }); - // After modification, with the help of the join method, join all the characters and return them. - return newString.join(''); -}; -export { upperCaseConversion }; diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/ArrayBufferToBase64.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/ArrayBufferToBase64.test.js deleted file mode 100644 index e3c77253bd..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/ArrayBufferToBase64.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import { bufferToBase64 } from '../ArrayBufferToBase64'; -import { TextEncoder } from 'util'; -describe('ArrayBufferToBase64', () => { - it('should encode "Hello, world!" as "SGVsbG8sIHdvcmxkIQ=="', () => { - const testString = 'Hello, world!'; - const encoder = new TextEncoder(); - const helloWorldBuffer = encoder.encode(testString); - const result = bufferToBase64(helloWorldBuffer); - expect(result).toBe('SGVsbG8sIHdvcmxkIQ=='); - }); - it('should encode binary buffer [55,23,177,234,68,26,90] as "Nxex6kQaWg=="', () => { - const testBuffer = new Uint8Array([55, 23, 177, 234, 68, 26, 90]); - const result = bufferToBase64(testBuffer); - expect(result).toBe('Nxex6kQaWg=='); - }); - it('should encode binary buffer [0,1,2,3,4,5,6,7,8,9] as "AAECAwQFBgcICQ=="', () => { - const testBuffer = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - const result = bufferToBase64(testBuffer); - expect(result).toBe('AAECAwQFBgcICQ=='); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/Base64ToArrayBuffer.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/Base64ToArrayBuffer.test.js deleted file mode 100644 index 04bc8b3ea2..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/Base64ToArrayBuffer.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { base64ToBuffer } from '../Base64ToArrayBuffer'; -import { TextDecoder } from 'util'; -describe('Base64ToArrayBuffer', () => { - it('should decode "SGVsbG8sIHdvcmxkIQ==" as "Hello, world!"', () => { - const testBase64String = 'SGVsbG8sIHdvcmxkIQ=='; - const buffer = base64ToBuffer(testBase64String); - const decoder = new TextDecoder(); - const helloWorldString = decoder.decode(buffer); - expect(helloWorldString).toBe('Hello, world!'); - }); - it('should decode base64 "Nxex6kQaWg==" as binary buffer [55,23,177,234,68,26,90]', () => { - const testBase64String = 'Nxex6kQaWg=='; - const buffer = base64ToBuffer(testBase64String); - const array = [...new Uint8Array(buffer)]; - expect(array).toEqual([55, 23, 177, 234, 68, 26, 90]); - }); - it('should decode base64 "AAECAwQFBgcICQ==" as binary buffer [0,1,2,3,4,5,6,7,8,9]', () => { - const testBase64String = 'AAECAwQFBgcICQ=='; - const buffer = base64ToBuffer(testBase64String); - const array = [...new Uint8Array(buffer)]; - expect(array).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToDecimal.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToDecimal.test.js deleted file mode 100644 index d41ec0a8bf..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToDecimal.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import binaryToDecimal from '../BinaryToDecimal'; -describe('BinaryToDecimal', () => { - it('expects to return correct decimal value', () => { - expect(binaryToDecimal('1000')).toBe(8); - }); - it('expects to return correct hexadecimal value for more than one hex digit', () => { - expect(binaryToDecimal('01101000')).toBe(104); - }); - it('expects to return correct hexadecimal value for padding-required binary', () => { - expect(binaryToDecimal('1000101')).toBe(69); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToHex.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToHex.test.js deleted file mode 100644 index 287965ec85..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/BinaryToHex.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import binaryToHex from '../BinaryToHex'; -describe('BinaryToHex', () => { - it('expects to return correct hexadecimal value', () => { - expect(binaryToHex('1000')).toBe('8'); - }); - it('expects to return correct hexadecimal value for more than one hex digit', () => { - expect(binaryToHex('11101010')).toBe('EA'); - }); - it('expects to return correct hexadecimal value for padding-required binary', () => { - expect(binaryToHex('1001101')).toBe('4D'); - }); - it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { - expect(binaryToHex('1111')).toBe(parseInt('1111', 2).toString(16).toUpperCase()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToHex.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToHex.test.js deleted file mode 100644 index a6231cf871..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToHex.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { decimalToHex } from '../DecimalToHex'; -describe('DecimalToHex', () => { - it('expects to return correct hexadecimal value', () => { - expect(decimalToHex(255)).toBe('FF'); - }); - it('expects to return correct hexadecimal value, matching (num).toString(16)', () => { - expect(decimalToHex(32768)).toBe((32768).toString(16).toUpperCase()); - }); - it('expects to not handle negative numbers', () => { - expect(decimalToHex(-32768)).not.toBe((-32768).toString(16).toUpperCase()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToRoman.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToRoman.test.js deleted file mode 100644 index 1570848867..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/DecimalToRoman.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { decimalToRoman } from '../DecimalToRoman'; -describe('decimalToRoman', () => { - it('expects to return correct roman numeral of given number', () => { - expect(decimalToRoman(34)).toBe('XXXIV'); - }); - it('expects to return correct roman numeral of given number', () => { - expect(decimalToRoman(28)).toBe('XXVIII'); - }); - it('expects to return correct roman numeral of given number', () => { - expect(decimalToRoman(2021)).toBe('MMXXI'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/HexToBinary.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/HexToBinary.test.js deleted file mode 100644 index 7f88a97299..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/HexToBinary.test.js +++ /dev/null @@ -1,25 +0,0 @@ -import hexToBinary from '../HexToBinary'; -describe('Testing hexToBinary', () => { - it('expects throw error in invalid types', () => { - expect(() => hexToBinary(false)).toThrowError(); - expect(() => hexToBinary(null)).toThrowError(); - expect(() => hexToBinary(23464)).toThrowError(); - }); - it('expects throw error in invalid hex', () => { - expect(() => hexToBinary('Hello i am not a valid Hex')).toThrowError(); - expect(() => hexToBinary('Gf46f')).toThrowError(); - expect(() => hexToBinary('M')).toThrowError(); - }); - it('expects to return correct hexadecimal value', () => { - expect(hexToBinary('8')).toBe('1000'); - }); - it('expects to return correct binary value for more than one hex digit', () => { - expect(hexToBinary('EA')).toBe('11101010'); - }); - it('expects to test its robustness as it should be case-insensitive', () => { - expect(hexToBinary('4d')).toBe('01001101'); - }); - it('expects to return correct hexadecimal value, matching (num).toString(2)', () => { - expect(hexToBinary('F')).toBe(parseInt('F', 16).toString(2)); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/MeterToFeetConversion.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/MeterToFeetConversion.test.js deleted file mode 100644 index 99c260ab2c..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/MeterToFeetConversion.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { meterToFeet, feetToMeter } from '../MeterToFeetConversion'; -describe('Testing conversion of Meter to Feet', () => { - it('with feet value', () => { - expect(meterToFeet(30.48)).toBe(100); - }); -}); -describe('Testing conversion of Feet to Meter', () => { - it('with feet value', () => { - expect(feetToMeter(10)).toBe(3.048); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/RgbHsvConversion.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/RgbHsvConversion.test.js deleted file mode 100644 index 7d2176b0f8..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/RgbHsvConversion.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { approximatelyEqualHsv, hsvToRgb, rgbToHsv } from '../RgbHsvConversion'; -describe('hsvToRgb', () => { - // Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html - it('should calculate the correct RGB values', () => { - expect(hsvToRgb(0, 0, 0)).toEqual([0, 0, 0]); - expect(hsvToRgb(0, 0, 1)).toEqual([255, 255, 255]); - expect(hsvToRgb(0, 1, 1)).toEqual([255, 0, 0]); - expect(hsvToRgb(60, 1, 1)).toEqual([255, 255, 0]); - expect(hsvToRgb(120, 1, 1)).toEqual([0, 255, 0]); - expect(hsvToRgb(240, 1, 1)).toEqual([0, 0, 255]); - expect(hsvToRgb(300, 1, 1)).toEqual([255, 0, 255]); - expect(hsvToRgb(180, 0.5, 0.5)).toEqual([64, 128, 128]); - expect(hsvToRgb(234, 0.14, 0.88)).toEqual([193, 196, 224]); - expect(hsvToRgb(330, 0.75, 0.5)).toEqual([128, 32, 80]); - }); -}); -describe('rgbToHsv', () => { - // "approximatelyEqualHsv" needed because of small deviations due to rounding for the RGB-values - it('should calculate the correct HSV values', () => { - expect(approximatelyEqualHsv(rgbToHsv(0, 0, 0), [0, 0, 0])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(255, 255, 255), [0, 0, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(255, 0, 0), [0, 1, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(255, 255, 0), [60, 1, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(0, 255, 0), [120, 1, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(0, 0, 255), [240, 1, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(255, 0, 255), [300, 1, 1])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(64, 128, 128), [180, 0.5, 0.5])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(193, 196, 224), [234, 0.14, 0.88])).toEqual(true); - expect(approximatelyEqualHsv(rgbToHsv(128, 32, 80), [330, 0.75, 0.5])).toEqual(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/RomanToDecimal.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/RomanToDecimal.test.js deleted file mode 100644 index 69ca8419ad..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/RomanToDecimal.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { romanToDecimal } from '../RomanToDecimal'; -describe('romanToDecimal', () => { - it('XXIIVV', () => { - expect(romanToDecimal('XXIIVV')).toBe(28); - }); - it('MDCCCIV', () => { - expect(romanToDecimal('MDCCCIV')).toBe(1804); - }); - it('XXIVI', () => { - expect(romanToDecimal('XXIVI')).toBe(25); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/TemperatureConversion.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/TemperatureConversion.test.js deleted file mode 100644 index 56cbe8752e..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/TemperatureConversion.test.js +++ /dev/null @@ -1,97 +0,0 @@ -import * as tc from '../TemperatureConversion.js'; -describe('Testing Conversion of Celsius to fahrenheit', () => { - it('with celsius value', () => { - const test1 = tc.celsiusToFahrenheit(10); - expect(test1).toBe(50); - }); -}); -describe('Testing Conversion of Celsius to kelvin', () => { - it('with celsius value', () => { - const test1 = tc.celsiusToKelvin(15); - expect(test1).toBe(288); - }); -}); -describe('Testing Conversion of Celsius to Rankine', () => { - it('with celsius value', () => { - const test1 = tc.celsiusToRankine(28); - expect(test1).toBe(542); - }); -}); -describe('Testing Conversion of Fahrenheit to Celsius', () => { - it('with Fahrenheit value', () => { - const test1 = tc.fahrenheitToCelsius(134); - expect(test1).toBe(57); - }); -}); -describe('Testing Conversion of Fahrenheit to Kelvin', () => { - it('with Fahrenheit value', () => { - const test1 = tc.fahrenheitToKelvin(125); - expect(test1).toBe(325); - }); -}); -describe('Testing Conversion of Fahrenheit to Rankine', () => { - it('with Fahrenheit value', () => { - const test1 = tc.fahrenheitToRankine(10); - expect(test1).toBe(470); - }); -}); -describe('Testing Conversion of Kelvin to Celsius', () => { - it('with Kelvin value', () => { - const test1 = tc.kelvinToCelsius(100); - expect(test1).toBe(-173); - }); -}); -describe('Testing Conversion of Kelvin to Fahrenheit', () => { - it('with Kelvin value', () => { - const test1 = tc.kelvinToFahrenheit(20); - expect(test1).toBe(-424); - }); -}); -describe('Testing Conversion of Kelvin to Rankine', () => { - it('with kelvin value', () => { - const test1 = tc.kelvinToRankine(69); - expect(test1).toBe(124); - }); -}); -describe('Testing Conversion of Rankine to Celsius', () => { - it('with Rankine value', () => { - const test1 = tc.rankineToCelsius(234); - expect(test1).toBe(-143); - }); -}); -describe('Testing Conversion of Rankine to Fahrenheit', () => { - it('with Rankine value', () => { - const test1 = tc.rankineToFahrenheit(98); - expect(test1).toBe(-362); - }); -}); -describe('Testing Conversion of Rankine to Kelvin', () => { - it('with Rankine value', () => { - const test1 = tc.rankineToKelvin(10); - expect(test1).toBe(6); - }); -}); -describe('Testing Conversion of Reamur to Celsius', () => { - it('with Reamur value', () => { - const test1 = tc.reaumurToCelsius(100); - expect(test1).toBe(125); - }); -}); -describe('Testing Conversion of Reamur to Fahrenheit', () => { - it('with Reamur value', () => { - const test1 = tc.reaumurToFahrenheit(100); - expect(test1).toBe(257); - }); -}); -describe('Testing Conversion of Reamur to Kelvin', () => { - it('with Reamur value', () => { - const test1 = tc.reaumurToKelvin(100); - expect(test1).toBe(398); - }); -}); -describe('Testing Conversion of Reamur to Rankine', () => { - it('with Reamur value', () => { - const test1 = tc.reaumurToRankine(100); - expect(test1).toBe(717); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/TitleCaseConversion.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/TitleCaseConversion.test.js deleted file mode 100644 index d7f18c3526..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/TitleCaseConversion.test.js +++ /dev/null @@ -1,39 +0,0 @@ -import { titleCaseConversion } from '../TitleCaseConversion'; -describe('Tests for the titleCaseConversion function', () => { - it('should return an empty string when the input is an empty string', () => { - expect(titleCaseConversion('')).toEqual(''); - }); - it('should return the input string when the input string is a title case string', () => { - expect(titleCaseConversion('A Proper Title Case String')).toEqual('A Proper Title Case String'); - }); - it('should return a title case string when input is an all-uppercase string', () => { - expect(titleCaseConversion('ALL UPPER CASE')).toEqual('All Upper Case'); - }); - it('should return a title case string when input is a title case string of with spaces', () => { - expect(titleCaseConversion('ALL UPPERCASE')).toEqual('All Uppercase'); - }); - it('should return a title case string when input is a title case string of with no spaces', () => { - expect(titleCaseConversion('ALLUPPERCASE')).toEqual('Alluppercase'); - }); - it('should return a title case string when input is a title case string with punctuation', () => { - expect(titleCaseConversion('All Title Case!')).toEqual('All Title Case!'); - }); - it('should return a title case string when input is an all-lowercase string with no spaces', () => { - expect(titleCaseConversion('lowercaseinput')).toEqual('Lowercaseinput'); - }); - it('should return a title case string when input is an all-lowercase string with spaces', () => { - expect(titleCaseConversion('lowercase input')).toEqual('Lowercase Input'); - }); - it('should return a title case string when input is an all-lowercase string with punctuation', () => { - expect(titleCaseConversion('lower, case, input.')).toEqual('Lower, Case, Input.'); - }); - it('should return a title case string when input is an mixed-case string', () => { - expect(titleCaseConversion('mixeD CaSe INPuT')).toEqual('Mixed Case Input'); - }); - it('should return a title case string when input is an mixed-case string with no spaces', () => { - expect(titleCaseConversion('mixeDCaSeINPuT')).toEqual('Mixedcaseinput'); - }); - it('should return a title case string when input is an mixed-case string with punctuation', () => { - expect(titleCaseConversion('mixeD, CaSe, INPuT!')).toEqual('Mixed, Case, Input!'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Conversions/test/UpperCaseConverstion.test.js b/docs/content/DS_ALGO/algorithms/Conversions/test/UpperCaseConverstion.test.js deleted file mode 100644 index 69727ed559..0000000000 --- a/docs/content/DS_ALGO/algorithms/Conversions/test/UpperCaseConverstion.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import { upperCaseConversion } from '../UpperCaseConversion'; -describe('Test the upperCaseConversion function', () => { - it('should return an empty string when the input is an empty string', () => { - expect(upperCaseConversion('')).toEqual(''); - }); - it('should return an all-uppercase string when input is an all-uppercase string', () => { - expect(upperCaseConversion('ALLUPPERCASE')).toEqual('ALLUPPERCASE'); - }); - it('should return an all-uppercase string when input is an all-uppercase string with spaces', () => { - expect(upperCaseConversion('ALL UPPERCASE')).toEqual('ALL UPPERCASE'); - }); - it('should return an all-uppercase string when input is an all-uppercase string with punctuation', () => { - expect(upperCaseConversion('ALL UPPER-CASE!')).toEqual('ALL UPPER-CASE!'); - }); - it('should return an all-uppercase string when input is an all-lowercase string', () => { - expect(upperCaseConversion('lowercaseinput')).toEqual('LOWERCASEINPUT'); - }); - it('should return an all-uppercase string when input is an all-lowercase string with spaces', () => { - expect(upperCaseConversion('lowercase input')).toEqual('LOWERCASE INPUT'); - }); - it('should return an all-uppercase string when input is an all-lowercase string with punctuation', () => { - expect(upperCaseConversion('lower-case, input.')).toEqual('LOWER-CASE, INPUT.'); - }); - it('should return an all-uppercase string when input is an mixed-case string', () => { - expect(upperCaseConversion('mixeDCaSeINPuT')).toEqual('MIXEDCASEINPUT'); - }); - it('should return an all-uppercase string when input is an mixed-case string with spaces', () => { - expect(upperCaseConversion('mixeD CaSe INPuT')).toEqual('MIXED CASE INPUT'); - }); - it('should return an all-uppercase string when input is an mixed-case string with punctuation', () => { - expect(upperCaseConversion('mixeD-CaSe INPuT!')).toEqual('MIXED-CASE INPUT!'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Recursive/BinaryEquivalent.js b/docs/content/DS_ALGO/algorithms/Recursive/BinaryEquivalent.js deleted file mode 100644 index 79ee05bd02..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/BinaryEquivalent.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Problem Statement: Given a positive number `num`, find it's binary equivalent using recursion - * - * What is Binary Equivalent? - * - In binary number system, a number is represented in terms of 0s and 1s, - * for example: - * - Binary Of 2 = 10 - * - Binary of 3 = 11 - * - Binary of 4 = 100 - * - * Reference on how to find Binary Equivalent - * - https://byjus.com/maths/decimal-to-binary/ - * - */ -export const binaryEquivalent = (num) => { - if (num === 0 || num === 1) { - return String(num); - } - return binaryEquivalent(Math.floor(num / 2)) + String(num % 2); -}; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/BinarySearch.js b/docs/content/DS_ALGO/algorithms/Recursive/BinarySearch.js deleted file mode 100644 index 4b613b1445..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/BinarySearch.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @function BinarySearch - * @description Search the integer inside the sorted integers array using Binary Search Algorithm. - * @param {Integer[]} arr - sorted array of integers - * @param {Integer} low - The input integer - * @param {Integer} high - The input integer - * @param {Integer} searchValue - The input integer - * @return {Integer} - return index of searchValue if found else return -1. - * @see [BinarySearch](https://en.wikipedia.org/wiki/Binary_search_algorithm) - */ -const binarySearch = (arr, searchValue, low = 0, high = arr.length - 1) => { - // base case - if (high < low || arr.length === 0) return -1; - const mid = low + Math.floor((high - low) / 2); - // If the element is present at the middle - if (arr[mid] === searchValue) { - return mid; - } - // If element is smaller than mid, then - // it can only be present in left subarray - if (arr[mid] > searchValue) { - return binarySearch(arr, searchValue, low, mid - 1); - } - // Else the element can only be present in right subarray - return binarySearch(arr, searchValue, mid + 1, high); -}; -export { binarySearch }; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/EucledianGCD.js b/docs/content/DS_ALGO/algorithms/Recursive/EucledianGCD.js deleted file mode 100644 index 5a4e1b0441..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/EucledianGCD.js +++ /dev/null @@ -1,28 +0,0 @@ -function euclideanGCDRecursive(first, second) { - /* - Calculates GCD of two numbers using Euclidean Recursive Algorithm - :param first: First number - :param second: Second number - :return: GCD of the numbers - */ - if (second === 0) { - return first; - } else { - return euclideanGCDRecursive(second, first % second); - } -} -function euclideanGCDIterative(first, second) { - /* - Calculates GCD of two numbers using Euclidean Iterative Algorithm - :param first: First number - :param second: Second number - :return: GCD of the numbers - */ - while (second !== 0) { - const temp = second; - second = first % second; - first = temp; - } - return first; -} -export { euclideanGCDIterative, euclideanGCDRecursive }; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/Factorial.js b/docs/content/DS_ALGO/algorithms/Recursive/Factorial.js deleted file mode 100644 index 799397db90..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/Factorial.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @function Factorial - * @description function to find factorial using recursion. - * @param {Integer} n - The input integer - * @return {Integer} - Factorial of n. - * @see [Factorial](https://en.wikipedia.org/wiki/Factorial) - * @example 5! = 1*2*3*4*5 = 120 - * @example 2! = 1*2 = 2 - */ -const factorial = (n) => { - if (n === 0) { - return 1; - } - return n * factorial(n - 1); -}; -export { factorial }; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/FibonacciNumberRecursive.js b/docs/content/DS_ALGO/algorithms/Recursive/FibonacciNumberRecursive.js deleted file mode 100644 index 2663227543..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/FibonacciNumberRecursive.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @function Fibonacci - * @description Function to return the N-th Fibonacci number. - * @param {Integer} n - The input integer - * @return {Integer} - Return the N-th Fibonacci number - * @see [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number) - */ -const fibonacci = (n) => { - if (n < 2) { - return n; - } - return fibonacci(n - 2) + fibonacci(n - 1); -}; -export { fibonacci }; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/FloodFill.js b/docs/content/DS_ALGO/algorithms/Recursive/FloodFill.js deleted file mode 100644 index 6787a21321..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/FloodFill.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Flood fill. - * - * Flood fill, also called seed fill, is an algorithm that determines and alters the area connected to a given node in a - * multi-dimensional array with some matching attribute. It is used in the "bucket" fill tool of paint programs to fill - * connected, similarly-colored areas with a different color. - * - * (description adapted from https://en.wikipedia.org/wiki/Flood_fill) - * @see https://www.techiedelight.com/flood-fill-algorithm/ - */ -const neighbors = [ - [-1, -1], - [-1, 0], - [-1, 1], - [0, -1], - [0, 1], - [1, -1], - [1, 0], - [1, 1] -]; -/** - * Implements the flood fill algorithm through a breadth-first approach using a queue. - * - * @param rgbData The image to which the algorithm is applied. - * @param location The start location on the image. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - */ -export function breadthFirstSearch(rgbData, location, targetColor, replacementColor) { - if (location[0] < 0 || location[0] >= rgbData.length || location[1] < 0 || location[1] >= rgbData[0].length) { - throw new Error('location should point to a pixel within the rgbData'); - } - const queue = []; - queue.push(location); - while (queue.length > 0) { - breadthFirstFill(rgbData, location, targetColor, replacementColor, queue); - } -} -/** - * Implements the flood fill algorithm through a depth-first approach using recursion. - * - * @param rgbData The image to which the algorithm is applied. - * @param location The start location on the image. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - */ -export function depthFirstSearch(rgbData, location, targetColor, replacementColor) { - if (location[0] < 0 || location[0] >= rgbData.length || location[1] < 0 || location[1] >= rgbData[0].length) { - throw new Error('location should point to a pixel within the rgbData'); - } - depthFirstFill(rgbData, location, targetColor, replacementColor); -} -/** - * Utility-function to implement the breadth-first loop. - * - * @param rgbData The image to which the algorithm is applied. - * @param location The start location on the image. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - * @param queue The locations that still need to be visited. - */ -function breadthFirstFill(rgbData, location, targetColor, replacementColor, queue) { - const currentLocation = queue[0]; - queue.shift(); - if (rgbData[currentLocation[0]][currentLocation[1]] === targetColor) { - rgbData[currentLocation[0]][currentLocation[1]] = replacementColor; - for (let i = 0; i < neighbors.length; i++) { - const x = currentLocation[0] + neighbors[i][0]; - const y = currentLocation[1] + neighbors[i][1]; - if (x >= 0 && x < rgbData.length && y >= 0 && y < rgbData[0].length) { - queue.push([x, y]); - } - } - } -} -/** - * Utility-function to implement the depth-first loop. - * - * @param rgbData The image to which the algorithm is applied. - * @param location The start location on the image. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - */ -function depthFirstFill(rgbData, location, targetColor, replacementColor) { - if (rgbData[location[0]][location[1]] === targetColor) { - rgbData[location[0]][location[1]] = replacementColor; - for (let i = 0; i < neighbors.length; i++) { - const x = location[0] + neighbors[i][0]; - const y = location[1] + neighbors[i][1]; - if (x >= 0 && x < rgbData.length && y >= 0 && y < rgbData[0].length) { - depthFirstFill(rgbData, [x, y], targetColor, replacementColor); - } - } - } -} diff --git a/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.js b/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.js deleted file mode 100644 index e13141eea5..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * The Koch snowflake is a fractal curve and one of the earliest fractals to have been described. - * - * The Koch snowflake can be built up iteratively, in a sequence of stages. The first stage is an equilateral triangle, - * and each successive stage is formed by adding outward bends to each side of the previous stage, making smaller - * equilateral triangles. This can be achieved through the following steps for each line: - * 1. divide the line segment into three segments of equal length. - * 2. draw an equilateral triangle that has the middle segment from step 1 as its base and points outward. - * 3. remove the line segment that is the base of the triangle from step 2. - * - * (description adapted from https://en.wikipedia.org/wiki/Koch_snowflake) - * (for a more detailed explanation and an implementation in the Processing language, see - * https://natureofcode.com/book/chapter-8-fractals/ #84-the-koch-curve-and-the-arraylist-technique). - */ -/** Class to handle the vector calculations. */ -export class Vector2 { - constructor(x, y) { - this.x = x; - this.y = y; - } - /** - * Vector addition - * - * @param vector The vector to be added. - * @returns The sum-vector. - */ - add(vector) { - const x = this.x + vector.x; - const y = this.y + vector.y; - return new Vector2(x, y); - } - /** - * Vector subtraction - * - * @param vector The vector to be subtracted. - * @returns The difference-vector. - */ - subtract(vector) { - const x = this.x - vector.x; - const y = this.y - vector.y; - return new Vector2(x, y); - } - /** - * Vector scalar multiplication - * - * @param scalar The factor by which to multiply the vector. - * @returns The scaled vector. - */ - multiply(scalar) { - const x = this.x * scalar; - const y = this.y * scalar; - return new Vector2(x, y); - } - /** - * Vector rotation (see https://en.wikipedia.org/wiki/Rotation_matrix) - * - * @param angleInDegrees The angle by which to rotate the vector. - * @returns The rotated vector. - */ - rotate(angleInDegrees) { - const radians = (angleInDegrees * Math.PI) / 180; - const ca = Math.cos(radians); - const sa = Math.sin(radians); - const x = ca * this.x - sa * this.y; - const y = sa * this.x + ca * this.y; - return new Vector2(x, y); - } -} -/** - * Go through the number of iterations determined by the argument "steps". - * - * Be careful with high values (above 5) since the time to calculate increases exponentially. - * - * @param initialVectors The vectors composing the shape to which the algorithm is applied. - * @param steps The number of iterations. - * @returns The transformed vectors after the iteration-steps. - */ -export function iterate(initialVectors, steps) { - let vectors = initialVectors; - for (let i = 0; i < steps; i++) { - vectors = iterationStep(vectors); - } - return vectors; -} -/** - * Loops through each pair of adjacent vectors. - * - * Each line between two adjacent vectors is divided into 4 segments by adding 3 additional vectors in-between the - * original two vectors. The vector in the middle is constructed through a 60 degree rotation so it is bent outwards. - * - * @param vectors The vectors composing the shape to which the algorithm is applied. - * @returns The transformed vectors after the iteration-step. - */ -function iterationStep(vectors) { - const newVectors = []; - for (let i = 0; i < vectors.length - 1; i++) { - const startVector = vectors[i]; - const endVector = vectors[i + 1]; - newVectors.push(startVector); - const differenceVector = endVector.subtract(startVector).multiply(1 / 3); - newVectors.push(startVector.add(differenceVector)); - newVectors.push(startVector.add(differenceVector).add(differenceVector.rotate(60))); - newVectors.push(startVector.add(differenceVector.multiply(2))); - } - newVectors.push(vectors[vectors.length - 1]); - return newVectors; -} diff --git a/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.manual-test.js b/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.manual-test.js deleted file mode 100644 index b1435c4930..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/KochSnowflake.manual-test.js +++ /dev/null @@ -1,52 +0,0 @@ -import { Vector2, iterate } from './KochSnowflake'; -/** - * Method to render the Koch snowflake to a canvas. - * - * @param canvasWidth The width of the canvas. - * @param steps The number of iterations. - * @returns The canvas of the rendered Koch snowflake. - */ -function getKochSnowflake(canvasWidth = 600, steps = 5) { - if (canvasWidth <= 0) { - throw new Error('canvasWidth should be greater than zero'); - } - const offsetX = canvasWidth / 10.0; - const offsetY = canvasWidth / 3.7; - const vector1 = new Vector2(offsetX, offsetY); - const vector2 = new Vector2(canvasWidth / 2, Math.sin(Math.PI / 3) * canvasWidth * 0.8 + offsetY); - const vector3 = new Vector2(canvasWidth - offsetX, offsetY); - const initialVectors = []; - initialVectors.push(vector1); - initialVectors.push(vector2); - initialVectors.push(vector3); - initialVectors.push(vector1); - const vectors = iterate(initialVectors, steps); - return drawToCanvas(vectors, canvasWidth, canvasWidth); -} -/** - * Utility-method to render the Koch snowflake to a canvas. - * - * @param vectors The vectors defining the edges to be rendered. - * @param canvasWidth The width of the canvas. - * @param canvasHeight The height of the canvas. - * @returns The canvas of the rendered edges. - */ -function drawToCanvas(vectors, canvasWidth, canvasHeight) { - const canvas = document.createElement('canvas'); - canvas.width = canvasWidth; - canvas.height = canvasHeight; - // Draw the edges - const ctx = canvas.getContext('2d'); - ctx.beginPath(); - ctx.moveTo(vectors[0].x, vectors[0].y); - for (let i = 1; i < vectors.length; i++) { - ctx.lineTo(vectors[i].x, vectors[i].y); - } - ctx.stroke(); - return canvas; -} -// plot the results if the script is executed in a browser with a window-object -if (typeof window !== 'undefined') { - const canvas = getKochSnowflake(); - document.body.append(canvas); -} diff --git a/docs/content/DS_ALGO/algorithms/Recursive/Palindrome.js b/docs/content/DS_ALGO/algorithms/Recursive/Palindrome.js deleted file mode 100644 index 19466ab823..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/Palindrome.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @function Palindrome - * @description Check whether the given string is Palindrome or not. - * @param {String} str - The input string - * @return {Boolean}. - * @see [Palindrome](https://en.wikipedia.org/wiki/Palindrome) - */ -const palindrome = (str) => { - if (typeof str !== 'string') { - throw new TypeError('Invalid Input'); - } - if (str.length <= 1) { - return true; - } - if (str[0] !== str[str.length - 1]) { - return false; - } else { - return palindrome(str.slice(1, str.length - 1)); - } -}; -export { palindrome }; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/SubsequenceRecursive.js b/docs/content/DS_ALGO/algorithms/Recursive/SubsequenceRecursive.js deleted file mode 100644 index 507ef11604..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/SubsequenceRecursive.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Problem Statement: Find all distinct, non-empty subsequence of given string in lexicographical order using recursive approach. - * - * What is subsequence? - * A Subsequence is sequence obtained by deleting some or no elements without changing the order of elements - * Example: Given a string = "abcd" - * 1. "abc" is a subsequence - * 2. "abd" is a subsequence - * 3. But "ba" is not a subsequence (because order is changed) - * - * What is lexicographical order? - * In simple terms, lexicographical order is dictionary order. - * Example: Given a string = "abcd" - * 1. "abc" will come before "abcd". - * 2. "abd" will come before "ac". - * - * References for meaning of subsequence & lexicographical: - * https://en.wikipedia.org/wiki/Subsequence - * https://en.wikipedia.org/wiki/Lexicographic_order - */ -export const subsequence = (str, seq, low, output = []) => { - if (low <= str.length && str.length !== 0) { - output.push(seq); - } - for (let i = low; i < str.length; i++) { - subsequence(str, seq + str[i], i + 1, output); - } - return output; -}; diff --git a/docs/content/DS_ALGO/algorithms/Recursive/TowerOfHanoi.js b/docs/content/DS_ALGO/algorithms/Recursive/TowerOfHanoi.js deleted file mode 100644 index ad599527bb..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/TowerOfHanoi.js +++ /dev/null @@ -1,15 +0,0 @@ -// wiki - https://en.wikipedia.org/wiki/Tower_of_Hanoi -// Recursive Javascript function to solve tower of hanoi -export function TowerOfHanoi(n, from, to, aux, output = []) { - if (n === 1) { - output.push(`Move disk 1 from rod ${from} to rod ${to}`); - return output; - } - TowerOfHanoi(n - 1, from, aux, to, output); - output.push(`Move disk ${n} from rod ${from} to rod ${to}`); - TowerOfHanoi(n - 1, aux, to, from, output); - return output; -} -// Driver code (A, C, B are the name of rods) -// const n = 4 -// TowerOfHanoi(n, 'A', 'C', 'B') diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/BinarySearch.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/BinarySearch.test.js deleted file mode 100644 index 9b4fd08b35..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/BinarySearch.test.js +++ /dev/null @@ -1,26 +0,0 @@ -import { binarySearch } from '../BinarySearch'; -describe('BinarySearch', () => { - const arr = [2, 3, 4, 10, 25, 40, 45, 60, 100, 501, 700, 755, 800, 999]; - const low = 0; - const high = arr.length - 1; - it('should return index 3 for searchValue 10', () => { - const searchValue = 10; - expect(binarySearch(arr, searchValue, low, high)).toBe(3); - }); - it('should return index 0 for searchValue 2', () => { - const searchValue = 2; - expect(binarySearch(arr, searchValue, low, high)).toBe(0); - }); - it('should return index 13 for searchValue 999', () => { - const searchValue = 999; - expect(binarySearch(arr, searchValue, low, high)).toBe(13); - }); - it('should return -1 for searchValue 1', () => { - const searchValue = 1; - expect(binarySearch(arr, searchValue, low, high)).toBe(-1); - }); - it('should return -1 for searchValue 1000', () => { - const searchValue = 1000; - expect(binarySearch(arr, searchValue, low, high)).toBe(-1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/Factorial.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/Factorial.test.js deleted file mode 100644 index 8b3be2cca1..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/Factorial.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import { factorial } from '../Factorial'; -describe('Factorial', () => { - it('should return factorial 1 for value "0"', () => { - expect(factorial(0)).toBe(1); - }); - it('should return factorial 120 for value "5"', () => { - expect(factorial(5)).toBe(120); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/FibonacciNumberRecursive.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/FibonacciNumberRecursive.test.js deleted file mode 100644 index 4bac438e84..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/FibonacciNumberRecursive.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { fibonacci } from '../FibonacciNumberRecursive'; -describe('FibonacciNumberRecursive', () => { - it('should return 0', () => { - expect(fibonacci(0)).toBe(0); - }); - it('should return 1', () => { - expect(fibonacci(1)).toBe(1); - }); - it('should return 5', () => { - expect(fibonacci(5)).toBe(5); - }); - it('should return 9', () => { - expect(fibonacci(9)).toBe(34); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/FloodFill.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/FloodFill.test.js deleted file mode 100644 index 52d9758a5f..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/FloodFill.test.js +++ /dev/null @@ -1,73 +0,0 @@ -import { breadthFirstSearch, depthFirstSearch } from '../FloodFill'; -// some constants -const black = [0, 0, 0]; -const green = [0, 255, 0]; -const violet = [255, 0, 255]; -const white = [255, 255, 255]; -const orange = [255, 128, 0]; -describe('FloodFill', () => { - it('should calculate the correct colors using breadth-first approach', () => { - expect(testBreadthFirst([1, 1], green, orange, [1, 1])).toEqual(orange); - expect(testBreadthFirst([1, 1], green, orange, [0, 1])).toEqual(violet); - expect(testBreadthFirst([1, 1], green, orange, [6, 4])).toEqual(white); - }); - it('should calculate the correct colors using depth-first approach', () => { - expect(testDepthFirst([1, 1], green, orange, [1, 1])).toEqual(orange); - expect(testDepthFirst([1, 1], green, orange, [0, 1])).toEqual(violet); - expect(testDepthFirst([1, 1], green, orange, [6, 4])).toEqual(white); - }); -}); -/** - * Utility-function to test the function "breadthFirstSearch". - * - * @param fillLocation The start location on the image where the flood fill is applied. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - * @param testLocation The location of the color to be checked. - * @return The color at testLocation. - */ -function testBreadthFirst(fillLocation, targetColor, replacementColor, testLocation) { - const rgbData = generateTestRgbData(); - breadthFirstSearch(rgbData, fillLocation, targetColor, replacementColor); - return rgbData[testLocation[0]][testLocation[1]]; -} -/** - * Utility-function to test the function "depthFirstSearch". - * - * @param fillLocation The start location on the image where the flood fill is applied. - * @param targetColor The old color to be replaced. - * @param replacementColor The new color to replace the old one. - * @param testLocation The location of the color to be checked. - * @return The color at testLocation. - */ -function testDepthFirst(fillLocation, targetColor, replacementColor, testLocation) { - // eslint-disable-line - const rgbData = generateTestRgbData(); - depthFirstSearch(rgbData, fillLocation, targetColor, replacementColor); - return rgbData[testLocation[0]][testLocation[1]]; -} -/** - * Generates the rgbData-matrix for the tests. - * - * @return example rgbData-matrix. - */ -function generateTestRgbData() { - const layout = [ - [violet, violet, green, green, black, green, green], - [violet, green, green, black, green, green, green], - [green, green, green, black, green, green, green], - [black, black, green, black, white, white, green], - [violet, violet, black, violet, violet, white, white], - [green, green, green, violet, violet, violet, violet], - [violet, violet, violet, violet, violet, violet, violet] - ]; - // transpose layout-matrix so the x-index comes before the y-index - const transposed = []; - for (let x = 0; x < layout[0].length; x++) { - transposed[x] = []; - for (let y = 0; y < layout.length; y++) { - transposed[x][y] = layout[y][x]; - } - } - return transposed; -} diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/KochSnowflake.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/KochSnowflake.test.js deleted file mode 100644 index 135a6dd53c..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/KochSnowflake.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import { iterate, Vector2 } from '../KochSnowflake'; -describe('KochSnowflake', () => { - it('should produce the correctly-transformed vectors', () => { - expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[0]).toEqual({ x: 0, y: 0 }); - expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[1]).toEqual({ x: 1 / 3, y: 0 }); - expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[2]).toEqual({ x: 1 / 2, y: Math.sin(Math.PI / 3) / 3 }); - expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[3]).toEqual({ x: 2 / 3, y: 0 }); - expect(iterate([new Vector2(0, 0), new Vector2(1, 0)], 1)[4]).toEqual({ x: 1, y: 0 }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Recursive/test/palindrome.test.js b/docs/content/DS_ALGO/algorithms/Recursive/test/palindrome.test.js deleted file mode 100644 index ca2e37ff32..0000000000 --- a/docs/content/DS_ALGO/algorithms/Recursive/test/palindrome.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { palindrome } from '../Palindrome'; -describe('Palindrome', () => { - it('expects to return true for palindrome string', () => { - const isPalindrome = palindrome('madam'); - expect(isPalindrome).toBe(true); - }); - it('expects to return true for Empty String', () => { - const isPalindrome = palindrome(''); - expect(isPalindrome).toBe(true); - }); - it('expects to return false for non-palindrome string', () => { - const isPalindrome = palindrome('foobar'); - expect(isPalindrome).toBe(false); - }); - it('Throw Error for Invalid Input', () => { - expect(() => palindrome(123)).toThrow('Invalid Input'); - expect(() => palindrome(null)).toThrow('Invalid Input'); - expect(() => palindrome(undefined)).toThrow('Invalid Input'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/AlphaNumericalSort.js b/docs/content/DS_ALGO/algorithms/Sorts/AlphaNumericalSort.js deleted file mode 100644 index a3a2b6d072..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/AlphaNumericalSort.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - https://en.wikipedia.org/wiki/Natural_sort_order - In computing, natural sort order (or natural sorting) is the ordering of strings in alphabetical order, - except that multi-digit numbers are treated atomically, i.e., as if they were a single character. Natural sort order - has been promoted as being more human-friendly ("natural") than machine-oriented, pure alphabetical sort order.[1] - For example, in alphabetical sorting, "z11" would be sorted before "z2" because the "1" in the first string is sorted as smaller - than "2", while in natural sorting "z2" is sorted before "z11" because "2" is treated as smaller than "11". - Alphabetical sorting: - 1.z11 - 2.z2 - Natural sorting: - 1. z2 - 2. z11 - P.S. use this function, as there are a lot of implementations on the stackoverflow and other forums, but many of them don't work correctly (can't pass all my tests) -*/ -const alphaNumericalSort = (a, b) => { - /* - https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare - The localeCompare() method returns a number indicating whether a reference string comes before, or after, or is the same as the given string in sort order. - The new locales and options arguments let applications specify the language whose sort order should be used and customize the behavior of the function. - In older implementations, which ignore the locales and options arguments, the locale and sort order used are entirely implementation-dependent. - Syntax: - localeCompare(compareString, locales, options) - */ - return a.localeCompare(b, undefined, { numeric: true }); -}; -export { alphaNumericalSort }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/BeadSort.js b/docs/content/DS_ALGO/algorithms/Sorts/BeadSort.js deleted file mode 100644 index 2b97cc9c84..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/BeadSort.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Bead Sort, also known as Gravity sort. - * - * This algorithm was inspired from natural phenomena and was designed keeping in mind objects (or beads) falling under - * the influence of gravity. - * - * NOTE: It only works for arrays of positive integers. - * - * Wikipedia: https://en.wikipedia.org/wiki/Bead_sort - */ -export function beadSort(sequence) { - /* Let's ensure our sequence has only Positive Integers */ - if (sequence.some((integer) => integer < 0)) { - throw RangeError('Sequence must be a list of Positive integers Only!'); - } - const sequenceLength = sequence.length; - const max = Math.max(...sequence); - // Set initial Grid - const grid = sequence.map((number) => { - const maxArr = new Array(max); - for (let i = 0; i < number; i++) { - maxArr[i] = '*'; - } - return maxArr; - }); - // Drop the Beads! - for (let col = 0; col < max; col++) { - let beadsCount = 0; - for (let row = 0; row < sequenceLength; row++) { - if (grid[row][col] === '*') { - beadsCount++; - } - } - for (let row = sequenceLength - 1; row > -1; row--) { - if (beadsCount) { - grid[row][col] = '*'; - beadsCount--; - } else {} - grid[row][col] = undefined; - } - } -} -/* Finally, let's turn our Bead rows into their Respective Numbers */ -return grid.map((beadArray) => { - const beadsArray = beadArray.filter((bead) => bead === '*'); - return beadsArray.length; -}); -} -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/BogoSort.js b/docs/content/DS_ALGO/algorithms/Sorts/BogoSort.js deleted file mode 100644 index ecabb8b396..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/BogoSort.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Checks whether the given array is sorted in ascending order. - */ -export function isSorted(array) { - const length = array.length; - for (let i = 0; i < length - 1; i++) { - if (array[i] > array[i + 1]) { - return false; - } - } - return true; -} -/** - * Shuffles the given array randomly in place. - */ -function shuffle(array) { - for (let i = array.length - 1; i; i--) { - const m = Math.floor(Math.random() * i); - const n = array[i - 1]; - array[i - 1] = array[m]; - array[m] = n; - } -} -/** - * Implementation of the bogosort algorithm. - * - * This sorting algorithm randomly rearranges the array until it is sorted. - * - * For more information see: https://en.wikipedia.org/wiki/Bogosort - */ -export function bogoSort(items) { - while (!isSorted(items)) { - shuffle(items); - } - return items; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/BubbleSort.js b/docs/content/DS_ALGO/algorithms/Sorts/BubbleSort.js deleted file mode 100644 index d166256905..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/BubbleSort.js +++ /dev/null @@ -1,54 +0,0 @@ -/* Bubble Sort is an algorithm to sort an array. It - * compares adjacent element and swaps their position - * The big O on bubble sort in worst and best case is O(N^2). - * Not efficient. - * Somehow if the array is sorted or nearly sorted then we can optimize bubble sort by adding a flag. - * - * In bubble sort, we keep iterating while something was swapped in - * the previous inner-loop iteration. By swapped I mean, in the - * inner loop iteration, we check each number if the number proceeding - * it is greater than itself, if so we swap them. - * - * Wikipedia: https://en.wikipedia.org/wiki/Bubble_sort - * Animated Visual: https://www.toptal.com/developers/sorting-algorithms/bubble-sort - */ -/** - * Using 2 for loops. - */ -export function bubbleSort(items) { - const length = items.length; - let noSwaps; - for (let i = length; i > 0; i--) { - // flag for optimization - noSwaps = true; - // Number of passes - for (let j = 0; j < i - 1; j++) { - // Compare the adjacent positions - if (items[j] > items[j + 1]) { - // Swap the numbers - [items[j], items[j + 1]] = [items[j + 1], items[j]]; - noSwaps = false; - } - } - if (noSwaps) { - break; - } - } - return items; -} -/** - * Using a while loop and a for loop. - */ -export function alternativeBubbleSort(arr) { - let swapped = true; - while (swapped) { - swapped = false; - for (let i = 0; i < arr.length - 1; i++) { - if (arr[i] > arr[i + 1]) { - [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; - swapped = true; - } - } - } - return arr; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/BucketSort.js b/docs/content/DS_ALGO/algorithms/Sorts/BucketSort.js deleted file mode 100644 index eccec713d0..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/BucketSort.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * BucketSort implementation. - * - * Wikipedia says: Bucket sort, or bin sort, is a sorting algorithm that works by distributing the elements of an array - * into a number of buckets. Each bucket is then sorted individually, either using a different sorting algorithm, or by - * recursively applying the bucket sorting algorithm. It is a distribution sort, and is a cousin of radix sort in the - * most to least significant digit flavour. Bucket sort is a generalization of pigeonhole sort. Bucket sort can be - * implemented with comparisons and therefore can also be considered a comparison sort algorithm. The computational - * complexity estimates involve the number of buckets. - * - * @see https://en.wikipedia.org/wiki/Bucket_sort#:~:text=Bucket%20sort%2C%20or%20bin%20sort,applying%20the%20bucket%20sorting%20algorithm.&text=Sort%20each%20non%2Dempty%20bucket. - * - * Time Complexity of Solution: - * Best Case O(n); Average Case O(n); Worst Case O(n) - * - * @param {number[]} list The array of numbers to be sorted. - * @param {number} size The size of the buckets used. If not provided, size will be 5. - * @return {number[]} An array of numbers sorted in increasing order. - */ -export function bucketSort(list, size) { - if (undefined === size) { - size = 5; - } - if (list.length === 0) { - return list; - } - let min = list[0]; - let max = list[0]; - // find min and max - for (let iList = 0; iList < list.length; iList++) { - if (list[iList] < min) { - min = list[iList]; - } else if (list[iList] > max) { - max = list[iList]; - } - } - // how many buckets we need - const count = Math.floor((max - min) / size) + 1; - // create buckets - const buckets = []; - for (let iCount = 0; iCount < count; iCount++) { - buckets.push([]); - } - // bucket fill - for (let iBucket = 0; iBucket < list.length; iBucket++) { - const key = Math.floor((list[iBucket] - min) / size); - buckets[key].push(list[iBucket]); - } - const sorted = []; - // now sort every bucket and merge it to the sorted list - for (let iBucket = 0; iBucket < buckets.length; iBucket++) { - const arr = buckets[iBucket].sort((a, b) => a - b); - for (let iSorted = 0; iSorted < arr.length; iSorted++) { - sorted.push(arr[iSorted]); - } - } - return sorted; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/CocktailShakerSort.js b/docs/content/DS_ALGO/algorithms/Sorts/CocktailShakerSort.js deleted file mode 100644 index 20dfe805a5..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/CocktailShakerSort.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Cocktail Shaker Sort is an algorithm that is a Bidirectional Bubble Sort. - * - * The algorithm extends bubble sort by operating in two directions. - * While it improves on bubble sort by more quickly moving items to the beginning of the list, it provides only marginal - * performance improvements. - * - * Wikipedia (Cocktail Shaker Sort): https://en.wikipedia.org/wiki/Cocktail_shaker_sort - * Wikipedia (Bubble Sort): https://en.wikipedia.org/wiki/Bubble_sort - */ -export function cocktailShakerSort(items) { - for (let i = items.length - 1; i > 0; i--) { - let j; - // Backwards - for (j = items.length - 1; j > i; j--) { - if (items[j] < items[j - 1]) { - [items[j], items[j - 1]] = [items[j - 1], items[j]]; - } - } - // Forwards - for (j = 0; j < i; j++) { - if (items[j] > items[j + 1]) { - [items[j], items[j + 1]] = [items[j + 1], items[j]]; - } - } - } - return items; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/CombSort.js b/docs/content/DS_ALGO/algorithms/Sorts/CombSort.js deleted file mode 100644 index 15b914aa08..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/CombSort.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Comb sort improves on bubble sort. - * - * The basic idea is to eliminate turtles, or small values - * near the end of the list, since in a bubble sort these slow the sorting - * down tremendously. Rabbits, large values around the beginning of the list, - * do not pose a problem in bubble sort. - * - * In bubble sort, when any two elements are compared, they always have a - * gap (distance from each other) of 1. The basic idea of comb sort is - * that the gap can be much more than 1. The inner loop of bubble sort, - * which does the actual swap, is modified such that gap between swapped - * elements goes down (for each iteration of outer loop) in steps of - * a "shrink factor" k: [ n/k, n/k2, n/k3, ..., 1 ]. - * - * Wikipedia: https://en.wikipedia.org/wiki/Comb_sort - */ -/** - * combSort returns an array of numbers sorted in increasing order. - * - * @param {number[]} list The array of numbers to sort. - * @return {number[]} The array of numbers sorted in increasing order. - */ -function combSort(list) { - if (list.length === 0) { - return list; - } - const shrink = 1.3; - let gap = list.length; - let isSwapped = true; - let i = 0; - while (gap > 1 || isSwapped) { - // Update the gap value for a next comb - gap = parseInt(parseFloat(gap) / shrink, 10); - isSwapped = false; - i = 0; - while (gap + i < list.length) { - if (list[i] > list[i + gap]) { - [list[i], list[i + gap]] = [list[i + gap], list[i]]; - isSwapped = true; - } - i += 1; - } - } - return list; -} -export { - combSort -}; -combSort -}; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/CountingSort.js b/docs/content/DS_ALGO/algorithms/Sorts/CountingSort.js deleted file mode 100644 index 280ae59246..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/CountingSort.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Counting sort is an algorithm for sorting a collection - * of objects according to keys that are small integers. - * - * It is an integer sorting algorithm. - * - * Wikipedia: https://en.wikipedia.org/wiki/Counting_sort - * Animated Visual: https://www.cs.usfca.edu/~galles/visualization/CountingSort.html - */ -export const countingSort = (arr, min, max) => { - // Create an auxiliary resultant array - const res = []; - // Create and initialize the frequency[count] array - const count = new Array(max - min + 1).fill(0); - // Populate the freq array - for (let i = 0; i < arr.length; i++) { - count[arr[i] - min]++; - } - // Create a prefix sum array out of the frequency[count] array - count[0] -= 1; - for (let i = 1; i < count.length; i++) { - count[i] += count[i - 1]; - } - // Populate the result array using the prefix sum array - for (let i = arr.length - 1; i >= 0; i--) { - res[count[arr[i] - min]] = arr[i]; - count[arr[i] - min]--; - } - return res; -}; -/** - * Implementation of Counting Sort - */ -// const array = [3, 0, 2, 5, 4, 1] -// countingSort(array, 0, 5) diff --git a/docs/content/DS_ALGO/algorithms/Sorts/CycleSort.js b/docs/content/DS_ALGO/algorithms/Sorts/CycleSort.js deleted file mode 100644 index c8a9d303f4..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/CycleSort.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Cycle sort is an in-place, unstable sorting algorithm, - * a comparison sort that is theoretically optimal in terms of the total - * number of writes to the original array, unlike any other in-place sorting - * algorithm. It is based on the idea that the permutation to be sorted can - * be factored into cycles, which can individually be rotated to give a sorted result. - * - * Wikipedia: https://en.wikipedia.org/wiki/Cycle_sort - */ -/** - * cycleSort takes an input array of numbers and returns the array sorted in increasing order. - * - * @param {number[]} list An array of numbers to be sorted. - * @return {number[]} An array of numbers sorted in increasing order. - */ -function cycleSort(list) { - for (let cycleStart = 0; cycleStart < list.length; cycleStart++) { - let value = list[cycleStart]; - let position = cycleStart; - // search position - for (let i = cycleStart + 1; i < list.length; i++) { - if (list[i] < value) { - position++; - } - } - // if it is the same, continue - if (position === cycleStart) { - continue; - } - while (value === list[position]) { - position++; - } - const oldValue = list[position]; - list[position] = value; - value = oldValue; - // rotate the rest - while (position !== cycleStart) { - position = cycleStart; - for (let i = cycleStart + 1; i < list.length; i++) { - if (list[i] < value) { - position++; - } - } - while (value === list[position]) { - position++; - } - const oldValueCycle = list[position]; - list[position] = value; - value = oldValueCycle; - } - } - return list; -} -export { - cycleSort -}; -cycleSort -}; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/FindSecondLargestElement.js b/docs/content/DS_ALGO/algorithms/Sorts/FindSecondLargestElement.js deleted file mode 100644 index dce6d9af27..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/FindSecondLargestElement.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Find Second Largest is a real technical interview question. - * Chances are you will be asked to find the second largest value - * inside of an array of numbers. You must also be able to filter - * out duplicate values. It's important to know how to do this with - * clean code that is also easy to explain. - * - * Resources: - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set - */ -const secondLargestElement = (array) => { - const largestElement = Math.max(...array); - let element = 0; - for (let i = 0; i < array.length; i++) { - if (element < array[i] && array[i] !== largestElement) { - element = array[i]; - } - } - return element; -}; -export { secondLargestElement }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/FisherYatesShuffle.js b/docs/content/DS_ALGO/algorithms/Sorts/FisherYatesShuffle.js deleted file mode 100644 index 16568e1268..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/FisherYatesShuffle.js +++ /dev/null @@ -1,15 +0,0 @@ -export const shuffle = (array) => { - let maxLength = array.length; - let temp; - let idx; - // While there remain elements to shuffle... - while (maxLength) { - // Pick a remaining element... - idx = Math.floor(Math.random() * maxLength--); - // And swap it with the current element - temp = array[maxLength]; - array[maxLength] = array[idx]; - array[idx] = temp; - } - return array; -}; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/FlashSort.js b/docs/content/DS_ALGO/algorithms/Sorts/FlashSort.js deleted file mode 100644 index ab158b0e9e..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/FlashSort.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Flashsort is a distribution sorting algorithm showing linear - * computational complexity O(n) for uniformly distributed - * data sets and relatively little additional memory requirement. - * - * Wikipedia: https://en.wikipedia.org/wiki/Flashsort - */ -export function flashSort(arr) { - let max = 0; - let min = arr[0]; - const n = arr.length; - const m = ~~(0.45 * n); - const l = new Array(m); - for (let i = 1; i < n; ++i) { - if (arr[i] < min) { - min = arr[i]; - } - if (arr[i] > arr[max]) { - max = i; - } - } - if (min === arr[max]) { - return arr; - } - const c1 = (m - 1) / (arr[max] - min); - for (let k = 0; k < m; k++) { - l[k] = 0; - } - for (let j = 0; j < n; ++j) { - const k = ~~(c1 * (arr[j] - min)); - ++l[k]; - } - for (let p = 1; p < m; ++p) { - l[p] = l[p] + l[p - 1]; - } - let hold = arr[max]; - arr[max] = arr[0]; - arr[0] = hold; - // permutation - let move = 0; - let t; - let flash; - let j = 0; - let k = m - 1; - while (move < n - 1) { - while (j > l[k] - 1) { - ++j; - k = ~~(c1 * (arr[j] - min)); - } - if (k < 0) break; - flash = arr[j]; - while (j !== l[k]) { - k = ~~(c1 * (flash - min)); - hold = arr[(t = --l[k])]; - arr[t] = flash; - flash = hold; - ++move; - } - } - // insertion - for (j = 1; j < n; j++) { - hold = arr[j]; - let i = j - 1; - while (i >= 0 && arr[i] > hold) { - arr[i + 1] = arr[i--]; - } - arr[i + 1] = hold; - } - return arr; -} -/** - * Implementation of Flash Sort - */ -// const array = [3, 0, 2, 5, -1, 4, 1, -2] -// flashSort(array) diff --git a/docs/content/DS_ALGO/algorithms/Sorts/GnomeSort.js b/docs/content/DS_ALGO/algorithms/Sorts/GnomeSort.js deleted file mode 100644 index 73f36d79cd..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/GnomeSort.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Gnome sort is a sort algorithm that moving an element to its proper place is accomplished by a series of swap - * more information: https://en.wikipedia.org/wiki/Gnome_sort - * - */ -export function gnomeSort(items) { - if (items.length <= 1) { - return; - } - let i = 1; - while (i < items.length) { - if (items[i - 1] <= items[i]) { - i++; - } else { - [items[i], items[i - 1]] = [items[i - 1], items[i]]; - i = Math.max(1, i - 1); - } - } -} -// Implementation of gnomeSort -// const ar = [5, 6, 7, 8, 1, 2, 12, 14] -// gnomeSort(ar) diff --git a/docs/content/DS_ALGO/algorithms/Sorts/HeapSort.js b/docs/content/DS_ALGO/algorithms/Sorts/HeapSort.js deleted file mode 100644 index f512d9b4ad..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/HeapSort.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Build a max heap out of the array. A heap is a specialized tree like - * data structure that satisfies the heap property. The heap property - * for max heap is the following: "if P is a parent node of C, then the - * key (the value) of node P is greater than the key of node C" - * Source: https://en.wikipedia.org/wiki/Heap_(data_structure) - */ -/* eslint no-extend-native: ["off", { "exceptions": ["Object"] }] */ -Array.prototype.heapify = function (index, heapSize) { - let largest = index; - const leftIndex = 2 * index + 1; - const rightIndex = 2 * index + 2; - if (leftIndex < heapSize && this[leftIndex] > this[largest]) { - largest = leftIndex; - } - if (rightIndex < heapSize && this[rightIndex] > this[largest]) { - largest = rightIndex; - } - if (largest !== index) { - const temp = this[largest]; - this[largest] = this[index]; - this[index] = temp; - this.heapify(largest, heapSize); - } -}; -/* - * Heap sort sorts an array by building a heap from the array and - * utilizing the heap property. - * For more information see: https://en.wikipedia.org/wiki/Heapsort - */ -export function heapSort(items) { - const length = items.length; - for (let i = Math.floor(length / 2) - 1; i > -1; i--) { - items.heapify(i, length); - } - for (let j = length - 1; j > 0; j--) { - const tmp = items[0]; - items[0] = items[j]; - items[j] = tmp; - items.heapify(0, j); - } - return items; -} -// Implementation of heapSort -// const ar = [5, 6, 7, 8, 1, 2, 12, 14] -// heapSort(ar) diff --git a/docs/content/DS_ALGO/algorithms/Sorts/HeapSortV2.js b/docs/content/DS_ALGO/algorithms/Sorts/HeapSortV2.js deleted file mode 100644 index 9f975e8963..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/HeapSortV2.js +++ /dev/null @@ -1,31 +0,0 @@ -let arrayLength = 0; -/* to create MAX array */ -function heapRoot(input, i) { - const left = 2 * i + 1; - const right = 2 * i + 2; - let max = i; - if (left < arrayLength && input[left] > input[max]) { - max = left; - } - if (right < arrayLength && input[right] > input[max]) { - max = right; - } - if (max !== i) { - swap(input, i, max); - heapRoot(input, max); - } -} -function swap(input, indexA, indexB) { - [input[indexA], input[indexB]] = [input[indexB], input[indexA]]; -} -export function heapSort(input) { - arrayLength = input.length; - for (let i = Math.floor(arrayLength / 2); i >= 0; i -= 1) { - heapRoot(input, i); - } - for (let i = input.length - 1; i > 0; i--) { - swap(input, 0, i); - arrayLength--; - heapRoot(input, 0); - } -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/InsertionSort.js b/docs/content/DS_ALGO/algorithms/Sorts/InsertionSort.js deleted file mode 100644 index f24f6a2b78..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/InsertionSort.js +++ /dev/null @@ -1,56 +0,0 @@ -/* In insertion sort, we divide the initial unsorted array into two parts; - * sorted part and unsorted part. Initially the sorted part just has one - * element (Array of only 1 element is a sorted array). We then pick up - * element one by one from unsorted part; insert into the sorted part at - * the correct position and expand sorted part one element at a time. - */ -export function insertionSort(unsortedList) { - const len = unsortedList.length; - for (let i = 1; i < len; i++) { - let j; - const tmp = unsortedList[i]; // Copy of the current element. - /* Check through the sorted part and compare with the number in tmp. If large, shift the number */ - for (j = i - 1; j >= 0 && unsortedList[j] > tmp; j--) { - // Shift the number - unsortedList[j + 1] = unsortedList[j]; - } - // Insert the copied number at the correct position - // in sorted part. - unsortedList[j + 1] = tmp; - } -} -/** - * @function insertionSortAlternativeImplementation - * @description InsertionSort is a stable sorting algorithm - * @param {Integer[]} array - Array of integers - * @return {Integer[]} - Sorted array - * @see [InsertionSort](https://en.wikipedia.org/wiki/Quicksort) - */ -/* - * Big-O Analysis - * Time Complexity - - O(N^2) on average and worst case scenario - - O(N) on best case scenario (when input array is already almost sorted) - * Space Complexity - - O(1) -*/ -export function insertionSortAlternativeImplementation(array) { - const length = array.length; - if (length < 2) return array; - for (let i = 1; i < length; i++) { - // Take current element in array - const currentItem = array[i]; - // Take index of previous element in array - let j = i - 1; - // While j >= 0 and previous element is greater than current element - while (j >= 0 && array[j] > currentItem) { - // Move previous, greater element towards the unsorted part - array[j + 1] = array[j]; - j--; - } - // Insert currentItem number at the correct position in sorted part. - array[j + 1] = currentItem; - } - // Return array sorted in ascending order - return array; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/IntroSort.js b/docs/content/DS_ALGO/algorithms/Sorts/IntroSort.js deleted file mode 100644 index bbd5d0b017..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/IntroSort.js +++ /dev/null @@ -1,308 +0,0 @@ -/** - * @function Intosort (As implemented in STD C++ Lib) - * The function performs introsort which is used in - * C++ Standard LIbrary, the implementation is inspired from] - * library routine itself. - * ALGORITHM: - * 1) It performs quicksort on array until the recursion depth - * exceeds a pre determined limit. - * 2) If the limit is reached it switches to heapsort - * 3) For array size less than a threshold(16) directly - * does insertion sort on array - * @param {Array} array the array to be sorted - * @param {Function} compare the comparison function - * - * @see [Introsort](https://en.wikipedia.org/wiki/Introsort) - * @author [Lakhan Nad](https://github.com/Lakhan-Nad) - */ -function introsort(array, compare) { - /** - * @function Default Comparison Function - * This function is same as implemented by - * Array.sort method - * @see [StackOverflow](https://stackoverflow.com/questions/47334234/how-to-implement-array-prototype-sort-default-compare-function) - * @param {*} a variable 1 - * @param {*} b variable 2 - * @returns {Number} - * -1 if a is less than b - * 0 if a is equal to b - * 1 if a greater than b - */ - const defaultComparator = function(x, y) { - if (x === undefined && y === undefined) return 0; - if (x === undefined) return 1; - if (y === undefined) return -1; - const xString = toString(x); - const yString = toString(y); - if (xString < yString) return -1; - if (xString > yString) return 1; - return 0; - }; - /** - * @function helper function for defaultComparator - * Converts a given object to String - * @throws TypeError() - * @param {Object} obj - * @returns {String} String representation of given object - */ - const toString = function(obj) { - if (obj === null) return 'null'; - if (typeof obj === 'boolean' || typeof obj === 'number') { - return obj.toString(); - } - if (typeof obj === 'string') return obj; - if (typeof obj === 'symbol') throw new TypeError(); - return obj.toString(); - }; - /** - * Checks if the value passed is an array - * or not - */ - if (Array.isArray(array) === false) { - return; - } - /** - * If the compare parameter is not a function - * or not passed at all use default comparator - * function - */ - if (typeof compare !== 'function') { - compare = defaultComparator; // If compare is not a comparator function - } - /** - * Use a closure to define the whole sort - * implementation this is done through - * [IIFE](https://en.wikipedia.org/wiki/Immediately_invoked_function_expression) - */ - return (function(array, comparator) { - const swap = function(index1, index2) { - const temp = array[index1]; - array[index1] = array[index2]; - array[index2] = temp; - }; - /** - * @constant THRESHOLD - * If the length of array is less than - * this then we simply perform insertion sort - */ - const THRESHOLD = 16; - /** - * @constant TUNEMAXDEPTH - * Constant usec to increase or decrease value - * of maxDepth - */ - const TUNEMAXDEPTH = 1; - const len = array.length; - /** - * Return if array is only of length 1 - * Array of size 1 is always sorted - */ - if (len === 1) { - return; - } - /** - * Calculate maxDepth = log2(len) - * Taken from implementation in stdc++ - */ - const maxDepth = Math.floor(Math.log2(len)) * TUNEMAXDEPTH; - /** - * The very first call to quicksort - * this initiates sort routine - */ - quickSort(0, len, maxDepth); - /** - * A final check call to insertion sort - * on sorted array - */ - insertionSort(0, len); - /** ********************* Implementation of various routines **************************/ - /** - * @function - * This is recursive quicksort implementation in array - * of segment [start,last-1] - * [QuickSort](https://en.wikipedia.org/wiki/Quicksort) - * @param {Number} start the start index of array segment to be sorted - * @param {Number} last one more than the last index of array segment - * @param {Number} depth this measures how many recursive calls are done - */ - function quickSort(start, last, depth) { - if (last - start <= THRESHOLD) { - insertionSort(start, last); - return; - } else if (depth <= 0) { - heapSort(start, last); - return; - } - let pivot = (last + start) >> 1; - pivot = partition(start, last, pivot); - quickSort(start, pivot, depth - 1); - quickSort(pivot + 1, last, depth - 1); - } - /** - * @function Helper function to quicksort - * @param {Number} start the start of array segment to partition - * @param {Number} last one more than last index of the array segment - * @param {Number} pivot the index of pivot to be used - * @returns {Number} the index of pivot after partition - */ - function partition(start, last, pivot) { - swap(start, pivot); - pivot = start; - let lo = start; - let hi = last; - while (true) { - lo++; - while (comparator(array[lo], array[pivot]) <= 0 && lo !== last) { - lo++; - } - hi--; - while (comparator(array[hi], array[pivot]) > 0 && hi !== start) { - hi--; - } - if (lo >= hi) { - break; - } - swap(lo, hi); - } - swap(start, hi); - return hi; - } - /** - * @function - * Performs insertion sort on array of range - * [start, last-1] - * @param {Number} start the first index of array segment to be sorted - * @param {Number} last one more than last index of array to be sorted - */ - function insertionSort(start, last) { - let i, j; - for (i = start + 1; i < last; i++) { - j = i - 1; - while (j >= 0 && comparator(array[j], array[j + 1]) > 0) { - swap(j, j + 1); - j--; - } - } - } - /** - * @function - * Performs heapsort in array segment of range [start, last-1] - * [HeapSort](https://en.wikipedia.org/wiki/Heapsort) - * @param {Number} start the first index of array segment to be sorted - * @param {Number} last one more than last index of array to be sorted - */ - function heapSort(start, last) { - let x = (last + start) >> 1; - while (x - start >= 0) { - heapify(x, start, last); - x--; - } - x = last - 1; - while (x - start > 0) { - swap(start, x); - heapify(start, start, x); - x--; - } - } - /** - * @function Helper function to heapsort routine - * @param {Number} cur the index we need to heapify - * @param {Number} start the start index of array segment that cur belongs to - * @param {Number} last one more than last index of segment that cur belongs to - */ - function heapify(cur, start, last) { - const size = last - start; - let max, lt, rt; - cur = cur - start; - while (true) { - max = cur; - lt = 2 * max + 1; - rt = 2 * max + 2; - if (lt < size && comparator(array[start + max], array[start + lt]) < 0) { - max = lt; - } - if (rt < size && comparator(array[start + max], array[start + rt]) < 0) { - max = rt; - } - if (max !== cur) { - swap(start + cur, start + max); - cur = max; - } else { - break; - } - } - } - })(array, compare); -} -/** - * @example Demo run of the sort routine - * The data is randomly generated - * Returns 'RIGHT:)' if the sort routine worked as expected, - * 'WRONG!!' otherwise - */ -function demo1() { - const data = []; - const size = 1000000; - let i = 0; - let temp; - const c = function(a, b) { - return a - b; - }; - for (i = 0; i < size; i++) { - temp = Math.random() * Number.MAX_SAFE_INTEGER; - data.push(temp); - } - introsort(data, c); - let faulty = false; - for (i = 1; i < size; i++) { - if (data[i] < data[i - 1]) { - faulty = true; - break; - } - } - if (faulty) { - return 'WRONG!!'; - } else { - return 'RIGHT:)'; - } -} -/** - * @example Demo run of the sort routine - * using the default compare function and - * comparing the results with Array.sort - */ -function demo2() { - const data = []; - const data2 = []; - const size = 1000000; - let i = 0; - let temp; - for (i = 0; i < size; i++) { - temp = Math.random() * Number.MAX_SAFE_INTEGER; - data.push(temp); - data2.push(temp); - } - introsort(data); - data2.sort(); - let faulty = false; - for (i = 1; i < size; i++) { - if (data[i] !== data2[i]) { - faulty = true; - break; - } - } - if (faulty) { - return 'WRONG Implemented Comparator!!'; - } else { - return 'Comparator Works Fine:)'; - } -} -export { - introsort, - demo1, - demo2 -}; -introsort, -demo1, -demo2 -}; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/MergeSort.js b/docs/content/DS_ALGO/algorithms/Sorts/MergeSort.js deleted file mode 100644 index 1ea55fe40d..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/MergeSort.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * MergeSort implementation. - * - * Merge Sort is an algorithm where the main list is divided down into two half sized lists, which then have merge sort - * called on these two smaller lists recursively until there is only a sorted list of one. - * - * On the way up the recursive calls, the lists will be merged together inserting - * the smaller value first, creating a larger sorted list. - */ -/** - * Sort and merge two given arrays. - * - * @param {Array} list1 Sublist to break down. - * @param {Array} list2 Sublist to break down. - * @return {Array} The merged list. - */ -export function merge(list1, list2) { - const results = []; - let i = 0; - let j = 0; - while (i < list1.length && j < list2.length) { - if (list1[i] < list2[j]) { - results.push(list1[i++]); - } else { - results.push(list2[j++]); - } - } - return results.concat(list1.slice(i), list2.slice(j)); -} -/** - * Break down the lists into smaller pieces to be merged. - * - * @param {Array} list List to be sorted. - * @return {Array} The sorted list. - */ -export function mergeSort(list) { - if (list.length < 2) return list; - const listHalf = Math.floor(list.length / 2); - const subList1 = list.slice(0, listHalf); - const subList2 = list.slice(listHalf, list.length); - return merge(mergeSort(subList1), mergeSort(subList2)); -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/OddEvenSort.js b/docs/content/DS_ALGO/algorithms/Sorts/OddEvenSort.js deleted file mode 100644 index 897453d7aa..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/OddEvenSort.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - odd-even sort or odd-even transposition sort - is a relatively simple sorting algorithm, developed originally for use on parallel processors with local interconnections. - It is a comparison sort related to bubble sort, with which it shares many characteristics. - for more information : https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort -*/ -// Helper function to swap array items -function swap(arr, i, j) { - const tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; -} -export function oddEvenSort(arr) { - let sorted = false; - while (!sorted) { - sorted = true; - for (let i = 1; i < arr.length - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - sorted = false; - } - } - for (let i = 0; i < arr.length - 1; i += 2) { - if (arr[i] > arr[i + 1]) { - swap(arr, i, i + 1); - sorted = false; - } - } - } -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/PancakeSort.js b/docs/content/DS_ALGO/algorithms/Sorts/PancakeSort.js deleted file mode 100644 index 978625d7f7..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/PancakeSort.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Unlike a traditional sorting algorithm, which attempts to sort with the fewest - * comparisons possible, the goal of pancake sort is to sort the sequence in as few reversals as - * possible. The idea is to do something similar to Selection Sort. We one by one place - * maximum element at the end and reduce the size of current array by one. - * - * Source: https://www.geeksforgeeks.org/pancake-sorting/ - * - * This sorting algorithm is inspired by the pancake problem (hence the name), - * where a spatula can be placed anywhere between two pancakes and flip all pancakes - * above. - * - * The interesting about this algorithm (besides its name) is that instead of comparisons, - * the algorithm relies on flipping an array. - * - * Source: https://en.wikipedia.org/wiki/Pancake_sorting#The_original_pancake_problem - * - */ -/** - * Unlike Array.prototype.reverse, flipArray reverses only a subarray of the given - * array, determined by the parameters startIndex and endIndex - * - * @param {number[]} array The array to flip - * @param {number} startIndex The start of the subarray - * @param {number} endIndex The end of the subarray - * @returns The flipped array - */ -export function flipArray(array, startIndex, endIndex) { - while (startIndex < endIndex) { - // swap front and back of the subarray - const temp = array[startIndex]; - array[startIndex] = array[endIndex]; - array[endIndex] = temp; - // essentially reducing the problem to a smaller subarray - startIndex++; - endIndex--; - } - return array; -} -/** - * Returns the index of the maximum number of a subarray in a given array - * - * @param {number[]} array The array to found the maximum number's index - * @param {*} startIndex The start of the subarray - * @param {*} endIndex The end of the subarray - * @returns The index of the maximum number - */ -export function findMax(array, startIndex, endIndex) { - let maxIndex = 0; - for (let i = startIndex; i <= endIndex; i++) { - if (array[i] > array[maxIndex]) maxIndex = i; - } - return maxIndex; -} -/** - * The Pancake Sort algorithm. - * - * Note that even though it's a completely different concept of sorting an - * array, it's rather simple! - * - * @param {number[]} array The array to sort - * @returns The sorted array - */ -export function pancakeSort(array) { - for (let subarraySize = array.length; subarraySize > 1; subarraySize--) { - const maximumIndex = findMax(array, 0, subarraySize - 1); - if (maximumIndex !== subarraySize - 1) { - flipArray(array, 0, maximumIndex); - flipArray(array, 0, subarraySize - 1); - } - } - return array; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/PigeonHoleSort.js b/docs/content/DS_ALGO/algorithms/Sorts/PigeonHoleSort.js deleted file mode 100644 index 230665dbb6..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/PigeonHoleSort.js +++ /dev/null @@ -1,30 +0,0 @@ -/* -https://en.wikipedia.org/wiki/Pigeonhole_sort -*Pigeonhole sorting is a sorting algorithm that is suitable -* for sorting lists of elements where the number of elements -* (n) and the length of the range of possible key values (N) -* are approximately the same. - */ -export function pigeonHoleSort(arr) { - let min = arr[0]; - let max = arr[0]; - for (let i = 0; i < arr.length; i++) { - if (arr[i] > max) { - max = arr[i]; - } - if (arr[i] < min) { - min = arr[i]; - } - } - const range = max - min + 1; - const pigeonhole = Array(range).fill(0); - for (let i = 0; i < arr.length; i++) { - pigeonhole[arr[i] - min]++; - } - let index = 0; - for (let j = 0; j < range; j++) { - while (pigeonhole[j]-- > 0) { - arr[index++] = j + min; - } - } -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/QuickSort.js b/docs/content/DS_ALGO/algorithms/Sorts/QuickSort.js deleted file mode 100644 index 7ae64bb127..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/QuickSort.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @function QuickSort - * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. - * @param {Integer[]} items - Array of integers - * @return {Integer[]} - Sorted array. - * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) - */ -function quickSort(items) { - const length = items.length; - if (length <= 1) { - return items; - } - const PIVOT = items[0]; - const GREATER = []; - const LESSER = []; - for (let i = 1; i < length; i++) { - if (items[i] > PIVOT) { - GREATER.push(items[i]); - } else { - LESSER.push(items[i]); - } - } - const sorted = [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)]; - return sorted; -} -export { quickSort }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/QuickSortRecursive.js b/docs/content/DS_ALGO/algorithms/Sorts/QuickSortRecursive.js deleted file mode 100644 index 132555d013..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/QuickSortRecursive.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - Quicksort is the most popular sorting algorithm and there have - lots of different implementations but the "recursive" or "Partition in place" - is one of the most efficient implementations below we have discussed how to - implement it. - Partition in place => "in place" Partition in place indicates that we - do not need any other space to store the auxiliary array and the term - "partition" denotes that we split the list into two parts one is less - than the pivot and the other is greater than the pivot and repeats this - process recursively and breaks the problem into sub-problems and makes - it singular so that the behavior or "divide and conquer" get involved - too. - Problem & Source of Explanation => https://www.cs.auckland.ac.nz/software/AlgAnim/qsort1a.html -*/ -/** - * Partition in place QuickSort. - * @param {number[]} inputList list of values. - * @param {number} low lower index for partition. - * @param {number} high higher index for partition. - */ -const quickSort = (inputList, low, high) => { - if (!Array.isArray(inputList)) { - throw new TypeError('Please input a valid list or array.'); - } - if (low < high) { - // get the partition index. - const pIndex = partition(inputList, low, high); - // recursively call the quickSort method again. - quickSort(inputList, low, pIndex - 1); - quickSort(inputList, pIndex + 1, high); - } - return inputList; -}; -/** - * Partition In Place method. - * @param {number[]} partitionList list for partitioning. - * @param {number} low lower index for partition. - * @param {number} high higher index for partition. - * @returns {number} `pIndex` pivot index value. - */ -const partition = (partitionList, low, high) => { - const pivot = partitionList[high]; - let pIndex = low; - for (let index = low; index <= high - 1; index++) { - if (partitionList[index] < pivot) { - // swap variables using array destructuring - [partitionList[index], partitionList[pIndex]] = [partitionList[pIndex], partitionList[index]]; - pIndex += 1; - } - } - [partitionList[pIndex], partitionList[high]] = [partitionList[high], partitionList[pIndex]]; - return pIndex; -}; -export { quickSort }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/RadixSort.js b/docs/content/DS_ALGO/algorithms/Sorts/RadixSort.js deleted file mode 100644 index 0c1676be4e..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/RadixSort.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Radix sorts an integer array without comparing the integers. - * It groups the integers by their digits which share the same - * significant position. - * For more information see: https://en.wikipedia.org/wiki/Radix_sort - */ -export function radixSort(items, RADIX) { - // default radix is then because we usually count to base 10 - if (RADIX === undefined || RADIX < 1) { - RADIX = 10; - } - let maxLength = false; - let placement = 1; - while (!maxLength) { - maxLength = true; - const buckets = []; - for (let i = 0; i < RADIX; i++) { - buckets.push([]); - } - for (let j = 0; j < items.length; j++) { - const tmp = items[j] / placement; - buckets[Math.floor(tmp % RADIX)].push(items[j]); - if (maxLength && tmp > 0) { - maxLength = false; - } - } - let a = 0; - for (let b = 0; b < RADIX; b++) { - const buck = buckets[b]; - for (let k = 0; k < buck.length; k++) { - items[a] = buck[k]; - a++; - } - } - placement *= RADIX; - } - return items; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/SelectionSort.js b/docs/content/DS_ALGO/algorithms/Sorts/SelectionSort.js deleted file mode 100644 index b466ea40ca..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/SelectionSort.js +++ /dev/null @@ -1,35 +0,0 @@ -/* The selection sort algorithm sorts an array by repeatedly finding the minimum element - *(considering ascending order) from unsorted part and putting it at the beginning. The - *algorithm maintains two subarrays in a given array. - *1) The subarray which is already sorted. - *2) Remaining subarray which is unsorted. - * - *In every iteration of selection sort, the minimum element (considering ascending order) - *from the unsorted subarray is picked and moved to the sorted subarray. - */ -export const selectionSort = (list) => { - if (!Array.isArray(list)) { - throw new TypeError('Given input is not an array'); - } - const items = [...list]; // We don't want to modify the original array - const length = items.length; - for (let i = 0; i < length - 1; i++) { - if (typeof items[i] !== 'number') { - throw new TypeError('One of the items in your array is not a number'); - } - // Number of passes - let min = i; // min holds the current minimum number position for each pass; i holds the Initial min number - for (let j = i + 1; j < length; j++) { - // Note that j = i + 1 as we only need to go through unsorted array - if (items[j] < items[min]) { - // Compare the numbers - min = j; // Change the current min number position if a smaller num is found } - } - if (min !== i) { - // After each pass, if the current min num != initial min num, exchange the position. - // Swap the numbers - [items[i], items[min]] = [items[min], items[i]]; - } - } - return items; - }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/ShellSort.js b/docs/content/DS_ALGO/algorithms/Sorts/ShellSort.js deleted file mode 100644 index e2fb1b247f..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/ShellSort.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Shell Sort sorts an array based on insertion sort algorithm - * more information: https://en.wikipedia.org/wiki/Shellsort - * - */ -export function shellSort(items) { - let interval = 1; - while (interval < items.length / 3) { - interval = interval * 3 + 1; - } - while (interval > 0) { - for (let outer = interval; outer < items.length; outer++) { - const value = items[outer]; - let inner = outer; - while (inner > interval - 1 && items[inner - interval] >= value) { - items[inner] = items[inner - interval]; - inner = inner - interval; - } - items[inner] = value; - } - interval = (interval - 1) / 3; - } - return items; -} diff --git a/docs/content/DS_ALGO/algorithms/Sorts/TimSort.js b/docs/content/DS_ALGO/algorithms/Sorts/TimSort.js deleted file mode 100644 index 67eab66247..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/TimSort.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @function Timsort is a hybrid stable sorting algorithm, derived from merge sort and insertion sort, - * designed to perform well on many kinds of real-world data. - * It was implemented by Tim Peters in 2002 for use in the Python programming language. - * It is also used to sort arrays of non-primitive type in Java SE 7, - * on the Android platform, in GNU Octave, on V8, Swift and Rust. - * 1) It sorts small partitions using Insertion Sort. - * 2) Merges the partition using Merge Sort. - * @see [Timsort](https://en.wikipedia.org/wiki/Timsort) - * @param {Array} array - */ -const Timsort = (array) => { - // Default size of a partition - const RUN = 32; - const n = array.length; - // Sorting the partitions using Insertion Sort - for (let i = 0; i < n; i += RUN) { - InsertionSort(array, i, Math.min(i + RUN - 1, n - 1)); - } - for (let size = RUN; size < n; size *= 2) { - for (let left = 0; left < n; left += 2 * size) { - const mid = left + size - 1; - const right = Math.min(left + 2 * size - 1, n - 1); - Merge(array, left, mid, right); - } - } -}; -/** - * @function performs insertion sort on the partition - * @param {Array} array array to be sorted - * @param {Number} left left index of partition - * @param {Number} right right index of partition - */ -const InsertionSort = (array, left, right) => { - for (let i = left + 1; i <= right; i++) { - const key = array[i]; - let j = i - 1; - while (j >= left && array[j] > key) { - array[j + 1] = array[j]; - j--; - } - array[j + 1] = key; - } -}; -/** - * @function merges two sorted partitions - * @param {Array} array array to be sorted - * @param {Number} left left index of partition - * @param {Number} mid mid index of partition - * @param {Number} right right index of partition - */ -const Merge = (array, left, mid, right) => { - if (mid >= right) return; - const len1 = mid - left + 1; - const len2 = right - mid; - const larr = Array(len1); - const rarr = Array(len2); - for (let i = 0; i < len1; i++) { - larr[i] = array[left + i]; - } - for (let i = 0; i < len2; i++) { - rarr[i] = array[mid + 1 + i]; - } - let i = 0; - let j = 0; - let k = left; - while (i < larr.length && j < rarr.length) { - if (larr[i] < rarr[j]) { - array[k++] = larr[i++]; - } else { - array[k++] = rarr[j++]; - } - } - while (i < larr.length) { - array[k++] = larr[i++]; - } - while (j < rarr.length) { - array[k++] = rarr[j++]; - } -}; -/** - * @example Test of Timsort functions. - * Data is randomly generated. - * Return "RIGHT" if it works as expected, - * otherwise "FAULTY" - */ -const demo = () => { - const size = 1000000; - const data = Array(size); - for (let i = 0; i < size; i++) { - data[i] = Math.random() * Number.MAX_SAFE_INTEGER; - } - const isSorted = function (array) { - const n = array.length; - for (let i = 0; i < n - 1; i++) { - if (array[i] > array[i + 1]) return false; - } - return true; - }; - Timsort(data); - if (isSorted(data)) { - return 'RIGHT'; - } else { - return 'FAULTY'; - } -}; -export { Timsort, demo }; diff --git a/docs/content/DS_ALGO/algorithms/Sorts/TopologicalSort.js b/docs/content/DS_ALGO/algorithms/Sorts/TopologicalSort.js deleted file mode 100644 index 0e114529de..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/TopologicalSort.js +++ /dev/null @@ -1,72 +0,0 @@ -export function TopologicalSorter() { - const graph = {}; - let isVisitedNode; - let finishTimeCount; - let finishingTimeList; - let nextNode; - - this.addOrder = function(nodeA, nodeB) { - nodeA = String(nodeA); - nodeB = String(nodeB); - graph[nodeA] = graph[nodeA] || []; - graph[nodeA].push(nodeB); - }; << - << << < HEAD - this.sortAndGetOrderedItems = function() { - === - === = - - this.sortAndGetOrderedItems = function() { - >>> - >>> > 1 f628061e(formatting) - isVisitedNode = Object.create(null); - finishTimeCount = 0; - finishingTimeList = []; - for (const node in graph) { - if (Object.prototype.hasOwnProperty.call(graph, node) && !isVisitedNode[node]) { - dfsTraverse(node); - } - } << - << << < HEAD - finishingTimeList.sort(function(item1, item2) { - return item1.finishTime > item2.finishTime ? -1 : 1; - }); - return finishingTimeList.map(function(value) { - === - === = - - finishingTimeList.sort(function(item1, item2) { - return item1.finishTime > item2.finishTime ? -1 : 1; - }); - - return finishingTimeList.map(function(value) { - >>> - >>> > 1 f628061e(formatting) - return value.node; - }); - }; - - function dfsTraverse(node) { - isVisitedNode[node] = true; - if (graph[node]) { - for (let i = 0; i < graph[node].length; i++) { - nextNode = graph[node][i]; - if (isVisitedNode[nextNode]) continue; - dfsTraverse(nextNode); - } - } - finishingTimeList.push({ - node: node, - finishTime: ++finishTimeCount - }); - } - } - /* TEST */ - // const topoSorter = new TopologicalSorter() - // topoSorter.addOrder(5, 2) - // topoSorter.addOrder(5, 0) - // topoSorter.addOrder(4, 0) - // topoSorter.addOrder(4, 1) - // topoSorter.addOrder(2, 3) - // topoSorter.addOrder(3, 1) - // topoSorter.sortAndGetOrderedItems() \ No newline at end of file diff --git a/docs/content/DS_ALGO/algorithms/Sorts/WiggleSort.js b/docs/content/DS_ALGO/algorithms/Sorts/WiggleSort.js deleted file mode 100644 index a6e188d146..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/WiggleSort.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Wiggle sort sorts the array into a wave like array. - * An array ‘arr[0..n-1]' is sorted in wave form if arr[0] >= arr[1] <= arr[2] >= arr[3] <= arr[4] >= ….. - * - */ -export const wiggleSort = function (arr) { - for (let i = 0; i < arr.length; ++i) { - const shouldNotBeLessThan = i % 2; - const isLessThan = arr[i] < arr[i + 1]; - if (shouldNotBeLessThan && isLessThan) { - [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; - } - } - return arr; -}; -// Implementation of wiggle sort -// > wiggleSort([3, 5, 2, 1, 6, 4]) -// [ 3, 5, 2, 6, 1, 4 ] diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/AlphaNumericalSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/AlphaNumericalSort.test.js deleted file mode 100644 index 74112f4a70..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/AlphaNumericalSort.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import { alphaNumericalSort } from '../AlphaNumericalSort'; -describe('alphaNumericalComparer', () => { - test('given array of eng symbols return correct sorted array', () => { - const src = ['b', 'a', 'c']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['a', 'b', 'c']); - }); - test('given array of numbers return correct sorted array', () => { - const src = ['15', '0', '5']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['0', '5', '15']); - }); - test('correct sort with numbers and strings', () => { - const src = ['3', 'a1b15c', 'z', 'a1b14c']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['3', 'a1b14c', 'a1b15c', 'z']); - }); - test('correct sort with long numbers', () => { - const src = ['abc999999999999999999999999999999999cba', 'abc999999999999999999999999999999990cba', 'ab']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['ab', 'abc999999999999999999999999999999990cba', 'abc999999999999999999999999999999999cba']); - }); - test('correct sort with z prefix', () => { - const src = ['z', 'abc003def', 'abc1def', 'a']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['a', 'abc1def', 'abc003def', 'z']); - }); - test('correct sort with other language', () => { - const src = ['а10б', 'а2б', 'в10г', 'в05г']; - src.sort(alphaNumericalSort); - expect(src).toEqual(['а2б', 'а10б', 'в05г', 'в10г']); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/BeadSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/BeadSort.test.js deleted file mode 100644 index afa8af3152..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/BeadSort.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import { beadSort } from '../BeadSort'; -describe('BeadSort', () => { - it('should sort arrays correctly', () => { - expect(beadSort([5, 4, 3, 2, 1])).toEqual([1, 2, 3, 4, 5]); - expect(beadSort([7, 9, 4, 3, 5])).toEqual([3, 4, 5, 7, 9]); - }); - it('should throw a RangeError when the array contains negative integers', () => { - expect(() => beadSort([-1, 5, 8, 4, 3, 19])).toThrow(RangeError); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/BogoSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/BogoSort.test.js deleted file mode 100644 index 7bd0ffde9b..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/BogoSort.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { bogoSort, isSorted } from '../BogoSort'; -describe('isSorted', () => { - it('should return true for empty arrays', () => { - expect(isSorted([])).toBe(true); - }); - it('should return true for single-element arrays', () => { - expect(isSorted([1])).toBe(true); - }); - it('should return true for arrays that are properly sorted', () => { - expect(isSorted([1, 2, 3])).toBe(true); - }); - it('should return false for arrays that are not properly sorted', () => { - expect(isSorted([3, 2, 1])).toBe(false); - }); -}); -describe('bogoSort', () => { - it('should (eventually) sort the array', () => { - expect(bogoSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/BubbleSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/BubbleSort.test.js deleted file mode 100644 index 9515ff87f8..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/BubbleSort.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { alternativeBubbleSort, bubbleSort } from '../BubbleSort'; -describe('bubbleSort', () => { - it('should sort arrays correctly', () => { - expect(bubbleSort([5, 4, 1, 2, 3])).toEqual([1, 2, 3, 4, 5]); - expect(bubbleSort([])).toEqual([]); - expect(bubbleSort([1, 2, 3])).toEqual([1, 2, 3]); - expect(bubbleSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]); - expect(bubbleSort([5, 6, 7, 8, 9, 4])).toEqual([4, 5, 6, 7, 8, 9]); - }); -}); -describe('alternativeBubbleSort', () => { - it('should sort arrays correctly', () => { - expect(alternativeBubbleSort([5, 4, 1, 2, 3])).toEqual([1, 2, 3, 4, 5]); - expect(alternativeBubbleSort([])).toEqual([]); - expect(alternativeBubbleSort([1, 2, 3])).toEqual([1, 2, 3]); - expect(alternativeBubbleSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/BucketSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/BucketSort.test.js deleted file mode 100644 index b84e2661f9..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/BucketSort.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import { bucketSort } from '../BucketSort'; -describe('Tests for bucketSort function', () => { - it('should correctly sort an input list that is sorted backwards', () => { - const array = [5, 4, 3, 2, 1]; - expect(bucketSort(array)).toEqual([1, 2, 3, 4, 5]); - }); - it('should correctly sort an input list that is unsorted', () => { - const array = [15, 24, 3, 2224, 1]; - expect(bucketSort(array)).toEqual([1, 3, 15, 24, 2224]); - }); - describe('Variations of input array lengths', () => { - it('should return an empty list with the input list is an empty list', () => { - expect(bucketSort([])).toEqual([]); - }); - it('should correctly sort an input list of length 1', () => { - expect(bucketSort([100])).toEqual([100]); - }); - it('should correctly sort an input list of an odd length', () => { - expect(bucketSort([101, -10, 321])).toEqual([-10, 101, 321]); - }); - it('should correctly sort an input list of an even length', () => { - expect(bucketSort([40, 42, 56, 45, 12, 3])).toEqual([3, 12, 40, 42, 45, 56]); - }); - }); - describe('Variations of input array elements', () => { - it('should correctly sort an input list that contains only positive numbers', () => { - expect(bucketSort([50, 33, 11, 2])).toEqual([2, 11, 33, 50]); - }); - it('should correctly sort an input list that contains only negative numbers', () => { - expect(bucketSort([-1, -21, -2, -35])).toEqual([-35, -21, -2, -1]); - }); - it('should correctly sort an input list that contains only a mix of positive and negative numbers', () => { - expect(bucketSort([-40, 42, 56, -45, 12, -3])).toEqual([-45, -40, -3, 12, 42, 56]); - }); - it('should correctly sort an input list that contains only whole numbers', () => { - expect(bucketSort([11, 3, 12, 4, -15])).toEqual([-15, 3, 4, 11, 12]); - }); - it('should correctly sort an input list that contains only decimal numbers', () => { - expect(bucketSort([1.0, 1.42, 2.56, 33.45, 13.12, 2.3])).toEqual([1.0, 1.42, 2.3, 2.56, 13.12, 33.45]); - }); - it('should correctly sort an input list that contains only a mix of whole and decimal', () => { - expect(bucketSort([32.4, 12.42, 56, 45, 12, 3])).toEqual([3, 12, 12.42, 32.4, 45, 56]); - }); - it('should correctly sort an input list that contains only fractional numbers', () => { - expect(bucketSort([0.98, 0.4259, 0.56, -0.456, -0.12, 0.322])).toEqual([-0.456, -0.12, 0.322, 0.4259, 0.56, 0.98]); - }); - it('should correctly sort an input list that contains only a mix of whole, decimal, and fractional', () => { - expect(bucketSort([-40, -0.222, 5.6, -4.5, 12, 0.333])).toEqual([-40, -4.5, -0.222, 0.333, 5.6, 12]); - }); - it('should correctly sort an input list that contains duplicates', () => { - expect(bucketSort([4, 3, 4, 2, 1, 2])).toEqual([1, 2, 2, 3, 4, 4]); - }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/CocktailShakerSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/CocktailShakerSort.test.js deleted file mode 100644 index b1d518804d..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/CocktailShakerSort.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { cocktailShakerSort } from '../CocktailShakerSort'; -describe('CocktailShakerSort', () => { - it('should sort arrays correctly', () => { - expect(cocktailShakerSort([5, 4, 1, 2, 3])).toEqual([1, 2, 3, 4, 5]); - expect(cocktailShakerSort([1, 2, 3])).toEqual([1, 2, 3]); - expect(cocktailShakerSort([5, 6, 7, 8, 1, 2, 12, 14])).toEqual([1, 2, 5, 6, 7, 8, 12, 14]); - }); - it('should work for empty arrays, too', () => { - expect(cocktailShakerSort([])).toEqual([]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/CombSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/CombSort.test.js deleted file mode 100644 index 961f8f32ad..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/CombSort.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import { combSort } from '../CombSort'; -describe('combSort function', () => { - it('should correctly sort an input list that is sorted backwards', () => { - const array = [5, 4, 3, 2, 1]; - expect(combSort(array)).toEqual([1, 2, 3, 4, 5]); - }); - it('should correctly sort an input list that is unsorted', () => { - const array = [15, 24, 3, 2224, 1]; - expect(combSort(array)).toEqual([1, 3, 15, 24, 2224]); - }); - describe('Variations of input array lengths', () => { - it('should return an empty list with the input list is an empty list', () => { - expect(combSort([])).toEqual([]); - }); - it('should correctly sort an input list of length 1', () => { - expect(combSort([100])).toEqual([100]); - }); - it('should correctly sort an input list of an odd length', () => { - expect(combSort([101, -10, 321])).toEqual([-10, 101, 321]); - }); - it('should correctly sort an input list of an even length', () => { - expect(combSort([40, 42, 56, 45, 12, 3])).toEqual([3, 12, 40, 42, 45, 56]); - }); - }); - describe('Variations of input array elements', () => { - it('should correctly sort an input list that contains only positive numbers', () => { - expect(combSort([50, 33, 11, 2])).toEqual([2, 11, 33, 50]); - }); - it('should correctly sort an input list that contains only negative numbers', () => { - expect(combSort([-1, -21, -2, -35])).toEqual([-35, -21, -2, -1]); - }); - it('should correctly sort an input list that contains only a mix of positive and negative numbers', () => { - expect(combSort([-40, 42, 56, -45, 12, -3])).toEqual([-45, -40, -3, 12, 42, 56]); - }); - it('should correctly sort an input list that contains only whole numbers', () => { - expect(combSort([11, 3, 12, 4, -15])).toEqual([-15, 3, 4, 11, 12]); - }); - it('should correctly sort an input list that contains only decimal numbers', () => { - expect(combSort([1.0, 1.42, 2.56, 33.45, 13.12, 2.3])).toEqual([1.0, 1.42, 2.3, 2.56, 13.12, 33.45]); - }); - it('should correctly sort an input list that contains only a mix of whole and decimal', () => { - expect(combSort([32.4, 12.42, 56, 45, 12, 3])).toEqual([3, 12, 12.42, 32.4, 45, 56]); - }); - it('should correctly sort an input list that contains only fractional numbers', () => { - expect(combSort([0.98, 0.4259, 0.56, -0.456, -0.12, 0.322])).toEqual([-0.456, -0.12, 0.322, 0.4259, 0.56, 0.98]); - }); - it('should correctly sort an input list that contains only a mix of whole, decimal, and fractional', () => { - expect(combSort([-40, -0.222, 5.6, -4.5, 12, 0.333])).toEqual([-40, -4.5, -0.222, 0.333, 5.6, 12]); - }); - it('should correctly sort an input list that contains duplicates', () => { - expect(combSort([4, 3, 4, 2, 1, 2])).toEqual([1, 2, 2, 3, 4, 4]); - }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/CycleSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/CycleSort.test.js deleted file mode 100644 index 5f3cb8e442..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/CycleSort.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import { cycleSort } from '../CycleSort'; -describe('cycleSort function', () => { - it('should correctly sort an input list that is sorted backwards', () => { - const array = [5, 4, 3, 2, 1]; - expect(cycleSort(array)).toEqual([1, 2, 3, 4, 5]); - }); - it('should correctly sort an input list that is unsorted', () => { - const array = [15, 24, 3, 2224, 1]; - expect(cycleSort(array)).toEqual([1, 3, 15, 24, 2224]); - }); - describe('Variations of input array lengths', () => { - it('should return an empty list with the input list is an empty list', () => { - expect(cycleSort([])).toEqual([]); - }); - it('should correctly sort an input list of length 1', () => { - expect(cycleSort([100])).toEqual([100]); - }); - it('should correctly sort an input list of an odd length', () => { - expect(cycleSort([101, -10, 321])).toEqual([-10, 101, 321]); - }); - it('should correctly sort an input list of an even length', () => { - expect(cycleSort([40, 42, 56, 45, 12, 3])).toEqual([3, 12, 40, 42, 45, 56]); - }); - }); - describe('Variations of input array elements', () => { - it('should correctly sort an input list that contains only positive numbers', () => { - expect(cycleSort([50, 33, 11, 2])).toEqual([2, 11, 33, 50]); - }); - it('should correctly sort an input list that contains only negative numbers', () => { - expect(cycleSort([-1, -21, -2, -35])).toEqual([-35, -21, -2, -1]); - }); - it('should correctly sort an input list that contains only a mix of positive and negative numbers', () => { - expect(cycleSort([-40, 42, 56, -45, 12, -3])).toEqual([-45, -40, -3, 12, 42, 56]); - }); - it('should correctly sort an input list that contains only whole numbers', () => { - expect(cycleSort([11, 3, 12, 4, -15])).toEqual([-15, 3, 4, 11, 12]); - }); - it('should correctly sort an input list that contains only decimal numbers', () => { - expect(cycleSort([1.0, 1.42, 2.56, 33.45, 13.12, 2.3])).toEqual([1.0, 1.42, 2.3, 2.56, 13.12, 33.45]); - }); - it('should correctly sort an input list that contains only a mix of whole and decimal', () => { - expect(cycleSort([32.4, 12.42, 56, 45, 12, 3])).toEqual([3, 12, 12.42, 32.4, 45, 56]); - }); - it('should correctly sort an input list that contains only fractional numbers', () => { - expect(cycleSort([0.98, 0.4259, 0.56, -0.456, -0.12, 0.322])).toEqual([-0.456, -0.12, 0.322, 0.4259, 0.56, 0.98]); - }); - it('should correctly sort an input list that contains only a mix of whole, decimal, and fractional', () => { - expect(cycleSort([-40, -0.222, 5.6, -4.5, 12, 0.333])).toEqual([-40, -4.5, -0.222, 0.333, 5.6, 12]); - }); - it('should correctly sort an input list that contains duplicates', () => { - expect(cycleSort([4, 3, 4, 2, 1, 2])).toEqual([1, 2, 2, 3, 4, 4]); - }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/FisherYatesShuffle.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/FisherYatesShuffle.test.js deleted file mode 100644 index 122ad88873..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/FisherYatesShuffle.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { shuffle } from '../FisherYatesShuffle'; -describe('shuffle', () => { - it('expects to have a new array with same size', () => { - const fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; - const mixedArray = shuffle(fibonacci); - expect(mixedArray).toHaveLength(fibonacci.length); - }); - it('expects to have a new array with same values', () => { - const fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]; - const mixedArray = shuffle(fibonacci); - expect(mixedArray).toContain(0); - expect(mixedArray).toContain(1); - expect(mixedArray).toContain(2); - expect(mixedArray).toContain(3); - expect(mixedArray).toContain(5); - expect(mixedArray).toContain(8); - expect(mixedArray).toContain(13); - expect(mixedArray).toContain(21); - expect(mixedArray).toContain(34); - expect(mixedArray).toContain(55); - expect(mixedArray).toContain(89); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/InsertionSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/InsertionSort.test.js deleted file mode 100644 index 34aaf8d2be..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/InsertionSort.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { insertionSortAlternativeImplementation } from '../InsertionSort'; -describe('insertionSortAlternativeImplementation', () => { - it('expects to work with empty array', () => { - expect(insertionSortAlternativeImplementation([])).toEqual([]); - }); - it('expects to return input array when array.length is less than 2', () => { - const input = [3]; - expect(insertionSortAlternativeImplementation(input)).toEqual(input); - }); - it('expects to return array sorted in ascending order', () => { - expect(insertionSortAlternativeImplementation([14, 11])).toEqual([11, 14]); - expect(insertionSortAlternativeImplementation([21, 22, 23])).toEqual([21, 22, 23]); - expect(insertionSortAlternativeImplementation([1, 3, 2, 3, 7, 2])).toEqual([1, 2, 2, 3, 3, 7]); - expect(insertionSortAlternativeImplementation([1, 6, 4, 5, 9, 2])).toEqual([1, 2, 4, 5, 6, 9]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/MergeSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/MergeSort.test.js deleted file mode 100644 index 9cdefa75cb..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/MergeSort.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { merge, mergeSort } from '../MergeSort'; -describe('merge', () => { - it('should merge arrays correctly', () => { - expect(merge([5, 4], [1, 2, 3])).toEqual([1, 2, 3, 5, 4]); - expect(merge([], [1, 2])).toEqual([1, 2]); - expect(merge([1, 2, 3], [1])).toEqual([1, 1, 2, 3]); - expect(merge([], [])).toEqual([]); - }); -}); -describe('MergeSort', () => { - it('should work for empty arrays', () => { - expect(mergeSort([])).toEqual([]); - }); - it('should sort arrays correctly', () => { - expect(mergeSort([5, 4])).toEqual([4, 5]); - expect(mergeSort([8, 4, 10, 15, 9])).toEqual([4, 8, 9, 10, 15]); - expect(mergeSort([1, 2, 3])).toEqual([1, 2, 3]); - expect(mergeSort([10, 5, 3, 8, 2, 6, 4, 7, 9, 1])).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/PancakeSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/PancakeSort.test.js deleted file mode 100644 index 8545dfa243..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/PancakeSort.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import { flipArray, findMax, pancakeSort } from '../PancakeSort'; -describe('flipArray', () => { - it('should flip any subarray of any array', () => { - expect(flipArray([1, 2, 3, 4], 0, 3)).toEqual([4, 3, 2, 1]); - expect(flipArray([1, 2, 3, 4, 5], 2, 4)).toEqual([1, 2, 5, 4, 3]); - expect(flipArray([], 0, 0)).toEqual([]); - }); -}); -describe('findMax', () => { - it('should find the index of the maximum value in any subarray of any array', () => { - expect(findMax([1, 3, 2, 5], 0, 3)).toEqual(3); - expect(findMax([1, 3, 2, 5], 0, 2)).toEqual(1); - }); -}); -describe('pancakeSort', () => { - it('should sort any array', () => { - expect(pancakeSort([4, 3, 2, 1])).toEqual([1, 2, 3, 4]); - expect(pancakeSort([3, 1, 4, 2])).toEqual([1, 2, 3, 4]); - expect(pancakeSort([100, 1000, 10, 1])).toEqual([1, 10, 100, 1000]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSort.test.js deleted file mode 100644 index 88eeead63e..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSort.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { quickSort } from '../QuickSort'; -describe('QuickSort', () => { - it('should work for empty arrays', () => { - expect(quickSort([])).toEqual([]); - }); - it('should sort arrays correctly', () => { - expect(quickSort([5, 4, 3, 10, 2, 1])).toEqual([1, 2, 3, 4, 5, 10]); - expect(quickSort([5, 4])).toEqual([4, 5]); - expect(quickSort([1, 2, 3])).toEqual([1, 2, 3]); - expect(quickSort([0, 5, 3, 2, 2])).toEqual([0, 2, 2, 3, 5]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSortRecursive.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSortRecursive.test.js deleted file mode 100644 index d5fb2d96ac..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/QuickSortRecursive.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { quickSort } from '../QuickSortRecursive'; -describe('QuickSortRecursive | Partition In Place Method', () => { - it('Expectedly, throw some error if we pass a non-array input', () => { - expect(() => quickSort('xyz', 0, 2)).toThrow('Please input a valid list or array.'); - expect(() => quickSort(null, 0, 4)).toThrow('Please input a valid list or array.'); - expect(() => quickSort(55, 0, 2)).toThrow('Please input a valid list or array.'); - }); - it('Expectedly, the quickSort method will sort the unsorted list in ascending order', () => { - const unSortArray = [5, 9, 3, 4, 6, 2, 0, 1, 7, 8]; - const sortedExpectedArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - expect(quickSort(unSortArray, 0, unSortArray.length - 1)).toEqual(sortedExpectedArray); - }); - it('Expectedly, the quickSort method will arrange the list of character values in dictionary order.', () => { - const unSortList = ['d', 'e', 'c', 'a', 'f', 'b']; - const sortedExpectedList = ['a', 'b', 'c', 'd', 'e', 'f']; - expect(quickSort(unSortList, 0, unSortList.length - 1)).toEqual(sortedExpectedList); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/Sorts/test/SelectionSort.test.js b/docs/content/DS_ALGO/algorithms/Sorts/test/SelectionSort.test.js deleted file mode 100644 index a5eb382fcf..0000000000 --- a/docs/content/DS_ALGO/algorithms/Sorts/test/SelectionSort.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { selectionSort } from '../SelectionSort'; -describe('selectionSort', () => { - it('expects to return the array sorted in ascending order', () => { - const toSort = [5, 6, 7, 8, 1, 2, 12, 14]; - const expected = [1, 2, 5, 6, 7, 8, 12, 14]; - expect(selectionSort(toSort)).toEqual(expected); - }); - it('expects to throw if it is not a valid array', () => { - expect(() => selectionSort('abc')).toThrow('Given input is not an array'); - expect(() => selectionSort(123)).toThrow('Given input is not an array'); - expect(() => selectionSort({})).toThrow('Given input is not an array'); - expect(() => selectionSort(null)).toThrow('Given input is not an array'); - expect(() => selectionSort()).toThrow('Given input is not an array'); - }); - it('expects to throw if one of the elements in the array is not a number', () => { - expect(() => selectionSort([1, 'x', 2])).toThrow('One of the items in your array is not a number'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/articulation-points/README.md b/docs/content/DS_ALGO/algorithms/graph/articulation-points/README.md deleted file mode 100644 index 9ee8d31b7e..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/articulation-points/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Articulation Points (or Cut Vertices) - -A vertex in an undirected connected graph is an articulation point -(or cut vertex) if removing it (and edges through it) disconnects -the graph. Articulation points represent vulnerabilities in a -connected network - single points whose failure would split the -network into 2 or more disconnected components. They are useful for -designing reliable networks. - -For a disconnected undirected graph, an articulation point is a -vertex removing which increases number of connected components. - -![Articulation Points](https://www.geeksforgeeks.org/wp-content/uploads/ArticulationPoints.png) - -![Articulation Points](https://www.geeksforgeeks.org/wp-content/uploads/ArticulationPoints1.png) - -![Articulation Points](https://www.geeksforgeeks.org/wp-content/uploads/ArticulationPoints21.png) - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/articulation-points-or-cut-vertices-in-a-graph/) -- [YouTube](https://www.youtube.com/watch?v=2kREIkF9UAs&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/articulation-points/articulationPoints.js b/docs/content/DS_ALGO/algorithms/graph/articulation-points/articulationPoints.js deleted file mode 100644 index 9d741cbc4e..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/articulation-points/articulationPoints.js +++ /dev/null @@ -1,120 +0,0 @@ -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * Helper class for visited vertex metadata. - */ -class VisitMetadata { - constructor({ - discoveryTime, - lowDiscoveryTime - }) { - this.discoveryTime = discoveryTime; - this.lowDiscoveryTime = lowDiscoveryTime; - // We need this in order to check graph root node, whether it has two - // disconnected children or not. - this.independentChildrenCount = 0; - } -} -/** - * Tarjan's algorithm for finding articulation points in graph. - * - * @param {Graph} graph - * @return {Object} - */ -export default function articulationPoints(graph) { - // Set of vertices we've already visited during DFS. - const visitedSet = {}; - // Set of articulation points. - const articulationPointsSet = {}; - // Time needed to discover to the current vertex. - let discoveryTime = 0; - // Peek the start vertex for DFS traversal. - const startVertex = graph.getAllVertices()[0]; - const dfsCallbacks = { - /** - * @param {GraphVertex} currentVertex - * @param {GraphVertex} previousVertex - */ - enterVertex: ({ - currentVertex, - previousVertex - }) => { - // Tick discovery time. - discoveryTime += 1; - // Put current vertex to visited set. - visitedSet[currentVertex.getKey()] = new VisitMetadata({ - discoveryTime, - lowDiscoveryTime: discoveryTime - }); - if (previousVertex) { - // Update children counter for previous vertex. - visitedSet[previousVertex.getKey()].independentChildrenCount += 1; - } - }, - /** - * @param {GraphVertex} currentVertex - * @param {GraphVertex} previousVertex - */ - leaveVertex: ({ - currentVertex, - previousVertex - }) => { - if (previousVertex === null) { - // Don't do anything for the root vertex if it is already current (not previous one) - return; - } - // Update the low time with the smallest time of adjacent vertices. - // Get minimum low discovery time from all neighbors. - /** @param {GraphVertex} neighbor */ - visitedSet[currentVertex.getKey()].lowDiscoveryTime = currentVertex - .getNeighbors() - .filter((earlyNeighbor) => earlyNeighbor.getKey() !== previousVertex.getKey()) - /** - * @param {number} lowestDiscoveryTime - * @param {GraphVertex} neighbor - */ - .reduce((lowestDiscoveryTime, neighbor) => { - const neighborLowTime = visitedSet[neighbor.getKey()].lowDiscoveryTime; - return neighborLowTime < lowestDiscoveryTime ? neighborLowTime : lowestDiscoveryTime; - }, visitedSet[currentVertex.getKey()].lowDiscoveryTime); - // Detect whether previous vertex is articulation point or not. - // To do so we need to check two [OR] conditions: - // 1. Is it a root vertex with at least two independent children. - // 2. If its visited time is <= low time of adjacent vertex. - if (previousVertex === startVertex) { - // Check that root vertex has at least two independent children. - if (visitedSet[previousVertex.getKey()].independentChildrenCount >= 2) { - articulationPointsSet[previousVertex.getKey()] = previousVertex; - } - } else { - // Get current vertex low discovery time. - const currentLowDiscoveryTime = visitedSet[currentVertex.getKey()].lowDiscoveryTime; - // Compare current vertex low discovery time with parent discovery time. Check if there - // are any short path (back edge) exists. If we can't get to current vertex other then - // via parent then the parent vertex is articulation point for current one. - const parentDiscoveryTime = visitedSet[previousVertex.getKey()].discoveryTime; - if (parentDiscoveryTime <= currentLowDiscoveryTime) { - articulationPointsSet[previousVertex.getKey()] = previousVertex; - } - } - }, - allowTraversal: ({ - nextVertex - }) => { - return !visitedSet[nextVertex.getKey()]; - } - }; - // Do Depth First Search traversal over submitted graph. - depthFirstSearch(graph, startVertex, dfsCallbacks); - return articulationPointsSet; -} -nextVertex -}) => { - return !visitedSet[nextVertex.getKey()]; -} -}; -// Do Depth First Search traversal over submitted graph. -depthFirstSearch(graph, startVertex, dfsCallbacks); - - -return articulationPointsSet; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/articulation-points/test/articulationPoints.test.js b/docs/content/DS_ALGO/algorithms/graph/articulation-points/test/articulationPoints.test.js deleted file mode 100644 index feb824fdc7..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/articulation-points/test/articulationPoints.test.js +++ /dev/null @@ -1,147 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import articulationPoints from '../articulationPoints'; -describe('articulationPoints', () => { - it('should find articulation points in simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(2); - expect(articulationPointsSet[0].getKey()).toBe(vertexC.getKey()); - expect(articulationPointsSet[1].getKey()).toBe(vertexB.getKey()); - }); - it('should find articulation points in simple graph with back edge', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeAC = new GraphEdge(vertexA, vertexC); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(1); - expect(articulationPointsSet[0].getKey()).toBe(vertexC.getKey()); - }); - it('should find articulation points in simple graph with back edge #2', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeCE = new GraphEdge(vertexC, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAE).addEdge(edgeCE).addEdge(edgeBC).addEdge(edgeCD); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(1); - expect(articulationPointsSet[0].getKey()).toBe(vertexC.getKey()); - }); - it('should find articulation points in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeFH = new GraphEdge(vertexF, vertexH); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC).addEdge(edgeCD).addEdge(edgeDE).addEdge(edgeEG).addEdge(edgeEF).addEdge(edgeGF).addEdge(edgeFH); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(4); - expect(articulationPointsSet[0].getKey()).toBe(vertexF.getKey()); - expect(articulationPointsSet[1].getKey()).toBe(vertexE.getKey()); - expect(articulationPointsSet[2].getKey()).toBe(vertexD.getKey()); - expect(articulationPointsSet[3].getKey()).toBe(vertexC.getKey()); - }); - it('should find articulation points in graph starting with articulation root vertex', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeFH = new GraphEdge(vertexF, vertexH); - const graph = new Graph(); - graph.addEdge(edgeDE).addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC).addEdge(edgeCD).addEdge(edgeEG).addEdge(edgeEF).addEdge(edgeGF).addEdge(edgeFH); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(4); - expect(articulationPointsSet[0].getKey()).toBe(vertexF.getKey()); - expect(articulationPointsSet[1].getKey()).toBe(vertexE.getKey()); - expect(articulationPointsSet[2].getKey()).toBe(vertexC.getKey()); - expect(articulationPointsSet[3].getKey()).toBe(vertexD.getKey()); - }); - it('should find articulation points in yet another graph #1', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeDE); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(2); - expect(articulationPointsSet[0].getKey()).toBe(vertexD.getKey()); - expect(articulationPointsSet[1].getKey()).toBe(vertexC.getKey()); - }); - it('should find articulation points in yet another graph #2', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeCE = new GraphEdge(vertexC, vertexE); - const edgeCF = new GraphEdge(vertexC, vertexF); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeFG = new GraphEdge(vertexF, vertexG); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeCE).addEdge(edgeCF).addEdge(edgeEG).addEdge(edgeFG); - const articulationPointsSet = Object.values(articulationPoints(graph)); - expect(articulationPointsSet.length).toBe(1); - expect(articulationPointsSet[0].getKey()).toBe(vertexC.getKey()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/README.md b/docs/content/DS_ALGO/algorithms/graph/bellman-ford/README.md deleted file mode 100644 index 037bca168d..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Bellman-Ford Algorithm - -The Bellman-Ford algorithm is an algorithm that computes shortest -paths from a single source vertex to all of the other vertices -in a weighted digraph. It is slower than Dijkstra's algorithm -for the same problem, but more versatile, as it is capable of -handling graphs in which some of the edge weights are negative -numbers. - -![Bellman-Ford](https://upload.wikimedia.org/wikipedia/commons/2/2e/Shortest_path_Dijkstra_vs_BellmanFord.gif) - -## Complexity - -Worst-case performance `O(|V||E|)` -Best-case performance `O(|E|)` -Worst-case space complexity `O(|V|)` - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm) -- [On YouTube by Michael Sambol](https://www.youtube.com/watch?v=obWXjtg0L64&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/bellmanFord.js b/docs/content/DS_ALGO/algorithms/graph/bellman-ford/bellmanFord.js deleted file mode 100644 index 98f3e32805..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/bellmanFord.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @param {Graph} graph - * @param {GraphVertex} startVertex - * @return {{distances, previousVertices}} - */ -export default function bellmanFord(graph, startVertex) { - const distances = {}; - const previousVertices = {}; - // Init all distances with infinity assuming that currently we can't reach - // any of the vertices except start one. - distances[startVertex.getKey()] = 0; - graph.getAllVertices().forEach((vertex) => { - previousVertices[vertex.getKey()] = null; - if (vertex.getKey() !== startVertex.getKey()) { - distances[vertex.getKey()] = Infinity; - } - }); - // We need (|V| - 1) iterations. - for (let iteration = 0; iteration < graph.getAllVertices().length - 1; iteration += 1) { - // During each iteration go through all vertices. - Object.keys(distances).forEach((vertexKey) => { - const vertex = graph.getVertexByKey(vertexKey); - // Go through all vertex edges. - graph.getNeighbors(vertex).forEach((neighbor) => { - const edge = graph.findEdge(vertex, neighbor); - // Find out if the distance to the neighbor is shorter in this iteration - // then in previous one. - const distanceToVertex = distances[vertex.getKey()]; - const distanceToNeighbor = distanceToVertex + edge.weight; - if (distanceToNeighbor < distances[neighbor.getKey()]) { - distances[neighbor.getKey()] = distanceToNeighbor; - previousVertices[neighbor.getKey()] = vertex; - } - }); - }); - } - return { - distances, - previousVertices - }; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/test/bellmanFord.test.js b/docs/content/DS_ALGO/algorithms/graph/bellman-ford/test/bellmanFord.test.js deleted file mode 100644 index e2ab0a579b..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bellman-ford/test/bellmanFord.test.js +++ /dev/null @@ -1,105 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import bellmanFord from '../bellmanFord'; -describe('bellmanFord', () => { - it('should find minimum paths to all vertices for undirected graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB, 4); - const edgeAE = new GraphEdge(vertexA, vertexE, 7); - const edgeAC = new GraphEdge(vertexA, vertexC, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 6); - const edgeBD = new GraphEdge(vertexB, vertexD, 5); - const edgeEC = new GraphEdge(vertexE, vertexC, 8); - const edgeED = new GraphEdge(vertexE, vertexD, 2); - const edgeDC = new GraphEdge(vertexD, vertexC, 11); - const edgeDG = new GraphEdge(vertexD, vertexG, 10); - const edgeDF = new GraphEdge(vertexD, vertexF, 2); - const edgeFG = new GraphEdge(vertexF, vertexG, 3); - const edgeEG = new GraphEdge(vertexE, vertexG, 5); - const graph = new Graph(); - graph - .addVertex(vertexH) - .addEdge(edgeAB) - .addEdge(edgeAE) - .addEdge(edgeAC) - .addEdge(edgeBC) - .addEdge(edgeBD) - .addEdge(edgeEC) - .addEdge(edgeED) - .addEdge(edgeDC) - .addEdge(edgeDG) - .addEdge(edgeDF) - .addEdge(edgeFG) - .addEdge(edgeEG); - const { distances, previousVertices } = bellmanFord(graph, vertexA); - expect(distances).toEqual({ - H: Infinity, - A: 0, - B: 4, - E: 7, - C: 3, - D: 9, - G: 12, - F: 11 - }); - expect(previousVertices.F.getKey()).toBe('D'); - expect(previousVertices.D.getKey()).toBe('B'); - expect(previousVertices.B.getKey()).toBe('A'); - expect(previousVertices.G.getKey()).toBe('E'); - expect(previousVertices.C.getKey()).toBe('A'); - expect(previousVertices.A).toBeNull(); - expect(previousVertices.H).toBeNull(); - }); - it('should find minimum paths to all vertices for directed graph with negative edge weights', () => { - const vertexS = new GraphVertex('S'); - const vertexE = new GraphVertex('E'); - const vertexA = new GraphVertex('A'); - const vertexD = new GraphVertex('D'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexH = new GraphVertex('H'); - const edgeSE = new GraphEdge(vertexS, vertexE, 8); - const edgeSA = new GraphEdge(vertexS, vertexA, 10); - const edgeED = new GraphEdge(vertexE, vertexD, 1); - const edgeDA = new GraphEdge(vertexD, vertexA, -4); - const edgeDC = new GraphEdge(vertexD, vertexC, -1); - const edgeAC = new GraphEdge(vertexA, vertexC, 2); - const edgeCB = new GraphEdge(vertexC, vertexB, -2); - const edgeBA = new GraphEdge(vertexB, vertexA, 1); - const graph = new Graph(true); - graph - .addVertex(vertexH) - .addEdge(edgeSE) - .addEdge(edgeSA) - .addEdge(edgeED) - .addEdge(edgeDA) - .addEdge(edgeDC) - .addEdge(edgeAC) - .addEdge(edgeCB) - .addEdge(edgeBA); - const { distances, previousVertices } = bellmanFord(graph, vertexS); - expect(distances).toEqual({ - H: Infinity, - S: 0, - A: 5, - B: 5, - C: 7, - D: 9, - E: 8 - }); - expect(previousVertices.H).toBeNull(); - expect(previousVertices.S).toBeNull(); - expect(previousVertices.B.getKey()).toBe('C'); - expect(previousVertices.C.getKey()).toBe('A'); - expect(previousVertices.A.getKey()).toBe('D'); - expect(previousVertices.D.getKey()).toBe('E'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/README.md b/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/README.md deleted file mode 100644 index 3e41041404..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Breadth-First Search (BFS) - -Breadth-first search (BFS) is an algorithm for traversing -or searching tree or graph data structures. It starts at -the tree root (or some arbitrary node of a graph, sometimes -referred to as a 'search key') and explores the neighbor -nodes first, before moving to the next level neighbors. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Breadth-first_search) -- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/) -- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/) -- [BFS Visualization](https://www.cs.usfca.edu/~galles/visualization/BFS.html) diff --git a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/breadthFirstSearch.js b/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/breadthFirstSearch.js deleted file mode 100644 index f1057b7986..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/breadthFirstSearch.js +++ /dev/null @@ -1,83 +0,0 @@ -import Queue from '../../../data-structures/queue/Queue'; -/** - * @typedef {Object} Callbacks - * - * @property {function(vertices: Object): boolean} [allowTraversal] - - * Determines whether DFS should traverse from the vertex to its neighbor - * (along the edge). By default prohibits visiting the same vertex again. - * - * @property {function(vertices: Object)} [enterVertex] - Called when BFS enters the vertex. - * - * @property {function(vertices: Object)} [leaveVertex] - Called when BFS leaves the vertex. - */ -/** - * @param {Callbacks} [callbacks] - * @returns {Callbacks} - */ -function initCallbacks(callbacks = {}) { - const initiatedCallback = callbacks; - const stubCallback = () => {}; - const allowTraversalCallback = (() => { - const seen = {}; - return ({ - nextVertex - }) => { - if (!seen[nextVertex.getKey()]) { - seen[nextVertex.getKey()] = true; - return true; - } - return false; - }; - })(); - initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback; - initiatedCallback.enterVertex = callbacks.enterVertex || stubCallback; - initiatedCallback.leaveVertex = callbacks.leaveVertex || stubCallback; - return initiatedCallback; -} -/** - * @param {Graph} graph - * @param {GraphVertex} startVertex - * @param {Callbacks} [originalCallbacks] - */ -export default function breadthFirstSearch(graph, startVertex, originalCallbacks) { - const callbacks = initCallbacks(originalCallbacks); - const vertexQueue = new Queue(); - // Do initial queue setup. - vertexQueue.enqueue(startVertex); - let previousVertex = null; - // Traverse all vertices from the queue. - while (!vertexQueue.isEmpty()) { - const currentVertex = vertexQueue.dequeue(); - callbacks.enterVertex({ - currentVertex, - previousVertex - }); - // Add all neighbors to the queue for future traversals. - graph.getNeighbors(currentVertex).forEach((nextVertex) => { - if (callbacks.allowTraversal({ - previousVertex, - currentVertex, - nextVertex - })) { - vertexQueue.enqueue(nextVertex); - } - }); - callbacks.leaveVertex({ - currentVertex, - previousVertex - }); - // Memorize current vertex before next loop. - previousVertex = currentVertex; - } -} -} -}); -callbacks.leaveVertex({ - currentVertex, - previousVertex -}); -// Memorize current vertex before next loop. -previousVertex = currentVertex; - -} -} diff --git a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/test/breadthFirstSearch.test.js b/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/test/breadthFirstSearch.test.js deleted file mode 100644 index 7a17dbd35d..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/breadth-first-search/test/breadthFirstSearch.test.js +++ /dev/null @@ -1,303 +0,0 @@ -import Graph from '../../../../data-structures/graph/Graph'; -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import breadthFirstSearch from '../breadthFirstSearch'; -describe('breadthFirstSearch', () => { - it('should perform BFS operation on graph', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCG = new GraphEdge(vertexC, vertexG); - const edgeAD = new GraphEdge(vertexA, vertexD); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const edgeDH = new GraphEdge(vertexD, vertexH); - const edgeGH = new GraphEdge(vertexG, vertexH); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDH).addEdge(edgeGH); - expect(graph.toString()).toBe('A,B,C,G,D,E,F,H'); - const enterVertexCallback = jest.fn(); - const leaveVertexCallback = jest.fn(); - // Traverse graphs without callbacks first. - breadthFirstSearch(graph, vertexA); - // Traverse graph with enterVertex and leaveVertex callbacks. - breadthFirstSearch(graph, vertexA, { - enterVertex: enterVertexCallback, - leaveVertex: leaveVertexCallback - }); - expect(enterVertexCallback).toHaveBeenCalledTimes(8); - expect(leaveVertexCallback).toHaveBeenCalledTimes(8); - const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexB, - previousVertex: vertexA - }, - { - currentVertex: vertexD, - previousVertex: vertexB - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexC, - previousVertex: vertexE - }, - { - currentVertex: vertexH, - previousVertex: vertexC - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexG, - previousVertex: vertexF - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); - } - const leaveVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexB, - previousVertex: vertexA - }, - { - currentVertex: vertexD, - previousVertex: vertexB - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexC, - previousVertex: vertexE - }, - { - currentVertex: vertexH, - previousVertex: vertexC - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexG, - previousVertex: vertexF - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); - } - }); - it('should allow to create custom vertex visiting logic', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCG = new GraphEdge(vertexC, vertexG); - const edgeAD = new GraphEdge(vertexA, vertexD); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const edgeDH = new GraphEdge(vertexD, vertexH); - const edgeGH = new GraphEdge(vertexG, vertexH); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDH).addEdge(edgeGH); - expect(graph.toString()).toBe('A,B,C,G,D,E,F,H'); - const enterVertexCallback = jest.fn(); - const leaveVertexCallback = jest.fn(); - // Traverse graph with enterVertex and leaveVertex callbacks. - breadthFirstSearch(graph, vertexA, { - enterVertex: enterVertexCallback, - leaveVertex: leaveVertexCallback, - allowTraversal: ({ - currentVertex, - nextVertex - }) => { - return !(currentVertex === vertexA && nextVertex === vertexB); - } - }); - expect(enterVertexCallback).toHaveBeenCalledTimes(7); - expect(leaveVertexCallback).toHaveBeenCalledTimes(7); - const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexH, - previousVertex: vertexE - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexH, - previousVertex: vertexD - } - ]; - for (let callIndex = 0; callIndex < 7; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); - } - const leaveVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexH, - previousVertex: vertexE - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexH, - previousVertex: vertexD - } - ]; - for (let callIndex = 0; callIndex < 7; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); - } - }); -}); -// Traverse graph with enterVertex and leaveVertex callbacks. -breadthFirstSearch(graph, vertexA, { - enterVertex: enterVertexCallback, - leaveVertex: leaveVertexCallback, - allowTraversal: ({ - currentVertex, - nextVertex - }) => { - return !(currentVertex === vertexA && nextVertex === vertexB); - } -}); -expect(enterVertexCallback).toHaveBeenCalledTimes(7); -expect(leaveVertexCallback).toHaveBeenCalledTimes(7); -const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexH, - previousVertex: vertexE - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexH, - previousVertex: vertexD - } -]; -for (let callIndex = 0; callIndex < 7; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); -} -const leaveVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexE, - previousVertex: vertexD - }, - { - currentVertex: vertexH, - previousVertex: vertexE - }, - { - currentVertex: vertexF, - previousVertex: vertexH - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexH, - previousVertex: vertexD - } -]; -for (let callIndex = 0; callIndex < 7; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); -} -}); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/bridges/README.md b/docs/content/DS_ALGO/algorithms/graph/bridges/README.md deleted file mode 100644 index 89f1458cde..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bridges/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Bridges in Graph - -In graph theory, a **bridge**, **isthmus**, **cut-edge**, or **cut arc** is an edge -of a graph whose deletion increases its number of connected components. Equivalently, -an edge is a bridge if and only if it is not contained in any cycle. A graph is said -to be bridgeless or isthmus-free if it contains no bridges. - -![Bridges in graph](https://upload.wikimedia.org/wikipedia/commons/d/df/Graph_cut_edges.svg) - -A graph with 16 vertices and 6 bridges (highlighted in red) - -![Bridgeless](https://upload.wikimedia.org/wikipedia/commons/b/bf/Undirected.svg) - -An undirected connected graph with no cut edges - -![Bridges in graph](https://www.geeksforgeeks.org/wp-content/uploads/Bridge1.png) - -![Bridges in graph](https://www.geeksforgeeks.org/wp-content/uploads/Bridge2.png) - -![Bridges in graph](https://www.geeksforgeeks.org/wp-content/uploads/Bridge3.png) - -## References - -- [GeeksForGeeks on YouTube](https://www.youtube.com/watch?v=thLQYBlz2DM&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Wikipedia](https://en.wikipedia.org/wiki/Bridge_%28graph_theory%29#Tarjan.27s_Bridge-finding_algorithm) -- [GeeksForGeeks](https://www.geeksforgeeks.org/bridge-in-a-graph/) diff --git a/docs/content/DS_ALGO/algorithms/graph/bridges/graphBridges.js b/docs/content/DS_ALGO/algorithms/graph/bridges/graphBridges.js deleted file mode 100644 index 91dda81195..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bridges/graphBridges.js +++ /dev/null @@ -1,103 +0,0 @@ -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * Helper class for visited vertex metadata. - */ -class VisitMetadata { - constructor({ - discoveryTime, - lowDiscoveryTime - }) { - this.discoveryTime = discoveryTime; - this.lowDiscoveryTime = lowDiscoveryTime; - } -} -/** - * @param {Graph} graph - * @return {Object} - */ -export default function graphBridges(graph) { - // Set of vertices we've already visited during DFS. - const visitedSet = {}; - // Set of bridges. - const bridges = {}; - // Time needed to discover to the current vertex. - let discoveryTime = 0; - // Peek the start vertex for DFS traversal. - const startVertex = graph.getAllVertices()[0]; - const dfsCallbacks = { - /** - * @param {GraphVertex} currentVertex - */ - enterVertex: ({ - currentVertex - }) => { - // Tick discovery time. - discoveryTime += 1; - // Put current vertex to visited set. - visitedSet[currentVertex.getKey()] = new VisitMetadata({ - discoveryTime, - lowDiscoveryTime: discoveryTime - }); - }, - /** - * @param {GraphVertex} currentVertex - * @param {GraphVertex} previousVertex - */ - leaveVertex: ({ - currentVertex, - previousVertex - }) => { - if (previousVertex === null) { - // Don't do anything for the root vertex if it is already current (not previous one). - return; - } - // Check if current node is connected to any early node other then previous one. - visitedSet[currentVertex.getKey()].lowDiscoveryTime = currentVertex - .getNeighbors() - .filter((earlyNeighbor) => earlyNeighbor.getKey() !== previousVertex.getKey()) - .reduce( - /** - * @param {number} lowestDiscoveryTime - * @param {GraphVertex} neighbor - */ - (lowestDiscoveryTime, neighbor) => { - const neighborLowTime = visitedSet[neighbor.getKey()].lowDiscoveryTime; - return neighborLowTime < lowestDiscoveryTime ? neighborLowTime : lowestDiscoveryTime; - }, - visitedSet[currentVertex.getKey()].lowDiscoveryTime - ); - // Compare low discovery times. In case if current low discovery time is less than the one - // in previous vertex then update previous vertex low time. - const currentLowDiscoveryTime = visitedSet[currentVertex.getKey()].lowDiscoveryTime; - const previousLowDiscoveryTime = visitedSet[previousVertex.getKey()].lowDiscoveryTime; - if (currentLowDiscoveryTime < previousLowDiscoveryTime) { - visitedSet[previousVertex.getKey()].lowDiscoveryTime = currentLowDiscoveryTime; - } - // Compare current vertex low discovery time with parent discovery time. Check if there - // are any short path (back edge) exists. If we can't get to current vertex other then - // via parent then the parent vertex is articulation point for current one. - const parentDiscoveryTime = visitedSet[previousVertex.getKey()].discoveryTime; - if (parentDiscoveryTime < currentLowDiscoveryTime) { - const bridge = graph.findEdge(previousVertex, currentVertex); - bridges[bridge.getKey()] = bridge; - } - }, - allowTraversal: ({ - nextVertex - }) => { - return !visitedSet[nextVertex.getKey()]; - } - }; - // Do Depth First Search traversal over submitted graph. - depthFirstSearch(graph, startVertex, dfsCallbacks); - return bridges; -} -}) => { - return !visitedSet[nextVertex.getKey()]; -} -}; -// Do Depth First Search traversal over submitted graph. -depthFirstSearch(graph, startVertex, dfsCallbacks); - -return bridges; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/bridges/test/graphBridges.test.js b/docs/content/DS_ALGO/algorithms/graph/bridges/test/graphBridges.test.js deleted file mode 100644 index 5b60d96991..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/bridges/test/graphBridges.test.js +++ /dev/null @@ -1,129 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import graphBridges from '../graphBridges'; -describe('graphBridges', () => { - it('should find bridges in simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(3); - expect(bridges[0].getKey()).toBe(edgeCD.getKey()); - expect(bridges[1].getKey()).toBe(edgeBC.getKey()); - expect(bridges[2].getKey()).toBe(edgeAB.getKey()); - }); - it('should find bridges in simple graph with back edge', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeAC = new GraphEdge(vertexA, vertexC); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(1); - expect(bridges[0].getKey()).toBe(edgeCD.getKey()); - }); - it('should find bridges in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeFH = new GraphEdge(vertexF, vertexH); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC).addEdge(edgeCD).addEdge(edgeDE).addEdge(edgeEG).addEdge(edgeEF).addEdge(edgeGF).addEdge(edgeFH); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(3); - expect(bridges[0].getKey()).toBe(edgeFH.getKey()); - expect(bridges[1].getKey()).toBe(edgeDE.getKey()); - expect(bridges[2].getKey()).toBe(edgeCD.getKey()); - }); - it('should find bridges in graph starting with different root vertex', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeFH = new GraphEdge(vertexF, vertexH); - const graph = new Graph(); - graph.addEdge(edgeDE).addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC).addEdge(edgeCD).addEdge(edgeEG).addEdge(edgeEF).addEdge(edgeGF).addEdge(edgeFH); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(3); - expect(bridges[0].getKey()).toBe(edgeFH.getKey()); - expect(bridges[1].getKey()).toBe(edgeDE.getKey()); - expect(bridges[2].getKey()).toBe(edgeCD.getKey()); - }); - it('should find bridges in yet another graph #1', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeDE); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(2); - expect(bridges[0].getKey()).toBe(edgeDE.getKey()); - expect(bridges[1].getKey()).toBe(edgeCD.getKey()); - }); - it('should find bridges in yet another graph #2', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeCE = new GraphEdge(vertexC, vertexE); - const edgeCF = new GraphEdge(vertexC, vertexF); - const edgeEG = new GraphEdge(vertexE, vertexG); - const edgeFG = new GraphEdge(vertexF, vertexG); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeCE).addEdge(edgeCF).addEdge(edgeEG).addEdge(edgeFG); - const bridges = Object.values(graphBridges(graph)); - expect(bridges.length).toBe(1); - expect(bridges[0].getKey()).toBe(edgeCD.getKey()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/README.md b/docs/content/DS_ALGO/algorithms/graph/depth-first-search/README.md deleted file mode 100644 index b45a31b7e0..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Depth-First Search (DFS) - -Depth-first search (DFS) is an algorithm for traversing or -searching tree or graph data structures. One starts at -the root (selecting some arbitrary node as the root in -the case of a graph) and explores as far as possible -along each branch before backtracking. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Depth-first_search) -- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/) -- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/) -- [DFS Visualization](https://www.cs.usfca.edu/~galles/visualization/DFS.html) diff --git a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/depthFirstSearch.js b/docs/content/DS_ALGO/algorithms/graph/depth-first-search/depthFirstSearch.js deleted file mode 100644 index 2c32c023ea..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/depthFirstSearch.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @typedef {Object} Callbacks - * - * @property {function(vertices: Object): boolean} [allowTraversal] - - * Determines whether DFS should traverse from the vertex to its neighbor - * (along the edge). By default prohibits visiting the same vertex again. - * - * @property {function(vertices: Object)} [enterVertex] - Called when DFS enters the vertex. - * - * @property {function(vertices: Object)} [leaveVertex] - Called when DFS leaves the vertex. - */ -/** - * @param {Callbacks} [callbacks] - * @returns {Callbacks} - */ -function initCallbacks(callbacks = {}) { - const initiatedCallback = callbacks; - const stubCallback = () => {}; - const allowTraversalCallback = (() => { - const seen = {}; - return ({ - nextVertex - }) => { - if (!seen[nextVertex.getKey()]) { - seen[nextVertex.getKey()] = true; - return true; - } - return false; - }; - })(); - initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback; - initiatedCallback.enterVertex = callbacks.enterVertex || stubCallback; - initiatedCallback.leaveVertex = callbacks.leaveVertex || stubCallback; - return initiatedCallback; -} -/** - * @param {Graph} graph - * @param {GraphVertex} currentVertex - * @param {GraphVertex} previousVertex - * @param {Callbacks} callbacks - */ -function depthFirstSearchRecursive(graph, currentVertex, previousVertex, callbacks) { - callbacks.enterVertex({ - currentVertex, - previousVertex - }); - graph.getNeighbors(currentVertex).forEach((nextVertex) => { - if (callbacks.allowTraversal({ - previousVertex, - currentVertex, - nextVertex - })) { - depthFirstSearchRecursive(graph, nextVertex, currentVertex, callbacks); - } - }); - callbacks.leaveVertex({ - currentVertex, - previousVertex - }); -} -/** - * @param {Graph} graph - * @param {GraphVertex} startVertex - * @param {Callbacks} [callbacks] - */ -export default function depthFirstSearch(graph, startVertex, callbacks) { - const previousVertex = null; - depthFirstSearchRecursive(graph, startVertex, previousVertex, initCallbacks(callbacks)); -} -}); -} -/** - * @param {Graph} graph - * @param {GraphVertex} startVertex - * @param {Callbacks} [callbacks] - */ -export default function depthFirstSearch(graph, startVertex, callbacks) { - const previousVertex = null; - depthFirstSearchRecursive(graph, startVertex, previousVertex, initCallbacks(callbacks)); -} -} diff --git a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/test/depthFirstSearch.test.js b/docs/content/DS_ALGO/algorithms/graph/depth-first-search/test/depthFirstSearch.test.js deleted file mode 100644 index 69f7aa1de8..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/depth-first-search/test/depthFirstSearch.test.js +++ /dev/null @@ -1,286 +0,0 @@ -import Graph from '../../../../data-structures/graph/Graph'; -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import depthFirstSearch from '../depthFirstSearch'; -describe('depthFirstSearch', () => { -it('should perform DFS operation on graph', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCG = new GraphEdge(vertexC, vertexG); - const edgeAD = new GraphEdge(vertexA, vertexD); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const edgeDG = new GraphEdge(vertexD, vertexG); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDG); - expect(graph.toString()).toBe('A,B,C,G,D,E,F'); - const enterVertexCallback = jest.fn(); - const leaveVertexCallback = jest.fn(); - // Traverse graphs without callbacks first to check default ones. - depthFirstSearch(graph, vertexA); - // Traverse graph with enterVertex and leaveVertex callbacks. - depthFirstSearch(graph, vertexA, { - enterVertex: enterVertexCallback, - leaveVertex: leaveVertexCallback - }); - expect(enterVertexCallback).toHaveBeenCalledTimes(graph.getAllVertices().length); - expect(leaveVertexCallback).toHaveBeenCalledTimes(graph.getAllVertices().length); - const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexB, - previousVertex: vertexA - }, - { - currentVertex: vertexC, - previousVertex: vertexB - }, - { - currentVertex: vertexG, - previousVertex: vertexC - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexF, - previousVertex: vertexE - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); - } - const leaveVertexParamsMap = [{ - currentVertex: vertexG, - previousVertex: vertexC - }, - { - currentVertex: vertexC, - previousVertex: vertexB - }, - { - currentVertex: vertexB, - previousVertex: vertexA - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexF, - previousVertex: vertexE - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexA, - previousVertex: null - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); - } -}); -it('allow users to redefine vertex visiting logic', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCG = new GraphEdge(vertexC, vertexG); - const edgeAD = new GraphEdge(vertexA, vertexD); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const edgeDG = new GraphEdge(vertexD, vertexG); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCG).addEdge(edgeAD).addEdge(edgeAE).addEdge(edgeEF).addEdge(edgeFD).addEdge(edgeDG); - expect(graph.toString()).toBe('A,B,C,G,D,E,F'); - const enterVertexCallback = jest.fn(); - const leaveVertexCallback = jest.fn(); - depthFirstSearch(graph, vertexA, { - enterVertex: enterVertexCallback, - leaveVertex: leaveVertexCallback, - allowTraversal: ({ - currentVertex, - nextVertex - }) => { - return !(currentVertex === vertexA && nextVertex === vertexB); - } - }); - expect(enterVertexCallback).toHaveBeenCalledTimes(7); - expect(leaveVertexCallback).toHaveBeenCalledTimes(7); - const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexF, - previousVertex: vertexE - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexG, - previousVertex: vertexD - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); - } - const leaveVertexParamsMap = [{ - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexF, - previousVertex: vertexE - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexA, - previousVertex: null - } - ]; - for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); - } -}); -}); -currentVertex, -nextVertex -}) => { - return !(currentVertex === vertexA && nextVertex === vertexB); -} -}); -expect(enterVertexCallback).toHaveBeenCalledTimes(7); -expect(leaveVertexCallback).toHaveBeenCalledTimes(7); -const enterVertexParamsMap = [{ - currentVertex: vertexA, - previousVertex: null - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexF, - previousVertex: vertexE - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexG, - previousVertex: vertexD - } -]; -for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = enterVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(enterVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(enterVertexParamsMap[callIndex].previousVertex); -} -const leaveVertexParamsMap = [{ - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexD, - previousVertex: vertexA - }, - { - currentVertex: vertexG, - previousVertex: vertexD - }, - { - currentVertex: vertexD, - previousVertex: vertexF - }, - { - currentVertex: vertexF, - previousVertex: vertexE - }, - { - currentVertex: vertexE, - previousVertex: vertexA - }, - { - currentVertex: vertexA, - previousVertex: null - } -]; -for (let callIndex = 0; callIndex < graph.getAllVertices().length; callIndex += 1) { - const params = leaveVertexCallback.mock.calls[callIndex][0]; - expect(params.currentVertex).toEqual(leaveVertexParamsMap[callIndex].currentVertex); - expect(params.previousVertex).toEqual(leaveVertexParamsMap[callIndex].previousVertex); -} -}); -}); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/README.md b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/README.md deleted file mode 100644 index 2ca7e32f6c..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Detect Cycle in Graphs - -In graph theory, a **cycle** is a path of edges and vertices -wherein a vertex is reachable from itself. There are several -different types of cycles, principally a **closed walk** and -a **simple cycle**. - -## Definitions - -A **closed walk** consists of a sequence of vertices starting -and ending at the same vertex, with each two consecutive vertices -in the sequence adjacent to each other in the graph. In a directed graph, -each edge must be traversed by the walk consistently with its direction: -the edge must be oriented from the earlier of two consecutive vertices -to the later of the two vertices in the sequence. -The choice of starting vertex is not important: traversing the same cyclic -sequence of edges from different starting vertices produces the same closed walk. - -A **simple cycle may** be defined either as a closed walk with no repetitions of -vertices and edges allowed, other than the repetition of the starting and ending -vertex, or as the set of edges in such a walk. The two definitions are equivalent -in directed graphs, where simple cycles are also called directed cycles: the cyclic -sequence of vertices and edges in a walk is completely determined by the set of -edges that it uses. In undirected graphs the set of edges of a cycle can be -traversed by a walk in either of two directions, giving two possible directed cycles -for every undirected cycle. A circuit can be a closed walk allowing repetitions of -vertices but not edges; however, it can also be a simple cycle, so explicit -definition is recommended when it is used. - -## Example - -![Cycles](https://upload.wikimedia.org/wikipedia/commons/e/e7/Graph_cycle.gif) - -A graph with edges colored to illustrate **path** `H-A-B` (green), closed path or -**walk with a repeated vertex** `B-D-E-F-D-C-B` (blue) and a **cycle with no repeated edge** or -vertex `H-D-G-H` (red) - -### Cycle in undirected graph - -![Undirected Cycle](https://www.geeksforgeeks.org/wp-content/uploads/cycleGraph.png) - -### Cycle in directed graph - -![Directed Cycle](https://cdncontribute.geeksforgeeks.org/wp-content/uploads/cycle.png) - -## References - -General information: - -- [Wikipedia]() - -Cycles in undirected graphs: - -- [Detect Cycle in Undirected Graph on GeeksForGeeks](https://www.geeksforgeeks.org/detect-cycle-undirected-graph/) -- [Detect Cycle in Undirected Graph Algorithm on YouTube](https://www.youtube.com/watch?v=n_t0a_8H8VY&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) - -Cycles in directed graphs: - -- [Detect Cycle in Directed Graph on GeeksForGeeks](https://www.geeksforgeeks.org/detect-cycle-in-a-graph/) -- [Detect Cycle in Directed Graph Algorithm on YouTube](https://www.youtube.com/watch?v=rKQaZuoUR4M&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectDirectedCycle.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectDirectedCycle.js deleted file mode 100644 index 0eb2f79c3f..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectDirectedCycle.js +++ /dev/null @@ -1,89 +0,0 @@ -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * Detect cycle in directed graph using Depth First Search. - * - * @param {Graph} graph - */ -export default function detectDirectedCycle(graph) { - let cycle = null; - // Will store parents (previous vertices) for all visited nodes. - // This will be needed in order to specify what path exactly is a cycle. - const dfsParentMap = {}; - // White set (UNVISITED) contains all the vertices that haven't been visited at all. - const whiteSet = {}; - // Gray set (VISITING) contains all the vertices that are being visited right now - // (in current path). - const graySet = {}; - // Black set (VISITED) contains all the vertices that has been fully visited. - // Meaning that all children of the vertex has been visited. - const blackSet = {}; - // If we encounter vertex in gray set it means that we've found a cycle. - // Because when vertex in gray set it means that its neighbors or its neighbors - // neighbors are still being explored. - // Init white set and add all vertices to it. - /** @param {GraphVertex} vertex */ - graph.getAllVertices().forEach((vertex) => { - whiteSet[vertex.getKey()] = vertex; - }); - // Describe BFS callbacks. - const callbacks = { - enterVertex: ({ - currentVertex, - previousVertex - }) => { - if (graySet[currentVertex.getKey()]) { - // If current vertex already in grey set it means that cycle is detected. - // Let's detect cycle path. - cycle = {}; - let currentCycleVertex = currentVertex; - let previousCycleVertex = previousVertex; - while (previousCycleVertex.getKey() !== currentVertex.getKey()) { - cycle[currentCycleVertex.getKey()] = previousCycleVertex; - currentCycleVertex = previousCycleVertex; - previousCycleVertex = dfsParentMap[previousCycleVertex.getKey()]; - } - cycle[currentCycleVertex.getKey()] = previousCycleVertex; - } else { - // Otherwise let's add current vertex to gray set and remove it from white set. - graySet[currentVertex.getKey()] = currentVertex; - delete whiteSet[currentVertex.getKey()]; - // Update DFS parents list. - dfsParentMap[currentVertex.getKey()] = previousVertex; - } - }, - leaveVertex: ({ - currentVertex - }) => { - // If all node's children has been visited let's remove it from gray set - // and move it to the black set meaning that all its neighbors are visited. - blackSet[currentVertex.getKey()] = currentVertex; - delete graySet[currentVertex.getKey()]; - }, - allowTraversal: ({ - nextVertex - }) => { - // If cycle was detected we must forbid all further traversing since it will - // cause infinite traversal loop. - if (cycle) { - return false; - } - // Allow traversal only for the vertices that are not in black set - // since all black set vertices have been already visited. - return !blackSet[nextVertex.getKey()]; - } - }; - // Start exploring vertices. - while (Object.keys(whiteSet).length) { - // Pick fist vertex to start BFS from. - const firstWhiteKey = Object.keys(whiteSet)[0]; - const startVertex = whiteSet[firstWhiteKey]; - // Do Depth First Search. - depthFirstSearch(graph, startVertex, callbacks); - } - return cycle; -} -// Do Depth First Search. -depthFirstSearch(graph, startVertex, callbacks); -} -return cycle; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycle.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycle.js deleted file mode 100644 index 88c63508aa..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycle.js +++ /dev/null @@ -1,58 +0,0 @@ -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * Detect cycle in undirected graph using Depth First Search. - * - * @param {Graph} graph - */ -export default function detectUndirectedCycle(graph) { - let cycle = null; - // List of vertices that we have visited. - const visitedVertices = {}; - // List of parents vertices for every visited vertex. - const parents = {}; - // Callbacks for DFS traversing. - const callbacks = { - allowTraversal: ({ - currentVertex, - nextVertex - }) => { - // Don't allow further traversal in case if cycle has been detected. - if (cycle) { - return false; - } - // Don't allow traversal from child back to its parent. - const currentVertexParent = parents[currentVertex.getKey()]; - const currentVertexParentKey = currentVertexParent ? currentVertexParent.getKey() : null; - return currentVertexParentKey !== nextVertex.getKey(); - }, - enterVertex: ({ - currentVertex, - previousVertex - }) => { - if (visitedVertices[currentVertex.getKey()]) { - // Compile cycle path based on parents of previous vertices. - cycle = {}; - let currentCycleVertex = currentVertex; - let previousCycleVertex = previousVertex; - while (previousCycleVertex.getKey() !== currentVertex.getKey()) { - cycle[currentCycleVertex.getKey()] = previousCycleVertex; - currentCycleVertex = previousCycleVertex; - previousCycleVertex = parents[previousCycleVertex.getKey()]; - } - cycle[currentCycleVertex.getKey()] = previousCycleVertex; - } else { - // Add next vertex to visited set. - visitedVertices[currentVertex.getKey()] = currentVertex; - parents[currentVertex.getKey()] = previousVertex; - } - } - }; - // Start DFS traversing. - const startVertex = graph.getAllVertices()[0]; - depthFirstSearch(graph, startVertex, callbacks); - return cycle; -} // Start DFS traversing. -const startVertex = graph.getAllVertices()[0]; -depthFirstSearch(graph, startVertex, callbacks); -return cycle; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycleUsingDisjointSet.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycleUsingDisjointSet.js deleted file mode 100644 index f8eca1736c..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/detectUndirectedCycleUsingDisjointSet.js +++ /dev/null @@ -1,28 +0,0 @@ -import DisjointSet from '../../../data-structures/disjoint-set/DisjointSet'; -/** - * Detect cycle in undirected graph using disjoint sets. - * - * @param {Graph} graph - */ -export default function detectUndirectedCycleUsingDisjointSet(graph) { - // Create initial singleton disjoint sets for each graph vertex. - /** @param {GraphVertex} graphVertex */ - const keyExtractor = (graphVertex) => graphVertex.getKey(); - const disjointSet = new DisjointSet(keyExtractor); - graph.getAllVertices().forEach((graphVertex) => disjointSet.makeSet(graphVertex)); - // Go trough all graph edges one by one and check if edge vertices are from the - // different sets. In this case joint those sets together. Do this until you find - // an edge where to edge vertices are already in one set. This means that current - // edge will create a cycle. - let cycleFound = false; - /** @param {GraphEdge} graphEdge */ - graph.getAllEdges().forEach((graphEdge) => { - if (disjointSet.inSameSet(graphEdge.startVertex, graphEdge.endVertex)) { - // Cycle found. - cycleFound = true; - } else { - disjointSet.union(graphEdge.startVertex, graphEdge.endVertex); - } - }); - return cycleFound; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectDirectedCycle.test.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectDirectedCycle.test.js deleted file mode 100644 index 528858ee70..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectDirectedCycle.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import detectDirectedCycle from '../detectDirectedCycle'; -describe('detectDirectedCycle', () => { - it('should detect directed cycle', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeDA = new GraphEdge(vertexD, vertexA); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const graph = new Graph(true); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC).addEdge(edgeDA).addEdge(edgeDE).addEdge(edgeEF); - expect(detectDirectedCycle(graph)).toBeNull(); - graph.addEdge(edgeFD); - expect(detectDirectedCycle(graph)).toEqual({ - D: vertexF, - F: vertexE, - E: vertexD - }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycle.test.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycle.test.js deleted file mode 100644 index 06a36175d0..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycle.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import detectUndirectedCycle from '../detectUndirectedCycle'; -describe('detectUndirectedCycle', () => { - it('should detect undirected cycle', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const edgeAF = new GraphEdge(vertexA, vertexF); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBE = new GraphEdge(vertexB, vertexE); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAF).addEdge(edgeAB).addEdge(edgeBE).addEdge(edgeBC).addEdge(edgeCD); - expect(detectUndirectedCycle(graph)).toBeNull(); - graph.addEdge(edgeDE); - expect(detectUndirectedCycle(graph)).toEqual({ - B: vertexC, - C: vertexD, - D: vertexE, - E: vertexB - }); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycleUsingDisjointSet.test.js b/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycleUsingDisjointSet.test.js deleted file mode 100644 index 95fc3aa6b1..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/detect-cycle/test/detectUndirectedCycleUsingDisjointSet.test.js +++ /dev/null @@ -1,25 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import detectUndirectedCycleUsingDisjointSet from '../detectUndirectedCycleUsingDisjointSet'; -describe('detectUndirectedCycleUsingDisjointSet', () => { - it('should detect undirected cycle', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const edgeAF = new GraphEdge(vertexA, vertexF); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBE = new GraphEdge(vertexB, vertexE); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAF).addEdge(edgeAB).addEdge(edgeBE).addEdge(edgeBC).addEdge(edgeCD); - expect(detectUndirectedCycleUsingDisjointSet(graph)).toBe(false); - graph.addEdge(edgeDE); - expect(detectUndirectedCycleUsingDisjointSet(graph)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/dijkstra/README.md b/docs/content/DS_ALGO/algorithms/graph/dijkstra/README.md deleted file mode 100644 index 87b0cc144a..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/dijkstra/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Dijkstra's Algorithm - -Dijkstra's algorithm is an algorithm for finding the shortest -paths between nodes in a graph, which may represent, for example, -road networks. - -The algorithm exists in many variants; Dijkstra's original variant -found the shortest path between two nodes, but a more common -variant fixes a single node as the "source" node and finds -shortest paths from the source to all other nodes in the graph, -producing a shortest-path tree. - -![Dijkstra](https://upload.wikimedia.org/wikipedia/commons/5/57/Dijkstra_Animation.gif) - -Dijkstra's algorithm to find the shortest path between `a` and `b`. -It picks the unvisited vertex with the lowest distance, -calculates the distance through it to each unvisited neighbor, -and updates the neighbor's distance if smaller. Mark visited -(set to red) when done with neighbors. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) -- [On YouTube by Nathaniel Fan](https://www.youtube.com/watch?v=gdmfOwyQlcI&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [On YouTube by Tushar Roy](https://www.youtube.com/watch?v=lAXZGERcDf4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/dijkstra/dijkstra.js b/docs/content/DS_ALGO/algorithms/graph/dijkstra/dijkstra.js deleted file mode 100644 index d4143ff84f..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/dijkstra/dijkstra.js +++ /dev/null @@ -1,66 +0,0 @@ -import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue'; -/** - * @typedef {Object} ShortestPaths - * @property {Object} distances - shortest distances to all vertices - * @property {Object} previousVertices - shortest paths to all vertices. - */ -/** - * Implementation of Dijkstra algorithm of finding the shortest paths to graph nodes. - * @param {Graph} graph - graph we're going to traverse. - * @param {GraphVertex} startVertex - traversal start vertex. - * @return {ShortestPaths} - */ -export default function dijkstra(graph, startVertex) { - // Init helper variables that we will need for Dijkstra algorithm. - const distances = {}; - const visitedVertices = {}; - const previousVertices = {}; - const queue = new PriorityQueue(); - // Init all distances with infinity assuming that currently we can't reach - // any of the vertices except the start one. - graph.getAllVertices().forEach((vertex) => { - distances[vertex.getKey()] = Infinity; - previousVertices[vertex.getKey()] = null; - }); - // We are already at the startVertex so the distance to it is zero. - distances[startVertex.getKey()] = 0; - // Init vertices queue. - queue.add(startVertex, distances[startVertex.getKey()]); - // Iterate over the priority queue of vertices until it is empty. - while (!queue.isEmpty()) { - // Fetch next closest vertex. - const currentVertex = queue.poll(); - // Iterate over every unvisited neighbor of the current vertex. - currentVertex.getNeighbors().forEach((neighbor) => { - // Don't visit already visited vertices. - if (!visitedVertices[neighbor.getKey()]) { - // Update distances to every neighbor from current vertex. - const edge = graph.findEdge(currentVertex, neighbor); - const existingDistanceToNeighbor = distances[neighbor.getKey()]; - const distanceToNeighborFromCurrent = distances[currentVertex.getKey()] + edge.weight; - // If we've found shorter path to the neighbor - update it. - if (distanceToNeighborFromCurrent < existingDistanceToNeighbor) { - distances[neighbor.getKey()] = distanceToNeighborFromCurrent; - // Change priority of the neighbor in a queue since it might have became closer. - if (queue.hasValue(neighbor)) { - queue.changePriority(neighbor, distances[neighbor.getKey()]); - } - // Remember previous closest vertex. - previousVertices[neighbor.getKey()] = currentVertex; - } - // Add neighbor to the queue for further visiting. - if (!queue.hasValue(neighbor)) { - queue.add(neighbor, distances[neighbor.getKey()]); - } - } - }); - // Add current vertex to visited ones to avoid visiting it again later. - visitedVertices[currentVertex.getKey()] = currentVertex; - } - // Return the set of shortest distances to all vertices and the set of - // shortest paths to all vertices in a graph. - return { - distances, - previousVertices - }; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/dijkstra/test/dijkstra.test.js b/docs/content/DS_ALGO/algorithms/graph/dijkstra/test/dijkstra.test.js deleted file mode 100644 index 9a6375a231..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/dijkstra/test/dijkstra.test.js +++ /dev/null @@ -1,105 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import dijkstra from '../dijkstra'; -describe('dijkstra', () => { - it('should find minimum paths to all vertices for undirected graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB, 4); - const edgeAE = new GraphEdge(vertexA, vertexE, 7); - const edgeAC = new GraphEdge(vertexA, vertexC, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 6); - const edgeBD = new GraphEdge(vertexB, vertexD, 5); - const edgeEC = new GraphEdge(vertexE, vertexC, 8); - const edgeED = new GraphEdge(vertexE, vertexD, 2); - const edgeDC = new GraphEdge(vertexD, vertexC, 11); - const edgeDG = new GraphEdge(vertexD, vertexG, 10); - const edgeDF = new GraphEdge(vertexD, vertexF, 2); - const edgeFG = new GraphEdge(vertexF, vertexG, 3); - const edgeEG = new GraphEdge(vertexE, vertexG, 5); - const graph = new Graph(); - graph - .addVertex(vertexH) - .addEdge(edgeAB) - .addEdge(edgeAE) - .addEdge(edgeAC) - .addEdge(edgeBC) - .addEdge(edgeBD) - .addEdge(edgeEC) - .addEdge(edgeED) - .addEdge(edgeDC) - .addEdge(edgeDG) - .addEdge(edgeDF) - .addEdge(edgeFG) - .addEdge(edgeEG); - const { distances, previousVertices } = dijkstra(graph, vertexA); - expect(distances).toEqual({ - H: Infinity, - A: 0, - B: 4, - E: 7, - C: 3, - D: 9, - G: 12, - F: 11 - }); - expect(previousVertices.F.getKey()).toBe('D'); - expect(previousVertices.D.getKey()).toBe('B'); - expect(previousVertices.B.getKey()).toBe('A'); - expect(previousVertices.G.getKey()).toBe('E'); - expect(previousVertices.C.getKey()).toBe('A'); - expect(previousVertices.A).toBeNull(); - expect(previousVertices.H).toBeNull(); - }); - it('should find minimum paths to all vertices for directed graph with negative edge weights', () => { - const vertexS = new GraphVertex('S'); - const vertexE = new GraphVertex('E'); - const vertexA = new GraphVertex('A'); - const vertexD = new GraphVertex('D'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexH = new GraphVertex('H'); - const edgeSE = new GraphEdge(vertexS, vertexE, 8); - const edgeSA = new GraphEdge(vertexS, vertexA, 10); - const edgeED = new GraphEdge(vertexE, vertexD, 1); - const edgeDA = new GraphEdge(vertexD, vertexA, -4); - const edgeDC = new GraphEdge(vertexD, vertexC, -1); - const edgeAC = new GraphEdge(vertexA, vertexC, 2); - const edgeCB = new GraphEdge(vertexC, vertexB, -2); - const edgeBA = new GraphEdge(vertexB, vertexA, 1); - const graph = new Graph(true); - graph - .addVertex(vertexH) - .addEdge(edgeSE) - .addEdge(edgeSA) - .addEdge(edgeED) - .addEdge(edgeDA) - .addEdge(edgeDC) - .addEdge(edgeAC) - .addEdge(edgeCB) - .addEdge(edgeBA); - const { distances, previousVertices } = dijkstra(graph, vertexS); - expect(distances).toEqual({ - H: Infinity, - S: 0, - A: 5, - B: 5, - C: 7, - D: 9, - E: 8 - }); - expect(previousVertices.H).toBeNull(); - expect(previousVertices.S).toBeNull(); - expect(previousVertices.B.getKey()).toBe('C'); - expect(previousVertices.C.getKey()).toBe('A'); - expect(previousVertices.A.getKey()).toBe('D'); - expect(previousVertices.D.getKey()).toBe('E'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/README.md b/docs/content/DS_ALGO/algorithms/graph/eulerian-path/README.md deleted file mode 100644 index 70e2100a39..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Eulerian Path - -In graph theory, an **Eulerian trail** (or **Eulerian path**) is a -trail in a finite graph which visits every edge exactly once. -Similarly, an **Eulerian circuit** or **Eulerian cycle** is an -Eulerian trail which starts and ends on the same vertex. - -Euler proved that a necessary condition for the existence of Eulerian -circuits is that all vertices in the graph have an even degree, and -stated that connected graphs with all vertices of even degree have -an Eulerian circuit. - -![Eulerian Circuit](https://upload.wikimedia.org/wikipedia/commons/7/72/Labelled_Eulergraph.svg) - -Every vertex of this graph has an even degree. Therefore, this is -an Eulerian graph. Following the edges in alphabetical order gives -an Eulerian circuit/cycle. - -For the existence of Eulerian trails it is necessary that zero or -two vertices have an odd degree; this means the Königsberg graph -is not Eulerian. If there are no vertices of odd degree, -all Eulerian trails are circuits. If there are exactly two vertices -of odd degree, all Eulerian trails start at one of them and end at -the other. A graph that has an Eulerian trail but not an Eulerian -circuit is called semi-Eulerian. - -![Königsberg graph](https://upload.wikimedia.org/wikipedia/commons/9/96/K%C3%B6nigsberg_graph.svg) - -The Königsberg Bridges multigraph. This multigraph is not Eulerian, -therefore, a solution does not exist. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Eulerian_path) -- [YouTube](https://www.youtube.com/watch?v=vvP4Fg4r-Ns&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/eulerianPath.js b/docs/content/DS_ALGO/algorithms/graph/eulerian-path/eulerianPath.js deleted file mode 100644 index eae35d6d66..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/eulerianPath.js +++ /dev/null @@ -1,84 +0,0 @@ -import graphBridges from '../bridges/graphBridges'; -/** - * Fleury's algorithm of finding Eulerian Path (visit all graph edges exactly once). - * - * @param {Graph} graph - * @return {GraphVertex[]} - */ -export default function eulerianPath(graph) { - const eulerianPathVertices = []; - // Set that contains all vertices with even rank (number of neighbors). - const evenRankVertices = {}; - // Set that contains all vertices with odd rank (number of neighbors). - const oddRankVertices = {}; - // Set of all not visited edges. - const notVisitedEdges = {}; - graph.getAllEdges().forEach((vertex) => { - notVisitedEdges[vertex.getKey()] = vertex; - }); - // Detect whether graph contains Eulerian Circuit or Eulerian Path or none of them. - /** @params {GraphVertex} vertex */ - graph.getAllVertices().forEach((vertex) => { - if (vertex.getDegree() % 2) { - oddRankVertices[vertex.getKey()] = vertex; - } else { - evenRankVertices[vertex.getKey()] = vertex; - } - }); - // Check whether we're dealing with Eulerian Circuit or Eulerian Path only. - // Graph would be an Eulerian Circuit in case if all its vertices has even degree. - // If not all vertices have even degree then graph must contain only two odd-degree - // vertices in order to have Euler Path. - const isCircuit = !Object.values(oddRankVertices).length; - if (!isCircuit && Object.values(oddRankVertices).length !== 2) { - throw new Error('Eulerian path must contain two odd-ranked vertices'); - } - // Pick start vertex for traversal. - let startVertex = null; - if (isCircuit) { - // For Eulerian Circuit it doesn't matter from what vertex to start thus we'll just - // peek a first node. - const evenVertexKey = Object.keys(evenRankVertices)[0]; - startVertex = evenRankVertices[evenVertexKey]; - } else { - // For Eulerian Path we need to start from one of two odd-degree vertices. - const oddVertexKey = Object.keys(oddRankVertices)[0]; - startVertex = oddRankVertices[oddVertexKey]; - } - // Start traversing the graph. - let currentVertex = startVertex; - while (Object.values(notVisitedEdges).length) { - // Add current vertex to Eulerian path. - eulerianPathVertices.push(currentVertex); - // Detect all bridges in graph. - // We need to do it in order to not delete bridges if there are other edges - // exists for deletion. - const bridges = graphBridges(graph); - // Peek the next edge to delete from graph. - const currentEdges = currentVertex.getEdges(); - /** @var {GraphEdge} edgeToDelete */ - let edgeToDelete = null; - if (currentEdges.length === 1) { - // If there is only one edge left we need to peek it. - [edgeToDelete] = currentEdges; - } else { - // If there are many edges left then we need to peek any of those except bridges. - [edgeToDelete] = currentEdges.filter((edge) => !bridges[edge.getKey()]); - } - // Detect next current vertex. - if (currentVertex.getKey() === edgeToDelete.startVertex.getKey()) { - currentVertex = edgeToDelete.endVertex; - } else { - currentVertex = edgeToDelete.startVertex; - } - // Delete edge from not visited edges set. - delete notVisitedEdges[edgeToDelete.getKey()]; - // If last edge were deleted then add finish vertex to Eulerian Path. - if (Object.values(notVisitedEdges).length === 0) { - eulerianPathVertices.push(currentVertex); - } - // Delete the edge from graph. - graph.deleteEdge(edgeToDelete); - } - return eulerianPathVertices; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/test/eulerianPath.test.js b/docs/content/DS_ALGO/algorithms/graph/eulerian-path/test/eulerianPath.test.js deleted file mode 100644 index eb5ba9998e..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/eulerian-path/test/eulerianPath.test.js +++ /dev/null @@ -1,103 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import eulerianPath from '../eulerianPath'; -describe('eulerianPath', () => { - it('should throw an error when graph is not Eulerian', () => { - function findEulerianPathInNotEulerianGraph() { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeCE = new GraphEdge(vertexC, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCE); - eulerianPath(graph); - } - expect(findEulerianPathInNotEulerianGraph).toThrowError(); - }); - it('should find Eulerian Circuit in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeAF = new GraphEdge(vertexA, vertexF); - const edgeAG = new GraphEdge(vertexA, vertexG); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeBE = new GraphEdge(vertexB, vertexE); - const edgeEB = new GraphEdge(vertexE, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeED = new GraphEdge(vertexE, vertexD); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(); - graph - .addEdge(edgeAB) - .addEdge(edgeAE) - .addEdge(edgeAF) - .addEdge(edgeAG) - .addEdge(edgeGF) - .addEdge(edgeBE) - .addEdge(edgeEB) - .addEdge(edgeBC) - .addEdge(edgeED) - .addEdge(edgeCD); - const graphEdgesCount = graph.getAllEdges().length; - const eulerianPathSet = eulerianPath(graph); - expect(eulerianPathSet.length).toBe(graphEdgesCount + 1); - expect(eulerianPathSet[0].getKey()).toBe(vertexA.getKey()); - expect(eulerianPathSet[1].getKey()).toBe(vertexB.getKey()); - expect(eulerianPathSet[2].getKey()).toBe(vertexE.getKey()); - expect(eulerianPathSet[3].getKey()).toBe(vertexB.getKey()); - expect(eulerianPathSet[4].getKey()).toBe(vertexC.getKey()); - expect(eulerianPathSet[5].getKey()).toBe(vertexD.getKey()); - expect(eulerianPathSet[6].getKey()).toBe(vertexE.getKey()); - expect(eulerianPathSet[7].getKey()).toBe(vertexA.getKey()); - expect(eulerianPathSet[8].getKey()).toBe(vertexF.getKey()); - expect(eulerianPathSet[9].getKey()).toBe(vertexG.getKey()); - expect(eulerianPathSet[10].getKey()).toBe(vertexA.getKey()); - }); - it('should find Eulerian Path in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeDC = new GraphEdge(vertexD, vertexC); - const edgeCE = new GraphEdge(vertexC, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFH = new GraphEdge(vertexF, vertexH); - const edgeFG = new GraphEdge(vertexF, vertexG); - const edgeHG = new GraphEdge(vertexH, vertexG); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeBD).addEdge(edgeDC).addEdge(edgeCE).addEdge(edgeEF).addEdge(edgeFH).addEdge(edgeFG).addEdge(edgeHG); - const graphEdgesCount = graph.getAllEdges().length; - const eulerianPathSet = eulerianPath(graph); - expect(eulerianPathSet.length).toBe(graphEdgesCount + 1); - expect(eulerianPathSet[0].getKey()).toBe(vertexC.getKey()); - expect(eulerianPathSet[1].getKey()).toBe(vertexA.getKey()); - expect(eulerianPathSet[2].getKey()).toBe(vertexB.getKey()); - expect(eulerianPathSet[3].getKey()).toBe(vertexD.getKey()); - expect(eulerianPathSet[4].getKey()).toBe(vertexC.getKey()); - expect(eulerianPathSet[5].getKey()).toBe(vertexE.getKey()); - expect(eulerianPathSet[6].getKey()).toBe(vertexF.getKey()); - expect(eulerianPathSet[7].getKey()).toBe(vertexH.getKey()); - expect(eulerianPathSet[8].getKey()).toBe(vertexG.getKey()); - expect(eulerianPathSet[9].getKey()).toBe(vertexF.getKey()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/README.md b/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/README.md deleted file mode 100644 index 23d9592333..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# Floyd-Warshall Algorithm - -In computer science, the **Floyd-Warshall algorithm** is an algorithm for finding -shortest paths in a weighted graph with positive or negative edge weights (but -with no negative cycles). A single execution of the algorithm will find the -lengths (summed weights) of shortest paths between all pairs of vertices. Although -it does not return details of the paths themselves, it is possible to reconstruct -the paths with simple modifications to the algorithm. - -## Algorithm - -The Floyd-Warshall algorithm compares all possible paths through the graph between -each pair of vertices. It is able to do this with `O(|V|^3)` comparisons in a graph. -This is remarkable considering that there may be up to `|V|^2` edges in the graph, -and every combination of edges is tested. It does so by incrementally improving an -estimate on the shortest path between two vertices, until the estimate is optimal. - -Consider a graph `G` with vertices `V` numbered `1` through `N`. Further consider -a function `shortestPath(i, j, k)` that returns the shortest possible path -from `i` to `j` using vertices only from the set `{1, 2, ..., k}` as -intermediate points along the way. Now, given this function, our goal is to -find the shortest path from each `i` to each `j` using only vertices -in `{1, 2, ..., N}`. - -![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/f9b75e25063384ccca499c56f9a279abf661ad3b) - -![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/34ac7c89bbb18df3fd660225fd38997079e5e513) -![Recursive Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/0326d6c14def89269c029da59eba012d0f2edc9d) - -This formula is the heart of the Floyd-Warshall algorithm. - -## Example - -The algorithm above is executed on the graph on the left below: - -![Example](https://upload.wikimedia.org/wikipedia/commons/2/2e/Floyd-Warshall_example.svg) - -In the tables below `i` is row numbers and `j` is column numbers. - -**k = 0** - -| | 1 | 2 | 3 | 4 | -| :---: | :-: | :-: | :-: | :-: | -| **1** | 0 | ∞ | −2 | ∞ | -| **2** | 4 | 0 | 3 | ∞ | -| **3** | ∞ | ∞ | 0 | 2 | -| **4** | ∞ | −1 | ∞ | 0 | - -**k = 1** - -| | 1 | 2 | 3 | 4 | -| :---: | :-: | :-: | :-: | :-: | -| **1** | 0 | ∞ | −2 | ∞ | -| **2** | 4 | 0 | 2 | ∞ | -| **3** | ∞ | ∞ | 0 | 2 | -| **4** | ∞ | − | ∞ | 0 | - -**k = 2** - -| | 1 | 2 | 3 | 4 | -| :---: | :-: | :-: | :-: | :-: | -| **1** | 0 | ∞ | −2 | ∞ | -| **2** | 4 | 0 | 2 | ∞ | -| **3** | ∞ | ∞ | 0 | 2 | -| **4** | 3 | −1 | 1 | 0 | - -**k = 3** - -| | 1 | 2 | 3 | 4 | -| :---: | :-: | :-: | :-: | :-: | -| **1** | 0 | ∞ | −2 | 0 | -| **2** | 4 | 0 | 2 | 4 | -| **3** | ∞ | ∞ | 0 | 2 | -| **4** | 3 | −1 | 1 | 0 | - -**k = 4** - -| | 1 | 2 | 3 | 4 | -| :---: | :-: | :-: | :-: | :-: | -| **1** | 0 | −1 | −2 | 0 | -| **2** | 4 | 0 | 2 | 4 | -| **3** | 5 | 1 | 0 | 2 | -| **4** | 3 | −1 | 1 | 0 | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm) -- [YouTube (by Abdul Bari)](https://www.youtube.com/watch?v=oNI0rf2P9gE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=74) -- [YouTube (by Tushar Roy)](https://www.youtube.com/watch?v=LwJdNfdLF9s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=75) diff --git a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/floydWarshall.js b/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/floydWarshall.js deleted file mode 100644 index 72062f6bf1..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/floydWarshall.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @param {Graph} graph - * @return {{distances: number[][], nextVertices: GraphVertex[][]}} - */ -export default function floydWarshall(graph) { - // Get all graph vertices. - const vertices = graph.getAllVertices(); - // Init previous vertices matrix with nulls meaning that there are no - // previous vertices exist that will give us shortest path. - const nextVertices = Array(vertices.length) - .fill(null) - .map(() => { - return Array(vertices.length).fill(null); - }); - // Init distances matrix with Infinities meaning there are no paths - // between vertices exist so far. - const distances = Array(vertices.length) - .fill(null) - .map(() => { - return Array(vertices.length).fill(Infinity); - }); - // Init distance matrix with the distance we already now (from existing edges). - // And also init previous vertices from the edges. - vertices.forEach((startVertex, startIndex) => { - vertices.forEach((endVertex, endIndex) => { - if (startVertex === endVertex) { - // Distance to the vertex itself is 0. - distances[startIndex][endIndex] = 0; - } else { - // Find edge between the start and end vertices. - const edge = graph.findEdge(startVertex, endVertex); - if (edge) { - // There is an edge from vertex with startIndex to vertex with endIndex. - // Save distance and previous vertex. - distances[startIndex][endIndex] = edge.weight; - nextVertices[startIndex][endIndex] = startVertex; - } else { - distances[startIndex][endIndex] = Infinity; - } - } - }); - }); - // Now let's go to the core of the algorithm. - // Let's all pair of vertices (from start to end ones) and try to check if there - // is a shorter path exists between them via middle vertex. Middle vertex may also - // be one of the graph vertices. As you may see now we're going to have three - // loops over all graph vertices: for start, end and middle vertices. - vertices.forEach((middleVertex, middleIndex) => { - // Path starts from startVertex with startIndex. - vertices.forEach((startVertex, startIndex) => { - // Path ends to endVertex with endIndex. - vertices.forEach((endVertex, endIndex) => { - // Compare existing distance from startVertex to endVertex, with distance - // from startVertex to endVertex but via middleVertex. - // Save the shortest distance and previous vertex that allows - // us to have this shortest distance. - const distViaMiddle = distances[startIndex][middleIndex] + distances[middleIndex][endIndex]; - if (distances[startIndex][endIndex] > distViaMiddle) { - // We've found a shortest pass via middle vertex. - distances[startIndex][endIndex] = distViaMiddle; - nextVertices[startIndex][endIndex] = middleVertex; - } - }); - }); - }); - // Shortest distance from x to y: distance[x][y]. - // Next vertex after x one in path from x to y: nextVertices[x][y]. - return { - distances, - nextVertices - }; -} -nextVertices -}; -} -} diff --git a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/test/floydWarshall.test.js b/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/test/floydWarshall.test.js deleted file mode 100644 index 06ae95ae18..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/floyd-warshall/test/floydWarshall.test.js +++ /dev/null @@ -1,163 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import floydWarshall from '../floydWarshall'; -describe('floydWarshall', () => { - it('should find minimum paths to all vertices for undirected graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAB = new GraphEdge(vertexA, vertexB, 4); - const edgeAE = new GraphEdge(vertexA, vertexE, 7); - const edgeAC = new GraphEdge(vertexA, vertexC, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 6); - const edgeBD = new GraphEdge(vertexB, vertexD, 5); - const edgeEC = new GraphEdge(vertexE, vertexC, 8); - const edgeED = new GraphEdge(vertexE, vertexD, 2); - const edgeDC = new GraphEdge(vertexD, vertexC, 11); - const edgeDG = new GraphEdge(vertexD, vertexG, 10); - const edgeDF = new GraphEdge(vertexD, vertexF, 2); - const edgeFG = new GraphEdge(vertexF, vertexG, 3); - const edgeEG = new GraphEdge(vertexE, vertexG, 5); - const graph = new Graph(); - // Add vertices first just to have them in desired order. - graph - .addVertex(vertexA) - .addVertex(vertexB) - .addVertex(vertexC) - .addVertex(vertexD) - .addVertex(vertexE) - .addVertex(vertexF) - .addVertex(vertexG) - .addVertex(vertexH); - // Now, when vertices are in correct order let's add edges. - graph - .addEdge(edgeAB) - .addEdge(edgeAE) - .addEdge(edgeAC) - .addEdge(edgeBC) - .addEdge(edgeBD) - .addEdge(edgeEC) - .addEdge(edgeED) - .addEdge(edgeDC) - .addEdge(edgeDG) - .addEdge(edgeDF) - .addEdge(edgeFG) - .addEdge(edgeEG); - const { distances, nextVertices } = floydWarshall(graph); - const vertices = graph.getAllVertices(); - const vertexAIndex = vertices.indexOf(vertexA); - const vertexBIndex = vertices.indexOf(vertexB); - const vertexCIndex = vertices.indexOf(vertexC); - const vertexDIndex = vertices.indexOf(vertexD); - const vertexEIndex = vertices.indexOf(vertexE); - const vertexFIndex = vertices.indexOf(vertexF); - const vertexGIndex = vertices.indexOf(vertexG); - const vertexHIndex = vertices.indexOf(vertexH); - expect(distances[vertexAIndex][vertexHIndex]).toBe(Infinity); - expect(distances[vertexAIndex][vertexAIndex]).toBe(0); - expect(distances[vertexAIndex][vertexBIndex]).toBe(4); - expect(distances[vertexAIndex][vertexEIndex]).toBe(7); - expect(distances[vertexAIndex][vertexCIndex]).toBe(3); - expect(distances[vertexAIndex][vertexDIndex]).toBe(9); - expect(distances[vertexAIndex][vertexGIndex]).toBe(12); - expect(distances[vertexAIndex][vertexFIndex]).toBe(11); - expect(nextVertices[vertexAIndex][vertexFIndex]).toBe(vertexD); - expect(nextVertices[vertexAIndex][vertexDIndex]).toBe(vertexB); - expect(nextVertices[vertexAIndex][vertexBIndex]).toBe(vertexA); - expect(nextVertices[vertexAIndex][vertexGIndex]).toBe(vertexE); - expect(nextVertices[vertexAIndex][vertexCIndex]).toBe(vertexA); - expect(nextVertices[vertexAIndex][vertexAIndex]).toBe(null); - expect(nextVertices[vertexAIndex][vertexHIndex]).toBe(null); - }); - it('should find minimum paths to all vertices for directed graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 3); - const edgeBA = new GraphEdge(vertexB, vertexA, 8); - const edgeAD = new GraphEdge(vertexA, vertexD, 7); - const edgeDA = new GraphEdge(vertexD, vertexA, 2); - const edgeBC = new GraphEdge(vertexB, vertexC, 2); - const edgeCA = new GraphEdge(vertexC, vertexA, 5); - const edgeCD = new GraphEdge(vertexC, vertexD, 1); - const graph = new Graph(true); - // Add vertices first just to have them in desired order. - graph.addVertex(vertexA).addVertex(vertexB).addVertex(vertexC).addVertex(vertexD); - // Now, when vertices are in correct order let's add edges. - graph.addEdge(edgeAB).addEdge(edgeBA).addEdge(edgeAD).addEdge(edgeDA).addEdge(edgeBC).addEdge(edgeCA).addEdge(edgeCD); - const { distances, nextVertices } = floydWarshall(graph); - const vertices = graph.getAllVertices(); - const vertexAIndex = vertices.indexOf(vertexA); - const vertexBIndex = vertices.indexOf(vertexB); - const vertexCIndex = vertices.indexOf(vertexC); - const vertexDIndex = vertices.indexOf(vertexD); - expect(distances[vertexAIndex][vertexAIndex]).toBe(0); - expect(distances[vertexAIndex][vertexBIndex]).toBe(3); - expect(distances[vertexAIndex][vertexCIndex]).toBe(5); - expect(distances[vertexAIndex][vertexDIndex]).toBe(6); - expect(distances).toEqual([ - [0, 3, 5, 6], - [5, 0, 2, 3], - [3, 6, 0, 1], - [2, 5, 7, 0] - ]); - expect(nextVertices[vertexAIndex][vertexDIndex]).toBe(vertexC); - expect(nextVertices[vertexAIndex][vertexCIndex]).toBe(vertexB); - expect(nextVertices[vertexBIndex][vertexDIndex]).toBe(vertexC); - expect(nextVertices[vertexAIndex][vertexAIndex]).toBe(null); - expect(nextVertices[vertexAIndex][vertexBIndex]).toBe(vertexA); - }); - it('should find minimum paths to all vertices for directed graph with negative edge weights', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeFE = new GraphEdge(vertexF, vertexE, 8); - const edgeFA = new GraphEdge(vertexF, vertexA, 10); - const edgeED = new GraphEdge(vertexE, vertexD, 1); - const edgeDA = new GraphEdge(vertexD, vertexA, -4); - const edgeDC = new GraphEdge(vertexD, vertexC, -1); - const edgeAC = new GraphEdge(vertexA, vertexC, 2); - const edgeCB = new GraphEdge(vertexC, vertexB, -2); - const edgeBA = new GraphEdge(vertexB, vertexA, 1); - const graph = new Graph(true); - // Add vertices first just to have them in desired order. - graph.addVertex(vertexA).addVertex(vertexB).addVertex(vertexC).addVertex(vertexD).addVertex(vertexE).addVertex(vertexF).addVertex(vertexG); - // Now, when vertices are in correct order let's add edges. - graph.addEdge(edgeFE).addEdge(edgeFA).addEdge(edgeED).addEdge(edgeDA).addEdge(edgeDC).addEdge(edgeAC).addEdge(edgeCB).addEdge(edgeBA); - const { distances, nextVertices } = floydWarshall(graph); - const vertices = graph.getAllVertices(); - const vertexAIndex = vertices.indexOf(vertexA); - const vertexBIndex = vertices.indexOf(vertexB); - const vertexCIndex = vertices.indexOf(vertexC); - const vertexDIndex = vertices.indexOf(vertexD); - const vertexEIndex = vertices.indexOf(vertexE); - const vertexGIndex = vertices.indexOf(vertexG); - const vertexFIndex = vertices.indexOf(vertexF); - expect(distances[vertexFIndex][vertexGIndex]).toBe(Infinity); - expect(distances[vertexFIndex][vertexFIndex]).toBe(0); - expect(distances[vertexFIndex][vertexAIndex]).toBe(5); - expect(distances[vertexFIndex][vertexBIndex]).toBe(5); - expect(distances[vertexFIndex][vertexCIndex]).toBe(7); - expect(distances[vertexFIndex][vertexDIndex]).toBe(9); - expect(distances[vertexFIndex][vertexEIndex]).toBe(8); - expect(nextVertices[vertexFIndex][vertexGIndex]).toBe(null); - expect(nextVertices[vertexFIndex][vertexFIndex]).toBe(null); - expect(nextVertices[vertexAIndex][vertexBIndex]).toBe(vertexC); - expect(nextVertices[vertexAIndex][vertexCIndex]).toBe(vertexA); - expect(nextVertices[vertexFIndex][vertexBIndex]).toBe(vertexE); - expect(nextVertices[vertexEIndex][vertexBIndex]).toBe(vertexD); - expect(nextVertices[vertexDIndex][vertexBIndex]).toBe(vertexC); - expect(nextVertices[vertexCIndex][vertexBIndex]).toBe(vertexC); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/README.md b/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/README.md deleted file mode 100644 index aed0f9a74e..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Hamiltonian Path - -**Hamiltonian path** (or **traceable path**) is a path in an -undirected or directed graph that visits each vertex exactly once. -A **Hamiltonian cycle** (or **Hamiltonian circuit**) is a -Hamiltonian path that is a cycle. Determining whether such paths -and cycles exist in graphs is the **Hamiltonian path problem**. - -![Hamiltonian cycle](https://upload.wikimedia.org/wikipedia/commons/6/6c/Hamiltonian_path_3d.svg) - -One possible Hamiltonian cycle through every vertex of a -dodecahedron is shown in red - like all platonic solids, the -dodecahedron is Hamiltonian. - -## Naive Algorithm - -Generate all possible configurations of vertices and print a -configuration that satisfies the given constraints. There -will be `n!` (n factorial) configurations. - -``` -while there are untried configurations -{ - generate the next configuration - if ( there are edges between two consecutive vertices of this - configuration and there is an edge from the last vertex to - the first ). - { - print this configuration; - break; - } -} -``` - -## Backtracking Algorithm - -Create an empty path array and add vertex `0` to it. Add other -vertices, starting from the vertex `1`. Before adding a vertex, -check for whether it is adjacent to the previously added vertex -and not already added. If we find such a vertex, we add the -vertex as part of the solution. If we do not find a vertex -then we return false. - -## References - -- [Hamiltonian path on Wikipedia](https://en.wikipedia.org/wiki/Hamiltonian_path) -- [Hamiltonian path on YouTube](https://www.youtube.com/watch?v=dQr4wZCiJJ4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Hamiltonian cycle on GeeksForGeeks](https://www.geeksforgeeks.org/backtracking-set-7-hamiltonian-cycle/) diff --git a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/hamiltonianCycle.js b/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/hamiltonianCycle.js deleted file mode 100644 index fc53ebae4c..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/hamiltonianCycle.js +++ /dev/null @@ -1,118 +0,0 @@ -import GraphVertex from '../../../data-structures/graph/GraphVertex'; -/** - * @param {number[][]} adjacencyMatrix - * @param {object} verticesIndices - * @param {GraphVertex[]} cycle - * @param {GraphVertex} vertexCandidate - * @return {boolean} - */ -function isSafe(adjacencyMatrix, verticesIndices, cycle, vertexCandidate) { - const endVertex = cycle[cycle.length - 1]; - // Get end and candidate vertices indices in adjacency matrix. - const candidateVertexAdjacencyIndex = verticesIndices[vertexCandidate.getKey()]; - const endVertexAdjacencyIndex = verticesIndices[endVertex.getKey()]; - // Check if last vertex in the path and candidate vertex are adjacent. - if (adjacencyMatrix[endVertexAdjacencyIndex][candidateVertexAdjacencyIndex] === Infinity) { - return false; - } - // Check if vertexCandidate is being added to the path for the first time. - const candidateDuplicate = cycle.find((vertex) => vertex.getKey() === vertexCandidate.getKey()); - return !candidateDuplicate; -} -/** - * @param {number[][]} adjacencyMatrix - * @param {object} verticesIndices - * @param {GraphVertex[]} cycle - * @return {boolean} - */ -function isCycle(adjacencyMatrix, verticesIndices, cycle) { - // Check if first and last vertices in hamiltonian path are adjacent. - // Get start and end vertices from the path. - const startVertex = cycle[0]; - const endVertex = cycle[cycle.length - 1]; - // Get start/end vertices indices in adjacency matrix. - const startVertexAdjacencyIndex = verticesIndices[startVertex.getKey()]; - const endVertexAdjacencyIndex = verticesIndices[endVertex.getKey()]; - // Check if we can go from end vertex to the start one. - return adjacencyMatrix[endVertexAdjacencyIndex][startVertexAdjacencyIndex] !== Infinity; -} -/** - * @param {number[][]} adjacencyMatrix - * @param {GraphVertex[]} vertices - * @param {object} verticesIndices - * @param {GraphVertex[][]} cycles - * @param {GraphVertex[]} cycle - */ -function hamiltonianCycleRecursive({ - adjacencyMatrix, - vertices, - verticesIndices, - cycles, - cycle -}) { - // Clone cycle in order to prevent it from modification by other DFS branches. - const currentCycle = [...cycle].map((vertex) => new GraphVertex(vertex.value)); - if (vertices.length === currentCycle.length) { - // Hamiltonian path is found. - // Now we need to check if it is cycle or not. - if (isCycle(adjacencyMatrix, verticesIndices, currentCycle)) { - // Another solution has been found. Save it. - cycles.push(currentCycle); - } - return; - } - for (let vertexIndex = 0; vertexIndex < vertices.length; vertexIndex += 1) { - // Get vertex candidate that we will try to put into next path step and see if it fits. - const vertexCandidate = vertices[vertexIndex]; - // Check if it is safe to put vertex candidate to cycle. - if (isSafe(adjacencyMatrix, verticesIndices, currentCycle, vertexCandidate)) { - // Add candidate vertex to cycle path. - currentCycle.push(vertexCandidate); - // Try to find other vertices in cycle. - hamiltonianCycleRecursive({ - adjacencyMatrix, - vertices, - verticesIndices, - cycles, - cycle: currentCycle - }); - // BACKTRACKING. - // Remove candidate vertex from cycle path in order to try another one. - currentCycle.pop(); - } - } -} -/** - * @param {Graph} graph - * @return {GraphVertex[][]} - */ -export default function hamiltonianCycle(graph) { - // Gather some information about the graph that we will need to during - // the problem solving. - const verticesIndices = graph.getVerticesIndices(); - const adjacencyMatrix = graph.getAdjacencyMatrix(); - const vertices = graph.getAllVertices(); - // Define start vertex. We will always pick the first one - // this it doesn't matter which vertex to pick in a cycle. - // Every vertex is in a cycle so we can start from any of them. - const startVertex = vertices[0]; - // Init cycles array that will hold all solutions. - const cycles = []; - // Init cycle array that will hold current cycle path. - const cycle = [startVertex]; - // Try to find cycles recursively in Depth First Search order. - hamiltonianCycleRecursive({ - adjacencyMatrix, - vertices, - verticesIndices, - cycles, - cycle - }); - // Return found cycles. - return cycles; -} -cycle -}); -// Return found cycles. -return cycles; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/test/hamiltonianCycle.test.js b/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/test/hamiltonianCycle.test.js deleted file mode 100644 index d6a1a14b47..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/hamiltonian-cycle/test/hamiltonianCycle.test.js +++ /dev/null @@ -1,62 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import hamiltonianCycle from '../hamiltonianCycle'; -describe('hamiltonianCycle', () => { - it('should find hamiltonian paths in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBE = new GraphEdge(vertexB, vertexE); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAE).addEdge(edgeAC).addEdge(edgeBE).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCD).addEdge(edgeDE); - const hamiltonianCycleSet = hamiltonianCycle(graph); - expect(hamiltonianCycleSet.length).toBe(8); - expect(hamiltonianCycleSet[0][0].getKey()).toBe(vertexA.getKey()); - expect(hamiltonianCycleSet[0][1].getKey()).toBe(vertexB.getKey()); - expect(hamiltonianCycleSet[0][2].getKey()).toBe(vertexE.getKey()); - expect(hamiltonianCycleSet[0][3].getKey()).toBe(vertexD.getKey()); - expect(hamiltonianCycleSet[0][4].getKey()).toBe(vertexC.getKey()); - expect(hamiltonianCycleSet[1][0].getKey()).toBe(vertexA.getKey()); - expect(hamiltonianCycleSet[1][1].getKey()).toBe(vertexB.getKey()); - expect(hamiltonianCycleSet[1][2].getKey()).toBe(vertexC.getKey()); - expect(hamiltonianCycleSet[1][3].getKey()).toBe(vertexD.getKey()); - expect(hamiltonianCycleSet[1][4].getKey()).toBe(vertexE.getKey()); - expect(hamiltonianCycleSet[2][0].getKey()).toBe(vertexA.getKey()); - expect(hamiltonianCycleSet[2][1].getKey()).toBe(vertexE.getKey()); - expect(hamiltonianCycleSet[2][2].getKey()).toBe(vertexB.getKey()); - expect(hamiltonianCycleSet[2][3].getKey()).toBe(vertexD.getKey()); - expect(hamiltonianCycleSet[2][4].getKey()).toBe(vertexC.getKey()); - expect(hamiltonianCycleSet[3][0].getKey()).toBe(vertexA.getKey()); - expect(hamiltonianCycleSet[3][1].getKey()).toBe(vertexE.getKey()); - expect(hamiltonianCycleSet[3][2].getKey()).toBe(vertexD.getKey()); - expect(hamiltonianCycleSet[3][3].getKey()).toBe(vertexB.getKey()); - expect(hamiltonianCycleSet[3][4].getKey()).toBe(vertexC.getKey()); - }); - it('should return false for graph without Hamiltonian path', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAE = new GraphEdge(vertexA, vertexE); - const edgeBE = new GraphEdge(vertexB, vertexE); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAE).addEdge(edgeBE).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCD); - const hamiltonianCycleSet = hamiltonianCycle(graph); - expect(hamiltonianCycleSet.length).toBe(0); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/kruskal/README.md b/docs/content/DS_ALGO/algorithms/graph/kruskal/README.md deleted file mode 100644 index 61a85ba0fc..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/kruskal/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Kruskal's Algorithm - -Kruskal's algorithm is a minimum-spanning-tree algorithm which -finds an edge of the least possible weight that connects any two -trees in the forest. It is a greedy algorithm in graph theory -as it finds a minimum spanning tree for a connected weighted -graph adding increasing cost arcs at each step. This means it -finds a subset of the edges that forms a tree that includes every -vertex, where the total weight of all the edges in the tree is -minimized. If the graph is not connected, then it finds a -minimum spanning forest (a minimum spanning tree for each -connected component). - -![Kruskal Algorithm](https://upload.wikimedia.org/wikipedia/commons/5/5c/MST_kruskal_en.gif) - -![Kruskal Demo](https://upload.wikimedia.org/wikipedia/commons/b/bb/KruskalDemo.gif) - -A demo for Kruskal's algorithm based on Euclidean distance. - -## Minimum Spanning Tree - -A **minimum spanning tree** (MST) or minimum weight spanning tree -is a subset of the edges of a connected, edge-weighted -(un)directed graph that connects all the vertices together, -without any cycles and with the minimum possible total edge -weight. That is, it is a spanning tree whose sum of edge weights -is as small as possible. More generally, any edge-weighted -undirected graph (not necessarily connected) has a minimum -spanning forest, which is a union of the minimum spanning -trees for its connected components. - -![Minimum Spanning Tree](https://upload.wikimedia.org/wikipedia/commons/d/d2/Minimum_spanning_tree.svg) - -A planar graph and its minimum spanning tree. Each edge is -labeled with its weight, which here is roughly proportional -to its length. - -![Minimum Spanning Tree](https://upload.wikimedia.org/wikipedia/commons/c/c9/Multiple_minimum_spanning_trees.svg) - -This figure shows there may be more than one minimum spanning -tree in a graph. In the figure, the two trees below the graph -are two possibilities of minimum spanning tree of the given graph. - -## References - -- [Minimum Spanning Tree on Wikipedia](https://en.wikipedia.org/wiki/Minimum_spanning_tree) -- [Kruskal's Algorithm on Wikipedia](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm) -- [Kruskal's Algorithm on YouTube by Tushar Roy](https://www.youtube.com/watch?v=fAuF0EuZVCk&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Kruskal's Algorithm on YouTube by Michael Sambol](https://www.youtube.com/watch?v=71UQH7Pr9kU&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/kruskal/kruskal.js b/docs/content/DS_ALGO/algorithms/graph/kruskal/kruskal.js deleted file mode 100644 index 44a3a0e156..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/kruskal/kruskal.js +++ /dev/null @@ -1,52 +0,0 @@ -import Graph from '../../../data-structures/graph/Graph'; -import QuickSort from '../../sorting/quick-sort/QuickSort'; -import DisjointSet from '../../../data-structures/disjoint-set/DisjointSet'; -/** - * @param {Graph} graph - * @return {Graph} - */ -export default function kruskal(graph) { - // It should fire error if graph is directed since the algorithm works only - // for undirected graphs. - if (graph.isDirected) { - throw new Error("Kruskal's algorithms works only for undirected graphs"); - } - // Init new graph that will contain minimum spanning tree of original graph. - const minimumSpanningTree = new Graph(); - // Sort all graph edges in increasing order. - const sortingCallbacks = { - /** - * @param {GraphEdge} graphEdgeA - * @param {GraphEdge} graphEdgeB - */ - compareCallback: (graphEdgeA, graphEdgeB) => { - if (graphEdgeA.weight === graphEdgeB.weight) { - return 1; - } - return graphEdgeA.weight <= graphEdgeB.weight ? -1 : 1; - } - }; - const sortedEdges = new QuickSort(sortingCallbacks).sort(graph.getAllEdges()); - // Create disjoint sets for all graph vertices. - const keyCallback = (graphVertex) => graphVertex.getKey(); - const disjointSet = new DisjointSet(keyCallback); - graph.getAllVertices().forEach((graphVertex) => { - disjointSet.makeSet(graphVertex); - }); - // Go through all edges started from the minimum one and try to add them - // to minimum spanning tree. The criteria of adding the edge would be whether - // it is forms the cycle or not (if it connects two vertices from one disjoint - // set or not). - for (let edgeIndex = 0; edgeIndex < sortedEdges.length; edgeIndex += 1) { - /** @var {GraphEdge} currentEdge */ - const currentEdge = sortedEdges[edgeIndex]; - // Check if edge forms the cycle. If it does then skip it. - if (!disjointSet.inSameSet(currentEdge.startVertex, currentEdge.endVertex)) { - // Unite two subsets into one. - disjointSet.union(currentEdge.startVertex, currentEdge.endVertex); - // Add this edge to spanning tree. - minimumSpanningTree.addEdge(currentEdge); - } - } - return minimumSpanningTree; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/kruskal/test/kruskal.test.js b/docs/content/DS_ALGO/algorithms/graph/kruskal/test/kruskal.test.js deleted file mode 100644 index 71e01afbae..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/kruskal/test/kruskal.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import kruskal from '../kruskal'; -describe('kruskal', () => { - it('should fire an error for directed graph', () => { - function applyPrimToDirectedGraph() { - const graph = new Graph(true); - kruskal(graph); - } - expect(applyPrimToDirectedGraph).toThrowError(); - }); - it('should find minimum spanning tree', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB, 2); - const edgeAD = new GraphEdge(vertexA, vertexD, 3); - const edgeAC = new GraphEdge(vertexA, vertexC, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 4); - const edgeBE = new GraphEdge(vertexB, vertexE, 3); - const edgeDF = new GraphEdge(vertexD, vertexF, 7); - const edgeEC = new GraphEdge(vertexE, vertexC, 1); - const edgeEF = new GraphEdge(vertexE, vertexF, 8); - const edgeFG = new GraphEdge(vertexF, vertexG, 9); - const edgeFC = new GraphEdge(vertexF, vertexC, 6); - const graph = new Graph(); - graph - .addEdge(edgeAB) - .addEdge(edgeAD) - .addEdge(edgeAC) - .addEdge(edgeBC) - .addEdge(edgeBE) - .addEdge(edgeDF) - .addEdge(edgeEC) - .addEdge(edgeEF) - .addEdge(edgeFC) - .addEdge(edgeFG); - expect(graph.getWeight()).toEqual(46); - const minimumSpanningTree = kruskal(graph); - expect(minimumSpanningTree.getWeight()).toBe(24); - expect(minimumSpanningTree.getAllVertices().length).toBe(graph.getAllVertices().length); - expect(minimumSpanningTree.getAllEdges().length).toBe(graph.getAllVertices().length - 1); - expect(minimumSpanningTree.toString()).toBe('E,C,A,B,D,F,G'); - }); - it('should find minimum spanning tree for simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 1); - const edgeAD = new GraphEdge(vertexA, vertexD, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 1); - const edgeBD = new GraphEdge(vertexB, vertexD, 3); - const edgeCD = new GraphEdge(vertexC, vertexD, 1); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAD).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCD); - expect(graph.getWeight()).toEqual(9); - const minimumSpanningTree = kruskal(graph); - expect(minimumSpanningTree.getWeight()).toBe(3); - expect(minimumSpanningTree.getAllVertices().length).toBe(graph.getAllVertices().length); - expect(minimumSpanningTree.getAllEdges().length).toBe(graph.getAllVertices().length - 1); - expect(minimumSpanningTree.toString()).toBe('A,B,C,D'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/prim/README.md b/docs/content/DS_ALGO/algorithms/graph/prim/README.md deleted file mode 100644 index 0ae771df5d..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/prim/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Prim's Algorithm - -In computer science, **Prim's algorithm** is a greedy algorithm that -finds a minimum spanning tree for a weighted undirected graph. - -The algorithm operates by building this tree one vertex at a -time, from an arbitrary starting vertex, at each step adding -the cheapest possible connection from the tree to another vertex. - -![Prim's Algorithm](https://upload.wikimedia.org/wikipedia/commons/f/f7/Prim%27s_algorithm.svg) - -Prim's algorithm starting at vertex `A`. In the third step, edges -`BD` and `AB` both have weight `2`, so `BD` is chosen arbitrarily. -After that step, `AB` is no longer a candidate for addition -to the tree because it links two nodes that are already -in the tree. - -## Minimum Spanning Tree - -A **minimum spanning tree** (MST) or minimum weight spanning tree -is a subset of the edges of a connected, edge-weighted -(un)directed graph that connects all the vertices together, -without any cycles and with the minimum possible total edge -weight. That is, it is a spanning tree whose sum of edge weights -is as small as possible. More generally, any edge-weighted -undirected graph (not necessarily connected) has a minimum -spanning forest, which is a union of the minimum spanning -trees for its connected components. - -![Minimum Spanning Tree](https://upload.wikimedia.org/wikipedia/commons/d/d2/Minimum_spanning_tree.svg) - -A planar graph and its minimum spanning tree. Each edge is -labeled with its weight, which here is roughly proportional -to its length. - -![Minimum Spanning Tree](https://upload.wikimedia.org/wikipedia/commons/c/c9/Multiple_minimum_spanning_trees.svg) - -This figure shows there may be more than one minimum spanning -tree in a graph. In the figure, the two trees below the graph -are two possibilities of minimum spanning tree of the given graph. - -## References - -- [Minimum Spanning Tree on Wikipedia](https://en.wikipedia.org/wiki/Minimum_spanning_tree) -- [Prim's Algorithm on Wikipedia](https://en.wikipedia.org/wiki/Prim%27s_algorithm) -- [Prim's Algorithm on YouTube by Tushar Roy](https://www.youtube.com/watch?v=oP2-8ysT3QQ&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Prim's Algorithm on YouTube by Michael Sambol](https://www.youtube.com/watch?v=cplfcGZmX7I&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/prim/prim.js b/docs/content/DS_ALGO/algorithms/graph/prim/prim.js deleted file mode 100644 index a8966f88a0..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/prim/prim.js +++ /dev/null @@ -1,57 +0,0 @@ -import Graph from '../../../data-structures/graph/Graph'; -import PriorityQueue from '../../../data-structures/priority-queue/PriorityQueue'; -/** - * @param {Graph} graph - * @return {Graph} - */ -export default function prim(graph) { - // It should fire error if graph is directed since the algorithm works only - // for undirected graphs. - if (graph.isDirected) { - throw new Error("Prim's algorithms works only for undirected graphs"); - } - // Init new graph that will contain minimum spanning tree of original graph. - const minimumSpanningTree = new Graph(); - // This priority queue will contain all the edges that are starting from - // visited nodes and they will be ranked by edge weight - so that on each step - // we would always pick the edge with minimal edge weight. - const edgesQueue = new PriorityQueue(); - // Set of vertices that has been already visited. - const visitedVertices = {}; - // Vertex from which we will start graph traversal. - const startVertex = graph.getAllVertices()[0]; - // Add start vertex to the set of visited ones. - visitedVertices[startVertex.getKey()] = startVertex; - // Add all edges of start vertex to the queue. - startVertex.getEdges().forEach((graphEdge) => { - edgesQueue.add(graphEdge, graphEdge.weight); - }); - // Now let's explore all queued edges. - while (!edgesQueue.isEmpty()) { - // Fetch next queued edge with minimal weight. - /** @var {GraphEdge} currentEdge */ - const currentMinEdge = edgesQueue.poll(); - // Find out the next unvisited minimal vertex to traverse. - let nextMinVertex = null; - if (!visitedVertices[currentMinEdge.startVertex.getKey()]) { - nextMinVertex = currentMinEdge.startVertex; - } else if (!visitedVertices[currentMinEdge.endVertex.getKey()]) { - nextMinVertex = currentMinEdge.endVertex; - } - // If all vertices of current edge has been already visited then skip this round. - if (nextMinVertex) { - // Add current min edge to MST. - minimumSpanningTree.addEdge(currentMinEdge); - // Add vertex to the set of visited ones. - visitedVertices[nextMinVertex.getKey()] = nextMinVertex; - // Add all current vertex's edges to the queue. - nextMinVertex.getEdges().forEach((graphEdge) => { - // Add only vertices that link to unvisited nodes. - if (!visitedVertices[graphEdge.startVertex.getKey()] || !visitedVertices[graphEdge.endVertex.getKey()]) { - edgesQueue.add(graphEdge, graphEdge.weight); - } - }); - } - } - return minimumSpanningTree; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/prim/test/prim.test.js b/docs/content/DS_ALGO/algorithms/graph/prim/test/prim.test.js deleted file mode 100644 index 9ae9e32f9b..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/prim/test/prim.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import prim from '../prim'; -describe('prim', () => { - it('should fire an error for directed graph', () => { - function applyPrimToDirectedGraph() { - const graph = new Graph(true); - prim(graph); - } - expect(applyPrimToDirectedGraph).toThrowError(); - }); - it('should find minimum spanning tree', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const edgeAB = new GraphEdge(vertexA, vertexB, 2); - const edgeAD = new GraphEdge(vertexA, vertexD, 3); - const edgeAC = new GraphEdge(vertexA, vertexC, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 4); - const edgeBE = new GraphEdge(vertexB, vertexE, 3); - const edgeDF = new GraphEdge(vertexD, vertexF, 7); - const edgeEC = new GraphEdge(vertexE, vertexC, 1); - const edgeEF = new GraphEdge(vertexE, vertexF, 8); - const edgeFG = new GraphEdge(vertexF, vertexG, 9); - const edgeFC = new GraphEdge(vertexF, vertexC, 6); - const graph = new Graph(); - graph - .addEdge(edgeAB) - .addEdge(edgeAD) - .addEdge(edgeAC) - .addEdge(edgeBC) - .addEdge(edgeBE) - .addEdge(edgeDF) - .addEdge(edgeEC) - .addEdge(edgeEF) - .addEdge(edgeFC) - .addEdge(edgeFG); - expect(graph.getWeight()).toEqual(46); - const minimumSpanningTree = prim(graph); - expect(minimumSpanningTree.getWeight()).toBe(24); - expect(minimumSpanningTree.getAllVertices().length).toBe(graph.getAllVertices().length); - expect(minimumSpanningTree.getAllEdges().length).toBe(graph.getAllVertices().length - 1); - expect(minimumSpanningTree.toString()).toBe('A,B,C,E,D,F,G'); - }); - it('should find minimum spanning tree for simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 1); - const edgeAD = new GraphEdge(vertexA, vertexD, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 1); - const edgeBD = new GraphEdge(vertexB, vertexD, 3); - const edgeCD = new GraphEdge(vertexC, vertexD, 1); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeAD).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCD); - expect(graph.getWeight()).toEqual(9); - const minimumSpanningTree = prim(graph); - expect(minimumSpanningTree.getWeight()).toBe(3); - expect(minimumSpanningTree.getAllVertices().length).toBe(graph.getAllVertices().length); - expect(minimumSpanningTree.getAllEdges().length).toBe(graph.getAllVertices().length - 1); - expect(minimumSpanningTree.toString()).toBe('A,B,C,D'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/README.md b/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/README.md deleted file mode 100644 index 7436627f75..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Strongly Connected Component - -A directed graph is called **strongly connected** if there is a path -in each direction between each pair of vertices of the graph. -In a directed graph G that may not itself be strongly connected, -a pair of vertices `u` and `v` are said to be strongly connected -to each other if there is a path in each direction between them. - -![Strongly Connected](https://upload.wikimedia.org/wikipedia/commons/5/5c/Scc.png) - -Graph with strongly connected components marked - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Strongly_connected_component) -- [YouTube](https://www.youtube.com/watch?v=RpgcYiky7uw&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/stronglyConnectedComponents.js b/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/stronglyConnectedComponents.js deleted file mode 100644 index 9149378eb7..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/stronglyConnectedComponents.js +++ /dev/null @@ -1,133 +0,0 @@ -import Stack from '../../../data-structures/stack/Stack'; -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * @param {Graph} graph - * @return {Stack} - */ -function getVerticesSortedByDfsFinishTime(graph) { - // Set of all visited vertices during DFS pass. - const visitedVerticesSet = {}; - // Stack of vertices by finish time. - // All vertices in this stack are ordered by finished time in decreasing order. - // Vertex that has been finished first will be at the bottom of the stack and - // vertex that has been finished last will be at the top of the stack. - const verticesByDfsFinishTime = new Stack(); - // Set of all vertices we're going to visit. - const notVisitedVerticesSet = {}; - graph.getAllVertices().forEach((vertex) => { - notVisitedVerticesSet[vertex.getKey()] = vertex; - }); - // Specify DFS traversal callbacks. - const dfsCallbacks = { - enterVertex: ({ - currentVertex - }) => { - // Add current vertex to visited set. - visitedVerticesSet[currentVertex.getKey()] = currentVertex; - // Delete current vertex from not visited set. - delete notVisitedVerticesSet[currentVertex.getKey()]; - }, - leaveVertex: ({ - currentVertex - }) => { - // Push vertex to the stack when leaving it. - // This will make stack to be ordered by finish time in decreasing order. - verticesByDfsFinishTime.push(currentVertex); - }, - allowTraversal: ({ - nextVertex - }) => { - // Don't allow to traverse the nodes that have been already visited. - return !visitedVerticesSet[nextVertex.getKey()]; - } - }; - // Do FIRST DFS PASS traversal for all graph vertices to fill the verticesByFinishTime stack. - while (Object.values(notVisitedVerticesSet).length) { - // Peek any vertex to start DFS traversal from. - const startVertexKey = Object.keys(notVisitedVerticesSet)[0]; - const startVertex = notVisitedVerticesSet[startVertexKey]; - delete notVisitedVerticesSet[startVertexKey]; - depthFirstSearch(graph, startVertex, dfsCallbacks); - } - return verticesByDfsFinishTime; -} -/** - * @param {Graph} graph - * @param {Stack} verticesByFinishTime - * @return {*[]} - */ -function getSCCSets(graph, verticesByFinishTime) { - // Array of arrays of strongly connected vertices. - const stronglyConnectedComponentsSets = []; - // Array that will hold all vertices that are being visited during one DFS run. - let stronglyConnectedComponentsSet = []; - // Visited vertices set. - const visitedVerticesSet = {}; - // Callbacks for DFS traversal. - const dfsCallbacks = { - enterVertex: ({ - currentVertex - }) => { - // Add current vertex to SCC set of current DFS round. - stronglyConnectedComponentsSet.push(currentVertex); - // Add current vertex to visited set. - visitedVerticesSet[currentVertex.getKey()] = currentVertex; - }, - leaveVertex: ({ - previousVertex - }) => { - // Once DFS traversal is finished push the set of found strongly connected - // components during current DFS round to overall strongly connected components set. - // The sign that traversal is about to be finished is that we came back to start vertex - // which doesn't have parent. - if (previousVertex === null) { - stronglyConnectedComponentsSets.push([...stronglyConnectedComponentsSet]); - } - }, - allowTraversal: ({ - nextVertex - }) => { - // Don't allow traversal of already visited vertices. - return !visitedVerticesSet[nextVertex.getKey()]; - } - }; - while (!verticesByFinishTime.isEmpty()) { - /** @var {GraphVertex} startVertex */ - const startVertex = verticesByFinishTime.pop(); - // Reset the set of strongly connected vertices. - stronglyConnectedComponentsSet = []; - // Don't do DFS on already visited vertices. - if (!visitedVerticesSet[startVertex.getKey()]) { - // Do DFS traversal. - depthFirstSearch(graph, startVertex, dfsCallbacks); - } - } - return stronglyConnectedComponentsSets; -} -/** - * Kosaraju's algorithm. - * - * @param {Graph} graph - * @return {*[]} - */ -export default function stronglyConnectedComponents(graph) { - // In this algorithm we will need to do TWO DFS PASSES overt the graph. - // Get stack of vertices ordered by DFS finish time. - // All vertices in this stack are ordered by finished time in decreasing order: - // Vertex that has been finished first will be at the bottom of the stack and - // vertex that has been finished last will be at the top of the stack. - const verticesByFinishTime = getVerticesSortedByDfsFinishTime(graph); - // Reverse the graph. - graph.reverse(); - // Do DFS once again on reversed graph. - return getSCCSets(graph, verticesByFinishTime); -} // Get stack of vertices ordered by DFS finish time. -// All vertices in this stack are ordered by finished time in decreasing order: -// Vertex that has been finished first will be at the bottom of the stack and -// vertex that has been finished last will be at the top of the stack. -const verticesByFinishTime = getVerticesSortedByDfsFinishTime(graph); -// Reverse the graph. -graph.reverse(); -// Do DFS once again on reversed graph. -return getSCCSets(graph, verticesByFinishTime); -} diff --git a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/test/stronglyConnectedComponents.test.js b/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/test/stronglyConnectedComponents.test.js deleted file mode 100644 index 5af1f67102..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/strongly-connected-components/test/stronglyConnectedComponents.test.js +++ /dev/null @@ -1,80 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import stronglyConnectedComponents from '../stronglyConnectedComponents'; -describe('stronglyConnectedComponents', () => { - it('should detect strongly connected components in simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCA = new GraphEdge(vertexC, vertexA); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(true); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCA).addEdge(edgeCD); - const components = stronglyConnectedComponents(graph); - expect(components).toBeDefined(); - expect(components.length).toBe(2); - expect(components[0][0].getKey()).toBe(vertexA.getKey()); - expect(components[0][1].getKey()).toBe(vertexC.getKey()); - expect(components[0][2].getKey()).toBe(vertexB.getKey()); - expect(components[1][0].getKey()).toBe(vertexD.getKey()); - }); - it('should detect strongly connected components in graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const vertexI = new GraphVertex('I'); - const vertexJ = new GraphVertex('J'); - const vertexK = new GraphVertex('K'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCA = new GraphEdge(vertexC, vertexA); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeDE = new GraphEdge(vertexD, vertexE); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeFD = new GraphEdge(vertexF, vertexD); - const edgeGF = new GraphEdge(vertexG, vertexF); - const edgeGH = new GraphEdge(vertexG, vertexH); - const edgeHI = new GraphEdge(vertexH, vertexI); - const edgeIJ = new GraphEdge(vertexI, vertexJ); - const edgeJG = new GraphEdge(vertexJ, vertexG); - const edgeJK = new GraphEdge(vertexJ, vertexK); - const graph = new Graph(true); - graph - .addEdge(edgeAB) - .addEdge(edgeBC) - .addEdge(edgeCA) - .addEdge(edgeBD) - .addEdge(edgeDE) - .addEdge(edgeEF) - .addEdge(edgeFD) - .addEdge(edgeGF) - .addEdge(edgeGH) - .addEdge(edgeHI) - .addEdge(edgeIJ) - .addEdge(edgeJG) - .addEdge(edgeJK); - const components = stronglyConnectedComponents(graph); - expect(components).toBeDefined(); - expect(components.length).toBe(4); - expect(components[0][0].getKey()).toBe(vertexG.getKey()); - expect(components[0][1].getKey()).toBe(vertexJ.getKey()); - expect(components[0][2].getKey()).toBe(vertexI.getKey()); - expect(components[0][3].getKey()).toBe(vertexH.getKey()); - expect(components[1][0].getKey()).toBe(vertexK.getKey()); - expect(components[2][0].getKey()).toBe(vertexA.getKey()); - expect(components[2][1].getKey()).toBe(vertexC.getKey()); - expect(components[2][2].getKey()).toBe(vertexB.getKey()); - expect(components[3][0].getKey()).toBe(vertexD.getKey()); - expect(components[3][1].getKey()).toBe(vertexF.getKey()); - expect(components[3][2].getKey()).toBe(vertexE.getKey()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/README.md b/docs/content/DS_ALGO/algorithms/graph/topological-sorting/README.md deleted file mode 100644 index b030e25bde..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Topological Sorting - -In the field of computer science, a topological sort or -topological ordering of a directed graph is a linear ordering -of its vertices such that for every directed edge `uv` from -vertex `u` to vertex `v`, `u` comes before `v` in the ordering. - -For instance, the vertices of the graph may represent tasks to -be performed, and the edges may represent constraints that one -task must be performed before another; in this application, a -topological ordering is just a valid sequence for the tasks. - -A topological ordering is possible if and only if the graph has -no directed cycles, that is, if it is a [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) -(DAG). Any DAG has at least one topological ordering, and algorithms are -known for constructing a topological ordering of any DAG in linear time. - -![Directed Acyclic Graph](https://upload.wikimedia.org/wikipedia/commons/c/c6/Topological_Ordering.svg) - -A topological ordering of a directed acyclic graph: every edge goes from -earlier in the ordering (upper left) to later in the ordering (lower right). -A directed graph is acyclic if and only if it has a topological ordering. - -## Example - -![Topologic Sorting](https://upload.wikimedia.org/wikipedia/commons/0/03/Directed_acyclic_graph_2.svg) - -The graph shown above has many valid topological sorts, including: - -- `5, 7, 3, 11, 8, 2, 9, 10` (visual left-to-right, top-to-bottom) -- `3, 5, 7, 8, 11, 2, 9, 10` (smallest-numbered available vertex first) -- `5, 7, 3, 8, 11, 10, 9, 2` (fewest edges first) -- `7, 5, 11, 3, 10, 8, 9, 2` (largest-numbered available vertex first) -- `5, 7, 11, 2, 3, 8, 9, 10` (attempting top-to-bottom, left-to-right) -- `3, 7, 8, 5, 11, 10, 2, 9` (arbitrary) - -## Application - -The canonical application of topological sorting is in -**scheduling a sequence of jobs** or tasks based on their dependencies. The jobs -are represented by vertices, and there is an edge from `x` to `y` if -job `x` must be completed before job `y` can be started (for -example, when washing clothes, the washing machine must finish -before we put the clothes in the dryer). Then, a topological sort -gives an order in which to perform the jobs. - -Other application is **dependency resolution**. Each vertex is a package -and each edge is a dependency of package `a` on package 'b'. Then topological -sorting will provide a sequence of installing dependencies in a way that every -next dependency has its dependent packages to be installed in prior. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Topological_sorting) -- [Topological Sorting on YouTube by Tushar Roy](https://www.youtube.com/watch?v=ddTC4Zovtbc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/test/topologicalSort.test.js b/docs/content/DS_ALGO/algorithms/graph/topological-sorting/test/topologicalSort.test.js deleted file mode 100644 index 188976a576..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/test/topologicalSort.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import topologicalSort from '../topologicalSort'; -describe('topologicalSort', () => { - it('should do topological sorting on graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const vertexE = new GraphVertex('E'); - const vertexF = new GraphVertex('F'); - const vertexG = new GraphVertex('G'); - const vertexH = new GraphVertex('H'); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeBD = new GraphEdge(vertexB, vertexD); - const edgeCE = new GraphEdge(vertexC, vertexE); - const edgeDF = new GraphEdge(vertexD, vertexF); - const edgeEF = new GraphEdge(vertexE, vertexF); - const edgeEH = new GraphEdge(vertexE, vertexH); - const edgeFG = new GraphEdge(vertexF, vertexG); - const graph = new Graph(true); - graph.addEdge(edgeAC).addEdge(edgeBC).addEdge(edgeBD).addEdge(edgeCE).addEdge(edgeDF).addEdge(edgeEF).addEdge(edgeEH).addEdge(edgeFG); - const sortedVertices = topologicalSort(graph); - expect(sortedVertices).toBeDefined(); - expect(sortedVertices.length).toBe(graph.getAllVertices().length); - expect(sortedVertices).toEqual([vertexB, vertexD, vertexA, vertexC, vertexE, vertexH, vertexF, vertexG]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/topologicalSort.js b/docs/content/DS_ALGO/algorithms/graph/topological-sorting/topologicalSort.js deleted file mode 100644 index 1a2f627c3c..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/topological-sorting/topologicalSort.js +++ /dev/null @@ -1,39 +0,0 @@ -import Stack from '../../../data-structures/stack/Stack'; -import depthFirstSearch from '../depth-first-search/depthFirstSearch'; -/** - * @param {Graph} graph - */ -export default function topologicalSort(graph) { - // Create a set of all vertices we want to visit. - const unvisitedSet = {}; - graph.getAllVertices().forEach((vertex) => { - unvisitedSet[vertex.getKey()] = vertex; - }); - // Create a set for all vertices that we've already visited. - const visitedSet = {}; - // Create a stack of already ordered vertices. - const sortedStack = new Stack(); - const dfsCallbacks = { - enterVertex: ({ currentVertex }) => { - // Add vertex to visited set in case if all its children has been explored. - visitedSet[currentVertex.getKey()] = currentVertex; - // Remove this vertex from unvisited set. - delete unvisitedSet[currentVertex.getKey()]; - }, - leaveVertex: ({ currentVertex }) => { - // If the vertex has been totally explored then we may push it to stack. - sortedStack.push(currentVertex); - }, - allowTraversal: ({ nextVertex }) => { - return !visitedSet[nextVertex.getKey()]; - } - }; - // Let's go and do DFS for all unvisited nodes. - while (Object.keys(unvisitedSet).length) { - const currentVertexKey = Object.keys(unvisitedSet)[0]; - const currentVertex = unvisitedSet[currentVertexKey]; - // Do DFS for current node. - depthFirstSearch(graph, currentVertex, dfsCallbacks); - } - return sortedStack.toArray(); -} diff --git a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/README.md b/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/README.md deleted file mode 100644 index 54f42c9723..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Travelling Salesman Problem - -The travelling salesman problem (TSP) asks the following question: -"Given a list of cities and the distances between each pair of -cities, what is the shortest possible route that visits each city -and returns to the origin city?" - -![Travelling Salesman](https://upload.wikimedia.org/wikipedia/commons/1/11/GLPK_solution_of_a_travelling_salesman_problem.svg) - -Solution of a travelling salesman problem: the black line shows -the shortest possible loop that connects every red dot. - -![Travelling Salesman Graph](https://upload.wikimedia.org/wikipedia/commons/3/30/Weighted_K4.svg) - -TSP can be modelled as an undirected weighted graph, such that -cities are the graph's vertices, paths are the graph's edges, -and a path's distance is the edge's weight. It is a minimization -problem starting and finishing at a specified vertex after having -visited each other vertex exactly once. Often, the model is a -complete graph (i.e. each pair of vertices is connected by an -edge). If no path exists between two cities, adding an arbitrarily -long edge will complete the graph without affecting the optimal tour. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Travelling_salesman_problem) diff --git a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/bfTravellingSalesman.js b/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/bfTravellingSalesman.js deleted file mode 100644 index 6a68342c31..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/bfTravellingSalesman.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Get all possible paths - * @param {GraphVertex} startVertex - * @param {GraphVertex[][]} [paths] - * @param {GraphVertex[]} [path] - */ -function findAllPaths(startVertex, paths = [], path = []) { - // Clone path. - const currentPath = [...path]; - // Add startVertex to the path. - currentPath.push(startVertex); - // Generate visited set from path. - const visitedSet = currentPath.reduce((accumulator, vertex) => { - const updatedAccumulator = { ...accumulator }; - updatedAccumulator[vertex.getKey()] = vertex; - return updatedAccumulator; - }, {}); - // Get all unvisited neighbors of startVertex. - const unvisitedNeighbors = startVertex.getNeighbors().filter((neighbor) => { - return !visitedSet[neighbor.getKey()]; - }); - // If there no unvisited neighbors then treat current path as complete and save it. - if (!unvisitedNeighbors.length) { - paths.push(currentPath); - return paths; - } - // Go through all the neighbors. - for (let neighborIndex = 0; neighborIndex < unvisitedNeighbors.length; neighborIndex += 1) { - const currentUnvisitedNeighbor = unvisitedNeighbors[neighborIndex]; - findAllPaths(currentUnvisitedNeighbor, paths, currentPath); - } - return paths; -} -/** - * @param {number[][]} adjacencyMatrix - * @param {object} verticesIndices - * @param {GraphVertex[]} cycle - * @return {number} - */ -function getCycleWeight(adjacencyMatrix, verticesIndices, cycle) { - let weight = 0; - for (let cycleIndex = 1; cycleIndex < cycle.length; cycleIndex += 1) { - const fromVertex = cycle[cycleIndex - 1]; - const toVertex = cycle[cycleIndex]; - const fromVertexIndex = verticesIndices[fromVertex.getKey()]; - const toVertexIndex = verticesIndices[toVertex.getKey()]; - weight += adjacencyMatrix[fromVertexIndex][toVertexIndex]; - } - return weight; -} -/** - * BRUTE FORCE approach to solve Traveling Salesman Problem. - * - * @param {Graph} graph - * @return {GraphVertex[]} - */ -export default function bfTravellingSalesman(graph) { - // Pick starting point from where we will traverse the graph. - const startVertex = graph.getAllVertices()[0]; - // BRUTE FORCE. - // Generate all possible paths from startVertex. - const allPossiblePaths = findAllPaths(startVertex); - // Filter out paths that are not cycles. - const allPossibleCycles = allPossiblePaths.filter((path) => { - /** @var {GraphVertex} */ - const lastVertex = path[path.length - 1]; - const lastVertexNeighbors = lastVertex.getNeighbors(); - return lastVertexNeighbors.includes(startVertex); - }); - // Go through all possible cycles and pick the one with minimum overall tour weight. - const adjacencyMatrix = graph.getAdjacencyMatrix(); - const verticesIndices = graph.getVerticesIndices(); - let salesmanPath = []; - let salesmanPathWeight = null; - for (let cycleIndex = 0; cycleIndex < allPossibleCycles.length; cycleIndex += 1) { - const currentCycle = allPossibleCycles[cycleIndex]; - const currentCycleWeight = getCycleWeight(adjacencyMatrix, verticesIndices, currentCycle); - // If current cycle weight is smaller then previous ones treat current cycle as most optimal. - if (salesmanPathWeight === null || currentCycleWeight < salesmanPathWeight) { - salesmanPath = currentCycle; - salesmanPathWeight = currentCycleWeight; - } - } - // Return the solution. - return salesmanPath; -} diff --git a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/test/bfTravellingSalesman.test.js b/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/test/bfTravellingSalesman.test.js deleted file mode 100644 index c7d4081c3b..0000000000 --- a/docs/content/DS_ALGO/algorithms/graph/travelling-salesman/test/bfTravellingSalesman.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import GraphVertex from '../../../../data-structures/graph/GraphVertex'; -import GraphEdge from '../../../../data-structures/graph/GraphEdge'; -import Graph from '../../../../data-structures/graph/Graph'; -import bfTravellingSalesman from '../bfTravellingSalesman'; -describe('bfTravellingSalesman', () => { - it('should solve problem for simple graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 1); - const edgeBD = new GraphEdge(vertexB, vertexD, 1); - const edgeDC = new GraphEdge(vertexD, vertexC, 1); - const edgeCA = new GraphEdge(vertexC, vertexA, 1); - const edgeBA = new GraphEdge(vertexB, vertexA, 5); - const edgeDB = new GraphEdge(vertexD, vertexB, 8); - const edgeCD = new GraphEdge(vertexC, vertexD, 7); - const edgeAC = new GraphEdge(vertexA, vertexC, 4); - const edgeAD = new GraphEdge(vertexA, vertexD, 2); - const edgeDA = new GraphEdge(vertexD, vertexA, 3); - const edgeBC = new GraphEdge(vertexB, vertexC, 3); - const edgeCB = new GraphEdge(vertexC, vertexB, 9); - const graph = new Graph(true); - graph - .addEdge(edgeAB) - .addEdge(edgeBD) - .addEdge(edgeDC) - .addEdge(edgeCA) - .addEdge(edgeBA) - .addEdge(edgeDB) - .addEdge(edgeCD) - .addEdge(edgeAC) - .addEdge(edgeAD) - .addEdge(edgeDA) - .addEdge(edgeBC) - .addEdge(edgeCB); - const salesmanPath = bfTravellingSalesman(graph); - expect(salesmanPath.length).toBe(4); - expect(salesmanPath[0].getKey()).toEqual(vertexA.getKey()); - expect(salesmanPath[1].getKey()).toEqual(vertexB.getKey()); - expect(salesmanPath[2].getKey()).toEqual(vertexD.getKey()); - expect(salesmanPath[3].getKey()).toEqual(vertexC.getKey()); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/README.md b/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/README.md deleted file mode 100644 index 7d6eb76bfc..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Reversed Linked List Traversal - -[中文](README.zh-CN.md) - -The task is to traverse the given linked list in reversed order. - -For example for the following linked list: - -![](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg) - -The order of traversal should be: - -```text -37 → 99 → 12 -``` - -The time complexity is `O(n)` because we visit every node only once. - -## Reference - -- [Wikipedia](https://en.wikipedia.org/wiki/Linked_list) diff --git a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/reverseTraversal.js b/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/reverseTraversal.js deleted file mode 100644 index 76845c5385..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/reverseTraversal.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Traversal callback function. - * @callback traversalCallback - * @param {*} nodeValue - */ -/** - * @param {LinkedListNode} node - * @param {traversalCallback} callback - */ -function reverseTraversalRecursive(node, callback) { - if (node) { - reverseTraversalRecursive(node.next, callback); - callback(node.value); - } -} -/** - * @param {LinkedList} linkedList - * @param {traversalCallback} callback - */ -export default function reverseTraversal(linkedList, callback) { - reverseTraversalRecursive(linkedList.head, callback); -} diff --git a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/test/reverseTraversal.test.js b/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/test/reverseTraversal.test.js deleted file mode 100644 index b16fb172df..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/reverse-traversal/test/reverseTraversal.test.js +++ /dev/null @@ -1,26 +0,0 @@ -import LinkedList from '../../../../data-structures/linked-list/LinkedList'; -import reverseTraversal from '../reverseTraversal'; -describe('reverseTraversal', () => { - it('should traverse linked list in reverse order', () => { - const linkedList = new LinkedList(); - linkedList.append(1).append(2).append(3); - const traversedNodeValues = []; - const traversalCallback = (nodeValue) => { - traversedNodeValues.push(nodeValue); - }; - reverseTraversal(linkedList, traversalCallback); - expect(traversedNodeValues).toEqual([3, 2, 1]); - }); -}); -// it('should reverse traversal the linked list with callback', () => { -// const linkedList = new LinkedList(); -// -// linkedList -// .append(1) -// .append(2) -// .append(3); -// -// expect(linkedList.toString()).toBe('1,2,3'); -// expect(linkedList.reverseTraversal(linkedList.head, value => value * 2)).toEqual([6, 4, 2]); -// expect(() => linkedList.reverseTraversal(linkedList.head)).toThrow(); -// }); diff --git a/docs/content/DS_ALGO/algorithms/linked-list/traversal/README.md b/docs/content/DS_ALGO/algorithms/linked-list/traversal/README.md deleted file mode 100644 index 247acb157a..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/traversal/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Linked List Traversal - -[中文](README.zh-CN.md) - -The task is to traverse the given linked list in straight order. - -For example for the following linked list: - -![Singly linked list](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg) - -The order of traversal should be: - -```text -12 → 99 → 37 -``` - -The time complexity is `O(n)` because we visit every node only once. - -## Reference - -- [Wikipedia](https://en.wikipedia.org/wiki/Linked_list) diff --git a/docs/content/DS_ALGO/algorithms/linked-list/traversal/test/traversal.test.js b/docs/content/DS_ALGO/algorithms/linked-list/traversal/test/traversal.test.js deleted file mode 100644 index 600f1cce18..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/traversal/test/traversal.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import LinkedList from '../../../../data-structures/linked-list/LinkedList'; -import traversal from '../traversal'; -describe('traversal', () => { - it('should traverse linked list', () => { - const linkedList = new LinkedList(); - linkedList.append(1).append(2).append(3); - const traversedNodeValues = []; - const traversalCallback = (nodeValue) => { - traversedNodeValues.push(nodeValue); - }; - traversal(linkedList, traversalCallback); - expect(traversedNodeValues).toEqual([1, 2, 3]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/linked-list/traversal/traversal.js b/docs/content/DS_ALGO/algorithms/linked-list/traversal/traversal.js deleted file mode 100644 index aec16c3da9..0000000000 --- a/docs/content/DS_ALGO/algorithms/linked-list/traversal/traversal.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Traversal callback function. - * @callback traversalCallback - * @param {*} nodeValue - */ -/** - * @param {LinkedList} linkedList - * @param {traversalCallback} callback - */ -export default function traversal(linkedList, callback) { - let currentNode = linkedList.head; - while (currentNode) { - callback(currentNode.value); - currentNode = currentNode.next; - } -} diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/README.md b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/README.md deleted file mode 100644 index cbc40cacbd..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/README.md +++ /dev/null @@ -1,103 +0,0 @@ -# Binary representation of floating-point numbers - -Have you ever wondered how computers store the floating-point numbers like `3.1416` (𝝿) or `9.109 × 10⁻³¹` (the mass of the electron in kg) in the memory which is limited by a finite number of ones and zeroes (aka bits)? - -It seems pretty straightforward for integers (i.e. `17`). Let's say we have 16 bits (2 bytes) to store the number. In 16 bits we may store the integers in a range of `[0, 65535]`: - -```text -(0000000000000000)₂ = (0)₁₀ - -(0000000000010001)₂ = - (1 × 2⁴) + - (0 × 2³) + - (0 × 2²) + - (0 × 2¹) + - (1 × 2⁰) = (17)₁₀ - -(1111111111111111)₂ = - (1 × 2¹⁵) + - (1 × 2¹⁴) + - (1 × 2¹³) + - (1 × 2¹²) + - (1 × 2¹¹) + - (1 × 2¹⁰) + - (1 × 2⁹) + - (1 × 2⁸) + - (1 × 2⁷) + - (1 × 2⁶) + - (1 × 2⁵) + - (1 × 2⁴) + - (1 × 2³) + - (1 × 2²) + - (1 × 2¹) + - (1 × 2⁰) = (65535)₁₀ -``` - -If we need a signed integer we may use [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement) and shift the range of `[0, 65535]` towards the negative numbers. In this case, our 16 bits would represent the numbers in a range of `[-32768, +32767]`. - -As you might have noticed, this approach won't allow you to represent the numbers like `-27.15625` (numbers after the decimal point are just being ignored). - -We're not the first ones who have noticed this issue though. Around ≈36 years ago some smart folks overcame this limitation by introducing the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard for floating-point arithmetic. - -The IEEE 754 standard describes the way (the framework) of using those 16 bits (or 32, or 64 bits) to store the numbers of wider range, including the small floating numbers (smaller than 1 and closer to 0). - -To get the idea behind the standard we might recall the [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation) - a way of expressing numbers that are too large or too small (usually would result in a long string of digits) to be conveniently written in decimal form. - -![Scientific number notation](images/03-scientific-notation.png) - -As you may see from the image, the number representation might be split into three parts: - -- **sign** -- **fraction (aka significand)** - the valuable digits (the meaning, the payload) of the number -- **exponent** - controls how far and in which direction to move the decimal point in the fraction - -The **base** part we may omit by just agreeing on what it will be equal to. In our case, we'll be using `2` as a base. - -Instead of using all 16 bits (or 32 bits, or 64 bits) to store the fraction of the number, we may share the bits and store a sign, exponent, and fraction at the same time. Depending on the number of bits that we're going to use to store the number we end up with the following splits: - -| Floating-point format | Total bits | Sign bits | Exponent bits | Fraction bits | Base | -| :--------------------------------------------------------------------------------------- | :--------: | :-------: | :-----------: | :-----------: | :--: | -| [Half-precision](https://en.wikipedia.org/wiki/Half-precision_floating-point_format) | 16 | 1 | 5 | 10 | 2 | -| [Single-precision](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) | 32 | 1 | 8 | 23 | 2 | -| [Double-precision](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) | 64 | 1 | 11 | 52 | 2 | - -With this approach, the number of bits for the fraction has been reduced (i.e. for the 16-bits number it was reduced from 16 bits to 10 bits). It means that the fraction might take a narrower range of values now (losing some precision). However, since we also have an exponent part, it will actually increase the ultimate number range and also allow us to describe the numbers between 0 and 1 (if the exponent is negative). - -> For example, a signed 32-bit integer variable has a maximum value of 2³¹ − 1 = 2,147,483,647, whereas an IEEE 754 32-bit base-2 floating-point variable has a maximum value of ≈ 3.4028235 × 10³⁸. - -To make it possible to have a negative exponent, the IEEE 754 standard uses the [biased exponent](https://en.wikipedia.org/wiki/Exponent_bias). The idea is simple - subtract the bias from the exponent value to make it negative. For example, if the exponent has 5 bits, it might take the values from the range of `[0, 31]` (all values are positive here). But if we subtract the value of `15` from it, the range will be `[-15, 16]`. The number `15` is called bias, and it is being calculated by the following formula: - -``` -exponent_bias = 2 ^ (k−1) − 1 - -k - number of exponent bits -``` - -I've tried to describe the logic behind the converting of floating-point numbers from a binary format back to the decimal format on the image below. Hopefully, it will give you a better understanding of how the IEEE 754 standard works. The 16-bits number is being used here for simplicity, but the same approach works for 32-bits and 64-bits numbers as well. - -![Half-precision floating point number format explained in one picture](images/02-half-precision-floating-point-number-explained.png) - -> Checkout the [interactive version of this diagram](https://trekhleb.dev/blog/2021/binary-floating-point/) to play around with setting bits on and off, and seeing how it would influence the final result - -Here is the number ranges that different floating-point formats support: - -| Floating-point format | Exp min | Exp max | Range | Min positive | -| :-------------------- | :------ | :------ | :---------------- | :----------- | -| Half-precision | −14 | +15 | ±65,504 | 6.10 × 10⁻⁵ | -| Single-precision | −126 | +127 | ±3.4028235 × 10³⁸ | 1.18 × 10⁻³⁸ | - -Be aware that this is by no means a complete and sufficient overview of the IEEE 754 standard. It is rather a simplified and basic overview. Several corner cases were omitted in the examples above for simplicity of presentation (i.e. `-0`, `-∞`, `+∞` and `NaN` (not a number) values) - -## Code examples - -- See the [bitsToFloat.js](bitsToFloat.js) for the example of how to convert array of bits to the floating point number (the example is a bit artificial but still it gives the overview of how the conversion is going on) -- See the [floatAsBinaryString.js](floatAsBinaryString.js) for the example of how to see the actual binary representation of the floating-point number in JavaScript - -## References - -You might also want to check out the following resources to get a deeper understanding of the binary representation of floating-point numbers: - -- [Interactive version of this article](https://trekhleb.dev/blog/2021/binary-floating-point/) (allows setting the bits manually and seeing the resulting floating number) -- [Here is what you need to know about JavaScript's Number type](https://indepth.dev/posts/1139/here-is-what-you-need-to-know-about-javascripts-number-type) -- [Float Exposed](https://float.exposed/) -- [IEEE754 Visualization](https://bartaz.github.io/ieee754-visualization/) diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/bitsToFloat.test.js b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/bitsToFloat.test.js deleted file mode 100644 index 0a8841d429..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/bitsToFloat.test.js +++ /dev/null @@ -1,29 +0,0 @@ -import { testCases16Bits, testCases32Bits, testCases64Bits } from '../testCases'; -import { bitsToFloat16, bitsToFloat32, bitsToFloat64 } from '../bitsToFloat'; -describe('bitsToFloat16', () => { - it('should convert floating point binary bits to floating point decimal number', () => { - for (let testCaseIndex = 0; testCaseIndex < testCases16Bits.length; testCaseIndex += 1) { - const [decimal, binary] = testCases16Bits[testCaseIndex]; - const bits = binary.split('').map((bitString) => parseInt(bitString, 10)); - expect(bitsToFloat16(bits)).toBeCloseTo(decimal, 4); - } - }); -}); -describe('bitsToFloat32', () => { - it('should convert floating point binary bits to floating point decimal number', () => { - for (let testCaseIndex = 0; testCaseIndex < testCases32Bits.length; testCaseIndex += 1) { - const [decimal, binary] = testCases32Bits[testCaseIndex]; - const bits = binary.split('').map((bitString) => parseInt(bitString, 10)); - expect(bitsToFloat32(bits)).toBeCloseTo(decimal, 7); - } - }); -}); -describe('bitsToFloat64', () => { - it('should convert floating point binary bits to floating point decimal number', () => { - for (let testCaseIndex = 0; testCaseIndex < testCases64Bits.length; testCaseIndex += 1) { - const [decimal, binary] = testCases64Bits[testCaseIndex]; - const bits = binary.split('').map((bitString) => parseInt(bitString, 10)); - expect(bitsToFloat64(bits)).toBeCloseTo(decimal, 14); - } - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/floatAsBinaryString.test.js b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/floatAsBinaryString.test.js deleted file mode 100644 index 805764712c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/__tests__/floatAsBinaryString.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { floatAs32BinaryString, floatAs64BinaryString } from '../floatAsBinaryString'; -import { testCases32Bits, testCases64Bits } from '../testCases'; -describe('floatAs32Binary', () => { - it('should create a binary representation of the floating numbers', () => { - for (let testCaseIndex = 0; testCaseIndex < testCases32Bits.length; testCaseIndex += 1) { - const [decimal, binary] = testCases32Bits[testCaseIndex]; - expect(floatAs32BinaryString(decimal)).toBe(binary); - } - }); -}); -describe('floatAs64Binary', () => { - it('should create a binary representation of the floating numbers', () => { - for (let testCaseIndex = 0; testCaseIndex < testCases64Bits.length; testCaseIndex += 1) { - const [decimal, binary] = testCases64Bits[testCaseIndex]; - expect(floatAs64BinaryString(decimal)).toBe(binary); - } - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/bitsToFloat.js b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/bitsToFloat.js deleted file mode 100644 index 0f6f7de50e..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/bitsToFloat.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Sequence of 0s and 1s. - * @typedef {number[]} Bits - */ -/** - * @typedef {{ - * signBitsCount: number, - * exponentBitsCount: number, - * fractionBitsCount: number, - * }} PrecisionConfig - */ -/** - * @typedef {{ - * half: PrecisionConfig, - * single: PrecisionConfig, - * double: PrecisionConfig - * }} PrecisionConfigs - */ -/** - * ┌───────────────── sign bit - * │ ┌───────────── exponent bits - * │ │ ┌───── fraction bits - * │ │ │ - * X XXXXX XXXXXXXXXX - * - * @type {PrecisionConfigs} - */ -const precisionConfigs = { - // @see: https://en.wikipedia.org/wiki/Half-precision_floating-point_format - half: { - signBitsCount: 1, - exponentBitsCount: 5, - fractionBitsCount: 10 - }, - // @see: https://en.wikipedia.org/wiki/Single-precision_floating-point_format - single: { - signBitsCount: 1, - exponentBitsCount: 8, - fractionBitsCount: 23 - }, - // @see: https://en.wikipedia.org/wiki/Double-precision_floating-point_format - double: { - signBitsCount: 1, - exponentBitsCount: 11, - fractionBitsCount: 52 - } -}; -/** - * Converts the binary representation of the floating point number to decimal float number. - * - * @param {Bits} bits - sequence of bits that represents the floating point number. - * @param {PrecisionConfig} precisionConfig - half/single/double precision config. - * @return {number} - floating point number decoded from its binary representation. - */ -function bitsToFloat(bits, precisionConfig) { - const { signBitsCount, exponentBitsCount } = precisionConfig; - // Figuring out the sign. - const sign = (-1) ** bits[0]; // -1^1 = -1, -1^0 = 1 - // Calculating the exponent value. - const exponentBias = 2 ** (exponentBitsCount - 1) - 1; - const exponentBits = bits.slice(signBitsCount, signBitsCount + exponentBitsCount); - const exponentUnbiased = exponentBits.reduce((exponentSoFar, currentBit, bitIndex) => { - const bitPowerOfTwo = 2 ** (exponentBitsCount - bitIndex - 1); - return exponentSoFar + currentBit * bitPowerOfTwo; - }, 0); - const exponent = exponentUnbiased - exponentBias; - // Calculating the fraction value. - const fractionBits = bits.slice(signBitsCount + exponentBitsCount); - const fraction = fractionBits.reduce((fractionSoFar, currentBit, bitIndex) => { - const bitPowerOfTwo = 2 ** -(bitIndex + 1); - return fractionSoFar + currentBit * bitPowerOfTwo; - }, 0); - // Putting all parts together to calculate the final number. - return sign * 2 ** exponent * (1 + fraction); -} -/** - * Converts the 16-bit binary representation of the floating point number to decimal float number. - * - * @param {Bits} bits - sequence of bits that represents the floating point number. - * @return {number} - floating point number decoded from its binary representation. - */ -export function bitsToFloat16(bits) { - return bitsToFloat(bits, precisionConfigs.half); -} -/** - * Converts the 32-bit binary representation of the floating point number to decimal float number. - * - * @param {Bits} bits - sequence of bits that represents the floating point number. - * @return {number} - floating point number decoded from its binary representation. - */ -export function bitsToFloat32(bits) { - return bitsToFloat(bits, precisionConfigs.single); -} -/** - * Converts the 64-bit binary representation of the floating point number to decimal float number. - * - * @param {Bits} bits - sequence of bits that represents the floating point number. - * @return {number} - floating point number decoded from its binary representation. - */ -export function bitsToFloat64(bits) { - return bitsToFloat(bits, precisionConfigs.double); -} diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/floatAsBinaryString.js b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/floatAsBinaryString.js deleted file mode 100644 index 0af7c287be..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/floatAsBinaryString.js +++ /dev/null @@ -1,51 +0,0 @@ -// @see: https://en.wikipedia.org/wiki/Single-precision_floating-point_format -const singlePrecisionBytesLength = 4; // 32 bits -// @see: https://en.wikipedia.org/wiki/Double-precision_floating-point_format -const doublePrecisionBytesLength = 8; // 64 bits -const bitsInByte = 8; -/** - * Converts the float number into its IEEE 754 binary representation. - * @see: https://en.wikipedia.org/wiki/IEEE_754 - * - * @param {number} floatNumber - float number in decimal format. - * @param {number} byteLength - number of bytes to use to store the float number. - * @return {string} - binary string representation of the float number. - */ -function floatAsBinaryString(floatNumber, byteLength) { - let numberAsBinaryString = ''; - const arrayBuffer = new ArrayBuffer(byteLength); - const dataView = new DataView(arrayBuffer); - const byteOffset = 0; - const littleEndian = false; - if (byteLength === singlePrecisionBytesLength) { - dataView.setFloat32(byteOffset, floatNumber, littleEndian); - } else { - dataView.setFloat64(byteOffset, floatNumber, littleEndian); - } - for (let byteIndex = 0; byteIndex < byteLength; byteIndex += 1) { - let bits = dataView.getUint8(byteIndex).toString(2); - if (bits.length < bitsInByte) { - bits = new Array(bitsInByte - bits.length).fill('0').join('') + bits; - } - numberAsBinaryString += bits; - } - return numberAsBinaryString; -} -/** - * Converts the float number into its IEEE 754 64-bits binary representation. - * - * @param {number} floatNumber - float number in decimal format. - * @return {string} - 64 bits binary string representation of the float number. - */ -export function floatAs64BinaryString(floatNumber) { - return floatAsBinaryString(floatNumber, doublePrecisionBytesLength); -} -/** - * Converts the float number into its IEEE 754 32-bits binary representation. - * - * @param {number} floatNumber - float number in decimal format. - * @return {string} - 32 bits binary string representation of the float number. - */ -export function floatAs32BinaryString(floatNumber) { - return floatAsBinaryString(floatNumber, singlePrecisionBytesLength); -} diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/02-half-precision-floating-point-number-explained.png b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/02-half-precision-floating-point-number-explained.png deleted file mode 100644 index 1bc0a5b835..0000000000 Binary files a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/02-half-precision-floating-point-number-explained.png and /dev/null differ diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/03-scientific-notation.png b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/03-scientific-notation.png deleted file mode 100644 index 449aa6faf5..0000000000 Binary files a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/images/03-scientific-notation.png and /dev/null differ diff --git a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/testCases.js b/docs/content/DS_ALGO/algorithms/math/binary-floating-point/testCases.js deleted file mode 100644 index d354621b88..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/binary-floating-point/testCases.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @typedef {[number, string]} TestCase - * @property {number} decimal - * @property {string} binary - */ -/** - * @type {TestCase[]} - */ -export const testCases16Bits = [ - [-65504, '1111101111111111'], - [-10344, '1111000100001101'], - [-27.15625, '1100111011001010'], - [-1, '1011110000000000'], - [-0.09997558, '1010111001100110'], - [0, '0000000000000000'], - [5.9604644775390625e-8, '0000000000000001'], - [0.000004529, '0000000001001100'], - [0.0999755859375, '0010111001100110'], - [0.199951171875, '0011001001100110'], - [0.300048828125, '0011010011001101'], - [1, '0011110000000000'], - [1.5, '0011111000000000'], - [1.75, '0011111100000000'], - [1.875, '0011111110000000'], - [65504, '0111101111111111'] -]; -/** - * @type {TestCase[]} - */ -export const testCases32Bits = [ - [-3.40282346638528859812e38, '11111111011111111111111111111111'], - [-10345.5595703125, '11000110001000011010011000111101'], - [-27.15625, '11000001110110010100000000000000'], - [-1, '10111111100000000000000000000000'], - [-0.1, '10111101110011001100110011001101'], - [0, '00000000000000000000000000000000'], - [1.40129846432481707092e-45, '00000000000000000000000000000001'], - [0.00000456, '00110110100110010000001000011010'], - [0.1, '00111101110011001100110011001101'], - [0.2, '00111110010011001100110011001101'], - [0.3, '00111110100110011001100110011010'], - [1, '00111111100000000000000000000000'], - [1.5, '00111111110000000000000000000000'], - [1.75, '00111111111000000000000000000000'], - [1.875, '00111111111100000000000000000000'], - [3.40282346638528859812e38, '01111111011111111111111111111111'] -]; -/** - * @type {TestCase[]} - */ -export const testCases64Bits = [ - [-1.79769313486231570815e308, '1111111111101111111111111111111111111111111111111111111111111111'], - [-10345.5595703125, '1100000011000100001101001100011110100000000000000000000000000000'], - [-27.15625, '1100000000111011001010000000000000000000000000000000000000000000'], - [-1, '1011111111110000000000000000000000000000000000000000000000000000'], - [-0.1, '1011111110111001100110011001100110011001100110011001100110011010'], - [0, '0000000000000000000000000000000000000000000000000000000000000000'], - [4.94065645841246544177e-324, '0000000000000000000000000000000000000000000000000000000000000001'], - [0.00000456, '0011111011010011001000000100001101000001011100110011110011100100'], - [0.1, '0011111110111001100110011001100110011001100110011001100110011010'], - [0.2, '0011111111001001100110011001100110011001100110011001100110011010'], - [0.3, '0011111111010011001100110011001100110011001100110011001100110011'], - [1, '0011111111110000000000000000000000000000000000000000000000000000'], - [1.5, '0011111111111000000000000000000000000000000000000000000000000000'], - [1.75, '0011111111111100000000000000000000000000000000000000000000000000'], - [1.875, '0011111111111110000000000000000000000000000000000000000000000000'], - [1.79769313486231570815e308, '0111111111101111111111111111111111111111111111111111111111111111'] -]; diff --git a/docs/content/DS_ALGO/algorithms/math/bits/README.md b/docs/content/DS_ALGO/algorithms/math/bits/README.md deleted file mode 100644 index e3be351398..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/README.md +++ /dev/null @@ -1,272 +0,0 @@ -# Bit Manipulation - -[français](README.fr-FR.md), - -#### Get Bit - -This method shifts the relevant bit to the zeroth position. -Then we perform `AND` operation with one which has bit -pattern like `0001`. This clears all bits from the original -number except the relevant one. If the relevant bit is one, -the result is `1`, otherwise the result is `0`. - -> See [getBit.js](getBit.js) for further details. - -#### Set Bit - -This method shifts `1` over by `bitPosition` bits, creating a -value that looks like `00100`. Then we perform `OR` operation -that sets specific bit into `1` but it does not affect on -other bits of the number. - -> See [setBit.js](setBit.js) for further details. - -#### Clear Bit - -This method shifts `1` over by `bitPosition` bits, creating a -value that looks like `00100`. Than it inverts this mask to get -the number that looks like `11011`. Then `AND` operation is -being applied to both the number and the mask. That operation -unsets the bit. - -> See [clearBit.js](clearBit.js) for further details. - -#### Update Bit - -This method is a combination of "Clear Bit" and "Set Bit" methods. - -> See [updateBit.js](updateBit.js) for further details. - -#### isEven - -This method determines if the number provided is even. -It is based on the fact that odd numbers have their last -right bit to be set to 1. - -```text -Number: 5 = 0b0101 -isEven: false - -Number: 4 = 0b0100 -isEven: true -``` - -> See [isEven.js](isEven.js) for further details. - -#### isPositive - -This method determines if the number is positive. It is based on the fact that all positive -numbers have their leftmost bit to be set to `0`. However, if the number provided is zero -or negative zero, it should still return `false`. - -```text -Number: 1 = 0b0001 -isPositive: true - -Number: -1 = -0b0001 -isPositive: false -``` - -> See [isPositive.js](isPositive.js) for further details. - -#### Multiply By Two - -This method shifts original number by one bit to the left. -Thus all binary number components (powers of two) are being -multiplying by two and thus the number itself is being -multiplied by two. - -``` -Before the shift -Number: 0b0101 = 5 -Powers of two: 0 + 2^2 + 0 + 2^0 - -After the shift -Number: 0b1010 = 10 -Powers of two: 2^3 + 0 + 2^1 + 0 -``` - -> See [multiplyByTwo.js](multiplyByTwo.js) for further details. - -#### Divide By Two - -This method shifts original number by one bit to the right. -Thus all binary number components (powers of two) are being -divided by two and thus the number itself is being -divided by two without remainder. - -``` -Before the shift -Number: 0b0101 = 5 -Powers of two: 0 + 2^2 + 0 + 2^0 - -After the shift -Number: 0b0010 = 2 -Powers of two: 0 + 0 + 2^1 + 0 -``` - -> See [divideByTwo.js](divideByTwo.js) for further details. - -#### Switch Sign - -This method make positive numbers to be negative and backwards. -To do so it uses "Twos Complement" approach which does it by -inverting all of the bits of the number and adding 1 to it. - -``` -1101 -3 -1110 -2 -1111 -1 -0000 0 -0001 1 -0010 2 -0011 3 -``` - -> See [switchSign.js](switchSign.js) for further details. - -#### Multiply Two Signed Numbers - -This method multiplies two signed integer numbers using bitwise operators. -This method is based on the following facts: - -```text -a * b can be written in the below formats: - 0 if a is zero or b is zero or both a and b are zeroes - 2a * (b/2) if b is even - 2a * (b - 1)/2 + a if b is odd and positive - 2a * (b + 1)/2 - a if b is odd and negative -``` - -The advantage of this approach is that in each recursive step one of the operands -reduces to half its original value. Hence, the run time complexity is `O(log(b))` where `b` is -the operand that reduces to half on each recursive step. - -> See [multiply.js](multiply.js) for further details. - -#### Multiply Two Unsigned Numbers - -This method multiplies two integer numbers using bitwise operators. -This method is based on that "Every number can be denoted as the sum of powers of 2". - -The main idea of bitwise multiplication is that every number may be split -to the sum of powers of two: - -I.e. - -```text -19 = 2^4 + 2^1 + 2^0 -``` - -Then multiplying number `x` by `19` is equivalent of: - -```text -x * 19 = x * 2^4 + x * 2^1 + x * 2^0 -``` - -Now we need to remember that `x * 2^4` is equivalent of shifting `x` left -by `4` bits (`x << 4`). - -> See [multiplyUnsigned.js](multiplyUnsigned.js) for further details. - -#### Count Set Bits - -This method counts the number of set bits in a number using bitwise operators. -The main idea is that we shift the number right by one bit at a time and check -the result of `&` operation that is `1` if bit is set and `0` otherwise. - -```text -Number: 5 = 0b0101 -Count of set bits = 2 -``` - -> See [countSetBits.js](countSetBits.js) for further details. - -#### Count Bits to Flip One Number to Another - -This methods outputs the number of bits required to convert one number to another. -This makes use of property that when numbers are `XOR`-ed the result will be number -of different bits. - -``` -5 = 0b0101 -1 = 0b0001 -Count of Bits to be Flipped: 1 -``` - -> See [bitsDiff.js](bitsDiff.js) for further details. - -#### Count Bits of a Number - -To calculate the number of valuable bits we need to shift `1` one bit left each -time and see if shifted number is bigger than the input number. - -``` -5 = 0b0101 -Count of valuable bits is: 3 -When we shift 1 four times it will become bigger than 5. -``` - -> See [bitLength.js](bitLength.js) for further details. - -#### Is Power of Two - -This method checks if a number provided is power of two. It uses the following -property. Let's say that `powerNumber` is a number that has been formed as a power -of two (i.e. 2, 4, 8, 16 etc.). Then if we'll do `&` operation between `powerNumber` -and `powerNumber - 1` it will return `0` (in case if number is power of two). - -``` -Number: 4 = 0b0100 -Number: 3 = (4 - 1) = 0b0011 -4 & 3 = 0b0100 & 0b0011 = 0b0000 <-- Equal to zero, is power of two. - -Number: 10 = 0b01010 -Number: 9 = (10 - 1) = 0b01001 -10 & 9 = 0b01010 & 0b01001 = 0b01000 <-- Not equal to zero, not a power of two. -``` - -> See [isPowerOfTwo.js](isPowerOfTwo.js) for further details. - -#### Full Adder - -This method adds up two integer numbers using bitwise operators. - -It implements [full adder]() -electronics circuit logic to sum two 32-bit integers in two's complement format. -It's using the boolean logic to cover all possible cases of adding two input bits: -with and without a "carry bit" from adding the previous less-significant stage. - -Legend: - -- `A`: Number `A` -- `B`: Number `B` -- `ai`: ith bit of number `A` -- `bi`: ith bit of number `B` -- `carryIn`: a bit carried in from the previous less-significant stage -- `carryOut`: a bit to carry to the next most-significant stage -- `bitSum`: The sum of `ai`, `bi`, and `carryIn` -- `resultBin`: The full result of adding current stage with all less-significant stages (in binary) -- `resultDec`: The full result of adding current stage with all less-significant stages (in decimal) - -``` -A = 3: 011 -B = 6: 110 -┌──────┬────┬────┬─────────┬──────────┬─────────┬───────────┬───────────┐ -│ bit │ ai │ bi │ carryIn │ carryOut │ bitSum │ resultBin │ resultDec │ -├──────┼────┼────┼─────────┼──────────┼─────────┼───────────┼───────────┤ -│ 0 │ 1 │ 0 │ 0 │ 0 │ 1 │ 1 │ 1 │ -│ 1 │ 1 │ 1 │ 0 │ 1 │ 0 │ 01 │ 1 │ -│ 2 │ 0 │ 1 │ 1 │ 1 │ 0 │ 001 │ 1 │ -│ 3 │ 0 │ 0 │ 1 │ 0 │ 1 │ 1001 │ 9 │ -└──────┴────┴────┴─────────┴──────────┴─────────┴───────────┴───────────┘ -``` - -> See [fullAdder.js](fullAdder.js) for further details. -> See [Full Adder on YouTube](https://www.youtube.com/watch?v=wvJc9CZcvBc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8). - -## References - -- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Negative Numbers in binary on YouTube](https://www.youtube.com/watch?v=4qH4unVtJkE&t=0s&index=30&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Bit Hacks on stanford.edu](https://graphics.stanford.edu/~seander/bithacks.html) diff --git a/docs/content/DS_ALGO/algorithms/math/bits/bitLength.js b/docs/content/DS_ALGO/algorithms/math/bits/bitLength.js deleted file mode 100644 index 7dc66a7222..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/bitLength.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Return the number of bits used in the binary representation of the number. - * - * @param {number} number - * @return {number} - */ -export default function bitLength(number) { - let bitsCounter = 0; - while (1 << bitsCounter <= number) { - bitsCounter += 1; - } - return bitsCounter; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/bitsDiff.js b/docs/content/DS_ALGO/algorithms/math/bits/bitsDiff.js deleted file mode 100644 index 57b3f73208..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/bitsDiff.js +++ /dev/null @@ -1,12 +0,0 @@ -import countSetBits from './countSetBits'; -/** - * Counts the number of bits that need to be change in order - * to convert numberA to numberB. - * - * @param {number} numberA - * @param {number} numberB - * @return {number} - */ -export default function bitsDiff(numberA, numberB) { - return countSetBits(numberA ^ numberB); -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/clearBit.js b/docs/content/DS_ALGO/algorithms/math/bits/clearBit.js deleted file mode 100644 index 5a6cecade0..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/clearBit.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @param {number} number - * @param {number} bitPosition - zero based. - * @return {number} - */ -export default function clearBit(number, bitPosition) { - const mask = ~(1 << bitPosition); - return number & mask; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/countSetBits.js b/docs/content/DS_ALGO/algorithms/math/bits/countSetBits.js deleted file mode 100644 index 4b7c0dae80..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/countSetBits.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @param {number} originalNumber - * @return {number} - */ -export default function countSetBits(originalNumber) { - let setBitsCount = 0; - let number = originalNumber; - while (number) { - // Add last bit of the number to the sum of set bits. - setBitsCount += number & 1; - // Shift number right by one bit to investigate other bits. - number >>>= 1; - } - return setBitsCount; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/divideByTwo.js b/docs/content/DS_ALGO/algorithms/math/bits/divideByTwo.js deleted file mode 100644 index 0b14d522f9..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/divideByTwo.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} number - * @return {number} - */ -export default function divideByTwo(number) { - return number >> 1; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/fullAdder.js b/docs/content/DS_ALGO/algorithms/math/bits/fullAdder.js deleted file mode 100644 index 4ca9a536f9..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/fullAdder.js +++ /dev/null @@ -1,63 +0,0 @@ -import getBit from './getBit'; -/** - * Add two numbers using only binary operators. - * - * This is an implementation of full adders logic circuit. - * https://en.wikipedia.org/wiki/Adder_(electronics) - * Inspired by: https://www.youtube.com/watch?v=wvJc9CZcvBc - * - * Table(1) - * INPUT | OUT - * C Ai Bi | C Si | Row - * -------- | -----| --- - * 0 0 0 | 0 0 | 1 - * 0 0 1 | 0 1 | 2 - * 0 1 0 | 0 1 | 3 - * 0 1 1 | 1 0 | 4 - * -------- | ---- | -- - * 1 0 0 | 0 1 | 5 - * 1 0 1 | 1 0 | 6 - * 1 1 0 | 1 0 | 7 - * 1 1 1 | 1 1 | 8 - * --------------------- - * - * Legend: - * INPUT C = Carry in, from the previous less-significant stage - * INPUT Ai = ith bit of Number A - * INPUT Bi = ith bit of Number B - * OUT C = Carry out to the next most-significant stage - * OUT Si = Bit Sum, ith least significant bit of the result - * - * - * @param {number} a - * @param {number} b - * @return {number} - */ -export default function fullAdder(a, b) { - let result = 0; - let carry = 0; - // The operands of all bitwise operators are converted to signed - // 32-bit integers in two's complement format. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers - for (let i = 0; i < 32; i += 1) { - const ai = getBit(a, i); - const bi = getBit(b, i); - const carryIn = carry; - // Calculate binary Ai + Bi without carry (half adder) - // See Table(1) rows 1 - 4: Si = Ai ^ Bi - const aiPlusBi = ai ^ bi; - // Calculate ith bit of the result by adding the carry bit to Ai + Bi - // For Table(1) rows 5 - 8 carryIn = 1: Si = Ai ^ Bi ^ 1, flip the bit - // Fpr Table(1) rows 1 - 4 carryIn = 0: Si = Ai ^ Bi ^ 0, a no-op. - const bitSum = aiPlusBi ^ carryIn; - // Carry out one to the next most-significant stage - // when at least one of these is true: - // 1) Table(1) rows 6, 7: one of Ai OR Bi is 1 AND carryIn = 1 - // 2) Table(1) rows 4, 8: Both Ai AND Bi are 1 - const carryOut = (aiPlusBi & carryIn) | (ai & bi); - carry = carryOut; - // Set ith least significant bit of the result to bitSum. - result |= bitSum << i; - } - return result; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/getBit.js b/docs/content/DS_ALGO/algorithms/math/bits/getBit.js deleted file mode 100644 index 74e1c9c35c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/getBit.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @param {number} number - * @param {number} bitPosition - zero based. - * @return {number} - */ -export default function getBit(number, bitPosition) { - return (number >> bitPosition) & 1; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/isEven.js b/docs/content/DS_ALGO/algorithms/math/bits/isEven.js deleted file mode 100644 index c9455f3b46..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/isEven.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} number - * @return {boolean} - */ -export default function isEven(number) { - return (number & 1) === 0; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/isPositive.js b/docs/content/DS_ALGO/algorithms/math/bits/isPositive.js deleted file mode 100644 index b83f449304..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/isPositive.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @param {number} number - 32-bit integer. - * @return {boolean} - */ -export default function isPositive(number) { - // Zero is neither a positive nor a negative number. - if (number === 0) { - return false; - } - // The most significant 32nd bit can be used to determine whether the number is positive. - return ((number >> 31) & 1) === 0; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/isPowerOfTwo.js b/docs/content/DS_ALGO/algorithms/math/bits/isPowerOfTwo.js deleted file mode 100644 index 3254876d7b..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/isPowerOfTwo.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} number - * @return bool - */ -export default function isPowerOfTwo(number) { - return (number & (number - 1)) === 0; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/multiply.js b/docs/content/DS_ALGO/algorithms/math/bits/multiply.js deleted file mode 100644 index 1945290af8..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/multiply.js +++ /dev/null @@ -1,37 +0,0 @@ -import multiplyByTwo from './multiplyByTwo'; -import divideByTwo from './divideByTwo'; -import isEven from './isEven'; -import isPositive from './isPositive'; -/** - * Multiply two signed numbers using bitwise operations. - * - * If a is zero or b is zero or if both a and b are zeros: - * multiply(a, b) = 0 - * - * If b is even: - * multiply(a, b) = multiply(2a, b/2) - * - * If b is odd and b is positive: - * multiply(a, b) = multiply(2a, (b-1)/2) + a - * - * If b is odd and b is negative: - * multiply(a, b) = multiply(2a, (b+1)/2) - a - * - * Time complexity: O(log b) - * - * @param {number} a - * @param {number} b - * @return {number} - */ -export default function multiply(a, b) { - // If a is zero or b is zero or if both a and b are zeros then the production is also zero. - if (b === 0 || a === 0) { - return 0; - } - // Otherwise we will have four different cases that are described above. - const multiplyByOddPositive = () => multiply(multiplyByTwo(a), divideByTwo(b - 1)) + a; - const multiplyByOddNegative = () => multiply(multiplyByTwo(a), divideByTwo(b + 1)) - a; - const multiplyByEven = () => multiply(multiplyByTwo(a), divideByTwo(b)); - const multiplyByOdd = () => (isPositive(b) ? multiplyByOddPositive() : multiplyByOddNegative()); - return isEven(b) ? multiplyByEven() : multiplyByOdd(); -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/multiplyByTwo.js b/docs/content/DS_ALGO/algorithms/math/bits/multiplyByTwo.js deleted file mode 100644 index 5f16df3dd7..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/multiplyByTwo.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} number - * @return {number} - */ -export default function multiplyByTwo(number) { - return number << 1; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/multiplyUnsigned.js b/docs/content/DS_ALGO/algorithms/math/bits/multiplyUnsigned.js deleted file mode 100644 index 8f6b9e3909..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/multiplyUnsigned.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Multiply to unsigned numbers using bitwise operator. - * - * The main idea of bitwise multiplication is that every number may be split - * to the sum of powers of two: - * - * I.e. 19 = 2^4 + 2^1 + 2^0 - * - * Then multiplying number x by 19 is equivalent of: - * - * x * 19 = x * 2^4 + x * 2^1 + x * 2^0 - * - * Now we need to remember that (x * 2^4) is equivalent of shifting x left by 4 bits (x << 4). - * - * @param {number} number1 - * @param {number} number2 - * @return {number} - */ -export default function multiplyUnsigned(number1, number2) { - let result = 0; - // Let's treat number2 as a multiplier for the number1. - let multiplier = number2; - // Multiplier current bit index. - let bitIndex = 0; - // Go through all bits of number2. - while (multiplier !== 0) { - // Check if current multiplier bit is set. - if (multiplier & 1) { - // In case if multiplier's bit at position bitIndex is set - // it would mean that we need to multiply number1 by the power - // of bit with index bitIndex and then add it to the result. - result += number1 << bitIndex; - } - bitIndex += 1; - multiplier >>= 1; - } - return result; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/setBit.js b/docs/content/DS_ALGO/algorithms/math/bits/setBit.js deleted file mode 100644 index d9b880f581..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/setBit.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @param {number} number - * @param {number} bitPosition - zero based. - * @return {number} - */ -export default function setBit(number, bitPosition) { - return number | (1 << bitPosition); -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/switchSign.js b/docs/content/DS_ALGO/algorithms/math/bits/switchSign.js deleted file mode 100644 index 26c7845ffe..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/switchSign.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Switch the sign of the number using "Twos Complement" approach. - * @param {number} number - * @return {number} - */ -export default function switchSign(number) { - return ~number + 1; -} diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/bitLength.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/bitLength.test.js deleted file mode 100644 index 0053e96401..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/bitLength.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import bitLength from '../bitLength'; -describe('bitLength', () => { - it('should calculate number of bits that the number is consists of', () => { - expect(bitLength(0b0)).toBe(0); - expect(bitLength(0b1)).toBe(1); - expect(bitLength(0b01)).toBe(1); - expect(bitLength(0b101)).toBe(3); - expect(bitLength(0b0101)).toBe(3); - expect(bitLength(0b10101)).toBe(5); - expect(bitLength(0b11110101)).toBe(8); - expect(bitLength(0b00011110101)).toBe(8); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/bitsDiff.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/bitsDiff.test.js deleted file mode 100644 index e923d3e145..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/bitsDiff.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import bitsDiff from '../bitsDiff'; -describe('bitsDiff', () => { - it('should calculate bits difference between two numbers', () => { - expect(bitsDiff(0, 0)).toBe(0); - expect(bitsDiff(1, 1)).toBe(0); - expect(bitsDiff(124, 124)).toBe(0); - expect(bitsDiff(0, 1)).toBe(1); - expect(bitsDiff(1, 0)).toBe(1); - expect(bitsDiff(1, 2)).toBe(2); - expect(bitsDiff(1, 3)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/clearBit.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/clearBit.test.js deleted file mode 100644 index 3db71abad1..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/clearBit.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import clearBit from '../clearBit'; -describe('clearBit', () => { - it('should clear bit at specific position', () => { - // 1 = 0b0001 - expect(clearBit(1, 0)).toBe(0); - expect(clearBit(1, 1)).toBe(1); - expect(clearBit(1, 2)).toBe(1); - // 10 = 0b1010 - expect(clearBit(10, 0)).toBe(10); - expect(clearBit(10, 1)).toBe(8); - expect(clearBit(10, 3)).toBe(2); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/countSetBits.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/countSetBits.test.js deleted file mode 100644 index 5f726b506c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/countSetBits.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import countSetBits from '../countSetBits'; -describe('countSetBits', () => { - it('should return number of set bits', () => { - expect(countSetBits(0)).toBe(0); - expect(countSetBits(1)).toBe(1); - expect(countSetBits(2)).toBe(1); - expect(countSetBits(3)).toBe(2); - expect(countSetBits(4)).toBe(1); - expect(countSetBits(5)).toBe(2); - expect(countSetBits(21)).toBe(3); - expect(countSetBits(255)).toBe(8); - expect(countSetBits(1023)).toBe(10); - expect(countSetBits(-1)).toBe(32); - expect(countSetBits(-21)).toBe(30); - expect(countSetBits(-255)).toBe(25); - expect(countSetBits(-1023)).toBe(23); - expect(countSetBits(-4294967296)).toBe(0); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/divideByTwo.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/divideByTwo.test.js deleted file mode 100644 index 9a2cca06dd..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/divideByTwo.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import divideByTwo from '../divideByTwo'; -describe('divideByTwo', () => { - it('should divide numbers by two using bitwise operations', () => { - expect(divideByTwo(0)).toBe(0); - expect(divideByTwo(1)).toBe(0); - expect(divideByTwo(3)).toBe(1); - expect(divideByTwo(10)).toBe(5); - expect(divideByTwo(17)).toBe(8); - expect(divideByTwo(125)).toBe(62); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/fullAdder.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/fullAdder.test.js deleted file mode 100644 index 01a3239e51..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/fullAdder.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import fullAdder from '../fullAdder'; -describe('fullAdder', () => { - it('should add up two numbers', () => { - expect(fullAdder(0, 0)).toBe(0); - expect(fullAdder(2, 0)).toBe(2); - expect(fullAdder(0, 2)).toBe(2); - expect(fullAdder(1, 2)).toBe(3); - expect(fullAdder(2, 1)).toBe(3); - expect(fullAdder(6, 6)).toBe(12); - expect(fullAdder(-2, 4)).toBe(2); - expect(fullAdder(4, -2)).toBe(2); - expect(fullAdder(-4, -4)).toBe(-8); - expect(fullAdder(4, -5)).toBe(-1); - expect(fullAdder(2, 121)).toBe(123); - expect(fullAdder(121, 2)).toBe(123); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/getBit.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/getBit.test.js deleted file mode 100644 index 6a4c56481c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/getBit.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import getBit from '../getBit'; -describe('getBit', () => { - it('should get bit at specific position', () => { - // 1 = 0b0001 - expect(getBit(1, 0)).toBe(1); - expect(getBit(1, 1)).toBe(0); - // 2 = 0b0010 - expect(getBit(2, 0)).toBe(0); - expect(getBit(2, 1)).toBe(1); - // 3 = 0b0011 - expect(getBit(3, 0)).toBe(1); - expect(getBit(3, 1)).toBe(1); - // 10 = 0b1010 - expect(getBit(10, 0)).toBe(0); - expect(getBit(10, 1)).toBe(1); - expect(getBit(10, 2)).toBe(0); - expect(getBit(10, 3)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/isEven.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/isEven.test.js deleted file mode 100644 index 88b45226ea..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/isEven.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import isEven from '../isEven'; -describe('isEven', () => { - it('should detect if a number is even', () => { - expect(isEven(0)).toBe(true); - expect(isEven(2)).toBe(true); - expect(isEven(-2)).toBe(true); - expect(isEven(1)).toBe(false); - expect(isEven(-1)).toBe(false); - expect(isEven(-3)).toBe(false); - expect(isEven(3)).toBe(false); - expect(isEven(8)).toBe(true); - expect(isEven(9)).toBe(false); - expect(isEven(121)).toBe(false); - expect(isEven(122)).toBe(true); - expect(isEven(1201)).toBe(false); - expect(isEven(1202)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/isPositive.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/isPositive.test.js deleted file mode 100644 index 3ffdd2471a..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/isPositive.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import isPositive from '../isPositive'; -describe('isPositive', () => { - it('should detect if a number is positive', () => { - expect(isPositive(1)).toBe(true); - expect(isPositive(2)).toBe(true); - expect(isPositive(3)).toBe(true); - expect(isPositive(5665)).toBe(true); - expect(isPositive(56644325)).toBe(true); - expect(isPositive(0)).toBe(false); - expect(isPositive(-0)).toBe(false); - expect(isPositive(-1)).toBe(false); - expect(isPositive(-2)).toBe(false); - expect(isPositive(-126)).toBe(false); - expect(isPositive(-5665)).toBe(false); - expect(isPositive(-56644325)).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/isPowerOfTwo.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/isPowerOfTwo.test.js deleted file mode 100644 index 4a7b375c19..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/isPowerOfTwo.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import isPowerOfTwo from '../isPowerOfTwo'; -describe('isPowerOfTwo', () => { - it('should detect if the number is power of two', () => { - expect(isPowerOfTwo(1)).toBe(true); - expect(isPowerOfTwo(2)).toBe(true); - expect(isPowerOfTwo(3)).toBe(false); - expect(isPowerOfTwo(4)).toBe(true); - expect(isPowerOfTwo(5)).toBe(false); - expect(isPowerOfTwo(6)).toBe(false); - expect(isPowerOfTwo(7)).toBe(false); - expect(isPowerOfTwo(8)).toBe(true); - expect(isPowerOfTwo(9)).toBe(false); - expect(isPowerOfTwo(16)).toBe(true); - expect(isPowerOfTwo(23)).toBe(false); - expect(isPowerOfTwo(32)).toBe(true); - expect(isPowerOfTwo(127)).toBe(false); - expect(isPowerOfTwo(128)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/multiply.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/multiply.test.js deleted file mode 100644 index fb691b8a2d..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/multiply.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import multiply from '../multiply'; -describe('multiply', () => { - it('should multiply two numbers', () => { - expect(multiply(0, 0)).toBe(0); - expect(multiply(2, 0)).toBe(0); - expect(multiply(0, 2)).toBe(0); - expect(multiply(1, 2)).toBe(2); - expect(multiply(2, 1)).toBe(2); - expect(multiply(6, 6)).toBe(36); - expect(multiply(-2, 4)).toBe(-8); - expect(multiply(4, -2)).toBe(-8); - expect(multiply(-4, -4)).toBe(16); - expect(multiply(4, -5)).toBe(-20); - expect(multiply(2, 121)).toBe(242); - expect(multiply(121, 2)).toBe(242); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyByTwo.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyByTwo.test.js deleted file mode 100644 index 52a4ea66fe..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyByTwo.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import multiplyByTwo from '../multiplyByTwo'; -describe('multiplyByTwo', () => { - it('should multiply numbers by two using bitwise operations', () => { - expect(multiplyByTwo(0)).toBe(0); - expect(multiplyByTwo(1)).toBe(2); - expect(multiplyByTwo(3)).toBe(6); - expect(multiplyByTwo(10)).toBe(20); - expect(multiplyByTwo(17)).toBe(34); - expect(multiplyByTwo(125)).toBe(250); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyUnsigned.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyUnsigned.test.js deleted file mode 100644 index 3952a30e56..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/multiplyUnsigned.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import multiplyUnsigned from '../multiplyUnsigned'; -describe('multiplyUnsigned', () => { - it('should multiply two unsigned numbers', () => { - expect(multiplyUnsigned(0, 2)).toBe(0); - expect(multiplyUnsigned(2, 0)).toBe(0); - expect(multiplyUnsigned(1, 1)).toBe(1); - expect(multiplyUnsigned(1, 2)).toBe(2); - expect(multiplyUnsigned(2, 7)).toBe(14); - expect(multiplyUnsigned(7, 2)).toBe(14); - expect(multiplyUnsigned(30, 2)).toBe(60); - expect(multiplyUnsigned(17, 34)).toBe(578); - expect(multiplyUnsigned(170, 2340)).toBe(397800); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/setBit.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/setBit.test.js deleted file mode 100644 index 71239ecd6f..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/setBit.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import setBit from '../setBit'; -describe('setBit', () => { - it('should set bit at specific position', () => { - // 1 = 0b0001 - expect(setBit(1, 0)).toBe(1); - expect(setBit(1, 1)).toBe(3); - expect(setBit(1, 2)).toBe(5); - // 10 = 0b1010 - expect(setBit(10, 0)).toBe(11); - expect(setBit(10, 1)).toBe(10); - expect(setBit(10, 2)).toBe(14); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/switchSign.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/switchSign.test.js deleted file mode 100644 index a317cc2877..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/switchSign.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import switchSign from '../switchSign'; -describe('switchSign', () => { - it('should switch the sign of the number using twos complement approach', () => { - expect(switchSign(0)).toBe(0); - expect(switchSign(1)).toBe(-1); - expect(switchSign(-1)).toBe(1); - expect(switchSign(32)).toBe(-32); - expect(switchSign(-32)).toBe(32); - expect(switchSign(23)).toBe(-23); - expect(switchSign(-23)).toBe(23); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/test/updateBit.test.js b/docs/content/DS_ALGO/algorithms/math/bits/test/updateBit.test.js deleted file mode 100644 index 186558982d..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/test/updateBit.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import updateBit from '../updateBit'; -describe('updateBit', () => { - it('should update bit at specific position', () => { - // 1 = 0b0001 - expect(updateBit(1, 0, 1)).toBe(1); - expect(updateBit(1, 0, 0)).toBe(0); - expect(updateBit(1, 1, 1)).toBe(3); - expect(updateBit(1, 2, 1)).toBe(5); - // 10 = 0b1010 - expect(updateBit(10, 0, 1)).toBe(11); - expect(updateBit(10, 0, 0)).toBe(10); - expect(updateBit(10, 1, 1)).toBe(10); - expect(updateBit(10, 1, 0)).toBe(8); - expect(updateBit(10, 2, 1)).toBe(14); - expect(updateBit(10, 2, 0)).toBe(10); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/bits/updateBit.js b/docs/content/DS_ALGO/algorithms/math/bits/updateBit.js deleted file mode 100644 index f634d0c351..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/bits/updateBit.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @param {number} number - * @param {number} bitPosition - zero based. - * @param {number} bitValue - 0 or 1. - * @return {number} - */ -export default function updateBit(number, bitPosition, bitValue) { - // Normalized bit value. - const bitValueNormalized = bitValue ? 1 : 0; - // Init clear mask. - const clearMask = ~(1 << bitPosition); - // Clear bit value and then set it up to required value. - return (number & clearMask) | (bitValueNormalized << bitPosition); -} diff --git a/docs/content/DS_ALGO/algorithms/math/complex-number/ComplexNumber.js b/docs/content/DS_ALGO/algorithms/math/complex-number/ComplexNumber.js deleted file mode 100644 index c173fcc83c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/complex-number/ComplexNumber.js +++ /dev/null @@ -1,138 +0,0 @@ -import radianToDegree from '../radian/radianToDegree'; -export default class ComplexNumber { - /** - * z = re + im * i - * z = radius * e^(i * phase) - * - * @param {number} [re] - * @param {number} [im] - */ - constructor({ re = 0, im = 0 } = {}) { - this.re = re; - this.im = im; - } - /** - * @param {ComplexNumber|number} addend - * @return {ComplexNumber} - */ - add(addend) { - // Make sure we're dealing with complex number. - const complexAddend = this.toComplexNumber(addend); - return new ComplexNumber({ - re: this.re + complexAddend.re, - im: this.im + complexAddend.im - }); - } - /** - * @param {ComplexNumber|number} subtrahend - * @return {ComplexNumber} - */ - subtract(subtrahend) { - // Make sure we're dealing with complex number. - const complexSubtrahend = this.toComplexNumber(subtrahend); - return new ComplexNumber({ - re: this.re - complexSubtrahend.re, - im: this.im - complexSubtrahend.im - }); - } - /** - * @param {ComplexNumber|number} multiplicand - * @return {ComplexNumber} - */ - multiply(multiplicand) { - // Make sure we're dealing with complex number. - const complexMultiplicand = this.toComplexNumber(multiplicand); - return new ComplexNumber({ - re: this.re * complexMultiplicand.re - this.im * complexMultiplicand.im, - im: this.re * complexMultiplicand.im + this.im * complexMultiplicand.re - }); - } - /** - * @param {ComplexNumber|number} divider - * @return {ComplexNumber} - */ - divide(divider) { - // Make sure we're dealing with complex number. - const complexDivider = this.toComplexNumber(divider); - // Get divider conjugate. - const dividerConjugate = this.conjugate(complexDivider); - // Multiply dividend by divider's conjugate. - const finalDivident = this.multiply(dividerConjugate); - // Calculating final divider using formula (a + bi)(a − bi) = a^2 + b^2 - const finalDivider = complexDivider.re ** 2 + complexDivider.im ** 2; - return new ComplexNumber({ - re: finalDivident.re / finalDivider, - im: finalDivident.im / finalDivider - }); - } - /** - * @param {ComplexNumber|number} number - */ - conjugate(number) { - // Make sure we're dealing with complex number. - const complexNumber = this.toComplexNumber(number); - return new ComplexNumber({ - re: complexNumber.re, - im: -1 * complexNumber.im - }); - } - /** - * @return {number} - */ - getRadius() { - return Math.sqrt(this.re ** 2 + this.im ** 2); - } - /** - * @param {boolean} [inRadians] - * @return {number} - */ - getPhase(inRadians = true) { - let phase = Math.atan(Math.abs(this.im) / Math.abs(this.re)); - if (this.re < 0 && this.im > 0) { - phase = Math.PI - phase; - } else if (this.re < 0 && this.im < 0) { - phase = -(Math.PI - phase); - } else if (this.re > 0 && this.im < 0) { - phase = -phase; - } else if (this.re === 0 && this.im > 0) { - phase = Math.PI / 2; - } else if (this.re === 0 && this.im < 0) { - phase = -Math.PI / 2; - } else if (this.re < 0 && this.im === 0) { - phase = Math.PI; - } else if (this.re > 0 && this.im === 0) { - phase = 0; - } else if (this.re === 0 && this.im === 0) { - // More correctly would be to set 'indeterminate'. - // But just for simplicity reasons let's set zero. - phase = 0; - } - if (!inRadians) { - phase = radianToDegree(phase); - } - return phase; - } - /** - * @param {boolean} [inRadians] - * @return {{radius: number, phase: number}} - */ - getPolarForm(inRadians = true) { - return { - radius: this.getRadius(), - phase: this.getPhase(inRadians) - }; - } - /** - * Convert real numbers to complex number. - * In case if complex number is provided then lefts it as is. - * - * @param {ComplexNumber|number} number - * @return {ComplexNumber} - */ - toComplexNumber(number) { - if (number instanceof ComplexNumber) { - return number; - } - return new ComplexNumber({ re: number }); - } -} diff --git a/docs/content/DS_ALGO/algorithms/math/complex-number/README.md b/docs/content/DS_ALGO/algorithms/math/complex-number/README.md deleted file mode 100644 index 916d276c11..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/complex-number/README.md +++ /dev/null @@ -1,227 +0,0 @@ -# Complex Number - -[français](README.fr-FR.md). - -A **complex number** is a number that can be expressed in the -form `a + b * i`, where `a` and `b` are real numbers, and `i` is a solution of -the equation `x^2 = −1`. Because no _real number_ satisfies this -equation, `i` is called an _imaginary number_. For the complex -number `a + b * i`, `a` is called the _real part_, and `b` is called -the _imaginary part_. - -![Complex Number](https://www.mathsisfun.com/numbers/images/complex-example.svg) - -A Complex Number is a combination of a Real Number and an Imaginary Number: - -![Complex Number](https://www.mathsisfun.com/numbers/images/complex-number.svg) - -Geometrically, complex numbers extend the concept of the one-dimensional number -line to the _two-dimensional complex plane_ by using the horizontal axis for the -real part and the vertical axis for the imaginary part. The complex -number `a + b * i` can be identified with the point `(a, b)` in the complex plane. - -A complex number whose real part is zero is said to be _purely imaginary_; the -points for these numbers lie on the vertical axis of the complex plane. A complex -number whose imaginary part is zero can be viewed as a _real number_; its point -lies on the horizontal axis of the complex plane. - -| Complex Number | Real Part | Imaginary Part | | -| :------------- | :-------: | :------------: | ---------------- | -| 3 + 2i | 3 | 2 | | -| 5 | 5 | **0** | Purely Real | -| −6i | **0** | -6 | Purely Imaginary | - -A complex number can be visually represented as a pair of numbers `(a, b)` forming -a vector on a diagram called an _Argand diagram_, representing the _complex plane_. -`Re` is the real axis, `Im` is the imaginary axis, and `i` satisfies `i^2 = −1`. - -![Complex Number](https://upload.wikimedia.org/wikipedia/commons/a/af/Complex_number_illustration.svg) - -> Complex does not mean complicated. It means the two types of numbers, real and -> imaginary, together form a complex, just like a building complex (buildings -> joined together). - -## Polar Form - -An alternative way of defining a point `P` in the complex plane, other than using -the x- and y-coordinates, is to use the distance of the point from `O`, the point -whose coordinates are `(0, 0)` (the origin), together with the angle subtended -between the positive real axis and the line segment `OP` in a counterclockwise -direction. This idea leads to the polar form of complex numbers. - -![Polar Form](https://upload.wikimedia.org/wikipedia/commons/7/7a/Complex_number_illustration_modarg.svg) - -The _absolute value_ (or modulus or magnitude) of a complex number `z = x + yi` is: - -![Radius](https://wikimedia.org/api/rest_v1/media/math/render/svg/b59629c801aa0ddcdf17ee489e028fb9f8d4ea75) - -The argument of `z` (in many applications referred to as the "phase") is the angle -of the radius `OP` with the positive real axis, and is written as `arg(z)`. As -with the modulus, the argument can be found from the rectangular form `x+yi`: - -![Phase](https://wikimedia.org/api/rest_v1/media/math/render/svg/7cbbdd9bb1dd5df86dd2b820b20f82995023e566) - -Together, `r` and `φ` give another way of representing complex numbers, the -polar form, as the combination of modulus and argument fully specify the -position of a point on the plane. Recovering the original rectangular -co-ordinates from the polar form is done by the formula called trigonometric -form: - -![Polar Form](https://wikimedia.org/api/rest_v1/media/math/render/svg/b03de1e1b7b049880b5e4870b68a57bc180ff6ce) - -Using Euler's formula this can be written as: - -![Euler's Form](https://wikimedia.org/api/rest_v1/media/math/render/svg/0a087c772212e7375cb321d83fc1fcc715cd0ed2) - -## Basic Operations - -### Adding - -To add two complex numbers we add each part separately: - -```text -(a + b * i) + (c + d * i) = (a + c) + (b + d) * i -``` - -**Example** - -```text -(3 + 5i) + (4 − 3i) = (3 + 4) + (5 − 3)i = 7 + 2i -``` - -On complex plane the adding operation will look like the following: - -![Complex Addition](https://www.mathsisfun.com/algebra/images/complex-plane-vector-add.svg) - -### Subtracting - -To subtract two complex numbers we subtract each part separately: - -```text -(a + b * i) - (c + d * i) = (a - c) + (b - d) * i -``` - -**Example** - -```text -(3 + 5i) - (4 − 3i) = (3 - 4) + (5 + 3)i = -1 + 8i -``` - -### Multiplying - -To multiply complex numbers each part of the first complex number gets multiplied -by each part of the second complex number: - -Just use "FOIL", which stands for "**F**irsts, **O**uters, **I**nners, **L**asts" ( -see [Binomial Multiplication](ttps://www.mathsisfun.com/algebra/polynomials-multiplying.html) for -more details): - -![Complex Multiplication](https://www.mathsisfun.com/algebra/images/foil-complex.svg) - -- Firsts: `a × c` -- Outers: `a × di` -- Inners: `bi × c` -- Lasts: `bi × di` - -In general it looks like this: - -```text -(a + bi)(c + di) = ac + adi + bci + bdi^2 -``` - -But there is also a quicker way! - -Use this rule: - -```text -(a + bi)(c + di) = (ac − bd) + (ad + bc)i -``` - -**Example** - -```text -(3 + 2i)(1 + 7i) -= 3×1 + 3×7i + 2i×1+ 2i×7i -= 3 + 21i + 2i + 14i^2 -= 3 + 21i + 2i − 14 (because i^2 = −1) -= −11 + 23i -``` - -```text -(3 + 2i)(1 + 7i) = (3×1 − 2×7) + (3×7 + 2×1)i = −11 + 23i -``` - -### Conjugates - -We will need to know about conjugates in a minute! - -A conjugate is where we change the sign in the middle like this: - -![Complex Conjugate](https://www.mathsisfun.com/numbers/images/complex-conjugate.svg) - -A conjugate is often written with a bar over it: - -```text -______ -5 − 3i = 5 + 3i -``` - -On the complex plane the conjugate number will be mirrored against real axes. - -![Complex Conjugate](https://upload.wikimedia.org/wikipedia/commons/6/69/Complex_conjugate_picture.svg) - -### Dividing - -The conjugate is used to help complex division. - -The trick is to _multiply both top and bottom by the conjugate of the bottom_. - -**Example** - -```text -2 + 3i ------- -4 − 5i -``` - -Multiply top and bottom by the conjugate of `4 − 5i`: - -```text - (2 + 3i) * (4 + 5i) 8 + 10i + 12i + 15i^2 -= ------------------- = ---------------------- - (4 − 5i) * (4 + 5i) 16 + 20i − 20i − 25i^2 -``` - -Now remember that `i^2 = −1`, so: - -```text - 8 + 10i + 12i − 15 −7 + 22i −7 22 -= ------------------- = -------- = -- + -- * i - 16 + 20i − 20i + 25 41 41 41 - -``` - -There is a faster way though. - -In the previous example, what happened on the bottom was interesting: - -```text -(4 − 5i)(4 + 5i) = 16 + 20i − 20i − 25i -``` - -The middle terms `(20i − 20i)` cancel out! Also `i^2 = −1` so we end up with this: - -```text -(4 − 5i)(4 + 5i) = 4^2 + 5^2 -``` - -Which is really quite a simple result. The general rule is: - -```text -(a + bi)(a − bi) = a^2 + b^2 -``` - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Complex_number) -- [Math is Fun](https://www.mathsisfun.com/numbers/complex-numbers.html) diff --git a/docs/content/DS_ALGO/algorithms/math/complex-number/test/ComplexNumber.test.js b/docs/content/DS_ALGO/algorithms/math/complex-number/test/ComplexNumber.test.js deleted file mode 100644 index fd86dcd266..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/complex-number/test/ComplexNumber.test.js +++ /dev/null @@ -1,135 +0,0 @@ -import ComplexNumber from '../ComplexNumber'; -describe('ComplexNumber', () => { - it('should create complex numbers', () => { - const complexNumber = new ComplexNumber({ re: 1, im: 2 }); - expect(complexNumber).toBeDefined(); - expect(complexNumber.re).toBe(1); - expect(complexNumber.im).toBe(2); - const defaultComplexNumber = new ComplexNumber(); - expect(defaultComplexNumber.re).toBe(0); - expect(defaultComplexNumber.im).toBe(0); - }); - it('should add complex numbers', () => { - const complexNumber1 = new ComplexNumber({ re: 1, im: 2 }); - const complexNumber2 = new ComplexNumber({ re: 3, im: 8 }); - const complexNumber3 = complexNumber1.add(complexNumber2); - const complexNumber4 = complexNumber2.add(complexNumber1); - expect(complexNumber3.re).toBe(1 + 3); - expect(complexNumber3.im).toBe(2 + 8); - expect(complexNumber4.re).toBe(1 + 3); - expect(complexNumber4.im).toBe(2 + 8); - }); - it('should add complex and natural numbers', () => { - const complexNumber = new ComplexNumber({ re: 1, im: 2 }); - const realNumber = new ComplexNumber({ re: 3 }); - const complexNumber3 = complexNumber.add(realNumber); - const complexNumber4 = realNumber.add(complexNumber); - const complexNumber5 = complexNumber.add(3); - expect(complexNumber3.re).toBe(1 + 3); - expect(complexNumber3.im).toBe(2); - expect(complexNumber4.re).toBe(1 + 3); - expect(complexNumber4.im).toBe(2); - expect(complexNumber5.re).toBe(1 + 3); - expect(complexNumber5.im).toBe(2); - }); - it('should subtract complex numbers', () => { - const complexNumber1 = new ComplexNumber({ re: 1, im: 2 }); - const complexNumber2 = new ComplexNumber({ re: 3, im: 8 }); - const complexNumber3 = complexNumber1.subtract(complexNumber2); - const complexNumber4 = complexNumber2.subtract(complexNumber1); - expect(complexNumber3.re).toBe(1 - 3); - expect(complexNumber3.im).toBe(2 - 8); - expect(complexNumber4.re).toBe(3 - 1); - expect(complexNumber4.im).toBe(8 - 2); - }); - it('should subtract complex and natural numbers', () => { - const complexNumber = new ComplexNumber({ re: 1, im: 2 }); - const realNumber = new ComplexNumber({ re: 3 }); - const complexNumber3 = complexNumber.subtract(realNumber); - const complexNumber4 = realNumber.subtract(complexNumber); - const complexNumber5 = complexNumber.subtract(3); - expect(complexNumber3.re).toBe(1 - 3); - expect(complexNumber3.im).toBe(2); - expect(complexNumber4.re).toBe(3 - 1); - expect(complexNumber4.im).toBe(-2); - expect(complexNumber5.re).toBe(1 - 3); - expect(complexNumber5.im).toBe(2); - }); - it('should multiply complex numbers', () => { - const complexNumber1 = new ComplexNumber({ re: 3, im: 2 }); - const complexNumber2 = new ComplexNumber({ re: 1, im: 7 }); - const complexNumber3 = complexNumber1.multiply(complexNumber2); - const complexNumber4 = complexNumber2.multiply(complexNumber1); - const complexNumber5 = complexNumber1.multiply(5); - expect(complexNumber3.re).toBe(-11); - expect(complexNumber3.im).toBe(23); - expect(complexNumber4.re).toBe(-11); - expect(complexNumber4.im).toBe(23); - expect(complexNumber5.re).toBe(15); - expect(complexNumber5.im).toBe(10); - }); - it('should multiply complex numbers by themselves', () => { - const complexNumber = new ComplexNumber({ re: 1, im: 1 }); - const result = complexNumber.multiply(complexNumber); - expect(result.re).toBe(0); - expect(result.im).toBe(2); - }); - it('should calculate i in power of two', () => { - const complexNumber = new ComplexNumber({ re: 0, im: 1 }); - const result = complexNumber.multiply(complexNumber); - expect(result.re).toBe(-1); - expect(result.im).toBe(0); - }); - it('should divide complex numbers', () => { - const complexNumber1 = new ComplexNumber({ re: 2, im: 3 }); - const complexNumber2 = new ComplexNumber({ re: 4, im: -5 }); - const complexNumber3 = complexNumber1.divide(complexNumber2); - const complexNumber4 = complexNumber1.divide(2); - expect(complexNumber3.re).toBe(-7 / 41); - expect(complexNumber3.im).toBe(22 / 41); - expect(complexNumber4.re).toBe(1); - expect(complexNumber4.im).toBe(1.5); - }); - it('should return complex number in polar form', () => { - const complexNumber1 = new ComplexNumber({ re: 3, im: 3 }); - expect(complexNumber1.getPolarForm().radius).toBe(Math.sqrt(3 ** 2 + 3 ** 2)); - expect(complexNumber1.getPolarForm().phase).toBe(Math.PI / 4); - expect(complexNumber1.getPolarForm(false).phase).toBe(45); - const complexNumber2 = new ComplexNumber({ re: -3, im: 3 }); - expect(complexNumber2.getPolarForm().radius).toBe(Math.sqrt(3 ** 2 + 3 ** 2)); - expect(complexNumber2.getPolarForm().phase).toBe(3 * (Math.PI / 4)); - expect(complexNumber2.getPolarForm(false).phase).toBe(135); - const complexNumber3 = new ComplexNumber({ re: -3, im: -3 }); - expect(complexNumber3.getPolarForm().radius).toBe(Math.sqrt(3 ** 2 + 3 ** 2)); - expect(complexNumber3.getPolarForm().phase).toBe(-3 * (Math.PI / 4)); - expect(complexNumber3.getPolarForm(false).phase).toBe(-135); - const complexNumber4 = new ComplexNumber({ re: 3, im: -3 }); - expect(complexNumber4.getPolarForm().radius).toBe(Math.sqrt(3 ** 2 + 3 ** 2)); - expect(complexNumber4.getPolarForm().phase).toBe(-1 * (Math.PI / 4)); - expect(complexNumber4.getPolarForm(false).phase).toBe(-45); - const complexNumber5 = new ComplexNumber({ re: 5, im: 7 }); - expect(complexNumber5.getPolarForm().radius).toBeCloseTo(8.6); - expect(complexNumber5.getPolarForm().phase).toBeCloseTo(0.95); - expect(complexNumber5.getPolarForm(false).phase).toBeCloseTo(54.46); - const complexNumber6 = new ComplexNumber({ re: 0, im: 0.25 }); - expect(complexNumber6.getPolarForm().radius).toBeCloseTo(0.25); - expect(complexNumber6.getPolarForm().phase).toBeCloseTo(1.57); - expect(complexNumber6.getPolarForm(false).phase).toBeCloseTo(90); - const complexNumber7 = new ComplexNumber({ re: 0, im: -0.25 }); - expect(complexNumber7.getPolarForm().radius).toBeCloseTo(0.25); - expect(complexNumber7.getPolarForm().phase).toBeCloseTo(-1.57); - expect(complexNumber7.getPolarForm(false).phase).toBeCloseTo(-90); - const complexNumber8 = new ComplexNumber(); - expect(complexNumber8.getPolarForm().radius).toBeCloseTo(0); - expect(complexNumber8.getPolarForm().phase).toBeCloseTo(0); - expect(complexNumber8.getPolarForm(false).phase).toBeCloseTo(0); - const complexNumber9 = new ComplexNumber({ re: -0.25, im: 0 }); - expect(complexNumber9.getPolarForm().radius).toBeCloseTo(0.25); - expect(complexNumber9.getPolarForm().phase).toBeCloseTo(Math.PI); - expect(complexNumber9.getPolarForm(false).phase).toBeCloseTo(180); - const complexNumber10 = new ComplexNumber({ re: 0.25, im: 0 }); - expect(complexNumber10.getPolarForm().radius).toBeCloseTo(0.25); - expect(complexNumber10.getPolarForm().phase).toBeCloseTo(0); - expect(complexNumber10.getPolarForm(false).phase).toBeCloseTo(0); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/README.md b/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/README.md deleted file mode 100644 index 57da9ad012..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Euclidean algorithm - -[français](README.fr-FR.md). - -In mathematics, the Euclidean algorithm, or Euclid's algorithm, -is an efficient method for computing the greatest common divisor -(GCD) of two numbers, the largest number that divides both of -them without leaving a remainder. - -The Euclidean algorithm is based on the principle that the -greatest common divisor of two numbers does not change if -the larger number is replaced by its difference with the -smaller number. For example, `21` is the GCD of `252` and -`105` (as `252 = 21 × 12` and `105 = 21 × 5`), and the same -number `21` is also the GCD of `105` and `252 − 105 = 147`. -Since this replacement reduces the larger of the two numbers, -repeating this process gives successively smaller pairs of -numbers until the two numbers become equal. -When that occurs, they are the GCD of the original two numbers. - -By reversing the steps, the GCD can be expressed as a sum of -the two original numbers each multiplied by a positive or -negative integer, e.g., `21 = 5 × 105 + (−2) × 252`. -The fact that the GCD can always be expressed in this way is -known as Bézout's identity. - -![GCD](https://upload.wikimedia.org/wikipedia/commons/3/37/Euclid%27s_algorithm_Book_VII_Proposition_2_3.png) - -Euclid's method for finding the greatest common divisor (GCD) -of two starting lengths `BA` and `DC`, both defined to be -multiples of a common "unit" length. The length `DC` being -shorter, it is used to "measure" `BA`, but only once because -remainder `EA` is less than `DC`. EA now measures (twice) -the shorter length `DC`, with remainder `FC` shorter than `EA`. -Then `FC` measures (three times) length `EA`. Because there is -no remainder, the process ends with `FC` being the `GCD`. -On the right Nicomachus' example with numbers `49` and `21` -resulting in their GCD of `7` (derived from Heath 1908:300). - -![GCD](https://upload.wikimedia.org/wikipedia/commons/7/74/24x60.svg) - -A `24-by-60` rectangle is covered with ten `12-by-12` square -tiles, where `12` is the GCD of `24` and `60`. More generally, -an `a-by-b` rectangle can be covered with square tiles of -side-length `c` only if `c` is a common divisor of `a` and `b`. - -![GCD](https://upload.wikimedia.org/wikipedia/commons/1/1c/Euclidean_algorithm_1071_462.gif) - -Subtraction-based animation of the Euclidean algorithm. -The initial rectangle has dimensions `a = 1071` and `b = 462`. -Squares of size `462×462` are placed within it leaving a -`462×147` rectangle. This rectangle is tiled with `147×147` -squares until a `21×147` rectangle is left, which in turn is -tiled with `21×21` squares, leaving no uncovered area. -The smallest square size, `21`, is the GCD of `1071` and `462`. - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Euclidean_algorithm) diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithm.js b/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithm.js deleted file mode 100644 index 1c55ff9c42..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithm.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Recursive version of Euclidean Algorithm of finding greatest common divisor (GCD). - * @param {number} originalA - * @param {number} originalB - * @return {number} - */ -export default function euclideanAlgorithm(originalA, originalB) { - // Make input numbers positive. - const a = Math.abs(originalA); - const b = Math.abs(originalB); - // To make algorithm work faster instead of subtracting one number from the other - // we may use modulo operation. - return b === 0 ? a : euclideanAlgorithm(b, a % b); -} diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithmIterative.js b/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithmIterative.js deleted file mode 100644 index ae3db67f5f..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/euclideanAlgorithmIterative.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Iterative version of Euclidean Algorithm of finding greatest common divisor (GCD). - * @param {number} originalA - * @param {number} originalB - * @return {number} - */ -export default function euclideanAlgorithmIterative(originalA, originalB) { - // Make input numbers positive. - let a = Math.abs(originalA); - let b = Math.abs(originalB); - // Subtract one number from another until both numbers would become the same. - // This will be out GCD. Also quit the loop if one of the numbers is zero. - while (a && b && a !== b) { - [a, b] = a > b ? [a - b, b] : [a, b - a]; - } - // Return the number that is not equal to zero since the last subtraction (it will be a GCD). - return a || b; -} diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithm.test.js b/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithm.test.js deleted file mode 100644 index dad294cce3..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithm.test.js +++ /dev/null @@ -1,25 +0,0 @@ -import euclideanAlgorithm from '../euclideanAlgorithm'; -describe('euclideanAlgorithm', () => { - it('should calculate GCD recursively', () => { - expect(euclideanAlgorithm(0, 0)).toBe(0); - expect(euclideanAlgorithm(2, 0)).toBe(2); - expect(euclideanAlgorithm(0, 2)).toBe(2); - expect(euclideanAlgorithm(1, 2)).toBe(1); - expect(euclideanAlgorithm(2, 1)).toBe(1); - expect(euclideanAlgorithm(6, 6)).toBe(6); - expect(euclideanAlgorithm(2, 4)).toBe(2); - expect(euclideanAlgorithm(4, 2)).toBe(2); - expect(euclideanAlgorithm(12, 4)).toBe(4); - expect(euclideanAlgorithm(4, 12)).toBe(4); - expect(euclideanAlgorithm(5, 13)).toBe(1); - expect(euclideanAlgorithm(27, 13)).toBe(1); - expect(euclideanAlgorithm(24, 60)).toBe(12); - expect(euclideanAlgorithm(60, 24)).toBe(12); - expect(euclideanAlgorithm(252, 105)).toBe(21); - expect(euclideanAlgorithm(105, 252)).toBe(21); - expect(euclideanAlgorithm(1071, 462)).toBe(21); - expect(euclideanAlgorithm(462, 1071)).toBe(21); - expect(euclideanAlgorithm(462, -1071)).toBe(21); - expect(euclideanAlgorithm(-462, -1071)).toBe(21); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithmIterative.test.js b/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithmIterative.test.js deleted file mode 100644 index fee938a858..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-algorithm/test/euclideanAlgorithmIterative.test.js +++ /dev/null @@ -1,25 +0,0 @@ -import euclideanAlgorithmIterative from '../euclideanAlgorithmIterative'; -describe('euclideanAlgorithmIterative', () => { - it('should calculate GCD iteratively', () => { - expect(euclideanAlgorithmIterative(0, 0)).toBe(0); - expect(euclideanAlgorithmIterative(2, 0)).toBe(2); - expect(euclideanAlgorithmIterative(0, 2)).toBe(2); - expect(euclideanAlgorithmIterative(1, 2)).toBe(1); - expect(euclideanAlgorithmIterative(2, 1)).toBe(1); - expect(euclideanAlgorithmIterative(6, 6)).toBe(6); - expect(euclideanAlgorithmIterative(2, 4)).toBe(2); - expect(euclideanAlgorithmIterative(4, 2)).toBe(2); - expect(euclideanAlgorithmIterative(12, 4)).toBe(4); - expect(euclideanAlgorithmIterative(4, 12)).toBe(4); - expect(euclideanAlgorithmIterative(5, 13)).toBe(1); - expect(euclideanAlgorithmIterative(27, 13)).toBe(1); - expect(euclideanAlgorithmIterative(24, 60)).toBe(12); - expect(euclideanAlgorithmIterative(60, 24)).toBe(12); - expect(euclideanAlgorithmIterative(252, 105)).toBe(21); - expect(euclideanAlgorithmIterative(105, 252)).toBe(21); - expect(euclideanAlgorithmIterative(1071, 462)).toBe(21); - expect(euclideanAlgorithmIterative(462, 1071)).toBe(21); - expect(euclideanAlgorithmIterative(462, -1071)).toBe(21); - expect(euclideanAlgorithmIterative(-462, -1071)).toBe(21); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/README.md b/docs/content/DS_ALGO/algorithms/math/euclidean-distance/README.md deleted file mode 100644 index 8925da13ec..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# Euclidean Distance - -In mathematics, the **Euclidean distance** between two points in Euclidean space is the length of a line segment between the two points. It can be calculated from the Cartesian coordinates of the points using the Pythagorean theorem, therefore occasionally being called the Pythagorean distance. - -![Euclidean distance between two points](https://upload.wikimedia.org/wikipedia/commons/5/55/Euclidean_distance_2d.svg) - -## Distance formulas - -### One dimension - -The distance between any two points on the real line is the absolute value of the numerical difference of their coordinates - -![One dimension formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/7d75418dbec9482dbcb70f9063ad66e9cf7b5db9) - -### Two dimensions - -![Two dimensions formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/9c0157084fd89f5f3d462efeedc47d3d7aa0b773) - -### Higher dimensions - -In three dimensions, for points given by their Cartesian coordinates, the distance is - -![Three dimensions formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/d1d13a40a7b203b455ae6d4be8b3cce898bda625) - -Example: the distance between the two points `(8,2,6)` and `(3,5,7)`: - -![3-dimension example](https://www.mathsisfun.com/algebra/images/dist-2-points-3d.svg) - -In general, for points given by Cartesian coordinates in `n`-dimensional Euclidean space, the distance is - -![n-dimensional formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/a0ef4fe055b2a51b4cca43a05e5d1cd93f758dcc) - -## References - -- [Euclidean Distance on MathIsFun](https://www.mathsisfun.com/algebra/distance-2-points.html) -- [Euclidean Distance on Wikipedia](https://en.wikipedia.org/wiki/Euclidean_distance) diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/__tests__/euclideanDistance.test.js b/docs/content/DS_ALGO/algorithms/math/euclidean-distance/__tests__/euclideanDistance.test.js deleted file mode 100644 index c7b985d5db..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/__tests__/euclideanDistance.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import euclideanDistance from '../euclideanDistance'; -describe('euclideanDistance', () => { - it('should calculate euclidean distance between vectors', () => { - expect(euclideanDistance([[1]], [[2]])).toEqual(1); - expect(euclideanDistance([[2]], [[1]])).toEqual(1); - expect(euclideanDistance([[5, 8]], [[7, 3]])).toEqual(5.39); - expect(euclideanDistance([[5], [8]], [[7], [3]])).toEqual(5.39); - expect(euclideanDistance([[8, 2, 6]], [[3, 5, 7]])).toEqual(5.92); - expect(euclideanDistance([[8], [2], [6]], [[3], [5], [7]])).toEqual(5.92); - expect(euclideanDistance([[[8]], [[2]], [[6]]], [[[3]], [[5]], [[7]]])).toEqual(5.92); - }); - it('should throw an error in case if two matrices are of different shapes', () => { - expect(() => euclideanDistance([[1]], [[[2]]])).toThrowError('Matrices have different dimensions'); - expect(() => euclideanDistance([[1]], [[2, 3]])).toThrowError('Matrices have different shapes'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/euclideanDistance.js b/docs/content/DS_ALGO/algorithms/math/euclidean-distance/euclideanDistance.js deleted file mode 100644 index bc53520b48..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/euclidean-distance/euclideanDistance.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @typedef {import('../matrix/Matrix.js').Matrix} Matrix - */ -import * as mtrx from '../matrix/Matrix'; -/** - * Calculates the euclidean distance between 2 matrices. - * - * @param {Matrix} a - * @param {Matrix} b - * @returns {number} - * @trows {Error} - */ -const euclideanDistance = (a, b) => { - mtrx.validateSameShape(a, b); - let squaresTotal = 0; - mtrx.walk(a, (indices, aCellValue) => { - const bCellValue = mtrx.getCellAtIndex(b, indices); - squaresTotal += (aCellValue - bCellValue) ** 2; - }); - return Number(Math.sqrt(squaresTotal).toFixed(2)); -}; -export default euclideanDistance; diff --git a/docs/content/DS_ALGO/algorithms/math/factorial/README.md b/docs/content/DS_ALGO/algorithms/math/factorial/README.md deleted file mode 100644 index b7ab38e6c4..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/factorial/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Factorial - -In mathematics, the factorial of a non-negative integer `n`, -denoted by `n!`, is the product of all positive integers less -than or equal to `n`. For example: - -``` -5! = 5 * 4 * 3 * 2 * 1 = 120 -``` - -| n | n! | -| --- | ----------------: | -| 0 | 1 | -| 1 | 1 | -| 2 | 2 | -| 3 | 6 | -| 4 | 24 | -| 5 | 120 | -| 6 | 720 | -| 7 | 5 040 | -| 8 | 40 320 | -| 9 | 362 880 | -| 10 | 3 628 800 | -| 11 | 39 916 800 | -| 12 | 479 001 600 | -| 13 | 6 227 020 800 | -| 14 | 87 178 291 200 | -| 15 | 1 307 674 368 000 | - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Factorial) diff --git a/docs/content/DS_ALGO/algorithms/math/factorial/factorial.js b/docs/content/DS_ALGO/algorithms/math/factorial/factorial.js deleted file mode 100644 index 0dd45e7870..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/factorial/factorial.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @param {number} number - * @return {number} - */ -export default function factorial(number) { - let result = 1; - for (let i = 2; i <= number; i += 1) { - result *= i; - } - return result; -} diff --git a/docs/content/DS_ALGO/algorithms/math/factorial/factorialRecursive.js b/docs/content/DS_ALGO/algorithms/math/factorial/factorialRecursive.js deleted file mode 100644 index 64f80acdab..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/factorial/factorialRecursive.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} number - * @return {number} - */ -export default function factorialRecursive(number) { - return number > 1 ? number * factorialRecursive(number - 1) : 1; -} diff --git a/docs/content/DS_ALGO/algorithms/math/factorial/test/factorial.test.js b/docs/content/DS_ALGO/algorithms/math/factorial/test/factorial.test.js deleted file mode 100644 index d764d30920..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/factorial/test/factorial.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import factorial from '../factorial'; -describe('factorial', () => { - it('should calculate factorial', () => { - expect(factorial(0)).toBe(1); - expect(factorial(1)).toBe(1); - expect(factorial(5)).toBe(120); - expect(factorial(8)).toBe(40320); - expect(factorial(10)).toBe(3628800); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/factorial/test/factorialRecursive.test.js b/docs/content/DS_ALGO/algorithms/math/factorial/test/factorialRecursive.test.js deleted file mode 100644 index 21566bae18..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/factorial/test/factorialRecursive.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import factorialRecursive from '../factorialRecursive'; -describe('factorialRecursive', () => { - it('should calculate factorial', () => { - expect(factorialRecursive(0)).toBe(1); - expect(factorialRecursive(1)).toBe(1); - expect(factorialRecursive(5)).toBe(120); - expect(factorialRecursive(8)).toBe(40320); - expect(factorialRecursive(10)).toBe(3628800); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fast-powering/README.md b/docs/content/DS_ALGO/algorithms/math/fast-powering/README.md deleted file mode 100644 index fc0e4b550e..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fast-powering/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Fast Powering Algorithm - -[français](README.fr-FR.md). - -**The power of a number** says how many times to use the number in a -multiplication. - -It is written as a small number to the right and above the base number. - -![Power](https://www.mathsisfun.com/algebra/images/exponent-8-2.svg) - -## Naive Algorithm Complexity - -How to find `a` raised to the power `b`? - -We multiply `a` to itself, `b` times. That -is, `a^b = a * a * a * ... * a` (`b` occurrences of `a`). - -This operation will take `O(n)` time since we need to do multiplication operation -exactly `n` times. - -## Fast Power Algorithm - -Can we do better than naive algorithm does? Yes we may solve the task of -powering in `O(log(n))` time. - -The algorithm uses divide and conquer approach to compute power. Currently the -algorithm work for two positive integers `X` and `Y`. - -The idea behind the algorithm is based on the fact that: - -For **even** `Y`: - -```text -X^Y = X^(Y/2) * X^(Y/2) -``` - -For **odd** `Y`: - -```text -X^Y = X^(Y//2) * X^(Y//2) * X -where Y//2 is result of division of Y by 2 without reminder. -``` - -**For example** - -```text -2^4 = (2 * 2) * (2 * 2) = (2^2) * (2^2) -``` - -```text -2^5 = (2 * 2) * (2 * 2) * 2 = (2^2) * (2^2) * (2) -``` - -Now, since on each step we need to compute the same `X^(Y/2)` power twice we may optimise -it by saving it to some intermediate variable to avoid its duplicate calculation. - -**Time Complexity** - -Since each iteration we split the power by half then we will call function -recursively `log(n)` times. This the time complexity of the algorithm is reduced to: - -```text -O(log(n)) -``` - -## References - -- [YouTube](https://www.youtube.com/watch?v=LUWavfN9zEo&index=80&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&t=0s) -- [Wikipedia](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) diff --git a/docs/content/DS_ALGO/algorithms/math/fast-powering/fastPowering.js b/docs/content/DS_ALGO/algorithms/math/fast-powering/fastPowering.js deleted file mode 100644 index a89ca8f768..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fast-powering/fastPowering.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Fast Powering Algorithm. - * Recursive implementation to compute power. - * - * Complexity: log(n) - * - * @param {number} base - Number that will be raised to the power. - * @param {number} power - The power that number will be raised to. - * @return {number} - */ -export default function fastPowering(base, power) { - if (power === 0) { - // Anything that is raised to the power of zero is 1. - return 1; - } - if (power % 2 === 0) { - // If the power is even... - // we may recursively redefine the result via twice smaller powers: - // x^8 = x^4 * x^4. - const multiplier = fastPowering(base, power / 2); - return multiplier * multiplier; - } - // If the power is odd... - // we may recursively redefine the result via twice smaller powers: - // x^9 = x^4 * x^4 * x. - const multiplier = fastPowering(base, Math.floor(power / 2)); - return multiplier * multiplier * base; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fast-powering/test/fastPowering.test.js b/docs/content/DS_ALGO/algorithms/math/fast-powering/test/fastPowering.test.js deleted file mode 100644 index e0e1a96a6c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fast-powering/test/fastPowering.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import fastPowering from '../fastPowering'; -describe('fastPowering', () => { - it('should compute power in log(n) time', () => { - expect(fastPowering(1, 1)).toBe(1); - expect(fastPowering(2, 0)).toBe(1); - expect(fastPowering(2, 2)).toBe(4); - expect(fastPowering(2, 3)).toBe(8); - expect(fastPowering(2, 4)).toBe(16); - expect(fastPowering(2, 5)).toBe(32); - expect(fastPowering(2, 6)).toBe(64); - expect(fastPowering(2, 7)).toBe(128); - expect(fastPowering(2, 8)).toBe(256); - expect(fastPowering(3, 4)).toBe(81); - expect(fastPowering(190, 2)).toBe(36100); - expect(fastPowering(11, 5)).toBe(161051); - expect(fastPowering(13, 11)).toBe(1792160394037); - expect(fastPowering(9, 16)).toBe(1853020188851841); - expect(fastPowering(16, 16)).toBe(18446744073709552000); - expect(fastPowering(7, 21)).toBe(558545864083284000); - expect(fastPowering(100, 9)).toBe(1000000000000000000); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/README.md b/docs/content/DS_ALGO/algorithms/math/fibonacci/README.md deleted file mode 100644 index a3c683458e..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Fibonacci Number - -[français](README.fr-FR.md), - -In mathematics, the Fibonacci numbers are the numbers in the following -integer sequence, called the Fibonacci sequence, and characterized by -the fact that every number after the first two is the sum of the two -preceding ones: - -`0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...` - -A tiling with squares whose side lengths are successive Fibonacci numbers - -![Fibonacci](https://upload.wikimedia.org/wikipedia/commons/d/db/34%2A21-FibonacciBlocks.png) - -The Fibonacci spiral: an approximation of the golden spiral created by drawing circular arcs connecting the opposite corners of squares in the Fibonacci tiling;[4] this one uses squares of sizes 1, 1, 2, 3, 5, 8, 13 and 21. - -![Fibonacci Spiral](https://upload.wikimedia.org/wikipedia/commons/2/2e/FibonacciSpiral.svg) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Fibonacci_number) diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacci.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacci.js deleted file mode 100644 index d3c100a9c2..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacci.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Return a fibonacci sequence as an array. - * - * @param n - * @return {number[]} - */ -export default function fibonacci(n) { - const fibSequence = [1]; - let currentValue = 1; - let previousValue = 0; - if (n === 1) { - return fibSequence; - } - let iterationsCounter = n - 1; - while (iterationsCounter) { - currentValue += previousValue; - previousValue = currentValue - previousValue; - fibSequence.push(currentValue); - iterationsCounter -= 1; - } - return fibSequence; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNth.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNth.js deleted file mode 100644 index e2eaa473d3..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNth.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Calculate fibonacci number at specific position using Dynamic Programming approach. - * - * @param n - * @return {number} - */ -export default function fibonacciNth(n) { - let currentValue = 1; - let previousValue = 0; - if (n === 1) { - return 1; - } - let iterationsCounter = n - 1; - while (iterationsCounter) { - currentValue += previousValue; - previousValue = currentValue - previousValue; - iterationsCounter -= 1; - } - return currentValue; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNthClosedForm.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNthClosedForm.js deleted file mode 100644 index 3fc2fe69fa..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/fibonacciNthClosedForm.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Calculate fibonacci number at specific position using closed form function (Binet's formula). - * @see: https://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression - * - * @param {number} position - Position number of fibonacci sequence (must be number from 1 to 75). - * @return {number} - */ -export default function fibonacciClosedForm(position) { - const topMaxValidPosition = 70; - // Check that position is valid. - if (position < 1 || position > topMaxValidPosition) { - throw new Error(`Can't handle position smaller than 1 or greater than ${topMaxValidPosition}`); - } - // Calculate √5 to re-use it in further formulas. - const sqrt5 = Math.sqrt(5); - // Calculate φ constant (≈ 1.61803). - const phi = (1 + sqrt5) / 2; - // Calculate fibonacci number using Binet's formula. - return Math.floor(phi ** position / sqrt5 + 0.5); -} diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacci.test.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacci.test.js deleted file mode 100644 index b726ed6c52..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacci.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import fibonacci from '../fibonacci'; -describe('fibonacci', () => { - it('should calculate fibonacci correctly', () => { - expect(fibonacci(1)).toEqual([1]); - expect(fibonacci(2)).toEqual([1, 1]); - expect(fibonacci(3)).toEqual([1, 1, 2]); - expect(fibonacci(4)).toEqual([1, 1, 2, 3]); - expect(fibonacci(5)).toEqual([1, 1, 2, 3, 5]); - expect(fibonacci(6)).toEqual([1, 1, 2, 3, 5, 8]); - expect(fibonacci(7)).toEqual([1, 1, 2, 3, 5, 8, 13]); - expect(fibonacci(8)).toEqual([1, 1, 2, 3, 5, 8, 13, 21]); - expect(fibonacci(9)).toEqual([1, 1, 2, 3, 5, 8, 13, 21, 34]); - expect(fibonacci(10)).toEqual([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNth.test.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNth.test.js deleted file mode 100644 index b41786b7e1..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNth.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import fibonacciNth from '../fibonacciNth'; -describe('fibonacciNth', () => { - it('should calculate fibonacci correctly', () => { - expect(fibonacciNth(1)).toBe(1); - expect(fibonacciNth(2)).toBe(1); - expect(fibonacciNth(3)).toBe(2); - expect(fibonacciNth(4)).toBe(3); - expect(fibonacciNth(5)).toBe(5); - expect(fibonacciNth(6)).toBe(8); - expect(fibonacciNth(7)).toBe(13); - expect(fibonacciNth(8)).toBe(21); - expect(fibonacciNth(20)).toBe(6765); - expect(fibonacciNth(30)).toBe(832040); - expect(fibonacciNth(50)).toBe(12586269025); - expect(fibonacciNth(70)).toBe(190392490709135); - expect(fibonacciNth(71)).toBe(308061521170129); - expect(fibonacciNth(72)).toBe(498454011879264); - expect(fibonacciNth(73)).toBe(806515533049393); - expect(fibonacciNth(74)).toBe(1304969544928657); - expect(fibonacciNth(75)).toBe(2111485077978050); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNthClosedForm.test.js b/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNthClosedForm.test.js deleted file mode 100644 index 8be5130363..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fibonacci/test/fibonacciNthClosedForm.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import fibonacciNthClosedForm from '../fibonacciNthClosedForm'; -describe('fibonacciClosedForm', () => { - it('should throw an error when trying to calculate fibonacci for not allowed positions', () => { - const calculateFibonacciForNotAllowedPosition = () => { - fibonacciNthClosedForm(76); - }; - expect(calculateFibonacciForNotAllowedPosition).toThrow(); - }); - it('should calculate fibonacci correctly', () => { - expect(fibonacciNthClosedForm(1)).toBe(1); - expect(fibonacciNthClosedForm(2)).toBe(1); - expect(fibonacciNthClosedForm(3)).toBe(2); - expect(fibonacciNthClosedForm(4)).toBe(3); - expect(fibonacciNthClosedForm(5)).toBe(5); - expect(fibonacciNthClosedForm(6)).toBe(8); - expect(fibonacciNthClosedForm(7)).toBe(13); - expect(fibonacciNthClosedForm(8)).toBe(21); - expect(fibonacciNthClosedForm(20)).toBe(6765); - expect(fibonacciNthClosedForm(30)).toBe(832040); - expect(fibonacciNthClosedForm(50)).toBe(12586269025); - expect(fibonacciNthClosedForm(70)).toBe(190392490709135); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/README.md b/docs/content/DS_ALGO/algorithms/math/fourier-transform/README.md deleted file mode 100644 index 86e86cc5d1..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# Fourier Transform - -[français](README.fr-FR.md). - -## Definitions - -The **Fourier Transform** (**FT**) decomposes a function of time (a signal) into -the frequencies that make it up, in a way similar to how a musical chord can be -expressed as the frequencies (or pitches) of its constituent notes. - -The **Discrete Fourier Transform** (**DFT**) converts a finite sequence of -equally-spaced samples of a function into a same-length sequence of -equally-spaced samples of the discrete-time Fourier transform (DTFT), which is a -complex-valued function of frequency. The interval at which the DTFT is sampled -is the reciprocal of the duration of the input sequence. An inverse DFT is a -Fourier series, using the DTFT samples as coefficients of complex sinusoids at -the corresponding DTFT frequencies. It has the same sample-values as the original -input sequence. The DFT is therefore said to be a frequency domain representation -of the original input sequence. If the original sequence spans all the non-zero -values of a function, its DTFT is continuous (and periodic), and the DFT provides -discrete samples of one cycle. If the original sequence is one cycle of a periodic -function, the DFT provides all the non-zero values of one DTFT cycle. - -The Discrete Fourier transform transforms a sequence of `N` complex numbers: - -{xn} = x0, x1, x2 ..., xN-1 - -into another sequence of complex numbers: - -{Xk} = X0, X1, X2 ..., XN-1 - -which is defined by: - -![DFT](https://wikimedia.org/api/rest_v1/media/math/render/svg/1af0a78dc50bbf118ab6bd4c4dcc3c4ff8502223) - -The **Discrete-Time Fourier Transform** (**DTFT**) is a form of Fourier analysis -that is applicable to the uniformly-spaced samples of a continuous function. The -term discrete-time refers to the fact that the transform operates on discrete data -(samples) whose interval often has units of time. From only the samples, it -produces a function of frequency that is a periodic summation of the continuous -Fourier transform of the original continuous function. - -A **Fast Fourier Transform** (**FFT**) is an algorithm that samples a signal over -a period of time (or space) and divides it into its frequency components. These -components are single sinusoidal oscillations at distinct frequencies each with -their own amplitude and phase. - -This transformation is illustrated in Diagram below. Over the time period measured -in the diagram, the signal contains 3 distinct dominant frequencies. - -View of a signal in the time and frequency domain: - -![FFT](https://upload.wikimedia.org/wikipedia/commons/6/61/FFT-Time-Frequency-View.png) - -An FFT algorithm computes the discrete Fourier transform (DFT) of a sequence, or -its inverse (IFFT). Fourier analysis converts a signal from its original domain -to a representation in the frequency domain and vice versa. An FFT rapidly -computes such transformations by factorizing the DFT matrix into a product of -sparse (mostly zero) factors. As a result, it manages to reduce the complexity of -computing the DFT from O(n2), which arises if one simply applies the -definition of DFT, to O(n log n), where n is the data size. - -Here a discrete Fourier analysis of a sum of cosine waves at 10, 20, 30, 40, -and 50 Hz: - -![FFT](https://upload.wikimedia.org/wikipedia/commons/6/64/FFT_of_Cosine_Summation_Function.png) - -## Explanation - -The Fourier Transform is one of deepest insights ever made. Unfortunately, the -meaning is buried within dense equations: - -![](https://betterexplained.com/wp-content/plugins/wp-latexrender/pictures/45c088dbb767150fc0bacfeb49dd49e5.png) - -and - -![](https://betterexplained.com/wp-content/plugins/wp-latexrender/pictures/faeb9c5bf2e60add63ae4a70b293c7b4.png) - -Rather than jumping into the symbols, let's experience the key idea firsthand. Here's a plain-English metaphor: - -- _What does the Fourier Transform do?_ Given a smoothie, it finds the recipe. -- _How?_ Run the smoothie through filters to extract each ingredient. -- _Why?_ Recipes are easier to analyze, compare, and modify than the smoothie itself. -- _How do we get the smoothie back?_ Blend the ingredients. - -**Think With Circles, Not Just Sinusoids** - -The Fourier Transform is about circular paths (not 1-d sinusoids) and Euler's -formula is a clever way to generate one: - -![](https://betterexplained.com/wp-content/uploads/euler/equal_paths.png) - -Must we use imaginary exponents to move in a circle? Nope. But it's convenient -and compact. And sure, we can describe our path as coordinated motion in two -dimensions (real and imaginary), but don't forget the big picture: we're just -moving in a circle. - -**Discovering The Full Transform** - -The big insight: our signal is just a bunch of time spikes! If we merge the -recipes for each time spike, we should get the recipe for the full signal. - -The Fourier Transform builds the recipe frequency-by-frequency: - -![](https://betterexplained.com/wp-content/uploads/images/fourier-explained-20121219-224649.png) - -A few notes: - -- N = number of time samples we have -- n = current sample we're considering (0 ... N-1) -- xn = value of the signal at time n -- k = current frequency we're considering (0 Hertz up to N-1 Hertz) -- Xk = amount of frequency k in the signal (amplitude and phase, a complex number) -- The 1/N factor is usually moved to the reverse transform (going from frequencies back to time). This is allowed, though I prefer 1/N in the forward transform since it gives the actual sizes for the time spikes. You can get wild and even use 1/sqrt(N) on both transforms (going forward and back creates the 1/N factor). -- n/N is the percent of the time we've gone through. 2 _ pi _ k is our speed in radians / sec. e^-ix is our backwards-moving circular path. The combination is how far we've moved, for this speed and time. -- The raw equations for the Fourier Transform just say "add the complex numbers". Many programming languages cannot handle complex numbers directly, so you convert everything to rectangular coordinates and add those. - -Stuart Riffle has a great interpretation of the Fourier Transform: - -![](https://betterexplained.com/wp-content/uploads/images/DerivedDFT.png) - -## References - -- [An Interactive Guide To The Fourier Transform](https://betterexplained.com/articles/an-interactive-guide-to-the-fourier-transform/) -- [DFT on YouTube by Better Explained](https://www.youtube.com/watch?v=iN0VG9N2q0U&t=0s&index=77&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [FT on YouTube by 3Blue1Brown](https://www.youtube.com/watch?v=spUNpyF58BY&t=0s&index=76&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [FFT on YouTube by Simon Xu](https://www.youtube.com/watch?v=htCj9exbGo0&index=78&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&t=0s) -- Wikipedia - - [FT](https://en.wikipedia.org/wiki/Fourier_transform) - - [DFT](https://www.wikiwand.com/en/Discrete_Fourier_transform) - - [DTFT](https://en.wikipedia.org/wiki/Discrete-time_Fourier_transform) - - [FFT](https://www.wikiwand.com/en/Fast_Fourier_transform) diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/discreteFourierTransform.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/discreteFourierTransform.js deleted file mode 100644 index 00d36af72c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/discreteFourierTransform.js +++ /dev/null @@ -1,57 +0,0 @@ -import ComplexNumber from '../complex-number/ComplexNumber'; -const CLOSE_TO_ZERO_THRESHOLD = 1e-10; -/** - * Discrete Fourier Transform (DFT): time to frequencies. - * - * Time complexity: O(N^2) - * - * @param {number[]} inputAmplitudes - Input signal amplitudes over time (complex - * numbers with real parts only). - * @param {number} zeroThreshold - Threshold that is used to convert real and imaginary numbers - * to zero in case if they are smaller then this. - * - * @return {ComplexNumber[]} - Array of complex number. Each of the number represents the frequency - * or signal. All signals together will form input signal over discrete time periods. Each signal's - * complex number has radius (amplitude) and phase (angle) in polar form that describes the signal. - * - * @see https://gist.github.com/anonymous/129d477ddb1c8025c9ac - * @see https://betterexplained.com/articles/an-interactive-guide-to-the-fourier-transform/ - */ -export default function dft(inputAmplitudes, zeroThreshold = CLOSE_TO_ZERO_THRESHOLD) { - const N = inputAmplitudes.length; - const signals = []; - // Go through every discrete frequency. - for (let frequency = 0; frequency < N; frequency += 1) { - // Compound signal at current frequency that will ultimately - // take part in forming input amplitudes. - let frequencySignal = new ComplexNumber(); - // Go through every discrete point in time. - for (let timer = 0; timer < N; timer += 1) { - const currentAmplitude = inputAmplitudes[timer]; - // Calculate rotation angle. - const rotationAngle = -1 * (2 * Math.PI) * frequency * (timer / N); - // Remember that e^ix = cos(x) + i * sin(x); - const dataPointContribution = new ComplexNumber({ - re: Math.cos(rotationAngle), - im: Math.sin(rotationAngle) - }).multiply(currentAmplitude); - // Add this data point's contribution. - frequencySignal = frequencySignal.add(dataPointContribution); - } - // Close to zero? You're zero. - if (Math.abs(frequencySignal.re) < zeroThreshold) { - frequencySignal.re = 0; - } - if (Math.abs(frequencySignal.im) < zeroThreshold) { - frequencySignal.im = 0; - } - // Average contribution at this frequency. - // The 1/N factor is usually moved to the reverse transform (going from frequencies - // back to time). This is allowed, though it would be nice to have 1/N in the forward - // transform since it gives the actual sizes for the time spikes. - frequencySignal = frequencySignal.divide(N); - // Add current frequency signal to the list of compound signals. - signals[frequency] = frequencySignal; - } - return signals; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/fastFourierTransform.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/fastFourierTransform.js deleted file mode 100644 index 03346a9fe8..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/fastFourierTransform.js +++ /dev/null @@ -1,67 +0,0 @@ -import ComplexNumber from '../complex-number/ComplexNumber'; -import bitLength from '../bits/bitLength'; -/** - * Returns the number which is the flipped binary representation of input. - * - * @param {number} input - * @param {number} bitsCount - * @return {number} - */ -function reverseBits(input, bitsCount) { - let reversedBits = 0; - for (let bitIndex = 0; bitIndex < bitsCount; bitIndex += 1) { - reversedBits *= 2; - if (Math.floor(input / (1 << bitIndex)) % 2 === 1) { - reversedBits += 1; - } - } - return reversedBits; -} -/** - * Returns the radix-2 fast fourier transform of the given array. - * Optionally computes the radix-2 inverse fast fourier transform. - * - * @param {ComplexNumber[]} inputData - * @param {boolean} [inverse] - * @return {ComplexNumber[]} - */ -export default function fastFourierTransform(inputData, inverse = false) { - const bitsCount = bitLength(inputData.length - 1); - const N = 1 << bitsCount; - while (inputData.length < N) { - inputData.push(new ComplexNumber()); - } - const output = []; - for (let dataSampleIndex = 0; dataSampleIndex < N; dataSampleIndex += 1) { - output[dataSampleIndex] = inputData[reverseBits(dataSampleIndex, bitsCount)]; - } - for (let blockLength = 2; blockLength <= N; blockLength *= 2) { - const imaginarySign = inverse ? -1 : 1; - const phaseStep = new ComplexNumber({ - re: Math.cos((2 * Math.PI) / blockLength), - im: imaginarySign * Math.sin((2 * Math.PI) / blockLength) - }); - for (let blockStart = 0; blockStart < N; blockStart += blockLength) { - let phase = new ComplexNumber({ - re: 1, - im: 0 - }); - for (let signalId = blockStart; signalId < blockStart + blockLength / 2; signalId += 1) { - const component = output[signalId + blockLength / 2].multiply(phase); - const upd1 = output[signalId].add(component); - const upd2 = output[signalId].subtract(component); - output[signalId] = upd1; - output[signalId + blockLength / 2] = upd2; - phase = phase.multiply(phaseStep); - } - } - } - if (inverse) { - for (let signalId = 0; signalId < N; signalId += 1) { - output[signalId] /= N; - } - } - return output; -} -return output; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/inverseDiscreteFourierTransform.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/inverseDiscreteFourierTransform.js deleted file mode 100644 index 21826d1c9c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/inverseDiscreteFourierTransform.js +++ /dev/null @@ -1,44 +0,0 @@ -import ComplexNumber from '../complex-number/ComplexNumber'; -const CLOSE_TO_ZERO_THRESHOLD = 1e-10; -/** - * Inverse Discrete Fourier Transform (IDFT): frequencies to time. - * - * Time complexity: O(N^2) - * - * @param {ComplexNumber[]} frequencies - Frequencies summands of the final signal. - * @param {number} zeroThreshold - Threshold that is used to convert real and imaginary numbers - * to zero in case if they are smaller then this. - * - * @return {number[]} - Discrete amplitudes distributed in time. - */ -export default function inverseDiscreteFourierTransform(frequencies, zeroThreshold = CLOSE_TO_ZERO_THRESHOLD) { - const N = frequencies.length; - const amplitudes = []; - // Go through every discrete point of time. - for (let timer = 0; timer < N; timer += 1) { - // Compound amplitude at current time. - let amplitude = new ComplexNumber(); - // Go through all discrete frequencies. - for (let frequency = 0; frequency < N; frequency += 1) { - const currentFrequency = frequencies[frequency]; - // Calculate rotation angle. - const rotationAngle = 2 * Math.PI * frequency * (timer / N); - // Remember that e^ix = cos(x) + i * sin(x); - const frequencyContribution = new ComplexNumber({ - re: Math.cos(rotationAngle), - im: Math.sin(rotationAngle) - }).multiply(currentFrequency); - amplitude = amplitude.add(frequencyContribution); - } - // Close to zero? You're zero. - if (Math.abs(amplitude.re) < zeroThreshold) { - amplitude.re = 0; - } - if (Math.abs(amplitude.im) < zeroThreshold) { - amplitude.im = 0; - } - // Add current frequency signal to the list of compound signals. - amplitudes[timer] = amplitude.re; - } - return amplitudes; -} diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/FourierTester.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/FourierTester.js deleted file mode 100644 index 2e06fded55..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/FourierTester.js +++ /dev/null @@ -1,532 +0,0 @@ -import ComplexNumber from '../../complex-number/ComplexNumber'; -export const fourierTestCases = [{ - input: [{ - amplitude: 1 - }], - output: [{ - frequency: 0, - amplitude: 1, - phase: 0, - re: 1, - im: 0 - }] - }, - { - input: [{ - amplitude: 1 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 0.5, - phase: 0, - re: 0.5, - im: 0 - }, - { - frequency: 1, - amplitude: 0.5, - phase: 0, - re: 0.5, - im: 0 - } - ] - }, - { - input: [{ - amplitude: 2 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 1, - phase: 0, - re: 1, - im: 0 - }, - { - frequency: 1, - amplitude: 1, - phase: 0, - re: 1, - im: 0 - } - ] - }, - { - input: [{ - amplitude: 1 - }, { - amplitude: 0 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 0.33333, - phase: 0, - re: 0.33333, - im: 0 - }, - { - frequency: 1, - amplitude: 0.33333, - phase: 0, - re: 0.33333, - im: 0 - }, - { - frequency: 2, - amplitude: 0.33333, - phase: 0, - re: 0.33333, - im: 0 - } - ] - }, - { - input: [{ - amplitude: 1 - }, { - amplitude: 0 - }, { - amplitude: 0 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 1, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 2, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 3, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - } - ] - }, - { - input: [{ - amplitude: 0 - }, { - amplitude: 1 - }, { - amplitude: 0 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 1, - amplitude: 0.25, - phase: -90, - re: 0, - im: -0.25 - }, - { - frequency: 2, - amplitude: 0.25, - phase: 180, - re: -0.25, - im: 0 - }, - { - frequency: 3, - amplitude: 0.25, - phase: 90, - re: 0, - im: 0.25 - } - ] - }, - { - input: [{ - amplitude: 0 - }, { - amplitude: 0 - }, { - amplitude: 1 - }, { - amplitude: 0 - }], - output: [{ - frequency: 0, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 1, - amplitude: 0.25, - phase: 180, - re: -0.25, - im: 0 - }, - { - frequency: 2, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 3, - amplitude: 0.25, - phase: 180, - re: -0.25, - im: 0 - } - ] - }, - { - input: [{ - amplitude: 0 - }, { - amplitude: 0 - }, { - amplitude: 0 - }, { - amplitude: 2 - }], - output: [{ - frequency: 0, - amplitude: 0.5, - phase: 0, - re: 0.5, - im: 0 - }, - { - frequency: 1, - amplitude: 0.5, - phase: 90, - re: 0, - im: 0.5 - }, - { - frequency: 2, - amplitude: 0.5, - phase: 180, - re: -0.5, - im: 0 - }, - { - frequency: 3, - amplitude: 0.5, - phase: -90, - re: 0, - im: -0.5 - } - ] - }, - { - input: [{ - amplitude: 0 - }, { - amplitude: 1 - }, { - amplitude: 0 - }, { - amplitude: 2 - }], - output: [{ - frequency: 0, - amplitude: 0.75, - phase: 0, - re: 0.75, - im: 0 - }, - { - frequency: 1, - amplitude: 0.25, - phase: 90, - re: 0, - im: 0.25 - }, - { - frequency: 2, - amplitude: 0.75, - phase: 180, - re: -0.75, - im: 0 - }, - { - frequency: 3, - amplitude: 0.25, - phase: -90, - re: 0, - im: -0.25 - } - ] - }, - { - input: [{ - amplitude: 4 - }, { - amplitude: 1 - }, { - amplitude: 0 - }, { - amplitude: 2 - }], - output: [{ - frequency: 0, - amplitude: 1.75, - phase: 0, - re: 1.75, - im: 0 - }, - { - frequency: 1, - amplitude: 1.03077, - phase: 14.03624, - re: 0.99999, - im: 0.25 - }, - { - frequency: 2, - amplitude: 0.25, - phase: 0, - re: 0.25, - im: 0 - }, - { - frequency: 3, - amplitude: 1.03077, - phase: -14.03624, - re: 1, - im: -0.25 - } - ] - }, - { - input: [{ - amplitude: 4 - }, { - amplitude: 1 - }, { - amplitude: -3 - }, { - amplitude: 2 - }], - output: [{ - frequency: 0, - amplitude: 1, - phase: 0, - re: 1, - im: 0 - }, - { - frequency: 1, - amplitude: 1.76776, - phase: 8.1301, - re: 1.75, - im: 0.25 - }, - { - frequency: 2, - amplitude: 0.5, - phase: 180, - re: -0.5, - im: 0 - }, - { - frequency: 3, - amplitude: 1.76776, - phase: -8.1301, - re: 1.75, - im: -0.24999 - } - ] - }, - { - input: [{ - amplitude: 1 - }, { - amplitude: 2 - }, { - amplitude: 3 - }, { - amplitude: 4 - }], - output: [{ - frequency: 0, - amplitude: 2.5, - phase: 0, - re: 2.5, - im: 0 - }, - { - frequency: 1, - amplitude: 0.7071, - phase: 135, - re: -0.5, - im: 0.49999 - }, - { - frequency: 2, - amplitude: 0.5, - phase: 180, - re: -0.5, - im: 0 - }, - { - frequency: 3, - amplitude: 0.7071, - phase: -134.99999, - re: -0.49999, - im: -0.5 - } - ] - } -]; -export default class FourierTester { - /** - * @param {function} fourierTransform - */ - static testDirectFourierTransform(fourierTransform) { - fourierTestCases.forEach((testCase) => { - const { - input, - output: expectedOutput - } = testCase; - // Try to split input signal into sequence of pure sinusoids. - const formattedInput = input.map((sample) => sample.amplitude); - const currentOutput = fourierTransform(formattedInput); - // Check the signal has been split into proper amount of sub-signals. - expect(currentOutput.length).toBeGreaterThanOrEqual(formattedInput.length); - // Now go through all the signals and check their frequency, amplitude and phase. - expectedOutput.forEach((expectedSignal, frequency) => { - // Get template data we want to test against. - const currentSignal = currentOutput[frequency]; - const currentPolarSignal = currentSignal.getPolarForm(false); - // Check all signal parameters. - expect(frequency).toBe(expectedSignal.frequency); - expect(currentSignal.re).toBeCloseTo(expectedSignal.re, 4); - expect(currentSignal.im).toBeCloseTo(expectedSignal.im, 4); - expect(currentPolarSignal.phase).toBeCloseTo(expectedSignal.phase, 4); - expect(currentPolarSignal.radius).toBeCloseTo(expectedSignal.amplitude, 4); - }); - }); - } - /** - * @param {function} inverseFourierTransform - */ - static testInverseFourierTransform(inverseFourierTransform) { - fourierTestCases.forEach((testCase) => { - const { - input: expectedOutput, - output: inputFrequencies - } = testCase; - // Try to join frequencies into time signal. - const formattedInput = inputFrequencies.map((frequency) => { - return new ComplexNumber({ - re: frequency.re, - im: frequency.im - }); - }); - const currentOutput = inverseFourierTransform(formattedInput); - // Check the signal has been combined of proper amount of time samples. - expect(currentOutput.length).toBeLessThanOrEqual(formattedInput.length); - // Now go through all the amplitudes and check their values. - expectedOutput.forEach((expectedAmplitudes, timer) => { - // Get template data we want to test against. - const currentAmplitude = currentOutput[timer]; - // Check if current amplitude is close enough to the calculated one. - expect(currentAmplitude).toBeCloseTo(expectedAmplitudes.amplitude, 4); - }); - }); - } -} -phase: -134.99999, - re: -0.49999, - im: -0.5 -} -] -} -]; -export default class FourierTester { - /** - * @param {function} fourierTransform - */ - static testDirectFourierTransform(fourierTransform) { - fourierTestCases.forEach((testCase) => { - const { - input, - output: expectedOutput - } = testCase; - // Try to split input signal into sequence of pure sinusoids. - const formattedInput = input.map((sample) => sample.amplitude); - const currentOutput = fourierTransform(formattedInput); - // Check the signal has been split into proper amount of sub-signals. - expect(currentOutput.length).toBeGreaterThanOrEqual(formattedInput.length); - // Now go through all the signals and check their frequency, amplitude and phase. - expectedOutput.forEach((expectedSignal, frequency) => { - // Get template data we want to test against. - const currentSignal = currentOutput[frequency]; - const currentPolarSignal = currentSignal.getPolarForm(false); - // Check all signal parameters. - expect(frequency).toBe(expectedSignal.frequency); - expect(currentSignal.re).toBeCloseTo(expectedSignal.re, 4); - expect(currentSignal.im).toBeCloseTo(expectedSignal.im, 4); - expect(currentPolarSignal.phase).toBeCloseTo(expectedSignal.phase, 4); - expect(currentPolarSignal.radius).toBeCloseTo(expectedSignal.amplitude, 4); - }); - }); - } - /** - * @param {function} inverseFourierTransform - */ - static testInverseFourierTransform(inverseFourierTransform) { - fourierTestCases.forEach((testCase) => { - const { - input: expectedOutput, - output: inputFrequencies - } = testCase; - // Try to join frequencies into time signal. - const formattedInput = inputFrequencies.map((frequency) => { - return new ComplexNumber({ - re: frequency.re, - im: frequency.im - }); - }); - const currentOutput = inverseFourierTransform(formattedInput); - // Check the signal has been combined of proper amount of time samples. - expect(currentOutput.length).toBeLessThanOrEqual(formattedInput.length); - // Now go through all the amplitudes and check their values. - expectedOutput.forEach((expectedAmplitudes, timer) => { - // Get template data we want to test against. - const currentAmplitude = currentOutput[timer]; - // Check if current amplitude is close enough to the calculated one. - expect(currentAmplitude).toBeCloseTo(expectedAmplitudes.amplitude, 4); - }); - }); - } -} diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/discreteFourierTransform.test.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/discreteFourierTransform.test.js deleted file mode 100644 index 4e6df89a8a..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/discreteFourierTransform.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import discreteFourierTransform from '../discreteFourierTransform'; -import FourierTester from './FourierTester'; -describe('discreteFourierTransform', () => { - it('should split signal into frequencies', () => { - FourierTester.testDirectFourierTransform(discreteFourierTransform); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/fastFourierTransform.test.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/fastFourierTransform.test.js deleted file mode 100644 index 4eb7499201..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/fastFourierTransform.test.js +++ /dev/null @@ -1,82 +0,0 @@ -import fastFourierTransform from '../fastFourierTransform'; -import ComplexNumber from '../../complex-number/ComplexNumber'; -/** - * @param {ComplexNumber[]} sequence1 - * @param {ComplexNumber[]} sequence2 - * @param {Number} delta - * @return {boolean} - */ -function sequencesApproximatelyEqual(sequence1, sequence2, delta) { - if (sequence1.length !== sequence2.length) { - return false; - } - for (let numberIndex = 0; numberIndex < sequence1.length; numberIndex += 1) { - if (Math.abs(sequence1[numberIndex].re - sequence2[numberIndex].re) > delta) { - return false; - } - if (Math.abs(sequence1[numberIndex].im - sequence2[numberIndex].im) > delta) { - return false; - } - } - return true; -} -const delta = 1e-6; -describe('fastFourierTransform', () => { - it('should calculate the radix-2 discrete fourier transform #1', () => { - const input = [new ComplexNumber({ re: 0, im: 0 })]; - const expectedOutput = [new ComplexNumber({ re: 0, im: 0 })]; - const output = fastFourierTransform(input); - const invertedOutput = fastFourierTransform(output, true); - expect(sequencesApproximatelyEqual(expectedOutput, output, delta)).toBe(true); - expect(sequencesApproximatelyEqual(input, invertedOutput, delta)).toBe(true); - }); - it('should calculate the radix-2 discrete fourier transform #2', () => { - const input = [new ComplexNumber({ re: 1, im: 2 }), new ComplexNumber({ re: 2, im: 3 }), new ComplexNumber({ re: 8, im: 4 })]; - const expectedOutput = [ - new ComplexNumber({ re: 11, im: 9 }), - new ComplexNumber({ re: -10, im: 0 }), - new ComplexNumber({ re: 7, im: 3 }), - new ComplexNumber({ re: -4, im: -4 }) - ]; - const output = fastFourierTransform(input); - const invertedOutput = fastFourierTransform(output, true); - expect(sequencesApproximatelyEqual(expectedOutput, output, delta)).toBe(true); - expect(sequencesApproximatelyEqual(input, invertedOutput, delta)).toBe(true); - }); - it('should calculate the radix-2 discrete fourier transform #3', () => { - const input = [ - new ComplexNumber({ re: -83656.9359385182, im: 98724.08038374918 }), - new ComplexNumber({ re: -47537.415125808424, im: 88441.58381765135 }), - new ComplexNumber({ re: -24849.657029355192, im: -72621.79007878687 }), - new ComplexNumber({ re: 31451.27290052717, im: -21113.301128347346 }), - new ComplexNumber({ re: 13973.90836288876, im: -73378.36721594246 }), - new ComplexNumber({ re: 14981.520420492234, im: 63279.524958963884 }), - new ComplexNumber({ re: -9892.575367044381, im: -81748.44671677813 }), - new ComplexNumber({ re: -35933.00356823792, im: -46153.47157161784 }), - new ComplexNumber({ re: -22425.008561855735, im: -86284.24507370662 }), - new ComplexNumber({ re: -39327.43830818355, im: 30611.949874562706 }) - ]; - const expectedOutput = [ - new ComplexNumber({ re: -203215.3322151, im: -100242.4827503 }), - new ComplexNumber({ re: 99217.0805705, im: 270646.9331932 }), - new ComplexNumber({ re: -305990.9040412, im: 68224.8435751 }), - new ComplexNumber({ re: -14135.7758282, im: 199223.9878095 }), - new ComplexNumber({ re: -306965.6350922, im: 26030.1025439 }), - new ComplexNumber({ re: -76477.6755206, im: 40781.907899 }), - new ComplexNumber({ re: -48409.3099088, im: 54674.7959662 }), - new ComplexNumber({ re: -329683.0131713, im: 164287.7995937 }), - new ComplexNumber({ re: -50485.2048527, im: -330375.0546527 }), - new ComplexNumber({ re: 122235.7738708, im: 91091.6398019 }), - new ComplexNumber({ re: 47625.8850387, im: 73497.3981523 }), - new ComplexNumber({ re: -15619.8231136, im: 80804.868541 }), - new ComplexNumber({ re: 192234.0276101, im: 160833.3072355 }), - new ComplexNumber({ re: -96389.4195635, im: 393408.4543872 }), - new ComplexNumber({ re: -173449.0825417, im: 146875.7724104 }), - new ComplexNumber({ re: -179002.5662573, im: 239821.0124341 }) - ]; - const output = fastFourierTransform(input); - const invertedOutput = fastFourierTransform(output, true); - expect(sequencesApproximatelyEqual(expectedOutput, output, delta)).toBe(true); - expect(sequencesApproximatelyEqual(input, invertedOutput, delta)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/inverseDiscreteFourierTransform.test.js b/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/inverseDiscreteFourierTransform.test.js deleted file mode 100644 index e292ce58ef..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/fourier-transform/test/inverseDiscreteFourierTransform.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import inverseDiscreteFourierTransform from '../inverseDiscreteFourierTransform'; -import FourierTester from './FourierTester'; -describe('inverseDiscreteFourierTransform', () => { - it('should calculate output signal out of input frequencies', () => { - FourierTester.testInverseFourierTransform(inverseDiscreteFourierTransform); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/integer-partition/README.md b/docs/content/DS_ALGO/algorithms/math/integer-partition/README.md deleted file mode 100644 index 92a9b16629..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/integer-partition/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Integer Partition - -In number theory and combinatorics, a partition of a positive -integer `n`, also called an **integer partition**, is a way of -writing `n` as a sum of positive integers. - -Two sums that differ only in the order of their summands are -considered the same partition. For example, `4` can be partitioned -in five distinct ways: - -``` -4 -3 + 1 -2 + 2 -2 + 1 + 1 -1 + 1 + 1 + 1 -``` - -The order-dependent composition `1 + 3` is the same partition -as `3 + 1`, while the two distinct -compositions `1 + 2 + 1` and `1 + 1 + 2` represent the same -partition `2 + 1 + 1`. - -Young diagrams associated to the partitions of the positive -integers `1` through `8`. They are arranged so that images -under the reflection about the main diagonal of the square -are conjugate partitions. - -![Integer Partition](https://upload.wikimedia.org/wikipedia/commons/d/d8/Ferrer_partitioning_diagrams.svg) - -## References - -- [Wikipedia]() -- [YouTube](https://www.youtube.com/watch?v=ZaVM057DuzE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/math/integer-partition/integerPartition.js b/docs/content/DS_ALGO/algorithms/math/integer-partition/integerPartition.js deleted file mode 100644 index 0c9b252bb2..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/integer-partition/integerPartition.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @param {number} number - * @return {number} - */ -export default function integerPartition(number) { - // Create partition matrix for solving this task using Dynamic Programming. - const partitionMatrix = Array(number + 1) - .fill(null) - .map(() => { - return Array(number + 1).fill(null); - }); - // Fill partition matrix with initial values. - // Let's fill the first row that represents how many ways we would have - // to combine the numbers 1, 2, 3, ..., n with number 0. We would have zero - // ways obviously since with zero number we may form only zero. - for (let numberIndex = 1; numberIndex <= number; numberIndex += 1) { - partitionMatrix[0][numberIndex] = 0; - } - // Let's fill the first column. It represents the number of ways we can form - // number zero out of numbers 0, 0 and 1, 0 and 1 and 2, 0 and 1 and 2 and 3, ... - // Obviously there is only one way we could form number 0 - // and it is with number 0 itself. - for (let summandIndex = 0; summandIndex <= number; summandIndex += 1) { - partitionMatrix[summandIndex][0] = 1; - } - // Now let's go through other possible options of how we could form number m out of - // summands 0, 1, ..., m using Dynamic Programming approach. - for (let summandIndex = 1; summandIndex <= number; summandIndex += 1) { - for (let numberIndex = 1; numberIndex <= number; numberIndex += 1) { - if (summandIndex > numberIndex) { - // If summand number is bigger then current number itself then just it won't add - // any new ways of forming the number. Thus we may just copy the number from row above. - partitionMatrix[summandIndex][numberIndex] = partitionMatrix[summandIndex - 1][numberIndex]; - } else { - /* - * The number of combinations would equal to number of combinations of forming the same - * number but WITHOUT current summand number PLUS number of combinations of forming the - * number but WITH current summand. - * - * Example: - * Number of ways to form 5 using summands {0, 1, 2} would equal the SUM of: - * - number of ways to form 5 using summands {0, 1} (we've excluded summand 2) - * - number of ways to form 3 (because 5 - 2 = 3) using summands {0, 1, 2} - * (we've included summand 2) - */ - const combosWithoutSummand = partitionMatrix[summandIndex - 1][numberIndex]; - const combosWithSummand = partitionMatrix[summandIndex][numberIndex - summandIndex]; - partitionMatrix[summandIndex][numberIndex] = combosWithoutSummand + combosWithSummand; - } - } - } - return partitionMatrix[number][number]; -} diff --git a/docs/content/DS_ALGO/algorithms/math/integer-partition/test/integerPartition.test.js b/docs/content/DS_ALGO/algorithms/math/integer-partition/test/integerPartition.test.js deleted file mode 100644 index 8c4c533f0b..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/integer-partition/test/integerPartition.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import integerPartition from '../integerPartition'; -describe('integerPartition', () => { - it('should partition the number', () => { - expect(integerPartition(1)).toBe(1); - expect(integerPartition(2)).toBe(2); - expect(integerPartition(3)).toBe(3); - expect(integerPartition(4)).toBe(5); - expect(integerPartition(5)).toBe(7); - expect(integerPartition(6)).toBe(11); - expect(integerPartition(7)).toBe(15); - expect(integerPartition(8)).toBe(22); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/README.md b/docs/content/DS_ALGO/algorithms/math/is-power-of-two/README.md deleted file mode 100644 index 8e79ce29e1..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Is a power of two - -Given a positive integer, write a function to find if it is -a power of two or not. - -**Naive solution** - -In naive solution we just keep dividing the number by two -unless the number becomes `1` and every time we do so, we -check that remainder after division is always `0`. Otherwise, the number can't be a power of two. - -**Bitwise solution** - -Powers of two in binary form always have just one bit set. -The only exception is with a signed integer (e.g. an 8-bit -signed integer with a value of -128 looks like: `10000000`) - -``` -1: 0001 -2: 0010 -4: 0100 -8: 1000 -``` - -So after checking that the number is greater than zero, -we can use a bitwise hack to test that one and only one -bit is set. - -``` -number & (number - 1) -``` - -For example for number `8` that operations will look like: - -``` - 1000 -- 0001 - ---- - 0111 - - 1000 -& 0111 - ---- - 0000 -``` - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/program-to-find-whether-a-no-is-power-of-two/) -- [Bitwise Solution on Stanford](http://www.graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2) -- [Binary number subtraction on YouTube](https://www.youtube.com/watch?v=S9LJknZTyos&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=66) diff --git a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwo.js b/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwo.js deleted file mode 100644 index 035de33149..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwo.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @param {number} number - * @return {boolean} - */ -export default function isPowerOfTwo(number) { - // 1 (2^0) is the smallest power of two. - if (number < 1) { - return false; - } - // Let's find out if we can divide the number by two - // many times without remainder. - let dividedNumber = number; - while (dividedNumber !== 1) { - if (dividedNumber % 2 !== 0) { - // For every case when remainder isn't zero we can say that this number - // couldn't be a result of power of two. - return false; - } - dividedNumber /= 2; - } - return true; -} diff --git a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwoBitwise.js b/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwoBitwise.js deleted file mode 100644 index 1a1c301174..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/isPowerOfTwoBitwise.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param {number} number - * @return {boolean} - */ -export default function isPowerOfTwoBitwise(number) { - // 1 (2^0) is the smallest power of two. - if (number < 1) { - return false; - } - /* - * Powers of two in binary look like this: - * 1: 0001 - * 2: 0010 - * 4: 0100 - * 8: 1000 - * - * Note that there is always exactly 1 bit set. The only exception is with a signed integer. - * e.g. An 8-bit signed integer with a value of -128 looks like: - * 10000000 - * - * So after checking that the number is greater than zero, we can use a clever little bit - * hack to test that one and only one bit is set. - */ - return (number & (number - 1)) === 0; -} diff --git a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwo.test.js b/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwo.test.js deleted file mode 100644 index 2bbbf7c9b7..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwo.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import isPowerOfTwo from '../isPowerOfTwo'; -describe('isPowerOfTwo', () => { - it('should check if the number is made by multiplying twos', () => { - expect(isPowerOfTwo(-1)).toBe(false); - expect(isPowerOfTwo(0)).toBe(false); - expect(isPowerOfTwo(1)).toBe(true); - expect(isPowerOfTwo(2)).toBe(true); - expect(isPowerOfTwo(3)).toBe(false); - expect(isPowerOfTwo(4)).toBe(true); - expect(isPowerOfTwo(5)).toBe(false); - expect(isPowerOfTwo(6)).toBe(false); - expect(isPowerOfTwo(7)).toBe(false); - expect(isPowerOfTwo(8)).toBe(true); - expect(isPowerOfTwo(10)).toBe(false); - expect(isPowerOfTwo(12)).toBe(false); - expect(isPowerOfTwo(16)).toBe(true); - expect(isPowerOfTwo(31)).toBe(false); - expect(isPowerOfTwo(64)).toBe(true); - expect(isPowerOfTwo(1024)).toBe(true); - expect(isPowerOfTwo(1023)).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwoBitwise.test.js b/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwoBitwise.test.js deleted file mode 100644 index 794cc3d287..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/is-power-of-two/test/isPowerOfTwoBitwise.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import isPowerOfTwoBitwise from '../isPowerOfTwoBitwise'; -describe('isPowerOfTwoBitwise', () => { - it('should check if the number is made by multiplying twos', () => { - expect(isPowerOfTwoBitwise(-1)).toBe(false); - expect(isPowerOfTwoBitwise(0)).toBe(false); - expect(isPowerOfTwoBitwise(1)).toBe(true); - expect(isPowerOfTwoBitwise(2)).toBe(true); - expect(isPowerOfTwoBitwise(3)).toBe(false); - expect(isPowerOfTwoBitwise(4)).toBe(true); - expect(isPowerOfTwoBitwise(5)).toBe(false); - expect(isPowerOfTwoBitwise(6)).toBe(false); - expect(isPowerOfTwoBitwise(7)).toBe(false); - expect(isPowerOfTwoBitwise(8)).toBe(true); - expect(isPowerOfTwoBitwise(10)).toBe(false); - expect(isPowerOfTwoBitwise(12)).toBe(false); - expect(isPowerOfTwoBitwise(16)).toBe(true); - expect(isPowerOfTwoBitwise(31)).toBe(false); - expect(isPowerOfTwoBitwise(64)).toBe(true); - expect(isPowerOfTwoBitwise(1024)).toBe(true); - expect(isPowerOfTwoBitwise(1023)).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/README.md b/docs/content/DS_ALGO/algorithms/math/least-common-multiple/README.md deleted file mode 100644 index 88f38c78ff..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Least common multiple - -In arithmetic and number theory, the least common multiple, -lowest common multiple, or smallest common multiple of -two integers `a` and `b`, usually denoted by `LCM(a, b)`, is -the smallest positive integer that is divisible by -both `a` and `b`. Since division of integers by zero is -undefined, this definition has meaning only if `a` and `b` are -both different from zero. However, some authors define `lcm(a,0)` -as `0` for all `a`, which is the result of taking the `lcm` -to be the least upper bound in the lattice of divisibility. - -## Example - -What is the LCM of 4 and 6? - -Multiples of `4` are: - -``` -4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, ... -``` - -and the multiples of `6` are: - -``` -6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, ... -``` - -Common multiples of `4` and `6` are simply the numbers -that are in both lists: - -``` -12, 24, 36, 48, 60, 72, .... -``` - -So, from this list of the first few common multiples of -the numbers `4` and `6`, their least common multiple is `12`. - -## Computing the least common multiple - -The following formula reduces the problem of computing the -least common multiple to the problem of computing the greatest -common divisor (GCD), also known as the greatest common factor: - -``` -lcm(a, b) = |a * b| / gcd(a, b) -``` - -![LCM](https://upload.wikimedia.org/wikipedia/commons/c/c9/Symmetrical_5-set_Venn_diagram_LCM_2_3_4_5_7.svg) - -A Venn diagram showing the least common multiples of -combinations of `2`, `3`, `4`, `5` and `7` (`6` is skipped as -it is `2 × 3`, both of which are already represented). - -For example, a card game which requires its cards to be -divided equally among up to `5` players requires at least `60` -cards, the number at the intersection of the `2`, `3`, `4` -and `5` sets, but not the `7` set. - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Least_common_multiple) diff --git a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/leastCommonMultiple.js b/docs/content/DS_ALGO/algorithms/math/least-common-multiple/leastCommonMultiple.js deleted file mode 100644 index 907ab7c594..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/leastCommonMultiple.js +++ /dev/null @@ -1,9 +0,0 @@ -import euclideanAlgorithm from '../euclidean-algorithm/euclideanAlgorithm'; -/** - * @param {number} a - * @param {number} b - * @return {number} - */ -export default function leastCommonMultiple(a, b) { - return a === 0 || b === 0 ? 0 : Math.abs(a * b) / euclideanAlgorithm(a, b); -} diff --git a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/test/leastCommonMultiple.test.js b/docs/content/DS_ALGO/algorithms/math/least-common-multiple/test/leastCommonMultiple.test.js deleted file mode 100644 index b30e217c95..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/least-common-multiple/test/leastCommonMultiple.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import leastCommonMultiple from '../leastCommonMultiple'; -describe('leastCommonMultiple', () => { - it('should find least common multiple', () => { - expect(leastCommonMultiple(0, 0)).toBe(0); - expect(leastCommonMultiple(1, 0)).toBe(0); - expect(leastCommonMultiple(0, 1)).toBe(0); - expect(leastCommonMultiple(4, 6)).toBe(12); - expect(leastCommonMultiple(6, 21)).toBe(42); - expect(leastCommonMultiple(7, 2)).toBe(14); - expect(leastCommonMultiple(3, 5)).toBe(15); - expect(leastCommonMultiple(7, 3)).toBe(21); - expect(leastCommonMultiple(1000000, 2)).toBe(1000000); - expect(leastCommonMultiple(-9, -18)).toBe(18); - expect(leastCommonMultiple(-7, -9)).toBe(63); - expect(leastCommonMultiple(-7, 9)).toBe(63); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/matrix/Matrix.js b/docs/content/DS_ALGO/algorithms/math/matrix/Matrix.js deleted file mode 100644 index 87199d414f..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/matrix/Matrix.js +++ /dev/null @@ -1,272 +0,0 @@ -/** - * @typedef {number} Cell - * @typedef {Cell[][]|Cell[][][]} Matrix - * @typedef {number[]} Shape - * @typedef {number[]} CellIndices - */ -/** - * Gets the matrix's shape. - * - * @param {Matrix} m - * @returns {Shape} - */ -export const shape = (m) => { - const shapes = []; - let dimension = m; - while (dimension && Array.isArray(dimension)) { - shapes.push(dimension.length); - dimension = (dimension.length && [...dimension][0]) || null; - } - return shapes; -}; -/** - * Checks if matrix has a correct type. - * - * @param {Matrix} m - * @throws {Error} - */ -const validateType = (m) => { - if (!m || !Array.isArray(m) || !Array.isArray(m[0])) { - throw new Error('Invalid matrix format'); - } -}; -/** - * Checks if matrix is two dimensional. - * - * @param {Matrix} m - * @throws {Error} - */ -const validate2D = (m) => { - validateType(m); - const aShape = shape(m); - if (aShape.length !== 2) { - throw new Error('Matrix is not of 2D shape'); - } -}; -/** - * Validates that matrices are of the same shape. - * - * @param {Matrix} a - * @param {Matrix} b - * @trows {Error} - */ -export const validateSameShape = (a, b) => { - validateType(a); - validateType(b); - const aShape = shape(a); - const bShape = shape(b); - if (aShape.length !== bShape.length) { - throw new Error('Matrices have different dimensions'); - } - while (aShape.length && bShape.length) { - if (aShape.pop() !== bShape.pop()) { - throw new Error('Matrices have different shapes'); - } - } -}; -/** - * Generates the matrix of specific shape with specific values. - * - * @param {Shape} mShape - the shape of the matrix to generate - * @param {function({CellIndex}): Cell} fill - cell values of a generated matrix. - * @returns {Matrix} - */ -export const generate = (mShape, fill) => { - /** - * Generates the matrix recursively. - * - * @param {Shape} recShape - the shape of the matrix to generate - * @param {CellIndices} recIndices - * @returns {Matrix} - */ - const generateRecursively = (recShape, recIndices) => { - if (recShape.length === 1) { - return Array(recShape[0]) - .fill(null) - .map((cellValue, cellIndex) => fill([...recIndices, cellIndex])); - } - const m = []; - for (let i = 0; i < recShape[0]; i += 1) { - m.push(generateRecursively(recShape.slice(1), [...recIndices, i])); - } - return m; - }; - return generateRecursively(mShape, []); -}; -/** - * Generates the matrix of zeros of specified shape. - * - * @param {Shape} mShape - shape of the matrix - * @returns {Matrix} - */ -export const zeros = (mShape) => { - return generate(mShape, () => 0); -}; -/** - * @param {Matrix} a - * @param {Matrix} b - * @return Matrix - * @throws {Error} - */ -export const dot = (a, b) => { - // Validate inputs. - validate2D(a); - validate2D(b); - // Check dimensions. - const aShape = shape(a); - const bShape = shape(b); - if (aShape[1] !== bShape[0]) { - throw new Error('Matrices have incompatible shape for multiplication'); - } - // Perform matrix multiplication. - const outputShape = [aShape[0], bShape[1]]; - const c = zeros(outputShape); - for (let bCol = 0; bCol < b[0].length; bCol += 1) { - for (let aRow = 0; aRow < a.length; aRow += 1) { - let cellSum = 0; - for (let aCol = 0; aCol < a[aRow].length; aCol += 1) { - cellSum += a[aRow][aCol] * b[aCol][bCol]; - } - c[aRow][bCol] = cellSum; - } - } - return c; -}; -/** - * Transposes the matrix. - * - * @param {Matrix} m - * @returns Matrix - * @throws {Error} - */ -export const t = (m) => { - validate2D(m); - const mShape = shape(m); - const transposed = zeros([mShape[1], mShape[0]]); - for (let row = 0; row < m.length; row += 1) { - for (let col = 0; col < m[0].length; col += 1) { - transposed[col][row] = m[row][col]; - } - } - return transposed; -}; -/** - * Traverses the matrix. - * - * @param {Matrix} m - * @param {function(indices: CellIndices, c: Cell)} visit - */ -export const walk = (m, visit) => { - /** - * Traverses the matrix recursively. - * - * @param {Matrix} recM - * @param {CellIndices} cellIndices - * @return {Matrix} - */ - const recWalk = (recM, cellIndices) => { - const recMShape = shape(recM); - if (recMShape.length === 1) { - for (let i = 0; i < recM.length; i += 1) { - visit([...cellIndices, i], recM[i]); - } - } - for (let i = 0; i < recM.length; i += 1) { - recWalk(recM[i], [...cellIndices, i]); - } - }; - recWalk(m, []); -}; -/** - * Gets the matrix cell value at specific index. - * - * @param {Matrix} m - Matrix that contains the cell that needs to be updated - * @param {CellIndices} cellIndices - Array of cell indices - * @return {Cell} - */ -export const getCellAtIndex = (m, cellIndices) => { - // We start from the row at specific index. - let cell = m[cellIndices[0]]; - // Going deeper into the next dimensions but not to the last one to preserve - // the pointer to the last dimension array. - for (let dimIdx = 1; dimIdx < cellIndices.length - 1; dimIdx += 1) { - cell = cell[cellIndices[dimIdx]]; - } - // At this moment the cell variable points to the array at the last needed dimension. - return cell[cellIndices[cellIndices.length - 1]]; -}; -/** - * Update the matrix cell at specific index. - * - * @param {Matrix} m - Matrix that contains the cell that needs to be updated - * @param {CellIndices} cellIndices - Array of cell indices - * @param {Cell} cellValue - New cell value - */ -export const updateCellAtIndex = (m, cellIndices, cellValue) => { - // We start from the row at specific index. - let cell = m[cellIndices[0]]; - // Going deeper into the next dimensions but not to the last one to preserve - // the pointer to the last dimension array. - for (let dimIdx = 1; dimIdx < cellIndices.length - 1; dimIdx += 1) { - cell = cell[cellIndices[dimIdx]]; - } - // At this moment the cell variable points to the array at the last needed dimension. - cell[cellIndices[cellIndices.length - 1]] = cellValue; -}; -/** - * Adds two matrices element-wise. - * - * @param {Matrix} a - * @param {Matrix} b - * @return {Matrix} - */ -export const add = (a, b) => { - validateSameShape(a, b); - const result = zeros(shape(a)); - walk(a, (cellIndices, cellValue) => { - updateCellAtIndex(result, cellIndices, cellValue); - }); - walk(b, (cellIndices, cellValue) => { - const currentCellValue = getCellAtIndex(result, cellIndices); - updateCellAtIndex(result, cellIndices, currentCellValue + cellValue); - }); - return result; -}; -/** - * Multiplies two matrices element-wise. - * - * @param {Matrix} a - * @param {Matrix} b - * @return {Matrix} - */ -export const mul = (a, b) => { - validateSameShape(a, b); - const result = zeros(shape(a)); - walk(a, (cellIndices, cellValue) => { - updateCellAtIndex(result, cellIndices, cellValue); - }); - walk(b, (cellIndices, cellValue) => { - const currentCellValue = getCellAtIndex(result, cellIndices); - updateCellAtIndex(result, cellIndices, currentCellValue * cellValue); - }); - return result; -}; -/** - * Subtract two matrices element-wise. - * - * @param {Matrix} a - * @param {Matrix} b - * @return {Matrix} - */ -export const sub = (a, b) => { - validateSameShape(a, b); - const result = zeros(shape(a)); - walk(a, (cellIndices, cellValue) => { - updateCellAtIndex(result, cellIndices, cellValue); - }); - walk(b, (cellIndices, cellValue) => { - const currentCellValue = getCellAtIndex(result, cellIndices); - updateCellAtIndex(result, cellIndices, currentCellValue - cellValue); - }); - return result; -}; diff --git a/docs/content/DS_ALGO/algorithms/math/matrix/README.md b/docs/content/DS_ALGO/algorithms/math/matrix/README.md deleted file mode 100644 index bfe021ff6b..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/matrix/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# Matrices - -In mathematics, a **matrix** (plural **matrices**) is a rectangular array or table of numbers, symbols, or expressions, arranged in rows and columns. For example, the dimension of the matrix below is `2 × 3` (read "two by three"), because there are two rows and three columns: - -``` -| 1 9 -13 | -| 20 5 -6 | -``` - -![An `m × n` matrix](https://upload.wikimedia.org/wikipedia/commons/b/bf/Matris.png) - -An `m × n` matrix: the `m` rows are horizontal, and the `n` columns are vertical. Each element of a matrix is often denoted by a variable with two subscripts. For example, a2,1 represents the element at the second row and first column of the matrix - -## Operations on matrices - -### Addition - -To add two matrices: add the numbers in the matching positions: - -![Matrices addition](https://www.mathsisfun.com/algebra/images/matrix-addition.gif) - -The two matrices must be the same size, i.e. the rows must match in size, and the columns must match in size. - -### Subtracting - -To subtract two matrices: subtract the numbers in the matching positions: - -![Matrices subtraction](https://www.mathsisfun.com/algebra/images/matrix-subtraction.gif) - -### Multiply by a Constant - -We can multiply a matrix by a constant (the value 2 in this case): - -![Matrices multiplication be a constant](https://www.mathsisfun.com/algebra/images/matrix-multiply-constant.gif) - -### Multiplying by Another Matrix - -To multiply a matrix by another matrix we need to do the [dot product](https://www.mathsisfun.com/algebra/vectors-dot-product.html) of rows and columns. - -To work out the answer for the **1st row** and **1st column**: - -![Matrices multiplication - 1st step](https://www.mathsisfun.com/algebra/images/matrix-multiply-a.svg) - -Here it is for the 1st row and 2nd column: - -![Matrices multiplication - 2st step](https://www.mathsisfun.com/algebra/images/matrix-multiply-b.svg) - -If we'll do the same for the rest of the rows and columns we'll get the following resulting matrix: - -![Matrices multiplication - Result](https://www.mathsisfun.com/algebra/images/matrix-multiply-c.svg) - -### Transposing - -To "transpose" a matrix, swap the rows and columns. - -We put a "T" in the top right-hand corner to mean transpose: - -![Transposing](https://www.mathsisfun.com/algebra/images/matrix-transpose.gif) - -## References - -- [Matrices on MathIsFun](https://www.mathsisfun.com/algebra/matrix-introduction.html) -- [Matrix on Wikipedia]() diff --git a/docs/content/DS_ALGO/algorithms/math/matrix/__tests__/Matrix.test.js b/docs/content/DS_ALGO/algorithms/math/matrix/__tests__/Matrix.test.js deleted file mode 100644 index e6f1ee5f65..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/matrix/__tests__/Matrix.test.js +++ /dev/null @@ -1,325 +0,0 @@ -import * as mtrx from '../Matrix'; -describe('Matrix', () => { - it('should throw when trying to add matrices of invalid shapes', () => { - expect(() => mtrx.dot([0], [1])).toThrowError('Invalid matrix format'); - expect(() => mtrx.dot([[0]], [1])).toThrowError('Invalid matrix format'); - expect(() => mtrx.dot([[[0]]], [[1]])).toThrowError('Matrix is not of 2D shape'); - expect(() => mtrx.dot([[0]], [[1], [2]])).toThrowError('Matrices have incompatible shape for multiplication'); - }); - it('should calculate matrices dimensions', () => { - expect(mtrx.shape([])).toEqual([0]); - expect(mtrx.shape([[]])).toEqual([1, 0]); - expect(mtrx.shape([[0]])).toEqual([1, 1]); - expect(mtrx.shape([[0, 0]])).toEqual([1, 2]); - expect( - mtrx.shape([ - [0, 0], - [0, 0] - ]) - ).toEqual([2, 2]); - expect( - mtrx.shape([ - [0, 0, 0], - [0, 0, 0] - ]) - ).toEqual([2, 3]); - expect( - mtrx.shape([ - [0, 0], - [0, 0], - [0, 0] - ]) - ).toEqual([3, 2]); - expect( - mtrx.shape([ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ]) - ).toEqual([3, 3]); - expect(mtrx.shape([[0], [0], [0]])).toEqual([3, 1]); - expect( - mtrx.shape([ - [[0], [0], [0]], - [[0], [0], [0]], - [[0], [0], [0]] - ]) - ).toEqual([3, 3, 1]); - expect( - mtrx.shape([ - [ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ], - [ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ], - [ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ] - ]) - ).toEqual([3, 3, 3]); - }); - it('should generate the matrix of zeros', () => { - expect(mtrx.zeros([1, 0])).toEqual([[]]); - expect(mtrx.zeros([1, 1])).toEqual([[0]]); - expect(mtrx.zeros([1, 3])).toEqual([[0, 0, 0]]); - expect(mtrx.zeros([3, 3])).toEqual([ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0] - ]); - expect(mtrx.zeros([3, 3, 1])).toEqual([ - [[0], [0], [0]], - [[0], [0], [0]], - [[0], [0], [0]] - ]); - }); - it('should generate the matrix with custom values', () => { - expect(mtrx.generate([1, 0], () => 1)).toEqual([[]]); - expect(mtrx.generate([1, 1], () => 1)).toEqual([[1]]); - expect(mtrx.generate([1, 3], () => 1)).toEqual([[1, 1, 1]]); - expect(mtrx.generate([3, 3], () => 1)).toEqual([ - [1, 1, 1], - [1, 1, 1], - [1, 1, 1] - ]); - expect(mtrx.generate([3, 3, 1], () => 1)).toEqual([ - [[1], [1], [1]], - [[1], [1], [1]], - [[1], [1], [1]] - ]); - }); - it('should generate a custom matrix based on specific cell indices', () => { - const indicesCallback = jest.fn((indices) => { - return indices[0] * 10 + indices[1]; - }); - const m = mtrx.generate([3, 3], indicesCallback); - expect(indicesCallback).toHaveBeenCalledTimes(3 * 3); - expect(indicesCallback.mock.calls[0][0]).toEqual([0, 0]); - expect(indicesCallback.mock.calls[1][0]).toEqual([0, 1]); - expect(indicesCallback.mock.calls[2][0]).toEqual([0, 2]); - expect(indicesCallback.mock.calls[3][0]).toEqual([1, 0]); - expect(indicesCallback.mock.calls[4][0]).toEqual([1, 1]); - expect(indicesCallback.mock.calls[5][0]).toEqual([1, 2]); - expect(indicesCallback.mock.calls[6][0]).toEqual([2, 0]); - expect(indicesCallback.mock.calls[7][0]).toEqual([2, 1]); - expect(indicesCallback.mock.calls[8][0]).toEqual([2, 2]); - expect(m).toEqual([ - [0, 1, 2], - [10, 11, 12], - [20, 21, 22] - ]); - }); - it('should multiply two matrices', () => { - let c; - c = mtrx.dot( - [ - [1, 2], - [3, 4] - ], - [ - [5, 6], - [7, 8] - ] - ); - expect(mtrx.shape(c)).toEqual([2, 2]); - expect(c).toEqual([ - [19, 22], - [43, 50] - ]); - c = mtrx.dot( - [ - [1, 2], - [3, 4] - ], - [[5], [6]] - ); - expect(mtrx.shape(c)).toEqual([2, 1]); - expect(c).toEqual([[17], [39]]); - c = mtrx.dot( - [ - [1, 2, 3], - [4, 5, 6] - ], - [ - [7, 8], - [9, 10], - [11, 12] - ] - ); - expect(mtrx.shape(c)).toEqual([2, 2]); - expect(c).toEqual([ - [58, 64], - [139, 154] - ]); - c = mtrx.dot( - [[3, 4, 2]], - [ - [13, 9, 7, 5], - [8, 7, 4, 6], - [6, 4, 0, 3] - ] - ); - expect(mtrx.shape(c)).toEqual([1, 4]); - expect(c).toEqual([[83, 63, 37, 45]]); - }); - it('should transpose matrices', () => { - expect(mtrx.t([[1, 2, 3]])).toEqual([[1], [2], [3]]); - expect(mtrx.t([[1], [2], [3]])).toEqual([[1, 2, 3]]); - expect( - mtrx.t([ - [1, 2, 3], - [4, 5, 6] - ]) - ).toEqual([ - [1, 4], - [2, 5], - [3, 6] - ]); - expect( - mtrx.t([ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]) - ).toEqual([ - [1, 4, 7], - [2, 5, 8], - [3, 6, 9] - ]); - }); - it('should throw when trying to transpose non 2D matrix', () => { - expect(() => { - mtrx.t([[[1]]]); - }).toThrowError('Matrix is not of 2D shape'); - }); - it('should add two matrices', () => { - expect(mtrx.add([[1]], [[2]])).toEqual([[3]]); - expect(mtrx.add([[1, 2, 3]], [[4, 5, 6]])).toEqual([[5, 7, 9]]); - expect(mtrx.add([[1], [2], [3]], [[4], [5], [6]])).toEqual([[5], [7], [9]]); - expect( - mtrx.add( - [ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ], - [ - [10, 11, 12], - [13, 14, 15], - [16, 17, 18] - ] - ) - ).toEqual([ - [11, 13, 15], - [17, 19, 21], - [23, 25, 27] - ]); - expect( - mtrx.add( - [ - [[1], [2], [3]], - [[4], [5], [6]], - [[7], [8], [9]] - ], - [ - [[10], [11], [12]], - [[13], [14], [15]], - [[16], [17], [18]] - ] - ) - ).toEqual([ - [[11], [13], [15]], - [[17], [19], [21]], - [[23], [25], [27]] - ]); - }); - it('should throw when trying to add matrices of different shape', () => { - expect(() => mtrx.add([[0]], [[[0]]])).toThrowError('Matrices have different dimensions'); - expect(() => mtrx.add([[0]], [[0, 0]])).toThrowError('Matrices have different shapes'); - }); - it('should do element wise multiplication two matrices', () => { - expect(mtrx.mul([[2]], [[3]])).toEqual([[6]]); - expect(mtrx.mul([[1, 2, 3]], [[4, 5, 6]])).toEqual([[4, 10, 18]]); - expect(mtrx.mul([[1], [2], [3]], [[4], [5], [6]])).toEqual([[4], [10], [18]]); - expect( - mtrx.mul( - [ - [1, 2], - [3, 4] - ], - [ - [5, 6], - [7, 8] - ] - ) - ).toEqual([ - [5, 12], - [21, 32] - ]); - expect( - mtrx.mul( - [ - [[1], [2]], - [[3], [4]] - ], - [ - [[5], [6]], - [[7], [8]] - ] - ) - ).toEqual([ - [[5], [12]], - [[21], [32]] - ]); - }); - it('should throw when trying to multiply matrices element-wise of different shape', () => { - expect(() => mtrx.mul([[0]], [[[0]]])).toThrowError('Matrices have different dimensions'); - expect(() => mtrx.mul([[0]], [[0, 0]])).toThrowError('Matrices have different shapes'); - }); - it('should do element wise subtraction two matrices', () => { - expect(mtrx.sub([[3]], [[2]])).toEqual([[1]]); - expect(mtrx.sub([[10, 12, 14]], [[4, 5, 6]])).toEqual([[6, 7, 8]]); - expect(mtrx.sub([[[10], [12], [14]]], [[[4], [5], [6]]])).toEqual([[[6], [7], [8]]]); - expect( - mtrx.sub( - [ - [10, 20], - [30, 40] - ], - [ - [5, 6], - [7, 8] - ] - ) - ).toEqual([ - [5, 14], - [23, 32] - ]); - expect( - mtrx.sub( - [ - [[10], [20]], - [[30], [40]] - ], - [ - [[5], [6]], - [[7], [8]] - ] - ) - ).toEqual([ - [[5], [14]], - [[23], [32]] - ]); - }); - it('should throw when trying to subtract matrices element-wise of different shape', () => { - expect(() => mtrx.sub([[0]], [[[0]]])).toThrowError('Matrices have different dimensions'); - expect(() => mtrx.sub([[0]], [[0, 0]])).toThrowError('Matrices have different shapes'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/README.md b/docs/content/DS_ALGO/algorithms/math/pascal-triangle/README.md deleted file mode 100644 index 8405e25af5..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Pascal's Triangle - -In mathematics, **Pascal's triangle** is a triangular array of -the [binomial coefficients](https://en.wikipedia.org/wiki/Binomial_coefficient). - -The rows of Pascal's triangle are conventionally enumerated -starting with row `n = 0` at the top (the `0th` row). The -entries in each row are numbered from the left beginning -with `k = 0` and are usually staggered relative to the -numbers in the adjacent rows. The triangle may be constructed -in the following manner: In row `0` (the topmost row), there -is a unique nonzero entry `1`. Each entry of each subsequent -row is constructed by adding the number above and to the -left with the number above and to the right, treating blank -entries as `0`. For example, the initial number in the -first (or any other) row is `1` (the sum of `0` and `1`), -whereas the numbers `1` and `3` in the third row are added -to produce the number `4` in the fourth row. - -![Pascal's Triangle](https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif) - -## Formula - -The entry in the `nth` row and `kth` column of Pascal's -triangle is denoted ![Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/206415d3742167e319b2e52c2ca7563b799abad7). -For example, the unique nonzero entry in the topmost -row is ![Formula example](https://wikimedia.org/api/rest_v1/media/math/render/svg/b7e35f86368d5978b46c07fd6dddca86bd6e635c). - -With this notation, the construction of the previous -paragraph may be written as follows: - -![Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/203b128a098e18cbb8cf36d004bd7282b28461bf) - -for any non-negative integer `n` and any -integer `k` between `0` and `n`, inclusive. - -![Binomial Coefficient](https://wikimedia.org/api/rest_v1/media/math/render/svg/a2457a7ef3c77831e34e06a1fe17a80b84a03181) - -## Calculating triangle entries in O(n) time - -We know that `i`-th entry in a line number `lineNumber` is -Binomial Coefficient `C(lineNumber, i)` and all lines start -with value `1`. The idea is to -calculate `C(lineNumber, i)` using `C(lineNumber, i-1)`. It -can be calculated in `O(1)` time using the following: - -``` -C(lineNumber, i) = lineNumber! / ((lineNumber - i)! * i!) -C(lineNumber, i - 1) = lineNumber! / ((lineNumber - i + 1)! * (i - 1)!) -``` - -We can derive following expression from above two expressions: - -``` -C(lineNumber, i) = C(lineNumber, i - 1) * (lineNumber - i + 1) / i -``` - -So `C(lineNumber, i)` can be calculated -from `C(lineNumber, i - 1)` in `O(1)` time. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Pascal%27s_triangle) -- [GeeksForGeeks](https://www.geeksforgeeks.org/pascal-triangle/) diff --git a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangle.js b/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangle.js deleted file mode 100644 index 563e6a3c0a..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangle.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @param {number} lineNumber - zero based. - * @return {number[]} - */ -export default function pascalTriangle(lineNumber) { - const currentLine = [1]; - const currentLineSize = lineNumber + 1; - for (let numIndex = 1; numIndex < currentLineSize; numIndex += 1) { - // See explanation of this formula in README. - currentLine[numIndex] = (currentLine[numIndex - 1] * (lineNumber - numIndex + 1)) / numIndex; - } - return currentLine; -} diff --git a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangleRecursive.js b/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangleRecursive.js deleted file mode 100644 index eee5eff007..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/pascalTriangleRecursive.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @param {number} lineNumber - zero based. - * @return {number[]} - */ -export default function pascalTriangleRecursive(lineNumber) { - if (lineNumber === 0) { - return [1]; - } - const currentLineSize = lineNumber + 1; - const previousLineSize = currentLineSize - 1; - // Create container for current line values. - const currentLine = []; - // We'll calculate current line based on previous one. - const previousLine = pascalTriangleRecursive(lineNumber - 1); - // Let's go through all elements of current line except the first and - // last one (since they were and will be filled with 1's) and calculate - // current coefficient based on previous line. - for (let numIndex = 0; numIndex < currentLineSize; numIndex += 1) { - const leftCoefficient = numIndex - 1 >= 0 ? previousLine[numIndex - 1] : 0; - const rightCoefficient = numIndex < previousLineSize ? previousLine[numIndex] : 0; - currentLine[numIndex] = leftCoefficient + rightCoefficient; - } - return currentLine; -} diff --git a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangle.test.js b/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangle.test.js deleted file mode 100644 index 5ba42a0767..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangle.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import pascalTriangle from '../pascalTriangle'; -describe('pascalTriangle', () => { - it('should calculate Pascal Triangle coefficients for specific line number', () => { - expect(pascalTriangle(0)).toEqual([1]); - expect(pascalTriangle(1)).toEqual([1, 1]); - expect(pascalTriangle(2)).toEqual([1, 2, 1]); - expect(pascalTriangle(3)).toEqual([1, 3, 3, 1]); - expect(pascalTriangle(4)).toEqual([1, 4, 6, 4, 1]); - expect(pascalTriangle(5)).toEqual([1, 5, 10, 10, 5, 1]); - expect(pascalTriangle(6)).toEqual([1, 6, 15, 20, 15, 6, 1]); - expect(pascalTriangle(7)).toEqual([1, 7, 21, 35, 35, 21, 7, 1]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangleRecursive.test.js b/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangleRecursive.test.js deleted file mode 100644 index a506bed5f2..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/pascal-triangle/test/pascalTriangleRecursive.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import pascalTriangleRecursive from '../pascalTriangleRecursive'; -describe('pascalTriangleRecursive', () => { - it('should calculate Pascal Triangle coefficients for specific line number', () => { - expect(pascalTriangleRecursive(0)).toEqual([1]); - expect(pascalTriangleRecursive(1)).toEqual([1, 1]); - expect(pascalTriangleRecursive(2)).toEqual([1, 2, 1]); - expect(pascalTriangleRecursive(3)).toEqual([1, 3, 3, 1]); - expect(pascalTriangleRecursive(4)).toEqual([1, 4, 6, 4, 1]); - expect(pascalTriangleRecursive(5)).toEqual([1, 5, 10, 10, 5, 1]); - expect(pascalTriangleRecursive(6)).toEqual([1, 6, 15, 20, 15, 6, 1]); - expect(pascalTriangleRecursive(7)).toEqual([1, 7, 21, 35, 35, 21, 7, 1]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/primality-test/README.md b/docs/content/DS_ALGO/algorithms/math/primality-test/README.md deleted file mode 100644 index d63de51377..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/primality-test/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Primality Test - -A **prime number** (or a **prime**) is a natural number greater than `1` that -cannot be formed by multiplying two smaller natural numbers. A natural number -greater than `1` that is not prime is called a composite number. For -example, `5` is prime because the only ways of writing it as a -product, `1 × 5` or `5 × 1`, involve `5` itself. However, `6` is -composite because it is the product of two numbers `(2 × 3)` that are -both smaller than `6`. - -![Prime Numbers](https://upload.wikimedia.org/wikipedia/commons/f/f0/Primes-vs-composites.svg) - -A **primality test** is an algorithm for determining whether an input -number is prime. Among other fields of mathematics, it is used -for cryptography. Unlike integer factorization, primality tests -do not generally give prime factors, only stating whether the -input number is prime or not. Factorization is thought to be -a computationally difficult problem, whereas primality testing -is comparatively easy (its running time is polynomial in the -size of the input). - -## References - -- [Prime Numbers on Wikipedia](https://en.wikipedia.org/wiki/Prime_number) -- [Primality Test on Wikipedia](https://en.wikipedia.org/wiki/Primality_test) diff --git a/docs/content/DS_ALGO/algorithms/math/primality-test/test/trialDivision.test.js b/docs/content/DS_ALGO/algorithms/math/primality-test/test/trialDivision.test.js deleted file mode 100644 index 9676b10bf1..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/primality-test/test/trialDivision.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import trialDivision from '../trialDivision'; -/** - * @param {function(n: number)} testFunction - */ -function primalityTest(testFunction) { - expect(testFunction(1)).toBe(false); - expect(testFunction(2)).toBe(true); - expect(testFunction(3)).toBe(true); - expect(testFunction(5)).toBe(true); - expect(testFunction(11)).toBe(true); - expect(testFunction(191)).toBe(true); - expect(testFunction(191)).toBe(true); - expect(testFunction(199)).toBe(true); - expect(testFunction(-1)).toBe(false); - expect(testFunction(0)).toBe(false); - expect(testFunction(4)).toBe(false); - expect(testFunction(6)).toBe(false); - expect(testFunction(12)).toBe(false); - expect(testFunction(14)).toBe(false); - expect(testFunction(25)).toBe(false); - expect(testFunction(192)).toBe(false); - expect(testFunction(200)).toBe(false); - expect(testFunction(400)).toBe(false); - // It should also deal with floats. - expect(testFunction(0.5)).toBe(false); - expect(testFunction(1.3)).toBe(false); - expect(testFunction(10.5)).toBe(false); -} -describe('trialDivision', () => { - it('should detect prime numbers', () => { - primalityTest(trialDivision); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/primality-test/trialDivision.js b/docs/content/DS_ALGO/algorithms/math/primality-test/trialDivision.js deleted file mode 100644 index 92fbfabcdd..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/primality-test/trialDivision.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @param {number} number - * @return {boolean} - */ -export default function trialDivision(number) { - // Check if number is integer. - if (number % 1 !== 0) { - return false; - } - if (number <= 1) { - // If number is less than one then it isn't prime by definition. - return false; - } - if (number <= 3) { - // All numbers from 2 to 3 are prime. - return true; - } - // If the number is not divided by 2 then we may eliminate all further even dividers. - if (number % 2 === 0) { - return false; - } - // If there is no dividers up to square root of n then there is no higher dividers as well. - const dividerLimit = Math.sqrt(number); - for (let divider = 3; divider <= dividerLimit; divider += 2) { - if (number % divider === 0) { - return false; - } - } - return true; -} diff --git a/docs/content/DS_ALGO/algorithms/math/prime-factors/README.md b/docs/content/DS_ALGO/algorithms/math/prime-factors/README.md deleted file mode 100644 index 4efddcdbcb..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/prime-factors/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Prime Factors - -**Prime number** is a whole number greater than `1` that **cannot** be made by multiplying other whole numbers. The first few prime numbers are: `2`, `3`, `5`, `7`, `11`, `13`, `17`, `19` and so on. - -If we **can** make it by multiplying other whole numbers it is a **Composite Number**. - -![Composite numbers](https://www.mathsisfun.com/numbers/images/prime-composite.svg) - -_Image source: [Math is Fun](https://www.mathsisfun.com/prime-factorization.html)_ - -**Prime factors** are those [prime numbers](https://en.wikipedia.org/wiki/Prime_number) which multiply together to give the original number. For example `39` will have prime factors of `3` and `13` which are also prime numbers. Another example is `15` whose prime factors are `3` and `5`. - -![Factors](https://www.mathsisfun.com/numbers/images/factor-2x3.svg) - -_Image source: [Math is Fun](https://www.mathsisfun.com/prime-factorization.html)_ - -## Finding the prime factors and their count accurately - -The approach is to keep on dividing the natural number `n` by indexes from `i = 2` to `i = n` (by prime indexes only). The value of `n` is being overridden by `(n / i)` on each iteration. - -The time complexity till now is `O(n)` in the worst case scenario since the loop runs from index `i = 2` to `i = n`. This time complexity can be reduced from `O(n)` to `O(sqrt(n))`. The optimisation is achievable when loop runs from `i = 2` to `i = sqrt(n)`. Now, we go only till `O(sqrt(n))` because when `i` becomes greater than `sqrt(n)`, we have the confirmation that there is no index `i` left which can divide `n` completely other than `n` itself. - -## Hardy-Ramanujan formula for approximate calculation of prime-factor count - -In 1917, a theorem was formulated by G.H Hardy and Srinivasa Ramanujan which states that the normal order of the number `ω(n)` of distinct prime factors of a number `n` is `log(log(n))`. - -Roughly speaking, this means that most numbers have about this number of distinct prime factors. - -## References - -- [Prime numbers on Math is Fun](https://www.mathsisfun.com/prime-factorization.html) -- [Prime numbers on Wikipedia](https://en.wikipedia.org/wiki/Prime_number) -- [Hardy-Ramanujan theorem on Wikipedia](https://en.wikipedia.org/wiki/Hardy%E2%80%93Ramanujan_theorem) -- [Prime factorization of a number on Youtube](https://www.youtube.com/watch?v=6PDtgHhpCHo&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=82) diff --git a/docs/content/DS_ALGO/algorithms/math/prime-factors/primeFactors.js b/docs/content/DS_ALGO/algorithms/math/prime-factors/primeFactors.js deleted file mode 100644 index b856e3e0ac..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/prime-factors/primeFactors.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Finds prime factors of a number. - * - * @param {number} n - the number that is going to be split into prime factors. - * @returns {number[]} - array of prime factors. - */ -export function primeFactors(n) { - // Clone n to avoid function arguments override. - let nn = n; - // Array that stores the all the prime factors. - const factors = []; - // Running the loop till sqrt(n) instead of n to optimise time complexity from O(n) to O(sqrt(n)). - for (let factor = 2; factor <= Math.sqrt(nn); factor += 1) { - // Check that factor divides n without a reminder. - while (nn % factor === 0) { - // Overriding the value of n. - nn /= factor; - // Saving the factor. - factors.push(factor); - } - } - // The ultimate reminder should be a last prime factor, - // unless it is not 1 (since 1 is not a prime number). - if (nn !== 1) { - factors.push(nn); - } - return factors; -} -/** - * Hardy-Ramanujan approximation of prime factors count. - * - * @param {number} n - * @returns {number} - approximate number of prime factors. - */ -export function hardyRamanujan(n) { - return Math.log(Math.log(n)); -} diff --git a/docs/content/DS_ALGO/algorithms/math/prime-factors/test/primeFactors.test.js b/docs/content/DS_ALGO/algorithms/math/prime-factors/test/primeFactors.test.js deleted file mode 100644 index 90bf5bbdce..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/prime-factors/test/primeFactors.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import { primeFactors, hardyRamanujan } from '../primeFactors'; -/** - * Calculates the error between exact and approximate prime factor counts. - * @param {number} exactCount - * @param {number} approximateCount - * @returns {number} - approximation error (percentage). - */ -function approximationError(exactCount, approximateCount) { - return Math.abs((exactCount - approximateCount) / exactCount) * 100; -} -describe('primeFactors', () => { - it('should find prime factors', () => { - expect(primeFactors(1)).toEqual([]); - expect(primeFactors(2)).toEqual([2]); - expect(primeFactors(3)).toEqual([3]); - expect(primeFactors(4)).toEqual([2, 2]); - expect(primeFactors(14)).toEqual([2, 7]); - expect(primeFactors(40)).toEqual([2, 2, 2, 5]); - expect(primeFactors(54)).toEqual([2, 3, 3, 3]); - expect(primeFactors(100)).toEqual([2, 2, 5, 5]); - expect(primeFactors(156)).toEqual([2, 2, 3, 13]); - expect(primeFactors(273)).toEqual([3, 7, 13]); - expect(primeFactors(300)).toEqual([2, 2, 3, 5, 5]); - expect(primeFactors(980)).toEqual([2, 2, 5, 7, 7]); - expect(primeFactors(1000)).toEqual([2, 2, 2, 5, 5, 5]); - expect(primeFactors(52734)).toEqual([2, 3, 11, 17, 47]); - expect(primeFactors(343434)).toEqual([2, 3, 7, 13, 17, 37]); - expect(primeFactors(456745)).toEqual([5, 167, 547]); - expect(primeFactors(510510)).toEqual([2, 3, 5, 7, 11, 13, 17]); - expect(primeFactors(8735463)).toEqual([3, 3, 11, 88237]); - expect(primeFactors(873452453)).toEqual([149, 1637, 3581]); - }); - it('should give approximate prime factors count using Hardy-Ramanujan theorem', () => { - expect(hardyRamanujan(2)).toBeCloseTo(-0.366, 2); - expect(hardyRamanujan(4)).toBeCloseTo(0.326, 2); - expect(hardyRamanujan(40)).toBeCloseTo(1.305, 2); - expect(hardyRamanujan(156)).toBeCloseTo(1.6193, 2); - expect(hardyRamanujan(980)).toBeCloseTo(1.929, 2); - expect(hardyRamanujan(52734)).toBeCloseTo(2.386, 2); - expect(hardyRamanujan(343434)).toBeCloseTo(2.545, 2); - expect(hardyRamanujan(456745)).toBeCloseTo(2.567, 2); - expect(hardyRamanujan(510510)).toBeCloseTo(2.575, 2); - expect(hardyRamanujan(8735463)).toBeCloseTo(2.771, 2); - expect(hardyRamanujan(873452453)).toBeCloseTo(3.024, 2); - }); - it('should give correct deviation between exact and approx counts', () => { - expect(approximationError(primeFactors(2).length, hardyRamanujan(2))).toBeCloseTo(136.651, 2); - expect(approximationError(primeFactors(4).length, hardyRamanujan(2))).toBeCloseTo(118.325, 2); - expect(approximationError(primeFactors(40).length, hardyRamanujan(2))).toBeCloseTo(109.162, 2); - expect(approximationError(primeFactors(156).length, hardyRamanujan(2))).toBeCloseTo(109.162, 2); - expect(approximationError(primeFactors(980).length, hardyRamanujan(2))).toBeCloseTo(107.33, 2); - expect(approximationError(primeFactors(52734).length, hardyRamanujan(52734))).toBeCloseTo(52.274, 2); - expect(approximationError(primeFactors(343434).length, hardyRamanujan(343434))).toBeCloseTo(57.578, 2); - expect(approximationError(primeFactors(456745).length, hardyRamanujan(456745))).toBeCloseTo(14.42, 2); - expect(approximationError(primeFactors(510510).length, hardyRamanujan(510510))).toBeCloseTo(63.201, 2); - expect(approximationError(primeFactors(8735463).length, hardyRamanujan(8735463))).toBeCloseTo(30.712, 2); - expect(approximationError(primeFactors(873452453).length, hardyRamanujan(873452453))).toBeCloseTo(0.823, 2); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/radian/README.md b/docs/content/DS_ALGO/algorithms/math/radian/README.md deleted file mode 100644 index 9abaad8784..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/radian/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Radian - -The **radian** (symbol **rad**) is the unit for measuring angles, and is the -standard unit of angular measure used in many areas of mathematics. - -The length of an arc of a unit circle is numerically equal to the measurement -in radians of the angle that it subtends; one radian is just under `57.3` degrees. - -An arc of a circle with the same length as the radius of that circle subtends an -angle of `1 radian`. The circumference subtends an angle of `2π radians`. - -![Radian](https://upload.wikimedia.org/wikipedia/commons/4/4e/Circle_radians.gif) - -A complete revolution is 2π radians (shown here with a circle of radius one and -thus circumference `2π`). - -![2 pi Radian](https://upload.wikimedia.org/wikipedia/commons/6/67/2pi-unrolled.gif) - -**Conversions** - -| Radians | Degrees | -| :-----: | :-----: | -| 0 | 0° | -| π/12 | 15° | -| π/6 | 30° | -| π/4 | 45° | -| 1 | 57.3° | -| π/3 | 60° | -| π/2 | 90° | -| π | 180° | -| 2π | 360° | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Radian) diff --git a/docs/content/DS_ALGO/algorithms/math/radian/degreeToRadian.js b/docs/content/DS_ALGO/algorithms/math/radian/degreeToRadian.js deleted file mode 100644 index ca02c09f29..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/radian/degreeToRadian.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} degree - * @return {number} - */ -export default function degreeToRadian(degree) { - return degree * (Math.PI / 180); -} diff --git a/docs/content/DS_ALGO/algorithms/math/radian/radianToDegree.js b/docs/content/DS_ALGO/algorithms/math/radian/radianToDegree.js deleted file mode 100644 index 5df1a8e643..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/radian/radianToDegree.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @param {number} radian - * @return {number} - */ -export default function radianToDegree(radian) { - return radian * (180 / Math.PI); -} diff --git a/docs/content/DS_ALGO/algorithms/math/radian/test/degreeToRadian.test.js b/docs/content/DS_ALGO/algorithms/math/radian/test/degreeToRadian.test.js deleted file mode 100644 index 9e109ea2d2..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/radian/test/degreeToRadian.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import degreeToRadian from '../degreeToRadian'; -describe('degreeToRadian', () => { - it('should convert degree to radian', () => { - expect(degreeToRadian(0)).toBe(0); - expect(degreeToRadian(45)).toBe(Math.PI / 4); - expect(degreeToRadian(90)).toBe(Math.PI / 2); - expect(degreeToRadian(180)).toBe(Math.PI); - expect(degreeToRadian(270)).toBe((3 * Math.PI) / 2); - expect(degreeToRadian(360)).toBe(2 * Math.PI); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/radian/test/radianToDegree.test.js b/docs/content/DS_ALGO/algorithms/math/radian/test/radianToDegree.test.js deleted file mode 100644 index 91037cb9d4..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/radian/test/radianToDegree.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import radianToDegree from '../radianToDegree'; -describe('radianToDegree', () => { - it('should convert radian to degree', () => { - expect(radianToDegree(0)).toBe(0); - expect(radianToDegree(Math.PI / 4)).toBe(45); - expect(radianToDegree(Math.PI / 2)).toBe(90); - expect(radianToDegree(Math.PI)).toBe(180); - expect(radianToDegree((3 * Math.PI) / 2)).toBe(270); - expect(radianToDegree(2 * Math.PI)).toBe(360); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/math/square-root/README.md b/docs/content/DS_ALGO/algorithms/math/square-root/README.md deleted file mode 100644 index 6ab10f6377..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/square-root/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Square Root (Newton's Method) - -In numerical analysis, a branch of mathematics, there are several square root -algorithms or methods of computing the principal square root of a non-negative real -number. As, generally, the roots of a function cannot be computed exactly. -The root-finding algorithms provide approximations to roots expressed as floating -point numbers. - -Finding ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/bff86975b0e7944720b3e635c53c22c032a7a6f1) is -the same as solving the equation ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6cf57722151ef19ba1ca918d702b95c335e21cad) for a -positive `x`. Therefore, any general numerical root-finding algorithm can be used. - -**Newton's method** (also known as the Newton-Raphson method), named after -_Isaac Newton_ and _Joseph Raphson_, is one example of a root-finding algorithm. It is a -method for finding successively better approximations to the roots of a real-valued function. - -Let's start by explaining the general idea of Newton's method and then apply it to our particular -case with finding a square root of the number. - -## Newton's Method General Idea - -The Newton-Raphson method in one variable is implemented as follows: - -The method starts with a function `f` defined over the real numbers `x`, the function's derivative `f'`, and an -initial guess `x0` for a root of the function `f`. If the function satisfies the assumptions made in the derivation -of the formula and the initial guess is close, then a better approximation `x1` is: - -![](https://wikimedia.org/api/rest_v1/media/math/render/svg/52c50eca0b7c4d64ef2fdca678665b73e944cb84) - -Geometrically, `(x1, 0)` is the intersection of the `x`-axis and the tangent of -the graph of `f` at `(x0, f (x0))`. - -The process is repeated as: - -![](https://wikimedia.org/api/rest_v1/media/math/render/svg/710c11b9ec4568d1cfff49b7c7d41e0a7829a736) - -until a sufficiently accurate value is reached. - -![](https://upload.wikimedia.org/wikipedia/commons/e/e0/NewtonIteration_Ani.gif) - -## Newton's Method of Finding a Square Root - -As it was mentioned above, finding ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/bff86975b0e7944720b3e635c53c22c032a7a6f1) is -the same as solving the equation ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6cf57722151ef19ba1ca918d702b95c335e21cad) for a -positive `x`. - -The derivative of the function `f(x)` in case of square root problem is `2x`. - -After applying the Newton's formula (see above) we get the following equation for our algorithm iterations: - -```text -x := x - (x² - S) / (2x) -``` - -The `x² − S` above is how far away `x²` is from where it needs to be, and the -division by `2x` is the derivative of `x²`, to scale how much we adjust `x` by how -quickly `x²` is changing. - -## References - -- [Methods of computing square roots on Wikipedia](https://en.wikipedia.org/wiki/Methods_of_computing_square_roots) -- [Newton's method on Wikipedia](https://en.wikipedia.org/wiki/Newton%27s_method) diff --git a/docs/content/DS_ALGO/algorithms/math/square-root/squareRoot.js b/docs/content/DS_ALGO/algorithms/math/square-root/squareRoot.js deleted file mode 100644 index c8386bed9c..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/square-root/squareRoot.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Calculates the square root of the number with given tolerance (precision) - * by using Newton's method. - * - * @param number - the number we want to find a square root for. - * @param [tolerance] - how many precise numbers after the floating point we want to get. - * @return {number} - */ -export default function squareRoot(number, tolerance = 0) { - // For now we won't support operations that involves manipulation with complex numbers. - if (number < 0) { - throw new Error('The method supports only positive integers'); - } - // Handle edge case with finding the square root of zero. - if (number === 0) { - return 0; - } - // We will start approximation from value 1. - let root = 1; - // Delta is a desired distance between the number and the square of the root. - // - if tolerance=0 then delta=1 - // - if tolerance=1 then delta=0.1 - // - if tolerance=2 then delta=0.01 - // - and so on... - const requiredDelta = 1 / 10 ** tolerance; - // Approximating the root value to the point when we get a desired precision. - while (Math.abs(number - root ** 2) > requiredDelta) { - // Newton's method reduces in this case to the so-called Babylonian method. - // These methods generally yield approximate results, but can be made arbitrarily - // precise by increasing the number of calculation steps. - root -= (root ** 2 - number) / (2 * root); - } - // Cut off undesired floating digits and return the root value. - return Math.round(root * 10 ** tolerance) / 10 ** tolerance; -} diff --git a/docs/content/DS_ALGO/algorithms/math/square-root/test/squareRoot.test.js b/docs/content/DS_ALGO/algorithms/math/square-root/test/squareRoot.test.js deleted file mode 100644 index cd2643a639..0000000000 --- a/docs/content/DS_ALGO/algorithms/math/square-root/test/squareRoot.test.js +++ /dev/null @@ -1,60 +0,0 @@ -import squareRoot from '../squareRoot'; -describe('squareRoot', () => { - it('should throw for negative numbers', () => { - function failingSquareRoot() { - squareRoot(-5); - } - expect(failingSquareRoot).toThrow(); - }); - it('should correctly calculate square root with default tolerance', () => { - expect(squareRoot(0)).toBe(0); - expect(squareRoot(1)).toBe(1); - expect(squareRoot(2)).toBe(1); - expect(squareRoot(3)).toBe(2); - expect(squareRoot(4)).toBe(2); - expect(squareRoot(15)).toBe(4); - expect(squareRoot(16)).toBe(4); - expect(squareRoot(256)).toBe(16); - expect(squareRoot(473)).toBe(22); - expect(squareRoot(14723)).toBe(121); - }); - it('should correctly calculate square root for integers with custom tolerance', () => { - let tolerance = 1; - expect(squareRoot(0, tolerance)).toBe(0); - expect(squareRoot(1, tolerance)).toBe(1); - expect(squareRoot(2, tolerance)).toBe(1.4); - expect(squareRoot(3, tolerance)).toBe(1.8); - expect(squareRoot(4, tolerance)).toBe(2); - expect(squareRoot(15, tolerance)).toBe(3.9); - expect(squareRoot(16, tolerance)).toBe(4); - expect(squareRoot(256, tolerance)).toBe(16); - expect(squareRoot(473, tolerance)).toBe(21.7); - expect(squareRoot(14723, tolerance)).toBe(121.3); - tolerance = 3; - expect(squareRoot(0, tolerance)).toBe(0); - expect(squareRoot(1, tolerance)).toBe(1); - expect(squareRoot(2, tolerance)).toBe(1.414); - expect(squareRoot(3, tolerance)).toBe(1.732); - expect(squareRoot(4, tolerance)).toBe(2); - expect(squareRoot(15, tolerance)).toBe(3.873); - expect(squareRoot(16, tolerance)).toBe(4); - expect(squareRoot(256, tolerance)).toBe(16); - expect(squareRoot(473, tolerance)).toBe(21.749); - expect(squareRoot(14723, tolerance)).toBe(121.338); - tolerance = 10; - expect(squareRoot(0, tolerance)).toBe(0); - expect(squareRoot(1, tolerance)).toBe(1); - expect(squareRoot(2, tolerance)).toBe(1.4142135624); - expect(squareRoot(3, tolerance)).toBe(1.7320508076); - expect(squareRoot(4, tolerance)).toBe(2); - expect(squareRoot(15, tolerance)).toBe(3.8729833462); - expect(squareRoot(16, tolerance)).toBe(4); - expect(squareRoot(256, tolerance)).toBe(16); - expect(squareRoot(473, tolerance)).toBe(21.7485631709); - expect(squareRoot(14723, tolerance)).toBe(121.3383698588); - }); - it('should correctly calculate square root for integers with custom tolerance', () => { - expect(squareRoot(4.5, 10)).toBe(2.1213203436); - expect(squareRoot(217.534, 10)).toBe(14.7490338667); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/ml/k-means/README.md b/docs/content/DS_ALGO/algorithms/ml/k-means/README.md deleted file mode 100644 index 922218b04f..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/k-means/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# k-Means Algorithm - -The **k-Means algorithm** is an unsupervised Machine Learning algorithm. It's a clustering algorithm, which groups the sample data on the basis of similarity between dimensions of vectors. - -In k-Means classification, the output is a set of classes assigned to each vector. Each cluster location is continuously optimized in order to get the accurate locations of each cluster such that they represent each group clearly. - -The idea is to calculate the similarity between cluster location and data vectors, and reassign clusters based on it. [Euclidean distance](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/euclidean-distance) is used mostly for this task. - -![Euclidean distance between two points](https://upload.wikimedia.org/wikipedia/commons/5/55/Euclidean_distance_2d.svg) - -_Image source: [Wikipedia](https://en.wikipedia.org/wiki/Euclidean_distance)_ - -The algorithm is as follows: - -1. Check for errors like invalid/inconsistent data -2. Initialize the `k` cluster locations with initial/random `k` points -3. Calculate the distance of each data point from each cluster -4. Assign the cluster label of each data point equal to that of the cluster at its minimum distance -5. Calculate the centroid of each cluster based on the data points it contains -6. Repeat each of the above steps until the centroid locations are varying - -Here is a visualization of k-Means clustering for better understanding: - -![KNN Visualization 1](https://upload.wikimedia.org/wikipedia/commons/e/ea/K-means_convergence.gif) - -_Image source: [Wikipedia](https://en.wikipedia.org/wiki/K-means_clustering)_ - -The centroids are moving continuously in order to create better distinction between the different set of data points. As we can see, after a few iterations, the difference in centroids is quite low between iterations. For example between iterations `13` and `14` the difference is quite small because there the optimizer is tuning boundary cases. - -## References - -- [k-Means neighbors algorithm on Wikipedia](https://en.wikipedia.org/wiki/K-means_clustering) diff --git a/docs/content/DS_ALGO/algorithms/ml/k-means/kMeans.js b/docs/content/DS_ALGO/algorithms/ml/k-means/kMeans.js deleted file mode 100644 index 24770a5d3f..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/k-means/kMeans.js +++ /dev/null @@ -1,64 +0,0 @@ -import * as mtrx from '../../math/matrix/Matrix'; -import euclideanDistance from '../../math/euclidean-distance/euclideanDistance'; -/** - * Classifies the point in space based on k-Means algorithm. - * - * @param {number[][]} data - array of dataSet points, i.e. [[0, 1], [3, 4], [5, 7]] - * @param {number} k - number of clusters - * @return {number[]} - the class of the point - */ -export default function KMeans(data, k = 1) { - if (!data) { - throw new Error('The data is empty'); - } - // Assign k clusters locations equal to the location of initial k points. - const dataDim = data[0].length; - const clusterCenters = data.slice(0, k); - // Continue optimization till convergence. - // Centroids should not be moving once optimized. - // Calculate distance of each candidate vector from each cluster center. - // Assign cluster number to each data vector according to minimum distance. - // Matrix of distance from each data point to each cluster centroid. - const distances = mtrx.zeros([data.length, k]); - // Vector data points' classes. The value of -1 means that no class has bee assigned yet. - const classes = Array(data.length).fill(-1); - let iterate = true; - while (iterate) { - iterate = false; - // Calculate and store the distance of each data point from each cluster. - for (let dataIndex = 0; dataIndex < data.length; dataIndex += 1) { - for (let clusterIndex = 0; clusterIndex < k; clusterIndex += 1) { - distances[dataIndex][clusterIndex] = euclideanDistance([clusterCenters[clusterIndex]], [data[dataIndex]]); - } - // Assign the closest cluster number to each dataSet point. - const closestClusterIdx = distances[dataIndex].indexOf(Math.min(...distances[dataIndex])); - // Check if data point class has been changed and we still need to re-iterate. - if (classes[dataIndex] !== closestClusterIdx) { - iterate = true; - } - classes[dataIndex] = closestClusterIdx; - } - // Recalculate cluster centroid values via all dimensions of the points under it. - for (let clusterIndex = 0; clusterIndex < k; clusterIndex += 1) { - // Reset cluster center coordinates since we need to recalculate them. - clusterCenters[clusterIndex] = Array(dataDim).fill(0); - let clusterSize = 0; - for (let dataIndex = 0; dataIndex < data.length; dataIndex += 1) { - if (classes[dataIndex] === clusterIndex) { - // Register one more data point of current cluster. - clusterSize += 1; - for (let dimensionIndex = 0; dimensionIndex < dataDim; dimensionIndex += 1) { - // Add data point coordinates to the cluster center coordinates. - clusterCenters[clusterIndex][dimensionIndex] += data[dataIndex][dimensionIndex]; - } - } - } - // Calculate the average for each cluster center coordinate. - for (let dimensionIndex = 0; dimensionIndex < dataDim; dimensionIndex += 1) { - clusterCenters[clusterIndex][dimensionIndex] = parseFloat(Number(clusterCenters[clusterIndex][dimensionIndex] / clusterSize).toFixed(2)); - } - } - } - // Return the clusters assigned. - return classes; -} diff --git a/docs/content/DS_ALGO/algorithms/ml/k-means/test/kMeans.test.js b/docs/content/DS_ALGO/algorithms/ml/k-means/test/kMeans.test.js deleted file mode 100644 index 8f7f7d1461..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/k-means/test/kMeans.test.js +++ /dev/null @@ -1,57 +0,0 @@ -import KMeans from '../kMeans'; -describe('kMeans', () => { - it('should throw an error on invalid data', () => { - expect(() => { - KMeans(); - }).toThrowError('The data is empty'); - }); - it('should throw an error on inconsistent data', () => { - expect(() => { - KMeans([[1, 2], [1]], 2); - }).toThrowError('Matrices have different shapes'); - }); - it('should find the nearest neighbour', () => { - const data = [ - [1, 1], - [6, 2], - [3, 3], - [4, 5], - [9, 2], - [2, 4], - [8, 7] - ]; - const k = 2; - const expectedClusters = [0, 1, 0, 1, 1, 0, 1]; - expect(KMeans(data, k)).toEqual(expectedClusters); - expect( - KMeans( - [ - [0, 0], - [0, 1], - [10, 10] - ], - 2 - ) - ).toEqual([0, 0, 1]); - }); - it('should find the clusters with equal distances', () => { - const dataSet = [ - [0, 0], - [1, 1], - [2, 2] - ]; - const k = 3; - const expectedCluster = [0, 1, 2]; - expect(KMeans(dataSet, k)).toEqual(expectedCluster); - }); - it('should find the nearest neighbour in 3D space', () => { - const dataSet = [ - [0, 0, 0], - [0, 1, 0], - [2, 0, 2] - ]; - const k = 2; - const expectedCluster = [1, 1, 0]; - expect(KMeans(dataSet, k)).toEqual(expectedCluster); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/ml/knn/README.md b/docs/content/DS_ALGO/algorithms/ml/knn/README.md deleted file mode 100644 index c05cb9496d..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/knn/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# k-Nearest Neighbors Algorithm - -The **k-nearest neighbors algorithm (k-NN)** is a supervised Machine Learning algorithm. It's a classification algorithm, determining the class of a sample vector using a sample data. - -In k-NN classification, the output is a class membership. An object is classified by a plurality vote of its neighbors, with the object being assigned to the class most common among its `k` nearest neighbors (`k` is a positive integer, typically small). If `k = 1`, then the object is simply assigned to the class of that single nearest neighbor. - -The idea is to calculate the similarity between two data points on the basis of a distance metric. [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance) is used mostly for this task. - -![Euclidean distance between two points](https://upload.wikimedia.org/wikipedia/commons/5/55/Euclidean_distance_2d.svg) - -_Image source: [Wikipedia](https://en.wikipedia.org/wiki/Euclidean_distance)_ - -The algorithm is as follows: - -1. Check for errors like invalid data/labels. -2. Calculate the euclidean distance of all the data points in training data with the classification point -3. Sort the distances of points along with their classes in ascending order -4. Take the initial `K` classes and find the mode to get the most similar class -5. Report the most similar class - -Here is a visualization of k-NN classification for better understanding: - -![KNN Visualization 1](https://upload.wikimedia.org/wikipedia/commons/e/e7/KnnClassification.svg) - -_Image source: [Wikipedia](https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm)_ - -The test sample (green dot) should be classified either to blue squares or to red triangles. If `k = 3` (solid line circle) it is assigned to the red triangles because there are `2` triangles and only `1` square inside the inner circle. If `k = 5` (dashed line circle) it is assigned to the blue squares (`3` squares vs. `2` triangles inside the outer circle). - -Another k-NN classification example: - -![KNN Visualization 2](https://media.geeksforgeeks.org/wp-content/uploads/graph2-2.png) - -_Image source: [GeeksForGeeks](https://media.geeksforgeeks.org/wp-content/uploads/graph2-2.png)_ - -Here, as we can see, the classification of unknown points will be judged by their proximity to other points. - -It is important to note that `K` is preferred to have odd values in order to break ties. Usually `K` is taken as `3` or `5`. - -## References - -- [k-nearest neighbors algorithm on Wikipedia](https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm) diff --git a/docs/content/DS_ALGO/algorithms/ml/knn/kNN.js b/docs/content/DS_ALGO/algorithms/ml/knn/kNN.js deleted file mode 100644 index e1fdd0bf58..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/knn/kNN.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Classifies the point in space based on k-nearest neighbors algorithm. - * - * @param {number[][]} dataSet - array of data points, i.e. [[0, 1], [3, 4], [5, 7]] - * @param {number[]} labels - array of classes (labels), i.e. [1, 1, 2] - * @param {number[]} toClassify - the point in space that needs to be classified, i.e. [5, 4] - * @param {number} k - number of nearest neighbors which will be taken into account (preferably odd) - * @return {number} - the class of the point - */ -import euclideanDistance from '../../math/euclidean-distance/euclideanDistance'; -export default function kNN(dataSet, labels, toClassify, k = 3) { - if (!dataSet || !labels || !toClassify) { - throw new Error('Either dataSet or labels or toClassify were not set'); - } - // Calculate distance from toClassify to each point for all dimensions in dataSet. - // Store distance and point's label into distances list. - const distances = []; - for (let i = 0; i < dataSet.length; i += 1) { - distances.push({ - dist: euclideanDistance([dataSet[i]], [toClassify]), - label: labels[i] - }); - } - // Sort distances list (from closer point to further ones). - // Take initial k values, count with class index - const kNearest = distances - .sort((a, b) => { - if (a.dist === b.dist) { - return 0; - } - return a.dist < b.dist ? -1 : 1; - }) - .slice(0, k); - // Count the number of instances of each class in top k members. - const labelsCounter = {}; - let topClass = 0; - let topClassCount = 0; - for (let i = 0; i < kNearest.length; i += 1) { - if (kNearest[i].label in labelsCounter) { - labelsCounter[kNearest[i].label] += 1; - } else { - labelsCounter[kNearest[i].label] = 1; - } - if (labelsCounter[kNearest[i].label] > topClassCount) { - topClassCount = labelsCounter[kNearest[i].label]; - topClass = kNearest[i].label; - } - } - // Return the class with highest count. - return topClass; -} diff --git a/docs/content/DS_ALGO/algorithms/ml/knn/test/knn.test.js b/docs/content/DS_ALGO/algorithms/ml/knn/test/knn.test.js deleted file mode 100644 index 29d714162f..0000000000 --- a/docs/content/DS_ALGO/algorithms/ml/knn/test/knn.test.js +++ /dev/null @@ -1,88 +0,0 @@ -import kNN from '../kNN'; -describe('kNN', () => { - it('should throw an error on invalid data', () => { - expect(() => { - kNN(); - }).toThrowError('Either dataSet or labels or toClassify were not set'); - }); - it('should throw an error on invalid labels', () => { - const noLabels = () => { - kNN([[1, 1]]); - }; - expect(noLabels).toThrowError('Either dataSet or labels or toClassify were not set'); - }); - it('should throw an error on not giving classification vector', () => { - const noClassification = () => { - kNN([[1, 1]], [1]); - }; - expect(noClassification).toThrowError('Either dataSet or labels or toClassify were not set'); - }); - it('should throw an error on not giving classification vector', () => { - const inconsistent = () => { - kNN([[1, 1]], [1], [1]); - }; - expect(inconsistent).toThrowError('Matrices have different shapes'); - }); - it('should find the nearest neighbour', () => { - let dataSet; - let labels; - let toClassify; - let expectedClass; - dataSet = [ - [1, 1], - [2, 2] - ]; - labels = [1, 2]; - toClassify = [1, 1]; - expectedClass = 1; - expect(kNN(dataSet, labels, toClassify)).toBe(expectedClass); - dataSet = [ - [1, 1], - [6, 2], - [3, 3], - [4, 5], - [9, 2], - [2, 4], - [8, 7] - ]; - labels = [1, 2, 1, 2, 1, 2, 1]; - toClassify = [1.25, 1.25]; - expectedClass = 1; - expect(kNN(dataSet, labels, toClassify)).toBe(expectedClass); - dataSet = [ - [1, 1], - [6, 2], - [3, 3], - [4, 5], - [9, 2], - [2, 4], - [8, 7] - ]; - labels = [1, 2, 1, 2, 1, 2, 1]; - toClassify = [1.25, 1.25]; - expectedClass = 2; - expect(kNN(dataSet, labels, toClassify, 5)).toBe(expectedClass); - }); - it('should find the nearest neighbour with equal distances', () => { - const dataSet = [ - [0, 0], - [1, 1], - [0, 2] - ]; - const labels = [1, 3, 3]; - const toClassify = [0, 1]; - const expectedClass = 3; - expect(kNN(dataSet, labels, toClassify)).toBe(expectedClass); - }); - it('should find the nearest neighbour in 3D space', () => { - const dataSet = [ - [0, 0, 0], - [0, 1, 1], - [0, 0, 2] - ]; - const labels = [1, 3, 3]; - const toClassify = [0, 0, 1]; - const expectedClass = 3; - expect(kNN(dataSet, labels, toClassify)).toBe(expectedClass); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/BinarySearch.js b/docs/content/DS_ALGO/algorithms/search/BinarySearch.js deleted file mode 100644 index c6de164573..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/BinarySearch.js +++ /dev/null @@ -1,82 +0,0 @@ -/* Binary Search: https://en.wikipedia.org/wiki/Binary_search_algorithm - * - * Search a sorted array by repeatedly dividing the search interval - * in half. Begin with an interval covering the whole array. If the value of the - * search key is less than the item in the middle of the interval, narrow the interval - * to the lower half. Otherwise narrow it to the upper half. Repeatedly check until the - * value is found or the interval is empty. - */ -function binarySearchRecursive(arr, x, low = 0, high = arr.length - 1) { - const mid = Math.floor(low + (high - low) / 2); - if (high >= low) { - if (arr[mid] === x) { - // item found => return its index - return mid; - } - if (x < arr[mid]) { - // arr[mid] is an upper bound for x, so if x is in arr => low <= x < mid - return binarySearchRecursive(arr, x, low, mid - 1); - } else { - // arr[mid] is a lower bound for x, so if x is in arr => mid < x <= high - return binarySearchRecursive(arr, x, mid + 1, high); - } - } else { - // if low > high => we have searched the whole array without finding the item - return -1; - } -} -function binarySearchIterative(arr, x, low = 0, high = arr.length - 1) { - while (high >= low) { - const mid = Math.floor(low + (high - low) / 2); - if (arr[mid] === x) { - // item found => return its index - return mid; - } - if (x < arr[mid]) { - // arr[mid] is an upper bound for x, so if x is in arr => low <= x < mid - high = mid - 1; - } else { - // arr[mid] is a lower bound for x, so if x is in arr => mid < x <= high - low = mid + 1; - } - } - // if low > high => we have searched the whole array without finding the item - return -1; -} -export { binarySearchIterative, binarySearchRecursive }; -/* ---------------------------------- Test ---------------------------------- */ -// const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] -// const stringArr = [ -// 'Alpha', -// 'Bravo', -// 'Charlie', -// 'Delta', -// 'Echo', -// 'Foxtrot', -// 'Golf', -// 'Hotel', -// 'India', -// 'Juliet', -// 'Kilo', -// 'Lima', -// 'Mike', -// 'November', -// 'Oscar', -// 'Papa', -// 'Quebec', -// 'Romeo', -// 'Sierra', -// 'Tango', -// 'Uniform', -// 'Victor', -// 'Whiskey', -// 'X-Ray', -// 'Yankee', -// 'Zulu' -// ] -// binarySearchRecursive(arr, 3) -// binarySearchIterative(arr, 7) -// binarySearchRecursive(arr, 13) -// binarySearchIterative(stringArr, 'Charlie') -// binarySearchRecursive(stringArr, 'Zulu') -// binarySearchIterative(stringArr, 'Sierra') diff --git a/docs/content/DS_ALGO/algorithms/search/ExponentialSearch.js b/docs/content/DS_ALGO/algorithms/search/ExponentialSearch.js deleted file mode 100644 index 4a67fd5937..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/ExponentialSearch.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Exponential Search - * - * The algorithm consists of two stages. The first stage determines a - * range in which the search key would reside if it were in the list. - * In the second stage, a binary search is performed on this range. - * - * - * - */ -function binarySearch(arr, value, floor, ceiling) { - // Middle index - const mid = Math.floor((floor + ceiling) / 2); - // If value is at the mid position return this position - if (arr[mid] === value) { - return mid; - } - if (floor > ceiling) return -1; - // If the middle element is great than the value - // search the left part of the array - if (arr[mid] > value) { - return binarySearch(arr, value, floor, mid - 1); - // If the middle element is lower than the value - // search the right part of the array - } else { - return binarySearch(arr, value, mid + 1, ceiling); - } -} -function exponentialSearch(arr, length, value) { - // If value is the first element of the array return this position - if (arr[0] === value) { - return 0; - } - // Find range for binary search - let i = 1; - while (i < length && arr[i] <= value) { - i = i * 2; - } - // Call binary search for the range found above - return binarySearch(arr, value, i / 2, Math.min(i, length)); -} -export { binarySearch, exponentialSearch }; -// const arr = [2, 3, 4, 10, 40, 65, 78, 100] -// const value = 78 -// const result = exponentialSearch(arr, arr.length, value) diff --git a/docs/content/DS_ALGO/algorithms/search/FibonacciSearch.js b/docs/content/DS_ALGO/algorithms/search/FibonacciSearch.js deleted file mode 100644 index 503d16cfa1..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/FibonacciSearch.js +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** - * Fibonacci Search JavaScript Implementation - * Author Alhassan Atama Isiaka - * Version v1.0.0 - * Copyright 2020 - * https://github.com/komputarist - * - * This implementation is based on Generalizing the Fibonacci search we - * define the Fibonacci search of degree K. Like the Fibonacci search, - * which it reduces to for K = 2, the Fibonacci search of degree K - * involves only addition and subtraction. - * Capocelli R.M. (1991) A Generalization of the Fibonacci Search. In: - * Bergum G.E., Philippou A.N., Horadam A.F. (eds) Applications of Fibonacci - * Numbers. Springer, Dordrecht. https://doi.org/10.1007/978-94-011-3586-3_9 - * - * This snippet is free. Feel free to improve on it - * - * We define a function fibonacciSearch() that takes an array of numbers, - * the item (number) to be searched for and the length of the items in the array - ****************************************************************************/ -export const fibonacciSearch = (arr, x, n) => { - let fib2 = 0; // (K-2)'th Fibonacci Number - let fib1 = 1; // (K-1)'th Fibonacci Number. - let fibK = fib2 + fib1; // Kth Fibonacci - /* We want to store the smallest fibonacci number smaller such that - number is greater than or equal to n, we use fibK for this */ - while (fibK < n) { - fib2 = fib1; - fib1 = fibK; - fibK = fib2 + fib1; - } - // This marks the eliminated range from front - let offset = -1; - /* while there are elements to be checked. We compare arr[fib2] with x. - When fibM becomes 1, fib2 becomes 0 */ - while (fibK > 1) { - // Check if fibK is a valid location - const i = Math.min(offset + fib2, n - 1); - /* If x is greater than the value at - index fib2, Partition the subarray array - from offset to i */ - if (arr[i] < x) { - fibK = fib1; - fib1 = fib2; - fib2 = fibK - fib1; - offset = i; - /* If x is greater than the value at - index fib2, cut the subarray array - from offset to i */ - } else if (arr[i] > x) { - fibK = fib2; - fib1 = fib1 - fib2; - fib2 = fibK - fib1; - } else { - // return index for found element - return i; - } - } - // comparing the last element with x */ - if (fib1 && arr[offset + 1] === x) { - return offset + 1; - } - // element not found. return -1 - return -1; -}; -// Example -// const myArray = [10, 22, 35, 40, 45, 50, 80, 82, 85, 90, 100] -// const n = myArray.length -// const x = 90 -// const fibFinder = fibonacciSearch(myArray, x, n) diff --git a/docs/content/DS_ALGO/algorithms/search/InterpolationSearch.js b/docs/content/DS_ALGO/algorithms/search/InterpolationSearch.js deleted file mode 100644 index c38142f868..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/InterpolationSearch.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Interpolation Search - * - * Time Complexity: - * -Best case: O(1) - * -Worst case: O(n) - * -O((log(log(n))) If the data are uniformly distributed - * - * - */ -export function interpolationSearch(arr, key) { - const length = arr.length - 1; - let low = 0; - let high = length; - let position = -1; - let delta = -1; - // Because the array is sorted the key must be between low and high - while (low <= high && key >= arr[low] && key <= arr[high]) { - delta = (key - arr[low]) / (arr[high] - arr[low]); - position = low + Math.floor((high - low) * delta); - // Target found return its position - if (arr[position] === key) { - return position; - } - // If the key is larger then it is in the upper part of the array - if (arr[position] < key) { - low = position + 1; - // If the key is smaller then it is in the lower part of the array - } else { - high = position - 1; - } - } - return -1; -} -// const arr = [2, 6, 8, 10, 12, 14, 16, 18, 20, 22, 26, 34, 39] -// interpolationSearch(arr, 2) -// interpolationSearch(arr, 12) -// interpolationSearch(arr, 1000) -// interpolationSearch(arr, 39) diff --git a/docs/content/DS_ALGO/algorithms/search/JumpSearch.js b/docs/content/DS_ALGO/algorithms/search/JumpSearch.js deleted file mode 100644 index b57ffc25cd..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/JumpSearch.js +++ /dev/null @@ -1,33 +0,0 @@ -/* The Jump Search algorithm allows to combine a linear search with a speed optimization. - * This means that instead of going 1 by 1, we will increase the step of √n and increase that - * step of √n which make the step getting bigger and bigger. - * The asymptotic analysis of Jump Search is o(√n). Like the binary search, it needs to be sorted. - * The advantage against binary search is that Jump Search traversed back only once. - */ -const jumpSearch = (arr, value) => { - const length = arr.length; - let step = Math.floor(Math.sqrt(length)); - let lowerBound = 0; - while (arr[Math.min(step, length) - 1] < value) { - lowerBound = step; - step += step; - if (lowerBound >= length) { - return -1; - } - } - const upperBound = Math.min(step, length); - while (arr[lowerBound] < value) { - lowerBound++; - if (lowerBound === upperBound) { - return -1; - } - } - if (arr[lowerBound] === value) { - return lowerBound; - } - return -1; -}; -const arr = [0, 0, 4, 7, 10, 23, 34, 40, 55, 68, 77, 90]; -jumpSearch(arr, 4); -jumpSearch(arr, 34); -jumpSearch(arr, 77); diff --git a/docs/content/DS_ALGO/algorithms/search/LinearSearch.js b/docs/content/DS_ALGO/algorithms/search/LinearSearch.js deleted file mode 100644 index 35fe308b9f..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/LinearSearch.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Linear search or sequential search is a method for finding a target - * value within a list. It sequentially checks each element of the list - * for the target value until a match is found or until all the elements - * have been searched. - */ -function SearchArray(searchNum, ar, output = (v) => console.log(v)) { - const position = Search(ar, searchNum); - if (position !== -1) { - output('The element was found at ' + (position + 1)); - } else { - output('The element not found'); - } -} -// Search "theArray" for the specified "key" value -function Search(theArray, key) { - for (let n = 0; n < theArray.length; n++) { - if (theArray[n] === key) { - return n; - } - } - return -1; -} -export { SearchArray, Search }; -// const ar = [1, 2, 3, 4, 5, 6, 7, 8, 9] -// SearchArray(3, ar) -// SearchArray(4, ar) -// SearchArray(11, ar) diff --git a/docs/content/DS_ALGO/algorithms/search/QuickSelectSearch.js b/docs/content/DS_ALGO/algorithms/search/QuickSelectSearch.js deleted file mode 100644 index 0a8d4bb07c..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/QuickSelectSearch.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Places the `k` smallest elements in `array` in the first `k` indices: `[0..k-1]` - * Modifies the passed in array *in place* - * Returns a slice of the wanted elements for convenience - * Efficient mainly because it never performs a full sort. - * - * The only guarantees are that: - * - * - The `k`th element is in its final sort index (if the array were to be sorted) - * - All elements before index `k` are smaller than the `k`th element - * - * [Reference](http://en.wikipedia.org/wiki/Quickselect) - */ -export function quickSelectSearch(array, k) { - if (!array || array.length <= k) { - throw new Error('Invalid arguments'); - } - let from = 0; - let to = array.length - 1; - while (from < to) { - let left = from; - let right = to; - const pivot = array[Math.ceil((left + right) * 0.5)]; - while (left < right) { - if (array[left] >= pivot) { - const tmp = array[left]; - array[left] = array[right]; - array[right] = tmp; - --right; - } else {}++left; - } - } - if (array[left] > pivot) { - --left; - } - if (k <= left) { - to = left; - } else { - from = left + 1; - } -} -return array; -} -/* ---------------------------------- Test ---------------------------------- */ -// const arr = [1121111, 21, 333, 41, 5, 66, 7777, 28, 19, 11110] -// quickSelectSearch(arr, 5) // [ 19, 21, 28, 41, 5, 66, 333, 11110, 1121111, 7777 ] -// quickSelectSearch(arr, 2) // [ 19, 5, 21, 41, 28, 333, 11110, 1121111, 7777, 66 ] -// quickSelectSearch(arr, 7) // [ 19, 5, 21, 41, 28, 66, 333, 7777, 11110, 1121111 ] diff --git a/docs/content/DS_ALGO/algorithms/search/SlidingWindow.js b/docs/content/DS_ALGO/algorithms/search/SlidingWindow.js deleted file mode 100644 index 1a9721c89f..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/SlidingWindow.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Sliding Window: - * This pattern involve creating a window which can either be - * an array or numbers from one position to another. - * - * Depending on a certain condition, the window either increases - * or closes (and a new window is created). - * - * Very useful for keeping track of a subset of data in an - * array/string etc. - * - * Time Complexity: Best - O(n); - * - * Examples: - * maxSubarraySum([1,2,5,2,8,1,5],2) // returns 10 - * maxSubarraySum([1,2,5,2,8,1,5],15) // returns null - * maxSubarraySum([5,2,6,9],3) // returns 17 - * @param {[Int]} arr - An array of integers on which we will perform the test. - * @param {Int} num - An integer that displays the size of the window you want to check. - * @returns {Int / Null} - Returns a total of N consecutive numbers or null - */ -function slidingWindow(arr, num) { - // Edge Case: - // If the length of the array shorter than the window size (num) return null. - if (arr.length < num) return null; - // The highest amount of consecutive numbers - let maxSum = 0; - // Temp amount of consecutive numbers - For comparative purposes - let tempSum = 0; - // loop over the array {num} times and save their total amount in {maxSum} - for (let i = 0; i < num; i++) { - maxSum += arr[i]; - } - // initialize {tempSum} to {maxSum}. - tempSum = maxSum; - // loop over the array n times - for (let i = num; i < arr.length; i++) { - // Add the next num in the array and remove the first one - tempSum = tempSum - arr[i - num] + arr[i]; - // save the largest number between {maxNum} and {tempNum} in maxSum. - maxSum = Math.max(maxSum, tempSum); - } - return maxSum; -} -export { slidingWindow }; diff --git a/docs/content/DS_ALGO/algorithms/search/StringSearch.js b/docs/content/DS_ALGO/algorithms/search/StringSearch.js deleted file mode 100644 index 8e91c5434c..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/StringSearch.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * String Search - */ -function makeTable(str) { - // create a table of size equal to the length of `str` - // table[i] will store the prefix of the longest prefix of the substring str[0..i] - const table = new Array(str.length); - let maxPrefix = 0; - // the longest prefix of the substring str[0] has length - table[0] = 0; - // for the substrings the following substrings, we have two cases - for (let i = 1; i < str.length; i++) { - // case 1. the current character doesn't match the last character of the longest prefix - while (maxPrefix > 0 && str.charAt(i) !== str.charAt(maxPrefix)) { - // if that is the case, we have to backtrack, and try find a character that will be equal to the current character - // if we reach 0, then we couldn't find a character - maxPrefix = table[maxPrefix - 1]; - } - // case 2. The last character of the longest prefix matches the current character in `str` - if (str.charAt(maxPrefix) === str.charAt(i)) { - // if that is the case, we know that the longest prefix at position i has one more character. - // for example consider `.` be any character not contained in the set [a.c] - // str = abc....abc - // consider `i` to be the last character `c` in `str` - // maxPrefix = will be 2 (the first `c` in `str`) - // maxPrefix now will be 3 - maxPrefix++; - // so the max prefix for table[9] is 3 - } - table[i] = maxPrefix; - } - return table; -} -// Find all the words that matches in a given string `str` -export function stringSearch(str, word) { - // find the prefix table in O(n) - const prefixes = makeTable(word); - const matches = []; - // `j` is the index in `P` - let j = 0; - // `i` is the index in `S` - let i = 0; - while (i < str.length) { - // Case 1. S[i] == P[j] so we move to the next index in `S` and `P` - if (str.charAt(i) === word.charAt(j)) { - i++; - j++; - } - // Case 2. `j` is equal to the length of `P` - // that means that we reached the end of `P` and thus we found a match - // Next we have to update `j` because we want to save some time - // instead of updating to j = 0 , we can jump to the last character of the longest prefix well known so far. - // j-1 means the last character of `P` because j is actually `P.length` - // e.g. - // S = a b a b d e - // P = `a b`a b - // we will jump to `a b` and we will compare d and a in the next iteration - // a b a b `d` e - // a b `a` b - if (j === word.length) { - matches.push(i - j); - j = prefixes[j - 1]; - // Case 3. - // S[i] != P[j] There's a mismatch! - } else if (str.charAt(i) !== word.charAt(j)) { - // if we found at least a character in common, do the same thing as in case 2 - if (j !== 0) { - j = prefixes[j - 1]; - } else { - // else j = 0, and we can move to the next character S[i+1] - i++; - } - } - } - return matches; -} -// stringSearch('Hello search the position of me', 'pos') \ No newline at end of file diff --git a/docs/content/DS_ALGO/algorithms/search/TernarySearch.js b/docs/content/DS_ALGO/algorithms/search/TernarySearch.js deleted file mode 100644 index 492f45bb3b..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/TernarySearch.js +++ /dev/null @@ -1,79 +0,0 @@ -/* Ternary search is similar to binary search but it divide the sorted array - * into three parts and determine which part the key lies in. The array will - * be divided into three intervals by using two middle points, mid1 and mid2. - * The value of the key will first compared with the two mid points, the value - * will be returned if there is a match. Then, if the value of the key is less - * than mid1, narrow the interval to the first part. Else, if the value of the - * key is greater than mid2, narrow the interval to the third part. Otherwise, - * narrow the interval to the middle part. Repeat the steps until the value is - * found or the interval is empty(value not found after checking all elements). - * - * Reference: https://www.geeksforgeeks.org/ternary-search/ - */ -function ternarySearchRecursive(arr, key, low = 0, high = arr.length - 1) { - if (high >= low) { - // find the mid1 and mid2 - const mid1 = Math.floor(low + (high - low) / 3); - const mid2 = Math.floor(high - (high - low) / 3); - // check if key is found at any mid - if (arr[mid1] === key) { - // return index of key if found - return mid1; - } - if (arr[mid2] === key) { - // return index of key if found - return mid2; - } - // since the key is not found at mid, - // check in which region it is present - // and repeat the Search operation - // in that region - if (key < arr[mid1]) { - // the key lies in between low and mid1 - return ternarySearchRecursive(arr, key, low, mid1 - 1); - } else if (key > arr[mid2]) { - // the key lies in between mid2 and high - return ternarySearchRecursive(arr, key, mid2 + 1, high); - } else { - // the key lies in between mid1 and mid2 - return ternarySearchRecursive(arr, key, mid1 + 1, mid2 - 1); - } - } else { - // if low > high => we have searched the whole array without finding the item - return -1; - } -} -function ternarySearchIterative(arr, key, low = 0, high = arr.length - 1) { - while (high >= low) { - // find the mid1 and mid2 - const mid1 = Math.floor(low + (high - low) / 3); - const mid2 = Math.floor(high - (high - low) / 3); - // check if key is found at any mid - if (arr[mid1] === key) { - // return index of key if found - return mid1; - } - if (arr[mid2] === key) { - // return index of key if found - return mid2; - } - // since the key is not found at mid, - // check in which region it is present - // and repeat the Search operation - // in that region - if (key < arr[mid1]) { - // the key lies in between low and mid1 - high = mid1 - 1; - } else if (key > arr[mid2]) { - // the key lies in between mid2 and high - low = mid2 + 1; - } else { - // the key lies in between mid1 and mid2 - low = mid1 + 1; - high = mid2 - 1; - } - } - // the key was not found - return -1; -} -export { ternarySearchRecursive, ternarySearchIterative }; diff --git a/docs/content/DS_ALGO/algorithms/search/UnionFind.js b/docs/content/DS_ALGO/algorithms/search/UnionFind.js deleted file mode 100644 index fba098b4a4..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/UnionFind.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * union find data structure for javascript - * - * In computer science, a disjoint-set data structure, also called a union-find data structure or merge-find set, - * is a data structure that stores a collection of disjoint (non-overlapping) sets. Equivalently, it stores a partition - * of a set into disjoint subsets. It provides operations for adding new sets, merging sets (replacing them by their union), - * and finding a representative member of a set. - * The last operation allows to find out efficiently if any two elements are in the same or different sets. - * - * Disjoint-set data structures play a key role in Kruskal's algorithm for finding the minimum spanning tree of a graph. - * The importance of minimum spanning trees means that disjoint-set data structures underlie a wide variety of algorithms. - * In addition, disjoint-set data structures also have applications to symbolic computation, as well in compilers, - * especially for register allocation problems. - * - * you can learn more on disjoint-set / union-find data structure at https://en.wikipedia.org/wiki/Disjoint-set_data_structure - */ -function UnionFind(n, key) { - if (!(this instanceof UnionFind)) return new UnionFind(n); - if (key && typeof key !== 'function') { - throw new Error('key has to be a function or else left undefined'); - } - let cnt, length; - // init Union Find with number of distinct groups. Each group will be referred to as index of the array of size 'size' starting at 0. - // Provide an optional key function that maps these indices. I.e. for the groups starting with 1 provide function(a){return a-1;}. The default value is function(a){return a;}. - key = - key || - function (a) { - return a; - }; - cnt = length = n; - const id = new Array(n); - const sz = new Array(n); - for (let i = 0; i < n; i++) { - id[i] = i; - sz[i] = 1; - } - // Returns the number of elements of uf object. - this.size = function () { - return length; - }; - // Returns the number of distinct groups left inside the object. - this.count = function () { - return cnt; - }; - // Return the root (value) of the group in which p is. - this.find = function (p) { - p = key(p); - while (p !== id[p]) { - id[p] = id[id[p]]; - p = id[p]; - } - return p; - }; - // Returns true if p and p are both in same group, false otherwise. - this.connected = function (p, q) { - p = key(p); - q = key(q); - ensureIndexWithinBounds(p, q); - return this.find(p) === this.find(q); - }; - // Combine elements in groups p and q into a single group. In other words connect the two groups. - this.union = function (p, q) { - p = key(p); - q = key(q); - ensureIndexWithinBounds(p, q); - const i = this.find(p); - const j = this.find(q); - if (i === j) return; - if (sz[i] < sz[j]) { - id[i] = j; - sz[j] += sz[i]; - } else { - id[j] = i; - sz[i] += sz[j]; - } - cnt--; - }; - function ensureIndexWithinBounds(args) { - for (let i = arguments.length - 1; i >= 0; i--) { - const p = arguments[i]; - if (p >= length) throw new Error('Index out of bounds. The maximum index can be length-1'); - } - } -} -export { UnionFind }; diff --git a/docs/content/DS_ALGO/algorithms/search/binary-search/README.md b/docs/content/DS_ALGO/algorithms/search/binary-search/README.md deleted file mode 100644 index 585b6e922d..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/binary-search/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Binary Search - -In computer science, binary search, also known as half-interval -search, logarithmic search, or binary chop, is a search algorithm -that finds the position of a target value within a sorted -array. Binary search compares the target value to the middle -element of the array; if they are unequal, the half in which -the target cannot lie is eliminated and the search continues -on the remaining half until it is successful. If the search -ends with the remaining half being empty, the target is not -in the array. - -![Binary Search](https://upload.wikimedia.org/wikipedia/commons/8/83/Binary_Search_Depiction.svg) - -## Complexity - -**Time Complexity**: `O(log(n))` - since we split search area by two for every -next iteration. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_algorithm) -- [YouTube](https://www.youtube.com/watch?v=P3YID7liBug&index=29&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/search/binary-search/binarySearch.js b/docs/content/DS_ALGO/algorithms/search/binary-search/binarySearch.js deleted file mode 100644 index 2b4c8bdd28..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/binary-search/binarySearch.js +++ /dev/null @@ -1,37 +0,0 @@ -import Comparator from '../../../utils/comparator/Comparator'; -/** - * Binary search implementation. - * - * @param {*[]} sortedArray - * @param {*} seekElement - * @param {function(a, b)} [comparatorCallback] - * @return {number} - */ -export default function binarySearch(sortedArray, seekElement, comparatorCallback) { - // Let's create comparator from the comparatorCallback function. - // Comparator object will give us common comparison methods like equal() and lessThen(). - const comparator = new Comparator(comparatorCallback); - // These two indices will contain current array (sub-array) boundaries. - let startIndex = 0; - let endIndex = sortedArray.length - 1; - // Let's continue to split array until boundaries are collapsed - // and there is nothing to split anymore. - while (startIndex <= endIndex) { - // Let's calculate the index of the middle element. - const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2); - // If we've found the element just return its position. - if (comparator.equal(sortedArray[middleIndex], seekElement)) { - return middleIndex; - } - // Decide which half to choose for seeking next: left or right one. - if (comparator.lessThan(sortedArray[middleIndex], seekElement)) { - // Go to the right half of the array. - startIndex = middleIndex + 1; - } else { - // Go to the left half of the array. - endIndex = middleIndex - 1; - } - } - // Return -1 if we have not found anything. - return -1; -} diff --git a/docs/content/DS_ALGO/algorithms/search/binary-search/test/binarySearch.test.js b/docs/content/DS_ALGO/algorithms/search/binary-search/test/binarySearch.test.js deleted file mode 100644 index 26e536f47b..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/binary-search/test/binarySearch.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import binarySearch from '../binarySearch'; -describe('binarySearch', () => { - it('should search number in sorted array', () => { - expect(binarySearch([], 1)).toBe(-1); - expect(binarySearch([1], 1)).toBe(0); - expect(binarySearch([1, 2], 1)).toBe(0); - expect(binarySearch([1, 2], 2)).toBe(1); - expect(binarySearch([1, 5, 10, 12], 1)).toBe(0); - expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 17)).toBe(5); - expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 1)).toBe(0); - expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 100)).toBe(7); - expect(binarySearch([1, 5, 10, 12, 14, 17, 22, 100], 0)).toBe(-1); - }); - it('should search object in sorted array', () => { - const sortedArrayOfObjects = [ - { key: 1, value: 'value1' }, - { key: 2, value: 'value2' }, - { key: 3, value: 'value3' } - ]; - const comparator = (a, b) => { - if (a.key === b.key) return 0; - return a.key < b.key ? -1 : 1; - }; - expect(binarySearch([], { key: 1 }, comparator)).toBe(-1); - expect(binarySearch(sortedArrayOfObjects, { key: 4 }, comparator)).toBe(-1); - expect(binarySearch(sortedArrayOfObjects, { key: 1 }, comparator)).toBe(0); - expect(binarySearch(sortedArrayOfObjects, { key: 2 }, comparator)).toBe(1); - expect(binarySearch(sortedArrayOfObjects, { key: 3 }, comparator)).toBe(2); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/interpolation-search/README.md b/docs/content/DS_ALGO/algorithms/search/interpolation-search/README.md deleted file mode 100644 index 1693a63e2d..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/interpolation-search/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Interpolation Search - -**Interpolation search** is an algorithm for searching for a key in an array that -has been ordered by numerical values assigned to the keys (key values). - -For example we have a sorted array of `n` uniformly distributed values `arr[]`, -and we need to write a function to search for a particular element `x` in the array. - -**Linear Search** finds the element in `O(n)` time, **Jump Search** takes `O(√ n)` time -and **Binary Search** take `O(Log n)` time. - -The **Interpolation Search** is an improvement over Binary Search for instances, -where the values in a sorted array are _uniformly_ distributed. Binary Search -always goes to the middle element to check. On the other hand, interpolation -search may go to different locations according to the value of the key being -searched. For example, if the value of the key is closer to the last element, -interpolation search is likely to start search toward the end side. - -To find the position to be searched, it uses following formula: - -``` -// The idea of formula is to return higher value of pos -// when element to be searched is closer to arr[hi]. And -// smaller value when closer to arr[lo] -pos = lo + ((x - arr[lo]) * (hi - lo) / (arr[hi] - arr[Lo])) - -arr[] - Array where elements need to be searched -x - Element to be searched -lo - Starting index in arr[] -hi - Ending index in arr[] -``` - -## Complexity - -**Time complexity**: `O(log(log(n))` - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/interpolation-search/) -- [Wikipedia](https://en.wikipedia.org/wiki/Interpolation_search) diff --git a/docs/content/DS_ALGO/algorithms/search/interpolation-search/interpolationSearch.js b/docs/content/DS_ALGO/algorithms/search/interpolation-search/interpolationSearch.js deleted file mode 100644 index 9c3482952a..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/interpolation-search/interpolationSearch.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Interpolation search implementation. - * - * @param {*[]} sortedArray - sorted array with uniformly distributed values - * @param {*} seekElement - * @return {number} - */ -export default function interpolationSearch(sortedArray, seekElement) { - let leftIndex = 0; - let rightIndex = sortedArray.length - 1; - while (leftIndex <= rightIndex) { - const rangeDelta = sortedArray[rightIndex] - sortedArray[leftIndex]; - const indexDelta = rightIndex - leftIndex; - const valueDelta = seekElement - sortedArray[leftIndex]; - // If valueDelta is less then zero it means that there is no seek element - // exists in array since the lowest element from the range is already higher - // then seek element. - if (valueDelta < 0) { - return -1; - } - // If range delta is zero then subarray contains all the same numbers - // and thus there is nothing to search for unless this range is all - // consists of seek number. - if (!rangeDelta) { - // By doing this we're also avoiding division by zero while - // calculating the middleIndex later. - return sortedArray[leftIndex] === seekElement ? leftIndex : -1; - } - // Do interpolation of the middle index. - const middleIndex = leftIndex + Math.floor((valueDelta * indexDelta) / rangeDelta); - // If we've found the element just return its position. - if (sortedArray[middleIndex] === seekElement) { - return middleIndex; - } - // Decide which half to choose for seeking next: left or right one. - if (sortedArray[middleIndex] < seekElement) { - // Go to the right half of the array. - leftIndex = middleIndex + 1; - } else { - // Go to the left half of the array. - rightIndex = middleIndex - 1; - } - } - return -1; -} diff --git a/docs/content/DS_ALGO/algorithms/search/interpolation-search/test/interpolationSearch.test.js b/docs/content/DS_ALGO/algorithms/search/interpolation-search/test/interpolationSearch.test.js deleted file mode 100644 index df4d6ddd8a..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/interpolation-search/test/interpolationSearch.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import interpolationSearch from '../interpolationSearch'; -describe('interpolationSearch', () => { - it('should search elements in sorted array of numbers', () => { - expect(interpolationSearch([], 1)).toBe(-1); - expect(interpolationSearch([1], 1)).toBe(0); - expect(interpolationSearch([1], 0)).toBe(-1); - expect(interpolationSearch([1, 1], 1)).toBe(0); - expect(interpolationSearch([1, 2], 1)).toBe(0); - expect(interpolationSearch([1, 2], 2)).toBe(1); - expect(interpolationSearch([10, 20, 30, 40, 50], 40)).toBe(3); - expect(interpolationSearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 14)).toBe(13); - expect(interpolationSearch([1, 6, 7, 8, 12, 13, 14, 19, 21, 23, 24, 24, 24, 300], 24)).toBe(10); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 600)).toBe(-1); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 1)).toBe(0); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 2)).toBe(1); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 3)).toBe(2); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 700)).toBe(3); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 800)).toBe(4); - expect(interpolationSearch([0, 2, 3, 700, 800, 1200, 1300, 1400, 1900], 1200)).toBe(5); - expect(interpolationSearch([1, 2, 3, 700, 800, 1200, 1300, 1400, 19000], 800)).toBe(4); - expect(interpolationSearch([0, 10, 11, 12, 13, 14, 15], 10)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/jump-search/README.md b/docs/content/DS_ALGO/algorithms/search/jump-search/README.md deleted file mode 100644 index 9b5b226edc..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/jump-search/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Jump Search - -Like Binary Search, **Jump Search** (or **Block Search**) is a searching algorithm -for sorted arrays. The basic idea is to check fewer elements (than linear search) -by jumping ahead by fixed steps or skipping some elements in place of searching all -elements. - -For example, suppose we have an array `arr[]` of size `n` and block (to be jumped) -of size `m`. Then we search at the indexes `arr[0]`, `arr[m]`, `arr[2 * m]`, ..., `arr[k * m]` and -so on. Once we find the interval `arr[k * m] < x < arr[(k+1) * m]`, we perform a -linear search operation from the index `k * m` to find the element `x`. - -**What is the optimal block size to be skipped?** -In the worst case, we have to do `n/m` jumps and if the last checked value is -greater than the element to be searched for, we perform `m - 1` comparisons more -for linear search. Therefore the total number of comparisons in the worst case -will be `((n/m) + m - 1)`. The value of the function `((n/m) + m - 1)` will be -minimum when `m = √n`. Therefore, the best step size is `m = √n`. - -## Complexity - -**Time complexity**: `O(√n)` - because we do search by blocks of size `√n`. - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/jump-search/) -- [Wikipedia](https://en.wikipedia.org/wiki/Jump_search) diff --git a/docs/content/DS_ALGO/algorithms/search/jump-search/jumpSearch.js b/docs/content/DS_ALGO/algorithms/search/jump-search/jumpSearch.js deleted file mode 100644 index 2ac2378f0b..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/jump-search/jumpSearch.js +++ /dev/null @@ -1,43 +0,0 @@ -import Comparator from '../../../utils/comparator/Comparator'; -/** - * Jump (block) search implementation. - * - * @param {*[]} sortedArray - * @param {*} seekElement - * @param {function(a, b)} [comparatorCallback] - * @return {number} - */ -export default function jumpSearch(sortedArray, seekElement, comparatorCallback) { - const comparator = new Comparator(comparatorCallback); - const arraySize = sortedArray.length; - if (!arraySize) { - // We can't find anything in empty array. - return -1; - } - // Calculate optimal jump size. - // Total number of comparisons in the worst case will be ((arraySize/jumpSize) + jumpSize - 1). - // The value of the function ((arraySize/jumpSize) + jumpSize - 1) will be minimum - // when jumpSize = √array.length. - const jumpSize = Math.floor(Math.sqrt(arraySize)); - // Find the block where the seekElement belong to. - let blockStart = 0; - let blockEnd = jumpSize; - while (comparator.greaterThan(seekElement, sortedArray[Math.min(blockEnd, arraySize) - 1])) { - // Jump to the next block. - blockStart = blockEnd; - blockEnd += jumpSize; - // If our next block is out of array then we couldn't found the element. - if (blockStart > arraySize) { - return -1; - } - } - // Do linear search for seekElement in subarray starting from blockStart. - let currentIndex = blockStart; - while (currentIndex < Math.min(blockEnd, arraySize)) { - if (comparator.equal(sortedArray[currentIndex], seekElement)) { - return currentIndex; - } - currentIndex += 1; - } - return -1; -} diff --git a/docs/content/DS_ALGO/algorithms/search/jump-search/test/jumpSearch.test.js b/docs/content/DS_ALGO/algorithms/search/jump-search/test/jumpSearch.test.js deleted file mode 100644 index 0a12746064..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/jump-search/test/jumpSearch.test.js +++ /dev/null @@ -1,35 +0,0 @@ -import jumpSearch from '../jumpSearch'; -describe('jumpSearch', () => { - it('should search for an element in sorted array', () => { - expect(jumpSearch([], 1)).toBe(-1); - expect(jumpSearch([1], 2)).toBe(-1); - expect(jumpSearch([1], 1)).toBe(0); - expect(jumpSearch([1, 2], 1)).toBe(0); - expect(jumpSearch([1, 2], 1)).toBe(0); - expect(jumpSearch([1, 1, 1], 1)).toBe(0); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 2)).toBe(1); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 0)).toBe(-1); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 0)).toBe(-1); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 7)).toBe(-1); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 5)).toBe(2); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 20)).toBe(4); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 30)).toBe(7); - expect(jumpSearch([1, 2, 5, 10, 20, 21, 24, 30, 48], 48)).toBe(8); - }); - it('should search object in sorted array', () => { - const sortedArrayOfObjects = [ - { key: 1, value: 'value1' }, - { key: 2, value: 'value2' }, - { key: 3, value: 'value3' } - ]; - const comparator = (a, b) => { - if (a.key === b.key) return 0; - return a.key < b.key ? -1 : 1; - }; - expect(jumpSearch([], { key: 1 }, comparator)).toBe(-1); - expect(jumpSearch(sortedArrayOfObjects, { key: 4 }, comparator)).toBe(-1); - expect(jumpSearch(sortedArrayOfObjects, { key: 1 }, comparator)).toBe(0); - expect(jumpSearch(sortedArrayOfObjects, { key: 2 }, comparator)).toBe(1); - expect(jumpSearch(sortedArrayOfObjects, { key: 3 }, comparator)).toBe(2); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/linear-search/README.md b/docs/content/DS_ALGO/algorithms/search/linear-search/README.md deleted file mode 100644 index 54cbc834d4..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/linear-search/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Linear Search - -In computer science, linear search or sequential search is a -method for finding a target value within a list. It sequentially -checks each element of the list for the target value until a -match is found or until all the elements have been searched. -Linear search runs in at worst linear time and makes at most `n` -comparisons, where `n` is the length of the list. - -![Linear Search](https://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif) - -## Complexity - -**Time Complexity**: `O(n)` - since in worst case we're checking each element -exactly once. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Linear_search) -- [TutorialsPoint](https://www.tutorialspoint.com/data_structures_algorithms/linear_search_algorithm.htm) -- [Youtube](https://www.youtube.com/watch?v=SGU9duLE30w) diff --git a/docs/content/DS_ALGO/algorithms/search/linear-search/linearSearch.js b/docs/content/DS_ALGO/algorithms/search/linear-search/linearSearch.js deleted file mode 100644 index f328d3ff72..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/linear-search/linearSearch.js +++ /dev/null @@ -1,19 +0,0 @@ -import Comparator from '../../../utils/comparator/Comparator'; -/** - * Linear search implementation. - * - * @param {*[]} array - * @param {*} seekElement - * @param {function(a, b)} [comparatorCallback] - * @return {number[]} - */ -export default function linearSearch(array, seekElement, comparatorCallback) { - const comparator = new Comparator(comparatorCallback); - const foundIndices = []; - array.forEach((element, index) => { - if (comparator.equal(element, seekElement)) { - foundIndices.push(index); - } - }); - return foundIndices; -} diff --git a/docs/content/DS_ALGO/algorithms/search/linear-search/test/linearSearch.test.js b/docs/content/DS_ALGO/algorithms/search/linear-search/test/linearSearch.test.js deleted file mode 100644 index 3905f3d3dc..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/linear-search/test/linearSearch.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import linearSearch from '../linearSearch'; -describe('linearSearch', () => { - it('should search all numbers in array', () => { - const array = [1, 2, 4, 6, 2]; - expect(linearSearch(array, 10)).toEqual([]); - expect(linearSearch(array, 1)).toEqual([0]); - expect(linearSearch(array, 2)).toEqual([1, 4]); - }); - it('should search all strings in array', () => { - const array = ['a', 'b', 'a']; - expect(linearSearch(array, 'c')).toEqual([]); - expect(linearSearch(array, 'b')).toEqual([1]); - expect(linearSearch(array, 'a')).toEqual([0, 2]); - }); - it('should search through objects as well', () => { - const comparatorCallback = (a, b) => { - if (a.key === b.key) { - return 0; - } - return a.key <= b.key ? -1 : 1; - }; - const array = [{ - key: 5 - }, { - key: 6 - }, { - key: 7 - }, { - key: 6 - }]; - expect(linearSearch(array, { - key: 10 - }, comparatorCallback)).toEqual([]); - expect(linearSearch(array, { - key: 5 - }, comparatorCallback)).toEqual([0]); - expect(linearSearch(array, { - key: 6 - }, comparatorCallback)).toEqual([1, 3]); - }); -}); -key: 6 -}]; -expect(linearSearch(array, { - key: 10 -}, comparatorCallback)).toEqual([]); -expect(linearSearch(array, { - key: 5 -}, comparatorCallback)).toEqual([0]); -expect(linearSearch(array, { -key: 6 -}, comparatorCallback)).toEqual([1, 3]); -}); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/test/SlidingWindow.test.js b/docs/content/DS_ALGO/algorithms/search/test/SlidingWindow.test.js deleted file mode 100644 index 0865758774..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/test/SlidingWindow.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import { slidingWindow } from '../SlidingWindow'; -test('expect to return the largest sum of sequence in the array', () => { - const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 2); - expect(sum).toBe(10); -}); -test('expect to return the largest sum of sequence in the array', () => { - const sum = slidingWindow([5, 2, 6, 9], 3); - expect(sum).toBe(17); -}); -test('expect to return null when the sequence size is larger then the array length', () => { - const sum = slidingWindow([1, 2, 5, 2, 8, 1, 5], 15); - expect(sum).toBe(null); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/test/TernarySearch.test.js b/docs/content/DS_ALGO/algorithms/search/test/TernarySearch.test.js deleted file mode 100644 index b8d632229a..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/test/TernarySearch.test.js +++ /dev/null @@ -1,29 +0,0 @@ -import { ternarySearchRecursive, ternarySearchIterative } from '../TernarySearch'; -test('should return the index of a number in an array of numbers:', () => { - const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3); - expect(indexNumber).toBe(2); -}); -test('should return the index of a number in an array of numbers:', () => { - const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 8); - expect(indexNumber).toBe(7); -}); -test('should return the index of a number in an array of numbers:', () => { - const indexNumber = ternarySearchRecursive([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0); - expect(indexNumber).toBe(-1); -}); -test('should return the index of a number in an array of numbers:', () => { - const indexNumber = ternarySearchIterative([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 12); - expect(indexNumber).toBe(-1); -}); -test('should return the index of a string in an array of strings:', () => { - const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Cathrynli'); - expect(indexNumber).toBe(1); -}); -test('should return the index of a string in an array of strings:', () => { - const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Josuke'); - expect(indexNumber).toBe(2); -}); -test('should return the index of a string in an array of strings:', () => { - const indexNumber = ternarySearchRecursive(['Ali', 'Cathrynli', 'Josuke', 'Thomas'], 'Angela'); - expect(indexNumber).toBe(-1); -}); diff --git a/docs/content/DS_ALGO/algorithms/search/test/UnionFind.test.js b/docs/content/DS_ALGO/algorithms/search/test/UnionFind.test.js deleted file mode 100644 index 31b1efbc0f..0000000000 --- a/docs/content/DS_ALGO/algorithms/search/test/UnionFind.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import { UnionFind } from '../UnionFind'; -const uf = new UnionFind(5); -test('should expose .size():', () => { - const size = uf.size(); - expect(size).toBe(5); -}); -test('should do .union(num1, num2):', () => { - uf.union(1, 2); - uf.union(3, 4); - uf.union(0, 4); - expect(uf.connected(1, 2)).toBe(true); - expect(uf.connected(1, 2)).toBe(true); - expect(uf.connected(3, 4)).toBe(true); - expect(uf.connected(3, 0)).toBe(true); - expect(uf.connected(4, 0)).toBe(true); - expect(uf.connected(1, 3)).toBe(false); - expect(uf.connected(1, 4)).toBe(false); - expect(uf.connected(1, 0)).toBe(false); - expect(uf.connected(2, 3)).toBe(false); - expect(uf.connected(2, 4)).toBe(false); - expect(uf.connected(2, 0)).toBe(false); -}); -test('.count(), should return the number of disparate groups:', () => { - expect(uf.count()).toBe(2); -}); -test('should check if two components are connected, .connected(num1, num2):', () => { - expect(uf.connected(1, 2)).toBe(true); - expect(uf.connected(1, 3)).toBe(false); -}); -test('should find the root of the tree in which the given element lives, .find(num):', () => { - expect(uf.find(1)).toBe(1); - expect(uf.find(2)).toBe(1); - expect(uf.find(3)).toBe(3); - expect(uf.find(4)).toBe(3); - expect(uf.find(0)).toBe(3); -}); -test('should always change the id of the smaller tree and preserve the id of the larger one', () => { - uf.union(2, 3); - expect(uf.count()).toBe(1); - expect(uf.find(0)).toBe(3); - expect(uf.find(1)).toBe(3); - expect(uf.find(2)).toBe(3); - expect(uf.find(3)).toBe(3); - expect(uf.find(4)).toBe(3); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/README.md b/docs/content/DS_ALGO/algorithms/sets/cartesian-product/README.md deleted file mode 100644 index bff469f1e6..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Cartesian Product - -In set theory a Cartesian product is a mathematical operation that returns a set -(or product set or simply product) from multiple sets. That is, for sets A and B, -the Cartesian product A × B is the set of all ordered pairs (a, b) -where a ∈ A and b ∈ B. - -Cartesian product `AxB` of two sets `A={x,y,z}` and `B={1,2,3}` - -![Cartesian Product of Two Sets](https://upload.wikimedia.org/wikipedia/commons/4/4e/Cartesian_Product_qtl1.svg) - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Cartesian_product) diff --git a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/cartesianProduct.js b/docs/content/DS_ALGO/algorithms/sets/cartesian-product/cartesianProduct.js deleted file mode 100644 index f203ec0d5c..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/cartesianProduct.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Generates Cartesian Product of two sets. - * @param {*[]} setA - * @param {*[]} setB - * @return {*[]} - */ -export default function cartesianProduct(setA, setB) { - // Check if input sets are not empty. - // Otherwise return null since we can't generate Cartesian Product out of them. - if (!setA || !setB || !setA.length || !setB.length) { - return null; - } - // Init product set. - const product = []; - // Now, let's go through all elements of a first and second set and form all possible pairs. - for (let indexA = 0; indexA < setA.length; indexA += 1) { - for (let indexB = 0; indexB < setB.length; indexB += 1) { - // Add current product pair to the product set. - product.push([setA[indexA], setB[indexB]]); - } - } - // Return cartesian product set. - return product; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/test/cartesianProduct.test.js b/docs/content/DS_ALGO/algorithms/sets/cartesian-product/test/cartesianProduct.test.js deleted file mode 100644 index 767c5f4faf..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/cartesian-product/test/cartesianProduct.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import cartesianProduct from '../cartesianProduct'; -describe('cartesianProduct', () => { - it('should return null if there is not enough info for calculation', () => { - const product1 = cartesianProduct([1], null); - const product2 = cartesianProduct([], null); - expect(product1).toBeNull(); - expect(product2).toBeNull(); - }); - it('should calculate the product of two sets', () => { - const product1 = cartesianProduct([1], [1]); - const product2 = cartesianProduct([1, 2], [3, 5]); - expect(product1).toEqual([[1, 1]]); - expect(product2).toEqual([ - [1, 3], - [1, 5], - [2, 3], - [2, 5] - ]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/combination-sum/README.md b/docs/content/DS_ALGO/algorithms/sets/combination-sum/README.md deleted file mode 100644 index 7648a025f8..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combination-sum/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Combination Sum Problem - -Given a **set** of candidate numbers (`candidates`) **(without duplicates)** and -a target number (`target`), find all unique combinations in `candidates` where -the candidate numbers sums to `target`. - -The **same** repeated number may be chosen from `candidates` unlimited number -of times. - -**Note:** - -- All numbers (including `target`) will be positive integers. -- The solution set must not contain duplicate combinations. - -## Examples - -``` -Input: candidates = [2,3,6,7], target = 7, - -A solution set is: -[ - [7], - [2,2,3] -] -``` - -``` -Input: candidates = [2,3,5], target = 8, - -A solution set is: -[ - [2,2,2,2], - [2,3,3], - [3,5] -] -``` - -## Explanations - -Since the problem is to get all the possible results, not the best or the -number of result, thus we don't need to consider DP (dynamic programming), -backtracking approach using recursion is needed to handle it. - -Here is an example of decision tree for the situation when `candidates = [2, 3]` and `target = 6`: - -``` - 0 - / \ - +2 +3 - / \ \ - +2 +3 +3 - / \ / \ \ - +2 ✘ ✘ ✘ ✓ - / \ - ✓ ✘ -``` - -## References - -- [LeetCode](https://leetcode.com/problems/combination-sum/description/) diff --git a/docs/content/DS_ALGO/algorithms/sets/combination-sum/combinationSum.js b/docs/content/DS_ALGO/algorithms/sets/combination-sum/combinationSum.js deleted file mode 100644 index 924b23aa8c..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combination-sum/combinationSum.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @param {number[]} candidates - candidate numbers we're picking from. - * @param {number} remainingSum - remaining sum after adding candidates to currentCombination. - * @param {number[][]} finalCombinations - resulting list of combinations. - * @param {number[]} currentCombination - currently explored candidates. - * @param {number} startFrom - index of the candidate to start further exploration from. - * @return {number[][]} - */ -function combinationSumRecursive(candidates, remainingSum, finalCombinations = [], currentCombination = [], startFrom = 0) { - if (remainingSum < 0) { - // By adding another candidate we've gone below zero. - // This would mean that the last candidate was not acceptable. - return finalCombinations; - } - if (remainingSum === 0) { - // If after adding the previous candidate our remaining sum - // became zero - we need to save the current combination since it is one - // of the answers we're looking for. - finalCombinations.push(currentCombination.slice()); - return finalCombinations; - } - // If we haven't reached zero yet let's continue to add all - // possible candidates that are left. - for (let candidateIndex = startFrom; candidateIndex < candidates.length; candidateIndex += 1) { - const currentCandidate = candidates[candidateIndex]; - // Let's try to add another candidate. - currentCombination.push(currentCandidate); - // Explore further option with current candidate being added. - combinationSumRecursive(candidates, remainingSum - currentCandidate, finalCombinations, currentCombination, candidateIndex); - // BACKTRACKING. - // Let's get back, exclude current candidate and try another ones later. - currentCombination.pop(); - } - return finalCombinations; -} -/** - * Backtracking algorithm of finding all possible combination for specific sum. - * - * @param {number[]} candidates - * @param {number} target - * @return {number[][]} - */ -export default function combinationSum(candidates, target) { - return combinationSumRecursive(candidates, target); -} diff --git a/docs/content/DS_ALGO/algorithms/sets/combination-sum/test/combinationSum.test.js b/docs/content/DS_ALGO/algorithms/sets/combination-sum/test/combinationSum.test.js deleted file mode 100644 index dfb7de0097..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combination-sum/test/combinationSum.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import combinationSum from '../combinationSum'; -describe('combinationSum', () => { - it('should find all combinations with specific sum', () => { - expect(combinationSum([1], 4)).toEqual([[1, 1, 1, 1]]); - expect(combinationSum([2, 3, 6, 7], 7)).toEqual([[2, 2, 3], [7]]); - expect(combinationSum([2, 3, 5], 8)).toEqual([ - [2, 2, 2, 2], - [2, 3, 3], - [3, 5] - ]); - expect(combinationSum([2, 5], 3)).toEqual([]); - expect(combinationSum([], 3)).toEqual([]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/combinations/README.md b/docs/content/DS_ALGO/algorithms/sets/combinations/README.md deleted file mode 100644 index 8255817e4c..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combinations/README.md +++ /dev/null @@ -1,70 +0,0 @@ -# Combinations - -When the order doesn't matter, it is a **Combination**. - -When the order **does** matter it is a **Permutation**. - -**"My fruit salad is a combination of apples, grapes and bananas"** -We don't care what order the fruits are in, they could also be -"bananas, grapes and apples" or "grapes, apples and bananas", -its the same fruit salad. - -## Combinations without repetitions - -This is how lotteries work. The numbers are drawn one at a -time, and if we have the lucky numbers (no matter what order) -we win! - -No Repetition: such as lottery numbers `(2,14,15,27,30,33)` - -**Number of combinations** - -![Formula](https://www.mathsisfun.com/combinatorics/images/combinations-no-repeat.png) - -where `n` is the number of things to choose from, and we choose `r` of them, -no repetition, order doesn't matter. - -It is often called "n choose r" (such as "16 choose 3"). And is also known as the Binomial Coefficient. - -## Combinations with repetitions - -Repetition is Allowed: such as coins in your pocket `(5,5,5,10,10)` - -Or let us say there are five flavours of ice cream: -`banana`, `chocolate`, `lemon`, `strawberry` and `vanilla`. - -We can have three scoops. How many variations will there be? - -Let's use letters for the flavours: `{b, c, l, s, v}`. -Example selections include: - -- `{c, c, c}` (3 scoops of chocolate) -- `{b, l, v}` (one each of banana, lemon and vanilla) -- `{b, v, v}` (one of banana, two of vanilla) - -**Number of combinations** - -![Formula](https://www.mathsisfun.com/combinatorics/images/combinations-repeat.gif) - -Where `n` is the number of things to choose from, and we -choose `r` of them. Repetition allowed, -order doesn't matter. - -## Cheat Sheets - -Permutations cheat sheet - -![Permutations Cheat Sheet](https://cdn-images-1.medium.com/max/2000/1*JNK-n0Pt0Vbxk0lxVpgT5A.png) - -Combinations cheat sheet - -![Combinations Cheat Sheet](https://cdn-images-1.medium.com/max/2000/1*7cFRn8jW4g_91YgDAbmxRQ.png) - -Permutations/combinations algorithm ideas. - -![Algorithms Idea](https://cdn-images-1.medium.com/max/2000/1*vLsSsZMnesCFPCYTYMbxrQ.png) - -## References - -- [Math Is Fun](https://www.mathsisfun.com/combinatorics/combinations-permutations.html) -- [Permutations/combinations cheat sheets](https://medium.com/@trekhleb/permutations-combinations-algorithms-cheat-sheet-68c14879aba5) diff --git a/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithRepetitions.js b/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithRepetitions.js deleted file mode 100644 index 3a701f7762..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithRepetitions.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param {*[]} comboOptions - * @param {number} comboLength - * @return {*[]} - */ -export default function combineWithRepetitions(comboOptions, comboLength) { - // If the length of the combination is 1 then each element of the original array - // is a combination itself. - if (comboLength === 1) { - return comboOptions.map((comboOption) => [comboOption]); - } - // Init combinations array. - const combos = []; - // Remember characters one by one and concatenate them to combinations of smaller lengths. - // We don't extract elements here because the repetitions are allowed. - comboOptions.forEach((currentOption, optionIndex) => { - // Generate combinations of smaller size. - const smallerCombos = combineWithRepetitions(comboOptions.slice(optionIndex), comboLength - 1); - // Concatenate currentOption with all combinations of smaller size. - smallerCombos.forEach((smallerCombo) => { - combos.push([currentOption].concat(smallerCombo)); - }); - }); - return combos; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithoutRepetitions.js b/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithoutRepetitions.js deleted file mode 100644 index df69b5bf1a..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combinations/combineWithoutRepetitions.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param {*[]} comboOptions - * @param {number} comboLength - * @return {*[]} - */ -export default function combineWithoutRepetitions(comboOptions, comboLength) { - // If the length of the combination is 1 then each element of the original array - // is a combination itself. - if (comboLength === 1) { - return comboOptions.map((comboOption) => [comboOption]); - } - // Init combinations array. - const combos = []; - // Extract characters one by one and concatenate them to combinations of smaller lengths. - // We need to extract them because we don't want to have repetitions after concatenation. - comboOptions.forEach((currentOption, optionIndex) => { - // Generate combinations of smaller size. - const smallerCombos = combineWithoutRepetitions(comboOptions.slice(optionIndex + 1), comboLength - 1); - // Concatenate currentOption with all combinations of smaller size. - smallerCombos.forEach((smallerCombo) => { - combos.push([currentOption].concat(smallerCombo)); - }); - }); - return combos; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithRepetitions.test.js b/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithRepetitions.test.js deleted file mode 100644 index bbeb8d0e68..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithRepetitions.test.js +++ /dev/null @@ -1,46 +0,0 @@ -import combineWithRepetitions from '../combineWithRepetitions'; -import factorial from '../../../math/factorial/factorial'; -describe('combineWithRepetitions', () => { - it('should combine string with repetitions', () => { - expect(combineWithRepetitions(['A'], 1)).toEqual([['A']]); - expect(combineWithRepetitions(['A', 'B'], 1)).toEqual([['A'], ['B']]); - expect(combineWithRepetitions(['A', 'B'], 2)).toEqual([ - ['A', 'A'], - ['A', 'B'], - ['B', 'B'] - ]); - expect(combineWithRepetitions(['A', 'B'], 3)).toEqual([ - ['A', 'A', 'A'], - ['A', 'A', 'B'], - ['A', 'B', 'B'], - ['B', 'B', 'B'] - ]); - expect(combineWithRepetitions(['A', 'B', 'C'], 2)).toEqual([ - ['A', 'A'], - ['A', 'B'], - ['A', 'C'], - ['B', 'B'], - ['B', 'C'], - ['C', 'C'] - ]); - expect(combineWithRepetitions(['A', 'B', 'C'], 3)).toEqual([ - ['A', 'A', 'A'], - ['A', 'A', 'B'], - ['A', 'A', 'C'], - ['A', 'B', 'B'], - ['A', 'B', 'C'], - ['A', 'C', 'C'], - ['B', 'B', 'B'], - ['B', 'B', 'C'], - ['B', 'C', 'C'], - ['C', 'C', 'C'] - ]); - const combinationOptions = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; - const combinationSlotsNumber = 4; - const combinations = combineWithRepetitions(combinationOptions, combinationSlotsNumber); - const n = combinationOptions.length; - const r = combinationSlotsNumber; - const expectedNumberOfCombinations = factorial(r + n - 1) / (factorial(r) * factorial(n - 1)); - expect(combinations.length).toBe(expectedNumberOfCombinations); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithoutRepetitions.test.js b/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithoutRepetitions.test.js deleted file mode 100644 index a88f30f56b..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/combinations/test/combineWithoutRepetitions.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import combineWithoutRepetitions from '../combineWithoutRepetitions'; -import factorial from '../../../math/factorial/factorial'; -import pascalTriangle from '../../../math/pascal-triangle/pascalTriangle'; -describe('combineWithoutRepetitions', () => { - it('should combine string without repetitions', () => { - expect(combineWithoutRepetitions(['A', 'B'], 3)).toEqual([]); - expect(combineWithoutRepetitions(['A', 'B'], 1)).toEqual([['A'], ['B']]); - expect(combineWithoutRepetitions(['A'], 1)).toEqual([['A']]); - expect(combineWithoutRepetitions(['A', 'B'], 2)).toEqual([['A', 'B']]); - expect(combineWithoutRepetitions(['A', 'B', 'C'], 2)).toEqual([ - ['A', 'B'], - ['A', 'C'], - ['B', 'C'] - ]); - expect(combineWithoutRepetitions(['A', 'B', 'C'], 3)).toEqual([['A', 'B', 'C']]); - expect(combineWithoutRepetitions(['A', 'B', 'C', 'D'], 3)).toEqual([ - ['A', 'B', 'C'], - ['A', 'B', 'D'], - ['A', 'C', 'D'], - ['B', 'C', 'D'] - ]); - expect(combineWithoutRepetitions(['A', 'B', 'C', 'D', 'E'], 3)).toEqual([ - ['A', 'B', 'C'], - ['A', 'B', 'D'], - ['A', 'B', 'E'], - ['A', 'C', 'D'], - ['A', 'C', 'E'], - ['A', 'D', 'E'], - ['B', 'C', 'D'], - ['B', 'C', 'E'], - ['B', 'D', 'E'], - ['C', 'D', 'E'] - ]); - const combinationOptions = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; - const combinationSlotsNumber = 4; - const combinations = combineWithoutRepetitions(combinationOptions, combinationSlotsNumber); - const n = combinationOptions.length; - const r = combinationSlotsNumber; - const expectedNumberOfCombinations = factorial(n) / (factorial(r) * factorial(n - r)); - expect(combinations.length).toBe(expectedNumberOfCombinations); - // This one is just to see one of the way of Pascal's triangle application. - expect(combinations.length).toBe(pascalTriangle(n)[r]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/README.md b/docs/content/DS_ALGO/algorithms/sets/fisher-yates/README.md deleted file mode 100644 index 241f3cb0bc..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Fisher-Yates shuffle - -The Fisher-Yates shuffle is an algorithm for generating a random -permutation of a finite sequence—in plain terms, the algorithm -shuffles the sequence. The algorithm effectively puts all the -elements into a hat; it continually determines the next element -by randomly drawing an element from the hat until no elements -remain. The algorithm produces an unbiased permutation: every -permutation is equally likely. The modern version of the -algorithm is efficient: it takes time proportional to the -number of items being shuffled and shuffles them in place. - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) diff --git a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/fisherYates.js b/docs/content/DS_ALGO/algorithms/sets/fisher-yates/fisherYates.js deleted file mode 100644 index 9b0371436b..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/fisherYates.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @param {*[]} originalArray - * @return {*[]} - */ -export default function fisherYates(originalArray) { - // Clone array from preventing original array from modification (for testing purpose). - const array = originalArray.slice(0); - for (let i = array.length - 1; i > 0; i -= 1) { - const randomIndex = Math.floor(Math.random() * (i + 1)); - [array[i], array[randomIndex]] = [array[randomIndex], array[i]]; - } - return array; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/test/fisherYates.test.js b/docs/content/DS_ALGO/algorithms/sets/fisher-yates/test/fisherYates.test.js deleted file mode 100644 index 16d8870589..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/fisher-yates/test/fisherYates.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import fisherYates from '../fisherYates'; -import { sortedArr } from '../../../sorting/SortTester'; -import QuickSort from '../../../sorting/quick-sort/QuickSort'; -describe('fisherYates', () => { - it('should shuffle small arrays', () => { - expect(fisherYates([])).toEqual([]); - expect(fisherYates([1])).toEqual([1]); - }); - it('should shuffle array randomly', () => { - const shuffledArray = fisherYates(sortedArr); - const sorter = new QuickSort(); - expect(shuffledArray.length).toBe(sortedArr.length); - expect(shuffledArray).not.toEqual(sortedArr); - expect(sorter.sort(shuffledArray)).toEqual(sortedArr); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/Knapsack.js b/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/Knapsack.js deleted file mode 100644 index dae327e481..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/Knapsack.js +++ /dev/null @@ -1,166 +0,0 @@ -import MergeSort from '../../sorting/merge-sort/MergeSort'; -export default class Knapsack { - /** - * @param {KnapsackItem[]} possibleItems - * @param {number} weightLimit - */ - constructor(possibleItems, weightLimit) { - this.selectedItems = []; - this.weightLimit = weightLimit; - this.possibleItems = possibleItems; - } - sortPossibleItemsByWeight() { - this.possibleItems = new MergeSort({ - /** - * @var KnapsackItem itemA - * @var KnapsackItem itemB - */ - compareCallback: (itemA, itemB) => { - if (itemA.weight === itemB.weight) { - return 0; - } - return itemA.weight < itemB.weight ? -1 : 1; - } - }).sort(this.possibleItems); - } - sortPossibleItemsByValue() { - this.possibleItems = new MergeSort({ - /** - * @var KnapsackItem itemA - * @var KnapsackItem itemB - */ - compareCallback: (itemA, itemB) => { - if (itemA.value === itemB.value) { - return 0; - } - return itemA.value > itemB.value ? -1 : 1; - } - }).sort(this.possibleItems); - } - sortPossibleItemsByValuePerWeightRatio() { - this.possibleItems = new MergeSort({ - /** - * @var KnapsackItem itemA - * @var KnapsackItem itemB - */ - compareCallback: (itemA, itemB) => { - if (itemA.valuePerWeightRatio === itemB.valuePerWeightRatio) { - return 0; - } - return itemA.valuePerWeightRatio > itemB.valuePerWeightRatio ? -1 : 1; - } - }).sort(this.possibleItems); - } - // Solve 0/1 knapsack problem - // Dynamic Programming approach. - solveZeroOneKnapsackProblem() { - // We do two sorts because in case of equal weights but different values - // we need to take the most valuable items first. - this.sortPossibleItemsByValue(); - this.sortPossibleItemsByWeight(); - this.selectedItems = []; - // Create knapsack values matrix. - const numberOfRows = this.possibleItems.length; - const numberOfColumns = this.weightLimit; - const knapsackMatrix = Array(numberOfRows) - .fill(null) - .map(() => { - return Array(numberOfColumns + 1).fill(null); - }); - // Fill the first column with zeros since it would mean that there is - // no items we can add to knapsack in case if weight limitation is zero. - for (let itemIndex = 0; itemIndex < this.possibleItems.length; itemIndex += 1) { - knapsackMatrix[itemIndex][0] = 0; - } - // Fill the first row with max possible values we would get by just adding - // or not adding the first item to the knapsack. - for (let weightIndex = 1; weightIndex <= this.weightLimit; weightIndex += 1) { - const itemIndex = 0; - const itemWeight = this.possibleItems[itemIndex].weight; - const itemValue = this.possibleItems[itemIndex].value; - knapsackMatrix[itemIndex][weightIndex] = itemWeight <= weightIndex ? itemValue : 0; - } - // Go through combinations of how we may add items to knapsack and - // define what weight/value we would receive using Dynamic Programming - // approach. - for (let itemIndex = 1; itemIndex < this.possibleItems.length; itemIndex += 1) { - for (let weightIndex = 1; weightIndex <= this.weightLimit; weightIndex += 1) { - const currentItemWeight = this.possibleItems[itemIndex].weight; - const currentItemValue = this.possibleItems[itemIndex].value; - if (currentItemWeight > weightIndex) { - // In case if item's weight is bigger then currently allowed weight - // then we can't add it to knapsack and the max possible value we can - // gain at the moment is the max value we got for previous item. - knapsackMatrix[itemIndex][weightIndex] = knapsackMatrix[itemIndex - 1][weightIndex]; - } else { - // Else we need to consider the max value we can gain at this point by adding - // current value or just by keeping the previous item for current weight. - knapsackMatrix[itemIndex][weightIndex] = Math.max( - currentItemValue + knapsackMatrix[itemIndex - 1][weightIndex - currentItemWeight], - knapsackMatrix[itemIndex - 1][weightIndex] - ); - } - } - } - // Now let's trace back the knapsack matrix to see what items we're going to add - // to the knapsack. - let itemIndex = this.possibleItems.length - 1; - let weightIndex = this.weightLimit; - while (itemIndex > 0) { - const currentItem = this.possibleItems[itemIndex]; - const prevItem = this.possibleItems[itemIndex - 1]; - // Check if matrix value came from top (from previous item). - // In this case this would mean that we need to include previous item - // to the list of selected items. - if (knapsackMatrix[itemIndex][weightIndex] && knapsackMatrix[itemIndex][weightIndex] === knapsackMatrix[itemIndex - 1][weightIndex]) { - // Check if there are several items with the same weight but with the different values. - // We need to add highest item in the matrix that is possible to get the highest value. - const prevSumValue = knapsackMatrix[itemIndex - 1][weightIndex]; - const prevPrevSumValue = knapsackMatrix[itemIndex - 2][weightIndex]; - if (!prevSumValue || (prevSumValue && prevPrevSumValue !== prevSumValue)) { - this.selectedItems.push(prevItem); - } - } else if (knapsackMatrix[itemIndex - 1][weightIndex - currentItem.weight]) { - this.selectedItems.push(prevItem); - weightIndex -= currentItem.weight; - } - itemIndex -= 1; - } - } - // Solve unbounded knapsack problem. - // Greedy approach. - solveUnboundedKnapsackProblem() { - this.sortPossibleItemsByValue(); - this.sortPossibleItemsByValuePerWeightRatio(); - for (let itemIndex = 0; itemIndex < this.possibleItems.length; itemIndex += 1) { - if (this.totalWeight < this.weightLimit) { - const currentItem = this.possibleItems[itemIndex]; - // Detect how much of current items we can push to knapsack. - const availableWeight = this.weightLimit - this.totalWeight; - const maxPossibleItemsCount = Math.floor(availableWeight / currentItem.weight); - if (maxPossibleItemsCount > currentItem.itemsInStock) { - // If we have more items in stock then it is allowed to add - // let's add the maximum allowed number of them. - currentItem.quantity = currentItem.itemsInStock; - } else if (maxPossibleItemsCount) { - // In case if we don't have specified number of items in stock - // let's add only items we have in stock. - currentItem.quantity = maxPossibleItemsCount; - } - this.selectedItems.push(currentItem); - } - } - } - get totalValue() { - /** @var {KnapsackItem} item */ - return this.selectedItems.reduce((accumulator, item) => { - return accumulator + item.totalValue; - }, 0); - } - get totalWeight() { - /** @var {KnapsackItem} item */ - return this.selectedItems.reduce((accumulator, item) => { - return accumulator + item.totalWeight; - }, 0); - } -} diff --git a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/KnapsackItem.js b/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/KnapsackItem.js deleted file mode 100644 index 3503440382..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/KnapsackItem.js +++ /dev/null @@ -1,29 +0,0 @@ -export default class KnapsackItem { - /** - * @param {Object} itemSettings - knapsack item settings, - * @param {number} itemSettings.value - value of the item. - * @param {number} itemSettings.weight - weight of the item. - * @param {number} itemSettings.itemsInStock - how many items are available to be added. - */ - constructor({ value, weight, itemsInStock = 1 }) { - this.value = value; - this.weight = weight; - this.itemsInStock = itemsInStock; - // Actual number of items that is going to be added to knapsack. - this.quantity = 1; - } - get totalValue() { - return this.value * this.quantity; - } - get totalWeight() { - return this.weight * this.quantity; - } - // This coefficient shows how valuable the 1 unit of weight is - // for current item. - get valuePerWeightRatio() { - return this.value / this.weight; - } - toString() { - return `v${this.value} w${this.weight} x ${this.quantity}`; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/README.md b/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/README.md deleted file mode 100644 index e2fa588597..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Knapsack Problem - -The knapsack problem or rucksack problem is a problem in -combinatorial optimization: Given a set of items, each with -a weight and a value, determine the number of each item to -include in a collection so that the total weight is less -than or equal to a given limit and the total value is as -large as possible. - -It derives its name from the problem faced by someone who is -constrained by a fixed-size knapsack and must fill it with the -most valuable items. - -Example of a one-dimensional (constraint) knapsack problem: -which boxes should be chosen to maximize the amount of money -while still keeping the overall weight under or equal to 15 kg? - -![knapsack problem](https://upload.wikimedia.org/wikipedia/commons/f/fd/Knapsack.svg) - -## Definition - -### 0/1 knapsack problem - -The most common problem being solved is the **0/1 knapsack problem**, -which restricts the number `xi` of copies of each kind of item to zero or one. - -Given a set of n items numbered from `1` up to `n`, each with a -weight `wi` and a value `vi`, along with a maximum weight -capacity `W`, - -maximize ![0/1 knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/85620037d368d2136fb3361702df6a489416931b) - -subject to ![0/1 knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/dd6e7c9bca4397980976ea6d19237500ce3b8176) -and ![0/1 knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/07dda71da2a630762c7b21b51ea54f86f422f951) - -Here `xi` represents the number of instances of item `i` to -include in the knapsack. Informally, the problem is to maximize -the sum of the values of the items in the knapsack so that the -sum of the weights is less than or equal to the knapsack's -capacity. - -### Bounded knapsack problem (BKP) - -The **bounded knapsack problem (BKP)** removes the restriction -that there is only one of each item, but restricts the number -`xi` of copies of each kind of item to a maximum non-negative -integer value `c`: - -maximize ![bounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/85620037d368d2136fb3361702df6a489416931b) - -subject to ![bounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/dd6e7c9bca4397980976ea6d19237500ce3b8176) -and ![bounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/6c8c5ac4f8247b3b8e01e89de76a1df0ea969821) - -### Unbounded knapsack problem (UKP) - -The **unbounded knapsack problem (UKP)** places no upper bound -on the number of copies of each kind of item and can be -formulated as above except for that the only restriction -on `xi` is that it is a non-negative integer. - -maximize ![unbounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/85620037d368d2136fb3361702df6a489416931b) - -subject to ![unbounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/dd6e7c9bca4397980976ea6d19237500ce3b8176) -and ![unbounded knapsack](https://wikimedia.org/api/rest_v1/media/math/render/svg/90a99710f61d5dea19e49ae5b31164d2b56b07e3) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Knapsack_problem) -- [0/1 Knapsack Problem on YouTube](https://www.youtube.com/watch?v=8LusJS5-AGo&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/Knapsack.test.js b/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/Knapsack.test.js deleted file mode 100644 index 9d6be24247..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/Knapsack.test.js +++ /dev/null @@ -1,127 +0,0 @@ -import Knapsack from '../Knapsack'; -import KnapsackItem from '../KnapsackItem'; -describe('Knapsack', () => { - it('should solve 0/1 knapsack problem', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 1, weight: 1 }), - new KnapsackItem({ value: 4, weight: 3 }), - new KnapsackItem({ value: 5, weight: 4 }), - new KnapsackItem({ value: 7, weight: 5 }) - ]; - const maxKnapsackWeight = 7; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveZeroOneKnapsackProblem(); - expect(knapsack.totalValue).toBe(9); - expect(knapsack.totalWeight).toBe(7); - expect(knapsack.selectedItems.length).toBe(2); - expect(knapsack.selectedItems[0].toString()).toBe('v5 w4 x 1'); - expect(knapsack.selectedItems[1].toString()).toBe('v4 w3 x 1'); - }); - it('should solve 0/1 knapsack problem regardless of items order', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 5, weight: 4 }), - new KnapsackItem({ value: 1, weight: 1 }), - new KnapsackItem({ value: 7, weight: 5 }), - new KnapsackItem({ value: 4, weight: 3 }) - ]; - const maxKnapsackWeight = 7; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveZeroOneKnapsackProblem(); - expect(knapsack.totalValue).toBe(9); - expect(knapsack.totalWeight).toBe(7); - expect(knapsack.selectedItems.length).toBe(2); - expect(knapsack.selectedItems[0].toString()).toBe('v5 w4 x 1'); - expect(knapsack.selectedItems[1].toString()).toBe('v4 w3 x 1'); - }); - it('should solve 0/1 knapsack problem with impossible items set', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 5, weight: 40 }), - new KnapsackItem({ value: 1, weight: 10 }), - new KnapsackItem({ value: 7, weight: 50 }), - new KnapsackItem({ value: 4, weight: 30 }) - ]; - const maxKnapsackWeight = 7; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveZeroOneKnapsackProblem(); - expect(knapsack.totalValue).toBe(0); - expect(knapsack.totalWeight).toBe(0); - expect(knapsack.selectedItems.length).toBe(0); - }); - it('should solve 0/1 knapsack problem with all equal weights', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 5, weight: 1 }), - new KnapsackItem({ value: 1, weight: 1 }), - new KnapsackItem({ value: 7, weight: 1 }), - new KnapsackItem({ value: 4, weight: 1 }), - new KnapsackItem({ value: 4, weight: 1 }), - new KnapsackItem({ value: 4, weight: 1 }) - ]; - const maxKnapsackWeight = 3; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveZeroOneKnapsackProblem(); - expect(knapsack.totalValue).toBe(16); - expect(knapsack.totalWeight).toBe(3); - expect(knapsack.selectedItems.length).toBe(3); - expect(knapsack.selectedItems[0].toString()).toBe('v4 w1 x 1'); - expect(knapsack.selectedItems[1].toString()).toBe('v5 w1 x 1'); - expect(knapsack.selectedItems[2].toString()).toBe('v7 w1 x 1'); - }); - it('should solve unbound knapsack problem', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 84, weight: 7 }), // v/w ratio is 12 - new KnapsackItem({ value: 5, weight: 2 }), // v/w ratio is 2.5 - new KnapsackItem({ value: 12, weight: 3 }), // v/w ratio is 4 - new KnapsackItem({ value: 10, weight: 1 }), // v/w ratio is 10 - new KnapsackItem({ value: 20, weight: 2 }) // v/w ratio is 10 - ]; - const maxKnapsackWeight = 15; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveUnboundedKnapsackProblem(); - expect(knapsack.totalValue).toBe(84 + 20 + 12 + 10 + 5); - expect(knapsack.totalWeight).toBe(15); - expect(knapsack.selectedItems.length).toBe(5); - expect(knapsack.selectedItems[0].toString()).toBe('v84 w7 x 1'); - expect(knapsack.selectedItems[1].toString()).toBe('v20 w2 x 1'); - expect(knapsack.selectedItems[2].toString()).toBe('v10 w1 x 1'); - expect(knapsack.selectedItems[3].toString()).toBe('v12 w3 x 1'); - expect(knapsack.selectedItems[4].toString()).toBe('v5 w2 x 1'); - }); - it('should solve unbound knapsack problem with items in stock', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 84, weight: 7, itemsInStock: 3 }), // v/w ratio is 12 - new KnapsackItem({ value: 5, weight: 2, itemsInStock: 2 }), // v/w ratio is 2.5 - new KnapsackItem({ value: 12, weight: 3, itemsInStock: 1 }), // v/w ratio is 4 - new KnapsackItem({ value: 10, weight: 1, itemsInStock: 6 }), // v/w ratio is 10 - new KnapsackItem({ value: 20, weight: 2, itemsInStock: 8 }) // v/w ratio is 10 - ]; - const maxKnapsackWeight = 17; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveUnboundedKnapsackProblem(); - expect(knapsack.totalValue).toBe(84 + 84 + 20 + 10); - expect(knapsack.totalWeight).toBe(17); - expect(knapsack.selectedItems.length).toBe(3); - expect(knapsack.selectedItems[0].toString()).toBe('v84 w7 x 2'); - expect(knapsack.selectedItems[1].toString()).toBe('v20 w2 x 1'); - expect(knapsack.selectedItems[2].toString()).toBe('v10 w1 x 1'); - }); - it('should solve unbound knapsack problem with items in stock and max weight more than sum of all items', () => { - const possibleKnapsackItems = [ - new KnapsackItem({ value: 84, weight: 7, itemsInStock: 3 }), // v/w ratio is 12 - new KnapsackItem({ value: 5, weight: 2, itemsInStock: 2 }), // v/w ratio is 2.5 - new KnapsackItem({ value: 12, weight: 3, itemsInStock: 1 }), // v/w ratio is 4 - new KnapsackItem({ value: 10, weight: 1, itemsInStock: 6 }), // v/w ratio is 10 - new KnapsackItem({ value: 20, weight: 2, itemsInStock: 8 }) // v/w ratio is 10 - ]; - const maxKnapsackWeight = 60; - const knapsack = new Knapsack(possibleKnapsackItems, maxKnapsackWeight); - knapsack.solveUnboundedKnapsackProblem(); - expect(knapsack.totalValue).toBe(3 * 84 + 2 * 5 + 1 * 12 + 6 * 10 + 8 * 20); - expect(knapsack.totalWeight).toBe(3 * 7 + 2 * 2 + 1 * 3 + 6 * 1 + 8 * 2); - expect(knapsack.selectedItems.length).toBe(5); - expect(knapsack.selectedItems[0].toString()).toBe('v84 w7 x 3'); - expect(knapsack.selectedItems[1].toString()).toBe('v20 w2 x 8'); - expect(knapsack.selectedItems[2].toString()).toBe('v10 w1 x 6'); - expect(knapsack.selectedItems[3].toString()).toBe('v12 w3 x 1'); - expect(knapsack.selectedItems[4].toString()).toBe('v5 w2 x 2'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/KnapsackItem.test.js b/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/KnapsackItem.test.js deleted file mode 100644 index d276db557a..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/knapsack-problem/test/KnapsackItem.test.js +++ /dev/null @@ -1,29 +0,0 @@ -import KnapsackItem from '../KnapsackItem'; -describe('KnapsackItem', () => { - it('should create knapsack item and count its total weight and value', () => { - const knapsackItem = new KnapsackItem({ value: 3, weight: 2 }); - expect(knapsackItem.value).toBe(3); - expect(knapsackItem.weight).toBe(2); - expect(knapsackItem.quantity).toBe(1); - expect(knapsackItem.valuePerWeightRatio).toBe(1.5); - expect(knapsackItem.toString()).toBe('v3 w2 x 1'); - expect(knapsackItem.totalValue).toBe(3); - expect(knapsackItem.totalWeight).toBe(2); - knapsackItem.quantity = 0; - expect(knapsackItem.value).toBe(3); - expect(knapsackItem.weight).toBe(2); - expect(knapsackItem.quantity).toBe(0); - expect(knapsackItem.valuePerWeightRatio).toBe(1.5); - expect(knapsackItem.toString()).toBe('v3 w2 x 0'); - expect(knapsackItem.totalValue).toBe(0); - expect(knapsackItem.totalWeight).toBe(0); - knapsackItem.quantity = 2; - expect(knapsackItem.value).toBe(3); - expect(knapsackItem.weight).toBe(2); - expect(knapsackItem.quantity).toBe(2); - expect(knapsackItem.valuePerWeightRatio).toBe(1.5); - expect(knapsackItem.toString()).toBe('v3 w2 x 2'); - expect(knapsackItem.totalValue).toBe(6); - expect(knapsackItem.totalWeight).toBe(4); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/README.md b/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/README.md deleted file mode 100644 index 6cae61f44e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Longest common subsequence problem - -The longest common subsequence (LCS) problem is the problem of finding -the longest subsequence common to all sequences in a set of sequences -(often just two sequences). It differs from the longest common substring -problem: unlike substrings, subsequences are not required to occupy -consecutive positions within the original sequences. - -## Application - -The longest common subsequence problem is a classic computer science -problem, the basis of data comparison programs such as the diff utility, -and has applications in bioinformatics. It is also widely used by -revision control systems such as Git for reconciling multiple changes -made to a revision-controlled collection of files. - -## Example - -- LCS for input Sequences `ABCDGH` and `AEDFHR` is `ADH` of length 3. -- LCS for input Sequences `AGGTAB` and `GXTXAYB` is `GTAB` of length 4. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) -- [YouTube](https://www.youtube.com/watch?v=NnD96abizww&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/longestCommonSubsequence.js b/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/longestCommonSubsequence.js deleted file mode 100644 index 241afaf152..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/longestCommonSubsequence.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @param {string[]} set1 - * @param {string[]} set2 - * @return {string[]} - */ -export default function longestCommonSubsequence(set1, set2) { - // Init LCS matrix. - const lcsMatrix = Array(set2.length + 1) - .fill(null) - .map(() => Array(set1.length + 1).fill(null)); - // Fill first row with zeros. - for (let columnIndex = 0; columnIndex <= set1.length; columnIndex += 1) { - lcsMatrix[0][columnIndex] = 0; - } - // Fill first column with zeros. - for (let rowIndex = 0; rowIndex <= set2.length; rowIndex += 1) { - lcsMatrix[rowIndex][0] = 0; - } - // Fill rest of the column that correspond to each of two strings. - for (let rowIndex = 1; rowIndex <= set2.length; rowIndex += 1) { - for (let columnIndex = 1; columnIndex <= set1.length; columnIndex += 1) { - if (set1[columnIndex - 1] === set2[rowIndex - 1]) { - lcsMatrix[rowIndex][columnIndex] = lcsMatrix[rowIndex - 1][columnIndex - 1] + 1; - } else {} - lcsMatrix[rowIndex][columnIndex] = Math.max(lcsMatrix[rowIndex - 1][columnIndex], lcsMatrix[rowIndex][columnIndex - 1]); - } - } -} -// Calculate LCS based on LCS matrix. -if (!lcsMatrix[set2.length][set1.length]) { - // If the length of largest common string is zero then return empty string. - return ['']; -} -const longestSequence = []; -let columnIndex = set1.length; -let rowIndex = set2.length; -while (columnIndex > 0 || rowIndex > 0) { - if (set1[columnIndex - 1] === set2[rowIndex - 1]) { - // Move by diagonal left-top. - longestSequence.unshift(set1[columnIndex - 1]); - columnIndex -= 1; - rowIndex -= 1; - } else if (lcsMatrix[rowIndex][columnIndex] === lcsMatrix[rowIndex][columnIndex - 1]) { - // Move left. - columnIndex -= 1; - } else { - // Move up. - rowIndex -= 1; - } -} -return longestSequence; -} -} diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/test/longestCommonSubsequence.test.js b/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/test/longestCommonSubsequence.test.js deleted file mode 100644 index 57a5da3255..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-common-subsequence/test/longestCommonSubsequence.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import longestCommonSubsequence from '../longestCommonSubsequence'; -describe('longestCommonSubsequence', () => { - it('should find longest common subsequence for two strings', () => { - expect(longestCommonSubsequence([''], [''])).toEqual(['']); - expect(longestCommonSubsequence([''], ['A', 'B', 'C'])).toEqual(['']); - expect(longestCommonSubsequence(['A', 'B', 'C'], [''])).toEqual(['']); - expect(longestCommonSubsequence(['A', 'B', 'C'], ['D', 'E', 'F', 'G'])).toEqual(['']); - expect(longestCommonSubsequence(['A', 'B', 'C', 'D', 'G', 'H'], ['A', 'E', 'D', 'F', 'H', 'R'])).toEqual(['A', 'D', 'H']); - expect(longestCommonSubsequence(['A', 'G', 'G', 'T', 'A', 'B'], ['G', 'X', 'T', 'X', 'A', 'Y', 'B'])).toEqual(['G', 'T', 'A', 'B']); - expect(longestCommonSubsequence(['A', 'B', 'C', 'D', 'A', 'F'], ['A', 'C', 'B', 'C', 'F'])).toEqual(['A', 'B', 'C', 'F']); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/README.md b/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/README.md deleted file mode 100644 index c50c30123d..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Longest Increasing Subsequence - -The longest increasing subsequence problem is to find a subsequence of a -given sequence in which the subsequence's elements are in sorted order, -lowest to highest, and in which the subsequence is as long as possible. -This subsequence is not necessarily contiguous, or unique. - -## Complexity - -The longest increasing subsequence problem is solvable in -time `O(n log n)`, where `n` denotes the length of the input sequence. - -Dynamic programming approach has complexity `O(n * n)`. - -## Example - -In the first 16 terms of the binary Van der Corput sequence - -``` -0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 -``` - -a longest increasing subsequence is - -``` -0, 2, 6, 9, 11, 15. -``` - -This subsequence has length six; -the input sequence has no seven-member increasing subsequences. -The longest increasing subsequence in this example is not unique: for -instance, - -``` -0, 4, 6, 9, 11, 15 or -0, 2, 6, 9, 13, 15 or -0, 4, 6, 9, 13, 15 -``` - -are other increasing subsequences of equal length in the same -input sequence. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Longest_increasing_subsequence) -- [Dynamic Programming Approach on YouTube](https://www.youtube.com/watch?v=CE2b_-XfVDk&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js b/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js deleted file mode 100644 index afa0c749f0..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/dpLongestIncreasingSubsequence.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Dynamic programming approach to find longest increasing subsequence. - * Complexity: O(n * n) - * - * @param {number[]} sequence - * @return {number} - */ -export default function dpLongestIncreasingSubsequence(sequence) { - // Create array with longest increasing substrings length and - // fill it with 1-s that would mean that each element of the sequence - // is itself a minimum increasing subsequence. - const lengthsArray = Array(sequence.length).fill(1); - let previousElementIndex = 0; - let currentElementIndex = 1; - while (currentElementIndex < sequence.length) { - if (sequence[previousElementIndex] < sequence[currentElementIndex]) { - // If current element is bigger then the previous one then - // current element is a part of increasing subsequence which - // length is by one bigger then the length of increasing subsequence - // for previous element. - const newLength = lengthsArray[previousElementIndex] + 1; - if (newLength > lengthsArray[currentElementIndex]) { - // Increase only if previous element would give us bigger subsequence length - // then we already have for current element. - lengthsArray[currentElementIndex] = newLength; - } - } - // Move previous element index right. - previousElementIndex += 1; - // If previous element index equals to current element index then - // shift current element right and reset previous element index to zero. - if (previousElementIndex === currentElementIndex) { - currentElementIndex += 1; - previousElementIndex = 0; - } - } - // Find the biggest element in lengthsArray. - // This number is the biggest length of increasing subsequence. - let longestIncreasingLength = 0; - for (let i = 0; i < lengthsArray.length; i += 1) { - if (lengthsArray[i] > longestIncreasingLength) { - longestIncreasingLength = lengthsArray[i]; - } - } - return longestIncreasingLength; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/test/dpLongestIncreasingSubsequence.test.js b/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/test/dpLongestIncreasingSubsequence.test.js deleted file mode 100644 index 4adfb20dd5..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/longest-increasing-subsequence/test/dpLongestIncreasingSubsequence.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import dpLongestIncreasingSubsequence from '../dpLongestIncreasingSubsequence'; -describe('dpLongestIncreasingSubsequence', () => { - it('should find longest increasing subsequence length', () => { - // Should be: - // 9 or - // 8 or - // 7 or - // 6 or - // ... - expect(dpLongestIncreasingSubsequence([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])).toBe(1); - // Should be: - // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 - expect(dpLongestIncreasingSubsequence([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])).toBe(10); - // Should be: - // -1, 0, 2, 3 - expect(dpLongestIncreasingSubsequence([3, 4, -1, 0, 6, 2, 3])).toBe(4); - // Should be: - // 0, 2, 6, 9, 11, 15 or - // 0, 4, 6, 9, 11, 15 or - // 0, 2, 6, 9, 13, 15 or - // 0, 4, 6, 9, 13, 15 - expect(dpLongestIncreasingSubsequence([0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15])).toBe(6); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/README.md b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/README.md deleted file mode 100644 index 0af472b122..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Maximum subarray problem - -The maximum subarray problem is the task of finding the contiguous -subarray within a one-dimensional array, `a[1...n]`, of numbers -which has the largest sum, where, - -![Maximum subarray](https://wikimedia.org/api/rest_v1/media/math/render/svg/e8960f093107b71b21827e726e2bad8b023779b2) - -![Maximum subarray](https://www.geeksforgeeks.org/wp-content/uploads/kadane-Algorithm.png) - -## Example - -The list usually contains both positive and negative numbers along -with `0`. For example, for the array of -values `−2, 1, −3, 4, −1, 2, 1, −5, 4` the contiguous subarray -with the largest sum is `4, −1, 2, 1`, with sum `6`. - -## Solutions - -- Brute Force solution `O(n^2)`: [bfMaximumSubarray.js](./bfMaximumSubarray.js) -- Divide and Conquer solution `O(n^2)`: [dcMaximumSubarraySum.js](./dcMaximumSubarraySum.js) -- Dynamic Programming solution `O(n)`: [dpMaximumSubarray.js](./dpMaximumSubarray.js) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Maximum_subarray_problem) -- [YouTube](https://www.youtube.com/watch?v=ohHWQf1HDfU&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [GeeksForGeeks](https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/) -- [LeetCode](https://leetcode.com/explore/interview/card/top-interview-questions-easy/97/dynamic-programming/566/discuss/1595195/C++Python-7-Simple-Solutions-w-Explanation-or-Brute-Force-+-DP-+-Kadane-+-Divide-and-Conquer) diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/bfMaximumSubarray.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/bfMaximumSubarray.js deleted file mode 100644 index a8999ffbc4..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/bfMaximumSubarray.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Brute Force solution. - * Complexity: O(n^2) - * - * @param {Number[]} inputArray - * @return {Number[]} - */ -export default function bfMaximumSubarray(inputArray) { - let maxSubarrayStartIndex = 0; - let maxSubarrayLength = 0; - let maxSubarraySum = null; - for (let startIndex = 0; startIndex < inputArray.length; startIndex += 1) { - let subarraySum = 0; - for (let arrLength = 1; arrLength <= inputArray.length - startIndex; arrLength += 1) { - subarraySum += inputArray[startIndex + (arrLength - 1)]; - if (maxSubarraySum === null || subarraySum > maxSubarraySum) { - maxSubarraySum = subarraySum; - maxSubarrayStartIndex = startIndex; - maxSubarrayLength = arrLength; - } - } - } - return inputArray.slice(maxSubarrayStartIndex, maxSubarrayStartIndex + maxSubarrayLength); -} diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dcMaximumSubarraySum.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dcMaximumSubarraySum.js deleted file mode 100644 index 3f3bfd20d1..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dcMaximumSubarraySum.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Divide and Conquer solution. - * Complexity: O(n^2) in case if no memoization applied - * - * @param {Number[]} inputArray - * @return {Number[]} - */ -export default function dcMaximumSubarraySum(inputArray) { - /** - * We are going through the inputArray array and for each element we have two options: - * - to pick - * - not to pick - * - * Also keep in mind, that the maximum sub-array must be contiguous. It means if we picked - * the element, we need to continue picking the next elements or stop counting the max sum. - * - * @param {number} elementIndex - the index of the element we're deciding to pick or not - * @param {boolean} mustPick - to pick or not to pick the element - * @returns {number} - maximum subarray sum that we'll get - */ - function solveRecursively(elementIndex, mustPick) { - if (elementIndex >= inputArray.length) { - return mustPick ? 0 : -Infinity; - } - return Math.max( - // Option #1: Pick the current element, and continue picking next one. - inputArray[elementIndex] + solveRecursively(elementIndex + 1, true), - // Option #2: Don't pick the current element. - mustPick ? 0 : solveRecursively(elementIndex + 1, false) - ); - } - return solveRecursively(0, false); -} diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dpMaximumSubarray.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dpMaximumSubarray.js deleted file mode 100644 index a4bf0f3e0c..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/dpMaximumSubarray.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Dynamic Programming solution. - * Complexity: O(n) - * - * @param {Number[]} inputArray - * @return {Number[]} - */ -export default function dpMaximumSubarray(inputArray) { - // We iterate through the inputArray once, using a greedy approach to keep track of the maximum - // sum we've seen so far and the current sum. - // - // The currentSum variable gets reset to 0 every time it drops below 0. - // - // The maxSum variable is set to -Infinity so that if all numbers are negative, the highest - // negative number will constitute the maximum subarray. - let maxSum = -Infinity; - let currentSum = 0; - // We need to keep track of the starting and ending indices that contributed to our maxSum - // so that we can return the actual subarray. From the beginning let's assume that whole array - // is contributing to maxSum. - let maxStartIndex = 0; - let maxEndIndex = inputArray.length - 1; - let currentStartIndex = 0; - inputArray.forEach((currentNumber, currentIndex) => { - currentSum += currentNumber; - // Update maxSum and the corresponding indices if we have found a new max. - if (maxSum < currentSum) { - maxSum = currentSum; - maxStartIndex = currentStartIndex; - maxEndIndex = currentIndex; - } - // Reset currentSum and currentStartIndex if currentSum drops below 0. - if (currentSum < 0) { - currentSum = 0; - currentStartIndex = currentIndex + 1; - } - }); - return inputArray.slice(maxStartIndex, maxEndIndex + 1); -} diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/bfMaximumSubarray.test.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/bfMaximumSubarray.test.js deleted file mode 100644 index ec9ae71014..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/bfMaximumSubarray.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import bfMaximumSubarray from '../bfMaximumSubarray'; -describe('bfMaximumSubarray', () => { - it('should find maximum subarray using the brute force algorithm', () => { - expect(bfMaximumSubarray([])).toEqual([]); - expect(bfMaximumSubarray([0, 0])).toEqual([0]); - expect(bfMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]); - expect(bfMaximumSubarray([0, 0, 1, 2])).toEqual([0, 0, 1, 2]); - expect(bfMaximumSubarray([0, 0, -1, 2])).toEqual([2]); - expect(bfMaximumSubarray([-1, -2, -3, -4, -5])).toEqual([-1]); - expect(bfMaximumSubarray([1, 2, 3, 2, 3, 4, 5])).toEqual([1, 2, 3, 2, 3, 4, 5]); - expect(bfMaximumSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual([4, -1, 2, 1]); - expect(bfMaximumSubarray([-2, -3, 4, -1, -2, 1, 5, -3])).toEqual([4, -1, -2, 1, 5]); - expect(bfMaximumSubarray([1, -3, 2, -5, 7, 6, -1, 4, 11, -23])).toEqual([7, 6, -1, 4, 11]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dcMaximumSubarraySum.test.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dcMaximumSubarraySum.test.js deleted file mode 100644 index 7574162557..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dcMaximumSubarraySum.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import dcMaximumSubarray from '../dcMaximumSubarraySum'; -describe('dcMaximumSubarraySum', () => { - it('should find maximum subarray sum using the divide and conquer algorithm', () => { - expect(dcMaximumSubarray([])).toEqual(-Infinity); - expect(dcMaximumSubarray([0, 0])).toEqual(0); - expect(dcMaximumSubarray([0, 0, 1])).toEqual(1); - expect(dcMaximumSubarray([0, 0, 1, 2])).toEqual(3); - expect(dcMaximumSubarray([0, 0, -1, 2])).toEqual(2); - expect(dcMaximumSubarray([-1, -2, -3, -4, -5])).toEqual(-1); - expect(dcMaximumSubarray([1, 2, 3, 2, 3, 4, 5])).toEqual(20); - expect(dcMaximumSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6); - expect(dcMaximumSubarray([-2, -3, 4, -1, -2, 1, 5, -3])).toEqual(7); - expect(dcMaximumSubarray([1, -3, 2, -5, 7, 6, -1, 4, 11, -23])).toEqual(27); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dpMaximumSubarray.test.js b/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dpMaximumSubarray.test.js deleted file mode 100644 index e5ee18ec75..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/maximum-subarray/test/dpMaximumSubarray.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import dpMaximumSubarray from '../dpMaximumSubarray'; -describe('dpMaximumSubarray', () => { - it('should find maximum subarray using the dynamic programming algorithm', () => { - expect(dpMaximumSubarray([])).toEqual([]); - expect(dpMaximumSubarray([0, 0])).toEqual([0]); - expect(dpMaximumSubarray([0, 0, 1])).toEqual([0, 0, 1]); - expect(dpMaximumSubarray([0, 0, 1, 2])).toEqual([0, 0, 1, 2]); - expect(dpMaximumSubarray([0, 0, -1, 2])).toEqual([2]); - expect(dpMaximumSubarray([-1, -2, -3, -4, -5])).toEqual([-1]); - expect(dpMaximumSubarray([1, 2, 3, 2, 3, 4, 5])).toEqual([1, 2, 3, 2, 3, 4, 5]); - expect(dpMaximumSubarray([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual([4, -1, 2, 1]); - expect(dpMaximumSubarray([-2, -3, 4, -1, -2, 1, 5, -3])).toEqual([4, -1, -2, 1, 5]); - expect(dpMaximumSubarray([1, -3, 2, -5, 7, 6, -1, 4, 11, -23])).toEqual([7, 6, -1, 4, 11]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/permutations/README.md b/docs/content/DS_ALGO/algorithms/sets/permutations/README.md deleted file mode 100644 index b2bb9b4301..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/permutations/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Permutations - -When the order doesn't matter, it is a **Combination**. - -When the order **does** matter it is a **Permutation**. - -**"The combination to the safe is 472"**. We do care about the order. `724` won't work, nor will `247`. -It has to be exactly `4-7-2`. - -## Permutations without repetitions - -A permutation, also called an "arrangement number" or "order", is a rearrangement of -the elements of an ordered list `S` into a one-to-one correspondence with `S` itself. - -Below are the permutations of string `ABC`. - -```MATH -ABC ACB BAC BCA CBA CAB -``` - -Or for example the first three people in a running race: you can't be first and second. - -**Number of combinations** - -```MATH -n * (n-1) * (n -2) * ... * 1 = n! -``` - -## Permutations with repetitions - -When repetition is allowed we have permutations with repetitions. -For example the the lock below: it could be `333`. - -###### Number of combinations - -```MATH -n * n * n ... (r times) = n^r -``` - -## Cheat Sheets - -Permutations cheat sheet - -![Permutations Cheat Sheet](https://cdn-images-1.medium.com/max/2000/1*JNK-n0Pt0Vbxk0lxVpgT5A.png) - -Combinations cheat sheet - -![Combinations Cheat Sheet](https://cdn-images-1.medium.com/max/2000/1*7cFRn8jW4g_91YgDAbmxRQ.png) - -Permutations/combinations algorithm ideas. - -![Algorithms Idea](https://cdn-images-1.medium.com/max/2000/1*vLsSsZMnesCFPCYTYMbxrQ.png) - -## References - -- [Math Is Fun](https://www.mathsisfun.com/combinatorics/combinations-permutations.html) -- [Permutations/combinations cheat sheets](https://medium.com/@trekhleb/permutations-combinations-algorithms-cheat-sheet-68c14879aba5) diff --git a/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithRepetitions.js b/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithRepetitions.js deleted file mode 100644 index 57d44fb2f7..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithRepetitions.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @param {*[]} permutationOptions - * @param {number} permutationLength - * @return {*[]} - */ -export default function permutateWithRepetitions(permutationOptions, permutationLength = permutationOptions.length) { - if (permutationLength === 1) { - return permutationOptions.map((permutationOption) => [permutationOption]); - } - // Init permutations array. - const permutations = []; - // Get smaller permutations. - const smallerPermutations = permutateWithRepetitions(permutationOptions, permutationLength - 1); - // Go through all options and join it to the smaller permutations. - permutationOptions.forEach((currentOption) => { - smallerPermutations.forEach((smallerPermutation) => { - permutations.push([currentOption].concat(smallerPermutation)); - }); - }); - return permutations; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithoutRepetitions.js b/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithoutRepetitions.js deleted file mode 100644 index 50cba0dd2f..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/permutations/permutateWithoutRepetitions.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param {*[]} permutationOptions - * @return {*[]} - */ -export default function permutateWithoutRepetitions(permutationOptions) { - if (permutationOptions.length === 1) { - return [permutationOptions]; - } - // Init permutations array. - const permutations = []; - // Get all permutations for permutationOptions excluding the first element. - const smallerPermutations = permutateWithoutRepetitions(permutationOptions.slice(1)); - // Insert first option into every possible position of every smaller permutation. - const firstOption = permutationOptions[0]; - for (let permIndex = 0; permIndex < smallerPermutations.length; permIndex += 1) { - const smallerPermutation = smallerPermutations[permIndex]; - // Insert first option into every possible position of smallerPermutation. - for (let positionIndex = 0; positionIndex <= smallerPermutation.length; positionIndex += 1) { - const permutationPrefix = smallerPermutation.slice(0, positionIndex); - const permutationSuffix = smallerPermutation.slice(positionIndex); - permutations.push(permutationPrefix.concat([firstOption], permutationSuffix)); - } - } - return permutations; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithRepetitions.test.js b/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithRepetitions.test.js deleted file mode 100644 index 4f08c18fa2..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithRepetitions.test.js +++ /dev/null @@ -1,46 +0,0 @@ -import permutateWithRepetitions from '../permutateWithRepetitions'; -describe('permutateWithRepetitions', () => { - it('should permutate string with repetition', () => { - const permutations1 = permutateWithRepetitions(['A']); - expect(permutations1).toEqual([['A']]); - const permutations2 = permutateWithRepetitions(['A', 'B']); - expect(permutations2).toEqual([ - ['A', 'A'], - ['A', 'B'], - ['B', 'A'], - ['B', 'B'] - ]); - const permutations3 = permutateWithRepetitions(['A', 'B', 'C']); - expect(permutations3).toEqual([ - ['A', 'A', 'A'], - ['A', 'A', 'B'], - ['A', 'A', 'C'], - ['A', 'B', 'A'], - ['A', 'B', 'B'], - ['A', 'B', 'C'], - ['A', 'C', 'A'], - ['A', 'C', 'B'], - ['A', 'C', 'C'], - ['B', 'A', 'A'], - ['B', 'A', 'B'], - ['B', 'A', 'C'], - ['B', 'B', 'A'], - ['B', 'B', 'B'], - ['B', 'B', 'C'], - ['B', 'C', 'A'], - ['B', 'C', 'B'], - ['B', 'C', 'C'], - ['C', 'A', 'A'], - ['C', 'A', 'B'], - ['C', 'A', 'C'], - ['C', 'B', 'A'], - ['C', 'B', 'B'], - ['C', 'B', 'C'], - ['C', 'C', 'A'], - ['C', 'C', 'B'], - ['C', 'C', 'C'] - ]); - const permutations4 = permutateWithRepetitions(['A', 'B', 'C', 'D']); - expect(permutations4.length).toBe(4 * 4 * 4 * 4); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithoutRepetitions.test.js b/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithoutRepetitions.test.js deleted file mode 100644 index 9763f244e9..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/permutations/test/permutateWithoutRepetitions.test.js +++ /dev/null @@ -1,60 +0,0 @@ -import permutateWithoutRepetitions from '../permutateWithoutRepetitions'; -import factorial from '../../../math/factorial/factorial'; -describe('permutateWithoutRepetitions', () => { - it('should permutate string', () => { - const permutations1 = permutateWithoutRepetitions(['A']); - expect(permutations1).toEqual([['A']]); - const permutations2 = permutateWithoutRepetitions(['A', 'B']); - expect(permutations2.length).toBe(2); - expect(permutations2).toEqual([ - ['A', 'B'], - ['B', 'A'] - ]); - const permutations6 = permutateWithoutRepetitions(['A', 'A']); - expect(permutations6.length).toBe(2); - expect(permutations6).toEqual([ - ['A', 'A'], - ['A', 'A'] - ]); - const permutations3 = permutateWithoutRepetitions(['A', 'B', 'C']); - expect(permutations3.length).toBe(factorial(3)); - expect(permutations3).toEqual([ - ['A', 'B', 'C'], - ['B', 'A', 'C'], - ['B', 'C', 'A'], - ['A', 'C', 'B'], - ['C', 'A', 'B'], - ['C', 'B', 'A'] - ]); - const permutations4 = permutateWithoutRepetitions(['A', 'B', 'C', 'D']); - expect(permutations4.length).toBe(factorial(4)); - expect(permutations4).toEqual([ - ['A', 'B', 'C', 'D'], - ['B', 'A', 'C', 'D'], - ['B', 'C', 'A', 'D'], - ['B', 'C', 'D', 'A'], - ['A', 'C', 'B', 'D'], - ['C', 'A', 'B', 'D'], - ['C', 'B', 'A', 'D'], - ['C', 'B', 'D', 'A'], - ['A', 'C', 'D', 'B'], - ['C', 'A', 'D', 'B'], - ['C', 'D', 'A', 'B'], - ['C', 'D', 'B', 'A'], - ['A', 'B', 'D', 'C'], - ['B', 'A', 'D', 'C'], - ['B', 'D', 'A', 'C'], - ['B', 'D', 'C', 'A'], - ['A', 'D', 'B', 'C'], - ['D', 'A', 'B', 'C'], - ['D', 'B', 'A', 'C'], - ['D', 'B', 'C', 'A'], - ['A', 'D', 'C', 'B'], - ['D', 'A', 'C', 'B'], - ['D', 'C', 'A', 'B'], - ['D', 'C', 'B', 'A'] - ]); - const permutations5 = permutateWithoutRepetitions(['A', 'B', 'C', 'D', 'E', 'F']); - expect(permutations5.length).toBe(factorial(6)); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/power-set/README.md b/docs/content/DS_ALGO/algorithms/sets/power-set/README.md deleted file mode 100644 index 888986dfa7..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/power-set/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Power Set - -Power set of a set `S` is the set of all of the subsets of `S`, including the -empty set and `S` itself. Power set of set `S` is denoted as `P(S)`. - -For example for `{x, y, z}`, the subsets -are: - -```text -{ - {}, // (also denoted empty set ∅ or the null set) - {x}, - {y}, - {z}, - {x, y}, - {x, z}, - {y, z}, - {x, y, z} -} -``` - -![Power Set](https://www.mathsisfun.com/sets/images/power-set.svg) - -Here is how we may illustrate the elements of the power set of the set `{x, y, z}` ordered with respect to -inclusion: - -![](https://upload.wikimedia.org/wikipedia/commons/e/ea/Hasse_diagram_of_powerset_of_3.svg) - -**Number of Subsets** - -If `S` is a finite set with `|S| = n` elements, then the number of subsets -of `S` is `|P(S)| = 2^n`. This fact, which is the motivation for the -notation `2^S`, may be demonstrated simply as follows: - -> First, order the elements of `S` in any manner. We write any subset of `S` in -> the format `{γ1, γ2, ..., γn}` where `γi , 1 ≤ i ≤ n`, can take the value -> of `0` or `1`. If `γi = 1`, the `i`-th element of `S` is in the subset; -> otherwise, the `i`-th element is not in the subset. Clearly the number of -> distinct subsets that can be constructed this way is `2^n` as `γi ∈ {0, 1}`. - -## Algorithms - -### Bitwise Solution - -Each number in binary representation in a range from `0` to `2^n` does exactly -what we need: it shows by its bits (`0` or `1`) whether to include related -element from the set or not. For example, for the set `{1, 2, 3}` the binary -number of `0b010` would mean that we need to include only `2` to the current set. - -| | `abc` | Subset | -| :-: | :---: | :---------: | -| `0` | `000` | `{}` | -| `1` | `001` | `{c}` | -| `2` | `010` | `{b}` | -| `3` | `011` | `{c, b}` | -| `4` | `100` | `{a}` | -| `5` | `101` | `{a, c}` | -| `6` | `110` | `{a, b}` | -| `7` | `111` | `{a, b, c}` | - -> See [bwPowerSet.js](./bwPowerSet.js) file for bitwise solution. - -### Backtracking Solution - -In backtracking approach we're constantly trying to add next element of the set -to the subset, memorizing it and then removing it and try the same with the next -element. - -> See [btPowerSet.js](./btPowerSet.js) file for backtracking solution. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Power_set) -- [Math is Fun](https://www.mathsisfun.com/sets/power-set.html) diff --git a/docs/content/DS_ALGO/algorithms/sets/power-set/btPowerSet.js b/docs/content/DS_ALGO/algorithms/sets/power-set/btPowerSet.js deleted file mode 100644 index edc369cddb..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/power-set/btPowerSet.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @param {*[]} originalSet - Original set of elements we're forming power-set of. - * @param {*[][]} allSubsets - All subsets that have been formed so far. - * @param {*[]} currentSubSet - Current subset that we're forming at the moment. - * @param {number} startAt - The position of in original set we're starting to form current subset. - * @return {*[][]} - All subsets of original set. - */ -function btPowerSetRecursive(originalSet, allSubsets = [[]], currentSubSet = [], startAt = 0) { - // Let's iterate over originalSet elements that may be added to the subset - // without having duplicates. The value of startAt prevents adding the duplicates. - for (let position = startAt; position < originalSet.length; position += 1) { - // Let's push current element to the subset - currentSubSet.push(originalSet[position]); - // Current subset is already valid so let's memorize it. - // We do array destruction here to save the clone of the currentSubSet. - // We need to save a clone since the original currentSubSet is going to be - // mutated in further recursive calls. - allSubsets.push([...currentSubSet]); - // Let's try to generate all other subsets for the current subset. - // We're increasing the position by one to avoid duplicates in subset. - btPowerSetRecursive(originalSet, allSubsets, currentSubSet, position + 1); - // BACKTRACK. Exclude last element from the subset and try the next valid one. - currentSubSet.pop(); - } - // Return all subsets of a set. - return allSubsets; -} -/** - * Find power-set of a set using BACKTRACKING approach. - * - * @param {*[]} originalSet - * @return {*[][]} - */ -export default function btPowerSet(originalSet) { - return btPowerSetRecursive(originalSet); -} diff --git a/docs/content/DS_ALGO/algorithms/sets/power-set/bwPowerSet.js b/docs/content/DS_ALGO/algorithms/sets/power-set/bwPowerSet.js deleted file mode 100644 index 52d3718fa5..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/power-set/bwPowerSet.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Find power-set of a set using BITWISE approach. - * - * @param {*[]} originalSet - * @return {*[][]} - */ -export default function bwPowerSet(originalSet) { - const subSets = []; - // We will have 2^n possible combinations (where n is a length of original set). - // It is because for every element of original set we will decide whether to include - // it or not (2 options for each set element). - const numberOfCombinations = 2 ** originalSet.length; - // Each number in binary representation in a range from 0 to 2^n does exactly what we need: - // it shows by its bits (0 or 1) whether to include related element from the set or not. - // For example, for the set {1, 2, 3} the binary number of 0b010 would mean that we need to - // include only "2" to the current set. - for (let combinationIndex = 0; combinationIndex < numberOfCombinations; combinationIndex += 1) { - const subSet = []; - for (let setElementIndex = 0; setElementIndex < originalSet.length; setElementIndex += 1) { - // Decide whether we need to include current element into the subset or not. - if (combinationIndex & (1 << setElementIndex)) { - subSet.push(originalSet[setElementIndex]); - } - } - // Add current subset to the list of all subsets. - subSets.push(subSet); - } - return subSets; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/power-set/test/btPowerSet.test.js b/docs/content/DS_ALGO/algorithms/sets/power-set/test/btPowerSet.test.js deleted file mode 100644 index ab85c67c4e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/power-set/test/btPowerSet.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import btPowerSet from '../btPowerSet'; -describe('btPowerSet', () => { - it('should calculate power set of given set using backtracking approach', () => { - expect(btPowerSet([1])).toEqual([[], [1]]); - expect(btPowerSet([1, 2, 3])).toEqual([[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/power-set/test/bwPowerSet.test.js b/docs/content/DS_ALGO/algorithms/sets/power-set/test/bwPowerSet.test.js deleted file mode 100644 index 589b384a9f..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/power-set/test/bwPowerSet.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import bwPowerSet from '../bwPowerSet'; -describe('bwPowerSet', () => { - it('should calculate power set of given set using bitwise approach', () => { - expect(bwPowerSet([1])).toEqual([[], [1]]); - expect(bwPowerSet([1, 2, 3])).toEqual([[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/README.md b/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/README.md deleted file mode 100644 index c24b27b3d1..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Shortest Common Supersequence - -The shortest common supersequence (SCS) of two sequences `X` and `Y` -is the shortest sequence which has `X` and `Y` as subsequences. - -In other words assume we're given two strings str1 and str2, find -the shortest string that has both str1 and str2 as subsequences. - -This is a problem closely related to the longest common -subsequence problem. - -## Example - -``` -Input: str1 = "geek", str2 = "eke" -Output: "geeke" - -Input: str1 = "AGGTAB", str2 = "GXTXAYB" -Output: "AGXGTXAYB" -``` - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/shortest-common-supersequence/) diff --git a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/shortestCommonSupersequence.js b/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/shortestCommonSupersequence.js deleted file mode 100644 index 03ec2c6f13..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/shortestCommonSupersequence.js +++ /dev/null @@ -1,62 +0,0 @@ -import longestCommonSubsequence from '../longest-common-subsequence/longestCommonSubsequence'; -/** - * @param {string[]} set1 - * @param {string[]} set2 - * @return {string[]} - */ -export default function shortestCommonSupersequence(set1, set2) { - // Let's first find the longest common subsequence of two sets. - const lcs = longestCommonSubsequence(set1, set2); - // If LCS is empty then the shortest common supersequence would be just - // concatenation of two sequences. - if (lcs.length === 1 && lcs[0] === '') { - return set1.concat(set2); - } - // Now let's add elements of set1 and set2 in order before/inside/after the LCS. - let supersequence = []; - let setIndex1 = 0; - let setIndex2 = 0; - let lcsIndex = 0; - let setOnHold1 = false; - let setOnHold2 = false; - while (lcsIndex < lcs.length) { - // Add elements of the first set to supersequence in correct order. - if (setIndex1 < set1.length) { - if (!setOnHold1 && set1[setIndex1] !== lcs[lcsIndex]) { - supersequence.push(set1[setIndex1]); - setIndex1 += 1; - } else {} - setOnHold1 = true; - } - } - // Add elements of the second set to supersequence in correct order. - if (setIndex2 < set2.length) { - if (!setOnHold2 && set2[setIndex2] !== lcs[lcsIndex]) { - supersequence.push(set2[setIndex2]); - setIndex2 += 1; - } else {} - setOnHold2 = true; - } -} -// Add LCS element to the supersequence in correct order. -if (setOnHold1 && setOnHold2) { - supersequence.push(lcs[lcsIndex]); - lcsIndex += 1; - setIndex1 += 1; - setIndex2 += 1; - setOnHold1 = false; - setOnHold2 = false; -} -} -// Attach set1 leftovers. -if (setIndex1 < set1.length) { - supersequence = supersequence.concat(set1.slice(setIndex1)); -} -// Attach set2 leftovers. -if (setIndex2 < set2.length) { - supersequence = supersequence.concat(set2.slice(setIndex2)); -} -return supersequence; -} -return supersequence; -} diff --git a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/test/shortestCommonSupersequence.test.js b/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/test/shortestCommonSupersequence.test.js deleted file mode 100644 index bbd9ca4f3e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sets/shortest-common-supersequence/test/shortestCommonSupersequence.test.js +++ /dev/null @@ -1,46 +0,0 @@ -import shortestCommonSupersequence from '../shortestCommonSupersequence'; -describe('shortestCommonSupersequence', () => { - it('should find shortest common supersequence of two sequences', () => { - // LCS (longest common subsequence) is empty - expect(shortestCommonSupersequence(['A', 'B', 'C'], ['D', 'E', 'F'])).toEqual(['A', 'B', 'C', 'D', 'E', 'F']); - // LCS (longest common subsequence) is "EE" - expect(shortestCommonSupersequence(['G', 'E', 'E', 'K'], ['E', 'K', 'E'])).toEqual(['G', 'E', 'K', 'E', 'K']); - // LCS (longest common subsequence) is "GTAB" - expect(shortestCommonSupersequence(['A', 'G', 'G', 'T', 'A', 'B'], ['G', 'X', 'T', 'X', 'A', 'Y', 'B'])).toEqual([ - 'A', - 'G', - 'G', - 'X', - 'T', - 'X', - 'A', - 'Y', - 'B' - ]); - // LCS (longest common subsequence) is "BCBA". - expect(shortestCommonSupersequence(['A', 'B', 'C', 'B', 'D', 'A', 'B'], ['B', 'D', 'C', 'A', 'B', 'A'])).toEqual([ - 'A', - 'B', - 'D', - 'C', - 'A', - 'B', - 'D', - 'A', - 'B' - ]); - // LCS (longest common subsequence) is "BDABA". - expect(shortestCommonSupersequence(['B', 'D', 'C', 'A', 'B', 'A'], ['A', 'B', 'C', 'B', 'D', 'A', 'B', 'A', 'C'])).toEqual([ - 'A', - 'B', - 'C', - 'B', - 'D', - 'C', - 'A', - 'B', - 'A', - 'C' - ]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/Sort.js b/docs/content/DS_ALGO/algorithms/sorting/Sort.js deleted file mode 100644 index 92d9f50863..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/Sort.js +++ /dev/null @@ -1,28 +0,0 @@ -import Comparator from '../../utils/comparator/Comparator'; -/** - * @typedef {Object} SorterCallbacks - * @property {function(a: *, b: *)} compareCallback - If provided then all elements comparisons - * will be done through this callback. - * @property {function(a: *)} visitingCallback - If provided it will be called each time the sorting - * function is visiting the next element. - */ -export default class Sort { - constructor(originalCallbacks) { - this.callbacks = Sort.initSortingCallbacks(originalCallbacks); - this.comparator = new Comparator(this.callbacks.compareCallback); - } - /** - * @param {SorterCallbacks} originalCallbacks - * @returns {SorterCallbacks} - */ - static initSortingCallbacks(originalCallbacks) { - const callbacks = originalCallbacks || {}; - const stubCallback = () => {}; - callbacks.compareCallback = callbacks.compareCallback || undefined; - callbacks.visitingCallback = callbacks.visitingCallback || stubCallback; - return callbacks; - } - sort() { - throw new Error('sort method must be implemented'); - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/SortTester.js b/docs/content/DS_ALGO/algorithms/sorting/SortTester.js deleted file mode 100644 index 745d967ee4..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/SortTester.js +++ /dev/null @@ -1,64 +0,0 @@ -export const sortedArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; -export const reverseArr = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; -export const notSortedArr = [15, 8, 5, 12, 10, 1, 16, 9, 11, 7, 20, 3, 2, 6, 17, 18, 4, 13, 14, 19]; -export const equalArr = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; -export const negativeArr = [-1, 0, 5, -10, 20, 13, -7, 3, 2, -3]; -export const negativeArrSorted = [-10, -7, -3, -1, 0, 2, 3, 5, 13, 20]; -export class SortTester { - static testSort(SortingClass) { - const sorter = new SortingClass(); - expect(sorter.sort([])).toEqual([]); - expect(sorter.sort([1])).toEqual([1]); - expect(sorter.sort([1, 2])).toEqual([1, 2]); - expect(sorter.sort([2, 1])).toEqual([1, 2]); - expect(sorter.sort([3, 4, 2, 1, 0, 0, 4, 3, 4, 2])).toEqual([0, 0, 1, 2, 2, 3, 3, 4, 4, 4]); - expect(sorter.sort(sortedArr)).toEqual(sortedArr); - expect(sorter.sort(reverseArr)).toEqual(sortedArr); - expect(sorter.sort(notSortedArr)).toEqual(sortedArr); - expect(sorter.sort(equalArr)).toEqual(equalArr); - } - static testNegativeNumbersSort(SortingClass) { - const sorter = new SortingClass(); - expect(sorter.sort(negativeArr)).toEqual(negativeArrSorted); - } - static testSortWithCustomComparator(SortingClass) { - const callbacks = { - compareCallback: (a, b) => { - if (a.length === b.length) { - return 0; - } - return a.length < b.length ? -1 : 1; - } - }; - const sorter = new SortingClass(callbacks); - expect(sorter.sort([''])).toEqual(['']); - expect(sorter.sort(['a'])).toEqual(['a']); - expect(sorter.sort(['aa', 'a'])).toEqual(['a', 'aa']); - expect(sorter.sort(['aa', 'q', 'bbbb', 'ccc'])).toEqual(['q', 'aa', 'ccc', 'bbbb']); - expect(sorter.sort(['aa', 'aa'])).toEqual(['aa', 'aa']); - } - static testSortStability(SortingClass) { - const callbacks = { - compareCallback: (a, b) => { - if (a.length === b.length) { - return 0; - } - return a.length < b.length ? -1 : 1; - } - }; - const sorter = new SortingClass(callbacks); - expect(sorter.sort(['bb', 'aa', 'c'])).toEqual(['c', 'bb', 'aa']); - expect(sorter.sort(['aa', 'q', 'a', 'bbbb', 'ccc'])).toEqual(['q', 'a', 'aa', 'ccc', 'bbbb']); - } - static testAlgorithmTimeComplexity(SortingClass, arrayToBeSorted, numberOfVisits) { - const visitingCallback = jest.fn(); - const callbacks = { - visitingCallback - }; - const sorter = new SortingClass(callbacks); - sorter.sort(arrayToBeSorted); - expect(visitingCallback).toHaveBeenCalledTimes(numberOfVisits); - } -} -} -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/BubbleSort.js b/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/BubbleSort.js deleted file mode 100644 index 7d77b49977..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/BubbleSort.js +++ /dev/null @@ -1,30 +0,0 @@ -import Sort from '../Sort'; -export default class BubbleSort extends Sort { - sort(originalArray) { - // Flag that holds info about whether the swap has occur or not. - let swapped = false; - // Clone original array to prevent its modification. - const array = [...originalArray]; - for (let i = 1; i < array.length; i += 1) { - swapped = false; - // Call visiting callback. - this.callbacks.visitingCallback(array[i]); - for (let j = 0; j < array.length - i; j += 1) { - // Call visiting callback. - this.callbacks.visitingCallback(array[j]); - // Swap elements if they are in wrong order. - if (this.comparator.lessThan(array[j + 1], array[j])) { - [array[j], array[j + 1]] = [array[j + 1], array[j]]; - // Register the swap. - swapped = true; - } - } - // If there were no swaps then array is already sorted and there is - // no need to proceed. - if (!swapped) { - return array; - } - } - return array; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/README.md deleted file mode 100644 index 2f1770f52e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Bubble Sort - -Bubble sort, sometimes referred to as sinking sort, is a -simple sorting algorithm that repeatedly steps through -the list to be sorted, compares each pair of adjacent -items and swaps them if they are in the wrong order -(ascending or descending arrangement). The pass through -the list is repeated until no swaps are needed, which -indicates that the list is sorted. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/c/c8/Bubble-sort-example-300px.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| --------------- | :--: | :-----------: | :-----------: | :----: | :----: | :------- | -| **Bubble sort** | n | n2 | n2 | 1 | Yes | | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Bubble_sort) -- [YouTube](https://www.youtube.com/watch?v=6Gv8vg0kcHc&index=27&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/test/BubbleSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/test/BubbleSort.test.js deleted file mode 100644 index b03386a71e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/bubble-sort/test/BubbleSort.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import BubbleSort from '../BubbleSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 20; -const NOT_SORTED_ARRAY_VISITING_COUNT = 189; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 209; -const EQUAL_ARRAY_VISITING_COUNT = 20; -describe('BubbleSort', () => { - it('should sort array', () => { - SortTester.testSort(BubbleSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(BubbleSort); - }); - it('should do stable sorting', () => { - SortTester.testSortStability(BubbleSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(BubbleSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(BubbleSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(BubbleSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(BubbleSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(BubbleSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/CountingSort.js b/docs/content/DS_ALGO/algorithms/sorting/counting-sort/CountingSort.js deleted file mode 100644 index ab8e6971d5..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/CountingSort.js +++ /dev/null @@ -1,63 +0,0 @@ -import Sort from '../Sort'; -export default class CountingSort extends Sort { - /** - * @param {number[]} originalArray - * @param {number} [smallestElement] - * @param {number} [biggestElement] - */ - sort(originalArray, smallestElement = undefined, biggestElement = undefined) { - // Init biggest and smallest elements in array in order to build number bucket array later. - let detectedSmallestElement = smallestElement || 0; - let detectedBiggestElement = biggestElement || 0; - if (smallestElement === undefined || biggestElement === undefined) { - originalArray.forEach((element) => { - // Visit element. - this.callbacks.visitingCallback(element); - // Detect biggest element. - if (this.comparator.greaterThan(element, detectedBiggestElement)) { - detectedBiggestElement = element; - } - // Detect smallest element. - if (this.comparator.lessThan(element, detectedSmallestElement)) { - detectedSmallestElement = element; - } - }); - } - // Init buckets array. - // This array will hold frequency of each number from originalArray. - const buckets = Array(detectedBiggestElement - detectedSmallestElement + 1).fill(0); - originalArray.forEach((element) => { - // Visit element. - this.callbacks.visitingCallback(element); - buckets[element - detectedSmallestElement] += 1; - }); - // Add previous frequencies to the current one for each number in bucket - // to detect how many numbers less then current one should be standing to - // the left of current one. - for (let bucketIndex = 1; bucketIndex < buckets.length; bucketIndex += 1) { - buckets[bucketIndex] += buckets[bucketIndex - 1]; - } - // Now let's shift frequencies to the right so that they show correct numbers. - // I.e. if we won't shift right than the value of buckets[5] will display how many - // elements less than 5 should be placed to the left of 5 in sorted array - // INCLUDING 5th. After shifting though this number will not include 5th anymore. - buckets.pop(); - buckets.unshift(0); - // Now let's assemble sorted array. - const sortedArray = Array(originalArray.length).fill(null); - for (let elementIndex = 0; elementIndex < originalArray.length; elementIndex += 1) { - // Get the element that we want to put into correct sorted position. - const element = originalArray[elementIndex]; - // Visit element. - this.callbacks.visitingCallback(element); - // Get correct position of this element in sorted array. - const elementSortedPosition = buckets[element - detectedSmallestElement]; - // Put element into correct position in sorted array. - sortedArray[elementSortedPosition] = element; - // Increase position of current element in the bucket for future correct placements. - buckets[element - detectedSmallestElement] += 1; - } - // Return sorted array. - return sortedArray; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/counting-sort/README.md deleted file mode 100644 index dd6fd7f240..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Counting Sort - -In computer science, **counting sort** is an algorithm for sorting -a collection of objects according to keys that are small integers; -that is, it is an integer sorting algorithm. It operates by -counting the number of objects that have each distinct key value, -and using arithmetic on those counts to determine the positions -of each key value in the output sequence. Its running time is -linear in the number of items and the difference between the -maximum and minimum key values, so it is only suitable for direct -use in situations where the variation in keys is not significantly -greater than the number of items. However, it is often used as a -subroutine in another sorting algorithm, radix sort, that can -handle larger keys more efficiently. - -Because counting sort uses key values as indexes into an array, -it is not a comparison sort, and the `Ω(n log n)` lower bound for -comparison sorting does not apply to it. Bucket sort may be used -for many of the same tasks as counting sort, with a similar time -analysis; however, compared to counting sort, bucket sort requires -linked lists, dynamic arrays or a large amount of preallocated -memory to hold the sets of items within each bucket, whereas -counting sort instead stores a single number (the count of items) -per bucket. - -Counting sorting works best when the range of numbers for each array -element is very small. - -## Algorithm - -**Step I** - -In first step we calculate the count of all the elements of the -input array `A`. Then Store the result in the count array `C`. -The way we count is depicted below. - -![Counting Sort](https://3.bp.blogspot.com/-jJchly1BkTc/WLGqCFDdvCI/AAAAAAAAAHA/luljAlz2ptMndIZNH0KLTTuQMNsfzDeFQCLcB/s1600/CSortUpdatedStepI.gif) - -**Step II** - -In second step we calculate how many elements exist in the input -array `A` which are less than or equals for the given index. -`Ci` = numbers of elements less than or equals to `i` in input array. - -![Counting Sort](https://1.bp.blogspot.com/-1vFu-VIRa9Y/WLHGuZkdF3I/AAAAAAAAAHs/8jKu2dbQee4ap9xlVcNsILrclqw0UxAVACLcB/s1600/Step-II.png) - -**Step III** - -In this step we place the input array `A` element at sorted -position by taking help of constructed count array `C` ,i.e what -we constructed in step two. We used the result array `B` to store -the sorted elements. Here we handled the index of `B` start from -zero. - -![Counting Sort](https://1.bp.blogspot.com/-xPqylngqASY/WLGq3p9n9vI/AAAAAAAAAHM/JHdtXAkJY8wYzDMBXxqarjmhpPhM0u8MACLcB/s1600/ResultArrayCS.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| ----------------- | :---: | :-----: | :---: | :----: | :----: | :-------------------------- | -| **Counting sort** | n + r | n + r | n + r | n + r | Yes | r - biggest number in array | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Counting_sort) -- [YouTube](https://www.youtube.com/watch?v=OKd534EWcdk&index=61&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [EfficientAlgorithms](https://efficientalgorithms.blogspot.com/2016/09/lenear-sorting-counting-sort.html) diff --git a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/test/CountingSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/counting-sort/test/CountingSort.test.js deleted file mode 100644 index d9fd37ffd9..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/counting-sort/test/CountingSort.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import CountingSort from '../CountingSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 60; -const NOT_SORTED_ARRAY_VISITING_COUNT = 60; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 60; -const EQUAL_ARRAY_VISITING_COUNT = 60; -describe('CountingSort', () => { - it('should sort array', () => { - SortTester.testSort(CountingSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(CountingSort); - }); - it('should allow to use specify max/min integer value in array to make sorting faster', () => { - const visitingCallback = jest.fn(); - const sorter = new CountingSort({ visitingCallback }); - // Detect biggest number in array in prior. - const biggestElement = Math.max(...notSortedArr); - // Detect smallest number in array in prior. - const smallestElement = Math.min(...notSortedArr); - const sortedArray = sorter.sort(notSortedArr, smallestElement, biggestElement); - expect(sortedArray).toEqual(sortedArr); - // Normally visitingCallback is being called 60 times but in this case - // it should be called only 40 times. - expect(visitingCallback).toHaveBeenCalledTimes(40); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(CountingSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(CountingSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(CountingSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(CountingSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/HeapSort.js b/docs/content/DS_ALGO/algorithms/sorting/heap-sort/HeapSort.js deleted file mode 100644 index 5dab9ef456..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/HeapSort.js +++ /dev/null @@ -1,23 +0,0 @@ -import Sort from '../Sort'; -import MinHeap from '../../../data-structures/heap/MinHeap'; -export default class HeapSort extends Sort { - sort(originalArray) { - const sortedArray = []; - const minHeap = new MinHeap(this.callbacks.compareCallback); - // Insert all array elements to the heap. - originalArray.forEach((element) => { - // Call visiting callback. - this.callbacks.visitingCallback(element); - minHeap.add(element); - }); - // Now we have min heap with minimal element always on top. - // Let's poll that minimal element one by one and thus form the sorted array. - while (!minHeap.isEmpty()) { - const nextMinElement = minHeap.poll(); - // Call visiting callback. - this.callbacks.visitingCallback(nextMinElement); - sortedArray.push(nextMinElement); - } - return sortedArray; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/heap-sort/README.md deleted file mode 100644 index 616b80a76d..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Heap Sort - -Heapsort is a comparison-based sorting algorithm. -Heapsort can be thought of as an improved selection -sort: like that algorithm, it divides its input into -a sorted and an unsorted region, and it iteratively -shrinks the unsorted region by extracting the largest -element and moving that to the sorted region. The -improvement consists of the use of a heap data structure -rather than a linear-time search to find the maximum. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/1/1b/Sorting_heapsort_anim.gif) - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/4/4d/Heapsort-example.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| ------------- | :-----------: | :-----------: | :-----------: | :----: | :----: | :------- | -| **Heap sort** | n log(n) | n log(n) | n log(n) | 1 | No | | - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Heapsort) diff --git a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/test/HeapSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/heap-sort/test/HeapSort.test.js deleted file mode 100644 index 785472ea7a..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/heap-sort/test/HeapSort.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import HeapSort from '../HeapSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -// These numbers don't take into account up/dow heapifying of the heap. -// Thus these numbers are higher in reality. -const SORTED_ARRAY_VISITING_COUNT = 40; -const NOT_SORTED_ARRAY_VISITING_COUNT = 40; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 40; -const EQUAL_ARRAY_VISITING_COUNT = 40; -describe('HeapSort', () => { - it('should sort array', () => { - SortTester.testSort(HeapSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(HeapSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(HeapSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(HeapSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(HeapSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(HeapSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(HeapSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/InsertionSort.js b/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/InsertionSort.js deleted file mode 100644 index 14de891147..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/InsertionSort.js +++ /dev/null @@ -1,23 +0,0 @@ -import Sort from '../Sort'; -export default class InsertionSort extends Sort { - sort(originalArray) { - const array = [...originalArray]; - // Go through all array elements... - for (let i = 1; i < array.length; i += 1) { - let currentIndex = i; - // Call visiting callback. - this.callbacks.visitingCallback(array[i]); - // Check if previous element is greater than current element. - // If so, swap the two elements. - while (array[currentIndex - 1] !== undefined && this.comparator.lessThan(array[currentIndex], array[currentIndex - 1])) { - // Call visiting callback. - this.callbacks.visitingCallback(array[currentIndex - 1]); - // Swap the elements. - [array[currentIndex - 1], array[currentIndex]] = [array[currentIndex], array[currentIndex - 1]]; - // Shift current index left. - currentIndex -= 1; - } - } - return array; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/README.md deleted file mode 100644 index 3b7bac2bbb..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Insertion Sort - -Insertion sort is a simple sorting algorithm that builds -the final sorted array (or list) one item at a time. -It is much less efficient on large lists than more -advanced algorithms such as quicksort, heapsort, or merge -sort. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/4/42/Insertion_sort.gif) - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/0/0f/Insertion-sort-example-300px.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| ------------------ | :--: | :-----------: | :-----------: | :----: | :----: | :------- | -| **Insertion sort** | n | n2 | n2 | 1 | Yes | | - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Insertion_sort) diff --git a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/test/InsertionSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/test/InsertionSort.test.js deleted file mode 100644 index 63a0090791..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/insertion-sort/test/InsertionSort.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import InsertionSort from '../InsertionSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 19; -const NOT_SORTED_ARRAY_VISITING_COUNT = 100; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 209; -const EQUAL_ARRAY_VISITING_COUNT = 19; -describe('InsertionSort', () => { - it('should sort array', () => { - SortTester.testSort(InsertionSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(InsertionSort); - }); - it('should do stable sorting', () => { - SortTester.testSortStability(InsertionSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(InsertionSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(InsertionSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(InsertionSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(InsertionSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(InsertionSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/MergeSort.js b/docs/content/DS_ALGO/algorithms/sorting/merge-sort/MergeSort.js deleted file mode 100644 index 339d32b0cf..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/MergeSort.js +++ /dev/null @@ -1,46 +0,0 @@ -import Sort from '../Sort'; -export default class MergeSort extends Sort { - sort(originalArray) { - // Call visiting callback. - this.callbacks.visitingCallback(null); - // If array is empty or consists of one element then return this array since it is sorted. - if (originalArray.length <= 1) { - return originalArray; - } - // Split array on two halves. - const middleIndex = Math.floor(originalArray.length / 2); - const leftArray = originalArray.slice(0, middleIndex); - const rightArray = originalArray.slice(middleIndex, originalArray.length); - // Sort two halves of split array - const leftSortedArray = this.sort(leftArray); - const rightSortedArray = this.sort(rightArray); - // Merge two sorted arrays into one. - return this.mergeSortedArrays(leftSortedArray, rightSortedArray); - } - mergeSortedArrays(leftArray, rightArray) { - const sortedArray = []; - // Use array pointers to exclude old elements after they have been added to the sorted array. - let leftIndex = 0; - let rightIndex = 0; - while (leftIndex < leftArray.length && rightIndex < rightArray.length) { - let minElement = null; - // Find the minimum element between the left and right array. - if (this.comparator.lessThanOrEqual(leftArray[leftIndex], rightArray[rightIndex])) { - minElement = leftArray[leftIndex]; - // Increment index pointer to the right - leftIndex += 1; - } else { - minElement = rightArray[rightIndex]; - // Increment index pointer to the right - rightIndex += 1; - } - // Add the minimum element to the sorted array. - sortedArray.push(minElement); - // Call visiting callback. - this.callbacks.visitingCallback(minElement); - } - // There will be elements remaining from either the left OR the right - // Concatenate the remaining elements into the sorted array - return sortedArray.concat(leftArray.slice(leftIndex)).concat(rightArray.slice(rightIndex)); - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/merge-sort/README.md deleted file mode 100644 index 72421c033f..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Merge Sort - -In computer science, merge sort (also commonly spelled -mergesort) is an efficient, general-purpose, -comparison-based sorting algorithm. Most implementations -produce a stable sort, which means that the implementation -preserves the input order of equal elements in the sorted -output. Mergesort is a divide and conquer algorithm that -was invented by John von Neumann in 1945. - -An example of merge sort. First divide the list into -the smallest unit (1 element), then compare each -element with the adjacent list to sort and merge the -two adjacent lists. Finally all the elements are sorted -and merged. - -![Merge Sort](https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif) - -A recursive merge sort algorithm used to sort an array of 7 -integer values. These are the steps a human would take to -emulate merge sort (top-down). - -![Merge Sort](https://upload.wikimedia.org/wikipedia/commons/e/e6/Merge_sort_algorithm_diagram.svg) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| -------------- | :-----------: | :-----------: | :-----------: | :----: | :----: | :------- | -| **Merge sort** | n log(n) | n log(n) | n log(n) | n | Yes | | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Merge_sort) -- [YouTube](https://www.youtube.com/watch?v=KF2j-9iSf4Q&index=27&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/test/MergeSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/merge-sort/test/MergeSort.test.js deleted file mode 100644 index 1634f3573d..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/merge-sort/test/MergeSort.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import MergeSort from '../MergeSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 79; -const NOT_SORTED_ARRAY_VISITING_COUNT = 102; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 87; -const EQUAL_ARRAY_VISITING_COUNT = 79; -describe('MergeSort', () => { - it('should sort array', () => { - SortTester.testSort(MergeSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(MergeSort); - }); - it('should do stable sorting', () => { - SortTester.testSortStability(MergeSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(MergeSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(MergeSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(MergeSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(MergeSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(MergeSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSort.js b/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSort.js deleted file mode 100644 index 9f9351f5cf..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSort.js +++ /dev/null @@ -1,40 +0,0 @@ -import Sort from '../Sort'; -export default class QuickSort extends Sort { - /** - * @param {*[]} originalArray - * @return {*[]} - */ - sort(originalArray) { - // Clone original array to prevent it from modification. - const array = [...originalArray]; - // If array has less than or equal to one elements then it is already sorted. - if (array.length <= 1) { - return array; - } - // Init left and right arrays. - const leftArray = []; - const rightArray = []; - // Take the first element of array as a pivot. - const pivotElement = array.shift(); - const centerArray = [pivotElement]; - // Split all array elements between left, center and right arrays. - while (array.length) { - const currentElement = array.shift(); - // Call visiting callback. - this.callbacks.visitingCallback(currentElement); - if (this.comparator.equal(currentElement, pivotElement)) { - centerArray.push(currentElement); - } else if (this.comparator.lessThan(currentElement, pivotElement)) {} - leftArray.push(currentElement); - } else { - rightArray.push(currentElement); - } - } - // Sort left and right arrays. - const leftArraySorted = this.sort(leftArray); - const rightArraySorted = this.sort(rightArray); - // Let's now join sorted left array with center array and with sorted right array. - return leftArraySorted.concat(centerArray, rightArraySorted); -} -} -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSortInPlace.js b/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSortInPlace.js deleted file mode 100644 index b7f79ace7e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/QuickSortInPlace.js +++ /dev/null @@ -1,65 +0,0 @@ -import Sort from '../Sort'; -export default class QuickSortInPlace extends Sort { - /** Sorting in place avoids unnecessary use of additional memory, but modifies input array. - * - * This process is difficult to describe, but much clearer with a visualization: - * @see: http://www.algomation.com/algorithm/quick-sort-visualization - * - * @param {*[]} originalArray - Not sorted array. - * @param {number} inputLowIndex - * @param {number} inputHighIndex - * @param {boolean} recursiveCall - * @return {*[]} - Sorted array. - */ - sort(originalArray, inputLowIndex = 0, inputHighIndex = originalArray.length - 1, recursiveCall = false) { - // Copies array on initial call, and then sorts in place. - const array = recursiveCall ? originalArray : [...originalArray]; - /** - * The partitionArray() operates on the subarray between lowIndex and highIndex, inclusive. - * It arbitrarily chooses the last element in the subarray as the pivot. - * Then, it partially sorts the subarray into elements than are less than the pivot, - * and elements that are greater than or equal to the pivot. - * Each time partitionArray() is executed, the pivot element is in its final sorted position. - * - * @param {number} lowIndex - * @param {number} highIndex - * @return {number} - */ - const partitionArray = (lowIndex, highIndex) => { - /** - * Swaps two elements in array. - * @param {number} leftIndex - * @param {number} rightIndex - */ - const swap = (leftIndex, rightIndex) => { - const temp = array[leftIndex]; - array[leftIndex] = array[rightIndex]; - array[rightIndex] = temp; - }; - const pivot = array[highIndex]; - // visitingCallback is used for time-complexity analysis. - this.callbacks.visitingCallback(pivot); - let partitionIndex = lowIndex; - for (let currentIndex = lowIndex; currentIndex < highIndex; currentIndex += 1) { - if (this.comparator.lessThan(array[currentIndex], pivot)) { - swap(partitionIndex, currentIndex); - partitionIndex += 1; - } - } - // The element at the partitionIndex is guaranteed to be greater than or equal to pivot. - // All elements to the left of partitionIndex are guaranteed to be less than pivot. - // Swapping the pivot with the partitionIndex therefore places the pivot in its - // final sorted position. - swap(partitionIndex, highIndex); - return partitionIndex; - }; - // Base case is when low and high converge. - if (inputLowIndex < inputHighIndex) { - const partitionIndex = partitionArray(inputLowIndex, inputHighIndex); - const RECURSIVE_CALL = true; - this.sort(array, inputLowIndex, partitionIndex - 1, RECURSIVE_CALL); - this.sort(array, partitionIndex + 1, inputHighIndex, RECURSIVE_CALL); - } - return array; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/quick-sort/README.md deleted file mode 100644 index 3009f64e61..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Quicksort - -Quicksort is a divide and conquer algorithm. -Quicksort first divides a large array into two smaller -sub-arrays: the low elements and the high elements. -Quicksort can then recursively sort the sub-arrays - -The steps are: - -1. Pick an element, called a pivot, from the array. -2. Partitioning: reorder the array so that all elements with - values less than the pivot come before the pivot, while all - elements with values greater than the pivot come after it - (equal values can go either way). After this partitioning, - the pivot is in its final position. This is called the - partition operation. -3. Recursively apply the above steps to the sub-array of - elements with smaller values and separately to the - sub-array of elements with greater values. - -Animated visualization of the quicksort algorithm. -The horizontal lines are pivot values. - -![Quicksort](https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| -------------- | :-----------: | :-----------: | :-----------: | :----: | :----: | :------------------------------------------------------------ | -| **Quick sort** | n log(n) | n log(n) | n2 | log(n) | No | Quicksort is usually done in-place with O(log(n)) stack space | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Quicksort) -- [YouTube](https://www.youtube.com/watch?v=SLauY6PpjW4&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSort.test.js deleted file mode 100644 index 11a5f95f3b..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSort.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import QuickSort from '../QuickSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 190; -const NOT_SORTED_ARRAY_VISITING_COUNT = 62; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 190; -const EQUAL_ARRAY_VISITING_COUNT = 19; -describe('QuickSort', () => { - it('should sort array', () => { - SortTester.testSort(QuickSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(QuickSort); - }); - it('should do stable sorting', () => { - SortTester.testSortStability(QuickSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(QuickSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSortInPlace.test.js b/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSortInPlace.test.js deleted file mode 100644 index b20387d397..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/quick-sort/test/QuickSortInPlace.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import QuickSortInPlace from '../QuickSortInPlace'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 19; -const NOT_SORTED_ARRAY_VISITING_COUNT = 12; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 19; -const EQUAL_ARRAY_VISITING_COUNT = 19; -describe('QuickSortInPlace', () => { - it('should sort array', () => { - SortTester.testSort(QuickSortInPlace); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(QuickSortInPlace); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(QuickSortInPlace); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSortInPlace, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSortInPlace, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSortInPlace, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(QuickSortInPlace, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/radix-sort/README.md deleted file mode 100644 index 457f9e9482..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Radix Sort - -In computer science, **radix sort** is a non-comparative integer sorting -algorithm that sorts data with integer keys by grouping keys by the individual -digits which share the same significant position and value. A positional notation -is required, but because integers can represent strings of characters -(e.g., names or dates) and specially formatted floating point numbers, radix -sort is not limited to integers. - -_Where does the name come from?_ - -In mathematical numeral systems, the _radix_ or base is the number of unique digits, -including the digit zero, used to represent numbers in a positional numeral system. -For example, a binary system (using numbers 0 and 1) has a radix of 2 and a decimal -system (using numbers 0 to 9) has a radix of 10. - -## Efficiency - -The topic of the efficiency of radix sort compared to other sorting algorithms is -somewhat tricky and subject to quite a lot of misunderstandings. Whether radix -sort is equally efficient, less efficient or more efficient than the best -comparison-based algorithms depends on the details of the assumptions made. -Radix sort complexity is `O(wn)` for `n` keys which are integers of word size `w`. -Sometimes `w` is presented as a constant, which would make radix sort better -(for sufficiently large `n`) than the best comparison-based sorting algorithms, -which all perform `O(n log n)` comparisons to sort `n` keys. However, in -general `w` cannot be considered a constant: if all `n` keys are distinct, -then `w` has to be at least `log n` for a random-access machine to be able to -store them in memory, which gives at best a time complexity `O(n log n)`. That -would seem to make radix sort at most equally efficient as the best -comparison-based sorts (and worse if keys are much longer than `log n`). - -![Radix Sort](https://www.researchgate.net/publication/291086231/figure/fig1/AS:614214452404240@1523451545568/Simplistic-illustration-of-the-steps-performed-in-a-radix-sort-In-this-example-the.png) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| -------------- | :----: | :-----: | :----: | :----: | :----: | :------------------------ | -| **Radix sort** | n \* k | n \* k | n \* k | n + k | Yes | k - length of longest key | - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Radix_sort) -- [YouTube](https://www.youtube.com/watch?v=XiuSW_mEn7g&index=62&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [ResearchGate](https://www.researchgate.net/figure/Simplistic-illustration-of-the-steps-performed-in-a-radix-sort-In-this-example-the_fig1_291086231) diff --git a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/RadixSort.js b/docs/content/DS_ALGO/algorithms/sorting/radix-sort/RadixSort.js deleted file mode 100644 index a7ec4c6b10..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/RadixSort.js +++ /dev/null @@ -1,132 +0,0 @@ -import Sort from '../Sort'; -// Using charCode (a = 97, b = 98, etc), we can map characters to buckets from 0 - 25 -const BASE_CHAR_CODE = 97; -const NUMBER_OF_POSSIBLE_DIGITS = 10; -const ENGLISH_ALPHABET_LENGTH = 26; -export default class RadixSort extends Sort { - /** - * @param {*[]} originalArray - * @return {*[]} - */ - sort(originalArray) { - // Assumes all elements of array are of the same type - const isArrayOfNumbers = this.isArrayOfNumbers(originalArray); - let sortedArray = [...originalArray]; - const numPasses = this.determineNumPasses(sortedArray); - for (let currentIndex = 0; currentIndex < numPasses; currentIndex += 1) { - const buckets = isArrayOfNumbers ? - this.placeElementsInNumberBuckets(sortedArray, currentIndex) : - this.placeElementsInCharacterBuckets(sortedArray, currentIndex, numPasses); - - // Flatten buckets into sortedArray, and repeat at next index - sortedArray = buckets.reduce((acc, val) => { - return [...acc, ...val]; - }, []); - } - return sortedArray; - } - /** - * @param {*[]} array - * @param {number} index - * @return {*[]} - */ - placeElementsInNumberBuckets(array, index) { - // See below. These are used to determine which digit to use for bucket allocation - const modded = 10 ** (index + 1); - const divided = 10 ** index; - const buckets = this.createBuckets(NUMBER_OF_POSSIBLE_DIGITS); - array.forEach((element) => { - this.callbacks.visitingCallback(element); - if (element < divided) { - buckets[0].push(element); - } else { - /** - * Say we have element of 1,052 and are currently on index 1 (starting from 0). This means - * we want to use '5' as the bucket. `modded` would be 10 ** (1 + 1), which - * is 100. So we take 1,052 % 100 (52) and divide it by 10 (5.2) and floor it (5). - */ - const currentDigit = Math.floor((element % modded) / divided); - buckets[currentDigit].push(element); - } - }); - return buckets; - } - /** - * @param {*[]} array - * @param {number} index - * @param {number} numPasses - * @return {*[]} - */ - placeElementsInCharacterBuckets(array, index, numPasses) { - const buckets = this.createBuckets(ENGLISH_ALPHABET_LENGTH); - array.forEach((element) => { - this.callbacks.visitingCallback(element); - const currentBucket = this.getCharCodeOfElementAtIndex(element, index, numPasses); - buckets[currentBucket].push(element); - }); - return buckets; - } - /** - * @param {string} element - * @param {number} index - * @param {number} numPasses - * @return {number} - */ - getCharCodeOfElementAtIndex(element, index, numPasses) { - // Place element in last bucket if not ready to organize - if (numPasses - index > element.length) { - return ENGLISH_ALPHABET_LENGTH - 1; - } - /** - * If each character has been organized, use first character to determine bucket, - * otherwise iterate backwards through element - */ - const charPos = index > element.length - 1 ? 0 : element.length - index - 1; - return element.toLowerCase().charCodeAt(charPos) - BASE_CHAR_CODE; - } - /** - * Number of passes is determined by the length of the longest element in the array. - * For integers, this log10(num), and for strings, this would be the length of the string. - */ - determineNumPasses(array) { - return this.getLengthOfLongestElement(array); - } - /** - * @param {*[]} array - * @return {number} - */ - getLengthOfLongestElement(array) { - if (this.isArrayOfNumbers(array)) { - return Math.floor(Math.log10(Math.max(...array))) + 1; - } - return array.reduce((acc, val) => { - return val.length > acc ? val.length : acc; - }, -Infinity); - } - /** - * @param {*[]} array - * @return {boolean} - */ - isArrayOfNumbers(array) { - // Assumes all elements of array are of the same type - return this.isNumber(array[0]); - } - /** - * @param {number} numBuckets - * @return {*[]} - */ - createBuckets(numBuckets) { - /** - * Mapping buckets to an array instead of filling them with - * an array prevents each bucket from containing a reference to the same array - */ - return new Array(numBuckets).fill(null).map(() => []); - } - /** - * @param {*} element - * @return {boolean} - */ - isNumber(element) { - return Number.isInteger(element); - } -} \ No newline at end of file diff --git a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/test/RadixSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/radix-sort/test/RadixSort.test.js deleted file mode 100644 index 8e60f479ee..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/radix-sort/test/RadixSort.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import RadixSort from '../RadixSort'; -import { SortTester } from '../../SortTester'; -// Complexity constants. -const ARRAY_OF_STRINGS_VISIT_COUNT = 24; -const ARRAY_OF_INTEGERS_VISIT_COUNT = 77; -describe('RadixSort', () => { - it('should sort array', () => { - SortTester.testSort(RadixSort); - }); - it('should visit array of strings n (number of strings) x m (length of longest element) times', () => { - SortTester.testAlgorithmTimeComplexity(RadixSort, ['zzz', 'bb', 'a', 'rr', 'rrb', 'rrba'], ARRAY_OF_STRINGS_VISIT_COUNT); - }); - it('should visit array of integers n (number of elements) x m (length of longest integer) times', () => { - SortTester.testAlgorithmTimeComplexity(RadixSort, [3, 1, 75, 32, 884, 523, 4343456, 232, 123, 656, 343], ARRAY_OF_INTEGERS_VISIT_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/selection-sort/README.md deleted file mode 100644 index 3553642d94..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Selection Sort - -Selection sort is a sorting algorithm, specifically an -in-place comparison sort. It has O(n2) time complexity, -making it inefficient on large lists, and generally -performs worse than the similar insertion sort. -Selection sort is noted for its simplicity, and it has -performance advantages over more complicated algorithms -in certain situations, particularly where auxiliary -memory is limited. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/b/b0/Selection_sort_animation.gif) - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/9/94/Selection-Sort-Animation.gif) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| ------------------ | :-----------: | :-----------: | :-----------: | :----: | :----: | :------- | -| **Selection sort** | n2 | n2 | n2 | 1 | No | | - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Selection_sort) diff --git a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/SelectionSort.js b/docs/content/DS_ALGO/algorithms/sorting/selection-sort/SelectionSort.js deleted file mode 100644 index ca1c3c636d..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/SelectionSort.js +++ /dev/null @@ -1,25 +0,0 @@ -import Sort from '../Sort'; -export default class SelectionSort extends Sort { - sort(originalArray) { - // Clone original array to prevent its modification. - const array = [...originalArray]; - for (let i = 0; i < array.length - 1; i += 1) { - let minIndex = i; - // Call visiting callback. - this.callbacks.visitingCallback(array[i]); - // Find minimum element in the rest of array. - for (let j = i + 1; j < array.length; j += 1) { - // Call visiting callback. - this.callbacks.visitingCallback(array[j]); - if (this.comparator.lessThan(array[j], array[minIndex])) { - minIndex = j; - } - } - // If new minimum element has been found then swap it with current i-th element. - if (minIndex !== i) { - [array[i], array[minIndex]] = [array[minIndex], array[i]]; - } - } - return array; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/test/SelectionSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/selection-sort/test/SelectionSort.test.js deleted file mode 100644 index 8c7ee0edec..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/selection-sort/test/SelectionSort.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import SelectionSort from '../SelectionSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 209; -const NOT_SORTED_ARRAY_VISITING_COUNT = 209; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 209; -const EQUAL_ARRAY_VISITING_COUNT = 209; -describe('SelectionSort', () => { - it('should sort array', () => { - SortTester.testSort(SelectionSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(SelectionSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(SelectionSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(SelectionSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(SelectionSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(SelectionSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(SelectionSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/README.md b/docs/content/DS_ALGO/algorithms/sorting/shell-sort/README.md deleted file mode 100644 index 3e32fb9cb0..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Shellsort - -Shellsort, also known as Shell sort or Shell's method, -is an in-place comparison sort. It can be seen as either a -generalization of sorting by exchange (bubble sort) or sorting -by insertion (insertion sort). The method starts by sorting -pairs of elements far apart from each other, then progressively -reducing the gap between elements to be compared. Starting -with far apart elements, it can move some out-of-place -elements into position faster than a simple nearest neighbor -exchange - -![Shellsort](https://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif) - -## How Shell Sort Works - -For our example and ease of understanding, we take the interval -of `4`. Make a virtual sub-list of all values located at the -interval of 4 positions. Here these values are -`{35, 14}`, `{33, 19}`, `{42, 27}` and `{10, 44}` - -![Shellsort](https://www.tutorialspoint.com/data_structures_algorithms/images/shell_sort_gap_4.jpg) - -We compare values in each sub-list and swap them (if necessary) -in the original array. After this step, the new array should -look like this - -![Shellsort](https://www.tutorialspoint.com/data_structures_algorithms/images/shell_sort_step_1.jpg) - -Then, we take interval of 2 and this gap generates two sub-lists - -- `{14, 27, 35, 42}`, `{19, 10, 33, 44}` - -![Shellsort](https://www.tutorialspoint.com/data_structures_algorithms/images/shell_sort_gap_2.jpg) - -We compare and swap the values, if required, in the original array. -After this step, the array should look like this - -![Shellsort](https://www.tutorialspoint.com/data_structures_algorithms/images/shell_sort_step_2.jpg) - -> UPD: On the picture below there is a typo and result array is supposed to be `[14, 10, 27, 19, 35, 33, 42, 44]`. - -Finally, we sort the rest of the array using interval of value 1. -Shell sort uses insertion sort to sort the array. - -![Shellsort](https://www.tutorialspoint.com/data_structures_algorithms/images/shell_sort.jpg) - -## Complexity - -| Name | Best | Average | Worst | Memory | Stable | Comments | -| -------------- | :-----------: | :---------------------: | :-------------------------: | :----: | :----: | :------- | -| **Shell sort** | n log(n) | depends on gap sequence | n (log(n))2 | 1 | No | | - -## References - -- [Tutorials Point](https://www.tutorialspoint.com/data_structures_algorithms/shell_sort_algorithm.htm) -- [Wikipedia](https://en.wikipedia.org/wiki/Shellsort) -- [YouTube by Rob Edwards](https://www.youtube.com/watch?v=ddeLSDsYVp8&index=79&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/ShellSort.js b/docs/content/DS_ALGO/algorithms/sorting/shell-sort/ShellSort.js deleted file mode 100644 index 8a81ed2b4b..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/ShellSort.js +++ /dev/null @@ -1,33 +0,0 @@ -import Sort from '../Sort'; -export default class ShellSort extends Sort { - sort(originalArray) { - // Prevent original array from mutations. - const array = [...originalArray]; - // Define a gap distance. - let gap = Math.floor(array.length / 2); - // Until gap is bigger then zero do elements comparisons and swaps. - while (gap > 0) { - // Go and compare all distant element pairs. - for (let i = 0; i < array.length - gap; i += 1) { - let currentIndex = i; - let gapShiftedIndex = i + gap; - while (currentIndex >= 0) { - // Call visiting callback. - this.callbacks.visitingCallback(array[currentIndex]); - // Compare and swap array elements if needed. - if (this.comparator.lessThan(array[gapShiftedIndex], array[currentIndex])) { - const tmp = array[currentIndex]; - array[currentIndex] = array[gapShiftedIndex]; - array[gapShiftedIndex] = tmp; - } - gapShiftedIndex = currentIndex; - currentIndex -= gap; - } - } - // Shrink the gap. - gap = Math.floor(gap / 2); - } - // Return sorted copy of an original array. - return array; - } -} diff --git a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/test/ShellSort.test.js b/docs/content/DS_ALGO/algorithms/sorting/shell-sort/test/ShellSort.test.js deleted file mode 100644 index 190fca2022..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/shell-sort/test/ShellSort.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import ShellSort from '../ShellSort'; -import { equalArr, notSortedArr, reverseArr, sortedArr, SortTester } from '../../SortTester'; -// Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 320; -const NOT_SORTED_ARRAY_VISITING_COUNT = 320; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 320; -const EQUAL_ARRAY_VISITING_COUNT = 320; -describe('ShellSort', () => { - it('should sort array', () => { - SortTester.testSort(ShellSort); - }); - it('should sort array with custom comparator', () => { - SortTester.testSortWithCustomComparator(ShellSort); - }); - it('should sort negative numbers', () => { - SortTester.testNegativeNumbersSort(ShellSort); - }); - it('should visit EQUAL array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(ShellSort, equalArr, EQUAL_ARRAY_VISITING_COUNT); - }); - it('should visit SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(ShellSort, sortedArr, SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit NOT SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(ShellSort, notSortedArr, NOT_SORTED_ARRAY_VISITING_COUNT); - }); - it('should visit REVERSE SORTED array element specified number of times', () => { - SortTester.testAlgorithmTimeComplexity(ShellSort, reverseArr, REVERSE_SORTED_ARRAY_VISITING_COUNT); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/sorting/test/Sort.test.js b/docs/content/DS_ALGO/algorithms/sorting/test/Sort.test.js deleted file mode 100644 index 3e2b317f1e..0000000000 --- a/docs/content/DS_ALGO/algorithms/sorting/test/Sort.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import Sort from '../Sort'; -describe('Sort', () => { - it('should throw an error when trying to call Sort.sort() method directly', () => { - function doForbiddenSort() { - const sorter = new Sort(); - sorter.sort(); - } - expect(doForbiddenSort).toThrow(); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/README.md b/docs/content/DS_ALGO/algorithms/statistics/weighted-random/README.md deleted file mode 100644 index 169b521189..0000000000 --- a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# Weighted Random - -![Weighted Random](images/cover.png) - -## What is "Weighted Random" - -Let's say you have a list of **items**. Item could be anything. For example, we may have a list of fruits and vegetables that you like to eat: `[ '🍌', '🍎', '🥕' ]`. - -The list of **weights** represent the weight (or probability, or importance) of each item. Weights are numbers. For example, the weights like `[3, 7, 1]` would say that: - -- you would like to eat `🍎 apples` more often (`7` out of `3 + 7 + 1 = 11` times), -- then you would like to eat `bananas 🍌` less often (only `3` out of `11` times), -- and the `carrots 🥕` you really don't like (want to eat it only `1` out of `11` times). - -> If we speak in terms of probabilities than the weights list might be an array of floats that sum up to `1` (i.e. `[0.1, 0.5, 0.2, 0.2]`). - -The **Weighted Random** in this case will be the function that will randomly return you the item from the list, and it will take each item's weight into account, so that items with the higher weight will be picked more often. - -Example of the function interface: - -```javascript -const items = ['🍌', '🍎', '🥕']; -const weights = [3, 7, 1]; - -function weightedRandom(items, weights) { - // implementation goes here ... -} - -const nextSnackToEat = weightedRandom(items, weights); // Could be '🍎' -``` - -## Applications of Weighted Random - -- In [Genetic Algorithm](https://en.wikipedia.org/wiki/Genetic_algorithm) the weighted random is used during the "Selection" phase, when we need to select the fittest/strongest individuums based on their fitness score for mating and for producing the next stronger generation. You may find an **example** in the [Self-Parking Car in 500 Lines of Code](https://trekhleb.dev/blog/2021/self-parking-car-evolution/) article. -- In [Recurrent Neural Networks (RNN)](https://en.wikipedia.org/wiki/Recurrent_neural_network) when trying to decide what letter to choose next (to form the sentence) based on the next letter probability. You may find an **example** in the [Recipe Generation using Recurrent Neural Network (RNN)](https://nbviewer.org/github/trekhleb/machine-learning-experiments/blob/master/experiments/recipe_generation_rnn/recipe_generation_rnn.ipynb) Jupyter notebook. -- In [Nginx Load Balancing](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/) to send HTTP requests more often to the servers with the higher weights. -- And more... - -## The Algorithm - -The **straightforward approach** would be to: - -1. Repeat each item in the list according to its weight. -2. Pick the random item from the list. - -For example in our case with fruits and vegetables we could generate the following list of size `3 + 7 + 1 = 11`: - -```javascript -const items = ['🍌', '🍎', '🥕']; -const weights = [3, 7, 1]; - -// Repeating the items based on weights. -const weightedItems = ['🍌', '🍌', '🍌', '🍎', '🍎', '🍎', '🍎', '🍎', '🍎', '🍎', '🥕']; - -// And now just pick the random item from weightedItems array. -``` - -However, as you may see, this approach may require a lot of memory, in case if we have a lot of items to repeat in `weightedItems` list. Think of it as if you would need to repeat a string like `"some-random-string"` (`18` bytes) a ten million times. You will need to allocate around `180Mb` of additional memory space just for this array. - -The **more efficient approach** would be to: - -1. Prepare the list of cumulative weights for each item (i.e. the `cumulativeWeights` list which will have the same number of elements as the original `weights` list). In our case it will look like this: `cumulativeWeights = [3, 3 + 7, 3 + 7 + 1] = [3, 10, 11]` -2. Generate the random number `randomNumber` from `0` to the highest cumulative weight value. In our case the random number will be in a range of `[0..11]`. Let's say that we have `randomNumber = 8`. -3. Go through the `cumulativeWeights` list from left to right and pick the first element which is higher or equal to the `randomNumber`. The index of such element we will use to pick the item from the `items` array. - -The idea behind this approach is that the higher weights will "occupy" more numeric space. Therefore, there is a higher chance that the random number will fall into the "higher weight numeric bucket". - -```javascript -const weights = [3, 7, 1]; -const cumulativeWeights = [3, 10, 11]; - -// In a pseudo-representation we may think about the cumulativeWeights array like this. -const pseudoCumulativeWeights = [ - 1, - 2, - 3, // <-- [3] numbers - 4, - 5, - 6, - 7, - 8, - 9, - 10, // <-- [7] numbers - 11 // <-- [1] number -]; -``` - -Here is an example of how the `weightedRandom` function might be implemented: - -```javascript -/** - * Picks the random item based on its weight. - * The items with higher weight will be picked more often (with a higher probability). - * - * For example: - * - items = ['banana', 'orange', 'apple'] - * - weights = [0, 0.2, 0.8] - * - weightedRandom(items, weights) in 80% of cases will return 'apple', in 20% of cases will return - * 'orange' and it will never return 'banana' (because probability of picking the banana is 0%) - * - * @param {any[]} items - * @param {number[]} weights - * @returns {{item: any, index: number}} - */ -export default function weightedRandom(items, weights) { - if (items.length !== weights.length) { - throw new Error('Items and weights must be of the same size'); - } - - if (!items.length) { - throw new Error('Items must not be empty'); - } - - // Preparing the cumulative weights array. - // For example: - // - weights = [1, 4, 3] - // - cumulativeWeights = [1, 5, 8] - const cumulativeWeights = []; - for (let i = 0; i < weights.length; i += 1) { - cumulativeWeights[i] = weights[i] + (cumulativeWeights[i - 1] || 0); - } - - // Getting the random number in a range of [0...sum(weights)] - // For example: - // - weights = [1, 4, 3] - // - maxCumulativeWeight = 8 - // - range for the random number is [0...8] - const maxCumulativeWeight = cumulativeWeights[cumulativeWeights.length - 1]; - const randomNumber = maxCumulativeWeight * Math.random(); - - // Picking the random item based on its weight. - // The items with higher weight will be picked more often. - for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) { - if (cumulativeWeights[itemIndex] >= randomNumber) { - return { - item: items[itemIndex], - index: itemIndex - }; - } - } -} -``` - -## Implementation - -- Check the [weightedRandom.js](weightedRandom.js) file for the implementation of the `weightedRandom()` function. -- Check the [weightedRandom.test.js](__test__/weightedRandom.test.js) file for the tests-cases. diff --git a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/images/cover.png b/docs/content/DS_ALGO/algorithms/statistics/weighted-random/images/cover.png deleted file mode 100644 index a4bf41b65f..0000000000 Binary files a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/images/cover.png and /dev/null differ diff --git a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/test/weightedRandom.test.js b/docs/content/DS_ALGO/algorithms/statistics/weighted-random/test/weightedRandom.test.js deleted file mode 100644 index e1a65ea483..0000000000 --- a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/test/weightedRandom.test.js +++ /dev/null @@ -1,89 +0,0 @@ -import weightedRandom from '../weightedRandom'; -describe('weightedRandom', () => { - it('should throw an error when the number of weights does not match the number of items', () => { - const getWeightedRandomWithInvalidInputs = () => { - weightedRandom(['a', 'b', 'c'], [10, 0]); - }; - expect(getWeightedRandomWithInvalidInputs).toThrow('Items and weights must be of the same size'); - }); - it('should throw an error when the number of weights or items are empty', () => { - const getWeightedRandomWithInvalidInputs = () => { - weightedRandom([], []); - }; - expect(getWeightedRandomWithInvalidInputs).toThrow('Items must not be empty'); - }); - it('should correctly do random selection based on wights in straightforward cases', () => { - expect(weightedRandom(['a', 'b', 'c'], [1, 0, 0])).toEqual({ - index: 0, - item: 'a' - }); - expect(weightedRandom(['a', 'b', 'c'], [0, 1, 0])).toEqual({ - index: 1, - item: 'b' - }); - expect(weightedRandom(['a', 'b', 'c'], [0, 0, 1])).toEqual({ - index: 2, - item: 'c' - }); - expect(weightedRandom(['a', 'b', 'c'], [0, 1, 1])).not.toEqual({ - index: 0, - item: 'a' - }); - expect(weightedRandom(['a', 'b', 'c'], [1, 0, 1])).not.toEqual({ - index: 1, - item: 'b' - }); - expect(weightedRandom(['a', 'b', 'c'], [1, 1, 0])).not.toEqual({ - index: 2, - item: 'c' - }); - }); - it('should correctly do random selection based on wights', () => { - // Number of times we're going to select the random items based on their weights. - const ATTEMPTS_NUM = 1000; - // The +/- delta in the number of times each item has been actually selected. - // I.e. if we want the item 'a' to be selected 300 times out of 1000 cases (30%) - // then 267 times is acceptable since it is bigger that 250 (which is 300 - 50) - // ans smaller than 350 (which is 300 + 50) - const THRESHOLD = 50; - const items = ['a', 'b', 'c']; // The actual items values don't matter. - const weights = [0.1, 0.3, 0.6]; - const counter = []; - for (let i = 0; i < ATTEMPTS_NUM; i += 1) { - const randomItem = weightedRandom(items, weights); - if (!counter[randomItem.index]) { - counter[randomItem.index] = 1; - } else {} - counter[randomItem.index] += 1; - } - } - for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) { - /* - i.e. item with the index of 0 must be selected 100 times (ideally) - or with the threshold of [100 - 50, 100 + 50] times. - i.e. item with the index of 1 must be selected 300 times (ideally) - or with the threshold of [300 - 50, 300 + 50] times. - i.e. item with the index of 2 must be selected 600 times (ideally) - or with the threshold of [600 - 50, 600 + 50] times. - */ - expect(counter[itemIndex]).toBeGreaterThan(ATTEMPTS_NUM * weights[itemIndex] - THRESHOLD); - expect(counter[itemIndex]).toBeLessThan(ATTEMPTS_NUM * weights[itemIndex] + THRESHOLD); - } - }); -}); -} -} -for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) { - /* - i.e. item with the index of 0 must be selected 100 times (ideally) - or with the threshold of [100 - 50, 100 + 50] times. - i.e. item with the index of 1 must be selected 300 times (ideally) - or with the threshold of [300 - 50, 300 + 50] times. - i.e. item with the index of 2 must be selected 600 times (ideally) - or with the threshold of [600 - 50, 600 + 50] times. - */ - expect(counter[itemIndex]).toBeGreaterThan(ATTEMPTS_NUM * weights[itemIndex] - THRESHOLD); - expect(counter[itemIndex]).toBeLessThan(ATTEMPTS_NUM * weights[itemIndex] + THRESHOLD); -} -}); -}); diff --git a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/weightedRandom.js b/docs/content/DS_ALGO/algorithms/statistics/weighted-random/weightedRandom.js deleted file mode 100644 index e071324591..0000000000 --- a/docs/content/DS_ALGO/algorithms/statistics/weighted-random/weightedRandom.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Picks the random item based on its weight. - * The items with higher weight will be picked more often (with a higher probability). - * - * For example: - * - items = ['banana', 'orange', 'apple'] - * - weights = [0, 0.2, 0.8] - * - weightedRandom(items, weights) in 80% of cases will return 'apple', in 20% of cases will return - * 'orange' and it will never return 'banana' (because probability of picking the banana is 0%) - * - * @param {any[]} items - * @param {number[]} weights - * @returns {{item: any, index: number}} - */ -/* eslint-disable consistent-return */ -export default function weightedRandom(items, weights) { - if (items.length !== weights.length) { - throw new Error('Items and weights must be of the same size'); - } - if (!items.length) { - throw new Error('Items must not be empty'); - } - // Preparing the cumulative weights array. - // For example: - // - weights = [1, 4, 3] - // - cumulativeWeights = [1, 5, 8] - const cumulativeWeights = []; - for (let i = 0; i < weights.length; i += 1) { - cumulativeWeights[i] = weights[i] + (cumulativeWeights[i - 1] || 0); - } - // Getting the random number in a range of [0...sum(weights)] - // For example: - // - weights = [1, 4, 3] - // - maxCumulativeWeight = 8 - // - range for the random number is [0...8] - const maxCumulativeWeight = cumulativeWeights[cumulativeWeights.length - 1]; - const randomNumber = maxCumulativeWeight * Math.random(); - // Picking the random item based on its weight. - // The items with higher weight will be picked more often. - for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) { - if (cumulativeWeights[itemIndex] >= randomNumber) { - return { - item: items[itemIndex], - index: itemIndex - }; - } - } -} diff --git a/docs/content/DS_ALGO/algorithms/string/AlphaNumericPalindrome.js b/docs/content/DS_ALGO/algorithms/string/AlphaNumericPalindrome.js deleted file mode 100644 index 99bf27affc..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/AlphaNumericPalindrome.js +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** - * @function alphaNumericPlaindrome - * @description alphaNumericPlaindrome should return true if the string has alphanumeric characters that are palindrome irrespective of special characters and the letter case. - * @param {string} str the string to check - * @returns {Boolean} - * @see [Factorial](https://en.wikipedia.org/wiki/Palindrome) - * @example - * The function alphaNumericPlaindrome() receives a string with varying formats - * like "racecar", "RaceCar", and "race CAR" - * The string can also have special characters - * like "2A3*3a2", "2A3 3a2", and "2_A3*3#A2" - * - * But the catch is, we have to check only if the alphanumeric characters - * are palindrome i.e remove spaces, symbols, punctuations etc - * and the case of the characters doesn't matter - * - ****************************************************************************/ -const alphaNumericPlaindrome = (str) => { - // removing all the special characters and turning everything to lowercase - const newStr = str.replace(/[^a-zA-Z0-9]*/g, '').toLowerCase(); - for (let i = 0; i < newStr.length; i++) { - if (newStr[i] !== newStr[newStr.length - 1 - i]) { - return false; - } - } - return true; -}; -export { alphaNumericPlaindrome }; diff --git a/docs/content/DS_ALGO/algorithms/string/AlternativeStringArrange.js b/docs/content/DS_ALGO/algorithms/string/AlternativeStringArrange.js deleted file mode 100644 index cabc6ec48b..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/AlternativeStringArrange.js +++ /dev/null @@ -1,36 +0,0 @@ -// Alternative arrange the two given strings in one string in O(n) time complexity. -// Problem Source & Explanation: https://www.geeksforgeeks.org/alternatively-merge-two-strings-in-java/ -/** - * Alternative arrange the two given strings in one string in O(n) time complexity. - * @param {String} str1 first input string - * @param {String} str2 second input string - * @returns `String` return one alternative arrange string. - */ -const AlternativeStringArrange = (str1, str2) => { - // firstly, check that both inputs are strings. - if (typeof str1 !== 'string' || typeof str2 !== 'string') { - return 'Not string(s)'; - } - // output string value. - let outStr = ''; - // get first string length. - const firstStringLength = str1.length; - // get second string length. - const secondStringLength = str2.length; - // absolute length for operation. - const absLength = firstStringLength > secondStringLength ? firstStringLength : secondStringLength; - // Iterate the character count until the absolute count is reached. - for (let charCount = 0; charCount < absLength; charCount++) { - // If firstStringLength is lesser than the charCount it means they are able to re-arrange. - if (charCount < firstStringLength) { - outStr += str1[charCount]; - } - // If secondStringLength is lesser than the charCount it means they are able to re-arrange. - if (charCount < secondStringLength) { - outStr += str2[charCount]; - } - } - // return the output string. - return outStr; -}; -export { AlternativeStringArrange }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckAnagram.js b/docs/content/DS_ALGO/algorithms/string/CheckAnagram.js deleted file mode 100644 index 4d5ea4c5bf..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckAnagram.js +++ /dev/null @@ -1,62 +0,0 @@ -// An [Anagram](https://en.wikipedia.org/wiki/Anagram) is a string that is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. Anagram check is not case-sensitive; -/** - * @function checkAnagramRegex - * @param {string} str1 - * @param {string} str2 - * @returns {boolean} - * @description - check anagram with the help of Regex - * @example - checkAnagramRegex('node', 'deno') => true - * @example - checkAnagramRegex('Eleven plus two', 'Twelve plus one') => true - */ -const checkAnagramRegex = (str1, str2) => { - // check that inputs are strings. - if (typeof str1 !== 'string' || typeof str2 !== 'string') { - throw new TypeError('Both arguments should be strings.'); - } - // If both strings have not same lengths then they can not be anagram. - if (str1.length !== str2.length) { - return false; - } - /** - * str1 converted to an array and traverse each letter of str1 by reduce method - * reduce method return string which is empty or not. - * if it returns empty string '' -> falsy, with Logical !(NOT) Operator, it's will be converted to boolean and return true else false - */ - return ![...str1].reduce( - (str2Acc, cur) => str2Acc.replace(new RegExp(cur, 'i'), ''), // remove the similar letter from str2Acc in case-insensitive - str2 - ); -}; -/** - * @function checkAnagramMap - * @description - check anagram via using HashMap - * @param {string} str1 - * @param {string} str2 - * @returns {boolean} - * @example - checkAnagramMap('node', 'deno') => true - * @example - checkAnagramMap('Eleven plus two', 'Twelve plus one') => true - */ -const checkAnagramMap = (str1, str2) => { - // check that inputs are strings. - if (typeof str1 !== 'string' || typeof str2 !== 'string') { - throw new TypeError('Both arguments should be strings.'); - } - // If both strings have not same lengths then they can not be anagram. - if (str1.length !== str2.length) { - return false; - } - const str1List = Array.from(str1.toUpperCase()); // str1 to array - // get the occurrences of str1 characters by using HashMap - const str1Occurs = str1List.reduce((map, char) => map.set(char, map.get(char) + 1 || 1), new Map()); - for (const char of str2.toUpperCase()) { - // if char has not exist to the map it's return false - if (!str1Occurs.has(char)) { - return false; - } - let getCharCount = str1Occurs.get(char); - str1Occurs.set(char, --getCharCount); - getCharCount === 0 && str1Occurs.delete(char); - } - return true; -}; -export { checkAnagramRegex, checkAnagramMap }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckCamelCase.js b/docs/content/DS_ALGO/algorithms/string/CheckCamelCase.js deleted file mode 100644 index ace2f0efd1..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckCamelCase.js +++ /dev/null @@ -1,16 +0,0 @@ -// CheckCamelCase method checks the given string is in camelCase or not. -// Problem Source & Explanation: https://en.wikipedia.org/wiki/Camel_case -/** - * checkCamelCase method returns true if the string in camelCase, else return the false. - * @param {String} varName the name of the variable to check. - * @returns `Boolean` return true if the string is in camelCase, else return false. - */ -const checkCamelCase = (varName) => { - // firstly, check that input is a string or not. - if (typeof varName !== 'string') { - throw new TypeError('Argument is not a string.'); - } - const pat = /^[a-z][A-Za-z]*$/; - return pat.test(varName); -}; -export { checkCamelCase }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckFlatCase.js b/docs/content/DS_ALGO/algorithms/string/CheckFlatCase.js deleted file mode 100644 index 3fdb62a46c..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckFlatCase.js +++ /dev/null @@ -1,18 +0,0 @@ -// checkFlatCase method checks if the given string is in flatcase or not. Flatcase is a convention -// where all letters are in lowercase, and there are no spaces between words. -// thisvariable is an example of flatcase. In camelCase it would be thisVariable, snake_case this_variable and so on. -// Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) -/** - * checkFlatCase method returns true if the string in flatcase, else return the false. - * @param {string} varname the name of the variable to check. - * @returns {boolean} return true if the string is in flatcase, else return false. - */ -const checkFlatCase = (varname) => { - // firstly, check that input is a string or not. - if (typeof varname !== 'string') { - return new TypeError('Argument is not a string.'); - } - const pat = /^[a-z]*$/; - return pat.test(varname); -}; -export { checkFlatCase }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckKebabCase.js b/docs/content/DS_ALGO/algorithms/string/CheckKebabCase.js deleted file mode 100644 index c9159ebe25..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckKebabCase.js +++ /dev/null @@ -1,16 +0,0 @@ -// CheckKebabCase method checks the given string is in kebab-case or not. -// Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) -/** - * CheckKebabCase method returns true if the string in kebab-case, else return the false. - * @param {String} varName the name of the variable to check. - * @returns `Boolean` return true if the string is in kebab-case, else return false. - */ -const CheckKebabCase = (varName) => { - // firstly, check that input is a string or not. - if (typeof varName !== 'string') { - return new TypeError('Argument is not a string.'); - } - const pat = /(\w+)-(\w)([\w-]*)/; - return pat.test(varName) && !varName.includes('_'); -}; -export { CheckKebabCase }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckPalindrome.js b/docs/content/DS_ALGO/algorithms/string/CheckPalindrome.js deleted file mode 100644 index 7d3a8cd9d9..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckPalindrome.js +++ /dev/null @@ -1,16 +0,0 @@ -// Palindrome check is case sensitive; i.e. Aba is not a palindrome -// input is a string -const checkPalindrome = (str) => { - // check that input is a string - if (typeof str !== 'string') { - return 'Not a string'; - } - if (str.length === 0) { - return 'Empty string'; - } - // Reverse only works with array, thus convert the string to array, reverse it and convert back to string - // return as palindrome if the reversed string is equal to the input string - const reversed = [...str].reverse().join(''); - return str === reversed ? 'Palindrome' : 'Not a Palindrome'; -}; -export { checkPalindrome }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckPangram.js b/docs/content/DS_ALGO/algorithms/string/CheckPangram.js deleted file mode 100644 index bfe8430c66..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckPangram.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * What is Pangram? - * Pangram is a sentence that contains all the letters in the alphabet https://en.wikipedia.org/wiki/Pangram - */ -/** - * @function checkPangramRegex - * @description - This function check pangram with the help of regex pattern - * @param {string} string - * @returns {boolean} - * @example - checkPangramRegex("'The quick brown fox jumps over the lazy dog' is a pangram") => true - * @example - checkPangramRegex('"Waltz, bad nymph, for quick jigs vex." is a pangram') => true - */ -const checkPangramRegex = (string) => { - if (typeof string !== 'string') { - throw new TypeError('The given value is not a string'); - } - /** - * Match all 26 alphabets using regex, with the help of: - * Capturing group - () -> Groups multiple tokens together and creates a capture group for extracting a substring or using a backreference. - * Character set - [a-z] -> Matches a char in the range a to z in case-insensitive for the 'i' flag - * Negative lookahead - (?!) -> Specifies a group that can not match after the main expression (if it matches, the result is discarded). - * Dot - . -> Matches any character except linebreaks. Equivalent to - * Star - * -> Matches 0 or more of the preceding token. - * Numeric reference - \{$n} -> Matches the results of a capture group. E.g. - \1 matches the results of the first capture group & \3 matches the third. - */ - return string.match(/([a-z])(?!.*\1)/gi).length === 26; -}; -/** - * @function checkPangramSet - * @description - This function detect the pangram sentence by HashSet - * @param {string} string - * @returns {boolean} - */ -const checkPangramSet = (string) => { - if (typeof string !== 'string') { - throw new TypeError('The given value is not a string'); - } - const lettersSet = new Set(); - for (const letter of string.toUpperCase()) { - if (/[A-Z]/.test(letter)) { - // if the letter is a valid uppercase alphabet then the add method insert the letter to the HashSet - lettersSet.add(letter); - } - } - return lettersSet.size === 26; -}; -export { checkPangramRegex, checkPangramSet }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckPascalCase.js b/docs/content/DS_ALGO/algorithms/string/CheckPascalCase.js deleted file mode 100644 index 82181872a7..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckPascalCase.js +++ /dev/null @@ -1,16 +0,0 @@ -// CheckPascalCase method checks the given string is in PascalCase or not. -// Problem Source & Explanation: https://www.theserverside.com/definition/Pascal-case -/** - * CheckPascalCase method returns true if the string in PascalCase, else return the false. - * @param {String} VarName the name of the variable to check. - * @returns `Boolean` return true if the string is in PascalCase, else return false. - */ -const CheckPascalCase = (VarName) => { - // firstly, check that input is a string or not. - if (typeof VarName !== 'string') { - return new TypeError('Argument is not a string.'); - } - const pat = /^[A-Z][A-Za-z]*$/; - return pat.test(VarName); -}; -export { CheckPascalCase }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckRearrangePalindrome.js b/docs/content/DS_ALGO/algorithms/string/CheckRearrangePalindrome.js deleted file mode 100644 index bb967329cf..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckRearrangePalindrome.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * What is a palindrome? https://en.wikipedia.org/wiki/Palindrome - * Receives a string and returns whether it can be rearranged to become a palindrome or not - * The string can only be a palindrome if the count of ALL characters is even or if the ONLY ONE character count is odd - * Input is a string - * - **/ -export const palindromeRearranging = (str) => { - // check that input is a string - if (typeof str !== 'string') { - return 'Not a string'; - } - // Check if is a empty string - if (str.length === 0) { - return 'Empty string'; - } - // First obtain the character count for each character in the string and store it in an object. - // Filter the object's values to only the odd character counts. - const charCounts = [...str].reduce((counts, char) => { - counts[char] = counts[char] ? counts[char] + 1 : 1; - return counts; - }, {}); - // If the length of the resulting array is 0 or 1, the string can be a palindrome. - return Object.values(charCounts).filter((count) => count % 2 !== 0).length <= 1; -}; -// testing -// > palindromeRearranging('aaeccrr') -// true -// > palindromeRearranging('leve') -// false diff --git a/docs/content/DS_ALGO/algorithms/string/CheckSnakeCase.js b/docs/content/DS_ALGO/algorithms/string/CheckSnakeCase.js deleted file mode 100644 index ef588f6735..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckSnakeCase.js +++ /dev/null @@ -1,16 +0,0 @@ -// CheckSnakeCase method checks the given string is in snake_case or not. -// Problem Source & Explanation: https://en.wikipedia.org/wiki/Naming_convention_(programming) -/** - * checkSnakeCase method returns true if the string in snake_case, else return the false. - * @param {String} varName the name of the variable to check. - * @returns `Boolean` return true if the string is in snake_case, else return false. - */ -const checkSnakeCase = (varName) => { - // firstly, check that input is a string or not. - if (typeof varName !== 'string') { - throw new TypeError('Argument is not a string.'); - } - const pat = /(.*?)_([a-zA-Z])*/; - return pat.test(varName); -}; -export { checkSnakeCase }; diff --git a/docs/content/DS_ALGO/algorithms/string/CheckWordOccurrence.js b/docs/content/DS_ALGO/algorithms/string/CheckWordOccurrence.js deleted file mode 100644 index ccac1bd206..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CheckWordOccurrence.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @function checkWordOccurrence - * @description - this function count all the words in a sentence and return an word occurrence object - * @param {string} str - * @param {boolean} isCaseSensitive - * @returns {Object} - */ -const checkWordOccurrence = (str, isCaseSensitive = false) => { - if (typeof str !== 'string') { - throw new TypeError('The first param should be a string'); - } - if (typeof isCaseSensitive !== 'boolean') { - throw new TypeError('The second param should be a boolean'); - } - const modifiedStr = isCaseSensitive ? str.toLowerCase() : str; - return modifiedStr - .split(/\s+/) // remove all spaces and distribute all word in List - .reduce((occurrence, word) => { - occurrence[word] = occurrence[word] + 1 || 1; - return occurrence; - }, {}); -}; -export { checkWordOccurrence }; diff --git a/docs/content/DS_ALGO/algorithms/string/CountVowels.js b/docs/content/DS_ALGO/algorithms/string/CountVowels.js deleted file mode 100644 index 0267711a35..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CountVowels.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @function countVowels - * @description Given a string of words or phrases, count the number of vowels. - * @param {String} str - The input string - * @return {Number} - The number of vowels - * @example countVowels("ABCDE") => 2 - * @example countVowels("Hello") => 2 - */ -const countVowels = (str) => { - if (typeof str !== 'string') { - throw new TypeError('Input should be a string'); - } - const vowelRegex = /[aeiou]/gi; - const vowelsArray = str.match(vowelRegex) || []; - return vowelsArray.length; -}; -export { countVowels }; diff --git a/docs/content/DS_ALGO/algorithms/string/CreatePermutations.js b/docs/content/DS_ALGO/algorithms/string/CreatePermutations.js deleted file mode 100644 index 1f0ee3d7de..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/CreatePermutations.js +++ /dev/null @@ -1,33 +0,0 @@ -/* -a permutation of a set is, loosely speaking, an arrangement of its members into a sequence or linear order, or if the set is already ordered, a rearrangement of its elements. -The word "permutation" also refers to the act or process of changing the linear order of an ordered set -More at : https://en.wikipedia.org/wiki/Permutation -*/ -const createPermutations = (str) => { - // convert string to array - const arr = str.split(''); - // get array length - const strLen = arr.length; - // this will hold all the permutations - const perms = []; - let rest; - let picked; - let restPerms; - let next; - // if strLen is zero, return the same string - if (strLen === 0) { - return [str]; - } - // loop to the length to get all permutations - for (let i = 0; i < strLen; i++) { - rest = Object.create(arr); - picked = rest.splice(i, 1); - restPerms = createPermutations(rest.join('')); - for (let j = 0, jLen = restPerms.length; j < jLen; j++) { - next = picked.concat(restPerms[j]); - perms.push(next.join('')); - } - } - return perms; -}; -export { createPermutations }; diff --git a/docs/content/DS_ALGO/algorithms/string/DiceCoefficient.js b/docs/content/DS_ALGO/algorithms/string/DiceCoefficient.js deleted file mode 100644 index 6f653891c1..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/DiceCoefficient.js +++ /dev/null @@ -1,39 +0,0 @@ -/* The Sørensen-Dice coefficient is a statistic used to gauge the similarity of two samples. - * Applied to strings, it can give you a value between 0 and 1 (included) which tells you how similar they are. - * Dice coefficient is calculated by comparing the bigrams of both strings, - * a bigram is a substring of the string of length 2. - * read more: https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient - */ -// Time complexity: O(m + n), m and n being the sizes of string A and string B -// Find the bistrings of a string and return a hashmap (key => bistring, value => count) -function mapBigrams(string) { - const bigrams = new Map(); - for (let i = 0; i < string.length - 1; i++) { - const bigram = string.substring(i, i + 2); - const count = bigrams.get(bigram); - bigrams.set(bigram, (count || 0) + 1); - } - return bigrams; -} -// Calculate the number of common bigrams between a map of bigrams and a string -function countCommonBigrams(bigrams, string) { - let count = 0; - for (let i = 0; i < string.length - 1; i++) { - const bigram = string.substring(i, i + 2); - if (bigrams.has(bigram)) count++; - } - return count; -} -// Calculate Dice coeff of 2 strings -function diceCoefficient(stringA, stringB) { - if (stringA === stringB) return 1; - else if (stringA.length < 2 || stringB.length < 2) return 0; - const bigramsA = mapBigrams(stringA); - const lengthA = stringA.length - 1; - const lengthB = stringB.length - 1; - let dice = (2 * countCommonBigrams(bigramsA, stringB)) / (lengthA + lengthB); - // cut 0.xxxxxx to 0.xx for simplicity - dice = Math.floor(dice * 100) / 100; - return dice; -} -export { diceCoefficient }; diff --git a/docs/content/DS_ALGO/algorithms/string/FormatPhoneNumber.js b/docs/content/DS_ALGO/algorithms/string/FormatPhoneNumber.js deleted file mode 100644 index e238046489..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/FormatPhoneNumber.js +++ /dev/null @@ -1,15 +0,0 @@ -// function that takes 10 digits and returns a string of the formatted phone number -// e.g.: 1234567890 -> (123) 456-7890 -const formatPhoneNumber = (numbers) => { - const numbersString = numbers.toString(); - if (numbersString.length !== 10 || isNaN(numbersString)) { - // return "Invalid phone number." - throw new TypeError('Invalid phone number.'); - } - const arr = '(XXX) XXX-XXXX'.split(''); - Array.from(numbersString).forEach((n) => { - arr[arr.indexOf('X')] = n; - }); - return arr.join(''); -}; -export { formatPhoneNumber }; diff --git a/docs/content/DS_ALGO/algorithms/string/GenerateGUID.js b/docs/content/DS_ALGO/algorithms/string/GenerateGUID.js deleted file mode 100644 index 6c92a1cf04..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/GenerateGUID.js +++ /dev/null @@ -1,16 +0,0 @@ -/* -Generates a UUID/GUID in Node.Js. -The script uses `Math.random` in combination with the timestamp for better randomness. -The function generate an RFC4122 (https://www.ietf.org/rfc/rfc4122.txt) version 4 UUID/GUID -*/ -export const Guid = () => { - const pattern = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; - let currentDateMilliseconds = new Date().getTime(); - return pattern.replace(/[xy]/g, (currentChar) => { - const randomChar = (currentDateMilliseconds + Math.random() * 16) % 16 | 0; - currentDateMilliseconds = Math.floor(currentDateMilliseconds / 16); - return (currentChar === 'x' ? randomChar : (randomChar & 0x7) | 0x8).toString(16); - }); -}; -// > Guid() -// 'edc848db-3478-1760-8b55-7986003d895f' diff --git a/docs/content/DS_ALGO/algorithms/string/HammingDistance.js b/docs/content/DS_ALGO/algorithms/string/HammingDistance.js deleted file mode 100644 index 8925d18f33..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/HammingDistance.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Hamming Distance: https://en.wikipedia.org/wiki/Hamming_distance - * - * - * Hamming distance is a metric for comparing two binary data strings. - * - * While comparing two binary strings of equal length, Hamming distance - * is the number of bit positions in which the two bits are different. - * The Hamming distance between two strings, a and b is denoted as d(a,b) - */ -/** - * @param {string} a - * @param {string} b - * @return {number} - */ -export const hammingDistance = (a, b) => { - if (a.length !== b.length) { - throw new Error('Strings must be of the same length'); - } - let distance = 0; - for (let i = 0; i < a.length; i += 1) { - if (a[i] !== b[i]) { - distance += 1; - } - } - return distance; -}; diff --git a/docs/content/DS_ALGO/algorithms/string/KMPPatternSearching.js b/docs/content/DS_ALGO/algorithms/string/KMPPatternSearching.js deleted file mode 100644 index 2b36189d7d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/KMPPatternSearching.js +++ /dev/null @@ -1,48 +0,0 @@ -// Implementing KMP Search Algorithm to search all the instances of pattern in -// given text -// Reference Book: Introduction to Algorithms, CLRS -// Explanation: https://www.topcoder.com/community/competitive-programming/tutorials/introduction-to-string-searching-algorithms/ -const computeLPS = (pattern) => { - const lps = Array(pattern.length); - lps[0] = 0; - for (let i = 1; i < pattern.length; i++) { - let matched = lps[i - 1]; - while (matched > 0 && pattern[i] !== pattern[matched]) { - matched = lps[matched - 1]; - } - if (pattern[i] === pattern[matched]) { - matched++; - } - lps[i] = matched; - } - return lps; -}; -/** - * Returns all indices where pattern starts in text - * @param {*} text a big text in which pattern string is to find - * @param {*} pattern the string to find - */ -const KMPSearch = (text, pattern) => { - if (!pattern || !text) { - return []; // no results - } - // lps[i] = length of proper prefix of pattern[0]...pattern[i-1] - // which is also proper suffix of it - const lps = computeLPS(pattern); - const result = []; - let matched = 0; - for (let i = 0; i < text.length; i++) { - while (matched > 0 && text[i] !== pattern[matched]) { - matched = lps[matched - 1]; - } - if (text[i] === pattern[matched]) { - matched++; - } - if (matched === pattern.length) { - result.push(i - pattern.length + 1); - matched = lps[matched - 1]; - } - } - return result; -}; -export { KMPSearch }; diff --git a/docs/content/DS_ALGO/algorithms/string/LevenshteinDistance.js b/docs/content/DS_ALGO/algorithms/string/LevenshteinDistance.js deleted file mode 100644 index 376b7b7024..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/LevenshteinDistance.js +++ /dev/null @@ -1,37 +0,0 @@ -/* The Levenshtein distance (a.k.a edit distance) is a -measure of similarity between two strings. It is -defined as the minimum number of changes required to -convert string a into string b (this is done by -inserting, deleting or replacing a character in -string a). -The smaller the Levenshtein distance, -the more similar the strings are. This is a very -common problem in the application of Dynamic Programming. -*/ -const levenshteinDistance = (a, b) => { - // Declaring array 'D' with rows = len(a) + 1 and columns = len(b) + 1: - const distanceMatrix = Array(b.length + 1) - .fill(null) - .map(() => Array(a.length + 1).fill(null)); - // Initializing first column: - for (let i = 0; i <= a.length; i += 1) { - distanceMatrix[0][i] = i; - } - // Initializing first row: - for (let j = 0; j <= b.length; j += 1) { - distanceMatrix[j][0] = j; - } - for (let j = 1; j <= b.length; j += 1) { - for (let i = 1; i <= a.length; i += 1) { - const indicator = a[i - 1] === b[j - 1] ? 0 : 1; - // choosing the minimum of all three, vis-a-vis: - distanceMatrix[j][i] = Math.min( - distanceMatrix[j][i - 1] + 1, // deletion - distanceMatrix[j - 1][i] + 1, // insertion - distanceMatrix[j - 1][i - 1] + indicator // substitution - ); - } - } - return distanceMatrix[b.length][a.length]; -}; -export { levenshteinDistance }; diff --git a/docs/content/DS_ALGO/algorithms/string/Lower.js b/docs/content/DS_ALGO/algorithms/string/Lower.js deleted file mode 100644 index 4f2f78c67d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/Lower.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @function lower - * @description Will convert the entire string to lowercase letters. - * @param {String} str - The input string - * @returns {String} Lowercase string - * @example lower("HELLO") => hello - * @example lower("He_llo") => he_llo - */ -const lower = (str) => { - if (typeof str !== 'string') { - throw new TypeError('Invalid Input Type'); - } - return str.replace(/[A-Z]/g, (_, indexOfUpperChar) => { - const asciiCode = str.charCodeAt(indexOfUpperChar); - return String.fromCharCode(asciiCode + 32); - }); -}; -export { lower }; diff --git a/docs/content/DS_ALGO/algorithms/string/MaxCharacter.js b/docs/content/DS_ALGO/algorithms/string/MaxCharacter.js deleted file mode 100644 index d3d9e9fceb..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/MaxCharacter.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - Given a string of characters, return the character that appears the most often. - Example: input = "Hello World!" return "l" -*/ -const maxCharacter = (value) => { - if (typeof value !== 'string') { - throw new TypeError('The param should be a string'); - } else if (!value) { - throw new Error('The param should be a valid string'); - } - const occurrences = {}; - for (let i = 0; i < value.length; i++) { - const char = value[i]; - if (/\s/.test(char)) continue; - occurrences[char] = occurrences[char] + 1 || 1; - } - let maxCharacter = null; - let maxCount = 0; - Object.keys(occurrences).forEach((char) => { - if (occurrences[char] > maxCount) { - maxCount = occurrences[char]; - maxCharacter = char; - } - }); - return maxCharacter; -}; -export { maxCharacter }; diff --git a/docs/content/DS_ALGO/algorithms/string/MaxWord.js b/docs/content/DS_ALGO/algorithms/string/MaxWord.js deleted file mode 100644 index fc6616e249..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/MaxWord.js +++ /dev/null @@ -1,51 +0,0 @@ -// Given a sentence, return the most occurring word -/** - * @param {string} sentence - the sentence you want to find the most occurring word - * @returns {string} - the most occurring word - * - * @example - * - maxWord('lala lili lala'); // lala - */ -const maxWord = (sentence = '') => { - if (typeof sentence !== 'string') { - throw new TypeError('the param should be string'); - } - if (!sentence) { - return null; - } - const words = sentence.split(' '); - if (words.length < 2) { - return words[0]; - } - const occurrences = {}; - words.forEach((word) => { - occurrences[word.toLocaleLowerCase()] = occurrences[word.toLocaleLowerCase()] + 1 || 1; - }); - const max = Object.keys(occurrences).reduce( - (n, word) => { - if (occurrences[word] > n.count) { - return { - word, - count: occurrences[word] - }; - } else {} - return n; - } - }, - { - word: '', - count: 0 - } -); -return max.word; -}; -export { - maxWord -}; -} -); -return max.word; -}; -export { - maxWord -}; diff --git a/docs/content/DS_ALGO/algorithms/string/PatternMatching.js b/docs/content/DS_ALGO/algorithms/string/PatternMatching.js deleted file mode 100644 index 523db882b3..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/PatternMatching.js +++ /dev/null @@ -1,33 +0,0 @@ -/* -Pattern matching is case insensitive as -the inputs are converted to lower case before the -algorithm is run. -The algorithm will run through the entire text and -return the starting index if the given pattern is -available in the text -*/ -const checkIfPatternExists = (text, pattern) => { - if (typeof text !== 'string' || typeof pattern !== 'string') { - throw new TypeError('Given input is not a string'); - } - const textLength = text.length; // Store the length of the text in a variable - const patternLength = pattern.length; // Store the length of the pattern in a variable - // Iterate through the text until the textlength - patternlength index - for (let i = 0; i <= textLength - patternLength; i++) { - // For each character in the text check if the subsequent character - // are matching the given pattern; if not break from the condition - for (let j = 0; j < textLength; j++) { - if (text[i + j] !== pattern[j]) break; - // For each iteration of j check if the value of - // j + 1 is equal to the length of the pattern - if (j + 1 === patternLength) { - return `Given pattern is found at index ${i}`; - } - } - } -}; -export { - checkIfPatternExists -}; -checkIfPatternExists -}; diff --git a/docs/content/DS_ALGO/algorithms/string/PermutateString.js b/docs/content/DS_ALGO/algorithms/string/PermutateString.js deleted file mode 100644 index 323c72269c..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/PermutateString.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; -const permutate = (aString) => { - if (typeof aString !== 'string' || !aString) { - throw new Error('The arg must be a valid, non empty string'); - } - const characters = aString.split(''); - let permutations = [[characters.shift()]]; - while (characters.length) { - const currentCharacter = characters.shift(); - permutations = calculateCurrentCharacterPermutation(permutations, currentCharacter); - } - return permutations - .map((character) => character.join('')) - .filter((item, index, self) => self.indexOf(item) === index) - .sort(); -}; -const calculateCurrentCharacterPermutation = (allPermutations, currentCharacter) => { - const currentPermutations = []; - allPermutations.forEach((permutation) => { - let index = 0; - while (index <= permutation.length) { - const tmp = [...permutation]; - tmp.splice(index, 0, currentCharacter); - currentPermutations.push(tmp); - index++; - } - }); - return currentPermutations; -}; -export { permutate }; diff --git a/docs/content/DS_ALGO/algorithms/string/ReverseString.js b/docs/content/DS_ALGO/algorithms/string/ReverseString.js deleted file mode 100644 index 2d55ee0631..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ReverseString.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * A short example showing how to reverse a string. - */ -function ReverseStringIterative(string) { - if (typeof string !== 'string') { - throw new TypeError('The given value is not a string'); - } - let reversedString = ''; - let index; - for (index = string.length - 1; index >= 0; index--) { - reversedString += string[index]; - } - return reversedString; -} -/** - * JS disallows string mutation so we're actually a bit slower. - * - * @complexity O(n) - */ -function ReverseStringIterativeInplace(string) { - if (typeof string !== 'string') { - throw new TypeError('The given value is not a string'); - } - const _string = string.split(''); - for (let i = 0; i < Math.floor(_string.length / 2); i++) { - const first = _string[i]; - _string[i] = _string[_string.length - 1 - i]; - _string[_string.length - 1 - i] = first; - } - return _string.join(''); -} -export { ReverseStringIterative, ReverseStringIterativeInplace }; diff --git a/docs/content/DS_ALGO/algorithms/string/ReverseWords.js b/docs/content/DS_ALGO/algorithms/string/ReverseWords.js deleted file mode 100644 index c5640e9524..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ReverseWords.js +++ /dev/null @@ -1,15 +0,0 @@ -const reverseWords = (str) => { - if (typeof str !== 'string') { - throw new TypeError('The given value is not a string'); - } - // Split string into words - // Ex. "I Love JS" => ["I", "Love", "JS"] - const words = str.split(' '); - // reverse words - // ["I", "Love", "JS"] => ["JS", "Love", "I"] - const reversedWords = words.reverse(); - // join reversed words with space and return - // ["JS", "Love", "I"] => "JS Love I" - return reversedWords.join(' '); -}; -export { reverseWords }; diff --git a/docs/content/DS_ALGO/algorithms/string/ScrambleStrings.js b/docs/content/DS_ALGO/algorithms/string/ScrambleStrings.js deleted file mode 100644 index ad31996afa..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ScrambleStrings.js +++ /dev/null @@ -1,39 +0,0 @@ -// Problem Statement and Explanation: https://leetcode.com/problems/scramble-string/ -/** - * Given two strings s1 and s2 of the same length, return true if s2 is a scrambled string of s1, otherwise, return false. - * @param {string} s1 - * @param {string} s2 - * @return {boolean} - */ -const isScramble = (s1, s2) => { - return helper({}, s1, s2); -}; -const helper = function (dp, s1, s2) { - const map = {}; - if (dp[s1 + s2] !== undefined) return dp[s1 + s2]; - if (s1 === s2) return true; - for (let j = 0; j < s1.length; j++) { - if (map[s1[j]] === undefined) map[s1[j]] = 0; - if (map[s2[j]] === undefined) map[s2[j]] = 0; - map[s1[j]]++; - map[s2[j]]--; - } - for (const key in map) { - if (map[key] !== 0) { - dp[s1 + s2] = false; - return false; - } - } - for (let i = 1; i < s1.length; i++) { - if ( - (helper(dp, s1.substr(0, i), s2.substr(0, i)) && helper(dp, s1.substr(i), s2.substr(i))) || - (helper(dp, s1.substr(0, i), s2.substr(s2.length - i)) && helper(dp, s1.substr(i), s2.substr(0, s2.length - i))) - ) { - dp[s1 + s2] = true; - return true; - } - } - dp[s1 + s2] = false; - return false; -}; -export { isScramble }; diff --git a/docs/content/DS_ALGO/algorithms/string/Upper.js b/docs/content/DS_ALGO/algorithms/string/Upper.js deleted file mode 100644 index 6e106a45f0..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/Upper.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @function upper - * @description Will convert the entire string to uppercase letters. - * @param {String} str - The input string - * @return {String} Uppercase string - * @example upper("hello") => HELLO - * @example upper("He_llo") => HE_LLO - */ -const upper = (str) => { - if (typeof str !== 'string') { - throw new TypeError('Argument should be string'); - } - return str.replace(/[a-z]/g, (_, indexOfLowerChar) => { - const asciiCode = str.charCodeAt(indexOfLowerChar); - return String.fromCharCode(asciiCode - 32); - }); -}; -export { upper }; diff --git a/docs/content/DS_ALGO/algorithms/string/ValidateCreditCard.js b/docs/content/DS_ALGO/algorithms/string/ValidateCreditCard.js deleted file mode 100644 index 075231239d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ValidateCreditCard.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Validate a given credit card number - * - * The core of the validation of credit card numbers is the Luhn algorithm. - * - * The validation sum should be completely divisible by 10 which is calculated as follows, - * every first digit is added directly to the validation sum. - * For every second digit in the credit card number, the digit is multiplied by 2. - * If the product is greater than 10 the digits of the product are added. - * This resultant digit is considered for the validation sum rather than the digit itself. - * - * Ref: https://www.geeksforgeeks.org/luhn-algorithm/ - */ -const luhnValidation = (creditCardNumber) => { - let validationSum = 0; - creditCardNumber.split('').forEach((digit, index) => { - let currentDigit = parseInt(digit); - if (index % 2 === 0) { - // Multiply every 2nd digit from the left by 2 - currentDigit *= 2; - // if product is greater than 10 add the individual digits of the product to get a single digit - if (currentDigit > 9) { - currentDigit %= 10; - currentDigit += 1; - } - } - validationSum += currentDigit; - }); - return validationSum % 10 === 0; -}; -const validateCreditCard = (creditCardString) => { - const validStartSubString = ['4', '5', '6', '37', '34', '35']; // Valid credit card numbers start with these numbers - if (typeof creditCardString !== 'string') { - throw new TypeError('The given value is not a string'); - } - const errorMessage = `${creditCardString} is an invalid credit card number because `; - if (isNaN(creditCardString)) { - throw new TypeError(errorMessage + 'it has nonnumerical characters.'); - } - const creditCardStringLength = creditCardString.length; - if (!(creditCardStringLength >= 13 && creditCardStringLength <= 16)) { - throw new Error(errorMessage + 'of its length.'); - } - if (!validStartSubString.some((subString) => creditCardString.startsWith(subString))) { - throw new Error(errorMessage + 'of its first two digits.'); - } - if (!luhnValidation(creditCardString)) { - throw new Error(errorMessage + 'it fails the Luhn check.'); - } - return true; -}; -export { - validateCreditCard -}; -validateCreditCard -}; diff --git a/docs/content/DS_ALGO/algorithms/string/ValidateEmail.js b/docs/content/DS_ALGO/algorithms/string/ValidateEmail.js deleted file mode 100644 index 63bec976f7..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ValidateEmail.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Returns whether the given string is a valid email address or not. - */ -const validateEmail = (str) => { - if (str === '' || str === null) { - throw new TypeError('Email Address String Null or Empty.'); - } - return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str); -}; -export { validateEmail }; diff --git a/docs/content/DS_ALGO/algorithms/string/ValidateUrl.js b/docs/content/DS_ALGO/algorithms/string/ValidateUrl.js deleted file mode 100644 index 5b8197ddf5..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/ValidateUrl.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @function ValidateURL - * @description validate the URL. - * @param {String} url - The input URL string - * @return {Boolean} - */ -const validateURL = (url) => { - const URL_PATTERN = /^(https?:\/\/(?:www\.|(?!www))[^\s.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})$/gi; - return URL_PATTERN.test(url); -}; -export { validateURL }; diff --git a/docs/content/DS_ALGO/algorithms/string/hamming-distance/README.md b/docs/content/DS_ALGO/algorithms/string/hamming-distance/README.md deleted file mode 100644 index cf5d6cf032..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/hamming-distance/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Hamming Distance - -the Hamming distance between two strings of equal length is the -number of positions at which the corresponding symbols are -different. In other words, it measures the minimum number of -substitutions required to change one string into the other, or -the minimum number of errors that could have transformed one -string into the other. In a more general context, the Hamming -distance is one of several string metrics for measuring the -edit distance between two sequences. - -## Examples - -The Hamming distance between: - -- "ka**rol**in" and "ka**thr**in" is **3**. -- "k**a**r**ol**in" and "k**e**r**st**in" is **3**. -- 10**1**1**1**01 and 10**0**1**0**01 is **2**. -- 2**17**3**8**96 and 2**23**3**7**96 is **3**. - -## References - -[Wikipedia](https://en.wikipedia.org/wiki/Hamming_distance) diff --git a/docs/content/DS_ALGO/algorithms/string/hamming-distance/hammingDistance.js b/docs/content/DS_ALGO/algorithms/string/hamming-distance/hammingDistance.js deleted file mode 100644 index 68b081a30a..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/hamming-distance/hammingDistance.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @param {string} a - * @param {string} b - * @return {number} - */ -export default function hammingDistance(a, b) { - if (a.length !== b.length) { - throw new Error('Strings must be of the same length'); - } - let distance = 0; - for (let i = 0; i < a.length; i += 1) { - if (a[i] !== b[i]) { - distance += 1; - } - } - return distance; -} diff --git a/docs/content/DS_ALGO/algorithms/string/hamming-distance/test/hammingDistance.test.js b/docs/content/DS_ALGO/algorithms/string/hamming-distance/test/hammingDistance.test.js deleted file mode 100644 index b61b10b460..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/hamming-distance/test/hammingDistance.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import hammingDistance from '../hammingDistance'; -describe('hammingDistance', () => { - it('should throw an error when trying to compare the strings of different lengths', () => { - const compareStringsOfDifferentLength = () => { - hammingDistance('a', 'aa'); - }; - expect(compareStringsOfDifferentLength).toThrowError(); - }); - it('should calculate difference between two strings', () => { - expect(hammingDistance('a', 'a')).toBe(0); - expect(hammingDistance('a', 'b')).toBe(1); - expect(hammingDistance('abc', 'add')).toBe(2); - expect(hammingDistance('karolin', 'kathrin')).toBe(3); - expect(hammingDistance('karolin', 'kerstin')).toBe(3); - expect(hammingDistance('1011101', '1001001')).toBe(2); - expect(hammingDistance('2173896', '2233796')).toBe(3); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/README.md b/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/README.md deleted file mode 100644 index 140705355d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Knuth-Morris-Pratt Algorithm - -The Knuth-Morris-Pratt string searching algorithm (or -KMP algorithm) searches for occurrences of a "word" `W` -within a main "text string" `T` by employing the -observation that when a mismatch occurs, the word itself -embodies sufficient information to determine where the -next match could begin, thus bypassing re-examination -of previously matched characters. - -## Complexity - -- **Time:** `O(|W| + |T|)` (much faster comparing to trivial `O(|W| * |T|)`) -- **Space:** `O(|W|)` - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) -- [YouTube](https://www.youtube.com/watch?v=GTJr8OvyEVQ&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/knuthMorrisPratt.js b/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/knuthMorrisPratt.js deleted file mode 100644 index 0771cb5e73..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/knuthMorrisPratt.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @see https://www.youtube.com/watch?v=GTJr8OvyEVQ - * @param {string} word - * @return {number[]} - */ -function buildPatternTable(word) { - const patternTable = [0]; - let prefixIndex = 0; - let suffixIndex = 1; - while (suffixIndex < word.length) { - if (word[prefixIndex] === word[suffixIndex]) { - patternTable[suffixIndex] = prefixIndex + 1; - suffixIndex += 1; - prefixIndex += 1; - } else if (prefixIndex === 0) { - patternTable[suffixIndex] = 0; - suffixIndex += 1; - } else { - prefixIndex = patternTable[prefixIndex - 1]; - } - } - return patternTable; -} -/** - * @param {string} text - * @param {string} word - * @return {number} - */ -export default function knuthMorrisPratt(text, word) { - if (word.length === 0) { - return 0; - } - let textIndex = 0; - let wordIndex = 0; - const patternTable = buildPatternTable(word); - while (textIndex < text.length) { - if (text[textIndex] === word[wordIndex]) { - // We've found a match. - if (wordIndex === word.length - 1) { - return textIndex - word.length + 1; - } - wordIndex += 1; - textIndex += 1; - } else if (wordIndex > 0) { - wordIndex = patternTable[wordIndex - 1]; - } else { - // wordIndex = 0; - textIndex += 1; - } - } - return -1; -} diff --git a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/test/knuthMorrisPratt.test.js b/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/test/knuthMorrisPratt.test.js deleted file mode 100644 index 625c0ed4a7..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/knuth-morris-pratt/test/knuthMorrisPratt.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import knuthMorrisPratt from '../knuthMorrisPratt'; -describe('knuthMorrisPratt', () => { - it('should find word position in given text', () => { - expect(knuthMorrisPratt('', '')).toBe(0); - expect(knuthMorrisPratt('a', '')).toBe(0); - expect(knuthMorrisPratt('a', 'a')).toBe(0); - expect(knuthMorrisPratt('abcbcglx', 'abca')).toBe(-1); - expect(knuthMorrisPratt('abcbcglx', 'bcgl')).toBe(3); - expect(knuthMorrisPratt('abcxabcdabxabcdabcdabcy', 'abcdabcy')).toBe(15); - expect(knuthMorrisPratt('abcxabcdabxabcdabcdabcy', 'abcdabca')).toBe(-1); - expect(knuthMorrisPratt('abcxabcdabxaabcdabcabcdabcdabcy', 'abcdabca')).toBe(12); - expect(knuthMorrisPratt('abcxabcdabxaabaabaaaabcdabcdabcy', 'aabaabaaa')).toBe(11); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/README.md b/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/README.md deleted file mode 100644 index 4ff739c1b5..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# Levenshtein Distance - -The Levenshtein distance is a string metric for measuring the -difference between two sequences. Informally, the Levenshtein -distance between two words is the minimum number of -single-character edits (insertions, deletions or substitutions) -required to change one word into the other. - -## Definition - -Mathematically, the Levenshtein distance between two strings -`a` and `b` (of length `|a|` and `|b|` respectively) is given by -![Levenshtein](https://wikimedia.org/api/rest_v1/media/math/render/svg/4cf357d8f2135035207088d2c7b890fb4b64e410) -where - -![Levenshtein](https://wikimedia.org/api/rest_v1/media/math/render/svg/f0a48ecfc9852c042382fdc33c19e11a16948e85) - -where -![Levenshtein](https://wikimedia.org/api/rest_v1/media/math/render/svg/52512ede08444b13838c570ba4a3fc71d54dbce9) -is the indicator function equal to `0` when -![Levenshtein](https://wikimedia.org/api/rest_v1/media/math/render/svg/231fda9ee578f0328c5ca28088d01928bb0aaaec) -and equal to 1 otherwise, and -![Levenshtein](https://wikimedia.org/api/rest_v1/media/math/render/svg/bdc0315678caad28648aafedb6ebafb16bd1655c) -is the distance between the first `i` characters of `a` and the first -`j` characters of `b`. - -Note that the first element in the minimum corresponds to -deletion (from `a` to `b`), the second to insertion and -the third to match or mismatch, depending on whether the -respective symbols are the same. - -## Example - -For example, the Levenshtein distance between `kitten` and -`sitting` is `3`, since the following three edits change one -into the other, and there is no way to do it with fewer than -three edits: - -1. **k**itten → **s**itten (substitution of "s" for "k") -2. sitt**e**n → sitt**i**n (substitution of "i" for "e") -3. sittin → sittin**g** (insertion of "g" at the end). - -## Applications - -This has a wide range of applications, for instance, spell checkers, correction -systems for optical character recognition, fuzzy string searching, and software -to assist natural language translation based on translation memory. - -## Dynamic Programming Approach Explanation - -Let's take a simple example of finding minimum edit distance between -strings `ME` and `MY`. Intuitively you already know that minimum edit distance -here is `1` operation, which is replacing `E` with `Y`. But -let's try to formalize it in a form of the algorithm in order to be able to -do more complex examples like transforming `Saturday` into `Sunday`. - -To apply the mathematical formula mentioned above to `ME → MY` transformation -we need to know minimum edit distances of `ME → M`, `M → MY` and `M → M` transformations -in prior. Then we will need to pick the minimum one and add _one_ operation to -transform last letters `E → Y`. So minimum edit distance of `ME → MY` transformation -is being calculated based on three previously possible transformations. - -To explain this further let's draw the following matrix: - -![Levenshtein Matrix](https://cdn-images-1.medium.com/max/1600/1*aTunSUoy0BJyYBVn4tWGrA.png) - -- Cell `(0:1)` contains red number 1. It means that we need 1 operation to - transform `M` to an empty string. And it is by deleting `M`. This is why this number is red. -- Cell `(0:2)` contains red number 2. It means that we need 2 operations - to transform `ME` to an empty string. And it is by deleting `E` and `M`. -- Cell `(1:0)` contains green number 1. It means that we need 1 operation - to transform an empty string to `M`. And it is by inserting `M`. This is why this number is green. -- Cell `(2:0)` contains green number 2. It means that we need 2 operations - to transform an empty string to `MY`. And it is by inserting `Y` and `M`. -- Cell `(1:1)` contains number 0. It means that it costs nothing - to transform `M` into `M`. -- Cell `(1:2)` contains red number 1. It means that we need 1 operation - to transform `ME` to `M`. And it is by deleting `E`. -- And so on... - -This looks easy for such small matrix as ours (it is only `3x3`). But here you -may find basic concepts that may be applied to calculate all those numbers for -bigger matrices (let's say a `9x7` matrix for `Saturday → Sunday` transformation). - -According to the formula you only need three adjacent cells `(i-1:j)`, `(i-1:j-1)`, and `(i:j-1)` to -calculate the number for current cell `(i:j)`. All we need to do is to find the -minimum of those three cells and then add `1` in case if we have different -letters in `i`'s row and `j`'s column. - -You may clearly see the recursive nature of the problem. - -![Levenshtein Matrix](https://cdn-images-1.medium.com/max/1600/1*w8UB4DSvBnAK6mBXRGQDjw.png) - -Let's draw a decision graph for this problem. - -![Minimum Edit Distance Decision Graph](https://cdn-images-1.medium.com/max/1600/1*8jD0qvr5B9PwRFM_9z7q9A.png) - -You may see a number of overlapping sub-problems on the picture that are marked -with red. Also there is no way to reduce the number of operations and make it -less than a minimum of those three adjacent cells from the formula. - -Also you may notice that each cell number in the matrix is being calculated -based on previous ones. Thus the tabulation technique (filling the cache in -bottom-up direction) is being applied here. - -Applying this principle further we may solve more complicated cases like -with `Saturday → Sunday` transformation. - -![Levenshtein distance](https://cdn-images-1.medium.com/max/2600/1*497gMaFErzJpCXG7kS_7dw.png) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Levenshtein_distance) -- [YouTube](https://www.youtube.com/watch?v=We3YDTzNXEk&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [ITNext](https://itnext.io/dynamic-programming-vs-divide-and-conquer-2fea680becbe) diff --git a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/levenshteinDistance.js b/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/levenshteinDistance.js deleted file mode 100644 index fcc00c50fb..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/levenshteinDistance.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @param {string} a - * @param {string} b - * @return {number} - */ -export default function levenshteinDistance(a, b) { - // Create empty edit distance matrix for all possible modifications of - // substrings of a to substrings of b. - const distanceMatrix = Array(b.length + 1) - .fill(null) - .map(() => Array(a.length + 1).fill(null)); - // Fill the first row of the matrix. - // If this is first row then we're transforming empty string to a. - // In this case the number of transformations equals to size of a substring. - for (let i = 0; i <= a.length; i += 1) { - distanceMatrix[0][i] = i; - } - // Fill the first column of the matrix. - // If this is first column then we're transforming empty string to b. - // In this case the number of transformations equals to size of b substring. - for (let j = 0; j <= b.length; j += 1) { - distanceMatrix[j][0] = j; - } - for (let j = 1; j <= b.length; j += 1) { - for (let i = 1; i <= a.length; i += 1) { - const indicator = a[i - 1] === b[j - 1] ? 0 : 1; - distanceMatrix[j][i] = Math.min( - distanceMatrix[j][i - 1] + 1, // deletion - distanceMatrix[j - 1][i] + 1, // insertion - distanceMatrix[j - 1][i - 1] + indicator // substitution - ); - } - } - return distanceMatrix[b.length][a.length]; -} diff --git a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/test/levenshteinDistance.test.js b/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/test/levenshteinDistance.test.js deleted file mode 100644 index 3fccb08490..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/levenshtein-distance/test/levenshteinDistance.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import levenshteinDistance from '../levenshteinDistance'; -describe('levenshteinDistance', () => { - it('should calculate edit distance between two strings', () => { - expect(levenshteinDistance('', '')).toBe(0); - expect(levenshteinDistance('a', '')).toBe(1); - expect(levenshteinDistance('', 'a')).toBe(1); - expect(levenshteinDistance('abc', '')).toBe(3); - expect(levenshteinDistance('', 'abc')).toBe(3); - // Should just add I to the beginning. - expect(levenshteinDistance('islander', 'slander')).toBe(1); - // Needs to substitute M by K, T by M and add an A to the end - expect(levenshteinDistance('mart', 'karma')).toBe(3); - // Substitute K by S, E by I and insert G at the end. - expect(levenshteinDistance('kitten', 'sitting')).toBe(3); - // Should add 4 letters FOOT at the beginning. - expect(levenshteinDistance('ball', 'football')).toBe(4); - // Should delete 4 letters FOOT at the beginning. - expect(levenshteinDistance('football', 'foot')).toBe(4); - // Needs to substitute the first 5 chars: INTEN by EXECU - expect(levenshteinDistance('intention', 'execution')).toBe(5); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/README.md b/docs/content/DS_ALGO/algorithms/string/longest-common-substring/README.md deleted file mode 100644 index abcd8de939..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Longest Common Substring Problem - -The longest common substring problem is to find the longest string -(or strings) that is a substring (or are substrings) of two or more -strings. - -## Example - -The longest common substring of the strings `ABABC`, `BABCA` and -`ABCBA` is string `ABC` of length 3. Other common substrings are -`A`, `AB`, `B`, `BA`, `BC` and `C`. - -``` -ABABC - ||| - BABCA - ||| - ABCBA -``` - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Longest_common_substring_problem) -- [YouTube](https://www.youtube.com/watch?v=BysNXJHzCEs&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/longestCommonSubstring.js b/docs/content/DS_ALGO/algorithms/string/longest-common-substring/longestCommonSubstring.js deleted file mode 100644 index 2a5539d111..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/longestCommonSubstring.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @param {string} string1 - * @param {string} string2 - * @return {string} - */ -export default function longestCommonSubstring(string1, string2) { - // Convert strings to arrays to treat unicode symbols length correctly. - // For example: - // '𐌵'.length === 2 - // [...'𐌵'].length === 1 - const s1 = [...string1]; - const s2 = [...string2]; - // Init the matrix of all substring lengths to use Dynamic Programming approach. - const substringMatrix = Array(s2.length + 1) - .fill(null) - .map(() => { - return Array(s1.length + 1).fill(null); - }); - // Fill the first row and first column with zeros to provide initial values. - for (let columnIndex = 0; columnIndex <= s1.length; columnIndex += 1) { - substringMatrix[0][columnIndex] = 0; - } - for (let rowIndex = 0; rowIndex <= s2.length; rowIndex += 1) { - substringMatrix[rowIndex][0] = 0; - } - // Build the matrix of all substring lengths to use Dynamic Programming approach. - let longestSubstringLength = 0; - let longestSubstringColumn = 0; - let longestSubstringRow = 0; - for (let rowIndex = 1; rowIndex <= s2.length; rowIndex += 1) { - for (let columnIndex = 1; columnIndex <= s1.length; columnIndex += 1) { - if (s1[columnIndex - 1] === s2[rowIndex - 1]) { - substringMatrix[rowIndex][columnIndex] = substringMatrix[rowIndex - 1][columnIndex - 1] + 1; - } else {} - substringMatrix[rowIndex][columnIndex] = 0; - } - // Try to find the biggest length of all common substring lengths - // and to memorize its last character position (indices) - if (substringMatrix[rowIndex][columnIndex] > longestSubstringLength) { - longestSubstringLength = substringMatrix[rowIndex][columnIndex]; - longestSubstringColumn = columnIndex; - longestSubstringRow = rowIndex; - } - } -} -if (longestSubstringLength === 0) { - // Longest common substring has not been found. - return ''; -} -// Detect the longest substring from the matrix. -let longestSubstring = ''; -while (substringMatrix[longestSubstringRow][longestSubstringColumn] > 0) { - longestSubstring = s1[longestSubstringColumn - 1] + longestSubstring; - longestSubstringRow -= 1; - longestSubstringColumn -= 1; -} -return longestSubstring; -} -} diff --git a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/test/longestCommonSubstring.test.js b/docs/content/DS_ALGO/algorithms/string/longest-common-substring/test/longestCommonSubstring.test.js deleted file mode 100644 index 0dca6a7d4d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/longest-common-substring/test/longestCommonSubstring.test.js +++ /dev/null @@ -1,22 +0,0 @@ -import longestCommonSubstring from '../longestCommonSubstring'; -describe('longestCommonSubstring', () => { - it('should find longest common substring between two strings', () => { - expect(longestCommonSubstring('', '')).toBe(''); - expect(longestCommonSubstring('ABC', '')).toBe(''); - expect(longestCommonSubstring('', 'ABC')).toBe(''); - expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC'); - expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC'); - expect( - longestCommonSubstring( - 'Algorithms and data structures implemented in JavaScript', - 'Here you may find Algorithms and data structures that are implemented in JavaScript' - ) - ).toBe('Algorithms and data structures '); - }); - it('should handle unicode correctly', () => { - expect(longestCommonSubstring('𐌵𐌵**ABC', '𐌵𐌵--ABC')).toBe('ABC'); - expect(longestCommonSubstring('𐌵𐌵**A', '𐌵𐌵--A')).toBe('𐌵𐌵'); - expect(longestCommonSubstring('A买B时', '买B时GD')).toBe('买B时'); - expect(longestCommonSubstring('After test买时 case', 'another_test买时')).toBe('test买时'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/palindrome/README.md b/docs/content/DS_ALGO/algorithms/string/palindrome/README.md deleted file mode 100644 index b4a7b9d5bf..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/palindrome/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Palindrome Check - -A [Palindrome](https://en.wikipedia.org/wiki/Palindrome) is a string that reads the same forwards and backwards. -This means that the second half of the string is the reverse of the -first half. - -## Examples - -The following are palindromes (thus would return `TRUE`): - -``` -- "a" -- "pop" -> p + o + p -- "deed" -> de + ed -- "kayak" -> ka + y + ak -- "racecar" -> rac + e + car -``` - -The following are NOT palindromes (thus would return `FALSE`): - -``` -- "rad" -- "dodo" -- "polo" -``` - -## References - -- [GeeksForGeeks - Check if a number is Palindrome](https://www.geeksforgeeks.org/check-if-a-number-is-palindrome/) diff --git a/docs/content/DS_ALGO/algorithms/string/palindrome/isPalindrome.js b/docs/content/DS_ALGO/algorithms/string/palindrome/isPalindrome.js deleted file mode 100644 index e824642b84..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/palindrome/isPalindrome.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @param {string} string - * @return {boolean} - */ -export default function isPalindrome(string) { - let left = 0; - let right = string.length - 1; - while (left < right) { - if (string[left] !== string[right]) { - return false; - } - left += 1; - right -= 1; - } - return true; -} diff --git a/docs/content/DS_ALGO/algorithms/string/palindrome/test/isPalindrome.test.js b/docs/content/DS_ALGO/algorithms/string/palindrome/test/isPalindrome.test.js deleted file mode 100644 index 5f2cf8efb1..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/palindrome/test/isPalindrome.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import isPalindrome from '../isPalindrome'; -describe('palindromeCheck', () => { - it('should return whether or not the string is a palindrome', () => { - expect(isPalindrome('a')).toBe(true); - expect(isPalindrome('pop')).toBe(true); - expect(isPalindrome('deed')).toBe(true); - expect(isPalindrome('kayak')).toBe(true); - expect(isPalindrome('racecar')).toBe(true); - expect(isPalindrome('rad')).toBe(false); - expect(isPalindrome('dodo')).toBe(false); - expect(isPalindrome('polo')).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/rabin-karp/README.md b/docs/content/DS_ALGO/algorithms/string/rabin-karp/README.md deleted file mode 100644 index 35476f77b2..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/rabin-karp/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Rabin Karp Algorithm - -In computer science, the Rabin-Karp algorithm or Karp-Rabin algorithm -is a string searching algorithm created by Richard M. Karp and -Michael O. Rabin (1987) that uses hashing to find any one of a set -of pattern strings in a text. - -## Algorithm - -The Rabin-Karp algorithm seeks to speed up the testing of equality of -the pattern to the substrings in the text by using a hash function. A -hash function is a function which converts every string into a numeric -value, called its hash value; for example, we might -have `hash('hello') = 5`. The algorithm exploits the fact -that if two strings are equal, their hash values are also equal. Thus, -string matching is reduced (almost) to computing the hash value of the -search pattern and then looking for substrings of the input string with -that hash value. - -However, there are two problems with this approach. First, because there -are so many different strings and so few hash values, some differing -strings will have the same hash value. If the hash values match, the -pattern and the substring may not match; consequently, the potential -match of search pattern and the substring must be confirmed by comparing -them; that comparison can take a long time for long substrings. -Luckily, a good hash function on reasonable strings usually does not -have many collisions, so the expected search time will be acceptable. - -## Hash Function Used - -The key to the Rabin-Karp algorithm's performance is the efficient computation -of hash values of the successive substrings of the text. -The **Rabin fingerprint** is a popular and effective rolling hash function. - -The **polynomial hash function** described in this example is not a Rabin -fingerprint, but it works equally well. It treats every substring as a -number in some base, the base being usually a large prime. - -## Complexity - -For text of length `n` and `p` patterns of combined length `m`, its average -and best case running time is `O(n + m)` in space `O(p)`, but its -worst-case time is `O(n * m)`. - -## Application - -A practical application of the algorithm is detecting plagiarism. -Given source material, the algorithm can rapidly search through a paper -for instances of sentences from the source material, ignoring details -such as case and punctuation. Because of the abundance of the sought -strings, single-string searching algorithms are impractical. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm) -- [YouTube](https://www.youtube.com/watch?v=H4VrKHVG5qI&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/algorithms/string/rabin-karp/rabinKarp.js b/docs/content/DS_ALGO/algorithms/string/rabin-karp/rabinKarp.js deleted file mode 100644 index 3ce1935120..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/rabin-karp/rabinKarp.js +++ /dev/null @@ -1,31 +0,0 @@ -import PolynomialHash from '../../cryptography/polynomial-hash/PolynomialHash'; -/** - * @param {string} text - Text that may contain the searchable word. - * @param {string} word - Word that is being searched in text. - * @return {number} - Position of the word in text. - */ -export default function rabinKarp(text, word) { - const hasher = new PolynomialHash(); - // Calculate word hash that we will use for comparison with other substring hashes. - const wordHash = hasher.hash(word); - let prevFrame = null; - let currentFrameHash = null; - // Go through all substring of the text that may match. - for (let charIndex = 0; charIndex <= text.length - word.length; charIndex += 1) { - const currentFrame = text.substring(charIndex, charIndex + word.length); - // Calculate the hash of current substring. - if (currentFrameHash === null) { - currentFrameHash = hasher.hash(currentFrame); - } else { - currentFrameHash = hasher.roll(currentFrameHash, prevFrame, currentFrame); - } - prevFrame = currentFrame; - // Compare the hash of current substring and seeking string. - // In case if hashes match let's make sure that substrings are equal. - // In case of hash collision the strings may not be equal. - if (wordHash === currentFrameHash && text.substr(charIndex, word.length) === word) { - return charIndex; - } - } - return -1; -} diff --git a/docs/content/DS_ALGO/algorithms/string/rabin-karp/test/rabinKarp.test.js b/docs/content/DS_ALGO/algorithms/string/rabin-karp/test/rabinKarp.test.js deleted file mode 100644 index a30454a766..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/rabin-karp/test/rabinKarp.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import rabinKarp from '../rabinKarp'; -describe('rabinKarp', () => { - it('should find substring in a string', () => { - expect(rabinKarp('', '')).toBe(0); - expect(rabinKarp('a', '')).toBe(0); - expect(rabinKarp('a', 'a')).toBe(0); - expect(rabinKarp('ab', 'b')).toBe(1); - expect(rabinKarp('abcbcglx', 'abca')).toBe(-1); - expect(rabinKarp('abcbcglx', 'bcgl')).toBe(3); - expect(rabinKarp('abcxabcdabxabcdabcdabcy', 'abcdabcy')).toBe(15); - expect(rabinKarp('abcxabcdabxabcdabcdabcy', 'abcdabca')).toBe(-1); - expect(rabinKarp('abcxabcdabxaabcdabcabcdabcdabcy', 'abcdabca')).toBe(12); - expect(rabinKarp('abcxabcdabxaabaabaaaabcdabcdabcy', 'aabaabaaa')).toBe(11); - expect(rabinKarp("^ !/'#'pp", " !/'#'pp")).toBe(1); - }); - it('should work with bigger texts', () => { - const text = - 'Lorem Ipsum is simply dummy text of the printing and ' + - "typesetting industry. Lorem Ipsum has been the industry's standard " + - 'dummy text ever since the 1500s, when an unknown printer took a ' + - 'galley of type and scrambled it to make a type specimen book. It ' + - 'has survived not only five centuries, but also the leap into ' + - 'electronic typesetting, remaining essentially unchanged. It was ' + - 'popularised in the 1960s with the release of Letraset sheets ' + - 'containing Lorem Ipsum passages, and more recently with desktop' + - 'publishing software like Aldus PageMaker including versions of Lorem ' + - 'Ipsum.'; - expect(rabinKarp(text, 'Lorem')).toBe(0); - expect(rabinKarp(text, 'versions')).toBe(549); - expect(rabinKarp(text, 'versions of Lorem Ipsum.')).toBe(549); - expect(rabinKarp(text, 'versions of Lorem Ipsum:')).toBe(-1); - expect(rabinKarp(text, 'Lorem Ipsum passages, and more recently with')).toBe(446); - }); - it('should work with UTF symbols', () => { - expect(rabinKarp('a\u{ffff}', '\u{ffff}')).toBe(1); - expect(rabinKarp('\u0000耀\u0000', '耀\u0000')).toBe(1); - // @TODO: Provide Unicode support. - // expect(rabinKarp('a\u{20000}', '\u{20000}')).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/README.md b/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/README.md deleted file mode 100644 index 104a3a1243..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# Regular Expression Matching - -Given an input string `s` and a pattern `p`, implement regular -expression matching with support for `.` and `*`. - -- `.` Matches any single character. -- `*` Matches zero or more of the preceding element. - -The matching should cover the **entire** input string (not partial). - -**Note** - -- `s` could be empty and contains only lowercase letters `a-z`. -- `p` could be empty and contains only lowercase letters `a-z`, and characters like `.` or `*`. - -## Examples - -**Example #1** - -Input: - -``` -s = 'aa' -p = 'a' -``` - -Output: `false` - -Explanation: `a` does not match the entire string `aa`. - -**Example #2** - -Input: - -``` -s = 'aa' -p = 'a*' -``` - -Output: `true` - -Explanation: `*` means zero or more of the preceding element, `a`. -Therefore, by repeating `a` once, it becomes `aa`. - -**Example #3** - -Input: - -``` -s = 'ab' -p = '.*' -``` - -Output: `true` - -Explanation: `.*` means "zero or more (`*`) of any character (`.`)". - -**Example #4** - -Input: - -``` -s = 'aab' -p = 'c*a*b' -``` - -Output: `true` - -Explanation: `c` can be repeated 0 times, `a` can be repeated -1 time. Therefore it matches `aab`. - -## References - -- [YouTube](https://www.youtube.com/watch?v=l3hda49XcDE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=71&t=0s) -- [LeetCode](https://leetcode.com/problems/regular-expression-matching/description/) diff --git a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/regularExpressionMatching.js b/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/regularExpressionMatching.js deleted file mode 100644 index 98c114536b..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/regularExpressionMatching.js +++ /dev/null @@ -1,123 +0,0 @@ -const ZERO_OR_MORE_CHARS = '*'; -const ANY_CHAR = '.'; -/** - * Dynamic programming approach. - * - * @param {string} string - * @param {string} pattern - * @return {boolean} - */ -export default function regularExpressionMatching(string, pattern) { - /* - * Let's initiate dynamic programming matrix for this string and pattern. - * We will have pattern characters on top (as columns) and string characters - * will be placed to the left of the table (as rows). - * - * Example: - * - * a * b . b - * - - - - - - - * a - - - - - - - * a - - - - - - - * b - - - - - - - * y - - - - - - - * b - - - - - - - */ - const matchMatrix = Array(string.length + 1) - .fill(null) - .map(() => { - return Array(pattern.length + 1).fill(null); - }); - // Let's fill the top-left cell with true. This would mean that empty - // string '' matches to empty pattern ''. - matchMatrix[0][0] = true; - // Let's fill the first row of the matrix with false. That would mean that - // empty string can't match any non-empty pattern. - // - // Example: - // string: '' - // pattern: 'a.z' - // - // The one exception here is patterns like a*b* that matches the empty string. - for (let columnIndex = 1; columnIndex <= pattern.length; columnIndex += 1) { - const patternIndex = columnIndex - 1; - if (pattern[patternIndex] === ZERO_OR_MORE_CHARS) { - matchMatrix[0][columnIndex] = matchMatrix[0][columnIndex - 2]; - } else { - matchMatrix[0][columnIndex] = false; - } - } - // Let's fill the first column with false. That would mean that empty pattern - // can't match any non-empty string. - // - // Example: - // string: 'ab' - // pattern: '' - for (let rowIndex = 1; rowIndex <= string.length; rowIndex += 1) { - matchMatrix[rowIndex][0] = false; - } - // Not let's go through every letter of the pattern and every letter of - // the string and compare them one by one. - for (let rowIndex = 1; rowIndex <= string.length; rowIndex += 1) { - for (let columnIndex = 1; columnIndex <= pattern.length; columnIndex += 1) { - // Take into account that fact that matrix contain one extra column and row. - const stringIndex = rowIndex - 1; - const patternIndex = columnIndex - 1; - if (pattern[patternIndex] === ZERO_OR_MORE_CHARS) { - /* - * In case if current pattern character is special '*' character we have - * two options: - * - * 1. Since * char allows it previous char to not be presented in a string we - * need to check if string matches the pattern without '*' char and without the - * char that goes before '*'. That would mean to go two positions left on the - * same row. - * - * 2. Since * char allows it previous char to be presented in a string many times we - * need to check if char before * is the same as current string char. If they are the - * same that would mean that current string matches the current pattern in case if - * the string WITHOUT current char matches the same pattern. This would mean to go - * one position up in the same row. - */ - if (matchMatrix[rowIndex][columnIndex - 2] === true) { - matchMatrix[rowIndex][columnIndex] = true; - } else if ( - (pattern[patternIndex - 1] === string[stringIndex] || pattern[patternIndex - 1] === ANY_CHAR) && - matchMatrix[rowIndex - 1][columnIndex] === true - ) { - matchMatrix[rowIndex][columnIndex] = true; - } else { - matchMatrix[rowIndex][columnIndex] = false; - } - } else if (pattern[patternIndex] === string[stringIndex] || pattern[patternIndex] === ANY_CHAR) { - /* - * In case if current pattern char is the same as current string char - * or it may be any character (in case if pattern contains '.' char) - * we need to check if there was a match for the pattern and for the - * string by WITHOUT current char. This would mean that we may copy - * left-top diagonal value. - * - * Example: - * - * a b - * a 1 - - * b - 1 - */ - matchMatrix[rowIndex][columnIndex] = matchMatrix[rowIndex - 1][columnIndex - 1]; - } else { - /* - * In case if pattern char and string char are different we may - * treat this case as "no-match". - * - * Example: - * - * a b - * a - - - * c - 0 - */ - matchMatrix[rowIndex][columnIndex] = false; - } - } - } - return matchMatrix[string.length][pattern.length]; -} diff --git a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/test/regularExpressionMatching.test.js b/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/test/regularExpressionMatching.test.js deleted file mode 100644 index 86c7a47091..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/regular-expression-matching/test/regularExpressionMatching.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import regularExpressionMatching from '../regularExpressionMatching'; -describe('regularExpressionMatching', () => { - it('should match regular expressions in a string', () => { - expect(regularExpressionMatching('', '')).toBe(true); - expect(regularExpressionMatching('a', 'a')).toBe(true); - expect(regularExpressionMatching('aa', 'aa')).toBe(true); - expect(regularExpressionMatching('aab', 'aab')).toBe(true); - expect(regularExpressionMatching('aab', 'aa.')).toBe(true); - expect(regularExpressionMatching('aab', '.a.')).toBe(true); - expect(regularExpressionMatching('aab', '...')).toBe(true); - expect(regularExpressionMatching('a', 'a*')).toBe(true); - expect(regularExpressionMatching('aaa', 'a*')).toBe(true); - expect(regularExpressionMatching('aaab', 'a*b')).toBe(true); - expect(regularExpressionMatching('aaabb', 'a*b*')).toBe(true); - expect(regularExpressionMatching('aaabb', 'a*b*c*')).toBe(true); - expect(regularExpressionMatching('', 'a*')).toBe(true); - expect(regularExpressionMatching('xaabyc', 'xa*b.c')).toBe(true); - expect(regularExpressionMatching('aab', 'c*a*b*')).toBe(true); - expect(regularExpressionMatching('mississippi', 'mis*is*.p*.')).toBe(true); - expect(regularExpressionMatching('ab', '.*')).toBe(true); - expect(regularExpressionMatching('', 'a')).toBe(false); - expect(regularExpressionMatching('a', '')).toBe(false); - expect(regularExpressionMatching('aab', 'aa')).toBe(false); - expect(regularExpressionMatching('aab', 'baa')).toBe(false); - expect(regularExpressionMatching('aabc', '...')).toBe(false); - expect(regularExpressionMatching('aaabbdd', 'a*b*c*')).toBe(false); - expect(regularExpressionMatching('mississippi', 'mis*is*p*.')).toBe(false); - expect(regularExpressionMatching('ab', 'a*')).toBe(false); - expect(regularExpressionMatching('abba', 'a*b*.c')).toBe(false); - expect(regularExpressionMatching('abba', '.*c')).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/AlphaNumericPalindrome.test.js b/docs/content/DS_ALGO/algorithms/string/test/AlphaNumericPalindrome.test.js deleted file mode 100644 index a4d0448175..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/AlphaNumericPalindrome.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { alphaNumericPlaindrome } from '../AlphaNumericPalindrome'; -test('should return true if the given string has alphanumeric characters that are palindrom irrespective of case and symbols', () => { - expect(alphaNumericPlaindrome('eye')).toBe(true); -}); -test('should return true if the given string has alphanumeric characters that are palindrom irrespective of case and symbols', () => { - expect(alphaNumericPlaindrome('0_0 (: /-:) 0-0')).toBe(true); -}); -test('should return true if the given string has alphanumeric characters that are palindrom irrespective of case and symbols', () => { - expect(alphaNumericPlaindrome('five|_/|four')).toBe(false); -}); -test('should return true if the given string has alphanumeric characters that are palindrom irrespective of case and symbols', () => { - expect(alphaNumericPlaindrome('A man, a plan, a canal. Panama')).toBe(true); -}); -test('should return true if the given string has alphanumeric characters that are palindrom irrespective of case and symbols', () => { - expect(alphaNumericPlaindrome('1 eye for of 1 eye.')).toBe(false); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckAnagram.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckAnagram.test.js deleted file mode 100644 index b7aa9e7e23..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckAnagram.test.js +++ /dev/null @@ -1,143 +0,0 @@ -import { checkAnagramMap, checkAnagramRegex } from '../CheckAnagram'; -describe('Testing checkAnagramRegex', () => { - it.each` - inputOne | inputTwo - ${123456} | ${'abcd'} - ${[1, 2, 3, 4, 5, 6]} | ${'abcd'} - ${{ test: 'test' }} | ${'abcd'} - ${'abcd'} | ${123456} - ${'abcd'} | ${[1, 2, 3, 4, 5, 6]} - ${'abcd'} | ${{ test: 'test' }} - `('expects to throw the type Error given values $inputOne and $inputTwo', ({ inputOne, inputTwo }) => { - expect(() => checkAnagramRegex(inputOne, inputTwo)).toThrowError(); - }); - it('expects to return false if the arguments have different lengths', () => { - const SUT = checkAnagramRegex('abs', 'abds'); - expect(SUT).toBe(false); - }); - it('expects to return false if the arguments are not anagrams', () => { - const SUT = checkAnagramRegex('abcs', 'abds'); - expect(SUT).toBe(false); - }); - it('expects to return true if the arguments are anagrams', () => { - const SUT = checkAnagramRegex('abcd', 'bcad'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments of length 1 and are the same letter', () => { - const SUT = checkAnagramRegex('a', 'a'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments of are both empty strings', () => { - const SUT = checkAnagramRegex('', ''); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams with an odd length', () => { - const SUT = checkAnagramRegex('abcde', 'edcab'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams with an even length', () => { - const SUT = checkAnagramRegex('abcdef', 'fedcab'); - expect(SUT).toBe(true); - }); - it('expects to return false if either argument is an empty string while the other is not', () => { - const SUT = checkAnagramRegex('', 'edcab'); - expect(SUT).toBe(false); - const SUT2 = checkAnagramRegex('edcab', ''); - expect(SUT2).toBe(false); - }); - it('expects to return true if the arguments contain the same letters but have unequal case', () => { - const SUT = checkAnagramRegex('ABDCE', 'abcde'); - expect(SUT).toBe(true); - const SUT2 = checkAnagramRegex('AbCdE', 'aBCdE'); - expect(SUT2).toBe(true); - const SUT3 = checkAnagramRegex('Eleven plus two', 'Twelve plus one'); - expect(SUT3).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain number characters', () => { - const SUT = checkAnagramRegex('a1b2', '12ba'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain space characters', () => { - const SUT = checkAnagramRegex('a1 b2', '1 2ba'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain punctuation characters', () => { - const SUT = checkAnagramRegex('a!1b@2', '1@2ba!'); - expect(SUT).toBe(true); - }); - it('expects to return false if the arguments contain the same letters but contain a different amount of space characters', () => { - const SUT = checkAnagramRegex('ea cb', 'e cba'); - expect(SUT).toBe(false); - }); -}); -describe('Testing checkAnagramMap', () => { - it.each` - inputOne | inputTwo - ${123456} | ${'abcd'} - ${[1, 2, 3, 4, 5, 6]} | ${'abcd'} - ${{ test: 'test' }} | ${'abcd'} - ${'abcd'} | ${123456} - ${'abcd'} | ${[1, 2, 3, 4, 5, 6]} - ${'abcd'} | ${{ test: 'test' }} - `('expects to throw the type Error given values $inputOne and $inputTwo', ({ inputOne, inputTwo }) => { - expect(() => checkAnagramMap(inputOne, inputTwo)).toThrowError(); - }); - it('expects to return false if the arguments have different lengths', () => { - const SUT = checkAnagramMap('abs', 'abds'); - expect(SUT).toBe(false); - }); - it('expects to return false if the arguments are not anagrams', () => { - const SUT = checkAnagramMap('abcs', 'abds'); - expect(SUT).toBe(false); - }); - it('expects to return true if the arguments are anagrams', () => { - const SUT = checkAnagramMap('abcd', 'bcad'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments of length 1 and are the same letter', () => { - const SUT = checkAnagramMap('a', 'a'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments of are both empty strings', () => { - const SUT = checkAnagramMap('', ''); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams with an odd length', () => { - const SUT = checkAnagramMap('abcde', 'edcab'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams with an even length', () => { - const SUT = checkAnagramMap('abcdef', 'fedcab'); - expect(SUT).toBe(true); - }); - it('expects to return false if either argument is an empty string while the other is not', () => { - const SUT = checkAnagramMap('', 'edcab'); - expect(SUT).toBe(false); - const SUT2 = checkAnagramMap('edcab', ''); - expect(SUT2).toBe(false); - }); - it('expects to return true if the arguments contain the same letters but have unequal case', () => { - const SUT = checkAnagramMap('ABDCE', 'abcde'); - expect(SUT).toBe(true); - const SUT2 = checkAnagramMap('AbCdE', 'aBCdE'); - expect(SUT2).toBe(true); - const SUT3 = checkAnagramMap('Eleven plus two', 'Twelve plus one'); - expect(SUT3).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain number characters', () => { - const SUT = checkAnagramMap('a1b2', '12ba'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain space characters', () => { - const SUT = checkAnagramMap('a1 b2', '1 2ba'); - expect(SUT).toBe(true); - }); - it('expects to return true if the arguments are anagrams and contain punctuation characters', () => { - const SUT = checkAnagramMap('a!1b@2', '1@2ba!'); - expect(SUT).toBe(true); - }); - it('expects to return false if the arguments contain the same letters but contain a different amount of space characters', () => { - const SUT = checkAnagramMap('ea cb', 'e cba'); - expect(SUT).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckCamelCase.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckCamelCase.test.js deleted file mode 100644 index 27d2a35eca..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckCamelCase.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { checkCamelCase } from '../CheckCamelCase'; -describe('checkCamelCase', () => { - it('expect to throw an error if input is not a string', () => { - expect(() => checkCamelCase(null)).toThrow(); - }); - it('expects to return true if the input is in camel case format', () => { - const value = 'dockerBuild'; - const result = checkCamelCase(value); - expect(result).toBe(true); - }); - it('expects to return false if the input is not in camel case format', () => { - const value = 'docker_build'; - const result = checkCamelCase(value); - expect(result).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckFlatCase.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckFlatCase.test.js deleted file mode 100644 index c18596cdc1..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckFlatCase.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { checkFlatCase } from '../CheckFlatCase'; -describe('checkFlatCase function', () => { - it('should return false when the input string is not in flatcase', () => { - const actual = checkFlatCase('this is not in flatcase'); - expect(actual).toBe(false); - }); - it('should return true when the input string is a single letter character', () => { - const actual = checkFlatCase('a'); - expect(actual).toBe(true); - }); - it('should return true when the input string is a string of lowercase letter characters with no spaces', () => { - const actual = checkFlatCase('abcdefghijklmnopqrstuvwxyz'); - expect(actual).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckPalindrome.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckPalindrome.test.js deleted file mode 100644 index f7d083dce2..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckPalindrome.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { checkPalindrome } from '../CheckPalindrome'; -describe('checkPalindrome', () => { - it('expects to return "Palindrome" if the given string is a palindrome', () => { - const SUT = checkPalindrome('madam'); - expect(SUT).toBe('Palindrome'); - }); - it('expects to return "Empty string" if the given string is empty', () => { - const SUT = checkPalindrome(''); - expect(SUT).toBe('Empty string'); - }); - it('expects to return "Not a string" if the given string is not a string', () => { - const SUT = checkPalindrome(123); - expect(SUT).toBe('Not a string'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckPangram.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckPangram.test.js deleted file mode 100644 index c0ae8c2498..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckPangram.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import { checkPangramRegex, checkPangramSet } from '../CheckPangram'; -describe('Testing checkPangramRegex function', () => { - it('"The quick brown fox jumps over the lazy dog" is a pangram', () => { - expect(checkPangramRegex('The quick brown fox jumps over the lazy dog')).toBe(true); - }); - it('"Waltz, bad nymph, for quick jigs vex." is a pangram', () => { - expect(checkPangramRegex('Waltz, bad nymph, for quick jigs vex.')).toBe(true); - }); - it('"Jived fox nymph grabs quick waltz." is a pangram', () => { - expect(checkPangramRegex('Jived fox nymph grabs quick waltz.')).toBe(true); - }); - it('"My name is Unknown" is NOT a pangram', () => { - expect(checkPangramRegex('My name is Unknown')).toBe(false); - }); - it('"The quick brown fox jumps over the la_y dog" is NOT a pangram', () => { - expect(checkPangramRegex('The quick brown fox jumps over the la_y dog')).toBe(false); - }); - it('Throws an error if given param is not a string', () => { - expect(() => { - checkPangramRegex(undefined); - }).toThrow('The given value is not a string'); - }); -}); -describe('Testing checkPangramSet function', () => { - it('"The quick brown fox jumps over the lazy dog" is a pangram', () => { - expect(checkPangramSet('The quick brown fox jumps over the lazy dog')).toBe(true); - }); - it('"Waltz, bad nymph, for quick jigs vex." is a pangram', () => { - expect(checkPangramSet('Waltz, bad nymph, for quick jigs vex.')).toBe(true); - }); - it('"Jived fox nymph grabs quick waltz." is a pangram', () => { - expect(checkPangramSet('Jived fox nymph grabs quick waltz.')).toBe(true); - }); - it('"My name is Unknown" is NOT a pangram', () => { - expect(checkPangramSet('My name is Unknown')).toBe(false); - }); - it('"The quick brown fox jumps over the la_y dog" is NOT a pangram', () => { - expect(checkPangramSet('The quick brown fox jumps over the la_y dog')).toBe(false); - }); - it('Throws an error if given param is not a string', () => { - expect(() => { - checkPangramSet(undefined); - }).toThrow('The given value is not a string'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckSnakeCase.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckSnakeCase.test.js deleted file mode 100644 index 1daeb28fab..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckSnakeCase.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { checkSnakeCase } from '../CheckSnakeCase'; -describe('checkSnakeCase', () => { - it('expect to throw an error if input is not a string', () => { - expect(() => checkSnakeCase(0)).toThrow(); - }); - it('expects to return true if the input is in snake case format', () => { - const value = 'docker_build'; - const result = checkSnakeCase(value); - expect(result).toBe(true); - }); - it('expects to return false if the input is not in snake case format', () => { - const value = 'dockerBuild'; - const result = checkSnakeCase(value); - expect(result).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CheckWordOcurrence.test.js b/docs/content/DS_ALGO/algorithms/string/test/CheckWordOcurrence.test.js deleted file mode 100644 index 62395d94c6..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CheckWordOcurrence.test.js +++ /dev/null @@ -1,21 +0,0 @@ -import { checkWordOccurrence } from '../CheckWordOccurrence'; -describe('Testing checkWordOccurrence', () => { - it('expects throw on insert wrong string', () => { - const value = 123; - expect(() => checkWordOccurrence(value)).toThrow(); - }); - it('expect throw on insert wrong param for case sensitive', () => { - const value = 'hello'; - expect(() => checkWordOccurrence(value, value)).toThrow(); - }); - it('check occurrence with case sensitive', () => { - const stringToTest = 'The quick brown fox jumps over the lazy dog'; - const expectResult = { The: 1, quick: 1, brown: 1, fox: 1, jumps: 1, over: 1, the: 1, lazy: 1, dog: 1 }; - expect(checkWordOccurrence(stringToTest)).toEqual(expectResult); - }); - it('check occurrence with case insensitive', () => { - const stringToTest = 'The quick brown fox jumps over the lazy dog'; - const expectResult = { the: 2, quick: 1, brown: 1, fox: 1, jumps: 1, over: 1, lazy: 1, dog: 1 }; - expect(checkWordOccurrence(stringToTest, true)).toEqual(expectResult); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CountVowels.test.js b/docs/content/DS_ALGO/algorithms/string/test/CountVowels.test.js deleted file mode 100644 index 4701683a4a..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CountVowels.test.js +++ /dev/null @@ -1,56 +0,0 @@ -import { countVowels } from '../CountVowels'; -describe('CountVowels', () => { - it('expect throws on use wrong param', () => { - expect(() => countVowels(0)).toThrow(); - }); - it('count the vowels in a string', () => { - const value = 'Mad World'; - const count = countVowels(value); - expect(count).toBe(2); - }); - it('should return 0 when input is a string with no vowels', () => { - const value = 'bcdfgh'; - const count = countVowels(value); - expect(count).toBe(0); - }); - it('should return 1 when input is a string of length 1 that is a vowel', () => { - const value = 'a'; - const count = countVowels(value); - expect(count).toBe(1); - }); - it('should return the correct result when input is in all uppercase letters', () => { - const value = 'ABCDE'; - const count = countVowels(value); - expect(count).toBe(2); - }); - it('should return the correct result when input is in all lowercase letters', () => { - const value = 'abcdefghi'; - const count = countVowels(value); - expect(count).toBe(3); - }); - it('should return the correct result when input string contains spaces', () => { - const value = 'abc def ghi'; - const count = countVowels(value); - expect(count).toBe(3); - }); - it('should return the correct result when input contains number characters', () => { - const value = 'a1b2c3'; - const count = countVowels(value); - expect(count).toBe(1); - }); - it('should return the correct result when input contains punctuation characters', () => { - const value = 'a!b.ce)'; - const count = countVowels(value); - expect(count).toBe(2); - }); - it('should return 0 when the input is an empty string', () => { - const value = ''; - const count = countVowels(value); - expect(count).toBe(0); - }); - it('should count multiple occurrences of the same vowel in the input', () => { - const value = 'aaaaa'; - const count = countVowels(value); - expect(count).toBe(5); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/CreatePermutations.test.js b/docs/content/DS_ALGO/algorithms/string/test/CreatePermutations.test.js deleted file mode 100644 index df9e90262f..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/CreatePermutations.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import { createPermutations } from '../CreatePermutations'; -describe('createPermutations', () => { - it('expects to generate 6 different combinations', () => { - const text = 'abc'; - const SUT = createPermutations(text); - expect(SUT).toStrictEqual(['abc', 'acb', 'bac', 'bca', 'cab', 'cba']); - }); - it('expects to generate 2 different combinations', () => { - const text = '12'; - const SUT = createPermutations(text); - expect(SUT).toStrictEqual(['12', '21']); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/DiceCoefficient.test.js b/docs/content/DS_ALGO/algorithms/string/test/DiceCoefficient.test.js deleted file mode 100644 index ba0a0e0ef6..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/DiceCoefficient.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { diceCoefficient } from '../DiceCoefficient'; -describe('diceCoefficient', () => { - it('should calculate edit distance between two strings', () => { - // equal strings return 1 (max possible value) - expect(diceCoefficient('abc', 'abc')).toBe(1); - expect(diceCoefficient('', '')).toBe(1); - // string length needs to be at least 2 (unless equal) - expect(diceCoefficient('a', '')).toBe(0); - expect(diceCoefficient('', 'a')).toBe(0); - expect(diceCoefficient('skate', 'ate')).toBe(0.66); - expect(diceCoefficient('money', 'honey')).toBe(0.75); - expect(diceCoefficient('love', 'hate')).toBe(0); - expect(diceCoefficient('skilled', 'killed')).toBe(0.9); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/FormatPhoneNumber.test.js b/docs/content/DS_ALGO/algorithms/string/test/FormatPhoneNumber.test.js deleted file mode 100644 index 4f01b61276..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/FormatPhoneNumber.test.js +++ /dev/null @@ -1,24 +0,0 @@ -import { formatPhoneNumber } from '../FormatPhoneNumber'; -describe('PhoneNumberFormatting', () => { - it('expects to return the formatted phone number', () => { - expect(formatPhoneNumber('1234567890')).toEqual('(123) 456-7890'); - }); - it('expects to return the formatted phone number', () => { - expect(formatPhoneNumber(1234567890)).toEqual('(123) 456-7890'); - }); - it('expects to throw a type error', () => { - expect(() => { - formatPhoneNumber('1234567'); - }).toThrow('Invalid phone number.'); - }); - it('expects to throw a type error', () => { - expect(() => { - formatPhoneNumber('123456text'); - }).toThrow('Invalid phone number.'); - }); - it('expects to throw a type error', () => { - expect(() => { - formatPhoneNumber(12345); - }).toThrow('Invalid phone number.'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/HammingDistance.test.js b/docs/content/DS_ALGO/algorithms/string/test/HammingDistance.test.js deleted file mode 100644 index a3ebbc2ce5..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/HammingDistance.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { hammingDistance } from '../HammingDistance'; -test('should throw an error when trying to compare the strings of different length', () => { - const compareStringsOfDifferentLength = () => { - hammingDistance('abc', 'abcd'); - }; - expect(compareStringsOfDifferentLength).toThrowError(); -}); -test('should calculate difference between two strings', () => { - expect(hammingDistance('a', 'a')).toBe(0); -}); -test('should calculate difference between two strings', () => { - expect(hammingDistance('abc', 'add')).toBe(2); -}); -test('should calculate difference between two strings', () => { - expect(hammingDistance('1011101', '1001001')).toBe(2); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/KMPPatternSearching.test.js b/docs/content/DS_ALGO/algorithms/string/test/KMPPatternSearching.test.js deleted file mode 100644 index 298ba985a8..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/KMPPatternSearching.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { KMPSearch } from '../KMPPatternSearching'; -describe('KMP Matcher', () => { - it('TC1: expects to return matching indices for pattern in text', () => { - const text = 'ABC ABCDAB ABCDABCDABDE'; - const pattern = 'ABCDABD'; - expect(KMPSearch(text, pattern)).toStrictEqual([15]); - }); - it('TC2: expects to return matching indices for pattern in text', () => { - const text = 'ABC ABCDABD ABCDABCDABDE'; - const pattern = 'ABCDABD'; - expect(KMPSearch(text, pattern)).toStrictEqual([4, 16]); - }); - it('TC3: expects to return matching indices for pattern in text', () => { - const text = 'AAAAA'; - const pattern = 'AAA'; - expect(KMPSearch(text, pattern)).toStrictEqual([0, 1, 2]); - }); - it('TC4: expects to return matching indices for pattern in text', () => { - const text = 'ABCD'; - const pattern = 'BA'; - expect(KMPSearch(text, pattern)).toStrictEqual([]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/LevenshteinDistance.test.js b/docs/content/DS_ALGO/algorithms/string/test/LevenshteinDistance.test.js deleted file mode 100644 index 7783ff682a..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/LevenshteinDistance.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import { levenshteinDistance } from '../LevenshteinDistance'; -describe('levenshteinDistance', () => { - it('should calculate edit distance between two strings', () => { - expect(levenshteinDistance('', '')).toBe(0); - expect(levenshteinDistance('a', '')).toBe(1); - expect(levenshteinDistance('', 'a')).toBe(1); - expect(levenshteinDistance('abc', '')).toBe(3); - expect(levenshteinDistance('', 'abc')).toBe(3); - // Should just add I to the beginning. - expect(levenshteinDistance('igloo', 'gloo')).toBe(1); - // Should just substitute i with o, m with g and insert e at end - expect(levenshteinDistance('firm', 'forge')).toBe(3); - // Should just substitute f with s, g with t and delete h - expect(levenshteinDistance('fighting', 'sitting')).toBe(3); - // Should add 4 letters b, a, s and e at the beginning. - expect(levenshteinDistance('ball', 'baseball')).toBe(4); - // Should delete 4 letters b, a, s and e at the beginning and replace the last 4 with f, o, o, t - expect(levenshteinDistance('baseball', 'foot')).toBe(8); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/Lower.test.js b/docs/content/DS_ALGO/algorithms/string/test/Lower.test.js deleted file mode 100644 index 3f401c4164..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/Lower.test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { lower } from '../Lower'; -describe('Testing the Lower function', () => { - it('Test 1: Check by invalid type', () => { - expect(() => lower(345)).toThrowError(); - expect(() => lower(true)).toThrowError(); - expect(() => lower(null)).toThrowError(); - }); - it('Test 2: Check by uppercase string', () => { - expect(lower('WORLD')).toBe('world'); - expect(lower('Hello_WORLD')).toBe('hello_world'); - }); - it('Test 3: Check by lowercase string', () => { - expect(lower('hello')).toBe('hello'); - expect(lower('hello_world')).toBe('hello_world'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/MaxCharacter.test.js b/docs/content/DS_ALGO/algorithms/string/test/MaxCharacter.test.js deleted file mode 100644 index 5a2a640cab..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/MaxCharacter.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { maxCharacter } from '../MaxCharacter'; -describe('Testing the maxCharacter function', () => { - it('Expect throw with wrong arg', () => { - expect(() => maxCharacter(123)).toThrow(); - }); - it('Check the max character in string', () => { - const theString = "I can't do that"; - const maxChar = maxCharacter(theString); - expect(maxChar).toBe('t'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/MaxWord.test.js b/docs/content/DS_ALGO/algorithms/string/test/MaxWord.test.js deleted file mode 100644 index 17763d3df6..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/MaxWord.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { maxWord } from '../MaxWord'; -describe('Testing the maxWord function', () => { - it('Expect throw with non string argument', () => { - expect(() => maxWord(10)).toThrow(); - }); - it('get the max word', () => { - const string = 'be be be be a a banana'; - const mostOccurringWord = maxWord(string); - expect(mostOccurringWord).toBe('be'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/PatternMatching.test.js b/docs/content/DS_ALGO/algorithms/string/test/PatternMatching.test.js deleted file mode 100644 index 418e231839..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/PatternMatching.test.js +++ /dev/null @@ -1,26 +0,0 @@ -import { checkIfPatternExists } from '../PatternMatching'; -describe('checkIfPatternExists', () => { - it('expects to find a pattern with correct input', () => { - const text = 'AABAACAADAABAAAABAA'; - const pattern = 'AABA'; - const SUT = checkIfPatternExists(text.toLowerCase(), pattern.toLowerCase()); - expect(SUT).toBe('Given pattern is found at index 0'); - }); - it('expects to return a message when there is no pattern', () => { - const text = 'ABCDEFG'; - const pattern = 'AEG'; - const SUT = checkIfPatternExists(text.toLowerCase(), pattern.toLowerCase()); - expect(SUT).toBe(undefined); - }); - it('expects to find a pattern independent of casing', () => { - const text = 'AbCAAAAAAB'; - const pattern = 'abc'; - const SUT = checkIfPatternExists(text, pattern); - expect(SUT).toBe(undefined); - }); - it('expects to throw an error message when given input is not a string', () => { - const text = 123444456; - const pattern = 123; - expect(() => checkIfPatternExists(text, pattern)).toThrow('Given input is not a string'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/PermutateString.test.js b/docs/content/DS_ALGO/algorithms/string/test/PermutateString.test.js deleted file mode 100644 index b93967593d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/PermutateString.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import { permutate } from '../PermutateString'; -describe('Permutate a string', () => { - it('expects to throw an Error with an empty string', () => { - expect(() => { - permutate(); - }).toThrow('The arg must be a valid, non empty string'); - }); - it('expects to permute "no" into [no, on]', () => { - expect(['no', 'on']).toEqual(permutate('no')); - }); - it('expects to permute "yes" into [esy, eys, sey, sye, yes, yse]', () => { - expect(['esy', 'eys', 'sey', 'sye', 'yes', 'yse']).toEqual(permutate('yes')); - }); - it('expects to permute "good" into [dgoo dogo doog gdoo godo good odgo odog ogdo ogod oodg oogd ]', () => { - expect(['dgoo', 'dogo', 'doog', 'gdoo', 'godo', 'good', 'odgo', 'odog', 'ogdo', 'ogod', 'oodg', 'oogd']).toEqual(permutate('good')); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ReverseString.test.js b/docs/content/DS_ALGO/algorithms/string/test/ReverseString.test.js deleted file mode 100644 index bdd37fb178..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ReverseString.test.js +++ /dev/null @@ -1,50 +0,0 @@ -import { ReverseStringIterative, ReverseStringIterativeInplace } from '../ReverseString'; -describe('ReverseStringIterative', () => { - it('expects to reverse a simple string', () => { - expect(ReverseStringIterative('reverse')).toEqual('esrever'); - expect(ReverseStringIterative('some')).toEqual('emos'); - expect(ReverseStringIterative('string')).toEqual('gnirts'); - expect(ReverseStringIterative('The Algorithms Javascript')).toEqual('tpircsavaJ smhtiroglA ehT'); - }); - it('expects to reverse a string with spaces in between', () => { - expect(ReverseStringIterative('reverse me')).toEqual('em esrever'); - }); - it('expects to reverse a simple string without capitalizing the first letter', () => { - expect(ReverseStringIterative('Javascript')).toEqual('tpircsavaJ'); - }); - it.each` - input - ${123456} - ${[1, 2, 3, 4, 5, 6]} - ${{ test: 'test' }} - ${null} - `('expects to throw a type error given a value that is $input', ({ input }) => { - expect(() => ReverseStringIterative(input)).toThrow('The given value is not a string'); - }); - it('expects to return a empty string with an empty string is given', () => { - expect(ReverseStringIterative('')).toEqual(''); - }); -}); -describe('ReverseStringIterativeInplace', () => { - it('expects to reverse a simple string', () => { - expect(ReverseStringIterativeInplace('reverse')).toEqual('esrever'); - expect(ReverseStringIterativeInplace('some')).toEqual('emos'); - expect(ReverseStringIterativeInplace('string')).toEqual('gnirts'); - expect(ReverseStringIterativeInplace('The Algorithms Javascript')).toEqual('tpircsavaJ smhtiroglA ehT'); - }); - it('expects to reverse a simple string without capitalizing the first letter', () => { - expect(ReverseStringIterativeInplace('Javascript')).toEqual('tpircsavaJ'); - }); - it('expects to return an empty string given an empty string', () => { - expect(ReverseStringIterativeInplace('Javascript')).toEqual('tpircsavaJ'); - }); - it.each` - input - ${123456} - ${[1, 2, 3, 4, 5, 6]} - ${{ test: 'test' }} - ${null} - `('expects to throw a type error given a value that is $input', ({ input }) => { - expect(() => ReverseStringIterativeInplace(input)).toThrow('The given value is not a string'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ReverseWords.test.js b/docs/content/DS_ALGO/algorithms/string/test/ReverseWords.test.js deleted file mode 100644 index 864cb84dfa..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ReverseWords.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import { reverseWords } from '../ReverseWords'; -describe('reverseWords', () => { - it('expects to reverse words to return a joined word', () => { - expect(reverseWords('I Love JS')).toBe('JS Love I'); - expect(reverseWords('Hello World')).toBe('World Hello'); - expect(reverseWords('The Algorithms Javascript')).toBe('Javascript Algorithms The'); - }); - it.each` - input - ${123456} - ${[1, 2, 3, 4, 5, 6]} - ${{ test: 'test' }} - ${null} - `('expects to throw a type error given a value that is $input', ({ input }) => { - expect(() => { - reverseWords(input); - }).toThrow('The given value is not a string'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ScrambleStrings.test.js b/docs/content/DS_ALGO/algorithms/string/test/ScrambleStrings.test.js deleted file mode 100644 index 1572e43ed7..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ScrambleStrings.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { isScramble } from '../ScrambleStrings'; -describe('ScrambleStrings', () => { - it('expects to return true for same string', () => { - expect(isScramble('a', 'a')).toBe(true); - }); - it('expects to return false for non-scrambled strings', () => { - expect(isScramble('abcde', 'caebd')).toBe(false); - }); - it('expects to return true for scrambled strings', () => { - expect(isScramble('great', 'rgeat')).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/Upper.test.js b/docs/content/DS_ALGO/algorithms/string/test/Upper.test.js deleted file mode 100644 index c86902e460..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/Upper.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { upper } from '../Upper'; -describe('Upper', () => { - it('return uppercase strings', () => { - expect(upper('hello')).toBe('HELLO'); - expect(upper('WORLD')).toBe('WORLD'); - expect(upper('hello_WORLD')).toBe('HELLO_WORLD'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ValidateCreditCard.test.js b/docs/content/DS_ALGO/algorithms/string/test/ValidateCreditCard.test.js deleted file mode 100644 index 302e4c351b..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ValidateCreditCard.test.js +++ /dev/null @@ -1,48 +0,0 @@ -import { validateCreditCard } from '../ValidateCreditCard'; -describe('Validate credit card number', () => { - it('should throw error if card number is boolean', () => { - const invalidCC = true; - expect(() => validateCreditCard(invalidCC)).toThrow('The given value is not a string'); - }); - it('returns true if the credit card number is valid', () => { - const validCreditCard = '4111111111111111'; - const validationResult = validateCreditCard(validCreditCard); - expect(validationResult).toBe(true); - }); - it('should throw an error on non-numeric character in given credit card number', () => { - const nonNumericCCNumbers = ['123ABCDEF', 'ABCDKDKD', 'ADS232']; - nonNumericCCNumbers.forEach((nonNumericCC) => - expect(() => validateCreditCard(nonNumericCC)).toThrow( - `${nonNumericCC} is an invalid credit card number because ` + 'it has nonnumerical characters.' - ) - ); - }); - it('should throw an error on credit card with invalid length', () => { - const ccWithInvalidLength = ['41111', '4111111111111111111111']; - ccWithInvalidLength.forEach((invalidCC) => - expect(() => validateCreditCard(invalidCC)).toThrow(`${invalidCC} is an invalid credit card number because ` + 'of its length.') - ); - }); - it('should throw an error on credit card with invalid start substring', () => { - const ccWithInvalidStartSubstring = [ - '12345678912345', - '23456789123456', - '789123456789123', - '891234567891234', - '912345678912345', - '31345678912345', - '32345678912345', - '33345678912345', - '38345678912345' - ]; - ccWithInvalidStartSubstring.forEach((invalidCC) => - expect(() => validateCreditCard(invalidCC)).toThrow(`${invalidCC} is an invalid credit card number because ` + 'of its first two digits.') - ); - }); - it('should throw an error on credit card with luhn check fail', () => { - const invalidCCs = ['411111111111111', '371211111111111', '49999999999999']; - invalidCCs.forEach((invalidCC) => - expect(() => validateCreditCard(invalidCC)).toThrow(`${invalidCC} is an invalid credit card number because ` + 'it fails the Luhn check.') - ); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ValidateEmail.test.js b/docs/content/DS_ALGO/algorithms/string/test/ValidateEmail.test.js deleted file mode 100644 index b07c09ba58..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ValidateEmail.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { validateEmail } from '../ValidateEmail'; -describe('Validation of an Email Address', () => { - it('expects to return false', () => { - expect(validateEmail('mahfoudh.arous.com')).toEqual(false); - }); - it('expects to return false', () => { - expect(validateEmail('mahfoudh.arous@com')).toEqual(false); - }); - it('expects to return true', () => { - expect(validateEmail('mahfoudh.arous@gmail.com')).toEqual(true); - }); - it('expects to return true', () => { - expect(validateEmail('icristianbaciu@.helsinki.edu')).toEqual(true); - }); - it('expects to throw a type error', () => { - expect(() => { - validateEmail(''); - }).toThrow('Email Address String Null or Empty.'); - expect(() => { - validateEmail(null); - }).toThrow('Email Address String Null or Empty.'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/test/ValidateUrl.test.js b/docs/content/DS_ALGO/algorithms/string/test/ValidateUrl.test.js deleted file mode 100644 index d39b414f1f..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/test/ValidateUrl.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { validateURL } from '../ValidateUrl'; -describe('ValidateUrl', () => { - it('expects to return false', () => { - expect(validateURL('google')).toEqual(false); - expect(validateURL('link: https://www.google.com')).toEqual(false); - }); - it('expects to return true', () => { - expect(validateURL('http://www.google.com')).toEqual(true); - expect(validateURL('https://www.google.com')).toEqual(true); - expect(validateURL('www.google.com')).toEqual(true); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/z-algorithm/README.md b/docs/content/DS_ALGO/algorithms/string/z-algorithm/README.md deleted file mode 100644 index 131b9eaf9c..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/z-algorithm/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Z Algorithm - -The Z-algorithm finds occurrences of a "word" `W` -within a main "text string" `T` in linear time `O(|W| + |T|)`. - -Given a string `S` of length `n`, the algorithm produces -an array, `Z` where `Z[i]` represents the longest substring -starting from `S[i]` which is also a prefix of `S`. Finding -`Z` for the string obtained by concatenating the word, `W` -with a nonce character, say `$` followed by the text, `T`, -helps with pattern matching, for if there is some index `i` -such that `Z[i]` equals the pattern length, then the pattern -must be present at that point. - -While the `Z` array can be computed with two nested loops in `O(|W| * |T|)` time, the -following strategy shows how to obtain it in linear time, based -on the idea that as we iterate over the letters in the string -(index `i` from `1` to `n - 1`), we maintain an interval `[L, R]` -which is the interval with maximum `R` such that `1 ≤ L ≤ i ≤ R` -and `S[L...R]` is a prefix that is also a substring (if no such -interval exists, just let `L = R = - 1`). For `i = 1`, we can -simply compute `L` and `R` by comparing `S[0...]` to `S[1...]`. - -**Example of Z array** - -``` -Index 0 1 2 3 4 5 6 7 8 9 10 11 -Text a a b c a a b x a a a z -Z values X 1 0 0 3 1 0 0 2 2 1 0 -``` - -Other examples - -``` -str = a a a a a a -Z[] = x 5 4 3 2 1 -``` - -``` -str = a a b a a c d -Z[] = x 1 0 2 1 0 0 -``` - -``` -str = a b a b a b a b -Z[] = x 0 6 0 4 0 2 0 -``` - -**Example of Z box** - -![z-box](https://ivanyu.me/wp-content/uploads/2014/09/zalg1.png) - -## Complexity - -- **Time:** `O(|W| + |T|)` -- **Space:** `O(|W|)` - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/) -- [YouTube](https://www.youtube.com/watch?v=CpZh4eF8QBw&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=70) -- [Z Algorithm by Ivan Yurchenko](https://ivanyu.me/blog/2013/10/15/z-algorithm/) diff --git a/docs/content/DS_ALGO/algorithms/string/z-algorithm/test/zAlgorithm.test.js b/docs/content/DS_ALGO/algorithms/string/z-algorithm/test/zAlgorithm.test.js deleted file mode 100644 index 4dbcc90e3d..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/z-algorithm/test/zAlgorithm.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import zAlgorithm from '../zAlgorithm'; -describe('zAlgorithm', () => { - it('should find word positions in given text', () => { - expect(zAlgorithm('abcbcglx', 'abca')).toEqual([]); - expect(zAlgorithm('abca', 'abca')).toEqual([0]); - expect(zAlgorithm('abca', 'abcadfd')).toEqual([]); - expect(zAlgorithm('abcbcglabcx', 'abc')).toEqual([0, 7]); - expect(zAlgorithm('abcbcglx', 'bcgl')).toEqual([3]); - expect(zAlgorithm('abcbcglx', 'cglx')).toEqual([4]); - expect(zAlgorithm('abcxabcdabxabcdabcdabcy', 'abcdabcy')).toEqual([15]); - expect(zAlgorithm('abcxabcdabxabcdabcdabcy', 'abcdabca')).toEqual([]); - expect(zAlgorithm('abcxabcdabxaabcdabcabcdabcdabcy', 'abcdabca')).toEqual([12]); - expect(zAlgorithm('abcxabcdabxaabaabaaaabcdabcdabcy', 'aabaabaaa')).toEqual([11]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/string/z-algorithm/zAlgorithm.js b/docs/content/DS_ALGO/algorithms/string/z-algorithm/zAlgorithm.js deleted file mode 100644 index d2edd3fc0f..0000000000 --- a/docs/content/DS_ALGO/algorithms/string/z-algorithm/zAlgorithm.js +++ /dev/null @@ -1,106 +0,0 @@ -// The string separator that is being used for "word" and "text" concatenation. -const SEPARATOR = '$'; -/** - * @param {string} zString - * @return {number[]} - */ -function buildZArray(zString) { - // Initiate zArray and fill it with zeros. - const zArray = new Array(zString.length).fill(null).map(() => 0); - // Z box boundaries. - let zBoxLeftIndex = 0; - let zBoxRightIndex = 0; - // Position of current zBox character that is also a position of - // the same character in prefix. - // For example: - // Z string: ab$xxabxx - // Indices: 012345678 - // Prefix: ab....... - // Z box: .....ab.. - // Z box shift for 'a' would be 0 (0-position in prefix and 0-position in Z box) - // Z box shift for 'b' would be 1 (1-position in prefix and 1-position in Z box) - let zBoxShift = 0; - // Go through all characters of the zString. - for (let charIndex = 1; charIndex < zString.length; charIndex += 1) { - if (charIndex > zBoxRightIndex) { - // We're OUTSIDE of Z box. In other words this is a case when we're - // starting from Z box of size 1. - // In this case let's make current character to be a Z box of length 1. - zBoxLeftIndex = charIndex; - zBoxRightIndex = charIndex; - // Now let's go and check current and the following characters to see if - // they are the same as a prefix. By doing this we will also expand our - // Z box. For example if starting from current position we will find 3 - // more characters that are equal to the ones in the prefix we will expand - // right Z box boundary by 3. - while (zBoxRightIndex < zString.length && zString[zBoxRightIndex - zBoxLeftIndex] === zString[zBoxRightIndex]) { - // Expanding Z box right boundary. - zBoxRightIndex += 1; - } - // Now we may calculate how many characters starting from current position - // are are the same as the prefix. We may calculate it by difference between - // right and left Z box boundaries. - zArray[charIndex] = zBoxRightIndex - zBoxLeftIndex; - // Move right Z box boundary left by one position just because we've used - // [zBoxRightIndex - zBoxLeftIndex] index calculation above. - zBoxRightIndex -= 1; - } else { - // We're INSIDE of Z box. - // Calculate corresponding Z box shift. Because we want to copy the values - // from zArray that have been calculated before. - zBoxShift = charIndex - zBoxLeftIndex; - // Check if the value that has been already calculated before - // leaves us inside of Z box or it goes beyond the checkbox - // right boundary. - if (zArray[zBoxShift] < zBoxRightIndex - charIndex + 1) { - // If calculated value don't force us to go outside Z box - // then we're safe and we may simply use previously calculated value. - zArray[charIndex] = zArray[zBoxShift]; - } else { - // In case if previously calculated values forces us to go outside of Z box - // we can't safely copy previously calculated zArray value. It is because - // we are sure that there is no further prefix matches outside of Z box. - // Thus such values must be re-calculated and reduced to certain point. - // To do so we need to shift left boundary of Z box to current position. - zBoxLeftIndex = charIndex; - // And start comparing characters one by one as we normally do for the case - // when we are outside of checkbox. - while (zBoxRightIndex < zString.length && zString[zBoxRightIndex - zBoxLeftIndex] === zString[zBoxRightIndex]) { - zBoxRightIndex += 1; - } - zArray[charIndex] = zBoxRightIndex - zBoxLeftIndex; - zBoxRightIndex -= 1; - } - } - } - // Return generated zArray. - return zArray; -} -/** - * @param {string} text - * @param {string} word - * @return {number[]} - */ -export default function zAlgorithm(text, word) { - // The list of word's positions in text. Word may be found in the same text - // in several different positions. Thus it is an array. - const wordPositions = []; - // Concatenate word and string. Word will be a prefix to a string. - const zString = `${word}${SEPARATOR}${text}`; - // Generate Z-array for concatenated string. - const zArray = buildZArray(zString); - // Based on Z-array properties each cell will tell us the length of the match between - // the string prefix and current sub-text. Thus we're may find all positions in zArray - // with the number that equals to the length of the word (zString prefix) and based on - // that positions we'll be able to calculate word positions in text. - for (let charIndex = 1; charIndex < zArray.length; charIndex += 1) { - if (zArray[charIndex] === word.length) { - // Since we did concatenation to form zString we need to subtract prefix - // and separator lengths. - const wordPosition = charIndex - word.length - SEPARATOR.length; - wordPositions.push(wordPosition); - } - } - // Return the list of word positions. - return wordPositions; -} diff --git a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/README.md b/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/README.md deleted file mode 100644 index cc6cb30b81..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Breadth-First Search (BFS) - -Breadth-first search (BFS) is an algorithm for traversing -or searching tree or graph data structures. It starts at -the tree root (or some arbitrary node of a graph, sometimes -referred to as a 'search key') and explores the neighbor -nodes first, before moving to the next level neighbors. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif) - -## Pseudocode - -```text -BFS(root) - Pre: root is the node of the BST - Post: the nodes in the BST have been visited in breadth first order - q ← queue - while root = ø - yield root.value - if root.left = ø - q.enqueue(root.left) - end if - if root.right = ø - q.enqueue(root.right) - end if - if !q.isEmpty() - root ← q.dequeue() - else - root ← ø - end if - end while -end BFS -``` - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Breadth-first_search) -- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/) -- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/) diff --git a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/breadthFirstSearch.js b/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/breadthFirstSearch.js deleted file mode 100644 index 7a773116d2..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/breadthFirstSearch.js +++ /dev/null @@ -1,45 +0,0 @@ -import Queue from '../../../data-structures/queue/Queue'; -/** - * @typedef {Object} Callbacks - * @property {function(node: BinaryTreeNode, child: BinaryTreeNode): boolean} allowTraversal - - * Determines whether BFS should traverse from the node to its child. - * @property {function(node: BinaryTreeNode)} enterNode - Called when BFS enters the node. - * @property {function(node: BinaryTreeNode)} leaveNode - Called when BFS leaves the node. - */ -/** - * @param {Callbacks} [callbacks] - * @returns {Callbacks} - */ -function initCallbacks(callbacks = {}) { - const initiatedCallback = callbacks; - const stubCallback = () => {}; - const defaultAllowTraversal = () => true; - initiatedCallback.allowTraversal = callbacks.allowTraversal || defaultAllowTraversal; - initiatedCallback.enterNode = callbacks.enterNode || stubCallback; - initiatedCallback.leaveNode = callbacks.leaveNode || stubCallback; - return initiatedCallback; -} -/** - * @param {BinaryTreeNode} rootNode - * @param {Callbacks} [originalCallbacks] - */ -export default function breadthFirstSearch(rootNode, originalCallbacks) { - const callbacks = initCallbacks(originalCallbacks); - const nodeQueue = new Queue(); - // Do initial queue setup. - nodeQueue.enqueue(rootNode); - while (!nodeQueue.isEmpty()) { - const currentNode = nodeQueue.dequeue(); - callbacks.enterNode(currentNode); - // Add all children to the queue for future traversals. - // Traverse left branch. - if (currentNode.left && callbacks.allowTraversal(currentNode, currentNode.left)) { - nodeQueue.enqueue(currentNode.left); - } - // Traverse right branch. - if (currentNode.right && callbacks.allowTraversal(currentNode, currentNode.right)) { - nodeQueue.enqueue(currentNode.right); - } - callbacks.leaveNode(currentNode); - } -} diff --git a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/test/breadthFirstSearch.test.js b/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/test/breadthFirstSearch.test.js deleted file mode 100644 index 022c489a23..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/breadth-first-search/test/breadthFirstSearch.test.js +++ /dev/null @@ -1,84 +0,0 @@ -import BinaryTreeNode from '../../../../data-structures/tree/BinaryTreeNode'; -import breadthFirstSearch from '../breadthFirstSearch'; -describe('breadthFirstSearch', () => { - it('should perform BFS operation on tree', () => { - const nodeA = new BinaryTreeNode('A'); - const nodeB = new BinaryTreeNode('B'); - const nodeC = new BinaryTreeNode('C'); - const nodeD = new BinaryTreeNode('D'); - const nodeE = new BinaryTreeNode('E'); - const nodeF = new BinaryTreeNode('F'); - const nodeG = new BinaryTreeNode('G'); - nodeA.setLeft(nodeB).setRight(nodeC); - nodeB.setLeft(nodeD).setRight(nodeE); - nodeC.setLeft(nodeF).setRight(nodeG); - // In-order traversing. - expect(nodeA.toString()).toBe('D,B,E,A,F,C,G'); - const enterNodeCallback = jest.fn(); - const leaveNodeCallback = jest.fn(); - // Traverse tree without callbacks first to check default ones. - breadthFirstSearch(nodeA); - // Traverse tree with callbacks. - breadthFirstSearch(nodeA, { - enterNode: enterNodeCallback, - leaveNode: leaveNodeCallback - }); - expect(enterNodeCallback).toHaveBeenCalledTimes(7); - expect(leaveNodeCallback).toHaveBeenCalledTimes(7); - // Check node entering. - expect(enterNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(enterNodeCallback.mock.calls[1][0].value).toEqual('B'); - expect(enterNodeCallback.mock.calls[2][0].value).toEqual('C'); - expect(enterNodeCallback.mock.calls[3][0].value).toEqual('D'); - expect(enterNodeCallback.mock.calls[4][0].value).toEqual('E'); - expect(enterNodeCallback.mock.calls[5][0].value).toEqual('F'); - expect(enterNodeCallback.mock.calls[6][0].value).toEqual('G'); - // Check node leaving. - expect(leaveNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(leaveNodeCallback.mock.calls[1][0].value).toEqual('B'); - expect(leaveNodeCallback.mock.calls[2][0].value).toEqual('C'); - expect(leaveNodeCallback.mock.calls[3][0].value).toEqual('D'); - expect(leaveNodeCallback.mock.calls[4][0].value).toEqual('E'); - expect(leaveNodeCallback.mock.calls[5][0].value).toEqual('F'); - expect(leaveNodeCallback.mock.calls[6][0].value).toEqual('G'); - }); - it('allow users to redefine node visiting logic', () => { - const nodeA = new BinaryTreeNode('A'); - const nodeB = new BinaryTreeNode('B'); - const nodeC = new BinaryTreeNode('C'); - const nodeD = new BinaryTreeNode('D'); - const nodeE = new BinaryTreeNode('E'); - const nodeF = new BinaryTreeNode('F'); - const nodeG = new BinaryTreeNode('G'); - nodeA.setLeft(nodeB).setRight(nodeC); - nodeB.setLeft(nodeD).setRight(nodeE); - nodeC.setLeft(nodeF).setRight(nodeG); - // In-order traversing. - expect(nodeA.toString()).toBe('D,B,E,A,F,C,G'); - const enterNodeCallback = jest.fn(); - const leaveNodeCallback = jest.fn(); - // Traverse tree without callbacks first to check default ones. - breadthFirstSearch(nodeA); - // Traverse tree with callbacks. - breadthFirstSearch(nodeA, { - allowTraversal: (node, child) => { - // Forbid traversing left half of the tree. - return child.value !== 'B'; - }, - enterNode: enterNodeCallback, - leaveNode: leaveNodeCallback - }); - expect(enterNodeCallback).toHaveBeenCalledTimes(4); - expect(leaveNodeCallback).toHaveBeenCalledTimes(4); - // Check node entering. - expect(enterNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(enterNodeCallback.mock.calls[1][0].value).toEqual('C'); - expect(enterNodeCallback.mock.calls[2][0].value).toEqual('F'); - expect(enterNodeCallback.mock.calls[3][0].value).toEqual('G'); - // Check node leaving. - expect(leaveNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(leaveNodeCallback.mock.calls[1][0].value).toEqual('C'); - expect(leaveNodeCallback.mock.calls[2][0].value).toEqual('F'); - expect(leaveNodeCallback.mock.calls[3][0].value).toEqual('G'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/README.md b/docs/content/DS_ALGO/algorithms/tree/depth-first-search/README.md deleted file mode 100644 index 155f82492b..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Depth-First Search (DFS) - -Depth-first search (DFS) is an algorithm for traversing or -searching tree or graph data structures. One starts at -the root (selecting some arbitrary node as the root in -the case of a graph) and explores as far as possible -along each branch before backtracking. - -![Algorithm Visualization](https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Depth-first_search) -- [Tree Traversals (Inorder, Preorder and Postorder)](https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/) -- [BFS vs DFS](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/) diff --git a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/depthFirstSearch.js b/docs/content/DS_ALGO/algorithms/tree/depth-first-search/depthFirstSearch.js deleted file mode 100644 index acc5e41e22..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/depthFirstSearch.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @typedef {Object} TraversalCallbacks - * - * @property {function(node: BinaryTreeNode, child: BinaryTreeNode): boolean} allowTraversal - * - Determines whether DFS should traverse from the node to its child. - * - * @property {function(node: BinaryTreeNode)} enterNode - Called when DFS enters the node. - * - * @property {function(node: BinaryTreeNode)} leaveNode - Called when DFS leaves the node. - */ -/** - * Extend missing traversal callbacks with default callbacks. - * - * @param {TraversalCallbacks} [callbacks] - The object that contains traversal callbacks. - * @returns {TraversalCallbacks} - Traversal callbacks extended with defaults callbacks. - */ -function initCallbacks(callbacks = {}) { - // Init empty callbacks object. - const initiatedCallbacks = {}; - // Empty callback that we will use in case if user didn't provide real callback function. - const stubCallback = () => {}; - // By default we will allow traversal of every node - // in case if user didn't provide a callback for that. - const defaultAllowTraversalCallback = () => true; - // Copy original callbacks to our initiatedCallbacks object or use default callbacks instead. - initiatedCallbacks.allowTraversal = callbacks.allowTraversal || defaultAllowTraversalCallback; - initiatedCallbacks.enterNode = callbacks.enterNode || stubCallback; - initiatedCallbacks.leaveNode = callbacks.leaveNode || stubCallback; - // Returned processed list of callbacks. - return initiatedCallbacks; -} -/** - * Recursive depth-first-search traversal for binary. - * - * @param {BinaryTreeNode} node - binary tree node that we will start traversal from. - * @param {TraversalCallbacks} callbacks - the object that contains traversal callbacks. - */ -export function depthFirstSearchRecursive(node, callbacks) { - // Call the "enterNode" callback to notify that the node is going to be entered. - callbacks.enterNode(node); - // Traverse left branch only if case if traversal of the left node is allowed. - if (node.left && callbacks.allowTraversal(node, node.left)) { - depthFirstSearchRecursive(node.left, callbacks); - } - // Traverse right branch only if case if traversal of the right node is allowed. - if (node.right && callbacks.allowTraversal(node, node.right)) { - depthFirstSearchRecursive(node.right, callbacks); - } - // Call the "leaveNode" callback to notify that traversal - // of the current node and its children is finished. - callbacks.leaveNode(node); -} -/** - * Perform depth-first-search traversal of the rootNode. - * For every traversal step call "allowTraversal", "enterNode" and "leaveNode" callbacks. - * See TraversalCallbacks type definition for more details about the shape of callbacks object. - * - * @param {BinaryTreeNode} rootNode - The node from which we start traversing. - * @param {TraversalCallbacks} [callbacks] - Traversal callbacks. - */ -export default function depthFirstSearch(rootNode, callbacks) { - // In case if user didn't provide some callback we need to replace them with default ones. - const processedCallbacks = initCallbacks(callbacks); - // Now, when we have all necessary callbacks we may proceed to recursive traversal. - depthFirstSearchRecursive(rootNode, processedCallbacks); -} diff --git a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/test/depthFirstSearch.test.js b/docs/content/DS_ALGO/algorithms/tree/depth-first-search/test/depthFirstSearch.test.js deleted file mode 100644 index 6d7e66f95a..0000000000 --- a/docs/content/DS_ALGO/algorithms/tree/depth-first-search/test/depthFirstSearch.test.js +++ /dev/null @@ -1,84 +0,0 @@ -import BinaryTreeNode from '../../../../data-structures/tree/BinaryTreeNode'; -import depthFirstSearch from '../depthFirstSearch'; -describe('depthFirstSearch', () => { - it('should perform DFS operation on tree', () => { - const nodeA = new BinaryTreeNode('A'); - const nodeB = new BinaryTreeNode('B'); - const nodeC = new BinaryTreeNode('C'); - const nodeD = new BinaryTreeNode('D'); - const nodeE = new BinaryTreeNode('E'); - const nodeF = new BinaryTreeNode('F'); - const nodeG = new BinaryTreeNode('G'); - nodeA.setLeft(nodeB).setRight(nodeC); - nodeB.setLeft(nodeD).setRight(nodeE); - nodeC.setLeft(nodeF).setRight(nodeG); - // In-order traversing. - expect(nodeA.toString()).toBe('D,B,E,A,F,C,G'); - const enterNodeCallback = jest.fn(); - const leaveNodeCallback = jest.fn(); - // Traverse tree without callbacks first to check default ones. - depthFirstSearch(nodeA); - // Traverse tree with callbacks. - depthFirstSearch(nodeA, { - enterNode: enterNodeCallback, - leaveNode: leaveNodeCallback - }); - expect(enterNodeCallback).toHaveBeenCalledTimes(7); - expect(leaveNodeCallback).toHaveBeenCalledTimes(7); - // Check node entering. - expect(enterNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(enterNodeCallback.mock.calls[1][0].value).toEqual('B'); - expect(enterNodeCallback.mock.calls[2][0].value).toEqual('D'); - expect(enterNodeCallback.mock.calls[3][0].value).toEqual('E'); - expect(enterNodeCallback.mock.calls[4][0].value).toEqual('C'); - expect(enterNodeCallback.mock.calls[5][0].value).toEqual('F'); - expect(enterNodeCallback.mock.calls[6][0].value).toEqual('G'); - // Check node leaving. - expect(leaveNodeCallback.mock.calls[0][0].value).toEqual('D'); - expect(leaveNodeCallback.mock.calls[1][0].value).toEqual('E'); - expect(leaveNodeCallback.mock.calls[2][0].value).toEqual('B'); - expect(leaveNodeCallback.mock.calls[3][0].value).toEqual('F'); - expect(leaveNodeCallback.mock.calls[4][0].value).toEqual('G'); - expect(leaveNodeCallback.mock.calls[5][0].value).toEqual('C'); - expect(leaveNodeCallback.mock.calls[6][0].value).toEqual('A'); - }); - it('allow users to redefine node visiting logic', () => { - const nodeA = new BinaryTreeNode('A'); - const nodeB = new BinaryTreeNode('B'); - const nodeC = new BinaryTreeNode('C'); - const nodeD = new BinaryTreeNode('D'); - const nodeE = new BinaryTreeNode('E'); - const nodeF = new BinaryTreeNode('F'); - const nodeG = new BinaryTreeNode('G'); - nodeA.setLeft(nodeB).setRight(nodeC); - nodeB.setLeft(nodeD).setRight(nodeE); - nodeC.setLeft(nodeF).setRight(nodeG); - // In-order traversing. - expect(nodeA.toString()).toBe('D,B,E,A,F,C,G'); - const enterNodeCallback = jest.fn(); - const leaveNodeCallback = jest.fn(); - // Traverse tree without callbacks first to check default ones. - depthFirstSearch(nodeA); - // Traverse tree with callbacks. - depthFirstSearch(nodeA, { - allowTraversal: (node, child) => { - // Forbid traversing left part of the tree. - return child.value !== 'B'; - }, - enterNode: enterNodeCallback, - leaveNode: leaveNodeCallback - }); - expect(enterNodeCallback).toHaveBeenCalledTimes(4); - expect(leaveNodeCallback).toHaveBeenCalledTimes(4); - // Check node entering. - expect(enterNodeCallback.mock.calls[0][0].value).toEqual('A'); - expect(enterNodeCallback.mock.calls[1][0].value).toEqual('C'); - expect(enterNodeCallback.mock.calls[2][0].value).toEqual('F'); - expect(enterNodeCallback.mock.calls[3][0].value).toEqual('G'); - // Check node leaving. - expect(leaveNodeCallback.mock.calls[0][0].value).toEqual('F'); - expect(leaveNodeCallback.mock.calls[1][0].value).toEqual('G'); - expect(leaveNodeCallback.mock.calls[2][0].value).toEqual('C'); - expect(leaveNodeCallback.mock.calls[3][0].value).toEqual('A'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/README.md deleted file mode 100644 index c944d8215d..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# Best Time to Buy and Sell Stock - -## Task Description - -Say you have an array prices for which the `i`-th element is the price of a given stock on day `i`. - -Find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). - -> Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). - -**Example #1** - -``` -Input: [7, 1, 5, 3, 6, 4] -Output: 7 -``` - -_Explanation:_ Buy on day `2` (`price = 1`) and sell on day `3` (`price = 5`), `profit = 5-1 = 4`. Then buy on day `4` (`price = 3`) and sell on day `5` (`price = 6`), `profit = 6-3 = 3`. - -**Example #2** - -``` -Input: [1, 2, 3, 4, 5] -Output: 4 -``` - -_Explanation:_ Buy on day `1` (`price = 1`) and sell on day `5` (`price = 5`), `profit = 5-1 = 4`. Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again. - -**Example #3** - -``` -Input: [7, 6, 4, 3, 1] -Output: 0 -``` - -_Explanation:_ In this case, no transaction is done, i.e. max `profit = 0`. - -## Possible Solutions - -### Divide and conquer approach `O(2^n)` - -We may try **all** combinations of buying and selling and find out the most profitable one by applying _divide and conquer approach_. - -Let's say we have an array of prices `[7, 6, 4, 3, 1]` and we're on the _1st_ day of trading (at the very beginning of the array). At this point we may say that the overall maximum profit would be the _maximum_ of two following values: - -1. _Option 1: Keep the money_ → profit would equal to the profit from buying/selling the rest of the stocks → `keepProfit = profit([6, 4, 3, 1])`. -2. _Option 2: Buy/sell at current price_ → profit in this case would equal to the profit from buying/selling the rest of the stocks plus (or minus, depending on whether we're selling or buying) the current stock price → `buySellProfit = -7 + profit([6, 4, 3, 1])`. - -The overall profit would be equal to → `overalProfit = Max(keepProfit, buySellProfit)`. - -As you can see the `profit([6, 4, 3, 1])` task is being solved in the same recursive manner. - -> See the full code example in [dqBestTimeToBuySellStocks.js](dqBestTimeToBuySellStocks.js) - -#### Time Complexity - -As you may see, every recursive call will produce _2_ more recursive branches. The depth of the recursion will be `n` (size of prices array) and thus, the time complexity will equal to `O(2^n)`. - -As you may see, this is very inefficient. For example for just `20` prices the number of recursive calls will be somewhere close to `2M`! - -#### Additional Space Complexity - -If we avoid cloning the prices array between recursive function calls and will use the array pointer then additional space complexity will be proportional to the depth of the recursion: `O(n)` - -## Peak Valley Approach `O(n)` - -If we plot the prices array (i.e. `[7, 1, 5, 3, 6, 4]`) we may notice that the points of interest are the consecutive valleys and peaks - -![Peak Valley Approach](https://leetcode.com/media/original_images/122_maxprofit_1.png) - -_Image source: [LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/)_ - -So, if we will track the growing price and will sell the stocks immediately _before_ the price goes down we'll get the maximum profit (remember, we bought the stock in the valley at its low price). - -> See the full code example in [peakvalleyBestTimeToBuySellStocks.js](peakvalleyBestTimeToBuySellStocks.js) - -#### Time Complexity - -Since the algorithm requires only one pass through the prices array, the time complexity would equal `O(n)`. - -#### Additional Space Complexity - -Except of the prices array itself the algorithm consumes the constant amount of memory. Thus, additional space complexity is `O(1)`. - -## Accumulator Approach `O(n)` - -There is even simpler approach exists. Let's say we have the prices array which looks like this `[1, 7, 2, 3, 6, 7, 6, 7]`: - -![Simple One Pass](https://leetcode.com/media/original_images/122_maxprofit_2.png) - -_Image source: [LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/)_ - -You may notice, that we don't even need to keep tracking of a constantly growing price. Instead, we may simply add the price difference for _all growing segments_ of the chart which eventually sums up to the highest possible profit, - -> See the full code example in [accumulatorBestTimeToBuySellStocks.js](accumulatorBestTimeToBuySellStocks.js) - -#### Time Complexity - -Since the algorithm requires only one pass through the prices array, the time complexity would equal `O(n)`. - -#### Additional Space Complexity - -Except of the prices array itself the algorithm consumes the constant amount of memory. Thus, additional space complexity is `O(1)`. - -## References - -- [Best Time to Buy and Sell Stock on LeetCode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dpBestTimeToBuySellStocks.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dpBestTimeToBuySellStocks.test.js deleted file mode 100644 index 15a2a1efd8..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dpBestTimeToBuySellStocks.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import dpBestTimeToBuySellStocks from '../dpBestTimeToBuySellStocks'; -describe('dpBestTimeToBuySellStocks', () => { - it('should find the best time to buy and sell stocks', () => { - let visit; - expect(dpBestTimeToBuySellStocks([1, 5])).toEqual(4); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(1); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([1, 5], visit)).toEqual(4); - expect(visit).toHaveBeenCalledTimes(2); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([5, 1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(2); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([1, 5, 10], visit)).toEqual(9); - expect(visit).toHaveBeenCalledTimes(3); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([10, 1, 5, 20, 15, 21], visit)).toEqual(25); - expect(visit).toHaveBeenCalledTimes(6); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([7, 1, 5, 3, 6, 4], visit)).toEqual(7); - expect(visit).toHaveBeenCalledTimes(6); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([1, 2, 3, 4, 5], visit)).toEqual(4); - expect(visit).toHaveBeenCalledTimes(5); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([7, 6, 4, 3, 1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(5); - visit = jest.fn(); - expect(dpBestTimeToBuySellStocks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], visit)).toEqual(19); - expect(visit).toHaveBeenCalledTimes(20); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dqBestTimeToBuySellStocks.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dqBestTimeToBuySellStocks.test.js deleted file mode 100644 index e4f9e109ba..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/__tests__/dqBestTimeToBuySellStocks.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import dqBestTimeToBuySellStocks from '../dqBestTimeToBuySellStocks'; -describe('dqBestTimeToBuySellStocks', () => { - it('should find the best time to buy and sell stocks', () => { - let visit; - expect(dqBestTimeToBuySellStocks([1, 5])).toEqual(4); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(3); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([1, 5], visit)).toEqual(4); - expect(visit).toHaveBeenCalledTimes(7); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([5, 1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(7); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([1, 5, 10], visit)).toEqual(9); - expect(visit).toHaveBeenCalledTimes(15); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([10, 1, 5, 20, 15, 21], visit)).toEqual(25); - expect(visit).toHaveBeenCalledTimes(127); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([7, 1, 5, 3, 6, 4], visit)).toEqual(7); - expect(visit).toHaveBeenCalledTimes(127); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([1, 2, 3, 4, 5], visit)).toEqual(4); - expect(visit).toHaveBeenCalledTimes(63); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([7, 6, 4, 3, 1], visit)).toEqual(0); - expect(visit).toHaveBeenCalledTimes(63); - visit = jest.fn(); - expect(dqBestTimeToBuySellStocks([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], visit)).toEqual(19); - expect(visit).toHaveBeenCalledTimes(2097151); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/accumulatorBestTimeToBuySellStocks.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/accumulatorBestTimeToBuySellStocks.js deleted file mode 100644 index 4b4cfe3a72..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/accumulatorBestTimeToBuySellStocks.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Finds the maximum profit from selling and buying the stocks. - * ACCUMULATOR APPROACH. - * - * @param {number[]} prices - Array of stock prices, i.e. [7, 6, 4, 3, 1] - * @param {function(): void} visit - Visiting callback to calculate the number of iterations. - * @return {number} - The maximum profit - */ -const accumulatorBestTimeToBuySellStocks = (prices, visit = () => {}) => { - visit(); - let profit = 0; - for (let day = 1; day < prices.length; day += 1) { - visit(); - // Add the increase of the price from yesterday till today (if there was any) to the profit. - profit += Math.max(prices[day] - prices[day - 1], 0); - } - return profit; -}; -export default accumulatorBestTimeToBuySellStocks; diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dpBestTimeToBuySellStocks.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dpBestTimeToBuySellStocks.js deleted file mode 100644 index cba0425889..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dpBestTimeToBuySellStocks.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Finds the maximum profit from selling and buying the stocks. - * DYNAMIC PROGRAMMING APPROACH. - * - * @param {number[]} prices - Array of stock prices, i.e. [7, 6, 4, 3, 1] - * @param {function(): void} visit - Visiting callback to calculate the number of iterations. - * @return {number} - The maximum profit - */ -const dpBestTimeToBuySellStocks = (prices, visit = () => {}) => { - visit(); - let lastBuy = -prices[0]; - let lastSold = 0; - for (let day = 1; day < prices.length; day += 1) { - visit(); - const curBuy = Math.max(lastBuy, lastSold - prices[day]); - const curSold = Math.max(lastSold, lastBuy + prices[day]); - lastBuy = curBuy; - lastSold = curSold; - } - return lastSold; -}; -export default dpBestTimeToBuySellStocks; diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dqBestTimeToBuySellStocks.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dqBestTimeToBuySellStocks.js deleted file mode 100644 index 7de4b9d7b8..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/dqBestTimeToBuySellStocks.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Finds the maximum profit from selling and buying the stocks. - * DIVIDE & CONQUER APPROACH. - * - * @param {number[]} prices - Array of stock prices, i.e. [7, 6, 4, 3, 1] - * @param {function(): void} visit - Visiting callback to calculate the number of iterations. - * @return {number} - The maximum profit - */ -const dqBestTimeToBuySellStocks = (prices, visit = () => {}) => { - /** - * Recursive implementation of the main function. It is hidden from the users. - * - * @param {boolean} buy - Whether we're allow to sell or to buy now - * @param {number} day - Current day of trading (current index of prices array) - * @returns {number} - Max profit from buying/selling - */ - const recursiveBuyerSeller = (buy, day) => { - // Registering the recursive call visit to calculate the complexity. - visit(); - // Quitting the recursion if this is the last day of trading (prices array ended). - if (day === prices.length) { - return 0; - } - // If we're buying - we're loosing money (-1), if we're selling we're getting money (+1). - const operationSign = buy ? -1 : +1; - return Math.max( - // Option 1: Don't do anything. - recursiveBuyerSeller(buy, day + 1), - // Option 2: Sell or Buy at the current price. - operationSign * prices[day] + recursiveBuyerSeller(!buy, day + 1) - ); - }; - const buy = true; - const day = 0; - return recursiveBuyerSeller(buy, day); -}; -export default dqBestTimeToBuySellStocks; diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/peakvalleyBestTimeToBuySellStocks.js b/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/peakvalleyBestTimeToBuySellStocks.js deleted file mode 100644 index c593772e72..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/best-time-to-buy-sell-stocks/peakvalleyBestTimeToBuySellStocks.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Finds the maximum profit from selling and buying the stocks. - * PEAK VALLEY APPROACH. - * - * @param {number[]} prices - Array of stock prices, i.e. [7, 6, 4, 3, 1] - * @param {function(): void} visit - Visiting callback to calculate the number of iterations. - * @return {number} - The maximum profit - */ -const peakvalleyBestTimeToBuySellStocks = (prices, visit = () => {}) => { - visit(); - let profit = 0; - let low = prices[0]; - let high = prices[0]; - prices.slice(1).forEach((currentPrice) => { - visit(); - if (currentPrice < high) { - // If price went down, we need to sell. - profit += high - low; - low = currentPrice; - high = currentPrice; - } else { - // If price went up, we don't need to do anything but increase a high record. - high = currentPrice; - } - }); - // In case if price went up during the last day - // and we didn't have chance to sell inside the forEach loop. - profit += high - low; - return profit; -}; -export default peakvalleyBestTimeToBuySellStocks; diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/README.md deleted file mode 100644 index 654885afcc..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Tower of Hanoi - -The Tower of Hanoi (also called the Tower of Brahma or Lucas' -Tower and sometimes pluralized) is a mathematical game or puzzle. -It consists of three rods and a number of disks of different sizes, -which can slide onto any rod. The puzzle starts with the disks in -a neat stack in ascending order of size on one rod, the smallest -at the top, thus making a conical shape. - -The objective of the puzzle is to move the entire stack to another -rod, obeying the following simple rules: - -- Only one disk can be moved at a time. -- Each move consists of taking the upper disk from one of the - stacks and placing it on top of another stack or on an empty rod. -- No disk may be placed on top of a smaller disk. - -![Hanoi Tower](https://upload.wikimedia.org/wikipedia/commons/8/8d/Iterative_algorithm_solving_a_6_disks_Tower_of_Hanoi.gif) - -Animation of an iterative algorithm solving 6-disk problem - -With `3` disks, the puzzle can be solved in `7` moves. The minimal -number of moves required to solve a Tower of Hanoi puzzle -is `2^n − 1`, where `n` is the number of disks. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Tower_of_Hanoi) -- [HackerEarth](https://www.hackerearth.com/blog/algorithms/tower-hanoi-recursion-game-algorithm-explained/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/hanoiTower.js b/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/hanoiTower.js deleted file mode 100644 index e82250f057..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/hanoiTower.js +++ /dev/null @@ -1,65 +0,0 @@ -import Stack from '../../../data-structures/stack/Stack'; -/** - * @param {number} numberOfDiscs - * @param {Stack} fromPole - * @param {Stack} withPole - * @param {Stack} toPole - * @param {function(disc: number, fromPole: number[], toPole: number[])} moveCallback - */ -function hanoiTowerRecursive({ numberOfDiscs, fromPole, withPole, toPole, moveCallback }) { - if (numberOfDiscs === 1) { - // Base case with just one disc. - moveCallback(fromPole.peek(), fromPole.toArray(), toPole.toArray()); - const disc = fromPole.pop(); - toPole.push(disc); - } else { - // In case if there are more discs then move them recursively. - // Expose the bottom disc on fromPole stack. - hanoiTowerRecursive({ - numberOfDiscs: numberOfDiscs - 1, - fromPole, - withPole: toPole, - toPole: withPole, - moveCallback - }); - // Move the disc that was exposed to its final destination. - hanoiTowerRecursive({ - numberOfDiscs: 1, - fromPole, - withPole, - toPole, - moveCallback - }); - // Move temporary tower from auxiliary pole to its final destination. - hanoiTowerRecursive({ - numberOfDiscs: numberOfDiscs - 1, - fromPole: withPole, - withPole: fromPole, - toPole, - moveCallback - }); - } -} -/** - * @param {number} numberOfDiscs - * @param {function(disc: number, fromPole: number[], toPole: number[])} moveCallback - * @param {Stack} [fromPole] - * @param {Stack} [withPole] - * @param {Stack} [toPole] - */ -export default function hanoiTower({ numberOfDiscs, moveCallback, fromPole = new Stack(), withPole = new Stack(), toPole = new Stack() }) { - // Each of three poles of Tower of Hanoi puzzle is represented as a stack - // that might contain elements (discs). Each disc is represented as a number. - // Larger discs have bigger number equivalent. - // Let's create the discs and put them to the fromPole. - for (let discSize = numberOfDiscs; discSize > 0; discSize -= 1) { - fromPole.push(discSize); - } - hanoiTowerRecursive({ - numberOfDiscs, - fromPole, - withPole, - toPole, - moveCallback - }); -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/test/hanoiTower.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/test/hanoiTower.test.js deleted file mode 100644 index be7330f2da..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/hanoi-tower/test/hanoiTower.test.js +++ /dev/null @@ -1,48 +0,0 @@ -import hanoiTower from '../hanoiTower'; -import Stack from '../../../../data-structures/stack/Stack'; -describe('hanoiTower', () => { - it('should solve tower of hanoi puzzle with 2 discs', () => { - const moveCallback = jest.fn(); - const numberOfDiscs = 2; - const fromPole = new Stack(); - const withPole = new Stack(); - const toPole = new Stack(); - hanoiTower({ - numberOfDiscs, - moveCallback, - fromPole, - withPole, - toPole - }); - expect(moveCallback).toHaveBeenCalledTimes(2 ** numberOfDiscs - 1); - expect(fromPole.toArray()).toEqual([]); - expect(toPole.toArray()).toEqual([1, 2]); - expect(moveCallback.mock.calls[0][0]).toBe(1); - expect(moveCallback.mock.calls[0][1]).toEqual([1, 2]); - expect(moveCallback.mock.calls[0][2]).toEqual([]); - expect(moveCallback.mock.calls[1][0]).toBe(2); - expect(moveCallback.mock.calls[1][1]).toEqual([2]); - expect(moveCallback.mock.calls[1][2]).toEqual([]); - expect(moveCallback.mock.calls[2][0]).toBe(1); - expect(moveCallback.mock.calls[2][1]).toEqual([1]); - expect(moveCallback.mock.calls[2][2]).toEqual([2]); - }); - it('should solve tower of hanoi puzzle with 3 discs', () => { - const moveCallback = jest.fn(); - const numberOfDiscs = 3; - hanoiTower({ - numberOfDiscs, - moveCallback - }); - expect(moveCallback).toHaveBeenCalledTimes(2 ** numberOfDiscs - 1); - }); - it('should solve tower of hanoi puzzle with 6 discs', () => { - const moveCallback = jest.fn(); - const numberOfDiscs = 6; - hanoiTower({ - numberOfDiscs, - moveCallback - }); - expect(moveCallback).toHaveBeenCalledTimes(2 ** numberOfDiscs - 1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/README.md deleted file mode 100644 index 02d0547ac0..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# Jump Game - -## The Problem - -Given an array of non-negative integers, you are initially positioned at -the first index of the array. Each element in the array represents your maximum -jump length at that position. - -Determine if you are able to reach the last index. - -**Example #1** - -``` -Input: [2,3,1,1,4] -Output: true -Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. -``` - -**Example #2** - -``` -Input: [3,2,1,0,4] -Output: false -Explanation: You will always arrive at index 3 no matter what. Its maximum - jump length is 0, which makes it impossible to reach the last index. -``` - -## Naming - -We call a position in the array a **"good index"** if starting at that position, -we can reach the last index. Otherwise, that index is called a **"bad index"**. -The problem then reduces to whether or not index 0 is a "good index". - -## Solutions - -### Approach 1: Backtracking - -This is the inefficient solution where we try every single jump pattern that -takes us from the first position to the last. We start from the first position -and jump to every index that is reachable. We repeat the process until last -index is reached. When stuck, backtrack. - -> See [backtrackingJumpGame.js](backtrackingJumpGame.js) file - -**Time complexity:**: `O(2^n)`. -There are 2n (upper bound) ways of jumping from -the first position to the last, where `n` is the length of -array `nums`. - -**Auxiliary Space Complexity**: `O(n)`. -Recursion requires additional memory for the stack frames. - -### Approach 2: Dynamic Programming Top-down - -Top-down Dynamic Programming can be thought of as optimized -backtracking. It relies on the observation that once we determine -that a certain index is good / bad, this result will never change. -This means that we can store the result and not need to recompute -it every time. - -Therefore, for each position in the array, we remember whether the -index is good or bad. Let's call this array memo and let its values -be either one of: GOOD, BAD, UNKNOWN. This technique is -called memoization. - -> See [dpTopDownJumpGame.js](dpTopDownJumpGame.js) file - -**Time complexity:**: `O(n^2)`. -For every element in the array, say `i`, we are looking at the -next `nums[i]` elements to its right aiming to find a GOOD -index. `nums[i]` can be at most `n`, where `n` is the length -of array `nums`. - -**Auxiliary Space Complexity**: `O(2 * n) = O(n)`. -First `n` originates from recursion. Second `n` comes from the -usage of the memo table. - -### Approach 3: Dynamic Programming Bottom-up - -Top-down to bottom-up conversion is done by eliminating recursion. -In practice, this achieves better performance as we no longer have the -method stack overhead and might even benefit from some caching. More -importantly, this step opens up possibilities for future optimization. -The recursion is usually eliminated by trying to reverse the order of -the steps from the top-down approach. - -The observation to make here is that we only ever jump to the right. -This means that if we start from the right of the array, every time -we will query a position to our right, that position has already be -determined as being GOOD or BAD. This means we don't need to recurse -anymore, as we will always hit the memo table. - -> See [dpBottomUpJumpGame.js](dpBottomUpJumpGame.js) file - -**Time complexity:**: `O(n^2)`. -For every element in the array, say `i`, we are looking at the -next `nums[i]` elements to its right aiming to find a GOOD -index. `nums[i]` can be at most `n`, where `n` is the length -of array `nums`. - -**Auxiliary Space Complexity**: `O(n)`. -This comes from the usage of the memo table. - -### Approach 4: Greedy - -Once we have our code in the bottom-up state, we can make one final, -important observation. From a given position, when we try to see if -we can jump to a GOOD position, we only ever use one - the first one. -In other words, the left-most one. If we keep track of this left-most -GOOD position as a separate variable, we can avoid searching for it in -the array. Not only that, but we can stop using the array altogether. - -> See [greedyJumpGame.js](greedyJumpGame.js) file - -**Time complexity:**: `O(n)`. -We are doing a single pass through the `nums` array, hence `n` steps, -where `n` is the length of array `nums`. - -**Auxiliary Space Complexity**: `O(1)`. -We are not using any extra memory. - -## References - -- [Jump Game Fully Explained on LeetCode](https://leetcode.com/articles/jump-game/) -- [Dynamic Programming vs Divide and Conquer](https://itnext.io/dynamic-programming-vs-divide-and-conquer-2fea680becbe) -- [Dynamic Programming](https://en.wikipedia.org/wiki/Dynamic_programming) -- [Memoization on Wikipedia](https://en.wikipedia.org/wiki/Memoization) -- [Top-Down and Bottom-Up Design on Wikipedia](https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/backtrackingJumpGame.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/backtrackingJumpGame.js deleted file mode 100644 index 2b2f3726c2..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/backtrackingJumpGame.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * BACKTRACKING approach of solving Jump Game. - * - * This is the inefficient solution where we try every single jump - * pattern that takes us from the first position to the last. - * We start from the first position and jump to every index that - * is reachable. We repeat the process until last index is reached. - * When stuck, backtrack. - * - * @param {number[]} numbers - array of possible jump length. - * @param {number} startIndex - index from where we start jumping. - * @param {number[]} currentJumps - current jumps path. - * @return {boolean} - */ -export default function backtrackingJumpGame(numbers, startIndex = 0, currentJumps = []) { - if (startIndex === numbers.length - 1) { - // We've jumped directly to last cell. This situation is a solution. - return true; - } - // Check what the longest jump we could make from current position. - // We don't need to jump beyond the array. - const maxJumpLength = Math.min( - numbers[startIndex], // Jump is within array. - numbers.length - 1 - startIndex // Jump goes beyond array. - ); - // Let's start jumping from startIndex and see whether any - // jump is successful and has reached the end of the array. - for (let jumpLength = maxJumpLength; jumpLength > 0; jumpLength -= 1) { - // Try next jump. - const nextIndex = startIndex + jumpLength; - currentJumps.push(nextIndex); - const isJumpSuccessful = backtrackingJumpGame(numbers, nextIndex, currentJumps); - // Check if current jump was successful. - if (isJumpSuccessful) { - return true; - } - // BACKTRACKING. - // If previous jump wasn't successful then retreat and try the next one. - currentJumps.pop(); - } - return false; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpBottomUpJumpGame.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpBottomUpJumpGame.js deleted file mode 100644 index 7f2267dc2f..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpBottomUpJumpGame.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * DYNAMIC PROGRAMMING BOTTOM-UP approach of solving Jump Game. - * - * This comes out as an optimisation of DYNAMIC PROGRAMMING TOP-DOWN approach. - * - * The observation to make here is that we only ever jump to the right. - * This means that if we start from the right of the array, every time we - * will query a position to our right, that position has already be - * determined as being GOOD or BAD. This means we don't need to recurse - * anymore, as we will always hit the memo table. - * - * We call a position in the array a "good" one if starting at that - * position, we can reach the last index. Otherwise, that index - * is called a "bad" one. - * - * @param {number[]} numbers - array of possible jump length. - * @return {boolean} - */ -export default function dpBottomUpJumpGame(numbers) { - // Init cells goodness table. - const cellsGoodness = Array(numbers.length).fill(undefined); - // Mark the last cell as "good" one since it is where we ultimately want to get. - cellsGoodness[cellsGoodness.length - 1] = true; - // Go throw all cells starting from the one before the last - // one (since the last one is "good" already) and fill cellsGoodness table. - for (let cellIndex = numbers.length - 2; cellIndex >= 0; cellIndex -= 1) { - const maxJumpLength = Math.min(numbers[cellIndex], numbers.length - 1 - cellIndex); - for (let jumpLength = maxJumpLength; jumpLength > 0; jumpLength -= 1) { - const nextIndex = cellIndex + jumpLength; - if (cellsGoodness[nextIndex] === true) { - cellsGoodness[cellIndex] = true; - // Once we detected that current cell is good one we don't need to - // do further cells checking. - break; - } - } - } - // Now, if the zero's cell is good one then we can jump from it to the end of the array. - return cellsGoodness[0] === true; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpTopDownJumpGame.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpTopDownJumpGame.js deleted file mode 100644 index 100f68a265..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/dpTopDownJumpGame.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * DYNAMIC PROGRAMMING TOP-DOWN approach of solving Jump Game. - * - * This comes out as an optimisation of BACKTRACKING approach. - * - * It relies on the observation that once we determine that a certain - * index is good / bad, this result will never change. This means that - * we can store the result and not need to recompute it every time. - * - * We call a position in the array a "good" one if starting at that - * position, we can reach the last index. Otherwise, that index - * is called a "bad" one. - * - * @param {number[]} numbers - array of possible jump length. - * @param {number} startIndex - index from where we start jumping. - * @param {number[]} currentJumps - current jumps path. - * @param {boolean[]} cellsGoodness - holds information about whether cell is "good" or "bad" - * @return {boolean} - */ -export default function dpTopDownJumpGame(numbers, startIndex = 0, currentJumps = [], cellsGoodness = []) { - if (startIndex === numbers.length - 1) { - // We've jumped directly to last cell. This situation is a solution. - return true; - } - // Init cell goodness table if it is empty. - // This is DYNAMIC PROGRAMMING feature. - const currentCellsGoodness = [...cellsGoodness]; - if (!currentCellsGoodness.length) { - numbers.forEach(() => currentCellsGoodness.push(undefined)); - // Mark the last cell as "good" one since it is where we ultimately want to get. - currentCellsGoodness[cellsGoodness.length - 1] = true; - } - // Check what the longest jump we could make from current position. - // We don't need to jump beyond the array. - const maxJumpLength = Math.min( - numbers[startIndex], // Jump is within array. - numbers.length - 1 - startIndex // Jump goes beyond array. - ); - // Let's start jumping from startIndex and see whether any - // jump is successful and has reached the end of the array. - for (let jumpLength = maxJumpLength; jumpLength > 0; jumpLength -= 1) { - // Try next jump. - const nextIndex = startIndex + jumpLength; - // Jump only into "good" or "unknown" cells. - // This is top-down dynamic programming optimisation of backtracking algorithm. - if (currentCellsGoodness[nextIndex] !== false) { - currentJumps.push(nextIndex); - const isJumpSuccessful = dpTopDownJumpGame(numbers, nextIndex, currentJumps, currentCellsGoodness); - // Check if current jump was successful. - if (isJumpSuccessful) { - return true; - } - // BACKTRACKING. - // If previous jump wasn't successful then retreat and try the next one. - currentJumps.pop(); - // Mark current cell as "bad" to avoid its deep visiting later. - currentCellsGoodness[nextIndex] = false; - } - } - return false; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/greedyJumpGame.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/greedyJumpGame.js deleted file mode 100644 index 6bbe86af63..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/greedyJumpGame.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * GREEDY approach of solving Jump Game. - * - * This comes out as an optimisation of DYNAMIC PROGRAMMING BOTTOM_UP approach. - * - * Once we have our code in the bottom-up state, we can make one final, - * important observation. From a given position, when we try to see if - * we can jump to a GOOD position, we only ever use one - the first one. - * In other words, the left-most one. If we keep track of this left-most - * GOOD position as a separate variable, we can avoid searching for it - * in the array. Not only that, but we can stop using the array altogether. - * - * We call a position in the array a "good" one if starting at that - * position, we can reach the last index. Otherwise, that index - * is called a "bad" one. - * - * @param {number[]} numbers - array of possible jump length. - * @return {boolean} - */ -export default function greedyJumpGame(numbers) { - // The "good" cell is a cell from which we may jump to the last cell of the numbers array. - // The last cell in numbers array is for sure the "good" one since it is our goal to reach. - let leftGoodPosition = numbers.length - 1; - // Go through all numbers from right to left. - for (let numberIndex = numbers.length - 2; numberIndex >= 0; numberIndex -= 1) { - // If we can reach the "good" cell from the current one then for sure the current - // one is also "good". Since after all we'll be able to reach the end of the array - // from it. - const maxCurrentJumpLength = numberIndex + numbers[numberIndex]; - if (maxCurrentJumpLength >= leftGoodPosition) { - leftGoodPosition = numberIndex; - } - } - // If the most left "good" position is the zero's one then we may say that it IS - // possible jump to the end of the array from the first cell; - return leftGoodPosition === 0; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/backtrackingJumpGame.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/backtrackingJumpGame.test.js deleted file mode 100644 index 8b68bf64ba..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/backtrackingJumpGame.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import backtrackingJumpGame from '../backtrackingJumpGame'; -describe('backtrackingJumpGame', () => { - it('should solve Jump Game problem in backtracking manner', () => { - expect(backtrackingJumpGame([1, 0])).toBe(true); - expect(backtrackingJumpGame([100, 0])).toBe(true); - expect(backtrackingJumpGame([2, 3, 1, 1, 4])).toBe(true); - expect(backtrackingJumpGame([1, 1, 1, 1, 1])).toBe(true); - expect(backtrackingJumpGame([1, 1, 1, 10, 1])).toBe(true); - expect(backtrackingJumpGame([1, 5, 2, 1, 0, 2, 0])).toBe(true); - expect(backtrackingJumpGame([1, 0, 1])).toBe(false); - expect(backtrackingJumpGame([3, 2, 1, 0, 4])).toBe(false); - expect(backtrackingJumpGame([0, 0, 0, 0, 0])).toBe(false); - expect(backtrackingJumpGame([5, 4, 3, 2, 1, 0, 0])).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpBottomUpJumpGame.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpBottomUpJumpGame.test.js deleted file mode 100644 index 0775bbe5b2..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpBottomUpJumpGame.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import dpBottomUpJumpGame from '../dpBottomUpJumpGame'; -describe('dpBottomUpJumpGame', () => { - it('should solve Jump Game problem in bottom-up dynamic programming manner', () => { - expect(dpBottomUpJumpGame([1, 0])).toBe(true); - expect(dpBottomUpJumpGame([100, 0])).toBe(true); - expect(dpBottomUpJumpGame([2, 3, 1, 1, 4])).toBe(true); - expect(dpBottomUpJumpGame([1, 1, 1, 1, 1])).toBe(true); - expect(dpBottomUpJumpGame([1, 1, 1, 10, 1])).toBe(true); - expect(dpBottomUpJumpGame([1, 5, 2, 1, 0, 2, 0])).toBe(true); - expect(dpBottomUpJumpGame([1, 0, 1])).toBe(false); - expect(dpBottomUpJumpGame([3, 2, 1, 0, 4])).toBe(false); - expect(dpBottomUpJumpGame([0, 0, 0, 0, 0])).toBe(false); - expect(dpBottomUpJumpGame([5, 4, 3, 2, 1, 0, 0])).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpTopDownJumpGame.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpTopDownJumpGame.test.js deleted file mode 100644 index 874fe83b8f..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/dpTopDownJumpGame.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import dpTopDownJumpGame from '../dpTopDownJumpGame'; -describe('dpTopDownJumpGame', () => { - it('should solve Jump Game problem in top-down dynamic programming manner', () => { - expect(dpTopDownJumpGame([1, 0])).toBe(true); - expect(dpTopDownJumpGame([100, 0])).toBe(true); - expect(dpTopDownJumpGame([2, 3, 1, 1, 4])).toBe(true); - expect(dpTopDownJumpGame([1, 1, 1, 1, 1])).toBe(true); - expect(dpTopDownJumpGame([1, 1, 1, 10, 1])).toBe(true); - expect(dpTopDownJumpGame([1, 5, 2, 1, 0, 2, 0])).toBe(true); - expect(dpTopDownJumpGame([1, 0, 1])).toBe(false); - expect(dpTopDownJumpGame([3, 2, 1, 0, 4])).toBe(false); - expect(dpTopDownJumpGame([0, 0, 0, 0, 0])).toBe(false); - expect(dpTopDownJumpGame([5, 4, 3, 2, 1, 0, 0])).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/greedyJumpGame.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/greedyJumpGame.test.js deleted file mode 100644 index 84f13f3db3..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/jump-game/test/greedyJumpGame.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import greedyJumpGame from '../greedyJumpGame'; -describe('greedyJumpGame', () => { - it('should solve Jump Game problem in greedy manner', () => { - expect(greedyJumpGame([1, 0])).toBe(true); - expect(greedyJumpGame([100, 0])).toBe(true); - expect(greedyJumpGame([2, 3, 1, 1, 4])).toBe(true); - expect(greedyJumpGame([1, 1, 1, 1, 1])).toBe(true); - expect(greedyJumpGame([1, 1, 1, 10, 1])).toBe(true); - expect(greedyJumpGame([1, 5, 2, 1, 0, 2, 0])).toBe(true); - expect(greedyJumpGame([1, 0, 1])).toBe(false); - expect(greedyJumpGame([3, 2, 1, 0, 4])).toBe(false); - expect(greedyJumpGame([0, 0, 0, 0, 0])).toBe(false); - expect(greedyJumpGame([5, 4, 3, 2, 1, 0, 0])).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/README.md deleted file mode 100644 index 2b0d64f333..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Knight's Tour - -A **knight's tour** is a sequence of moves of a knight on a chessboard -such that the knight visits every square only once. If the knight -ends on a square that is one knight's move from the beginning -square (so that it could tour the board again immediately, -following the same path), the tour is **closed**, otherwise it -is **open**. - -The **knight's tour problem** is the mathematical problem of -finding a knight's tour. Creating a program to find a knight's -tour is a common problem given to computer science students. -Variations of the knight's tour problem involve chessboards of -different sizes than the usual `8×8`, as well as irregular -(non-rectangular) boards. - -The knight's tour problem is an instance of the more -general **Hamiltonian path problem** in graph theory. The problem of finding -a closed knight's tour is similarly an instance of the Hamiltonian -cycle problem. - -![Knight's Tour](https://upload.wikimedia.org/wikipedia/commons/d/da/Knight%27s_tour_anim_2.gif) - -An open knight's tour of a chessboard. - -![Knight's Tour](https://upload.wikimedia.org/wikipedia/commons/c/ca/Knights-Tour-Animation.gif) - -An animation of an open knight's tour on a 5 by 5 board. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Knight%27s_tour) -- [GeeksForGeeks](https://www.geeksforgeeks.org/backtracking-set-1-the-knights-tour-problem/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/knightTour.js b/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/knightTour.js deleted file mode 100644 index 56bfa1c36e..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/knightTour.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @param {number[][]} chessboard - * @param {number[]} position - * @return {number[][]} - */ -function getPossibleMoves(chessboard, position) { - // Generate all knight moves (even those that go beyond the board). - const possibleMoves = [ - [position[0] - 1, position[1] - 2], - [position[0] - 2, position[1] - 1], - [position[0] + 1, position[1] - 2], - [position[0] + 2, position[1] - 1], - [position[0] - 2, position[1] + 1], - [position[0] - 1, position[1] + 2], - [position[0] + 1, position[1] + 2], - [position[0] + 2, position[1] + 1] - ]; - // Filter out all moves that go beyond the board. - return possibleMoves.filter((move) => { - const boardSize = chessboard.length; - return move[0] >= 0 && move[1] >= 0 && move[0] < boardSize && move[1] < boardSize; - }); -} -/** - * @param {number[][]} chessboard - * @param {number[]} move - * @return {boolean} - */ -function isMoveAllowed(chessboard, move) { - return chessboard[move[0]][move[1]] !== 1; -} -/** - * @param {number[][]} chessboard - * @param {number[][]} moves - * @return {boolean} - */ -function isBoardCompletelyVisited(chessboard, moves) { - const totalPossibleMovesCount = chessboard.length ** 2; - const existingMovesCount = moves.length; - return totalPossibleMovesCount === existingMovesCount; -} -/** - * @param {number[][]} chessboard - * @param {number[][]} moves - * @return {boolean} - */ -function knightTourRecursive(chessboard, moves) { - const currentChessboard = chessboard; - // If board has been completely visited then we've found a solution. - if (isBoardCompletelyVisited(currentChessboard, moves)) { - return true; - } - // Get next possible knight moves. - const lastMove = moves[moves.length - 1]; - const possibleMoves = getPossibleMoves(currentChessboard, lastMove); - // Try to do next possible moves. - for (let moveIndex = 0; moveIndex < possibleMoves.length; moveIndex += 1) { - const currentMove = possibleMoves[moveIndex]; - // Check if current move is allowed. We aren't allowed to go to - // the same cells twice. - if (isMoveAllowed(currentChessboard, currentMove)) { - // Actually do the move. - moves.push(currentMove); - currentChessboard[currentMove[0]][currentMove[1]] = 1; - // If further moves starting from current are successful then - // return true meaning the solution is found. - if (knightTourRecursive(currentChessboard, moves)) { - return true; - } - // BACKTRACKING. - // If current move was unsuccessful then step back and try to do another move. - moves.pop(); - currentChessboard[currentMove[0]][currentMove[1]] = 0; - } - } - // Return false if we haven't found solution. - return false; -} -/** - * @param {number} chessboardSize - * @return {number[][]} - */ -export default function knightTour(chessboardSize) { - // Init chessboard. - const chessboard = Array(chessboardSize) - .fill(null) - .map(() => Array(chessboardSize).fill(0)); - // Init moves array. - const moves = []; - // Do first move and place the knight to the 0x0 cell. - const firstMove = [0, 0]; - moves.push(firstMove); - chessboard[firstMove[0]][firstMove[0]] = 1; - // Recursively try to do the next move. - const solutionWasFound = knightTourRecursive(chessboard, moves); - return solutionWasFound ? moves : []; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/test/knightTour.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/test/knightTour.test.js deleted file mode 100644 index 20df9a22be..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/knight-tour/test/knightTour.test.js +++ /dev/null @@ -1,38 +0,0 @@ -import knightTour from '../knightTour'; -describe('knightTour', () => { - it('should not find solution on 3x3 board', () => { - const moves = knightTour(3); - expect(moves.length).toBe(0); - }); - it('should find one solution to do knight tour on 5x5 board', () => { - const moves = knightTour(5); - expect(moves.length).toBe(25); - expect(moves).toEqual([ - [0, 0], - [1, 2], - [2, 0], - [0, 1], - [1, 3], - [3, 4], - [2, 2], - [4, 1], - [3, 3], - [1, 4], - [0, 2], - [1, 0], - [3, 1], - [4, 3], - [2, 4], - [0, 3], - [1, 1], - [3, 0], - [4, 2], - [2, 1], - [4, 0], - [3, 2], - [4, 4], - [2, 3], - [0, 4] - ]); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/QueenPosition.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/QueenPosition.js deleted file mode 100644 index 34a2b30380..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/QueenPosition.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Class that represents queen position on the chessboard. - */ -export default class QueenPosition { - /** - * @param {number} rowIndex - * @param {number} columnIndex - */ - constructor(rowIndex, columnIndex) { - this.rowIndex = rowIndex; - this.columnIndex = columnIndex; - } - /** - * @return {number} - */ - get leftDiagonal() { - // Each position on the same left (\) diagonal has the same difference of - // rowIndex and columnIndex. This fact may be used to quickly check if two - // positions (queens) are on the same left diagonal. - // @see https://youtu.be/xouin83ebxE?t=1m59s - return this.rowIndex - this.columnIndex; - } - /** - * @return {number} - */ - get rightDiagonal() { - // Each position on the same right diagonal (/) has the same - // sum of rowIndex and columnIndex. This fact may be used to quickly - // check if two positions (queens) are on the same right diagonal. - // @see https://youtu.be/xouin83ebxE?t=1m59s - return this.rowIndex + this.columnIndex; - } - toString() { - return `${this.rowIndex},${this.columnIndex}`; - } -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/README.md deleted file mode 100644 index 4eefad9b02..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# N-Queens Problem - -The **eight queens puzzle** is the problem of placing eight chess queens -on an `8×8` chessboard so that no two queens threaten each other. -Thus, a solution requires that no two queens share the same row, -column, or diagonal. The eight queens puzzle is an example of the -more general _n queens problem_ of placing n non-attacking queens -on an `n×n` chessboard, for which solutions exist for all natural -numbers `n` with the exception of `n=2` and `n=3`. - -For example, following is a solution for 4 Queen problem. - -![N Queens](https://cdncontribute.geeksforgeeks.org/wp-content/uploads/N_Queen_Problem.jpg) - -The expected output is a binary matrix which has 1s for the blocks -where queens are placed. For example following is the output matrix -for above 4 queen solution. - -``` -{ 0, 1, 0, 0} -{ 0, 0, 0, 1} -{ 1, 0, 0, 0} -{ 0, 0, 1, 0} -``` - -## Naive Algorithm - -Generate all possible configurations of queens on board and print a -configuration that satisfies the given constraints. - -``` -while there are untried configurations -{ - generate the next configuration - if queens don't attack in this configuration then - { - print this configuration; - } -} -``` - -## Backtracking Algorithm - -The idea is to place queens one by one in different columns, -starting from the leftmost column. When we place a queen in a -column, we check for clashes with already placed queens. In -the current column, if we find a row for which there is no -clash, we mark this row and column as part of the solution. -If we do not find such a row due to clashes then we backtrack -and return false. - -``` -1) Start in the leftmost column -2) If all queens are placed - return true -3) Try all rows in the current column. Do following for every tried row. - a) If the queen can be placed safely in this row then mark this [row, - column] as part of the solution and recursively check if placing - queen here leads to a solution. - b) If placing queen in [row, column] leads to a solution then return - true. - c) If placing queen doesn't lead to a solution then umark this [row, - column] (Backtrack) and go to step (a) to try other rows. -3) If all rows have been tried and nothing worked, return false to trigger - backtracking. -``` - -## Bitwise Solution - -Bitwise algorithm basically approaches the problem like this: - -- Queens can attack diagonally, vertically, or horizontally. As a result, there - can only be one queen in each row, one in each column, and at most one on each - diagonal. -- Since we know there can only one queen per row, we will start at the first row, - place a queen, then move to the second row, place a second queen, and so on until - either a) we reach a valid solution or b) we reach a dead end (ie. we can't place - a queen such that it is "safe" from the other queens). -- Since we are only placing one queen per row, we don't need to worry about - horizontal attacks, since no queen will ever be on the same row as another queen. -- That means we only need to check three things before placing a queen on a - certain square: 1) The square's column doesn't have any other queens on it, 2) - the square's left diagonal doesn't have any other queens on it, and 3) the - square's right diagonal doesn't have any other queens on it. -- If we ever reach a point where there is nowhere safe to place a queen, we can - give up on our current attempt and immediately test out the next possibility. - -First let's talk about the recursive function. You'll notice that it accepts -3 parameters: `leftDiagonal`, `column`, and `rightDiagonal`. Each of these is -technically an integer, but the algorithm takes advantage of the fact that an -integer is represented by a sequence of bits. So, think of each of these -parameters as a sequence of `N` bits. - -Each bit in each of the parameters represents whether the corresponding location -on the current row is "available". - -For example: - -- For `N=4`, column having a value of `0010` would mean that the 3rd column is - already occupied by a queen. -- For `N=8`, ld having a value of `00011000` at row 5 would mean that the - top-left-to-bottom-right diagonals that pass through columns 4 and 5 of that - row are already occupied by queens. - -Below is a visual aid for `leftDiagonal`, `column`, and `rightDiagonal`. - -![](http://gregtrowbridge.com/content/images/2014/Jul/Screenshot-from-2014-06-17-19-46-20.png) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Eight_queens_puzzle) -- [GeeksForGeeks](https://www.geeksforgeeks.org/backtracking-set-3-n-queen-problem/) -- [On YouTube by Abdul Bari](https://www.youtube.com/watch?v=xFv_Hl4B83A&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [On YouTube by Tushar Roy](https://www.youtube.com/watch?v=xouin83ebxE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- Bitwise Solution - - [Wikipedia](https://en.wikipedia.org/wiki/Eight_queens_puzzle) - - [Solution by Greg Trowbridge](http://gregtrowbridge.com/a-bitwise-solution-to-the-n-queens-problem-in-javascript/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueens.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueens.js deleted file mode 100644 index 584ae4b32b..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueens.js +++ /dev/null @@ -1,82 +0,0 @@ -import QueenPosition from './QueenPosition'; -/** - * @param {QueenPosition[]} queensPositions - * @param {number} rowIndex - * @param {number} columnIndex - * @return {boolean} - */ -function isSafe(queensPositions, rowIndex, columnIndex) { - // New position to which the Queen is going to be placed. - const newQueenPosition = new QueenPosition(rowIndex, columnIndex); - // Check if new queen position conflicts with any other queens. - for (let queenIndex = 0; queenIndex < queensPositions.length; queenIndex += 1) { - const currentQueenPosition = queensPositions[queenIndex]; - if ( - // Check if queen has been already placed. - currentQueenPosition && - // Check if there are any queen on the same column. - (newQueenPosition.columnIndex === currentQueenPosition.columnIndex || - // Check if there are any queen on the same row. - newQueenPosition.rowIndex === currentQueenPosition.rowIndex || - // Check if there are any queen on the same left diagonal. - newQueenPosition.leftDiagonal === currentQueenPosition.leftDiagonal || - // Check if there are any queen on the same right diagonal. - newQueenPosition.rightDiagonal === currentQueenPosition.rightDiagonal) - ) { - // Can't place queen into current position since there are other queens that - // are threatening it. - return false; - } - } - // Looks like we're safe. - return true; -} -/** - * @param {QueenPosition[][]} solutions - * @param {QueenPosition[]} previousQueensPositions - * @param {number} queensCount - * @param {number} rowIndex - * @return {boolean} - */ -function nQueensRecursive(solutions, previousQueensPositions, queensCount, rowIndex) { - // Clone positions array. - const queensPositions = [...previousQueensPositions].map((queenPosition) => { - return !queenPosition ? queenPosition : new QueenPosition(queenPosition.rowIndex, queenPosition.columnIndex); - }); - if (rowIndex === queensCount) { - // We've successfully reached the end of the board. - // Store solution to the list of solutions. - solutions.push(queensPositions); - // Solution found. - return true; - } - // Let's try to put queen at row rowIndex into its safe column position. - for (let columnIndex = 0; columnIndex < queensCount; columnIndex += 1) { - if (isSafe(queensPositions, rowIndex, columnIndex)) { - // Place current queen to its current position. - queensPositions[rowIndex] = new QueenPosition(rowIndex, columnIndex); - // Try to place all other queens as well. - nQueensRecursive(solutions, queensPositions, queensCount, rowIndex + 1); - // BACKTRACKING. - // Remove the queen from the row to avoid isSafe() returning false. - queensPositions[rowIndex] = null; - } - } - return false; -} -/** - * @param {number} queensCount - * @return {QueenPosition[][]} - */ -export default function nQueens(queensCount) { - // Init NxN chessboard with zeros. - // const chessboard = Array(queensCount).fill(null).map(() => Array(queensCount).fill(0)); - // This array will hold positions or coordinates of each of - // N queens in form of [rowIndex, columnIndex]. - const queensPositions = Array(queensCount).fill(null); - /** @var {QueenPosition[][]} solutions */ - const solutions = []; - // Solve problem recursively. - nQueensRecursive(solutions, queensPositions, queensCount, 0); - return solutions; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueensBitwise.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueensBitwise.js deleted file mode 100644 index 2bcaf61c56..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/nQueensBitwise.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Checks all possible board configurations. - * - * @param {number} boardSize - Size of the squared chess board. - * @param {number} leftDiagonal - Sequence of N bits that show whether the corresponding location - * on the current row is "available" (no other queens are threatening from left diagonal). - * @param {number} column - Sequence of N bits that show whether the corresponding location - * on the current row is "available" (no other queens are threatening from columns). - * @param {number} rightDiagonal - Sequence of N bits that show whether the corresponding location - * on the current row is "available" (no other queens are threatening from right diagonal). - * @param {number} solutionsCount - Keeps track of the number of valid solutions. - * @return {number} - Number of possible solutions. - */ -function nQueensBitwiseRecursive(boardSize, leftDiagonal = 0, column = 0, rightDiagonal = 0, solutionsCount = 0) { - // Keeps track of the number of valid solutions. - let currentSolutionsCount = solutionsCount; - // Helps to identify valid solutions. - // isDone simply has a bit sequence with 1 for every entry up to the Nth. For example, - // when N=5, done will equal 11111. The "isDone" variable simply allows us to not worry about any - // bits beyond the Nth. - const isDone = 2 ** boardSize - 1; - // All columns are occupied (i.e. 0b1111 for boardSize = 4), so the solution must be complete. - // Since the algorithm never places a queen illegally (ie. when it can attack or be attacked), - // we know that if all the columns have been filled, we must have a valid solution. - if (column === isDone) { - return currentSolutionsCount + 1; - } - // Gets a bit sequence with "1"s wherever there is an open "slot". - // All that's happening here is we're taking col, ld, and rd, and if any of the columns are - // "under attack", we mark that column as 0 in poss, basically meaning "we can't put a queen in - // this column". Thus all bits position in poss that are '1's are available for placing - // queen there. - let availablePositions = ~(leftDiagonal | rightDiagonal | column); - // Loops as long as there is a valid place to put another queen. - // For N=4 the isDone=0b1111. Then if availablePositions=0b0000 (which would mean that all places - // are under threatening) we must stop trying to place a queen. - while (availablePositions & isDone) { - // firstAvailablePosition just stores the first non-zero bit (ie. the first available location). - // So if firstAvailablePosition was 0010, it would mean the 3rd column of the current row. - // And that would be the position will be placing our next queen. - // - // For example: - // availablePositions = 0b01100 - // firstAvailablePosition = 100 - const firstAvailablePosition = availablePositions & -availablePositions; - // This line just marks that position in the current row as being "taken" by flipping that - // column in availablePositions to zero. This way, when the while loop continues, we'll know - // not to try that location again. - // - // For example: - // availablePositions = 0b0100 - // firstAvailablePosition = 0b10 - // 0b0110 - 0b10 = 0b0100 - availablePositions -= firstAvailablePosition; - /* - * The operators >> 1 and 1 << simply move all the bits in a bit sequence one digit to the - * right or left, respectively. So calling (rd|bit)<<1 simply says: combine rd and bit with - * an OR operation, then move everything in the result to the left by one digit. - * - * More specifically, if rd is 0001 (meaning that the top-right-to-bottom-left diagonal through - * column 4 of the current row is occupied), and bit is 0100 (meaning that we are planning to - * place a queen in column 2 of the current row), (rd|bit) results in 0101 (meaning that after - * we place a queen in column 2 of the current row, the second and the fourth - * top-right-to-bottom-left diagonals will be occupied). - * - * Now, if add in the << operator, we get (rd|bit)<<1, which takes the 0101 we worked out in - * our previous bullet point, and moves everything to the left by one. The result, therefore, - * is 1010. - */ - currentSolutionsCount += nQueensBitwiseRecursive( - boardSize, - (leftDiagonal | firstAvailablePosition) >> 1, - column | firstAvailablePosition, - (rightDiagonal | firstAvailablePosition) << 1, - solutionsCount - ); - } - return currentSolutionsCount; -} -/** - * @param {number} boardSize - Size of the squared chess board. - * @return {number} - Number of possible solutions. - * @see http://gregtrowbridge.com/a-bitwise-solution-to-the-n-queens-problem-in-javascript/ - */ -export default function nQueensBitwise(boardSize) { - return nQueensBitwiseRecursive(boardSize); -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/QueensPosition.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/QueensPosition.test.js deleted file mode 100644 index 6074959b56..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/QueensPosition.test.js +++ /dev/null @@ -1,14 +0,0 @@ -import QueenPosition from '../QueenPosition'; -describe('QueenPosition', () => { - it('should store queen position on chessboard', () => { - const position1 = new QueenPosition(0, 0); - const position2 = new QueenPosition(2, 1); - expect(position2.columnIndex).toBe(1); - expect(position2.rowIndex).toBe(2); - expect(position1.leftDiagonal).toBe(0); - expect(position1.rightDiagonal).toBe(0); - expect(position2.leftDiagonal).toBe(1); - expect(position2.rightDiagonal).toBe(3); - expect(position2.toString()).toBe('2,1'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueens.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueens.test.js deleted file mode 100644 index cc0491bb04..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueens.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import nQueens from '../nQueens'; -describe('nQueens', () => { - it('should not hae solution for 3 queens', () => { - const solutions = nQueens(3); - expect(solutions.length).toBe(0); - }); - it('should solve n-queens problem for 4 queens', () => { - const solutions = nQueens(4); - expect(solutions.length).toBe(2); - // First solution. - expect(solutions[0][0].toString()).toBe('0,1'); - expect(solutions[0][1].toString()).toBe('1,3'); - expect(solutions[0][2].toString()).toBe('2,0'); - expect(solutions[0][3].toString()).toBe('3,2'); - // Second solution (mirrored). - expect(solutions[1][0].toString()).toBe('0,2'); - expect(solutions[1][1].toString()).toBe('1,0'); - expect(solutions[1][2].toString()).toBe('2,3'); - expect(solutions[1][3].toString()).toBe('3,1'); - }); - it('should solve n-queens problem for 6 queens', () => { - const solutions = nQueens(6); - expect(solutions.length).toBe(4); - // First solution. - expect(solutions[0][0].toString()).toBe('0,1'); - expect(solutions[0][1].toString()).toBe('1,3'); - expect(solutions[0][2].toString()).toBe('2,5'); - expect(solutions[0][3].toString()).toBe('3,0'); - expect(solutions[0][4].toString()).toBe('4,2'); - expect(solutions[0][5].toString()).toBe('5,4'); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueensBitwise.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueensBitwise.test.js deleted file mode 100644 index 3f2a038fc6..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/n-queens/test/nQueensBitwise.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import nQueensBitwise from '../nQueensBitwise'; -describe('nQueensBitwise', () => { - it('should have solutions for 4 to N queens', () => { - expect(nQueensBitwise(4)).toBe(2); - expect(nQueensBitwise(5)).toBe(10); - expect(nQueensBitwise(6)).toBe(4); - expect(nQueensBitwise(7)).toBe(40); - expect(nQueensBitwise(8)).toBe(92); - expect(nQueensBitwise(9)).toBe(352); - expect(nQueensBitwise(10)).toBe(724); - expect(nQueensBitwise(11)).toBe(2680); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/README.md deleted file mode 100644 index fa796ce114..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Rain Terraces (Trapping Rain Water) Problem - -Given an array of non-negative integers representing terraces in an elevation map -where the width of each bar is `1`, compute how much water it is able to trap -after raining. - -![Rain Terraces](https://www.geeksforgeeks.org/wp-content/uploads/watertrap.png) - -## Examples - -**Example #1** - -``` -Input: arr[] = [2, 0, 2] -Output: 2 -Structure is like below: - -| | -|_| - -We can trap 2 units of water in the middle gap. -``` - -**Example #2** - -``` -Input: arr[] = [3, 0, 0, 2, 0, 4] -Output: 10 -Structure is like below: - - | -| | -| | | -|__|_| - -We can trap "3*2 units" of water between 3 an 2, -"1 unit" on top of bar 2 and "3 units" between 2 -and 4. See below diagram also. -``` - -**Example #3** - -``` -Input: arr[] = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1] -Output: 6 -Structure is like below: - - | - | || | -_|_||_|||||| - -Trap "1 unit" between first 1 and 2, "4 units" between -first 2 and 3 and "1 unit" between second last 1 and last 2. -``` - -## The Algorithm - -An element of array can store water if there are higher bars on left and right. -We can find amount of water to be stored in every element by finding the heights -of bars on left and right sides. The idea is to compute amount of water that can -be stored in every element of array. For example, consider the array -`[3, 0, 0, 2, 0, 4]`, We can trap "3\*2 units" of water between 3 an 2, "1 unit" -on top of bar 2 and "3 units" between 2 and 4. See below diagram also. - -### Approach 1: Brute force - -**Intuition** - -For each element in the array, we find the maximum level of water it can trap -after the rain, which is equal to the minimum of maximum height of bars on both -the sides minus its own height. - -**Steps** - -- Initialize `answer = 0` -- Iterate the array from left to right: - - Initialize `max_left = 0` and `max_right = 0` - - Iterate from the current element to the beginning of array updating: `max_left = max(max_left, height[j])` - - Iterate from the current element to the end of array updating: `max_right = max(max_right, height[j])` - - Add `min(max_left, max_right) − height[i]` to `answer` - -**Complexity Analysis** - -Time complexity: `O(n^2)`. For each element of array, we iterate the left and right parts. - -Auxiliary space complexity: `O(1)` extra space. - -### Approach 2: Dynamic Programming - -**Intuition** - -In brute force, we iterate over the left and right parts again and again just to -find the highest bar size up to that index. But, this could be stored. Voila, -dynamic programming. - -So we may pre-compute highest bar on left and right of every bar in `O(n)` time. -Then use these pre-computed values to find the amount of water in every array element. - -The concept is illustrated as shown: - -![DP Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/Figures/42/trapping_rain_water.png) - -**Steps** - -- Find maximum height of bar from the left end up to an index `i` in the array `left_max`. -- Find maximum height of bar from the right end up to an index `i` in the array `right_max`. -- Iterate over the `height` array and update `answer`: - - Add `min(max_left[i], max_right[i]) − height[i]` to `answer`. - -**Complexity Analysis** - -Time complexity: `O(n)`. We store the maximum heights upto a point using 2 -iterations of `O(n)` each. We finally update `answer` using the stored -values in `O(n)`. - -Auxiliary space complexity: `O(n)` extra space. Additional space -for `left_max` and `right_max` arrays than in Approach 1. - -## References - -- [GeeksForGeeks](https://www.geeksforgeeks.org/trapping-rain-water/) -- [LeetCode](https://leetcode.com/problems/trapping-rain-water/solution/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/bfRainTerraces.js b/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/bfRainTerraces.js deleted file mode 100644 index 7f608eeab8..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/bfRainTerraces.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * BRUTE FORCE approach of solving Trapping Rain Water problem. - * - * @param {number[]} terraces - * @return {number} - */ -export default function bfRainTerraces(terraces) { - let waterAmount = 0; - for (let terraceIndex = 0; terraceIndex < terraces.length; terraceIndex += 1) { - // Get left most high terrace. - let leftHighestLevel = 0; - for (let leftIndex = terraceIndex - 1; leftIndex >= 0; leftIndex -= 1) { - leftHighestLevel = Math.max(leftHighestLevel, terraces[leftIndex]); - } - // Get right most high terrace. - let rightHighestLevel = 0; - for (let rightIndex = terraceIndex + 1; rightIndex < terraces.length; rightIndex += 1) { - rightHighestLevel = Math.max(rightHighestLevel, terraces[rightIndex]); - } - // Add current terrace water amount. - const terraceBoundaryLevel = Math.min(leftHighestLevel, rightHighestLevel); - if (terraceBoundaryLevel > terraces[terraceIndex]) { - // Terrace will be able to store the water if the lowest of two left and right highest - // terraces are still higher than the current one. - waterAmount += terraceBoundaryLevel - terraces[terraceIndex]; - } - } - return waterAmount; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/dpRainTerraces.js b/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/dpRainTerraces.js deleted file mode 100644 index 1f210ef484..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/dpRainTerraces.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * DYNAMIC PROGRAMMING approach of solving Trapping Rain Water problem. - * - * @param {number[]} terraces - * @return {number} - */ -export default function dpRainTerraces(terraces) { - let waterAmount = 0; - // Init arrays that will keep the list of left and right maximum levels for specific positions. - const leftMaxLevels = new Array(terraces.length).fill(0); - const rightMaxLevels = new Array(terraces.length).fill(0); - // Calculate the highest terrace level from the LEFT relative to the current terrace. - [leftMaxLevels[0]] = terraces; - for (let terraceIndex = 1; terraceIndex < terraces.length; terraceIndex += 1) { - leftMaxLevels[terraceIndex] = Math.max(terraces[terraceIndex], leftMaxLevels[terraceIndex - 1]); - } - // Calculate the highest terrace level from the RIGHT relative to the current terrace. - rightMaxLevels[terraces.length - 1] = terraces[terraces.length - 1]; - for (let terraceIndex = terraces.length - 2; terraceIndex >= 0; terraceIndex -= 1) { - rightMaxLevels[terraceIndex] = Math.max(terraces[terraceIndex], rightMaxLevels[terraceIndex + 1]); - } - // Not let's go through all terraces one by one and calculate how much water - // each terrace may accumulate based on previously calculated values. - for (let terraceIndex = 0; terraceIndex < terraces.length; terraceIndex += 1) { - // Pick the lowest from the left/right highest terraces. - const currentTerraceBoundary = Math.min(leftMaxLevels[terraceIndex], rightMaxLevels[terraceIndex]); - if (currentTerraceBoundary > terraces[terraceIndex]) { - waterAmount += currentTerraceBoundary - terraces[terraceIndex]; - } - } - return waterAmount; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/bfRainTerraces.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/bfRainTerraces.test.js deleted file mode 100644 index 147563ec2c..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/bfRainTerraces.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import bfRainTerraces from '../bfRainTerraces'; -describe('bfRainTerraces', () => { - it('should find the amount of water collected after raining', () => { - expect(bfRainTerraces([1])).toBe(0); - expect(bfRainTerraces([1, 0])).toBe(0); - expect(bfRainTerraces([0, 1])).toBe(0); - expect(bfRainTerraces([0, 1, 0])).toBe(0); - expect(bfRainTerraces([0, 1, 0, 0])).toBe(0); - expect(bfRainTerraces([0, 1, 0, 0, 1, 0])).toBe(2); - expect(bfRainTerraces([0, 2, 0, 0, 1, 0])).toBe(2); - expect(bfRainTerraces([2, 0, 2])).toBe(2); - expect(bfRainTerraces([2, 0, 5])).toBe(2); - expect(bfRainTerraces([3, 0, 0, 2, 0, 4])).toBe(10); - expect(bfRainTerraces([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6); - expect(bfRainTerraces([1, 1, 1, 1, 1])).toBe(0); - expect(bfRainTerraces([1, 2, 3, 4, 5])).toBe(0); - expect(bfRainTerraces([4, 1, 3, 1, 2, 1, 2, 1])).toBe(4); - expect(bfRainTerraces([0, 2, 4, 3, 4, 2, 4, 0, 8, 7, 0])).toBe(7); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/dpRainTerraces.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/dpRainTerraces.test.js deleted file mode 100644 index 64f402d98a..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/rain-terraces/test/dpRainTerraces.test.js +++ /dev/null @@ -1,20 +0,0 @@ -import dpRainTerraces from '../dpRainTerraces'; -describe('dpRainTerraces', () => { - it('should find the amount of water collected after raining', () => { - expect(dpRainTerraces([1])).toBe(0); - expect(dpRainTerraces([1, 0])).toBe(0); - expect(dpRainTerraces([0, 1])).toBe(0); - expect(dpRainTerraces([0, 1, 0])).toBe(0); - expect(dpRainTerraces([0, 1, 0, 0])).toBe(0); - expect(dpRainTerraces([0, 1, 0, 0, 1, 0])).toBe(2); - expect(dpRainTerraces([0, 2, 0, 0, 1, 0])).toBe(2); - expect(dpRainTerraces([2, 0, 2])).toBe(2); - expect(dpRainTerraces([2, 0, 5])).toBe(2); - expect(dpRainTerraces([3, 0, 0, 2, 0, 4])).toBe(10); - expect(dpRainTerraces([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6); - expect(dpRainTerraces([1, 1, 1, 1, 1])).toBe(0); - expect(dpRainTerraces([1, 2, 3, 4, 5])).toBe(0); - expect(dpRainTerraces([4, 1, 3, 1, 2, 1, 2, 1])).toBe(4); - expect(dpRainTerraces([0, 2, 4, 3, 4, 2, 4, 0, 8, 7, 0])).toBe(7); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/README.md deleted file mode 100644 index d26f63cf4f..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Recursive Staircase Problem - -## The Problem - -There are `n` stairs, a person standing at the bottom wants to reach the top. The person can climb either `1` or `2` stairs at a time. _Count the number of ways, the person can reach the top._ - -![](https://cdncontribute.geeksforgeeks.org/wp-content/uploads/nth-stair.png) - -## The Solution - -This is an interesting problem because there are several ways of how it may be solved that illustrate different programming paradigms. - -- [Brute Force Recursive Solution](./recursiveStaircaseBF.js) - Time: `O(2^n)`; Space: `O(1)` -- [Recursive Solution With Memoization](./recursiveStaircaseMEM.js) - Time: `O(n)`; Space: `O(n)` -- [Dynamic Programming Solution](./recursiveStaircaseDP.js) - Time: `O(n)`; Space: `O(n)` -- [Iterative Solution](./recursiveStaircaseIT.js) - Time: `O(n)`; Space: `O(1)` - -## References - -- [On YouTube by Gayle Laakmann McDowell](https://www.youtube.com/watch?v=eREiwuvzaUM&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=81&t=0s) -- [GeeksForGeeks](https://www.geeksforgeeks.org/count-ways-reach-nth-stair/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseBF.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseBF.js deleted file mode 100644 index d05220cc81..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseBF.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Recursive Staircase Problem (Brute Force Solution). - * - * @param {number} stairsNum - Number of stairs to climb on. - * @return {number} - Number of ways to climb a staircase. - */ -export default function recursiveStaircaseBF(stairsNum) { - if (stairsNum <= 0) { - // There is no way to go down - you climb the stairs only upwards. - // Also if you're standing on the ground floor that you don't need to do any further steps. - return 0; - } - if (stairsNum === 1) { - // There is only one way to go to the first step. - return 1; - } - if (stairsNum === 2) { - // There are two ways to get to the second steps: (1 + 1) or (2). - return 2; - } - // Sum up how many steps we need to take after doing one step up with the number of - // steps we need to take after doing two steps up. - return recursiveStaircaseBF(stairsNum - 1) + recursiveStaircaseBF(stairsNum - 2); -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseDP.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseDP.js deleted file mode 100644 index e95be213b9..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseDP.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Recursive Staircase Problem (Dynamic Programming Solution). - * - * @param {number} stairsNum - Number of stairs to climb on. - * @return {number} - Number of ways to climb a staircase. - */ -export default function recursiveStaircaseDP(stairsNum) { - if (stairsNum < 0) { - // There is no way to go down - you climb the stairs only upwards. - return 0; - } - // Init the steps vector that will hold all possible ways to get to the corresponding step. - const steps = new Array(stairsNum + 1).fill(0); - // Init the number of ways to get to the 0th, 1st and 2nd steps. - steps[0] = 0; - steps[1] = 1; - steps[2] = 2; - if (stairsNum <= 2) { - // Return the number of ways to get to the 0th or 1st or 2nd steps. - return steps[stairsNum]; - } - // Calculate every next step based on two previous ones. - for (let currentStep = 3; currentStep <= stairsNum; currentStep += 1) { - steps[currentStep] = steps[currentStep - 1] + steps[currentStep - 2]; - } - // Return possible ways to get to the requested step. - return steps[stairsNum]; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseIT.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseIT.js deleted file mode 100644 index c4286d1076..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseIT.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Recursive Staircase Problem (Iterative Solution). - * - * @param {number} stairsNum - Number of stairs to climb on. - * @return {number} - Number of ways to climb a staircase. - */ -export default function recursiveStaircaseIT(stairsNum) { - if (stairsNum <= 0) { - // There is no way to go down - you climb the stairs only upwards. - // Also you don't need to do anything to stay on the 0th step. - return 0; - } - // Init the number of ways to get to the 0th, 1st and 2nd steps. - const steps = [1, 2]; - if (stairsNum <= 2) { - // Return the number of possible ways of how to get to the 1st or 2nd steps. - return steps[stairsNum - 1]; - } - // Calculate the number of ways to get to the n'th step based on previous ones. - // Comparing to Dynamic Programming solution we don't store info for all the steps but - // rather for two previous ones only. - for (let currentStep = 3; currentStep <= stairsNum; currentStep += 1) { - [steps[0], steps[1]] = [steps[1], steps[0] + steps[1]]; - } - // Return possible ways to get to the requested step. - return steps[1]; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseMEM.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseMEM.js deleted file mode 100644 index 2e755d1578..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/recursiveStaircaseMEM.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Recursive Staircase Problem (Recursive Solution With Memoization). - * - * @param {number} totalStairs - Number of stairs to climb on. - * @return {number} - Number of ways to climb a staircase. - */ -export default function recursiveStaircaseMEM(totalStairs) { - // Memo table that will hold all recursively calculated results to avoid calculating them - // over and over again. - const memo = []; - // Recursive closure. - const getSteps = (stairsNum) => { - if (stairsNum <= 0) { - // There is no way to go down - you climb the stairs only upwards. - // Also if you're standing on the ground floor that you don't need to do any further steps. - return 0; - } - if (stairsNum === 1) { - // There is only one way to go to the first step. - return 1; - } - if (stairsNum === 2) { - // There are two ways to get to the second steps: (1 + 1) or (2). - return 2; - } - // Avoid recursion for the steps that we've calculated recently. - if (memo[stairsNum]) { - return memo[stairsNum]; - } - // Sum up how many steps we need to take after doing one step up with the number of - // steps we need to take after doing two steps up. - memo[stairsNum] = getSteps(stairsNum - 1) + getSteps(stairsNum - 2); - return memo[stairsNum]; - }; - // Return possible ways to get to the requested step. - return getSteps(totalStairs); -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseBF.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseBF.test.js deleted file mode 100644 index 745e7c947f..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseBF.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import recursiveStaircaseBF from '../recursiveStaircaseBF'; -describe('recursiveStaircaseBF', () => { - it('should calculate number of variants using Brute Force solution', () => { - expect(recursiveStaircaseBF(-1)).toBe(0); - expect(recursiveStaircaseBF(0)).toBe(0); - expect(recursiveStaircaseBF(1)).toBe(1); - expect(recursiveStaircaseBF(2)).toBe(2); - expect(recursiveStaircaseBF(3)).toBe(3); - expect(recursiveStaircaseBF(4)).toBe(5); - expect(recursiveStaircaseBF(5)).toBe(8); - expect(recursiveStaircaseBF(6)).toBe(13); - expect(recursiveStaircaseBF(7)).toBe(21); - expect(recursiveStaircaseBF(8)).toBe(34); - expect(recursiveStaircaseBF(9)).toBe(55); - expect(recursiveStaircaseBF(10)).toBe(89); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseDP.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseDP.test.js deleted file mode 100644 index d225fdfa3b..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseDP.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import recursiveStaircaseDP from '../recursiveStaircaseDP'; -describe('recursiveStaircaseDP', () => { - it('should calculate number of variants using Dynamic Programming solution', () => { - expect(recursiveStaircaseDP(-1)).toBe(0); - expect(recursiveStaircaseDP(0)).toBe(0); - expect(recursiveStaircaseDP(1)).toBe(1); - expect(recursiveStaircaseDP(2)).toBe(2); - expect(recursiveStaircaseDP(3)).toBe(3); - expect(recursiveStaircaseDP(4)).toBe(5); - expect(recursiveStaircaseDP(5)).toBe(8); - expect(recursiveStaircaseDP(6)).toBe(13); - expect(recursiveStaircaseDP(7)).toBe(21); - expect(recursiveStaircaseDP(8)).toBe(34); - expect(recursiveStaircaseDP(9)).toBe(55); - expect(recursiveStaircaseDP(10)).toBe(89); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseIT.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseIT.test.js deleted file mode 100644 index 9fc10f3c4e..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseIT.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import recursiveStaircaseIT from '../recursiveStaircaseIT'; -describe('recursiveStaircaseIT', () => { - it('should calculate number of variants using Iterative solution', () => { - expect(recursiveStaircaseIT(-1)).toBe(0); - expect(recursiveStaircaseIT(0)).toBe(0); - expect(recursiveStaircaseIT(1)).toBe(1); - expect(recursiveStaircaseIT(2)).toBe(2); - expect(recursiveStaircaseIT(3)).toBe(3); - expect(recursiveStaircaseIT(4)).toBe(5); - expect(recursiveStaircaseIT(5)).toBe(8); - expect(recursiveStaircaseIT(6)).toBe(13); - expect(recursiveStaircaseIT(7)).toBe(21); - expect(recursiveStaircaseIT(8)).toBe(34); - expect(recursiveStaircaseIT(9)).toBe(55); - expect(recursiveStaircaseIT(10)).toBe(89); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseMEM.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseMEM.test.js deleted file mode 100644 index d89054c3db..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/recursive-staircase/test/recursiveStaircaseMEM.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import recursiveStaircaseMEM from '../recursiveStaircaseMEM'; -describe('recursiveStaircaseMEM', () => { - it('should calculate number of variants using Brute Force with Memoization', () => { - expect(recursiveStaircaseMEM(-1)).toBe(0); - expect(recursiveStaircaseMEM(0)).toBe(0); - expect(recursiveStaircaseMEM(1)).toBe(1); - expect(recursiveStaircaseMEM(2)).toBe(2); - expect(recursiveStaircaseMEM(3)).toBe(3); - expect(recursiveStaircaseMEM(4)).toBe(5); - expect(recursiveStaircaseMEM(5)).toBe(8); - expect(recursiveStaircaseMEM(6)).toBe(13); - expect(recursiveStaircaseMEM(7)).toBe(21); - expect(recursiveStaircaseMEM(8)).toBe(34); - expect(recursiveStaircaseMEM(9)).toBe(55); - expect(recursiveStaircaseMEM(10)).toBe(89); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/README.md deleted file mode 100644 index 92f7ec26ee..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/README.md +++ /dev/null @@ -1,110 +0,0 @@ -# Square Matrix In-Place Rotation - -## The Problem - -You are given an `n x n` 2D matrix (representing an image). -Rotate the matrix by `90` degrees (clockwise). - -**Note** - -You have to rotate the image **in-place**, which means you -have to modify the input 2D matrix directly. **DO NOT** allocate -another 2D matrix and do the rotation. - -## Examples - -**Example #1** - -Given input matrix: - -``` -[ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9], -] -``` - -Rotate the input matrix in-place such that it becomes: - -``` -[ - [7, 4, 1], - [8, 5, 2], - [9, 6, 3], -] -``` - -**Example #2** - -Given input matrix: - -``` -[ - [5, 1, 9, 11], - [2, 4, 8, 10], - [13, 3, 6, 7], - [15, 14, 12, 16], -] -``` - -Rotate the input matrix in-place such that it becomes: - -``` -[ - [15, 13, 2, 5], - [14, 3, 4, 1], - [12, 6, 8, 9], - [16, 7, 10, 11], -] -``` - -## Algorithm - -We would need to do two reflections of the matrix: - -- reflect vertically -- reflect diagonally from bottom-left to top-right - -Or we also could Furthermore, you can reflect diagonally -top-left/bottom-right and reflect horizontally. - -A common question is how do you even figure out what kind -of reflections to do? Simply rip a square piece of paper, -write a random word on it so you know its rotation. Then, -flip the square piece of paper around until you figure out -how to come to the solution. - -Here is an example of how first line may be rotated using -diagonal top-right/bottom-left rotation along with horizontal -rotation. - -``` -Let's say we have a string at the top of the matrix: - -A B C -• • • -• • • - -Let's do top-right/bottom-left diagonal reflection: - -A B C -/ / • -/ • • - -And now let's do horizontal reflection: - -A → → -B → → -C → → - -The string has been rotated to 90 degree: - -• • A -• • B -• • C -``` - -## References - -- [LeetCode](https://leetcode.com/problems/rotate-image/description/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/squareMatrixRotation.js b/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/squareMatrixRotation.js deleted file mode 100644 index 971ac6e37c..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/squareMatrixRotation.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @param {*[][]} originalMatrix - * @return {*[][]} - */ -export default function squareMatrixRotation(originalMatrix) { - const matrix = originalMatrix.slice(); - // Do top-right/bottom-left diagonal reflection of the matrix. - for (let rowIndex = 0; rowIndex < matrix.length; rowIndex += 1) { - for (let columnIndex = rowIndex + 1; columnIndex < matrix.length; columnIndex += 1) { - // Swap elements. - [matrix[columnIndex][rowIndex], matrix[rowIndex][columnIndex]] = [matrix[rowIndex][columnIndex], matrix[columnIndex][rowIndex]]; - } - } - // Do horizontal reflection of the matrix. - for (let rowIndex = 0; rowIndex < matrix.length; rowIndex += 1) { - for (let columnIndex = 0; columnIndex < matrix.length / 2; columnIndex += 1) { - // Swap elements. - [matrix[rowIndex][matrix.length - columnIndex - 1], matrix[rowIndex][columnIndex]] = [ - matrix[rowIndex][columnIndex], - matrix[rowIndex][matrix.length - columnIndex - 1] - ]; - } - } - return matrix; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/test/squareMatrixRotation.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/test/squareMatrixRotation.test.js deleted file mode 100644 index d6293ccf72..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/square-matrix-rotation/test/squareMatrixRotation.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import squareMatrixRotation from '../squareMatrixRotation'; -describe('squareMatrixRotation', () => { - it('should rotate matrix #0 in-place', () => { - const matrix = [[1]]; - const rotatedMatrix = [[1]]; - expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix); - }); - it('should rotate matrix #1 in-place', () => { - const matrix = [ - [1, 2], - [3, 4] - ]; - const rotatedMatrix = [ - [3, 1], - [4, 2] - ]; - expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix); - }); - it('should rotate matrix #2 in-place', () => { - const matrix = [ - [1, 2, 3], - [4, 5, 6], - [7, 8, 9] - ]; - const rotatedMatrix = [ - [7, 4, 1], - [8, 5, 2], - [9, 6, 3] - ]; - expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix); - }); - it('should rotate matrix #3 in-place', () => { - const matrix = [ - [5, 1, 9, 11], - [2, 4, 8, 10], - [13, 3, 6, 7], - [15, 14, 12, 16] - ]; - const rotatedMatrix = [ - [15, 13, 2, 5], - [14, 3, 4, 1], - [12, 6, 8, 9], - [16, 7, 10, 11] - ]; - expect(squareMatrixRotation(matrix)).toEqual(rotatedMatrix); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/README.md b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/README.md deleted file mode 100644 index 68f6dc184e..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# Unique Paths Problem - -A robot is located at the top-left corner of a `m x n` grid -(marked 'Start' in the diagram below). - -The robot can only move either down or right at any point in -time. The robot is trying to reach the bottom-right corner -of the grid (marked 'Finish' in the diagram below). - -How many possible unique paths are there? - -![Unique Paths](https://leetcode.com/static/images/problemset/robot_maze.png) - -## Examples - -**Example #1** - -``` -Input: m = 3, n = 2 -Output: 3 -Explanation: -From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: -1. Right -> Right -> Down -2. Right -> Down -> Right -3. Down -> Right -> Right -``` - -**Example #2** - -``` -Input: m = 7, n = 3 -Output: 28 -``` - -## Algorithms - -### Backtracking - -First thought that might came to mind is that we need to build a decision tree -where `D` means moving down and `R` means moving right. For example in case -of boars `width = 3` and `height = 2` we will have the following decision tree: - -``` - START - / \ - D R - / / \ - R D R - / / \ - R R D - - END END END -``` - -We can see three unique branches here that is the answer to our problem. - -**Time Complexity**: `O(2 ^ n)` - roughly in worst case with square board -of size `n`. - -**Auxiliary Space Complexity**: `O(m + n)` - since we need to store current path with -positions. - -### Dynamic Programming - -Let's treat `BOARD[i][j]` as our sub-problem. - -Since we have restriction of moving only to the right -and down we might say that number of unique paths to the current -cell is a sum of numbers of unique paths to the cell above the -current one and to the cell to the left of current one. - -``` -BOARD[i][j] = BOARD[i - 1][j] + BOARD[i][j - 1]; // since we can only move down or right. -``` - -Base cases are: - -``` -BOARD[0][any] = 1; // only one way to reach any top slot. -BOARD[any][0] = 1; // only one way to reach any slot in the leftmost column. -``` - -For the board `3 x 2` our dynamic programming matrix will look like: - -| | 0 | 1 | 1 | -| :---: | :-: | :-: | :-: | -| **0** | 0 | 1 | 1 | -| **1** | 1 | 2 | 3 | - -Each cell contains the number of unique paths to it. We need -the bottom right one with number `3`. - -**Time Complexity**: `O(m * n)` - since we're going through each cell of the DP matrix. - -**Auxiliary Space Complexity**: `O(m * n)` - since we need to have DP matrix. - -### Pascal's Triangle Based - -This question is actually another form of Pascal Triangle. - -The corner of this rectangle is at `m + n - 2` line, and -at `min(m, n) - 1` position of the Pascal's Triangle. - -## References - -- [LeetCode](https://leetcode.com/problems/unique-paths/description/) diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/btUniquePaths.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/btUniquePaths.js deleted file mode 100644 index 857940e2a6..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/btUniquePaths.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * BACKTRACKING approach of solving Unique Paths problem. - * - * @param {number} width - Width of the board. - * @param {number} height - Height of the board. - * @param {number[][]} steps - The steps that have been already made. - * @param {number} uniqueSteps - Total number of unique steps. - * @return {number} - Number of unique paths. - */ -export default function btUniquePaths(width, height, steps = [[0, 0]], uniqueSteps = 0) { - // Fetch current position on board. - const currentPos = steps[steps.length - 1]; - // Check if we've reached the end. - if (currentPos[0] === width - 1 && currentPos[1] === height - 1) { - // In case if we've reached the end let's increase total - // number of unique steps. - return uniqueSteps + 1; - } - // Let's calculate how many unique path we will have - // by going right and by going down. - let rightUniqueSteps = 0; - let downUniqueSteps = 0; - // Do right step if possible. - if (currentPos[0] < width - 1) { - steps.push([currentPos[0] + 1, currentPos[1]]); - // Calculate how many unique paths we'll get by moving right. - rightUniqueSteps = btUniquePaths(width, height, steps, uniqueSteps); - // BACKTRACK and try another move. - steps.pop(); - } - // Do down step if possible. - if (currentPos[1] < height - 1) { - steps.push([currentPos[0], currentPos[1] + 1]); - // Calculate how many unique paths we'll get by moving down. - downUniqueSteps = btUniquePaths(width, height, steps, uniqueSteps); - // BACKTRACK and try another move. - steps.pop(); - } - // Total amount of unique steps will be equal to total amount of - // unique steps by going right plus total amount of unique steps - // by going down. - return rightUniqueSteps + downUniqueSteps; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/dpUniquePaths.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/dpUniquePaths.js deleted file mode 100644 index 3bddd9ba50..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/dpUniquePaths.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * DYNAMIC PROGRAMMING approach of solving Unique Paths problem. - * - * @param {number} width - Width of the board. - * @param {number} height - Height of the board. - * @return {number} - Number of unique paths. - */ -export default function dpUniquePaths(width, height) { - // Init board. - const board = Array(height) - .fill(null) - .map(() => { - return Array(width).fill(0); - }); - // Base case. - // There is only one way of getting to board[0][any] and - // there is also only one way of getting to board[any][0]. - // This is because we have a restriction of moving right - // and down only. - for (let rowIndex = 0; rowIndex < height; rowIndex += 1) { - for (let columnIndex = 0; columnIndex < width; columnIndex += 1) { - if (rowIndex === 0 || columnIndex === 0) { - board[rowIndex][columnIndex] = 1; - } - } - } - // Now, since we have this restriction of moving only to the right - // and down we might say that number of unique paths to the current - // cell is a sum of numbers of unique paths to the cell above the - // current one and to the cell to the left of current one. - for (let rowIndex = 1; rowIndex < height; rowIndex += 1) { - for (let columnIndex = 1; columnIndex < width; columnIndex += 1) { - const uniquesFromTop = board[rowIndex - 1][columnIndex]; - const uniquesFromLeft = board[rowIndex][columnIndex - 1]; - board[rowIndex][columnIndex] = uniquesFromTop + uniquesFromLeft; - } - } - return board[height - 1][width - 1]; -} diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/btUniquePaths.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/btUniquePaths.test.js deleted file mode 100644 index ecab144e07..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/btUniquePaths.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import btUniquePaths from '../btUniquePaths'; -describe('btUniquePaths', () => { - it('should find the number of unique paths on board', () => { - expect(btUniquePaths(3, 2)).toBe(3); - expect(btUniquePaths(7, 3)).toBe(28); - expect(btUniquePaths(3, 7)).toBe(28); - expect(btUniquePaths(10, 10)).toBe(48620); - expect(btUniquePaths(100, 1)).toBe(1); - expect(btUniquePaths(1, 100)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/dpUniquePaths.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/dpUniquePaths.test.js deleted file mode 100644 index 84618194f4..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/dpUniquePaths.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import dpUniquePaths from '../dpUniquePaths'; -describe('dpUniquePaths', () => { - it('should find the number of unique paths on board', () => { - expect(dpUniquePaths(3, 2)).toBe(3); - expect(dpUniquePaths(7, 3)).toBe(28); - expect(dpUniquePaths(3, 7)).toBe(28); - expect(dpUniquePaths(10, 10)).toBe(48620); - expect(dpUniquePaths(100, 1)).toBe(1); - expect(dpUniquePaths(1, 100)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/uniquePaths.test.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/uniquePaths.test.js deleted file mode 100644 index a3d0724412..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/test/uniquePaths.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import uniquePaths from '../uniquePaths'; -describe('uniquePaths', () => { - it('should find the number of unique paths on board', () => { - expect(uniquePaths(3, 2)).toBe(3); - expect(uniquePaths(7, 3)).toBe(28); - expect(uniquePaths(3, 7)).toBe(28); - expect(uniquePaths(10, 10)).toBe(48620); - expect(uniquePaths(100, 1)).toBe(1); - expect(uniquePaths(1, 100)).toBe(1); - }); -}); diff --git a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/uniquePaths.js b/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/uniquePaths.js deleted file mode 100644 index 6d6fed57e5..0000000000 --- a/docs/content/DS_ALGO/algorithms/uncategorized/unique-paths/uniquePaths.js +++ /dev/null @@ -1,11 +0,0 @@ -import pascalTriangle from '../../math/pascal-triangle/pascalTriangle'; -/** - * @param {number} width - * @param {number} height - * @return {number} - */ -export default function uniquePaths(width, height) { - const pascalLine = width + height - 2; - const pascalLinePosition = Math.min(width, height) - 1; - return pascalTriangle(pascalLine)[pascalLinePosition]; -} diff --git a/docs/content/DS_ALGO/data-structures/Hashes/SHA1.js b/docs/content/DS_ALGO/data-structures/Hashes/SHA1.js deleted file mode 100644 index 4ce5a306de..0000000000 --- a/docs/content/DS_ALGO/data-structures/Hashes/SHA1.js +++ /dev/null @@ -1,161 +0,0 @@ -//= =============================================================== -// SHA1.js -// -// Module that replicates the SHA-1 Cryptographic Hash -// function in Javascript. -//= =============================================================== -// main variables -const CHAR_SIZE = 8; -/** - * Adds padding to binary/hex string representation - * - * @param {string} str - string representation (binary/hex) - * @param {int} bits - total number of bits wanted - * @return {string} - string representation padding with empty (0) bits - * - * @example - * pad("10011", 8); // "00010011" - */ -function pad(str, bits) { - let res = str; - while (res.length % bits !== 0) { - res = '0' + res; - } - return res; -} -/** - * Separates string into chunks of the same size - * - * @param {string} str - string to separate into chunks - * @param {int} size - number of characters wanted in each chunk - * @return {array} - array of original string split into chunks - * - * @example - * chunkify("this is a test", 2) - */ -function chunkify(str, size) { - const chunks = []; - for (let i = 0; i < str.length; i += size) { - chunks.push(str.slice(i, i + size)); - } - return chunks; -} -/** - * Rotates string representation of bits to the left - * - * @param {string} bits - string representation of bits - * @param {int} turns - number of rotations to make - * @return {string} - string representation of bits after rotation - * - * @example - * rotateLeft("1011", 3); // "1101" - */ -function rotateLeft(bits, turns) { - return bits.substr(turns) + bits.substr(0, turns); -} -/** - * Pre-processes message to feed the algorithm loop - * - * @param {string} message - message to pre-process - * @return {string} - processed message - */ -function preProcess(message) { - // convert message to binary representation padded to - // 8 bits, and add 1 - let m = - message - .split('') - .map((e) => e.charCodeAt(0)) - .map((e) => e.toString(2)) - .map((e) => pad(e, 8)) - .join('') + '1'; - // extend message by adding empty bits (0) - while (m.length % 512 !== 448) { - m += '0'; - } - // length of message in binary, padded, and extended - // to a 64 bit representation - let ml = (message.length * CHAR_SIZE).toString(2); - ml = pad(ml, 8); - ml = '0'.repeat(64 - ml.length) + ml; - return m + ml; -} -/** - * Hashes message using SHA-1 Cryptographic Hash Function - * - * @param {string} message - message to hash - * @return {string} - message digest (hash value) - */ -function SHA1(message) { - // main variables - let H0 = 0x67452301; - let H1 = 0xefcdab89; - let H2 = 0x98badcfe; - let H3 = 0x10325476; - let H4 = 0xc3d2e1f0; - // pre-process message and split into 512 bit chunks - const bits = preProcess(message); - const chunks = chunkify(bits, 512); - chunks.forEach(function(chunk, i) { - // break each chunk into 16 32-bit words - const words = chunkify(chunk, 32); - // extend 16 32-bit words to 80 32-bit words - for (let i = 16; i < 80; i++) { - const val = [words[i - 3], words[i - 8], words[i - 14], words[i - 16]].map((e) => parseInt(e, 2)).reduce((acc, curr) => curr ^ acc, 0); - const bin = (val >>> 0).toString(2); - const paddedBin = pad(bin, 32); - const word = rotateLeft(paddedBin, 1); - words.push(word); - } - // initialize variables for this chunk - let [a, b, c, d, e] = [H0, H1, H2, H3, H4]; - for (let i = 0; i < 80; i++) { - let f, k; - if (i < 20) { - f = (b & c) | (~b & d); - k = 0x5a827999; - } else if (i < 40) { - f = b ^ c ^ d; - k = 0x6ed9eba1; - } else if (i < 60) { - f = (b & c) | (b & d) | (c & d); - k = 0x8f1bbcdc; - } else { - f = b ^ c ^ d; - k = 0xca62c1d6; - } - // make sure f is unsigned - f >>>= 0; - const aRot = rotateLeft(pad(a.toString(2), 32), 5); - const aInt = parseInt(aRot, 2) >>> 0; - const wordInt = parseInt(words[i], 2) >>> 0; - const t = aInt + f + e + k + wordInt; - e = d >>> 0; - d = c >>> 0; - const bRot = rotateLeft(pad(b.toString(2), 32), 30); - c = parseInt(bRot, 2) >>> 0; - b = a >>> 0; - a = t >>> 0; - } - // add values for this chunk to main hash variables (unsigned) - H0 = (H0 + a) >>> 0; - H1 = (H1 + b) >>> 0; - H2 = (H2 + c) >>> 0; - H3 = (H3 + d) >>> 0; - H4 = (H4 + e) >>> 0; - }); - // combine hash values of main hash variables and return - const HH = [H0, H1, H2, H3, H4] - .map((e) => e.toString(16)) - .map((e) => pad(e, 8)) - .join(''); - return HH; -} -// export SHA1 function -export { - SHA1 -}; - -SH -A1 -}; diff --git a/docs/content/DS_ALGO/data-structures/Hashes/SHA256.js b/docs/content/DS_ALGO/data-structures/Hashes/SHA256.js deleted file mode 100644 index 3566554b28..0000000000 --- a/docs/content/DS_ALGO/data-structures/Hashes/SHA256.js +++ /dev/null @@ -1,169 +0,0 @@ -//= =============================================================== -// SHA256.js -// -// Module that replicates the SHA-256 Cryptographic Hash -// function in Javascript. -//= =============================================================== -// main variables -const CHAR_SIZE = 8; -const K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, - 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, - 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, - 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; -/** - * Adds padding to binary/hex string representation - * - * @param {string} str - string representation (binary/hex) - * @param {int} bits - total number of bits wanted - * @return {string} - string representation padding with empty (0) bits - * - * @example - * pad("10011", 8); // "00010011" - */ -function pad(str, bits) { - let res = str; - while (res.length % bits !== 0) { - res = '0' + res; - } - return res; -} -/** - * Separates string into chunks of the same size - * - * @param {string} str - string to separate into chunks - * @param {int} size - number of characters wanted in each chunk - * @return {array} - array of original string split into chunks - * - * @example - * chunkify("this is a test", 2) - */ -function chunkify(str, size) { - const chunks = []; - for (let i = 0; i < str.length; i += size) { - chunks.push(str.slice(i, i + size)); - } - return chunks; -} -/** - * Rotates string representation of bits to th left - * - * @param {string} bits - string representation of bits - * @param {int} turns - number of rotations to make - * @return {string} - string representation of bits after rotation - * - * @example - * rotateLeft("1011", 3); // "1101" - */ -function rotateRight(bits, turns) { - return bits.substr(bits.length - turns) + bits.substr(0, bits.length - turns); -} -/** - * Pre-processes message to feed the algorithm loop - * - * @param {string} message - message to pre-process - * @return {string} - processed message - */ -function preProcess(message) { - // convert message to binary representation padded to - // 8 bits, and add 1 - let m = - message - .split('') - .map((e) => e.charCodeAt(0)) - .map((e) => e.toString(2)) - .map((e) => pad(e, 8)) - .join('') + '1'; - // extend message by adding empty bits (0) - while (m.length % 512 !== 448) { - m += '0'; - } - // length of message in binary, padded, and extended - // to a 64 bit representation - let ml = (message.length * CHAR_SIZE).toString(2); - ml = pad(ml, 8); - ml = '0'.repeat(64 - ml.length) + ml; - return m + ml; -} -/** - * Hashes message using SHA-256 Cryptographic Hash Function - * - * @param {string} message - message to hash - * @return {string} - message digest (hash value) - */ -function SHA256(message) { - // initial hash variables - let H0 = 0x6a09e667; - let H1 = 0xbb67ae85; - let H2 = 0x3c6ef372; - let H3 = 0xa54ff53a; - let H4 = 0x510e527f; - let H5 = 0x9b05688c; - let H6 = 0x1f83d9ab; - let H7 = 0x5be0cd19; - // pre-process message and split into 512 bit chunks - const bits = preProcess(message); - const chunks = chunkify(bits, 512); - chunks.forEach(function (chunk, i) { - // break each chunk into 16 32-bit words - const words = chunkify(chunk, 32); - // extend 16 32-bit words to 80 32-bit words - for (let i = 16; i < 64; i++) { - const W1 = words[i - 15]; - const W2 = words[i - 2]; - const R1 = rotateRight(W1, 7); - const R2 = rotateRight(W1, 18); - const R3 = rotateRight(W2, 17); - const R4 = rotateRight(W2, 19); - const S0 = parseInt(R1, 2) ^ parseInt(R2, 2) ^ (parseInt(W1, 2) >>> 3); - const S1 = parseInt(R3, 2) ^ parseInt(R4, 2) ^ (parseInt(W2, 2) >>> 10); - const val = parseInt(words[i - 16], 2) + S0 + parseInt(words[i - 7], 2) + S1; - words[i] = pad((val >>> 0).toString(2), 32); - } - // initialize variables for this chunk - let [a, b, c, d, e, f, g, h] = [H0, H1, H2, H3, H4, H5, H6, H7]; - for (let i = 0; i < 64; i++) { - const S1 = - [6, 11, 25] - .map((turns) => rotateRight(pad(e.toString(2), 32), turns)) - .map((bitstring) => parseInt(bitstring, 2)) - .reduce((acc, curr) => acc ^ curr, 0) >>> 0; - const CH = ((e & f) ^ (~e & g)) >>> 0; - const temp1 = (h + S1 + CH + K[i] + parseInt(words[i], 2)) >>> 0; - const S0 = - [2, 13, 22] - .map((turns) => rotateRight(pad(a.toString(2), 32), turns)) - .map((bitstring) => parseInt(bitstring, 2)) - .reduce((acc, curr) => acc ^ curr, 0) >>> 0; - const maj = ((a & b) ^ (a & c) ^ (b & c)) >>> 0; - const temp2 = (S0 + maj) >>> 0; - h = g; - g = f; - f = e; - e = (d + temp1) >>> 0; - d = c; - c = b; - b = a; - a = (temp1 + temp2) >>> 0; - } - // add values for this chunk to main hash variables (unsigned) - H0 = (H0 + a) >>> 0; - H1 = (H1 + b) >>> 0; - H2 = (H2 + c) >>> 0; - H3 = (H3 + d) >>> 0; - H4 = (H4 + e) >>> 0; - H5 = (H5 + f) >>> 0; - H6 = (H6 + g) >>> 0; - H7 = (H7 + h) >>> 0; - }); - // combine hash values of main hash variables and return - const HH = [H0, H1, H2, H3, H4, H5, H6, H7] - .map((e) => e.toString(16)) - .map((e) => pad(e, 8)) - .join(''); - return HH; -} -// export SHA256 function -export { SHA256 }; diff --git a/docs/content/DS_ALGO/data-structures/Trees/BreadthFirstTreeTraversal.js b/docs/content/DS_ALGO/data-structures/Trees/BreadthFirstTreeTraversal.js deleted file mode 100644 index b91d5c4a80..0000000000 --- a/docs/content/DS_ALGO/data-structures/Trees/BreadthFirstTreeTraversal.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - Breadth First Tree Traversal or level order traversal implementation in javascript - Author: @GerardUbuntu -*/ -class Node { - constructor(data) { - this.data = data; - this.left = null; - this.right = null; - } -} -class BinaryTree { - constructor() { - this.root = null; - this.traversal = []; - } - breadthFirst() { - const h = this.getHeight(this.root); - for (let i = 0; i !== h; i++) { - this.traverseLevel(this.root, i); - } - return this.traversal; - } - // Computing the height of the tree - getHeight(node) { - if (node === null) { - return 0; - } - const lheight = this.getHeight(node.left); - const rheight = this.getHeight(node.right); - return lheight > rheight ? lheight + 1 : rheight + 1; - } - traverseLevel(node, levelRemaining) { - if (node === null) { - return; - } - if (levelRemaining === 0) { - this.traversal.push(node.data); - } else { - this.traverseLevel(node.left, levelRemaining - 1); - this.traverseLevel(node.right, levelRemaining - 1); - } - } -} -export { BinaryTree, Node }; diff --git a/docs/content/DS_ALGO/data-structures/Trees/DepthFirstSearch.js b/docs/content/DS_ALGO/data-structures/Trees/DepthFirstSearch.js deleted file mode 100644 index fe348dbb0d..0000000000 --- a/docs/content/DS_ALGO/data-structures/Trees/DepthFirstSearch.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Author: Surendra Kumar - * DFS Algorithm implementation in JavaScript - * DFS Algorithm for traversing or searching graph data structures. - */ -function traverseDFS(root) { - const stack = [root]; - const res = []; - while (stack.length) { - const curr = stack.pop(); - res.push(curr.key); - if (curr.right) { - stack.push(curr.right); - } - if (curr.left) { - stack.push(curr.left); - } - } - return res.reverse(); -} -function searchDFS(tree, value) { - const stack = []; - stack.push(tree[0]); - while (stack.length !== 0) { - for (let i = 0; i < stack.length; i++) { - const node = stack.pop(); - if (node.value === value) { - return node; - } - if (node.right) { - stack.push(tree[node.right]); - } - if (node.left) { - stack.push(tree[node.left]); - } - } - } - return null; -} -const tree = [{ - value: 6, - left: 1, - right: 2 - }, - { - value: 5, - left: 3, - right: 4 - }, - { - value: 7, - left: null, - right: 5 - }, - { - value: 3, - left: 6, - right: null - }, - { - value: 4, - left: null, - right: null - }, - { - value: 9, - left: 7, - right: 8 - }, - { - value: 2, - left: 9, - right: null - }, - { - value: 8, - left: null, - right: null - }, - { - value: 10, - left: null, - right: null - }, - { - value: 1, - left: null, - right: null - } -]; -searchDFS(tree, 9); -searchDFS(tree, 10); -traverseDFS(6); -// 6 -// / \ -// 5 7 -// / \ \ -// 3 4 9 -// / / \ -// 2 8 10 -// / -// 1 -left: 7, - right: 8 -}, { - value: 2, - left: 9, - right: null -}, { - value: 8, - left: null, - right: null -}, { - value: 10, - left: null, - right: null -}, { - value: 1, - left: null, - right: null -} -]; -searchDFS(tree, 9); -searchDFS(tree, 10); -traverseDFS(6); -// 6 -// / \ -// 5 7 -// / \ \ -// 3 4 9 -// / / \ -// 2 8 10 -// / -// 1 diff --git a/docs/content/DS_ALGO/data-structures/Trees/FenwickTree.js b/docs/content/DS_ALGO/data-structures/Trees/FenwickTree.js deleted file mode 100644 index 350a4e8073..0000000000 --- a/docs/content/DS_ALGO/data-structures/Trees/FenwickTree.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Author: Mohit Kumar - * Fedwick Tree Implementation in JavaScript - * Fedwick Tree Implementation for finding prefix sum. - */ -class FenwickTree { - constructor(feneickArray, array, n) { - for (let i = 1; i <= n; i++) { - feneickArray[i] = 0; - } - for (let i = 0; i < n; i++) { - this.update(feneickArray, n, i, array[i]); - } - } - update(feneickArray, n, index, value) { - index = index + 1; - while (index <= n) { - feneickArray[index] += value; - index += index & -index; - } - } - getPrefixSum(feneickArray, index) { - let currSum = 0; - index = index + 1; - while (index > 0) { - currSum += feneickArray[index]; - index -= index & -index; - } - return currSum; - } -} -export { FenwickTree }; diff --git a/docs/content/DS_ALGO/data-structures/Trees/test/BreadthFirstTreeTraversal.test.js b/docs/content/DS_ALGO/data-structures/Trees/test/BreadthFirstTreeTraversal.test.js deleted file mode 100644 index 4a2ebb24ba..0000000000 --- a/docs/content/DS_ALGO/data-structures/Trees/test/BreadthFirstTreeTraversal.test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { BinaryTree, Node } from '../BreadthFirstTreeTraversal'; -describe('Breadth First Tree Traversal', () => { - const binaryTree = new BinaryTree(); - const root = new Node(7); - root.left = new Node(5); - root.right = new Node(8); - root.left.left = new Node(3); - root.left.right = new Node(6); - root.right.right = new Node(9); - binaryTree.root = root; - // Visualization : - // - // 7 - // / \ - // 5 8 - // / \ \ - // 3 6 9 - it('Binary tree - Level order traversal', () => { - expect(binaryTree.traversal).toStrictEqual([]); - const traversal = binaryTree.breadthFirst(); - expect(traversal).toStrictEqual([7, 5, 8, 3, 6, 9]); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/Trees/test/FenwickTree.test.js b/docs/content/DS_ALGO/data-structures/Trees/test/FenwickTree.test.js deleted file mode 100644 index 30ecd226a7..0000000000 --- a/docs/content/DS_ALGO/data-structures/Trees/test/FenwickTree.test.js +++ /dev/null @@ -1,17 +0,0 @@ -import { FenwickTree } from '../FenwickTree'; -describe('Fenwick Tree Implementation', () => { - const fenwickArray = new Array(1000); - const array = [3, 2, 0, 6, 5, -1, 2]; - const length = array.length; - const fenwickTree = new FenwickTree(fenwickArray, array, length); - it('Fenwick Tree - Prefix sum of array', () => { - const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6); - expect(prefixSum).toBe(23); - }); - array[2] += 6; - fenwickTree.update(fenwickArray, length, 2, 6); - it('Fenwick Tree - Prefix sum of Updated array', () => { - const prefixSum = fenwickTree.getPrefixSum(fenwickArray, 6); - expect(prefixSum).toBe(23); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSet.js b/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSet.js deleted file mode 100644 index 1a859879a8..0000000000 --- a/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSet.js +++ /dev/null @@ -1,78 +0,0 @@ -import DisjointSetItem from './DisjointSetItem'; -export default class DisjointSet { - /** - * @param {function(value: *)} [keyCallback] - */ - constructor(keyCallback) { - this.keyCallback = keyCallback; - this.items = {}; - } - /** - * @param {*} itemValue - * @return {DisjointSet} - */ - makeSet(itemValue) { - const disjointSetItem = new DisjointSetItem(itemValue, this.keyCallback); - if (!this.items[disjointSetItem.getKey()]) { - // Add new item only in case if it not presented yet. - this.items[disjointSetItem.getKey()] = disjointSetItem; - } - return this; - } - /** - * Find set representation node. - * - * @param {*} itemValue - * @return {(string|null)} - */ - find(itemValue) { - const templateDisjointItem = new DisjointSetItem(itemValue, this.keyCallback); - // Try to find item itself; - const requiredDisjointItem = this.items[templateDisjointItem.getKey()]; - if (!requiredDisjointItem) { - return null; - } - return requiredDisjointItem.getRoot().getKey(); - } - /** - * Union by rank. - * - * @param {*} valueA - * @param {*} valueB - * @return {DisjointSet} - */ - union(valueA, valueB) { - const rootKeyA = this.find(valueA); - const rootKeyB = this.find(valueB); - if (rootKeyA === null || rootKeyB === null) { - throw new Error('One or two values are not in sets'); - } - if (rootKeyA === rootKeyB) { - // In case if both elements are already in the same set then just return its key. - return this; - } - const rootA = this.items[rootKeyA]; - const rootB = this.items[rootKeyB]; - if (rootA.getRank() < rootB.getRank()) { - // If rootB's tree is bigger then make rootB to be a new root. - rootB.addChild(rootA); - return this; - } - // If rootA's tree is bigger then make rootA to be a new root. - rootA.addChild(rootB); - return this; - } - /** - * @param {*} valueA - * @param {*} valueB - * @return {boolean} - */ - inSameSet(valueA, valueB) { - const rootKeyA = this.find(valueA); - const rootKeyB = this.find(valueB); - if (rootKeyA === null || rootKeyB === null) { - throw new Error('One or two values are not in sets'); - } - return rootKeyA === rootKeyB; - } -} diff --git a/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSetItem.js b/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSetItem.js deleted file mode 100644 index 31cb8c5545..0000000000 --- a/docs/content/DS_ALGO/data-structures/disjoint-set/DisjointSetItem.js +++ /dev/null @@ -1,82 +0,0 @@ -export default class DisjointSetItem { - /** - * @param {*} value - * @param {function(value: *)} [keyCallback] - */ - constructor(value, keyCallback) { - this.value = value; - this.keyCallback = keyCallback; - /** @var {DisjointSetItem} this.parent */ - this.parent = null; - this.children = {}; - } - /** - * @return {*} - */ - getKey() { - // Allow user to define custom key generator. - if (this.keyCallback) { - return this.keyCallback(this.value); - } - // Otherwise use value as a key by default. - return this.value; - } - /** - * @return {DisjointSetItem} - */ - getRoot() { - return this.isRoot() ? this : this.parent.getRoot(); - } - /** - * @return {boolean} - */ - isRoot() { - return this.parent === null; - } - /** - * Rank basically means the number of all ancestors. - * - * @return {number} - */ - getRank() { - if (this.getChildren().length === 0) { - return 0; - } - let rank = 0; - /** @var {DisjointSetItem} child */ - this.getChildren().forEach((child) => { - // Count child itself. - rank += 1; - // Also add all children of current child. - rank += child.getRank(); - }); - return rank; - } - /** - * @return {DisjointSetItem[]} - */ - getChildren() { - return Object.values(this.children); - } - /** - * @param {DisjointSetItem} parentItem - * @param {boolean} forceSettingParentChild - * @return {DisjointSetItem} - */ - setParent(parentItem, forceSettingParentChild = true) { - this.parent = parentItem; - if (forceSettingParentChild) { - parentItem.addChild(this); - } - return this; - } - /** - * @param {DisjointSetItem} childItem - * @return {DisjointSetItem} - */ - addChild(childItem) { - this.children[childItem.getKey()] = childItem; - childItem.setParent(this, false); - return this; - } -} diff --git a/docs/content/DS_ALGO/data-structures/disjoint-set/README.md b/docs/content/DS_ALGO/data-structures/disjoint-set/README.md deleted file mode 100644 index 91ee2625b0..0000000000 --- a/docs/content/DS_ALGO/data-structures/disjoint-set/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Disjoint Set - -**Disjoint-set** data structure (also called a union-find data structure or merge-find set) is a data -structure that tracks a set of elements partitioned into a number of disjoint (non-overlapping) subsets. - -> It provides near-constant-time operations (bounded by the inverse Ackermann function) to _add new sets_, -> to _merge existing sets_, and to _determine whether elements are in the same set_. -> In addition to many other uses (see the Applications section), disjoint-sets play a key role in Kruskal's algorithm for finding the minimum spanning tree of a graph. - -![disjoint set](https://upload.wikimedia.org/wikipedia/commons/6/67/Dsu_disjoint_sets_init.svg) - -_MakeSet_ creates 8 singletons. - -![disjoint set](https://upload.wikimedia.org/wikipedia/commons/a/ac/Dsu_disjoint_sets_final.svg) - -After some operations of _Union_, some sets are grouped together. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) -- [By Abdul Bari on YouTube](https://www.youtube.com/watch?v=wU6udHRIkcc&index=14&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSet.test.js b/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSet.test.js deleted file mode 100644 index 6a95164ce8..0000000000 --- a/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSet.test.js +++ /dev/null @@ -1,84 +0,0 @@ -import DisjointSet from '../DisjointSet'; -describe('DisjointSet', () => { - it('should throw error when trying to union and check not existing sets', () => { - function mergeNotExistingSets() { - const disjointSet = new DisjointSet(); - disjointSet.union('A', 'B'); - } - function checkNotExistingSets() { - const disjointSet = new DisjointSet(); - disjointSet.inSameSet('A', 'B'); - } - expect(mergeNotExistingSets).toThrow(); - expect(checkNotExistingSets).toThrow(); - }); - it('should do basic manipulations on disjoint set', () => { - const disjointSet = new DisjointSet(); - expect(disjointSet.find('A')).toBeNull(); - expect(disjointSet.find('B')).toBeNull(); - disjointSet.makeSet('A'); - expect(disjointSet.find('A')).toBe('A'); - expect(disjointSet.find('B')).toBeNull(); - disjointSet.makeSet('B'); - expect(disjointSet.find('A')).toBe('A'); - expect(disjointSet.find('B')).toBe('B'); - disjointSet.makeSet('C'); - expect(disjointSet.inSameSet('A', 'B')).toBe(false); - disjointSet.union('A', 'B'); - expect(disjointSet.find('A')).toBe('A'); - expect(disjointSet.find('B')).toBe('A'); - expect(disjointSet.inSameSet('A', 'B')).toBe(true); - expect(disjointSet.inSameSet('B', 'A')).toBe(true); - expect(disjointSet.inSameSet('A', 'C')).toBe(false); - disjointSet.union('A', 'A'); - disjointSet.union('B', 'C'); - expect(disjointSet.find('A')).toBe('A'); - expect(disjointSet.find('B')).toBe('A'); - expect(disjointSet.find('C')).toBe('A'); - expect(disjointSet.inSameSet('A', 'B')).toBe(true); - expect(disjointSet.inSameSet('B', 'C')).toBe(true); - expect(disjointSet.inSameSet('A', 'C')).toBe(true); - disjointSet.makeSet('E').makeSet('F').makeSet('G').makeSet('H').makeSet('I'); - disjointSet.union('E', 'F').union('F', 'G').union('G', 'H').union('H', 'I'); - expect(disjointSet.inSameSet('A', 'I')).toBe(false); - expect(disjointSet.inSameSet('E', 'I')).toBe(true); - disjointSet.union('I', 'C'); - expect(disjointSet.find('I')).toBe('E'); - expect(disjointSet.inSameSet('A', 'I')).toBe(true); - }); - it('should union smaller set with bigger one making bigger one to be new root', () => { - const disjointSet = new DisjointSet(); - disjointSet.makeSet('A').makeSet('B').makeSet('C').union('B', 'C').union('A', 'C'); - expect(disjointSet.find('A')).toBe('B'); - }); - it('should do basic manipulations on disjoint set with custom key extractor', () => { - const keyExtractor = (value) => value.key; - const disjointSet = new DisjointSet(keyExtractor); - const itemA = { key: 'A', value: 1 }; - const itemB = { key: 'B', value: 2 }; - const itemC = { key: 'C', value: 3 }; - expect(disjointSet.find(itemA)).toBeNull(); - expect(disjointSet.find(itemB)).toBeNull(); - disjointSet.makeSet(itemA); - expect(disjointSet.find(itemA)).toBe('A'); - expect(disjointSet.find(itemB)).toBeNull(); - disjointSet.makeSet(itemB); - expect(disjointSet.find(itemA)).toBe('A'); - expect(disjointSet.find(itemB)).toBe('B'); - disjointSet.makeSet(itemC); - expect(disjointSet.inSameSet(itemA, itemB)).toBe(false); - disjointSet.union(itemA, itemB); - expect(disjointSet.find(itemA)).toBe('A'); - expect(disjointSet.find(itemB)).toBe('A'); - expect(disjointSet.inSameSet(itemA, itemB)).toBe(true); - expect(disjointSet.inSameSet(itemB, itemA)).toBe(true); - expect(disjointSet.inSameSet(itemA, itemC)).toBe(false); - disjointSet.union(itemA, itemC); - expect(disjointSet.find(itemA)).toBe('A'); - expect(disjointSet.find(itemB)).toBe('A'); - expect(disjointSet.find(itemC)).toBe('A'); - expect(disjointSet.inSameSet(itemA, itemB)).toBe(true); - expect(disjointSet.inSameSet(itemB, itemC)).toBe(true); - expect(disjointSet.inSameSet(itemA, itemC)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSetItem.test.js b/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSetItem.test.js deleted file mode 100644 index 6608b5925c..0000000000 --- a/docs/content/DS_ALGO/data-structures/disjoint-set/test/DisjointSetItem.test.js +++ /dev/null @@ -1,86 +0,0 @@ -import DisjointSetItem from '../DisjointSetItem'; -describe('DisjointSetItem', () => { - it('should do basic manipulation with disjoint set item', () => { - const itemA = new DisjointSetItem('A'); - const itemB = new DisjointSetItem('B'); - const itemC = new DisjointSetItem('C'); - const itemD = new DisjointSetItem('D'); - expect(itemA.getRank()).toBe(0); - expect(itemA.getChildren()).toEqual([]); - expect(itemA.getKey()).toBe('A'); - expect(itemA.getRoot()).toEqual(itemA); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(true); - itemA.addChild(itemB); - itemD.setParent(itemC); - expect(itemA.getRank()).toBe(1); - expect(itemC.getRank()).toBe(1); - expect(itemB.getRank()).toBe(0); - expect(itemD.getRank()).toBe(0); - expect(itemA.getChildren().length).toBe(1); - expect(itemC.getChildren().length).toBe(1); - expect(itemA.getChildren()[0]).toEqual(itemB); - expect(itemC.getChildren()[0]).toEqual(itemD); - expect(itemB.getChildren().length).toBe(0); - expect(itemD.getChildren().length).toBe(0); - expect(itemA.getRoot()).toEqual(itemA); - expect(itemB.getRoot()).toEqual(itemA); - expect(itemC.getRoot()).toEqual(itemC); - expect(itemD.getRoot()).toEqual(itemC); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(false); - expect(itemC.isRoot()).toBe(true); - expect(itemD.isRoot()).toBe(false); - itemA.addChild(itemC); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(false); - expect(itemC.isRoot()).toBe(false); - expect(itemD.isRoot()).toBe(false); - expect(itemA.getRank()).toEqual(3); - expect(itemB.getRank()).toEqual(0); - expect(itemC.getRank()).toEqual(1); - }); - it('should do basic manipulation with disjoint set item with custom key extractor', () => { - const keyExtractor = (value) => { - return value.key; - }; - const itemA = new DisjointSetItem({ key: 'A', value: 1 }, keyExtractor); - const itemB = new DisjointSetItem({ key: 'B', value: 2 }, keyExtractor); - const itemC = new DisjointSetItem({ key: 'C', value: 3 }, keyExtractor); - const itemD = new DisjointSetItem({ key: 'D', value: 4 }, keyExtractor); - expect(itemA.getRank()).toBe(0); - expect(itemA.getChildren()).toEqual([]); - expect(itemA.getKey()).toBe('A'); - expect(itemA.getRoot()).toEqual(itemA); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(true); - itemA.addChild(itemB); - itemD.setParent(itemC); - expect(itemA.getRank()).toBe(1); - expect(itemC.getRank()).toBe(1); - expect(itemB.getRank()).toBe(0); - expect(itemD.getRank()).toBe(0); - expect(itemA.getChildren().length).toBe(1); - expect(itemC.getChildren().length).toBe(1); - expect(itemA.getChildren()[0]).toEqual(itemB); - expect(itemC.getChildren()[0]).toEqual(itemD); - expect(itemB.getChildren().length).toBe(0); - expect(itemD.getChildren().length).toBe(0); - expect(itemA.getRoot()).toEqual(itemA); - expect(itemB.getRoot()).toEqual(itemA); - expect(itemC.getRoot()).toEqual(itemC); - expect(itemD.getRoot()).toEqual(itemC); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(false); - expect(itemC.isRoot()).toBe(true); - expect(itemD.isRoot()).toBe(false); - itemA.addChild(itemC); - expect(itemA.isRoot()).toBe(true); - expect(itemB.isRoot()).toBe(false); - expect(itemC.isRoot()).toBe(false); - expect(itemD.isRoot()).toBe(false); - expect(itemA.getRank()).toEqual(3); - expect(itemB.getRank()).toEqual(0); - expect(itemC.getRank()).toEqual(1); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedList.js b/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedList.js deleted file mode 100644 index bc0279d681..0000000000 --- a/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedList.js +++ /dev/null @@ -1,218 +0,0 @@ -import DoublyLinkedListNode from './DoublyLinkedListNode'; -import Comparator from '../../utils/comparator/Comparator'; -export default class DoublyLinkedList { - /** - * @param {Function} [comparatorFunction] - */ - constructor(comparatorFunction) { - /** @var DoublyLinkedListNode */ - this.head = null; - /** @var DoublyLinkedListNode */ - this.tail = null; - this.compare = new Comparator(comparatorFunction); - } - /** - * @param {*} value - * @return {DoublyLinkedList} - */ - prepend(value) { - // Make new node to be a head. - const newNode = new DoublyLinkedListNode(value, this.head); - // If there is head, then it won't be head anymore. - // Therefore, make its previous reference to be new node (new head). - // Then mark the new node as head. - if (this.head) { - this.head.previous = newNode; - } - this.head = newNode; - // If there is no tail yet let's make new node a tail. - if (!this.tail) { - this.tail = newNode; - } - return this; - } - /** - * @param {*} value - * @return {DoublyLinkedList} - */ - append(value) { - const newNode = new DoublyLinkedListNode(value); - // If there is no head yet let's make new node a head. - if (!this.head) { - this.head = newNode; - this.tail = newNode; - return this; - } - // Attach new node to the end of linked list. - this.tail.next = newNode; - // Attach current tail to the new node's previous reference. - newNode.previous = this.tail; - // Set new node to be the tail of linked list. - this.tail = newNode; - return this; - } - /** - * @param {*} value - * @return {DoublyLinkedListNode} - */ - delete(value) { - if (!this.head) { - return null; - } - let deletedNode = null; - let currentNode = this.head; - while (currentNode) { - if (this.compare.equal(currentNode.value, value)) { - deletedNode = currentNode; - if (deletedNode === this.head) { - // If HEAD is going to be deleted... - // Set head to second node, which will become new head. - this.head = deletedNode.next; - // Set new head's previous to null. - if (this.head) { - this.head.previous = null; - } - // If all the nodes in list has same value that is passed as argument - // then all nodes will get deleted, therefore tail needs to be updated. - if (deletedNode === this.tail) { - this.tail = null; - } - } else if (deletedNode === this.tail) { - // If TAIL is going to be deleted... - // Set tail to second last node, which will become new tail. - this.tail = deletedNode.previous; - this.tail.next = null; - } else { - // If MIDDLE node is going to be deleted... - const previousNode = deletedNode.previous; - const nextNode = deletedNode.next; - previousNode.next = nextNode; - nextNode.previous = previousNode; - } - } - currentNode = currentNode.next; - } - return deletedNode; - } - /** - * @param {Object} findParams - * @param {*} findParams.value - * @param {function} [findParams.callback] - * @return {DoublyLinkedListNode} - */ - find({ - value = undefined, - callback = undefined - }) { - if (!this.head) { - return null; - } - let currentNode = this.head; - while (currentNode) { - // If callback is specified then try to find node by callback. - if (callback && callback(currentNode.value)) { - return currentNode; - } - // If value is specified then try to compare by value.. - if (value !== undefined && this.compare.equal(currentNode.value, value)) { - return currentNode; - } - currentNode = currentNode.next; - } - return null; - } - /** - * @return {DoublyLinkedListNode} - */ - deleteTail() { - if (!this.tail) { - // No tail to delete. - return null; - } - if (this.head === this.tail) { - // There is only one node in linked list. - const deletedTail = this.tail; - this.head = null; - this.tail = null; - return deletedTail; - } - // If there are many nodes in linked list... - const deletedTail = this.tail; - this.tail = this.tail.previous; - this.tail.next = null; - return deletedTail; - } - /** - * @return {DoublyLinkedListNode} - */ - deleteHead() { - if (!this.head) { - return null; - } - const deletedHead = this.head; - if (this.head.next) { - this.head = this.head.next; - this.head.previous = null; - } else { - this.head = null; - this.tail = null; - } - return deletedHead; - } - /** - * @return {DoublyLinkedListNode[]} - */ - toArray() { - const nodes = []; - let currentNode = this.head; - while (currentNode) { - nodes.push(currentNode); - currentNode = currentNode.next; - } - return nodes; - } - /** - * @param {*[]} values - Array of values that need to be converted to linked list. - * @return {DoublyLinkedList} - */ - fromArray(values) { - values.forEach((value) => this.append(value)); - return this; - } - /** - * @param {function} [callback] - * @return {string} - */ - toString(callback) { - return this.toArray() - .map((node) => node.toString(callback)) - .toString(); - } - /** - * Reverse a linked list. - * @returns {DoublyLinkedList} - */ - reverse() { - let currNode = this.head; - let prevNode = null; - let nextNode = null; - while (currNode) { - // Store next node. - nextNode = currNode.next; - prevNode = currNode.previous; - // Change next node of the current node so it would link to previous node. - currNode.next = prevNode; - currNode.previous = nextNode; - // Move prevNode and currNode nodes one step forward. - prevNode = currNode; - currNode = nextNode; - } - // Reset head and tail. - this.tail = this.head; - this.head = prevNode; - return this; - } -} -return this; -} -} diff --git a/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedListNode.js b/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedListNode.js deleted file mode 100644 index 0bf5c6f3e2..0000000000 --- a/docs/content/DS_ALGO/data-structures/doubly-linked-list/DoublyLinkedListNode.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class DoublyLinkedListNode { - constructor(value, next = null, previous = null) { - this.value = value; - this.next = next; - this.previous = previous; - } - toString(callback) { - return callback ? callback(this.value) : `${this.value}`; - } -} diff --git a/docs/content/DS_ALGO/data-structures/doubly-linked-list/README.md b/docs/content/DS_ALGO/data-structures/doubly-linked-list/README.md deleted file mode 100644 index 9db8f7d2d0..0000000000 --- a/docs/content/DS_ALGO/data-structures/doubly-linked-list/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# Doubly Linked List - -In computer science, a **doubly linked list** is a linked data structure that -consists of a set of sequentially linked records called nodes. Each node contains -two fields, called links, that are references to the previous and to the next -node in the sequence of nodes. The beginning and ending nodes' previous and next -links, respectively, point to some kind of terminator, typically a sentinel -node or null, to facilitate the traversal of the list. If there is only one -sentinel node, then the list is circularly linked via the sentinel node. It can -be conceptualized as two singly linked lists formed from the same data items, -but in opposite sequential orders. - -![Doubly Linked List](https://upload.wikimedia.org/wikipedia/commons/5/5e/Doubly-linked-list.svg) - -The two node links allow traversal of the list in either direction. While adding -or removing a node in a doubly linked list requires changing more links than the -same operations on a singly linked list, the operations are simpler and -potentially more efficient (for nodes other than first nodes) because there -is no need to keep track of the previous node during traversal or no need -to traverse the list to find the previous node, so that its link can be modified. - -## Pseudocode for Basic Operations - -### Insert - -```text -Add(value) - Pre: value is the value to add to the list - Post: value has been placed at the tail of the list - n ← node(value) - if head = ø - head ← n - tail ← n - else - n.previous ← tail - tail.next ← n - tail ← n - end if -end Add -``` - -### Delete - -```text -Remove(head, value) - Pre: head is the head node in the list - value is the value to remove from the list - Post: value is removed from the list, true; otherwise false - if head = ø - return false - end if - if value = head.value - if head = tail - head ← ø - tail ← ø - else - head ← head.next - head.previous ← ø - end if - return true - end if - n ← head.next - while n != ø and value !== n.value - n ← n.next - end while - if n = tail - tail ← tail.previous - tail.next ← ø - return true - else if n != ø - n.previous.next ← n.next - n.next.previous ← n.previous - return true - end if - return false -end Remove -``` - -### Reverse Traversal - -```text -ReverseTraversal(tail) - Pre: tail is the node of the list to traverse - Post: the list has been traversed in reverse order - n ← tail - while n != ø - yield n.value - n ← n.previous - end while -end Reverse Traversal -``` - -## Complexities - -## Time Complexity - -| Access | Search | Insertion | Deletion | -| :----: | :----: | :-------: | :------: | -| O(n) | O(n) | O(1) | O(n) | - -### Space Complexity - -O(n) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Doubly_linked_list) -- [YouTube](https://www.youtube.com/watch?v=JdQeNxWCguQ&t=7s&index=72&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedList.test.js b/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedList.test.js deleted file mode 100644 index ce755c458a..0000000000 --- a/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedList.test.js +++ /dev/null @@ -1,267 +0,0 @@ -import DoublyLinkedList from '../DoublyLinkedList'; -describe('DoublyLinkedList', () => { - it('should create empty linked list', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.toString()).toBe(''); - }); - it('should append node to linked list', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - linkedList.append(1); - linkedList.append(2); - expect(linkedList.head.next.value).toBe(2); - expect(linkedList.tail.previous.value).toBe(1); - expect(linkedList.toString()).toBe('1,2'); - }); - it('should prepend node to linked list', () => { - const linkedList = new DoublyLinkedList(); - linkedList.prepend(2); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - linkedList.append(1); - linkedList.prepend(3); - expect(linkedList.head.next.next.previous).toBe(linkedList.head.next); - expect(linkedList.tail.previous.next).toBe(linkedList.tail); - expect(linkedList.tail.previous.value).toBe(2); - expect(linkedList.toString()).toBe('3,2,1'); - }); - it('should create linked list from array', () => { - const linkedList = new DoublyLinkedList(); - linkedList.fromArray([1, 1, 2, 3, 3, 3, 4, 5]); - expect(linkedList.toString()).toBe('1,1,2,3,3,3,4,5'); - }); - it('should delete node by value from linked list', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.delete(5)).toBeNull(); - linkedList.append(1); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - linkedList.append(3); - linkedList.append(3); - linkedList.append(4); - linkedList.append(5); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('5'); - const deletedNode = linkedList.delete(3); - expect(deletedNode.value).toBe(3); - expect(linkedList.tail.previous.previous.value).toBe(2); - expect(linkedList.toString()).toBe('1,1,2,4,5'); - linkedList.delete(3); - expect(linkedList.toString()).toBe('1,1,2,4,5'); - linkedList.delete(1); - expect(linkedList.toString()).toBe('2,4,5'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.head.next.next).toBe(linkedList.tail); - expect(linkedList.tail.previous.previous).toBe(linkedList.head); - expect(linkedList.tail.toString()).toBe('5'); - linkedList.delete(5); - expect(linkedList.toString()).toBe('2,4'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('4'); - linkedList.delete(4); - expect(linkedList.toString()).toBe('2'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - expect(linkedList.head).toBe(linkedList.tail); - linkedList.delete(2); - expect(linkedList.toString()).toBe(''); - }); - it('should delete linked list tail', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.deleteTail()).toBeNull(); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('3'); - const deletedNode1 = linkedList.deleteTail(); - expect(deletedNode1.value).toBe(3); - expect(linkedList.toString()).toBe('1,2'); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode2 = linkedList.deleteTail(); - expect(deletedNode2.value).toBe(2); - expect(linkedList.toString()).toBe('1'); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('1'); - const deletedNode3 = linkedList.deleteTail(); - expect(deletedNode3.value).toBe(1); - expect(linkedList.toString()).toBe(''); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - }); - it('should delete linked list head', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.deleteHead()).toBeNull(); - linkedList.append(1); - linkedList.append(2); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode1 = linkedList.deleteHead(); - expect(deletedNode1.value).toBe(1); - expect(linkedList.head.previous).toBeNull(); - expect(linkedList.toString()).toBe('2'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode2 = linkedList.deleteHead(); - expect(deletedNode2.value).toBe(2); - expect(linkedList.toString()).toBe(''); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - }); - it('should be possible to store objects in the list and to print them out', () => { - const linkedList = new DoublyLinkedList(); - const nodeValue1 = { - value: 1, - key: 'key1' - }; - const nodeValue2 = { - value: 2, - key: 'key2' - }; - linkedList.append(nodeValue1).prepend(nodeValue2); - const nodeStringifier = (value) => `${value.key}:${value.value}`; - expect(linkedList.toString(nodeStringifier)).toBe('key2:2,key1:1'); - }); - it('should find node by value', () => { - const linkedList = new DoublyLinkedList(); - expect(linkedList.find({ - value: 5 - })).toBeNull(); - linkedList.append(1); - expect(linkedList.find({ - value: 1 - })).toBeDefined(); - linkedList.append(2).append(3); - const node = linkedList.find({ - value: 2 - }); - expect(node.value).toBe(2); - expect(linkedList.find({ - value: 5 - })).toBeNull(); - }); - it('should find node by callback', () => { - const linkedList = new DoublyLinkedList(); - linkedList.append({ - value: 1, - key: 'test1' - }).append({ - value: 2, - key: 'test2' - }).append({ - value: 3, - key: 'test3' - }); - const node = linkedList.find({ - callback: (value) => value.key === 'test2' - }); - expect(node).toBeDefined(); - expect(node.value.value).toBe(2); - expect(node.value.key).toBe('test2'); - expect(linkedList.find({ - callback: (value) => value.key === 'test5' - })).toBeNull(); - }); - it('should find node by means of custom compare function', () => { - const comparatorFunction = (a, b) => { - if (a.customValue === b.customValue) { - return 0; - } - return a.customValue < b.customValue ? -1 : 1; - }; - const linkedList = new DoublyLinkedList(comparatorFunction); - linkedList.append({ - value: 1, - customValue: 'test1' - }).append({ - value: 2, - customValue: 'test2' - }).append({ - value: 3, - customValue: 'test3' - }); - const node = linkedList.find({ - value: { - value: 2, - customValue: 'test2' - } - }); - expect(node).toBeDefined(); - expect(node.value.value).toBe(2); - expect(node.value.customValue).toBe('test2'); - expect(linkedList.find({ - value: 2, - customValue: 'test5' - })).toBeNull(); - }); - it('should reverse linked list', () => { - const linkedList = new DoublyLinkedList(); - // Add test values to linked list. - linkedList.append(1).append(2).append(3).append(4); - expect(linkedList.toString()).toBe('1,2,3,4'); - expect(linkedList.head.value).toBe(1); - expect(linkedList.tail.value).toBe(4); - // Reverse linked list. - linkedList.reverse(); - expect(linkedList.toString()).toBe('4,3,2,1'); - expect(linkedList.head.previous).toBeNull(); - expect(linkedList.head.value).toBe(4); - expect(linkedList.head.next.value).toBe(3); - expect(linkedList.head.next.next.value).toBe(2); - expect(linkedList.head.next.next.next.value).toBe(1); - expect(linkedList.tail.next).toBeNull(); - expect(linkedList.tail.value).toBe(1); - expect(linkedList.tail.previous.value).toBe(2); - expect(linkedList.tail.previous.previous.value).toBe(3); - expect(linkedList.tail.previous.previous.previous.value).toBe(4); - // Reverse linked list back to initial state. - linkedList.reverse(); - expect(linkedList.toString()).toBe('1,2,3,4'); - expect(linkedList.head.previous).toBeNull(); - expect(linkedList.head.value).toBe(1); - expect(linkedList.head.next.value).toBe(2); - expect(linkedList.head.next.next.value).toBe(3); - expect(linkedList.head.next.next.next.value).toBe(4); - expect(linkedList.tail.next).toBeNull(); - expect(linkedList.tail.value).toBe(4); - expect(linkedList.tail.previous.value).toBe(3); - expect(linkedList.tail.previous.previous.value).toBe(2); - expect(linkedList.tail.previous.previous.previous.value).toBe(1); - }); -}); -// Add test values to linked list. -linkedList.append(1).append(2).append(3).append(4); -expect(linkedList.toString()).toBe('1,2,3,4'); -expect(linkedList.head.value).toBe(1); -expect(linkedList.tail.value).toBe(4); -// Reverse linked list. -linkedList.reverse(); -expect(linkedList.toString()).toBe('4,3,2,1'); -expect(linkedList.head.previous).toBeNull(); -expect(linkedList.head.value).toBe(4); -expect(linkedList.head.next.value).toBe(3); -expect(linkedList.head.next.next.value).toBe(2); -expect(linkedList.head.next.next.next.value).toBe(1); -expect(linkedList.tail.next).toBeNull(); -expect(linkedList.tail.value).toBe(1); -expect(linkedList.tail.previous.value).toBe(2); -expect(linkedList.tail.previous.previous.value).toBe(3); -expect(linkedList.tail.previous.previous.previous.value).toBe(4); -// Reverse linked list back to initial state. -linkedList.reverse(); -expect(linkedList.toString()).toBe('1,2,3,4'); -expect(linkedList.head.previous).toBeNull(); -expect(linkedList.head.value).toBe(1); -expect(linkedList.head.next.value).toBe(2); -expect(linkedList.head.next.next.value).toBe(3); -expect(linkedList.head.next.next.next.value).toBe(4); -expect(linkedList.tail.next).toBeNull(); -expect(linkedList.tail.value).toBe(4); -expect(linkedList.tail.previous.value).toBe(3); -expect(linkedList.tail.previous.previous.value).toBe(2); -expect(linkedList.tail.previous.previous.previous.value).toBe(1); -}); -}); diff --git a/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedListNode.test.js b/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedListNode.test.js deleted file mode 100644 index 010019d51a..0000000000 --- a/docs/content/DS_ALGO/data-structures/doubly-linked-list/test/DoublyLinkedListNode.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import DoublyLinkedListNode from '../DoublyLinkedListNode'; -describe('DoublyLinkedListNode', () => { - it('should create list node with value', () => { - const node = new DoublyLinkedListNode(1); - expect(node.value).toBe(1); - expect(node.next).toBeNull(); - expect(node.previous).toBeNull(); - }); - it('should create list node with object as a value', () => { - const nodeValue = { value: 1, key: 'test' }; - const node = new DoublyLinkedListNode(nodeValue); - expect(node.value.value).toBe(1); - expect(node.value.key).toBe('test'); - expect(node.next).toBeNull(); - expect(node.previous).toBeNull(); - }); - it('should link nodes together', () => { - const node2 = new DoublyLinkedListNode(2); - const node1 = new DoublyLinkedListNode(1, node2); - const node3 = new DoublyLinkedListNode(10, node1, node2); - expect(node1.next).toBeDefined(); - expect(node1.previous).toBeNull(); - expect(node2.next).toBeNull(); - expect(node2.previous).toBeNull(); - expect(node3.next).toBeDefined(); - expect(node3.previous).toBeDefined(); - expect(node1.value).toBe(1); - expect(node1.next.value).toBe(2); - expect(node3.next.value).toBe(1); - expect(node3.previous.value).toBe(2); - }); - it('should convert node to string', () => { - const node = new DoublyLinkedListNode(1); - expect(node.toString()).toBe('1'); - node.value = 'string value'; - expect(node.toString()).toBe('string value'); - }); - it('should convert node to string with custom stringifier', () => { - const nodeValue = { value: 1, key: 'test' }; - const node = new DoublyLinkedListNode(nodeValue); - const toStringCallback = (value) => `value: ${value.value}, key: ${value.key}`; - expect(node.toString(toStringCallback)).toBe('value: 1, key: test'); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/Graph.js b/docs/content/DS_ALGO/data-structures/graph/Graph.js deleted file mode 100644 index d2749a062d..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graph.js +++ /dev/null @@ -1,169 +0,0 @@ -export default class Graph { - /** - * @param {boolean} isDirected - */ - constructor(isDirected = false) { - this.vertices = {}; - this.edges = {}; - this.isDirected = isDirected; - } - /** - * @param {GraphVertex} newVertex - * @returns {Graph} - */ - addVertex(newVertex) { - this.vertices[newVertex.getKey()] = newVertex; - return this; - } - /** - * @param {string} vertexKey - * @returns GraphVertex - */ - getVertexByKey(vertexKey) { - return this.vertices[vertexKey]; - } - /** - * @param {GraphVertex} vertex - * @returns {GraphVertex[]} - */ - getNeighbors(vertex) { - return vertex.getNeighbors(); - } - /** - * @return {GraphVertex[]} - */ - getAllVertices() { - return Object.values(this.vertices); - } - /** - * @return {GraphEdge[]} - */ - getAllEdges() { - return Object.values(this.edges); - } - /** - * @param {GraphEdge} edge - * @returns {Graph} - */ - addEdge(edge) { - // Try to find and end start vertices. - let startVertex = this.getVertexByKey(edge.startVertex.getKey()); - let endVertex = this.getVertexByKey(edge.endVertex.getKey()); - // Insert start vertex if it wasn't inserted. - if (!startVertex) { - this.addVertex(edge.startVertex); - startVertex = this.getVertexByKey(edge.startVertex.getKey()); - } - // Insert end vertex if it wasn't inserted. - if (!endVertex) { - this.addVertex(edge.endVertex); - endVertex = this.getVertexByKey(edge.endVertex.getKey()); - } - // Check if edge has been already added. - if (this.edges[edge.getKey()]) { - throw new Error('Edge has already been added before'); - } else { - this.edges[edge.getKey()] = edge; - } - // Add edge to the vertices. - if (this.isDirected) { - // If graph IS directed then add the edge only to start vertex. - startVertex.addEdge(edge); - } else { - // If graph ISN'T directed then add the edge to both vertices. - startVertex.addEdge(edge); - endVertex.addEdge(edge); - } - return this; - } - /** - * @param {GraphEdge} edge - */ - deleteEdge(edge) { - // Delete edge from the list of edges. - if (this.edges[edge.getKey()]) { - delete this.edges[edge.getKey()]; - } else { - throw new Error('Edge not found in graph'); - } - // Try to find and end start vertices and delete edge from them. - const startVertex = this.getVertexByKey(edge.startVertex.getKey()); - const endVertex = this.getVertexByKey(edge.endVertex.getKey()); - startVertex.deleteEdge(edge); - endVertex.deleteEdge(edge); - } - /** - * @param {GraphVertex} startVertex - * @param {GraphVertex} endVertex - * @return {(GraphEdge|null)} - */ - findEdge(startVertex, endVertex) { - const vertex = this.getVertexByKey(startVertex.getKey()); - if (!vertex) { - return null; - } - return vertex.findEdge(endVertex); - } - /** - * @return {number} - */ - getWeight() { - return this.getAllEdges().reduce((weight, graphEdge) => { - return weight + graphEdge.weight; - }, 0); - } - /** - * Reverse all the edges in directed graph. - * @return {Graph} - */ - reverse() { - /** @param {GraphEdge} edge */ - this.getAllEdges().forEach((edge) => { - // Delete straight edge from graph and from vertices. - this.deleteEdge(edge); - // Reverse the edge. - edge.reverse(); - // Add reversed edge back to the graph and its vertices. - this.addEdge(edge); - }); - return this; - } - /** - * @return {object} - */ - getVerticesIndices() { - const verticesIndices = {}; - this.getAllVertices().forEach((vertex, index) => { - verticesIndices[vertex.getKey()] = index; - }); - return verticesIndices; - } - /** - * @return {*[][]} - */ - getAdjacencyMatrix() { - const vertices = this.getAllVertices(); - const verticesIndices = this.getVerticesIndices(); - // Init matrix with infinities meaning that there is no ways of - // getting from one vertex to another yet. - const adjacencyMatrix = Array(vertices.length) - .fill(null) - .map(() => { - return Array(vertices.length).fill(Infinity); - }); - // Fill the columns. - vertices.forEach((vertex, vertexIndex) => { - vertex.getNeighbors().forEach((neighbor) => { - const neighborIndex = verticesIndices[neighbor.getKey()]; - adjacencyMatrix[vertexIndex][neighborIndex] = this.findEdge(vertex, neighbor).weight; - }); - }); - return adjacencyMatrix; - } - /** - * @return {string} - */ - toString() { - return Object.keys(this.vertices).toString(); - } -} diff --git a/docs/content/DS_ALGO/data-structures/graph/GraphEdge.js b/docs/content/DS_ALGO/data-structures/graph/GraphEdge.js deleted file mode 100644 index a47a7ad980..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/GraphEdge.js +++ /dev/null @@ -1,35 +0,0 @@ -export default class GraphEdge { - /** - * @param {GraphVertex} startVertex - * @param {GraphVertex} endVertex - * @param {number} [weight=1] - */ - constructor(startVertex, endVertex, weight = 0) { - this.startVertex = startVertex; - this.endVertex = endVertex; - this.weight = weight; - } - /** - * @return {string} - */ - getKey() { - const startVertexKey = this.startVertex.getKey(); - const endVertexKey = this.endVertex.getKey(); - return `${startVertexKey}_${endVertexKey}`; - } - /** - * @return {GraphEdge} - */ - reverse() { - const tmp = this.startVertex; - this.startVertex = this.endVertex; - this.endVertex = tmp; - return this; - } - /** - * @return {string} - */ - toString() { - return this.getKey(); - } -} diff --git a/docs/content/DS_ALGO/data-structures/graph/GraphVertex.js b/docs/content/DS_ALGO/data-structures/graph/GraphVertex.js deleted file mode 100644 index 68b97828ef..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/GraphVertex.js +++ /dev/null @@ -1,119 +0,0 @@ -import LinkedList from '../linked-list/LinkedList'; -export default class GraphVertex { - /** - * @param {*} value - */ - constructor(value) { - if (value === undefined) { - throw new Error('Graph vertex must have a value'); - } - /** - * @param {GraphEdge} edgeA - * @param {GraphEdge} edgeB - */ - const edgeComparator = (edgeA, edgeB) => { - if (edgeA.getKey() === edgeB.getKey()) { - return 0; - } - return edgeA.getKey() < edgeB.getKey() ? -1 : 1; - }; - // Normally you would store string value like vertex name. - // But generally it may be any object as well - this.value = value; - this.edges = new LinkedList(edgeComparator); - } - /** - * @param {GraphEdge} edge - * @returns {GraphVertex} - */ - addEdge(edge) { - this.edges.append(edge); - return this; - } - /** - * @param {GraphEdge} edge - */ - deleteEdge(edge) { - this.edges.delete(edge); - } - /** - * @returns {GraphVertex[]} - */ - getNeighbors() { - const edges = this.edges.toArray(); - /** @param {LinkedListNode} node */ - const neighborsConverter = (node) => { - return node.value.startVertex === this ? node.value.endVertex : node.value.startVertex; - }; - // Return either start or end vertex. - // For undirected graphs it is possible that current vertex will be the end one. - return edges.map(neighborsConverter); - } - /** - * @return {GraphEdge[]} - */ - getEdges() { - return this.edges.toArray().map((linkedListNode) => linkedListNode.value); - } - /** - * @return {number} - */ - getDegree() { - return this.edges.toArray().length; - } - /** - * @param {GraphEdge} requiredEdge - * @returns {boolean} - */ - hasEdge(requiredEdge) { - const edgeNode = this.edges.find({ - callback: (edge) => edge === requiredEdge - }); - return !!edgeNode; - } - /** - * @param {GraphVertex} vertex - * @returns {boolean} - */ - hasNeighbor(vertex) { - const vertexNode = this.edges.find({ - callback: (edge) => edge.startVertex === vertex || edge.endVertex === vertex - }); - return !!vertexNode; - } - /** - * @param {GraphVertex} vertex - * @returns {(GraphEdge|null)} - */ - findEdge(vertex) { - const edgeFinder = (edge) => { - return edge.startVertex === vertex || edge.endVertex === vertex; - }; - const edge = this.edges.find({ - callback: edgeFinder - }); - return edge ? edge.value : null; - } - /** - * @returns {string} - */ - getKey() { - return this.value; - } - /** - * @return {GraphVertex} - */ - deleteAllEdges() { - this.getEdges().forEach((edge) => this.deleteEdge(edge)); - return this; - } - /** - * @param {function} [callback] - * @returns {string} - */ - toString(callback) { - return callback ? callback(this.value) : `${this.value}`; - } -} -} -} diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/BellmanFord.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/BellmanFord.js deleted file mode 100644 index 7e3b5f611a..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/BellmanFord.js +++ /dev/null @@ -1,56 +0,0 @@ -/* -The Bellman-Ford algorithm is an algorithm that computes shortest paths -from a single source vertex to all of the other vertices in a weighted digraph. -It also detects negative weight cycle. -Complexity: - Worst-case performance O(VE) - Best-case performance O(E) - Worst-case space complexity O(V) -Reference: - https://en.wikipedia.org/wiki/Bellman-Ford_algorithm - https://cp-algorithms.com/graph/bellman_ford.html -*/ -/** - * - * @param graph Graph in the format (u, v, w) where - * the edge is from vertex u to v. And weight - * of the edge is w. - * @param V Number of vertices in graph - * @param E Number of edges in graph - * @param src Starting node - * @param dest Destination node - * @returns Shortest distance from source to destination - */ -function BellmanFord(graph, V, E, src, dest) { - // Initialize distance of all vertices as infinite. - const dis = Array(V).fill(Infinity); - // initialize distance of source as 0 - dis[src] = 0; - // Relax all edges |V| - 1 times. A simple - // shortest path from src to any other - // vertex can have at-most |V| - 1 edges - for (let i = 0; i < V - 1; i++) { - for (let j = 0; j < E; j++) { - if (dis[graph[j][0]] + graph[j][2] < dis[graph[j][1]]) { - dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2]; - } - } - } - // check for negative-weight cycles. - for (let i = 0; i < E; i++) { - const x = graph[i][0]; - const y = graph[i][1]; - const weight = graph[i][2]; - if (dis[x] !== Infinity && dis[x] + weight < dis[y]) { - return null; - } - } - for (let i = 0; i < V; i++) { - if (i === dest) return dis[i]; - } -} -export { - BellmanFord -}; -BellmanFord -}; diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstSearch.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstSearch.js deleted file mode 100644 index 0a0ee37861..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstSearch.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Breadth-first search is an algorithm for traversing a graph. - * - * It discovers all nodes reachable from the starting position by exploring all of the neighbor nodes at the present - * depth prior to moving on to the nodes at the next depth level. - * - * (description adapted from https://en.wikipedia.org/wiki/Breadth-first_search) - * @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core - */ -export function breadthFirstSearch(graph, startingNode) { - // visited keeps track of all nodes visited - const visited = new Set(); - // queue contains the nodes to be explored in the future - const queue = [startingNode]; - while (queue.length > 0) { - // start with the queue's first node - const node = queue.shift(); - if (!visited.has(node)) { - // mark the node as visited - visited.add(node); - const neighbors = graph[node]; - // put all its neighbors into the queue - for (let i = 0; i < neighbors.length; i++) { - queue.push(neighbors[i]); - } - } - } - return visited; -} diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstShortestPath.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstShortestPath.js deleted file mode 100644 index 216998ea5e..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/BreadthFirstShortestPath.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Breadth-first approach can be applied to determine the shortest path between two nodes in an equi-weighted graph. - * - * It searches the target node among all neighbors of the starting node, then the process is repeated on the level of - * the neighbors of the neighbors and so on. - * - * @see https://en.wikipedia.org/wiki/Breadth-first_search - * @see https://www.koderdojo.com/blog/breadth-first-search-and-shortest-path-in-csharp-and-net-core - */ -export function breadthFirstShortestPath(graph, startNode, targetNode) { - // check if startNode & targetNode are identical - if (startNode === targetNode) { - return [startNode]; - } - // visited keeps track of all nodes visited - const visited = new Set(); - // queue contains the paths to be explored in the future - const initialPath = [startNode]; - const queue = [initialPath]; - while (queue.length > 0) { - // start with the queue's first path - const path = queue.shift(); - const node = path[path.length - 1]; - // explore this node if it hasn't been visited yet - if (!visited.has(node)) { - // mark the node as visited - visited.add(node); - const neighbors = graph[node]; - // create a new path in the queue for each neighbor - for (let i = 0; i < neighbors.length; i++) { - const newPath = path.concat([neighbors[i]]); - // the first path to contain the target node is the shortest path - if (neighbors[i] === targetNode) { - return newPath; - } - // queue the new path - queue.push(newPath); - } - } - } - // the target node was not reachable - return []; -} diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/ConnectedComponents.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/ConnectedComponents.js deleted file mode 100644 index a7ccd4208a..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/ConnectedComponents.js +++ /dev/null @@ -1,62 +0,0 @@ -class GraphUnweightedUndirectedAdjacencyList { - // Unweighted Undirected Graph class - constructor() { - this.connections = {}; - } - addNode(node) { - // Function to add a node to the graph (connection represented by set) - this.connections[node] = new Set(); - } - addEdge(node1, node2) { - // Function to add an edge (adds the node too if they are not present in the graph) - if (!(node1 in this.connections)) { - this.addNode(node1); - } - if (!(node2 in this.connections)) { - this.addNode(node2); - } - this.connections[node1].add(node2); - this.connections[node2].add(node1); - } - DFSComponent(components, node, visited) { - // Helper function to populate the visited set with the nodes in each component - // adding the first visited node in the component to the array - components.push(node); - const stack = [node]; - // populating the visited set using DFS (Iterative) - while (stack.length > 0) { - const curr = stack.pop(); - visited.add(curr.toString()); - for (const neighbour of this.connections[curr].keys()) { - if (!visited.has(neighbour.toString())) { - stack.push(neighbour); - } - } - } - } - connectedComponents() { - // Function to generate the Connected Components - // Result is an array containing 1 node from each component - const visited = new Set(); - const components = []; - for (const node of Object.keys(this.connections)) { - if (!visited.has(node.toString())) { - this.DFSComponent(components, node, visited); - } - } - return components; - } -} - -export { - GraphUnweightedUndirectedAdjacencyList -}; - -// Example -// const graph = new GraphUnweightedUndirectedAdjacencyList() -// graph.addEdge(1, 2) // Component 1 -// graph.addEdge(3, 4) // Component 2 -// graph.addEdge(3, 5) // Component 2 -// const components = graph.connectedComponents() -// graph.addEdge(3, 5) // Component 2 -// const components = graph.connectedComponents() \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/Density.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/Density.js deleted file mode 100644 index 78f65cf41e..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/Density.js +++ /dev/null @@ -1,10 +0,0 @@ -/* -The density of a network is a measure of how many edges exist proportional to -how many edges would exist in a complete network (where all possible edges). -https://networkx.org/documentation/networkx-1.9/reference/generated/networkx.classes.function.density.html -*/ -function density(numberOfNodes, numberOfEdges, isDirected = false) { - const multi = isDirected ? 1 : 2; - return (multi * numberOfEdges) / (numberOfNodes * (numberOfNodes - 1)); -} -export { density }; diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchIterative.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchIterative.js deleted file mode 100644 index 0d106dadbe..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchIterative.js +++ /dev/null @@ -1,57 +0,0 @@ -class GraphUnweightedUndirected { - // Unweighted Undirected Graph class - constructor() { - this.connections = {}; - } - addNode(node) { - // Function to add a node to the graph (connection represented by set) - this.connections[node] = new Set(); - } - addEdge(node1, node2) { - // Function to add an edge (adds the node too if they are not present in the graph) - if (!(node1 in this.connections)) { - this.addNode(node1); - } - if (!(node2 in this.connections)) { - this.addNode(node2); - } - this.connections[node1].add(node2); - this.connections[node2].add(node1); - } - DFSIterative(node, value) { - // DFS Function to search if a node with the given value is present in the graph - const stack = [node]; - const visited = new Set(); - while (stack.length > 0) { - const currNode = stack.pop(); - // if the current node contains the value being searched for, true is returned - if (currNode === value) { - return true; - } - // adding the current node to the visited set - visited.add(currNode); - // adding neighbours in the stack - for (const neighbour of this.connections[currNode]) { - if (!visited.has(neighbour)) { - stack.push(neighbour); - } - } - } - return false; - } -} - -export { - GraphUnweightedUndirected -}; - -// Example -// const graph = new GraphUnweightedUndirected() -// graph.addEdge(1, 2) -// graph.addEdge(2, 3) -// graph.addEdge(2, 4) -// graph.addEdge(3, 5) -// graph.DFSIterative(5, 1) -// graph.DFSIterative(5, 100) -// graph.DFSIterative(5, 1) -// graph.DFSIterative(5, 100) \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchRecursive.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchRecursive.js deleted file mode 100644 index 1861f206a3..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/DepthFirstSearchRecursive.js +++ /dev/null @@ -1,53 +0,0 @@ -class GraphUnweightedUndirected { - // Unweighted Undirected Graph class - constructor() { - this.connections = {}; - } - addNode(node) { - // Function to add a node to the graph (connection represented by set) - this.connections[node] = new Set(); - } - addEdge(node1, node2) { - // Function to add an edge (adds the node too if they are not present in the graph) - if (!(node1 in this.connections)) { - this.addNode(node1); - } - if (!(node2 in this.connections)) { - this.addNode(node2); - } - this.connections[node1].add(node2); - this.connections[node2].add(node1); - } - DFSRecursive(node, value, visited = new Set()) { - // DFS Function to search if a node with the given value is present in the graph - // checking if the searching node has been found - if (node === value) { - return true; - } - // adding the current node to the visited set - visited.add(node); - // calling the helper function recursively for all unvisited nodes - for (const neighbour of this.connections[node]) { - if (!visited.has(neighbour)) { - if (this.DFSRecursive(neighbour, value, visited)) { - return true; - } - } - } - return false; - } -} - -export { - GraphUnweightedUndirected -}; - -// const graph = new GraphUnweightedUndirected() -// graph.addEdge(1, 2) -// graph.addEdge(2, 3) -// graph.addEdge(2, 4) -// graph.addEdge(3, 5) -// graph.DFSRecursive(5, 1) -// graph.DFSRecursive(5, 100) -// graph.DFSRecursive(5, 1) -// graph.DFSRecursive(5, 100) \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/Dijkstra.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/Dijkstra.js deleted file mode 100644 index aa92e06e2b..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/Dijkstra.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Author: Samarth Jain - * Dijkstra's Algorithm implementation in JavaScript - * Dijkstra's Algorithm calculates the minimum distance between two nodes. - * It is used to find the shortest path. - * It uses graph data structure. - */ -function createGraph(V, E) { - // V - Number of vertices in graph - // E - Number of edges in graph (u,v,w) - const adjList = []; // Adjacency list - for (let i = 0; i < V; i++) { - adjList.push([]); - } - for (let i = 0; i < E.length; i++) { - adjList[E[i][0]].push([E[i][1], E[i][2]]); - adjList[E[i][1]].push([E[i][0], E[i][2]]); - } - return adjList; -} -function djikstra(graph, V, src) { - const vis = Array(V).fill(0); - const dist = []; - for (let i = 0; i < V; i++) dist.push([10000, -1]); - dist[src][0] = 0; - for (let i = 0; i < V - 1; i++) { - let mn = -1; - for (let j = 0; j < V; j++) { - if (vis[j] === 0) { - if (mn === -1 || dist[j][0] < dist[mn][0]) mn = j; - } - } - vis[mn] = 1; - for (let j = 0; j < graph[mn].length; j++) { - const edge = graph[mn][j]; - if (vis[edge[0]] === 0 && dist[edge[0]][0] > dist[mn][0] + edge[1]) { - dist[edge[0]][0] = dist[mn][0] + edge[1]; - dist[edge[0]][1] = mn; - } - } - } - return dist; -} -export { - createGraph, - djikstra -}; -// const V = 9 -// const E = [ -// [0, 1, 4], -// [0, 7, 8], -// [1, 7, 11], -// [1, 2, 8], -// [7, 8, 7], -// [6, 7, 1], -// [2, 8, 2], -// [6, 8, 6], -// [5, 6, 2], -// [2, 5, 4], -// [2, 3, 7], -// [3, 5, 14], -// [3, 4, 9], -// [4, 5, 10] -// ] -// const graph = createGraph(V, E) -// const distances = djikstra(graph, V, 0) -/** - * The first value in the array determines the minimum distance and the - * second value represents the parent node from which the minimum distance has been calculated - */ -* The first value in the array determines the minimum distance and the * - second value represents the parent node from which the minimum distance has been calculated * - - / / diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/DijkstraSmallestPath.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/DijkstraSmallestPath.js deleted file mode 100644 index 8093d2f56f..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/DijkstraSmallestPath.js +++ /dev/null @@ -1,105 +0,0 @@ -// starting at s -function solve(graph, s) { - const solutions = {}; - solutions[s] = []; - solutions[s].dist = 0; - while (true) { - let p = null; - let neighbor = null; - let dist = Infinity; - for (const n in solutions) { - if (!solutions[n]) { - continue; - } - const ndist = solutions[n].dist; - const adj = graph[n]; - for (const a in adj) { - if (solutions[a]) { - continue; - } - const d = adj[a] + ndist; - if (d < dist) { - p = solutions[n]; - neighbor = a; - dist = d; - } - } - } - // no more solutions - if (dist === Infinity) { - break; - } - // extend parent's solution path - solutions[neighbor] = p.concat(neighbor); - // extend parent's cost - solutions[neighbor].dist = dist; - } - return solutions; -} - -export { - solve -}; - -// // create graph -// const graph = {} -// const layout = { -// R: ['2'], -// 2: ['3', '4'], -// 3: ['4', '6', '13'], -// 4: ['5', '8'], -// 5: ['7', '11'], -// 6: ['13', '15'], -// 7: ['10'], -// 8: ['11', '13'], -// 9: ['14'], -// 10: [], -// 11: ['12'], -// 12: [], -// 13: ['14'], -// 14: [], -// 15: [] -// } -// // convert uni-directional to bi-directional graph -// let graph = { -// a: {e:1, b:1, g:3}, -// b: {a:1, c:1}, -// c: {b:1, d:1}, -// d: {c:1, e:1}, -// e: {d:1, a:1}, -// f: {g:1, h:1}, -// g: {a:3, f:1}, -// h: {f:1} -// }; -// for (const id in layout) { -// if (!graph[id]) { graph[id] = {} } -// layout[id].forEach(function (aid) { -// graph[id][aid] = 1 -// if (!graph[aid]) { graph[aid] = {} } -// graph[aid][id] = 1 -// }) -// } -// // choose start node -// const start = '10' -// // get all solutions -// const solutions = solve(graph, start) -// // for s in solutions.. -// ' -> ' + s + ': [' + solutions[s].join(', ') + '] (dist:' + solutions[s].dist + ')' -// From '10' to -// -> 2: [7, 5, 4, 2] (dist:4) -// -> 3: [7, 5, 4, 3] (dist:4) -// -> 4: [7, 5, 4] (dist:3) -// -> 5: [7, 5] (dist:2) -// -> 6: [7, 5, 4, 3, 6] (dist:5) -// -> 7: [7] (dist:1) -// -> 8: [7, 5, 4, 8] (dist:4) -// -> 9: [7, 5, 4, 3, 13, 14, 9] (dist:7) -// -> 10: [] (dist:0) -// -> 11: [7, 5, 11] (dist:3) -// -> 12: [7, 5, 11, 12] (dist:4) -// -> 13: [7, 5, 4, 3, 13] (dist:5) -// -> 14: [7, 5, 4, 3, 13, 14] (dist:6) -// -> 15: [7, 5, 4, 3, 6, 15] (dist:6) -// -> R: [7, 5, 4, 2, R] (dist:5) -// -> 15: [7, 5, 4, 3, 6, 15] (dist:6) -// -> R: [7, 5, 4, 2, R] (dist:5) \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/FloydWarshall.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/FloydWarshall.js deleted file mode 100644 index b1401a696b..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/FloydWarshall.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - Source: - https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm - Complexity: - O(|V|^3) where V is the set of vertices -*/ -const FloydWarshall = (dist) => { - // Input:- dist: 2D Array where dist[i][j] = edge weight b/w i and j - // Output:- dist: 2D Array where dist[i][j] = shortest dist b/w i and j - const n = dist.length; - for (let k = 0; k < n; k++) { - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - if (dist[i][j] > dist[i][k] + dist[k][j]) { - // dist from i to j via k is lesser than the current distance - dist[i][j] = dist[i][k] + dist[k][j]; - } - } - } - } - return dist; -}; - -export { - FloydWarshall -}; - -// For the following graph (edge weights are shown in brackets) -// 4 1 dist[1][2] = dist[2][1] = 1 -// \ (2)/ \ dist[1][3] = dist[3][1] = 2 -// \ / \(1) dist[1][4] = dist[4][1] = Infinity -// (1)\ / \ dist[3][4] = dist[4][3] = 1 -// 3 2 dist[2][4] = dist[4][2] = Infinity -// dist[2][3] = dist[3][2] = Infinity -// Output should be: -// [ [0, 1, 2, 3], -// [1, 0, 3, 4], -// [2, 3, 0, 1], -// [3, 4, 1, 0] ] -// FloydWarshall( -// [[0, 1, 2, Infinity], -// [1, 0, Infinity, Infinity], -// [2, Infinity, 0, 1], -// [Infinity, Infinity, 1, 0] -// ] -// ) -// ] -// ) \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/KruskalMST.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/KruskalMST.js deleted file mode 100644 index 2d2b1caf30..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/KruskalMST.js +++ /dev/null @@ -1,111 +0,0 @@ -class DisjointSetTreeNode { - // Disjoint Set Node to store the parent and rank - constructor(key) { - this.key = key; - this.parent = this; - this.rank = 0; - } -} -class DisjointSetTree { - // Disjoint Set DataStructure - constructor() { - // map to from node name to the node object - this.map = {}; - } - makeSet(x) { - // Function to create a new set with x as its member - this.map[x] = new DisjointSetTreeNode(x); - } - findSet(x) { - // Function to find the set x belongs to (with path-compression) - if (this.map[x] !== this.map[x].parent) { - this.map[x].parent = this.findSet(this.map[x].parent.key); - } - return this.map[x].parent; - } - union(x, y) { - // Function to merge 2 disjoint sets - this.link(this.findSet(x), this.findSet(y)); - } - link(x, y) { - // Helper function for union operation - if (x.rank > y.rank) { - y.parent = x; - } else { - x.parent = y; - if (x.rank === y.rank) { - y.rank += 1; - } - } - } -} -class GraphWeightedUndirectedAdjacencyList { - // Weighted Undirected Graph class - constructor() { - this.connections = {}; - this.nodes = 0; - } - addNode(node) { - // Function to add a node to the graph (connection represented by set) - this.connections[node] = {}; - this.nodes += 1; - } - addEdge(node1, node2, weight) { - // Function to add an edge (adds the node too if they are not present in the graph) - if (!(node1 in this.connections)) { - this.addNode(node1); - } - if (!(node2 in this.connections)) { - this.addNode(node2); - } - this.connections[node1][node2] = weight; - this.connections[node2][node1] = weight; - } - KruskalMST() { - // Kruskal's Algorithm to generate a Minimum Spanning Tree (MST) of a graph - // Details: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm - // getting the edges in ascending order of weights - const edges = []; - const seen = new Set(); - for (const start of Object.keys(this.connections)) { - for (const end of Object.keys(this.connections[start])) { - if (!seen.has(`${start} ${end}`)) { - seen.add(`${end} ${start}`); - edges.push([start, end, this.connections[start][end]]); - } - } - } - edges.sort((a, b) => a[2] - b[2]); - // creating the disjoint set - const disjointSet = new DisjointSetTree(); - Object.keys(this.connections).forEach((node) => disjointSet.makeSet(node)); - // MST generation - const graph = new GraphWeightedUndirectedAdjacencyList(); - let numEdges = 0; - let index = 0; - while (numEdges < this.nodes - 1) { - const [u, v, w] = edges[index]; - index += 1; - if (disjointSet.findSet(u) !== disjointSet.findSet(v)) { - numEdges += 1; - graph.addEdge(u, v, w); - disjointSet.union(u, v); - } - } - return graph; - } -} - -export { - GraphWeightedUndirectedAdjacencyList -}; - -// const graph = new GraphWeightedUndirectedAdjacencyList() -// graph.addEdge(1, 2, 1) -// graph.addEdge(2, 3, 2) -// graph.addEdge(3, 4, 1) -// graph.addEdge(3, 5, 100) // Removed in MST -// graph.addEdge(4, 5, 5) -// graph.KruskalMST() -// graph.addEdge(4, 5, 5) -// graph.KruskalMST() \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/NodeNeighbors.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/NodeNeighbors.js deleted file mode 100644 index 0b06ca8a37..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/NodeNeighbors.js +++ /dev/null @@ -1,40 +0,0 @@ -// https://en.wikipedia.org/wiki/Neighbourhood_(graph_theory) -class Graph { - // Generic graph: the algorithm works regardless of direction or weight - constructor() { - this.edges = []; - } - addEdge(node1, node2) { - // Adding edges to the graph - this.edges.push({ - node1, - node2 - }); - } - nodeNeighbors(node) { - // Returns an array with all of the node neighbors - const neighbors = new Set(); - for (const edge of this.edges) { - // Checks if they have an edge between them and if the neighbor is not - // already in the neighbors array - if (edge.node1 === node && !neighbors.has(edge.node2)) { - neighbors.add(edge.node2); - } else if (edge.node2 === node && !neighbors.has(edge.node1)) {} - neighbors.add(edge.node1); - } - } - return neighbors; -} -} -export { - Graph -}; -// const graph = new Graph() -// graph.addEdge(1, 2) -// graph.addEdge(2, 3) -// graph.addEdge(3, 5) -// graph.addEdge(1, 5) -// graph.nodeNeighbors(1) -// graph.addEdge(3, 5) -// graph.addEdge(1, 5) -// graph.nodeNeighbors(1) diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/NumberOfIslands.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/NumberOfIslands.js deleted file mode 100644 index f76810ec1f..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/NumberOfIslands.js +++ /dev/null @@ -1,76 +0,0 @@ -/* Number of Islands -https://dev.to/rattanakchea/amazons-interview-question-count-island-21h6 -Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. -a two dimensional grid map -each element is going to represent a piece of land -1 is land, -0 is water -output a number which is the number of islands -Example 1: - Input: - 11110 - 11010 - 11000 - 00000 - Output: 1 -Example 2: - Input: - 11000 - 11000 - 00100 - 00011 - Output: 3 -I: two dimensional array -O: a single integer; total number of islands -Pseudocode: - OUTER FUNCTION - set count to 0 - INNER FUNCTION - flood (col, row) - if the tile is water - return - make tile water(flood tile) - invoke flood on the neighbor coordinates - iterate over the matrix (col, row) - if the current element is a 1 - increment count - invoke flood (coordinates for col and row) - Return the count -*/ -const islands = (matrixGrid) => { - const matrix = matrixGrid; - let counter = 0; - const flood = (row, col) => { - if (row < 0 || col < 0) return; // Off the map above or left - if (row >= matrix.length || col >= matrix[row].length) return; // Off the map below or right - const tile = matrix[row][col]; - if (tile !== '1') return; - matrix[row][col] = '0'; - flood(row + 1, col); // Down - flood(row - 1, col); // Up - flood(row, col + 1); // Right - flood(row, col - 1); // Left - }; - for (let row = 0; row < matrix.length; row += 1) { - for (let col = 0; col < matrix[row].length; col += 1) { - const current = matrix[row][col]; - if (current === '1') { - flood(row, col); - counter += 1; - } - } - } - return counter; -}; - -export { - islands -}; - -// islands( -// ['1', '1', '0', '0', '0'], -// ['1', '1', '0', '0', '0'], -// ['0', '0', '1', '0', '0'], -// ['0', '0', '0', '1', '1'] -// ) -// ['0', '0', '0', '1', '1'] -// ) \ No newline at end of file diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/PrimMST.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/PrimMST.js deleted file mode 100644 index 5d8c444bc5..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/PrimMST.js +++ /dev/null @@ -1,195 +0,0 @@ -// Priority Queue Helper functions -function getParentPosition(position) { - // Get the parent node of the current node - return Math.floor((position - 1) / 2); -} -function getChildrenPosition(position) { - // Get the children nodes of the current node - return [2 * position + 1, 2 * position + 2]; -} -class PriorityQueue { - // Priority Queue class using Minimum Binary Heap - constructor() { - this._heap = []; - this.keys = {}; - } - isEmpty() { - // Checking if the heap is empty - return this._heap.length === 0; - } - push(key, priority) { - // Adding element to the queue (equivalent to add) - this._heap.push([key, priority]); - this.keys[key] = this._heap.length - 1; - this._shiftUp(this.keys[key]); - } - pop() { - // Removing the element with least priority (equivalent to extractMin) - this._swap(0, this._heap.length - 1); - const [key] = this._heap.pop(); - delete this.keys[key]; - this._shiftDown(0); - return key; - } - contains(key) { - // Check if a given key is present in the queue - return key in this.keys; - } - update(key, priority) { - // Update the priority of the given element (equivalent to decreaseKey) - const currPos = this.keys[key]; - this._heap[currPos][1] = priority; - const parentPos = getParentPosition(currPos); - const currPriority = this._heap[currPos][1]; - let parentPriority = Infinity; - if (parentPos >= 0) { - parentPriority = this._heap[parentPos][1]; - } - const [child1Pos, child2Pos] = getChildrenPosition(currPos); - let [child1Priority, child2Priority] = [Infinity, Infinity]; - if (child1Pos < this._heap.length) { - child1Priority = this._heap[child1Pos][1]; - } - if (child2Pos < this._heap.length) { - child2Priority = this._heap[child2Pos][1]; - } - if (parentPos >= 0 && parentPriority > currPriority) { - this._shiftUp(currPos); - } else if (child2Pos < this._heap.length && (child1Priority < currPriority || child2Priority < currPriority)) { - this._shiftDown(currPos); - } - } - _shiftUp(position) { - // Helper function to shift up a node to proper position (equivalent to bubbleUp) - let currPos = position; - let parentPos = getParentPosition(currPos); - let currPriority = this._heap[currPos][1]; - let parentPriority = Infinity; - if (parentPos >= 0) { - parentPriority = this._heap[parentPos][1]; - } - while (parentPos >= 0 && parentPriority > currPriority) { - this._swap(currPos, parentPos); - currPos = parentPos; - parentPos = getParentPosition(currPos); - currPriority = this._heap[currPos][1]; - try { - parentPriority = this._heap[parentPos][1]; - } catch (error) {} - parentPriority = Infinity; - } - } - this.keys[this._heap[currPos][0]] = currPos; -} -_shiftDown(position) { - // Helper function to shift down a node to proper position (equivalent to bubbleDown) - let currPos = position; - let [child1Pos, child2Pos] = getChildrenPosition(currPos); - let [child1Priority, child2Priority] = [Infinity, Infinity]; - if (child1Pos < this._heap.length) { - child1Priority = this._heap[child1Pos][1]; - } - if (child2Pos < this._heap.length) { - child2Priority = this._heap[child2Pos][1]; - } - let currPriority; - try { - currPriority = this._heap[currPos][1]; - } catch { - return; - } - while (child2Pos < this._heap.length && (child1Priority < currPriority || child2Priority < currPriority)) { - if (child1Priority < currPriority && child1Priority < child2Priority) { - this._swap(child1Pos, currPos); - currPos = child1Pos; - } else { - this._swap(child2Pos, currPos); - currPos = child2Pos; - } - [child1Pos, child2Pos] = getChildrenPosition(currPos); - try { - [child1Priority, child2Priority] = [this._heap[child1Pos][1], this._heap[child2Pos][1]]; - } catch (error) {} [child1Priority, child2Priority] = [Infinity, Infinity]; - } - currPriority = this._heap[currPos][1]; -} -this.keys[this._heap[currPos][0]] = currPos; -if (child1Pos < this._heap.length && child1Priority < currPriority) { - this._swap(child1Pos, currPos); - this.keys[this._heap[child1Pos][0]] = child1Pos; -} -} -_swap(position1, position2) { - // Helper function to swap 2 nodes - [this._heap[position1], this._heap[position2]] = [this._heap[position2], this._heap[position1]]; - this.keys[this._heap[position1][0]] = position1; - this.keys[this._heap[position2][0]] = position2; -} -} -class GraphWeightedUndirectedAdjacencyList { - // Weighted Undirected Graph class - constructor() { - this.connections = {}; - } - addNode(node) { - // Function to add a node to the graph (connection represented by set) - this.connections[node] = {}; - } - addEdge(node1, node2, weight) { - // Function to add an edge (adds the node too if they are not present in the graph) - if (!(node1 in this.connections)) { - this.addNode(node1); - } - if (!(node2 in this.connections)) { - this.addNode(node2); - } - this.connections[node1][node2] = weight; - this.connections[node2][node1] = weight; - } - PrimMST(start) { - // Prim's Algorithm to generate a Minimum Spanning Tree (MST) of a graph - // Details: https://en.wikipedia.org/wiki/Prim%27s_algorithm - const distance = {}; - const parent = {}; - const priorityQueue = new PriorityQueue(); - // Initialization - for (const node in this.connections) { - distance[node] = node === start.toString() ? 0 : Infinity; - parent[node] = null; - priorityQueue.push(node, distance[node]); - } - // Updating 'distance' object - while (!priorityQueue.isEmpty()) { - const node = priorityQueue.pop(); - Object.keys(this.connections[node]).forEach((neighbour) => { - if (priorityQueue.contains(neighbour) && distance[node] + this.connections[node][neighbour] < distance[neighbour]) { - distance[neighbour] = distance[node] + this.connections[node][neighbour]; - parent[neighbour] = node; - priorityQueue.update(neighbour, distance[neighbour]); - } - }); - } - // MST Generation from the 'parent' object - const graph = new GraphWeightedUndirectedAdjacencyList(); - Object.keys(parent).forEach((node) => { - if (node && parent[node]) { - graph.addEdge(node, parent[node], this.connections[node][parent[node]]); - } - }); - return graph; - } -} -export { - GraphWeightedUndirectedAdjacencyList -}; -// const graph = new GraphWeightedUndirectedAdjacencyList() -// graph.addEdge(1, 2, 1) -// graph.addEdge(2, 3, 2) -// graph.addEdge(3, 4, 1) -// graph.addEdge(3, 5, 100) // Removed in MST -// graph.addEdge(4, 5, 5) -// graph.PrimMST(1) -// graph.addEdge(3, 4, 1) -// graph.addEdge(3, 5, 100) // Removed in MST -// graph.addEdge(4, 5, 5) -// graph.PrimMST(1) diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BellmanFord.test.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BellmanFord.test.js deleted file mode 100644 index bfdf45185c..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BellmanFord.test.js +++ /dev/null @@ -1,50 +0,0 @@ -import { BellmanFord } from '../BellmanFord.js'; -test('Test Case 1', () => { - const V = 5; - const E = 8; - const destination = 3; - const graph = [ - [0, 1, -1], - [0, 2, 4], - [1, 2, 3], - [1, 3, 2], - [1, 4, 2], - [3, 2, 5], - [3, 1, 1], - [4, 3, -3] - ]; - const dist = BellmanFord(graph, V, E, 0, destination); - expect(dist).toBe(-2); -}); -test('Test Case 2', () => { - const V = 6; - const E = 9; - const destination = 4; - const graph = [ - [0, 1, 3], - [0, 3, 6], - [0, 5, -1], - [1, 2, -3], - [1, 4, -2], - [5, 2, 5], - [2, 3, 1], - [4, 3, 5], - [5, 4, 2] - ]; - const dist = BellmanFord(graph, V, E, 0, destination); - expect(dist).toBe(1); -}); -test('Test Case 3', () => { - const V = 4; - const E = 5; - const destination = 1; - const graph = [ - [0, 3, -1], - [0, 2, 4], - [3, 2, 2], - [3, 1, 5], - [2, 1, -1] - ]; - const dist = BellmanFord(graph, V, E, 0, destination); - expect(dist).toBe(0); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstSearch.test.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstSearch.test.js deleted file mode 100644 index ccb30ae05e..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstSearch.test.js +++ /dev/null @@ -1,25 +0,0 @@ -import { breadthFirstSearch } from '../BreadthFirstSearch'; -describe('BreadthFirstSearch', () => { - const graph = { - A: ['B', 'D'], - B: ['E'], - C: ['D'], - D: ['A'], - E: ['D'], - F: ['G'], - G: [] - }; - /* - A <-> B - ʌ | - | | - v v - C --> D <-- E - F --> G - */ - it('should return the visited nodes', () => { - expect(Array.from(breadthFirstSearch(graph, 'C'))).toEqual(['C', 'D', 'A', 'B', 'E']); - expect(Array.from(breadthFirstSearch(graph, 'A'))).toEqual(['A', 'B', 'D', 'E']); - expect(Array.from(breadthFirstSearch(graph, 'F'))).toEqual(['F', 'G']); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstShortestPath.test.js b/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstShortestPath.test.js deleted file mode 100644 index 0535862801..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/Graphs/test/BreadthFirstShortestPath.test.js +++ /dev/null @@ -1,26 +0,0 @@ -import { breadthFirstShortestPath } from '../BreadthFirstShortestPath'; -describe('BreadthFirstShortestPath', () => { - const graph = { - A: ['B', 'D'], - B: ['E'], - C: ['D'], - D: ['A'], - E: ['D'], - F: ['G'], - G: [] - }; - /* - A <-> B - ʌ | - | | - v v - C --> D <-- E - F --> G - */ - it('should return the visited nodes', () => { - expect(breadthFirstShortestPath(graph, 'C', 'E')).toEqual(['C', 'D', 'A', 'B', 'E']); - expect(breadthFirstShortestPath(graph, 'E', 'B')).toEqual(['E', 'D', 'A', 'B']); - expect(breadthFirstShortestPath(graph, 'F', 'G')).toEqual(['F', 'G']); - expect(breadthFirstShortestPath(graph, 'A', 'G')).toEqual([]); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/README.md b/docs/content/DS_ALGO/data-structures/graph/README.md deleted file mode 100644 index 4617d1aca3..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Graph - -[_Français_](README.fr-FR.md), - -In computer science, a **graph** is an abstract data type -that is meant to implement the undirected graph and -directed graph concepts from mathematics, specifically -the field of graph theory - -A graph data structure consists of a finite (and possibly -mutable) set of vertices or nodes or points, together -with a set of unordered pairs of these vertices for an -undirected graph or a set of ordered pairs for a -directed graph. These pairs are known as edges, arcs, -or lines for an undirected graph and as arrows, -directed edges, directed arcs, or directed lines -for a directed graph. The vertices may be part of -the graph structure, or may be external entities -represented by integer indices or references. - -![Graph](https://www.tutorialspoint.com/data_structures_algorithms/images/graph.jpg) - -## References - -- [Wikipedia]() -- [Introduction to Graphs on YouTube](https://www.youtube.com/watch?v=gXgEDyodOJU&index=9&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [Graphs representation on YouTube](https://www.youtube.com/watch?v=k1wraWzqtvQ&index=10&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/graph/test/Graph.test.js b/docs/content/DS_ALGO/data-structures/graph/test/Graph.test.js deleted file mode 100644 index 63ee3cb30a..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/test/Graph.test.js +++ /dev/null @@ -1,263 +0,0 @@ -import Graph from '../Graph'; -import GraphVertex from '../GraphVertex'; -import GraphEdge from '../GraphEdge'; -describe('Graph', () => { - it('should add vertices to graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - graph.addVertex(vertexA).addVertex(vertexB); - expect(graph.toString()).toBe('A,B'); - expect(graph.getVertexByKey(vertexA.getKey())).toEqual(vertexA); - expect(graph.getVertexByKey(vertexB.getKey())).toEqual(vertexB); - }); - it('should add edges to undirected graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const edgeAB = new GraphEdge(vertexA, vertexB); - graph.addEdge(edgeAB); - expect(graph.getAllVertices().length).toBe(2); - expect(graph.getAllVertices()[0]).toEqual(vertexA); - expect(graph.getAllVertices()[1]).toEqual(vertexB); - const graphVertexA = graph.getVertexByKey(vertexA.getKey()); - const graphVertexB = graph.getVertexByKey(vertexB.getKey()); - expect(graph.toString()).toBe('A,B'); - expect(graphVertexA).toBeDefined(); - expect(graphVertexB).toBeDefined(); - expect(graph.getVertexByKey('not existing')).toBeUndefined(); - expect(graphVertexA.getNeighbors().length).toBe(1); - expect(graphVertexA.getNeighbors()[0]).toEqual(vertexB); - expect(graphVertexA.getNeighbors()[0]).toEqual(graphVertexB); - expect(graphVertexB.getNeighbors().length).toBe(1); - expect(graphVertexB.getNeighbors()[0]).toEqual(vertexA); - expect(graphVertexB.getNeighbors()[0]).toEqual(graphVertexA); - }); - it('should add edges to directed graph', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const edgeAB = new GraphEdge(vertexA, vertexB); - graph.addEdge(edgeAB); - const graphVertexA = graph.getVertexByKey(vertexA.getKey()); - const graphVertexB = graph.getVertexByKey(vertexB.getKey()); - expect(graph.toString()).toBe('A,B'); - expect(graphVertexA).toBeDefined(); - expect(graphVertexB).toBeDefined(); - expect(graphVertexA.getNeighbors().length).toBe(1); - expect(graphVertexA.getNeighbors()[0]).toEqual(vertexB); - expect(graphVertexA.getNeighbors()[0]).toEqual(graphVertexB); - expect(graphVertexB.getNeighbors().length).toBe(0); - }); - it('should find edge by vertices in undirected graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB, 10); - graph.addEdge(edgeAB); - const graphEdgeAB = graph.findEdge(vertexA, vertexB); - const graphEdgeBA = graph.findEdge(vertexB, vertexA); - const graphEdgeAC = graph.findEdge(vertexA, vertexC); - const graphEdgeCA = graph.findEdge(vertexC, vertexA); - expect(graphEdgeAC).toBeNull(); - expect(graphEdgeCA).toBeNull(); - expect(graphEdgeAB).toEqual(edgeAB); - expect(graphEdgeBA).toEqual(edgeAB); - expect(graphEdgeAB.weight).toBe(10); - }); - it('should find edge by vertices in directed graph', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB, 10); - graph.addEdge(edgeAB); - const graphEdgeAB = graph.findEdge(vertexA, vertexB); - const graphEdgeBA = graph.findEdge(vertexB, vertexA); - const graphEdgeAC = graph.findEdge(vertexA, vertexC); - const graphEdgeCA = graph.findEdge(vertexC, vertexA); - expect(graphEdgeAC).toBeNull(); - expect(graphEdgeCA).toBeNull(); - expect(graphEdgeBA).toBeNull(); - expect(graphEdgeAB).toEqual(edgeAB); - expect(graphEdgeAB.weight).toBe(10); - }); - it('should return vertex neighbors', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - graph.addEdge(edgeAB).addEdge(edgeAC); - const neighbors = graph.getNeighbors(vertexA); - expect(neighbors.length).toBe(2); - expect(neighbors[0]).toEqual(vertexB); - expect(neighbors[1]).toEqual(vertexC); - }); - it('should throw an error when trying to add edge twice', () => { - function addSameEdgeTwice() { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const edgeAB = new GraphEdge(vertexA, vertexB); - graph.addEdge(edgeAB).addEdge(edgeAB); - } - expect(addSameEdgeTwice).toThrow(); - }); - it('should return the list of all added edges', () => { - const graph = new Graph(true); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - graph.addEdge(edgeAB).addEdge(edgeBC); - const edges = graph.getAllEdges(); - expect(edges.length).toBe(2); - expect(edges[0]).toEqual(edgeAB); - expect(edges[1]).toEqual(edgeBC); - }); - it('should calculate total graph weight for default graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeAD = new GraphEdge(vertexA, vertexD); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeAD); - expect(graph.getWeight()).toBe(0); - }); - it('should calculate total graph weight for weighted graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 1); - const edgeBC = new GraphEdge(vertexB, vertexC, 2); - const edgeCD = new GraphEdge(vertexC, vertexD, 3); - const edgeAD = new GraphEdge(vertexA, vertexD, 4); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeAD); - expect(graph.getWeight()).toBe(10); - }); - it('should be possible to delete edges from graph', () => { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeAC = new GraphEdge(vertexA, vertexC); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeAC); - expect(graph.getAllEdges().length).toBe(3); - graph.deleteEdge(edgeAB); - expect(graph.getAllEdges().length).toBe(2); - expect(graph.getAllEdges()[0].getKey()).toBe(edgeBC.getKey()); - expect(graph.getAllEdges()[1].getKey()).toBe(edgeAC.getKey()); - }); - it('should should throw an error when trying to delete not existing edge', () => { - function deleteNotExistingEdge() { - const graph = new Graph(); - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - graph.addEdge(edgeAB); - graph.deleteEdge(edgeBC); - } - expect(deleteNotExistingEdge).toThrowError(); - }); - it('should be possible to reverse graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const graph = new Graph(true); - graph.addEdge(edgeAB).addEdge(edgeAC).addEdge(edgeCD); - expect(graph.toString()).toBe('A,B,C,D'); - expect(graph.getAllEdges().length).toBe(3); - expect(graph.getNeighbors(vertexA).length).toBe(2); - expect(graph.getNeighbors(vertexA)[0].getKey()).toBe(vertexB.getKey()); - expect(graph.getNeighbors(vertexA)[1].getKey()).toBe(vertexC.getKey()); - expect(graph.getNeighbors(vertexB).length).toBe(0); - expect(graph.getNeighbors(vertexC).length).toBe(1); - expect(graph.getNeighbors(vertexC)[0].getKey()).toBe(vertexD.getKey()); - expect(graph.getNeighbors(vertexD).length).toBe(0); - graph.reverse(); - expect(graph.toString()).toBe('A,B,C,D'); - expect(graph.getAllEdges().length).toBe(3); - expect(graph.getNeighbors(vertexA).length).toBe(0); - expect(graph.getNeighbors(vertexB).length).toBe(1); - expect(graph.getNeighbors(vertexB)[0].getKey()).toBe(vertexA.getKey()); - expect(graph.getNeighbors(vertexC).length).toBe(1); - expect(graph.getNeighbors(vertexC)[0].getKey()).toBe(vertexA.getKey()); - expect(graph.getNeighbors(vertexD).length).toBe(1); - expect(graph.getNeighbors(vertexD)[0].getKey()).toBe(vertexC.getKey()); - }); - it('should return vertices indices', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeBD = new GraphEdge(vertexB, vertexD); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeBD); - const verticesIndices = graph.getVerticesIndices(); - expect(verticesIndices).toEqual({ - A: 0, - B: 1, - C: 2, - D: 3 - }); - }); - it('should generate adjacency matrix for undirected graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeBC = new GraphEdge(vertexB, vertexC); - const edgeCD = new GraphEdge(vertexC, vertexD); - const edgeBD = new GraphEdge(vertexB, vertexD); - const graph = new Graph(); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeBD); - const adjacencyMatrix = graph.getAdjacencyMatrix(); - expect(adjacencyMatrix).toEqual([ - [Infinity, 0, Infinity, Infinity], - [0, Infinity, 0, 0], - [Infinity, 0, Infinity, 0], - [Infinity, 0, 0, Infinity] - ]); - }); - it('should generate adjacency matrix for directed graph', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const vertexD = new GraphVertex('D'); - const edgeAB = new GraphEdge(vertexA, vertexB, 2); - const edgeBC = new GraphEdge(vertexB, vertexC, 1); - const edgeCD = new GraphEdge(vertexC, vertexD, 5); - const edgeBD = new GraphEdge(vertexB, vertexD, 7); - const graph = new Graph(true); - graph.addEdge(edgeAB).addEdge(edgeBC).addEdge(edgeCD).addEdge(edgeBD); - const adjacencyMatrix = graph.getAdjacencyMatrix(); - expect(adjacencyMatrix).toEqual([ - [Infinity, 2, Infinity, Infinity], - [Infinity, Infinity, 1, 7], - [Infinity, Infinity, Infinity, 5], - [Infinity, Infinity, Infinity, Infinity] - ]); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/test/GraphEdge.test.js b/docs/content/DS_ALGO/data-structures/graph/test/GraphEdge.test.js deleted file mode 100644 index 9c19f6e753..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/test/GraphEdge.test.js +++ /dev/null @@ -1,34 +0,0 @@ -import GraphEdge from '../GraphEdge'; -import GraphVertex from '../GraphVertex'; -describe('GraphEdge', () => { - it('should create graph edge with default weight', () => { - const startVertex = new GraphVertex('A'); - const endVertex = new GraphVertex('B'); - const edge = new GraphEdge(startVertex, endVertex); - expect(edge.getKey()).toBe('A_B'); - expect(edge.toString()).toBe('A_B'); - expect(edge.startVertex).toEqual(startVertex); - expect(edge.endVertex).toEqual(endVertex); - expect(edge.weight).toEqual(0); - }); - it('should create graph edge with predefined weight', () => { - const startVertex = new GraphVertex('A'); - const endVertex = new GraphVertex('B'); - const edge = new GraphEdge(startVertex, endVertex, 10); - expect(edge.startVertex).toEqual(startVertex); - expect(edge.endVertex).toEqual(endVertex); - expect(edge.weight).toEqual(10); - }); - it('should be possible to do edge reverse', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const edge = new GraphEdge(vertexA, vertexB, 10); - expect(edge.startVertex).toEqual(vertexA); - expect(edge.endVertex).toEqual(vertexB); - expect(edge.weight).toEqual(10); - edge.reverse(); - expect(edge.startVertex).toEqual(vertexB); - expect(edge.endVertex).toEqual(vertexA); - expect(edge.weight).toEqual(10); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/graph/test/GraphVertex.test.js b/docs/content/DS_ALGO/data-structures/graph/test/GraphVertex.test.js deleted file mode 100644 index bb48ab9a7d..0000000000 --- a/docs/content/DS_ALGO/data-structures/graph/test/GraphVertex.test.js +++ /dev/null @@ -1,131 +0,0 @@ -import GraphVertex from '../GraphVertex'; -import GraphEdge from '../GraphEdge'; -describe('GraphVertex', () => { - it('should throw an error when trying to create vertex without value', () => { - let vertex = null; - function createEmptyVertex() { - vertex = new GraphVertex(); - } - expect(vertex).toBeNull(); - expect(createEmptyVertex).toThrow(); - }); - it('should create graph vertex', () => { - const vertex = new GraphVertex('A'); - expect(vertex).toBeDefined(); - expect(vertex.value).toBe('A'); - expect(vertex.toString()).toBe('A'); - expect(vertex.getKey()).toBe('A'); - expect(vertex.edges.toString()).toBe(''); - expect(vertex.getEdges()).toEqual([]); - }); - it('should add edges to vertex and check if it exists', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const edgeAB = new GraphEdge(vertexA, vertexB); - vertexA.addEdge(edgeAB); - expect(vertexA.hasEdge(edgeAB)).toBe(true); - expect(vertexB.hasEdge(edgeAB)).toBe(false); - expect(vertexA.getEdges().length).toBe(1); - expect(vertexA.getEdges()[0].toString()).toBe('A_B'); - }); - it('should delete edges from vertex', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - vertexA.addEdge(edgeAB).addEdge(edgeAC); - expect(vertexA.hasEdge(edgeAB)).toBe(true); - expect(vertexB.hasEdge(edgeAB)).toBe(false); - expect(vertexA.hasEdge(edgeAC)).toBe(true); - expect(vertexC.hasEdge(edgeAC)).toBe(false); - expect(vertexA.getEdges().length).toBe(2); - expect(vertexA.getEdges()[0].toString()).toBe('A_B'); - expect(vertexA.getEdges()[1].toString()).toBe('A_C'); - vertexA.deleteEdge(edgeAB); - expect(vertexA.hasEdge(edgeAB)).toBe(false); - expect(vertexA.hasEdge(edgeAC)).toBe(true); - expect(vertexA.getEdges()[0].toString()).toBe('A_C'); - vertexA.deleteEdge(edgeAC); - expect(vertexA.hasEdge(edgeAB)).toBe(false); - expect(vertexA.hasEdge(edgeAC)).toBe(false); - expect(vertexA.getEdges().length).toBe(0); - }); - it('should delete all edges from vertex', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - vertexA.addEdge(edgeAB).addEdge(edgeAC); - expect(vertexA.hasEdge(edgeAB)).toBe(true); - expect(vertexB.hasEdge(edgeAB)).toBe(false); - expect(vertexA.hasEdge(edgeAC)).toBe(true); - expect(vertexC.hasEdge(edgeAC)).toBe(false); - expect(vertexA.getEdges().length).toBe(2); - vertexA.deleteAllEdges(); - expect(vertexA.hasEdge(edgeAB)).toBe(false); - expect(vertexB.hasEdge(edgeAB)).toBe(false); - expect(vertexA.hasEdge(edgeAC)).toBe(false); - expect(vertexC.hasEdge(edgeAC)).toBe(false); - expect(vertexA.getEdges().length).toBe(0); - }); - it('should return vertex neighbors in case if current node is start one', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - const edgeAC = new GraphEdge(vertexA, vertexC); - vertexA.addEdge(edgeAB).addEdge(edgeAC); - expect(vertexB.getNeighbors()).toEqual([]); - const neighbors = vertexA.getNeighbors(); - expect(neighbors.length).toBe(2); - expect(neighbors[0]).toEqual(vertexB); - expect(neighbors[1]).toEqual(vertexC); - }); - it('should return vertex neighbors in case if current node is end one', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeBA = new GraphEdge(vertexB, vertexA); - const edgeCA = new GraphEdge(vertexC, vertexA); - vertexA.addEdge(edgeBA).addEdge(edgeCA); - expect(vertexB.getNeighbors()).toEqual([]); - const neighbors = vertexA.getNeighbors(); - expect(neighbors.length).toBe(2); - expect(neighbors[0]).toEqual(vertexB); - expect(neighbors[1]).toEqual(vertexC); - }); - it('should check if vertex has specific neighbor', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - vertexA.addEdge(edgeAB); - expect(vertexA.hasNeighbor(vertexB)).toBe(true); - expect(vertexA.hasNeighbor(vertexC)).toBe(false); - }); - it('should edge by vertex', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - const vertexC = new GraphVertex('C'); - const edgeAB = new GraphEdge(vertexA, vertexB); - vertexA.addEdge(edgeAB); - expect(vertexA.findEdge(vertexB)).toEqual(edgeAB); - expect(vertexA.findEdge(vertexC)).toBeNull(); - }); - it('should calculate vertex degree', () => { - const vertexA = new GraphVertex('A'); - const vertexB = new GraphVertex('B'); - expect(vertexA.getDegree()).toBe(0); - const edgeAB = new GraphEdge(vertexA, vertexB); - vertexA.addEdge(edgeAB); - expect(vertexA.getDegree()).toBe(1); - const edgeBA = new GraphEdge(vertexB, vertexA); - vertexA.addEdge(edgeBA); - expect(vertexA.getDegree()).toBe(2); - vertexA.addEdge(edgeAB); - expect(vertexA.getDegree()).toBe(3); - expect(vertexA.getEdges().length).toEqual(3); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/hash-table/HashTable.js b/docs/content/DS_ALGO/data-structures/hash-table/HashTable.js deleted file mode 100644 index 3856d380c8..0000000000 --- a/docs/content/DS_ALGO/data-structures/hash-table/HashTable.js +++ /dev/null @@ -1,104 +0,0 @@ -import LinkedList from '../linked-list/LinkedList'; -// Hash table size directly affects on the number of collisions. -// The bigger the hash table size the less collisions you'll get. -// For demonstrating purposes hash table size is small to show how collisions -// are being handled. -const defaultHashTableSize = 32; -export default class HashTable { - /** - * @param {number} hashTableSize - */ - constructor(hashTableSize = defaultHashTableSize) { - // Create hash table of certain size and fill each bucket with empty linked list. - this.buckets = Array(hashTableSize) - .fill(null) - .map(() => new LinkedList()); - // Just to keep track of all actual keys in a fast way. - this.keys = {}; - } - /** - * Converts key string to hash number. - * - * @param {string} key - * @return {number} - */ - hash(key) { - // For simplicity reasons we will just use character codes sum of all characters of the key - // to calculate the hash. - // - // But you may also use more sophisticated approaches like polynomial string hash to reduce the - // number of collisions: - // - // hash = charCodeAt(0) * PRIME^(n-1) + charCodeAt(1) * PRIME^(n-2) + ... + charCodeAt(n-1) - // - // where charCodeAt(i) is the i-th character code of the key, n is the length of the key and - // PRIME is just any prime number like 31. - const hash = Array.from(key).reduce((hashAccumulator, keySymbol) => hashAccumulator + keySymbol.charCodeAt(0), 0); - // Reduce hash number so it would fit hash table size. - return hash % this.buckets.length; - } - /** - * @param {string} key - * @param {*} value - */ - set(key, value) { - const keyHash = this.hash(key); - this.keys[key] = keyHash; - const bucketLinkedList = this.buckets[keyHash]; - const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key }); - if (!node) { - // Insert new node. - bucketLinkedList.append({ key, value }); - } else { - // Update value of existing node. - node.value.value = value; - } - } - /** - * @param {string} key - * @return {*} - */ - delete(key) { - const keyHash = this.hash(key); - delete this.keys[key]; - const bucketLinkedList = this.buckets[keyHash]; - const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key }); - if (node) { - return bucketLinkedList.delete(node.value); - } - return null; - } - /** - * @param {string} key - * @return {*} - */ - get(key) { - const bucketLinkedList = this.buckets[this.hash(key)]; - const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key }); - return node ? node.value.value : undefined; - } - /** - * @param {string} key - * @return {boolean} - */ - has(key) { - return Object.hasOwnProperty.call(this.keys, key); - } - /** - * @return {string[]} - */ - getKeys() { - return Object.keys(this.keys); - } - /** - * Gets the list of all the stored values in the hash table. - * - * @return {*[]} - */ - getValues() { - return this.buckets.reduce((values, bucket) => { - const bucketValues = bucket.toArray().map((linkedListNode) => linkedListNode.value.value); - return values.concat(bucketValues); - }, []); - } -} diff --git a/docs/content/DS_ALGO/data-structures/hash-table/README.md b/docs/content/DS_ALGO/data-structures/hash-table/README.md deleted file mode 100644 index 91f905ea21..0000000000 --- a/docs/content/DS_ALGO/data-structures/hash-table/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Hash Table - -[_Français_](README.fr-FR.md), - -In computing, a **hash table** (hash map) is a data -structure which implements an _associative array_ -abstract data type, a structure that can _map keys -to values_. A hash table uses a _hash function_ to -compute an index into an array of buckets or slots, -from which the desired value can be found - -Ideally, the hash function will assign each key to a -unique bucket, but most hash table designs employ an -imperfect hash function, which might cause hash -collisions where the hash function generates the same -index for more than one key. Such collisions must be -accommodated in some way. - -![Hash Table](https://upload.wikimedia.org/wikipedia/commons/7/7d/Hash_table_3_1_1_0_1_0_0_SP.svg) - -Hash collision resolved by separate chaining. - -![Hash Collision](https://upload.wikimedia.org/wikipedia/commons/d/d0/Hash_table_5_0_1_1_1_1_1_LL.svg) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Hash_table) -- [YouTube](https://www.youtube.com/watch?v=shs0KM3wKv8&index=4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/hash-table/test/HashTable.test.js b/docs/content/DS_ALGO/data-structures/hash-table/test/HashTable.test.js deleted file mode 100644 index f405d89429..0000000000 --- a/docs/content/DS_ALGO/data-structures/hash-table/test/HashTable.test.js +++ /dev/null @@ -1,86 +0,0 @@ -import HashTable from '../HashTable'; -describe('HashTable', () => { - it('should create hash table of certain size', () => { - const defaultHashTable = new HashTable(); - expect(defaultHashTable.buckets.length).toBe(32); - const biggerHashTable = new HashTable(64); - expect(biggerHashTable.buckets.length).toBe(64); - }); - it('should generate proper hash for specified keys', () => { - const hashTable = new HashTable(); - expect(hashTable.hash('a')).toBe(1); - expect(hashTable.hash('b')).toBe(2); - expect(hashTable.hash('abc')).toBe(6); - }); - it('should set, read and delete data with collisions', () => { - const hashTable = new HashTable(3); - expect(hashTable.hash('a')).toBe(1); - expect(hashTable.hash('b')).toBe(2); - expect(hashTable.hash('c')).toBe(0); - expect(hashTable.hash('d')).toBe(1); - hashTable.set('a', 'sky-old'); - hashTable.set('a', 'sky'); - hashTable.set('b', 'sea'); - hashTable.set('c', 'earth'); - hashTable.set('d', 'ocean'); - expect(hashTable.has('x')).toBe(false); - expect(hashTable.has('b')).toBe(true); - expect(hashTable.has('c')).toBe(true); - const stringifier = (value) => `${value.key}:${value.value}`; - expect(hashTable.buckets[0].toString(stringifier)).toBe('c:earth'); - expect(hashTable.buckets[1].toString(stringifier)).toBe('a:sky,d:ocean'); - expect(hashTable.buckets[2].toString(stringifier)).toBe('b:sea'); - expect(hashTable.get('a')).toBe('sky'); - expect(hashTable.get('d')).toBe('ocean'); - expect(hashTable.get('x')).not.toBeDefined(); - hashTable.delete('a'); - expect(hashTable.delete('not-existing')).toBeNull(); - expect(hashTable.get('a')).not.toBeDefined(); - expect(hashTable.get('d')).toBe('ocean'); - hashTable.set('d', 'ocean-new'); - expect(hashTable.get('d')).toBe('ocean-new'); - }); - it('should be possible to add objects to hash table', () => { - const hashTable = new HashTable(); - hashTable.set('objectKey', { prop1: 'a', prop2: 'b' }); - const object = hashTable.get('objectKey'); - expect(object).toBeDefined(); - expect(object.prop1).toBe('a'); - expect(object.prop2).toBe('b'); - }); - it('should track actual keys', () => { - const hashTable = new HashTable(3); - hashTable.set('a', 'sky-old'); - hashTable.set('a', 'sky'); - hashTable.set('b', 'sea'); - hashTable.set('c', 'earth'); - hashTable.set('d', 'ocean'); - expect(hashTable.getKeys()).toEqual(['a', 'b', 'c', 'd']); - expect(hashTable.has('a')).toBe(true); - expect(hashTable.has('x')).toBe(false); - hashTable.delete('a'); - expect(hashTable.has('a')).toBe(false); - expect(hashTable.has('b')).toBe(true); - expect(hashTable.has('x')).toBe(false); - }); - it('should get all the values', () => { - const hashTable = new HashTable(3); - hashTable.set('a', 'alpha'); - hashTable.set('b', 'beta'); - hashTable.set('c', 'gamma'); - expect(hashTable.getValues()).toEqual(['gamma', 'alpha', 'beta']); - }); - it('should get all the values from empty hash table', () => { - const hashTable = new HashTable(); - expect(hashTable.getValues()).toEqual([]); - }); - it('should get all the values in case of hash collision', () => { - const hashTable = new HashTable(3); - // Keys `ab` and `ba` in current implementation should result in one hash (one bucket). - // We need to make sure that several items from one bucket will be serialized. - hashTable.set('ab', 'one'); - hashTable.set('ba', 'two'); - hashTable.set('ac', 'three'); - expect(hashTable.getValues()).toEqual(['one', 'two', 'three']); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/heap/Heap.js b/docs/content/DS_ALGO/data-structures/heap/Heap.js deleted file mode 100644 index b548a756f9..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/Heap.js +++ /dev/null @@ -1,234 +0,0 @@ -import Comparator from '../../utils/comparator/Comparator'; -/** - * Parent class for Min and Max Heaps. - */ -export default class Heap { - /** - * @constructs Heap - * @param {Function} [comparatorFunction] - */ - constructor(comparatorFunction) { - if (new.target === Heap) { - throw new TypeError('Cannot construct Heap instance directly'); - } - // Array representation of the heap. - this.heapContainer = []; - this.compare = new Comparator(comparatorFunction); - } - /** - * @param {number} parentIndex - * @return {number} - */ - getLeftChildIndex(parentIndex) { - return 2 * parentIndex + 1; - } - /** - * @param {number} parentIndex - * @return {number} - */ - getRightChildIndex(parentIndex) { - return 2 * parentIndex + 2; - } - /** - * @param {number} childIndex - * @return {number} - */ - getParentIndex(childIndex) { - return Math.floor((childIndex - 1) / 2); - } - /** - * @param {number} childIndex - * @return {boolean} - */ - hasParent(childIndex) { - return this.getParentIndex(childIndex) >= 0; - } - /** - * @param {number} parentIndex - * @return {boolean} - */ - hasLeftChild(parentIndex) { - return this.getLeftChildIndex(parentIndex) < this.heapContainer.length; - } - /** - * @param {number} parentIndex - * @return {boolean} - */ - hasRightChild(parentIndex) { - return this.getRightChildIndex(parentIndex) < this.heapContainer.length; - } - /** - * @param {number} parentIndex - * @return {*} - */ - leftChild(parentIndex) { - return this.heapContainer[this.getLeftChildIndex(parentIndex)]; - } - /** - * @param {number} parentIndex - * @return {*} - */ - rightChild(parentIndex) { - return this.heapContainer[this.getRightChildIndex(parentIndex)]; - } - /** - * @param {number} childIndex - * @return {*} - */ - parent(childIndex) { - return this.heapContainer[this.getParentIndex(childIndex)]; - } - /** - * @param {number} indexOne - * @param {number} indexTwo - */ - swap(indexOne, indexTwo) { - const tmp = this.heapContainer[indexTwo]; - this.heapContainer[indexTwo] = this.heapContainer[indexOne]; - this.heapContainer[indexOne] = tmp; - } - /** - * @return {*} - */ - peek() { - if (this.heapContainer.length === 0) { - return null; - } - return this.heapContainer[0]; - } - /** - * @return {*} - */ - poll() { - if (this.heapContainer.length === 0) { - return null; - } - if (this.heapContainer.length === 1) { - return this.heapContainer.pop(); - } - const item = this.heapContainer[0]; - // Move the last element from the end to the head. - this.heapContainer[0] = this.heapContainer.pop(); - this.heapifyDown(); - return item; - } - /** - * @param {*} item - * @return {Heap} - */ - add(item) { - this.heapContainer.push(item); - this.heapifyUp(); - return this; - } - /** - * @param {*} item - * @param {Comparator} [comparator] - * @return {Heap} - */ - remove(item, comparator = this.compare) { - // Find number of items to remove. - const numberOfItemsToRemove = this.find(item, comparator).length; - for (let iteration = 0; iteration < numberOfItemsToRemove; iteration += 1) { - // We need to find item index to remove each time after removal since - // indices are being changed after each heapify process. - const indexToRemove = this.find(item, comparator).pop(); - // If we need to remove last child in the heap then just remove it. - // There is no need to heapify the heap afterwards. - if (indexToRemove === this.heapContainer.length - 1) { - this.heapContainer.pop(); - } else { - // Move last element in heap to the vacant (removed) position. - this.heapContainer[indexToRemove] = this.heapContainer.pop(); - // Get parent. - const parentItem = this.parent(indexToRemove); - // If there is no parent or parent is in correct order with the node - // we're going to delete then heapify down. Otherwise heapify up. - if (this.hasLeftChild(indexToRemove) && (!parentItem || this.pairIsInCorrectOrder(parentItem, this.heapContainer[indexToRemove]))) { - this.heapifyDown(indexToRemove); - } else { - this.heapifyUp(indexToRemove); - } - } - } - return this; - } - /** - * @param {*} item - * @param {Comparator} [comparator] - * @return {Number[]} - */ - find(item, comparator = this.compare) { - const foundItemIndices = []; - for (let itemIndex = 0; itemIndex < this.heapContainer.length; itemIndex += 1) { - if (comparator.equal(item, this.heapContainer[itemIndex])) { - foundItemIndices.push(itemIndex); - } - } - return foundItemIndices; - } - /** - * @return {boolean} - */ - isEmpty() { - return !this.heapContainer.length; - } - /** - * @return {string} - */ - toString() { - return this.heapContainer.toString(); - } - /** - * @param {number} [customStartIndex] - */ - heapifyUp(customStartIndex) { - // Take the last element (last in array or the bottom left in a tree) - // in the heap container and lift it up until it is in the correct - // order with respect to its parent element. - let currentIndex = customStartIndex || this.heapContainer.length - 1; - while (this.hasParent(currentIndex) && !this.pairIsInCorrectOrder(this.parent(currentIndex), this.heapContainer[currentIndex])) { - this.swap(currentIndex, this.getParentIndex(currentIndex)); - currentIndex = this.getParentIndex(currentIndex); - } - } - /** - * @param {number} [customStartIndex] - */ - heapifyDown(customStartIndex = 0) { - // Compare the parent element to its children and swap parent with the appropriate - // child (smallest child for MinHeap, largest child for MaxHeap). - // Do the same for next children after swap. - let currentIndex = customStartIndex; - let nextIndex = null; - while (this.hasLeftChild(currentIndex)) { - if (this.hasRightChild(currentIndex) && this.pairIsInCorrectOrder(this.rightChild(currentIndex), this.leftChild(currentIndex))) { - nextIndex = this.getRightChildIndex(currentIndex); - } else {} - nextIndex = this.getLeftChildIndex(currentIndex); - } - if (this.pairIsInCorrectOrder(this.heapContainer[currentIndex], this.heapContainer[nextIndex])) { - break; - } - this.swap(currentIndex, nextIndex); - currentIndex = nextIndex; - } -} -/** - * Checks if pair of heap elements is in correct order. - * For MinHeap the first element must be always smaller or equal. - * For MaxHeap the first element must be always bigger or equal. - * - * @param {*} firstElement - * @param {*} secondElement - * @return {boolean} - */ -/* istanbul ignore next */ -pairIsInCorrectOrder(firstElement, secondElement) { - throw new Error(` - You have to implement heap pair comparision method - for ${firstElement} and ${secondElement} values. - `); -} -} -} diff --git a/docs/content/DS_ALGO/data-structures/heap/MaxHeap.js b/docs/content/DS_ALGO/data-structures/heap/MaxHeap.js deleted file mode 100644 index ba378bcb47..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/MaxHeap.js +++ /dev/null @@ -1,15 +0,0 @@ -import Heap from './Heap'; -export default class MaxHeap extends Heap { - /** - * Checks if pair of heap elements is in correct order. - * For MinHeap the first element must be always smaller or equal. - * For MaxHeap the first element must be always bigger or equal. - * - * @param {*} firstElement - * @param {*} secondElement - * @return {boolean} - */ - pairIsInCorrectOrder(firstElement, secondElement) { - return this.compare.greaterThanOrEqual(firstElement, secondElement); - } -} diff --git a/docs/content/DS_ALGO/data-structures/heap/MinHeap.js b/docs/content/DS_ALGO/data-structures/heap/MinHeap.js deleted file mode 100644 index 66eac6b99d..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/MinHeap.js +++ /dev/null @@ -1,15 +0,0 @@ -import Heap from './Heap'; -export default class MinHeap extends Heap { - /** - * Checks if pair of heap elements is in correct order. - * For MinHeap the first element must be always smaller or equal. - * For MaxHeap the first element must be always bigger or equal. - * - * @param {*} firstElement - * @param {*} secondElement - * @return {boolean} - */ - pairIsInCorrectOrder(firstElement, secondElement) { - return this.compare.lessThanOrEqual(firstElement, secondElement); - } -} diff --git a/docs/content/DS_ALGO/data-structures/heap/README.md b/docs/content/DS_ALGO/data-structures/heap/README.md deleted file mode 100644 index bac80d80cb..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Heap (data-structure) - -[_Français_](README.fr-FR.md), -[_Türkçe_](README.tr-TR.md), - -In computer science, a **heap** is a specialized tree-based -data structure that satisfies the heap property described -below. - -In a _min heap_, if `P` is a parent node of `C`, then the -key (the value) of `P` is less than or equal to the -key of `C`. - -![MinHeap](https://upload.wikimedia.org/wikipedia/commons/6/69/Min-heap.png) - -In a _max heap_, the key of `P` is greater than or equal -to the key of `C` - -![Heap](https://upload.wikimedia.org/wikipedia/commons/3/38/Max-Heap.svg) - -The node at the "top" of the heap with no parents is -called the root node. - -## References - -- [Wikipedia]() -- [YouTube](https://www.youtube.com/watch?v=t0Cq6tVNRBA&index=5&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/heap/test/Heap.test.js b/docs/content/DS_ALGO/data-structures/heap/test/Heap.test.js deleted file mode 100644 index be6106363d..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/test/Heap.test.js +++ /dev/null @@ -1,10 +0,0 @@ -import Heap from '../Heap'; -describe('Heap', () => { - it('should not allow to create instance of the Heap directly', () => { - const instantiateHeap = () => { - const heap = new Heap(); - heap.add(5); - }; - expect(instantiateHeap).toThrow(); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/heap/test/MaxHeap.test.js b/docs/content/DS_ALGO/data-structures/heap/test/MaxHeap.test.js deleted file mode 100644 index ab088cddbb..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/test/MaxHeap.test.js +++ /dev/null @@ -1,131 +0,0 @@ -import MaxHeap from '../MaxHeap'; -import Comparator from '../../../utils/comparator/Comparator'; -describe('MaxHeap', () => { - it('should create an empty max heap', () => { - const maxHeap = new MaxHeap(); - expect(maxHeap).toBeDefined(); - expect(maxHeap.peek()).toBeNull(); - expect(maxHeap.isEmpty()).toBe(true); - }); - it('should add items to the heap and heapify it up', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(5); - expect(maxHeap.isEmpty()).toBe(false); - expect(maxHeap.peek()).toBe(5); - expect(maxHeap.toString()).toBe('5'); - maxHeap.add(3); - expect(maxHeap.peek()).toBe(5); - expect(maxHeap.toString()).toBe('5,3'); - maxHeap.add(10); - expect(maxHeap.peek()).toBe(10); - expect(maxHeap.toString()).toBe('10,3,5'); - maxHeap.add(1); - expect(maxHeap.peek()).toBe(10); - expect(maxHeap.toString()).toBe('10,3,5,1'); - maxHeap.add(1); - expect(maxHeap.peek()).toBe(10); - expect(maxHeap.toString()).toBe('10,3,5,1,1'); - expect(maxHeap.poll()).toBe(10); - expect(maxHeap.toString()).toBe('5,3,1,1'); - expect(maxHeap.poll()).toBe(5); - expect(maxHeap.toString()).toBe('3,1,1'); - expect(maxHeap.poll()).toBe(3); - expect(maxHeap.toString()).toBe('1,1'); - }); - it('should poll items from the heap and heapify it down', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(5); - maxHeap.add(3); - maxHeap.add(10); - maxHeap.add(11); - maxHeap.add(1); - expect(maxHeap.toString()).toBe('11,10,5,3,1'); - expect(maxHeap.poll()).toBe(11); - expect(maxHeap.toString()).toBe('10,3,5,1'); - expect(maxHeap.poll()).toBe(10); - expect(maxHeap.toString()).toBe('5,3,1'); - expect(maxHeap.poll()).toBe(5); - expect(maxHeap.toString()).toBe('3,1'); - expect(maxHeap.poll()).toBe(3); - expect(maxHeap.toString()).toBe('1'); - expect(maxHeap.poll()).toBe(1); - expect(maxHeap.toString()).toBe(''); - expect(maxHeap.poll()).toBeNull(); - expect(maxHeap.toString()).toBe(''); - }); - it('should heapify down through the right branch as well', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(3); - maxHeap.add(12); - maxHeap.add(10); - expect(maxHeap.toString()).toBe('12,3,10'); - maxHeap.add(11); - expect(maxHeap.toString()).toBe('12,11,10,3'); - expect(maxHeap.poll()).toBe(12); - expect(maxHeap.toString()).toBe('11,3,10'); - }); - it('should be possible to find item indices in heap', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(3); - maxHeap.add(12); - maxHeap.add(10); - maxHeap.add(11); - maxHeap.add(11); - expect(maxHeap.toString()).toBe('12,11,10,3,11'); - expect(maxHeap.find(5)).toEqual([]); - expect(maxHeap.find(12)).toEqual([0]); - expect(maxHeap.find(11)).toEqual([1, 4]); - }); - it('should be possible to remove items from heap with heapify down', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(3); - maxHeap.add(12); - maxHeap.add(10); - maxHeap.add(11); - maxHeap.add(11); - expect(maxHeap.toString()).toBe('12,11,10,3,11'); - expect(maxHeap.remove(12).toString()).toEqual('11,11,10,3'); - expect(maxHeap.remove(12).peek()).toEqual(11); - expect(maxHeap.remove(11).toString()).toEqual('10,3'); - expect(maxHeap.remove(10).peek()).toEqual(3); - }); - it('should be possible to remove items from heap with heapify up', () => { - const maxHeap = new MaxHeap(); - maxHeap.add(3); - maxHeap.add(10); - maxHeap.add(5); - maxHeap.add(6); - maxHeap.add(7); - maxHeap.add(4); - maxHeap.add(6); - maxHeap.add(8); - maxHeap.add(2); - maxHeap.add(1); - expect(maxHeap.toString()).toBe('10,8,6,7,6,4,5,3,2,1'); - expect(maxHeap.remove(4).toString()).toEqual('10,8,6,7,6,1,5,3,2'); - expect(maxHeap.remove(3).toString()).toEqual('10,8,6,7,6,1,5,2'); - expect(maxHeap.remove(5).toString()).toEqual('10,8,6,7,6,1,2'); - expect(maxHeap.remove(10).toString()).toEqual('8,7,6,2,6,1'); - expect(maxHeap.remove(6).toString()).toEqual('8,7,1,2'); - expect(maxHeap.remove(2).toString()).toEqual('8,7,1'); - expect(maxHeap.remove(1).toString()).toEqual('8,7'); - expect(maxHeap.remove(7).toString()).toEqual('8'); - expect(maxHeap.remove(8).toString()).toEqual(''); - }); - it('should be possible to remove items from heap with custom finding comparator', () => { - const maxHeap = new MaxHeap(); - maxHeap.add('a'); - maxHeap.add('bb'); - maxHeap.add('ccc'); - maxHeap.add('dddd'); - expect(maxHeap.toString()).toBe('dddd,ccc,bb,a'); - const comparator = new Comparator((a, b) => { - if (a.length === b.length) { - return 0; - } - return a.length < b.length ? -1 : 1; - }); - maxHeap.remove('hey', comparator); - expect(maxHeap.toString()).toBe('dddd,a,bb'); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/heap/test/MinHeap.test.js b/docs/content/DS_ALGO/data-structures/heap/test/MinHeap.test.js deleted file mode 100644 index 266ff07b34..0000000000 --- a/docs/content/DS_ALGO/data-structures/heap/test/MinHeap.test.js +++ /dev/null @@ -1,148 +0,0 @@ -import MinHeap from '../MinHeap'; -import Comparator from '../../../utils/comparator/Comparator'; -describe('MinHeap', () => { - it('should create an empty min heap', () => { - const minHeap = new MinHeap(); - expect(minHeap).toBeDefined(); - expect(minHeap.peek()).toBeNull(); - expect(minHeap.isEmpty()).toBe(true); - }); - it('should add items to the heap and heapify it up', () => { - const minHeap = new MinHeap(); - minHeap.add(5); - expect(minHeap.isEmpty()).toBe(false); - expect(minHeap.peek()).toBe(5); - expect(minHeap.toString()).toBe('5'); - minHeap.add(3); - expect(minHeap.peek()).toBe(3); - expect(minHeap.toString()).toBe('3,5'); - minHeap.add(10); - expect(minHeap.peek()).toBe(3); - expect(minHeap.toString()).toBe('3,5,10'); - minHeap.add(1); - expect(minHeap.peek()).toBe(1); - expect(minHeap.toString()).toBe('1,3,10,5'); - minHeap.add(1); - expect(minHeap.peek()).toBe(1); - expect(minHeap.toString()).toBe('1,1,10,5,3'); - expect(minHeap.poll()).toBe(1); - expect(minHeap.toString()).toBe('1,3,10,5'); - expect(minHeap.poll()).toBe(1); - expect(minHeap.toString()).toBe('3,5,10'); - expect(minHeap.poll()).toBe(3); - expect(minHeap.toString()).toBe('5,10'); - }); - it('should poll items from the heap and heapify it down', () => { - const minHeap = new MinHeap(); - minHeap.add(5); - minHeap.add(3); - minHeap.add(10); - minHeap.add(11); - minHeap.add(1); - expect(minHeap.toString()).toBe('1,3,10,11,5'); - expect(minHeap.poll()).toBe(1); - expect(minHeap.toString()).toBe('3,5,10,11'); - expect(minHeap.poll()).toBe(3); - expect(minHeap.toString()).toBe('5,11,10'); - expect(minHeap.poll()).toBe(5); - expect(minHeap.toString()).toBe('10,11'); - expect(minHeap.poll()).toBe(10); - expect(minHeap.toString()).toBe('11'); - expect(minHeap.poll()).toBe(11); - expect(minHeap.toString()).toBe(''); - expect(minHeap.poll()).toBeNull(); - expect(minHeap.toString()).toBe(''); - }); - it('should heapify down through the right branch as well', () => { - const minHeap = new MinHeap(); - minHeap.add(3); - minHeap.add(12); - minHeap.add(10); - expect(minHeap.toString()).toBe('3,12,10'); - minHeap.add(11); - expect(minHeap.toString()).toBe('3,11,10,12'); - expect(minHeap.poll()).toBe(3); - expect(minHeap.toString()).toBe('10,11,12'); - }); - it('should be possible to find item indices in heap', () => { - const minHeap = new MinHeap(); - minHeap.add(3); - minHeap.add(12); - minHeap.add(10); - minHeap.add(11); - minHeap.add(11); - expect(minHeap.toString()).toBe('3,11,10,12,11'); - expect(minHeap.find(5)).toEqual([]); - expect(minHeap.find(3)).toEqual([0]); - expect(minHeap.find(11)).toEqual([1, 4]); - }); - it('should be possible to remove items from heap with heapify down', () => { - const minHeap = new MinHeap(); - minHeap.add(3); - minHeap.add(12); - minHeap.add(10); - minHeap.add(11); - minHeap.add(11); - expect(minHeap.toString()).toBe('3,11,10,12,11'); - expect(minHeap.remove(3).toString()).toEqual('10,11,11,12'); - expect(minHeap.remove(3).peek()).toEqual(10); - expect(minHeap.remove(11).toString()).toEqual('10,12'); - expect(minHeap.remove(3).peek()).toEqual(10); - }); - it('should be possible to remove items from heap with heapify up', () => { - const minHeap = new MinHeap(); - minHeap.add(3); - minHeap.add(10); - minHeap.add(5); - minHeap.add(6); - minHeap.add(7); - minHeap.add(4); - minHeap.add(6); - minHeap.add(8); - minHeap.add(2); - minHeap.add(1); - expect(minHeap.toString()).toBe('1,2,4,6,3,5,6,10,8,7'); - expect(minHeap.remove(8).toString()).toEqual('1,2,4,6,3,5,6,10,7'); - expect(minHeap.remove(7).toString()).toEqual('1,2,4,6,3,5,6,10'); - expect(minHeap.remove(1).toString()).toEqual('2,3,4,6,10,5,6'); - expect(minHeap.remove(2).toString()).toEqual('3,6,4,6,10,5'); - expect(minHeap.remove(6).toString()).toEqual('3,5,4,10'); - expect(minHeap.remove(10).toString()).toEqual('3,5,4'); - expect(minHeap.remove(5).toString()).toEqual('3,4'); - expect(minHeap.remove(3).toString()).toEqual('4'); - expect(minHeap.remove(4).toString()).toEqual(''); - }); - it('should be possible to remove items from heap with custom finding comparator', () => { - const minHeap = new MinHeap(); - minHeap.add('dddd'); - minHeap.add('ccc'); - minHeap.add('bb'); - minHeap.add('a'); - expect(minHeap.toString()).toBe('a,bb,ccc,dddd'); - const comparator = new Comparator((a, b) => { - if (a.length === b.length) { - return 0; - } - return a.length < b.length ? -1 : 1; - }); - minHeap.remove('hey', comparator); - expect(minHeap.toString()).toBe('a,bb,dddd'); - }); - it('should remove values from heap and correctly re-order the tree', () => { - const minHeap = new MinHeap(); - minHeap.add(1); - minHeap.add(2); - minHeap.add(3); - minHeap.add(4); - minHeap.add(5); - minHeap.add(6); - minHeap.add(7); - minHeap.add(8); - minHeap.add(9); - expect(minHeap.toString()).toBe('1,2,3,4,5,6,7,8,9'); - minHeap.remove(2); - expect(minHeap.toString()).toBe('1,4,3,8,5,6,7,9'); - minHeap.remove(4); - expect(minHeap.toString()).toBe('1,5,3,8,9,6,7'); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/linked-list/LinkedList.js b/docs/content/DS_ALGO/data-structures/linked-list/LinkedList.js deleted file mode 100644 index d007654b62..0000000000 --- a/docs/content/DS_ALGO/data-structures/linked-list/LinkedList.js +++ /dev/null @@ -1,232 +0,0 @@ -import LinkedListNode from './LinkedListNode'; -import Comparator from '../../utils/comparator/Comparator'; -export default class LinkedList { - /** - * @param {Function} [comparatorFunction] - */ - constructor(comparatorFunction) { - /** @var LinkedListNode */ - this.head = null; - /** @var LinkedListNode */ - this.tail = null; - this.compare = new Comparator(comparatorFunction); - } - /** - * @param {*} value - * @return {LinkedList} - */ - prepend(value) { - // Make new node to be a head. - const newNode = new LinkedListNode(value, this.head); - this.head = newNode; - // If there is no tail yet let's make new node a tail. - if (!this.tail) { - this.tail = newNode; - } - return this; - } - /** - * @param {*} value - * @return {LinkedList} - */ - append(value) { - const newNode = new LinkedListNode(value); - // If there is no head yet let's make new node a head. - if (!this.head) { - this.head = newNode; - this.tail = newNode; - return this; - } - // Attach new node to the end of linked list. - this.tail.next = newNode; - this.tail = newNode; - return this; - } - /** - * @param {*} value - * @param {number} index - * @return {LinkedList} - */ - insert(value, rawIndex) { - const index = rawIndex < 0 ? 0 : rawIndex; - if (index === 0) { - this.prepend(value); - } else { - let count = 1; - let currentNode = this.head; - const newNode = new LinkedListNode(value); - while (currentNode) { - if (count === index) break; - currentNode = currentNode.next; - count += 1; - } - if (currentNode) { - newNode.next = currentNode.next; - currentNode.next = newNode; - } else { - if (this.tail) { - this.tail.next = newNode; - this.tail = newNode; - } else { - this.head = newNode; - this.tail = newNode; - } - } - } - return this; - } - /** - * @param {*} value - * @return {LinkedListNode} - */ - delete(value) { - if (!this.head) { - return null; - } - let deletedNode = null; - // If the head must be deleted then make next node that is different - // from the head to be a new head. - while (this.head && this.compare.equal(this.head.value, value)) { - deletedNode = this.head; - this.head = this.head.next; - } - let currentNode = this.head; - if (currentNode !== null) { - // If next node must be deleted then make next node to be a next next one. - while (currentNode.next) { - if (this.compare.equal(currentNode.next.value, value)) { - deletedNode = currentNode.next; - currentNode.next = currentNode.next.next; - } else { - currentNode = currentNode.next; - } - } - } - // Check if tail must be deleted. - if (this.compare.equal(this.tail.value, value)) { - this.tail = currentNode; - } - return deletedNode; - } - /** - * @param {Object} findParams - * @param {*} findParams.value - * @param {function} [findParams.callback] - * @return {LinkedListNode} - */ - find({ - value = undefined, - callback = undefined - }) { - if (!this.head) { - return null; - } - let currentNode = this.head; - while (currentNode) { - // If callback is specified then try to find node by callback. - if (callback && callback(currentNode.value)) { - return currentNode; - } - // If value is specified then try to compare by value.. - if (value !== undefined && this.compare.equal(currentNode.value, value)) { - return currentNode; - } - currentNode = currentNode.next; - } - return null; - } - /** - * @return {LinkedListNode} - */ - deleteTail() { - const deletedTail = this.tail; - if (this.head === this.tail) { - // There is only one node in linked list. - this.head = null; - this.tail = null; - return deletedTail; - } - // If there are many nodes in linked list... - // Rewind to the last node and delete "next" link for the node before the last one. - let currentNode = this.head; - while (currentNode.next) { - if (!currentNode.next.next) { - currentNode.next = null; - } else {} - currentNode = currentNode.next; - } - } - this.tail = currentNode; - return deletedTail; -} -/** - * @return {LinkedListNode} - */ -deleteHead() { - if (!this.head) { - return null; - } - const deletedHead = this.head; - if (this.head.next) { - this.head = this.head.next; - } else { - this.head = null; - this.tail = null; - } - return deletedHead; -} -/** - * @param {*[]} values - Array of values that need to be converted to linked list. - * @return {LinkedList} - */ -fromArray(values) { - values.forEach((value) => this.append(value)); - return this; -} -/** - * @return {LinkedListNode[]} - */ -toArray() { - const nodes = []; - let currentNode = this.head; - while (currentNode) { - nodes.push(currentNode); - currentNode = currentNode.next; - } - return nodes; -} -/** - * @param {function} [callback] - * @return {string} - */ -toString(callback) { - return this.toArray() - .map((node) => node.toString(callback)) - .toString(); -} -/** - * Reverse a linked list. - * @returns {LinkedList} - */ -reverse() { - let currNode = this.head; - let prevNode = null; - let nextNode = null; - while (currNode) { - // Store next node. - nextNode = currNode.next; - // Change next node of the current node so it would link to previous node. - currNode.next = prevNode; - // Move prevNode and currNode nodes one step forward. - prevNode = currNode; - currNode = nextNode; - } - // Reset head and tail. - this.tail = this.head; - this.head = prevNode; - return this; -} -} -return this; -} -} diff --git a/docs/content/DS_ALGO/data-structures/linked-list/LinkedListNode.js b/docs/content/DS_ALGO/data-structures/linked-list/LinkedListNode.js deleted file mode 100644 index c697e6759c..0000000000 --- a/docs/content/DS_ALGO/data-structures/linked-list/LinkedListNode.js +++ /dev/null @@ -1,9 +0,0 @@ -export default class LinkedListNode { - constructor(value, next = null) { - this.value = value; - this.next = next; - } - toString(callback) { - return callback ? callback(this.value) : `${this.value}`; - } -} diff --git a/docs/content/DS_ALGO/data-structures/linked-list/README.md b/docs/content/DS_ALGO/data-structures/linked-list/README.md deleted file mode 100644 index d39b49e065..0000000000 --- a/docs/content/DS_ALGO/data-structures/linked-list/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# Linked List - -In computer science, a **linked list** is a linear collection -of data elements, in which linear order is not given by -their physical placement in memory. Instead, each -element points to the next. It is a data structure -consisting of a group of nodes which together represent -a sequence. Under the simplest form, each node is -composed of data and a reference (in other words, -a link) to the next node in the sequence. This structure -allows for efficient insertion or removal of elements -from any position in the sequence during iteration. -More complex variants add additional links, allowing -efficient insertion or removal from arbitrary element -references. A drawback of linked lists is that access -time is linear (and difficult to pipeline). Faster -access, such as random access, is not feasible. Arrays -have better cache locality as compared to linked lists. - -![Linked List](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg) - -## Pseudocode for Basic Operations - -### Insert - -```text -Add(value) - Pre: value is the value to add to the list - Post: value has been placed at the tail of the list - n ← node(value) - if head = ø - head ← n - tail ← n - else - tail.next ← n - tail ← n - end if -end Add -``` - -```text -Prepend(value) - Pre: value is the value to add to the list - Post: value has been placed at the head of the list - n ← node(value) - n.next ← head - head ← n - if tail = ø - tail ← n - end -end Prepend -``` - -### Search - -```text -Contains(head, value) - Pre: head is the head node in the list - value is the value to search for - Post: the item is either in the linked list, true; otherwise false - n ← head - while n != ø and n.value != value - n ← n.next - end while - if n = ø - return false - end if - return true -end Contains -``` - -### Delete - -```text -Remove(head, value) - Pre: head is the head node in the list - value is the value to remove from the list - Post: value is removed from the list, true, otherwise false - if head = ø - return false - end if - n ← head - if n.value = value - if head = tail - head ← ø - tail ← ø - else - head ← head.next - end if - return true - end if - while n.next != ø and n.next.value != value - n ← n.next - end while - if n.next != ø - if n.next = tail - tail ← n - tail.next = null - else - n.next ← n.next.next - end if - return true - end if - return false -end Remove -``` - -### Traverse - -```text -Traverse(head) - Pre: head is the head node in the list - Post: the items in the list have been traversed - n ← head - while n != ø - yield n.value - n ← n.next - end while -end Traverse -``` - -### Traverse in Reverse - -```text -ReverseTraversal(head, tail) - Pre: head and tail belong to the same list - Post: the items in the list have been traversed in reverse order - if tail != ø - curr ← tail - while curr != head - prev ← head - while prev.next != curr - prev ← prev.next - end while - yield curr.value - curr ← prev - end while - yield curr.value - end if -end ReverseTraversal -``` - -## Complexities - -### Time Complexity - -| Access | Search | Insertion | Deletion | -| :----: | :----: | :-------: | :------: | -| O(n) | O(n) | O(1) | O(n) | - -### Space Complexity - -O(n) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Linked_list) -- [YouTube](https://www.youtube.com/watch?v=njTh_OwMljA&index=2&t=1s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedList.test.js b/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedList.test.js deleted file mode 100644 index 2cebd4344b..0000000000 --- a/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedList.test.js +++ /dev/null @@ -1,280 +0,0 @@ -import LinkedList from '../LinkedList'; -describe('LinkedList', () => { - it('should create empty linked list', () => { - const linkedList = new LinkedList(); - expect(linkedList.toString()).toBe(''); - }); - it('should append node to linked list', () => { - const linkedList = new LinkedList(); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - linkedList.append(1); - linkedList.append(2); - expect(linkedList.toString()).toBe('1,2'); - expect(linkedList.tail.next).toBeNull(); - }); - it('should prepend node to linked list', () => { - const linkedList = new LinkedList(); - linkedList.prepend(2); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - linkedList.append(1); - linkedList.prepend(3); - expect(linkedList.toString()).toBe('3,2,1'); - }); - it('should insert node to linked list', () => { - const linkedList = new LinkedList(); - linkedList.insert(4, 3); - expect(linkedList.head.toString()).toBe('4'); - expect(linkedList.tail.toString()).toBe('4'); - linkedList.insert(3, 2); - linkedList.insert(2, 1); - linkedList.insert(1, -7); - linkedList.insert(10, 9); - expect(linkedList.toString()).toBe('1,4,2,3,10'); - }); - it('should delete node by value from linked list', () => { - const linkedList = new LinkedList(); - expect(linkedList.delete(5)).toBeNull(); - linkedList.append(1); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - linkedList.append(3); - linkedList.append(3); - linkedList.append(4); - linkedList.append(5); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('5'); - const deletedNode = linkedList.delete(3); - expect(deletedNode.value).toBe(3); - expect(linkedList.toString()).toBe('1,1,2,4,5'); - linkedList.delete(3); - expect(linkedList.toString()).toBe('1,1,2,4,5'); - linkedList.delete(1); - expect(linkedList.toString()).toBe('2,4,5'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('5'); - linkedList.delete(5); - expect(linkedList.toString()).toBe('2,4'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('4'); - linkedList.delete(4); - expect(linkedList.toString()).toBe('2'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - linkedList.delete(2); - expect(linkedList.toString()).toBe(''); - }); - it('should delete linked list tail', () => { - const linkedList = new LinkedList(); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('3'); - const deletedNode1 = linkedList.deleteTail(); - expect(deletedNode1.value).toBe(3); - expect(linkedList.toString()).toBe('1,2'); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode2 = linkedList.deleteTail(); - expect(deletedNode2.value).toBe(2); - expect(linkedList.toString()).toBe('1'); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('1'); - const deletedNode3 = linkedList.deleteTail(); - expect(deletedNode3.value).toBe(1); - expect(linkedList.toString()).toBe(''); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - }); - it('should delete linked list head', () => { - const linkedList = new LinkedList(); - expect(linkedList.deleteHead()).toBeNull(); - linkedList.append(1); - linkedList.append(2); - expect(linkedList.head.toString()).toBe('1'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode1 = linkedList.deleteHead(); - expect(deletedNode1.value).toBe(1); - expect(linkedList.toString()).toBe('2'); - expect(linkedList.head.toString()).toBe('2'); - expect(linkedList.tail.toString()).toBe('2'); - const deletedNode2 = linkedList.deleteHead(); - expect(deletedNode2.value).toBe(2); - expect(linkedList.toString()).toBe(''); - expect(linkedList.head).toBeNull(); - expect(linkedList.tail).toBeNull(); - }); - it('should be possible to store objects in the list and to print them out', () => { - const linkedList = new LinkedList(); - const nodeValue1 = { - value: 1, - key: 'key1' - }; - const nodeValue2 = { - value: 2, - key: 'key2' - }; - linkedList.append(nodeValue1).prepend(nodeValue2); - const nodeStringifier = (value) => `${value.key}:${value.value}`; - expect(linkedList.toString(nodeStringifier)).toBe('key2:2,key1:1'); - }); - it('should find node by value', () => { - const linkedList = new LinkedList(); - expect(linkedList.find({ - value: 5 - })).toBeNull(); - linkedList.append(1); - expect(linkedList.find({ - value: 1 - })).toBeDefined(); - linkedList.append(2).append(3); - const node = linkedList.find({ - value: 2 - }); - expect(node.value).toBe(2); - expect(linkedList.find({ - value: 5 - })).toBeNull(); - }); - it('should find node by callback', () => { - const linkedList = new LinkedList(); - linkedList.append({ - value: 1, - key: 'test1' - }).append({ - value: 2, - key: 'test2' - }).append({ - value: 3, - key: 'test3' - }); - const node = linkedList.find({ - callback: (value) => value.key === 'test2' - }); - expect(node).toBeDefined(); - expect(node.value.value).toBe(2); - expect(node.value.key).toBe('test2'); - expect(linkedList.find({ - callback: (value) => value.key === 'test5' - })).toBeNull(); - }); - it('should create linked list from array', () => { - const linkedList = new LinkedList(); - linkedList.fromArray([1, 1, 2, 3, 3, 3, 4, 5]); - expect(linkedList.toString()).toBe('1,1,2,3,3,3,4,5'); - }); - it('should find node by means of custom compare function', () => { - const comparatorFunction = (a, b) => { - if (a.customValue === b.customValue) { - return 0; - } - return a.customValue < b.customValue ? -1 : 1; - }; - const linkedList = new LinkedList(comparatorFunction); - linkedList.append({ - value: 1, - customValue: 'test1' - }).append({ - value: 2, - customValue: 'test2' - }).append({ - value: 3, - customValue: 'test3' - }); - const node = linkedList.find({ - value: { - value: 2, - customValue: 'test2' - } - }); - expect(node).toBeDefined(); - expect(node.value.value).toBe(2); - expect(node.value.customValue).toBe('test2'); - expect(linkedList.find({ - value: { - value: 2, - customValue: 'test5' - } - })).toBeNull(); - }); - it('should find preferring callback over compare function', () => { - const greaterThan = (value, compareTo) => (value > compareTo ? 0 : 1); - const linkedList = new LinkedList(greaterThan); - linkedList.fromArray([1, 2, 3, 4, 5]); - let node = linkedList.find({ - value: 3 - }); - expect(node.value).toBe(4); - node = linkedList.find({ - callback: (value) => value < 3 - }); - expect(node.value).toBe(1); - }); - it('should convert to array', () => { - const linkedList = new LinkedList(); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - expect(linkedList.toArray().join(',')).toBe('1,2,3'); - }); - it('should reverse linked list', () => { - const linkedList = new LinkedList(); - // Add test values to linked list. - linkedList.append(1).append(2).append(3); - expect(linkedList.toString()).toBe('1,2,3'); - expect(linkedList.head.value).toBe(1); - expect(linkedList.tail.value).toBe(3); - // Reverse linked list. - linkedList.reverse(); - expect(linkedList.toString()).toBe('3,2,1'); - expect(linkedList.head.value).toBe(3); - expect(linkedList.tail.value).toBe(1); - // Reverse linked list back to initial state. - linkedList.reverse(); - expect(linkedList.toString()).toBe('1,2,3'); - expect(linkedList.head.value).toBe(1); - expect(linkedList.tail.value).toBe(3); - }); -}); -it('should find preferring callback over compare function', () => { - const greaterThan = (value, compareTo) => (value > compareTo ? 0 : 1); - const linkedList = new LinkedList(greaterThan); - linkedList.fromArray([1, 2, 3, 4, 5]); - let node = linkedList.find({ - value: 3 - }); - expect(node.value).toBe(4); - node = linkedList.find({ - callback: (value) => value < 3 - }); - expect(node.value).toBe(1); -}); -it('should convert to array', () => { - const linkedList = new LinkedList(); - linkedList.append(1); - linkedList.append(2); - linkedList.append(3); - expect(linkedList.toArray().join(',')).toBe('1,2,3'); -}); -it('should reverse linked list', () => { -const linkedList = new LinkedList(); -// Add test values to linked list. -linkedList.append(1).append(2).append(3); -expect(linkedList.toString()).toBe('1,2,3'); -expect(linkedList.head.value).toBe(1); -expect(linkedList.tail.value).toBe(3); -// Reverse linked list. -linkedList.reverse(); -expect(linkedList.toString()).toBe('3,2,1'); -expect(linkedList.head.value).toBe(3); -expect(linkedList.tail.value).toBe(1); -// Reverse linked list back to initial state. -linkedList.reverse(); -expect(linkedList.toString()).toBe('1,2,3'); -expect(linkedList.head.value).toBe(1); -expect(linkedList.tail.value).toBe(3); -}); -}); diff --git a/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedListNode.test.js b/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedListNode.test.js deleted file mode 100644 index b94ee4c022..0000000000 --- a/docs/content/DS_ALGO/data-structures/linked-list/test/LinkedListNode.test.js +++ /dev/null @@ -1,35 +0,0 @@ -import LinkedListNode from '../LinkedListNode'; -describe('LinkedListNode', () => { - it('should create list node with value', () => { - const node = new LinkedListNode(1); - expect(node.value).toBe(1); - expect(node.next).toBeNull(); - }); - it('should create list node with object as a value', () => { - const nodeValue = { value: 1, key: 'test' }; - const node = new LinkedListNode(nodeValue); - expect(node.value.value).toBe(1); - expect(node.value.key).toBe('test'); - expect(node.next).toBeNull(); - }); - it('should link nodes together', () => { - const node2 = new LinkedListNode(2); - const node1 = new LinkedListNode(1, node2); - expect(node1.next).toBeDefined(); - expect(node2.next).toBeNull(); - expect(node1.value).toBe(1); - expect(node1.next.value).toBe(2); - }); - it('should convert node to string', () => { - const node = new LinkedListNode(1); - expect(node.toString()).toBe('1'); - node.value = 'string value'; - expect(node.toString()).toBe('string value'); - }); - it('should convert node to string with custom stringifier', () => { - const nodeValue = { value: 1, key: 'test' }; - const node = new LinkedListNode(nodeValue); - const toStringCallback = (value) => `value: ${value.value}, key: ${value.key}`; - expect(node.toString(toStringCallback)).toBe('value: 1, key: test'); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/priority-queue/PriorityQueue.js b/docs/content/DS_ALGO/data-structures/priority-queue/PriorityQueue.js deleted file mode 100644 index 5d796ab0c0..0000000000 --- a/docs/content/DS_ALGO/data-structures/priority-queue/PriorityQueue.js +++ /dev/null @@ -1,88 +0,0 @@ -import MinHeap from '../heap/MinHeap'; -import Comparator from '../../utils/comparator/Comparator'; -// It is the same as min heap except that when comparing two elements -// we take into account its priority instead of the element's value. -export default class PriorityQueue extends MinHeap { - constructor() { - // Call MinHip constructor first. - super(); - // Setup priorities map. - this.priorities = new Map(); - // Use custom comparator for heap elements that will take element priority - // instead of element value into account. - this.compare = new Comparator(this.comparePriority.bind(this)); - } - /** - * Add item to the priority queue. - * @param {*} item - item we're going to add to the queue. - * @param {number} [priority] - items priority. - * @return {PriorityQueue} - */ - add(item, priority = 0) { - this.priorities.set(item, priority); - super.add(item); - return this; - } - /** - * Remove item from priority queue. - * @param {*} item - item we're going to remove. - * @param {Comparator} [customFindingComparator] - custom function for finding the item to remove - * @return {PriorityQueue} - */ - remove(item, customFindingComparator) { - super.remove(item, customFindingComparator); - this.priorities.delete(item); - return this; - } - /** - * Change priority of the item in a queue. - * @param {*} item - item we're going to re-prioritize. - * @param {number} priority - new item's priority. - * @return {PriorityQueue} - */ - changePriority(item, priority) { - this.remove(item, new Comparator(this.compareValue)); - this.add(item, priority); - return this; - } - /** - * Find item by ite value. - * @param {*} item - * @return {Number[]} - */ - findByValue(item) { - return this.find(item, new Comparator(this.compareValue)); - } - /** - * Check if item already exists in a queue. - * @param {*} item - * @return {boolean} - */ - hasValue(item) { - return this.findByValue(item).length > 0; - } - /** - * Compares priorities of two items. - * @param {*} a - * @param {*} b - * @return {number} - */ - comparePriority(a, b) { - if (this.priorities.get(a) === this.priorities.get(b)) { - return 0; - } - return this.priorities.get(a) < this.priorities.get(b) ? -1 : 1; - } - /** - * Compares values of two items. - * @param {*} a - * @param {*} b - * @return {number} - */ - compareValue(a, b) { - if (a === b) { - return 0; - } - return a < b ? -1 : 1; - } -} diff --git a/docs/content/DS_ALGO/data-structures/priority-queue/README.md b/docs/content/DS_ALGO/data-structures/priority-queue/README.md deleted file mode 100644 index f204bc0a7e..0000000000 --- a/docs/content/DS_ALGO/data-structures/priority-queue/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Priority Queue - -[_Français_](README.fr-FR.md), - -In computer science, a **priority queue** is an abstract data type -which is like a regular queue or stack data structure, but where -additionally each element has a "priority" associated with it. -In a priority queue, an element with high priority is served before -an element with low priority. If two elements have the same -priority, they are served according to their order in the queue. - -While priority queues are often implemented with heaps, they are -conceptually distinct from heaps. A priority queue is an abstract -concept like "a list" or "a map"; just as a list can be implemented -with a linked list or an array, a priority queue can be implemented -with a heap or a variety of other methods such as an unordered -array. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Priority_queue) -- [YouTube](https://www.youtube.com/watch?v=wptevk0bshY&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=6) diff --git a/docs/content/DS_ALGO/data-structures/priority-queue/test/PriorityQueue.test.js b/docs/content/DS_ALGO/data-structures/priority-queue/test/PriorityQueue.test.js deleted file mode 100644 index c2861e5cba..0000000000 --- a/docs/content/DS_ALGO/data-structures/priority-queue/test/PriorityQueue.test.js +++ /dev/null @@ -1,92 +0,0 @@ -import PriorityQueue from '../PriorityQueue'; -describe('PriorityQueue', () => { - it('should create default priority queue', () => { - const priorityQueue = new PriorityQueue(); - expect(priorityQueue).toBeDefined(); - }); - it('should insert items to the queue and respect priorities', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - expect(priorityQueue.peek()).toBe(10); - priorityQueue.add(5, 2); - expect(priorityQueue.peek()).toBe(10); - priorityQueue.add(100, 0); - expect(priorityQueue.peek()).toBe(100); - }); - it('should be possible to use objects in priority queue', () => { - const priorityQueue = new PriorityQueue(); - const user1 = { name: 'Mike' }; - const user2 = { name: 'Bill' }; - const user3 = { name: 'Jane' }; - priorityQueue.add(user1, 1); - expect(priorityQueue.peek()).toBe(user1); - priorityQueue.add(user2, 2); - expect(priorityQueue.peek()).toBe(user1); - priorityQueue.add(user3, 0); - expect(priorityQueue.peek()).toBe(user3); - }); - it('should poll from queue with respect to priorities', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - priorityQueue.add(5, 2); - priorityQueue.add(100, 0); - priorityQueue.add(200, 0); - expect(priorityQueue.poll()).toBe(100); - expect(priorityQueue.poll()).toBe(200); - expect(priorityQueue.poll()).toBe(10); - expect(priorityQueue.poll()).toBe(5); - }); - it('should be possible to change priority of head node', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - priorityQueue.add(5, 2); - priorityQueue.add(100, 0); - priorityQueue.add(200, 0); - expect(priorityQueue.peek()).toBe(100); - priorityQueue.changePriority(100, 10); - priorityQueue.changePriority(10, 20); - expect(priorityQueue.poll()).toBe(200); - expect(priorityQueue.poll()).toBe(5); - expect(priorityQueue.poll()).toBe(100); - expect(priorityQueue.poll()).toBe(10); - }); - it('should be possible to change priority of internal nodes', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - priorityQueue.add(5, 2); - priorityQueue.add(100, 0); - priorityQueue.add(200, 0); - expect(priorityQueue.peek()).toBe(100); - priorityQueue.changePriority(200, 10); - priorityQueue.changePriority(10, 20); - expect(priorityQueue.poll()).toBe(100); - expect(priorityQueue.poll()).toBe(5); - expect(priorityQueue.poll()).toBe(200); - expect(priorityQueue.poll()).toBe(10); - }); - it('should be possible to change priority along with node addition', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - priorityQueue.add(5, 2); - priorityQueue.add(100, 0); - priorityQueue.add(200, 0); - priorityQueue.changePriority(200, 10); - priorityQueue.changePriority(10, 20); - priorityQueue.add(15, 15); - expect(priorityQueue.poll()).toBe(100); - expect(priorityQueue.poll()).toBe(5); - expect(priorityQueue.poll()).toBe(200); - expect(priorityQueue.poll()).toBe(15); - expect(priorityQueue.poll()).toBe(10); - }); - it('should be possible to search in priority queue by value', () => { - const priorityQueue = new PriorityQueue(); - priorityQueue.add(10, 1); - priorityQueue.add(5, 2); - priorityQueue.add(100, 0); - priorityQueue.add(200, 0); - priorityQueue.add(15, 15); - expect(priorityQueue.hasValue(70)).toBe(false); - expect(priorityQueue.hasValue(15)).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/queue/Queue.js b/docs/content/DS_ALGO/data-structures/queue/Queue.js deleted file mode 100644 index 4b879d9b70..0000000000 --- a/docs/content/DS_ALGO/data-structures/queue/Queue.js +++ /dev/null @@ -1,51 +0,0 @@ -import LinkedList from '../linked-list/LinkedList'; -export default class Queue { - constructor() { - // We're going to implement Queue based on LinkedList since the two - // structures are quite similar. Namely, they both operate mostly on - // the elements at the beginning and the end. Compare enqueue/dequeue - // operations of Queue with append/deleteHead operations of LinkedList. - this.linkedList = new LinkedList(); - } - /** - * @return {boolean} - */ - isEmpty() { - return !this.linkedList.head; - } - /** - * Read the element at the front of the queue without removing it. - * @return {*} - */ - peek() { - if (this.isEmpty()) { - return null; - } - return this.linkedList.head.value; - } - /** - * Add a new element to the end of the queue (the tail of the linked list). - * This element will be processed after all elements ahead of it. - * @param {*} value - */ - enqueue(value) { - this.linkedList.append(value); - } - /** - * Remove the element at the front of the queue (the head of the linked list). - * If the queue is empty, return null. - * @return {*} - */ - dequeue() { - const removedHead = this.linkedList.deleteHead(); - return removedHead ? removedHead.value : null; - } - /** - * @param [callback] - * @return {string} - */ - toString(callback) { - // Return string representation of the queue's linked list. - return this.linkedList.toString(callback); - } -} diff --git a/docs/content/DS_ALGO/data-structures/queue/README.md b/docs/content/DS_ALGO/data-structures/queue/README.md deleted file mode 100644 index d19e17dfa9..0000000000 --- a/docs/content/DS_ALGO/data-structures/queue/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# Queue - -[_Français_](README.fr-FR.md), - -In computer science, a **queue** is a particular kind of abstract data -type or collection in which the entities in the collection are -kept in order and the principle (or only) operations on the -collection are the addition of entities to the rear terminal -position, known as enqueue, and removal of entities from the -front terminal position, known as dequeue. This makes the queue -a First-In-First-Out (FIFO) data structure. In a FIFO data -structure, the first element added to the queue will be the -first one to be removed. This is equivalent to the requirement -that once a new element is added, all elements that were added -before have to be removed before the new element can be removed. -Often a peek or front operation is also entered, returning the -value of the front element without dequeuing it. A queue is an -example of a linear data structure, or more abstractly a -sequential collection. - -Representation of a FIFO (first in, first out) queue - -![Queue](https://upload.wikimedia.org/wikipedia/commons/5/52/Data_Queue.svg) - -## References - -- [Wikipedia]() -- [YouTube](https://www.youtube.com/watch?v=wjI1WNcIntg&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=3&) diff --git a/docs/content/DS_ALGO/data-structures/queue/test/Queue.test.js b/docs/content/DS_ALGO/data-structures/queue/test/Queue.test.js deleted file mode 100644 index c5654ea308..0000000000 --- a/docs/content/DS_ALGO/data-structures/queue/test/Queue.test.js +++ /dev/null @@ -1,46 +0,0 @@ -import Queue from '../Queue'; -describe('Queue', () => { - it('should create empty queue', () => { - const queue = new Queue(); - expect(queue).not.toBeNull(); - expect(queue.linkedList).not.toBeNull(); - }); - it('should enqueue data to queue', () => { - const queue = new Queue(); - queue.enqueue(1); - queue.enqueue(2); - expect(queue.toString()).toBe('1,2'); - }); - it('should be possible to enqueue/dequeue objects', () => { - const queue = new Queue(); - queue.enqueue({ value: 'test1', key: 'key1' }); - queue.enqueue({ value: 'test2', key: 'key2' }); - const stringifier = (value) => `${value.key}:${value.value}`; - expect(queue.toString(stringifier)).toBe('key1:test1,key2:test2'); - expect(queue.dequeue().value).toBe('test1'); - expect(queue.dequeue().value).toBe('test2'); - }); - it('should peek data from queue', () => { - const queue = new Queue(); - expect(queue.peek()).toBeNull(); - queue.enqueue(1); - queue.enqueue(2); - expect(queue.peek()).toBe(1); - expect(queue.peek()).toBe(1); - }); - it('should check if queue is empty', () => { - const queue = new Queue(); - expect(queue.isEmpty()).toBe(true); - queue.enqueue(1); - expect(queue.isEmpty()).toBe(false); - }); - it('should dequeue from queue in FIFO order', () => { - const queue = new Queue(); - queue.enqueue(1); - queue.enqueue(2); - expect(queue.dequeue()).toBe(1); - expect(queue.dequeue()).toBe(2); - expect(queue.dequeue()).toBeNull(); - expect(queue.isEmpty()).toBe(true); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/stack/README.md b/docs/content/DS_ALGO/data-structures/stack/README.md deleted file mode 100644 index 24a7586f56..0000000000 --- a/docs/content/DS_ALGO/data-structures/stack/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Stack - -[_Français_](README.fr-FR.md), - -In computer science, a **stack** is an abstract data type that serves -as a collection of elements, with two principal operations: - -- **push**, which adds an element to the collection, and -- **pop**, which removes the most recently added element that was not yet removed. - -The order in which elements come off a stack gives rise to its -alternative name, LIFO (last in, first out). Additionally, a -peek operation may give access to the top without modifying -the stack. The name "stack" for this type of structure comes -from the analogy to a set of physical items stacked on top of -each other, which makes it easy to take an item off the top -of the stack, while getting to an item deeper in the stack -may require taking off multiple other items first. - -Simple representation of a stack runtime with push and pop operations. - -![Stack](https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png) - -## References - -- [Wikipedia]() -- [YouTube](https://www.youtube.com/watch?v=wjI1WNcIntg&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=3&) diff --git a/docs/content/DS_ALGO/data-structures/stack/Stack.js b/docs/content/DS_ALGO/data-structures/stack/Stack.js deleted file mode 100644 index 14990b9079..0000000000 --- a/docs/content/DS_ALGO/data-structures/stack/Stack.js +++ /dev/null @@ -1,57 +0,0 @@ -import LinkedList from '../linked-list/LinkedList'; -export default class Stack { - constructor() { - // We're going to implement Stack based on LinkedList since these - // structures are quite similar. Compare push/pop operations of the Stack - // with prepend/deleteHead operations of LinkedList. - this.linkedList = new LinkedList(); - } - /** - * @return {boolean} - */ - isEmpty() { - // The stack is empty if its linked list doesn't have a head. - return !this.linkedList.head; - } - /** - * @return {*} - */ - peek() { - if (this.isEmpty()) { - // If the linked list is empty then there is nothing to peek from. - return null; - } - // Just read the value from the start of linked list without deleting it. - return this.linkedList.head.value; - } - /** - * @param {*} value - */ - push(value) { - // Pushing means to lay the value on top of the stack. Therefore let's just add - // the new value at the start of the linked list. - this.linkedList.prepend(value); - } - /** - * @return {*} - */ - pop() { - // Let's try to delete the first node (the head) from the linked list. - // If there is no head (the linked list is empty) just return null. - const removedHead = this.linkedList.deleteHead(); - return removedHead ? removedHead.value : null; - } - /** - * @return {*[]} - */ - toArray() { - return this.linkedList.toArray().map((linkedListNode) => linkedListNode.value); - } - /** - * @param {function} [callback] - * @return {string} - */ - toString(callback) { - return this.linkedList.toString(callback); - } -} diff --git a/docs/content/DS_ALGO/data-structures/stack/test/Stack.test.js b/docs/content/DS_ALGO/data-structures/stack/test/Stack.test.js deleted file mode 100644 index 0e91aedd6b..0000000000 --- a/docs/content/DS_ALGO/data-structures/stack/test/Stack.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import Stack from '../Stack'; -describe('Stack', () => { - it('should create empty stack', () => { - const stack = new Stack(); - expect(stack).not.toBeNull(); - expect(stack.linkedList).not.toBeNull(); - }); - it('should stack data to stack', () => { - const stack = new Stack(); - stack.push(1); - stack.push(2); - expect(stack.toString()).toBe('2,1'); - }); - it('should peek data from stack', () => { - const stack = new Stack(); - expect(stack.peek()).toBeNull(); - stack.push(1); - stack.push(2); - expect(stack.peek()).toBe(2); - expect(stack.peek()).toBe(2); - }); - it('should check if stack is empty', () => { - const stack = new Stack(); - expect(stack.isEmpty()).toBe(true); - stack.push(1); - expect(stack.isEmpty()).toBe(false); - }); - it('should pop data from stack', () => { - const stack = new Stack(); - stack.push(1); - stack.push(2); - expect(stack.pop()).toBe(2); - expect(stack.pop()).toBe(1); - expect(stack.pop()).toBeNull(); - expect(stack.isEmpty()).toBe(true); - }); - it('should be possible to push/pop objects', () => { - const stack = new Stack(); - stack.push({ value: 'test1', key: 'key1' }); - stack.push({ value: 'test2', key: 'key2' }); - const stringifier = (value) => `${value.key}:${value.value}`; - expect(stack.toString(stringifier)).toBe('key2:test2,key1:test1'); - expect(stack.pop().value).toBe('test2'); - expect(stack.pop().value).toBe('test1'); - }); - it('should be possible to convert stack to array', () => { - const stack = new Stack(); - expect(stack.peek()).toBeNull(); - stack.push(1); - stack.push(2); - stack.push(3); - expect(stack.toArray()).toEqual([3, 2, 1]); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/BinaryTreeNode.js b/docs/content/DS_ALGO/data-structures/tree/BinaryTreeNode.js deleted file mode 100644 index 67845da757..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/BinaryTreeNode.js +++ /dev/null @@ -1,181 +0,0 @@ -import Comparator from '../../utils/comparator/Comparator'; -import HashTable from '../hash-table/HashTable'; -export default class BinaryTreeNode { - /** - * @param {*} [value] - node value. - */ - constructor(value = null) { - this.left = null; - this.right = null; - this.parent = null; - this.value = value; - // Any node related meta information may be stored here. - this.meta = new HashTable(); - // This comparator is used to compare binary tree nodes with each other. - this.nodeComparator = new Comparator(); - } - /** - * @return {number} - */ - get leftHeight() { - if (!this.left) { - return 0; - } - return this.left.height + 1; - } - /** - * @return {number} - */ - get rightHeight() { - if (!this.right) { - return 0; - } - return this.right.height + 1; - } - /** - * @return {number} - */ - get height() { - return Math.max(this.leftHeight, this.rightHeight); - } - /** - * @return {number} - */ - get balanceFactor() { - return this.leftHeight - this.rightHeight; - } - /** - * Get parent's sibling if it exists. - * @return {BinaryTreeNode} - */ - get uncle() { - // Check if current node has parent. - if (!this.parent) { - return undefined; - } - // Check if current node has grand-parent. - if (!this.parent.parent) { - return undefined; - } - // Check if grand-parent has two children. - if (!this.parent.parent.left || !this.parent.parent.right) { - return undefined; - } - // So for now we know that current node has grand-parent and this - // grand-parent has two children. Let's find out who is the uncle. - if (this.nodeComparator.equal(this.parent, this.parent.parent.left)) { - // Right one is an uncle. - return this.parent.parent.right; - } - // Left one is an uncle. - return this.parent.parent.left; - } - /** - * @param {*} value - * @return {BinaryTreeNode} - */ - setValue(value) { - this.value = value; - return this; - } - /** - * @param {BinaryTreeNode} node - * @return {BinaryTreeNode} - */ - setLeft(node) { - // Reset parent for left node since it is going to be detached. - if (this.left) { - this.left.parent = null; - } - // Attach new node to the left. - this.left = node; - // Make current node to be a parent for new left one. - if (this.left) { - this.left.parent = this; - } - return this; - } - /** - * @param {BinaryTreeNode} node - * @return {BinaryTreeNode} - */ - setRight(node) { - // Reset parent for right node since it is going to be detached. - if (this.right) { - this.right.parent = null; - } - // Attach new node to the right. - this.right = node; - // Make current node to be a parent for new right one. - if (node) { - this.right.parent = this; - } - return this; - } - /** - * @param {BinaryTreeNode} nodeToRemove - * @return {boolean} - */ - removeChild(nodeToRemove) { - if (this.left && this.nodeComparator.equal(this.left, nodeToRemove)) { - this.left = null; - return true; - } - if (this.right && this.nodeComparator.equal(this.right, nodeToRemove)) { - this.right = null; - return true; - } - return false; - } - /** - * @param {BinaryTreeNode} nodeToReplace - * @param {BinaryTreeNode} replacementNode - * @return {boolean} - */ - replaceChild(nodeToReplace, replacementNode) { - if (!nodeToReplace || !replacementNode) { - return false; - } - if (this.left && this.nodeComparator.equal(this.left, nodeToReplace)) { - this.left = replacementNode; - return true; - } - if (this.right && this.nodeComparator.equal(this.right, nodeToReplace)) { - this.right = replacementNode; - return true; - } - return false; - } - /** - * @param {BinaryTreeNode} sourceNode - * @param {BinaryTreeNode} targetNode - */ - static copyNode(sourceNode, targetNode) { - targetNode.setValue(sourceNode.value); - targetNode.setLeft(sourceNode.left); - targetNode.setRight(sourceNode.right); - } - /** - * @return {*[]} - */ - traverseInOrder() { - let traverse = []; - // Add left node. - if (this.left) { - traverse = traverse.concat(this.left.traverseInOrder()); - } - // Add root. - traverse.push(this.value); - // Add right node. - if (this.right) { - traverse = traverse.concat(this.right.traverseInOrder()); - } - return traverse; - } - /** - * @return {string} - */ - toString() { - return this.traverseInOrder().toString(); - } -} diff --git a/docs/content/DS_ALGO/data-structures/tree/README.md b/docs/content/DS_ALGO/data-structures/tree/README.md deleted file mode 100644 index 32b145009f..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Tree - -- [Binary Search Tree](binary-search-tree) -- [AVL Tree](avl-tree) -- [Red-Black Tree](red-black-tree) -- [Segment Tree](segment-tree) - with min/max/sum range queries examples -- [Fenwick Tree](fenwick-tree) (Binary Indexed Tree) - -In computer science, a **tree** is a widely used abstract data type (ADT) — or data structure implementing this ADT—that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node, represented as a set of linked nodes. - -A tree data structure can be defined recursively (locally) as a collection of nodes (starting at a root node), where each node is a data structure consisting of a value, together with a list of references to nodes (the "children"), with the constraints that no reference is duplicated, and none points to the root. - -A simple unordered tree; in this diagram, the node labeled 7 has two children, labeled 2 and 6, and one parent, labeled 2. The root node, at the top, has no parent. - -![Tree](https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_tree.svg) - -## References - -- [Wikipedia]() -- [YouTube](https://www.youtube.com/watch?v=oSWTXtMglKE&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=8) diff --git a/docs/content/DS_ALGO/data-structures/tree/avl-tree/AvlTree.js b/docs/content/DS_ALGO/data-structures/tree/avl-tree/AvlTree.js deleted file mode 100644 index fda637c83e..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/avl-tree/AvlTree.js +++ /dev/null @@ -1,138 +0,0 @@ -import BinarySearchTree from '../binary-search-tree/BinarySearchTree'; -export default class AvlTree extends BinarySearchTree { - /** - * @param {*} value - */ - insert(value) { - // Do the normal BST insert. - super.insert(value); - // Let's move up to the root and check balance factors along the way. - let currentNode = this.root.find(value); - while (currentNode) { - this.balance(currentNode); - currentNode = currentNode.parent; - } - } - /** - * @param {*} value - * @return {boolean} - */ - remove(value) { - // Do standard BST removal. - super.remove(value); - // Balance the tree starting from the root node. - this.balance(this.root); - } - /** - * @param {BinarySearchTreeNode} node - */ - balance(node) { - // If balance factor is not OK then try to balance the node. - if (node.balanceFactor > 1) { - // Left rotation. - if (node.left.balanceFactor > 0) { - // Left-Left rotation - this.rotateLeftLeft(node); - } else if (node.left.balanceFactor < 0) { - // Left-Right rotation. - this.rotateLeftRight(node); - } - } else if (node.balanceFactor < -1) { - // Right rotation. - if (node.right.balanceFactor < 0) { - // Right-Right rotation - this.rotateRightRight(node); - } else if (node.right.balanceFactor > 0) { - // Right-Left rotation. - this.rotateRightLeft(node); - } - } - } - /** - * @param {BinarySearchTreeNode} rootNode - */ - rotateLeftLeft(rootNode) { - // Detach left node from root node. - const leftNode = rootNode.left; - rootNode.setLeft(null); - // Make left node to be a child of rootNode's parent. - if (rootNode.parent) { - rootNode.parent.setLeft(leftNode); - } else if (rootNode === this.root) { - // If root node is root then make left node to be a new root. - this.root = leftNode; - } - // If left node has a right child then detach it and - // attach it as a left child for rootNode. - if (leftNode.right) { - rootNode.setLeft(leftNode.right); - } - // Attach rootNode to the right of leftNode. - leftNode.setRight(rootNode); - } - /** - * @param {BinarySearchTreeNode} rootNode - */ - rotateLeftRight(rootNode) { - // Detach left node from rootNode since it is going to be replaced. - const leftNode = rootNode.left; - rootNode.setLeft(null); - // Detach right node from leftNode. - const leftRightNode = leftNode.right; - leftNode.setRight(null); - // Preserve leftRightNode's left subtree. - if (leftRightNode.left) { - leftNode.setRight(leftRightNode.left); - leftRightNode.setLeft(null); - } - // Attach leftRightNode to the rootNode. - rootNode.setLeft(leftRightNode); - // Attach leftNode as left node for leftRight node. - leftRightNode.setLeft(leftNode); - // Do left-left rotation. - this.rotateLeftLeft(rootNode); - } - /** - * @param {BinarySearchTreeNode} rootNode - */ - rotateRightLeft(rootNode) { - // Detach right node from rootNode since it is going to be replaced. - const rightNode = rootNode.right; - rootNode.setRight(null); - // Detach left node from rightNode. - const rightLeftNode = rightNode.left; - rightNode.setLeft(null); - if (rightLeftNode.right) { - rightNode.setLeft(rightLeftNode.right); - rightLeftNode.setRight(null); - } - // Attach rightLeftNode to the rootNode. - rootNode.setRight(rightLeftNode); - // Attach rightNode as right node for rightLeft node. - rightLeftNode.setRight(rightNode); - // Do right-right rotation. - this.rotateRightRight(rootNode); - } - /** - * @param {BinarySearchTreeNode} rootNode - */ - rotateRightRight(rootNode) { - // Detach right node from root node. - const rightNode = rootNode.right; - rootNode.setRight(null); - // Make right node to be a child of rootNode's parent. - if (rootNode.parent) { - rootNode.parent.setRight(rightNode); - } else if (rootNode === this.root) { - // If root node is root then make right node to be a new root. - this.root = rightNode; - } - // If right node has a left child then detach it and - // attach it as a right child for rootNode. - if (rightNode.left) { - rootNode.setRight(rightNode.left); - } - // Attach rootNode to the left of rightNode. - rightNode.setLeft(rootNode); - } -} diff --git a/docs/content/DS_ALGO/data-structures/tree/avl-tree/README.md b/docs/content/DS_ALGO/data-structures/tree/avl-tree/README.md deleted file mode 100644 index 899d71b68e..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/avl-tree/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# AVL Tree - -In computer science, an **AVL tree** (named after inventors -Adelson-Velsky and Landis) is a self-balancing binary search -tree. It was the first such data structure to be invented. -In an AVL tree, the heights of the two child subtrees of any -node differ by at most one; if at any time they differ by -more than one, rebalancing is done to restore this property. -Lookup, insertion, and deletion all take `O(log n)` time in -both the average and worst cases, where n is the number of -nodes in the tree prior to the operation. Insertions and -deletions may require the tree to be rebalanced by one or -more tree rotations. - -Animation showing the insertion of several elements into an AVL -tree. It includes left, right, left-right and right-left rotations. - -![AVL Tree](https://upload.wikimedia.org/wikipedia/commons/f/fd/AVL_Tree_Example.gif) - -AVL tree with balance factors (green) - -![AVL Tree](https://upload.wikimedia.org/wikipedia/commons/a/ad/AVL-tree-wBalance_K.svg) - -### AVL Tree Rotations - -**Left-Left Rotation** - -![Left-Left Rotation](http://btechsmartclass.com/data_structures/ds_images/LL%20Rotation.png) - -**Right-Right Rotation** - -![Right-Right Rotation](http://btechsmartclass.com/data_structures/ds_images/RR%20Rotation.png) - -**Left-Right Rotation** - -![Left-Right Rotation](http://btechsmartclass.com/data_structures/ds_images/LR%20Rotation.png) - -**Right-Left Rotation** - -![Right-Right Rotation](http://btechsmartclass.com/data_structures/ds_images/RL%20Rotation.png) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/AVL_tree) -- [Tutorials Point](https://www.tutorialspoint.com/data_structures_algorithms/avl_tree_algorithm.htm) -- [BTech](http://btechsmartclass.com/data_structures/avl-trees.html) -- [AVL Tree Insertion on YouTube](https://www.youtube.com/watch?v=rbg7Qf8GkQ4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=12&) -- [AVL Tree Interactive Visualisations](https://www.cs.usfca.edu/~galles/visualization/AVLtree.html) diff --git a/docs/content/DS_ALGO/data-structures/tree/avl-tree/test/AvlTRee.test.js b/docs/content/DS_ALGO/data-structures/tree/avl-tree/test/AvlTRee.test.js deleted file mode 100644 index 10530fc8b9..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/avl-tree/test/AvlTRee.test.js +++ /dev/null @@ -1,228 +0,0 @@ -import AvlTree from '../AvlTree'; -describe('AvlTree', () => { - it('should do simple left-left rotation', () => { - const tree = new AvlTree(); - tree.insert(4); - tree.insert(3); - tree.insert(2); - expect(tree.toString()).toBe('2,3,4'); - expect(tree.root.value).toBe(3); - expect(tree.root.height).toBe(1); - tree.insert(1); - expect(tree.toString()).toBe('1,2,3,4'); - expect(tree.root.value).toBe(3); - expect(tree.root.height).toBe(2); - tree.insert(0); - expect(tree.toString()).toBe('0,1,2,3,4'); - expect(tree.root.value).toBe(3); - expect(tree.root.left.value).toBe(1); - expect(tree.root.height).toBe(2); - }); - it('should do complex left-left rotation', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(20); - tree.insert(40); - tree.insert(10); - expect(tree.root.value).toBe(30); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('10,20,30,40'); - tree.insert(25); - expect(tree.root.value).toBe(30); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('10,20,25,30,40'); - tree.insert(5); - expect(tree.root.value).toBe(20); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('5,10,20,25,30,40'); - }); - it('should do simple right-right rotation', () => { - const tree = new AvlTree(); - tree.insert(2); - tree.insert(3); - tree.insert(4); - expect(tree.toString()).toBe('2,3,4'); - expect(tree.root.value).toBe(3); - expect(tree.root.height).toBe(1); - tree.insert(5); - expect(tree.toString()).toBe('2,3,4,5'); - expect(tree.root.value).toBe(3); - expect(tree.root.height).toBe(2); - tree.insert(6); - expect(tree.toString()).toBe('2,3,4,5,6'); - expect(tree.root.value).toBe(3); - expect(tree.root.right.value).toBe(5); - expect(tree.root.height).toBe(2); - }); - it('should do complex right-right rotation', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(20); - tree.insert(40); - tree.insert(50); - expect(tree.root.value).toBe(30); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('20,30,40,50'); - tree.insert(35); - expect(tree.root.value).toBe(30); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('20,30,35,40,50'); - tree.insert(55); - expect(tree.root.value).toBe(40); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('20,30,35,40,50,55'); - }); - it('should do left-right rotation', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(20); - tree.insert(25); - expect(tree.root.height).toBe(1); - expect(tree.root.value).toBe(25); - expect(tree.toString()).toBe('20,25,30'); - }); - it('should do right-left rotation', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(40); - tree.insert(35); - expect(tree.root.height).toBe(1); - expect(tree.root.value).toBe(35); - expect(tree.toString()).toBe('30,35,40'); - }); - it('should create balanced tree: case #1', () => { - // @see: https://www.youtube.com/watch?v=rbg7Qf8GkQ4&t=839s - const tree = new AvlTree(); - tree.insert(1); - tree.insert(2); - tree.insert(3); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(1); - expect(tree.toString()).toBe('1,2,3'); - tree.insert(6); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('1,2,3,6'); - tree.insert(15); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('1,2,3,6,15'); - tree.insert(-2); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('-2,1,2,3,6,15'); - tree.insert(-5); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('-5,-2,1,2,3,6,15'); - tree.insert(-8); - expect(tree.root.value).toBe(2); - expect(tree.root.height).toBe(3); - expect(tree.toString()).toBe('-8,-5,-2,1,2,3,6,15'); - }); - it('should create balanced tree: case #2', () => { - // @see https://www.youtube.com/watch?v=7m94k2Qhg68 - const tree = new AvlTree(); - tree.insert(43); - tree.insert(18); - tree.insert(22); - tree.insert(9); - tree.insert(21); - tree.insert(6); - expect(tree.root.value).toBe(18); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('6,9,18,21,22,43'); - tree.insert(8); - expect(tree.root.value).toBe(18); - expect(tree.root.height).toBe(2); - expect(tree.toString()).toBe('6,8,9,18,21,22,43'); - }); - it('should do left right rotation and keeping left right node safe', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(15); - tree.insert(40); - tree.insert(10); - tree.insert(18); - tree.insert(35); - tree.insert(45); - tree.insert(5); - tree.insert(12); - expect(tree.toString()).toBe('5,10,12,15,18,30,35,40,45'); - expect(tree.root.height).toBe(3); - tree.insert(11); - expect(tree.toString()).toBe('5,10,11,12,15,18,30,35,40,45'); - expect(tree.root.height).toBe(3); - }); - it('should do left right rotation and keeping left right node safe', () => { - const tree = new AvlTree(); - tree.insert(30); - tree.insert(15); - tree.insert(40); - tree.insert(10); - tree.insert(18); - tree.insert(35); - tree.insert(45); - tree.insert(42); - tree.insert(47); - expect(tree.toString()).toBe('10,15,18,30,35,40,42,45,47'); - expect(tree.root.height).toBe(3); - tree.insert(43); - expect(tree.toString()).toBe('10,15,18,30,35,40,42,43,45,47'); - expect(tree.root.height).toBe(3); - }); - it('should remove values from the tree with right-right rotation', () => { - const tree = new AvlTree(); - tree.insert(10); - tree.insert(20); - tree.insert(30); - tree.insert(40); - expect(tree.toString()).toBe('10,20,30,40'); - tree.remove(10); - expect(tree.toString()).toBe('20,30,40'); - expect(tree.root.value).toBe(30); - expect(tree.root.left.value).toBe(20); - expect(tree.root.right.value).toBe(40); - expect(tree.root.balanceFactor).toBe(0); - }); - it('should remove values from the tree with left-left rotation', () => { - const tree = new AvlTree(); - tree.insert(10); - tree.insert(20); - tree.insert(30); - tree.insert(5); - expect(tree.toString()).toBe('5,10,20,30'); - tree.remove(30); - expect(tree.toString()).toBe('5,10,20'); - expect(tree.root.value).toBe(10); - expect(tree.root.left.value).toBe(5); - expect(tree.root.right.value).toBe(20); - expect(tree.root.balanceFactor).toBe(0); - }); - it('should keep balance after removal', () => { - const tree = new AvlTree(); - tree.insert(1); - tree.insert(2); - tree.insert(3); - tree.insert(4); - tree.insert(5); - tree.insert(6); - tree.insert(7); - tree.insert(8); - tree.insert(9); - expect(tree.toString()).toBe('1,2,3,4,5,6,7,8,9'); - expect(tree.root.value).toBe(4); - expect(tree.root.height).toBe(3); - expect(tree.root.balanceFactor).toBe(-1); - tree.remove(8); - expect(tree.root.value).toBe(4); - expect(tree.root.balanceFactor).toBe(-1); - tree.remove(9); - expect(tree.contains(8)).toBeFalsy(); - expect(tree.contains(9)).toBeFalsy(); - expect(tree.toString()).toBe('1,2,3,4,5,6,7'); - expect(tree.root.value).toBe(4); - expect(tree.root.height).toBe(2); - expect(tree.root.balanceFactor).toBe(0); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTree.js b/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTree.js deleted file mode 100644 index 638d67f9a5..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTree.js +++ /dev/null @@ -1,38 +0,0 @@ -import BinarySearchTreeNode from './BinarySearchTreeNode'; -export default class BinarySearchTree { - /** - * @param {function} [nodeValueCompareFunction] - */ - constructor(nodeValueCompareFunction) { - this.root = new BinarySearchTreeNode(null, nodeValueCompareFunction); - // Steal node comparator from the root. - this.nodeComparator = this.root.nodeComparator; - } - /** - * @param {*} value - * @return {BinarySearchTreeNode} - */ - insert(value) { - return this.root.insert(value); - } - /** - * @param {*} value - * @return {boolean} - */ - contains(value) { - return this.root.contains(value); - } - /** - * @param {*} value - * @return {boolean} - */ - remove(value) { - return this.root.remove(value); - } - /** - * @return {string} - */ - toString() { - return this.root.toString(); - } -} diff --git a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTreeNode.js b/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTreeNode.js deleted file mode 100644 index 4888f3eee7..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/BinarySearchTreeNode.js +++ /dev/null @@ -1,131 +0,0 @@ -import BinaryTreeNode from '../BinaryTreeNode'; -import Comparator from '../../../utils/comparator/Comparator'; -export default class BinarySearchTreeNode extends BinaryTreeNode { - /** - * @param {*} [value] - node value. - * @param {function} [compareFunction] - comparator function for node values. - */ - constructor(value = null, compareFunction = undefined) { - super(value); - // This comparator is used to compare node values with each other. - this.compareFunction = compareFunction; - this.nodeValueComparator = new Comparator(compareFunction); - } - /** - * @param {*} value - * @return {BinarySearchTreeNode} - */ - insert(value) { - if (this.nodeValueComparator.equal(this.value, null)) { - this.value = value; - return this; - } - if (this.nodeValueComparator.lessThan(value, this.value)) { - // Insert to the left. - if (this.left) { - return this.left.insert(value); - } - const newNode = new BinarySearchTreeNode(value, this.compareFunction); - this.setLeft(newNode); - return newNode; - } - if (this.nodeValueComparator.greaterThan(value, this.value)) { - // Insert to the right. - if (this.right) { - return this.right.insert(value); - } - const newNode = new BinarySearchTreeNode(value, this.compareFunction); - this.setRight(newNode); - return newNode; - } - return this; - } - /** - * @param {*} value - * @return {BinarySearchTreeNode} - */ - find(value) { - // Check the root. - if (this.nodeValueComparator.equal(this.value, value)) { - return this; - } - if (this.nodeValueComparator.lessThan(value, this.value) && this.left) { - // Check left nodes. - return this.left.find(value); - } - if (this.nodeValueComparator.greaterThan(value, this.value) && this.right) { - // Check right nodes. - return this.right.find(value); - } - return null; - } - /** - * @param {*} value - * @return {boolean} - */ - contains(value) { - return !!this.find(value); - } - /** - * @param {*} value - * @return {boolean} - */ - remove(value) { - const nodeToRemove = this.find(value); - if (!nodeToRemove) { - throw new Error('Item not found in the tree'); - } - const { - parent - } = nodeToRemove; - if (!nodeToRemove.left && !nodeToRemove.right) { - // Node is a leaf and thus has no children. - if (parent) { - // Node has a parent. Just remove the pointer to this node from the parent. - parent.removeChild(nodeToRemove); - } else { - // Node has no parent. Just erase current node value. - nodeToRemove.setValue(undefined); - } - } else if (nodeToRemove.left && nodeToRemove.right) { - // Node has two children. - // Find the next biggest value (minimum value in the right branch) - // and replace current value node with that next biggest value. - const nextBiggerNode = nodeToRemove.right.findMin(); - if (!this.nodeComparator.equal(nextBiggerNode, nodeToRemove.right)) { - this.remove(nextBiggerNode.value); - nodeToRemove.setValue(nextBiggerNode.value); - } else { - // In case if next right value is the next bigger one and it doesn't have left child - // then just replace node that is going to be deleted with the right node. - nodeToRemove.setValue(nodeToRemove.right.value); - nodeToRemove.setRight(nodeToRemove.right.right); - } - } else { - // Node has only one child. - // Make this child to be a direct child of current node's parent. - /** @var BinarySearchTreeNode */ - const childNode = nodeToRemove.left || nodeToRemove.right; - if (parent) { - parent.replaceChild(nodeToRemove, childNode); - } else {} - BinaryTreeNode.copyNode(childNode, nodeToRemove); - } - } - // Clear the parent of removed node. - nodeToRemove.parent = null; - return true; -} -/** - * @return {BinarySearchTreeNode} - */ -findMin() { - if (!this.left) { - return this; - } - return this.left.findMin(); -} -} -return this.left.findMin(); -} -} diff --git a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/README.md b/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/README.md deleted file mode 100644 index 468b6f6d0b..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/README.md +++ /dev/null @@ -1,274 +0,0 @@ -# Binary Search Tree - -In computer science, **binary search trees** (BST), sometimes called -ordered or sorted binary trees, are a particular type of container: -data structures that store "items" (such as numbers, names etc.) -in memory. They allow fast lookup, addition and removal of -items, and can be used to implement either dynamic sets of -items, or lookup tables that allow finding an item by its key -(e.g., finding the phone number of a person by name). - -Binary search trees keep their keys in sorted order, so that lookup -and other operations can use the principle of binary search: -when looking for a key in a tree (or a place to insert a new key), -they traverse the tree from root to leaf, making comparisons to -keys stored in the nodes of the tree and deciding, on the basis -of the comparison, to continue searching in the left or right -subtrees. On average, this means that each comparison allows -the operations to skip about half of the tree, so that each -lookup, insertion or deletion takes time proportional to the -logarithm of the number of items stored in the tree. This is -much better than the linear time required to find items by key -in an (unsorted) array, but slower than the corresponding -operations on hash tables. - -A binary search tree of size 9 and depth 3, with 8 at the root. -The leaves are not drawn. - -![Binary Search Tree](https://upload.wikimedia.org/wikipedia/commons/d/da/Binary_search_tree.svg) - -## Pseudocode for Basic Operations - -### Insertion - -```text -insert(value) - Pre: value has passed custom type checks for type T - Post: value has been placed in the correct location in the tree - if root = ø - root ← node(value) - else - insertNode(root, value) - end if -end insert -``` - -```text -insertNode(current, value) - Pre: current is the node to start from - Post: value has been placed in the correct location in the tree - if value < current.value - if current.left = ø - current.left ← node(value) - else - InsertNode(current.left, value) - end if - else - if current.right = ø - current.right ← node(value) - else - InsertNode(current.right, value) - end if - end if -end insertNode -``` - -### Searching - -```text -contains(root, value) - Pre: root is the root node of the tree, value is what we would like to locate - Post: value is either located or not - if root = ø - return false - end if - if root.value = value - return true - else if value < root.value - return contains(root.left, value) - else - return contains(root.right, value) - end if -end contains -``` - -### Deletion - -```text -remove(value) - Pre: value is the value of the node to remove, root is the node of the BST - count is the number of items in the BST - Post: node with value is removed if found in which case yields true, otherwise false - nodeToRemove ← findNode(value) - if nodeToRemove = ø - return false - end if - parent ← findParent(value) - if count = 1 - root ← ø - else if nodeToRemove.left = ø and nodeToRemove.right = ø - if nodeToRemove.value < parent.value - parent.left ← nodeToRemove.right - else - parent.right ← nodeToRemove.right - end if - else if nodeToRemove.left != ø and nodeToRemove.right != ø - next ← nodeToRemove.right - while next.left != ø - next ← next.left - end while - if next != nodeToRemove.right - remove(next.value) - nodeToRemove.value ← next.value - else - nodeToRemove.value ← next.value - nodeToRemove.right ← nodeToRemove.right.right - end if - else - if nodeToRemove.left = ø - next ← nodeToRemove.right - else - next ← nodeToRemove.left - end if - if root = nodeToRemove - root = next - else if parent.left = nodeToRemove - parent.left = next - else if parent.right = nodeToRemove - parent.right = next - end if - end if - count ← count - 1 - return true -end remove -``` - -### Find Parent of Node - -```text -findParent(value, root) - Pre: value is the value of the node we want to find the parent of - root is the root node of the BST and is != ø - Post: a reference to the prent node of value if found; otherwise ø - if value = root.value - return ø - end if - if value < root.value - if root.left = ø - return ø - else if root.left.value = value - return root - else - return findParent(value, root.left) - end if - else - if root.right = ø - return ø - else if root.right.value = value - return root - else - return findParent(value, root.right) - end if - end if -end findParent -``` - -### Find Node - -```text -findNode(root, value) - Pre: value is the value of the node we want to find the parent of - root is the root node of the BST - Post: a reference to the node of value if found; otherwise ø - if root = ø - return ø - end if - if root.value = value - return root - else if value < root.value - return findNode(root.left, value) - else - return findNode(root.right, value) - end if -end findNode -``` - -### Find Minimum - -```text -findMin(root) - Pre: root is the root node of the BST - root = ø - Post: the smallest value in the BST is located - if root.left = ø - return root.value - end if - findMin(root.left) -end findMin -``` - -### Find Maximum - -```text -findMax(root) - Pre: root is the root node of the BST - root = ø - Post: the largest value in the BST is located - if root.right = ø - return root.value - end if - findMax(root.right) -end findMax -``` - -### Traversal - -#### InOrder Traversal - -```text -inorder(root) - Pre: root is the root node of the BST - Post: the nodes in the BST have been visited in inorder - if root != ø - inorder(root.left) - yield root.value - inorder(root.right) - end if -end inorder -``` - -#### PreOrder Traversal - -```text -preorder(root) - Pre: root is the root node of the BST - Post: the nodes in the BST have been visited in preorder - if root != ø - yield root.value - preorder(root.left) - preorder(root.right) - end if -end preorder -``` - -#### PostOrder Traversal - -```text -postorder(root) - Pre: root is the root node of the BST - Post: the nodes in the BST have been visited in postorder - if root != ø - postorder(root.left) - postorder(root.right) - yield root.value - end if -end postorder -``` - -## Complexities - -### Time Complexity - -| Access | Search | Insertion | Deletion | -| :-------: | :-------: | :-------: | :-------: | -| O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | - -### Space Complexity - -O(n) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Binary_search_tree) -- [Inserting to BST on YouTube](https://www.youtube.com/watch?v=wcIRPqTR3Kc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=9&t=0s) -- [BST Interactive Visualisations](https://www.cs.usfca.edu/~galles/visualization/BST.html) diff --git a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTree.test.js b/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTree.test.js deleted file mode 100644 index 7675299ab5..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTree.test.js +++ /dev/null @@ -1,89 +0,0 @@ -import BinarySearchTree from '../BinarySearchTree'; -describe('BinarySearchTree', () => { - it('should create binary search tree', () => { - const bst = new BinarySearchTree(); - expect(bst).toBeDefined(); - expect(bst.root).toBeDefined(); - expect(bst.root.value).toBeNull(); - expect(bst.root.left).toBeNull(); - expect(bst.root.right).toBeNull(); - }); - it('should insert values', () => { - const bst = new BinarySearchTree(); - const insertedNode1 = bst.insert(10); - const insertedNode2 = bst.insert(20); - bst.insert(5); - expect(bst.toString()).toBe('5,10,20'); - expect(insertedNode1.value).toBe(10); - expect(insertedNode2.value).toBe(20); - }); - it('should check if value exists', () => { - const bst = new BinarySearchTree(); - bst.insert(10); - bst.insert(20); - bst.insert(5); - expect(bst.contains(20)).toBe(true); - expect(bst.contains(40)).toBe(false); - }); - it('should remove nodes', () => { - const bst = new BinarySearchTree(); - bst.insert(10); - bst.insert(20); - bst.insert(5); - expect(bst.toString()).toBe('5,10,20'); - const removed1 = bst.remove(5); - expect(bst.toString()).toBe('10,20'); - expect(removed1).toBe(true); - const removed2 = bst.remove(20); - expect(bst.toString()).toBe('10'); - expect(removed2).toBe(true); - }); - it('should insert object values', () => { - const nodeValueCompareFunction = (a, b) => { - const normalizedA = a || { - value: null - }; - const normalizedB = b || { - value: null - }; - if (normalizedA.value === normalizedB.value) { - return 0; - } - return normalizedA.value < normalizedB.value ? -1 : 1; - }; - const obj1 = { - key: 'obj1', - value: 1, - toString: () => 'obj1' - }; - const obj2 = { - key: 'obj2', - value: 2, - toString: () => 'obj2' - }; - const obj3 = { - key: 'obj3', - value: 3, - toString: () => 'obj3' - }; - const bst = new BinarySearchTree(nodeValueCompareFunction); - bst.insert(obj2); - bst.insert(obj3); - bst.insert(obj1); - expect(bst.toString()).toBe('obj1,obj2,obj3'); - }); - it('should be traversed to sorted array', () => { - const bst = new BinarySearchTree(); - bst.insert(10); - bst.insert(-10); - bst.insert(20); - bst.insert(-20); - bst.insert(25); - bst.insert(6); - expect(bst.toString()).toBe('-20,-10,6,10,20,25'); - expect(bst.root.height).toBe(2); - bst.insert(4); - expect(bst.toString()).toBe('-20,-10,4,6,10,20,25'); - expect(bst.root.height).toBe(3); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTreeNode.test.js b/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTreeNode.test.js deleted file mode 100644 index f64d43a9d2..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/binary-search-tree/test/BinarySearchTreeNode.test.js +++ /dev/null @@ -1,204 +0,0 @@ -import BinarySearchTreeNode from '../BinarySearchTreeNode'; -describe('BinarySearchTreeNode', () => { - it('should create binary search tree', () => { - const bstNode = new BinarySearchTreeNode(2); - expect(bstNode.value).toBe(2); - expect(bstNode.left).toBeNull(); - expect(bstNode.right).toBeNull(); - }); - it('should insert in itself if it is empty', () => { - const bstNode = new BinarySearchTreeNode(); - bstNode.insert(1); - expect(bstNode.value).toBe(1); - expect(bstNode.left).toBeNull(); - expect(bstNode.right).toBeNull(); - }); - it('should insert nodes in correct order', () => { - const bstNode = new BinarySearchTreeNode(2); - const insertedNode1 = bstNode.insert(1); - expect(insertedNode1.value).toBe(1); - expect(bstNode.toString()).toBe('1,2'); - expect(bstNode.contains(1)).toBe(true); - expect(bstNode.contains(3)).toBe(false); - const insertedNode2 = bstNode.insert(3); - expect(insertedNode2.value).toBe(3); - expect(bstNode.toString()).toBe('1,2,3'); - expect(bstNode.contains(3)).toBe(true); - expect(bstNode.contains(4)).toBe(false); - bstNode.insert(7); - expect(bstNode.toString()).toBe('1,2,3,7'); - expect(bstNode.contains(7)).toBe(true); - expect(bstNode.contains(8)).toBe(false); - bstNode.insert(4); - expect(bstNode.toString()).toBe('1,2,3,4,7'); - expect(bstNode.contains(4)).toBe(true); - expect(bstNode.contains(8)).toBe(false); - bstNode.insert(6); - expect(bstNode.toString()).toBe('1,2,3,4,6,7'); - expect(bstNode.contains(6)).toBe(true); - expect(bstNode.contains(8)).toBe(false); - }); - it('should not insert duplicates', () => { - const bstNode = new BinarySearchTreeNode(2); - bstNode.insert(1); - expect(bstNode.toString()).toBe('1,2'); - expect(bstNode.contains(1)).toBe(true); - expect(bstNode.contains(3)).toBe(false); - bstNode.insert(1); - expect(bstNode.toString()).toBe('1,2'); - expect(bstNode.contains(1)).toBe(true); - expect(bstNode.contains(3)).toBe(false); - }); - it('should find min node', () => { - const node = new BinarySearchTreeNode(10); - node.insert(20); - node.insert(30); - node.insert(5); - node.insert(40); - node.insert(1); - expect(node.findMin()).not.toBeNull(); - expect(node.findMin().value).toBe(1); - }); - it('should be possible to attach meta information to binary search tree nodes', () => { - const node = new BinarySearchTreeNode(10); - node.insert(20); - const node1 = node.insert(30); - node.insert(5); - node.insert(40); - const node2 = node.insert(1); - node.meta.set('color', 'red'); - node1.meta.set('color', 'black'); - node2.meta.set('color', 'white'); - expect(node.meta.get('color')).toBe('red'); - expect(node.findMin()).not.toBeNull(); - expect(node.findMin().value).toBe(1); - expect(node.findMin().meta.get('color')).toBe('white'); - expect(node.find(30).meta.get('color')).toBe('black'); - }); - it('should find node', () => { - const node = new BinarySearchTreeNode(10); - node.insert(20); - node.insert(30); - node.insert(5); - node.insert(40); - node.insert(1); - expect(node.find(6)).toBeNull(); - expect(node.find(5)).not.toBeNull(); - expect(node.find(5).value).toBe(5); - }); - it('should remove leaf nodes', () => { - const bstRootNode = new BinarySearchTreeNode(); - bstRootNode.insert(10); - bstRootNode.insert(20); - bstRootNode.insert(5); - expect(bstRootNode.toString()).toBe('5,10,20'); - const removed1 = bstRootNode.remove(5); - expect(bstRootNode.toString()).toBe('10,20'); - expect(removed1).toBe(true); - const removed2 = bstRootNode.remove(20); - expect(bstRootNode.toString()).toBe('10'); - expect(removed2).toBe(true); - }); - it('should remove nodes with one child', () => { - const bstRootNode = new BinarySearchTreeNode(); - bstRootNode.insert(10); - bstRootNode.insert(20); - bstRootNode.insert(5); - bstRootNode.insert(30); - expect(bstRootNode.toString()).toBe('5,10,20,30'); - bstRootNode.remove(20); - expect(bstRootNode.toString()).toBe('5,10,30'); - bstRootNode.insert(1); - expect(bstRootNode.toString()).toBe('1,5,10,30'); - bstRootNode.remove(5); - expect(bstRootNode.toString()).toBe('1,10,30'); - }); - it('should remove nodes with two children', () => { - const bstRootNode = new BinarySearchTreeNode(); - bstRootNode.insert(10); - bstRootNode.insert(20); - bstRootNode.insert(5); - bstRootNode.insert(30); - bstRootNode.insert(15); - bstRootNode.insert(25); - expect(bstRootNode.toString()).toBe('5,10,15,20,25,30'); - expect(bstRootNode.find(20).left.value).toBe(15); - expect(bstRootNode.find(20).right.value).toBe(30); - bstRootNode.remove(20); - expect(bstRootNode.toString()).toBe('5,10,15,25,30'); - bstRootNode.remove(15); - expect(bstRootNode.toString()).toBe('5,10,25,30'); - bstRootNode.remove(10); - expect(bstRootNode.toString()).toBe('5,25,30'); - expect(bstRootNode.value).toBe(25); - bstRootNode.remove(25); - expect(bstRootNode.toString()).toBe('5,30'); - bstRootNode.remove(5); - expect(bstRootNode.toString()).toBe('30'); - }); - it('should remove node with no parent', () => { - const bstRootNode = new BinarySearchTreeNode(); - expect(bstRootNode.toString()).toBe(''); - bstRootNode.insert(1); - bstRootNode.insert(2); - expect(bstRootNode.toString()).toBe('1,2'); - bstRootNode.remove(1); - expect(bstRootNode.toString()).toBe('2'); - bstRootNode.remove(2); - expect(bstRootNode.toString()).toBe(''); - }); - it('should throw error when trying to remove not existing node', () => { - const bstRootNode = new BinarySearchTreeNode(); - bstRootNode.insert(10); - bstRootNode.insert(20); - function removeNotExistingElementFromTree() { - bstRootNode.remove(30); - } - expect(removeNotExistingElementFromTree).toThrow(); - }); - it('should be possible to use objects as node values', () => { - const nodeValueComparatorCallback = (a, b) => { - const normalizedA = a || { - value: null - }; - const normalizedB = b || { - value: null - }; - if (normalizedA.value === normalizedB.value) { - return 0; - } - return normalizedA.value < normalizedB.value ? -1 : 1; - }; - const obj1 = { - key: 'obj1', - value: 1, - toString: () => 'obj1' - }; - const obj2 = { - key: 'obj2', - value: 2, - toString: () => 'obj2' - }; - const obj3 = { - key: 'obj3', - value: 3, - toString: () => 'obj3' - }; - const bstNode = new BinarySearchTreeNode(obj2, nodeValueComparatorCallback); - bstNode.insert(obj1); - expect(bstNode.toString()).toBe('obj1,obj2'); - expect(bstNode.contains(obj1)).toBe(true); - expect(bstNode.contains(obj3)).toBe(false); - bstNode.insert(obj3); - expect(bstNode.toString()).toBe('obj1,obj2,obj3'); - expect(bstNode.contains(obj3)).toBe(true); - expect(bstNode.findMin().value).toEqual(obj1); - }); - it('should abandon removed node', () => { - const rootNode = new BinarySearchTreeNode('foo'); - rootNode.insert('bar'); - const childNode = rootNode.find('bar'); - rootNode.remove('bar'); - expect(childNode.parent).toBeNull(); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/FenwickTree.js b/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/FenwickTree.js deleted file mode 100644 index 3e7330695f..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/FenwickTree.js +++ /dev/null @@ -1,61 +0,0 @@ -export default class FenwickTree { - /** - * Constructor creates empty fenwick tree of size 'arraySize', - * however, array size is size+1, because index is 1-based. - * - * @param {number} arraySize - */ - constructor(arraySize) { - this.arraySize = arraySize; - // Fill tree array with zeros. - this.treeArray = Array(this.arraySize + 1).fill(0); - } - /** - * Adds value to existing value at position. - * - * @param {number} position - * @param {number} value - * @return {FenwickTree} - */ - increase(position, value) { - if (position < 1 || position > this.arraySize) { - throw new Error('Position is out of allowed range'); - } - for (let i = position; i <= this.arraySize; i += i & -i) { - this.treeArray[i] += value; - } - return this; - } - /** - * Query sum from index 1 to position. - * - * @param {number} position - * @return {number} - */ - query(position) { - if (position < 1 || position > this.arraySize) { - throw new Error('Position is out of allowed range'); - } - let sum = 0; - for (let i = position; i > 0; i -= i & -i) { - sum += this.treeArray[i]; - } - return sum; - } - /** - * Query sum from index leftIndex to rightIndex. - * - * @param {number} leftIndex - * @param {number} rightIndex - * @return {number} - */ - queryRange(leftIndex, rightIndex) { - if (leftIndex > rightIndex) { - throw new Error('Left index can not be greater than right one'); - } - if (leftIndex === 1) { - return this.query(rightIndex); - } - return this.query(rightIndex) - this.query(leftIndex - 1); - } -} diff --git a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/README.md b/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/README.md deleted file mode 100644 index 7f6bd29458..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Fenwick Tree / Binary Indexed Tree - -A **Fenwick tree** or **binary indexed tree** is a data -structure that can efficiently update elements and -calculate prefix sums in a table of numbers. - -When compared with a flat array of numbers, the Fenwick tree achieves a -much better balance between two operations: element update and prefix sum -calculation. In a flat array of `n` numbers, you can either store the elements, -or the prefix sums. In the first case, computing prefix sums requires linear -time; in the second case, updating the array elements requires linear time -(in both cases, the other operation can be performed in constant time). -Fenwick trees allow both operations to be performed in `O(log n)` time. -This is achieved by representing the numbers as a tree, where the value of -each node is the sum of the numbers in that subtree. The tree structure allows -operations to be performed using only `O(log n)` node accesses. - -## Implementation Notes - -Binary Indexed Tree is represented as an array. Each node of Binary Indexed Tree -stores sum of some elements of given array. Size of Binary Indexed Tree is equal -to `n` where `n` is size of input array. In current implementation we have used -size as `n+1` for ease of implementation. All the indexes are 1-based. - -![Binary Indexed Tree](https://www.geeksforgeeks.org/wp-content/uploads/BITSum.png) - -On the picture below you may see animated example of -creation of binary indexed tree for the -array `[1, 2, 3, 4, 5]` by inserting one by one. - -![Fenwick Tree](https://upload.wikimedia.org/wikipedia/commons/d/dc/BITDemo.gif) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Fenwick_tree) -- [GeeksForGeeks](https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/) -- [YouTube](https://www.youtube.com/watch?v=CWDQJGaN1gY&index=18&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) diff --git a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/test/FenwickTree.test.js b/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/test/FenwickTree.test.js deleted file mode 100644 index c7d6996fa5..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/fenwick-tree/test/FenwickTree.test.js +++ /dev/null @@ -1,90 +0,0 @@ -import FenwickTree from '../FenwickTree'; -describe('FenwickTree', () => { - it('should create empty fenwick tree of correct size', () => { - const tree1 = new FenwickTree(5); - expect(tree1.treeArray.length).toBe(5 + 1); - for (let i = 0; i < 5; i += 1) { - expect(tree1.treeArray[i]).toBe(0); - } - const tree2 = new FenwickTree(50); - expect(tree2.treeArray.length).toBe(50 + 1); - }); - it('should create correct fenwick tree', () => { - const inputArray = [3, 2, -1, 6, 5, 4, -3, 3, 7, 2, 3]; - const tree = new FenwickTree(inputArray.length); - expect(tree.treeArray.length).toBe(inputArray.length + 1); - inputArray.forEach((value, index) => { - tree.increase(index + 1, value); - }); - expect(tree.treeArray).toEqual([0, 3, 5, -1, 10, 5, 9, -3, 19, 7, 9, 3]); - expect(tree.query(1)).toBe(3); - expect(tree.query(2)).toBe(5); - expect(tree.query(3)).toBe(4); - expect(tree.query(4)).toBe(10); - expect(tree.query(5)).toBe(15); - expect(tree.query(6)).toBe(19); - expect(tree.query(7)).toBe(16); - expect(tree.query(8)).toBe(19); - expect(tree.query(9)).toBe(26); - expect(tree.query(10)).toBe(28); - expect(tree.query(11)).toBe(31); - expect(tree.queryRange(1, 1)).toBe(3); - expect(tree.queryRange(1, 2)).toBe(5); - expect(tree.queryRange(2, 4)).toBe(7); - expect(tree.queryRange(6, 9)).toBe(11); - tree.increase(3, 1); - expect(tree.query(1)).toBe(3); - expect(tree.query(2)).toBe(5); - expect(tree.query(3)).toBe(5); - expect(tree.query(4)).toBe(11); - expect(tree.query(5)).toBe(16); - expect(tree.query(6)).toBe(20); - expect(tree.query(7)).toBe(17); - expect(tree.query(8)).toBe(20); - expect(tree.query(9)).toBe(27); - expect(tree.query(10)).toBe(29); - expect(tree.query(11)).toBe(32); - expect(tree.queryRange(1, 1)).toBe(3); - expect(tree.queryRange(1, 2)).toBe(5); - expect(tree.queryRange(2, 4)).toBe(8); - expect(tree.queryRange(6, 9)).toBe(11); - }); - it('should correctly execute queries', () => { - const tree = new FenwickTree(5); - tree.increase(1, 4); - tree.increase(3, 7); - expect(tree.query(1)).toBe(4); - expect(tree.query(3)).toBe(11); - expect(tree.query(5)).toBe(11); - expect(tree.queryRange(2, 3)).toBe(7); - tree.increase(2, 5); - expect(tree.query(5)).toBe(16); - tree.increase(1, 3); - expect(tree.queryRange(1, 1)).toBe(7); - expect(tree.query(5)).toBe(19); - expect(tree.queryRange(1, 5)).toBe(19); - }); - it('should throw exceptions', () => { - const tree = new FenwickTree(5); - const increaseAtInvalidLowIndex = () => { - tree.increase(0, 1); - }; - const increaseAtInvalidHighIndex = () => { - tree.increase(10, 1); - }; - const queryInvalidLowIndex = () => { - tree.query(0); - }; - const queryInvalidHighIndex = () => { - tree.query(10); - }; - const rangeQueryInvalidIndex = () => { - tree.queryRange(3, 2); - }; - expect(increaseAtInvalidLowIndex).toThrowError(); - expect(increaseAtInvalidHighIndex).toThrowError(); - expect(queryInvalidLowIndex).toThrowError(); - expect(queryInvalidHighIndex).toThrowError(); - expect(rangeQueryInvalidIndex).toThrowError(); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/README.md b/docs/content/DS_ALGO/data-structures/tree/red-black-tree/README.md deleted file mode 100644 index 82858d6363..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# Red-Black Tree - -A **red-black tree** is a kind of self-balancing binary search -tree in computer science. Each node of the binary tree has -an extra bit, and that bit is often interpreted as the -color (red or black) of the node. These color bits are used -to ensure the tree remains approximately balanced during -insertions and deletions. - -Balance is preserved by painting each node of the tree with -one of two colors in a way that satisfies certain properties, -which collectively constrain how unbalanced the tree can -become in the worst case. When the tree is modified, the -new tree is subsequently rearranged and repainted to -restore the coloring properties. The properties are -designed in such a way that this rearranging and recoloring -can be performed efficiently. - -The balancing of the tree is not perfect, but it is good -enough to allow it to guarantee searching in `O(log n)` time, -where `n` is the total number of elements in the tree. -The insertion and deletion operations, along with the tree -rearrangement and recoloring, are also performed -in `O(log n)` time. - -An example of a red-black tree: - -![red-black tree](https://upload.wikimedia.org/wikipedia/commons/6/66/Red-black_tree_example.svg) - -## Properties - -In addition to the requirements imposed on a binary search -tree the following must be satisfied by a red-black tree: - -- Each node is either red or black. -- The root is black. This rule is sometimes omitted. - Since the root can always be changed from red to black, - but not necessarily vice versa, this rule has little - effect on analysis. -- All leaves (NIL) are black. -- If a node is red, then both its children are black. -- Every path from a given node to any of its descendant - NIL nodes contains the same number of black nodes. - -Some definitions: the number of black nodes from the root -to a node is the node's **black depth**; the uniform -number of black nodes in all paths from root to the leaves -is called the **black-height** of the red-black tree. - -These constraints enforce a critical property of red-black -trees: _the path from the root to the farthest leaf is no more than twice as long as the path from the root to the nearest leaf_. -The result is that the tree is roughly height-balanced. -Since operations such as inserting, deleting, and finding -values require worst-case time proportional to the height -of the tree, this theoretical upper bound on the height -allows red-black trees to be efficient in the worst case, -unlike ordinary binary search trees. - -## Balancing during insertion - -### If uncle is RED - -![Red Black Tree Balancing](https://www.geeksforgeeks.org/wp-content/uploads/redBlackCase2.png) - -### If uncle is BLACK - -- Left Left Case (`p` is left child of `g` and `x` is left child of `p`) -- Left Right Case (`p` is left child of `g` and `x` is right child of `p`) -- Right Right Case (`p` is right child of `g` and `x` is right child of `p`) -- Right Left Case (`p` is right child of `g` and `x` is left child of `p`) - -#### Left Left Case (See g, p and x) - -![Red Black Tree Balancing](https://www.geeksforgeeks.org/wp-content/uploads/redBlackCase3a1.png) - -#### Left Right Case (See g, p and x) - -![Red Black Tree Balancing](https://www.geeksforgeeks.org/wp-content/uploads/redBlackCase3b.png) - -#### Right Right Case (See g, p and x) - -![Red Black Tree Balancing](https://www.geeksforgeeks.org/wp-content/uploads/redBlackCase3c.png) - -#### Right Left Case (See g, p and x) - -![Red Black Tree Balancing](https://www.geeksforgeeks.org/wp-content/uploads/redBlackCase3d.png) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree) -- [Red Black Tree Insertion by Tushar Roy (YouTube)](https://www.youtube.com/watch?v=UaLIHuR1t8Q&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=63) -- [Red Black Tree Deletion by Tushar Roy (YouTube)](https://www.youtube.com/watch?v=CTvfzU_uNKE&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=64) -- [Red Black Tree Insertion on GeeksForGeeks](https://www.geeksforgeeks.org/red-black-tree-set-2-insert/) -- [Red Black Tree Interactive Visualisations](https://www.cs.usfca.edu/~galles/visualization/RedBlack.html) diff --git a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/RedBlackTree.js b/docs/content/DS_ALGO/data-structures/tree/red-black-tree/RedBlackTree.js deleted file mode 100644 index 35705e6242..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/RedBlackTree.js +++ /dev/null @@ -1,265 +0,0 @@ -import BinarySearchTree from '../binary-search-tree/BinarySearchTree'; -// Possible colors of red-black tree nodes. -const RED_BLACK_TREE_COLORS = { - red: 'red', - black: 'black' -}; -// Color property name in meta information of the nodes. -const COLOR_PROP_NAME = 'color'; -export default class RedBlackTree extends BinarySearchTree { - /** - * @param {*} value - * @return {BinarySearchTreeNode} - */ - insert(value) { - const insertedNode = super.insert(value); - // if (!this.root.left && !this.root.right) { - if (this.nodeComparator.equal(insertedNode, this.root)) { - // Make root to always be black. - this.makeNodeBlack(insertedNode); - } else { - // Make all newly inserted nodes to be red. - this.makeNodeRed(insertedNode); - } - // Check all conditions and balance the node. - this.balance(insertedNode); - return insertedNode; - } - /** - * @param {*} value - * @return {boolean} - */ - remove(value) { - throw new Error(`Can't remove ${value}. Remove method is not implemented yet`); - } - /** - * @param {BinarySearchTreeNode} node - */ - balance(node) { - // If it is a root node then nothing to balance here. - if (this.nodeComparator.equal(node, this.root)) { - return; - } - // If the parent is black then done. Nothing to balance here. - if (this.isNodeBlack(node.parent)) { - return; - } - const grandParent = node.parent.parent; - if (node.uncle && this.isNodeRed(node.uncle)) { - // If node has red uncle then we need to do RECOLORING. - // Recolor parent and uncle to black. - this.makeNodeBlack(node.uncle); - this.makeNodeBlack(node.parent); - if (!this.nodeComparator.equal(grandParent, this.root)) { - // Recolor grand-parent to red if it is not root. - this.makeNodeRed(grandParent); - } else { - // If grand-parent is black root don't do anything. - // Since root already has two black sibling that we've just recolored. - return; - } - // Now do further checking for recolored grand-parent. - this.balance(grandParent); - } else if (!node.uncle || this.isNodeBlack(node.uncle)) { - // If node uncle is black or absent then we need to do ROTATIONS. - if (grandParent) { - // Grand parent that we will receive after rotations. - let newGrandParent; - if (this.nodeComparator.equal(grandParent.left, node.parent)) { - // Left case. - if (this.nodeComparator.equal(node.parent.left, node)) { - // Left-left case. - newGrandParent = this.leftLeftRotation(grandParent); - } else { - // Left-right case. - newGrandParent = this.leftRightRotation(grandParent); - } - } else { - // Right case. - if (this.nodeComparator.equal(node.parent.right, node)) { - // Right-right case. - newGrandParent = this.rightRightRotation(grandParent); - } else { - // Right-left case. - newGrandParent = this.rightLeftRotation(grandParent); - } - } - // Set newGrandParent as a root if it doesn't have parent. - if (newGrandParent && newGrandParent.parent === null) { - this.root = newGrandParent; - // Recolor root into black. - this.makeNodeBlack(this.root); - } - // Check if new grand parent don't violate red-black-tree rules. - this.balance(newGrandParent); - } - } - } - /** - * Left Left Case (p is left child of g and x is left child of p) - * @param {BinarySearchTreeNode|BinaryTreeNode} grandParentNode - * @return {BinarySearchTreeNode} - */ - leftLeftRotation(grandParentNode) { - // Memorize the parent of grand-parent node. - const grandGrandParent = grandParentNode.parent; - // Check what type of sibling is our grandParentNode is (left or right). - let grandParentNodeIsLeft; - if (grandGrandParent) { - grandParentNodeIsLeft = this.nodeComparator.equal(grandGrandParent.left, grandParentNode); - } - // Memorize grandParentNode's left node. - const parentNode = grandParentNode.left; - // Memorize parent's right node since we're going to transfer it to - // grand parent's left subtree. - const parentRightNode = parentNode.right; - // Make grandParentNode to be right child of parentNode. - parentNode.setRight(grandParentNode); - // Move child's right subtree to grandParentNode's left subtree. - grandParentNode.setLeft(parentRightNode); - // Put parentNode node in place of grandParentNode. - if (grandGrandParent) { - if (grandParentNodeIsLeft) { - grandGrandParent.setLeft(parentNode); - } else {} - grandGrandParent.setRight(parentNode); - } - } else { - // Make parent node a root - parentNode.parent = null; - } - // Swap colors of grandParentNode and parentNode. - this.swapNodeColors(parentNode, grandParentNode); - // Return new root node. - return parentNode; -} -/** - * Left Right Case (p is left child of g and x is right child of p) - * @param {BinarySearchTreeNode|BinaryTreeNode} grandParentNode - * @return {BinarySearchTreeNode} - */ -leftRightRotation(grandParentNode) { - // Memorize left and left-right nodes. - const parentNode = grandParentNode.left; - const childNode = parentNode.right; - // We need to memorize child left node to prevent losing - // left child subtree. Later it will be re-assigned to - // parent's right sub-tree. - const childLeftNode = childNode.left; - // Make parentNode to be a left child of childNode node. - childNode.setLeft(parentNode); - // Move child's left subtree to parent's right subtree. - parentNode.setRight(childLeftNode); - // Put left-right node in place of left node. - grandParentNode.setLeft(childNode); - // Now we're ready to do left-left rotation. - return this.leftLeftRotation(grandParentNode); -} -/** - * Right Right Case (p is right child of g and x is right child of p) - * @param {BinarySearchTreeNode|BinaryTreeNode} grandParentNode - * @return {BinarySearchTreeNode} - */ -rightRightRotation(grandParentNode) { - // Memorize the parent of grand-parent node. - const grandGrandParent = grandParentNode.parent; - // Check what type of sibling is our grandParentNode is (left or right). - let grandParentNodeIsLeft; - if (grandGrandParent) { - grandParentNodeIsLeft = this.nodeComparator.equal(grandGrandParent.left, grandParentNode); - } - // Memorize grandParentNode's right node. - const parentNode = grandParentNode.right; - // Memorize parent's left node since we're going to transfer it to - // grand parent's right subtree. - const parentLeftNode = parentNode.left; - // Make grandParentNode to be left child of parentNode. - parentNode.setLeft(grandParentNode); - // Transfer all left nodes from parent to right sub-tree of grandparent. - grandParentNode.setRight(parentLeftNode); - // Put parentNode node in place of grandParentNode. - if (grandGrandParent) { - if (grandParentNodeIsLeft) { - grandGrandParent.setLeft(parentNode); - } else {} - grandGrandParent.setRight(parentNode); - } -} else { - // Make parent node a root. - parentNode.parent = null; -} -// Swap colors of granParent and parent nodes. -this.swapNodeColors(parentNode, grandParentNode); -// Return new root node. -return parentNode; -} -/** - * Right Left Case (p is right child of g and x is left child of p) - * @param {BinarySearchTreeNode|BinaryTreeNode} grandParentNode - * @return {BinarySearchTreeNode} - */ -rightLeftRotation(grandParentNode) { - // Memorize right and right-left nodes. - const parentNode = grandParentNode.right; - const childNode = parentNode.left; - // We need to memorize child right node to prevent losing - // right child subtree. Later it will be re-assigned to - // parent's left sub-tree. - const childRightNode = childNode.right; - // Make parentNode to be a right child of childNode. - childNode.setRight(parentNode); - // Move child's right subtree to parent's left subtree. - parentNode.setLeft(childRightNode); - // Put childNode node in place of parentNode. - grandParentNode.setRight(childNode); - // Now we're ready to do right-right rotation. - return this.rightRightRotation(grandParentNode); -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} node - * @return {BinarySearchTreeNode} - */ -makeNodeRed(node) { - node.meta.set(COLOR_PROP_NAME, RED_BLACK_TREE_COLORS.red); - return node; -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} node - * @return {BinarySearchTreeNode} - */ -makeNodeBlack(node) { - node.meta.set(COLOR_PROP_NAME, RED_BLACK_TREE_COLORS.black); - return node; -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} node - * @return {boolean} - */ -isNodeRed(node) { - return node.meta.get(COLOR_PROP_NAME) === RED_BLACK_TREE_COLORS.red; -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} node - * @return {boolean} - */ -isNodeBlack(node) { - return node.meta.get(COLOR_PROP_NAME) === RED_BLACK_TREE_COLORS.black; -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} node - * @return {boolean} - */ -isNodeColored(node) { - return this.isNodeRed(node) || this.isNodeBlack(node); -} -/** - * @param {BinarySearchTreeNode|BinaryTreeNode} firstNode - * @param {BinarySearchTreeNode|BinaryTreeNode} secondNode - */ -swapNodeColors(firstNode, secondNode) { - const firstColor = firstNode.meta.get(COLOR_PROP_NAME); - const secondColor = secondNode.meta.get(COLOR_PROP_NAME); - firstNode.meta.set(COLOR_PROP_NAME, secondColor); - secondNode.meta.set(COLOR_PROP_NAME, firstColor); -} -} diff --git a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/test/RedBlackTree.test.js b/docs/content/DS_ALGO/data-structures/tree/red-black-tree/test/RedBlackTree.test.js deleted file mode 100644 index 160e11f7aa..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/red-black-tree/test/RedBlackTree.test.js +++ /dev/null @@ -1,249 +0,0 @@ -import RedBlackTree from '../RedBlackTree'; -describe('RedBlackTree', () => { - it('should always color first inserted node as black', () => { - const tree = new RedBlackTree(); - const firstInsertedNode = tree.insert(10); - expect(tree.isNodeColored(firstInsertedNode)).toBe(true); - expect(tree.isNodeBlack(firstInsertedNode)).toBe(true); - expect(tree.isNodeRed(firstInsertedNode)).toBe(false); - expect(tree.toString()).toBe('10'); - expect(tree.root.height).toBe(0); - }); - it('should always color new leaf node as red', () => { - const tree = new RedBlackTree(); - const firstInsertedNode = tree.insert(10); - const secondInsertedNode = tree.insert(15); - const thirdInsertedNode = tree.insert(5); - expect(tree.isNodeBlack(firstInsertedNode)).toBe(true); - expect(tree.isNodeRed(secondInsertedNode)).toBe(true); - expect(tree.isNodeRed(thirdInsertedNode)).toBe(true); - expect(tree.toString()).toBe('5,10,15'); - expect(tree.root.height).toBe(1); - }); - it('should balance itself', () => { - const tree = new RedBlackTree(); - tree.insert(5); - tree.insert(10); - tree.insert(15); - tree.insert(20); - tree.insert(25); - tree.insert(30); - expect(tree.toString()).toBe('5,10,15,20,25,30'); - expect(tree.root.height).toBe(3); - }); - it('should balance itself when parent is black', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - expect(tree.isNodeBlack(node1)).toBe(true); - const node2 = tree.insert(-10); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - const node3 = tree.insert(20); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - expect(tree.isNodeRed(node3)).toBe(true); - const node4 = tree.insert(-20); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - const node5 = tree.insert(25); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - const node6 = tree.insert(6); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - expect(tree.toString()).toBe('-20,-10,6,10,20,25'); - expect(tree.root.height).toBe(2); - const node7 = tree.insert(4); - expect(tree.root.left.value).toEqual(node2.value); - expect(tree.toString()).toBe('-20,-10,4,6,10,20,25'); - expect(tree.root.height).toBe(3); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeBlack(node4)).toBe(true); - expect(tree.isNodeBlack(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - expect(tree.isNodeBlack(node6)).toBe(true); - expect(tree.isNodeRed(node7)).toBe(true); - }); - it('should balance itself when uncle is red', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - const node2 = tree.insert(-10); - const node3 = tree.insert(20); - const node4 = tree.insert(-20); - const node5 = tree.insert(6); - const node6 = tree.insert(15); - const node7 = tree.insert(25); - const node8 = tree.insert(2); - const node9 = tree.insert(8); - expect(tree.toString()).toBe('-20,-10,2,6,8,10,15,20,25'); - expect(tree.root.height).toBe(3); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeBlack(node4)).toBe(true); - expect(tree.isNodeBlack(node5)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - expect(tree.isNodeRed(node7)).toBe(true); - expect(tree.isNodeRed(node8)).toBe(true); - expect(tree.isNodeRed(node9)).toBe(true); - const node10 = tree.insert(4); - expect(tree.toString()).toBe('-20,-10,2,4,6,8,10,15,20,25'); - expect(tree.root.height).toBe(3); - expect(tree.root.value).toBe(node5.value); - expect(tree.isNodeBlack(node5)).toBe(true); - expect(tree.isNodeRed(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - expect(tree.isNodeRed(node10)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - expect(tree.isNodeRed(node7)).toBe(true); - expect(tree.isNodeBlack(node4)).toBe(true); - expect(tree.isNodeBlack(node8)).toBe(true); - expect(tree.isNodeBlack(node9)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - }); - it('should do left-left rotation', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - const node2 = tree.insert(-10); - const node3 = tree.insert(20); - const node4 = tree.insert(7); - const node5 = tree.insert(15); - expect(tree.toString()).toBe('-10,7,10,15,20'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - const node6 = tree.insert(13); - expect(tree.toString()).toBe('-10,7,10,13,15,20'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node5)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - expect(tree.isNodeRed(node3)).toBe(true); - }); - it('should do left-right rotation', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - const node2 = tree.insert(-10); - const node3 = tree.insert(20); - const node4 = tree.insert(7); - const node5 = tree.insert(15); - expect(tree.toString()).toBe('-10,7,10,15,20'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - const node6 = tree.insert(17); - expect(tree.toString()).toBe('-10,7,10,15,17,20'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node6)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - expect(tree.isNodeRed(node3)).toBe(true); - }); - it('should do recoloring, left-left and left-right rotation', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - const node2 = tree.insert(-10); - const node3 = tree.insert(20); - const node4 = tree.insert(-20); - const node5 = tree.insert(6); - const node6 = tree.insert(15); - const node7 = tree.insert(30); - const node8 = tree.insert(1); - const node9 = tree.insert(9); - expect(tree.toString()).toBe('-20,-10,1,6,9,10,15,20,30'); - expect(tree.root.height).toBe(3); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeRed(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeBlack(node4)).toBe(true); - expect(tree.isNodeBlack(node5)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - expect(tree.isNodeRed(node7)).toBe(true); - expect(tree.isNodeRed(node8)).toBe(true); - expect(tree.isNodeRed(node9)).toBe(true); - tree.insert(4); - expect(tree.toString()).toBe('-20,-10,1,4,6,9,10,15,20,30'); - expect(tree.root.height).toBe(3); - }); - it('should do right-left rotation', () => { - const tree = new RedBlackTree(); - const node1 = tree.insert(10); - const node2 = tree.insert(-10); - const node3 = tree.insert(20); - const node4 = tree.insert(-20); - const node5 = tree.insert(6); - const node6 = tree.insert(30); - expect(tree.toString()).toBe('-20,-10,6,10,20,30'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node3)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - const node7 = tree.insert(25); - const rightNode = tree.root.right; - const rightLeftNode = rightNode.left; - const rightRightNode = rightNode.right; - expect(rightNode.value).toBe(node7.value); - expect(rightLeftNode.value).toBe(node3.value); - expect(rightRightNode.value).toBe(node6.value); - expect(tree.toString()).toBe('-20,-10,6,10,20,25,30'); - expect(tree.root.height).toBe(2); - expect(tree.isNodeBlack(node1)).toBe(true); - expect(tree.isNodeBlack(node2)).toBe(true); - expect(tree.isNodeBlack(node7)).toBe(true); - expect(tree.isNodeRed(node4)).toBe(true); - expect(tree.isNodeRed(node5)).toBe(true); - expect(tree.isNodeRed(node3)).toBe(true); - expect(tree.isNodeRed(node6)).toBe(true); - }); - it('should do left-left rotation with left grand-parent', () => { - const tree = new RedBlackTree(); - tree.insert(20); - tree.insert(15); - tree.insert(25); - tree.insert(10); - tree.insert(5); - expect(tree.toString()).toBe('5,10,15,20,25'); - expect(tree.root.height).toBe(2); - }); - it('should do right-right rotation with left grand-parent', () => { - const tree = new RedBlackTree(); - tree.insert(20); - tree.insert(15); - tree.insert(25); - tree.insert(17); - tree.insert(19); - expect(tree.toString()).toBe('15,17,19,20,25'); - expect(tree.root.height).toBe(2); - }); - it('should throw an error when trying to remove node', () => { - const removeNodeFromRedBlackTree = () => { - const tree = new RedBlackTree(); - tree.remove(1); - }; - expect(removeNodeFromRedBlackTree).toThrowError(); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/segment-tree/README.md b/docs/content/DS_ALGO/data-structures/tree/segment-tree/README.md deleted file mode 100644 index ebf3c4b068..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/segment-tree/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Segment Tree - -In computer science, a **segment tree** also known as a statistic tree -is a tree data structure used for storing information about intervals, -or segments. It allows querying which of the stored segments contain -a given point. It is, in principle, a static structure; that is, -it's a structure that cannot be modified once it's built. A similar -data structure is the interval tree. - -A segment tree is a binary tree. The root of the tree represents the -whole array. The two children of the root represent the -first and second halves of the array. Similarly, the -children of each node corresponds to the two halves of -the array corresponding to the node. - -We build the tree bottom up, with the value of each node -being the "minimum" (or any other function) of its children's values. This will -take `O(n log n)` time. The number -of operations done is the height of the tree, which -is `O(log n)`. To do range queries, each node splits the -query into two parts, one sub-query for each child. -If a query contains the whole subarray of a node, we -can use the precomputed value at the node. Using this -optimisation, we can prove that only `O(log n)` minimum -operations are done. - -![Min Segment Tree](https://www.geeksforgeeks.org/wp-content/uploads/RangeMinimumQuery.png) - -![Sum Segment Tree](https://www.geeksforgeeks.org/wp-content/uploads/segment-tree1.png) - -## Application - -A segment tree is a data structure designed to perform -certain array operations efficiently - especially those -involving range queries. - -Applications of the segment tree are in the areas of computational geometry, -and geographic information systems. - -Current implementation of Segment Tree implies that you may -pass any binary (with two input params) function to it and -thus you're able to do range query for variety of functions. -In tests you may find examples of doing `min`, `max` and `sum` range -queries on SegmentTree. - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Segment_tree) -- [YouTube](https://www.youtube.com/watch?v=ZBHKZF5w4YU&index=65&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -- [GeeksForGeeks](https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/) diff --git a/docs/content/DS_ALGO/data-structures/tree/segment-tree/SegmentTree.js b/docs/content/DS_ALGO/data-structures/tree/segment-tree/SegmentTree.js deleted file mode 100644 index 03f989d741..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/segment-tree/SegmentTree.js +++ /dev/null @@ -1,127 +0,0 @@ -import isPowerOfTwo from '../../../algorithms/math/is-power-of-two/isPowerOfTwo'; -export default class SegmentTree { - /** - * @param {number[]} inputArray - * @param {function} operation - binary function (i.e. sum, min) - * @param {number} operationFallback - operation fallback value (i.e. 0 for sum, Infinity for min) - */ - constructor(inputArray, operation, operationFallback) { - this.inputArray = inputArray; - this.operation = operation; - this.operationFallback = operationFallback; - // Init array representation of segment tree. - this.segmentTree = this.initSegmentTree(this.inputArray); - this.buildSegmentTree(); - } - /** - * @param {number[]} inputArray - * @return {number[]} - */ - initSegmentTree(inputArray) { - let segmentTreeArrayLength; - const inputArrayLength = inputArray.length; - if (isPowerOfTwo(inputArrayLength)) { - // If original array length is a power of two. - segmentTreeArrayLength = 2 * inputArrayLength - 1; - } else { - // If original array length is not a power of two then we need to find - // next number that is a power of two and use it to calculate - // tree array size. This is happens because we need to fill empty children - // in perfect binary tree with nulls.And those nulls need extra space. - const currentPower = Math.floor(Math.log2(inputArrayLength)); - const nextPower = currentPower + 1; - const nextPowerOfTwoNumber = 2 ** nextPower; - segmentTreeArrayLength = 2 * nextPowerOfTwoNumber - 1; - } - return new Array(segmentTreeArrayLength).fill(null); - } - /** - * Build segment tree. - */ - buildSegmentTree() { - const leftIndex = 0; - const rightIndex = this.inputArray.length - 1; - const position = 0; - this.buildTreeRecursively(leftIndex, rightIndex, position); - } - /** - * Build segment tree recursively. - * - * @param {number} leftInputIndex - * @param {number} rightInputIndex - * @param {number} position - */ - buildTreeRecursively(leftInputIndex, rightInputIndex, position) { - // If low input index and high input index are equal that would mean - // the we have finished splitting and we are already came to the leaf - // of the segment tree. We need to copy this leaf value from input - // array to segment tree. - if (leftInputIndex === rightInputIndex) { - this.segmentTree[position] = this.inputArray[leftInputIndex]; - return; - } - // Split input array on two halves and process them recursively. - const middleIndex = Math.floor((leftInputIndex + rightInputIndex) / 2); - // Process left half of the input array. - this.buildTreeRecursively(leftInputIndex, middleIndex, this.getLeftChildIndex(position)); - // Process right half of the input array. - this.buildTreeRecursively(middleIndex + 1, rightInputIndex, this.getRightChildIndex(position)); - // Once every tree leaf is not empty we're able to build tree bottom up using - // provided operation function. - this.segmentTree[position] = this.operation(this.segmentTree[this.getLeftChildIndex(position)], this.segmentTree[this.getRightChildIndex(position)]); - } - /** - * Do range query on segment tree in context of this.operation function. - * - * @param {number} queryLeftIndex - * @param {number} queryRightIndex - * @return {number} - */ - rangeQuery(queryLeftIndex, queryRightIndex) { - const leftIndex = 0; - const rightIndex = this.inputArray.length - 1; - const position = 0; - return this.rangeQueryRecursive(queryLeftIndex, queryRightIndex, leftIndex, rightIndex, position); - } - /** - * Do range query on segment tree recursively in context of this.operation function. - * - * @param {number} queryLeftIndex - left index of the query - * @param {number} queryRightIndex - right index of the query - * @param {number} leftIndex - left index of input array segment - * @param {number} rightIndex - right index of input array segment - * @param {number} position - root position in binary tree - * @return {number} - */ - rangeQueryRecursive(queryLeftIndex, queryRightIndex, leftIndex, rightIndex, position) { - if (queryLeftIndex <= leftIndex && queryRightIndex >= rightIndex) { - // Total overlap. - return this.segmentTree[position]; - } - if (queryLeftIndex > rightIndex || queryRightIndex < leftIndex) { - // No overlap. - return this.operationFallback; - } - // Partial overlap. - const middleIndex = Math.floor((leftIndex + rightIndex) / 2); - const leftOperationResult = this.rangeQueryRecursive(queryLeftIndex, queryRightIndex, leftIndex, middleIndex, this.getLeftChildIndex(position)); - const rightOperationResult = this.rangeQueryRecursive(queryLeftIndex, queryRightIndex, middleIndex + 1, rightIndex, this.getRightChildIndex(position)); - return this.operation(leftOperationResult, rightOperationResult); - } - /** - * Left child index. - * @param {number} parentIndex - * @return {number} - */ - getLeftChildIndex(parentIndex) { - return 2 * parentIndex + 1; - } - /** - * Right child index. - * @param {number} parentIndex - * @return {number} - */ - getRightChildIndex(parentIndex) { - return 2 * parentIndex + 2; - } -} diff --git a/docs/content/DS_ALGO/data-structures/tree/segment-tree/test/SegmentTree.test.js b/docs/content/DS_ALGO/data-structures/tree/segment-tree/test/SegmentTree.test.js deleted file mode 100644 index c98716c99f..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/segment-tree/test/SegmentTree.test.js +++ /dev/null @@ -1,79 +0,0 @@ -import SegmentTree from '../SegmentTree'; -describe('SegmentTree', () => { - it('should build tree for input array #0 with length of power of two', () => { - const array = [-1, 2]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.segmentTree).toEqual([-1, -1, 2]); - expect(segmentTree.segmentTree.length).toBe(2 * array.length - 1); - }); - it('should build tree for input array #1 with length of power of two', () => { - const array = [-1, 2, 4, 0]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.segmentTree).toEqual([-1, -1, 0, -1, 2, 4, 0]); - expect(segmentTree.segmentTree.length).toBe(2 * array.length - 1); - }); - it('should build tree for input array #0 with length not of power of two', () => { - const array = [0, 1, 2]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.segmentTree).toEqual([0, 0, 2, 0, 1, null, null]); - expect(segmentTree.segmentTree.length).toBe(2 * 4 - 1); - }); - it('should build tree for input array #1 with length not of power of two', () => { - const array = [-1, 3, 4, 0, 2, 1]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.segmentTree).toEqual([-1, -1, 0, -1, 4, 0, 1, -1, 3, null, null, 0, 2, null, null]); - expect(segmentTree.segmentTree.length).toBe(2 * 8 - 1); - }); - it('should build max array', () => { - const array = [-1, 2, 4, 0]; - const segmentTree = new SegmentTree(array, Math.max, -Infinity); - expect(segmentTree.segmentTree).toEqual([4, 2, 4, -1, 2, 4, 0]); - expect(segmentTree.segmentTree.length).toBe(2 * array.length - 1); - }); - it('should build sum array', () => { - const array = [-1, 2, 4, 0]; - const segmentTree = new SegmentTree(array, (a, b) => a + b, 0); - expect(segmentTree.segmentTree).toEqual([5, 1, 4, -1, 2, 4, 0]); - expect(segmentTree.segmentTree.length).toBe(2 * array.length - 1); - }); - it('should do min range query on power of two length array', () => { - const array = [-1, 3, 4, 0, 2, 1]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.rangeQuery(0, 5)).toBe(-1); - expect(segmentTree.rangeQuery(0, 2)).toBe(-1); - expect(segmentTree.rangeQuery(1, 3)).toBe(0); - expect(segmentTree.rangeQuery(2, 4)).toBe(0); - expect(segmentTree.rangeQuery(4, 5)).toBe(1); - expect(segmentTree.rangeQuery(2, 2)).toBe(4); - }); - it('should do min range query on not power of two length array', () => { - const array = [-1, 2, 4, 0]; - const segmentTree = new SegmentTree(array, Math.min, Infinity); - expect(segmentTree.rangeQuery(0, 4)).toBe(-1); - expect(segmentTree.rangeQuery(0, 1)).toBe(-1); - expect(segmentTree.rangeQuery(1, 3)).toBe(0); - expect(segmentTree.rangeQuery(1, 2)).toBe(2); - expect(segmentTree.rangeQuery(2, 3)).toBe(0); - expect(segmentTree.rangeQuery(2, 2)).toBe(4); - }); - it('should do max range query', () => { - const array = [-1, 3, 4, 0, 2, 1]; - const segmentTree = new SegmentTree(array, Math.max, -Infinity); - expect(segmentTree.rangeQuery(0, 5)).toBe(4); - expect(segmentTree.rangeQuery(0, 1)).toBe(3); - expect(segmentTree.rangeQuery(1, 3)).toBe(4); - expect(segmentTree.rangeQuery(2, 4)).toBe(4); - expect(segmentTree.rangeQuery(4, 5)).toBe(2); - expect(segmentTree.rangeQuery(3, 3)).toBe(0); - }); - it('should do sum range query', () => { - const array = [-1, 3, 4, 0, 2, 1]; - const segmentTree = new SegmentTree(array, (a, b) => a + b, 0); - expect(segmentTree.rangeQuery(0, 5)).toBe(9); - expect(segmentTree.rangeQuery(0, 1)).toBe(2); - expect(segmentTree.rangeQuery(1, 3)).toBe(7); - expect(segmentTree.rangeQuery(2, 4)).toBe(6); - expect(segmentTree.rangeQuery(4, 5)).toBe(3); - expect(segmentTree.rangeQuery(3, 3)).toBe(0); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/tree/test/BinaryTreeNode.test.js b/docs/content/DS_ALGO/data-structures/tree/test/BinaryTreeNode.test.js deleted file mode 100644 index 93f08ff3fc..0000000000 --- a/docs/content/DS_ALGO/data-structures/tree/test/BinaryTreeNode.test.js +++ /dev/null @@ -1,196 +0,0 @@ -import BinaryTreeNode from '../BinaryTreeNode'; -describe('BinaryTreeNode', () => { - it('should create node', () => { - const node = new BinaryTreeNode(); - expect(node).toBeDefined(); - expect(node.value).toBeNull(); - expect(node.left).toBeNull(); - expect(node.right).toBeNull(); - const leftNode = new BinaryTreeNode(1); - const rightNode = new BinaryTreeNode(3); - const rootNode = new BinaryTreeNode(2); - rootNode.setLeft(leftNode).setRight(rightNode); - expect(rootNode.value).toBe(2); - expect(rootNode.left.value).toBe(1); - expect(rootNode.right.value).toBe(3); - }); - it('should set parent', () => { - const leftNode = new BinaryTreeNode(1); - const rightNode = new BinaryTreeNode(3); - const rootNode = new BinaryTreeNode(2); - rootNode.setLeft(leftNode).setRight(rightNode); - expect(rootNode.parent).toBeNull(); - expect(rootNode.left.parent.value).toBe(2); - expect(rootNode.right.parent.value).toBe(2); - expect(rootNode.right.parent).toEqual(rootNode); - }); - it('should traverse node', () => { - const leftNode = new BinaryTreeNode(1); - const rightNode = new BinaryTreeNode(3); - const rootNode = new BinaryTreeNode(2); - rootNode.setLeft(leftNode).setRight(rightNode); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 3]); - expect(rootNode.toString()).toBe('1,2,3'); - }); - it('should remove child node', () => { - const leftNode = new BinaryTreeNode(1); - const rightNode = new BinaryTreeNode(3); - const rootNode = new BinaryTreeNode(2); - rootNode.setLeft(leftNode).setRight(rightNode); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 3]); - expect(rootNode.removeChild(rootNode.left)).toBe(true); - expect(rootNode.traverseInOrder()).toEqual([2, 3]); - expect(rootNode.removeChild(rootNode.right)).toBe(true); - expect(rootNode.traverseInOrder()).toEqual([2]); - expect(rootNode.removeChild(rootNode.right)).toBe(false); - expect(rootNode.traverseInOrder()).toEqual([2]); - }); - it('should replace child node', () => { - const leftNode = new BinaryTreeNode(1); - const rightNode = new BinaryTreeNode(3); - const rootNode = new BinaryTreeNode(2); - rootNode.setLeft(leftNode).setRight(rightNode); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 3]); - const replacementNode = new BinaryTreeNode(5); - rightNode.setRight(replacementNode); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 3, 5]); - expect(rootNode.replaceChild(rootNode.right, rootNode.right.right)).toBe(true); - expect(rootNode.right.value).toBe(5); - expect(rootNode.right.right).toBeNull(); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 5]); - expect(rootNode.replaceChild(rootNode.right, rootNode.right.right)).toBe(false); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 5]); - expect(rootNode.replaceChild(rootNode.right, replacementNode)).toBe(true); - expect(rootNode.traverseInOrder()).toEqual([1, 2, 5]); - expect(rootNode.replaceChild(rootNode.left, replacementNode)).toBe(true); - expect(rootNode.traverseInOrder()).toEqual([5, 2, 5]); - expect(rootNode.replaceChild(new BinaryTreeNode(), new BinaryTreeNode())).toBe(false); - }); - it('should calculate node height', () => { - const root = new BinaryTreeNode(1); - const left = new BinaryTreeNode(3); - const right = new BinaryTreeNode(2); - const grandLeft = new BinaryTreeNode(5); - const grandRight = new BinaryTreeNode(6); - const grandGrandLeft = new BinaryTreeNode(7); - expect(root.height).toBe(0); - expect(root.balanceFactor).toBe(0); - root.setLeft(left).setRight(right); - expect(root.height).toBe(1); - expect(left.height).toBe(0); - expect(root.balanceFactor).toBe(0); - left.setLeft(grandLeft).setRight(grandRight); - expect(root.height).toBe(2); - expect(left.height).toBe(1); - expect(grandLeft.height).toBe(0); - expect(grandRight.height).toBe(0); - expect(root.balanceFactor).toBe(1); - grandLeft.setLeft(grandGrandLeft); - expect(root.height).toBe(3); - expect(left.height).toBe(2); - expect(grandLeft.height).toBe(1); - expect(grandRight.height).toBe(0); - expect(grandGrandLeft.height).toBe(0); - expect(root.balanceFactor).toBe(2); - }); - it('should calculate node height for right nodes as well', () => { - const root = new BinaryTreeNode(1); - const right = new BinaryTreeNode(2); - root.setRight(right); - expect(root.height).toBe(1); - expect(right.height).toBe(0); - expect(root.balanceFactor).toBe(-1); - }); - it('should set null for left and right node', () => { - const root = new BinaryTreeNode(2); - const left = new BinaryTreeNode(1); - const right = new BinaryTreeNode(3); - root.setLeft(left); - root.setRight(right); - expect(root.left.value).toBe(1); - expect(root.right.value).toBe(3); - root.setLeft(null); - root.setRight(null); - expect(root.left).toBeNull(); - expect(root.right).toBeNull(); - }); - it('should be possible to create node with object as a value', () => { - const obj1 = { key: 'object_1', toString: () => 'object_1' }; - const obj2 = { key: 'object_2' }; - const node1 = new BinaryTreeNode(obj1); - const node2 = new BinaryTreeNode(obj2); - node1.setLeft(node2); - expect(node1.value).toEqual(obj1); - expect(node2.value).toEqual(obj2); - expect(node1.left.value).toEqual(obj2); - node1.removeChild(node2); - expect(node1.value).toEqual(obj1); - expect(node2.value).toEqual(obj2); - expect(node1.left).toBeNull(); - expect(node1.toString()).toBe('object_1'); - expect(node2.toString()).toBe('[object Object]'); - }); - it('should be possible to attach meta information to the node', () => { - const redNode = new BinaryTreeNode(1); - const blackNode = new BinaryTreeNode(2); - redNode.meta.set('color', 'red'); - blackNode.meta.set('color', 'black'); - expect(redNode.meta.get('color')).toBe('red'); - expect(blackNode.meta.get('color')).toBe('black'); - }); - it('should detect right uncle', () => { - const grandParent = new BinaryTreeNode('grand-parent'); - const parent = new BinaryTreeNode('parent'); - const uncle = new BinaryTreeNode('uncle'); - const child = new BinaryTreeNode('child'); - expect(grandParent.uncle).not.toBeDefined(); - expect(parent.uncle).not.toBeDefined(); - grandParent.setLeft(parent); - expect(parent.uncle).not.toBeDefined(); - expect(child.uncle).not.toBeDefined(); - parent.setLeft(child); - expect(child.uncle).not.toBeDefined(); - grandParent.setRight(uncle); - expect(parent.uncle).not.toBeDefined(); - expect(child.uncle).toBeDefined(); - expect(child.uncle).toEqual(uncle); - }); - it('should detect left uncle', () => { - const grandParent = new BinaryTreeNode('grand-parent'); - const parent = new BinaryTreeNode('parent'); - const uncle = new BinaryTreeNode('uncle'); - const child = new BinaryTreeNode('child'); - expect(grandParent.uncle).not.toBeDefined(); - expect(parent.uncle).not.toBeDefined(); - grandParent.setRight(parent); - expect(parent.uncle).not.toBeDefined(); - expect(child.uncle).not.toBeDefined(); - parent.setRight(child); - expect(child.uncle).not.toBeDefined(); - grandParent.setLeft(uncle); - expect(parent.uncle).not.toBeDefined(); - expect(child.uncle).toBeDefined(); - expect(child.uncle).toEqual(uncle); - }); - it('should be possible to set node values', () => { - const node = new BinaryTreeNode('initial_value'); - expect(node.value).toBe('initial_value'); - node.setValue('new_value'); - expect(node.value).toBe('new_value'); - }); - it('should be possible to copy node', () => { - const root = new BinaryTreeNode('root'); - const left = new BinaryTreeNode('left'); - const right = new BinaryTreeNode('right'); - root.setLeft(left).setRight(right); - expect(root.toString()).toBe('left,root,right'); - const newRoot = new BinaryTreeNode('new_root'); - const newLeft = new BinaryTreeNode('new_left'); - const newRight = new BinaryTreeNode('new_right'); - newRoot.setLeft(newLeft).setRight(newRight); - expect(newRoot.toString()).toBe('new_left,new_root,new_right'); - BinaryTreeNode.copyNode(root, newRoot); - expect(root.toString()).toBe('left,root,right'); - expect(newRoot.toString()).toBe('left,root,right'); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/trie/README.md b/docs/content/DS_ALGO/data-structures/trie/README.md deleted file mode 100644 index 968f6da2a2..0000000000 --- a/docs/content/DS_ALGO/data-structures/trie/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Trie - -In computer science, a **trie**, also called digital tree and sometimes -radix tree or prefix tree (as they can be searched by prefixes), -is a kind of search tree—an ordered tree data structure that is -used to store a dynamic set or associative array where the keys -are usually strings. Unlike a binary search tree, no node in the -tree stores the key associated with that node; instead, its -position in the tree defines the key with which it is associated. -All the descendants of a node have a common prefix of the string -associated with that node, and the root is associated with the -empty string. Values are not necessarily associated with every -node. Rather, values tend only to be associated with leaves, -and with some inner nodes that correspond to keys of interest. -For the space-optimized presentation of prefix tree, see compact -prefix tree. - -![Trie](https://upload.wikimedia.org/wikipedia/commons/b/be/Trie_example.svg) - -## References - -- [Wikipedia](https://en.wikipedia.org/wiki/Trie) -- [YouTube](https://www.youtube.com/watch?v=zIjfhVPRZCg&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=7&t=0s) diff --git a/docs/content/DS_ALGO/data-structures/trie/Trie.js b/docs/content/DS_ALGO/data-structures/trie/Trie.js deleted file mode 100644 index 5c48565fde..0000000000 --- a/docs/content/DS_ALGO/data-structures/trie/Trie.js +++ /dev/null @@ -1,88 +0,0 @@ -import TrieNode from './TrieNode'; -// Character that we will use for trie tree root. -const HEAD_CHARACTER = '*'; -export default class Trie { - constructor() { - this.head = new TrieNode(HEAD_CHARACTER); - } - /** - * @param {string} word - * @return {Trie} - */ - addWord(word) { - const characters = Array.from(word); - let currentNode = this.head; - for (let charIndex = 0; charIndex < characters.length; charIndex += 1) { - const isComplete = charIndex === characters.length - 1; - currentNode = currentNode.addChild(characters[charIndex], isComplete); - } - return this; - } - /** - * @param {string} word - * @return {Trie} - */ - deleteWord(word) { - const depthFirstDelete = (currentNode, charIndex = 0) => { - if (charIndex >= word.length) { - // Return if we're trying to delete the character that is out of word's scope. - return; - } - const character = word[charIndex]; - const nextNode = currentNode.getChild(character); - if (nextNode == null) { - // Return if we're trying to delete a word that has not been added to the Trie. - return; - } - // Go deeper. - depthFirstDelete(nextNode, charIndex + 1); - // Since we're going to delete a word let's un-mark its last character isCompleteWord flag. - if (charIndex === word.length - 1) { - nextNode.isCompleteWord = false; - } - // childNode is deleted only if: - // - childNode has NO children - // - childNode.isCompleteWord === false - currentNode.removeChild(character); - }; - // Start depth-first deletion from the head node. - depthFirstDelete(this.head); - return this; - } - /** - * @param {string} word - * @return {string[]} - */ - suggestNextCharacters(word) { - const lastCharacter = this.getLastCharacterNode(word); - if (!lastCharacter) { - return null; - } - return lastCharacter.suggestChildren(); - } - /** - * Check if complete word exists in Trie. - * - * @param {string} word - * @return {boolean} - */ - doesWordExist(word) { - const lastCharacter = this.getLastCharacterNode(word); - return !!lastCharacter && lastCharacter.isCompleteWord; - } - /** - * @param {string} word - * @return {TrieNode} - */ - getLastCharacterNode(word) { - const characters = Array.from(word); - let currentNode = this.head; - for (let charIndex = 0; charIndex < characters.length; charIndex += 1) { - if (!currentNode.hasChild(characters[charIndex])) { - return null; - } - currentNode = currentNode.getChild(characters[charIndex]); - } - return currentNode; - } -} diff --git a/docs/content/DS_ALGO/data-structures/trie/TrieNode.js b/docs/content/DS_ALGO/data-structures/trie/TrieNode.js deleted file mode 100644 index 96abb43949..0000000000 --- a/docs/content/DS_ALGO/data-structures/trie/TrieNode.js +++ /dev/null @@ -1,76 +0,0 @@ -import HashTable from '../hash-table/HashTable'; -export default class TrieNode { - /** - * @param {string} character - * @param {boolean} isCompleteWord - */ - constructor(character, isCompleteWord = false) { - this.character = character; - this.isCompleteWord = isCompleteWord; - this.children = new HashTable(); - } - /** - * @param {string} character - * @return {TrieNode} - */ - getChild(character) { - return this.children.get(character); - } - /** - * @param {string} character - * @param {boolean} isCompleteWord - * @return {TrieNode} - */ - addChild(character, isCompleteWord = false) { - if (!this.children.has(character)) { - this.children.set(character, new TrieNode(character, isCompleteWord)); - } - const childNode = this.children.get(character); - // In cases similar to adding "car" after "carpet" we need to mark "r" character as complete. - childNode.isCompleteWord = childNode.isCompleteWord || isCompleteWord; - return childNode; - } - /** - * @param {string} character - * @return {TrieNode} - */ - removeChild(character) { - const childNode = this.getChild(character); - // Delete childNode only if: - // - childNode has NO children, - // - childNode.isCompleteWord === false. - if (childNode && !childNode.isCompleteWord && !childNode.hasChildren()) { - this.children.delete(character); - } - return this; - } - /** - * @param {string} character - * @return {boolean} - */ - hasChild(character) { - return this.children.has(character); - } - /** - * Check whether current TrieNode has children or not. - * @return {boolean} - */ - hasChildren() { - return this.children.getKeys().length !== 0; - } - /** - * @return {string[]} - */ - suggestChildren() { - return [...this.children.getKeys()]; - } - /** - * @return {string} - */ - toString() { - let childrenAsString = this.suggestChildren().toString(); - childrenAsString = childrenAsString ? `:${childrenAsString}` : ''; - const isCompleteString = this.isCompleteWord ? '*' : ''; - return `${this.character}${isCompleteString}${childrenAsString}`; - } -} diff --git a/docs/content/DS_ALGO/data-structures/trie/test/Trie.test.js b/docs/content/DS_ALGO/data-structures/trie/test/Trie.test.js deleted file mode 100644 index b515f5cfa2..0000000000 --- a/docs/content/DS_ALGO/data-structures/trie/test/Trie.test.js +++ /dev/null @@ -1,75 +0,0 @@ -import Trie from '../Trie'; -describe('Trie', () => { - it('should create trie', () => { - const trie = new Trie(); - expect(trie).toBeDefined(); - expect(trie.head.toString()).toBe('*'); - }); - it('should add words to trie', () => { - const trie = new Trie(); - trie.addWord('cat'); - expect(trie.head.toString()).toBe('*:c'); - expect(trie.head.getChild('c').toString()).toBe('c:a'); - trie.addWord('car'); - expect(trie.head.toString()).toBe('*:c'); - expect(trie.head.getChild('c').toString()).toBe('c:a'); - expect(trie.head.getChild('c').getChild('a').toString()).toBe('a:t,r'); - expect(trie.head.getChild('c').getChild('a').getChild('t').toString()).toBe('t*'); - }); - it('should delete words from trie', () => { - const trie = new Trie(); - trie.addWord('carpet'); - trie.addWord('car'); - trie.addWord('cat'); - trie.addWord('cart'); - expect(trie.doesWordExist('carpet')).toBe(true); - expect(trie.doesWordExist('car')).toBe(true); - expect(trie.doesWordExist('cart')).toBe(true); - expect(trie.doesWordExist('cat')).toBe(true); - // Try to delete not-existing word first. - trie.deleteWord('carpool'); - expect(trie.doesWordExist('carpet')).toBe(true); - expect(trie.doesWordExist('car')).toBe(true); - expect(trie.doesWordExist('cart')).toBe(true); - expect(trie.doesWordExist('cat')).toBe(true); - trie.deleteWord('carpet'); - expect(trie.doesWordExist('carpet')).toEqual(false); - expect(trie.doesWordExist('car')).toEqual(true); - expect(trie.doesWordExist('cart')).toBe(true); - expect(trie.doesWordExist('cat')).toBe(true); - trie.deleteWord('cat'); - expect(trie.doesWordExist('car')).toEqual(true); - expect(trie.doesWordExist('cart')).toBe(true); - expect(trie.doesWordExist('cat')).toBe(false); - trie.deleteWord('car'); - expect(trie.doesWordExist('car')).toEqual(false); - expect(trie.doesWordExist('cart')).toBe(true); - trie.deleteWord('cart'); - expect(trie.doesWordExist('car')).toEqual(false); - expect(trie.doesWordExist('cart')).toBe(false); - }); - it('should suggests next characters', () => { - const trie = new Trie(); - trie.addWord('cat'); - trie.addWord('cats'); - trie.addWord('car'); - trie.addWord('caption'); - expect(trie.suggestNextCharacters('ca')).toEqual(['t', 'r', 'p']); - expect(trie.suggestNextCharacters('cat')).toEqual(['s']); - expect(trie.suggestNextCharacters('cab')).toBeNull(); - }); - it('should check if word exists', () => { - const trie = new Trie(); - trie.addWord('cat'); - trie.addWord('cats'); - trie.addWord('carpet'); - trie.addWord('car'); - trie.addWord('caption'); - expect(trie.doesWordExist('cat')).toBe(true); - expect(trie.doesWordExist('cats')).toBe(true); - expect(trie.doesWordExist('carpet')).toBe(true); - expect(trie.doesWordExist('car')).toBe(true); - expect(trie.doesWordExist('cap')).toBe(false); - expect(trie.doesWordExist('call')).toBe(false); - }); -}); diff --git a/docs/content/DS_ALGO/data-structures/trie/test/TrieNode.test.js b/docs/content/DS_ALGO/data-structures/trie/test/TrieNode.test.js deleted file mode 100644 index 048dc83bb8..0000000000 --- a/docs/content/DS_ALGO/data-structures/trie/test/TrieNode.test.js +++ /dev/null @@ -1,66 +0,0 @@ -import TrieNode from '../TrieNode'; -describe('TrieNode', () => { - it('should create trie node', () => { - const trieNode = new TrieNode('c', true); - expect(trieNode.character).toBe('c'); - expect(trieNode.isCompleteWord).toBe(true); - expect(trieNode.toString()).toBe('c*'); - }); - it('should add child nodes', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a', true); - trieNode.addChild('o'); - expect(trieNode.toString()).toBe('c:a,o'); - }); - it('should get child nodes', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a'); - trieNode.addChild('o'); - expect(trieNode.getChild('a').toString()).toBe('a'); - expect(trieNode.getChild('a').character).toBe('a'); - expect(trieNode.getChild('o').toString()).toBe('o'); - expect(trieNode.getChild('b')).toBeUndefined(); - }); - it('should check if node has children', () => { - const trieNode = new TrieNode('c'); - expect(trieNode.hasChildren()).toBe(false); - trieNode.addChild('a'); - expect(trieNode.hasChildren()).toBe(true); - }); - it('should check if node has specific child', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a'); - trieNode.addChild('o'); - expect(trieNode.hasChild('a')).toBe(true); - expect(trieNode.hasChild('o')).toBe(true); - expect(trieNode.hasChild('b')).toBe(false); - }); - it('should suggest next children', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a'); - trieNode.addChild('o'); - expect(trieNode.suggestChildren()).toEqual(['a', 'o']); - }); - it('should delete child node if the child node has NO children', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a'); - expect(trieNode.hasChild('a')).toBe(true); - trieNode.removeChild('a'); - expect(trieNode.hasChild('a')).toBe(false); - }); - it('should NOT delete child node if the child node has children', () => { - const trieNode = new TrieNode('c'); - trieNode.addChild('a'); - const childNode = trieNode.getChild('a'); - childNode.addChild('r'); - trieNode.removeChild('a'); - expect(trieNode.hasChild('a')).toEqual(true); - }); - it('should NOT delete child node if the child node completes a word', () => { - const trieNode = new TrieNode('c'); - const IS_COMPLETE_WORD = true; - trieNode.addChild('a', IS_COMPLETE_WORD); - trieNode.removeChild('a'); - expect(trieNode.hasChild('a')).toEqual(true); - }); -}); diff --git a/docs/content/DS_ALGO/utils/comparator/Comparator.js b/docs/content/DS_ALGO/utils/comparator/Comparator.js deleted file mode 100644 index 110896bc9e..0000000000 --- a/docs/content/DS_ALGO/utils/comparator/Comparator.js +++ /dev/null @@ -1,74 +0,0 @@ -export default class Comparator { - /** - * Constructor. - * @param {function(a: *, b: *)} [compareFunction] - It may be custom compare function that, let's - * say may compare custom objects together. - */ - constructor(compareFunction) { - this.compare = compareFunction || Comparator.defaultCompareFunction; - } - /** - * Default comparison function. It just assumes that "a" and "b" are strings or numbers. - * @param {(string|number)} a - * @param {(string|number)} b - * @returns {number} - */ - static defaultCompareFunction(a, b) { - if (a === b) { - return 0; - } - return a < b ? -1 : 1; - } - /** - * Checks if two variables are equal. - * @param {*} a - * @param {*} b - * @return {boolean} - */ - equal(a, b) { - return this.compare(a, b) === 0; - } - /** - * Checks if variable "a" is less than "b". - * @param {*} a - * @param {*} b - * @return {boolean} - */ - lessThan(a, b) { - return this.compare(a, b) < 0; - } - /** - * Checks if variable "a" is greater than "b". - * @param {*} a - * @param {*} b - * @return {boolean} - */ - greaterThan(a, b) { - return this.compare(a, b) > 0; - } - /** - * Checks if variable "a" is less than or equal to "b". - * @param {*} a - * @param {*} b - * @return {boolean} - */ - lessThanOrEqual(a, b) { - return this.lessThan(a, b) || this.equal(a, b); - } - /** - * Checks if variable "a" is greater than or equal to "b". - * @param {*} a - * @param {*} b - * @return {boolean} - */ - greaterThanOrEqual(a, b) { - return this.greaterThan(a, b) || this.equal(a, b); - } - /** - * Reverses the comparison order. - */ - reverse() { - const compareOriginal = this.compare; - this.compare = (a, b) => compareOriginal(b, a); - } -} diff --git a/docs/content/DS_ALGO/utils/comparator/test/Comparator.test.js b/docs/content/DS_ALGO/utils/comparator/test/Comparator.test.js deleted file mode 100644 index 69c10f1648..0000000000 --- a/docs/content/DS_ALGO/utils/comparator/test/Comparator.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import Comparator from '../Comparator'; -describe('Comparator', () => { - it('should compare with default comparator function', () => { - const comparator = new Comparator(); - expect(comparator.equal(0, 0)).toBe(true); - expect(comparator.equal(0, 1)).toBe(false); - expect(comparator.equal('a', 'a')).toBe(true); - expect(comparator.lessThan(1, 2)).toBe(true); - expect(comparator.lessThan(-1, 2)).toBe(true); - expect(comparator.lessThan('a', 'b')).toBe(true); - expect(comparator.lessThan('a', 'ab')).toBe(true); - expect(comparator.lessThan(10, 2)).toBe(false); - expect(comparator.lessThanOrEqual(10, 2)).toBe(false); - expect(comparator.lessThanOrEqual(1, 1)).toBe(true); - expect(comparator.lessThanOrEqual(0, 0)).toBe(true); - expect(comparator.greaterThan(0, 0)).toBe(false); - expect(comparator.greaterThan(10, 0)).toBe(true); - expect(comparator.greaterThanOrEqual(10, 0)).toBe(true); - expect(comparator.greaterThanOrEqual(10, 10)).toBe(true); - expect(comparator.greaterThanOrEqual(0, 10)).toBe(false); - }); - it('should compare with custom comparator function', () => { - const comparator = new Comparator((a, b) => { - if (a.length === b.length) { - return 0; - } - return a.length < b.length ? -1 : 1; - }); - expect(comparator.equal('a', 'b')).toBe(true); - expect(comparator.equal('a', '')).toBe(false); - expect(comparator.lessThan('b', 'aa')).toBe(true); - expect(comparator.greaterThanOrEqual('a', 'aa')).toBe(false); - expect(comparator.greaterThanOrEqual('aa', 'a')).toBe(true); - expect(comparator.greaterThanOrEqual('a', 'a')).toBe(true); - comparator.reverse(); - expect(comparator.equal('a', 'b')).toBe(true); - expect(comparator.equal('a', '')).toBe(false); - expect(comparator.lessThan('b', 'aa')).toBe(false); - expect(comparator.greaterThanOrEqual('a', 'aa')).toBe(true); - expect(comparator.greaterThanOrEqual('aa', 'a')).toBe(false); - expect(comparator.greaterThanOrEqual('a', 'a')).toBe(true); - }); -}); diff --git a/docs/content/books/c-handbook.pdf b/docs/content/books/c-handbook.pdf deleted file mode 100644 index 5598bafd24..0000000000 Binary files a/docs/content/books/c-handbook.pdf and /dev/null differ diff --git a/docs/content/books/es5-to-esnext.pdf b/docs/content/books/es5-to-esnext.pdf deleted file mode 100644 index 59f90369cd..0000000000 Binary files a/docs/content/books/es5-to-esnext.pdf and /dev/null differ diff --git a/docs/content/books/linuxcommandshandbook.pdf b/docs/content/books/linuxcommandshandbook.pdf deleted file mode 100644 index 20a18dc6c8..0000000000 Binary files a/docs/content/books/linuxcommandshandbook.pdf and /dev/null differ diff --git a/docs/content/cheat-sheets/7z.md b/docs/content/cheat-sheets/7z.md deleted file mode 100644 index d1ffbb002d..0000000000 --- a/docs/content/cheat-sheets/7z.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: title -subtitle: subtitle -date: '2022-01-03' -thumb_img_alt: lorem-ipsum -content_img_alt: lorem-ipsum -excerpt: lorem-ipsum -seo: - title: '' - description: '' - robots: [] - extra: [] -template: post -thumb_img_path: images/css-72a655a7.jpg ---- - ---- - -## tags: [compression] - -7z [Args] [archive.7z] [files / folders to archive] -A file archiver with highest compression ratio - -Args: -a add -d delete -e extract -l list -t test -u update -x extract with full paths - - DO NOT USE the 7-zip format for backup purpose on Linux/Unix. - 7-zip does not store the owner/group of the file. - - On Linux/Unix, in order to backup directories you must use tar : - - to backup a directory : tar cf - directory | 7z a -si directory.tar.7z - - to restore your backup : 7z x -so directory.tar.7z | tar xf - - - If you want to send files and directories (not the owner of file) to others - Unix/MacOS/Windows users, you can use the 7-zip format. - -Example 1: Quick and Easy - Add all files in dir1 to archive.7z with Default Settings. -7z a archive.7z dir1 - -Example 2: Add all files in dir1 to archive.7z with Max Compression -7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on archive.7z dir1 - - -t7z 7z archive - -m0=lzma lzma method - -mx=9 level of compression = 9 (ultra) - -mfb=64 number of fast bytes for lzma = 64 - -md=32m dictionary size = 32 Mb - -ms=on solid archive = on - -Example 3: Add (store) all files in dir1 to archive.7z with No Compression -7z a -m0=copy archive.7z dir1 - -7z exit codes: - - 0 normal (no errors or warnings) - 1 warning (non-fatal errors) - 2 fatal error - 7 bad cli arguments - 8 not enough memory for operation - 255 process was interrupted diff --git a/docs/content/cheat-sheets/CHEATSHEET.md b/docs/content/cheat-sheets/CHEATSHEET.md deleted file mode 100644 index 13dfcffc45..0000000000 --- a/docs/content/cheat-sheets/CHEATSHEET.md +++ /dev/null @@ -1,3067 +0,0 @@ -# Vanilla JS - -> Global object: properties - -```js -Object.length(obj); -``` - -> length is a property of a function object, and indicates how many arguments the function expects, i.e. the number of formal parameters. This number does not include the rest parameter. Has a value of 1. - -```js -Object.prototype; -``` - -> Represents the Object prototype object and allows to add new properties and methods to all objects of type Object. -> Methods of the Object constructor - -```js -Object.assign(target, ...sources); -``` - -> Copies the values of all enumerable own properties from one or more source objects to a target object. method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object - -```js -Object.create(MyObject); -``` - -> Creates a new object with the specified prototype object and properties. The object which should be the prototype of the newly-created object. - -```js -Object.defineProperty(obj, prop, descriptor); -``` - -> Adds the named property described by a given descriptor to an object. - -```js -Object.defineProperties(obj, props); -``` - -> Adds the named properties described by the given descriptors to an object. - -```js -Object.entries(obj); -``` - -> Returns an array containing all of the [key, value] pairs of a given object's own enumerable string properties. - -```js -Object.freeze(obj); -``` - -> Freezes an object: other code can't delete or change any properties. - -```js -Object.getOwnPropertyDescriptor(obj, prop); -``` - -> Returns a property descriptor for a named property on an object. - -```js -Object.getOwnPropertyDescriptors(obj); -``` - -> Returns an object containing all own property descriptors for an object. - -```js -Object.getOwnPropertyNames(obj); -``` - -> Returns an array containing the names of all of the given object's own enumerable and non-enumerable properties. - -```js -Object.getOwnPropertySymbols(obj); -``` - -> Returns an array of all symbol properties found directly upon a given object. - -```js -Object.getPrototypeOf(obj); -``` - -> Returns the prototype of the specified object. - -```js -Object.is(value1, value2); -``` - -> Compares if two values are the same value. Equates all NaN values (which differs from both Abstract Equality Comparison and Strict Equality Comparison). - -```js -Object.isExtensible(obj); -``` - -> Determines if extending of an object is allowed. - -```js -Object.isFrozen(obj); -``` - -> Determines if an object was frozen. - -```js -Object.isSealed(obj); -``` - -> Determines if an object is sealed. - -```js -Object.keys(obj); -``` - -> Returns an array containing the names of all of the given object's own enumerable string properties. - -```js -Object.preventExtensions(obj); -``` - -> Prevents any extensions of an object. - -```js -Object.seal(obj); -``` - -> Prevents other code from deleting properties of an object. - -```js -Object.setPrototypeOf(obj, prototype); -``` - -> Sets the prototype (i.e., the internal [[Prototype]] property). - -```js -Object.values(obj); -``` - -> Returns an array containing the values that correspond to all of a given object's own enumerable string properties. -> Object instances and Object prototype object (Object.prototype.property or Object.prototype.method()) -> Properties - -```js -obj.constructor; -``` - -> Specifies the function that creates an object's prototype. - -```js -obj.__proto__; -``` - -> Points to the object which was used as prototype when the object was instantiated. -> Methods - -```js -obj.hasOwnProperty(prop); -``` - -> Returns a boolean indicating whether an object contains the specified property as a direct property of that object and not inherited through the prototype chain. - -```js -prototypeObj.isPrototypeOf(object); -``` - -> Returns a boolean indicating whether the object this method is called upon is in the prototype chain of the specified object. - -```js -obj.propertyIsEnumerable(prop); -``` - -> Returns a boolean indicating if the internal ECMAScript [[Enumerable]] attribute is set. - -```js -obj.toLocaleString(); -``` - -> Calls toString(). - -```js -obj.toString(); -``` - -> Returns a string representation of the object. - -```js -object.valueOf(); -``` - -> Returns the primitive value of the specified object. - -## Global object: properties - -```js -Array.length; -``` - -> Reflects the number of elements in an array. - -```js -Array.prototype; -``` - -> Represents the prototype for the Array constructor and allows to add new properties and methods to all Array objects. - -## Global object: methods - -```js -Array.from(arrayLike[, mapFn[, thisArg]]) - -``` - -> Creates a new Array instance from an array-like or iterable object. - -```js -Array.isArray(obj); -``` - -> Returns true if a variable is an array, if not false. - -```js - -Array.of(element0[, element1[, ...[, elementN]]]); - -``` - -> Creates a new Array instance with a variable number of arguments, regardless of number or type of the arguments. -> Instance: properties - -```js -arr.length; -``` - -> Reflects the number of elements in an array. -> Instance: mutator methods - -```js -arr.copyWithin(target, start, end); -``` - -> Copies a sequence of array elements within the array. - -```js -arr.fill(value, start, end); -``` - -> Fills all the elements of an array from a start index to an end index with a static value. - -```js -arr.pop(); -``` - -> Removes the last element from an array and returns that element. - -```js - -arr.push([element1[, ...[, elementN]]]) - -``` - -> Adds one or more elements to the end of an array and returns the new length of the array. - -```js -arr.reverse(); -``` - -> Reverses the order of the elements of an array in place — the first becomes the last, and the last becomes the first. - -```js -arr.shift(); -``` - -> Removes the first element from an array and returns that element. - -```js -arr.sort(); -``` - -> Sorts the elements of an array in place and returns the array. - -```js - -array.splice(start, deleteCount, item1, item2, ...) - -``` - -> Adds and/or removes elements from an array. - -```js - -arr.unshift([element1[, ...[, elementN]]]) - -``` - -> Adds one or more elements to the front of an array and returns the new length of the array. -> Instance: accessor methods - -```js - -arr.concat(value1[, value2[, ...[, valueN]]]) - -``` - -> Returns a new array comprised of this array joined with other array(s) and/or value(s). - -```js -arr.includes(searchElement, fromIndex); -``` - -> Determines whether an array contains a certain element, returning true or false as appropriate. - -```js - -arr.indexOf(searchElement[, fromIndex]) - -``` - -> Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. - -```js -arr.join(separator); -``` - -> Joins all elements of an array into a string. - -```js -arr.lastIndexOf(searchElement, fromIndex); -``` - -> Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. - -```js -arr.slice(begin, end); -``` - -> Extracts a section of an array and returns a new array. - -```js -arr.toString(); -``` - -> Returns a string representing the array and its elements. Overrides the Object.prototype.toString() method. - -```js -arr.toLocaleString(locales, options); -``` - -> Returns a localized string representing the array and its elements. Overrides the Object.prototype.toLocaleString() method. -> Instance: iteration methods - -```js -arr.entries(); -``` - -> Returns a new Array Iterator object that contains the key/value pairs for each index in the array. - -```js - -arr.every(callback[, thisArg]) - -``` - -> Returns true if every element in this array satisfies the provided testing function. - -```js - -arr.filter(callback[, thisArg]) - -``` - -> Creates a new array with all of the elements of this array for which the provided filtering function returns true. - -```js - -arr.find(callback[, thisArg]) - -``` - -> Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. - -```js - -arr.findIndex(callback[, thisArg]) - -``` - -> Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. - -```js - -arr.forEach(callback[, thisArg]) - -``` - -> Calls a function for each element in the array. - -```js -arr.keys(); -``` - -> Returns a new Array Iterator that contains the keys for each index in the array. - -```js - -arr.map(callback[, initialValue]) - -``` - -> Creates a new array with the results of calling a provided function on every element in this array. - -```js - -arr.reduce(callback[, initialValue]) - -``` - -> Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. - -```js - -arr.reduceRight(callback[, initialValue]) - -``` - -> Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. - -```js - -arr.some(callback[, initialValue]) - -``` - -> Returns true if at least one element in this array satisfies the provided testing function. - -```js -arr.values(); -``` - -> Returns a new Array Iterator object that contains the values for each index in the array. - ---- - -# NodeJS - ---- - -```js -let http = require('http'); -``` - -> An example of a web server written with Node which responds with 'Hello World'. -> To run the server, put the code into a file called example.js and execute it with the node program. - -```js -http.createServer(function (request, response) { - response.writeHead(200, { 'Content-Type': 'text/plain' }); - response.end('Hello World\n'); -}).listen(8124); -console.log('Server running at http://127.0.0.1:8124/'); -``` - -## GLOBAL OBJECTS - -### In browsers, the top-level scope is the global scope. - -> That means that in browsers if you're in the global scope let something will define a global variable. -> In Node this is different. The top-level scope is not the global scope; let something inside a Node module will be local to that module. - -```js -__filename; -``` - ---- - -> The filename of the code being executed. (absolute path) -> \_\_dirname; - -``` - -> The name of the directory that the currently executing script resides in. (absolute path) -module; -``` - ---- - -> A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require(). - -```js -exports; -``` - ---- - -> A reference to the module.exports that is shorter to type. - -```js -process; -``` - ---- - -> The process object is a global object and can be accessed from anywhere. It is an instance of EventEmitter. - -```js -Buffer; -``` - ---- - -> The Buffer class is a global type for dealing with binary data directly. - -```js - -console.log([data], [...]); - -``` - ---- - -> Prints to stdout with newline. - -```js - -console.info([data], [...]); - -``` - -> Same as console.log. - -```js - -console.error([data], [...]); -``` - ---- - -> Same as console.log but prints to stderr. - -```js - -console.warn([data], [...]); - -``` - ---- - -> Same as console.error. - -```js -console.dir(obj); -``` - -> Uses util.inspect on obj and prints resulting string to stdout. - -```js -console.time(label); -``` - ---- - -> Mark a time. - -```js -console.timeEnd(label); -``` - -> Finish timer, record output. - -```js -console.trace(label); -``` - ---- - -> Print a stack trace to stderr of the current position. - -```js -console.assert(expression, [message]); -``` - ---- - -> Same as assert.ok() where if the expression evaluates as false throw an AssertionError with message. - -```js - -setTimeout(callback, delay, [arg], [...]); - -``` - -> To schedule execution of a one-time callback after delay milliseconds. Optionally you can also pass arguments to the callback. - -```js -clearTimeout(t); -``` - -> Stop a timer that was previously created with setTimeout(). - -```js - -setInterval(callback, delay, [arg], [...]); -``` - ---- - -> To schedule the repeated execution of callback every delay milliseconds. Optionally you can also pass arguments to the callback. - -```js -clearInterval(t); -``` - -> Stop a timer that was previously created with setInterval(). - -```js - -setImmediate(callback, [arg], [...]); - -``` - -> To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout and setInterval. - -```js -clearImmediate(immediateObject); -``` - -> Stop a timer that was previously created with setImmediate(). - -```js -unref(); -``` - -> Allow you to create a timer that is active but if it is the only item left in the event loop, node won't keep the program running. - -```js -ref(); -``` - -``` - -> If you had previously unref()d a timer you can call ref() to explicitly request the timer hold the program open. -let module = require('./module.js'); - -``` - -> Loads the module module.js in the same directory. - -```js -module.require('./another_module.js'); -``` - ---- - -> load another_module as if require() was called from the module itself. - -```js -module.id; -``` - -> The identifier for the module. Typically this is the fully resolved filename. - -```js -module.filename; -``` - ---- - -> The fully resolved filename to the module. - -```js -module.loaded; -``` - -```` - -> Whether or not the module is done loading, or is in the process of loading. - -```js - -module.parent; - -```` - -```` - -> The module that required this one. - -```js - -module.children; -```` - ---- - -> The module objects required by this one. - -```js -exports.area = function (r) { - return Math.PI * r * r; -}; -``` - -> If you want the root of your module's export to be a function (such as a constructor) -> or if you want to export a complete object in one assignment instead of building it one property at a time, -> assign it to module.exports instead of exports. - -```js - -module.exports = function(width) { -return { - area: function() { - return width * width; - } -}; -} -//************** - // * PROCESS - * http://nodejs.org/api/process.html -*/ -> ---------------------------------------------------------------------------\\ -process.on('exit', function(code) {}); - -``` - -> Emitted when the process is about to exit -> process.on('uncaughtException', function(err) {}); - -``` ---- -> Emitted when an exception bubbles all the way back to the event loop. (should not be used) -process.stdout; - -``` - -> A writable stream to stdout. - -```js -process.stderr; -``` - -> A writable stream to stderr. - -```js -process.stdin; -``` - ---- - -> A readable stream for stdin. - -````js - -process.argv; -> An array containing the command line arguments. - -```js - -process.env; - -```` - -> An object containing the user environment. - -```js -process.execPath; -``` - -> This is the absolute pathname of the executable that started the process. - -```js -process.execArgv; -``` - -> This is the set of node-specific command line options from the executable that started the process. - -````js - -process.arch; -> What processor architecture you're running on: 'arm', 'ia32', or 'x64'. - -```js - -process.config; - -```` - -> An Object containing the JavaScript representation of the configure options that were used to compile the current node executable. - -```js -process.pid; -``` - -> The PID of the process. - -```js -process.platform; -``` - -> What platform you're running on: 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'. - -```js -process.title; -``` - ---- - -> Getter/setter to set what is displayed in 'ps'. - -```js -process.version; -``` - -> A compiled-in property t -> hat exposes NODE_VERSION. - -```js -process.versions; -``` - -> A property exposing version strings of node and its dependencies. - -```js - -> process.abort(); - -``` - -> This causes node to emit an abort. This will cause node to exit and generate a core file. - -````js - -process.chdir(dir); -> Changes the current working directory of the process or throws an exception if that fails. - -```js - -process.cwd(); -```` - ---- - -> Returns the current working directory of the process. -> ?process.exit([code]); -> Ends the process with the specified code. If omitted, exit uses the 'success' code 0. - -```js -process.getgid(); -``` - -> Gets the group identity of the process. - -````js - -process.setgid(id); -> Sets the group identity of the process. - -```js - -process.getuid(); - -```` - -> Gets the user identity of the process. - -````js - -process.setuid(id); -> Sets the user identity of the process. - -```js - -process.getgroups(); -```` - ---- - -> Returns an array with the supplementary group IDs. - -```js -process.setgroups(grps); -``` - ---- - -> Sets the supplementary group IDs. - -```js -process.initgroups(user, extra_grp); -``` - ---- - -> Reads /etc/group and initializes the group access list, using all groups of which the user is a member. - -```js -process.kill(pid, [signal]); -``` - -> Send a signal to a process. pid is the process id and signal is the string describing the signal to send. - -```js -process.memoryUsage(); -``` - -> Returns an object describing the memory usage of the Node process measured in bytes. - -```js -process.nextTick(callback); -``` - -> On the next loop around the event loop call this callback. - -````js - -process.maxTickDepth; -> Callbacks passed to process.nextTick will usually be called at the end of the current flow of execution, and are thus approximately as fast as calling a function synchronously. - -```js - -process.umask([mask]); - -```` - -> Sets or reads the process's file mode creation mask. - -```js -process.uptime(); -``` - -> Number of seconds Node has been running. - -```js -process.hrtime(); -``` - -> Returns the current high-resolution real time in a [seconds, nanoseconds] tuple Array. - -````js - -//************** - // * CHILD PROCESS - * http://nodejs.org/api/child_process.html -*/ -> ---------------------------------------------------------------------------\\ -> Node provides a tri-directional popen facility through the child_process module. - > It is possible to stream data through a child's stdin, stdout, and stderr in a fully non-blocking way. - -```js - -ChildProcess; -> Class. ChildProcess is an EventEmitter. - -```js - -child.stdin; -> A Writable Stream that represents the child process's stdin -child.stdout; -> A Readable Stream that represents the child process's stdout -child.stderr; -> A Readable Stream that represents the child process's stderr. - -```js - -child.pid; -> The PID of the child process -child.connected; -> If .connected is false, it is no longer possible to send messages -child.kill([signal]); - -```` - -> Send a signal to the child process -> child.send(message, [sendHandle]); - -```` - -> When using child_process.fork() you can write to the child using child.send(message, [sendHandle]) and messages are received by a 'message' event on the child. - -```js - -child.disconnect(); - -```` - -> Close the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. - -```js -child_process.spawn(command, [args], [options]); -``` - -> Launches a new process with the given command, with command line arguments in args. If omitted, args defaults to an empty Array. - -````js - -child_process.exec(command, [options], callback); -> Runs a command in a shell and buffers the output. - -```js - -child_process.execFile(file, [args], [options], [callback]); -```` - ---- - -> Runs a command in a shell and buffers the output. - -```js -child_process.fork(modulePath, [args], [options]); -``` - ---- - -> This is a special case of the spawn() functionality for spawning Node processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. - -````js - -//************** - // * UTIL - * http://nodejs.org/api/util.html -*/ -> ---------------------------------------------------------------------------\\ -> These functions are in the module 'util'. Use require('util') to access them. - -```js - -util.format(format, [...]); - -```` - -> Returns a formatted string using the first argument as a printf-like format. (%s, %d, %j) -> util.debug(string); - -```` ---- -> A synchronous output function. Will block the process and output string immediately to stderr. - -```js - -util.error([...]); - -```` - -> Same as util.debug() except this will output all arguments immediately to stderr. - -```js - -util.puts([...]); - -``` - -> A synchronous output function. Will block the process and output all arguments to stdout with newlines after each argument. - -```js - -util.print([...]); - -``` - -> A synchronous output function. Will block the process, cast each argument to a string then output to stdout. (no newlines) -> util.log(string); - -```` - -> Output with timestamp on stdout. - -```js - -util.inspect(object, [opts]); -```` - ---- - -> Return a string representation of object, which is useful for debugging. (options: showHidden, depth, colors, customInspect) -> util.isArray(object); - -```` - -> Returns true if the given "object" is an Array. false otherwise. - -```js - -util.isRegExp(object); - -```` - -> Returns true if the given "object" is a RegExp. false otherwise. - -```js -util.isDate(object); -``` - -> Returns true if the given "object" is a Date. false otherwise. - -```js -util.isError(object); -``` - -> Returns true if the given "object" is an Error. false otherwise. - -````js - -util.promisify(fn) -> Takes a function whose last argument is a callback and returns a version that returns promises. - -```js - -util.inherits(constructor, superConstructor); -```` - ---- - -> Inherit the prototype methods from one constructor into another. - -```js - -//************** - // * EVENTS - * http://nodejs.org/api/events.html -*/ -> ---------------------------------------------------------------------------\\ -> All objects which emit events are instances of events.EventEmitter. You can access this module by doing: require("events"); - -``` - -> To access the EventEmitter class, require('events').EventEmitter. -> All EventEmitters emit the event 'newListener' when new listeners are added and 'removeListener' when a listener is removed. - -```js -emitter.addListener(event, listener); -``` - -> Adds a listener to the end of the listeners array for the specified event. - -````js - -emitter.on(event, listener); -> Same as emitter.addListener(). - -```js - -emitter.once(event, listener); - -```` - -> Adds a one time listener for the event. This listener is invoked only the next time the event is fired, after which it is removed. - -````js - -emitter.removeListener(event, listener); -> Remove a listener from the listener array for the specified event. - -```js - -emitter.removeAllListeners([event]); - -```` - -> Removes all listeners, or those of the specified event. - -````js - -emitter.setMaxListeners(n); -> By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. - -```js - -emitter.listeners(event); -> Returns an array of listeners for the specified event. - -```js - -emitter.emit(event, [arg1], [arg2], [...]); -```` - ---- - -> Execute each of the listeners in order with the supplied arguments. Returns true if event had listeners, false otherwise. - -```js -EventEmitter.listenerCount(emitter, event); -``` - ---- - -> Return the number of listeners for a given event. -> A stream is an abstract interface implemented by various objects in Node. For example a request to an HTTP server is a stream, as is stdout. -> Streams are readable, writable, or both. All streams are instances of EventEmitter. -> The Readable stream interface is the abstraction for a source of data that you are reading from. -> In other words, data comes out of a Readable stream. -> A Readable stream will not start emitting data until you indicate that you are ready to receive it. -> Examples of readable streams include: http responses on the client, http requests on the server, fs read streams -> zlib streams, crypto streams, tcp sockets, child process stdout and stderr, process.stdin. - -```js -let readable = getReadableStreamSomehow(); -readable.on('readable', function () {}); -``` - -> When a chunk of data can be read from the stream, it will emit a 'readable' event. - -```js -readable.on('data', function (chunk) {}); -``` - ---- - -> If you attach a data event listener, then it will switch the stream into flowing mode, and data will be passed to your handler as soon as it is available. - -```js -readable.on('end', function () {}); -``` - -> This event fires when there will be no more data to read. - -```js -readable.on('close', function () {}); -``` - ---- - -> Emitted when the underlying resource (for example, the backing file descriptor) has been closed. Not all streams will emit this. - -```js -readable.on('error', function () {}); -``` - ---- - -> Emitted if there was an error receiving data. -> The read() method pulls some data out of the internal buffer and returns it. If there is no data available, then it will return null. -> This method should only be called in non-flowing mode. In flowing-mode, this method is called automatically until the internal buffer is drained. - -```js -readable.read([size]); -readable.setEncoding(encoding); -``` - -> Call this function to cause the stream to return strings of the specified encoding instead of Buffer objects. - -```js -readable.resume(); -``` - -> This method will cause the readable stream to resume emitting data events. - -```js -readable.pause(); -``` - -> This method will cause a stream in flowing-mode to stop emitting data events. - -```js -readable.pipe(destination, [options]); -``` - -> This method pulls all the data out of a readable stream, and writes it to the supplied destination, automatically managing the flow so that the destination is not overwhelmed by a fast readable stream. - -```js -readable.unpipe([destination]); -``` - -> This method will remove the hooks set up for a previous pipe() call. If the destination is not specified, then all pipes are removed. - -````js - -readable.unshift(chunk); -> This is useful in certain cases where a stream is being consumed by a parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party. -> The Writable stream interface is an abstraction for a destination that you are writing data to. - > Examples of writable streams include: http requests on the client, http responses on the server, fs write streams, -> zlib streams, crypto streams, tcp sockets, child process stdin, process.stdout, process.stderr. - -```js - -let writer = getWritableStreamSomehow(); -writable.write(chunk, [encoding], [callback]); -```` - ---- - -> This method writes some data to the underlying system, and calls the supplied callback once the data has been fully handled. - -````js - -writer.once('drain', write); -> If a writable.write(chunk) call returns false, then the drain event will indicate when it is appropriate to begin writing more data to the stream. - -```js - -writable.end([chunk], [encoding], [callback]); -```` - ---- - -> Call this method when no more data will be written to the stream. - -````js - -writer.on('finish', function() {}); -> When the end() method has been called, and all data has been flushed to the underlying system, this event is emitted. - -```js - -writer.on('pipe', function(src) {}); -```` - ---- - -> This is emitted whenever the pipe() method is called on a readable stream, adding this writable to its set of destinations. - -```js -writer.on('unpipe', function (src) {}); -``` - -> This is emitted whenever the unpipe() method is called on a readable stream, removing this writable from its set of destinations. - -```js -writer.on('error', function (src) {}); -``` - -> Emitted if there was an error when writing or piping data. -> Duplex streams are streams that implement both the Readable and Writable interfaces. See above for usage. -> Examples of Duplex streams include: tcp sockets, zlib streams, crypto streams. -> Transform streams are Duplex streams where the output is in some way computed from the input. They implement both the Readable and Writable interfaces. See above for usage. -> Examples of Transform streams include: zlib streams, crypto streams. - -````js - -//************** - // * FILE SYSTEM - * http://nodejs.org/api/fs.html -*/ -> ---------------------------------------------------------------------------\\ -> To use this module do require('fs'). - > All the methods have asynchronous and synchronous forms. - -```js - -fs.rename(oldPath, newPath, callback); -```` - ---- - -> Asynchronous rename. No arguments other than a possible exception are given to the completion callback.Asynchronous ftruncate. No arguments other than a possible exception are given to the completion callback. - -```js -fs.renameSync(oldPath, newPath); -``` - -> Synchronous rename. - -```js -fs.ftruncate(fd, len, callback); -``` - -> Asynchronous ftruncate. No arguments other than a possible exception are given to the completion callback. - -```js -fs.ftruncateSync(fd, len); -``` - -> Synchronous ftruncate. - -````js - -fs.truncate(path, len, callback); -> Asynchronous truncate. No arguments other than a possible exception are given to the completion callback. - -```js - -fs.truncateSync(path, len); -> Synchronous truncate. - -```js - -fs.chown(path, uid, gid, callback); -> Asynchronous chown. No arguments other than a possible exception are given to the completion callback. - -```js - -fs.chownSync(path, uid, gid); - -```` - -> Synchronous chown. - -```js -fs.fchown(fd, uid, gid, callback); -``` - ---- - -> Asynchronous fchown. No arguments other than a possible exception are given to the completion callback. - -```js -fs.fchownSync(fd, uid, gid); -``` - ---- - -> Synchronous fchown. - -```js -fs.lchown(path, uid, gid, callback); -``` - -> Asynchronous lchown. No arguments other than a possible exception are given to the completion callback. - -```js -fs.lchownSync(path, uid, gid); -``` - -> Synchronous lchown. - -```js -fs.chmod(path, mode, callback); -``` - -> Asynchronous chmod. No arguments other than a possible exception are given to the completion callback. - -```js -fs.chmodSync(path, mode); -``` - -> Synchronous chmod. - -```js -fs.fchmod(fd, mode, callback); -``` - -> Asynchronous fchmod. No arguments other than a possible exception are given to the completion callback. - -```js -fs.fchmodSync(fd, mode); -``` - -> Synchronous fchmod. - -```js -fs.lchmod(path, mode, callback); -``` - -> Asynchronous lchmod. No arguments other than a possible exception are given to the completion callback. - -```js -fs.lchmodSync(path, mode); -``` - -> Synchronous lchmod. - -```js -fs.stat(path, callback); -``` - -> Asynchronous stat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. - -```js -fs.statSync(path); -``` - -> Synchronous stat. Returns an instance of fs.Stats. - -```js -fs.lstat(path, callback); -``` - -> Asynchronous lstat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to. - -```js -fs.lstatSync(path); -``` - -> Synchronous lstat. Returns an instance of fs.Stats. - -````js - -fs.fstat(fd, callback); -> Asynchronous fstat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd. - -```js - -fs.fstatSync(fd); -```` - ---- - -> Synchronous fstat. Returns an instance of fs.Stats. - -````js - -fs.link(srcpath, dstpath, callback); -> Asynchronous link. No arguments other than a possible exception are given to the completion callback. - -```js - -fs.linkSync(srcpath, dstpath); - -```` - -> Synchronous link. - -```js -fs.symlink(srcpath, dstpath, [type], callback); -``` - ---- - -> Asynchronous symlink. No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms) - -```js -fs.symlinkSync(srcpath, dstpath, [type]); -``` - -> Synchronous symlink. - -```js -fs.readlink(path, callback); -``` - -> Asynchronous readlink. The callback gets two arguments (err, linkString). - -```js -fs.readlinkSync(path); -``` - ---- - -> Synchronous readlink. Returns the symbolic link's string value. - -```js -fs.unlink(path, callback); -``` - ---- - -> Asynchronous unlink. No arguments other than a possible exception are given to the completion callback. - -````js - -fs.unlinkSync(path); -> Synchronous unlink. - -```js - -fs.realpath(path, [cache], callback); -> Asynchronous realpath. The callback gets two arguments (err, resolvedPath). - -```js - -fs.realpathSync(path, [cache]); - -```` - -> Synchronous realpath. Returns the resolved path. - -````js - -fs.rmdir(path, callback); -> Asynchronous rmdir. No arguments other than a possible exception are given to the completion callback. - -```js - -fs.rmdirSync(path); -```` - ---- - -> Synchronous rmdir. - -```js -fs.mkdir(path, [mode], callback); -``` - -> Asynchronous mkdir. No arguments other than a possible exception are given to the completion callback. mode defaults to 0777. - -```js -fs.mkdirSync(path, [mode]); -``` - -> Synchronous mkdir. - -```js -fs.readdir(path, callback); -``` - -> Asynchronous readdir. Reads the contents of a directory. The callback gets two arguments (err, files) where files is an array of the names of the files in the directory excluding '.' and '..'. - -```js -fs.readdirSync(path); -``` - -> Synchronous readdir. Returns an array of filenames excluding '.' and '..'. - -```js -fs.close(fd, callback); -``` - -> Asynchronous close. No arguments other than a possible exception are given to the completion callback. - -```js -fs.closeSync(fd); -``` - -> Synchronous close. - -```js -fs.open(path, flags, [mode], callback); -``` - -> Asynchronous file open. - -```js -fs.openSync(path, flags, [mode]); -``` - -> Synchronous version of fs.open(). - -```js -fs.utimes(path, atime, mtime, callback); -``` - ---- - -> Change file timestamps of the file referenced by the supplied path. - -```js -fs.utimesSync(path, atime, mtime); -``` - -> Synchronous version of fs.utimes(). - -```js -fs.futimes(fd, atime, mtime, callback); -``` - -> Change the file timestamps of a file referenced by the supplied file descriptor. - -```js -fs.futimesSync(fd, atime, mtime); -``` - -> Synchronous version of fs.futimes(). - -```js -fs.fsync(fd, callback); -``` - -> Asynchronous fsync. No arguments other than a possible exception are given to the completion callback. - -```js -fs.fsyncSync(fd); -``` - -> Synchronous fsync. - -```js -fs.write(fd, buffer, offset, length, position, callback); -``` - ---- - -> Write buffer to the file specified by fd. - -```js -fs.writeSync(fd, buffer, offset, length, position); -``` - -> Synchronous version of fs.write(). Returns the number of bytes written. - -```js -fs.read(fd, buffer, offset, length, position, callback); -``` - -> Read data from the file specified by fd. - -```js -fs.readSync(fd, buffer, offset, length, position); -``` - -> Synchronous version of fs.read. Returns the number of bytesRead. - -```js -fs.readFile(filename, [options], callback); -``` - -> Asynchronously reads the entire contents of a file. - -```js -fs.readFileSync(filename, [options]); -``` - -> Synchronous version of fs.readFile. Returns the contents of the filename. If the encoding option is specified then this function returns a string. Otherwise it returns a buffer. - -```js -fs.writeFile(filename, data, [options], callback); -``` - -> Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer. - -```js -fs.writeFileSync(filename, data, [options]); -``` - -> The synchronous version of fs.writeFile. - -```js -fs.appendFile(filename, data, [options], callback); -``` - ---- - -> Asynchronously append data to a file, creating the file if it not yet exists. data can be a string or a buffer. - -```js -fs.appendFileSync(filename, data, [options]); -``` - -> The synchronous version of fs.appendFile. - -```js -fs.watch(filename, [options], [listener]); -``` - -> Watch for changes on filename, where filename is either a file or a directory. The returned object is a fs.FSWatcher. The listener callback gets two arguments (event, filename). event is either 'rename' or 'change', and filename is the name of the file which triggered the event. - -```js -fs.exists(path, callback); -``` - ---- - -> Test whether or not the given path exists by checking with the file system. Then call the callback argument with either true or false. (should not be used) -> fs.existsSync(path); - -```` -> Synchronous version of fs.exists. (should not be used) -> fs.Stats: objects returned from fs.stat(), fs.lstat() and fs.fstat() and their synchronous counterparts are of this type. - -```js - -stats.isFile(); -stats.isDirectory() -stats.isBlockDevice() -stats.isCharacterDevice() -stats.isSymbolicLink() -> (only valid with fs.lstat()) -stats.isFIFO() -stats.isSocket() -fs.createReadStream(path, [options]); - -```` - -> Returns a new ReadStream object. - -```js -fs.createWriteStream(path, [options]); -``` - ---- - -> Returns a new WriteStream object. -> Use require('path') to use this module. -> This module contains utilities for handling and transforming file paths. -> Almost all these methods perform only string transformations. -> The file system is not consulted to check whether paths are valid. - -````js - -path.normalize(p); -> Normalize a string path, taking care of '..' and '.' parts. - -```js - -path.join([path1], [path2], [...]); - -```` - -> Join all arguments together and normalize the resulting path. - -```js - -path.resolve([from ...], to); - -``` - -> Resolves 'to' to an absolute path. - -```js -path.relative(from, to); -``` - -> Solve the relative path from 'from' to 'to'. - -````js - -path.dirname(p); -> Return the directory name of a path. Similar to the Unix dirname command. - -```js - -path.basename(p, [ext]); - -```` - -> Return the last portion of a path. Similar to the Unix basename command. - -```js -path.extname(p); -``` - ---- - -> Return the extension of the path, from the last '.' to end of string in the last portion of the path. - -```js -path.sep; -``` - ---- - -> The platform-specific file separator. '\\' or '/'. - -```js -path.delimiter; -``` - ---- - -> The platform-specific path delimiter, ';' or ':'. -> To use the HTTP server and client one must require('http'). - -```js -http.STATUS_CODES; -``` - -> A collection of all the standard HTTP response status codes, and the short description of each. - -```js -http.request(options, [callback]); -``` - -```` ---- -> This function allows one to transparently issue requests. - -```js - -http.get(options, [callback]); - -```` - -> Set the method to GET and calls req.end() automatically. - -```js -server = http.createServer([requestListener]); -``` - ---- - -> Returns a new web server object. The requestListener is a function which is automatically added to the 'request' event. - -```js -server.listen(port, [hostname], [backlog], [callback]); -``` - -> Begin accepting connections on the specified port and hostname. - -```js -server.listen(path, [callback]); -``` - -> Start a UNIX socket server listening for connections on the given path. - -```js -server.listen(handle, [callback]); -``` - -> The handle object can be set to either a server or socket (anything with an underlying \_handle member), or a {fd: } object. - -```js -server.close([callback]); -``` - -> Stops the server from accepting new connections. - -````js - -server.setTimeout(msecs, callback); -> Sets the timeout value for sockets, and emits a 'timeout' event on the Server object, passing the socket as an argument, if a timeout occurs. - -```js - -server.maxHeadersCount; -```` - ---- - -> Limits maximum incoming headers count, equal to 1000 by default. If set to 0 - no limit will be applied. - -```js -server.timeout; -``` - -> The number of milliseconds of inactivity before a socket is presumed to have timed out. - -```js -server.on('request', function (request, response) {}); -``` - -> Emitted each time there is a request. - -```js -server.on('connection', function (socket) {}); -``` - -> When a new TCP stream is established. - -```js -server.on('close', function () {}); -``` - ---- - -> Emitted when the server closes. - -```js -server.on('checkContinue', function (request, response) {}); -``` - ---- - -> Emitted each time a request with an http Expect: 100-continue is received. - -```js -server.on('connect', function (request, socket, head) {}); -``` - -> Emitted each time a client requests a http CONNECT method. - -```js -server.on('upgrade', function (request, socket, head) {}); -``` - -> Emitted each time a client requests a http upgrade. - -```js -server.on('clientError', function (exception, socket) {}); -``` - -> If a client connection emits an 'error' event - it will forwarded here. - -```js -request.write(chunk, [encoding]); -``` - -> Sends a chunk of the body. - -```js -request.end([data], [encoding]); -``` - -> Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. - -```js -request.abort(); -``` - -> Aborts a request. - -```js -request.setTimeout(timeout, [callback]); -``` - ---- - -> Once a socket is assigned to this request and is connected socket.setTimeout() will be called. - -```js -request.setNoDelay([noDelay]); -``` - -> Once a socket is assigned to this request and is connected socket.setNoDelay() will be called. - -```js -request.setSocketKeepAlive([enable], [initialDelay]); -``` - -> Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called. - -```js -request.on('response', function (response) {}); -``` - -> Emitted when a response is received to this request. This event is emitted only once. - -````js - -request.on('socket', function(socket) { }); -> Emitted after a socket is assigned to this request. - -```js - -request.on('connect', function(response, socket, head) { }); - -```` - -> Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed. - -```js -request.on('upgrade', function (response, socket, head) {}); -``` - -> Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed. - -```js -request.on('continue', function () {}); -``` - -> Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body. - -```js -response.write(chunk, [encoding]); -``` - -> This sends a chunk of the response body. If this merthod is called and response.writeHead() has not been called, it will switch to implicit header mode and flush the implicit headers. - -```js -response.writeContinue(); -``` - -> Sends a HTTP/1.1 100 Continue message to the client, indicating that the request body should be sent. - -````js - -response.writeHead(statusCode, [reasonPhrase], [headers]); -> Sends a response header to the request. - -```js - -response.setTimeout(msecs, callback); -> Sets the Socket's timeout value to msecs. If a callback is provided, then it is added as a listener on the 'timeout' event on the response object. - -```js - -response.setHeader(name, value); -> Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here if you need to send multiple headers with the same name. - -```js - -response.getHeader(name); - -```` - -> Reads out a header that's already been queued but not sent to the client. Note that the name is case insensitive. - -```js -response.removeHeader(name); -``` - -> Removes a header that's queued for implicit sending. - -```js -response.addTrailers(headers); -``` - -> This method adds HTTP trailing headers (a header but at the end of the message) to the response. - -```js -response.end([data], [encoding]); -``` - -> This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, response.end(), MUST be called on each response. - -````js - -response.statusCode; -> When using implicit headers (not calling response.writeHead() explicitly), this property controls the status code that will be sent to the client when the headers get flushed. - -```js - -response.headersSent; -> Boolean (read-only). True if headers were sent, false otherwise. - -```js - -response.sendDate; -> When true, the Date header will be automatically generated and sent in the response if it is not already present in the headers. Defaults to true. - -```js - -response.on('close', function () { }); -```` - ---- - -> Indicates that the underlying connection was terminated before response.end() was called or able to flush. - -```js -response.on('finish', function () {}); -``` - ---- - -> Emitted when the response has been sent. - -````js - -message.httpVersion; -> In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. - -```js - -message.headers; - -```` - -> The request/response headers object. - -```js -message.trailers; -``` - ---- - -> The request/response trailers object. Only populated after the 'end' event. - -```js -message.method; -``` - -> The request method as a string. Read only. Example: 'GET', 'DELETE'. - -````js - -message.url; -> Request URL string. This contains only the URL that is present in the actual HTTP request. - -```js - -message.statusCode; - -```` - -> The 3-digit HTTP response status code. E.G. 404. - -```js -message.socket; -``` - -> The net.Socket object associated with the connection. - -```js -message.setTimeout(msecs, callback); -``` - -> Calls message.connection.setTimeout(msecs, callback). -> This module has utilities for URL resolution and parsing. Call require('url') to use it. - -```js -url.parse(urlStr, [parseQueryString], [slashesDenoteHost]); -``` - ---- - -> Take a URL string, and return an object. - -```js -url.format(urlObj); -``` - -> Take a parsed URL object, and return a formatted URL string. - -```js -url.resolve(from, to); -``` - -> Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. - -````js - -//************** - // * QUERY STRING - * http://nodejs.org/api/querystring.html -*/ -> ---------------------------------------------------------------------------\\ -> This module provides utilities for dealing with query strings. Call require('querystring') to use it. - -```js - -querystring.stringify(obj, [sep], [eq]); - -```` - -> Serialize an object to a query string. Optionally override the default separator ('&') and assignment ('=') characters. - -```js -querystring.parse(str, [sep], [eq], [options]); -``` - ---- - -> Deserialize a query string to an object. Optionally override the default separator ('&') and assignment ('=') characters. -> This module is used for writing unit tests for your applications, you can access it with require('assert'). - -```js -assert.fail(actual, expected, message, operator); -``` - -> Throws an exception that displays the values for actual and expected separated by the provided operator. - -```js -assert(value, message); -assert.ok(value, [message]); -``` - ---- - -> Tests if value is truthy, it is equivalent to assert.equal(true, !!value, message); - -```js -assert.equal(actual, expected, [message]); -``` - ---- - -> Tests shallow, coercive equality with the equal comparison operator ( == ). - -```js -assert.notEqual(actual, expected, [message]); -``` - -> Tests shallow, coercive non-equality with the not equal comparison operator ( != ). - -```js -assert.deepEqual(actual, expected, [message]); -``` - -> Tests for deep equality. - -```js -assert.notDeepEqual(actual, expected, [message]); -``` - -> Tests for any deep inequality. - -```js -assert.strictEqual(actual, expected, [message]); -``` - ---- - -> Tests strict equality, as determined by the strict equality operator ( === ) - -```js -assert.notStrictEqual(actual, expected, [message]); -``` - -> Tests strict non-equality, as determined by the strict not equal operator ( !== ) - -```js -assert.throws(block, [error], [message]); -``` - -> Expects block to throw an error. error can be constructor, RegExp or validation function. - -```js -assert.doesNotThrow(block, [message]); -``` - -> Expects block not to throw an error, see assert.throws for details. - -```js -assert.ifError(value); -``` - -> Tests if value is not a false value, throws if it is a true value. Useful when testing the first argument, error in callbacks. -> Provides a few basic operating-system related utility functions. -> Use require('os') to access this module. - -```js -os.tmpdir(); -``` - -> Returns the operating system's default directory for temp files. - -```js -os.endianness(); -``` - -> Returns the endianness of the CPU. Possible values are "BE" or "LE". - -```js -os.hostname(); -``` - -> Returns the hostname of the operating system. - -```js -os.type(); -``` - -> Returns the operating system name. - -```js -os.platform(); -``` - -> Returns the operating system platform. - -```js -os.arch(); -``` - -> Returns the operating system CPU architecture. - -```js -os.release(); -``` - ---- - -> Returns the operating system release. - -````js - -os.uptime(); -> Returns the system uptime in seconds. - -```js - -os.loadavg(); -```` - ---- - -> Returns an array containing the 1, 5, and 15 minute load averages. - -```js -os.totalmem(); -``` - -> Returns the total amount of system memory in bytes. - -```js -os.freemem(); -``` - ---- - -> Returns the amount of free system memory in bytes. - -```js -os.cpus(); -``` - -> Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of milliseconds the CPU/core spent in: user, nice, sys, idle, and irq). - -```js -os.networkInterfaces(); -``` - ---- - -> Get a list of network interfaces. - -```js - -os.EOL; -> A constant defining the appropriate End-of-line marker for the operating system. - -``` - -> Buffer is used to dealing with binary data -> Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap - -```js -Buffer.from(size); -``` - -> Allocates a new buffer of size octets. - -```js -Buffer.from(array); -``` - -> Allocates a new buffer using an array of octets. - -```js -Buffer.from(str, [encoding]); -``` - -> Allocates a new buffer containing the given str. encoding defaults to 'utf8'. - -```js -Buffer.isEncoding(encoding); -``` - -> Returns true if the encoding is a valid encoding argument, or false otherwise. - -```js -Buffer.isBuffer(obj); -``` - -> Tests if obj is a Buffer - -```js -Buffer.concat(list, [totalLength]); -``` - -> Returns a buffer which is the result of concatenating all the buffers in the list together. - -```js -Buffer.byteLength(string, [encoding]); -``` - -> Gives the actual byte length of a string. - -```js -buf.write(string, [offset], [length], [encoding]); -``` - -> Writes string to the buffer at offset using the given encoding -> buf.toString([encoding], [start], [end]); - -```` - ---- -> Decodes and returns a string from buffer data encoded with encoding (defaults to 'utf8') beginning at start (defaults to 0) and ending at end (defaults to buffer.length). - -```js - -buf.toJSON(); - -```` - -> Returns a JSON-representation of the Buffer instance, which is identical to the output for JSON Arrays - -```js -buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd]); -``` - ---- - -> Does copy between buffers. The source and target regions can be overlapped - -```js -buf.slice([start], [end]); -``` - -> Returns a new buffer which references the same memory as the old, but offset and cropped by the start (defaults to 0) and end (defaults to buffer.length) indexes. Negative indexes start from the end of the buffer. - -```js -buf.fill(value, [offset], [end]); -``` - -> Fills the buffer with the specified value - -```js -buf[index]; -``` - -> Get and set the octet at index - -```js -buf.length; -``` - -> The size of the buffer in bytes, Note that this is not necessarily the size of the contents - -```js -buffer.INSPECT_MAX_BYTES; -``` - -> How many bytes will be returned when buffer.inspect() is called. This can be overridden by user modules. - -```js - -``` - -# ReactJS - ---- - -```bash - -npm install --save react -#// declarative and flexible JavaScript library for building UI -npm install --save react-dom -# > serves as the entry point of the DOM-related rendering paths -npm install --save prop-types -#// runtime type checking for React props and similar objects -``` - -## notes: don't forget the command lines - -> Create and return a new React element of the given type. - -> Code written with JSX will be converted to use React.createElement(). - -> You will not typically invoke React.createElement() directly if you are using JSX. - -```js -React.createElement(type, [props], [...children]); -``` - -> Clone and return a new React element using element as the starting point. - -> The resulting element will have the original element's props with the new props merged in shallowly. - -```js -React.cloneElement(element, [props], [...children]); -``` - -> Verifies the object is a React element. Returns true or false. - -```js -React.isValidElement(object); -``` - -> React.Children> provides utilities for dealing with the this.props.children opaque data structure. -> Invokes a function on every immediate child contained within children with this set to thisArg. - -```js - -React.Children.map(children, function[(thisArg)]) - -``` - -> Like React.Children.map() but does not return an array. - -```js - -React.Children.forEach(children, function[(thisArg)]) - -``` - -> Returns the total number of components in children, equal to the number of times that a callback passed to map or forEach would be invoked. - -```js -React.Children.count(children); -``` - -> Verifies that children has only one child (a React element) and returns it. - -> Otherwise this method throws an error. - -```js -React.Children.only(children); -``` - -> Returns the children opaque data structure as a flat array with keys assigned to each child. - -> Useful if you want to manipulate collections of children in your render methods, especially if you want to reorder or slice this.props.children before passing it down. - -```js -React.Children.toArray(children); -``` - -> The React.Fragment component lets you return multiple elements in a render() method without creating an additional DOM element - -> You can also use it with the shorthand <> syntax. - -```js - -class Component extends React.Component { - -``` - -> Will be called before it is mounted -> constructor(props) { -> Call this method before any other statement -> or this.props will be undefined in the constructor -> super(props); - -> The constructor is also often used to bind event handlers to the class instance. - -> Binding makes sure the method has access to component attributes like this.props and this.state - -```js -this.method = this.method.bind(this); -``` - -> The constructor is the right place to initialize state. - -```js - - this.state = { - active: true, -``` - -> In rare cases, it's okay to initialize state based on props. - -> This effectively "forks" the props and sets the state with the initial props. - -> If you "fork" props by using them for state, you might also want to implement componentWillReceiveProps(nextProps) -> to keep the state up-to-date with them. But lifting state up is often easier and less bug-prone. - -```js - - color: props.initialColor - }; -} - -``` - -> Enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. - -> setState() does not always immediately update the component. It may batch or defer the update until later. - -> This makes reading this.state right after calling setState() a potential pitfall. - -> Instead, use componentDidUpdate or a setState callback. - -> You may optionally pass an object as the first argument to setState() instead of a function. - -```jsx - - - -setState(updater[, callback]) { } - -``` - -> Invoked just before mounting occurs (before render()) - -> This is the only lifecycle hook called on server rendering. - -```js - -componentWillMount() { } - -``` - -> Invoked immediately after a component is mounted. - -> Initialization that requires DOM nodes should go here. - -> If you need to load data from a remote endpoint, this is a good place to instantiate the network request. - -> This method is a good place to set up any subscriptions. If you do that, don't forget to unsubscribe in componentWillUnmount(). - -```js - -componentDidMount() { } - -``` - -> Invoked before a mounted component receives new props. - -> If you need to update the state in response to prop changes (for example, to reset it), you may compare this.props and nextProps and perform state transitions using this.setState() in this method. - -```js - -componentWillReceiveProps(nextProps) { } - -``` - -> Let React know if a component's output is not affected by the current change in state or props. - -> The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior. - -> shouldComponentUpdate() is invoked before rendering when new props or state are being received. Defaults to true. - -> This method is not called for the initial render or when forceUpdate() is used. - -> Returning false does not prevent child components from re-rendering when their state changes. - -```js - -shouldComponentUpdate(nextProps, nextState) { } - -``` - -> Invoked just before rendering when new props or state are being received. - -> Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render. - -> Note that you cannot call this.setState() here; nor should you do anything else - -```` - -> (e.g. dispatch a Redux action) that would trigger an update to a React component before componentWillUpdate() returns. - - > If you need to update state in response to props changes, use componentWillReceiveProps() instead. - -```js - -componentWillUpdate(nextProps, nextState) { } - -```` - -> Invoked immediately after updating occurs. This method is not called for the initial render. - -> Use this as an opportunity to operate on the DOM when the component has been updated. - -> This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). - -```js - -componentDidUpdate(prevProps, prevState) { } - -``` - -> Invoked immediately before a component is unmounted and destroyed. - -> Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount(). - -```js - -componentWillUnmount() { } - -``` - -> Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. - -> Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them. - -```js - -componentDidCatch() { } - -``` - -> This method is required. - -> It should be pure, meaning that it does not modify component state, it returns the same result each time it's invoked, and - -``` - -> it does not directly interact with the browser (use lifecycle methods for this) - -``` - -> It must return one of the following types: react elements, string and numbers, portals, null or booleans. - -```js - -render() { - -``` - -> Contains the props that were defined by the caller of this component. - -```js -console.log(this.props); -``` - -> Contains data specific to this component that may change over time. - -````js - -> The state is user-defined, and it should be a plain JavaScript object. - -```js - -> If you don't use it in render(), it shouldn't be in the state. - -```js - -> For example, you can put timer IDs directly on the instance. - -```js - -> Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. - -```js - -> Treat this.state as if it were immutable. - -```js - - console.log(this.state); - return ( -
    - {/* Comment goes here */} - Hello, {this.props.name}! -
    - ); -} -} - -```` - -> Can be defined as a property on the component class itself, to set the default props for the class. - -> This is used for undefined props, but not for null props. - -```js -Component.defaultProps = { - color: 'blue' -}; -component = new Component(); -``` - -> By default, when your component's state or props change, your component will re-render. - -> If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate(). - -> Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). - -````js - -component.forceUpdate(callback) -//************** - // * REACT.DOM - * The react-dom package provides DOM-specific methods that can be used at the top level of - * your app and as an escape hatch to get outside of the React model if you need to. - -```js - - * Most of your components should not need to use this module. - -```js - - * https://reactjs.org/docs/react-dom.html -*/ -//------------------------------------------------------------------------------\\ -//------------------------------------------------------------------------------\\ - -```` - -> Render a React element into the DOM in the supplied container and return a reference - -```` - -> to the component (or returns null for stateless components). - -```js - -ReactDOM.render(element, container[, callback]) - -```` - -> Same as render(), but is used to hydrate a container whose HTML contents were rendered - -```` - -> by ReactDOMServer. React will attempt to attach event listeners to the existing markup. - -```js - -ReactDOM.hydrate(element, container[, callback]) - -```` - -> Remove a mounted React component from the DOM and clean up its event handlers and state. - -> If no component was mounted in the container, calling this function does nothing. - -> Returns true if a component was unmounted and false if there was no component to unmount. - -```js -ReactDOM.unmountComponentAtNode(container); -``` - -> If this component has been mounted into the DOM, this returns the corresponding native browser - -``` - -> DOM element. This method is useful for reading values out of the DOM, such as form field values - -``` - -> and performing DOM measurements. In most cases, you can attach a ref to the DOM node and avoid - -```` - -> using findDOMNode at all. - -```js - -ReactDOM.findDOMNode(component) - -```` - -> Creates a portal. Portals provide a way to render children into a DOM node that exists outside - -```` - -> the hierarchy of the DOM component. - -```js - -ReactDOM.createPortal(child, container) -//****************************************************************************** - // * REACTDOMSERVER - * The ReactDOMServer object enables you to render components to static markup. - -```js - - * https://reactjs.org/docs/react-dom.html -*/ -//------------------------------------------------------------------------------\\ -//------------------------------------------------------------------------------\\ - -```` - -> Render a React element to its initial HTML. React will return an HTML string. - -> You can use this method to generate HTML on the server and send the markup down on the initial - -```` - -> request for faster page loads and to allow search engines to crawl your pages for SEO purposes. - -```js - -ReactDOMServer.renderToString(element) - -```` - -> Similar to renderToString, except this doesn't create extra DOM attributes that React uses - -``` - -> internally, such as data-reactroot. This is useful if you want to use React as a simple static - -``` - -> page generator, as stripping away the extra attributes can save some bytes. - -```js -ReactDOMServer.renderToStaticMarkup(element); -``` - -> Render a React element to its initial HTML. Returns a Readable stream that outputs an HTML string. - -> The HTML output by this stream is exactly equal to what ReactDOMServer.renderToString would return. - -> You can use this method to generate HTML on the server and send the markup down on the initial - -```` - -> request for faster page loads and to allow search engines to crawl your pages for SEO purposes. - -```js - -ReactDOMServer.renderToNodeStream(element) - -```` - -> Similar to renderToNodeStream, except this doesn't create extra DOM attributes that React uses - -``` - -> internally, such as data-reactroot. This is useful if you want to use React as a simple static - -``` - -> page generator, as stripping away the extra attributes can save some bytes. - -```js - -ReactDOMServer.renderToStaticNodeStream(element) -//*********** - // * TYPECHECKING WITH PROPTYPES - * https://reactjs.org/docs/typechecking-with-proptypes.html -*/ -//------------------------------------------------------------------------------\\ -//------------------------------------------------------------------------------\\ -import PropTypes from 'prop-types'; -MyComponent.propTypes = { - -``` - -> You can declare that a prop is a specific JS type. By default, these - -```` - -> are all optional. - -```js - -optionalArray: PropTypes.array, -optionalBool: PropTypes.bool, -optionalFunc: PropTypes.func, -optionalNumber: PropTypes.number, -optionalObject: PropTypes.object, -optionalString: PropTypes.string, -optionalSymbol: PropTypes.symbol, Anything that can be rendered: numbers, strings, elements or an array - -```` - -> (or fragment) containing these types. - -````js - -optionalNode: PropTypes.node, A React element. - -```js - -optionalElement: PropTypes.element, You can also declare that a prop is an instance of a class. This uses - -```` - -> JS's instanceof operator. - -```js - -optionalMessage: PropTypes.instanceOf(Message), You can ensure that your prop is limited to specific values by treating - -``` - -> it as an enum. - -```js - -optionalEnum: PropTypes.oneOf(['News', 'Photos']), An object that could be one of many types -optionalUnion: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number, - PropTypes.instanceOf(Message) -]), An array of a certain type -optionalArrayOf: PropTypes.arrayOf(PropTypes.number), An object with property values of a certain type -optionalObjectOf: PropTypes.objectOf(PropTypes.number), An object taking on a particular shape -optionalObjectWithShape: PropTypes.shape({ - color: PropTypes.string, - fontSize: PropTypes.number -}), You can chain any of the above with `isRequired` to make sure a warning - -``` - -> is shown if the prop isn't provided. - -```js - -requiredFunc: PropTypes.func.isRequired, A value of any data type -requiredAny: PropTypes.any.isRequired, You can also specify a custom validator. It should return an Error - -``` - -> object if the validation fails. Don't `console.warn` or throw, as this - -```` - -> won't work inside `oneOfType`. - -```js - -customProp: function(props, propName, componentName) { - if (!/matchme/.test(props[propName])) { - return new Error( - 'Invalid prop `' + propName + '` supplied to' + - ' `' + componentName + '`. Validation failed.' - ); - } -}, You can also supply a custom validator to `arrayOf` and `objectOf`. - - > It should return an Error object if the validation fails. The validator - -> will be called for each key in the array or object. The first two - -```` - -> arguments of the validator are the array or object itself, and the - -```` - -> current item's key. - -```js - -customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) { - if (!/matchme/.test(propValue[key])) { - return new Error( - 'Invalid prop `' + propFullName + '` supplied to' + - ' `' + componentName + '`. Validation failed.' - ); - } -}) -}; -```` diff --git a/docs/content/cheat-sheets/Gemfile.lock.md b/docs/content/cheat-sheets/Gemfile.lock.md deleted file mode 100644 index 99b9efbc43..0000000000 --- a/docs/content/cheat-sheets/Gemfile.lock.md +++ /dev/null @@ -1,264 +0,0 @@ ---- -title: title -subtitle: subtitle -date: '2022-01-03' -thumb_img_alt: lorem-ipsum -content_img_alt: lorem-ipsum -excerpt: lorem-ipsum -seo: - title: '' - description: '' - robots: [] - extra: [] -template: post -thumb_img_path: images/css-72a655a7.jpg ---- - -GEM -remote: https://rubygems.org/ -specs: -activesupport (6.0.3.1) -concurrent-ruby (~> 1.0, >= 1.0.2) -i18n (>= 0.7, < 2) -minitest (~> 5.1) -tzinfo (~> 1.1) -zeitwerk (~> 2.2, >= 2.2.2) -addressable (2.7.0) -public_suffix (>= 2.0.2, < 5.0) -coffee-script (2.4.1) -coffee-script-source -execjs -coffee-script-source (1.11.1) -colorator (1.1.0) -commonmarker (0.17.13) -ruby-enum (~> 0.5) -concurrent-ruby (1.1.6) -dnsruby (1.61.3) -addressable (~> 2.5) -em-websocket (0.5.1) -eventmachine (>= 0.12.9) -http_parser.rb (~> 0.6.0) -ethon (0.12.0) -ffi (>= 1.3.0) -eventmachine (1.2.7) -execjs (2.7.0) -faraday (1.0.1) -multipart-post (>= 1.2, < 3) -ffi (1.13.1) -forwardable-extended (2.6.0) -gemoji (3.0.1) -github-pages (206) -github-pages-health-check (= 1.16.1) -jekyll (= 3.8.7) -jekyll-avatar (= 0.7.0) -jekyll-coffeescript (= 1.1.1) -jekyll-commonmark-ghpages (= 0.1.6) -jekyll-default-layout (= 0.1.4) -jekyll-feed (= 0.13.0) -jekyll-gist (= 1.5.0) -jekyll-github-metadata (= 2.13.0) -jekyll-mentions (= 1.5.1) -jekyll-optional-front-matter (= 0.3.2) -jekyll-paginate (= 1.1.0) -jekyll-readme-index (= 0.3.0) -jekyll-redirect-from (= 0.15.0) -jekyll-relative-links (= 0.6.1) -jekyll-remote-theme (= 0.4.1) -jekyll-sass-converter (= 1.5.2) -jekyll-seo-tag (= 2.6.1) -jekyll-sitemap (= 1.4.0) -jekyll-swiss (= 1.0.0) -jekyll-theme-architect (= 0.1.1) -jekyll-theme-cayman (= 0.1.1) -jekyll-theme-dinky (= 0.1.1) -jekyll-theme-hacker (= 0.1.1) -jekyll-theme-leap-day (= 0.1.1) -jekyll-theme-merlot (= 0.1.1) -jekyll-theme-midnight (= 0.1.1) -jekyll-theme-minimal (= 0.1.1) -jekyll-theme-modernist (= 0.1.1) -jekyll-theme-primer (= 0.5.4) -jekyll-theme-slate (= 0.1.1) -jekyll-theme-tactile (= 0.1.1) -jekyll-theme-time-machine (= 0.1.1) -jekyll-titles-from-headings (= 0.5.3) -jemoji (= 0.11.1) -kramdown (= 1.17.0) -liquid (= 4.0.3) -mercenary (~> 0.3) -minima (= 2.5.1) -nokogiri (>= 1.10.4, < 2.0) -rouge (= 3.19.0) -terminal-table (~> 1.4) -github-pages-health-check (1.16.1) -addressable (~> 2.3) -dnsruby (~> 1.60) -octokit (~> 4.0) -public_suffix (~> 3.0) -typhoeus (~> 1.3) -html-pipeline (2.13.0) -activesupport (>= 2) -nokogiri (>= 1.4) -http_parser.rb (0.6.0) -i18n (0.9.5) -concurrent-ruby (~> 1.0) -jekyll (3.8.7) -addressable (~> 2.4) -colorator (~> 1.0) -em-websocket (~> 0.5) -i18n (~> 0.7) -jekyll-sass-converter (~> 1.0) -jekyll-watch (~> 2.0) -kramdown (~> 1.14) -liquid (~> 4.0) -mercenary (~> 0.3.3) -pathutil (~> 0.9) -rouge (>= 1.7, < 4) -safe_yaml (~> 1.0) -jekyll-avatar (0.7.0) -jekyll (>= 3.0, < 5.0) -jekyll-coffeescript (1.1.1) -coffee-script (~> 2.2) -coffee-script-source (~> 1.11.1) -jekyll-commonmark (1.3.1) -commonmarker (~> 0.14) -jekyll (>= 3.7, < 5.0) -jekyll-commonmark-ghpages (0.1.6) -commonmarker (~> 0.17.6) -jekyll-commonmark (~> 1.2) -rouge (>= 2.0, < 4.0) -jekyll-default-layout (0.1.4) -jekyll (~> 3.0) -jekyll-feed (0.13.0) -jekyll (>= 3.7, < 5.0) -jekyll-gist (1.5.0) -octokit (~> 4.2) -jekyll-github-metadata (2.13.0) -jekyll (>= 3.4, < 5.0) -octokit (~> 4.0, != 4.4.0) -jekyll-mentions (1.5.1) -html-pipeline (~> 2.3) -jekyll (>= 3.7, < 5.0) -jekyll-optional-front-matter (0.3.2) -jekyll (>= 3.0, < 5.0) -jekyll-paginate (1.1.0) -jekyll-readme-index (0.3.0) -jekyll (>= 3.0, < 5.0) -jekyll-redirect-from (0.15.0) -jekyll (>= 3.3, < 5.0) -jekyll-relative-links (0.6.1) -jekyll (>= 3.3, < 5.0) -jekyll-remote-theme (0.4.1) -addressable (~> 2.0) -jekyll (>= 3.5, < 5.0) -rubyzip (>= 1.3.0) -jekyll-sass-converter (1.5.2) -sass (~> 3.4) -jekyll-seo-tag (2.6.1) -jekyll (>= 3.3, < 5.0) -jekyll-sitemap (1.4.0) -jekyll (>= 3.7, < 5.0) -jekyll-swiss (1.0.0) -jekyll-theme-architect (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-cayman (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-dinky (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-hacker (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-leap-day (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-merlot (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-midnight (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-minimal (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-modernist (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-primer (0.5.4) -jekyll (> 3.5, < 5.0) -jekyll-github-metadata (~> 2.9) -jekyll-seo-tag (~> 2.0) -jekyll-theme-slate (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-tactile (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-theme-time-machine (0.1.1) -jekyll (~> 3.5) -jekyll-seo-tag (~> 2.0) -jekyll-titles-from-headings (0.5.3) -jekyll (>= 3.3, < 5.0) -jekyll-watch (2.2.1) -listen (~> 3.0) -jemoji (0.11.1) -gemoji (~> 3.0) -html-pipeline (~> 2.2) -jekyll (>= 3.0, < 5.0) -kramdown (1.17.0) -liquid (4.0.3) -listen (3.2.1) -rb-fsevent (~> 0.10, >= 0.10.3) -rb-inotify (~> 0.9, >= 0.9.10) -mercenary (0.3.6) -mini_portile2 (2.4.0) -minima (2.5.1) -jekyll (>= 3.5, < 5.0) -jekyll-feed (~> 0.9) -jekyll-seo-tag (~> 2.1) -minitest (5.14.1) -multipart-post (2.1.1) -nokogiri (1.10.9) -mini_portile2 (~> 2.4.0) -octokit (4.18.0) -faraday (>= 0.9) -sawyer (~> 0.8.0, >= 0.5.3) -pathutil (0.16.2) -forwardable-extended (~> 2.6) -public_suffix (3.1.1) -rb-fsevent (0.10.4) -rb-inotify (0.10.1) -ffi (~> 1.0) -rouge (3.19.0) -ruby-enum (0.8.0) -i18n -rubyzip (2.3.0) -safe_yaml (1.0.5) -sass (3.7.4) -sass-listen (~> 4.0.0) -sass-listen (4.0.0) -rb-fsevent (~> 0.9, >= 0.9.4) -rb-inotify (~> 0.9, >= 0.9.7) -sawyer (0.8.2) -addressable (>= 2.3.5) -faraday (> 0.8, < 2.0) -terminal-table (1.8.0) -unicode-display_width (~> 1.1, >= 1.1.1) -thread_safe (0.3.6) -typhoeus (1.4.0) -ethon (>= 0.9.0) -tzinfo (1.2.7) -thread_safe (~> 0.1) -unicode-display_width (1.7.0) -zeitwerk (2.3.0) - -PLATFORMS -ruby - -DEPENDENCIES -github-pages - -BUNDLED WITH -2.1.4 diff --git a/docs/content/cheat-sheets/JavaScript-Guide.md b/docs/content/cheat-sheets/JavaScript-Guide.md deleted file mode 100644 index 318df7fbcc..0000000000 --- a/docs/content/cheat-sheets/JavaScript-Guide.md +++ /dev/null @@ -1,5718 +0,0 @@ ---- -title: JavaScript -subtitle: JavaScript Cheat Sheet -excerpt: >- - A Node.js app runs in a single process, without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm. -date: '2021-11-21' -thumb_img_path: images/3.jpg -thumb_img_alt: JavaScript -content_img_path: images/3.jpg -content_img_alt: JavaScript -seo: - title: JavaScript - description: A Node.js app runs in a single process, without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm. - extra: - - name: 'og:type' - value: article - keyName: property - - name: 'og:title' - value: JavaScript - keyName: property - - name: 'og:description' - value: JavaScript Cheat Sheet - keyName: property - - name: 'og:image' - value: images/3.jpg - keyName: property - relativeUrl: true - - name: 'twitter:card' - value: summary_large_image - - name: 'twitter:title' - value: JavaScript - - name: 'twitter:description' - value: JavaScript Cheat Sheet - - name: 'twitter:image' - value: images/3.jpg - relativeUrl: true -template: page ---- - -# The Complete JavaScript Reference Guide - -You will want to bookmark this - ---- - -### The Complete JavaScript Reference Guide - -
    ### How to learn effectively - -**Learning**: The acquisition of skills and the ability to apply them in the future. - -**What makes an Effective learner?** - -- They are active listeners. -- They are engaged with the material. -- They are receptive of feedback. -- They are open to difficulty. - -**Why do active learning techniques feel difficult?** - -- It feels difficult because you are constantly receiving feedback, and so you are constantly adapting and perfecting the material. - -**Desirable Difficulty** - -- The skills we wish to obtain is often a difficult one. -- We want challenging but possible lessons based on current level of skill. - -**Effective learners space their practice** - -- Consistent effort > cramming => for **durable knowledge** - ---- - -### Getting visual feedback in your programs - -The first command we'll learn in JavaScript is `console.log`. This command is used to _print_ something onto the screen. As we write our first lines of code, we'll be using `console.log` frequently as a way to visually see the output of our programs. Let's write our first program: - - console.log("hello world"); - console.log("how are you?"); - -Executing the program above would print out the following: - - hello world - how are you? - -Nothing too ground breaking here, but pay close attention to the exact way we wrote the program. In particular, notice how we lay out the periods, parentheses, and quotation marks. We'll also terminate lines with semicolons (;). - -> _Depending on how you structure your code, sometimes you'll be able to omit semicolons at the end of lines. For now, you'll want to include them just as we do._ - -### Syntax - -We refer to the exact arrangement of the symbols, characters, and keywords as **syntax**. These details matter — your computer will only be able to "understand" proper JavaScript syntax. A programming language is similar to a spoken language. A spoken language like English has grammar rules that we should follow in order to be understood by fellow speakers. In the same way, a programming language like JavaScript has syntax rules that we ought to follow! - -As you write your first lines of code in this new language, you may make many syntax errors. Don't get frustrated! This is normal — all new programmers go through this phase. Every time we recognize an error in our code, we have an opportunity to reinforce your understanding of correct syntax. Adopt a growth mindset and learn from your mistakes. - -Additionally, one of the best things about programming is that we can get such immediate feedback from our creations. There is no penalty for making a mistake when programming. Write some code, run the code, read the errors, fix the errors, rinse and repeat! - -### Code comments - -Occasionally we'll want to leave **comments** or notes in our code. Commented lines will be ignored by our computer. This means that we can use comments to write plain english or temporarily avoid execution of some JavaScript lines. The proper _syntax_ for writing a comment is to begin the line with double forward slashes (`//`): - - // let's write another program!!! - console.log("hello world"); - - // console.log("how are you?"); - - console.log("goodbye moon"); - -The program above would only print: - - hello world - goodbye moon - -Comments are useful when annotating pieces of code to offer an explanation of how the code works. We'll want to strive to write straightforward code that is self-explanatory when possible, but we can also use comments to add additional clarity. The real art of programming is to write code so elegantly that it is easy to follow. - -**The Number Data Type** - -The **number** data type in JS is used to represent any numerical values, including integers and decimal numbers. - -**Basic Arithmetic Operators** - -Operators are the symbols that perform particular operations. - -- **+** (addition) -- **-** (subtraction) -- **asterisk** (multiplication) -- **/** (division) -- **%** (modulo) - -JS evaluates more complex expressions using the general math order of operations aka PEMDAS. - -- **PEMDAS** : Parentheses, Exponents, Multiplication, Division, Modulo, Addition, Subtraction. -- _To force a specific order of operation, use the group operator ( ) around a part of the expression._ - -**Modulo** : Very useful operation to check divisibility of numbers, check for even & odd, whether a number is prime, and much more! _(Discrete Math concept, circular problems can be solved with modulo)_ - -- Whenever you have a smaller number % a larger number, the answer will just be the initial small number. - console.log(7 % 10) // => 7; - -**The String Data Type** - -The **string** data type is a primitive data type that used to represent textual data. - -- can be wrapped by either **single** or **double** quotation marks, _best to choose one and stick with it for consistency_. -- If your string contains quotation marks inside, can layer single or double quotation marks to allow it to work. - "That's a great string"; (valid) - ‘Shakespeare wrote, "To be or not to be"'; (valid) - ‘That's a bad string'; (invalid) -- Alt. way to add other quotes within strings is to use template literals. - \`This is a temp'l'ate literal ${function}\` // use ${} to invoke functions within. -- **.length** : property that can be appended to data to return the length. -- empty strings have a length of zero. -- **indices** : indexes of data that begin at 0, can call upon index by using the bracket notation \[ \]. - console.log("bootcamp"\[0\]); // => "b" - console.log("bootcamp"\[10\]); // => "undefined" - console.log("boots"\[1 \* 2\]); // => "o" - console.log("boots"\["boot".length-1\]); // => "t" -- we can pass expressions through the brackets as well since JS always evaluates expressions first. -- The index of the last character of a string is always one less than it's length. -- **indexOf()** : method used to find the first index of a given character within a string. - console.log("bagel".indexOf("b")); // => 0 - console.log("bagel".indexOf("z")); // => -1 -- if the character inside the indexOf() search does not exist in the string, the output will be -1. -- the indexOf() search will return the first instanced index of the the char in the string. -- **concatenate** : word to describe joining strings together into a single string. - -**The Boolean Data Type** - -The **Boolean** data type is the simplest data type since there are only two values: **true** and **false**. - -- **Logical Operators** (B*oolean Operators*) are used to establish logic in our code. -- **!** (not) : reverses a Boolean value. - console.log(!true); // => false - console.log(!!false); // => false -- **Logical Order of Operations** : JS will evaluate !, then &&, then ||. -- **Short-Circuit Evaluation** : Because JS evalutes from left to right, expressions can "short-circuit". For example if we have true on the left of an || logical comparison, it will stop evaluating and yield true instead of wasting resources on processing the rest of the statement. - console.log(true || !false) // => stops after it sees "true ||" - -**Comparison Operators** - -All comparison operators will result in a boolean output. - -**The relative comparators** - -- **>** (greater than) -- **<** (less than) -- **>=** (greater than or equal to) -- **<=** (less than or equal to) -- **===** (equal to) -- **!==** (not equal to) - -Fun Fact: "a" < "b" is considered valid JS Code because string comparisons are compared lexicographically (meaning dictionary order), so "a" is less than "b" because it appears earlier! - -If there is ever a standstill comparison of two string lexicographically (i.e. app vs apple) the comparison will deem the shorter string lesser. - -**Difference between == and ===** - -#### === - -Strict Equality, will only return true if the two comparisons are entirely the same. - -#### == - -Loose Equality, will return true even if the values are of a different type, due to coercion. (Avoid using this) - -**Variables** - -Variables are used to store information to be referenced and manipulated in a program. - -- We initialize a variable by using the **let** keyword and a **=** single equals sign (assignment operator). - let bootcamp = "App Academy"; - console.log(bootcamp); // "App Academy" -- JS variable names can contain any alphanumeric characters, underscores, or dollar signs (cannot being with a number). -- If you do not declare a value for a variable, undefined is automatically set. - let bootcamp; - console.log(bootcamp); // undefined -- We can change the value of a previously declared variable (let, not const) by re-assigning it another value. -- **let** is the updated version of **var**; there are some differences in terms of hoisting and global/block scope - -**Assignment Shorthand** - -let num = 0; - num += 10; // same as num = num + 10 - num -= 2; // same as num = num — 2 - num /= 4; // same as num = num / 4 - num \*= 7; // same as num = num \* 7 - -- In general, any nonsensical arithmetic will result in **NaN** ; usually operations that include undefined. - -**Functions** - -A function is a procedure of code that will run when called. Functions are used so that we do not have to rewrite code to do the same thing over and over. (Think of them as ‘subprograms') - -- **Function Declaration** : Process when we first initially write our function. -- Includes three things: -- Name of the function. -- A list of _parameters_ () -- The code to execute {} -- **Function Calls** : We can call upon our function whenever and wherever\* we want. (\*wherever is only after the initial declaration) -- JS evaluates code top down, left to right. -- When we execute a declared function later on in our program we refer to this as **invoking** our function. -- Every function in JS returns undefined unless otherwise specified. -- When we hit a **return** statement in a function we immediately exit the function and return to where we called the function. -- When naming functions in JS always use camelCase and name it something appropriate. - -Greate code reads like English and almost explains itself. Think: Elegant, readable, and maintainable! - -**Parameters and Arguments** - -- **Parameters** : Comma seperated variables specified as part of a function's declaration. -- **Arguments** : Values passed to the function when it is invoked. -- _If the number of arguments passed during a function invocation is different than the number of paramters listed, it will still work._ -- However, is there are not enough arguments provided for parameters our function will likely yield **Nan**. - -### Including Comments - -Comments are important because they help other people understand what is going on in your code or remind you if you forgot something yourself. Keep in mind that they have to be marked properly so the browser won't try to execute them. - -In JavaScript you have two different options: - -- Single-line comments — To include a comment that is limited to a single line, precede it with `//` -- Multi-line comments — In case you want to write longer comments between several lines, wrap it in `/*` and `*/` to avoid it from being executed - -### Variables in JavaScript - -Variables are stand-in values that you can use to perform operations. You should be familiar with them from math class. - -### var, const, let - -You have three different possibilities for declaring a variable in JavaScript, each with their own specialties: - -- `var` — The most common variable. It can be reassigned but only accessed within a function. Variables defined with `var` move to the top when the code is executed. -- `const` — Can not be reassigned and not accessible before they appear within the code. -- `let` — Similar to `const`, the `let` variable can be reassigned but not re-declared. - -### Data Types - -Variables can contain different types of values and data types. You use `=` to assign them: - -- Numbers — `var age = 23` -- Variables — `var x` -- Text (strings) — `var a = "init"` -- Operations — `var b = 1 + 2 + 3` -- True or false statements — `var c = true` -- Constant numbers — `const PI = 3.14` -- Objects — `var name = {firstName:"John", lastName:"Doe"}` - -There are more possibilities. Note that variables are case sensitive. That means `lastname` and `lastName` will be handled as two different variables. - -### Objects - -Objects are certain kinds of variables. They are variables that can have their own values and methods. The latter are actions that you can perform on objects. - -var person = { - -firstName:"John", - -lastName:"Doe", - -age:20, - -nationality:"German" - -}; - -### The Next Level: Arrays - -Next up in our JavaScript cheat sheet are arrays. Arrays are part of many different programming languages. They are a way of organizing variables and properties into groups. Here's how to create one in JavaScript: - -var fruit = \["Banana", "Apple", "Pear"\]; - -Now you have an array called `fruit` which contains three items that you can use for future operations. - -### Array Methods - -Once you have created arrays, there are a few things you can do with them: - -- `concat()` — Join several arrays into one -- `indexOf()` — Returns the first position at which a given element appears in an array -- `join()` — Combine elements of an array into a single string and return the string -- `lastIndexOf()` — Gives the last position at which a given element appears in an array -- `pop()` — Removes the last element of an array -- `push()` — Add a new element at the end -- `reverse()` — Sort elements in a descending order -- `shift()` — Remove the first element of an array -- `slice()` — Pulls a copy of a portion of an array into a new array -- `sort()` — Sorts elements alphabetically -- `splice()` — Adds elements in a specified way and position -- `toString()` — Converts elements to strings -- `unshift()` —Adds a new element to the beginning -- `valueOf()` — Returns the primitive value of the specified object - -### Operators - -If you have variables, you can use them to perform different kinds of operations. To do so, you need operators. - -### Basic Operators - -- `+` — Addition -- `-` — Subtraction -- `*` — Multiplication -- `/` — Division -- `(...)` — Grouping operator, operations within brackets are executed earlier than those outside -- `%` — Modulus (remainder ) -- `++` — Increment numbers -- `--` — Decrement numbers - -### Comparison Operators - -- `==` — Equal to -- `===` — Equal value and equal type -- `!=` — Not equal -- `!==` — Not equal value or not equal type -- `>` — Greater than -- `<` — Less than -- `>=` — Greater than or equal to -- `<=` — Less than or equal to -- `?` — Ternary operator - -### Logical Operators - -- `&&` — Logical and -- `||` — Logical or -- `!` — Logical not - -### Bitwise Operators - -- `&` — AND statement -- `|` — OR statement -- `~` — NOT -- `^` — XOR -- `<<` — Left shift -- `>>` — Right shift -- `>>>` — Zero fill right shift - -### Functions - -JavaScript functions are blocks of code that perform a certain task. A basic function looks like this: - -function name(parameter1, parameter2, parameter3) { - -// what the function does - -} - -As you can see, it consists of the `function` keyword plus a name. The function's parameters are in the brackets and you have curly brackets around what the function performs. You can create your own, but to make your life easier - there are also a number of default functions. - -### Outputting Data - -A common application for functions is the output of data. For the output, you have the following options: - -- `alert()` — Output data in an alert box in the browser window -- `confirm()` — Opens up a yes/no dialog and returns true/false depending on user click -- `console.log()` — Writes information to the browser console, good for debugging purposes -- `document.write()` — Write directly to the HTML document -- `prompt()` — Creates a dialogue for user input - -### Global Functions - -Global functions are functions built into every browser capable of running JavaScript. - -- `decodeURI()` — Decodes a Uniform Resource Identifier (URI) created by `encodeURI` or similar -- `decodeURIComponent()` — Decodes a URI component -- `encodeURI()` — Encodes a URI into UTF-8 -- `encodeURIComponent()` — Same but for URI components -- `eval()` — Evaluates JavaScript code represented as a string -- `isFinite()` — Determines whether a passed value is a finite number -- `isNaN()` — Determines whether a value is NaN or not -- `Number()` —- Returns a number converted from its argument -- `parseFloat()` — Parses an argument and returns a floating-point number -- `parseInt()` — Parses its argument and returns an integer - -### JavaScript Loops - -Loops are part of most programming languages. They allow you to execute blocks of code desired number of times with different values: - -for (before loop; condition **for** loop; execute after loop) { - -// what to do during the loop - -} - -You have several parameters to create loops: - -- `for` — The most common way to create a loop in JavaScript -- `while` — Sets up conditions under which a loop executes -- `do while` — Similar to the `while` loop but it executes at least once and performs a check at the end to see if the condition is met to execute again -- `break` —Used to stop and exit the cycle at certain conditions -- `continue` — Skip parts of the cycle if certain conditions are met - -### If — Else Statements - -These types of statements are easy to understand. Using them, you can set conditions for when your code is executed. If certain conditions apply, something is done, if not — something else is executed. - -if (condition) { - -// what to do if condition is met - -} **else** { - -// what to do if condition is not met - -} - -A similar concept to `if else` is the `switch` statement. However, using the switch you select one of several code blocks to execute. - -### Strings - -Strings are what JavaScript calls to text that does not perform a function but can appear on the screen. - -var person = "John Doe"; - -In this case, `John Doe` is the string. - -### Escape Characters - -In JavaScript, strings are marked with single or double-quotes. If you want to use quotation marks in a string, you need to use special characters: - -- `\'` — Single quote -- `\"` — Double quote - -Aside from that you also have additional escape characters: - -- `\\` — Backslash -- `\b` — Backspace -- `\f` — Form feed -- `\n` — New line -- `\r` — Carriage return -- `\t` — Horizontal tabulator -- `\v` — Vertical tabulator - -### String Methods - -There are many different ways to work with strings: - -- `charAt()` — Returns a character at a specified position inside a string -- `charCodeAt()` — Gives you the Unicode of a character at that position -- `concat()` — Concatenates (joins) two or more strings into one -- `fromCharCode()` — Returns a string created from the specified sequence of UTF-16 code units -- `indexOf()` — Provides the position of the first occurrence of a specified text within a string -- `lastIndexOf()` — Same as `indexOf()` but with the last occurrence, searching backward -- `match()` — Retrieves the matches of a string against a search pattern -- `replace()` — Find and replace specified text in a string -- `search()` — Executes a search for a matching text and returns its position -- `slice()` — Extracts a section of a string and returns it as a new string -- `split()` — Splits a string object into an array of strings at a specified position -- `substr()` — Similar to `slice()` but extracts a substring depending on a specified number of characters -- `substring()` — Also similar to `slice()` but can't accept negative indices -- `toLowerCase()` — Convert strings to lower case -- `toUpperCase()` — Convert strings to upper case -- `valueOf()` — Returns the primitive value (that has no properties or methods) of a string object - -### Regular Expression Syntax - -Regular expressions are search patterns used to match character combinations in strings. The search pattern can be used for text search and text to replace operations. - -### Pattern Modifiers - -- `e` — Evaluate replacement -- `i` — Perform case-insensitive matching -- `g` — Perform global matching -- `m` — Perform multiple line matching -- `s` — Treat strings as a single line -- `x` — Allow comments and whitespace in the pattern -- `U` — Ungreedy pattern - -### Brackets - -- `[abc]` — Find any of the characters between the brackets -- `[^abc]` — Find any character which is not in the brackets -- `[0-9]` — Used to find any digit from 0 to 9 -- `[A-z]` — Find any character from uppercase A to lowercase z -- `(a|b|c)` — Find any of the alternatives separated with `|` - -### Metacharacters - -- `.` — Find a single character, except newline or line terminator -- `\w` — Word character -- `\W` — Non-word character -- `\d` — A digit -- `\D` — A non-digit character -- `\s` — Whitespace character -- `\S` — Non-whitespace character -- `\b` — Find a match at the beginning/end of a word -- `\B` — A match not at the beginning/end of a word -- `\0` — NUL character -- `\n` — A new line character -- `\f` — Form feed character -- `\r` — Carriage return character -- `\t` — Tab character -- `\v` — Vertical tab character -- `\xxx` — The character specified by an octal number xxx -- `\xdd` — Character specified by a hexadecimal number dd -- `\uxxxx` — The Unicode character specified by a hexadecimal number XXXX - -### Quantifiers - -- `n+` — Matches any string that contains at least one n -- `n*` — Any string that contains zero or more occurrences of n -- `n?` — A string that contains zero or one occurrence of n -- `n{X}` — String that contains a sequence of X n's -- `n{X,Y}` — Strings that contain a sequence of X to Y n's -- `n{X,}` — Matches any string that contains a sequence of at least X n's -- `n$` — Any string with n at the end of it -- `^n` — String with n at the beginning of it -- `?=n` — Any string that is followed by a specific string n -- `?!n` — String that is not followed by a specific string ni - -### Numbers and Math - -In JavaScript, you can also work with numbers, constants and perform mathematical functions. - -### Number Properties - -- `MAX_VALUE` — The maximum numeric value representable in JavaScript -- `MIN_VALUE` — Smallest positive numeric value representable in JavaScript -- `NaN` — The "Not-a-Number" value -- `NEGATIVE_INFINITY` — The negative Infinity value -- `POSITIVE_INFINITY` — Positive Infinity value - -### Number Methods - -- `toExponential()` — Returns the string with a rounded number written as exponential notation -- `toFixed()` — Returns the string of a number with a specified number of decimals -- `toPrecision()` — String of a number written with a specified length -- `toString()` — Returns a number as a string -- `valueOf()` — Returns a number as a number - -### Math Properties - -- `E` — Euler's number -- `LN2` — The natural logarithm of 2 -- `LN10` — Natural logarithm of 10 -- `LOG2E` — Base 2 logarithm of E -- `LOG10E` — Base 10 logarithm of E -- `PI` — The number PI -- `SQRT1_2` — Square root of 1/2 -- `SQRT2` — The square root of 2 - -### Math Methods - -- `abs(x)` — Returns the absolute (positive) value of x -- `acos(x)` — The arccosine of x, in radians -- `asin(x)` — Arcsine of x, in radians -- `atan(x)` — The arctangent of x as a numeric value -- `atan2(y,x)` — Arctangent of the quotient of its arguments -- `ceil(x)` — Value of x rounded up to its nearest integer -- `cos(x)` — The cosine of x (x is in radians) -- `exp(x)` — Value of Ex -- `floor(x)` — The value of x rounded down to its nearest integer -- `log(x)` — The natural logarithm (base E) of x -- `max(x,y,z,...,n)` — Returns the number with the highest value -- `min(x,y,z,...,n)` — Same for the number with the lowest value -- `pow(x,y)` — X to the power of y -- `random()` — Returns a random number between 0 and 1 -- `round(x)` — The value of x rounded to its nearest integer -- `sin(x)` — The sine of x (x is in radians) -- `sqrt(x)` — Square root of x -- `tan(x)` — The tangent of an angle - -### Dealing with Dates in JavaScript - -You can also work with and modify dates and time with JavaScript. This is the next chapter in the JavaScript cheat sheet. - -### Setting Dates - -- `Date()` — Creates a new date object with the current date and time -- `Date(2017, 5, 21, 3, 23, 10, 0)` — Create a custom date object. The numbers represent a year, month, day, hour, minutes, seconds, milliseconds. You can omit anything you want except for a year and month. -- `Date("2017-06-23")` — Date declaration as a string - -### Pulling Date and Time Values - -- `getDate()` — Get the day of the month as a number (1-31) -- `getDay()` — The weekday as a number (0-6) -- `getFullYear()` — Year as a four-digit number (yyyy) -- `getHours()` — Get the hour (0-23) -- `getMilliseconds()` — The millisecond (0-999) -- `getMinutes()` — Get the minute (0-59) -- `getMonth()` — Month as a number (0-11) -- `getSeconds()` — Get the second (0-59) -- `getTime()` — Get the milliseconds since January 1, 1970 -- `getUTCDate()` — The day (date) of the month in the specified date according to universal time (also available for day, month, full year, hours, minutes etc.) -- `parse` — Parses a string representation of a date and returns the number of milliseconds since January 1, 1970 - -### Set Part of a Date - -- `setDate()` — Set the day as a number (1-31) -- `setFullYear()` — Sets the year (optionally month and day) -- `setHours()` — Set the hour (0-23) -- `setMilliseconds()` — Set milliseconds (0-999) -- `setMinutes()` — Sets the minutes (0-59) -- `setMonth()` — Set the month (0-11) -- `setSeconds()` — Sets the seconds (0-59) -- `setTime()` — Set the time (milliseconds since January 1, 1970) -- `setUTCDate()` — Sets the day of the month for a specified date according to universal time (also available for day, month, full year, hours, minutes etc.) - -### DOM Mode - -The DOM is the Document Object Model of a page. It is the code of the structure of a webpage. JavaScript comes with a lot of different ways to create and manipulate HTML elements (called nodes). - -### Node Properties - -- `attributes` — Returns a live collection of all attributes registered to an element -- `baseURI` — Provides the absolute base URL of an HTML element -- `childNodes` — Gives a collection of an element's child nodes -- `firstChild` — Returns the first child node of an element -- `lastChild` — The last child node of an element -- `nextSibling` — Gives you the next node at the same node tree level -- `nodeName` —Returns the name of a node -- `nodeType` — Returns the type of a node -- `nodeValue` — Sets or returns the value of a node -- `ownerDocument` — The top-level document object for this node -- `parentNode` — Returns the parent node of an element -- `previousSibling` — Returns the node immediately preceding the current one -- `textContent` — Sets or returns the textual content of a node and its descendants - -### Node Methods - -- `appendChild()` — Adds a new child node to an element as the last child node -- `cloneNode()` — Clones an HTML element -- `compareDocumentPosition()` — Compares the document position of two elements -- `getFeature()` — Returns an object which implements the APIs of a specified feature -- `hasAttributes()` — Returns true if an element has any attributes, otherwise false -- `hasChildNodes()` — Returns true if an element has any child nodes, otherwise false -- `insertBefore()` — Inserts a new child node before a specified, existing child node -- `isDefaultNamespace()` — Returns true if a specified namespaceURI is the default, otherwise false -- `isEqualNode()` — Checks if two elements are equal -- `isSameNode()` — Checks if two elements are the same node -- `isSupported()` — Returns true if a specified feature is supported on the element -- `lookupNamespaceURI()` — Returns the namespace URI associated with a given node -- `lookupPrefix()` — Returns a DOMString containing the prefix for a given namespace URI if present -- `normalize()` — Joins adjacent text nodes and removes empty text nodes in an element -- `removeChild()` — Removes a child node from an element -- `replaceChild()` — Replaces a child node in an element - -### Element Methods - -- `getAttribute()` — Returns the specified attribute value of an element node -- `getAttributeNS()` — Returns string value of the attribute with the specified namespace and name -- `getAttributeNode()` — Gets the specified attribute node -- `getAttributeNodeNS()` — Returns the attribute node for the attribute with the given namespace and name -- `getElementsByTagName()` — Provides a collection of all child elements with the specified tag name -- `getElementsByTagNameNS()` — Returns a live HTMLCollection of elements with a certain tag name belonging to the given namespace -- `hasAttribute()` — Returns true if an element has any attributes, otherwise false -- `hasAttributeNS()` — Provides a true/false value indicating whether the current element in a given namespace has the specified attribute -- `removeAttribute()` — Removes a specified attribute from an element -- `removeAttributeNS()` — Removes the specified attribute from an element within a certain namespace -- `removeAttributeNode()` — Takes away a specified attribute node and returns the removed node -- `setAttribute()` — Sets or changes the specified attribute to a specified value -- `setAttributeNS()` — Adds a new attribute or changes the value of an attribute with the given namespace and name -- `setAttributeNode()` — Sets or changes the specified attribute node -- `setAttributeNodeNS()` — Adds a new namespaced attribute node to an element - -### Working with the User Browser - -Besides HTML elements, JavaScript is also able to take into account the user browser and incorporate its properties into the code. - -### Window Properties - -- `closed` — Checks whether a window has been closed or not and returns true or false -- `defaultStatus` — Sets or returns the default text in the status bar of a window -- `document` — Returns the document object for the window -- `frames` — Returns all `](#iframe-frameborder0-width100-height800px-srchttpscodepeniobgoonzpenwvebjbmiframe ) - - [**Introducing JSX**](#introducing-jsx ) - - [Consider this variable declaration:](#consider-this-variable-declaration ) - - [Why JSX?](#why-jsx ) - - [Embedding Expressions in JSX](#embedding-expressions-in-jsx ) - - [We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of automatic semicolon insertion.](#we-split-jsx-over-multiple-lines-for-readability-while-it-isnt-required-when-doing-this-we-also-recommend-wrapping-it-in-parentheses-to-avoid-the-pitfalls-of-automatic-semicolon-insertion ) - - [JSX is an Expression Too](#jsx-is-an-expression-too ) - - [Specifying Attributes with JSX](#specifying-attributes-with-jsx ) - - [Specifying Children with JSX](#specifying-children-with-jsx ) - - [JSX Prevents Injection Attacks](#jsx-prevents-injection-attacks ) - - [JSX Represents Objects](#jsx-represents-objects ) - - [We will explore rendering React elements to the DOM in the next section.](#we-will-explore-rendering-react-elements-to-the-dom-in-the-next-section ) - - [**Rendering Elements**](#rendering-elements ) - - [Elements are the smallest building blocks of React apps.](#elements-are-the-smallest-building-blocks-of-react-apps ) - - [Rendering an Element into the DOM](#rendering-an-element-into-the-dom ) - - [We call this a "root" DOM node because everything inside it will be managed by React DOM.](#we-call-this-a-root-dom-node-because-everything-inside-it-will-be-managed-by-react-dom ) - - [Updating the Rendered Element](#updating-the-rendered-element ) - - [React Only Updates What's Necessary](#react-only-updates-whats-necessary ) - - [**Components and Props**](#components-and-props ) - - [Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components. You can find a detailed component API reference here.](#components-let-you-split-the-ui-into-independent-reusable-pieces-and-think-about-each-piece-in-isolation-this-page-provides-an-introduction-to-the-idea-of-components-you-can-find-a-detailed-component-api-reference-here ) - - [Function and Class Components](#function-and-class-components ) - - [Rendering a Component](#rendering-a-component ) - - [For example, this code renders "Hello, Sara" on the page:](#for-example-this-code-renders-hello-sara-on-the-page ) - - [Composing Components](#composing-components ) - - [For example, we can create an `App` component that renders `Welcome` many times:](#for-example-we-can-create-an-app-component-that-renders-welcome-many-times ) - - [Extracting Components](#extracting-components ) - - [For example, consider this `Comment` component:](#for-example-consider-this-comment-component ) - - [We recommend naming props from the component's own point of view rather than the context in which it is being used.](#we-recommend-naming-props-from-the-components-own-point-of-view-rather-than-the-context-in-which-it-is-being-used ) - - [We can now simplify `Comment` a tiny bit:](#we-can-now-simplify-comment-a-tiny-bit ) - - [Props are Read-Only](#props-are-read-only ) - - [**State and Lifecycle**](#state-and-lifecycle ) - - [This page introduces the concept of state and lifecycle in a React component. You can find a detailed component API reference here.](#this-page-introduces-the-concept-of-state-and-lifecycle-in-a-react-component-you-can-find-a-detailed-component-api-reference-here ) - - [We can start by encapsulating how the clock looks:](#we-can-start-by-encapsulating-how-the-clock-looks ) - - [Converting a Function to a Class](#converting-a-function-to-a-class ) - - [Adding Local State to a Class](#adding-local-state-to-a-class ) - - [We will move the `date` from props to state in three steps:](#we-will-move-the-date-from-props-to-state-in-three-steps ) - - [Adding Lifecycle Methods to a Class](#adding-lifecycle-methods-to-a-class ) - - [We want to set up a timer whenever the `Clock` is rendered to the DOM for the first time. This is called "mounting" in React.](#we-want-to-set-up-a-timer-whenever-the-clock-is-rendered-to-the-dom-for-the-first-time-this-is-called-mounting-in-react ) - - [We also want to clear that timer whenever the DOM produced by the `Clock` is removed. This is called "unmounting" in React.](#we-also-want-to-clear-that-timer-whenever-the-dom-produced-by-the-clock-is-removed-this-is-called-unmounting-in-react ) - - [We can declare special methods on the component class to run some code when a component mounts and unmounts:](#we-can-declare-special-methods-on-the-component-class-to-run-some-code-when-a-component-mounts-and-unmounts ) - - [We will tear down the timer in the `componentWillUnmount()` lifecycle method:](#we-will-tear-down-the-timer-in-the-componentwillunmount-lifecycle-method ) - - [Using State Correctly](#using-state-correctly ) - - [Do Not Modify State Directly](#do-not-modify-state-directly ) - - [For example, this will not re-render a component:](#for-example-this-will-not-re-render-a-component ) - - [Instead, use `setState()`:](#instead-use-setstate ) - - [State Updates May Be Asynchronous](#state-updates-may-be-asynchronous ) - - [For example, this code may fail to update the counter:](#for-example-this-code-may-fail-to-update-the-counter ) - - [State Updates are Merged](#state-updates-are-merged ) - - [For example, your state may contain several independent variables:](#for-example-your-state-may-contain-several-independent-variables ) - - [The Data Flows Down](#the-data-flows-down ) - - [**Handling Events**](#handling-events ) - - [Handling events with React elements is very similar to handling events on DOM elements. There are some syntax differences:](#handling-events-with-react-elements-is-very-similar-to-handling-events-on-dom-elements-there-are-some-syntax-differences ) - - [For example, the HTML:](#for-example-the-html ) - - [In React, this could instead be:](#in-react-this-could-instead-be ) - - [Passing Arguments to Event Handlers](#passing-arguments-to-event-handlers ) - - [**Conditional Rendering**](#conditional-rendering ) - - [In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application.](#in-react-you-can-create-distinct-components-that-encapsulate-behavior-you-need-then-you-can-render-only-some-of-them-depending-on-the-state-of-your-application ) - - [We'll create a `Greeting` component that displays either of these components depending on whether a user is logged in:](#well-create-a-greeting-component-that-displays-either-of-these-components-depending-on-whether-a-user-is-logged-in ) - - [Element Variables](#element-variables ) - - [In the example below, we will create a stateful component called `LoginControl`.](#in-the-example-below-we-will-create-a-stateful-component-called-logincontrol ) - - [Inline If with Logical && Operator](#inline-if-with-logical--operator ) - - [Inline If-Else with Conditional Operator](#inline-if-else-with-conditional-operator ) - - [Preventing Component from Rendering](#preventing-component-from-rendering ) - - [**Lists and Keys**](#lists-and-keys ) - - [First, let's review how you transform lists in JavaScript.](#first-lets-review-how-you-transform-lists-in-javascript ) - - [Rendering Multiple Components](#rendering-multiple-components ) - - [Basic List Component](#basic-list-component ) - - [We can refactor the previous example into a component that accepts an array of `numbers` and outputs a list of elements.](#we-can-refactor-the-previous-example-into-a-component-that-accepts-an-array-of-numbers-and-outputs-a-list-of-elements ) - - [Keys](#keys ) - - [Extracting Components with Keys](#extracting-components-with-keys ) - - [For example, if you extract a `ListItem` component, you should keep the key on the `` elements in the array rather than on the `
  • ` element in the `ListItem` itself.](#for-example-if-you-extract-a-listitem-component-you-should-keep-the-key-on-the-listitem--elements-in-the-array-rather-than-on-the-li-element-in-the-listitem-itself ) - - [Keys Must Only Be Unique Among Siblings](#keys-must-only-be-unique-among-siblings ) - - [Embedding map() in JSX](#embedding-map-in-jsx ) - - [**Forms**](#forms ) - - [HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state. ##### For example, this form in plain HTML accepts a single name:](#html-form-elements-work-a-bit-differently-from-other-dom-elements-in-react-because-form-elements-naturally-keep-some-internal-state--for-example-this-form-in-plain-html-accepts-a-single-name ) - - [Controlled Components](#controlled-components ) - - [We can combine the two by making the React state be the "single source of truth". Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a "controlled component".](#we-can-combine-the-two-by-making-the-react-state-be-the-single-source-of-truth-then-the-react-component-that-renders-a-form-also-controls-what-happens-in-that-form-on-subsequent-user-input-an-input-form-element-whose-value-is-controlled-by-react-in-this-way-is-called-a-controlled-component ) - - [For example, if we want to make the previous example log the name when it is submitted, we can write the form as a controlled component:](#for-example-if-we-want-to-make-the-previous-example-log-the-name-when-it-is-submitted-we-can-write-the-form-as-a-controlled-component ) - - [The textarea Tag](#the-textarea-tag ) - - [In React, a ` -``` - -#### In React, a ` -``` - -In React, a ` -``` - -In React, a ` -``` - -#### In React, a ` - -
    - -
    - - - - diff --git a/docs/content/learning-area/html/forms/file-examples/file-example.html b/docs/content/learning-area/html/forms/file-examples/file-example.html deleted file mode 100644 index 338fffdfce..0000000000 --- a/docs/content/learning-area/html/forms/file-examples/file-example.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - Complete file example - - - - -
    -
    - - -
    -
    -

    No files currently selected for upload

    -
    -
    - -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/file-examples/file-with-accept.html b/docs/content/learning-area/html/forms/file-examples/file-with-accept.html deleted file mode 100644 index 62c553a4b5..0000000000 --- a/docs/content/learning-area/html/forms/file-examples/file-with-accept.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - File upload example with accept - - - - -
    -
    - - -
    -
    - -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/file-examples/simple-file.html b/docs/content/learning-area/html/forms/file-examples/simple-file.html deleted file mode 100644 index 173ba2f5c0..0000000000 --- a/docs/content/learning-area/html/forms/file-examples/simple-file.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - File upload example - - - - -
    -
    - - -
    -
    - -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/form-validation/custom-error-message.html b/docs/content/learning-area/html/forms/form-validation/custom-error-message.html deleted file mode 100644 index aa2b0730eb..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/custom-error-message.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Simple custom error message - - - - -
    - - - -
    - - - - diff --git a/docs/content/learning-area/html/forms/form-validation/detailed-custom-validation.html b/docs/content/learning-area/html/forms/form-validation/detailed-custom-validation.html deleted file mode 100644 index e02b46e9d6..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/detailed-custom-validation.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - Detailed custom validation - - - - -
    -

    - -

    - -
    - - - - diff --git a/docs/content/learning-area/html/forms/form-validation/fruit-length.html b/docs/content/learning-area/html/forms/form-validation/fruit-length.html deleted file mode 100644 index 2e8d46f9c7..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/fruit-length.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Favorite fruit length constraint - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/form-validation/fruit-pattern.html b/docs/content/learning-area/html/forms/form-validation/fruit-pattern.html deleted file mode 100644 index e83c93f9d3..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/fruit-pattern.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Favorite fruit with required and pattern attributes - - - - -
    - - - -
    - - diff --git a/docs/content/learning-area/html/forms/form-validation/fruit-required.html b/docs/content/learning-area/html/forms/form-validation/fruit-required.html deleted file mode 100644 index 306bc4cdc1..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/fruit-required.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Favorite fruit with required attribute - - - - -
    - - - -
    - - diff --git a/docs/content/learning-area/html/forms/form-validation/fruit-start.html b/docs/content/learning-area/html/forms/form-validation/fruit-start.html deleted file mode 100644 index c352fb266f..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/fruit-start.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Favorite fruit start - - - - -
    - - - -
    - - diff --git a/docs/content/learning-area/html/forms/form-validation/full-example.html b/docs/content/learning-area/html/forms/form-validation/full-example.html deleted file mode 100644 index 2642bd151f..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/full-example.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Full built-in validation example - - - - -
    -

    -

    - Do you have a driver's license?* - - - - -
    -

    -

    - - - -

    -

    - - - - - - - - - - -

    -

    - - -

    -

    - - -

    -

    - -

    -
    - - - diff --git a/docs/content/learning-area/html/forms/form-validation/min-max.html b/docs/content/learning-area/html/forms/form-validation/min-max.html deleted file mode 100644 index c9b3281fdd..0000000000 --- a/docs/content/learning-area/html/forms/form-validation/min-max.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Minimum and maximum examples - - - - -
    -

    - - -

    -

    - - -

    -

    - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/hidden-input-example/index.html b/docs/content/learning-area/html/forms/hidden-input-example/index.html deleted file mode 100644 index 6a86de4b84..0000000000 --- a/docs/content/learning-area/html/forms/hidden-input-example/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - <input type="hidden"> example - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    - -
    - - diff --git a/docs/content/learning-area/html/forms/html-form-structure/checkbox-label.html b/docs/content/learning-area/html/forms/html-form-structure/checkbox-label.html deleted file mode 100644 index 47fad09dd6..0000000000 --- a/docs/content/learning-area/html/forms/html-form-structure/checkbox-label.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Checkbox label example - - - -
    -

    - - -

    -

    - - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/html-form-structure/fieldset-legend.html b/docs/content/learning-area/html/forms/html-form-structure/fieldset-legend.html deleted file mode 100644 index 72bc859983..0000000000 --- a/docs/content/learning-area/html/forms/html-form-structure/fieldset-legend.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - fieldset and legend example - - - -
    -
    - Fruit juice size -

    -

    -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/html-form-structure/payment-form.css b/docs/content/learning-area/html/forms/html-form-structure/payment-form.css deleted file mode 100644 index 1dc7c37d5f..0000000000 --- a/docs/content/learning-area/html/forms/html-form-structure/payment-form.css +++ /dev/null @@ -1,67 +0,0 @@ -h1 { - margin-top: 0; -} - -ul { - margin: 0; - padding: 0; - list-style: none; -} - -form { - margin: 0 auto; - width: 400px; - padding: 1em; - border: 1px solid #ccc; - border-radius: 1em; -} - -div + div { - margin-top: 1em; -} - -label span { - display: inline-block; - width: 120px; - text-align: right; -} - -input, -textarea { - font: 1em sans-serif; - width: 250px; - box-sizing: border-box; - border: 1px solid #999; -} - -input[type='checkbox'], -input[type='radio'] { - width: auto; - border: none; -} - -input:focus, -textarea:focus { - border-color: #000; -} - -textarea { - vertical-align: top; - height: 5em; - resize: vertical; -} - -fieldset { - width: 250px; - box-sizing: border-box; - margin-left: 136px; - border: 1px solid #999; -} - -button { - margin: 20px 0 0 124px; -} - -label { - position: relative; -} diff --git a/docs/content/learning-area/html/forms/html-form-structure/payment-form.html b/docs/content/learning-area/html/forms/html-form-structure/payment-form.html deleted file mode 100644 index 3abd8caa33..0000000000 --- a/docs/content/learning-area/html/forms/html-form-structure/payment-form.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - Payment form example - - - - -
    -

    Payment form

    -

    - Required fields are followed by *. -

    -
    -

    Contact information

    -
    - Title -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    -
    -

    - - -

    -

    - - -

    -

    - - -

    -
    -
    -

    Payment information

    -

    - - -

    -

    - - -

    -

    - - -

    -
    -
    -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/html-form-structure/required-labels.html b/docs/content/learning-area/html/forms/html-form-structure/required-labels.html deleted file mode 100644 index f672f5778a..0000000000 --- a/docs/content/learning-area/html/forms/html-form-structure/required-labels.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - Required label examples - - - -
    -

    Required fields are followed by *.

    - - - - - - - - -
    - - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/image-type-example/colors-original.png b/docs/content/learning-area/html/forms/image-type-example/colors-original.png deleted file mode 100644 index 18fa5aa7ea..0000000000 Binary files a/docs/content/learning-area/html/forms/image-type-example/colors-original.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/image-type-example/colors.png b/docs/content/learning-area/html/forms/image-type-example/colors.png deleted file mode 100644 index 33a03e4b59..0000000000 Binary files a/docs/content/learning-area/html/forms/image-type-example/colors.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/image-type-example/index.html b/docs/content/learning-area/html/forms/image-type-example/index.html deleted file mode 100644 index f84fd9dc20..0000000000 --- a/docs/content/learning-area/html/forms/image-type-example/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - <input type="image"> example - - - - -
    -

    Login to your account

    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/image-type-example/login-original.png b/docs/content/learning-area/html/forms/image-type-example/login-original.png deleted file mode 100644 index c3a71120ca..0000000000 Binary files a/docs/content/learning-area/html/forms/image-type-example/login-original.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/image-type-example/login.png b/docs/content/learning-area/html/forms/image-type-example/login.png deleted file mode 100644 index fd9c3a5c7c..0000000000 Binary files a/docs/content/learning-area/html/forms/image-type-example/login.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/image-type-example/xy-coordinates-example.html b/docs/content/learning-area/html/forms/image-type-example/xy-coordinates-example.html deleted file mode 100644 index 63a30e1a5b..0000000000 --- a/docs/content/learning-area/html/forms/image-type-example/xy-coordinates-example.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - X Y coordinates example - - - - -
    -

    Choose your favourite color

    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/indeterminate-example/index.html b/docs/content/learning-area/html/forms/indeterminate-example/index.html deleted file mode 100644 index ec12206064..0000000000 --- a/docs/content/learning-area/html/forms/indeterminate-example/index.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - callback test - - - -
    -
    - Complete the recipe -
    - - -
      -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    -
    -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/month-examples/month-validation.html b/docs/content/learning-area/html/forms/month-examples/month-validation.html deleted file mode 100644 index 3fd2a0f9f0..0000000000 --- a/docs/content/learning-area/html/forms/month-examples/month-validation.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - Month example - - - - -
    -
    - - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/advanced-examples.html b/docs/content/learning-area/html/forms/native-form-widgets/advanced-examples.html deleted file mode 100644 index c88bec242f..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/advanced-examples.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Advanced examples - - - -
    -

    - - -

    -

    - - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -
    - - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/button-examples.html b/docs/content/learning-area/html/forms/native-form-widgets/button-examples.html deleted file mode 100644 index 3c67186441..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/button-examples.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Button examples - - - -
    -

    - -

    -

    - -

    -

    - -

    -

    - -

    -

    - -

    -

    - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/checkable-items.html b/docs/content/learning-area/html/forms/native-form-widgets/checkable-items.html deleted file mode 100644 index 7ba110f652..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/checkable-items.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - Checkable items examples - - - -
    -
    - Choose all the vegetables you like to eat -
      -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    -
    -
    - What is your favorite meal? -
      -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/drop-down-content.html b/docs/content/learning-area/html/forms/native-form-widgets/drop-down-content.html deleted file mode 100644 index d151c3d46f..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/drop-down-content.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - Drop down content examples - - - -
    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - - - - - - - - - - - -

    -

    - - - - - - -

    -

    - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/map.png b/docs/content/learning-area/html/forms/native-form-widgets/map.png deleted file mode 100644 index f7b3b2894b..0000000000 Binary files a/docs/content/learning-area/html/forms/native-form-widgets/map.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/native-form-widgets/multi-line-text-field.html b/docs/content/learning-area/html/forms/native-form-widgets/multi-line-text-field.html deleted file mode 100644 index 5f0bc44643..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/multi-line-text-field.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Multiple line text field example - - - - -
    -

    - - -

    -

    - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/other-examples.html b/docs/content/learning-area/html/forms/native-form-widgets/other-examples.html deleted file mode 100644 index 6957add5c3..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/other-examples.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Other examples - - - -
    -

    - - -

    -
    - -
    -

    - -

    -

    - 75/100 -

    -

    - 75 -

    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/positioned-legend.html b/docs/content/learning-area/html/forms/native-form-widgets/positioned-legend.html deleted file mode 100644 index eb609fce8a..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/positioned-legend.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - Positioned legend example - - - - -
    -
    - Choose all the vegetables you like to eat -
      -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    -
    -
    - What is your favorite meal? -
      -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    • - - -
    • -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/native-form-widgets/single-line-text-fields.html b/docs/content/learning-area/html/forms/native-form-widgets/single-line-text-fields.html deleted file mode 100644 index 1bb91ea757..0000000000 --- a/docs/content/learning-area/html/forms/native-form-widgets/single-line-text-fields.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Single line text field examples - - - -
    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - - -

    -

    - -

    -
    - - diff --git a/docs/content/learning-area/html/forms/number-example/index.html b/docs/content/learning-area/html/forms/number-example/index.html deleted file mode 100644 index bd235dc320..0000000000 --- a/docs/content/learning-area/html/forms/number-example/index.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - <input type="number"> example - - - - -
    -
    - - - -
    - -
    - -
    -
    - -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/postcard-example/background.jpg b/docs/content/learning-area/html/forms/postcard-example/background.jpg deleted file mode 100644 index 48a6a67bc5..0000000000 Binary files a/docs/content/learning-area/html/forms/postcard-example/background.jpg and /dev/null differ diff --git a/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff b/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff deleted file mode 100644 index 803f5133ea..0000000000 Binary files a/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff and /dev/null differ diff --git a/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff2 b/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff2 deleted file mode 100644 index 92f0e31003..0000000000 Binary files a/docs/content/learning-area/html/forms/postcard-example/fonts/journal-webfont.woff2 and /dev/null differ diff --git a/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff b/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff deleted file mode 100644 index 80e5501a5d..0000000000 Binary files a/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff and /dev/null differ diff --git a/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff2 b/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff2 deleted file mode 100644 index fae3bee07e..0000000000 Binary files a/docs/content/learning-area/html/forms/postcard-example/fonts/veteran_typewriter-webfont.woff2 and /dev/null differ diff --git a/docs/content/learning-area/html/forms/postcard-example/index.html b/docs/content/learning-area/html/forms/postcard-example/index.html deleted file mode 100644 index 0291f0dc26..0000000000 --- a/docs/content/learning-area/html/forms/postcard-example/index.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - Postcard example - - - - -
    -

    to: Mozilla

    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/postcard-example/postcard-start.html b/docs/content/learning-area/html/forms/postcard-example/postcard-start.html deleted file mode 100644 index d5c3358c63..0000000000 --- a/docs/content/learning-area/html/forms/postcard-example/postcard-start.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Postcard example - - - - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/basic-required-optional.html b/docs/content/learning-area/html/forms/pseudo-classes/basic-required-optional.html deleted file mode 100644 index 2df81a6d92..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/basic-required-optional.html +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Basic :required and :optional demo - - - - - -
    -
    - Feedback form -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/enabled-disabled-shipping.html b/docs/content/learning-area/html/forms/pseudo-classes/enabled-disabled-shipping.html deleted file mode 100644 index 85c3320a10..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/enabled-disabled-shipping.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - :enabled and :disabled demo — shipping form - - - - - -
    -
    - Shipping address -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    - Billing address -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/out-of-range.html b/docs/content/learning-area/html/forms/pseudo-classes/out-of-range.html deleted file mode 100644 index 71d7978105..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/out-of-range.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - - :out-of-range example - - - - - -
    -
    - Feedback form - -

    Required fields are labelled with "required".

    -
    - - - -
    -
    - - - -
    -
    - - - -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-default.html b/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-default.html deleted file mode 100644 index 6139228896..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-default.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Radio buttons :checked, :default - - - - - -
    -
    - Choose your favourite fruit - -

    - - - -

    -

    - - - -

    -

    - - - -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-indeterminate.html b/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-indeterminate.html deleted file mode 100644 index 284538e1e7..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/radios-checked-indeterminate.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - Radio buttons :checked, :indeterminate - - - - - -
    -
    - Choose your favourite fruit - -

    - - - -

    -

    - - - -

    -

    - - - -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/readonly-confirmation.html b/docs/content/learning-area/html/forms/pseudo-classes/readonly-confirmation.html deleted file mode 100644 index ccb62491da..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/readonly-confirmation.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - :read-only demo — confirmation form - - - - - -
    -
    - Check shipping details -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    - Final instructions -
    - - -
    -
    - - -
    -
    - -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/required-optional-generated.html b/docs/content/learning-area/html/forms/pseudo-classes/required-optional-generated.html deleted file mode 100644 index b0798903cb..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/required-optional-generated.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - :required and :optional with generated content - - - - - -
    -
    - Feedback form - -

    Required fields are labelled with "required".

    -
    - - - -
    -
    - - - -
    -
    - - - -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/user-valid-invalid.html b/docs/content/learning-area/html/forms/pseudo-classes/user-valid-invalid.html deleted file mode 100644 index 8b9b703e76..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/user-valid-invalid.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - :user-valid and :user-invalid example - - - - - -
    -
    - Feedback form - -

    Required fields are labelled with "required".

    -
    - - - -
    -
    - - - -
    -
    - - - -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/pseudo-classes/valid-invalid.html b/docs/content/learning-area/html/forms/pseudo-classes/valid-invalid.html deleted file mode 100644 index 240ef1331f..0000000000 --- a/docs/content/learning-area/html/forms/pseudo-classes/valid-invalid.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - :valid and :invalid example - - - - - -
    -
    - Feedback form - -

    Required fields are labelled with "required".

    -
    - - - -
    -
    - - - -
    -
    - - - -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/range-example/index.html b/docs/content/learning-area/html/forms/range-example/index.html deleted file mode 100644 index ea81341a3d..0000000000 --- a/docs/content/learning-area/html/forms/range-example/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - <input type="range"> example - - - - -
    -
    - - - -
    -
    - -
    -
    - - - diff --git a/docs/content/learning-area/html/forms/select-example/select-multiple.html b/docs/content/learning-area/html/forms/select-example/select-multiple.html deleted file mode 100644 index a80fd0a194..0000000000 --- a/docs/content/learning-area/html/forms/select-example/select-multiple.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - My test page - - - - - - - diff --git a/docs/content/learning-area/html/forms/sending-form-data/get-method.html b/docs/content/learning-area/html/forms/sending-form-data/get-method.html deleted file mode 100644 index 6685cda673..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/get-method.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Get method example - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/sending-form-data/php-example.html b/docs/content/learning-area/html/forms/sending-form-data/php-example.html deleted file mode 100644 index 29c8592cb5..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/php-example.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - PHP form submission example - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/sending-form-data/php-example.php b/docs/content/learning-area/html/forms/sending-form-data/php-example.php deleted file mode 100644 index 944b254178..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/php-example.php +++ /dev/null @@ -1,8 +0,0 @@ - - - - - Post method example - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/sending-form-data/python-example.py b/docs/content/learning-area/html/forms/sending-form-data/python-example.py deleted file mode 100644 index fdb25b600e..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/python-example.py +++ /dev/null @@ -1,21 +0,0 @@ -from flask import Flask -from flask import render_template -from flask import request - -app = Flask(__name__) - - -@app.route("/", methods=["GET", "POST"]) -def form(): - return render_template("form.html") - - -@app.route("/hello", methods=["GET", "POST"]) -def hello(): - return render_template("greeting.html", - say=request.form["say"], - to=request.form["to"]) - - -if __name__ == "__main__": - app.run() diff --git a/docs/content/learning-area/html/forms/sending-form-data/templates/form.html b/docs/content/learning-area/html/forms/sending-form-data/templates/form.html deleted file mode 100644 index 37c89352dc..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/templates/form.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Python form submission example - - - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - diff --git a/docs/content/learning-area/html/forms/sending-form-data/templates/greeting.html b/docs/content/learning-area/html/forms/sending-form-data/templates/greeting.html deleted file mode 100644 index cbee579495..0000000000 --- a/docs/content/learning-area/html/forms/sending-form-data/templates/greeting.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Greeting - - - -

    {{say}} {{to}}

    - - diff --git a/docs/content/learning-area/html/forms/styling-examples/appearence-tester.html b/docs/content/learning-area/html/forms/styling-examples/appearence-tester.html deleted file mode 100644 index 0c272580f6..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/appearence-tester.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - appearence tester - - - - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/styling-examples/checkboxes-styled.html b/docs/content/learning-area/html/forms/styling-examples/checkboxes-styled.html deleted file mode 100644 index 58e8ada52d..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/checkboxes-styled.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Checkboxes styled - - - - -
    -
    - Fruit preferences - -

    - -

    -

    - -

    -

    - -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/styling-examples/radios-styled.html b/docs/content/learning-area/html/forms/styling-examples/radios-styled.html deleted file mode 100644 index 0047690f0f..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/radios-styled.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Radio buttons styled - - - - -
    -
    - Choose your favourite fruit - -

    - -

    -

    - -

    -

    - -

    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/styling-examples/search-appearence.html b/docs/content/learning-area/html/forms/styling-examples/search-appearence.html deleted file mode 100644 index 9f317c9670..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/search-appearence.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - Search appearence - - - - -
    -
    -
    - - -
    -
    -
    -
    -
    -
    - - -
    -
    -
    - - diff --git a/docs/content/learning-area/html/forms/styling-examples/styled-file-picker.html b/docs/content/learning-area/html/forms/styling-examples/styled-file-picker.html deleted file mode 100644 index 00f4455124..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/styled-file-picker.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - Styled file picker example - - - - - -
    -
    - - -
      -
      -
      -
      - - - - diff --git a/docs/content/learning-area/html/forms/styling-examples/styled-search.html b/docs/content/learning-area/html/forms/styling-examples/styled-search.html deleted file mode 100644 index bc182f98d8..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/styled-search.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Styled search - - - - -
      -
      -
      - - -
      -
      -
      - - diff --git a/docs/content/learning-area/html/forms/styling-examples/ugly-controls.html b/docs/content/learning-area/html/forms/styling-examples/ugly-controls.html deleted file mode 100644 index c3e0922dba..0000000000 --- a/docs/content/learning-area/html/forms/styling-examples/ugly-controls.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Ugly controls basic styling - - - - - -
      -
      - -
      - -
      -
      -
      - - - - - - - - - - - - -
      -
      - - -
      -
      - - -
      -
      - - -
      -
      - - -
        -
        -
        - - 75/100 -
        -
        - - 75 -
        -
        -
        - - - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling-download.html b/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling-download.html deleted file mode 100644 index 879aa972d9..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling-download.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Advanced styling: Task 1 - - - - -
        - -
        -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling.html b/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling.html deleted file mode 100644 index 895ea1dc78..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Advanced styling: Task 1 - - - - - - - -
        - - - - - -
        - -
        - - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2-download.html b/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2-download.html deleted file mode 100644 index 4374e3649d..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2-download.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Advanced styling: Task 2 - - - - -
        -
        - Who is your favorite pony? -
          -
        • - - -
        • -
        • - - -
        • -
        • - - -
        • -
        -
        -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2.html b/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2.html deleted file mode 100644 index b1e6539c47..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling2.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - Advanced styling: Task 2 - - - - - - - -
        - - - - - -
        - -
        - - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling3-download.html b/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling3-download.html deleted file mode 100644 index 7e7015bf37..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/advanced-styling3-download.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - - Advanced styling: Task 3 - - - - -
        -
        - Feedback form - -

        Required fields are labelled with "required".

        -
        - - - -
        -
        - - - -
        -
        - - - -
        -
        -
        -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/marking.md b/docs/content/learning-area/html/forms/tasks/advanced-styling/marking.md deleted file mode 100644 index 1659e9d08d..0000000000 --- a/docs/content/learning-area/html/forms/tasks/advanced-styling/marking.md +++ /dev/null @@ -1,249 +0,0 @@ -# Advanced form styling marking guide - -The aim of the tasks is to demonstrate an understanding of the features covered in the [Advanced form styling](https://wiki.developer.mozilla.org/en-US/docs/Learn/Forms/Advanced_form_styling) and [UI pseudo-classes](https://wiki.developer.mozilla.org/en-US/docs/Learn/Forms/UI_pseudo-classes) lessons in Learn Web Development on MDN. - -## Task 1 - -In our first advanced styling tasks, we want you to handle making a search input as consistent as possible across browsers — a trickier task than with standard text inputs, even on modern browsers. - -We've already provided you with a basic reset to build upon. - -1. First of all, try giving the search box a consistent width, height, padding, and border color across browsers. This is pretty self-explanatory; `line-height` tends to work better than `height` for keeping a consistent height in which the input text is vertically-centered. -2. You'll find that some browsers will not behave in terms of the form element's height. This is due to native OS styling being used in some cases. How can you remove this native styling? The answer here is `-webkit-appearance: none;`. -3. Once you've removed the native styling, you'll need to add back one of the features it was providing, to keep same look and feel we originally had. How do you do this? Answer: rounded corners! We need `border-radius`. -4. One thing that is inconsistent across browsers (particularly looking at Safari here) is the position of the standard blue focus outline. How can you remove this? Answer: `outline: none;` -5. There is a major problem with just getting rid of the blue focus outline. What is it? Can you add some kind of styling back in so that users can tell when the search box is being hovered or focused? Answer: Use some kind of styling applied to the input using the `:hover` and `:focus` pseudo-classes. -6. Another thing that commonly denotes a search box is a magnifying glass icon. We've made one available in the same directory as `search-24px.png`, plus a `
        ` element after the search input to help you attach it, should you need it. Can you figure out a sensible way to attach it, and can you use some CSS to get it to sit to the right of the search box, and be lined up vertically as well? Answer: There are many ways to do this, but the easiest is probably to make it a background image of the `
        `, and then use flexbox to line it up. - -The finished CSS could look something like this: - -``` -body { - background-color: #fff; - color: #333; - font: 1em / 1.4 Helvetica Neue, Helvetica, Arial, sans-serif; - padding: 1em; - margin: 0; -} - -* { - box-sizing: border-box; -} - -button, -input, -select { - font-family: inherit; - font-size: 100%; - padding: 0; margin: 0; -} - -input[type="search"] { - line-height: 1.5rem; - padding: 5px; - border: 2px solid #ccc; - width: 200px; - - -webkit-appearance: none; - border-radius: 6px; - - outline: none; -} - -input[type="search"]:hover, input[type="search"]:focus { - border: 2px solid red; - box-shadow: 1px 1px 1px gray; -} - -div { - width: 36px; - height: 24px; - background: url(search-24px.png) no-repeat center; - background-size: 18px; -} - -form { - display: flex; - align-items: center; -} -``` - -## Task 2 - -In our next task we provide you with a set of three radio buttons. We want you to give them custom styling. - -We've already provided you with a basic reset to build upon. - -1. First of all, get rid of their default styling. Again, `-webkit-appearance: none;` is what you need here. -2. Next, give the radio buttons a reasonable base style — the style they have when the page first loads. This can be anything you like, but you probably want to set a width and height (of somewhere between about 18 and 24 pixels), and a subtle border and/or background color. -3. Now give the radio buttons a different style for when they are selected. You'll need to use the `:checked` pseudo-class for selecting when the radio button is selected. If you want to do something a bit more fancy, you can also use a combination of `:checked` and `::before` or `::after` to use some generated content to provide a central glyph, or image. You'd need to use absolute positioning on the generated content and relative positioning on the radio button to help line things up. Bear in mind that using an actual text character is a pain to align, so using a background image would be more successful. -4. Align the radio buttons nicely with the labels. A simple bit of flexbox would work nicely here as well. - -The finished CSS could look something like this: - -``` -body { - background-color: #fff; - color: #333; - font: 1em / 1.4 Helvetica Neue, Helvetica, Arial, sans-serif; - padding: 1em; - margin: 0; -} - -* { - box-sizing: border-box; -} - -button, -input, -select { - font-family: inherit; - font-size: 100%; - padding: 0; margin: 0; -} - -input[type="radio"] { - -webkit-appearance: none; - - height: 24px; - width: 24px; - border: 2px solid #ccc; -} - -input[type="radio"]:checked { - border: 2px solid red; - position: relative; -} - -input[type="radio"]:checked::before { - content: ''; - background-color: red; - width: 12px; - height: 12px; - position: absolute; - top: 4px; - left: 4px; -} - -li { - display: flex; - align-items: center; - margin-bottom: 10px; -} - -label { - width: 150px; - margin-right: 10px; -} -``` - -## Task 3 - -In our final task for this assessment series, we provide you with a feedback form that is already nicely-styled — you've already seen something similar if you've worked through our UI pseudo-classes article, and now we want you to come up with your own solution. - -What we'd like you to do is make use of some advanced pseudo-classes to provide some useful indicators of validity. - -1. First of all, we want you to provide some specific styling to visually indicate which inputs have to be filled in — they cannot be left empty. The basis of doing this is use of the `:required` pseudo-class. Apart from that, you can use whatever styling you like, as long as it reasonably indicates what inputs are reuired. In our case, we've used `:required` plus an adjacent combinator to attach some generated content to the `` that appears after the input, but the provided solution doesn't have to be this complex. -2. Second, we want you to provide a useful visual indicator of whether the data entered inside each input is valid or not. This requires use of the `:valid` and `:invalid` pseudo-classes. Again, any reasonable solution is OK here, and attaching something to the trailing `` in each case remains an option. - -The finished CSS could look something like this: - -``` -body { - background-color: #fff; - color: #333; - font: 1em / 1.4 Helvetica Neue, Helvetica, Arial, sans-serif; - padding: 1em; - margin: 0; -} - -* { - box-sizing: border-box; -} - -button, -input, -select { - font-family: inherit; - font-size: 100%; - padding: 0; margin: 0; -} - -fieldset { - padding: 10px 30px 0; - width: 400px; -} - -legend { - color: white; - background: black; - padding: 5px 10px; -} - -fieldset > div { - margin-bottom: 20px; - display: flex; - flex-flow: row wrap; -} - -button, label, input { - display: block; - font-family: inherit; - font-size: 100%; - padding: 0; - margin: 0; - box-sizing: border-box; - width: 100%; - padding: 5px; - height: 30px; -} - -input { - box-shadow: inset 1px 1px 3px #ccc; - border-radius: 5px; -} - -input:hover, input:focus { - background-color: #eee; -} - -button { - width: 60%; - margin: 0 auto; -} - -input + span { - position: relative; -} - -input:required + span::after { - font-size: 0.7rem; - position: absolute; - content: "required"; - color: white; - background-color: black; - padding: 5px 10px; - top: -26px; - left: -70px; -} - -input + span::before { - position: absolute; - right: -20px; - top: 5px; -} - -input:invalid { - border: 2px solid red; -} - -input:invalid + span::before { - content: '✖'; - color: red; -} - -input:valid + span::before { - content: '✓'; - color: green; -} -``` diff --git a/docs/content/learning-area/html/forms/tasks/advanced-styling/search-24px.png b/docs/content/learning-area/html/forms/tasks/advanced-styling/search-24px.png deleted file mode 100644 index d8d63df714..0000000000 Binary files a/docs/content/learning-area/html/forms/tasks/advanced-styling/search-24px.png and /dev/null differ diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls-download.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls-download.html deleted file mode 100644 index 66cb98ccd1..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls-download.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Basic controls: Task 1 - - - - -
        -
          -
        • User ID
        • -
        • Password
        • -
        • -
        -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls.html deleted file mode 100644 index 93cace5556..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Basic controls: Task 1 - - - - - - - -
        - - - - - -
        - -
        - - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2-download.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2-download.html deleted file mode 100644 index b438bb3030..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2-download.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - Basic controls: Task 2 - - - - -
        -
        - Who is your favorite pony? -
          -
        • - -
        • -
        • - -
        • -
        • - -
        • -
        -
        -
        - Hotdog preferences -
          -
        • - -
        • -
        • - -
        • -
        -
        - -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2.html deleted file mode 100644 index b70d9f30a7..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls2.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Basic controls: Task 2 - - - - - - - -
        - - - - - -
        - -
        - - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3-download.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3-download.html deleted file mode 100644 index bfabf9a55e..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3-download.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - Basic controls: Task 3 - - - - -
        -
          -
        • - -
        • -
        - -
        - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3.html b/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3.html deleted file mode 100644 index e0814406f8..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/basic-controls3.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - Basic controls: Task 3 - - - - - - - -
        - - - - - -
        - -
        - - - diff --git a/docs/content/learning-area/html/forms/tasks/basic-controls/marking.md b/docs/content/learning-area/html/forms/tasks/basic-controls/marking.md deleted file mode 100644 index 0aa8c5eb0b..0000000000 --- a/docs/content/learning-area/html/forms/tasks/basic-controls/marking.md +++ /dev/null @@ -1,111 +0,0 @@ -# Basic controls marking guide - -The aim of the tasks is to demonstrate an understanding of the features covered in the [Basic native form controls](https://developer.mozilla.org/en-US/docs/Learn/Forms/Basic_native_form_controls) lesson in Learn Web Development on MDN. - -## Task 1 - -This task starts you off nice and gently by asking you to create two input elements, for a user's ID and password, along with a submit button. - -1. Create appropriate inputs for user ID and password — you need to use appropriate `` elements, with `type`s of `text` and `password` respectively. They should also have `id`s and `name`s. -2. You should also associate them with their text labels semantically — use `
      • -
      • - -
      • - - -``` - -## Task 2 - -Now it's time to have a go at implementing a drop-down select menu, to allow a user to pick their favourite food from the choices provided. - -1. Create your basic select box structure. You should use a ``. -3. Inside the list, split the choices up into 2 subgroups — "mains" and "snacks". To do this, you should use `` elements inside the main ` - - - - - - - - - - - - - - -
      • - -
      • - - -``` - -## Task 3 - -In our final task of this set, we start with much the same list of food choices. However, this time we want to do things differently: - -1. Create a basic text input that is semantically associated with the provided label. This is done as you'd expect — use a simple `` with an `id` that maches the label's `for` value. -2. Put the food choices into a list that can be associated with a form input. For this, you need to wrap each option in an `
        + +
        +

        Documentation Commands:

        +

        documentation build src/components/DocsMenu.js -f md> ./notes/DocsMenu.md +documentation build src/components/Footer.js -f md> ./notes/Footer.md +documentation build src/components/Header.js -f md> ./notes/Header.md +documentation build src/components/index.js -f md> ./notes/index.md +documentation build src/components/SectionContent.js -f md> ./notes/SectionContent.md +documentation build src/components/SectionDocs.js -f md> ./notes/SectionDocs.md +documentation build src/components/SectionHero.js -f md> ./notes/SectionHero.md +documentation build src/components/CtaButtons.js -f md> ./notes/CtaButtons.md +documentation build src/components/DocsSubmenu.js -f md> ./notes/DocsSubmenu.md +documentation build src/components/FormField.js -f md> ./notes/FormField.md +documentation build src/components/Icon.js -f md> ./notes/Icon.md +documentation build src/components/Layout.js -f md> ./notes/Layout.md +documentation build src/components/SectionCta.js -f md> ./notes/SectionCta.md +documentation build src/components/SectionGrid.js -f md> ./notes/SectionGrid.md +documentation build src/components/Submenu.js -f md> ./notes/Submenu.md

        + + +

        Blog Content

        +

        :

        +
        +
        +

        Bash Cheat Sheet (MY COMMANDS

        +

        )

        +

        +

        Bash Cheat Sheet (MY COMMANDS) </summary

        +
        +

        1. Remove spaces from file and folder names and then remove numbers from files and folder names

        +

        Description: need to : sudo apt install rename

        +
        +

        Notes: Issue when renaming file without numbers collides with existing file name...

        +
        +
        code
        +
        find . -name "* *" -type d | rename 's/ /_/g'
        +find . -name "* *" -type f | rename 's/ /_/g'
        +
        +
        ```bash
        +>>>>>>> master
         find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh
        -
         find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh
        -
        -for i in *.html; do mv "$i" "${i%-*}.html"; done
        -
        -for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done
        -
        +for i in*.html; do mv "$i" "${i%-*}.html"; done
        +for i in*.*; do mv "$i" "${i%-*}.${i##*.}"; done
         ---
         ### Description: combine the contents of every file in the contaning directory.
        +<<<<<<< HEAD
         
         
         >Notes: this includes the contents of the file it's self...
        @@ -204,15 +683,24 @@ 

        code

        #### code: +======= +>Notes: this includes the contents of the file it's self... +###### code: +>>>>>>> master ```js //APPEND-DIR.js const fs = require('fs'); let cat = require('child_process') +<<<<<<< HEAD .execSync('cat *') +======= +.execSync('cat*') +>>>>>>> master .toString('UTF-8'); fs.writeFile('output.md', cat, err => { if (err) throw err; }); +<<<<<<< HEAD
        @@ -262,27 +750,77 @@

        Generalized

        CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 +======= +
        +
        +
        +

        2. Download Website Using Wget

        +

        Description

        +
        +

        Notes: ==> sudo apt install wget

        +
        +
        code
        +
        wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/
        +
        +
        +
        +

        3. Clean Out Messy Git Repo

        +
        +
        +

        Notes: To clear up clutter in repositories that only get used on your local machine.

        +
        +
        code
        +
        find . -empty -type d -print -delete
        +find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} +
        +find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o  -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o  -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} +
        +
        +
        +
        +

        4. clone all of a user's git repositories

        +

        Description: clone all of a user or organization's git repositories

        +
        +

        Notes:

        +
        +
        code
        +
        +

        Generalized

        +
        CNTX={users|orgs}; NAME={username|orgname}; PAGE=1
        +>>>>>>> master
         curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" |
           grep -e 'git_url*' |
           cut -d \" -f 4 |
           xargs -L1 git clone
         
        +<<<<<<< HEAD

        Clone all Git User

        CNTX={users}; NAME={bgoonz}; PAGE=1
        +=======
        +
        +

        Clone all Git User

        +
        CNTX={users}; NAME={bgoonz}; PAGE=1
        +>>>>>>> master
         curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master |
           grep -e 'git_url*' |
           cut -d \" -f 4 |
           xargs -L1 git clone
        +<<<<<<< HEAD
         
         
         

        Clone all Git Organization

        
         CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1
        +=======
        +
        +
        +

        Clone all Git Organization

        +
        CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1
        +>>>>>>> master
         curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master |
           grep -e 'git_url*' |
           cut -d \" -f 4 |
           xargs -L1 git clone
        +<<<<<<< HEAD
         
         
         
        @@ -291,6 +829,15 @@

        5. Git Workflow

        Description

        code
        git pull
        +=======
        +
        +
        +
        +

        5. Git Workflow

        +

        Description

        +
        code
        +
        git pull
        +>>>>>>> master
         git init
         git add .
         git commit -m"update"
        @@ -301,8 +848,12 @@ 
        code
        git commit -m"update" git push -u origin main
        +<<<<<<< HEAD
        
         git init
        +=======
        +
        git init
        +>>>>>>> master
         git add .
         git commit -m"update"
         git push -u origin bryan-guner
        @@ -317,6 +868,7 @@ 
        code
        git commit -m"update" git push -u origin preview
        +<<<<<<< HEAD

        6. Recursive Unzip In Place

        Description: @@ -330,9 +882,20 @@

        code
        +======= +
        +
        +

        6. Recursive Unzip In Place

        +

        Description: recursively unzips folders and then deletes the zip file by the same name

        +
        +

        Notes:

        +
        +
        code
        +
        find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;
        +>>>>>>> master
         find . -name "*.zip" -type f -print -delete
        -
         
        +<<<<<<< HEAD

        7. git pull keeping local changes

        Description

        @@ -391,6 +954,52 @@

        Description

        code
        sudo apt install tree
        +=======
        +
        +
        +

        7. git pull keeping local changes

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        git stash
        +git pull
        +git stash pop
        +
        +
        +
        +

        8. Prettier Code Formatter

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        sudo npm i prettier -g
        +prettier --write .
        +
        +
        +
        +

        9. Pandoc

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \;
        +find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \;
        +find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \;
        +
        +
        +
        +

        10. Gitpod Installs

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        sudo apt install tree
        +>>>>>>> master
         sudo apt install pandoc -y
         sudo apt install rename -y
         sudo apt install black -y
        @@ -398,6 +1007,7 @@ 
        code
        npm i lebab -g npm i prettier -g npm i npm-recursive-install -g +<<<<<<< HEAD
        @@ -425,20 +1035,45 @@

        Description

        code
        tree -d -I  'node_modules'
         
        +=======
        +
        +
        black .
        +prettier --write .
        +npm-recursive-install
        +
        +
        +
        +

        11. Repo Utils Package

        +

        Description: my standard repo utis package

        +
        +

        Notes:

        +
        +
        code
        +
        npm i @bgoonz11/repoutils
        +
        +
        +
        +

        12. Unix Tree Package Usage

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        tree -d -I  'node_modules'
        +>>>>>>> master
         tree  -I  'node_modules'
        -
         tree -f  -I  'node_modules' >TREE.md
        -
         tree -f -L 2  >README.md
        -
         tree -f  -I  'node_modules' >listing-path.md
        +<<<<<<< HEAD
         
         
        +=======
        +>>>>>>> master
         tree -f  -I  'node_modules' -d >TREE.md
        -
         tree -f >README.md
        -
         
        +<<<<<<< HEAD

        13. Find & Replace string in file & folder names recursively

        @@ -483,32 +1118,62 @@
        code
        #!/bin/bash
         
         for file in *.md.md
        +=======
        +
        +
        +

        13. Find & Replace string in file & folder names recursively

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find . -type f -exec rename 's/string1/string2/g' {} +
        +find . -type d -exec rename 's/-master//g' {} +
        +find . -type f -exec rename 's/\.download//g' {} +
        +find . -type d -exec rename 's/-main//g' {} +
        +rename 's/\.js\.download$/.js/'*.js\.download
        +rename 's/\.html\.markdown$/.md/' *.html\.markdown
        +find . -type d -exec rename 's/es6//g' {} +
        +
        +
        +
        +

        14. Remove double extensions

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        # !/bin/bash
        +for file in*.md.md
        +>>>>>>> master
         do
             mv "${file}" "${file%.md}"
         done
        -
        -#!/bin/bash
        -
        +# !/bin/bash
         for file in *.html.html
         do
             mv "${file}" "${file%.html}"
         done
         
        +<<<<<<< HEAD
        
         
         #!/bin/bash
         
         for file in *.html.png
        +=======
        +
        # !/bin/bash
        +for file in*.html.png
        +>>>>>>> master
         do
             mv "${file}" "${file%.png}"
         done
        -
         for file in *.jpg.jpg
         do
             mv "${file}" "${file%.png}"
         done
        -
         
        +<<<<<<< HEAD

        15. Truncate folder names down to 12 characters

        Description

        @@ -529,12 +1194,34 @@

        code

        //APPEND-DIR.js
        +=======
        +
        +
        +

        15. Truncate folder names down to 12 characters

        +

        Description: Truncate folder names down to 12 characters

        +
        +

        Notes: Truncate folder names down to 12 characters

        +
        +
        code
        +
        for d in ./*; do mv $d ${d:0:12}; done
        +
        +
        +
        +

        16.Appendir.js

        +

        Description: combine the contents of every file in the contaning directory

        +
        +

        Notes: this includes the contents of the file it's self...

        +
        +
        code
        +
        //APPEND-DIR.js
        +>>>>>>> master
         const fs = require('fs');
         let cat = require('child_process').execSync('cat *').toString('UTF-8');
         fs.writeFile('output.md', cat, (err) => {
             if (err) throw err;
         });
         
        +<<<<<<< HEAD

        17. Replace space in filename with underscore

        Description: followed by replace @@ -545,9 +1232,20 @@

        Description: f

        code
        find . -name "* *" -type f | rename 's/_//g'
         
        +=======
        +
        +
        +

        17. Replace space in filename with underscore

        +

        Description: followed by replace '#' with '_' in directory name

        +
        +

        Notes: Can be re-purposed to find and replace any set of strings in file or folder names.

        +
        +
        code
        +
        find . -name "* *" -type f | rename 's/_//g'
        +>>>>>>> master
         find . -name "* *" -type d | rename 's/#/_/g'
        -
         
        +<<<<<<< HEAD

        18. Filter & delete files by name and extension

        Description

        @@ -557,19 +1255,25 @@

        Description

        code
        find . -name '.bin' -type d -prune -exec rm -rf '{}' +
         
        +=======
        +
        +
        +

        18. Filter & delete files by name and extension

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find . -name '.bin' -type d -prune -exec rm -rf '{}' +
        +>>>>>>> master
         find . -name '*.html' -type d -prune -exec rm -rf '{}' +
        -
         find . -name 'nav-index' -type d -prune -exec rm -rf '{}' +
        -
         find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' +
        -
         find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' +
        -
         find . -name 'right.html' -type f -prune -exec rm -rf '{}' +
        -
         find . -name 'left.html' -type f -prune -exec rm -rf '{}' +
        -
         
        +<<<<<<< HEAD

        19. Remove lines containing string

        Description

        @@ -592,9 +1296,24 @@
        code
        sudo sed -i '/github\.com/d' ./*out.md +======= +
        +
        +

        19. Remove lines containing string

        +

        Description

        +
        +

        Notes: Remove lines not containing '.js'

        +
        sudo sed -i '/\.js/!d' ./*scrap2.md
        +
        +
        +
        code
        +
        sudo sed -i '/githubusercontent/d' ./*sandbox.md
        +sudo sed -i '/githubusercontent/d' ./*scrap2.md
        +sudo sed -i '/github\.com/d' ./*out.md
        +>>>>>>> master
         sudo sed -i '/author/d' ./*
        -
         
        +<<<<<<< HEAD

        20. Remove duplicate lines from a text file

        Description

        @@ -611,9 +1330,24 @@

        Description

        kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq.

        code
        sudo apt install uniq
        +=======
        +
        +
        +

        20. Remove duplicate lines from a text file

        +

        Description

        +
        +

        Notes: +//...syntax of uniq...// +$uniq [OPTION] [INPUT[OUTPUT]] +The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn't specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn't specified then uniq writes to the standard output. +Now, let's understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq.

        +
        +
        code
        +
        sudo apt install uniq
        +>>>>>>> master
         uniq -u input.txt output.txt
        -
         
        +<<<<<<< HEAD

        21. Remove lines containing string

        Description

        @@ -627,27 +1361,40 @@
        code
        sudo sed -i '/githubusercontent/d' ./*scrap2.md +======= +
        +
        +

        21. Remove lines containing string

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        sudo sed -i '/githubusercontent/d' ./*sandbox.md
        +sudo sed -i '/githubusercontent/d' ./*scrap2.md
        +>>>>>>> master
         sudo sed -i '/github\.com/d' ./*out.md
        -
         ---
         title: add_days
         tags: date,intermediate
         firstSeen: 2020-10-28T16:19:04+02:00
         lastUpdated: 2020-10-28T16:19:04+02:00
         ---
        -
         sudo sed -i '/title:/d' ./*output.md
         sudo sed -i '/firstSeen/d' ./*output.md
         sudo sed -i '/lastUpdated/d' ./*output.md
         sudo sed -i '/tags:/d' ./*output.md
        -
         sudo sed -i '/badstring/d' ./*
        +<<<<<<< HEAD
         
         
        +=======
        +>>>>>>> master
         sudo sed -i '/stargazers/d' ./repo.txt
         sudo sed -i '/node_modules/d' ./index.html
         sudo sed -i '/right\.html/d' ./index.html
         sudo sed -i '/right\.html/d' ./right.html
        +<<<<<<< HEAD
         
         
         
        @@ -685,10 +1432,49 @@ 

        Description

        code
        find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh
        +=======
        +
        +
        +
        +

        22. Zip directory excluding .git and node_modules all the way down (Linux

        +

        )

        +

        Descriptio: zip up an entire git directory

        +
        +

        Notes:

        +
        +
        code
        +

        `bash

        +

        !/bin/bash

        +

        TSTAMP=date '+%Y%m%d-%H%M%S' +zip -r $1.$TSTAMP.zip $1 -x ".git/*" -x "node_modules/*" shift; echo $@; +printf "\nCreated: $1.$TSTAMP.zip\n"

        +
        +

        usage

        +

        :

        +
        +

        - zipdir thedir

        +
        +

        - zip thedir -x "anotherexcludedsubdir" (important the double quotes to prevent glob expansion

        +

        )

        +
        +

        if in windows/git-bash, add 'zip' command this way

        +

        :

        +
        +

        https://stackoverflow.com/a/55749636/1482990

        +

        `

        +
        +

        23. Delete files containing a certain string

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh
        +>>>>>>> master
         vi doit.sh // check for murphy and his law
         source doit.sh
        -
         
        +<<<<<<< HEAD

        24

        Description

        @@ -728,6 +1514,38 @@
        code
        echo '<style>' +======= +
        +
        +

        24 Generate sitemap

        +

        Description

        +
        +

        Notes: bash command to auto generate sitemap.html which will list all files contained within parent directory.

        +
        +
        code
        +

        `bash

        +

        !/bin/sh

        +
        +

        find ./ | grep -i "\.*$" >files

        +

        find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i ".*$">files +listing="files" +out="" +html="index.html" +out="basename $out.html" +html="index.html" +cmd() { + echo ' <!DOCTYPE html>' + echo '' + echo '' + echo ' ' + echo ' ' + echo '' + echo ' ' + echo ' ' + echo " directory " + echo "" + echo '' + echo '' + echo '' + echo ""

        +

        continue with the HTML stuff

        +

        echo "" + echo "" + echo "

          " + awk '{print "<iframe src=\""$1"\">",""}' $listing

          +

          awk '{print "
        • "};
        • +

          {print " <a href=\""$1"\">",$1," "}' \ $listing

          +

          echo "" + echo "

        " + echo "" + echo "" +} +cmd $listing --sort=extension >>$html

        +

        `

        +
        +

        25. Index of Iframes

        +

        Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags

        +
        +

        Notes: Useful Follow up Code:

        +
        
        +
        +
        +
        code
        +

        `bash

        +

        !/bin/sh

        +
        +

        26. Filter Corrupted Git Repo For Troublesome File

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD
        +
        +
        +
        +

        27. OVERWRITE LOCAL CHANGES

        +

        Description

        +

        Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] +If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected.

        +
        +

        Notes: +First, run a fetch to update all origin/ refs to latest:

        +
        +
        code
        +

        `bash +git fetch --all

        +
        +

        Backup your current branch

        +

        : +git branch backup-master

        +
        +

        Then, you have two options

        +

        : +git reset --hard origin/master

        +
        +

        OR If you are on some other branch

        +

        : +git reset --hard origin/<branch_name>

        +
        +

        Explanation

        +

        :

        +
        +

        git fetch downloads the latest from remote without trying to merge or rebase anything

        +

        .

        +
        +

        Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master

        +

        git fetch --all +git reset --hard origin/master

        +

        `

        +
        +

        28. Remove Submodules

        +

        Description: To remove a submodule you need to

        +
        +

        Notes: +Delete the relevant section from the .gitmodules file. +Stage the .gitmodules changes git add .gitmodules +Delete the relevant section from .git/config. +Run git rm --cached path_to_submodule (no trailing slash). +Run rm -rf .git/modules/path_to_submodule (no trailing slash). +Commit git commit -m "Removed submodule " +Delete the now untracked submodule files rm -rf path_to_submodule

        +
        +
        code
        +
        git submodule deinit
        +
        +
        +
        +

        29. GET GISTS

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        sudo apt install wget
        +wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget
        +wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget
        +>>>>>>> master
         wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget
        -
         wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget
        +<<<<<<< HEAD
         
         
         
        @@ -1037,6 +1959,51 @@

        Description: ES5 --> ES6

        code
        # Safe:
         
        +=======
        +
        +
        +
        +

        30. Remove Remote OriginL

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        git remote remove origin
        +
        +
        +
        +

        31. just clone .git folder

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git
        +
        +
        +
        +

        32. Undo recent pull request

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        git reset --hard master@{"10 minutes ago"}
        +
        +
        +
        +

        33. Lebab

        +

        Description: ES5 --> ES6

        +
        +

        Notes:

        +
        +
        code
        +

        `bash

        +
        +

        Safe

        +

        : +>>>>>>> master lebab --replace ./ --transform arrow lebab --replace ./ --transform arrow-return lebab --replace ./ --transform for-of @@ -1045,12 +2012,19 @@

        code
        lebab --replace ./ --transform arg-spread lebab --replace ./ --transform obj-method lebab --replace ./ --transform obj-shorthand +<<<<<<< HEAD lebab --replace ./ --transform multi-var # ALL: +======= + lebab --replace ./ --transform multi-var

        +
        +

        ALL

        +

        : +>>>>>>> master lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow @@ -1079,6 +2053,7 @@

        code
        lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param +<<<<<<< HEAD lebab --replace ./ --transform includes @@ -1125,9 +2100,44 @@
        code
        +======= +lebab --replace ./ --transform includes

        +

        `

        +
        +

        34. Troubleshoot Ubuntu Input/Output Error

        +

        Description: Open Powershell as Administrator

        +
        +

        Notes:

        +
        +
        code
        +
         wsl.exe --shutdown
        + Get-Service LxssManager | Restart-Service
        +
        +
        +
        +

        35. Export Medium as Markdown

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        npm i mediumexporter -g
        +mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md
        +
        +
        +
        +

        36. Delete files in violation of a given size range (100MB for git

        +

        )

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find . -size +75M -a -print -a -exec rm -f {} \;
        +>>>>>>> master
         find . -size +98M -a -print -a -exec rm -f {} \;
        -
         
        +<<<<<<< HEAD

        37. download all links of given file type

        Description

        @@ -1163,9 +2173,37 @@
        code
        +======= +
        +
        + +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        wget -r -A.pdf https://overapi.com/git
        +
        +
        +
        +

        38. Kill all node processes

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        killall -s KILL node
        +
        +
        +
        +

        39. Remove string from file names recursively

        +

        Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories

        +
        code
        +
        find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
        +>>>>>>> master
         find . -type f -exec rename 's/-master//g' {} +
        -
         
        +<<<<<<< HEAD

        Notes: The same could be done for folder names by changing the -type f flag (for file) to a -type d flag (for directory)

        @@ -1212,17 +2250,53 @@

        Description

        code
        
         PARAM (
        +=======
        +
        +

        Notes: The same could be done for folder names by changing the-type fflag (for file) to a-type dflag (for directory) +`bash +find -type d -exec sed -i 's///g' {} + +find . -type d -exec rename 's/-master//g' {} +

        +
        +

        `

        +
        +

        40. Remove spaces from file and folder names recursively

        +

        Description: replaces spaces in file and folder names with an _ underscore

        +
        +

        Notes: need to run sudo apt install rename to use this command

        +
        +
        code
        +
        find . -name "* *" -type d | rename 's/ /_/g'
        +find . -name "* *" -type f | rename 's/ /_/g'
        +
        +
        +
        +

        41. Zip Each subdirectories in a given directory into their own zip file

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        for i in*/; do zip -r "${i%/}.zip" "$i"; done
        +
        +
        +
        +

        91. Unzip PowerShell

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        PARAM (
        +>>>>>>> master
             [string] $ZipFilesPath = "./",
             [string] $UnzipPath = "./RESULT"
         )
        -
         $Shell = New-Object -com Shell.Application
         $Location = $Shell.NameSpace($UnzipPath)
        -
         $ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP
        -
         $progress = 1
         foreach ($ZipFile in $ZipFiles) {
        +<<<<<<< HEAD
             Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)"
             $ZipFolder = $Shell.NameSpace($ZipFile.fullname)
         
        @@ -1253,9 +2327,36 @@ 
        code
        
         ln -s "$(pwd)" ~/NameOfLink
         
        +=======
        +Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1))* 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)"
        +    $ZipFolder = $Shell.NameSpace($ZipFile.fullname)
        +    $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - https://msdn.microsoft.com/library/bb787866%28VS.85%29.aspx
        +    $progress++
        +}
        +
        +
        +
        +

        92. return to bash from zsh

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
         sudo apt --purge remove zsh
        +
        +
        +
        + +

        Description: to working directory

        +
        +

        Notes:

        +
        +
        code
        +
        ln -s "$(pwd)" ~/NameOfLink
        +>>>>>>> master
         ln -s "$(pwd)" ~/Downloads
        -
         
        +<<<<<<< HEAD

        94. auto generate readme

        Description: rename existing readme to @@ -2451,6 +3552,1186 @@

        🧐 What's inside

        ├── package-lock.json ├── package.json └── README.md +======= +
        +
        +

        94. auto generate readme

        +

        Description: rename existing readme to blueprint.md

        +
        +

        Notes:

        +
        +
        code
        +
        npx @appnest/readme generate
        +
        +
        +
        +

        95. Log into postgres

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        sudo -u postgres psql
        +
        +
        +
        +

        96. URL To Subscribe To YouTube Channel

        +
        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1
        +
        +
        +
        +

        97. Embed Repl.it In Medium Post

        +
        code
        +
        https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com
        +https://repl.it/@bgoonz/node-db1-project?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com
        +https://repl.it/@bgoonz/interview-prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com
        +https://repl.it/@bgoonz/Database-Prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com
        +
        +
        +
        +

        98 rRmove text target="parent" from files called right.html

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +
        find . -name *right.html  -type f -exec sed -i 's/target="_parent"//g' {} +
        +find . -name*right.html  -type f -exec sed -i 's/target="_parent"//g' {} +
        +
        +
        +

        99. Cheat Sheet

        +

        Description

        +
        +

        Notes:

        +
        +
        code
        +

        `bash

        +

        !/bin/bash

        +

        revert

        +
        +

        SHORTCUTS and HISTORY

        +

        CTRL+A # move to beginning of line +CTRL+B # moves backward one character +CTRL+C # halts the current command +CTRL+D # deletes one character backward or logs out of current session, similar to exit +CTRL+E # moves to end of line +CTRL+F # moves forward one character +CTRL+G # aborts the current editing command and ring the terminal bell +CTRL+H # deletes one character under cursor (same as DELETE) +CTRL+J # same as RETURN +CTRL+K # deletes (kill) forward to end of line +CTRL+L # clears screen and redisplay the line +CTRL+M # same as RETURN +CTRL+N # next line in command history +CTRL+O # same as RETURN, then displays next line in history file +CTRL+P # previous line in command history +CTRL+Q # resumes suspended shell output +CTRL+R # searches backward +CTRL+S # searches forward or suspends shell output +CTRL+T # transposes two characters +CTRL+U # kills backward from point to the beginning of line +CTRL+V # makes the next character typed verbatim +CTRL+W # kills the word behind the cursor +CTRL+X # lists the possible filename completions of the current word +CTRL+Y # retrieves (yank) last item killed +CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background +ALT+B # moves backward one word +ALT+D # deletes next word +ALT+F # moves forward one word +ALT+H # deletes one character backward +ALT+T # transposes two words +ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. +ALT+U # capitalizes every character from the current cursor position to the end of the word +ALT+L # uncapitalizes every character from the current cursor position to the end of the word +ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. +ALT+R # reverts any changes to a command you've pulled from your history if you've edited it. +ALT+? # list possible completions to what is typed +ALT+^ # expand line to most recent match from history +CTRL+X then ( # start recording a keyboard macro +CTRL+X then ) # finish recording keyboard macro +CTRL+X then E # recall last recorded keyboard macro +CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands +BACKSPACE # deletes one character backward +DELETE # deletes one character under cursor +history # shows command line history +!! # repeats the last command +! # refers to command line 'n' +! # refers to command starting with 'string' +exit # logs out of current session

        +
        +

        BASH BASICS

        +

        env # displays all environment variables +echo $SHELL # displays the shell you're using +echo $BASH_VERSION # displays bash version +bash # if you want to use bash (type exit to go back to your previously opened shell) +whereis bash # locates the binary, source and manual-page for a command +which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) +clear # clears content on window (hide displayed lines)

        +
        +

        FILE COMMANDS

        +

        ls # lists your files in current directory, ls

        to print files in a specific directory +ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified +ls -a # lists all files in 'long format', including hidden files (name beginning with '.') +ln -s # creates symbolic link to file +readlink # shows where a symbolic links points to +tree # show directories and subdirectories in easilly readable file tree +mc # terminal file explorer (alternative to ncdu) +touch # creates or updates (edit) your file +mktemp -t # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) +cat # prints file raw content (will not be interpreted) +any_command > # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) +more # shows the first part of a file (move with space and type q to quit) +head # outputs the first lines of file (default: 10 lines) +tail # outputs the last lines of file (useful with -f option) (default: 10 lines) +vim # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist +mv # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) +cp # copies a file +rm # removes a file +find . -name # searches for a file or a directory in the current directory and all its sub-directories by its name +diff # compares files, and shows where they differ +wc # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations +sort # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. +sort -t -k # sorts the contents on specific sort key field starting from 1, using the field separator t. +rev # reverse string characters (hello becomes olleh) +chmod -options # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) +gzip # compresses files using gzip algorithm +gunzip # uncompresses files compressed by gzip +gzcat # lets you look at gzipped file without actually having to gunzip it +lpr # prints the file +lpq # checks out the printer queue +lprm # removes something from the printer queue +genscript # converts plain text files into postscript for printing and gives you some options for formatting +dvips # prints .dvi files (i.e. files produced by LaTeX) +grep # looks for the string in the files +grep -r # search recursively for pattern in directory +head -n file_name | tail +n # Print nth line from file. +head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines.

        +
        +

        DIRECTORY COMMANDS

        +

        mkdir # makes a new directory +rmdir # remove an empty directory +rmdir -rf # remove a non-empty directory +mv # rename a directory from to +cd # changes to home +cd .. # changes to the parent directory +cd # changes directory +cp -r # copy into including sub-directories +pwd # tells you where you currently are +cd ~ # changes to home. +cd - # changes to previous working directory

        +
        +

        SSH, SYSTEM INFO & NETWORK COMMANDS

        +

        ssh user@host # connects to host as user +ssh -p user@host # connects to host on specified port as user +ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login +whoami # returns your username +passwd # lets you change your password +quota -v # shows what your disk quota is +date # shows the current date and time +cal # shows the month's calendar +uptime # shows current uptime +w # displays whois online +finger # displays information about user +uname -a # shows kernel information +man # shows the manual for specified command +df # shows disk usage +du # shows the disk usage of the files and directories in filename (du -s give only a total) +last # lists your last logins +ps -u yourusername # lists your processes +kill # kills the processes with the ID you gave +killall # kill all processes with the name +top # displays your currently active processes +lsof # lists open files +bg # lists stopped or background jobs ; resume a stopped job in the background +fg # brings the most recent job in the foreground +fg # brings job to the foreground +ping # pings host and outputs results +whois # gets whois information for domain +dig # gets DNS information for domain +dig -x # reverses lookup host +wget # downloads file +time # report time consumed by command execution

        +
        +

        VARIABLES

        +

        varname=value # defines a variable +varname=value command # defines a variable to be in the environment of a particular subprocess +echo $varname # checks a variable's value +echo $$ # prints process ID of the current shell +echo $! # prints process ID of the most recently invoked background job +echo $? # displays the exit status of the last command +read # reads a string from the input and assigns it to a variable +read -p "prompt" # same as above but outputs a prompt to ask user for value +column -t # display info in pretty columns (often used with pipe) +let = # performs mathematical calculation using operators like +, -, , /, % +export VARNAME=value # defines an environment variable (will be available in subprocesses) +array[0]=valA # how to define an array +array[1]=valB +array[2]=valC +array=([2]=valC [0]=valA [1]=valB) # another way +array=(valA valB valC) # and another +${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed +${#array[i]} # to find out the length of any element in the array +${#array[@]} # to find out how many values there are in the array +declare -a # the variables are treated as arrays +declare -f # uses function names only +declare -F # displays function names without definitions +declare -i # the variables are treated as integers +declare -r # makes the variables read-only +declare -x # marks the variables for export via the environment +${varname:-word} # if varname exists and isn't null, return its value; otherwise return word +${varname:word} # if varname exists and isn't null, return its value; otherwise return word +${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value +${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script +${varname:+word} # if varname exists and isn't null, return word; otherwise return null +${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters +${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest +${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest +${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest +${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest +${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced +${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced +${#varname} # returns the length of the value of the variable as a character string +(patternlist) # matches zero or more occurrences of the given patterns ++(patternlist) # matches one or more occurrences of the given patterns +?(patternlist) # matches zero or one occurrence of the given patterns +@(patternlist) # matches exactly one of the given patterns +!(patternlist) # matches anything except one of the given patterns +$(UNIX command) # command substitution: runs the command and returns standard output

        +
        +

        FUNCTIONS

        +
        +

        The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth

        +

        .

        +
        +

        $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters

        +

        . +function functname() { + shell commands +} +unset -f functname # deletes a function definition +declare -f # displays all defined functions in your login session

        +
        +

        FLOW CONTROLS

        +

        statement1 && statement2 # and operator +statement1 || statement2 # or operator +-a # and operator inside a test conditional expression +-o # or operator inside a test conditional expression

        +
        +

        STRINGS

        +

        str1 == str2 # str1 matches str2 +str1 != str2 # str1 does not match str2 +str1 < str2 # str1 is less than str2 (alphabetically) +str1 > str2 # str1 is greater than str2 (alphabetically) +str1 > str2 # str1 is sorted after str2 +str1 \< str2 # str1 is sorted before str2 +-n str1 # str1 is not null (has length greater than 0) +-z str1 # str1 is null (has length 0)

        +
        +

        FILES

        +

        -a file # file exists or its compilation is successful +-d file # file exists and is a directory +-e file # file exists; same -a +-f file # file exists and is a regular file (i.e., not a directory or other special type of file) +-r file # you have read permission +-s file # file exists and is not empty +-w file # your have write permission +-x file # you have execute permission on file, or directory search permission if it is a directory +-N file # file was modified since it was last read +-O file # you own file +-G file # file's group ID matches yours (or one of yours, if you are in multiple groups) +file1 -nt file2 # file1 is newer than file2 +file1 -ot file2 # file1 is older than file2

        +
        +

        NUMBERS

        +

        -lt # less than +-le # less than or equal +-eq # equal +-ge # greater than or equal +-gt # greater than +-ne # not equal +if condition +then + statements +[elif condition + then statements...] +[else + statements] +fi +for x in {1..10} +do + statements +done +for name [in list] +do + statements that can use $name +done +for (( initialisation ; ending condition ; update )) +do + statements... +done +case expression in + pattern1 ) + statements ;; + pattern2 ) + statements ;; +esac +select name [in list] +do + statements that can use $name +done +while condition; do + statements +done +until condition; do + statements +done

        +
        +

        COMMAND-LINE PROCESSING CYCLE

        +
        +

        The default order for command lookup is functions, followed by built-ins, with scripts and executables last

        +

        .

        +
        +

        There are three built-ins that you can use to override this order: `command`, `builtin` and `enable

        +

        `. +command # removes alias and function lookup. Only built-ins and commands found in the search path are executed +builtin # looks up only built-in commands, ignoring functions and commands found in PATH +enable # enables and disables shell built-ins +eval # takes arguments and run them through the command-line processing steps all over again

        +
        +

        INPUT/OUTPUT REDIRECTORS

        +

        cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 +< file # takes standard input from file

        +
        +

        file # directs standard output to file

        +
        +

        file # directs standard output to file; append to file if it already exists +|file # forces standard output to file even if noclobber is set +n>|file # forces output to file from file descriptor n even if noclobber is set +<> file # uses file as both standard input and standard output +n<>file # uses file as both input and output for file descriptor n +n>file # directs file descriptor n to file +n>file # directs file description n to file; append to file if it already exists +n>& # duplicates standard output to file descriptor n +n<& # duplicates standard input from file descriptor n +n>&m # file descriptor n is made to be a copy of the output file descriptor +n<&m # file descriptor n is made to be a copy of the input file descriptor +&>file # directs standard output and standard error to file +<&- # closes the standard input +&- # closes the standard output +n>&- # closes the ouput from file descriptor n +n<&- # closes the input from file descripor n +|tee # output command to both terminal and a file (-a to append to file)

        +
        +
        +
        +

        PROCESS HANDLING

        +
        +

        To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y

        +

        .

        +
        +

        This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal

        +

        .

        +
        +

        Of course, to interrupt a job, type CTRL+C

        +

        . +myCommand & # runs job in the background and prompts back the shell +jobs # lists all jobs (use with -l to see associated PID) +fg # brings a background job into the foreground +fg %+ # brings most recently invoked background job +fg %- # brings second most recently invoked background job +fg %N # brings job number N +fg %string # brings job whose command begins with string +fg %?string # brings job whose command contains string +kill -l # returns a list of all signals on the system, by name and number +kill PID # terminates process with specified PID +kill -s SIGKILL 4500 # sends a signal to force or terminate the process +kill -15 913 # Ending PID 913 process with signal 15 (TERM) +kill %1 # Where %1 is the number of job as read from 'jobs' command. +ps # prints a line of information about the current running login shell and any processes running under it +ps -a # selects all processes with a tty except session leaders +trap cmd sig1 sig2 # executes a command when a signal is received by the script +trap "" sig1 sig2 # ignores that signals +trap - sig1 sig2 # resets the action taken when the signal is received to the default +disown <PID|JID> # removes the process from the list of jobs +wait # waits until all background jobs have finished +sleep # wait # of seconds before continuing +pv # display progress bar for data handling commands. often used with pipe like |pv +yes # give yes response everytime an input is requested from script/process

        +
        +

        TIPS & TRICKS

        +
        +

        set an alias

        +

        cd; nano .bash_profile

        +
        +

        alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile

        +
        +
        +

        to quickly go to a specific directory

        +

        cd; nano .bashrc

        +
        +

        shopt -s cdable_vars +export websites="/Users/mac/Documents/websites" +source .bashrc +cd $websites

        +
        +
        +

        DEBUGGING SHELL PROGRAMS

        +

        bash -n scriptname # don't run commands; check for syntax errors only +set -o noexec # alternative (set option in script) +bash -v scriptname # echo commands before running them +set -o verbose # alternative (set option in script) +bash -x scriptname # echo commands after command-line processing +set -o xtrace # alternative (set option in script) +trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits +function errtrap { + es=$? + echo "ERROR line $1: Command exited with status $es." +} +trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status +function dbgtrap { + echo "badvar is $badvar" +} +trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script

        +
        +

        ...section of code in which the problem occurs

        +

        ... +trap - DEBUG # turn off the DEBUG trap +function returntrap { + echo "A return occurred" +} +trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing

        +
        +

        COLORS AND BACKGROUNDS

        +
        +

        note: \e or \x1B also work instead of \033

        +
        +

        Reset

        +

        Color_Off='\033[0m' # Text Reset

        +
        +

        Regular Colors

        +

        Black='\033[0;30m' # Black +Red='\033[0;31m' # Red +Green='\033[0;32m' # Green +Yellow='\033[0;33m' # Yellow +Blue='\033[0;34m' # Blue +Purple='\033[0;35m' # Purple +Cyan='\033[0;36m' # Cyan +White='\033[0;97m' # White

        +
        +

        Additional colors

        +

        LGrey='\033[0;37m' # Ligth Gray +DGrey='\033[0;90m' # Dark Gray +LRed='\033[0;91m' # Ligth Red +LGreen='\033[0;92m' # Ligth Green +LYellow='\033[0;93m'# Ligth Yellow +LBlue='\033[0;94m' # Ligth Blue +LPurple='\033[0;95m'# Light Purple +LCyan='\033[0;96m' # Ligth Cyan

        +
        +

        Bold

        +

        BBlack='\033[1;30m' # Black +BRed='\033[1;31m' # Red +BGreen='\033[1;32m' # Green +BYellow='\033[1;33m'# Yellow +BBlue='\033[1;34m' # Blue +BPurple='\033[1;35m'# Purple +BCyan='\033[1;36m' # Cyan +BWhite='\033[1;37m' # White

        +
        +

        Underline

        +

        UBlack='\033[4;30m' # Black +URed='\033[4;31m' # Red +UGreen='\033[4;32m' # Green +UYellow='\033[4;33m'# Yellow +UBlue='\033[4;34m' # Blue +UPurple='\033[4;35m'# Purple +UCyan='\033[4;36m' # Cyan +UWhite='\033[4;37m' # White

        +
        +

        Background

        +

        On_Black='\033[40m' # Black +On_Red='\033[41m' # Red +On_Green='\033[42m' # Green +On_Yellow='\033[43m'# Yellow +On_Blue='\033[44m' # Blue +On_Purple='\033[45m'# Purple +On_Cyan='\033[46m' # Cyan +On_White='\033[47m' # White

        +
        +

        Example of usage

        +

        echo -e "${Green}This is GREEN text${Color_Off} and normal text" +echo -e "${Red}${On_White}This is Red test on White background${Color_Off}"

        +
        +

        option -e is mandatory, it enable interpretation of backslash escapes

        +

        printf "${Red} This is red \n" +` +

        +
        +
        +

        Find

        + +

        To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG

        +

        ) +find . -iname "*.jpg"

        +
        +

        To find directories

        +

        find . -type d

        +
        +

        To find files

        +

        find . -type f

        +
        +

        To find files by octal permission

        +

        find . -type f -perm 777

        +
        +

        To find files with setuid bit set

        +

        find . -xdev ( -perm -4000 ) -type f -print0 | xargs -0 ls -l

        +
        +

        To find files with extension '.txt' and remove them

        +

        find ./path/ -name '*.txt' -exec rm '{}' \;

        +
        +

        To find files with extension '.txt' and look for a string into them

        +

        find ./path/ -name '*.txt' | xargs grep 'string'

        +
        +

        To find files with size bigger than 5 Mebibyte and sort them by size

        +

        find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z

        +
        +

        To find files bigger than 2 Megabyte and list them

        +

        find . -type f -size +200000000c -exec ls -lh {} \; | awk '{ print $9 ": " $5 }'

        +
        +

        To find files modified more than 7 days ago and list file information

        +

        find . -type f -mtime +7d -ls

        +
        + +

        find . -type l -user -ls

        +
        +

        To search for and delete empty directories

        +

        find . -type d -empty -exec rmdir {} \;

        +
        +

        To search for directories named build at a max depth of 2 directories

        +

        find . -maxdepth 2 -name build -type d

        +
        +

        To search all files who are not in .git directory

        +

        find . ! -iwholename '.git' -type f

        +
        + +

        find . -type f -samefile MY_FILE_HERE 2>/dev/null

        +
        +

        To find all files in the current directory and modify their permissions

        +

        find . -type f -exec chmod 644 {} \;

        +

        +

        Preview

        + +

        Wiki Nav

        + +

        Dependencies

        +

        + Click to expand! +@algolia**algolia / algoliasearch-client-javascript@algolia/client-search +^ 4.10.3 +@algolia**algolia / algoliasearch-client-javascript@algolia/client-common +4.10.5 +@ghost**@algolia/requester-common +4.10.5 +@algolia**algolia / algoliasearch-client-javascript@algolia/transporter +4.10.5 +@stackbit**stackbit / gatsby-plugin-menus@stackbit/gatsby-plugin-menus +0.0.4 +@facebook**facebook / jestbabel-jest +^ 24.7.1 +@gatsbyjs**gatsbyjs / gatsbybabel-preset-gatsby +^ 0.1.11 +@gatsbyjs**gatsbyjs / gatsby ^ 2.5.0 +@keyz**keyz / identity-obj-proxy ^ 3.0.0 +@facebook**facebook / jest ^ 24.7.1 +@lodash**lodash / lodash ^ 4.17.11 +@facebook**facebook / reactreact-test-renderer +^ 16.8.6 +@getkirby-v2**getkirby-v2 / algolia-pluginalgolia +0.0.0 +@ecomfe**ecomfe / babel-runtime 6.26.0 +@paulmillr**paulmillr / chokidar 3.4.0 +@DefinitelyTyped**DefinitelyTyped / DefinitelyTyped@types/node +^ 13 +@micromatch**micromatch / anymatch ~ 3.1.1 +@micromatch**micromatch / braces ~ 3.0.2 +@chaijs**chaijs / chai ^ 4.2 +@microsoft**microsoft / dtslint ^ 3.3.0 +@eslint**eslint / eslint ^ 6.6.0 +@fsevents**fsevents / fsevents ~ 2.1.2 +@gulpjs**gulpjs / glob-parent ~ 5.1.0 +@sindresorhus**sindresorhus / is-binary-path ~ 2.1.0 +@micromatch**micromatch / is-glob ~ 4.0.1 +@mochajs**mochajs / mocha ^ 7.0.0 +@jonschlinkert**jonschlinkert / normalize-path ~ 3.0.0 +@istanbuljs**istanbuljs / nyc ^ 15.0.0 +@paulmillr**paulmillr / readdirp ~ 3.4.0 +@isaacs**isaacs / rimraf ^ 3.0.0 +@sinonjs**sinonjs / sinon ^ 9.0.1 +@domenic**domenic / sinon-chai ^ 3.3.0 +@anodynos**anodynos / upath ^ 1.2.0 +@JedWatson**JedWatson / classnames 2.2.6 +@bestiejs**bestiejs / benchmark.jsbenchmark +^ 1.0.0 +@browserify**browserify / browserify ^ 14.1.0 +@mochajs**mochajs / mocha ^ 2.1.0 +@jeromedecoster**jeromedecoster / opn-cli ^ 3.1.0 +@documentationjs**documentationjs / documentation ^ 13.2.5 +@babel**babel / babel@babel/core +7.12.3 +Cloudfare-Backup ↞↠ Search Website: search ↞↠ Backup Repo Deploy ↞↠ Github pages ↞↠ Go To Site Wiki

        +

        +
        +

        Docs Structure

        +

        +

        Docs Structure

        +
        ├── blog
        +│     ├── 300-react-questions.md
        +│     ├── awesome-graphql.md
        +│     ├── big-o-complexity.md
        +│     ├── blog-archive.md
        +│     ├── blogwcomments.md
        +│     ├── data-structures.md
        +│     ├── flow-control-in-python.md
        +│     ├── functions-in-python.md
        +│     ├── git-gateway.md
        +│     ├── index.md
        +│     ├── interview-questions-js.md
        +│     ├── netlify-cms.md
        +│     ├── platform-docs.md
        +│     ├── python-for-js-dev.md
        +│     ├── python-resources.md
        +│     ├── web-dev-trends.md
        +│     └── web-scraping.md
        +├── docs
        +│     ├── about
        +│     │     ├── eng-portfolio.md
        +│     │     ├── ideas-for-this-website.md
        +│     │     ├── index.md
        +│     │     ├── intrests.md
        +│     │     ├── job-search.md
        +│     │     └── resume.md
        +│     ├── articles
        +│     │     ├── basic-web-dev.md
        +│     │     ├── buffers.md
        +│     │     ├── dev-dep.md
        +│     │     ├── event-loop.md
        +│     │     ├── fs-module.md
        +│     │     ├── how-the-web-works.md
        +│     │     ├── http.md
        +│     │     ├── index.md
        +│     │     ├── install.md
        +│     │     ├── intro.md
        +│     │     ├── modules.md
        +│     │     ├── nextjs.md
        +│     │     ├── node-api-express.md
        +│     │     ├── node-cli-args.md
        +│     │     ├── node-common-modules.md
        +│     │     ├── node-env-variables.md
        +│     │     ├── node-js-language.md
        +│     │     ├── node-package-manager.md
        +│     │     ├── node-repl.md
        +│     │     ├── node-run-cli.md
        +│     │     ├── nodejs.md
        +│     │     ├── nodevsbrowser.md
        +│     │     ├── npm.md
        +│     │     ├── npx.md
        +│     │     ├── os-module.md
        +│     │     ├── reading-files.md
        +│     │     ├── semantic-html.md
        +│     │     ├── semantic.md
        +│     │     ├── the-uniform-resource-locator-(url).md
        +│     │     ├── understanding-firebase.md
        +│     │     ├── v8.md
        +│     │     ├── web-standards-checklist.md
        +│     │     ├── webdev-tools.md
        +│     │     └── writing-files.md
        +│     ├── audio
        +│     │     ├── audio-feature-extraction.md
        +│     │     ├── audio.md
        +│     │     ├── dfft.md
        +│     │     ├── discrete-fft.md
        +│     │     ├── dtw-python-explained.md
        +│     │     ├── dynamic-time-warping.md
        +│     │     ├── index.md
        +│     │     └── web-audio-api.md
        +│     ├── career
        +│     │     ├── dev-interview.md
        +│     │     ├── index.md
        +│     │     ├── interview-dos-n-donts.md
        +│     │     └── job-boards.md
        +│     ├── community
        +│     │     ├── an-open-letter-2-future-developers.md
        +│     │     ├── index.md
        +│     │     └── video-chat.md
        +│     ├── content
        +│     │     ├── algo.md
        +│     │     ├── archive.md
        +│     │     ├── gatsby-Queries-Mutations.md
        +│     │     ├── history-api.md
        +│     │     ├── index.md
        +│     │     ├── main-projects.md
        +│     │     └── trouble-shooting.md
        +│     ├── data-structures
        +│     │     └── index.md
        +│     ├── docs
        +│     │     ├── appendix.md
        +│     │     ├── art-of-command-line.md
        +│     │     ├── bash.md
        +│     │     ├── content.md
        +│     │     ├── css.md
        +│     │     ├── data-structures-docs.md
        +│     │     ├── es-6-features.md
        +│     │     ├── git-reference.md
        +│     │     ├── git-repos.md
        +│     │     ├── html-spec.md
        +│     │     ├── index.md
        +│     │     ├── markdown.md
        +│     │     ├── no-whiteboarding.md
        +│     │     ├── node-docs-complete.md
        +│     │     ├── node-docs-full.md
        +│     │     ├── regex-in-js.md
        +│     │     └── sitemap.md
        +│     ├── faq
        +│     │     ├── contact.md
        +│     │     ├── index.md
        +│     │     └── plug-ins.md
        +│     ├── gists.md
        +│     ├── index.md
        +│     ├── interact
        +│     │     ├── callstack-visual.md
        +│     │     ├── clock.md
        +│     │     ├── index.md
        +│     │     ├── jupyter-notebooks.md
        +│     │     ├── other-sites.md
        +│     │     └── video-chat.md
        +│     ├── interview
        +│     │     ├── index.md
        +│     │     ├── job-search-nav.md
        +│     │     └── review-concepts.md
        +│     ├── javascript
        +│     │     ├── arrow-functions.md
        +│     │     ├── asyncjs.md
        +│     │     ├── await-keyword.md
        +│     │     ├── bigo.md
        +│     │     ├── clean-code.md
        +│     │     ├── constructor-functions.md
        +│     │     ├── index.md
        +│     │     ├── promises.md
        +│     │     ├── review.md
        +│     │     └── this-is-about-this.md
        +│     ├── leetcode
        +│     │     └── index.md
        +│     ├── privacy-policy.md
        +│     ├── projects
        +│     │     ├── embeded-websites.md
        +│     │     ├── index.md
        +│     │     ├── list-of-projects.md
        +│     │     ├── mini-projects.md
        +│     │     └── my-websites.md
        +│     ├── python
        +│     │     ├── at-length.md
        +│     │     ├── cheat-sheet.md
        +│     │     ├── comprehensive-guide.md
        +│     │     ├── examples.md
        +│     │     ├── flow-control.md
        +│     │     ├── functions.md
        +│     │     ├── google-sheets-api.md
        +│     │     ├── index.md
        +│     │     ├── intro-for-js-devs.md
        +│     │     ├── python-ds.md
        +│     │     └── snippets.md
        +│     ├── quick-reference
        +│     │     ├── Emmet.md
        +│     │     ├── all-emojis.md
        +│     │     ├── create-react-app.md
        +│     │     ├── git-bash.md
        +│     │     ├── git-tricks.md
        +│     │     ├── google-firebase.md
        +│     │     ├── heroku-error-codes.md
        +│     │     ├── index.md
        +│     │     ├── installation.md
        +│     │     ├── markdown-dropdowns.md
        +│     │     ├── minifiction.md
        +│     │     ├── new-repo-instructions.md
        +│     │     ├── psql-setup.md
        +│     │     ├── pull-request-rubric.md
        +│     │     ├── quick-links.md
        +│     │     ├── topRepos.md
        +│     │     ├── understanding-path.md
        +│     │     └── vscode-themes.md
        +│     ├── react
        +│     │     ├── ajax-n-apis.md
        +│     │     ├── cheatsheet.md
        +│     │     ├── createReactApp.md
        +│     │     ├── demo.md
        +│     │     ├── dont-use-index-as-keys.md
        +│     │     ├── index.md
        +│     │     ├── jsx.md
        +│     │     ├── react-docs.md
        +│     │     ├── react-in-depth.md
        +│     │     ├── react2.md
        +│     │     └── render-elements.md
        +│     ├── reference
        +│     │     ├── awesome-lists.md
        +│     │     ├── awesome-static.md
        +│     │     ├── bash-commands.md
        +│     │     ├── bookmarks.md
        +│     │     ├── embed-the-web.md
        +│     │     ├── github-search.md
        +│     │     ├── google-cloud.md
        +│     │     ├── how-2-reinstall-npm.md
        +│     │     ├── how-to-kill-a-process.md
        +│     │     ├── index.md
        +│     │     ├── installing-node.md
        +│     │     ├── intro-to-nodejs.md
        +│     │     ├── notes-template.md
        +│     │     ├── psql.md
        +│     │     ├── resources.md
        +│     │     ├── vscode.md
        +│     │     └── web-api's.md
        +│     ├── search.md
        +│     ├── sitemap.md
        +│     ├── tips
        +│     │     ├── array-methods.md
        +│     │     ├── index.md
        +│     │     └── insert-into-array.md
        +│     ├── tools
        +│     │     ├── Archive.md
        +│     │     ├── data-structures.md
        +│     │     ├── dev-utilities.md
        +│     │     ├── index.md
        +│     │     └── markdown-html.md
        +│     └── tutorials
        +│         ├── enviorment-setup.md
        +│         └── index.md
        +├── index.md
        +├── privacy-policy.md
        +├── readme.md
        +├── showcase.md
        +└── tree.md
        +23 directories, 202 files
        +
        +

        SITEMAP

        +

        🌍⇒https://bgoonz-blog.netlify.app/🗺️ +🌍⇒blog🗺️ +🌍⇒docs🗺️ +🌍⇒readme🗺️ +🌍⇒review🗺️ +🌍⇒showcase🗺️ +🌍⇒blog/awesome-graphql🗺️ +🌍⇒blog/big-o-complexity🗺️ +🌍⇒blog/blog-archive🗺️ +🌍⇒blog/blogwcomments🗺️ +🌍⇒blog/data-structures🗺️ +🌍⇒blog/flow-control-in-python🗺️ +🌍⇒blog/functions-in-python🗺️ +🌍⇒blog/git-gateway🗺️ +🌍⇒blog/interview-questions-js🗺️ +🌍⇒blog/media-queries-explained🗺️ +🌍⇒blog/my-medium🗺️ +🌍⇒blog/netlify-cms🗺️ +🌍⇒blog/platform-docs🗺️ +🌍⇒blog/python-for-js-dev🗺️ +🌍⇒blog/python-resources🗺️ +🌍⇒blog/web-dev-trends🗺️ +🌍⇒blog/web-scraping🗺️ +🌍⇒docs/about🗺️ +🌍⇒docs/articles🗺️ +🌍⇒docs/audio🗺️ +🌍⇒docs/career🗺️ +🌍⇒docs/community🗺️ +🌍⇒docs/content🗺️ +🌍⇒docs/docs🗺️ +🌍⇒docs/faq🗺️ +🌍⇒docs/gallery🗺️ +🌍⇒docs/interact🗺️ +🌍⇒docs/javascript🗺️ +🌍⇒docs/leetcode🗺️ +🌍⇒docs/other-content🗺️ +🌍⇒docs/privacy-policy🗺️ +🌍⇒docs/projects🗺️ +🌍⇒docs/python🗺️ +🌍⇒docs/quick-reference🗺️ +🌍⇒docs/react🗺️ +🌍⇒docs/reference🗺️ +🌍⇒docs/search🗺️ +🌍⇒docs/sitemap🗺️ +🌍⇒docs/tools🗺️ +🌍⇒docs/tutorials🗺️ +🌍⇒docs/about/eng-portfolio🗺️ +🌍⇒docs/about/ideas-for-this-website🗺️ +🌍⇒docs/about/intrests🗺️ +🌍⇒docs/about/interview🗺️ +🌍⇒docs/about/resume🗺️ +🌍⇒docs/articles/basic-web-dev🗺️ +🌍⇒docs/articles/buffers🗺️ +🌍⇒docs/articles/dev-dep🗺️ +🌍⇒docs/articles/event-loop🗺️ +🌍⇒docs/articles/fs-module🗺️ +🌍⇒docs/articles/how-the-web-works🗺️ +🌍⇒docs/articles/http🗺️ +🌍⇒docs/articles/install🗺️ +🌍⇒docs/articles/intro🗺️ +🌍⇒docs/articles/media-queries-no-more🗺️ +🌍⇒docs/articles/module-exports🗺️ +🌍⇒docs/articles/nextjs🗺️ +🌍⇒docs/articles/node-api-express🗺️ +🌍⇒docs/articles/node-cli-args🗺️ +🌍⇒docs/articles/node-common-modules🗺️ +🌍⇒docs/articles/node-env-variables🗺️ +🌍⇒docs/articles/node-js-language🗺️ +🌍⇒docs/articles/node-package-manager🗺️ +🌍⇒docs/articles/node-repl🗺️ +🌍⇒docs/articles/node-run-cli🗺️ +🌍⇒docs/articles/nodejs🗺️ +🌍⇒docs/articles/nodevsbrowser🗺️ +🌍⇒docs/articles/npm🗺️ +🌍⇒docs/articles/npx🗺️ +🌍⇒docs/articles/os-module🗺️ +🌍⇒docs/articles/package-lock🗺️ +🌍⇒docs/articles/reading-files🗺️ +🌍⇒docs/articles/semantic🗺️ +🌍⇒docs/articles/semantic-html🗺️ +🌍⇒docs/articles/the-uniform-resource-locator-(url)🗺️>) +🌍⇒docs/articles/understanding-firebase🗺️ +🌍⇒docs/articles/v8🗺️ +🌍⇒docs/articles/web-standards-checklist🗺️ +🌍⇒docs/articles/webdev-tools🗺️ +🌍⇒docs/articles/write-2-json-with-python🗺️ +🌍⇒docs/articles/writing-files🗺️ +🌍⇒docs/audio/audio🗺️ +🌍⇒docs/audio/audio-feature-extraction🗺️ +🌍⇒docs/audio/dfft🗺️ +🌍⇒docs/audio/discrete-fft🗺️ +🌍⇒docs/audio/dtw-python-explained🗺️ +🌍⇒docs/audio/dynamic-time-warping🗺️ +🌍⇒docs/audio/web-audio-api🗺️ +🌍⇒docs/career/confidence🗺️ +🌍⇒docs/career/dev-interview🗺️ +🌍⇒docs/career/interview-dos-n-donts🗺️ +🌍⇒docs/career/job-boards🗺️ +🌍⇒docs/community/an-open-letter-2-future-developers🗺️ +🌍⇒docs/community/video-chat🗺️ +🌍⇒docs/content/algo🗺️ +🌍⇒docs/content/archive🗺️ +🌍⇒docs/content/data-structures-algo🗺️ +🌍⇒docs/content/gatsby-Queries-Mutations🗺️ +🌍⇒docs/content/history-api🗺️ +🌍⇒docs/content/projects🗺️ +🌍⇒docs/content/recent-projects🗺️ +🌍⇒docs/content/trouble-shooting🗺️ +🌍⇒docs/docs/appendix🗺️ +🌍⇒docs/docs/bash🗺️ +🌍⇒docs/docs/content🗺️ +🌍⇒docs/docs/css🗺️ +🌍⇒docs/docs/data-structures-docs🗺️ +🌍⇒docs/docs/git-reference🗺️ +🌍⇒docs/docs/git-repos🗺️ +🌍⇒docs/docs/html-spec🗺️ +🌍⇒docs/docs/markdown🗺️ +🌍⇒docs/docs/no-whiteboarding🗺️ +🌍⇒docs/docs/node-docs-complete🗺️ +🌍⇒docs/docs/node-docs-full🗺️ +🌍⇒docs/docs/regex-in-js🗺️ +🌍⇒docs/docs/sitemap🗺️ +🌍⇒docs/faq/contact🗺️ +🌍⇒docs/faq/plug-ins🗺️ +🌍⇒docs/interact/callstack-visual🗺️ +🌍⇒docs/interact/clock🗺️ +🌍⇒docs/interact/jupyter-notebooks🗺️ +🌍⇒docs/interact/other-sites🗺️ +🌍⇒docs/interact/video-chat🗺️ +🌍⇒docs/javascript/arrow-functions🗺️ +🌍⇒docs/javascript/await-keyword🗺️ +🌍⇒docs/javascript/bigo🗺️ +🌍⇒docs/javascript/clean-code🗺️ +🌍⇒docs/javascript/constructor-functions🗺️ +🌍⇒docs/javascript/promises🗺️ +🌍⇒docs/javascript/review🗺️ +🌍⇒docs/javascript/this-is-about-this🗺️ +🌍⇒docs/projects/medium-links🗺️ +🌍⇒docs/projects/my-websites🗺️ +🌍⇒docs/python/at-length🗺️ +🌍⇒docs/python/basics🗺️ +🌍⇒docs/python/cheat-sheet🗺️ +🌍⇒docs/python/comprehensive-guide🗺️ +🌍⇒docs/python/examples🗺️ +🌍⇒docs/python/flow-control🗺️ +🌍⇒docs/python/functions🗺️ +🌍⇒docs/python/google-sheets-api🗺️ +🌍⇒docs/python/intro-for-js-devs🗺️ +🌍⇒docs/python/python-ds🗺️ +🌍⇒docs/python/snippets🗺️ +🌍⇒docs/quick-reference/Emmet🗺️ +🌍⇒docs/quick-reference/all-emojis🗺️ +🌍⇒docs/quick-reference/create-react-app🗺️ +🌍⇒docs/quick-reference/git-bash🗺️ +🌍⇒docs/quick-reference/git-tricks🗺️ +🌍⇒docs/quick-reference/google-firebase🗺️ +🌍⇒docs/quick-reference/heroku-error-codes🗺️ +🌍⇒docs/quick-reference/installation🗺️ +🌍⇒docs/quick-reference/markdown-dropdowns🗺️ +🌍⇒docs/quick-reference/minifiction🗺️ +🌍⇒docs/quick-reference/new-repo-instructions🗺️ +🌍⇒docs/quick-reference/psql-setup🗺️ +🌍⇒docs/quick-reference/pull-request-rubric🗺️ +🌍⇒docs/quick-reference/quick-links🗺️ +🌍⇒docs/quick-reference/topRepos🗺️ +🌍⇒docs/quick-reference/understanding-path🗺️ +🌍⇒docs/quick-reference/vscode-themes🗺️ +🌍⇒docs/react/cheatsheet🗺️ +🌍⇒docs/react/createReactApp🗺️ +🌍⇒docs/react/demo🗺️ +🌍⇒docs/react/jsx🗺️ +🌍⇒docs/react/react-docs🗺️ +🌍⇒docs/react/react-in-depth🗺️ +🌍⇒docs/react/react2🗺️ +🌍⇒docs/react/render-elements🗺️ +🌍⇒docs/reference/awesome-lists🗺️ +🌍⇒docs/reference/awesome-static🗺️ +🌍⇒docs/reference/bookmarks🗺️ +🌍⇒docs/reference/embed-the-web🗺️ +🌍⇒docs/reference/github-search🗺️ +🌍⇒docs/reference/how-2-reinstall-npm🗺️ +🌍⇒docs/reference/how-to-kill-a-process🗺️ +🌍⇒docs/reference/installing-node🗺️ +🌍⇒docs/reference/intro-to-nodejs🗺️ +🌍⇒docs/reference/notes-template🗺️ +🌍⇒docs/reference/psql🗺️ +🌍⇒docs/reference/resources🗺️ +🌍⇒docs/reference/vscode🗺️ +🌍⇒docs/reference/web-api's🗺️ +🌍⇒docs/tools/data-structures🗺️ +🌍⇒docs/tools/dev-utilities🗺️ +🌍⇒docs/tools/google-cloud🗺️ +🌍⇒docs/tools/markdown-html🗺️ +🌍⇒docs/tools/more-tools🗺️ +🌍⇒docs/tutorials/google-lighthouse-cli🗺️

        +

        +
        +
        +

        +

        ↞↠ Getting Started With GatsbyJS ↞↠

        +

        #

        +
        +

        🚀 Quick start

        +
          +
        1. Create a Gatsby site. + Use the Gatsby CLI to create a new site, specifying the default starter.
          # create a new Gatsby site using the default starter
          +gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
          +
          +
        2. +
        3. Start developing. + Navigate into your new site's directory and start it up.
          cd my-default-starter/
          +gatsby develop
          +
          +
        4. +
        5. Open the source code and start editing! + Your site is now running at http://localhost:8000! + Note: You'll also see a second link:http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. + Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!
        6. +
        +
        +

        🧐 What's inside

        +

        ? +A quick look at the top-level files and directories you'll see in a Gatsby project. + . + ├── node_modules + ├── src + ├── .gitignore + ├── .prettierrc + ├── gatsby-browser.js + ├── gatsby-config.js + ├── gatsby-node.js + ├── gatsby-ssr.js + ├── LICENSE + ├── package-lock.json + ├── package.json + └── README.md

        +
          +
        1. /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
        2. +
        3. /src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for "source code".
        4. +
        5. .gitignore: This file tells git which files it should not track / not maintain a version history for.
        6. +
        7. .prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent.
        8. +
        9. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser.
        10. +
        11. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail).
        12. +
        13. gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
        14. +
        15. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering.
        16. +
        17. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license.
        18. +
        19. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly).
        20. +
        21. package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project.
        22. +
        23. README.md: A text file containing useful reference information about your project.
        24. +
        +
        +

        🎓 Learning Gatsby

        +

        Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start:

        +
          +
        • For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.com/tutorial/).\*\* It starts with zero assumptions about your level of ability and walks through every step of the process. +-
        • +
        • To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.com/docs/).\*\ In particular, check out the Guides, API Reference, and Advanced Tutorials* sections in the sidebar.
        • +
        +
        +

        💫 Deploy

        +

        Deploy to Netlify**

        +

        Deploy with Vercel**

        +

        Gatsby With Netlify CMS

        +

        This tutorial will use gatsby-personal-starter-blog, a Gatsby starter based on the official gatsby-starter-blog. The differences are that gatsby-personal-starter-blog is configured to run the blog on a subdirectory, /blog, and comes pre-installed with Netlify CMS for content editing. It also adds VS Code highlighting for code blocks.

        +
        +

        Prerequisites

        +
        +
        +

        Set up a Netlify CMS-managed Gatsby site in 5 steps

        +

        Step 1

        +

        Open your Terminal and run the following command from the Gatsby CLI to create a new Gatsby site using gatsby-personal-starter-blog.

        +
        gatsby new [your-project-name] https://github.com/thomaswangio/gatsby-personal-starter-blog
        +>>>>>>> master
         
        1. @@ -2549,6 +4830,7 @@

          Excerpt

          Inside a Gatsby project, you may see some or all of the following folders and files:

          /|-- /.cache|-- /plugins|-- /public|-- /src    |-- /api    |-- /pages    |-- /templates    |-- html.js|-- /static|-- gatsby-config.js|-- gatsby-node.js|-- gatsby-ssr.js|-- gatsby-browser.js
           
          +<<<<<<< HEAD

        [](https://www.gatsbyjs.com/docs/reference/gatsby-project-structure/#folders)Folders

        @@ -2813,6 +5095,242 @@

        SOURCECODE

        
         bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f
        +=======
        +

        Now you can go to http://localhost:8000 to see your new site, but what's extra cool is that Netlify CMS is pre-installed and you can access it at http://localhost:8000/admin +A CMS, or content management system, is useful because you can add content like blog posts from a dashboard on your site, instead of having to add posts manually with Markdown. However, you'll likely want to be able to access the CMS from a deployed website, not just locally. For that, you'll need to deploy to Netlify through GitHub, set up continuous deployment, and do a few configurations. You'll go over this in Step-5.

        +

        Step 3

        +

        Open the project in your code editor and open static/admin/config.yml. Replace your-username/your-repo-name with your GitHub username and project name. This step is important for managing and deploying the Netlify CMS interface.

        +
        backend:
        +-  name: test-repo
        ++  name: github
        ++  repo: your-username/your-repo-name
        +
        +

        Customizing your site

        +

        Head into gatsby-config.js and you can edit your siteMetadata, add a Google Analytics tracking ID, and your app icon/favicon. Test out the edits for the deployed build by quitting the development server and running gatsby build && gatsby serve. +You'll likely also want to edit the README.md and package.json files to include your own project details.

        +

        Step 4

        +

        Open github.com and create a new repository, with the same name as your project. Push your new Gatsby site's code to GitHub using the following Terminal commands:

        +
        git init
        +git add .
        +git commit -m "initial commit"
        +git remote add origin https://github.com/[your-username]/[your-repo-name].git
        +git push -u origin master
        +
        +

        Then, open app.netlify.com and add a "New site from Git". Choose your newly created repo and click on "Deploy site" with the default deployment settings.

        +
        +

        Note: if you don't see the correct repo listed, you may need to install or reconfigure the Netlify app on GitHub. +Netlify Dashboard for Creating a new site

        +
        +

        Step 5

        +

        To make sure that Netlify CMS has access to your GitHub repo, you need to set up an OAuth application on GitHub. The instructions for that are here: Netlify's Using an Authorization Provider. +For the "Homepage URL" – you can use your Netlify subdomain, [name-of-your-site].netlify.com, or you can use a custom domain. To customize the subdomain, look for the "Edit site name" field under "Domain Management" for your project on the Netlify app. To connect your Netlify site to your custom domain instead, see Netlify’s instructions on custom domains. +Once you've configured an authentication provider then you'll be able to use Netlify CMS at your deployed site to add new posts. +Netlify and GitHub Authorization +Copy the credentials of your new app listed on GitHub OAuth Apps and install a new auth provider on Netlify using them. +Setting up access control

        +

        Benefits of Netlify CMS, GitHub, and Netlify Workflow

        +

        Congrats! Now that Netlify CMS is successfully configured to your project, every time you add a new post, the content will be stored in your repository and versioned on GitHub because Netlify CMS is Git-based. Also, thanks to Netlify's Continuous Deployment, a new version will be deployed every time you add or edit a post.

        +

        You can learn more about Netlify CMS and how to configure it further in the Netlify CMS documentation

        +
        + +

        Gatsby Project Structure | Gatsby

        +
        +

        Excerpt

        +

        Inside a Gatsby project, you may see some or all of the following folders and files: Folders /.cache Automatically generated. This folder…

        +
        +
        +

        Inside a Gatsby project, you may see some or all of the following folders and files:

        +
        /|
        +-- /.cache
        +|-- /plugins
        +|-- /public
        +|-- /src
        +|-- /api
        +|-- /pages
        +|-- /templates
        +|-- html.js
        +|-- /static
        +|-- gatsby-config.js
        +|-- gatsby-node.js
        +|-- gatsby-ssr.js
        +|-- gatsby-browser.js
        +

        Folders

        +
          +
        • /.cache Automatically generated. This folder is an internal cache created automatically by Gatsby. The files inside this folder are not meant for modification. Should be added to the .gitignore file if not added already.
        • +
        • /plugins This folder hosts any project-specific ("local") plugins that aren't published as an npm package. Check out the plugin docs for more detail.
        • +
        • /public Automatically generated. The output of the build process will be exposed inside this folder. Should be added to the .gitignore file if not added already.
        • +
        • /src This directory will contain all of the code related to what you will see on the frontend of your site (what you see in the browser), like your site header, or a page template. "src" is a convention for "source code".
            +
          • /api JavaScript and TypeScript files under src/api become functions automatically with paths based on their file name. Check out the functions guide for more detail.
          • +
          • /pages Components under src/pages become pages automatically with paths based on their file name. Check out the pages recipes for more detail.
          • +
          • /templates Contains templates for programmatically creating pages. Check out the templates docs for more detail.
          • +
          • html.js For custom configuration of default .cache/default_html.js. Check out the custom HTML docs for more detail.
          • +
          +
        • +
        • /static If you put a file into the static folder, it will not be processed by webpack. Instead it will be copied into the public folder untouched. Check out the assets docs for more detail. +Files
        • +
        • gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser.
        • +
        • gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. Check out the config docs for more detail.
        • +
        • gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
        • +
        • gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. +Misc +Misc +The file/folder structure described above reflects Gatsby-specific files and folders. Since Gatsby sites are also React apps, it's common to use standard React code organization patterns such as folders like /components and /utils inside /src. The React docs have more information on a typical React app folder structure.
        • +
        +
        +

        Layout Components | Gatsby

        +
        +

        Excerpt

        +
        +

        In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from…

        +
        +
        +

        In this guide, you'll learn Gatsby's approach to layouts, how to create and use layout components, and how to prevent layout components from unmounting. +Gatsby's approach to layouts +Gatsby does not, by default, automatically apply layouts to pages (there are, however, ways to do so which will be covered in a later section). Instead, Gatsby follows React's compositional model of importing and using components. This makes it possible to create multiple levels of layouts, e.g. a global header and footer, and then on some pages, a sidebar menu. It also makes it possible to pass data between layout and page components. +What are layout components? +Layout components are for sections of your site that you want to share across multiple pages. For example, Gatsby sites will commonly have a layout component with a shared header and footer. Other common things to add to layouts are a sidebar and/or navigation menu. On this page for example, the header at the top is part of gatsbyjs.com's layout component. +How to create layout components +It is recommended to create your layout components alongside the rest of your components (e.g. into src/components/). +Here is an example of a very basic layout component at src/components/layout.js:

        +
        import React from "react"export default function Layout({ children }) {  return (    <div style={{ margin: `0 auto`, maxWidth: 650, padding: `0 1rem` }}>       {children}    </div>   )}
        +

        How to import and add layout components to pages +If you want to apply a layout to a page, you will need to include the Layout component and wrap your page in it. For example, here is how you would apply your layout to the front page:

        +
        import React from "react"import Layout from "../components/layout"export default function Home() {  return (    <Layout>       <h1> I'm in a layout!</h1>     </Layout>   );}
        +

        Repeat for every page and template that needs this layout. +How to prevent layout components from unmounting +As mentioned earlier, Gatsby does not, by default, automatically wrap pages in a layout component. The "top level" component is the page itself. As a result, when the "top level" component changes between pages, React will re-render all children. This means that shared components like navigations will unmount and remount. This will break CSS transitions or React state within those shared components. +If you need to set a wrapper component around page components that won't get unmounted on page changes, use the wrapPageElement browser API and the SSR equivalent. +Alternatively, you can prevent your layout component from unmounting by using gatsby-plugin-layout, which implements the wrapPageElement APIs for you.

        +
        +

        Adding Markdown Pages | Gatsby

        +
        +

        Excerpt

        +

        Gatsby can use Markdown files to create pages in your site. +You add plugins to read and understand folders with Markdown files and from them…

        +
        +
        +

        Gatsby can use Markdown files to create pages in your site. You add plugins to read and understand folders with Markdown files and from them create pages automatically. +Here are the steps Gatsby follows for making this happen.

        +
          +
        1. Read files into Gatsby from the filesystem
        2. +
        3. Transform Markdown to HTML and frontmatter to data
        4. +
        5. Add a Markdown file
        6. +
        7. Create a Collection Route component for the Markdown files +Read files into Gatsby from the filesystem +Use the plugin gatsby-source-filesystem to read files. +Install +npm install gatsby-source-filesystem +Add PluginAdd plugin +Open gatsby-config.js to add the gatsby-source-filesystem plugin. The path option is how you set the directory to search for files.
          module.exports = {  siteMetadata: {
          + title: "My Gatsby Site",  },  
          +plugins: [    {
          +  resolve: `gatsby-source-filesystem`,
          +options: {
          +     name: `markdown-pages`,
          +path: `${__dirname}/src/markdown-pages`,
          +},  
          +},  
          +],}
          +
          Completing the above step means that you've "sourced" the Markdown files from the filesystem. You can now "transform" the Markdown to HTML and the YAML frontmatter to JSON. +Transform Markdown to HTML and frontmatter to data using gatsby-transformer-remark +You'll use the plugin gatsby-transformer-remark to recognize files which are Markdown and read their content. The plugin will convert the frontmatter metadata part of your Markdown files as frontmatter and the content part as HTML. +Install transformer plugin +npm install gatsby-transformer-remark +Configure plugin +Add this to gatsby-config.js after the previously added gatsby-source-filesystem.
          module.exports = {  siteMetadata: {
          + title: "My Gatsby Site",  },  
          +plugins: [    {
          +  resolve: `gatsby-source-filesystem`,
          +options: {
          +     name: `markdown-pages`,
          +path: `${__dirname}/src/markdown-pages`,
          +},  
          +},  
          +`gatsby-transformer-remark`,  ],
          +}
          +
          Add a Markdown file +Create a folder in the /src directory of your Gatsby application called markdown-pages. Now create a Markdown file inside it with the name post-1.md. +Frontmatter for metadata in Markdown files +When you create a Markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called "frontmatter" and is denoted by the triple dashes at the start and end of the block. This block will be parsed by gatsby-transformer-remark as YAML. You can then query the data through the GraphQL API from your React components. +src/markdown-pages/post-1.md
          ---slug: "/blog/my-first-post"date: "2019-05-04"title: "My first blog post"---
          +
          What is important in this step is the key pair slug. The value that is assigned to the key slug is used in order to navigate to your post. +Create a Collection Route for the Markdown files +Create src/pages/{MarkdownRemark.frontmatter__slug}.js and add the following code: +src/pages/{MarkdownRemark.frontmatter__slug}.js
          import React from "react"
          +import { graphql } from "gatsby"export default function Template({  data, }) {  const { markdownRemark } = data   const { frontmatter, html } = markdownRemark  return (    <div className="blog-post-container">       <div className="blog-post">         <h1> {frontmatter.title}</h1>         <h2> {frontmatter.date}</h2>         <div          className="blog-post-content"          dangerouslySetInnerHTML={{__html: html }}        />       </div>     </div>   )}export const pageQuery = graphql`  query($id: String!) {    markdownRemark(id: {
          +eq: $id }) {      html      frontmatter {        date(formatString: "MMMM DD, YYYY")        slug        title      }    }  }`
          +
          Two things are important in the file above:
        8. +
        9. A GraphQL query is made in the second half of the file to get the Markdown data. Gatsby has automagically given you all the Markdown metadata and HTML in this query's result. + Note: To learn more about GraphQL, consider this excellent resource
        10. +
        11. The result of the query is injected by Gatsby into the component as the data prop. props.data.markdownRemark is the property that has all the details of the Markdown file. +Next you could create a page component at src/pages/blog/index.js to serve as a listing page for all your blog posts. +This should get you started on some basic Markdown functionality in your Gatsby site. You can further customize the frontmatter and the component file to get desired effects! +For more information, have a look in the working example using-markdown-pages. You can find it in the Gatsby examples section. +Other tutorials +
        12. +
        +
        +

        Overview

        +

        The _.get() method in Lodash retrieves the object’s value at a specific path. +If the value is not present at the object’s specific path, it will be resolved as undefined. This method will return the default value if specified in such a case.

        +

        Syntax

        +
        _.get(object, path, defaultValue)
        +
        +

        Parameters

        +

        This method accepts the following parameters:

        +
          +
        • object: The object in which the given path will be queried.
        • +
        • path: The path used to retrieve the value from the object.
        • +
        • defaultValue: The default value that will be returned for resolved values that are undefined.

          Return value

          +This method will return the value at the specified path if found. Otherwise, it will return the default value if specified.

          Example

          +Let’s look at an example of the _.get() method in the code snippet below:

          Explanation

          +In the HTML tab:
        • +
        • Line 5: We import the lodash script. +In the JavaScript tab:
        • +
        • Lines 2 to 15: We create an object to perform a query.
        • +
        • Line 18: We define a variable collegeYopPath to get the value.
        • +
        • Lines 19: We use the _.get() method and pass the object, collegeYopPath, and a default value as parameters.
        • +
        • Line 22: We define a variable falsyPath to get the value.
        • +
        • Lines 23: We use the _.get() method and pass the object, falsyPath and a default value as parameters.

          Output

          +
        • +
        • The _.get() method at line 19 contains a valid path, and therefore the expression is resolved, and 2021 is printed on the console.
        • +
        • The _.get() method at Line 23 contains an invalid path, and therefore the expression is resolved as undefined.
        • +
        +
        +

        Technoloy

        +

        tech-stack

        +
        +

        SOURCECODE

        +

        +

        Overview

        +

        The _.get() method in Lodash retrieves the object’s value at a specific path. +If the value is not present at the object’s specific path, it will be resolved as undefined. This method will return the default value if specified in such a case.

        +

        Syntax

        +
        _.get(object, path, defaultValue)
        +
        +

        Parameters

        +

        This method accepts the following parameters:

        +
          +
        • object: The object in which the given path will be queried.
        • +
        • path: The path used to retrieve the value from the object.
        • +
        • defaultValue: The default value that will be returned for resolved values that are undefined.

          Return value

          +This method will return the value at the specified path if found. Otherwise, it will return the default value if specified.

          Example

          +Let’s look at an example of the _.get() method in the code snippet below:

          Explanation

          +In the HTML tab:
        • +
        • Line 5: We import the lodash script. +In the JavaScript tab:
        • +
        • Lines 2 to 15: We create an object to perform a query.
        • +
        • Line 18: We define a variable collegeYopPath to get the value.
        • +
        • Lines 19: We use the _.get() method and pass the object, collegeYopPath, and a default value as parameters.
        • +
        • Line 22: We define a variable falsyPath to get the value.
        • +
        • Lines 23: We use the _.get() method and pass the object, falsyPath and a default value as parameters.

          Output

          +
        • +
        • The _.get() method at line 19 contains a valid path, and therefore the expression is resolved, and 2021 is printed on the console.
        • +
        • The _.get() method at Line 23 contains an invalid path, and therefore the expression is resolved as undefined.
        • +
        +
        +
        bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f
        +>>>>>>> master
         .
         ├── ./components
         │   ├── ./components/ActionLink.js
        @@ -2954,6 +5472,7 @@ 

        SOURCECODE

        ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js +<<<<<<< HEAD 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ @@ -3592,11 +6111,665 @@

        Source Code

        <tr> <td style={{ +======= +21 directories, 119 files +bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ +

        +
        +

        Source Code

        +

        + Folder Structure (src) +. +├── Combined_____-_____Doc.md +├── components +│ ├── ActionLink.js +│ ├── CtaButtons.js +│ ├── DarkToggle +│ │ ├── index.js +│ │ └── styles.js +│ ├── DocsMenu.js +│ ├── DocsSubmenu.js +│ ├── Footer.js +│ ├── Header.js +│ ├── Icon.js +│ ├── Layout.js +│ ├── SectionContent.js +│ ├── SectionCta.js +│ ├── SectionDocs.js +│ ├── SectionGrid.js +│ ├── SectionHero.js +│ ├── Submenu.js +│ ├── global.css +│ └── index.js +├── data +│ └── doc_sections.yml +├── hooks +│ ├── addScript.js +│ ├── index.js +│ ├── useDarkMode.js +│ ├── useEventListener.js +│ ├── useMediaQuery.js +│ ├── useOnClickOutside.js +│ ├── useQueryParam.js +│ ├── useSize.js +│ └── useStorage.js +├── html.js +├── pages +│ ├── blog +│ │ ├── 300-react-questions.md +│ │ ├── awesome-graphql.md +│ │ ├── big-o-complexity.md +│ │ ├── blog-archive.md +│ │ ├── blogwcomments.md +│ │ ├── data-structures.md +│ │ ├── flow-control-in-python.md +│ │ ├── functions-in-python.md +│ │ ├── git-gateway.md +│ │ ├── index.md +│ │ ├── interview-questions-js.md +│ │ ├── netlify-cms.md +│ │ ├── platform-docs.md +│ │ ├── python-for-js-dev.md +│ │ ├── python-resources.md +│ │ ├── web-dev-trends.md +│ │ └── web-scraping.md +│ ├── docs +│ │ ├── about +│ │ │ ├── eng-portfolio.md +│ │ │ ├── ideas-for-this-website.md +│ │ │ ├── index.md +│ │ │ ├── intrests.md +│ │ │ ├── job-search.md +│ │ │ └── resume.md +│ │ ├── articles +│ │ │ ├── basic-web-dev.md +│ │ │ ├── buffers.md +│ │ │ ├── dev-dep.md +│ │ │ ├── event-loop.md +│ │ │ ├── fs-module.md +│ │ │ ├── how-the-web-works.md +│ │ │ ├── http.md +│ │ │ ├── index.md +│ │ │ ├── install.md +│ │ │ ├── intro.md +│ │ │ ├── modules.md +│ │ │ ├── nextjs.md +│ │ │ ├── node-api-express.md +│ │ │ ├── node-cli-args.md +│ │ │ ├── node-common-modules.md +│ │ │ ├── node-env-variables.md +│ │ │ ├── node-js-language.md +│ │ │ ├── node-package-manager.md +│ │ │ ├── node-repl.md +│ │ │ ├── node-run-cli.md +│ │ │ ├── nodejs.md +│ │ │ ├── nodevsbrowser.md +│ │ │ ├── npm.md +│ │ │ ├── npx.md +│ │ │ ├── os-module.md +│ │ │ ├── reading-files.md +│ │ │ ├── semantic-html.md +│ │ │ ├── semantic.md +│ │ │ ├── the-uniform-resource-locator-(url).md +│ │ │ ├── understanding-firebase.md +│ │ │ ├── v8.md +│ │ │ ├── web-standards-checklist.md +│ │ │ ├── webdev-tools.md +│ │ │ └── writing-files.md +│ │ ├── audio +│ │ │ ├── audio-feature-extraction.md +│ │ │ ├── audio.md +│ │ │ ├── dfft.md +│ │ │ ├── discrete-fft.md +│ │ │ ├── dtw-python-explained.md +│ │ │ ├── dynamic-time-warping.md +│ │ │ ├── index.md +│ │ │ └── web-audio-api.md +│ │ ├── career +│ │ │ ├── dev-interview.md +│ │ │ ├── index.md +│ │ │ ├── interview-dos-n-donts.md +│ │ │ └── job-boards.md +│ │ ├── community +│ │ │ ├── an-open-letter-2-future-developers.md +│ │ │ ├── index.md +│ │ │ └── video-chat.md +│ │ ├── content +│ │ │ ├── algo.md +│ │ │ ├── archive.md +│ │ │ ├── gatsby-Queries-Mutations.md +│ │ │ ├── history-api.md +│ │ │ ├── index.md +│ │ │ ├── main-projects.md +│ │ │ └── trouble-shooting.md +│ │ ├── data-structures +│ │ │ └── index.md +│ │ ├── docs +│ │ │ ├── appendix.md +│ │ │ ├── art-of-command-line.md +│ │ │ ├── bash.md +│ │ │ ├── content.md +│ │ │ ├── css.md +│ │ │ ├── data-structures-docs.md +│ │ │ ├── es-6-features.md +│ │ │ ├── git-reference.md +│ │ │ ├── git-repos.md +│ │ │ ├── html-spec.md +│ │ │ ├── index.md +│ │ │ ├── markdown.md +│ │ │ ├── no-whiteboarding.md +│ │ │ ├── node-docs-complete.md +│ │ │ ├── node-docs-full.md +│ │ │ ├── regex-in-js.md +│ │ │ └── sitemap.md +│ │ ├── faq +│ │ │ ├── contact.md +│ │ │ ├── index.md +│ │ │ └── plug-ins.md +│ │ ├── gists.md +│ │ ├── index.md +│ │ ├── interact +│ │ │ ├── callstack-visual.md +│ │ │ ├── clock.md +│ │ │ ├── index.md +│ │ │ ├── jupyter-notebooks.md +│ │ │ ├── other-sites.md +│ │ │ └── video-chat.md +│ │ ├── interview +│ │ │ ├── index.md +│ │ │ ├── job-search-nav.md +│ │ │ └── review-concepts.md +│ │ ├── javascript +│ │ │ ├── arrow-functions.md +│ │ │ ├── asyncjs.md +│ │ │ ├── await-keyword.md +│ │ │ ├── bigo.md +│ │ │ ├── clean-code.md +│ │ │ ├── constructor-functions.md +│ │ │ ├── index.md +│ │ │ ├── promises.md +│ │ │ ├── review.md +│ │ │ └── this-is-about-this.md +│ │ ├── leetcode +│ │ │ └── index.md +│ │ ├── privacy-policy.md +│ │ ├── projects +│ │ │ ├── embeded-websites.md +│ │ │ ├── index.md +│ │ │ ├── list-of-projects.md +│ │ │ ├── mini-projects.md +│ │ │ └── my-websites.md +│ │ ├── python +│ │ │ ├── at-length.md +│ │ │ ├── cheat-sheet.md +│ │ │ ├── comprehensive-guide.md +│ │ │ ├── examples.md +│ │ │ ├── flow-control.md +│ │ │ ├── functions.md +│ │ │ ├── google-sheets-api.md +│ │ │ ├── index.md +│ │ │ ├── intro-for-js-devs.md +│ │ │ ├── python-ds.md +│ │ │ └── snippets.md +│ │ ├── quick-reference +│ │ │ ├── Emmet.md +│ │ │ ├── all-emojis.md +│ │ │ ├── create-react-app.md +│ │ │ ├── git-bash.md +│ │ │ ├── git-tricks.md +│ │ │ ├── google-firebase.md +│ │ │ ├── heroku-error-codes.md +│ │ │ ├── index.md +│ │ │ ├── installation.md +│ │ │ ├── markdown-dropdowns.md +│ │ │ ├── minifiction.md +│ │ │ ├── new-repo-instructions.md +│ │ │ ├── psql-setup.md +│ │ │ ├── pull-request-rubric.md +│ │ │ ├── quick-links.md +│ │ │ ├── topRepos.md +│ │ │ ├── understanding-path.md +│ │ │ └── vscode-themes.md +│ │ ├── react +│ │ │ ├── ajax-n-apis.md +│ │ │ ├── cheatsheet.md +│ │ │ ├── createReactApp.md +│ │ │ ├── demo.md +│ │ │ ├── dont-use-index-as-keys.md +│ │ │ ├── index.md +│ │ │ ├── jsx.md +│ │ │ ├── react-docs.md +│ │ │ ├── react-in-depth.md +│ │ │ ├── react2.md +│ │ │ └── render-elements.md +│ │ ├── reference +│ │ │ ├── awesome-lists.md +│ │ │ ├── awesome-static.md +│ │ │ ├── bash-commands.md +│ │ │ ├── bookmarks.md +│ │ │ ├── embed-the-web.md +│ │ │ ├── github-search.md +│ │ │ ├── google-cloud.md +│ │ │ ├── how-2-reinstall-npm.md +│ │ │ ├── how-to-kill-a-process.md +│ │ │ ├── index.md +│ │ │ ├── installing-node.md +│ │ │ ├── intro-to-nodejs.md +│ │ │ ├── notes-template.md +│ │ │ ├── psql.md +│ │ │ ├── resources.md +│ │ │ ├── vscode.md +│ │ │ └── web-api's.md +│ │ ├── search.md +│ │ ├── sitemap.md +│ │ ├── tips +│ │ │ ├── array-methods.md +│ │ │ ├── index.md +│ │ │ └── insert-into-array.md +│ │ ├── tools +│ │ │ ├── Archive.md +│ │ │ ├── data-structures.md +│ │ │ ├── dev-utilities.md +│ │ │ ├── index.md +│ │ │ └── markdown-html.md +│ │ └── tutorials +│ │ ├── enviorment-setup.md +│ │ └── index.md +│ ├── index.md +│ ├── privacy-policy.md +│ ├── readme.md +│ └── showcase.md +├── sass +│ ├── imports +│ │ ├── _animations.scss +│ │ ├── _buttons.scss +│ │ ├── _docs.scss +│ │ ├── _footer.scss +│ │ ├── _forms.scss +│ │ ├── _functions.scss +│ │ ├── _general.scss +│ │ ├── _header.scss +│ │ ├── _helpers.scss +│ │ ├── _icons.scss +│ │ ├── _palettes.scss +│ │ ├── _posts.scss +│ │ ├── _prism.scss +│ │ ├── _reset.scss +│ │ ├── _sections.scss +│ │ ├── _structure.scss +│ │ ├── _tables.scss +│ │ └── _variables.scss +│ └── main.scss +├── templates +│ ├── advanced.js +│ ├── blog.js +│ ├── docs.js +│ ├── page.js +│ ├── post.js +│ └── templates.md +└── utils + ├── attribute.js + ├── blm-badge.js + ├── classNames.js + ├── cycler.js + ├── getData.js + ├── getPage.js + ├── getPageByFilePath.js + ├── getPages.js + ├── htmlToReact.js + ├── index.js + ├── link.js + ├── markdownify.js + ├── pathJoin.js + ├── toStyleObj.js + ├── toUrl.js + └── withPrefix.js +32 directories, 272 files +
        +
        + Click To See Component Sourcecode
        +

        Component Structure

        +
        .
        +├── ActionLink.js
        +├── CtaButtons.js
        +├── DarkToggle
        +│     ├── index.js
        +│     └── styles.js
        +├── DocsMenu.js
        +├── DocsSubmenu.js
        +├── Footer.js
        +├── Header.js
        +├── Icon.js
        +├── Layout.js
        +├── SectionContent.js
        +├── SectionCta.js
        +├── SectionDocs.js
        +├── SectionGrid.js
        +├── SectionHero.js
        +├── Submenu.js
        +├── global.css
        +└── index.js
        +

        +
        import React from 'react';
        +import _ from 'lodash';
        +import { Link, withPrefix, classNames } from '../utils';
        +import Icon from './Icon';
        +export default class ActionLink extends React.Component {
        +    render() {
        +        let action = _.get(this.props, 'action', null);
        +        return (
        +            <Link
        +                to={withPrefix(_.get(action, 'url', null))}
        +                {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)}
        +                {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null)
        +                    ? {
        +                          rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '')
        +                      }
        +                    : null)}
        +                className={classNames({
        +                    button: _.get(action, 'style', null) !== 'link',
        +                    'button-secondary': _.get(action, 'style', null) === 'secondary',
        +                    'button-icon': _.get(action, 'style', null) === 'icon'
        +                })}
        +            >
        +                {_.get(action, 'style', null) === 'icon' &&_.get(action, 'icon_class', null) ? (
        +                    <React.Fragment>
        +                        <Icon {...this.props} icon={_.get(action, 'icon_class', null)} />
        +                        <span className="screen-reader-text"> {_.get(action, 'label', null)}</span>
        +                    </React.Fragment>
        +                ) : (
        +                    _.get(action, 'label', null)
        +                )}
        +            </Link>
        +        );
        +    }
        +}
        +
        +
        +

        Table of Contents

        +
          +
        • [getPage][1]
            +
          • [Parameters][2]
          • +
          +
        • +
        • [getPageByFilePath][3]
            +
          • [Parameters][4]
          • +
          +
        • +
        • [getPages][5]
            +
          • [Parameters][6]
          • +
          • [Examples][7]
          • +
          +
        • +
        +
        +

        getPage

        +

        Get the page at the provided urlPath.

        +

        Parameters

        +
          +
        • pages [Array][8] Array of page objects. All pages must have 'url' field.
        • +
        • urlPath [string][9] The url path to find the page by +Returns [Object][10]
        • +
        +
        +

        getPageByFilePath

        +

        Get the page at the provided filePath.

        +

        Parameters

        +
          +
        • pages [Array][8] Array of page objects. All pages must have 'url' field.
        • +
        • filePath [string][9] The file path to find the page by +Returns [Object][10]
        • +
        +
        +

        getPages

        +

        Get all the pages located under the provided urlPath, not including the +index page. I.e.: All pages having their URLs start with urlPath excluding +the page having its URL equal to urlPath.

        +

        Parameters

        +
          +
        • pages Array Array of page objects. All pages must have 'url' field.
        • +
        • urlPath string The url path to filter pages by

          Examples

          +
          pages => [
          +{url: '/'},
          +{url: '/about'},
          +{url: '/posts'},
          +{url: '/posts/hello'},
          +{url: '/posts/world'}
          +]
          +getPages(pages, /posts')
          +=> [
          +{url: '/posts/hello'},
          +{url: '/posts/world'}
          +]
          +
          +Returns Array
        • +
        +
        import React from 'react';
        +import_ from 'lodash';
        +import { Link, withPrefix, classNames } from '../utils';
        +export default class CtaButtons extends React.Component {
        +    render() {
        +        let actions = _.get(this.props, 'actions', null);
        +return_.map(actions, (action, action_idx) => (
        +            <Link
        +                key={action_idx}
        +                to={withPrefix(_.get(action, 'url', null))}
        +                {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)}
        +                {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null)
        +                    ? {
        +                          rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '')
        +                      }
        +                    : null)}
        +                className={classNames({
        +button:_.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary',
        +'button-secondary':_.get(action, 'style', null) === 'secondary'
        +                })}
        +            >
        +                {_.get(action, 'label', null)}
        +            </Link>
        +        ));
        +    }
        +}
        +
        +
        +
        import React from 'react';
        +import_ from 'lodash';
        +import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils';
        +import DocsSubmenu from './DocsSubmenu';
        +export default class DocsMenu extends React.Component {
        +    render() {
        +        let site = _.get(this.props, 'site', null);
        +let page =_.get(this.props, 'page', null);
        +        let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null);
        +        let root_page = getPage(this.props.pageContext.pages, root_docs_path);
        +        return (
        +            <nav id="docs-nav" className="docs-nav">
        +                <div id="docs-nav-inside" className="docs-nav-inside sticky">
        +                    <button id="docs-nav-toggle" className="docs-nav-toggle">
        +                        Navigate Docs
        +                        <span className="icon-angle-right" aria-hidden="true" />
        +                    </button>
        +                    <div className="docs-nav-menu">
        +                        <ul id="docs-menu" className="docs-menu">
        +                            <li
        +                                className={classNames('docs-menu-item', {
        +current:_.get(page, 'url', null) === _.get(root_page, 'url', null)
        +                                })}
        +                            >
        +                                <Link to={withPrefix(_.get(root_page, 'url', null))}> {_.get(root_page, 'frontmatter.title', null)}</Link>
        +                            </li>
        +                            {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => {
        +                                let section_path = pathJoin(root_docs_path, section);
        +                                let section_page = getPage(this.props.pageContext.pages, section_path);
        +                                let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight');
        +let child_count =_.size(child_pages);
        +                                let has_children = child_count > 0 ? true : false;
        +                                let is_current_page = _.get(page, 'url', null) ===_.get(section_page, 'url', null) ? true : false;
        +                                let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null));
        +                                return (
        +                                    <React.Fragment key={section_idx + '.1'}>
        +                                        <li
        +                                            key={section_idx}
        +                                            className={classNames('docs-menu-item', {
        +                                                'has-children': has_children,
        +                                                current: is_current_page,
        +                                                active: is_active
        +                                            })}
        +                                        >
        +                                            <Link to={withPrefix(_.get(section_page, 'url', null))}> {_.get(section_page, 'frontmatter.title', null)}</Link>
        +                                            {has_children && (
        +                                                <React.Fragment>
        +                                                    <button className="docs-submenu-toggle">
        +                                                        <span className="screen-reader-text"> Submenu</span>
        +                                                        <span className="icon-angle-right" aria-hidden="true" />
        +                                                    </button>
        +                                                    <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} />
        +                                                </React.Fragment>
        +                                            )}
        +                                        </li>
        +                                    </React.Fragment>
        +                                );
        +                            })}
        +                        </ul>
        +                    </div>
        +                </div>
        +            </nav>
        +        );
        +    }
        +}
        +
        +
        +
        import React from 'react';
        +import _from 'lodash';
        +import { classNames, Link, withPrefix } from '../utils';
        +export default class DocsSubmenu extends React.Component {
        +    render() {
        +let child_pages =_.get(this.props, 'child_pages', null);
        +        let page = _.get(this.props, 'page', null);
        +        return (
        +            <ul className="docs-submenu">
        +                {_.map(child_pages, (child_page, child_page_idx) => (
        +                    <li
        +                        key={child_page_idx}
        +                        className={classNames('docs-menu-item', {
        +                            current: _.get(page, 'url', null) ===_.get(child_page, 'url', null)
        +                        })}
        +                    >
        +                        <Link to={withPrefix(_.get(child_page, 'url', null))}> {_.get(child_page, 'frontmatter.title', null)}</Link>
        +                    </li>
        +                ))}
        +            </ul>
        +        );
        +    }
        +}
        +
        +
        +
        import _ from 'lodash';
        +import React from 'react';
        +import { htmlToReact } from '../utils';
        +import ActionLink from './ActionLink';
        +import addScript from './../hooks/addScript';
        +const Script = (props) => {
        +    importScript('./../hooks/addScript.js');
        +};
        +export default class Footer extends React.Component {
        +    render() {
        +        return (
        +            <footer id="colophon" className="site-footer outer">
        +                <div>
        +                    <center>
        +                        <br />
        +                        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/algoliasearch-netlify-frontend@1/dist/algoliasearchNetlify.css" />
        +                        <br />
        +                        <table cellPadding={0} cellSpacing={0} border={0}>
        +                            <tbody>
        +                                <tr>
        +                                    <td
        +                                        style={{
        +                                            fontFamily: 'Arial, Helvetica, sans-serif',
        +                                            fontSize: '7.5pt'
        +                                        }}
        +                                    >
        +                                        <center>
        +                                            <table
        +                                                width="95%"
        +                                                cellPadding={0}
        +                                                cellSpacing={0}
        +                                                border={0}
        +                                                style={{
        +                                                    fontFamily: 'Arial, Helvetica, sans-serif',
        +                                                    fontSize: '7.5pt'
        +                                                }}
        +                                            >
        +                                                <tbody>
        +                                                    <tr>
        +                                                        <td
        +                                                            style={{
        +                                                                fontFamily: 'Arial, Helvetica, sans-serif',
        +                                                                fontSize: '7.5pt'
        +                                                            }}
        +                                                            align="left"
        +                                                        >
        +                                                            <a target="_blank" href="https://search.freefind.com/siteindex.html?si=14588965">
        +                                                                index
        +                                                            </a>
        +                                                        </td>
        +                                                        <td
        +                                                            style={{
        +                                                                fontFamily: 'Arial, Helvetica, sans-serif',
        +                                                                fontSize: '7.5pt'
        +                                                            }}
        +                                                            align="center"
        +                                                        >
        +                                                            <a target="_blank" href="https://search.freefind.com/find.html?si=14588965&m=0&p=0">
        +                                                                sitemap
        +                                                            </a>
        +                                                        </td>
        +                                                        <td
        +                                                            style={{
        +                                                                fontFamily: 'Arial, Helvetica, sans-serif',
        +                                                                fontSize: '7.5pt'
        +                                                            }}
        +                                                            align="right"
        +                                                        >
        +                                                            <a target="_blank" href="https://search.freefind.com/find.html?si=14588965&pid=a">
        +                                                                advanced
        +                                                            </a>
        +                                                        </td>
        +                                                    </tr>
        +                                                </tbody>
        +                                            </table>
        +                                        </center>
        +                                        <form
        +                                            style={{
        +                                                margin: '0px',
        +                                                marginTop: '2px'
        +                                            }}
        +                                            action="https://search.freefind.com/find.html"
        +                                            method="get"
        +                                            acceptCharset="utf-8"
        +                                            target="_self"
        +                                        >
        +                                            <input type="hidden" name="si" defaultValue={14588965} />
        +                                            <input type="hidden" name="pid" defaultValue="r" />
        +                                            <input type="hidden" name="n" defaultValue={0} />
        +                                            <input type="hidden" name="_charset_" defaultValue />
        +                                            <input type="hidden" name="bcd" defaultValue="÷" />
        +                                            <input type="text" name="query" size={15} />
        +                                            <input type="submit" defaultValue="search" />
        +                                        </form>
        +                                    </td>
        +                                </tr>
        +                                <tr>
        +                                    <td
        +                                        style={{
        +>>>>>>> master
                                                     textAlign: 'center',
                                                     fontFamily: 'Arial, Helvetica, sans-serif',
                                                     fontSize: '7.5pt',
                                                     paddingTop: '4px'
                                                 }}
        +<<<<<<< HEAD
                     >
                     <a
                     style={{
        @@ -3776,6 +6949,171 @@ 

        Source Code

        height={40} viewBox="0 0 250 250" style={{ +======= + > + <a + style={{ + textDecoration: 'none', + color: 'transparent' + }} + href="https://www.freefind.com" + rel="nofollow" + > + search engine + </a> + <a + style={{ + textDecoration: 'none', + color: 'transparent' + }} + href="https://www.freefind.com" + rel="nofollow" + > + by + <span style={{ color: 'transparent' }}> freefind</span> + </a> + { + <iframe + src="https://bgoonz.github.io/fb-and-twitter-api-embeds/" + frameborder="0" + id="social-embed" + width="100%!important" + > + {' '} + </iframe> + } + </td> + </tr> + </tbody> + </table> + <a href="//pdfcrowd.com/url_to_pdf/?" onclick="if(!this.p)href+='&url='+encodeURIComponent(location.href);this.p=1"> + Save to PDF + </a> + </center> + </div> + <div className="inner"> + <div id="search" className="inner"> + {' '} + </div> + <div className="site-footer-inside"> + <p className="site-info"> + {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( + <span className="copyright"> {htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> + )} + {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( + <ActionLink key={action_idx} {...this.props} action={action} /> + ))}{' '} + </p> + {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( + <div className="social-links"> + {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( + <ActionLink key={action_idx} {...this.props} action={action} /> + ))}{' '} + </div> + )}{' '} + </div> + </div> + </footer> + ); + } +} +
        +
        +
        import React from 'react';
        +import_ from 'lodash';
        +import { Link, withPrefix, classNames } from '../utils';
        +import ActionLink from './ActionLink';
        +import Submenu from './Submenu';
        +export default class Header extends React.Component {
        +    render() {
        +        return (
        +            <header id="masthead" className="site-header outer">
        +                {/*<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/algoliasearch-netlify-frontend@1/dist/algoliasearchNetlify.css" />*/}
        +                <br />
        +                <div className="inner">
        +                    <div className="site-header-inside">
        +                        <div className="site-branding">
        +                            {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? (
        +                                <p className="site-logo">
        +                                    <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}>
        +                                        <img
        +                                            src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))}
        +                                            alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)}
        +                                        />
        +                                    </Link>
        +                                </p>
        +                            ) : (
        +                                <p className="site-title">
        +                                    {' '}
        +                                    WebDevHub
        +                                    <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}>
        +                                        {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)}
        +                                    </Link>
        +                                </p>
        +                            )}
        +                        </div>
        +                        <div id="search" className="inner">
        +                            {' '}
        +                        </div>
        +                        {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && (
        +                            <React.Fragment>
        +                                <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation">
        +                                    <div className="site-nav-inside">
        +                                        <button id="menu-close" className="menu-toggle">
        +                                            <span className="screen-reader-text"> Open Menu</span>
        +                                            <span className="icon-close" aria-hidden="true" />
        +                                        </button>
        +                                        <ul className="menu">
        +                                            {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => {
        +let page_url =_.trim(_.get(this.props, 'pageContext.url', null), '/');
        +let action_url =_.trim(_.get(action, 'url', null), '/');
        +                                                return (
        +                                                    <li
        +                                                        key={action_idx}
        +                                                        className={classNames('menu-item', {
        +'has-children':_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null),
        +                                                            current: page_url === action_url,
        +'menu-button':_.get(action, 'style', null) !== 'link'
        +                                                        })}
        +                                                    >
        +                                                        <ActionLink {...this.props} action={action} />
        +                                                        {_.get(action, 'has_subnav', null) &&_.get(action, 'subnav_links', null) && (
        +                                                            <React.Fragment>
        +                                                                <button className="submenu-toggle">
        +                                                                    <span className="icon-angle-right" aria-hidden="true" />
        +                                                                    <span className="screen-reader-text"> Sub-menu</span>
        +                                                                </button>
        +                                                                <Submenu
        +                                                                    {...this.props}
        +                                                                    submenu={_.get(action, 'subnav_links', null)}
        +                                                                    menu_class={'submenu'}
        +                                                                    page={this.props.pageContext}
        +                                                                />
        +                                                            </React.Fragment>
        +                                                        )}
        +                                                    </li>
        +                                                );
        +                                            })}
        +                                        </ul>
        +                                    </div>
        +                                </nav>
        +                                <button id="menu-open" className="menu-toggle">
        +                                    <span className="screen-reader-text"> Close Menu</span>
        +                                    <span className="icon-menu" aria-hidden="true" />
        +                                </button>
        +                            </React.Fragment>
        +                        )}
        +                    </div>
        +                </div>
        +                <div>
        +                    <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github">
        +                        <svg
        +                            aria-hidden="true"
        +                            width={40}
        +                            height={40}
        +                            viewBox="0 0 250 250"
        +                            style={{
        +>>>>>>> master
                                         zIndex: 100000,
                                         fill: 'black',
                                         color: '#fff',
        @@ -3785,6 +7123,7 @@ 

        Source Code

        left: '0px', transform: 'scale(-1.5, 1.5)' }} +<<<<<<< HEAD > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path @@ -4719,3 +8058,96 @@

        Source Code

        +======= + > + <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"> </path> + <path + className="octo-arm" + d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" + fill="currentColor" + style={{ transformOrigin: '130px 106px' }} + > + {' '} + </path> + <path + className="octo-body" + d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" + fill="currentColor" + > + {' '} + </path> + </svg> + </a> + </div> + </header> + ); + } +} +
        +
        +
        import React from 'react';
        +import _from 'lodash';
        +export default class Icon extends React.Component {
        +    render() {
        +let icon =_.get(this.props, 'icon', null);
        +        return (
        +            <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
        +                {icon === 'dev' ? (
        +                    <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" />
        +                ) : icon === 'facebook' ? (
        +                    <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" />
        +                ) : icon === 'github' ? (
        +                    <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
        +                ) : icon === 'instagram' ? (
        +                    <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" />
        +                ) : icon === 'linkedin' ? (
        +                    <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
        +                ) : icon === 'pinterest' ? (
        +                    <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" />
        +                ) : icon === 'reddit' ? (
        +                    <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" />
        +                ) : icon === 'twitter' ? (
        +                    <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" />
        +                ) : icon === 'youtube' ? (
        +                    <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" />
        +                ) : (
        +                    icon === 'vimeo' && (
        +                        <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" />
        +                    )
        +                )}
        +            </svg>
        +        );
        +    }
        +}
        +
        +
        + +
        +
        + + + + + + + + + + +>>>>>>> master diff --git a/docs/js/waypoints.min.js b/docs/js/waypoints.min.js index 6e5d6c059b..93c70a0fba 100644 --- a/docs/js/waypoints.min.js +++ b/docs/js/waypoints.min.js @@ -6,6 +6,7 @@ https://github.com/imakewebthings/jquery-waypoints/blob/master/MIT-license.txt https://github.com/imakewebthings/jquery-waypoints/blob/master/GPL-license.txt */ (function ($, k, m, i, d) { +<<<<<<< HEAD var e = $(i), g = 'waypoint.reached', b = function (o, n) { @@ -260,3 +261,51 @@ https://github.com/imakewebthings/jquery-waypoints/blob/master/GPL-license.txt $[m]('refresh'); }); })(jQuery, 'waypoint', 'waypoints', window); +======= +var e = $(i), g = 'waypoint.reached', b = function (o, n) { +o.element.trigger(g, n);if (o.options.triggerOnce) {o.element[k]('destroy');} +}, h = function (p, o) { +if (!o) {return -1;}var n = o.waypoints.length - 1;while (n >= 0 && o.waypoints[n].element[0] !== p[0]) {n -= 1}return n +}, f = [], l = function (n) { +$.extend(this, { element:$(n), oldScroll:0, waypoints:[], didScroll:false, didResize:false, doScroll:$.proxy(function () { +var q = this.element.scrollTop(), p = q > this.oldScroll, s = this, r = $.grep(this.waypoints, function (u, t) {return p ? (u.offset > s.oldScroll && u.offset <= q) : (u.offset <= s.oldScroll && u.offset > q)}), o = r.length;if (!this.oldScroll || !q) {$[m]("refresh")}this.oldScroll = q;if (!o) {return }if (!p) {r.reverse()}$.each(r, function (u, t) {if (t.options.continuous || u === o - 1) {b(t, [p ? "down" : "up"])}}) +}, this) });$(n).bind("scroll.waypoints", $.proxy(function () {if (!this.didScroll) { +this.didScroll = true;i.setTimeout($.proxy(function () { +this.doScroll();this.didScroll = false +}, this), $[m].settings.scrollThrottle) +}}, this)).bind("resize.waypoints", $.proxy(function () {if (!this.didResize) { +this.didResize = true;i.setTimeout($.proxy(function () { +$[m]("refresh");this.didResize = false +}, this), $[m].settings.resizeThrottle) +}}, this));e.load($.proxy(function () {this.doScroll()}, this)) +}, j = function (n) { +var o = null;$.each(f, function (p, q) {if (q.element[0] === n) { +o = q;return false +}});return o +}, c = { init:function (o, n) { +this.each(function () { +var u = $.fn[k].defaults.context, q, t = $(this);if (n && n.context) {u = n.context}if (!$.isWindow(u)) {u = t.closest(u)[0]}q = j(u);if (!q) { +q = new l(u);f.push(q) +}var p = h(t, q), s = p < 0 ? $.fn[k].defaults : q.waypoints[p].options, r = $.extend({}, s, n);r.offset = r.offset === "bottom-in-view" ? function () { +var v = $.isWindow(u) ? $[m]("viewportHeight") : $(u).height();return v - $(this).outerHeight() +} : r.offset;if (p < 0) {q.waypoints.push({ element:t, offset:null, options:r })}else {q.waypoints[p].options = r}if (o) {t.bind(g, o)}if (n && n.handler) {t.bind(g, n.handler)} +});$[m]("refresh");return this +}, remove:function () {return this.each(function (o, p) { +var n = $(p);$.each(f, function (r, s) { +var q = h(n, s);if (q >= 0) { +s.waypoints.splice(q, 1);if (!s.waypoints.length) { +s.element.unbind("scroll.waypoints resize.waypoints");f.splice(r, 1) +} +} +}) +})}, destroy:function () {return this.unbind(g)[k]("remove")} }, a = { refresh:function () {$.each(f, function (r, s) { +var q = $.isWindow(s.element[0]), n = q ? 0 : s.element.offset().top, p = q ? $[m]("viewportHeight") : s.element.height(), o = q ? 0 : s.element.scrollTop();$.each(s.waypoints, function (u, x) { +if (!x) {return }var t = x.options.offset, w = x.offset;if (typeof x.options.offset === "function") {t = x.options.offset.apply(x.element)}else {if (typeof x.options.offset === "string") { +var v = parseFloat(x.options.offset);t = x.options.offset.indexOf("%") ? Math.ceil(p * (v / 100)) : v +}}x.offset = x.element.offset().top - n + o - t;if (x.options.onlyOnScroll) {return }if (w !== null && s.oldScroll > w && s.oldScroll <= x.offset) {b(x, ["up"])}else {if (w !== null && s.oldScroll < w && s.oldScroll >= x.offset) {b(x, ["down"])}else {if (!w && s.element.scrollTop() > x.offset) {b(x, ["down"])}}} +});s.waypoints.sort(function (u, t) {return u.offset - t.offset}) +})}, viewportHeight:function () {return (i.innerHeight ? i.innerHeight : e.height())}, aggregate:function () { +var n = $();$.each(f, function (o, p) {$.each(p.waypoints, function (q, r) {n = n.add(r.element)})});return n +} };$.fn[k] = function (n) {if (c[n]) {return c[n].apply(this, Array.prototype.slice.call(arguments, 1))}else {if (typeof n === "function" || !n) {return c.init.apply(this, arguments)}else {if (typeof n === "object") {return c.init.apply(this, [null, n])}else {$.error("Method " + n + " does not exist on jQuery " + k)}}}};$.fn[k].defaults = { continuous:true, offset:0, triggerOnce:false, context:i };$[m] = function (n) {if (a[n]) {return a[n].apply(this)}else {return a.aggregate()}};$[m].settings = { resizeThrottle:200, scrollThrottle:100 };e.load(function () {$[m]("refresh")}) +})(jQuery, "waypoint", "waypoints", window); +>>>>>>> master diff --git a/eslintrc.json b/eslintrc.json deleted file mode 100644 index 2395c9ae4a..0000000000 --- a/eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "env": { - "node": true, - "es6": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 2018 - } -} diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index 923c76d2fc..0000000000 Binary files a/favicon.ico and /dev/null differ diff --git a/functions/deploy-succeeded.js b/functions/deploy-succeeded.js deleted file mode 100644 index 3311aac61b..0000000000 --- a/functions/deploy-succeeded.js +++ /dev/null @@ -1,31 +0,0 @@ -const contextCondition = 'production'; -const stateCondition = 'ready'; -const sitemapUrl = process.env.SITEMAP_URL; -const axios = require( 'axios' ); -exports.handler = async ( event ) => { - try { - const { - payload - } = JSON.parse( event.body ); - const { - state, - context - } = payload; - if ( sitemapUrl && state === stateCondition && context === contextCondition ) { - console.log( `Sending sitemap ping to google for ${sitemapUrl}` ); - await axios.get( `http://www.google.com/ping?sitemap=${sitemapUrl}` ); - return { - statusCode: 200, - body: `Submitted Successfully` - }; - } - console.log( 'Conditions not met, not submitting' ); - return { - statusCode: 200, - body: `Conditions not met, not submitting` - }; - } catch ( err ) { - console.log( err ); - throw err; - } -}; diff --git a/gatsby-browser.js b/gatsby-browser.js index 5f2652bffd..4b408692b6 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -9,21 +9,21 @@ // window.onGatsbyInitialClientRender() has run let initialized = false; exports.onInitialClientRender = () => { - initialized = true; - if ( 'onGatsbyInitialClientRender' in window && typeof window.onGatsbyInitialClientRender === 'function' ) { - window.onGatsbyInitialClientRender(); - } - if ( 'onGatsbyRouteUpdate' in window && typeof window.onGatsbyRouteUpdate === 'function' ) { - window.onGatsbyRouteUpdate(); - } + initialized = true; + if ( 'onGatsbyInitialClientRender' in window && typeof window.onGatsbyInitialClientRender === 'function' ) { + window.onGatsbyInitialClientRender(); + } + if ( 'onGatsbyRouteUpdate' in window && typeof window.onGatsbyRouteUpdate === 'function' ) { + window.onGatsbyRouteUpdate(); + } }; exports.onRouteUpdate = () => { - if ( initialized && 'onGatsbyRouteUpdate' in window && typeof window.onGatsbyRouteUpdate === 'function' ) { - window.onGatsbyRouteUpdate(); - } + if ( initialized && 'onGatsbyRouteUpdate' in window && typeof window.onGatsbyRouteUpdate === 'function' ) { + window.onGatsbyRouteUpdate(); + } }; exports.onPreRouteUpdate = () => { - if ( initialized && 'onGatsbyPreRouteUpdate' in window && typeof window.onGatsbyPreRouteUpdate === 'function' ) { - window.onGatsbyPreRouteUpdate(); - } + if ( initialized && 'onGatsbyPreRouteUpdate' in window && typeof window.onGatsbyPreRouteUpdate === 'function' ) { + window.onGatsbyPreRouteUpdate(); + } }; diff --git a/gatsby-browser.jsx b/gatsby-browser.jsx new file mode 100644 index 0000000000..9c867a7d5e --- /dev/null +++ b/gatsby-browser.jsx @@ -0,0 +1,9 @@ +const React = require("react") +const Layout = require("./src/components/layout") +// Logs when the client route changes +exports.onRouteUpdate = ({ location, prevLocation }) => { + console.log("new pathname", location.pathname) + console.log("old pathname", prevLocation ? prevLocation.pathname : null) +} +// Wraps every page in a component +exports.wrapPageElement = ({ element, props }) => {{element} \ No newline at end of file diff --git a/gatsby-config.js b/gatsby-config.js index e7ab2591c0..41e481b0ee 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -1,44 +1,82 @@ -const siteMetadata = require( './site-metadata.json' ); +/* Importing the site-metadata.json file and exporting it as a module. */ +const siteMetadata = require('./site-metadata.json'); module.exports = { - pathPrefix: '/', - siteMetadata: siteMetadata, - plugins: [ - `gatsby-plugin-react-helmet`, - `gatsby-source-data`, - `gatsby-transformer-remark`, - { - resolve: `gatsby-source-filesystem`, - options: { - name: `pages`, - path: `${__dirname}/src/pages` - } - }, - { - resolve: `gatsby-plugin-disqus`, - options: { - shortname: `webdevhub-1`, - } - }, - { - resolve: `gatsby-plugin-sass`, - options: {} - }, - { - resolve: `gatsby-remark-page-creator`, - options: {} - }, - { - resolve: `@stackbit/gatsby-plugin-menus`, - options: { - sourceUrlPath: `fields.url`, - pageContextProperty: `menus`, - }, - }, - { - resolve: `gatsby-plugin-disqus`, - options: { - shortname: `webdevhub-1` - } - }, - ] + pathPrefix: '/', + siteMetadata, + plugins: [ + 'gatsby-plugin-react-helmet', + 'gatsby-source-data', + 'gatsby-transformer-remark', + { + resolve: 'gatsby-source-filesystem', + options: { + name: 'pages', + path: `${__dirname}/src/pages` + } + }, + { + resolve: 'gatsby-transformer-remark', + options: { + plugins: ['gatsby-remark-prismjs'], + }, + }, + { + resolve: 'gatsby-remark-code-buttons', + options: { + // Optional button container class name. Defaults + // to 'gatsby-code-button-container'. + buttonContainerClass: 'customButtonContainerClass', + // Optional button class name. Defaults to 'gatsby-code-button'. + buttonClass: 'customButtonClass', + // Optional button text. Defaults to ''. + buttonText: 'customButtonText', + // Optional svg icon class name. Defaults to 'gatsby-code-button-icon'. + svgIconClass: 'customSvgIconClass', + // Optional svg icon. Defaults to svg string and can be + // replaced with any other valid svg. Use custom classes + // in the svg string and skip `iconClass` option. + svgIcon: 'customSvgIcon', + // Optional tooltip text. Defaults to ''. + tooltipText: 'customTooltipText', + // Optional toaster class name. Defaults to ''. + toasterClass: 'customToasterClass', + // Optional toaster text class name. Defaults to ''. + toasterTextClass: 'customToasterTextClass', + // Optional toaster text. Defaults to ''. + toasterText: 'customToasterText', + // Optional toaster duration. Defaults to 3500. + toasterDuration: 5000 + }, + }, + { + resolve: 'gatsby-plugin-disqus', + options: { + shortname: 'webdevhub-1', + } + }, + { + resolve: 'gatsby-plugin-no-sourcemaps', + }, + { + resolve: 'gatsby-plugin-sass', + options: {} + }, + { + resolve: 'gatsby-remark-page-creator', + options: {} + }, + { + resolve: '@stackbit/gatsby-plugin-menus', + options: { + sourceUrlPath: 'fields.url', + pageContextProperty: 'menus', + }, + }, + { + resolve: 'gatsby-plugin-disqus', + options: { + shortname: 'webdevhub-1' + } + }, + ] }; diff --git a/gatsby-node.js b/gatsby-node.js index a1bfac02e7..ea499190fe 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -1,5 +1,11 @@ -/** - * Implement Gatsby's Node APIs in this file. - * - * See: https://www.gatsbyjs.org/docs/node-apis/ - */ +// const path = require('path'); +// +// exports.onCreateWebpackConfig = ({ +// actions +// }) => { +// actions.setWebpackConfig({ +// resolve: { +// modules: [path.resolve(__dirname, 'src'), 'node_modules'] +// } +// }); +// }; diff --git a/gatsby-ssr.js b/gatsby-ssr.js index 506dc68bf4..ee23f0b8c3 100644 --- a/gatsby-ssr.js +++ b/gatsby-ssr.js @@ -1,3 +1,4 @@ +/* It's adding the scripts to the page. */ /** * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. * @@ -8,6 +9,7 @@ // + +;' . x | ex "$f"; done +echo "" | tee -a *.html \ No newline at end of file diff --git a/scripts/create-dir.js b/scripts/create-dir.js new file mode 100644 index 0000000000..b677a9a6f4 --- /dev/null +++ b/scripts/create-dir.js @@ -0,0 +1,10 @@ +const fs = require('fs') + +fs.mkdir('./newdir', err => { + if (err) { + console.error(err) + return + } + + console.log('directory created') +}) \ No newline at end of file diff --git a/scripts/create-dummy-text-file-4-every-subfolder.sh b/scripts/create-dummy-text-file-4-every-subfolder.sh new file mode 100644 index 0000000000..301631f2f3 --- /dev/null +++ b/scripts/create-dummy-text-file-4-every-subfolder.sh @@ -0,0 +1,6 @@ +for x in "./"/*/; do + (cd "$x" + files=(*) + printf '%s\n' "${files[@]}" > deleteme.txt + ) +done \ No newline at end of file diff --git a/scripts/delete-files-bigger-than.sh b/scripts/delete-files-bigger-than.sh new file mode 100644 index 0000000000..33a9507442 --- /dev/null +++ b/scripts/delete-files-bigger-than.sh @@ -0,0 +1 @@ +find . -size +75M -a -print -a -exec rm -f {} \; \ No newline at end of file diff --git a/scripts/delete-git-files.sh b/scripts/delete-git-files.sh new file mode 100644 index 0000000000..8d5cbdf725 --- /dev/null +++ b/scripts/delete-git-files.sh @@ -0,0 +1 @@ +find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + \ No newline at end of file diff --git a/scripts/delete-zip.sh b/scripts/delete-zip.sh new file mode 100644 index 0000000000..d2e0d59451 --- /dev/null +++ b/scripts/delete-zip.sh @@ -0,0 +1,8 @@ + +# check what you are about to delete before deleting: + +find . -name "*.zip" -type f -print + +#Delete: + +find . -name "*.zip" -type f -print -delete \ No newline at end of file diff --git a/scripts/dir-stream.js b/scripts/dir-stream.js new file mode 100644 index 0000000000..b6a0d148e7 --- /dev/null +++ b/scripts/dir-stream.js @@ -0,0 +1,42 @@ +const fs = require('fs') + +// The async `opendir` method creates a stream from the directory +// passed as its first argument. The stream is present in the callback +fs.opendir('./', (err, dir) => { + + if (err) { + // log and return if theres any error + console.error(err) + return + } + + // A scoped function is defined that reads the next + // file in the directory and calls itself recursively + const readNext = (dir) => { + // The `read` method gives us information on the + // next file in the directory. If there are no + // more files left, the value of `file` is null + dir.read((err, file) => { + if (err) { + // log and return error + console.error(err) + return + } + + // If file is null, we are done. + if (file === null) { + return + } + + // If the file exists, log the name, along with + // the icon for its type + const type = file.isDirectory() ? '📂' : '📄' + console.log(type, file.name) + // Recursively call `readNext` for the next directory entry + readNext(dir) + }) + } + + // Call the `readNext` function with the first directory entry + readNext(dir) +}) \ No newline at end of file diff --git a/scripts/generate-directory-index.html-from-files-in-working-directory.sh b/scripts/generate-directory-index.html-from-files-in-working-directory.sh new file mode 100644 index 0000000000..7299fcc3d4 --- /dev/null +++ b/scripts/generate-directory-index.html-from-files-in-working-directory.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# find ./ | grep -i "\.*$" >files +find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files +listing="files" + +out="" + +html="index.html" +out="basename $out.html" +html="index.html" +cmd() { + + echo ' ' + echo '' + echo '' + + echo ' ' + + echo ' ' + echo '' + echo ' ' + echo ' ' + + echo " directory " + + echo "" + echo '' + echo '' + + echo '' + + echo "" + + #################### continue with the HTML stuff: + + echo "" + + echo "" + + echo "
          " + + awk '{print "
        • ",$1," 
        • "}' $listing + + # awk '{print "
        • "}; + + # {print " ",$1,"
        •  "}' \ $listing + + echo "" + + echo "
        " + + echo "" + + echo "" + +} + +cmd $listing --sort=extension >>$html \ No newline at end of file diff --git a/scripts/get-links-from-webpage.sh b/scripts/get-links-from-webpage.sh new file mode 100644 index 0000000000..5ecbd911ab --- /dev/null +++ b/scripts/get-links-from-webpage.sh @@ -0,0 +1,11 @@ + + +lynx -dump https://distrokid.com/hyperfollow/mihirbeg/getting-there | awk '/http/{print $2}' > links2.txt + + + +## OR-------------------------------------------------------------------------------- +wget -qO- www.instagram.com/mihirbeg/ | +grep -Eoi ']+>' | +grep -Eo 'href="[^\"]+"' | +grep -Eo '(http|https)://[^/"]+'>output.md \ No newline at end of file diff --git a/scripts/gistfile1.txt b/scripts/gistfile1.txt new file mode 100644 index 0000000000..e21728b47e --- /dev/null +++ b/scripts/gistfile1.txt @@ -0,0 +1,5 @@ +sudo apt install uniq + + + +uniq -u input.txt output.txt diff --git a/scripts/git-filter-branch.sh b/scripts/git-filter-branch.sh new file mode 100644 index 0000000000..0b5a280063 --- /dev/null +++ b/scripts/git-filter-branch.sh @@ -0,0 +1 @@ +git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_website-components/0-DOJO/widgets-master/output/info/stats.json' HEAD diff --git a/scripts/isDir.js b/scripts/isDir.js new file mode 100644 index 0000000000..c2076d0855 --- /dev/null +++ b/scripts/isDir.js @@ -0,0 +1,15 @@ +const fs = require('fs') + +fs.readdir('./', { withFileTypes: true }, (err, files) => { + if (err) { + console.error(err) + return + } + + console.log('files: ') + files.forEach(file => { + // the `isDirectory` method returns true if the entry is a directory + const type = file.isDirectory() ? '📂' : '📄' + console.log(type, file.name) + }) +}) \ No newline at end of file diff --git a/scripts/list-html-files.sh b/scripts/list-html-files.sh new file mode 100644 index 0000000000..9173f0d6ee --- /dev/null +++ b/scripts/list-html-files.sh @@ -0,0 +1 @@ +find ./ | grep -i "\.html*$" \ No newline at end of file diff --git a/scripts/print-file-paths-recursive.sh b/scripts/print-file-paths-recursive.sh new file mode 100644 index 0000000000..800dbf8b65 --- /dev/null +++ b/scripts/print-file-paths-recursive.sh @@ -0,0 +1,5 @@ + +ls -R './' | awk ' +/:$/&&f{s=$0;f=0} +/:$/&&!f{sub(/:$/,"");s=$0;f=1;next} +NF&&f{ print s"/"$0 }'>listing.md \ No newline at end of file diff --git a/scripts/readStream.js b/scripts/readStream.js new file mode 100644 index 0000000000..4346a5ac17 --- /dev/null +++ b/scripts/readStream.js @@ -0,0 +1,37 @@ +const fs = require('fs') +// Initialize the time at which the program started +const startTime = new Date() + +// create a read stream from the `words.txt` file +const rStream = fs.createReadStream('words.txt') + +// initialize total word count +let total = 0 + +// the `on data` method registers a handler for everytime we +// receive new data from the file stream +rStream.on('data', b => { + // `b` here is the chunk of data received from the + // file stream + const bStr = b.toString() + // We split the string by spaces and new lines and add it to the + // total -- we subtract one because of the extra space/newline/broken word + // at the end of the chunk + // we shouldn't do this for the last chunk of data, which we handle later + total += bStr.split(/[\s\n]+/).length - 1 +}) + +rStream.on('end', () => { + // Finally, the `on end` handler is called once the data stream completes + + // we add one to the total, because we shouldn't subtract 1 from the last + // chunk of data in the `data` handler, for which we're compensating here + console.log('total words:', total + 1) + + + // Print the total time taken, as well as the total used program memory + console.log('total time:', (new Date()) - startTime) + + const memoryUsedMb = process.memoryUsage().heapUsed / 1024 / 1024 + console.log('the program used', memoryUsedMb, 'MB') +}) \ No newline at end of file diff --git a/scripts/reading-dir.js b/scripts/reading-dir.js new file mode 100644 index 0000000000..abdc09b6ea --- /dev/null +++ b/scripts/reading-dir.js @@ -0,0 +1,10 @@ +const fs = require('fs') + +fs.readdir('./', (err, files) => { + if (err) { + console.error(err) + return + } + + console.log('files: ', files) +}) \ No newline at end of file diff --git a/scripts/recursive-action.sh b/scripts/recursive-action.sh new file mode 100644 index 0000000000..69544c3510 --- /dev/null +++ b/scripts/recursive-action.sh @@ -0,0 +1,20 @@ +function RecurseDirs () +{ + oldIFS=$IFS + IFS=$'\n' + for f in "$@" + do + + # YOUR CODE HERE! +find . -type f -exec sed -n -e '/```javascript/,/```/p' *.html >out.js ./* {} \; + + + if [[ -d "${f}" ]]; then + cd "${f}" + RecurseDirs $(ls -1 ".") + cd .. + fi + done + IFS=$oldIFS +} +RecurseDirs "./" \ No newline at end of file diff --git a/scripts/recursive-remove-lines-contaning-string.sh b/scripts/recursive-remove-lines-contaning-string.sh new file mode 100644 index 0000000000..b8b72b04ac --- /dev/null +++ b/scripts/recursive-remove-lines-contaning-string.sh @@ -0,0 +1,2 @@ +find . -type f -exec sed -i '/badText/d' ./*.html {} \; +# Recursivley remove from all html files any lines contaning the string "badText" \ No newline at end of file diff --git a/scripts/recursive-unzip.sh b/scripts/recursive-unzip.sh new file mode 100644 index 0000000000..9d4bc02803 --- /dev/null +++ b/scripts/recursive-unzip.sh @@ -0,0 +1,9 @@ +#install unzip: +sudo apt install unzip + +# recursivley unzip all zip files into a folder by the same name: +find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; + + +# recursivley delete .zip files when done: +find . -name "*.zip" -type f -print -delete \ No newline at end of file diff --git a/scripts/recursivley-create-numbered-folders.sh b/scripts/recursivley-create-numbered-folders.sh new file mode 100644 index 0000000000..687fa82029 --- /dev/null +++ b/scripts/recursivley-create-numbered-folders.sh @@ -0,0 +1,6 @@ +n=1; +max=50; +while [ "$n" -le "$max" ]; do + mkdir "s$n" + n=`expr "$n" + 1`; +done \ No newline at end of file diff --git a/scripts/remember-git-credentials.sh b/scripts/remember-git-credentials.sh new file mode 100644 index 0000000000..5209c324b9 --- /dev/null +++ b/scripts/remember-git-credentials.sh @@ -0,0 +1 @@ + git config --global credential.helper store \ No newline at end of file diff --git a/scripts/remove-dir.js b/scripts/remove-dir.js new file mode 100644 index 0000000000..ba2ca6a442 --- /dev/null +++ b/scripts/remove-dir.js @@ -0,0 +1,10 @@ +const fs = require('fs') + +fs.rmdir('./newdir', err => { + if (err) { + console.error(err) + return + } + + console.log('directory deleted') +}) \ No newline at end of file diff --git a/scripts/remove-invalid-characters-from-file-names.sh b/scripts/remove-invalid-characters-from-file-names.sh new file mode 100644 index 0000000000..2b7d77743e --- /dev/null +++ b/scripts/remove-invalid-characters-from-file-names.sh @@ -0,0 +1 @@ +for f in */; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' -e 's/\.\.\././g' -e 's/\.\././g' -e 's/\.*$//'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done \ No newline at end of file diff --git a/scripts/remove-lines-contaning-string.sh b/scripts/remove-lines-contaning-string.sh new file mode 100644 index 0000000000..09920c0ab5 --- /dev/null +++ b/scripts/remove-lines-contaning-string.sh @@ -0,0 +1,13 @@ +sed -i '/target-string/d' ./js-in-one-page.html + + + +# examples: +sed -i '/\.git/d' ./index.html + +# Recursive + + +find . -type f -a \( -name "*.html" -o -name "*.js" -o -name "*.css" -o -name "*.md" \) -a -exec sed -i '/BADSTRING/d' '{}' + + +find . -name "*" -type f | xargs sed -i -e '/Mirrored from/d' \ No newline at end of file diff --git a/scripts/remove-space-from-filenames.sh b/scripts/remove-space-from-filenames.sh new file mode 100644 index 0000000000..01605467dc --- /dev/null +++ b/scripts/remove-space-from-filenames.sh @@ -0,0 +1 @@ + for file in *; do mv "$file" `echo $file | tr ' ' '_'` ; done \ No newline at end of file diff --git a/scripts/remove-string-from-file-names.sh b/scripts/remove-string-from-file-names.sh new file mode 100644 index 0000000000..dc24b904ee --- /dev/null +++ b/scripts/remove-string-from-file-names.sh @@ -0,0 +1 @@ +for filename in *badString*; do mv "$filename" "${filename//badstring/replaceString}"; done \ No newline at end of file diff --git a/scripts/remove-trailing-whitespace-from-file-names.sh b/scripts/remove-trailing-whitespace-from-file-names.sh new file mode 100644 index 0000000000..efea7a915f --- /dev/null +++ b/scripts/remove-trailing-whitespace-from-file-names.sh @@ -0,0 +1 @@ +rename 's/ *$//' * \ No newline at end of file diff --git a/scripts/remove-unnecessary-files-folders.sh b/scripts/remove-unnecessary-files-folders.sh new file mode 100644 index 0000000000..05b1c3b661 --- /dev/null +++ b/scripts/remove-unnecessary-files-folders.sh @@ -0,0 +1,16 @@ +# recursivley remove empty files +find . -empty -type f -print -delete + + + +# recursivley remove empty folders +find . -empty -type d -print -delete + + +# recursively remove .git folder, .gitignore file and .gitmodules file and .gitattributes file +find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + + + + +# Recursivley remove security, release, changelog, License & contributing files +find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + diff --git a/scripts/write-stream.js b/scripts/write-stream.js new file mode 100644 index 0000000000..b0e63e4a93 --- /dev/null +++ b/scripts/write-stream.js @@ -0,0 +1,43 @@ +const fs = require('fs') + +class Fibonacci { + // The Fibonacci class has the previous number and current + // number as its instance attributes + constructor() { + this.prev = 0 + this.current = 1 + } + + // the next method returns the current value, and + // increments the current value by adding the past value to it + next() { + const current = this.current + this.prev = current + this.current = current + this.prev + return current + } +} + +// Iniitalize a writeStream to a a new file "fibonacci.txt" +const writeStream = fs.createWriteStream('fibonacci.txt') + +// the on ready callback gets called once the file is available to write +writeStream.on('ready', () => { + // initialize a new object of the Fibonacci class + const f = new Fibonacci() + + // For each iteration, obtain the next number in the sequence + // and write to the file, adding a newline each time + for (let i = 0; i < 1000; i++) { + const n = f.next() + writeStream.write(String(n) + '\n', err => { + // if there is any error in writing, log it + if (err) { + console.error('error writing:', err) + } + }) + } + + // The `end` method closes the write stream, once we're done + writeStream.end() +}) \ No newline at end of file diff --git a/src/components/ActionLink.js b/src/components/ActionLink.js index 8224d9458d..5f808d1b8e 100644 --- a/src/components/ActionLink.js +++ b/src/components/ActionLink.js @@ -1,31 +1,24 @@ -import _ from 'lodash'; +/* This class is a React component that renders a link to a URL, with optional styling and attributes. */ import React from 'react'; -import { classNames, Link, withPrefix } from '../utils'; +import _ from 'lodash'; + +import {Link, withPrefix, classNames} from '../utils'; import Icon from './Icon'; + export default class ActionLink extends React.Component { render() { let action = _.get(this.props, 'action', null); return ( - - {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon_class', null) ? ( - - - {_.get(action, 'label', null)} - - ) : ( - _.get(action, 'label', null) - )} + + {((_.get(action, 'style', null) === 'icon') && _.get(action, 'icon_class', null)) ? ( + + {_.get(action, 'label', null)} + ) : + _.get(action, 'label', null) + } ); } diff --git a/src/components/CtaButtons.js b/src/components/CtaButtons.js index bb1b03723f..3c6681f879 100644 --- a/src/components/CtaButtons.js +++ b/src/components/CtaButtons.js @@ -1,24 +1,19 @@ -import _ from 'lodash'; +/* It's a React component that renders a button or a link. */ import React from 'react'; -import { classNames, Link, withPrefix } from '../utils'; +import _ from 'lodash'; + +import {Link, withPrefix, classNames} from '../utils'; + export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); - return _.map(actions, (action, action_idx) => ( - - {_.get(action, 'label', null)} - - )); + return ( + _.map(actions, (action, action_idx) => ( + {_.get(action, 'label', null)} + )) + ); } } diff --git a/src/components/DocsMenu.js b/src/components/DocsMenu.js index 5c8ebd1616..ec33f8e4df 100644 --- a/src/components/DocsMenu.js +++ b/src/components/DocsMenu.js @@ -1,67 +1,46 @@ - +/* It's a React component that renders a menu of links to pages in a Hugo site. */ import React from 'react'; import _ from 'lodash'; -import { classNames, getPage, getPages, Link, pathJoin, withPrefix } from '../utils'; + +import {getPage, classNames, Link, withPrefix, pathJoin, getPages} from '../utils'; import DocsSubmenu from './DocsSubmenu'; + export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); - let page = _.get( this.props, 'page', null ); - let rootPath = 'data.doc_sections.root_docs_path'; - let root_docs_path = _.get( site,rootPath, null ); - let pageContextProps = this.props.pageContext.pages; - let root_page = getPage(pageContextProps, root_docs_path); + let page = _.get(this.props, 'page', null); + let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); + let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( ); } diff --git a/src/components/DocsSubmenu.js b/src/components/DocsSubmenu.js index 588027df61..7e0414dad3 100644 --- a/src/components/DocsSubmenu.js +++ b/src/components/DocsSubmenu.js @@ -1,24 +1,20 @@ -import _ from 'lodash'; +/* This class renders a list of links to child pages of the current page. */ import React from 'react'; -import { classNames, Link, withPrefix } from '../utils'; +import _ from 'lodash'; + +import {classNames, Link, withPrefix} from '../utils'; + export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return (
          - {_.map(child_pages, (child_page, child_page_idx) => { - return ( -
        • - { _.get( child_page, 'frontmatter.title', null ) } -
        • - ); - })} + {_.map(child_pages, (child_page, child_page_idx) => ( +
        • + {_.get(child_page, 'frontmatter.title', null)} +
        • + ))}
        ); } diff --git a/src/components/Footer.js b/src/components/Footer.js index f871fe2a1c..bfa89e033e 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -1,3 +1,5 @@ +/* It creates a footer for the website. */ + import _ from 'lodash'; import React from 'react'; import { htmlToReact } from '../utils'; @@ -7,132 +9,85 @@ export default class Footer extends React.Component { return (
        diff --git a/src/components/FormField.js b/src/components/FormField.js new file mode 100644 index 0000000000..315411bf48 --- /dev/null +++ b/src/components/FormField.js @@ -0,0 +1,134 @@ +/* It's a React component that renders a form field based on the props passed to it */ +/* It's a React component that renders a form field based on the props passed to it. */ +import _ from 'lodash'; +import React from 'react'; + +export default class FormField extends React.Component { + render() { + const field = _.get(this.props, 'field'); + const inputType = _.get(field, 'input_type'); + const name = _.get(field, 'name'); + const defaultValue = _.get(field, 'default_value'); + const options = _.get(field, 'options'); + const required = _.get(field, 'is_required'); + const label = _.get(field, 'label'); + const labelId = `${name}-label`; + const attr = {}; + if (label) { + attr['aria-labelledby'] = labelId; + } + if (required) { + attr.required = true; + } + + switch (inputType) { + case 'checkbox': + return ( < + div className = "form-group form-checkbox" > + < + input type = "checkbox" + id = { + name + } + name = { + name + } { + ...attr + } + /> { + label && < label htmlFor = { + name + } > { + label + } < /label>} < + /div> + ); + case 'select': + return ( < + div className = "form-group" > { + label && < label htmlFor = { + name + } > { + label + } < /label>} < + div className = "form-select-wrap" > + < + select id = { + name + } + name = { + name + } { + ...attr + } > { + defaultValue && < option value = "" > { + defaultValue + } < /option>} { + _.map(options, (option, index) => ( < + option key = { + index + } + value = { + option + } > { + option + } < + /option> + )) + } < + /select> < + /div> < + /div> + ); + case 'textarea': return ( < + div className = "form-group" > { + label && < label htmlFor = { + name + } > { + label + } < /label>} < + textarea name = { + name + } + id = { + name + } + rows = "7" { + ...(defaultValue ? { + placeholder: defaultValue + } : null) + } { + ...attr + } + /> < + /div> + ); + default: + return ( < + div className = "form-group" > { + label && < label htmlFor = { + name + } > { + label + } < /label>} < + input type = { + inputType + } + name = { + name + } + id = { + name + } { + ...(defaultValue ? { + placeholder: defaultValue + } : null) + } { + ...attr + } + /> < + /div> + ); + } + } + } \ No newline at end of file diff --git a/src/components/Header.js b/src/components/Header.js index 960044c2c0..64369ff322 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -1,102 +1,116 @@ +/* It's a header component that renders a logo, a navbar, and a search bar. */ import _ from 'lodash'; import React from 'react'; -import { classNames, Link, withPrefix } from '../utils'; +import {classNames, Link, withPrefix} from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return (
        -
        +
        - { _.get( this.props, 'pageContext.site.siteMetadata.header.logo_img', null ) ? ( + { + _.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? (

        - - { + + {

        ) : (

        - - { _.get( this.props, 'pageContext.site.siteMetadata.header.title', null ) } - + + { + _.get(this.props, 'pageContext.site.siteMetadata.header.title', null) + }

        - ) } -
        - { _.get( this.props, 'pageContext.site.siteMetadata.header.has_nav', null ) && ( + ) + }
        + { + _.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( - ) } -
        + ) + } -
        - <> -
        -
        - -

        Search

        -
        -