diff --git a/.eslintignore b/.eslintignore index 50bf6cdd17..8b13789179 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,17 +1 @@ -alphametics -connect -diamond -food-chain -forth -grade-school -grains -list-ops -nth-prime -palindrome-products -queen-attack -rational-numbers -saddle-points -secret-handshake -sublist -twelve-days -variable-length-quantity + diff --git a/.gitattributes b/.gitattributes index 176a458f94..6313b56c57 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text=auto +* text=auto eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6ec34c7086..e2f46ecba4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,6 @@ -# Maintainers +# Maintainers config/maintainers.json @exercism/maintainers-admin # Code owners .github/CODEOWNERS @exercism/maintainers-admin +.github/workflows @exercism/javascript diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b1bb062b7b..e47d44c448 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -3,7 +3,7 @@ # # You may wish to alter this file to override the set of languages analyzed, # or to provide custom queries or build logic. -name: "codeql" +name: 'codeql' on: push: @@ -12,7 +12,7 @@ on: # The branches below must be a subset of the branches above branches: [master] schedule: - - cron: "0 14 * * 5" + - cron: '0 14 * * 5' jobs: analyze: @@ -23,7 +23,7 @@ jobs: matrix: # Override automatic language detection by changing the below list # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] - language: ["javascript"] + language: ['javascript'] # Learn more... # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml new file mode 100644 index 0000000000..f0775dd126 --- /dev/null +++ b/.github/workflows/format-code.yml @@ -0,0 +1,110 @@ +name: 'Format code' + +on: + issue_comment: + types: [created] + +jobs: + format: + name: 'Format code' + runs-on: ubuntu-latest + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/format') + steps: + - name: 'Post acknowledgement that it will format code' + continue-on-error: true # Never fail the build if this fails + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'The "Format code" action has started running.' + }) + + - name: 'Download PR data' + run: | + PR_DATA="/tmp/pr.json" + + jq -r ".issue.pull_request.url" "$GITHUB_EVENT_PATH" | \ + xargs curl --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' -o "$PR_DATA" --url + + - name: 'Check fork status' + id: fork_status + run: | + IS_FORK="$(jq '.head.repo.fork' "/tmp/pr.json")" + echo "::set-output name=fork::$IS_FORK" + + - name: 'Setup SSH deploy key' + if: steps.fork_status.outputs.fork == 'false' + run: | + mkdir ~/.ssh + echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + + - name: 'Checkout code' + run: | + PR_DATA="/tmp/pr.json" + + HEAD_REF=$(jq -r ".head.ref" "$PR_DATA") + + if [ ${{ steps.fork_status.outputs.fork }} == "false" ]; then + echo "::debug::Setting up repo using SSH" + HEAD_REPO=$(jq -r '.head.repo.ssh_url' "$PR_DATA") + else + echo "::debug::Setting up repo using HTTPS" + HEAD_REPO=$(jq -r '.head.repo.clone_url | sub("https://"; "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@")' "$PR_DATA") + fi + + git clone $HEAD_REPO . + git checkout -b "$HEAD_REF" "origin/$HEAD_REF" + + - name: 'Format code' + run: ./bin/format.sh + env: + EXERCISM_PRETTIER_VERSION: '2.1.2' + + - name: 'Commit formatted code' + run: | + # Check if there is nothing to commit (i.e. no formatting changes made) + if [ -z "$(git status --porcelain)" ]; then + echo "Code is already formatted correctly" + exit 0 + fi + + # Setup the git user (required to commit anything) + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + + # Commit the changes made by prettier + git add . + git commit -m "[CI] Format code" + git push + + - name: 'Post acknowledgement that it has formatted the code' + continue-on-error: true # Never fail the build if this fails + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'The "Format code" action has finished running.' + }) + + - name: 'Post reminder to trigger build manually' + continue-on-error: true # Never fail the build if this fails + if: steps.fork_status.outputs.fork == 'true' + uses: actions/github-script@6e5ee1dc1cb3740e5e5e76ad668e3f526edbfe45 # 2.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'For security reasons, `/format` does not trigger CI builds when the PR has been submitted from a fork. If checks were not passing due to code format, trigger a build to make the required checks pass, through one of the following ways:\n\n- Push an empty commit to this branch: `git commit --allow-empty -m "Trigger builds"`.\n- Close and reopen the PR.\n- Push a regular commit to this branch.' + }) diff --git a/.github/workflows/verify-code-formatting.yml b/.github/workflows/verify-code-formatting.yml new file mode 100644 index 0000000000..f938b4bb45 --- /dev/null +++ b/.github/workflows/verify-code-formatting.yml @@ -0,0 +1,18 @@ +name: javascript / format + +on: + push: + pull_request: + workflow_dispatch: + +jobs: + verify: + runs-on: ubuntu-latest + steps: + - name: 'Checkout code' + uses: actions/checkout@v2 + + - name: 'Verify formatting of all files' + run: ./bin/check-formatting.sh + env: + EXERCISM_PRETTIER_VERSION: '2.2.1' diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..b79e5482d8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +exercises/**/README.md +!/README.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..d9b803a046 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": true, + "singleQuote": true, + "endOfLine": "lf" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b173bf0c9b..1cd03f4041 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,27 +6,29 @@ We welcome contributions of all sorts and sizes, from reporting issues to submit --- -- [Code of Conduct](#code-of-conduct) -- [Exercises](#exercises) - - [New exercise](#new-exercise) - - [Implementing existing exercise](#implementing-existing-exercise) - - [ Creating a track-specific exercise](#creating-a-track-specific-exercise) - - [Existing exercises](#existing-exercises) - - [Improving the README.md](#improving-the-readmemd) - - [Syncing the exercise](#syncing-the-exercise) - - [Improving or adding mentor notes](#improving-or-adding-mentor-notes) - - [Improving or adding automated test analyzers](#improving-or-adding-automated-test-analyzers) -- [Documentation](#documentation) -- [Tools](#tools) - - [Fetch `configlet`](#fetch-configlet) - - [Fetch `canonical_data_syncer`](#fetch-canonical-data-syncer) - - [Scripts](#scripts) - - [`lint`](#lint) - - [`test`](#test) - - [`sync`](#sync) - - [`checksum`](#checksum) - - [`ci-check`](#ci-check) - - [`ci`](#ci) +- [Contributing](#contributing) + - [Code of Conduct](#code-of-conduct) + - [Exercises](#exercises) + - [New exercise](#new-exercise) + - [Implementing existing exercise](#implementing-existing-exercise) + - [Creating a track-specific exercise](#creating-a-track-specific-exercise) + - [Existing exercises](#existing-exercises) + - [Improving the README.md](#improving-the-readmemd) + - [Syncing the exercise](#syncing-the-exercise) + - [Improving or adding mentor notes](#improving-or-adding-mentor-notes) + - [Improving or adding automated test analyzers](#improving-or-adding-automated-test-analyzers) + - [Documentation](#documentation) + - [Tools](#tools) + - [Fetch configlet](#fetch-configlet) + - [Fetch canonical data syncer](#fetch-canonical-data-syncer) + - [Scripts](#scripts) + - [`format`](#format) + - [`lint`](#lint) + - [`test`](#test) + - [`sync`](#sync) + - [`checksum`](#checksum) + - [`ci-check`](#ci-check) + - [`ci`](#ci) --- @@ -70,6 +72,7 @@ If there is no such issue, you may open one. The baseline of work is as follows: 1. Run the tests locally, using `scripts/test`: `ASSIGNMENT=slug npx babel-node scripts/test`. 1. Run the linter locally, using `scripts/lint`: `ASSIGNMENT=slug npx babel-node scripts/lint`. 1. Create an entry in `config.json`: a unique _new_ UUID (you can use the `configlet uuid` tool to generate one, scroll down to [tools](#tools) to see how you can get it), give it a difficulty (should be similar to similar exercises), and make sure the _order_ of the file is sane. Currently the file is ordered first on core - non core, then on difficulty low to high, and finally lexographically. +1. Format the files, using `scripts/format`: `npx babel-node scripts/format`. The final step is opening a Pull Request, with these items all checked off. Make sure the tests run and the linter is happy. It will run automatically on your PR. @@ -128,6 +131,8 @@ You'll need LTS or higher NodeJS in order to contribute to the _code_ in this re - `jest` to run all the test files on all example implementations - `babel` to transpile everything so it works _regardless of your version of NodeJS_. +We also use `prettier` to format the files. **Prettier is _NOT_ installed when using `npm install`**, because the CI will enforce a certain version. Instead use `npx babel-node scripts/format` to run prettier. If you want to auto-format using your editor, match the version in the GitHub Workflow `verify-code-formatting.yml`. + ### Fetch configlet If you'd like to download [configlet][configlet], you can use the [`fetch-configlet`][bin-fetch-configlet] binary. It will run on Linux, Mac OSX and Windows, and download `configlet` to your local drive. Find more information about [configlet][configlet] [here][configlet]. @@ -155,6 +160,19 @@ If you'd like to download [`canonical_data_syncer`][canonical-data-syncer], you We have various `scripts` for you in order to aid with maintaining and contributing to this repository. +#### `format` + +```js +/* + * Run this script (from root directory): npx babel-node scripts/format + * + * This runs `prettier` on all applicable files, FORCES using the same version + * as the CI uses to check if the files have been formatted. + */ +``` + +Use this action to format all the files using the correct version of prettier. If you want your editor to do this automatically, make sure you install `prettier` (e.g. `npm install prettier@2.2.1`), where the version matches `.github/workflows/verify-code-formatting.yml`. + #### `lint` ```js diff --git a/README.md b/README.md index 1abfd68335..d227ecdc2a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ contribute to this track. It also has a list of tools you can use, of which the ## Running the test suite -This runs `jest` tests for all sample solutions. This *does not* use the regular way to run `jest`, because the example solution files must be renamed to be imported correctly into the test files. +This runs `jest` tests for all sample solutions. This _does not_ use the regular way to run `jest`, because the example solution files must be renamed to be imported correctly into the test files. ```shell npx babel-node scripts/test @@ -36,18 +36,17 @@ ASSIGNMENT=two-fer npx babel-node scripts/test ## Related repositories -* [Website Copy][git-website-copy] (Mentor Notes) -* [The JavaScript Analyzer][git-javascript-analyzer] (Automated Code Analysis) -* [The JavaScript Test Runner][git-javascript-test-runner] -* [The TypeScript track][git-typescript] -* [The TypeScript Analyzer][git-typescript-analyzer] +- [Website Copy][git-website-copy] (Mentor Notes) +- [The JavaScript Analyzer][git-javascript-analyzer] (Automated Code Analysis) +- [The JavaScript Test Runner][git-javascript-test-runner] +- [The TypeScript track][git-typescript] +- [The TypeScript Analyzer][git-typescript-analyzer] [web-exercism]: https://exercism.io [git-configlet]: https://github.com/exercism/docs/blob/master/language-tracks/configuration/configlet.md [bin-fetch-configlet]: https://github.com/exercism/javascript/blob/master/bin/fetch-configlet [file-config]: https://github.com/exercism/javascript/blob/master/config.json [file-contributing]: https://github.com/exercism/javascript/blob/master/CONTRIBUTING.md - [git-javascript]: https://github.com/exercism/javascript [git-javascript-analyzer]: https://github.com/exercism/javascript-analyzer [git-javascript-test-runner]: https://github.com/exercism/javascript-test-runner diff --git a/babel.config.js b/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/bin/check-formatting.sh b/bin/check-formatting.sh new file mode 100755 index 0000000000..4dc27e9523 --- /dev/null +++ b/bin/check-formatting.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +npx "prettier@$EXERCISM_PRETTIER_VERSION" --check "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}" diff --git a/bin/format.sh b/bin/format.sh new file mode 100755 index 0000000000..2a2141a4f8 --- /dev/null +++ b/bin/format.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if [ -z "$EXERCISM_PRETTIER_VERSION" ]; then + echo "This script requires the EXERCISM_PRETTIER_VERSION variable to work." + echo "Please see https://github.com/exercism/v3/blob/master/docs/maintainers/style-guide.md for guidance." + exit 1 +fi + +npx "prettier@$EXERCISM_PRETTIER_VERSION" --write "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}" diff --git a/bin/lint_all.sh b/bin/lint_all.sh deleted file mode 100755 index 596e9e4941..0000000000 --- a/bin/lint_all.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -script_name=$( basename "$0" ) -script_version="0.0.2" -usage="Usage: ${script_name} [-v|--version|-h|--help]" - -# Parse the command line parameters -while [[ $# -gt 0 ]] -do - param="$1" - case "${param}" in - -v|--version) - echo "${script_name}" version ${script_version} - exit 0 - ;; - -h|--help) - show_help=1 - shift - ;; - *) - echo "${script_name}": unknown option "${param}" - echo "${usage}" - exit 0 - ;; - esac -done - -# Show the help screen -if [[ ${show_help} -eq 1 ]] -then - echo "${usage}" - echo "With no parameters, hides .eslintignore and runs ESLint." - echo "Errors are sent to errors.txt and .eslintignore is" - echo "restored afterwards." - echo - echo "Options:" - echo " -h, --help display this help and exit" - echo " -v, --version display the version number and exit" - exit 0 -fi - -if [ ! -f .eslintignore ] -then - echo ".eslintignore file not found. Are you in the root directory?" - exit 1 -fi - -mv .eslintignore .eslintignore.temp -npx eslint . > errors.txt 2> /dev/null - -# TO-DO - what happens here if Node or ESLint are not installed -# or `npx` does not run for any other reason? - -if [ ! -z $? ] -then - echo "ESLint errors detected. See the file errors.txt for details." -fi - -mv .eslintignore.temp .eslintignore diff --git a/bin/run_example.sh b/bin/run_example.sh deleted file mode 100755 index 2c43849ab8..0000000000 --- a/bin/run_example.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env bash - -script_name=$( basename "$0" ) -script_version="0.0.2" -usage="Usage: ${script_name} [-v|--version|-h|--help]" - -# Parse the command line parameters -while [[ $# -gt 0 ]] -do - param="$1" - case "${param}" in - -v|--version) - echo "${script_name}" version ${script_version} - exit 0 - ;; - -h|--help) - show_help=1 - shift - ;; - *) - echo "${script_name}": unknown option "${param}" - echo "${usage}" - exit 0 - ;; - esac -done - -# Show the help screen -if [[ ${show_help} -eq 1 ]] -then - echo "${usage}" - echo "With no parameters, when run in an exercise directory, " - echo "this script will modify the example.js and *.spec.js files" - echo "so that Jest tests can be run on the example. The script" - echo "should then restore the directory to its original state." - echo "The intended use is to automate the process of making sure" - echo "an exercise still passes the tests before submitting changes." - echo - echo "Options:" - echo " -h, --help display this help and exit" - echo " -v, --version display the version number and exit" - exit 0 -fi - -if [ ! -f example.js ] -then - echo "Example file not found." - exit 0 -fi - -(( spec_files_count = $( ls | grep -c .spec.js ) )) - -if [ ${spec_files_count} -eq 0 ] -then - echo "No test file found." - exit 0 -elif [ ${spec_files_count} -gt 1 ] -then - echo "More than one test file found" - exit 0 -fi - -# To-do: this will probably fail if Jest is globally installed -# instead of locally. -jest_bin="../../node_modules/.bin/jest" -spec_file=$( ls *.spec.js ) -tmp_spec_file="tmp-${spec_file}" -js_file=${spec_file//.spec./.} -sed 's/ xtest/test/g' "${spec_file}" > "${tmp_spec_file}" -cp example.js ${js_file} -"${jest_bin}" "${tmp_spec_file}" -rm ${js_file} -rm "${tmp_spec_file}" - -exit 0 diff --git a/bin/tools/copy-babel-config b/bin/tools/copy-babel-config deleted file mode 100755 index 6dbb583a0f..0000000000 --- a/bin/tools/copy-babel-config +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env node - -/** - * This copies the current .babelrc to a specific exercise folder or to all - * of them if an exercise folder is not given. - * - * Usage: - * - * ./bin/tools/copy-babel-config - */ - -// @ts-check - -const fs = require('fs'); -const path = require('path'); - -const ROOT_PATH = path.join(__dirname, '..', '..'); -const BABEL_CONFIG_PATH = path.join(ROOT_PATH, 'babel.config.js'); -const EXERCISE = process.argv.slice(2).find(arg => !arg.startsWith('-')); - -process.stdout.write(`=> copy babel config for ${EXERCISE || 'all exercises'}\n`); - - -function execute(exercise) { - const EXERCISE_DIR = path.join(ROOT_PATH, 'exercises', exercise); - const destination = path.join(EXERCISE_DIR, path.basename(BABEL_CONFIG_PATH)); - - fs.copyFile(BABEL_CONFIG_PATH, destination, (err) => { - if (err) { - process.stderr.write(`=> error for ${exercise}: ${err.message}\n`); - } else { - process.stdout.write(`=> copied babel config to ${exercise}\n`); - } - }); - -} - -if (!EXERCISE) { - process.stdin.resume(); - process.stdout.write('?> are you sure? [Y/n]\n'); - process.stdin.once('data', (data) => { - process.stdin.pause(); - - const input = data.toString().trim(); - - if (!/^(?:\s?|y|yes)$/i.test(input)) { - process.stdout.write('=> ok bye\n'); - process.exit(0); - return; - } - - fs.readdir(path.join(ROOT_PATH, 'exercises'), (err, exercises) => { - if (err) { - process.stderr.write(err.message); - process.exit(-1); - } - - exercises.forEach(execute); - }); - }); -} else { - execute(EXERCISE); -} diff --git a/bin/tools/copy-eslint-config b/bin/tools/copy-eslint-config deleted file mode 100755 index 6178119ffc..0000000000 --- a/bin/tools/copy-eslint-config +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env node - -/** - * This copies the current .eslintrc to a specific exercise folder or to all - * of them if an exercise folder is not given. Merges the version field in case - * it's set. - * - * Usage: - * - * ./bin/tools/copy-eslint-config - */ - -// @ts-check - -const fs = require('fs'); -const path = require('path'); - -const ROOT_PATH = path.join(__dirname, '..', '..'); -const BABEL_CONFIG_PATH = path.join(ROOT_PATH, '.eslintrc'); -const EXERCISE = process.argv.slice(2).find(arg => !arg.startsWith('-')); - -process.stdout.write(`=> copy eslint config for ${EXERCISE || 'all exercises'}\n`); - - -function execute(exercise) { - const EXERCISE_DIR = path.join(ROOT_PATH, 'exercises', exercise); - const destination = path.join(EXERCISE_DIR, path.basename(BABEL_CONFIG_PATH)); - - fs.copyFile(BABEL_CONFIG_PATH, destination, (err) => { - if (err) { - process.stderr.write(`=> error for ${exercise}: ${err.message}\n`); - } else { - process.stdout.write(`=> copied eslint config to ${exercise}\n`); - } - }); - -} - -if (!EXERCISE) { - process.stdin.resume(); - process.stdout.write('?> are you sure? [Y/n]\n'); - process.stdin.once('data', (data) => { - process.stdin.pause(); - - const input = data.toString().trim(); - - if (!/^(?:\s?|y|yes)$/i.test(input)) { - process.stdout.write('=> ok bye\n'); - process.exit(0); - return; - } - - fs.readdir(path.join(ROOT_PATH, 'exercises'), (err, exercises) => { - if (err) { - process.stderr.write(err.message); - process.exit(-1); - } - - exercises.forEach(execute); - }); - }); -} else { - execute(EXERCISE); -} diff --git a/bin/tools/copy-package-json b/bin/tools/copy-package-json deleted file mode 100755 index be5f8c7ca7..0000000000 --- a/bin/tools/copy-package-json +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env node - -/** - * This copies the current package.json to a specific exercise folder or to all - * of them if an exercise folder is not given. Merges the version field in case - * it's set. - * - * Usage: - * - * ./bin/tools/copy-package-json - */ - -// @ts-check - -const fs = require('fs'); -const path = require('path'); - -const ROOT_PATH = path.join(__dirname, '..', '..'); -const EXERCISE = process.argv.slice(2).find(arg => !arg.startsWith('-')); - -process.stdout.write(`=> copy package.json for ${EXERCISE || 'all exercises'}\n`); - -function formatAsJson(data) { - return JSON.stringify(data, null, 2) + '\n'; -} - -// @ts-ignore -const BASE_PACKAGE_JSON = require('../../package.json'); - -function execute(exercise) { - const EXERCISE_DIR = path.join(ROOT_PATH, 'exercises', exercise); - const EXERCISE_PACKAGE_JSON = path.join(EXERCISE_DIR, 'package.json'); - - fs.readFile(EXERCISE_PACKAGE_JSON, (err, data) => { - const current = JSON.parse(err ? JSON.stringify(BASE_PACKAGE_JSON) : data.toString()); - const mergedPackage = formatAsJson( - { - ...BASE_PACKAGE_JSON, - version: current.version, - }, - ); - - fs.writeFile(EXERCISE_PACKAGE_JSON, mergedPackage, (innerErr) => { - if (innerErr) { - process.stderr.write(`=> error for ${exercise}: ${err.message}\n`); - } else { - process.stdout.write(`=> copied package.json to ${exercise}\n`); - } - }); - }); -} - -if (!EXERCISE) { - process.stdin.resume(); - process.stdout.write('?> are you sure? [Y/n]\n'); - process.stdin.once('data', (data) => { - process.stdin.pause(); - - const input = data.toString().trim(); - - if (!/^(?:\s?|y|yes)$/i.test(input)) { - process.stdout.write('=> ok bye\n'); - process.exit(0); - return; - } - - fs.readdir(path.join(ROOT_PATH, 'exercises'), (err, exercises) => { - if (err) { - process.stderr.write(err.message); - process.exit(-1); - } - - exercises.forEach(execute); - }); - }); -} else { - execute(EXERCISE); -} - -// Sanity check matching whitespace -fs.writeFile(path.join(ROOT_PATH, 'package.json'), formatAsJson(BASE_PACKAGE_JSON), () => {}); diff --git a/config.json b/config.json index a195a48fdf..6d40440a34 100644 --- a/config.json +++ b/config.json @@ -24,11 +24,7 @@ "core": true, "unlocked_by": null, "difficulty": 1, - "topics": [ - "optional_values", - "strings", - "text_formatting" - ] + "topics": ["optional_values", "strings", "text_formatting"] }, { "slug": "resistor-color", @@ -36,10 +32,7 @@ "core": true, "unlocked_by": null, "difficulty": 1, - "topics": [ - "arrays", - "strings" - ] + "topics": ["arrays", "strings"] }, { "slug": "resistor-color-duo", @@ -47,10 +40,7 @@ "core": true, "unlocked_by": null, "difficulty": 2, - "topics": [ - "strings", - "arrays" - ] + "topics": ["strings", "arrays"] }, { "slug": "gigasecond", @@ -58,9 +48,7 @@ "core": true, "unlocked_by": null, "difficulty": 1, - "topics": [ - "time" - ] + "topics": ["time"] }, { "slug": "rna-transcription", @@ -68,10 +56,7 @@ "core": true, "unlocked_by": null, "difficulty": 2, - "topics": [ - "strings", - "transforming" - ] + "topics": ["strings", "transforming"] }, { "slug": "space-age", @@ -79,9 +64,7 @@ "core": true, "unlocked_by": null, "difficulty": 2, - "topics": [ - "floating_point_numbers" - ] + "topics": ["floating_point_numbers"] }, { "slug": "pangram", @@ -105,10 +88,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 3, - "topics": [ - "classes", - "conditionals" - ] + "topics": ["classes", "conditionals"] }, { "slug": "matrix", @@ -144,13 +124,7 @@ "core": true, "unlocked_by": null, "difficulty": 4, - "topics": [ - "conditionals", - "loops", - "math", - "strings", - "text_formatting" - ] + "topics": ["conditionals", "loops", "math", "strings", "text_formatting"] }, { "slug": "linked-list", @@ -174,11 +148,7 @@ "core": true, "unlocked_by": null, "difficulty": 5, - "topics": [ - "arrays", - "maps", - "sorting" - ] + "topics": ["arrays", "maps", "sorting"] }, { "slug": "list-ops", @@ -186,12 +156,7 @@ "core": true, "unlocked_by": null, "difficulty": 6, - "topics": [ - "data_structures", - "loops", - "lists", - "recursion" - ] + "topics": ["data_structures", "loops", "lists", "recursion"] }, { "slug": "robot-name", @@ -260,11 +225,7 @@ "core": false, "unlocked_by": "resistor-color", "difficulty": 1, - "topics": [ - "booleans", - "integers", - "logic" - ] + "topics": ["booleans", "integers", "logic"] }, { "slug": "reverse-string", @@ -272,10 +233,7 @@ "core": false, "unlocked_by": "resistor-color", "difficulty": 2, - "topics": [ - "loops", - "strings" - ] + "topics": ["loops", "strings"] }, { "slug": "collatz-conjecture", @@ -298,12 +256,7 @@ "core": false, "unlocked_by": "resistor-color", "difficulty": 3, - "topics": [ - "conditionals", - "loops", - "exception_handling", - "integers" - ] + "topics": ["conditionals", "loops", "exception_handling", "integers"] }, { "slug": "clock", @@ -311,11 +264,7 @@ "core": false, "unlocked_by": "gigasecond", "difficulty": 5, - "topics": [ - "dates", - "globalization", - "time" - ] + "topics": ["dates", "globalization", "time"] }, { "slug": "meetup", @@ -338,12 +287,7 @@ "core": false, "unlocked_by": "rna-transcription", "difficulty": 2, - "topics": [ - "loops", - "integers", - "maps", - "transforming" - ] + "topics": ["loops", "integers", "maps", "transforming"] }, { "slug": "hamming", @@ -351,12 +295,7 @@ "core": false, "unlocked_by": "rna-transcription", "difficulty": 2, - "topics": [ - "conditionals", - "loops", - "equality", - "strings" - ] + "topics": ["conditionals", "loops", "equality", "strings"] }, { "slug": "raindrops", @@ -364,12 +303,7 @@ "core": false, "unlocked_by": "rna-transcription", "difficulty": 2, - "topics": [ - "conditionals", - "integers", - "strings", - "transforming" - ] + "topics": ["conditionals", "integers", "strings", "transforming"] }, { "slug": "nucleotide-count", @@ -391,12 +325,7 @@ "core": false, "unlocked_by": "rna-transcription", "difficulty": 5, - "topics": [ - "conditionals", - "loops", - "maps", - "strings" - ] + "topics": ["conditionals", "loops", "maps", "strings"] }, { "slug": "allergies", @@ -404,12 +333,7 @@ "core": false, "unlocked_by": "rna-transcription", "difficulty": 6, - "topics": [ - "arrays", - "bitwise_operations", - "conditionals", - "loops" - ] + "topics": ["arrays", "bitwise_operations", "conditionals", "loops"] }, { "slug": "word-count", @@ -417,12 +341,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 1, - "topics": [ - "loops", - "lists", - "regular_expressions", - "strings" - ] + "topics": ["loops", "lists", "regular_expressions", "strings"] }, { "slug": "difference-of-squares", @@ -430,12 +349,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 3, - "topics": [ - "algorithms", - "loops", - "integers", - "math" - ] + "topics": ["algorithms", "loops", "integers", "math"] }, { "slug": "perfect-numbers", @@ -443,13 +357,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 3, - "topics": [ - "arrays", - "conditionals", - "loops", - "integers", - "math" - ] + "topics": ["arrays", "conditionals", "loops", "integers", "math"] }, { "slug": "complex-numbers", @@ -457,9 +365,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 4, - "topics": [ - "math" - ] + "topics": ["math"] }, { "slug": "luhn", @@ -467,12 +373,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 4, - "topics": [ - "conditionals", - "loops", - "integers", - "strings" - ] + "topics": ["conditionals", "loops", "integers", "strings"] }, { "slug": "prime-factors", @@ -480,13 +381,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 4, - "topics": [ - "algorithms", - "conditionals", - "loops", - "integers", - "math" - ] + "topics": ["algorithms", "conditionals", "loops", "integers", "math"] }, { "slug": "grains", @@ -494,10 +389,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 5, - "topics": [ - "loops", - "integers" - ] + "topics": ["loops", "integers"] }, { "slug": "pythagorean-triplet", @@ -505,13 +397,7 @@ "core": false, "unlocked_by": "space-age", "difficulty": 5, - "topics": [ - "algorithms", - "conditionals", - "loops", - "integers", - "math" - ] + "topics": ["algorithms", "conditionals", "loops", "integers", "math"] }, { "slug": "palindrome-products", @@ -534,10 +420,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 1, - "topics": [ - "filtering", - "strings" - ] + "topics": ["filtering", "strings"] }, { "slug": "acronym", @@ -545,12 +428,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 2, - "topics": [ - "loops", - "regular_expressions", - "strings", - "transforming" - ] + "topics": ["loops", "regular_expressions", "strings", "transforming"] }, { "slug": "high-scores", @@ -558,9 +436,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 2, - "topics": [ - "arrays" - ] + "topics": ["arrays"] }, { "slug": "isogram", @@ -568,10 +444,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 2, - "topics": [ - "filtering", - "strings" - ] + "topics": ["filtering", "strings"] }, { "slug": "matching-brackets", @@ -593,10 +466,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 3, - "topics": [ - "parsing", - "transforming" - ] + "topics": ["parsing", "transforming"] }, { "slug": "series", @@ -604,12 +474,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 3, - "topics": [ - "loops", - "exception_handling", - "strings", - "text_formatting" - ] + "topics": ["loops", "exception_handling", "strings", "text_formatting"] }, { "slug": "largest-series-product", @@ -648,13 +513,7 @@ "core": false, "unlocked_by": "matrix", "difficulty": 4, - "topics": [ - "arrays", - "conditionals", - "loops", - "matrices", - "strings" - ] + "topics": ["arrays", "conditionals", "loops", "matrices", "strings"] }, { "slug": "spiral-matrix", @@ -709,11 +568,7 @@ "core": false, "unlocked_by": "matrix", "difficulty": 8, - "topics": [ - "domain_specific_languages", - "parsing", - "stacks" - ] + "topics": ["domain_specific_languages", "parsing", "stacks"] }, { "slug": "food-chain", @@ -721,10 +576,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 4, - "topics": [ - "algorithms", - "text_formatting" - ] + "topics": ["algorithms", "text_formatting"] }, { "slug": "house", @@ -732,13 +584,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 4, - "topics": [ - "arrays", - "conditionals", - "loops", - "recursion", - "strings" - ] + "topics": ["arrays", "conditionals", "loops", "recursion", "strings"] }, { "slug": "isbn-verifier", @@ -804,11 +650,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 5, - "topics": [ - "conditionals", - "loops", - "strings" - ] + "topics": ["conditionals", "loops", "strings"] }, { "slug": "resistor-color-trio", @@ -816,10 +658,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 5, - "topics": [ - "conditionals", - "loops" - ] + "topics": ["conditionals", "loops"] }, { "slug": "say", @@ -858,11 +697,7 @@ "core": false, "unlocked_by": "pascals-triangle", "difficulty": 5, - "topics": [ - "algorithms", - "floating_point_numbers", - "math" - ] + "topics": ["algorithms", "floating_point_numbers", "math"] }, { "slug": "sublist", @@ -870,10 +705,7 @@ "core": false, "unlocked_by": "linked-list", "difficulty": 4, - "topics": [ - "arrays", - "lists" - ] + "topics": ["arrays", "lists"] }, { "slug": "binary-search-tree", @@ -881,12 +713,7 @@ "core": false, "unlocked_by": "linked-list", "difficulty": 6, - "topics": [ - "algorithms", - "conditionals", - "loops", - "recursion" - ] + "topics": ["algorithms", "conditionals", "loops", "recursion"] }, { "slug": "custom-set", @@ -911,13 +738,7 @@ "core": false, "unlocked_by": "linked-list", "difficulty": 7, - "topics": [ - "algorithms", - "arrays", - "conditionals", - "loops", - "recursion" - ] + "topics": ["algorithms", "arrays", "conditionals", "loops", "recursion"] }, { "slug": "circular-buffer", @@ -940,11 +761,7 @@ "core": false, "unlocked_by": "linked-list", "difficulty": 8, - "topics": [ - "arrays", - "data_structures", - "lists" - ] + "topics": ["arrays", "data_structures", "lists"] }, { "slug": "word-search", @@ -968,10 +785,7 @@ "core": false, "unlocked_by": "grade-school", "difficulty": 5, - "topics": [ - "bitwise_operations", - "transforming" - ] + "topics": ["bitwise_operations", "transforming"] }, { "slug": "two-bucket", @@ -995,10 +809,7 @@ "core": false, "unlocked_by": "grade-school", "difficulty": 7, - "topics": [ - "algorithms", - "games" - ] + "topics": ["algorithms", "games"] }, { "slug": "scale-generator", @@ -1006,12 +817,7 @@ "core": false, "unlocked_by": "pangram", "difficulty": 3, - "topics": [ - "loops", - "pattern_recognition", - "strings", - "arrays" - ] + "topics": ["loops", "pattern_recognition", "strings", "arrays"] }, { "slug": "connect", @@ -1019,14 +825,7 @@ "core": false, "unlocked_by": "grade-school", "difficulty": 7, - "topics": [ - "arrays", - "conditionals", - "loops", - "games", - "maps", - "parsing" - ] + "topics": ["arrays", "conditionals", "loops", "games", "maps", "parsing"] }, { "slug": "bowling", @@ -1066,12 +865,7 @@ "core": false, "unlocked_by": "list-ops", "difficulty": 5, - "topics": [ - "algorithms", - "callbacks", - "loops", - "lists" - ] + "topics": ["algorithms", "callbacks", "loops", "lists"] }, { "slug": "flatten-array", @@ -1079,10 +873,7 @@ "core": false, "unlocked_by": "list-ops", "difficulty": 5, - "topics": [ - "arrays", - "recursion" - ] + "topics": ["arrays", "recursion"] }, { "slug": "nth-prime", @@ -1105,13 +896,7 @@ "core": false, "unlocked_by": "robot-name", "difficulty": 5, - "topics": [ - "conditionals", - "loops", - "integers", - "math", - "recursion" - ] + "topics": ["conditionals", "loops", "integers", "math", "recursion"] }, { "slug": "rotational-cipher", @@ -1119,12 +904,7 @@ "core": false, "unlocked_by": "simple-cipher", "difficulty": 2, - "topics": [ - "conditionals", - "strings", - "text_formatting", - "transforming" - ] + "topics": ["conditionals", "strings", "text_formatting", "transforming"] }, { "slug": "diffie-hellman", @@ -1147,12 +927,7 @@ "core": false, "difficulty": 4, "unlocked_by": "simple-cipher", - "topics": [ - "algorithms", - "arrays", - "filtering", - "math" - ] + "topics": ["algorithms", "arrays", "filtering", "math"] }, { "slug": "atbash-cipher", @@ -1221,13 +996,7 @@ "core": false, "unlocked_by": "secret-handshake", "difficulty": 5, - "topics": [ - "conditionals", - "loops", - "integers", - "lists", - "math" - ] + "topics": ["conditionals", "loops", "integers", "lists", "math"] }, { "slug": "change", @@ -1235,11 +1004,7 @@ "core": false, "unlocked_by": "secret-handshake", "difficulty": 8, - "topics": [ - "algorithms", - "performance", - "searching" - ] + "topics": ["algorithms", "performance", "searching"] }, { "slug": "protein-translation", @@ -1247,12 +1012,7 @@ "core": false, "unlocked_by": null, "difficulty": 1, - "topics": [ - "algorithms", - "conditionals", - "loops", - "strings" - ] + "topics": ["algorithms", "conditionals", "loops", "strings"] }, { "slug": "armstrong-numbers", @@ -1260,10 +1020,7 @@ "core": false, "unlocked_by": null, "difficulty": 2, - "topics": [ - "algorithms", - "math" - ] + "topics": ["algorithms", "math"] }, { "slug": "run-length-encoding", @@ -1295,12 +1052,7 @@ "core": false, "unlocked_by": null, "difficulty": 3, - "topics": [ - "conditionals", - "loops", - "pattern_recognition", - "transforming" - ] + "topics": ["conditionals", "loops", "pattern_recognition", "transforming"] }, { "slug": "all-your-base", @@ -1323,11 +1075,7 @@ "core": false, "unlocked_by": null, "difficulty": 7, - "topics": [ - "algorithms", - "arrays", - "games" - ] + "topics": ["algorithms", "arrays", "games"] }, { "slug": "queen-attack", @@ -1351,11 +1099,7 @@ "core": false, "unlocked_by": null, "difficulty": 8, - "topics": [ - "algorithms", - "events", - "reactive_programming" - ] + "topics": ["algorithms", "events", "reactive_programming"] }, { "slug": "zipper", @@ -1363,11 +1107,7 @@ "core": false, "unlocked_by": null, "difficulty": 8, - "topics": [ - "recursion", - "searching", - "trees" - ] + "topics": ["recursion", "searching", "trees"] }, { "slug": "dnd-character", @@ -1375,10 +1115,7 @@ "core": false, "unlocked_by": null, "difficulty": 2, - "topics": [ - "classes", - "randomness" - ] + "topics": ["classes", "randomness"] }, { "slug": "trinary", @@ -1460,11 +1197,7 @@ "core": false, "unlocked_by": "matrix", "difficulty": 4, - "topics": [ - "files", - "searching", - "text_formatting" - ] + "topics": ["files", "searching", "text_formatting"] }, { "slug": "yacht", @@ -1472,12 +1205,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 4, - "topics": [ - "arrays", - "conditionals", - "filtering", - "games" - ] + "topics": ["arrays", "conditionals", "filtering", "games"] }, { "slug": "dominoes", @@ -1485,9 +1213,7 @@ "core": false, "unlocked_by": "bob", "difficulty": 6, - "topics": [ - "graph_theory" - ] + "topics": ["graph_theory"] } ] } diff --git a/docs/ABOUT.md b/docs/ABOUT.md index ee0c31a3f8..4facadce96 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -1,8 +1,8 @@ -ECMAScript is the [standard][web-ecma] that defines JavaScript, a programming -language that allows web pages to be dynamic. It is an interpreted language, -which means that it doesn't need to be compiled: instead the -interpreter (such as a web browser) will parse the code and turn it into code that -their machine can run - suitable for creating dynamic websites that can run on +ECMAScript is the [standard][web-ecma] that defines JavaScript, a programming +language that allows web pages to be dynamic. It is an interpreted language, +which means that it doesn't need to be compiled: instead the +interpreter (such as a web browser) will parse the code and turn it into code that +their machine can run - suitable for creating dynamic websites that can run on any browser\* on any computer\*! JavaScript is not only for use in the browser. JavaScript runtimes, such as @@ -14,10 +14,10 @@ Mac OS. Mobile app development is also a possibility, utilising [react-native][w target Android, iOS and the web, all at once. > ECMAScript has grown to be one of the world’s most widely used general purpose -> programming languages. It is best known as the language embedded in web -> browsers but has also been widely adopted for server and embedded +> programming languages. It is best known as the language embedded in web +> browsers but has also been widely adopted for server and embedded > applications." -— [ECMA International Language Specification][web-ecma-2019] +> — [ECMA International Language Specification][web-ecma-2019] Starting with the 6th edition (commonly known as ES2015 or ES6) in 2015, a new edition of the standard will be released each year. The 6th edition was a major @@ -25,22 +25,22 @@ update which brought many enhancements over ES5, including notably template strings, expressive arrow function syntax, and cleaner syntax for defining classes. -But because new syntax and features are coming to JavaScript _each year_, +But because new syntax and features are coming to JavaScript _each year_, support for these changes is often incomplete in [current browsers][web-compat-browsers] and [the latest node][web-compat-node]. This doesn't mean we can't use it. Tools such as [Babel][web-babel] offer [transpilation][wiki-transpilation] for most features, allowing us to _write_ as if it's the future. **Note**: This track supports the latest ECMAScript syntax via Babel and the -[@babel/preset-env][web-babel-preset-env] plugin, and new experimental features -are enabled with each update of that plugin, matching the release of the +[@babel/preset-env][web-babel-preset-env] plugin, and new experimental features +are enabled with each update of that plugin, matching the release of the specifications. It automatically adapts to _your local node_ installation. This means you don't need to worry about what is and isn't supported. ----- +--- -\* There is a [small number of browsers][wiki-javascript-support] that doesn't -ship with a JavaScript runtime, or that has disabled JavaScript execution by +\* There is a [small number of browsers][wiki-javascript-support] that doesn't +ship with a JavaScript runtime, or that has disabled JavaScript execution by default. [wiki-javascript-support]: https://en.wikipedia.org/wiki/Comparison_of_web_browsers#JavaScript_support diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 082a1c39b9..ee2e7e3833 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,6 +1,6 @@ -This track relies on [NodeJS][web-nodejs] throughout to provide a runtime for -JavaScript. This means that we assume all execution of JavaScript on your -computer will happen using [NodeJS][web-nodejs]. +This track relies on [NodeJS][web-nodejs] throughout to provide a runtime for +JavaScript. This means that we assume all execution of JavaScript on your +computer will happen using [NodeJS][web-nodejs]. # Track Requirements @@ -8,7 +8,7 @@ Many machines come pre-installed with [NodeJS][web-nodejs], or might have been installed previously, or as a dependency. So before we do anything, we should check if it's already installed: -1. Open up a _terminal_ (`Terminal`, `cmd`, `Powershell`, `bash`, ...) +1. Open up a _terminal_ (`Terminal`, `cmd`, `Powershell`, `bash`, ...) 1. `node -v` If [NodeJS][web-nodejs] is installed, a version is displayed. Write this version @@ -19,7 +19,7 @@ Usually something along the lines of `'node' is not recognised`. ### If node is pre-installed -Browse to [the NodeJS website][web-nodejs]. It will display _two_ versions (if +Browse to [the NodeJS website][web-nodejs]. It will display _two_ versions (if it detects your OS. Otherwise select your OS first). If your `node -v` version matches one of these, you're good. If it doesn't, we recommend that you use Node LTS. If you're worried upgrading might break something on your system, you @@ -30,16 +30,16 @@ something unexpected happens. There are a couple of ways to install [NodeJS][web-nodejs]: -* via an [Installer or Binary][web-nodejs-download] -* via a [package manager][web-nodejs-package] +- via an [Installer or Binary][web-nodejs-download] +- via a [package manager][web-nodejs-package] Both options support Windows, MacOS, and Linux. If you don't know what to do, using an installer is the easier. - We recommend using the **LTS** version. This is also indicated as _recommended_ -on the [NodeJS][web-nodejs] website "for most users". + on the [NodeJS][web-nodejs] website "for most users". - Follow the instructions on the webpage and/or during the installer and install -[NodeJS][web-nodejs]. + [NodeJS][web-nodejs]. ### Testing the installation @@ -47,7 +47,7 @@ After the installer is done, or the package manager has completed, or the binary has been copied and the instructions have been followed, it's good to test if everything is alright. -1. Open up a _terminal_ (`Terminal`, `cmd`, `Powershell`, `bash`, ...) +1. Open up a _terminal_ (`Terminal`, `cmd`, `Powershell`, `bash`, ...) 1. `node -v` The version should match the one on the website. @@ -60,12 +60,12 @@ means that the open terminals don't know that a new program was installed. > > If you've used the official installer, your `PATH` should have been > automatically configured, but if your shell has trouble locating your globally -> installed modules — or if you build Node.js from source — update +> installed modules — or if you build Node.js from source — update > your `PATH` to include the `npm` binaries. > > On MacOS and Linux you may accomplish this by adding the following to either > `~/.bash_profile` or `~/.zshrc`: -> +> > ```bash > $ export PATH=/usr/local/share/npm/bin:$PATH > ``` @@ -75,7 +75,6 @@ means that the open terminals don't know that a new program was installed. > Usually these are found at `C:\Program Files\nodejs`. If you browse here with > your `File Explorer`, you should find `node.exe`, `npm.bat` and `npx.bat`. > -> > Close any open terminals and open a new one. ### Assignment Requirements @@ -88,7 +87,7 @@ Once CLI is all setup & configured, download the first exercise - `hello-world`: $ exercism download --exercise=hello-world --track=javascript ``` -Each assignment then needs some tools to run the tests. They can be installed +Each assignment then needs some tools to run the tests. They can be installed running this command within each assignment directory: ```bash @@ -101,13 +100,13 @@ $ npm install > if you're eager to understand what just happened, the following paragraphs are > for you: > -> This works because `npm` is a package manager that comes bundled with -> `NodeJS`, which has been installed per the steps above. The `npm` command +> This works because `npm` is a package manager that comes bundled with +> `NodeJS`, which has been installed per the steps above. The `npm` command > looks for a `package.json` file, which is present in _each_ assignment folder. > This file lists the `"dependencies"` above, which are then downloaded by `npm` > and placed into the `node_modules` folder. > -> The scripts in the `package.json` use the binaries from the local +> The scripts in the `package.json` use the binaries from the local > `node_modules` folder, and it's these scripts that are used to run the tests, > as listed in the `exercise` description. diff --git a/docs/LEARNING.md b/docs/LEARNING.md index 7cfc008266..6041766de0 100644 --- a/docs/LEARNING.md +++ b/docs/LEARNING.md @@ -1,5 +1,5 @@ If you want to learn JavaScript, check out the following resources. -* [Exploring ES6](https://leanpub.com/exploring-es6) book, by Axel Rauschmayer -* [ES6 Katas](http://es6katas.org) website -* [Babel compiler](https://github.com/babel/babel) +- [Exploring ES6](https://leanpub.com/exploring-es6) book, by Axel Rauschmayer +- [ES6 Katas](http://es6katas.org) website +- [Babel compiler](https://github.com/babel/babel) diff --git a/docs/RESOURCES.md b/docs/RESOURCES.md index 8ea977027f..bd3f4f6d8f 100644 --- a/docs/RESOURCES.md +++ b/docs/RESOURCES.md @@ -1,5 +1,4 @@ ## Recommended References -* [ECMAScript 2015 Language Specification](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) (pdf) -* [Mozilla JavaScript Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference) - +- [ECMAScript 2015 Language Specification](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) (pdf) +- [Mozilla JavaScript Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference) diff --git a/docs/TESTS.md b/docs/TESTS.md index 382902e0ec..d64634ae15 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -65,5 +65,5 @@ export class Bob { You can find more information about modules in the [Babel documentation](https://babeljs.io/docs/learn-es2015/#modules). -To make it easier to get started, there is a *skeleton* JavaScript file in the +To make it easier to get started, there is a _skeleton_ JavaScript file in the directory for the first exercise. diff --git a/exercises/accumulate/accumulate.js b/exercises/accumulate/accumulate.js index 9d8bea7420..55d1745771 100644 --- a/exercises/accumulate/accumulate.js +++ b/exercises/accumulate/accumulate.js @@ -4,5 +4,5 @@ // export const accumulate = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/accumulate/accumulate.spec.js b/exercises/accumulate/accumulate.spec.js index 876ec89b5d..dc5e9f0da8 100644 --- a/exercises/accumulate/accumulate.spec.js +++ b/exercises/accumulate/accumulate.spec.js @@ -2,31 +2,40 @@ import { accumulate } from './accumulate'; describe('accumulate()', () => { test('accumulation empty', () => { - const accumulator = e => e * e; + const accumulator = (e) => e * e; expect(accumulate([], accumulator)).toEqual([]); }); xtest('accumulate squares', () => { - const accumulator = number => number * number; + const accumulator = (number) => number * number; const result = accumulate([1, 2, 3], accumulator); expect(result).toEqual([1, 4, 9]); }); xtest('accumulate upcases', () => { - const accumulator = word => word.toUpperCase(); + const accumulator = (word) => word.toUpperCase(); const result = accumulate('hello world'.split(/\s/), accumulator); expect(result).toEqual(['HELLO', 'WORLD']); }); xtest('accumulate reversed strings', () => { - const accumulator = word => word.split('').reverse().join(''); - const result = accumulate('the quick brown fox etc'.split(/\s/), accumulator); + const accumulator = (word) => word.split('').reverse().join(''); + const result = accumulate( + 'the quick brown fox etc'.split(/\s/), + accumulator + ); expect(result).toEqual(['eht', 'kciuq', 'nworb', 'xof', 'cte']); }); xtest('accumulate recursively', () => { - const result = accumulate('a b c'.split(/\s/), char => accumulate('1 2 3'.split(/\s/), digit => char + digit)); + const result = accumulate('a b c'.split(/\s/), (char) => + accumulate('1 2 3'.split(/\s/), (digit) => char + digit) + ); - expect(result).toEqual([['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]); + expect(result).toEqual([ + ['a1', 'a2', 'a3'], + ['b1', 'b2', 'b3'], + ['c1', 'c2', 'c3'], + ]); }); }); diff --git a/exercises/accumulate/babel.config.js b/exercises/accumulate/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/accumulate/babel.config.js +++ b/exercises/accumulate/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/acronym/acronym.js b/exercises/acronym/acronym.js index 0a4959db52..45e9a0e57d 100644 --- a/exercises/acronym/acronym.js +++ b/exercises/acronym/acronym.js @@ -4,5 +4,5 @@ // export const parse = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/acronym/acronym.spec.js b/exercises/acronym/acronym.spec.js index 24d79fce13..a5923b0b4e 100644 --- a/exercises/acronym/acronym.spec.js +++ b/exercises/acronym/acronym.spec.js @@ -22,8 +22,11 @@ describe('Acronyms are produced from', () => { }); xtest('long phrases', () => { - expect(parse('Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me')) - .toEqual('ROTFLSHTMDCOALM'); + expect( + parse( + 'Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me' + ) + ).toEqual('ROTFLSHTMDCOALM'); }); xtest('phrases with consecutive delimiters', () => { diff --git a/exercises/acronym/babel.config.js b/exercises/acronym/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/acronym/babel.config.js +++ b/exercises/acronym/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/acronym/example.js b/exercises/acronym/example.js index 1a11bfb509..b7fd6b6a4d 100644 --- a/exercises/acronym/example.js +++ b/exercises/acronym/example.js @@ -1,5 +1,6 @@ -export const parse = phrase => phrase - .replace("'", '') - .match(/^[A-Z]|(?<=[^A-Z])[A-Z]|\b[a-z]/g) - .join('') - .toUpperCase(); +export const parse = (phrase) => + phrase + .replace("'", '') + .match(/^[A-Z]|(?<=[^A-Z])[A-Z]|\b[a-z]/g) + .join('') + .toUpperCase(); diff --git a/exercises/affine-cipher/README.md b/exercises/affine-cipher/README.md index f6cbdb8e7b..e52e1ff8ca 100644 --- a/exercises/affine-cipher/README.md +++ b/exercises/affine-cipher/README.md @@ -1,4 +1,4 @@ -## Affine Cipher +# Affine Cipher Create an implementation of the affine cipher, an ancient encryption system created in the Middle East. @@ -105,7 +105,7 @@ Once you get a test passing, you can enable the next one by changing `xtest` to Once you have a solution ready, you can submit it using: ```bash -exercism submit allergies.js +exercism submit affine-cipher.js ``` ## Submitting Incomplete Solutions @@ -115,4 +115,5 @@ completed the exercise. ## Exercise Source Credits -Jumpstart Lab Warm-up [http://jumpstartlab.com](http://jumpstartlab.com) \ No newline at end of file +Wikipedia [http://en.wikipedia.org/wiki/Affine_cipher](http://en.wikipedia.org/wiki/Affine_cipher) + diff --git a/exercises/affine-cipher/affine-cipher.js b/exercises/affine-cipher/affine-cipher.js index e6306aeddc..545736f6ab 100644 --- a/exercises/affine-cipher/affine-cipher.js +++ b/exercises/affine-cipher/affine-cipher.js @@ -1,7 +1,7 @@ export const encode = (phrase, key) => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const decode = (phrase, key) => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/affine-cipher/affine-cipher.spec.js b/exercises/affine-cipher/affine-cipher.spec.js index fb6d29f3ac..9156312c5d 100644 --- a/exercises/affine-cipher/affine-cipher.spec.js +++ b/exercises/affine-cipher/affine-cipher.spec.js @@ -23,21 +23,27 @@ describe('Affine cipher', () => { }); xtest('encode numbers', () => { - expect(encode('Testing,1 2 3, testing.', { a: 3, b: 4 })).toBe('jqgjc rw123 jqgjc rw'); + expect(encode('Testing,1 2 3, testing.', { a: 3, b: 4 })).toBe( + 'jqgjc rw123 jqgjc rw' + ); }); xtest('encode deep thought', () => { - expect(encode('Truth is fiction.', { a: 5, b: 17 })).toBe('iynia fdqfb ifje'); + expect(encode('Truth is fiction.', { a: 5, b: 17 })).toBe( + 'iynia fdqfb ifje' + ); }); - + xtest('encode all the letters', () => { - expect(encode('The quick brown fox jumps over the lazy dog.', { a: 17, b: 33 })).toBe('swxtj npvyk lruol iejdc blaxk swxmh qzglf'); + expect( + encode('The quick brown fox jumps over the lazy dog.', { a: 17, b: 33 }) + ).toBe('swxtj npvyk lruol iejdc blaxk swxmh qzglf'); }); xtest('encode with a not coprime to m', () => { expect(() => { encode('This is a test.', { a: 6, b: 17 }); - }).toThrowError('a and m must be coprime.') + }).toThrowError('a and m must be coprime.'); }); }); describe('decode', () => { @@ -46,23 +52,33 @@ describe('Affine cipher', () => { }); xtest('decode a sentence', () => { - expect(decode('qdwju nqcro muwhn odqun oppmd aunwd o', { a: 19, b: 16 })).toBe('anobstacleisoftenasteppingstone'); + expect( + decode('qdwju nqcro muwhn odqun oppmd aunwd o', { a: 19, b: 16 }) + ).toBe('anobstacleisoftenasteppingstone'); }); xtest('decode numbers', () => { - expect(decode('odpoz ub123 odpoz ub', { a: 25, b: 7 })).toBe('testing123testing'); + expect(decode('odpoz ub123 odpoz ub', { a: 25, b: 7 })).toBe( + 'testing123testing' + ); }); xtest('decode all the letters', () => { - expect(decode('swxtj npvyk lruol iejdc blaxk swxmh qzglf', { a: 17, b: 33 })).toBe('thequickbrownfoxjumpsoverthelazydog'); + expect( + decode('swxtj npvyk lruol iejdc blaxk swxmh qzglf', { a: 17, b: 33 }) + ).toBe('thequickbrownfoxjumpsoverthelazydog'); }); xtest('decode with no spaces in input', () => { - expect(decode('swxtjnpvyklruoliejdcblaxkswxmhqzglf', { a: 17, b: 33 })).toBe('thequickbrownfoxjumpsoverthelazydog'); + expect( + decode('swxtjnpvyklruoliejdcblaxkswxmhqzglf', { a: 17, b: 33 }) + ).toBe('thequickbrownfoxjumpsoverthelazydog'); }); xtest('decode with too many spaces', () => { - expect(decode('vszzm cly yd cg qdp', { a: 15, b: 16 })).toBe('jollygreengiant'); + expect(decode('vszzm cly yd cg qdp', { a: 15, b: 16 })).toBe( + 'jollygreengiant' + ); }); xtest('decode with a not coprime to m', () => { @@ -71,4 +87,4 @@ describe('Affine cipher', () => { }).toThrowError('a and m must be coprime.'); }); }); -}); \ No newline at end of file +}); diff --git a/exercises/affine-cipher/babel.config.js b/exercises/affine-cipher/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/affine-cipher/babel.config.js +++ b/exercises/affine-cipher/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/affine-cipher/example.js b/exercises/affine-cipher/example.js index 2266de041c..e2c7772280 100644 --- a/exercises/affine-cipher/example.js +++ b/exercises/affine-cipher/example.js @@ -9,17 +9,17 @@ const areCoprimes = (a, b) => { } return true; -} +}; const checkCoprime = (a, b) => { if (!areCoprimes(a, b)) { throw new Error('a and m must be coprime.'); } -} +}; const isNumber = (candidate) => { return !isNaN(Number(candidate)); -} +}; const findMMI = (a) => { let i = 1; @@ -32,18 +32,18 @@ const findMMI = (a) => { return i; } } -} +}; const positiveModulo = (a, b) => { return ((a % b) + b) % b; -} +}; const groupBy = (elements, groupLength) => { const result = [[]]; let i = 0; - elements.forEach(el => { - if (result[i] && result[i].length < groupLength ) { + elements.forEach((el) => { + if (result[i] && result[i].length < groupLength) { result[i].push(el); } else { i++; @@ -52,7 +52,7 @@ const groupBy = (elements, groupLength) => { }); return result; -} +}; export const encode = (phrase, { a, b }) => { checkCoprime(a, ALPHABET_LENGTH); @@ -62,8 +62,8 @@ export const encode = (phrase, { a, b }) => { phrase .toLowerCase() .split('') - .filter(char => char !== ' ') - .forEach(char => { + .filter((char) => char !== ' ') + .forEach((char) => { if (ALPHABET.includes(char)) { const x = ALPHABET.indexOf(char); const encodedIndex = (a * x + b) % ALPHABET_LENGTH; @@ -75,7 +75,7 @@ export const encode = (phrase, { a, b }) => { }); return groupBy(encodedText.split(''), 5) - .map(group => group.join('')) + .map((group) => group.join('')) .join(' '); }; @@ -86,8 +86,8 @@ export const decode = (phrase, { a, b }) => { return phrase .split('') - .filter(char => char !== ' ') - .map(char => { + .filter((char) => char !== ' ') + .map((char) => { if (isNumber(char)) { return char; } @@ -98,4 +98,4 @@ export const decode = (phrase, { a, b }) => { return ALPHABET[decodedIndex]; }) .join(''); -} +}; diff --git a/exercises/all-your-base/all-your-base.js b/exercises/all-your-base/all-your-base.js index b15659e745..ce43914067 100644 --- a/exercises/all-your-base/all-your-base.js +++ b/exercises/all-your-base/all-your-base.js @@ -4,5 +4,5 @@ // export const convert = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/all-your-base/babel.config.js b/exercises/all-your-base/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/all-your-base/babel.config.js +++ b/exercises/all-your-base/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/all-your-base/example.js b/exercises/all-your-base/example.js index f5160a4555..57eb0a2873 100644 --- a/exercises/all-your-base/example.js +++ b/exercises/all-your-base/example.js @@ -1,4 +1,4 @@ -const isValidBase = base => !base || base < 2 || Math.floor(base) !== base; +const isValidBase = (base) => !base || base < 2 || Math.floor(base) !== base; const isInputValid = (array, base) => { if (!array || !array.length) { @@ -33,8 +33,7 @@ export const convert = (array, inputBase, outputBase) => { } const regexp = new RegExp('^0.', 'g'); const str = array.join(''); - if (str.match(regexp) - || !isInputValid(array, inputBase)) { + if (str.match(regexp) || !isInputValid(array, inputBase)) { throw new Error('Input has wrong format'); } if (str === '0') { @@ -43,7 +42,9 @@ export const convert = (array, inputBase, outputBase) => { if (str === '1') { return [1]; } - const decimalValue = array - .reduce((accumulator, value) => accumulator * inputBase + value, 0); + const decimalValue = array.reduce( + (accumulator, value) => accumulator * inputBase + value, + 0 + ); return convertFromDecimalToBase(decimalValue, outputBase); }; diff --git a/exercises/allergies/allergies.js b/exercises/allergies/allergies.js index 6eaf09034e..acf1d5376f 100644 --- a/exercises/allergies/allergies.js +++ b/exercises/allergies/allergies.js @@ -5,14 +5,14 @@ export class Allergies { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } list() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } allergicTo() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/allergies/allergies.spec.js b/exercises/allergies/allergies.spec.js index 8b5047de45..18f9f9c51c 100644 --- a/exercises/allergies/allergies.spec.js +++ b/exercises/allergies/allergies.spec.js @@ -255,7 +255,7 @@ describe('Allergies', () => { 'tomatoes', 'chocolate', 'pollen', - 'cats' + 'cats', ]); }); @@ -269,7 +269,7 @@ describe('Allergies', () => { 'tomatoes', 'chocolate', 'pollen', - 'cats' + 'cats', ]); }); @@ -282,7 +282,7 @@ describe('Allergies', () => { 'tomatoes', 'chocolate', 'pollen', - 'cats' + 'cats', ]); }); }); diff --git a/exercises/allergies/babel.config.js b/exercises/allergies/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/allergies/babel.config.js +++ b/exercises/allergies/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/allergies/example.js b/exercises/allergies/example.js index 3844be905f..9b997105a8 100644 --- a/exercises/allergies/example.js +++ b/exercises/allergies/example.js @@ -16,10 +16,12 @@ export class Allergies { list() { // eslint-disable-next-line no-bitwise, no-restricted-properties - return possibleAllergies.filter((allergy, i) => this.allergenIndex & Math.pow(2, i)); + return possibleAllergies.filter( + (allergy, i) => this.allergenIndex & Math.pow(2, i) + ); } allergicTo(food) { - return this.list().some(allergy => allergy === food); + return this.list().some((allergy) => allergy === food); } } diff --git a/exercises/alphametics/alphametics.js b/exercises/alphametics/alphametics.js index e5c8b1b7bd..fd5babdcdc 100644 --- a/exercises/alphametics/alphametics.js +++ b/exercises/alphametics/alphametics.js @@ -4,5 +4,5 @@ // export const solve = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/alphametics/babel.config.js b/exercises/alphametics/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/alphametics/babel.config.js +++ b/exercises/alphametics/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/alphametics/example.js b/exercises/alphametics/example.js index c3ac838803..c57d43b181 100644 --- a/exercises/alphametics/example.js +++ b/exercises/alphametics/example.js @@ -1,23 +1,34 @@ export function solve(puzzle) { const parts = puzzle .split(/[+|==]/g) - .map(o => o.trim()) - .filter(o => o !== ''); + .map((o) => o.trim()) + .filter((o) => o !== ''); if (parts.length < 3) { return null; } const uniqueLetters = new Set(parts.join('').split('')); - const firstLetters = new Set(parts.map(p => p[0])); + const firstLetters = new Set(parts.map((p) => p[0])); - const numberCombinations = getNumberCombinations([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], uniqueLetters.size); + const numberCombinations = getNumberCombinations( + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + uniqueLetters.size + ); while (numberCombinations.length) { - const permutations = generate(Array(uniqueLetters.size).fill().map((_, i) => i)); + const permutations = generate( + Array(uniqueLetters.size) + .fill() + .map((_, i) => i) + ); const numberCombination = numberCombinations.pop(); for (const permutation of permutations) { - const newNumbers = assignNumbers(numberCombination, uniqueLetters, permutation); + const newNumbers = assignNumbers( + numberCombination, + uniqueLetters, + permutation + ); if (testNumbers(newNumbers, parts, firstLetters)) { return newNumbers; } @@ -44,15 +55,19 @@ function testNumbers(numbers, puzzleParts, firstLetters) { } const replaceRegex = new RegExp(`[${keys.join('')}]`, 'g'); - puzzleParts = puzzleParts.join(',') - .replace(replaceRegex, input => numbers[input]) + puzzleParts = puzzleParts + .join(',') + .replace(replaceRegex, (input) => numbers[input]) .split(',') - .map(t => parseInt(t)); + .map((t) => parseInt(t)); const total = puzzleParts.slice(puzzleParts.length - 1)[0]; - return total === puzzleParts - .slice(0, puzzleParts.length - 1) - .reduce((acc, val) => acc + val, 0); + return ( + total === + puzzleParts + .slice(0, puzzleParts.length - 1) + .reduce((acc, val) => acc + val, 0) + ); } function* generate(A) { const c = []; @@ -91,8 +106,9 @@ function getNumberCombinations(arr, size) { if (size == len) return [arr]; return arr.reduce((acc, val, i) => { - const res = getNumberCombinations(arr.slice(i + 1), size - 1) - .map(comb => [val].concat(comb)); + const res = getNumberCombinations(arr.slice(i + 1), size - 1).map((comb) => + [val].concat(comb) + ); return acc.concat(res); }, []); diff --git a/exercises/anagram/README.md b/exercises/anagram/README.md index 906f353b6b..7126e84983 100644 --- a/exercises/anagram/README.md +++ b/exercises/anagram/README.md @@ -1,6 +1,7 @@ # Anagram -Given a word and a list of possible anagrams, select the correct sublist. +An anagram is a rearrangement of letters to form a new word. +Given a word and a list of candidates, select the sublist of anagrams of the given word. Given `"listen"` and a list of candidates like `"enlists" "google" "inlets" "banana"` the program should return a list containing diff --git a/exercises/anagram/anagram.js b/exercises/anagram/anagram.js index 71364874c7..0733d01302 100644 --- a/exercises/anagram/anagram.js +++ b/exercises/anagram/anagram.js @@ -4,5 +4,5 @@ // export const findAnagrams = () => { - throw new Error("Remove this statement and implement this function"); -} + throw new Error('Remove this statement and implement this function'); +}; diff --git a/exercises/anagram/anagram.spec.js b/exercises/anagram/anagram.spec.js index 6415483134..59e73d546b 100644 --- a/exercises/anagram/anagram.spec.js +++ b/exercises/anagram/anagram.spec.js @@ -10,7 +10,7 @@ describe('Anagram', () => { xtest('detects two anagrams', () => { expect(findAnagrams('master', ['stream', 'pigeon', 'maters'])).toEqual([ 'stream', - 'maters' + 'maters', ]); }); @@ -32,7 +32,7 @@ describe('Anagram', () => { 'regally', 'clergy', 'largely', - 'leading' + 'leading', ]) ).toEqual(['gallery', 'regally', 'largely']); }); @@ -77,7 +77,7 @@ describe('Anagram', () => { xtest('words other than themselves can be anagrams', () => { expect(findAnagrams('LISTEN', ['Listen', 'Silent', 'LISTEN'])).toEqual([ - 'Silent' + 'Silent', ]); }); }); diff --git a/exercises/anagram/babel.config.js b/exercises/anagram/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/anagram/babel.config.js +++ b/exercises/anagram/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/anagram/example.js b/exercises/anagram/example.js index e3dc466449..c18d9ee016 100644 --- a/exercises/anagram/example.js +++ b/exercises/anagram/example.js @@ -1,9 +1,12 @@ -const normalize = str => str.toLowerCase().split('').sort().join(); -const sameWord = (word, candidate) => word.toLowerCase() === candidate.toLowerCase(); +const normalize = (str) => str.toLowerCase().split('').sort().join(); +const sameWord = (word, candidate) => + word.toLowerCase() === candidate.toLowerCase(); const isAnagram = (word, candiate) => normalize(word) === normalize(candiate); export const findAnagrams = (subject, candidates) => { const wordsCopy = Array.isArray(candidates) ? candidates : [...candidates]; - return wordsCopy.filter(candidate => !sameWord(subject, candidate) - && isAnagram(subject, candidate)); -} + return wordsCopy.filter( + (candidate) => + !sameWord(subject, candidate) && isAnagram(subject, candidate) + ); +}; diff --git a/exercises/armstrong-numbers/armstrong-numbers.js b/exercises/armstrong-numbers/armstrong-numbers.js index 3a9c2f8923..d3ff1cdc3b 100644 --- a/exercises/armstrong-numbers/armstrong-numbers.js +++ b/exercises/armstrong-numbers/armstrong-numbers.js @@ -4,5 +4,5 @@ // export const isArmstrongNumber = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/armstrong-numbers/babel.config.js b/exercises/armstrong-numbers/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/armstrong-numbers/babel.config.js +++ b/exercises/armstrong-numbers/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/armstrong-numbers/example.js b/exercises/armstrong-numbers/example.js index b8ea7fbf23..0fe35c82e6 100644 --- a/exercises/armstrong-numbers/example.js +++ b/exercises/armstrong-numbers/example.js @@ -1,7 +1,8 @@ -export const isArmstrongNumber = input => { +export const isArmstrongNumber = (input) => { const digits = [...String(input)]; - const sum = digits.reduce((total, current) => ( - total + (current ** digits.length) - ), 0); + const sum = digits.reduce( + (total, current) => total + current ** digits.length, + 0 + ); return sum === input; }; diff --git a/exercises/atbash-cipher/atbash-cipher.js b/exercises/atbash-cipher/atbash-cipher.js index 4dec2c0cb4..18545fb900 100644 --- a/exercises/atbash-cipher/atbash-cipher.js +++ b/exercises/atbash-cipher/atbash-cipher.js @@ -4,9 +4,9 @@ // export const encode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const decode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/atbash-cipher/babel.config.js b/exercises/atbash-cipher/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/atbash-cipher/babel.config.js +++ b/exercises/atbash-cipher/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/atbash-cipher/example.js b/exercises/atbash-cipher/example.js index aad2882e3a..7e4bb7dcba 100644 --- a/exercises/atbash-cipher/example.js +++ b/exercises/atbash-cipher/example.js @@ -1,8 +1,8 @@ const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'; -export const encode = message => { +export const encode = (message) => { const encodedMessage = [...message.toLowerCase().replace(/[ .,]/g, '')] - .map(char => { + .map((char) => { if (ALPHABET.includes(char)) { return ALPHABET[ALPHABET.length - 1 - ALPHABET.indexOf(char)]; } @@ -12,6 +12,6 @@ export const encode = message => { return encodedMessage.match(/.{1,5}/g).join(' '); }; -export const decode = message => { - return encode(message).replace(/ /g, '') +export const decode = (message) => { + return encode(message).replace(/ /g, ''); }; diff --git a/exercises/bank-account/README.md b/exercises/bank-account/README.md index a00a8982ec..46b811df8b 100644 --- a/exercises/bank-account/README.md +++ b/exercises/bank-account/README.md @@ -1,24 +1,42 @@ # Bank Account -Simulate a bank account supporting opening/closing, withdrawals, and deposits of money. +Simulate a bank account supporting opening/closing, withdrawals, and deposits +of money. Watch out for concurrent transactions! A bank account can be accessed in multiple ways. Clients can make deposits and withdrawals using the internet, mobile phones, etc. Shops can charge against the account. +Create an account that can be accessed from multiple threads/processes +(terminology depends on your programming language). + It should be possible to close an account; operations against a closed account must fail. +## Instructions + +Run the test file, and fix each of the errors in turn. When you get the +first test to pass, go to the first pending or skipped test, and make +that pass as well. When all of the tests are passing, feel free to +submit. + +Remember that passing code is just the first step. The goal is to work +towards a solution that is as readable and expressive as you can make +it. + Have fun! ## Setup -Go through the setup instructions for Javascript to install the necessary dependencies: +Go through the setup instructions for Javascript to install the necessary +dependencies: [https://exercism.io/tracks/javascript/installation](https://exercism.io/tracks/javascript/installation) ## Requirements +Please `cd` into exercise directory before running all below commands. + Install assignment dependencies: ```bash @@ -35,8 +53,20 @@ $ npm test In the test suites all tests but the first have been skipped. -Once you get a test passing, you can enable the next one by changing `xtest` to `test`. +Once you get a test passing, you can enable the next one by changing `xtest` to +`test`. + + +## Submitting Solutions + +Once you have a solution ready, you can submit it using: + +```bash +exercism submit bank-account.js +``` ## Submitting Incomplete Solutions -It's possible to submit an incomplete solution so you can see how others have completed the exercise. +It's possible to submit an incomplete solution so you can see how others have +completed the exercise. + diff --git a/exercises/bank-account/babel.config.js b/exercises/bank-account/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/bank-account/babel.config.js +++ b/exercises/bank-account/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/bank-account/bank-account.js b/exercises/bank-account/bank-account.js index 65514269e3..8c2448180a 100644 --- a/exercises/bank-account/bank-account.js +++ b/exercises/bank-account/bank-account.js @@ -4,7 +4,6 @@ // export class BankAccount { - constructor() { throw new Error('Remove this statement and implement this function'); } @@ -28,13 +27,10 @@ export class BankAccount { get balance() { throw new Error('Remove this statement and implement this function'); } - } export class ValueError extends Error { - constructor() { super('Bank account error'); } - } diff --git a/exercises/bank-account/bank-account.spec.js b/exercises/bank-account/bank-account.spec.js index 1cf4318d3a..24d6786d66 100644 --- a/exercises/bank-account/bank-account.spec.js +++ b/exercises/bank-account/bank-account.spec.js @@ -1,7 +1,6 @@ import { BankAccount, ValueError } from './bank-account'; describe('Bank Account', () => { - test('newly opened account has zero balance', () => { const account = new BankAccount(); account.open(); @@ -114,5 +113,4 @@ describe('Bank Account', () => { account.deposit(-50); }).toThrow(ValueError); }); - }); diff --git a/exercises/bank-account/example.js b/exercises/bank-account/example.js index 432644f957..7032ddb4fd 100644 --- a/exercises/bank-account/example.js +++ b/exercises/bank-account/example.js @@ -1,5 +1,4 @@ export class BankAccount { - open() { if (this._open) { throw new ValueError(); @@ -51,7 +50,6 @@ export class BankAccount { get isOpen() { return this._open; } - } export class ValueError extends Error {} diff --git a/exercises/beer-song/babel.config.js b/exercises/beer-song/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/beer-song/babel.config.js +++ b/exercises/beer-song/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/beer-song/beer-song.js b/exercises/beer-song/beer-song.js index 68078b164c..8340bc23bd 100644 --- a/exercises/beer-song/beer-song.js +++ b/exercises/beer-song/beer-song.js @@ -4,5 +4,5 @@ // export const recite = (initialBottlesCount, takeDownCount) => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/beer-song/beer-song.spec.js b/exercises/beer-song/beer-song.spec.js index 6b0af593f3..c02ee0d55d 100644 --- a/exercises/beer-song/beer-song.spec.js +++ b/exercises/beer-song/beer-song.spec.js @@ -6,35 +6,35 @@ describe('Beer Song', () => { test('first generic verse', () => { expect(recite(99, 1)).toEqual([ '99 bottles of beer on the wall, 99 bottles of beer.', - 'Take one down and pass it around, 98 bottles of beer on the wall.' + 'Take one down and pass it around, 98 bottles of beer on the wall.', ]); }); xtest('last generic verse', () => { expect(recite(3, 1)).toEqual([ '3 bottles of beer on the wall, 3 bottles of beer.', - 'Take one down and pass it around, 2 bottles of beer on the wall.' + 'Take one down and pass it around, 2 bottles of beer on the wall.', ]); }); xtest('verse with 2 bottles', () => { expect(recite(2, 1)).toEqual([ '2 bottles of beer on the wall, 2 bottles of beer.', - 'Take one down and pass it around, 1 bottle of beer on the wall.' + 'Take one down and pass it around, 1 bottle of beer on the wall.', ]); }); xtest('verse with 1 bottle', () => { expect(recite(1, 1)).toEqual([ '1 bottle of beer on the wall, 1 bottle of beer.', - 'Take it down and pass it around, no more bottles of beer on the wall.' + 'Take it down and pass it around, no more bottles of beer on the wall.', ]); }); xtest('verse with 0 bottles', () => { expect(recite(0, 1)).toEqual([ 'No more bottles of beer on the wall, no more bottles of beer.', - 'Go to the store and buy some more, 99 bottles of beer on the wall.' + 'Go to the store and buy some more, 99 bottles of beer on the wall.', ]); }); }); @@ -48,7 +48,7 @@ describe('Beer Song', () => { 'Take one down and pass it around, 98 bottles of beer on the wall.', '', '98 bottles of beer on the wall, 98 bottles of beer.', - 'Take one down and pass it around, 97 bottles of beer on the wall.' + 'Take one down and pass it around, 97 bottles of beer on the wall.', ]); }); @@ -61,7 +61,7 @@ describe('Beer Song', () => { 'Take it down and pass it around, no more bottles of beer on the wall.', '', 'No more bottles of beer on the wall, no more bottles of beer.', - 'Go to the store and buy some more, 99 bottles of beer on the wall.' + 'Go to the store and buy some more, 99 bottles of beer on the wall.', ]); }); @@ -365,7 +365,7 @@ describe('Beer Song', () => { 'Take it down and pass it around, no more bottles of beer on the wall.', '', 'No more bottles of beer on the wall, no more bottles of beer.', - 'Go to the store and buy some more, 99 bottles of beer on the wall.' + 'Go to the store and buy some more, 99 bottles of beer on the wall.', ]); }); }); diff --git a/exercises/beer-song/example.js b/exercises/beer-song/example.js index 0ecadb6b80..1f38385c64 100644 --- a/exercises/beer-song/example.js +++ b/exercises/beer-song/example.js @@ -41,8 +41,8 @@ function verse(number) { export const recite = (startBottles, takeDown) => { let verses = []; for (let i = startBottles; i > startBottles - takeDown; i--) { - if(verses.length > 0) { - verses.push('') + if (verses.length > 0) { + verses.push(''); } verses = verses.concat(verse(i)); } diff --git a/exercises/binary-search-tree/babel.config.js b/exercises/binary-search-tree/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/binary-search-tree/babel.config.js +++ b/exercises/binary-search-tree/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/binary-search-tree/binary-search-tree.js b/exercises/binary-search-tree/binary-search-tree.js index 59fc1697ab..911d765a9f 100644 --- a/exercises/binary-search-tree/binary-search-tree.js +++ b/exercises/binary-search-tree/binary-search-tree.js @@ -5,21 +5,21 @@ export class BinarySearchTree { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get data() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get right() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get left() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } insert() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/binary-search-tree/binary-search-tree.spec.js b/exercises/binary-search-tree/binary-search-tree.spec.js index 8be168edbf..01bbda6adf 100644 --- a/exercises/binary-search-tree/binary-search-tree.spec.js +++ b/exercises/binary-search-tree/binary-search-tree.spec.js @@ -3,7 +3,7 @@ import { BinarySearchTree } from './binary-search-tree'; function recordAllData(bst) { const out = []; - bst.each(data => out.push(data)); + bst.each((data) => out.push(data)); return out; } diff --git a/exercises/binary-search/babel.config.js b/exercises/binary-search/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/binary-search/babel.config.js +++ b/exercises/binary-search/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/binary-search/binary-search.js b/exercises/binary-search/binary-search.js index 00464dbc76..88e2fa3063 100644 --- a/exercises/binary-search/binary-search.js +++ b/exercises/binary-search/binary-search.js @@ -4,5 +4,5 @@ // export const find = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/binary-search/example.js b/exercises/binary-search/example.js index 2de4c2ab56..8561256842 100644 --- a/exercises/binary-search/example.js +++ b/exercises/binary-search/example.js @@ -12,5 +12,5 @@ export const find = (array, element) => { start = middle + 1; } } - throw new Error("Value not in array"); + throw new Error('Value not in array'); }; diff --git a/exercises/binary/babel.config.js b/exercises/binary/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/binary/babel.config.js +++ b/exercises/binary/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/binary/binary.js b/exercises/binary/binary.js index 74d0aeafb9..dfbca26ec8 100644 --- a/exercises/binary/binary.js +++ b/exercises/binary/binary.js @@ -5,10 +5,10 @@ export class Binary { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } toDecimal() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/binary/binary.spec.js b/exercises/binary/binary.spec.js index d184b9ea6b..b5d4c696a0 100644 --- a/exercises/binary/binary.spec.js +++ b/exercises/binary/binary.spec.js @@ -5,19 +5,26 @@ describe('binary', () => { xtest('1 is decimal 1', () => expect(new Binary('1').toDecimal()).toEqual(1)); - xtest('10 is decimal 2', () => expect(new Binary('10').toDecimal()).toEqual(2)); + xtest('10 is decimal 2', () => + expect(new Binary('10').toDecimal()).toEqual(2)); - xtest('11 is decimal 3', () => expect(new Binary('11').toDecimal()).toEqual(3)); + xtest('11 is decimal 3', () => + expect(new Binary('11').toDecimal()).toEqual(3)); - xtest('100 is decimal 4', () => expect(new Binary('100').toDecimal()).toEqual(4)); + xtest('100 is decimal 4', () => + expect(new Binary('100').toDecimal()).toEqual(4)); - xtest('1001 is decimal 9', () => expect(new Binary('1001').toDecimal()).toEqual(9)); + xtest('1001 is decimal 9', () => + expect(new Binary('1001').toDecimal()).toEqual(9)); - xtest('11010 is decimal 26', () => expect(new Binary('11010').toDecimal()).toEqual(26)); + xtest('11010 is decimal 26', () => + expect(new Binary('11010').toDecimal()).toEqual(26)); - xtest('10001101000 is decimal 1128', () => expect(new Binary('10001101000').toDecimal()).toEqual(1128)); + xtest('10001101000 is decimal 1128', () => + expect(new Binary('10001101000').toDecimal()).toEqual(1128)); - xtest('00011111 is decimal 31', () => expect(new Binary('00011111').toDecimal()).toEqual(31)); + xtest('00011111 is decimal 31', () => + expect(new Binary('00011111').toDecimal()).toEqual(31)); xtest('invalid inputs are decimal 0', () => { expect(new Binary('carrot').toDecimal()).toEqual(0); diff --git a/exercises/bob/.meta/description.md b/exercises/bob/.meta/description.md deleted file mode 100644 index 1072139fad..0000000000 --- a/exercises/bob/.meta/description.md +++ /dev/null @@ -1,10 +0,0 @@ -Bob is a lackadaisical teenager. In conversation, his responses are very limited. - -Bob answers 'Sure.' if you ask him a question. - -He answers 'Whoa, chill out!' if you yell at him. - -He says 'Fine. Be that way!' if you address him without actually saying -anything. - -He answers 'Whatever.' to anything else. diff --git a/exercises/bob/README.md b/exercises/bob/README.md index f50fc8e5ea..a97d4548ca 100644 --- a/exercises/bob/README.md +++ b/exercises/bob/README.md @@ -2,17 +2,19 @@ Bob is a lackadaisical teenager. In conversation, his responses are very limited. -Bob answers 'Sure.' if you ask him a question. +Bob answers 'Sure.' if you ask him a question, such as "How are you?". -He answers 'Whoa, chill out!' if you yell at him. +He answers 'Whoa, chill out!' if you YELL AT HIM (in all capitals). -He retorts 'Calm down, I know what I'm doing!' if you yell a question at him. +He answers 'Calm down, I know what I'm doing!' if you yell a question at him. He says 'Fine. Be that way!' if you address him without actually saying anything. He answers 'Whatever.' to anything else. +Bob's conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English. + ## Setup Go through the setup instructions for Javascript to install the necessary diff --git a/exercises/bob/babel.config.js b/exercises/bob/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/bob/babel.config.js +++ b/exercises/bob/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/bob/bob.js b/exercises/bob/bob.js index 49313cc075..cc8a6fe97a 100644 --- a/exercises/bob/bob.js +++ b/exercises/bob/bob.js @@ -4,5 +4,5 @@ // export const hey = (message) => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/bob/bob.spec.js b/exercises/bob/bob.spec.js index 29312c8e43..364db208c7 100644 --- a/exercises/bob/bob.spec.js +++ b/exercises/bob/bob.spec.js @@ -43,7 +43,7 @@ describe('Bob', () => { xtest('forceful question', () => { const result = hey('WHAT THE HELL WERE YOU THINKING?'); - expect(result).toEqual('Calm down, I know what I\'m doing!'); + expect(result).toEqual("Calm down, I know what I'm doing!"); }); xtest('shouting numbers', () => { diff --git a/exercises/bob/example.js b/exercises/bob/example.js index 0bab52a23e..878f573568 100644 --- a/exercises/bob/example.js +++ b/exercises/bob/example.js @@ -1,6 +1,7 @@ -const isSilence = message => message.replace(/\s+/g, '') === ''; -const isShouting = message => message.toUpperCase() === message && /[A-Z]/.test(message); -const isAQuestion = message => message.endsWith('?'); +const isSilence = (message) => message.replace(/\s+/g, '') === ''; +const isShouting = (message) => + message.toUpperCase() === message && /[A-Z]/.test(message); +const isAQuestion = (message) => message.endsWith('?'); export const hey = (message) => { if (isSilence(message)) { diff --git a/exercises/bowling/babel.config.js b/exercises/bowling/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/bowling/babel.config.js +++ b/exercises/bowling/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/bowling/bowling.js b/exercises/bowling/bowling.js index c3ca78cbf1..9d83338b7c 100644 --- a/exercises/bowling/bowling.js +++ b/exercises/bowling/bowling.js @@ -5,10 +5,10 @@ export class Bowling { roll() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } score() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 28e300814f..3ef119cad5 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -3,100 +3,343 @@ import { Bowling } from './bowling'; describe('Bowling', () => { describe('Check game can be scored correctly.', () => { test('should be able to score a game with all zeros', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(0); }); xtest('should be able to score a game with no strikes or spares', () => { - const rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; + const rolls = [ + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + 3, + 6, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(90); }); xtest('a spare followed by zeros is worth ten points', () => { - const rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + const rolls = [ + 6, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(10); }); xtest('points scored in the roll after a spare are counted twice', () => { - const rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + const rolls = [ + 6, + 4, + 3, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(16); }); xtest('consecutive spares each get a one roll bonus', () => { - const rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + const rolls = [ + 5, + 5, + 3, + 7, + 4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(31); }); xtest('a spare in the last frame gets a one roll bonus that is counted once', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 3, + 7, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(17); }); xtest('a strike earns ten points in a frame with a single roll', () => { const rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(10); }); xtest('points scored in the two rolls after a strike are counted twice as a bonus', () => { const rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(26); }); xtest('consecutive strikes each get the two roll bonus', () => { const rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(81); }); xtest('a strike in the last frame gets a two roll bonues that is counted once', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 7, + 1, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(18); }); xtest('rolling a spare with the two roll bonus does not get a bonus roll', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 7, + 3, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(20); }); xtest('strikes with the two roll bonus do not get bonus rolls', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 10, + 10, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(30); }); xtest('a strike with the one roll bonus after a spare in the last frame does not get a bonus', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 3, + 10, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(20); }); xtest('all strikes is a perfect game', () => { const rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(300); }); }); @@ -104,122 +347,353 @@ describe('Bowling', () => { describe('Check game rules.', () => { xtest('rolls can not score negative points', () => { const bowling = new Bowling(); - expect(() => { bowling.roll(-1); }) - .toThrow(new Error('Negative roll is invalid')); + expect(() => { + bowling.roll(-1); + }).toThrow(new Error('Negative roll is invalid')); }); xtest('a roll can not score more than 10 points', () => { const bowling = new Bowling(); - expect(() => { bowling.roll(11); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + expect(() => { + bowling.roll(11); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('two rolls in a frame can not score more than 10 points', () => { const bowling = new Bowling(); bowling.roll(5); - expect(() => { bowling.roll(6); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + expect(() => { + bowling.roll(6); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('bonus roll after a strike in the last frame cannot score more than 10 points', () => { const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(11); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(11); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('two bonus rolls after a strike in the last frame can not score more than 10 points', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 5, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(6); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(6); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 10, + 6, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); + rolls.forEach((roll) => { + bowling.roll(roll); + }); expect(bowling.score()).toEqual(26); }); xtest('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 6, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(10); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(10); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('second bonus roll after a strike in the last frame cannot score more than 10 points', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 10, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(11); }) - .toThrow(new Error('Pin count exceeds pins on the lane')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(11); + }).toThrow(new Error('Pin count exceeds pins on the lane')); }); xtest('an unstarted game can not be scored', () => { const bowling = new Bowling(); - expect(() => { bowling.score(); }) - .toThrow(new Error('Score cannot be taken until the end of the game')); + expect(() => { + bowling.score(); + }).toThrow(new Error('Score cannot be taken until the end of the game')); }); xtest('an incomplete game can not be scored', () => { const rolls = [0, 0]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.score(); }) - .toThrow(new Error('Score cannot be taken until the end of the game')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.score(); + }).toThrow(new Error('Score cannot be taken until the end of the game')); }); xtest('cannot roll if game already has ten frames', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(0); }) - .toThrow(new Error('Cannot roll after game is over')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(0); + }).toThrow(new Error('Cannot roll after game is over')); }); xtest('bonus rolls for a strike in the last frame must be rolled before score can be calculated', () => { const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.score(); }) - .toThrow(new Error('Score cannot be taken until the end of the game')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.score(); + }).toThrow(new Error('Score cannot be taken until the end of the game')); }); xtest('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 10, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.score(); }) - .toThrow(new Error('Score cannot be taken until the end of the game')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.score(); + }).toThrow(new Error('Score cannot be taken until the end of the game')); }); xtest('bonus roll for a spare in the last frame must be rolled before score can be calculated', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 3, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.score(); }) - .toThrow(new Error('Score cannot be taken until the end of the game')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.score(); + }).toThrow(new Error('Score cannot be taken until the end of the game')); }); xtest(' cannot roll after bonus roll for spare', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 2]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 7, + 3, + 2, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(2); }) - .toThrow(new Error('Cannot roll after game is over')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(2); + }).toThrow(new Error('Cannot roll after game is over')); }); xtest('cannot roll after bonus rolls for strike', () => { - const rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 2]; + const rolls = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 10, + 3, + 2, + ]; const bowling = new Bowling(); - rolls.forEach((roll) => { bowling.roll(roll); }); - expect(() => { bowling.roll(2); }) - .toThrow(new Error('Cannot roll after game is over')); + rolls.forEach((roll) => { + bowling.roll(roll); + }); + expect(() => { + bowling.roll(2); + }).toThrow(new Error('Cannot roll after game is over')); }); }); }); diff --git a/exercises/bowling/example.js b/exercises/bowling/example.js index 3cea48886e..a08793edb8 100644 --- a/exercises/bowling/example.js +++ b/exercises/bowling/example.js @@ -46,7 +46,8 @@ export class Bowling { } scoreOpenFrame(pins) { - this.frames[this.currentFrame - 1] = (this.maxPins - this.remainingPins) + pins; + this.frames[this.currentFrame - 1] = + this.maxPins - this.remainingPins + pins; this.applyStrikeBonus(pins); this.incrementFrame(); } @@ -60,12 +61,18 @@ export class Bowling { applyStrikeBonus(pins) { // on the two rolls after a strike are counted twice (on the frame of the strike) - if (this.frames[this.currentFrame - 3] === 'X' - && this.frames[this.currentFrame - 2] === 'X' - && this.frameRoll === 1 && this.currentFrame <= (this.maxFrames + 2)) { + if ( + this.frames[this.currentFrame - 3] === 'X' && + this.frames[this.currentFrame - 2] === 'X' && + this.frameRoll === 1 && + this.currentFrame <= this.maxFrames + 2 + ) { this.frameScores[this.currentFrame - 3] += pins; } - if (this.frames[this.currentFrame - 2] === 'X' && this.currentFrame <= (this.maxFrames + 1)) { + if ( + this.frames[this.currentFrame - 2] === 'X' && + this.currentFrame <= this.maxFrames + 1 + ) { this.frameScores[this.currentFrame - 2] += pins; } } @@ -73,22 +80,36 @@ export class Bowling { isGameOver() { if (this.currentFrame <= this.maxFrames) return false; - if (this.frames[this.maxFrames - 1] !== 'X' && this.frames[this.maxFrames - 1] !== 'S') return true; + if ( + this.frames[this.maxFrames - 1] !== 'X' && + this.frames[this.maxFrames - 1] !== 'S' + ) + return true; // spare in the last frame gets no more than bonus roll - if (this.frames[this.maxFrames - 1] === 'S' && this.frameRoll > 1) return true; + if (this.frames[this.maxFrames - 1] === 'S' && this.frameRoll > 1) + return true; // bonus roll after the spare in the last frame may get a strike but then the games ends // without another roll - if (this.frames[this.maxFrames - 1] === 'S' && this.frames[this.maxFrames] === 'X') return true; + if ( + this.frames[this.maxFrames - 1] === 'S' && + this.frames[this.maxFrames] === 'X' + ) + return true; if (this.frames[this.maxFrames - 1] === 'X') { // if the first bonus roll is not a strike then finish the bonus frame - if (this.frames[this.maxFrames] !== 'X' && this.currentFrame > this.maxFrames + 1) return true; + if ( + this.frames[this.maxFrames] !== 'X' && + this.currentFrame > this.maxFrames + 1 + ) + return true; if (this.frames[this.maxFrames] === 'X') { // if the second bonus roll is a strike, but was still used, the game is over - if (this.frames[this.maxFrames + 1] !== 'X' && this.frameRoll > 1) return true; + if (this.frames[this.maxFrames + 1] !== 'X' && this.frameRoll > 1) + return true; // if the second bonus roll is a strike the game is over if (this.frames[this.maxFrames + 1] === 'X') return true; } @@ -132,6 +153,6 @@ export class Bowling { if (!this.isGameOver()) { throw new Error('Score cannot be taken until the end of the game'); } - return this.frameScores.reduce((total, num) => (total + num)); + return this.frameScores.reduce((total, num) => total + num); } } diff --git a/exercises/change/babel.config.js b/exercises/change/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/change/babel.config.js +++ b/exercises/change/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/change/change.js b/exercises/change/change.js index c348490955..a1e61fa949 100755 --- a/exercises/change/change.js +++ b/exercises/change/change.js @@ -5,6 +5,6 @@ export class Change { calculate(coinArray, target) { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/change/change.spec.js b/exercises/change/change.spec.js index faa35a000f..64063a871a 100644 --- a/exercises/change/change.spec.js +++ b/exercises/change/change.spec.js @@ -36,7 +36,23 @@ describe('Change', () => { xtest('test large amount of change', () => { const change = new Change(); const result = change.calculate([1, 2, 5, 10, 20, 50, 100], 999); - expect(result).toEqual([2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100]); + expect(result).toEqual([ + 2, + 2, + 5, + 20, + 20, + 50, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + 100, + ]); }); xtest('test possible change without unit coins available', () => { @@ -60,21 +76,27 @@ describe('Change', () => { xtest('error testing for change smaller than the smallest of coins', () => { const change = new Change(); const message = 'The total 3 cannot be represented in the given currency.'; - const test = () => { change.calculate([5, 10], 3); }; + const test = () => { + change.calculate([5, 10], 3); + }; expect(test).toThrowError(message); }); xtest('error testing if no combination can add up to target', () => { const change = new Change(); const message = 'The total 94 cannot be represented in the given currency.'; - const test = () => { change.calculate([5, 10], 94); }; + const test = () => { + change.calculate([5, 10], 94); + }; expect(test).toThrowError(message); }); xtest('negative change is rejected', () => { const change = new Change(); const message = 'Negative totals are not allowed.'; - const test = () => { change.calculate([1, 2, 5], -5); }; + const test = () => { + change.calculate([1, 2, 5], -5); + }; expect(test).toThrowError(message); }); }); diff --git a/exercises/change/example.js b/exercises/change/example.js index 8454a9dbf7..6b2c7c600e 100644 --- a/exercises/change/example.js +++ b/exercises/change/example.js @@ -45,7 +45,7 @@ export class Change { candidates[target] = 0; candidates.fill(0); - const isNumber = element => typeof (element) === 'number'; + const isNumber = (element) => typeof element === 'number'; // save a new candidate to the candidates array const saveCandidate = (candidate) => { @@ -72,14 +72,16 @@ export class Change { }; // is everthing searched? - const isDone = () => ( - candidates.every(candidate => isNumber(candidate) || candidate.isSearched()) - ); + const isDone = () => + candidates.every( + (candidate) => isNumber(candidate) || candidate.isSearched() + ); // get the next unsearched member of the candidate array - const getNext = () => ( - candidates.find(candidate => !isNumber(candidate) && !candidate.isSearched()) - ); + const getNext = () => + candidates.find( + (candidate) => !isNumber(candidate) && !candidate.isSearched() + ); // for the candidate, generate another candate for each of the possible coins const branch = (current) => { @@ -103,10 +105,11 @@ export class Change { } if (target < Math.min.apply(null, coinArray)) { - throw new Error(`The total ${target} cannot be represented in the given currency.`); + throw new Error( + `The total ${target} cannot be represented in the given currency.` + ); } - initialize(); // process the arrange until everything is searched @@ -118,6 +121,8 @@ export class Change { // print the result if (!isNumber(candidates[target])) return candidates[target].getCoins(); - throw new Error(`The total ${target} cannot be represented in the given currency.`); + throw new Error( + `The total ${target} cannot be represented in the given currency.` + ); } } diff --git a/exercises/circular-buffer/babel.config.js b/exercises/circular-buffer/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/circular-buffer/babel.config.js +++ b/exercises/circular-buffer/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/circular-buffer/circular-buffer.js b/exercises/circular-buffer/circular-buffer.js index c34c1e278b..ce5136f121 100644 --- a/exercises/circular-buffer/circular-buffer.js +++ b/exercises/circular-buffer/circular-buffer.js @@ -5,23 +5,23 @@ class CircularBuffer { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } write() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } read() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } forceWrite() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } clear() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } @@ -29,12 +29,12 @@ export default CircularBuffer; export class BufferFullError extends Error { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } export class BufferEmptyError extends Error { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/circular-buffer/circular-buffer.spec.js b/exercises/circular-buffer/circular-buffer.spec.js index 421c6117fb..c63f23a6fb 100644 --- a/exercises/circular-buffer/circular-buffer.spec.js +++ b/exercises/circular-buffer/circular-buffer.spec.js @@ -1,4 +1,7 @@ -import CircularBuffer, { BufferFullError, BufferEmptyError } from './circular-buffer'; +import CircularBuffer, { + BufferFullError, + BufferEmptyError, +} from './circular-buffer'; describe('CircularBuffer', () => { test('reading an empty buffer throws a BufferEmptyError', () => { @@ -52,11 +55,11 @@ describe('CircularBuffer', () => { expect(buffer.read()).toBe('3'); }); - xtest('writes of undefined or null don\'t occupy buffer', () => { + xtest("writes of undefined or null don't occupy buffer", () => { const buffer = new CircularBuffer(3); buffer.write(null); buffer.write(undefined); - [1, 2, 3].map(i => buffer.write(i.toString())); + [1, 2, 3].map((i) => buffer.write(i.toString())); expect(buffer.read()).toBe('1'); }); @@ -88,12 +91,12 @@ describe('CircularBuffer', () => { xtest('alternate force write and read into full buffer', () => { const buffer = new CircularBuffer(5); - [1, 2, 3].map(i => buffer.write(i.toString())); + [1, 2, 3].map((i) => buffer.write(i.toString())); buffer.read(); buffer.read(); buffer.write('4'); buffer.read(); - [5, 6, 7, 8].map(i => buffer.write(i.toString())); + [5, 6, 7, 8].map((i) => buffer.write(i.toString())); buffer.forceWrite('A'); buffer.forceWrite('B'); expect(buffer.read()).toBe('6'); diff --git a/exercises/circular-buffer/example.js b/exercises/circular-buffer/example.js index c7170a1aa9..8ba5832015 100644 --- a/exercises/circular-buffer/example.js +++ b/exercises/circular-buffer/example.js @@ -1,13 +1,13 @@ export class BufferEmptyError extends Error { constructor(message) { super(); - this.message = message || "Buffer is empty."; + this.message = message || 'Buffer is empty.'; } } export class BufferFullError extends Error { constructor(message) { super(); - this.message = message || "Buffer is full."; + this.message = message || 'Buffer is full.'; } } diff --git a/exercises/clock/babel.config.js b/exercises/clock/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/clock/babel.config.js +++ b/exercises/clock/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/collatz-conjecture/babel.config.js b/exercises/collatz-conjecture/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/collatz-conjecture/babel.config.js +++ b/exercises/collatz-conjecture/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/collatz-conjecture/collatz-conjecture.js b/exercises/collatz-conjecture/collatz-conjecture.js index f316e19667..28767bc3c2 100644 --- a/exercises/collatz-conjecture/collatz-conjecture.js +++ b/exercises/collatz-conjecture/collatz-conjecture.js @@ -4,5 +4,5 @@ // export const steps = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/collatz-conjecture/example.js b/exercises/collatz-conjecture/example.js index 02fb85d04d..ed0f95f494 100644 --- a/exercises/collatz-conjecture/example.js +++ b/exercises/collatz-conjecture/example.js @@ -8,7 +8,9 @@ export const steps = (n) => { return step; } - return number % 2 === 0 ? iterate(number / 2, step + 1) : iterate((3 * number) + 1, step + 1); + return number % 2 === 0 + ? iterate(number / 2, step + 1) + : iterate(3 * number + 1, step + 1); }; return iterate(n, 0); }; diff --git a/exercises/complex-numbers/babel.config.js b/exercises/complex-numbers/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/complex-numbers/babel.config.js +++ b/exercises/complex-numbers/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/complex-numbers/complex-numbers.js b/exercises/complex-numbers/complex-numbers.js index b1636f7658..9cf27f5b01 100644 --- a/exercises/complex-numbers/complex-numbers.js +++ b/exercises/complex-numbers/complex-numbers.js @@ -5,42 +5,42 @@ export class ComplexNumber { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get real() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get imag() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } add() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } sub() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } div() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } mul() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get abs() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get conj() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get exp() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/complex-numbers/complex-numbers.spec.js b/exercises/complex-numbers/complex-numbers.spec.js index e8c559ef56..a0283aee65 100644 --- a/exercises/complex-numbers/complex-numbers.spec.js +++ b/exercises/complex-numbers/complex-numbers.spec.js @@ -190,7 +190,7 @@ describe('Complex numbers', () => { expect(actual).toEqual(expected); }); - xtest('Euler\'s identity/formula', () => { + xtest("Euler's identity/formula", () => { const expected = new ComplexNumber(-1, 0); const actual = new ComplexNumber(0, Math.PI).exp; diff --git a/exercises/complex-numbers/example.js b/exercises/complex-numbers/example.js index a4624e5ef6..ff3bba9ce7 100644 --- a/exercises/complex-numbers/example.js +++ b/exercises/complex-numbers/example.js @@ -14,22 +14,22 @@ export class ComplexNumber { mul(other) { return new ComplexNumber( - (this.real * other.real) - (this.imag * other.imag), - (this.imag * other.real) + (this.real * other.imag), + this.real * other.real - this.imag * other.imag, + this.imag * other.real + this.real * other.imag ); } div(other) { return new ComplexNumber( - ((this.real * other.real) + (this.imag * other.imag)) - / ((other.real * other.real) + (other.imag * other.imag)), - ((this.imag * other.real) - (this.real * other.imag)) - / ((other.real * other.real) + (other.imag * other.imag)), + (this.real * other.real + this.imag * other.imag) / + (other.real * other.real + other.imag * other.imag), + (this.imag * other.real - this.real * other.imag) / + (other.real * other.real + other.imag * other.imag) ); } get abs() { - return Math.sqrt((this.real * this.real) + (this.imag * this.imag)); + return Math.sqrt(this.real * this.real + this.imag * this.imag); } get conj() { @@ -39,7 +39,7 @@ export class ComplexNumber { get exp() { return new ComplexNumber( Math.exp(this.real) * Math.cos(this.imag), - Math.exp(this.real) * Math.sin(this.imag), + Math.exp(this.real) * Math.sin(this.imag) ); } } diff --git a/exercises/connect/README.md b/exercises/connect/README.md index 36591163c8..b8b68065d6 100644 --- a/exercises/connect/README.md +++ b/exercises/connect/README.md @@ -5,18 +5,18 @@ Compute the result for a game of Hex / Polygon. The abstract boardgame known as [Hex](https://en.wikipedia.org/wiki/Hex_%28board_game%29) / Polygon / CON-TAC-TIX is quite simple in rules, though complex in practice. Two players -place stones on a rhombus with hexagonal fields. The player to connect his/her -stones to the opposite side first wins. The four sides of the rhombus are +place stones on a parallelogram with hexagonal fields. The player to connect his/her +stones to the opposite side first wins. The four sides of the parallelogram are divided between the two players (i.e. one player gets assigned a side and the side directly opposite it and the other player gets assigned the two other sides). Your goal is to build a program that given a simple representation of a board computes the winner (or lack thereof). Note that all games need not be "fair". -(For example, players may have mismatched piece counts.) +(For example, players may have mismatched piece counts or the game's board might +have a different width and height.) -The boards look like this (with spaces added for readability, which won't be in -the representation passed to your code): +The boards look like this: ```text . O . X . diff --git a/exercises/connect/babel.config.js b/exercises/connect/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/connect/babel.config.js +++ b/exercises/connect/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/connect/connect.js b/exercises/connect/connect.js index 8c75bdc501..c27a6b8c81 100644 --- a/exercises/connect/connect.js +++ b/exercises/connect/connect.js @@ -5,10 +5,10 @@ export class Board { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } winner() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/connect/connect.spec.js b/exercises/connect/connect.spec.js index cae0d27f7a..c8bd390341 100644 --- a/exercises/connect/connect.spec.js +++ b/exercises/connect/connect.spec.js @@ -13,26 +13,17 @@ describe('Judging a game of connect', () => { }); xtest('X can win on a 1x1 board', () => { - const board = [ - 'X', - ]; + const board = ['X']; expect(new Board(board).winner()).toEqual('X'); }); xtest('O can win on a 1x1 board', () => { - const board = [ - 'O', - ]; + const board = ['O']; expect(new Board(board).winner()).toEqual('O'); }); xtest('only edges does not make a winner', () => { - const board = [ - 'O O O X', - ' X . . X', - ' X . . X', - ' X O O O', - ]; + const board = ['O O O X', ' X . . X', ' X . . X', ' X O O O']; expect(new Board(board).winner()).toEqual(''); }); diff --git a/exercises/connect/example.js b/exercises/connect/example.js index 1c2649d75b..9159886d03 100644 --- a/exercises/connect/example.js +++ b/exercises/connect/example.js @@ -4,7 +4,7 @@ */ export class Board { constructor(board) { - this.board = board.map(b => [...b]); + this.board = board.map((b) => [...b]); } winner() { const players = ['X', 'O']; @@ -33,12 +33,18 @@ export class Board { } checked = checked.slice(0); checked.push(pos); - const matches = this.neighbors(pos).filter(({ x, y }) => this.matches({ x, y }, XorO) && checked.filter(spot => spot.x === x && spot.y === y).length === 0); + const matches = this.neighbors(pos).filter( + ({ x, y }) => + this.matches({ x, y }, XorO) && + checked.filter((spot) => spot.x === x && spot.y === y).length === 0 + ); if (matches.length === 0) { return false; } - return matches.filter(spot => this.search(spot, XorO, checked)).length > 0; + return ( + matches.filter((spot) => this.search(spot, XorO, checked)).length > 0 + ); } neighbors({ x, y }) { return [ @@ -53,14 +59,14 @@ export class Board { ]; } startPositions(XorO) { - return XorO === 'X' ? - this.board.map((pos, i) => ({ x: i, y: i })) : - this.board[0].map((pos, i) => ({ x: 0, y: i })); + return XorO === 'X' + ? this.board.map((pos, i) => ({ x: i, y: i })) + : this.board[0].map((pos, i) => ({ x: 0, y: i })); } winningSpot({ x, y }, XorO) { - return XorO === 'X' ? - y === this.board[0].length - 1 + x : - x === this.board.length - 1; + return XorO === 'X' + ? y === this.board[0].length - 1 + x + : x === this.board.length - 1; } matches({ x, y }, XorO) { return this.board[x] !== undefined && this.board[x][y] === XorO; diff --git a/exercises/crypto-square/babel.config.js b/exercises/crypto-square/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/crypto-square/babel.config.js +++ b/exercises/crypto-square/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/crypto-square/crypto-square.js b/exercises/crypto-square/crypto-square.js index 5be7fc625a..16a7ee7c8a 100644 --- a/exercises/crypto-square/crypto-square.js +++ b/exercises/crypto-square/crypto-square.js @@ -5,22 +5,22 @@ export class Crypto { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } normalizePlaintext() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } size() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } plaintextSegments() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } ciphertext() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/crypto-square/crypto-square.spec.js b/exercises/crypto-square/crypto-square.spec.js index e852f171a1..82e312df16 100644 --- a/exercises/crypto-square/crypto-square.spec.js +++ b/exercises/crypto-square/crypto-square.spec.js @@ -33,7 +33,13 @@ describe('Crypto', () => { xtest('plain text segments', () => { const crypto = new Crypto('Never vex thine heart with idle woes'); - expect(crypto.plaintextSegments()).toEqual(['neverv', 'exthin', 'eheart', 'withid', 'lewoes']); + expect(crypto.plaintextSegments()).toEqual([ + 'neverv', + 'exthin', + 'eheart', + 'withid', + 'lewoes', + ]); }); xtest('plain text segments', () => { diff --git a/exercises/custom-set/babel.config.js b/exercises/custom-set/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/custom-set/babel.config.js +++ b/exercises/custom-set/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/custom-set/custom-set.js b/exercises/custom-set/custom-set.js index bac9903d71..a203975de1 100644 --- a/exercises/custom-set/custom-set.js +++ b/exercises/custom-set/custom-set.js @@ -5,42 +5,42 @@ export class CustomSet { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } empty() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } contains() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } add() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } subset() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } disjoint() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } eql() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } union() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } intersection() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } difference() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/custom-set/custom-set.spec.js b/exercises/custom-set/custom-set.spec.js index f322cba425..aec7416b08 100644 --- a/exercises/custom-set/custom-set.spec.js +++ b/exercises/custom-set/custom-set.spec.js @@ -52,7 +52,9 @@ describe('CustomSet', () => { }); xtest('set is a subset of larger set with same elements', () => { - const actual = new CustomSet([1, 2, 3]).subset(new CustomSet([4, 1, 2, 3])); + const actual = new CustomSet([1, 2, 3]).subset( + new CustomSet([4, 1, 2, 3]) + ); expect(actual).toBe(true); }); @@ -154,19 +156,25 @@ describe('CustomSet', () => { }); xtest('intersection of a non-empty set and an empty set is an empty set', () => { - const actual = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet([])); + const actual = new CustomSet([1, 2, 3, 4]).intersection( + new CustomSet([]) + ); const expected = new CustomSet([]); expect(actual.eql(expected)).toBe(true); }); xtest('intersection of two sets with no shared elements is an empty set', () => { - const actual = new CustomSet([1, 2, 3]).intersection(new CustomSet([4, 5, 6])); + const actual = new CustomSet([1, 2, 3]).intersection( + new CustomSet([4, 5, 6]) + ); const expected = new CustomSet([]); expect(actual.eql(expected)).toBe(true); }); xtest('intersection of two sets with shared elements is a set of the shared elements', () => { - const actual = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet([3, 2, 5])); + const actual = new CustomSet([1, 2, 3, 4]).intersection( + new CustomSet([3, 2, 5]) + ); const expected = new CustomSet([2, 3]); expect(actual.eql(expected)).toBe(true); }); diff --git a/exercises/custom-set/example.js b/exercises/custom-set/example.js index 74a105af05..67a6d4c3bd 100644 --- a/exercises/custom-set/example.js +++ b/exercises/custom-set/example.js @@ -1,7 +1,7 @@ export class CustomSet { constructor(data = []) { this.data = {}; - data.forEach(el => this.add(el)); + data.forEach((el) => this.add(el)); } add(el) { @@ -31,7 +31,9 @@ export class CustomSet { } difference(other) { - return new CustomSet(Object.keys(this.data).filter(el => other.data[el] === undefined)); + return new CustomSet( + Object.keys(this.data).filter((el) => other.data[el] === undefined) + ); } disjoint(other) { diff --git a/exercises/darts/README.md b/exercises/darts/README.md index 2440f0e241..64da0a60ac 100644 --- a/exercises/darts/README.md +++ b/exercises/darts/README.md @@ -15,6 +15,7 @@ In our particular instance of the game, the target rewards with 4 different amou The outer circle has a radius of 10 units (This is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1. Of course, they are all centered to the same point (That is, the circles are [concentric](http://mathworld.wolfram.com/ConcentricCircles.html)) defined by the coordinates (0, 0). Write a function that given a point in the target (defined by its `real` cartesian coordinates `x` and `y`), returns the correct amount earned by a dart landing in that point. + ## Setup Go through the setup instructions for Javascript to install the necessary diff --git a/exercises/darts/babel.config.js b/exercises/darts/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/darts/babel.config.js +++ b/exercises/darts/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/darts/darts.js b/exercises/darts/darts.js index f349f8765a..7b6d4dd3de 100644 --- a/exercises/darts/darts.js +++ b/exercises/darts/darts.js @@ -4,5 +4,5 @@ // export const score = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/darts/darts.spec.js b/exercises/darts/darts.spec.js index 4e6697dcf7..163cabbfcc 100644 --- a/exercises/darts/darts.spec.js +++ b/exercises/darts/darts.spec.js @@ -53,4 +53,3 @@ describe('Darts', () => { expect(score(0.5, -4)).toEqual(5); }); }); - diff --git a/exercises/diamond/babel.config.js b/exercises/diamond/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/diamond/babel.config.js +++ b/exercises/diamond/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/diamond/diamond.js b/exercises/diamond/diamond.js index a4fdc7397c..03b7ad0ce8 100644 --- a/exercises/diamond/diamond.js +++ b/exercises/diamond/diamond.js @@ -4,5 +4,5 @@ // export const rows = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/diamond/diamond.spec.js b/exercises/diamond/diamond.spec.js index e9a7e3fec9..f45094d9b4 100644 --- a/exercises/diamond/diamond.spec.js +++ b/exercises/diamond/diamond.spec.js @@ -21,7 +21,7 @@ describe('Diamond', () => { 'D D', ' C C ', ' B B ', - ' A ' + ' A ', ]); }); @@ -77,7 +77,7 @@ describe('Diamond', () => { ' D D ', ' C C ', ' B B ', - ' A ' + ' A ', ]); }); }); diff --git a/exercises/diamond/example.js b/exercises/diamond/example.js index b1b9d6e68a..1248f7c954 100644 --- a/exercises/diamond/example.js +++ b/exercises/diamond/example.js @@ -1,4 +1,4 @@ -export const rows = input => { +export const rows = (input) => { const inputIndex = input.charCodeAt() - 65; let output = []; let i = 0; @@ -13,9 +13,9 @@ export const rows = input => { function getLine(inputIndex, index) { const difference = inputIndex - index; - return `${spaceTimes(difference) + - printAlphabets(index) + - spaceTimes(difference)}`; + return `${ + spaceTimes(difference) + printAlphabets(index) + spaceTimes(difference) + }`; } function printAlphabets(index) { diff --git a/exercises/difference-of-squares/babel.config.js b/exercises/difference-of-squares/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/difference-of-squares/babel.config.js +++ b/exercises/difference-of-squares/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/difference-of-squares/difference-of-squares.js b/exercises/difference-of-squares/difference-of-squares.js index f0fc532829..19aad4d0ba 100644 --- a/exercises/difference-of-squares/difference-of-squares.js +++ b/exercises/difference-of-squares/difference-of-squares.js @@ -5,18 +5,18 @@ export class Squares { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get sumOfSquares() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get squareOfSum() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get difference() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/diffie-hellman/babel.config.js b/exercises/diffie-hellman/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/diffie-hellman/babel.config.js +++ b/exercises/diffie-hellman/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/diffie-hellman/diffie-hellman.js b/exercises/diffie-hellman/diffie-hellman.js index f3918f54df..63b9440d71 100644 --- a/exercises/diffie-hellman/diffie-hellman.js +++ b/exercises/diffie-hellman/diffie-hellman.js @@ -5,14 +5,14 @@ export class DiffieHellman { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } getPublicKeyFromPrivateKey() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } getSharedSecret() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/diffie-hellman/diffie-hellman.spec.js b/exercises/diffie-hellman/diffie-hellman.spec.js index 2296bfa96f..f16778843d 100644 --- a/exercises/diffie-hellman/diffie-hellman.spec.js +++ b/exercises/diffie-hellman/diffie-hellman.spec.js @@ -55,20 +55,26 @@ describe('diffie-hellman', () => { }); xtest('when given a private key, returns the correct public one', () => { - expect(diffieHellman.getPublicKeyFromPrivateKey(alicePrivateKey)).toEqual(alicePublicKey); + expect(diffieHellman.getPublicKeyFromPrivateKey(alicePrivateKey)).toEqual( + alicePublicKey + ); }); xtest('when given a different private key, returns the correct public one', () => { - expect(diffieHellman.getPublicKeyFromPrivateKey(bobPrivateKey)).toEqual(bobPublicKey); + expect(diffieHellman.getPublicKeyFromPrivateKey(bobPrivateKey)).toEqual( + bobPublicKey + ); }); xtest('can generate a shared secret from our private key and their public key', () => { const sharedSecret = 2; - expect(diffieHellman.getSharedSecret(alicePrivateKey, bobPublicKey)) - .toEqual(sharedSecret); + expect( + diffieHellman.getSharedSecret(alicePrivateKey, bobPublicKey) + ).toEqual(sharedSecret); - expect(diffieHellman.getSharedSecret(bobPrivateKey, alicePublicKey)) - .toEqual(sharedSecret); + expect( + diffieHellman.getSharedSecret(bobPrivateKey, alicePublicKey) + ).toEqual(sharedSecret); }); }); diff --git a/exercises/diffie-hellman/example.js b/exercises/diffie-hellman/example.js index 0989d669a7..c4884f9fd4 100644 --- a/exercises/diffie-hellman/example.js +++ b/exercises/diffie-hellman/example.js @@ -1,7 +1,1006 @@ /* eslint-disable max-len */ // array of first 1000 primes. const PRIMES = [ - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 61, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + 101, + 103, + 107, + 109, + 113, + 127, + 131, + 137, + 139, + 149, + 151, + 157, + 163, + 167, + 173, + 179, + 181, + 191, + 193, + 197, + 199, + 211, + 223, + 227, + 229, + 233, + 239, + 241, + 251, + 257, + 263, + 269, + 271, + 277, + 281, + 283, + 293, + 307, + 311, + 313, + 317, + 331, + 337, + 347, + 349, + 353, + 359, + 367, + 373, + 379, + 383, + 389, + 397, + 401, + 409, + 419, + 421, + 431, + 433, + 439, + 443, + 449, + 457, + 461, + 463, + 467, + 479, + 487, + 491, + 499, + 503, + 509, + 521, + 523, + 541, + 547, + 557, + 563, + 569, + 571, + 577, + 587, + 593, + 599, + 601, + 607, + 613, + 617, + 619, + 631, + 641, + 643, + 647, + 653, + 659, + 661, + 673, + 677, + 683, + 691, + 701, + 709, + 719, + 727, + 733, + 739, + 743, + 751, + 757, + 761, + 769, + 773, + 787, + 797, + 809, + 811, + 821, + 823, + 827, + 829, + 839, + 853, + 857, + 859, + 863, + 877, + 881, + 883, + 887, + 907, + 911, + 919, + 929, + 937, + 941, + 947, + 953, + 967, + 971, + 977, + 983, + 991, + 997, + 1009, + 1013, + 1019, + 1021, + 1031, + 1033, + 1039, + 1049, + 1051, + 1061, + 1063, + 1069, + 1087, + 1091, + 1093, + 1097, + 1103, + 1109, + 1117, + 1123, + 1129, + 1151, + 1153, + 1163, + 1171, + 1181, + 1187, + 1193, + 1201, + 1213, + 1217, + 1223, + 1229, + 1231, + 1237, + 1249, + 1259, + 1277, + 1279, + 1283, + 1289, + 1291, + 1297, + 1301, + 1303, + 1307, + 1319, + 1321, + 1327, + 1361, + 1367, + 1373, + 1381, + 1399, + 1409, + 1423, + 1427, + 1429, + 1433, + 1439, + 1447, + 1451, + 1453, + 1459, + 1471, + 1481, + 1483, + 1487, + 1489, + 1493, + 1499, + 1511, + 1523, + 1531, + 1543, + 1549, + 1553, + 1559, + 1567, + 1571, + 1579, + 1583, + 1597, + 1601, + 1607, + 1609, + 1613, + 1619, + 1621, + 1627, + 1637, + 1657, + 1663, + 1667, + 1669, + 1693, + 1697, + 1699, + 1709, + 1721, + 1723, + 1733, + 1741, + 1747, + 1753, + 1759, + 1777, + 1783, + 1787, + 1789, + 1801, + 1811, + 1823, + 1831, + 1847, + 1861, + 1867, + 1871, + 1873, + 1877, + 1879, + 1889, + 1901, + 1907, + 1913, + 1931, + 1933, + 1949, + 1951, + 1973, + 1979, + 1987, + 1993, + 1997, + 1999, + 2003, + 2011, + 2017, + 2027, + 2029, + 2039, + 2053, + 2063, + 2069, + 2081, + 2083, + 2087, + 2089, + 2099, + 2111, + 2113, + 2129, + 2131, + 2137, + 2141, + 2143, + 2153, + 2161, + 2179, + 2203, + 2207, + 2213, + 2221, + 2237, + 2239, + 2243, + 2251, + 2267, + 2269, + 2273, + 2281, + 2287, + 2293, + 2297, + 2309, + 2311, + 2333, + 2339, + 2341, + 2347, + 2351, + 2357, + 2371, + 2377, + 2381, + 2383, + 2389, + 2393, + 2399, + 2411, + 2417, + 2423, + 2437, + 2441, + 2447, + 2459, + 2467, + 2473, + 2477, + 2503, + 2521, + 2531, + 2539, + 2543, + 2549, + 2551, + 2557, + 2579, + 2591, + 2593, + 2609, + 2617, + 2621, + 2633, + 2647, + 2657, + 2659, + 2663, + 2671, + 2677, + 2683, + 2687, + 2689, + 2693, + 2699, + 2707, + 2711, + 2713, + 2719, + 2729, + 2731, + 2741, + 2749, + 2753, + 2767, + 2777, + 2789, + 2791, + 2797, + 2801, + 2803, + 2819, + 2833, + 2837, + 2843, + 2851, + 2857, + 2861, + 2879, + 2887, + 2897, + 2903, + 2909, + 2917, + 2927, + 2939, + 2953, + 2957, + 2963, + 2969, + 2971, + 2999, + 3001, + 3011, + 3019, + 3023, + 3037, + 3041, + 3049, + 3061, + 3067, + 3079, + 3083, + 3089, + 3109, + 3119, + 3121, + 3137, + 3163, + 3167, + 3169, + 3181, + 3187, + 3191, + 3203, + 3209, + 3217, + 3221, + 3229, + 3251, + 3253, + 3257, + 3259, + 3271, + 3299, + 3301, + 3307, + 3313, + 3319, + 3323, + 3329, + 3331, + 3343, + 3347, + 3359, + 3361, + 3371, + 3373, + 3389, + 3391, + 3407, + 3413, + 3433, + 3449, + 3457, + 3461, + 3463, + 3467, + 3469, + 3491, + 3499, + 3511, + 3517, + 3527, + 3529, + 3533, + 3539, + 3541, + 3547, + 3557, + 3559, + 3571, + 3581, + 3583, + 3593, + 3607, + 3613, + 3617, + 3623, + 3631, + 3637, + 3643, + 3659, + 3671, + 3673, + 3677, + 3691, + 3697, + 3701, + 3709, + 3719, + 3727, + 3733, + 3739, + 3761, + 3767, + 3769, + 3779, + 3793, + 3797, + 3803, + 3821, + 3823, + 3833, + 3847, + 3851, + 3853, + 3863, + 3877, + 3881, + 3889, + 3907, + 3911, + 3917, + 3919, + 3923, + 3929, + 3931, + 3943, + 3947, + 3967, + 3989, + 4001, + 4003, + 4007, + 4013, + 4019, + 4021, + 4027, + 4049, + 4051, + 4057, + 4073, + 4079, + 4091, + 4093, + 4099, + 4111, + 4127, + 4129, + 4133, + 4139, + 4153, + 4157, + 4159, + 4177, + 4201, + 4211, + 4217, + 4219, + 4229, + 4231, + 4241, + 4243, + 4253, + 4259, + 4261, + 4271, + 4273, + 4283, + 4289, + 4297, + 4327, + 4337, + 4339, + 4349, + 4357, + 4363, + 4373, + 4391, + 4397, + 4409, + 4421, + 4423, + 4441, + 4447, + 4451, + 4457, + 4463, + 4481, + 4483, + 4493, + 4507, + 4513, + 4517, + 4519, + 4523, + 4547, + 4549, + 4561, + 4567, + 4583, + 4591, + 4597, + 4603, + 4621, + 4637, + 4639, + 4643, + 4649, + 4651, + 4657, + 4663, + 4673, + 4679, + 4691, + 4703, + 4721, + 4723, + 4729, + 4733, + 4751, + 4759, + 4783, + 4787, + 4789, + 4793, + 4799, + 4801, + 4813, + 4817, + 4831, + 4861, + 4871, + 4877, + 4889, + 4903, + 4909, + 4919, + 4931, + 4933, + 4937, + 4943, + 4951, + 4957, + 4967, + 4969, + 4973, + 4987, + 4993, + 4999, + 5003, + 5009, + 5011, + 5021, + 5023, + 5039, + 5051, + 5059, + 5077, + 5081, + 5087, + 5099, + 5101, + 5107, + 5113, + 5119, + 5147, + 5153, + 5167, + 5171, + 5179, + 5189, + 5197, + 5209, + 5227, + 5231, + 5233, + 5237, + 5261, + 5273, + 5279, + 5281, + 5297, + 5303, + 5309, + 5323, + 5333, + 5347, + 5351, + 5381, + 5387, + 5393, + 5399, + 5407, + 5413, + 5417, + 5419, + 5431, + 5437, + 5441, + 5443, + 5449, + 5471, + 5477, + 5479, + 5483, + 5501, + 5503, + 5507, + 5519, + 5521, + 5527, + 5531, + 5557, + 5563, + 5569, + 5573, + 5581, + 5591, + 5623, + 5639, + 5641, + 5647, + 5651, + 5653, + 5657, + 5659, + 5669, + 5683, + 5689, + 5693, + 5701, + 5711, + 5717, + 5737, + 5741, + 5743, + 5749, + 5779, + 5783, + 5791, + 5801, + 5807, + 5813, + 5821, + 5827, + 5839, + 5843, + 5849, + 5851, + 5857, + 5861, + 5867, + 5869, + 5879, + 5881, + 5897, + 5903, + 5923, + 5927, + 5939, + 5953, + 5981, + 5987, + 6007, + 6011, + 6029, + 6037, + 6043, + 6047, + 6053, + 6067, + 6073, + 6079, + 6089, + 6091, + 6101, + 6113, + 6121, + 6131, + 6133, + 6143, + 6151, + 6163, + 6173, + 6197, + 6199, + 6203, + 6211, + 6217, + 6221, + 6229, + 6247, + 6257, + 6263, + 6269, + 6271, + 6277, + 6287, + 6299, + 6301, + 6311, + 6317, + 6323, + 6329, + 6337, + 6343, + 6353, + 6359, + 6361, + 6367, + 6373, + 6379, + 6389, + 6397, + 6421, + 6427, + 6449, + 6451, + 6469, + 6473, + 6481, + 6491, + 6521, + 6529, + 6547, + 6551, + 6553, + 6563, + 6569, + 6571, + 6577, + 6581, + 6599, + 6607, + 6619, + 6637, + 6653, + 6659, + 6661, + 6673, + 6679, + 6689, + 6691, + 6701, + 6703, + 6709, + 6719, + 6733, + 6737, + 6761, + 6763, + 6779, + 6781, + 6791, + 6793, + 6803, + 6823, + 6827, + 6829, + 6833, + 6841, + 6857, + 6863, + 6869, + 6871, + 6883, + 6899, + 6907, + 6911, + 6917, + 6947, + 6949, + 6959, + 6961, + 6967, + 6971, + 6977, + 6983, + 6991, + 6997, + 7001, + 7013, + 7019, + 7027, + 7039, + 7043, + 7057, + 7069, + 7079, + 7103, + 7109, + 7121, + 7127, + 7129, + 7151, + 7159, + 7177, + 7187, + 7193, + 7207, + 7211, + 7213, + 7219, + 7229, + 7237, + 7243, + 7247, + 7253, + 7283, + 7297, + 7307, + 7309, + 7321, + 7331, + 7333, + 7349, + 7351, + 7369, + 7393, + 7411, + 7417, + 7433, + 7451, + 7457, + 7459, + 7477, + 7481, + 7487, + 7489, + 7499, + 7507, + 7517, + 7523, + 7529, + 7537, + 7541, + 7547, + 7549, + 7559, + 7561, + 7573, + 7577, + 7583, + 7589, + 7591, + 7603, + 7607, + 7621, + 7639, + 7643, + 7649, + 7669, + 7673, + 7681, + 7687, + 7691, + 7699, + 7703, + 7717, + 7723, + 7727, + 7741, + 7753, + 7757, + 7759, + 7789, + 7793, + 7817, + 7823, + 7829, + 7841, + 7853, + 7867, + 7873, + 7877, + 7879, + 7883, + 7901, + 7907, + 7919, ]; /* eslint-enable max-len */ @@ -17,22 +1016,26 @@ export class DiffieHellman { getPublicKeyFromPrivateKey(privateKey) { if (privateKey <= 1 || privateKey > this.p - 1) { - throw Error('Private key a must be greater than one but less than modulus parameter p!'); + throw Error( + 'Private key a must be greater than one but less than modulus parameter p!' + ); } - return (this.g ** privateKey) % this.p; + return this.g ** privateKey % this.p; } getSharedSecret(ourPrivateKey, theirPublicKey) { - return (theirPublicKey ** ourPrivateKey) % this.p; + return theirPublicKey ** ourPrivateKey % this.p; } static validateInitialArguments(p, g) { const BIGGEST_PRIME = PRIMES[PRIMES.length - 1]; - return p >= 2 - && g >= 2 - && p <= BIGGEST_PRIME - && g <= BIGGEST_PRIME - && PRIMES.includes(p) - && PRIMES.includes(g); + return ( + p >= 2 && + g >= 2 && + p <= BIGGEST_PRIME && + g <= BIGGEST_PRIME && + PRIMES.includes(p) && + PRIMES.includes(g) + ); } } diff --git a/exercises/dnd-character/README.md b/exercises/dnd-character/README.md index 005a2b02d9..485f95a257 100644 --- a/exercises/dnd-character/README.md +++ b/exercises/dnd-character/README.md @@ -1,8 +1,15 @@ # D&D Character -For a game of [Dungeons & Dragons][DND], each player starts by generating a character they can play with. This character has, among other things, six abilities; strength, dexterity, constitution, intelligence, wisdom and charisma. These six abilities have scores that are determined randomly. You do this by rolling four 6-sided dice and record the sum of the largest three dice. You do this six times, once for each ability. +For a game of [Dungeons & Dragons][DND], each player starts by generating a +character they can play with. This character has, among other things, six +abilities; strength, dexterity, constitution, intelligence, wisdom and +charisma. These six abilities have scores that are determined randomly. You +do this by rolling four 6-sided dice and record the sum of the largest three +dice. You do this six times, once for each ability. -Your character's initial hitpoints are 10 + your character's constitution modifier. You find your character's constitution modifier by subtracting 10 from your character's constitution, divide by 2 and round down. +Your character's initial hitpoints are 10 + your character's constitution +modifier. You find your character's constitution modifier by subtracting 10 +from your character's constitution, divide by 2 and round down. Write a random character generator that follows the rules above. @@ -19,7 +26,8 @@ Because constitution is 3, the constitution modifier is -4 and the hitpoints are ## Notes -Most programming languages feature (pseudo-)random generators, but few programming languages are designed to roll dice. One such language is [Troll]. +Most programming languages feature (pseudo-)random generators, but few +programming languages are designed to roll dice. One such language is [Troll]. [DND]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons [Troll]: http://hjemmesider.diku.dk/~torbenm/Troll/ diff --git a/exercises/dnd-character/babel.config.js b/exercises/dnd-character/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/dnd-character/babel.config.js +++ b/exercises/dnd-character/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/dnd-character/dnd-character.js b/exercises/dnd-character/dnd-character.js index 3ea54d9814..dac0b6190d 100644 --- a/exercises/dnd-character/dnd-character.js +++ b/exercises/dnd-character/dnd-character.js @@ -4,39 +4,39 @@ // export const abilityModifier = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export class Character { static rollAbility() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get strength() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get dexterity() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get constitution() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get intelligence() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get wisdom() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get charisma() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get hitpoints() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/dnd-character/example.js b/exercises/dnd-character/example.js index 089eadbd12..739b9f7ff8 100644 --- a/exercises/dnd-character/example.js +++ b/exercises/dnd-character/example.js @@ -23,7 +23,7 @@ export class Character { } } -export const abilityModifier = abilityScore => { +export const abilityModifier = (abilityScore) => { if (abilityScore < 3) { throw new Error('Ability scores must be at least 3'); } diff --git a/exercises/dominoes/babel.config.js b/exercises/dominoes/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/dominoes/babel.config.js +++ b/exercises/dominoes/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/dominoes/dominoes.js b/exercises/dominoes/dominoes.js index 826756ae03..2081ec1c5f 100644 --- a/exercises/dominoes/dominoes.js +++ b/exercises/dominoes/dominoes.js @@ -4,5 +4,5 @@ // export const chain = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/dominoes/dominoes.spec.js b/exercises/dominoes/dominoes.spec.js index acd6b19962..bc924694d8 100644 --- a/exercises/dominoes/dominoes.spec.js +++ b/exercises/dominoes/dominoes.spec.js @@ -1,135 +1,180 @@ -import { chain } from './dominoes' +import { chain } from './dominoes'; function runTest(dominoes, expected) { if (expected) { - runTestsExpectingChain(dominoes) + runTestsExpectingChain(dominoes); } else { - runTestsExpectingNull(dominoes) + runTestsExpectingNull(dominoes); } } function runTestsExpectingNull(dominoes) { - const result = chain(dominoes) + const result = chain(dominoes); it('Should not have a chain', () => { - expect(result).toBe(null) - }) + expect(result).toBe(null); + }); } function runTestsExpectingChain(dominoes) { - const result = chain(dominoes) + const result = chain(dominoes); it('Should have a chain', () => { - expect(result).not.toBe(null) - }) + expect(result).not.toBe(null); + }); it('The number of dominoes in the output equals the number of dominoes in the input.', () => { - expect(result).toHaveLength(dominoes.length) - }) + expect(result).toHaveLength(dominoes.length); + }); it('For each adjacent pair of dominoes ... (a, b), (c, d) ...: b is equal to c.', () => { - expect(result.map((v, i) => { - if (i === result.length - 1) return true - return v[1] === result[i + 1][0] - }).every(Boolean)).toBe(true) - }) + expect( + result + .map((v, i) => { + if (i === result.length - 1) return true; + return v[1] === result[i + 1][0]; + }) + .every(Boolean) + ).toBe(true); + }); if (dominoes.length > 0) { it('For the dominoes on the ends (a, b) ... (c, d): a is equal to d.', () => { - expect(result[0][0] === result[result.length - 1][1]).toBe(true) - }) + expect(result[0][0] === result[result.length - 1][1]).toBe(true); + }); } // 4. Every domino appears in the output an equal number of times as the number of times it appears in the input. // (in other words, the dominoes in the output are the same dominoes as the ones in the input) it('Should have the same dominoes', () => { - const sortDomino = domino => ([...domino].sort()) - expect([...dominoes].map(sortDomino).sort()).toEqual([...result].map(sortDomino).sort()) - }) + const sortDomino = (domino) => [...domino].sort(); + expect([...dominoes].map(sortDomino).sort()).toEqual( + [...result].map(sortDomino).sort() + ); + }); } describe('Dominoes', () => { describe('empty input = empty output', () => { - runTest( - [], - true - ) - }) + runTest([], true); + }); xdescribe('singleton input = singleton output', () => { - runTest( - [[1, 1]], - true - ) - }) + runTest([[1, 1]], true); + }); - xdescribe('singleton that can\'t be chained', () => { - runTest( - [[1, 2]], - false - ) - }) + xdescribe("singleton that can't be chained", () => { + runTest([[1, 2]], false); + }); xdescribe('three elements', () => { runTest( - [[1, 2], [3, 1], [2, 3]], + [ + [1, 2], + [3, 1], + [2, 3], + ], true - ) - }) + ); + }); xdescribe('can reverse dominoes', () => { runTest( - [[1, 2], [1, 3], [2, 3]], + [ + [1, 2], + [1, 3], + [2, 3], + ], true - ) - }) + ); + }); - xdescribe('can\'t be chained', () => { + xdescribe("can't be chained", () => { runTest( - [[1, 2], [4, 1], [2, 3]], + [ + [1, 2], + [4, 1], + [2, 3], + ], false - ) - }) + ); + }); xdescribe('disconnected - simple', () => { runTest( - [[1, 1], [2, 2]], + [ + [1, 1], + [2, 2], + ], false - ) - }) + ); + }); xdescribe('disconnected - double loop', () => { runTest( - [[1, 2], [2, 1], [3, 4], [4, 3]], + [ + [1, 2], + [2, 1], + [3, 4], + [4, 3], + ], false - ) - }) + ); + }); xdescribe('disconnected - single isolated', () => { runTest( - [[1, 2], [2, 3], [3, 1], [4, 4]], + [ + [1, 2], + [2, 3], + [3, 1], + [4, 4], + ], false - ) - }) + ); + }); xdescribe('need backtrack', () => { runTest( - [[1, 2], [2, 3], [3, 1], [2, 4], [2, 4]], + [ + [1, 2], + [2, 3], + [3, 1], + [2, 4], + [2, 4], + ], true - ) - }) + ); + }); xdescribe('separate loops', () => { runTest( - [[1, 2], [2, 3], [3, 1], [1, 1], [2, 2], [3, 3]], + [ + [1, 2], + [2, 3], + [3, 1], + [1, 1], + [2, 2], + [3, 3], + ], true - ) - }) + ); + }); xdescribe('nine elements', () => { runTest( - [[1, 2], [5, 3], [3, 1], [1, 2], [2, 4], [1, 6], [2, 3], [3, 4], [5, 6]], + [ + [1, 2], + [5, 3], + [3, 1], + [1, 2], + [2, 4], + [1, 6], + [2, 3], + [3, 4], + [5, 6], + ], true - ) - }) + ); + }); }); diff --git a/exercises/dominoes/example.js b/exercises/dominoes/example.js index 1187fa4ee9..65c0b09e60 100644 --- a/exercises/dominoes/example.js +++ b/exercises/dominoes/example.js @@ -1,53 +1,56 @@ // Finding Eulerian Path export const chain = (dominoes) => { - if (dominoes.length === 0) return [] - let remainings = dominoes + if (dominoes.length === 0) return []; + let remainings = dominoes; - let solution = [dominoes[0][0]] + let solution = [dominoes[0][0]]; // find the first loop const f = () => { - const maybeNextDomino = remainings.find(matchOneEnd(last(solution))) - if (!maybeNextDomino) return false - remainings = removeOneDomino(maybeNextDomino, remainings) - solution.push(otherEnd(last(solution), maybeNextDomino)) - if (last(solution) === solution[0]) return true - if (remainings.length === 0) return false - return f() - } - if (!f()) return null + const maybeNextDomino = remainings.find(matchOneEnd(last(solution))); + if (!maybeNextDomino) return false; + remainings = removeOneDomino(maybeNextDomino, remainings); + solution.push(otherEnd(last(solution), maybeNextDomino)); + if (last(solution) === solution[0]) return true; + if (remainings.length === 0) return false; + return f(); + }; + if (!f()) return null; // back track solution and join new loops - let target = solution.length + let target = solution.length; const g = () => { - if (target < 0) return remainings.length === 0 + if (target < 0) return remainings.length === 0; // no more edge on this vertex? while (remainings.find(matchOneEnd(solution[target]))) { // find the loop - const firstHalf = solution.slice(0, target) - const secondHalf = solution.slice(target + 1) + const firstHalf = solution.slice(0, target); + const secondHalf = solution.slice(target + 1); - solution = [solution[target]] - if (!f()) return false - solution = [...firstHalf, ...solution, ...secondHalf] + solution = [solution[target]]; + if (!f()) return false; + solution = [...firstHalf, ...solution, ...secondHalf]; } - target -= 1 - return g() - } + target -= 1; + return g(); + }; - if (!g()) return null + if (!g()) return null; - return solution.slice(0, solution.length - 1).map((v, i) => ([solution[i], solution[i + 1]])) + return solution + .slice(0, solution.length - 1) + .map((v, i) => [solution[i], solution[i + 1]]); }; const removeOneDomino = (domino, dominoes) => { - const k = dominoes.findIndex(matchDomino(domino)) - return [...dominoes.slice(0, k), ...dominoes.slice(k + 1)] -} -const otherEnd = (x, [a, b]) => a === x ? b : a -const matchDomino = ([a, b]) => ([c, d]) => (a === c && b === d) || (a === d && b === c) -const matchOneEnd = x => d2 => d2.includes(x) -const last = xs => xs[xs.length - 1] + const k = dominoes.findIndex(matchDomino(domino)); + return [...dominoes.slice(0, k), ...dominoes.slice(k + 1)]; +}; +const otherEnd = (x, [a, b]) => (a === x ? b : a); +const matchDomino = ([a, b]) => ([c, d]) => + (a === c && b === d) || (a === d && b === c); +const matchOneEnd = (x) => (d2) => d2.includes(x); +const last = (xs) => xs[xs.length - 1]; diff --git a/exercises/etl/README.md b/exercises/etl/README.md index a7dcd54756..107a5c1b1b 100644 --- a/exercises/etl/README.md +++ b/exercises/etl/README.md @@ -13,7 +13,7 @@ moaning about how stupid we could possibly be.) ### The goal -We're going to extract some scrabble scores from a legacy system. +We're going to extract some Scrabble scores from a legacy system. The old system stored a list of letters per score: @@ -25,7 +25,7 @@ The old system stored a list of letters per score: - 8 points: "J", "X", - 10 points: "Q", "Z", -The shiny new scrabble system instead stores the score per letter, which +The shiny new Scrabble system instead stores the score per letter, which makes it much faster and easier to calculate the score for a word. It also stores the letters in lower-case regardless of the case of the input letters: diff --git a/exercises/etl/babel.config.js b/exercises/etl/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/etl/babel.config.js +++ b/exercises/etl/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/etl/etl.js b/exercises/etl/etl.js index d219e0bf06..9890b2afda 100644 --- a/exercises/etl/etl.js +++ b/exercises/etl/etl.js @@ -4,5 +4,5 @@ // export const transform = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/etl/etl.spec.js b/exercises/etl/etl.spec.js index bd75bc93a1..b752b8dd5f 100644 --- a/exercises/etl/etl.spec.js +++ b/exercises/etl/etl.spec.js @@ -11,7 +11,11 @@ describe('Transform', () => { xtest('transforms more values', () => { const old = { 1: ['A', 'E', 'I', 'O', 'U'] }; const expected = { - a: 1, e: 1, i: 1, o: 1, u: 1, + a: 1, + e: 1, + i: 1, + o: 1, + u: 1, }; expect(transform(old)).toEqual(expected); @@ -20,7 +24,10 @@ describe('Transform', () => { xtest('transforms more keys', () => { const old = { 1: ['A', 'E'], 2: ['D', 'G'] }; const expected = { - a: 1, e: 1, d: 2, g: 2, + a: 1, + e: 1, + d: 2, + g: 2, }; expect(transform(old)).toEqual(expected); diff --git a/exercises/flatten-array/babel.config.js b/exercises/flatten-array/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/flatten-array/babel.config.js +++ b/exercises/flatten-array/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/flatten-array/example.js b/exercises/flatten-array/example.js index c62cb0a9f3..d0412cd8ff 100644 --- a/exercises/flatten-array/example.js +++ b/exercises/flatten-array/example.js @@ -1,7 +1,9 @@ export const flatten = (arr) => { return arr - .reduce((acc, el) => (Array.isArray(el) - ? acc.concat(flatten(el)) - : acc.concat(el)), []) - .filter(el => el !== null && el !== undefined); -} + .reduce( + (acc, el) => + Array.isArray(el) ? acc.concat(flatten(el)) : acc.concat(el), + [] + ) + .filter((el) => el !== null && el !== undefined); +}; diff --git a/exercises/flatten-array/flatten-array.js b/exercises/flatten-array/flatten-array.js index 1e36318457..06de551447 100644 --- a/exercises/flatten-array/flatten-array.js +++ b/exercises/flatten-array/flatten-array.js @@ -4,5 +4,5 @@ // export const flatten = () => { - throw new Error("Remove this statement and implement this function"); -} + throw new Error('Remove this statement and implement this function'); +}; diff --git a/exercises/flatten-array/flatten-array.spec.js b/exercises/flatten-array/flatten-array.spec.js index 582a48fa3e..66b05fb4cf 100644 --- a/exercises/flatten-array/flatten-array.spec.js +++ b/exercises/flatten-array/flatten-array.spec.js @@ -18,27 +18,60 @@ describe('FlattenArray', () => { }); xtest('flattens a 3 level nested list', () => { - expect(flatten([1, [2, 3, 4], 5, [6, [7, 8]]])) - .toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + expect(flatten([1, [2, 3, 4], 5, [6, [7, 8]]])).toEqual([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + ]); }); xtest('flattens a 5 level nested list', () => { - expect(flatten([0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2])) - .toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); + expect(flatten([0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2])).toEqual([ + 0, + 2, + 2, + 3, + 8, + 100, + 4, + 50, + -2, + ]); }); xtest('flattens a 6 level nested list', () => { - expect(flatten([1, [2, [[3]], [4, [[5]]], 6, 7], 8])) - .toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + expect(flatten([1, [2, [[3]], [4, [[5]]], 6, 7], 8])).toEqual([ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + ]); }); xtest('flattens a 6 level nested list with null values', () => { - expect(flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])) - .toEqual([0, 2, 2, 3, 8, 100, -2]); + expect(flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([ + 0, + 2, + 2, + 3, + 8, + 100, + -2, + ]); }); xtest('returns an empty list if all values in nested list are null', () => { - expect(flatten([null, [[[null]]], null, null, [[null, null], null], null])) - .toEqual([]); + expect( + flatten([null, [[[null]]], null, null, [[null, null], null], null]) + ).toEqual([]); }); }); diff --git a/exercises/food-chain/babel.config.js b/exercises/food-chain/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/food-chain/babel.config.js +++ b/exercises/food-chain/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/food-chain/example.js b/exercises/food-chain/example.js index c5395276b8..49e6f5ef47 100644 --- a/exercises/food-chain/example.js +++ b/exercises/food-chain/example.js @@ -8,24 +8,28 @@ export class Song { */ verse(number) { switch (number) { - case 1: return `I know an old lady who swallowed a fly. + case 1: + return `I know an old lady who swallowed a fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 2: return `I know an old lady who swallowed a spider. + case 2: + return `I know an old lady who swallowed a spider. It wriggled and jiggled and tickled inside her. She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 3: return `I know an old lady who swallowed a bird. + case 3: + return `I know an old lady who swallowed a bird. How absurd to swallow a bird! She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 4: return `I know an old lady who swallowed a cat. + case 4: + return `I know an old lady who swallowed a cat. Imagine that, to swallow a cat! She swallowed the cat to catch the bird. She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. @@ -33,7 +37,8 @@ She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 5: return `I know an old lady who swallowed a dog. + case 5: + return `I know an old lady who swallowed a dog. What a hog, to swallow a dog! She swallowed the dog to catch the cat. She swallowed the cat to catch the bird. @@ -42,7 +47,8 @@ She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 6: return `I know an old lady who swallowed a goat. + case 6: + return `I know an old lady who swallowed a goat. Just opened her throat and swallowed a goat! She swallowed the goat to catch the dog. She swallowed the dog to catch the cat. @@ -52,7 +58,8 @@ She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 7: return `I know an old lady who swallowed a cow. + case 7: + return `I know an old lady who swallowed a cow. I don't know how she swallowed a cow! She swallowed the cow to catch the goat. She swallowed the goat to catch the dog. @@ -63,7 +70,8 @@ She swallowed the spider to catch the fly. I don't know why she swallowed the fly. Perhaps she'll die. `; - case 8: return `I know an old lady who swallowed a horse. + case 8: + return `I know an old lady who swallowed a horse. She's dead, of course! `; } @@ -84,7 +92,7 @@ She's dead, of course! const sequence = Array.from({ length: rangeLength }, (v, k) => first + k); // integers from first to last // build the final string - const str = sequence.map(x => this.verse(x)); + const str = sequence.map((x) => this.verse(x)); str.push(''); return str.join('\n'); } diff --git a/exercises/food-chain/food-chain.js b/exercises/food-chain/food-chain.js index 4e111227a4..3704489537 100644 --- a/exercises/food-chain/food-chain.js +++ b/exercises/food-chain/food-chain.js @@ -5,10 +5,10 @@ export class Song { verse() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } verses() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/forth/babel.config.js b/exercises/forth/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/forth/babel.config.js +++ b/exercises/forth/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/forth/example.js b/exercises/forth/example.js index 1792c0f5be..323800f91a 100644 --- a/exercises/forth/example.js +++ b/exercises/forth/example.js @@ -1,5 +1,5 @@ export class Forth { - constructor(){ + constructor() { this.stack = []; this.commands = Forth.basicCommands(); } @@ -16,7 +16,10 @@ export class Forth { // word definition const semicolon = words.indexOf(';', t); if (semicolon === -1) throw new Error('Unterminated definition'); - this.defineCommand(words[t + 1], words.slice(t + 2, semicolon).join(' ')); + this.defineCommand( + words[t + 1], + words.slice(t + 2, semicolon).join(' ') + ); t = semicolon; } else { // commands @@ -26,12 +29,12 @@ export class Forth { } } } - defineCommand(word, subprogram){ + defineCommand(word, subprogram) { if (Forth.isKeyword(word)) throw new Error('Invalid definition'); this.commands[word] = { arity: 0, // handled inside the call - execute: this.evaluate.bind(this, subprogram) - } + execute: this.evaluate.bind(this, subprogram), + }; } performCommand(command) { if (command.arity > this.stack.length) throw new Error('Stack empty'); @@ -48,14 +51,17 @@ export class Forth { '+': { arity: 2, execute: (a, b) => [a + b] }, '-': { arity: 2, execute: (a, b) => [a - b] }, '*': { arity: 2, execute: (a, b) => [a * b] }, - '/': { arity: 2, execute: (a, b) => { - if (b === 0) throw new Error('Division by zero'); - return [Math.floor(a / b)]; - } }, - dup: { arity: 1, execute: a => [a, a] }, + '/': { + arity: 2, + execute: (a, b) => { + if (b === 0) throw new Error('Division by zero'); + return [Math.floor(a / b)]; + }, + }, + dup: { arity: 1, execute: (a) => [a, a] }, drop: { arity: 1, execute: () => {} }, swap: { arity: 2, execute: (a, b) => [b, a] }, - over: { arity: 2, execute: (a, b) => [a, b, a] } + over: { arity: 2, execute: (a, b) => [a, b, a] }, }; } } diff --git a/exercises/forth/forth.js b/exercises/forth/forth.js index 1cc01ccde7..1314aef466 100644 --- a/exercises/forth/forth.js +++ b/exercises/forth/forth.js @@ -4,7 +4,6 @@ // export class Forth { - constructor() { throw Error('Remove this statement and implement this function'); } @@ -16,5 +15,4 @@ export class Forth { get stack() { throw Error('Remove this statement and implement this function'); } - } diff --git a/exercises/gigasecond/babel.config.js b/exercises/gigasecond/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/gigasecond/babel.config.js +++ b/exercises/gigasecond/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/gigasecond/gigasecond.js b/exercises/gigasecond/gigasecond.js index 9a3ca6335f..01df97fb98 100644 --- a/exercises/gigasecond/gigasecond.js +++ b/exercises/gigasecond/gigasecond.js @@ -4,5 +4,5 @@ // export const gigasecond = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/gigasecond/gigasecond.spec.js b/exercises/gigasecond/gigasecond.spec.js index 41b110b667..c514a35e63 100644 --- a/exercises/gigasecond/gigasecond.spec.js +++ b/exercises/gigasecond/gigasecond.spec.js @@ -1,34 +1,34 @@ import { gigasecond } from './gigasecond'; -describe('Gigasecond', () => { +describe('Gigasecond', () => { // date only specification of time test('tells a gigasecond anniversary since midnight', () => { const gs = gigasecond(new Date(Date.UTC(2011, 3, 25))); const expectedDate = new Date(Date.parse('2043-01-01T01:46:40Z')); expect(gs).toEqual(expectedDate); }); - + // second test for date only specification of time xtest('tells another gigasecond anniversary since midnight', () => { const gs = gigasecond(new Date(Date.UTC(1977, 5, 13))); const expectedDate = new Date(Date.parse('2009-02-19T01:46:40Z')); expect(gs).toEqual(expectedDate); }); - + // third test for date only specification of time xtest('tells gigasecond anniversary since midnight, from before UNIX epoch', () => { const gs = gigasecond(new Date(Date.UTC(1959, 6, 19))); const expectedDate = new Date(Date.parse('1991-03-27T01:46:40Z')); expect(gs).toEqual(expectedDate); }); - + // full time specified xtest('tells the anniversary, including a time', () => { const gs = gigasecond(new Date(Date.UTC(2015, 0, 24, 22, 0, 0))); const expectedDate = new Date(Date.parse('2046-10-02T23:46:40Z')); expect(gs).toEqual(expectedDate); }); - + // full time with day roll-over xtest('tells the anniversary is next day when you are born at night', () => { const gs = gigasecond(new Date(Date.UTC(2015, 0, 24, 23, 59, 59))); diff --git a/exercises/grade-school/README.md b/exercises/grade-school/README.md index 96bf5cca82..a432df8c38 100644 --- a/exercises/grade-school/README.md +++ b/exercises/grade-school/README.md @@ -15,8 +15,11 @@ In the end, you should be able to: as 1, 2, 3, etc., and students within a grade should be sorted alphabetically by name. - "Who all is enrolled in school right now?" - - "Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe. - Grade 3…" + - "Let me think. We have + Anna, Barb, and Charlie in grade 1, + Alex, Peter, and Zoe in grade 2 + and Jim in grade 5. + So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe and Jim" Note that all our students only have one name. (It's a small town, what do you want?) diff --git a/exercises/grade-school/babel.config.js b/exercises/grade-school/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/grade-school/babel.config.js +++ b/exercises/grade-school/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/grade-school/example.js b/exercises/grade-school/example.js index 5f19f40108..28c7abb29f 100644 --- a/exercises/grade-school/example.js +++ b/exercises/grade-school/example.js @@ -1,4 +1,3 @@ - function clone(obj) { return JSON.parse(JSON.stringify(obj)); } diff --git a/exercises/grade-school/grade-school.js b/exercises/grade-school/grade-school.js index 537b49e2d8..6385d9668f 100644 --- a/exercises/grade-school/grade-school.js +++ b/exercises/grade-school/grade-school.js @@ -5,14 +5,14 @@ export class GradeSchool { roster() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } add() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } grade() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/grains/babel.config.js b/exercises/grains/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/grains/babel.config.js +++ b/exercises/grains/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/grains/example.js b/exercises/grains/example.js index dde8bd9443..3c634af49c 100644 --- a/exercises/grains/example.js +++ b/exercises/grains/example.js @@ -5,7 +5,7 @@ * * @return {BigInt} Square of num */ -export const square = num => { +export const square = (num) => { if (num < 1 || num > 64) { throw new Error('square must be between 1 and 64'); } diff --git a/exercises/grains/grains.js b/exercises/grains/grains.js index 98e6e4d6d4..bd95f6dc6b 100644 --- a/exercises/grains/grains.js +++ b/exercises/grains/grains.js @@ -3,9 +3,9 @@ // convenience to get you started writing code faster. // export const square = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const total = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/grep/babel.config.js b/exercises/grep/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/grep/babel.config.js +++ b/exercises/grep/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/grep/example.js b/exercises/grep/example.js index ccbd7b6252..2f563e5077 100755 --- a/exercises/grep/example.js +++ b/exercises/grep/example.js @@ -1,13 +1,13 @@ #!/usr/bin/env node -const fs = require("fs"); -const path = require("path"); +const fs = require('fs'); +const path = require('path'); const VALID_OPTIONS = [ - "n", // add line numbers - "l", // print file names where pattern is found - "i", // ignore case - "v", // reverse files results - "x", // match entire line + 'n', // add line numbers + 'l', // print file names where pattern is found + 'i', // ignore case + 'v', // reverse files results + 'x', // match entire line ]; const ARGS = process.argv; @@ -17,13 +17,13 @@ function checkLineMatchesPattern(line, pattern) { let right = pattern; // ignore case - if (isOptionSet("i")) { + if (isOptionSet('i')) { left = line.toLowerCase(); right = pattern.toLowerCase(); } // match entire line - if (isOptionSet("x")) { + if (isOptionSet('x')) { return left === right; } @@ -39,13 +39,13 @@ function checkLineMatchesPattern(line, pattern) { * @returns {string[]} the lines */ function readLines(file) { - const data = fs.readFileSync(path.resolve(file), { encoding: "utf-8" }); + const data = fs.readFileSync(path.resolve(file), { encoding: 'utf-8' }); return data.split(/\r?\n/); } function getConfigFromArgs() { const config = { - pattern: "", + pattern: '', options: [], files: [], }; @@ -58,8 +58,8 @@ function getConfigFromArgs() { return; } - if (val.indexOf("-") !== -1) { - const option = val.replace("-", ""); + if (val.indexOf('-') !== -1) { + const option = val.replace('-', ''); if (!VALID_OPTIONS.includes(option)) { throw new Error(`Unknown option ${option}`); @@ -83,12 +83,12 @@ files.forEach((file) => { const lines = readLines(file); // print file names where pattern is found - if (isOptionSet("l")) { + if (isOptionSet('l')) { const foundMatch = lines.find((line) => { const lineMatchesPattern = checkLineMatchesPattern(line, pattern); // reverse files results - return isOptionSet("v") ? !lineMatchesPattern : lineMatchesPattern; + return isOptionSet('v') ? !lineMatchesPattern : lineMatchesPattern; }); if (foundMatch) { @@ -99,11 +99,11 @@ files.forEach((file) => { } lines.forEach((line, index) => { - let result = ""; + let result = ''; let shouldOutputLine = checkLineMatchesPattern(line, pattern); // reverse files results - if (isOptionSet("v")) { + if (isOptionSet('v')) { shouldOutputLine = !shouldOutputLine; } @@ -113,7 +113,7 @@ files.forEach((file) => { } // add line numbers - if (isOptionSet("n")) { + if (isOptionSet('n')) { result += `${index + 1}:`; } diff --git a/exercises/grep/grep.js b/exercises/grep/grep.js index d3837cbac0..6f3c394094 100755 --- a/exercises/grep/grep.js +++ b/exercises/grep/grep.js @@ -15,8 +15,8 @@ // // Read more about shebangs here: https://en.wikipedia.org/wiki/Shebang_(Unix) -const fs = require("fs"); -const path = require("path"); +const fs = require('fs'); +const path = require('path'); /** * Reads the given file and returns lines. @@ -27,16 +27,16 @@ const path = require("path"); * @returns {string[]} the lines */ function readLines(file) { - const data = fs.readFileSync(path.resolve(file), { encoding: "utf-8" }); + const data = fs.readFileSync(path.resolve(file), { encoding: 'utf-8' }); return data.split(/\r?\n/); } const VALID_OPTIONS = [ - "n", // add line numbers - "l", // print file names where pattern is found - "i", // ignore case - "v", // reverse files results - "x", // match entire line + 'n', // add line numbers + 'l', // print file names where pattern is found + 'i', // ignore case + 'v', // reverse files results + 'x', // match entire line ]; const ARGS = process.argv; diff --git a/exercises/grep/grep.spec.js b/exercises/grep/grep.spec.js index 7e5e9510f5..f83be90532 100755 --- a/exercises/grep/grep.spec.js +++ b/exercises/grep/grep.spec.js @@ -1,7 +1,7 @@ // @ts-check -const { spawnSync } = require("child_process"); -const { resolve, relative } = require("path"); +const { spawnSync } = require('child_process'); +const { resolve, relative } = require('path'); const BASE_DIR = resolve(__dirname); @@ -14,18 +14,18 @@ const BASE_DIR = resolve(__dirname); */ function spawnGrep(config) { const args = [ - resolve(BASE_DIR, "grep.js"), + resolve(BASE_DIR, 'grep.js'), ...config.flags, config.pattern, ...config.files.map((file) => - relative(BASE_DIR, resolve(BASE_DIR, "data", file)) + relative(BASE_DIR, resolve(BASE_DIR, 'data', file)) ), ]; return new Promise((resolve, reject) => { - const child = spawnSync("node", args, { stdio: "pipe", cwd: BASE_DIR }); + const child = spawnSync('node', args, { stdio: 'pipe', cwd: BASE_DIR }); const stderr = child.stderr.toString().trim(); - const stdout = child.stdout.toString().trim().split(/\r?\n/).join("\n"); + const stdout = child.stdout.toString().trim().split(/\r?\n/).join('\n'); // If anything is written to stderr, consider the entire process as failed. // @@ -48,7 +48,7 @@ function formatStringTemplate(stringTemplate) { return stringTemplate .split(/\r?\n/) .map((sentence) => sentence.trim()) - .join("\n"); + .join('\n'); } /** @@ -56,77 +56,77 @@ function formatStringTemplate(stringTemplate) { * @param {string} file */ function resolveDataFile(file) { - return relative(BASE_DIR, resolve(BASE_DIR, "data", file)); + return relative(BASE_DIR, resolve(BASE_DIR, 'data', file)); } -describe("grep exercise", () => { - describe("Test grepping a single file", () => { - it("One file, one match, no flags", () => { +describe('grep exercise', () => { + describe('Test grepping a single file', () => { + it('One file, one match, no flags', () => { return expect( spawnGrep({ - pattern: "Agamemnon", + pattern: 'Agamemnon', flags: [], - files: ["iliad.txt"], + files: ['iliad.txt'], }) - ).resolves.toBe("Of Atreus, Agamemnon, King of men."); + ).resolves.toBe('Of Atreus, Agamemnon, King of men.'); }); - xit("One file, one match, print line numbers flag", () => { + xit('One file, one match, print line numbers flag', () => { return expect( spawnGrep({ - pattern: "Forbidden", - flags: ["-n"], - files: ["paradise-lost.txt"], + pattern: 'Forbidden', + flags: ['-n'], + files: ['paradise-lost.txt'], }) - ).resolves.toBe("2:Of that Forbidden Tree, whose mortal tast"); + ).resolves.toBe('2:Of that Forbidden Tree, whose mortal tast'); }); - xit("One file, one match, case-insensitive flag", () => { + xit('One file, one match, case-insensitive flag', () => { return expect( spawnGrep({ - pattern: "FORBIDDEN", - flags: ["-i"], - files: ["paradise-lost.txt"], + pattern: 'FORBIDDEN', + flags: ['-i'], + files: ['paradise-lost.txt'], }) - ).resolves.toBe("Of that Forbidden Tree, whose mortal tast"); + ).resolves.toBe('Of that Forbidden Tree, whose mortal tast'); }); - xit("One file, one match, print file names flag", () => { + xit('One file, one match, print file names flag', () => { return expect( spawnGrep({ - pattern: "Forbidden", - flags: ["-l"], - files: ["paradise-lost.txt"], + pattern: 'Forbidden', + flags: ['-l'], + files: ['paradise-lost.txt'], }) - ).resolves.toBe(resolveDataFile("paradise-lost.txt")); + ).resolves.toBe(resolveDataFile('paradise-lost.txt')); }); - xit("One file, one match, match entire lines flag", () => { + xit('One file, one match, match entire lines flag', () => { return expect( spawnGrep({ - pattern: "With loss of Eden, till one greater Man", - flags: ["-x"], - files: ["paradise-lost.txt"], + pattern: 'With loss of Eden, till one greater Man', + flags: ['-x'], + files: ['paradise-lost.txt'], }) - ).resolves.toBe("With loss of Eden, till one greater Man"); + ).resolves.toBe('With loss of Eden, till one greater Man'); }); - xit("One file, one match, multiple flags", () => { + xit('One file, one match, multiple flags', () => { return expect( spawnGrep({ - pattern: "OF ATREUS, Agamemnon, KIng of MEN.", - flags: ["-n", "-i", "-x"], - files: ["iliad.txt"], + pattern: 'OF ATREUS, Agamemnon, KIng of MEN.', + flags: ['-n', '-i', '-x'], + files: ['iliad.txt'], }) - ).resolves.toBe("9:Of Atreus, Agamemnon, King of men."); + ).resolves.toBe('9:Of Atreus, Agamemnon, King of men.'); }); - xit("One file, several matches, no flags", () => { + xit('One file, several matches, no flags', () => { return expect( spawnGrep({ - pattern: "may", + pattern: 'may', flags: [], - files: ["midsummer-night.txt"], + files: ['midsummer-night.txt'], }) ).resolves.toBe( formatStringTemplate(`Nor how it may concern my modesty, @@ -135,12 +135,12 @@ describe("grep exercise", () => { ); }); - xit("One file, several matches, print line numbers flag", () => { + xit('One file, several matches, print line numbers flag', () => { return expect( spawnGrep({ - pattern: "may", - flags: ["-n"], - files: ["midsummer-night.txt"], + pattern: 'may', + flags: ['-n'], + files: ['midsummer-night.txt'], }) ).resolves.toBe( formatStringTemplate(`3:Nor how it may concern my modesty, @@ -149,22 +149,22 @@ describe("grep exercise", () => { ); }); - xit("One file, several matches, match entire lines flag", () => { + xit('One file, several matches, match entire lines flag', () => { return expect( spawnGrep({ - pattern: "may", - flags: ["-x"], - files: ["midsummer-night.txt"], + pattern: 'may', + flags: ['-x'], + files: ['midsummer-night.txt'], }) - ).resolves.toBe(""); + ).resolves.toBe(''); }); - xit("One file, several matches, case-insensitive flag", () => { + xit('One file, several matches, case-insensitive flag', () => { return expect( spawnGrep({ - pattern: "ACHILLES", - flags: ["-i"], - files: ["iliad.txt"], + pattern: 'ACHILLES', + flags: ['-i'], + files: ['iliad.txt'], }) ).resolves.toBe( formatStringTemplate(`Achilles sing, O Goddess! Peleus' son; @@ -172,12 +172,12 @@ describe("grep exercise", () => { ); }); - xit("One file, several matches, inverted flag", () => { + xit('One file, several matches, inverted flag', () => { return expect( spawnGrep({ - pattern: "Of", - flags: ["-v"], - files: ["paradise-lost.txt"], + pattern: 'Of', + flags: ['-v'], + files: ['paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`Brought Death into the World, and all our woe, @@ -188,32 +188,32 @@ describe("grep exercise", () => { ); }); - xit("One file, no matches, various flags", () => { + xit('One file, no matches, various flags', () => { return expect( spawnGrep({ - pattern: "Gandalf", - flags: ["-n", "-l", "-x", "-i"], - files: ["iliad.txt"], + pattern: 'Gandalf', + flags: ['-n', '-l', '-x', '-i'], + files: ['iliad.txt'], }) - ).resolves.toBe(""); + ).resolves.toBe(''); }); - xit("One file, one match, file flag takes precedence over line flag", () => { + xit('One file, one match, file flag takes precedence over line flag', () => { return expect( spawnGrep({ - pattern: "ten", - flags: ["-n", "-l"], - files: ["iliad.txt"], + pattern: 'ten', + flags: ['-n', '-l'], + files: ['iliad.txt'], }) - ).resolves.toBe(resolveDataFile("iliad.txt")); + ).resolves.toBe(resolveDataFile('iliad.txt')); }); - xit("One file, several matches, inverted and match entire lines flags", () => { + xit('One file, several matches, inverted and match entire lines flags', () => { return expect( spawnGrep({ - pattern: "Illustrious into Ades premature,", - flags: ["-x", "-v"], - files: ["iliad.txt"], + pattern: 'Illustrious into Ades premature,', + flags: ['-x', '-v'], + files: ['iliad.txt'], }) ).resolves.toBe( formatStringTemplate(`Achilles sing, O Goddess! Peleus' son; @@ -228,249 +228,249 @@ describe("grep exercise", () => { }); }); - describe("Test grepping multiples files at once", () => { - xit("Multiple files, one match, no flags", () => { + describe('Test grepping multiples files at once', () => { + xit('Multiple files, one match, no flags', () => { return expect( spawnGrep({ - pattern: "Agamemnon", + pattern: 'Agamemnon', flags: [], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( - `${resolveDataFile("iliad.txt")}:Of Atreus, Agamemnon, King of men.` + `${resolveDataFile('iliad.txt')}:Of Atreus, Agamemnon, King of men.` ); }); - xit("Multiple files, several matches, no flags", () => { + xit('Multiple files, several matches, no flags', () => { return expect( spawnGrep({ - pattern: "may", + pattern: 'may', flags: [], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:Nor how it may concern my modesty, ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:But I beseech your grace that I may know ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:The worst that may befall me in this case,`) ); }); - xit("Multiple files, several matches, print line numbers flag", () => { + xit('Multiple files, several matches, print line numbers flag', () => { return expect( spawnGrep({ - pattern: "that", - flags: ["-n"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'that', + flags: ['-n'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:5:But I beseech your grace that I may know ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:6:The worst that may befall me in this case, ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:2:Of that Forbidden Tree, whose mortal tast ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:6:Sing Heav'nly Muse, that on the secret top`) ); }); - it("Multiple files, one match, print file names flag", () => { + it('Multiple files, one match, print file names flag', () => { return expect( spawnGrep({ - pattern: "who", - flags: ["-l"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'who', + flags: ['-l'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( - formatStringTemplate(`${resolveDataFile("iliad.txt")} - ${resolveDataFile("paradise-lost.txt")}`) + formatStringTemplate(`${resolveDataFile('iliad.txt')} + ${resolveDataFile('paradise-lost.txt')}`) ); }); - xit("Multiple files, several matches, case-insensitive flag", () => { + xit('Multiple files, several matches, case-insensitive flag', () => { return expect( spawnGrep({ - pattern: "TO", - flags: ["-i"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'TO', + flags: ['-i'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:Caused to Achaia's host, sent many a soul - ${resolveDataFile("iliad.txt")}:Illustrious into Ades premature, + ${resolveDataFile('iliad.txt')}:Illustrious into Ades premature, ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:And Heroes gave (so stood the will of Jove) ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:To dogs and to all ravening fowls a prey, ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:I do entreat your grace to pardon me. ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:In such a presence here to plead my thoughts; - ${resolveDataFile("midsummer-night.txt")}:If I refuse to wed Demetrius. + ${resolveDataFile('midsummer-night.txt')}:If I refuse to wed Demetrius. ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Brought Death into the World, and all our woe, ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Restore us, and regain the blissful Seat, ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Sing Heav'nly Muse, that on the secret top`) ); }); - xit("Multiple files, several matches, inverted flag", () => { + xit('Multiple files, several matches, inverted flag', () => { return expect( spawnGrep({ - pattern: "a", - flags: ["-v"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'a', + flags: ['-v'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:Achilles sing, O Goddess! Peleus' son; - ${resolveDataFile("iliad.txt")}:The noble Chief Achilles from the son + ${resolveDataFile('iliad.txt')}:The noble Chief Achilles from the son ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:If I refuse to wed Demetrius.`) ); }); - xit("Multiple files, one match, match entire lines flag", () => { + xit('Multiple files, one match, match entire lines flag', () => { return expect( spawnGrep({ - pattern: "But I beseech your grace that I may know", - flags: ["-x"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'But I beseech your grace that I may know', + flags: ['-x'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( `${resolveDataFile( - "midsummer-night.txt:But I beseech your grace that I may know" + 'midsummer-night.txt:But I beseech your grace that I may know' )}` ); }); - xit("Multiple files, one match, multiple flags", () => { + xit('Multiple files, one match, multiple flags', () => { return expect( spawnGrep({ - pattern: "WITH LOSS OF EDEN, TILL ONE GREATER MAN", - flags: ["-n", "-i", "-x"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'WITH LOSS OF EDEN, TILL ONE GREATER MAN', + flags: ['-n', '-i', '-x'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( `${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:4:With loss of Eden, till one greater Man` ); }); - xit("Multiple files, no matches, various flags", () => { + xit('Multiple files, no matches, various flags', () => { return expect( spawnGrep({ - pattern: "Frodo", - flags: ["-n", "-l", "-x", "-i"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'Frodo', + flags: ['-n', '-l', '-x', '-i'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) - ).resolves.toBe(""); + ).resolves.toBe(''); }); - xit("Multiple files, several matches, file flag takes precedence over line number flag", () => { + xit('Multiple files, several matches, file flag takes precedence over line number flag', () => { return expect( spawnGrep({ - pattern: "who", - flags: ["-n", "-l"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'who', + flags: ['-n', '-l'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( - formatStringTemplate(`${resolveDataFile("iliad.txt")} - ${resolveDataFile("paradise-lost.txt")}`) + formatStringTemplate(`${resolveDataFile('iliad.txt')} + ${resolveDataFile('paradise-lost.txt')}`) ); }); - xit("Multiple files, several matches, inverted and match entire lines flags", () => { + xit('Multiple files, several matches, inverted and match entire lines flags', () => { return expect( spawnGrep({ - pattern: "Illustrious into Ades premature,", - flags: ["-x", "-v"], - files: ["iliad.txt", "midsummer-night.txt", "paradise-lost.txt"], + pattern: 'Illustrious into Ades premature,', + flags: ['-x', '-v'], + files: ['iliad.txt', 'midsummer-night.txt', 'paradise-lost.txt'], }) ).resolves.toBe( formatStringTemplate(`${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:Achilles sing, O Goddess! Peleus' son; ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:His wrath pernicious, who ten thousand woes ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:Caused to Achaia's host, sent many a soul ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:And Heroes gave (so stood the will of Jove) ${resolveDataFile( - "iliad.txt" + 'iliad.txt' )}:To dogs and to all ravening fowls a prey, - ${resolveDataFile("iliad.txt")}:When fierce dispute had separated once - ${resolveDataFile("iliad.txt")}:The noble Chief Achilles from the son - ${resolveDataFile("iliad.txt")}:Of Atreus, Agamemnon, King of men. + ${resolveDataFile('iliad.txt')}:When fierce dispute had separated once + ${resolveDataFile('iliad.txt')}:The noble Chief Achilles from the son + ${resolveDataFile('iliad.txt')}:Of Atreus, Agamemnon, King of men. ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:I do entreat your grace to pardon me. ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:I know not by what power I am made bold, ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:Nor how it may concern my modesty, ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:In such a presence here to plead my thoughts; ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:But I beseech your grace that I may know ${resolveDataFile( - "midsummer-night.txt" + 'midsummer-night.txt' )}:The worst that may befall me in this case, - ${resolveDataFile("midsummer-night.txt")}:If I refuse to wed Demetrius. + ${resolveDataFile('midsummer-night.txt')}:If I refuse to wed Demetrius. ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Of Mans First Disobedience, and the Fruit ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Of that Forbidden Tree, whose mortal tast ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Brought Death into the World, and all our woe, ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:With loss of Eden, till one greater Man ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Restore us, and regain the blissful Seat, ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Sing Heav'nly Muse, that on the secret top ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:Of Oreb, or of Sinai, didst inspire ${resolveDataFile( - "paradise-lost.txt" + 'paradise-lost.txt' )}:That Shepherd, who first taught the chosen Seed`) ); }); diff --git a/exercises/hamming/babel.config.js b/exercises/hamming/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/hamming/babel.config.js +++ b/exercises/hamming/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/hamming/example.js b/exercises/hamming/example.js index e12c412a8c..cd06a90e34 100644 --- a/exercises/hamming/example.js +++ b/exercises/hamming/example.js @@ -14,5 +14,6 @@ export const compute = (strand1, strand2) => { throw new Error('left and right strands must be of equal length'); } - return [...strand1].filter((element, index) => element !== strand2[index]).length; + return [...strand1].filter((element, index) => element !== strand2[index]) + .length; }; diff --git a/exercises/hamming/hamming.js b/exercises/hamming/hamming.js index 154173dea8..7eb271aad3 100644 --- a/exercises/hamming/hamming.js +++ b/exercises/hamming/hamming.js @@ -4,5 +4,5 @@ // export const compute = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/hamming/hamming.spec.js b/exercises/hamming/hamming.spec.js index e211668a0e..1a60b175ed 100644 --- a/exercises/hamming/hamming.spec.js +++ b/exercises/hamming/hamming.spec.js @@ -23,25 +23,25 @@ describe('Hamming', () => { xtest('disallow first strand longer', () => { expect(() => compute('AATG', 'AAA')).toThrow( - new Error('left and right strands must be of equal length'), + new Error('left and right strands must be of equal length') ); }); xtest('disallow second strand longer', () => { expect(() => compute('ATA', 'AGTG')).toThrow( - new Error('left and right strands must be of equal length'), + new Error('left and right strands must be of equal length') ); }); xtest('disallow left empty strand', () => { expect(() => compute('', 'G')).toThrow( - new Error('left strand must not be empty'), + new Error('left strand must not be empty') ); }); xtest('disallow right empty strand', () => { expect(() => compute('G', '')).toThrow( - new Error('right strand must not be empty'), + new Error('right strand must not be empty') ); }); }); diff --git a/exercises/hello-world/babel.config.js b/exercises/hello-world/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/hello-world/babel.config.js +++ b/exercises/hello-world/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/hello-world/hello-world.js b/exercises/hello-world/hello-world.js index 574bab1909..a73af330bd 100644 --- a/exercises/hello-world/hello-world.js +++ b/exercises/hello-world/hello-world.js @@ -4,5 +4,5 @@ // export const hello = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/hexadecimal/babel.config.js b/exercises/hexadecimal/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/hexadecimal/babel.config.js +++ b/exercises/hexadecimal/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/hexadecimal/example.js b/exercises/hexadecimal/example.js index f9dba3b8ce..5a77511593 100644 --- a/exercises/hexadecimal/example.js +++ b/exercises/hexadecimal/example.js @@ -2,7 +2,9 @@ export const toDecimal = (hex) => { const hexCharacters = [...hex]; for (let i = 0; i < hexCharacters.length; i += 1) { - if (/[^0-9a-fA-F]/.exec(hexCharacters[i])) { return 0; } + if (/[^0-9a-fA-F]/.exec(hexCharacters[i])) { + return 0; + } } return parseInt(hex, 16); diff --git a/exercises/hexadecimal/hexadecimal.js b/exercises/hexadecimal/hexadecimal.js index d35522e7bf..36bec68d75 100644 --- a/exercises/hexadecimal/hexadecimal.js +++ b/exercises/hexadecimal/hexadecimal.js @@ -4,5 +4,5 @@ // export const toDecimal = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/high-scores/babel.config.js b/exercises/high-scores/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/high-scores/babel.config.js +++ b/exercises/high-scores/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/high-scores/high-scores.js b/exercises/high-scores/high-scores.js index ee55a9d916..19084d6714 100644 --- a/exercises/high-scores/high-scores.js +++ b/exercises/high-scores/high-scores.js @@ -5,22 +5,22 @@ export class HighScores { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get scores() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get latest() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get personalBest() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get personalTopThree() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/house/babel.config.js b/exercises/house/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/house/babel.config.js +++ b/exercises/house/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/house/house.js b/exercises/house/house.js index 1e80439432..989997901f 100644 --- a/exercises/house/house.js +++ b/exercises/house/house.js @@ -5,10 +5,10 @@ export class House { static verse() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } static verses() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/house/house.spec.js b/exercises/house/house.spec.js index cbded56d56..496ffa1b59 100644 --- a/exercises/house/house.spec.js +++ b/exercises/house/house.spec.js @@ -2,9 +2,7 @@ import { House } from './house'; describe('House', () => { test('verse one - the house that jack built', () => { - const lyrics = [ - 'This is the house that Jack built.', - ]; + const lyrics = ['This is the house that Jack built.']; expect(House.verse(1)).toEqual(lyrics); }); diff --git a/exercises/isbn-verifier/babel.config.js b/exercises/isbn-verifier/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/isbn-verifier/babel.config.js +++ b/exercises/isbn-verifier/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/isbn-verifier/example.js b/exercises/isbn-verifier/example.js index 34dcf72516..3fb4b8c45f 100644 --- a/exercises/isbn-verifier/example.js +++ b/exercises/isbn-verifier/example.js @@ -1,4 +1,4 @@ -export const isValid = isbn => { +export const isValid = (isbn) => { isbn = isbn.replace(/-/g, ''); const isbnFormat = /^[0-9]{9}(X|\d)$/g; @@ -8,7 +8,7 @@ export const isValid = isbn => { const isbnLength = 10; const sumOfProducts = [...isbn] - .map(digit => (digit === 'X' ? 10 : Number(digit))) + .map((digit) => (digit === 'X' ? 10 : Number(digit))) .map((digit, index) => digit * (isbnLength - index)) .reduce((sum, value) => sum + value, 0); return sumOfProducts % 11 === 0; diff --git a/exercises/isbn-verifier/isbn-verifier.js b/exercises/isbn-verifier/isbn-verifier.js index 1ef31fa3ef..2f5877112c 100644 --- a/exercises/isbn-verifier/isbn-verifier.js +++ b/exercises/isbn-verifier/isbn-verifier.js @@ -4,5 +4,5 @@ // export const isValid = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/isogram/babel.config.js b/exercises/isogram/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/isogram/babel.config.js +++ b/exercises/isogram/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/isogram/example.js b/exercises/isogram/example.js index c3e04f4385..2e17d9eca5 100644 --- a/exercises/isogram/example.js +++ b/exercises/isogram/example.js @@ -1,4 +1,4 @@ -export const isIsogram = string => { +export const isIsogram = (string) => { const stringNoSpaceOrHyphen = string.replace(/ |-/g, ''); const uniqueLetters = stringNoSpaceOrHyphen .toLowerCase() diff --git a/exercises/isogram/isogram.js b/exercises/isogram/isogram.js index 728e9d90ed..9da2ad43b7 100644 --- a/exercises/isogram/isogram.js +++ b/exercises/isogram/isogram.js @@ -4,5 +4,5 @@ // export const isIsogram = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/kindergarten-garden/babel.config.js b/exercises/kindergarten-garden/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/kindergarten-garden/babel.config.js +++ b/exercises/kindergarten-garden/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/kindergarten-garden/example.js b/exercises/kindergarten-garden/example.js index 53bba07067..b8434366ad 100644 --- a/exercises/kindergarten-garden/example.js +++ b/exercises/kindergarten-garden/example.js @@ -31,7 +31,9 @@ function getPlants(pots, index) { } function parse(diagram) { - return diagram.split('\n').map(row => [...row].map(sign => plantCodes[sign])); + return diagram + .split('\n') + .map((row) => [...row].map((sign) => plantCodes[sign])); } export class Garden { diff --git a/exercises/kindergarten-garden/kindergarten-garden.js b/exercises/kindergarten-garden/kindergarten-garden.js index 87b091fb6c..31b44ae537 100644 --- a/exercises/kindergarten-garden/kindergarten-garden.js +++ b/exercises/kindergarten-garden/kindergarten-garden.js @@ -4,9 +4,7 @@ // export class Garden { - constructor() { throw new Error('Remove this statement and implement this function'); } - } diff --git a/exercises/kindergarten-garden/kindergarten-garden.spec.js b/exercises/kindergarten-garden/kindergarten-garden.spec.js index 192a09275e..550a9735bb 100644 --- a/exercises/kindergarten-garden/kindergarten-garden.spec.js +++ b/exercises/kindergarten-garden/kindergarten-garden.spec.js @@ -2,18 +2,30 @@ import { Garden } from './kindergarten-garden'; describe('Garden', () => { test('for Alice', () => { - expect(new Garden('RC\nGG').alice) - .toEqual(['radishes', 'clover', 'grass', 'grass']); + expect(new Garden('RC\nGG').alice).toEqual([ + 'radishes', + 'clover', + 'grass', + 'grass', + ]); }); xtest('another for Alice', () => { - expect(new Garden('VC\nRC').alice) - .toEqual(['violets', 'clover', 'radishes', 'clover']); + expect(new Garden('VC\nRC').alice).toEqual([ + 'violets', + 'clover', + 'radishes', + 'clover', + ]); }); xtest('for Bob', () => { - expect(new Garden('VVCG\nVVRC').bob) - .toEqual(['clover', 'grass', 'radishes', 'clover']); + expect(new Garden('VVCG\nVVRC').bob).toEqual([ + 'clover', + 'grass', + 'radishes', + 'clover', + ]); }); xtest('for Bob and Charlie', () => { @@ -28,63 +40,61 @@ describe('Full garden', () => { const garden = new Garden(diagram); xtest('for Alice', () => { - expect(garden.alice) - .toEqual(['violets', 'radishes', 'violets', 'radishes']); + expect(garden.alice).toEqual([ + 'violets', + 'radishes', + 'violets', + 'radishes', + ]); }); xtest('for Bob', () => { - expect(garden.bob) - .toEqual(['clover', 'grass', 'clover', 'clover']); + expect(garden.bob).toEqual(['clover', 'grass', 'clover', 'clover']); }); xtest('for Charlie', () => { - expect(garden.charlie) - .toEqual(['violets', 'violets', 'clover', 'grass']); + expect(garden.charlie).toEqual(['violets', 'violets', 'clover', 'grass']); }); xtest('for David', () => { - expect(garden.david) - .toEqual(['radishes', 'violets', 'clover', 'radishes']); + expect(garden.david).toEqual(['radishes', 'violets', 'clover', 'radishes']); }); xtest('for Eve', () => { - expect(garden.eve) - .toEqual(['clover', 'grass', 'radishes', 'grass']); + expect(garden.eve).toEqual(['clover', 'grass', 'radishes', 'grass']); }); xtest('for Fred', () => { - expect(garden.fred) - .toEqual(['grass', 'clover', 'violets', 'clover']); + expect(garden.fred).toEqual(['grass', 'clover', 'violets', 'clover']); }); xtest('for Ginny', () => { - expect(garden.ginny) - .toEqual(['clover', 'grass', 'grass', 'clover']); + expect(garden.ginny).toEqual(['clover', 'grass', 'grass', 'clover']); }); xtest('for Harriet', () => { - expect(garden.harriet) - .toEqual(['violets', 'radishes', 'radishes', 'violets']); + expect(garden.harriet).toEqual([ + 'violets', + 'radishes', + 'radishes', + 'violets', + ]); }); xtest('for Ileana', () => { - expect(garden.ileana) - .toEqual(['grass', 'clover', 'violets', 'clover']); + expect(garden.ileana).toEqual(['grass', 'clover', 'violets', 'clover']); }); xtest('for Joseph', () => { - expect(garden.joseph) - .toEqual(['violets', 'clover', 'violets', 'grass']); + expect(garden.joseph).toEqual(['violets', 'clover', 'violets', 'grass']); }); xtest('for Kincaid', () => { - expect(garden.kincaid) - .toEqual(['grass', 'clover', 'clover', 'grass']); + expect(garden.kincaid).toEqual(['grass', 'clover', 'clover', 'grass']); }); xtest('for Larry', () => { - expect(garden.larry) - .toEqual(['grass', 'violets', 'clover', 'violets']); + expect(garden.larry).toEqual(['grass', 'violets', 'clover', 'violets']); }); }); @@ -94,23 +104,24 @@ describe('Disordered class', () => { const garden = new Garden(diagram, students); xtest('Patricia', () => { - expect(garden.patricia) - .toEqual(['violets', 'clover', 'radishes', 'violets']); + expect(garden.patricia).toEqual([ + 'violets', + 'clover', + 'radishes', + 'violets', + ]); }); xtest('Roger', () => { - expect(garden.roger) - .toEqual(['radishes', 'radishes', 'grass', 'clover']); + expect(garden.roger).toEqual(['radishes', 'radishes', 'grass', 'clover']); }); xtest('Samantha', () => { - expect(garden.samantha) - .toEqual(['grass', 'violets', 'clover', 'grass']); + expect(garden.samantha).toEqual(['grass', 'violets', 'clover', 'grass']); }); xtest('Xander', () => { - expect(garden.xander) - .toEqual(['radishes', 'grass', 'clover', 'violets']); + expect(garden.xander).toEqual(['radishes', 'grass', 'clover', 'violets']); }); }); @@ -120,13 +131,14 @@ describe('Two gardens, different students', () => { const garden2 = new Garden(diagram, ['Bob', 'Charlie', 'Dan', 'Erin']); xtest('Bob and Charlie for each garden', () => { - expect(garden1.bob) - .toEqual(['radishes', 'radishes', 'grass', 'clover']); - expect(garden2.bob) - .toEqual(['violets', 'clover', 'radishes', 'violets']); - expect(garden1.charlie) - .toEqual(['grass', 'violets', 'clover', 'grass']); - expect(garden2.charlie) - .toEqual(['radishes', 'radishes', 'grass', 'clover']); + expect(garden1.bob).toEqual(['radishes', 'radishes', 'grass', 'clover']); + expect(garden2.bob).toEqual(['violets', 'clover', 'radishes', 'violets']); + expect(garden1.charlie).toEqual(['grass', 'violets', 'clover', 'grass']); + expect(garden2.charlie).toEqual([ + 'radishes', + 'radishes', + 'grass', + 'clover', + ]); }); }); diff --git a/exercises/largest-series-product/babel.config.js b/exercises/largest-series-product/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/largest-series-product/babel.config.js +++ b/exercises/largest-series-product/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/largest-series-product/example.js b/exercises/largest-series-product/example.js index 7d10f809d9..acae3b03f6 100644 --- a/exercises/largest-series-product/example.js +++ b/exercises/largest-series-product/example.js @@ -18,7 +18,7 @@ export const largestProduct = (digits, seriesLength) => { const product = digits .substring(i, i + seriesLength) .split('') - .map(digit => Number(digit)) + .map((digit) => Number(digit)) .reduce((a, b) => a * b); if (product > largestProduct) { largestProduct = product; diff --git a/exercises/largest-series-product/largest-series-product.js b/exercises/largest-series-product/largest-series-product.js index f8469465e8..0965c9cf9e 100644 --- a/exercises/largest-series-product/largest-series-product.js +++ b/exercises/largest-series-product/largest-series-product.js @@ -4,5 +4,5 @@ // export const largestProduct = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/largest-series-product/largest-series-product.spec.js b/exercises/largest-series-product/largest-series-product.spec.js index f224e79374..213625d003 100644 --- a/exercises/largest-series-product/largest-series-product.spec.js +++ b/exercises/largest-series-product/largest-series-product.spec.js @@ -71,4 +71,3 @@ describe('Largest Series Product', () => { ); }); }); - diff --git a/exercises/leap/babel.config.js b/exercises/leap/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/leap/babel.config.js +++ b/exercises/leap/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/leap/example.js b/exercises/leap/example.js index efa2e95968..233130362d 100644 --- a/exercises/leap/example.js +++ b/exercises/leap/example.js @@ -5,4 +5,5 @@ * @return {boolean} * Whether given year is a leap year. */ -export const isLeap = year => year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0); +export const isLeap = (year) => + year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0); diff --git a/exercises/leap/leap.js b/exercises/leap/leap.js index 042b2fca79..1b8ccc9f87 100644 --- a/exercises/leap/leap.js +++ b/exercises/leap/leap.js @@ -4,5 +4,5 @@ // export const isLeap = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/linked-list/.meta/hints.md b/exercises/linked-list/.meta/hints.md index 10c131766e..afad8c40ca 100644 --- a/exercises/linked-list/.meta/hints.md +++ b/exercises/linked-list/.meta/hints.md @@ -1,2 +1,3 @@ Your list must also implement the following interface: + - `delete` (delete the first occurence of a specified value) diff --git a/exercises/linked-list/README.md b/exercises/linked-list/README.md index 398d8226a2..af2e7b1d65 100644 --- a/exercises/linked-list/README.md +++ b/exercises/linked-list/README.md @@ -28,6 +28,7 @@ empty list. If you want to know more about linked lists, check [Wikipedia](https://en.wikipedia.org/wiki/Linked_list). Your list must also implement the following interface: + - `delete` (delete the first occurence of a specified value) diff --git a/exercises/linked-list/babel.config.js b/exercises/linked-list/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/linked-list/babel.config.js +++ b/exercises/linked-list/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/linked-list/example.js b/exercises/linked-list/example.js index 08207d81ff..b957a7b688 100644 --- a/exercises/linked-list/example.js +++ b/exercises/linked-list/example.js @@ -1,8 +1,8 @@ class Node { constructor({ value, next, prev }) { - this.value = value - this.next = next - this.prev = prev + this.value = value; + this.next = next; + this.prev = prev; } } @@ -13,103 +13,102 @@ export class LinkedList { } clear() { - this.tail = null - this.head = null + this.tail = null; + this.head = null; } pop() { if (!this.tail) { - throw new Error('list is empty') + throw new Error('list is empty'); } - const { value } = this.tail + const { value } = this.tail; if (this.tail.prev) { - this.tail = this.tail.prev - this.tail.next = null + this.tail = this.tail.prev; + this.tail.next = null; } else { - this.clear() + this.clear(); } - return value + return value; } push(value) { - const element = new Node({ value, prev: this.tail }) + const element = new Node({ value, prev: this.tail }); if (this.tail) { - this.tail.next = element + this.tail.next = element; } else { - this.head = element + this.head = element; } - this.tail = element + this.tail = element; } shift() { if (!this.head) { - throw new Error('list is empty') + throw new Error('list is empty'); } - const { value } = this.head + const { value } = this.head; if (this.head.next) { - this.head = this.head.next - this.head.prev = null + this.head = this.head.next; + this.head.prev = null; } else { - this.clear() + this.clear(); } return value; } unshift(value) { - const element = new Node({ value, next: this.head }) + const element = new Node({ value, next: this.head }); if (this.head) { - this.head.prev = element + this.head.prev = element; } else { - this.tail = element + this.tail = element; } - this.head = element + this.head = element; } - count() { - let count = 0 - let element = this.head + let count = 0; + let element = this.head; while (element) { - count += 1 - element = element.next + count += 1; + element = element.next; } - return count + return count; } delete(value) { - let element = this.head + let element = this.head; while (element) { if (element.value !== value) { - element = element.next + element = element.next; // eslint-disable-next-line no-continue - continue + continue; } if (element.prev) { - element.prev.next = element.next + element.prev.next = element.next; } else { - this.head = this.head.next + this.head = this.head.next; } if (element.next) { - element.next.prev = element.prev + element.next.prev = element.prev; } else { - this.tail = this.tail.prev + this.tail = this.tail.prev; } - break + break; } } } diff --git a/exercises/linked-list/linked-list.js b/exercises/linked-list/linked-list.js index 2f96567076..dc63705d8f 100644 --- a/exercises/linked-list/linked-list.js +++ b/exercises/linked-list/linked-list.js @@ -5,26 +5,26 @@ export class LinkedList { push() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } pop() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } shift() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } unshift() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } delete() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } count() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/list-ops/README.md b/exercises/list-ops/README.md index 04de6a62e5..6e55d5d8f7 100644 --- a/exercises/list-ops/README.md +++ b/exercises/list-ops/README.md @@ -6,7 +6,7 @@ In functional languages list operations like `length`, `map`, and `reduce` are very common. Implement a series of basic list operations, without using existing functions. -The precise number and names of the operations to be implemented will be +The precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include: @@ -19,6 +19,9 @@ operations you will implement include: * `foldr` (*given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right using `function(item, accumulator)`*); * `reverse` (*given a list, return a list with all the original items, but in reversed order*); +Using core language features to build and deconstruct arrays via destructuring, and using the array literal `[]` are allowed, but no functions from the `Array.prototype` should be used. + + ## Setup Go through the setup instructions for Javascript to install the necessary diff --git a/exercises/list-ops/babel.config.js b/exercises/list-ops/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/list-ops/babel.config.js +++ b/exercises/list-ops/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/list-ops/example.js b/exercises/list-ops/example.js index 038bc5faa3..ba18271555 100644 --- a/exercises/list-ops/example.js +++ b/exercises/list-ops/example.js @@ -1,95 +1,118 @@ const Null = { - get value() { return undefined }, - get next() { return this }, - get values() { return [] }, - - get() { return this.value }, - push(item) { return new Cons(item, this) }, - length() { return 0 }, - append(other) { return other }, - concat() { return this }, - forEach() { /* done */ }, - foldl(_, initial) { return initial }, - foldr(_, initial) { return initial }, - filter() { return Null }, - reverse() { return this }, - map() { return this }, -} + get value() { + return undefined; + }, + get next() { + return this; + }, + get values() { + return []; + }, + + get() { + return this.value; + }, + push(item) { + return new Cons(item, this); + }, + length() { + return 0; + }, + append(other) { + return other; + }, + concat() { + return this; + }, + forEach() { + /* done */ + }, + foldl(_, initial) { + return initial; + }, + foldr(_, initial) { + return initial; + }, + filter() { + return Null; + }, + reverse() { + return this; + }, + map() { + return this; + }, +}; class Cons { static fromArray([head, ...tail]) { if (head === undefined) { - return Null + return Null; } - return new Cons(head, Cons.fromArray(tail || [])) + return new Cons(head, Cons.fromArray(tail || [])); } constructor(value, next = Null) { - this.value = value - this.next = next + this.value = value; + this.next = next; } get values() { - return [this.value, ...this.next.values] + return [this.value, ...this.next.values]; } get(i) { - return i === 0 - ? this.value - : this.next.get(i - 1) + return i === 0 ? this.value : this.next.get(i - 1); } push(item) { - this.next = this.next.push(item) - return this + this.next = this.next.push(item); + return this; } length() { - return 1 + this.next.length() + return 1 + this.next.length(); } append(other) { - return other.foldl((result, item) => result.push(item), this) + return other.foldl((result, item) => result.push(item), this); } concat(others) { - return others.foldl((result, other) => result.append(other), this) + return others.foldl((result, other) => result.append(other), this); } foldl(callback, initial = undefined) { - return this.next.foldl(callback, callback(initial, this.value)) + return this.next.foldl(callback, callback(initial, this.value)); } forEach(callback) { - this.foldl((_, item) => callback(item)) + this.foldl((_, item) => callback(item)); } foldr(callback, initial = undefined) { - return callback(this.next.foldr(callback, initial), this.value) + return callback(this.next.foldr(callback, initial), this.value); } filter(predicate) { return this.foldl( (result, item) => (predicate(item) && result.push(item)) || result, - Null, - ) + Null + ); } map(expression) { - return this.foldl( - (result, item) => result.push(expression(item)), - Null, - ) + return this.foldl((result, item) => result.push(expression(item)), Null); } reverse() { - return this.next.reverse().push(this.value) + return this.next.reverse().push(this.value); } } export class List { constructor(values = []) { - return Cons.fromArray(values) + return Cons.fromArray(values); } } diff --git a/exercises/list-ops/list-ops.js b/exercises/list-ops/list-ops.js index 93597c1bae..ab0dcdd079 100644 --- a/exercises/list-ops/list-ops.js +++ b/exercises/list-ops/list-ops.js @@ -5,38 +5,38 @@ export class List { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } append() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } concat() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } filter() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } map() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } length() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } foldl() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } foldr() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } reverse() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/list-ops/list-ops.spec.js b/exercises/list-ops/list-ops.spec.js index 3f5e01ffaf..ec517a6864 100644 --- a/exercises/list-ops/list-ops.spec.js +++ b/exercises/list-ops/list-ops.spec.js @@ -20,7 +20,6 @@ describe('append entries to a list and return the new list', () => { }); }); - describe('concat lists and lists of lists into new list', () => { xtest('empty list', () => { const list1 = new List(); @@ -33,25 +32,23 @@ describe('concat lists and lists of lists into new list', () => { const list2 = new List([3]); const list3 = new List([]); const list4 = new List([4, 5, 6]); - const listOfLists = new List([list2, list3, list4]) + const listOfLists = new List([list2, list3, list4]); expect(list1.concat(listOfLists).values).toEqual([1, 2, 3, 4, 5, 6]); }); }); - describe('filter list returning only values that satisfy the filter function', () => { xtest('empty list', () => { const list1 = new List([]); - expect(list1.filter(el => el % 2 === 1).values).toEqual([]); + expect(list1.filter((el) => el % 2 === 1).values).toEqual([]); }); xtest('non empty list', () => { const list1 = new List([1, 2, 3, 5]); - expect(list1.filter(el => el % 2 === 1).values).toEqual([1, 3, 5]); + expect(list1.filter((el) => el % 2 === 1).values).toEqual([1, 3, 5]); }); }); - describe('returns the length of a list', () => { xtest('empty list', () => { const list1 = new List(); @@ -64,20 +61,18 @@ describe('returns the length of a list', () => { }); }); - describe('returns a list of elements whose values equal the list value transformed by the mapping function', () => { xtest('empty list', () => { const list1 = new List(); - expect(list1.map(el => ++el).values).toEqual([]); + expect(list1.map((el) => ++el).values).toEqual([]); }); xtest('non-empty list', () => { const list1 = new List([1, 3, 5, 7]); - expect(list1.map(el => ++el).values).toEqual([2, 4, 6, 8]); + expect(list1.map((el) => ++el).values).toEqual([2, 4, 6, 8]); }); }); - describe('folds (reduces) the given list from the left with a function', () => { xtest('empty list', () => { const list1 = new List(); @@ -90,7 +85,6 @@ describe('folds (reduces) the given list from the left with a function', () => { }); }); - describe('folds (reduces) the given list from the right with a function', () => { xtest('empty list', () => { const list1 = new List(); @@ -103,7 +97,6 @@ describe('folds (reduces) the given list from the right with a function', () => }); }); - describe('reverse the elements of a list', () => { xtest('empty list', () => { const list1 = new List(); diff --git a/exercises/luhn/README.md b/exercises/luhn/README.md index 65c3915f99..8633cfc1c0 100644 --- a/exercises/luhn/README.md +++ b/exercises/luhn/README.md @@ -19,27 +19,27 @@ are disallowed. ## Example 1: valid credit card number ```text -4539 1488 0343 6467 +4539 3195 0343 6467 ``` The first step of the Luhn algorithm is to double every second digit, starting from the right. We will be doubling ```text -4_3_ 1_8_ 0_4_ 6_6_ +4_3_ 3_9_ 0_4_ 6_6_ ``` If doubling the number results in a number greater than 9 then subtract 9 from the product. The results of our doubling: ```text -8569 2478 0383 3437 +8569 6195 0383 3437 ``` Then sum all of the digits: ```text -8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80 +8+5+6+9+6+1+9+5+0+3+8+3+3+4+3+7 = 80 ``` If the sum is evenly divisible by 10, then the number is valid. This number is valid! diff --git a/exercises/luhn/babel.config.js b/exercises/luhn/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/luhn/babel.config.js +++ b/exercises/luhn/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/luhn/example.js b/exercises/luhn/example.js index 5aa109cdc6..eb128fb824 100644 --- a/exercises/luhn/example.js +++ b/exercises/luhn/example.js @@ -1,10 +1,10 @@ -export const valid = number => { +export const valid = (number) => { const trimmed = number.replace(/\s/g, ''); const digits = [...trimmed]; const sum = digits // convert to integers - .map(d => parseInt(d, 10)) + .map((d) => parseInt(d, 10)) // double the second digits, starting from right .map((d, i) => { if ((i + digits.length) % 2 === 0) { @@ -13,7 +13,7 @@ export const valid = number => { return d; }) // limit to digits less than 10 - .map(d => { + .map((d) => { if (d > 9) { return d - 9; } diff --git a/exercises/luhn/luhn.js b/exercises/luhn/luhn.js index 55f22178b7..ba457e73f4 100644 --- a/exercises/luhn/luhn.js +++ b/exercises/luhn/luhn.js @@ -4,5 +4,5 @@ // export const valid = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js index a4d615ad69..3145f15e26 100644 --- a/exercises/luhn/luhn.spec.js +++ b/exercises/luhn/luhn.spec.js @@ -61,11 +61,11 @@ describe('Luhn', () => { expect(valid('091')).toEqual(true); }); - xtest('using ascii value for non-doubled non-digit isn\'t allowed', () => { + xtest("using ascii value for non-doubled non-digit isn't allowed", () => { expect(valid('055b 444 285')).toEqual(false); }); - xtest('using ascii value for doubled non-digit isn\'t allowed', () => { + xtest("using ascii value for doubled non-digit isn't allowed", () => { expect(valid(':9')).toEqual(false); }); }); diff --git a/exercises/matching-brackets/babel.config.js b/exercises/matching-brackets/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/matching-brackets/babel.config.js +++ b/exercises/matching-brackets/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/matching-brackets/example.js b/exercises/matching-brackets/example.js index 1020a4bbf8..9543ca1824 100644 --- a/exercises/matching-brackets/example.js +++ b/exercises/matching-brackets/example.js @@ -1,22 +1,22 @@ -export const isPaired = input => { - const brackets = input.replace(/[^{(\[\])}]/g, ""); //eslint-disable-line +export const isPaired = (input) => { + const brackets = input.replace(/[^{(\[\])}]/g, ''); //eslint-disable-line const bracketsAreMatching = (leftBracket, rightBracket) => - leftBracket === '(' && rightBracket === ')' || - leftBracket === '[' && rightBracket === ']' || - leftBracket === '{' && rightBracket === '}'; + (leftBracket === '(' && rightBracket === ')') || + (leftBracket === '[' && rightBracket === ']') || + (leftBracket === '{' && rightBracket === '}'); let arr = []; for (let letter of brackets) { - if (arr.length >= 1) { - const lastBracket = arr[arr.length - 1]; - if (bracketsAreMatching(lastBracket, letter)) { - arr.pop(); - } else { - arr.push(letter); - } + if (arr.length >= 1) { + const lastBracket = arr[arr.length - 1]; + if (bracketsAreMatching(lastBracket, letter)) { + arr.pop(); } else { - arr.push(letter); + arr.push(letter); } + } else { + arr.push(letter); + } } return arr.length === 0; }; diff --git a/exercises/matching-brackets/matching-brackets.js b/exercises/matching-brackets/matching-brackets.js index fd535e7b3a..8a0ef3cf07 100644 --- a/exercises/matching-brackets/matching-brackets.js +++ b/exercises/matching-brackets/matching-brackets.js @@ -4,5 +4,5 @@ // export const isPaired = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/matrix/babel.config.js b/exercises/matrix/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/matrix/babel.config.js +++ b/exercises/matrix/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/matrix/example.js b/exercises/matrix/example.js index 693da92bd6..23862634f3 100644 --- a/exercises/matrix/example.js +++ b/exercises/matrix/example.js @@ -12,7 +12,9 @@ function columnsFromRows(rows) { } function parseRows(description) { - return description.split('\n').map(row => row.split(' ').map(char => Number(char))); + return description + .split('\n') + .map((row) => row.split(' ').map((char) => Number(char))); } export class Matrix { diff --git a/exercises/matrix/matrix.js b/exercises/matrix/matrix.js index bc1a13564a..1eca092ec9 100644 --- a/exercises/matrix/matrix.js +++ b/exercises/matrix/matrix.js @@ -5,14 +5,14 @@ export class Matrix { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get rows() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get columns() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/matrix/matrix.spec.js b/exercises/matrix/matrix.spec.js index f3148e9be5..fe6761781e 100644 --- a/exercises/matrix/matrix.spec.js +++ b/exercises/matrix/matrix.spec.js @@ -26,7 +26,11 @@ describe('Matrix', () => { }); xtest('can extract column from non-square matrix with no corresponding row', () => { - expect(new Matrix('1 2 3 4\n5 6 7 8\n9 8 7 6').columns[3]).toEqual([4, 8, 6]); + expect(new Matrix('1 2 3 4\n5 6 7 8\n9 8 7 6').columns[3]).toEqual([ + 4, + 8, + 6, + ]); }); xtest('can extract column from non-square matrix with more columns than rows', () => { @@ -34,6 +38,10 @@ describe('Matrix', () => { }); xtest('extract column where numbers have different widths', () => { - expect(new Matrix('89 1903 3\n18 3 1\n9 4 800').columns[1]).toEqual([1903, 3, 4]); + expect(new Matrix('89 1903 3\n18 3 1\n9 4 800').columns[1]).toEqual([ + 1903, + 3, + 4, + ]); }); }); diff --git a/exercises/meetup/babel.config.js b/exercises/meetup/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/meetup/babel.config.js +++ b/exercises/meetup/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/meetup/example.js b/exercises/meetup/example.js index 71aa5398b2..de7da466e7 100644 --- a/exercises/meetup/example.js +++ b/exercises/meetup/example.js @@ -5,14 +5,14 @@ const weekday = [ 'Wednesday', 'Thursday', 'Friday', - 'Saturday' + 'Saturday', ]; const daysInMonth = (year, month) => { return new Date(year, month, 0).getDate(); }; -const getDayOfWeekCount = dayOfWeek => { +const getDayOfWeekCount = (dayOfWeek) => { return weekday.indexOf(dayOfWeek); }; diff --git a/exercises/meetup/meetup.js b/exercises/meetup/meetup.js index a9b7e2ca4e..1eb17a0b19 100644 --- a/exercises/meetup/meetup.js +++ b/exercises/meetup/meetup.js @@ -3,6 +3,6 @@ // convenience to get you started writing code faster. // -export const meetup = () => { - throw new Error("Remove this statement and implement this function"); -} +export const meetup = () => { + throw new Error('Remove this statement and implement this function'); +}; diff --git a/exercises/meetup/meetup.spec.js b/exercises/meetup/meetup.spec.js index 30f63de564..6f0d16d8e0 100644 --- a/exercises/meetup/meetup.spec.js +++ b/exercises/meetup/meetup.spec.js @@ -26,27 +26,39 @@ describe('Meetup', () => { }); xtest('wednesteenth of January 2013', () => { - expect(meetup(2013, 1, 'teenth', 'Wednesday')).toEqual(new Date(2013, 0, 16)); + expect(meetup(2013, 1, 'teenth', 'Wednesday')).toEqual( + new Date(2013, 0, 16) + ); }); xtest('wednesteenth of February 2013', () => { - expect(meetup(2013, 2, 'teenth', 'Wednesday')).toEqual(new Date(2013, 1, 13)); + expect(meetup(2013, 2, 'teenth', 'Wednesday')).toEqual( + new Date(2013, 1, 13) + ); }); xtest('wednesteenth of June 2013', () => { - expect(meetup(2013, 6, 'teenth', 'Wednesday')).toEqual(new Date(2013, 5, 19)); + expect(meetup(2013, 6, 'teenth', 'Wednesday')).toEqual( + new Date(2013, 5, 19) + ); }); xtest('thursteenth of May 2013', () => { - expect(meetup(2013, 5, 'teenth', 'Thursday')).toEqual(new Date(2013, 4, 16)); + expect(meetup(2013, 5, 'teenth', 'Thursday')).toEqual( + new Date(2013, 4, 16) + ); }); xtest('thursteenth of June 2013', () => { - expect(meetup(2013, 6, 'teenth', 'Thursday')).toEqual(new Date(2013, 5, 13)); + expect(meetup(2013, 6, 'teenth', 'Thursday')).toEqual( + new Date(2013, 5, 13) + ); }); xtest('thursteenth of September 2013', () => { - expect(meetup(2013, 9, 'teenth', 'Thursday')).toEqual(new Date(2013, 8, 19)); + expect(meetup(2013, 9, 'teenth', 'Thursday')).toEqual( + new Date(2013, 8, 19) + ); }); xtest('friteenth of April 2013', () => { @@ -62,15 +74,21 @@ describe('Meetup', () => { }); xtest('saturteenth of February 2013', () => { - expect(meetup(2013, 2, 'teenth', 'Saturday')).toEqual(new Date(2013, 1, 16)); + expect(meetup(2013, 2, 'teenth', 'Saturday')).toEqual( + new Date(2013, 1, 16) + ); }); xtest('saturteenth of April 2013', () => { - expect(meetup(2013, 4, 'teenth', 'Saturday')).toEqual(new Date(2013, 3, 13)); + expect(meetup(2013, 4, 'teenth', 'Saturday')).toEqual( + new Date(2013, 3, 13) + ); }); xtest('saturteenth of October 2013', () => { - expect(meetup(2013, 10, 'teenth', 'Saturday')).toEqual(new Date(2013, 9, 19)); + expect(meetup(2013, 10, 'teenth', 'Saturday')).toEqual( + new Date(2013, 9, 19) + ); }); xtest('sunteenth of May 2013', () => { @@ -158,19 +176,27 @@ describe('Meetup', () => { }); xtest('second Wednesday of July 2013', () => { - expect(meetup(2013, 7, 'second', 'Wednesday')).toEqual(new Date(2013, 6, 10)); + expect(meetup(2013, 7, 'second', 'Wednesday')).toEqual( + new Date(2013, 6, 10) + ); }); xtest('second Wednesday of August 2013', () => { - expect(meetup(2013, 8, 'second', 'Wednesday')).toEqual(new Date(2013, 7, 14)); + expect(meetup(2013, 8, 'second', 'Wednesday')).toEqual( + new Date(2013, 7, 14) + ); }); xtest('second Thursday of September 2013', () => { - expect(meetup(2013, 9, 'second', 'Thursday')).toEqual(new Date(2013, 8, 12)); + expect(meetup(2013, 9, 'second', 'Thursday')).toEqual( + new Date(2013, 8, 12) + ); }); xtest('second Thursday of October 2013', () => { - expect(meetup(2013, 10, 'second', 'Thursday')).toEqual(new Date(2013, 9, 10)); + expect(meetup(2013, 10, 'second', 'Thursday')).toEqual( + new Date(2013, 9, 10) + ); }); xtest('second Friday of November 2013', () => { @@ -178,11 +204,15 @@ describe('Meetup', () => { }); xtest('second Friday of December 2013', () => { - expect(meetup(2013, 12, 'second', 'Friday')).toEqual(new Date(2013, 11, 13)); + expect(meetup(2013, 12, 'second', 'Friday')).toEqual( + new Date(2013, 11, 13) + ); }); xtest('second Saturday of January 2013', () => { - expect(meetup(2013, 1, 'second', 'Saturday')).toEqual(new Date(2013, 0, 12)); + expect(meetup(2013, 1, 'second', 'Saturday')).toEqual( + new Date(2013, 0, 12) + ); }); xtest('second Saturday of February 2013', () => { @@ -214,11 +244,15 @@ describe('Meetup', () => { }); xtest('third Wednesday of July 2013', () => { - expect(meetup(2013, 7, 'third', 'Wednesday')).toEqual(new Date(2013, 6, 17)); + expect(meetup(2013, 7, 'third', 'Wednesday')).toEqual( + new Date(2013, 6, 17) + ); }); xtest('third Wednesday of August 2013', () => { - expect(meetup(2013, 8, 'third', 'Wednesday')).toEqual(new Date(2013, 7, 21)); + expect(meetup(2013, 8, 'third', 'Wednesday')).toEqual( + new Date(2013, 7, 21) + ); }); xtest('third Thursday of September 2013', () => { @@ -226,7 +260,9 @@ describe('Meetup', () => { }); xtest('third Thursday of October 2013', () => { - expect(meetup(2013, 10, 'third', 'Thursday')).toEqual(new Date(2013, 9, 17)); + expect(meetup(2013, 10, 'third', 'Thursday')).toEqual( + new Date(2013, 9, 17) + ); }); xtest('third Friday of November 2013', () => { @@ -270,35 +306,51 @@ describe('Meetup', () => { }); xtest('fourth Wednesday of July 2013', () => { - expect(meetup(2013, 7, 'fourth', 'Wednesday')).toEqual(new Date(2013, 6, 24)); + expect(meetup(2013, 7, 'fourth', 'Wednesday')).toEqual( + new Date(2013, 6, 24) + ); }); xtest('fourth Wednesday of August 2013', () => { - expect(meetup(2013, 8, 'fourth', 'Wednesday')).toEqual(new Date(2013, 7, 28)); + expect(meetup(2013, 8, 'fourth', 'Wednesday')).toEqual( + new Date(2013, 7, 28) + ); }); xtest('fourth Thursday of September 2013', () => { - expect(meetup(2013, 9, 'fourth', 'Thursday')).toEqual(new Date(2013, 8, 26)); + expect(meetup(2013, 9, 'fourth', 'Thursday')).toEqual( + new Date(2013, 8, 26) + ); }); xtest('fourth Thursday of October 2013', () => { - expect(meetup(2013, 10, 'fourth', 'Thursday')).toEqual(new Date(2013, 9, 24)); + expect(meetup(2013, 10, 'fourth', 'Thursday')).toEqual( + new Date(2013, 9, 24) + ); }); xtest('fourth Friday of November 2013', () => { - expect(meetup(2013, 11, 'fourth', 'Friday')).toEqual(new Date(2013, 10, 22)); + expect(meetup(2013, 11, 'fourth', 'Friday')).toEqual( + new Date(2013, 10, 22) + ); }); xtest('fourth Friday of December 2013', () => { - expect(meetup(2013, 12, 'fourth', 'Friday')).toEqual(new Date(2013, 11, 27)); + expect(meetup(2013, 12, 'fourth', 'Friday')).toEqual( + new Date(2013, 11, 27) + ); }); xtest('fourth Saturday of January 2013', () => { - expect(meetup(2013, 1, 'fourth', 'Saturday')).toEqual(new Date(2013, 0, 26)); + expect(meetup(2013, 1, 'fourth', 'Saturday')).toEqual( + new Date(2013, 0, 26) + ); }); xtest('fourth Saturday of February 2013', () => { - expect(meetup(2013, 2, 'fourth', 'Saturday')).toEqual(new Date(2013, 1, 23)); + expect(meetup(2013, 2, 'fourth', 'Saturday')).toEqual( + new Date(2013, 1, 23) + ); }); xtest('fourth Sunday of March 2013', () => { @@ -370,7 +422,9 @@ describe('Meetup', () => { }); xtest('last Wednesday of December 2014', () => { - expect(meetup(2014, 12, 'last', 'Wednesday')).toEqual(new Date(2014, 11, 31)); + expect(meetup(2014, 12, 'last', 'Wednesday')).toEqual( + new Date(2014, 11, 31) + ); }); xtest('last Sunday of February 2015', () => { diff --git a/exercises/minesweeper/README.md b/exercises/minesweeper/README.md index bf62108fa8..497e97099b 100644 --- a/exercises/minesweeper/README.md +++ b/exercises/minesweeper/README.md @@ -1,30 +1,40 @@ # Minesweeper -Add the numbers to a minesweeper board. +Add the mine counts to a completed Minesweeper board. Minesweeper is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square. In this exercise you have to create some code that counts the number of -mines adjacent to a square and transforms boards like this (where `*` -indicates a mine): - - +-----+ - | * * | - | * | - | * | - | | - +-----+ - -into this: - - +-----+ - |1*3*1| - |13*31| - | 2*2 | - | 111 | - +-----+ +mines adjacent to a given empty square and replaces that square with the +count. + +The board is a rectangle composed of blank space (' ') characters. A mine +is represented by an asterisk ('\*') character. + +If a given space has no adjacent mines at all, leave that square blank. + +## Examples + +For example you may receive a 5 x 4 board like this (empty spaces are +represented here with the '·' character for display on screen): + +``` +·*·*· +··*·· +··*·· +····· +``` + +And your code will transform it into this: + +``` +1*3*1 +13*31 +·2*2· +·111· +``` ## Setup diff --git a/exercises/minesweeper/babel.config.js b/exercises/minesweeper/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/minesweeper/babel.config.js +++ b/exercises/minesweeper/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/minesweeper/example.js b/exercises/minesweeper/example.js index 967a89c3ef..9c5c624083 100644 --- a/exercises/minesweeper/example.js +++ b/exercises/minesweeper/example.js @@ -20,10 +20,9 @@ function adjacentSquareHasMine(board, x, y, d) { } function countAdjacentMines(board, x, y) { - return DELTAS - .filter(d => adjacentSquareIsOnBoard(board, x, d)) - .filter(d => adjacentSquareHasMine(board, x, y, d)) - .length; + return DELTAS.filter((d) => + adjacentSquareIsOnBoard(board, x, d) + ).filter((d) => adjacentSquareHasMine(board, x, y, d)).length; } function cellToMineOrCount(cell, inputBoard, x, y) { @@ -35,7 +34,7 @@ function cellToMineOrCount(cell, inputBoard, x, y) { } function stringify(board) { - return board.map(row => row.join('')); + return board.map((row) => row.join('')); } function noDataPresent(rows) { @@ -47,11 +46,11 @@ export function annotate(rows) { return rows; } - const inputBoard = rows.map(row => [...row]); + const inputBoard = rows.map((row) => [...row]); return stringify( - inputBoard.map( - (row, x) => [...row].map((cell, y) => cellToMineOrCount(cell, inputBoard, x, y)), - ), + inputBoard.map((row, x) => + [...row].map((cell, y) => cellToMineOrCount(cell, inputBoard, x, y)) + ) ); } diff --git a/exercises/minesweeper/minesweeper.js b/exercises/minesweeper/minesweeper.js index d3e779a999..ced01d454c 100644 --- a/exercises/minesweeper/minesweeper.js +++ b/exercises/minesweeper/minesweeper.js @@ -3,6 +3,6 @@ // convenience to get you started writing code faster. // -export const annotate = (input) => { +export const annotate = (input) => { throw new Error('Remove this statement and implement this function'); -} +}; diff --git a/exercises/minesweeper/minesweeper.spec.js b/exercises/minesweeper/minesweeper.spec.js index 4b29543316..d605a93e04 100644 --- a/exercises/minesweeper/minesweeper.spec.js +++ b/exercises/minesweeper/minesweeper.spec.js @@ -10,58 +10,26 @@ describe(')', () => { }); xtest('handles no mines', () => { - const input = [ - ' ', - ' ', - ' ', - ]; - const expected = [ - ' ', - ' ', - ' ', - ]; + const input = [' ', ' ', ' ']; + const expected = [' ', ' ', ' ']; expect(annotate(input)).toEqual(expected); }); xtest('handles board with only mines', () => { - const input = [ - '***', - '***', - '***', - ]; - const expected = [ - '***', - '***', - '***', - ]; + const input = ['***', '***', '***']; + const expected = ['***', '***', '***']; expect(annotate(input)).toEqual(expected); }); xtest('handles mine surrounded by spaces', () => { - const input = [ - ' ', - ' * ', - ' ', - ]; - const expected = [ - '111', - '1*1', - '111', - ]; + const input = [' ', ' * ', ' ']; + const expected = ['111', '1*1', '111']; expect(annotate(input)).toEqual(expected); }); xtest('handles space surrounded by mines', () => { - const input = [ - '***', - '* *', - '***', - ]; - const expected = [ - '***', - '*8*', - '***', - ]; + const input = ['***', '* *', '***']; + const expected = ['***', '*8*', '***']; expect(annotate(input)).toEqual(expected); }); @@ -78,68 +46,25 @@ describe(')', () => { }); xtest('handles vertical line', () => { - const input = [ - ' ', - '*', - ' ', - '*', - ' ', - ]; - const expected = [ - '1', - '*', - '2', - '*', - '1', - ]; + const input = [' ', '*', ' ', '*', ' ']; + const expected = ['1', '*', '2', '*', '1']; expect(annotate(input)).toEqual(expected); }); xtest('handles vertical line, mines at edges', () => { - const input = [ - '*', - ' ', - ' ', - ' ', - '*', - ]; - const expected = [ - '*', - '1', - ' ', - '1', - '*', - ]; + const input = ['*', ' ', ' ', ' ', '*']; + const expected = ['*', '1', ' ', '1', '*']; expect(annotate(input)).toEqual(expected); }); xtest('handles cross', () => { - const input = [ - ' * ', - ' * ', - '*****', - ' * ', - ' * ', - ]; - const expected = [ - ' 2*2 ', - '25*52', - '*****', - '25*52', - ' 2*2 ', - ]; + const input = [' * ', ' * ', '*****', ' * ', ' * ']; + const expected = [' 2*2 ', '25*52', '*****', '25*52', ' 2*2 ']; expect(annotate(input)).toEqual(expected); }); xtest('handles large board', () => { - const input = [ - ' * * ', - ' * ', - ' * ', - ' * *', - ' * * ', - ' ', - ]; + const input = [' * * ', ' * ', ' * ', ' * *', ' * * ', ' ']; const expected = [ '1*22*1', '12*322', diff --git a/exercises/nth-prime/babel.config.js b/exercises/nth-prime/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/nth-prime/babel.config.js +++ b/exercises/nth-prime/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/nth-prime/example.js b/exercises/nth-prime/example.js index 8cbde3f884..faf7bf5624 100644 --- a/exercises/nth-prime/example.js +++ b/exercises/nth-prime/example.js @@ -1,4 +1,4 @@ -const isPrime = number => { +const isPrime = (number) => { if (number === 2 || number === 3) { return true; } @@ -13,7 +13,7 @@ const isPrime = number => { return true; }; -export const prime = ordinal => { +export const prime = (ordinal) => { if (ordinal === 0) { throw new Error('there is no zeroth prime'); } diff --git a/exercises/nth-prime/nth-prime.js b/exercises/nth-prime/nth-prime.js index 0b2d2275cf..6dbabc01d2 100644 --- a/exercises/nth-prime/nth-prime.js +++ b/exercises/nth-prime/nth-prime.js @@ -4,5 +4,5 @@ // export const prime = () => { - throw new Error("Remove this statement and implement this function"); -} + throw new Error('Remove this statement and implement this function'); +}; diff --git a/exercises/nth-prime/nth-prime.spec.js b/exercises/nth-prime/nth-prime.spec.js index cc1b12e9f5..5ebfd52ed2 100644 --- a/exercises/nth-prime/nth-prime.spec.js +++ b/exercises/nth-prime/nth-prime.spec.js @@ -21,5 +21,3 @@ describe('nth-prime', () => { expect(() => prime(0)).toThrow(new Error('there is no zeroth prime')); }); }); - - diff --git a/exercises/nucleotide-count/README.md b/exercises/nucleotide-count/README.md index 23c0635a13..bdb20b18f7 100644 --- a/exercises/nucleotide-count/README.md +++ b/exercises/nucleotide-count/README.md @@ -1,16 +1,24 @@ # Nucleotide Count -Given a single stranded DNA string, compute how many times each nucleotide occurs in the string. +Each of us inherits from our biological parents a set of chemical instructions known as DNA that influence how our bodies are constructed. All known life depends on DNA! -The genetic language of every living thing on the planet is DNA. -DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides. -4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine. +> Note: You do not need to understand anything about nucleotides or DNA to complete this exercise. -Here is an analogy: -- twigs are to birds nests as -- nucleotides are to DNA as -- legos are to lego houses as -- words are to sentences as... +DNA is a long chain of other chemicals and the most important are the four nucleotides, adenine, cytosine, guanine and thymine. A single DNA chain can contain billions of these four nucleotides and the order in which they occur is important! +We call the order of these nucleotides in a bit of DNA a "DNA sequence". + +We represent a DNA sequence as an ordered collection of these four nucleotides and a common way to do that is with a string of characters such as "ATTACG" for a DNA sequence of 6 nucleotides. +'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' for thymine. + +Given a string representing a DNA sequence, count how many of each nucleotide is present. +If the string contains characters that aren't A, C, G, or T then it is invalid and you should signal an error. + +For example: + +``` +"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2 +"INVALID" -> error +``` ## Setup diff --git a/exercises/nucleotide-count/babel.config.js b/exercises/nucleotide-count/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/nucleotide-count/babel.config.js +++ b/exercises/nucleotide-count/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/nucleotide-count/example.js b/exercises/nucleotide-count/example.js index 83fbd7849d..f93573bd87 100644 --- a/exercises/nucleotide-count/example.js +++ b/exercises/nucleotide-count/example.js @@ -1,11 +1,15 @@ -const count = (str, nuc) => [...str].filter(nucleotide => nucleotide === nuc).length; +const count = (str, nuc) => + [...str].filter((nucleotide) => nucleotide === nuc).length; export class NucleotideCounts { static parse(strand) { if (strand.replace(/A|C|G|T/g, '').length) { throw new Error('Invalid nucleotide in strand'); } else { - return `${count(strand, 'A')} ${count(strand, 'C')} ${count(strand, 'G')} ${count(strand, 'T')}`; + return `${count(strand, 'A')} ${count(strand, 'C')} ${count( + strand, + 'G' + )} ${count(strand, 'T')}`; } } } diff --git a/exercises/nucleotide-count/nucleotide-count.js b/exercises/nucleotide-count/nucleotide-count.js index a1ddcb6162..4a0fe58016 100644 --- a/exercises/nucleotide-count/nucleotide-count.js +++ b/exercises/nucleotide-count/nucleotide-count.js @@ -5,6 +5,6 @@ export class NucleotideCounts { static parse() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/nucleotide-count/nucleotide-count.spec.js b/exercises/nucleotide-count/nucleotide-count.spec.js index fc5877aa30..edfae63b4e 100644 --- a/exercises/nucleotide-count/nucleotide-count.spec.js +++ b/exercises/nucleotide-count/nucleotide-count.spec.js @@ -14,10 +14,16 @@ describe('count all nucleotides in a strand', () => { }); xtest('strand with multiple nucleotides', () => { - expect(NucleotideCounts.parse('AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC')).toEqual('20 12 17 21'); + expect( + NucleotideCounts.parse( + 'AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC' + ) + ).toEqual('20 12 17 21'); }); xtest('strand with invalid nucleotides', () => { - expect(() => NucleotideCounts.parse('AGXXACT')).toThrow(new Error('Invalid nucleotide in strand')); + expect(() => NucleotideCounts.parse('AGXXACT')).toThrow( + new Error('Invalid nucleotide in strand') + ); }); }); diff --git a/exercises/ocr-numbers/babel.config.js b/exercises/ocr-numbers/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/ocr-numbers/babel.config.js +++ b/exercises/ocr-numbers/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/ocr-numbers/example.js b/exercises/ocr-numbers/example.js index b86a51e4ad..34ae6ec18e 100644 --- a/exercises/ocr-numbers/example.js +++ b/exercises/ocr-numbers/example.js @@ -1,44 +1,14 @@ const PATTERNS = { - 0: [' _ ', - '| |', - '|_|', - ' '], - 1: [' ', - ' |', - ' |', - ' '], - 2: [' _ ', - ' _|', - '|_ ', - ' '], - 3: [' _ ', - ' _|', - ' _|', - ' '], - 4: [' ', - '|_|', - ' |', - ' '], - 5: [' _ ', - '|_ ', - ' _|', - ' '], - 6: [' _ ', - '|_ ', - '|_|', - ' '], - 7: [' _ ', - ' |', - ' |', - ' '], - 8: [' _ ', - '|_|', - '|_|', - ' '], - 9: [' _ ', - '|_|', - ' _|', - ' '], + 0: [' _ ', '| |', '|_|', ' '], + 1: [' ', ' |', ' |', ' '], + 2: [' _ ', ' _|', '|_ ', ' '], + 3: [' _ ', ' _|', ' _|', ' '], + 4: [' ', '|_|', ' |', ' '], + 5: [' _ ', '|_ ', ' _|', ' '], + 6: [' _ ', '|_ ', '|_|', ' '], + 7: [' _ ', ' |', ' |', ' '], + 8: [' _ ', '|_|', '|_|', ' '], + 9: [' _ ', '|_|', ' _|', ' '], }; const splitIntoRows = (text) => { @@ -68,9 +38,8 @@ const splitIntoDigits = (row) => { }; const getDigit = (text) => { - const digit = Object - .values(PATTERNS) - .map(x => x.join('')) + const digit = Object.values(PATTERNS) + .map((x) => x.join('')) .indexOf(text); if (digit === -1) { return '?'; @@ -78,6 +47,6 @@ const getDigit = (text) => { return digit; }; -const valuesInRow = row => splitIntoDigits(row).map(getDigit).join(''); +const valuesInRow = (row) => splitIntoDigits(row).map(getDigit).join(''); -export const convert = text => splitIntoRows(text).map(valuesInRow).join(','); +export const convert = (text) => splitIntoRows(text).map(valuesInRow).join(','); diff --git a/exercises/ocr-numbers/ocr-numbers.js b/exercises/ocr-numbers/ocr-numbers.js index 3c598bdde5..bc04770bfb 100644 --- a/exercises/ocr-numbers/ocr-numbers.js +++ b/exercises/ocr-numbers/ocr-numbers.js @@ -4,5 +4,5 @@ // export const convert = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/ocr-numbers/ocr-numbers.spec.js b/exercises/ocr-numbers/ocr-numbers.spec.js index 48e5eb74c6..d80e4a90ed 100644 --- a/exercises/ocr-numbers/ocr-numbers.spec.js +++ b/exercises/ocr-numbers/ocr-numbers.spec.js @@ -2,154 +2,102 @@ import { convert } from './ocr-numbers'; describe('ocr', () => { test('recognizes zero', () => { - expect(convert( - ' _ \n' - + '| |\n' - + '|_|\n' - + ' ', - )).toBe('0'); + expect(convert(' _ \n' + '| |\n' + '|_|\n' + ' ')).toBe('0'); }); xtest('recognizes one', () => { - expect(convert( - ' \n' - + ' |\n' - + ' |\n' - + ' ', - )).toBe('1'); + expect(convert(' \n' + ' |\n' + ' |\n' + ' ')).toBe('1'); }); xtest('recognizes two', () => { - expect(convert( - ' _ \n' - + ' _|\n' - + '|_ \n' - + ' ', - )).toBe('2'); + expect(convert(' _ \n' + ' _|\n' + '|_ \n' + ' ')).toBe('2'); }); xtest('recognizes three', () => { - expect(convert( - ' _ \n' - + ' _|\n' - + ' _|\n' - + ' ', - )).toBe('3'); + expect(convert(' _ \n' + ' _|\n' + ' _|\n' + ' ')).toBe('3'); }); xtest('recognizes four', () => { - expect(convert( - ' \n' - + '|_|\n' - + ' |\n' - + ' ', - )).toBe('4'); + expect(convert(' \n' + '|_|\n' + ' |\n' + ' ')).toBe('4'); }); xtest('recognizes five', () => { - expect(convert( - ' _ \n' - + '|_ \n' - + ' _|\n' - + ' ', - )).toBe('5'); + expect(convert(' _ \n' + '|_ \n' + ' _|\n' + ' ')).toBe('5'); }); xtest('recognizes six', () => { - expect(convert( - ' _ \n' - + '|_ \n' - + '|_|\n' - + ' ', - )).toBe('6'); + expect(convert(' _ \n' + '|_ \n' + '|_|\n' + ' ')).toBe('6'); }); xtest('recognizes seven', () => { - expect(convert( - ' _ \n' - + ' |\n' - + ' |\n' - + ' ', - )).toBe('7'); + expect(convert(' _ \n' + ' |\n' + ' |\n' + ' ')).toBe('7'); }); xtest('recognizes eight', () => { - expect(convert( - ' _ \n' - + '|_|\n' - + '|_|\n' - + ' ', - )).toBe('8'); + expect(convert(' _ \n' + '|_|\n' + '|_|\n' + ' ')).toBe('8'); }); xtest('recognizes nine', () => { - expect(convert( - ' _ \n' - + '|_|\n' - + ' _|\n' - + ' ', - )).toBe('9'); + expect(convert(' _ \n' + '|_|\n' + ' _|\n' + ' ')).toBe('9'); }); xtest('recognizes ten', () => { - expect(convert( - ' _ \n' - + ' || |\n' - + ' ||_|\n' - + ' ', - )).toBe('10'); + expect(convert(' _ \n' + ' || |\n' + ' ||_|\n' + ' ')).toBe('10'); }); xtest('identifies garble', () => { - expect(convert( - ' \n' - + '| |\n' - + '| |\n' - + ' ', - )).toBe('?'); + expect(convert(' \n' + '| |\n' + '| |\n' + ' ')).toBe('?'); }); xtest('converts 110101100', () => { - expect(convert( - ' _ _ _ _ \n' - + ' | || | || | | || || |\n' - + ' | ||_| ||_| | ||_||_|\n' - + ' ', - )).toBe('110101100'); + expect( + convert( + ' _ _ _ _ \n' + + ' | || | || | | || || |\n' + + ' | ||_| ||_| | ||_||_|\n' + + ' ' + ) + ).toBe('110101100'); }); xtest('identifies garble mixed in', () => { - expect(convert( - ' _ _ _ \n' - + ' | || | || | || || |\n' - + ' | | _| ||_| | ||_||_|\n' - + ' ', - )).toBe('11?10?1?0'); + expect( + convert( + ' _ _ _ \n' + + ' | || | || | || || |\n' + + ' | | _| ||_| | ||_||_|\n' + + ' ' + ) + ).toBe('11?10?1?0'); }); xtest('converts 1234567890', () => { - expect(convert( - ' _ _ _ _ _ _ _ _ \n' - + ' | _| _||_||_ |_ ||_||_|| |\n' - + ' ||_ _| | _||_| ||_| _||_|\n' - + ' ', - )).toBe('1234567890'); + expect( + convert( + ' _ _ _ _ _ _ _ _ \n' + + ' | _| _||_||_ |_ ||_||_|| |\n' + + ' ||_ _| | _||_| ||_| _||_|\n' + + ' ' + ) + ).toBe('1234567890'); }); xtest('converts 123 456 789', () => { - expect(convert( - ' _ _ \n' - + ' | _| _|\n' - + ' ||_ _|\n' - + ' \n' - + ' _ _ \n' - + '|_||_ |_ \n' - + ' | _||_|\n' - + ' \n' - + ' _ _ _ \n' - + ' ||_||_|\n' - + ' ||_| _|\n' - + ' ', - )).toBe('123,456,789'); + expect( + convert( + ' _ _ \n' + + ' | _| _|\n' + + ' ||_ _|\n' + + ' \n' + + ' _ _ \n' + + '|_||_ |_ \n' + + ' | _||_|\n' + + ' \n' + + ' _ _ _ \n' + + ' ||_||_|\n' + + ' ||_| _|\n' + + ' ' + ) + ).toBe('123,456,789'); }); }); diff --git a/exercises/octal/babel.config.js b/exercises/octal/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/octal/babel.config.js +++ b/exercises/octal/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/octal/example.js b/exercises/octal/example.js index b9c5b2c48c..1093c80914 100644 --- a/exercises/octal/example.js +++ b/exercises/octal/example.js @@ -2,7 +2,10 @@ export class Octal { constructor(octal) { const newOctal = octal.match(/[^0-7]/) ? '0' : octal; return { - toDecimal: () => newOctal.split('').reduce((prev, curr) => prev * 8 + parseInt(curr, 8), 0), + toDecimal: () => + newOctal + .split('') + .reduce((prev, curr) => prev * 8 + parseInt(curr, 8), 0), }; } } diff --git a/exercises/octal/octal.js b/exercises/octal/octal.js index 7ce1480f1a..5531d250aa 100644 --- a/exercises/octal/octal.js +++ b/exercises/octal/octal.js @@ -5,10 +5,10 @@ export class Octal { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } toDecimal() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md index c4c0f1c80b..99a3f89652 100644 --- a/exercises/palindrome-products/README.md +++ b/exercises/palindrome-products/README.md @@ -6,7 +6,7 @@ A palindromic number is a number that remains the same when its digits are reversed. For example, `121` is a palindromic number but `112` is not. Given a range of numbers, find the largest and smallest palindromes which -are products of numbers within that range. +are products of two numbers within that range. Your solution should return the largest and smallest palindromes, along with the factors of each within the range. If the largest or smallest palindrome has more diff --git a/exercises/palindrome-products/babel.config.js b/exercises/palindrome-products/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/palindrome-products/babel.config.js +++ b/exercises/palindrome-products/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/palindrome-products/example.js b/exercises/palindrome-products/example.js index 39361547db..34539c490e 100644 --- a/exercises/palindrome-products/example.js +++ b/exercises/palindrome-products/example.js @@ -1,4 +1,4 @@ -const reverseString = str => str.split('').reverse().join(''); +const reverseString = (str) => str.split('').reverse().join(''); class Palindrome { constructor(factor1, factor2) { @@ -18,7 +18,7 @@ class Palindrome { } merge(other) { - other.factors.forEach(f => this.factors.push(f)); + other.factors.forEach((f) => this.factors.push(f)); this.factors = this.factors.sort(); return this; } diff --git a/exercises/palindrome-products/palindrome-products.js b/exercises/palindrome-products/palindrome-products.js index 87966fcd52..9af6b5d15a 100644 --- a/exercises/palindrome-products/palindrome-products.js +++ b/exercises/palindrome-products/palindrome-products.js @@ -5,6 +5,6 @@ export class Palindromes { static generate() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/palindrome-products/palindrome-products.spec.js b/exercises/palindrome-products/palindrome-products.spec.js index 8f635d6b9f..badec50e33 100644 --- a/exercises/palindrome-products/palindrome-products.spec.js +++ b/exercises/palindrome-products/palindrome-products.spec.js @@ -4,7 +4,7 @@ describe('Palindromes', () => { test('smallest palindrome from single digit factors', () => { const palindromes = Palindromes.generate({ maxFactor: 9, minFactor: 1 }); const smallest = palindromes.smallest; - const expected = {value: 1, factors: [[1, 1]]}; + const expected = { value: 1, factors: [[1, 1]] }; expect(smallest.value).toEqual(expected.value); expect(sortFactors(smallest.factors)).toEqual(expected.factors); @@ -13,7 +13,13 @@ describe('Palindromes', () => { xtest('largest palindrome from single digit factors', () => { const palindromes = Palindromes.generate({ maxFactor: 9, minFactor: 1 }); const largest = palindromes.largest; - const expected = {value: 9, factors: [[1, 9], [3, 3]]}; + const expected = { + value: 9, + factors: [ + [1, 9], + [3, 3], + ], + }; expect(largest.value).toEqual(expected.value); expect(sortFactors(largest.factors)).toEqual(expected.factors); @@ -22,7 +28,7 @@ describe('Palindromes', () => { xtest('smallest palindrome from double digit factors', () => { const palindromes = Palindromes.generate({ maxFactor: 99, minFactor: 10 }); const smallest = palindromes.smallest; - const expected = {value: 121, factors: [[11, 11]]}; + const expected = { value: 121, factors: [[11, 11]] }; expect(smallest.value).toEqual(expected.value); expect(sortFactors(smallest.factors)).toEqual(expected.factors); @@ -31,50 +37,65 @@ describe('Palindromes', () => { xtest('largest palindrome from double digit factors', () => { const palindromes = Palindromes.generate({ maxFactor: 99, minFactor: 10 }); const largest = palindromes.largest; - const expected = {value: 9009, factors: [[91, 99]]}; + const expected = { value: 9009, factors: [[91, 99]] }; expect(largest.value).toEqual(expected.value); expect(sortFactors(largest.factors)).toEqual(expected.factors); }); xtest('smallest palindrome from triple digit factors', () => { - const palindromes = Palindromes.generate({ maxFactor: 999, minFactor: 100 }); + const palindromes = Palindromes.generate({ + maxFactor: 999, + minFactor: 100, + }); const smallest = palindromes.smallest; - const expected = {value: 10201, factors: [[101, 101]]}; + const expected = { value: 10201, factors: [[101, 101]] }; expect(smallest.value).toEqual(expected.value); expect(sortFactors(smallest.factors)).toEqual(expected.factors); }); xtest('largest palindrome from triple digit factors', () => { - const palindromes = Palindromes.generate({ maxFactor: 999, minFactor: 100 }); + const palindromes = Palindromes.generate({ + maxFactor: 999, + minFactor: 100, + }); const largest = palindromes.largest; - const expected = {value: 906609, factors: [[913, 993]]}; + const expected = { value: 906609, factors: [[913, 993]] }; expect(largest.value).toEqual(expected.value); expect(sortFactors(largest.factors)).toEqual(expected.factors); }); xtest('smallest palindrome from four digit factors', () => { - const palindromes = Palindromes.generate({ maxFactor: 9999, minFactor: 1000 }); + const palindromes = Palindromes.generate({ + maxFactor: 9999, + minFactor: 1000, + }); const smallest = palindromes.smallest; - const expected = {value: 1002001, factors: [[1001, 1001]]}; + const expected = { value: 1002001, factors: [[1001, 1001]] }; expect(smallest.value).toEqual(expected.value); expect(sortFactors(smallest.factors)).toEqual(expected.factors); }); xtest('largest palindrome from four digit factors', () => { - const palindromes = Palindromes.generate({ maxFactor: 9999, minFactor: 1000 }); + const palindromes = Palindromes.generate({ + maxFactor: 9999, + minFactor: 1000, + }); const largest = palindromes.largest; - const expected = {value: 99000099, factors: [[9901, 9999]]}; + const expected = { value: 99000099, factors: [[9901, 9999]] }; expect(largest.value).toEqual(expected.value); expect(sortFactors(largest.factors)).toEqual(expected.factors); }); xtest('empty result for smallest if no palindrome in range', () => { - const palindromes = Palindromes.generate({ maxFactor: 1003, minFactor: 1002 }); + const palindromes = Palindromes.generate({ + maxFactor: 1003, + minFactor: 1002, + }); const smallest = palindromes.smallest; expect(smallest.value).toBe(null); @@ -91,7 +112,10 @@ describe('Palindromes', () => { xtest('error for smallest if min is more than max', () => { expect(() => { - const palindromes = Palindromes.generate({ maxFactor: 1, minFactor: 10000 }); + const palindromes = Palindromes.generate({ + maxFactor: 1, + minFactor: 10000, + }); palindromes.smallest; }).toThrow(new Error('min must be <= max')); }); @@ -105,5 +129,5 @@ describe('Palindromes', () => { }); function sortFactors(factors) { - return factors.map(f => f.sort()).sort(); + return factors.map((f) => f.sort()).sort(); } diff --git a/exercises/pangram/babel.config.js b/exercises/pangram/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/pangram/babel.config.js +++ b/exercises/pangram/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/pangram/example.js b/exercises/pangram/example.js index a06bcd777d..848fce8cc2 100644 --- a/exercises/pangram/example.js +++ b/exercises/pangram/example.js @@ -2,7 +2,7 @@ const notAlpha = /[^a-z]+/gi; const alphaLength = 26; export const isPangram = (candidate) => { - const cleaned = (candidate.replace(notAlpha, '')).toLowerCase(); + const cleaned = candidate.replace(notAlpha, '').toLowerCase(); const sortedSet = new Set([...cleaned].sort()); return sortedSet.size === alphaLength; }; diff --git a/exercises/pangram/pangram.js b/exercises/pangram/pangram.js index 9c6dac167d..47769cc4d5 100644 --- a/exercises/pangram/pangram.js +++ b/exercises/pangram/pangram.js @@ -4,5 +4,5 @@ // export const isPangram = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/pangram/pangram.spec.js b/exercises/pangram/pangram.spec.js index 55cbf9eb23..302c8875ad 100644 --- a/exercises/pangram/pangram.spec.js +++ b/exercises/pangram/pangram.spec.js @@ -14,7 +14,9 @@ describe('Pangram()', () => { }); xtest("missing the letter 'x'", () => { - expect(isPangram('a quick movement of the enemy will jeopardize five gunboats')).toBe(false); + expect( + isPangram('a quick movement of the enemy will jeopardize five gunboats') + ).toBe(false); }); xtest("missing the letter 'h'", () => { @@ -26,11 +28,15 @@ describe('Pangram()', () => { }); xtest('with numbers', () => { - expect(isPangram('the 1 quick brown fox jumps over the 2 lazy dogs')).toBe(true); + expect(isPangram('the 1 quick brown fox jumps over the 2 lazy dogs')).toBe( + true + ); }); xtest('missing letters replaced by numbers', () => { - expect(isPangram('7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog')).toBe(false); + expect(isPangram('7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog')).toBe( + false + ); }); xtest('mixed case and punctuation', () => { @@ -38,6 +44,8 @@ describe('Pangram()', () => { }); xtest('case insensitive', () => { - expect(isPangram('the quick brown fox jumps over with lazy FX')).toBe(false); + expect(isPangram('the quick brown fox jumps over with lazy FX')).toBe( + false + ); }); }); diff --git a/exercises/pascals-triangle/babel.config.js b/exercises/pascals-triangle/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/pascals-triangle/babel.config.js +++ b/exercises/pascals-triangle/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/pascals-triangle/example.js b/exercises/pascals-triangle/example.js index 75f9f4f80a..a1af35ae58 100644 --- a/exercises/pascals-triangle/example.js +++ b/exercises/pascals-triangle/example.js @@ -1,4 +1,4 @@ -export const rows = size => { +export const rows = (size) => { if (size === 0) { return []; } else if (size === 1) { @@ -7,7 +7,7 @@ export const rows = size => { let triangleRows = [[1]]; - const getNextRow = row => { + const getNextRow = (row) => { let nextRow = []; nextRow.push(1); for (let i = 0; i <= row.length - 2; i++) { diff --git a/exercises/pascals-triangle/pascals-triangle.js b/exercises/pascals-triangle/pascals-triangle.js index f837837759..699a87abe3 100644 --- a/exercises/pascals-triangle/pascals-triangle.js +++ b/exercises/pascals-triangle/pascals-triangle.js @@ -4,5 +4,5 @@ // export const rows = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/pascals-triangle/pascals-triangle.spec.js b/exercises/pascals-triangle/pascals-triangle.spec.js index cd80ed4826..4641921044 100644 --- a/exercises/pascals-triangle/pascals-triangle.spec.js +++ b/exercises/pascals-triangle/pascals-triangle.spec.js @@ -28,7 +28,7 @@ describe('Pascals Triangle', () => { [1, 1], [1, 2, 1], [1, 3, 3, 1], - [1, 4, 6, 4, 1] + [1, 4, 6, 4, 1], ]); }); @@ -39,7 +39,7 @@ describe('Pascals Triangle', () => { [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], - [1, 5, 10, 10, 5, 1] + [1, 5, 10, 10, 5, 1], ]); }); @@ -54,7 +54,7 @@ describe('Pascals Triangle', () => { [1, 6, 15, 20, 15, 6, 1], [1, 7, 21, 35, 35, 21, 7, 1], [1, 8, 28, 56, 70, 56, 28, 8, 1], - [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] + [1, 9, 36, 84, 126, 126, 84, 36, 9, 1], ]); }); }); diff --git a/exercises/perfect-numbers/README.md b/exercises/perfect-numbers/README.md index a392e64c35..c5a975061e 100644 --- a/exercises/perfect-numbers/README.md +++ b/exercises/perfect-numbers/README.md @@ -1,9 +1,9 @@ # Perfect Numbers Determine if a number is perfect, abundant, or deficient based on -Nicomachus' (60 - 120 CE) classification scheme for natural numbers. +Nicomachus' (60 - 120 CE) classification scheme for positive integers. -The Greek mathematician [Nicomachus](https://en.wikipedia.org/wiki/Nicomachus) devised a classification scheme for natural numbers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum](https://en.wikipedia.org/wiki/Aliquot_sum). The aliquot sum is defined as the sum of the factors of a number not including the number itself. For example, the aliquot sum of 15 is (1 + 3 + 5) = 9 +The Greek mathematician [Nicomachus](https://en.wikipedia.org/wiki/Nicomachus) devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum](https://en.wikipedia.org/wiki/Aliquot_sum). The aliquot sum is defined as the sum of the factors of a number not including the number itself. For example, the aliquot sum of 15 is (1 + 3 + 5) = 9 - **Perfect**: aliquot sum = number - 6 is a perfect number because (1 + 2 + 3) = 6 diff --git a/exercises/perfect-numbers/babel.config.js b/exercises/perfect-numbers/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/perfect-numbers/babel.config.js +++ b/exercises/perfect-numbers/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/perfect-numbers/example.js b/exercises/perfect-numbers/example.js index 34f0ae3218..4bad0c9055 100644 --- a/exercises/perfect-numbers/example.js +++ b/exercises/perfect-numbers/example.js @@ -1,8 +1,8 @@ /** - * Calculate all the divisors for a given number. - * @param {number} number - natural number. - * @returns {array} that contains the divisors for a given number excluding the number itself. - */ + * Calculate all the divisors for a given number. + * @param {number} number - natural number. + * @returns {array} that contains the divisors for a given number excluding the number itself. + */ function getDivisors(number) { const divs = []; @@ -25,11 +25,11 @@ function getDivisors(number) { } /** - * Classify a given number as perfect, abundant or deficient. - * @param {number} - number to be classified. Note: if the number is equal or smaller than 0, - * then returns an error: Classification is only possible for natural numbers. - * @returns {string} - string that contains the classification (perfect, abundant or deficient). - */ + * Classify a given number as perfect, abundant or deficient. + * @param {number} - number to be classified. Note: if the number is equal or smaller than 0, + * then returns an error: Classification is only possible for natural numbers. + * @returns {string} - string that contains the classification (perfect, abundant or deficient). + */ export const classify = (number) => { // Check if the input is valid if (number <= 0) { diff --git a/exercises/perfect-numbers/perfect-numbers.js b/exercises/perfect-numbers/perfect-numbers.js index 488e243559..d2c0e5a701 100644 --- a/exercises/perfect-numbers/perfect-numbers.js +++ b/exercises/perfect-numbers/perfect-numbers.js @@ -4,5 +4,5 @@ // export const classify = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/perfect-numbers/perfect-numbers.spec.js b/exercises/perfect-numbers/perfect-numbers.spec.js index 0c328a6df1..ffe4638928 100644 --- a/exercises/perfect-numbers/perfect-numbers.spec.js +++ b/exercises/perfect-numbers/perfect-numbers.spec.js @@ -3,13 +3,15 @@ import { classify } from './perfect-numbers'; describe('Exercise - Perfect Numbers', () => { describe('Invalid Inputs', () => { test('Zero is rejected (not a natural number)', () => { - expect(() => classify(0)) - .toThrow(new Error('Classification is only possible for natural numbers.')); + expect(() => classify(0)).toThrow( + new Error('Classification is only possible for natural numbers.') + ); }); xtest('Negative integer is rejected (not a natural number)', () => { - expect(() => classify(-1)) - .toThrow(new Error('Classification is only possible for natural numbers.')); + expect(() => classify(-1)).toThrow( + new Error('Classification is only possible for natural numbers.') + ); }); }); diff --git a/exercises/phone-number/babel.config.js b/exercises/phone-number/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/phone-number/babel.config.js +++ b/exercises/phone-number/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/phone-number/example.js b/exercises/phone-number/example.js index 78824c7baf..d72bfbc643 100644 --- a/exercises/phone-number/example.js +++ b/exercises/phone-number/example.js @@ -1,4 +1,4 @@ -export const clean = number => { +export const clean = (number) => { if (/[a-zA-Z]/.test(number)) { throw new Error('Letters not permitted'); } else if (/[@:!]/.test(number)) { diff --git a/exercises/phone-number/phone-number.js b/exercises/phone-number/phone-number.js index 55816820ad..ba60516cfb 100644 --- a/exercises/phone-number/phone-number.js +++ b/exercises/phone-number/phone-number.js @@ -4,5 +4,5 @@ // export const clean = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/pig-latin/babel.config.js b/exercises/pig-latin/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/pig-latin/babel.config.js +++ b/exercises/pig-latin/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/pig-latin/example.js b/exercises/pig-latin/example.js index b4d5d8fb18..8783dc2c12 100644 --- a/exercises/pig-latin/example.js +++ b/exercises/pig-latin/example.js @@ -12,9 +12,6 @@ function translateWord(word) { export const translator = { translate(english) { - return english - .split(' ') - .map(translateWord) - .join(' '); + return english.split(' ').map(translateWord).join(' '); }, }; diff --git a/exercises/pig-latin/pig-latin.js b/exercises/pig-latin/pig-latin.js index 95d0e5ef4b..c760483044 100644 --- a/exercises/pig-latin/pig-latin.js +++ b/exercises/pig-latin/pig-latin.js @@ -5,6 +5,6 @@ export class translator { static translate() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/pig-latin/pig-latin.spec.js b/exercises/pig-latin/pig-latin.spec.js index adb1eb4b19..3604c9b8ce 100644 --- a/exercises/pig-latin/pig-latin.spec.js +++ b/exercises/pig-latin/pig-latin.spec.js @@ -97,7 +97,9 @@ describe('Pig Latin', () => { describe('phrases are translated', () => { xtest('a whole phrase', () => { - expect(translator.translate('quick fast run')).toEqual('ickquay astfay unray'); + expect(translator.translate('quick fast run')).toEqual( + 'ickquay astfay unray' + ); }); }); }); diff --git a/exercises/point-mutations/babel.config.js b/exercises/point-mutations/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/point-mutations/babel.config.js +++ b/exercises/point-mutations/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/point-mutations/example.js b/exercises/point-mutations/example.js index 09c587929d..03f2a5ab73 100644 --- a/exercises/point-mutations/example.js +++ b/exercises/point-mutations/example.js @@ -5,13 +5,18 @@ export class DNA { hammingDistance(comparison) { let distance = 0; - const calculationDistance = Math.min(this.nucleotides.length, comparison.length); + const calculationDistance = Math.min( + this.nucleotides.length, + comparison.length + ); for (let i = 0; i < calculationDistance; i += 1) { const currentNucleotide = this.nucleotides[i]; const comparisonNucleotide = comparison[i]; - if (currentNucleotide !== comparisonNucleotide) { distance += 1; } + if (currentNucleotide !== comparisonNucleotide) { + distance += 1; + } } return distance; diff --git a/exercises/point-mutations/point-mutations.js b/exercises/point-mutations/point-mutations.js index 254ab9a3b9..a3fe4a8812 100644 --- a/exercises/point-mutations/point-mutations.js +++ b/exercises/point-mutations/point-mutations.js @@ -5,10 +5,10 @@ export class DNA { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } hammingDistance() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/prime-factors/babel.config.js b/exercises/prime-factors/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/prime-factors/babel.config.js +++ b/exercises/prime-factors/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/prime-factors/prime-factors.js b/exercises/prime-factors/prime-factors.js index b8f2e857a2..3d0f819c36 100644 --- a/exercises/prime-factors/prime-factors.js +++ b/exercises/prime-factors/prime-factors.js @@ -4,5 +4,5 @@ // export const primeFactors = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/prime-factors/prime-factors.spec.js b/exercises/prime-factors/prime-factors.spec.js index 36afdbd4df..92bcd574d0 100644 --- a/exercises/prime-factors/prime-factors.spec.js +++ b/exercises/prime-factors/prime-factors.spec.js @@ -1,7 +1,8 @@ import { primeFactors } from './prime-factors'; describe('primeFactors', () => { - test('returns an empty array for 1', () => expect(primeFactors(1)).toEqual([])); + test('returns an empty array for 1', () => + expect(primeFactors(1)).toEqual([])); xtest('factors 2', () => expect(primeFactors(2)).toEqual([2])); @@ -19,7 +20,9 @@ describe('primeFactors', () => { xtest('factors 625', () => expect(primeFactors(625)).toEqual([5, 5, 5, 5])); - xtest('factors 901255', () => expect(primeFactors(901255)).toEqual([5, 17, 23, 461])); + xtest('factors 901255', () => + expect(primeFactors(901255)).toEqual([5, 17, 23, 461])); - xtest('factors 93819012551', () => expect(primeFactors(93819012551)).toEqual([11, 9539, 894119])); + xtest('factors 93819012551', () => + expect(primeFactors(93819012551)).toEqual([11, 9539, 894119])); }); diff --git a/exercises/protein-translation/babel.config.js b/exercises/protein-translation/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/protein-translation/babel.config.js +++ b/exercises/protein-translation/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/protein-translation/example.js b/exercises/protein-translation/example.js index 34cf0cccc3..821a471a28 100644 --- a/exercises/protein-translation/example.js +++ b/exercises/protein-translation/example.js @@ -18,7 +18,7 @@ const ACID_PROTEIN_MAP = { UGA: 'STOP', }; -const getProtein = codon => ACID_PROTEIN_MAP[codon] || 'INVALID'; +const getProtein = (codon) => ACID_PROTEIN_MAP[codon] || 'INVALID'; export const translate = (rnaStrand) => { const proteins = []; diff --git a/exercises/protein-translation/protein-translation.js b/exercises/protein-translation/protein-translation.js index 047c11cf0c..c2686a6dad 100644 --- a/exercises/protein-translation/protein-translation.js +++ b/exercises/protein-translation/protein-translation.js @@ -4,5 +4,5 @@ // export const translate = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/protein-translation/protein-translation.spec.js b/exercises/protein-translation/protein-translation.spec.js index 6f8ea2e3d0..44f0c22528 100644 --- a/exercises/protein-translation/protein-translation.spec.js +++ b/exercises/protein-translation/protein-translation.spec.js @@ -18,7 +18,12 @@ describe('ProteinTranslation', () => { }); xtest('Serine codons translate into protein', () => { - expect(translate('UCUUCCUCAUCG')).toEqual(['Serine', 'Serine', 'Serine', 'Serine']); + expect(translate('UCUUCCUCAUCG')).toEqual([ + 'Serine', + 'Serine', + 'Serine', + 'Serine', + ]); }); xtest('Tyrosine codons translate into protein', () => { @@ -46,11 +51,19 @@ describe('ProteinTranslation', () => { }); xtest('Small RNA strand', () => { - expect(translate('AUGUUUUCU')).toEqual(['Methionine', 'Phenylalanine', 'Serine']); + expect(translate('AUGUUUUCU')).toEqual([ + 'Methionine', + 'Phenylalanine', + 'Serine', + ]); }); xtest('Stop codon ends translation', () => { - expect(translate('AUGUUUUCUUAAAUG')).toEqual(['Methionine', 'Phenylalanine', 'Serine']); + expect(translate('AUGUUUUCUUAAAUG')).toEqual([ + 'Methionine', + 'Phenylalanine', + 'Serine', + ]); }); xtest('Invalid codon throws error', () => { diff --git a/exercises/proverb/babel.config.js b/exercises/proverb/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/proverb/babel.config.js +++ b/exercises/proverb/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/proverb/example.js b/exercises/proverb/example.js index cae9cc54d5..e8eb516334 100644 --- a/exercises/proverb/example.js +++ b/exercises/proverb/example.js @@ -3,7 +3,8 @@ const lastArgIsOptions = (args) => { return typeof last === 'object'; }; -const conclusion = (firstArg, qualifier = '') => `And all for the want of a ${qualifier}${firstArg}.`; +const conclusion = (firstArg, qualifier = '') => + `And all for the want of a ${qualifier}${firstArg}.`; export const proverb = (...args) => { let options = {}; @@ -12,9 +13,13 @@ export const proverb = (...args) => { } const allExceptLastArg = args.slice(0, -1); - const chainOfEvents = allExceptLastArg.map((arg, index) => `For want of a ${arg} the ${args[index + 1]} was lost.`); + const chainOfEvents = allExceptLastArg.map( + (arg, index) => `For want of a ${arg} the ${args[index + 1]} was lost.` + ); - const qualifier = options.qualifier ? `${options.qualifier} ` : options.qualifier; + const qualifier = options.qualifier + ? `${options.qualifier} ` + : options.qualifier; chainOfEvents.push(conclusion(args[0], qualifier)); return chainOfEvents.join('\n'); diff --git a/exercises/proverb/proverb.js b/exercises/proverb/proverb.js index 9edafb6a7c..8bb9a4b9fc 100644 --- a/exercises/proverb/proverb.js +++ b/exercises/proverb/proverb.js @@ -4,5 +4,5 @@ // export const proverb = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/proverb/proverb.spec.js b/exercises/proverb/proverb.spec.js index bba277c543..3a20f74218 100644 --- a/exercises/proverb/proverb.spec.js +++ b/exercises/proverb/proverb.spec.js @@ -6,7 +6,7 @@ describe('Proverb Test Suite', () => { expect(result).toEqual( `For want of a nail the shoe was lost. -And all for the want of a nail.`, +And all for the want of a nail.` ); }); @@ -16,7 +16,7 @@ And all for the want of a nail.`, expect(result).toEqual( `For want of a nail the shoe was lost. For want of a shoe the horse was lost. -And all for the want of a nail.`, +And all for the want of a nail.` ); }); @@ -26,7 +26,7 @@ And all for the want of a nail.`, `For want of a nail the shoe was lost. For want of a shoe the horse was lost. For want of a horse the rider was lost. -And all for the want of a nail.`, +And all for the want of a nail.` ); }); @@ -35,13 +35,20 @@ And all for the want of a nail.`, expect(result).toEqual( `For want of a key the value was lost. -And all for the want of a key.`, +And all for the want of a key.` ); }); xtest('the whole proveb', () => { - const result = proverb('nail', 'shoe', 'horse', 'rider', - 'message', 'battle', 'kingdom'); + const result = proverb( + 'nail', + 'shoe', + 'horse', + 'rider', + 'message', + 'battle', + 'kingdom' + ); expect(result).toEqual( `For want of a nail the shoe was lost. @@ -50,7 +57,7 @@ For want of a horse the rider was lost. For want of a rider the message was lost. For want of a message the battle was lost. For want of a battle the kingdom was lost. -And all for the want of a nail.`, +And all for the want of a nail.` ); }); @@ -59,9 +66,16 @@ And all for the want of a nail.`, }); xtest('the use of an optional qualifier in the final consequence', () => { - const result = proverb('nail', 'shoe', 'horse', 'rider', - 'message', 'battle', 'kingdom', - { qualifier: 'horseshoe' }); + const result = proverb( + 'nail', + 'shoe', + 'horse', + 'rider', + 'message', + 'battle', + 'kingdom', + { qualifier: 'horseshoe' } + ); expect(result).toEqual( `For want of a nail the shoe was lost. @@ -70,7 +84,7 @@ For want of a horse the rider was lost. For want of a rider the message was lost. For want of a message the battle was lost. For want of a battle the kingdom was lost. -And all for the want of a horseshoe nail.`, +And all for the want of a horseshoe nail.` ); }); }); diff --git a/exercises/pythagorean-triplet/babel.config.js b/exercises/pythagorean-triplet/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/pythagorean-triplet/babel.config.js +++ b/exercises/pythagorean-triplet/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/pythagorean-triplet/pythagorean-triplet.js b/exercises/pythagorean-triplet/pythagorean-triplet.js index d930e4fb8b..9eeb58b46f 100644 --- a/exercises/pythagorean-triplet/pythagorean-triplet.js +++ b/exercises/pythagorean-triplet/pythagorean-triplet.js @@ -5,22 +5,22 @@ export class Triplet { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } sum() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } product() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } isPythagorean() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } static where() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/pythagorean-triplet/pythagorean-triplet.spec.js b/exercises/pythagorean-triplet/pythagorean-triplet.spec.js index 6c247e3398..41cfcc2a47 100644 --- a/exercises/pythagorean-triplet/pythagorean-triplet.spec.js +++ b/exercises/pythagorean-triplet/pythagorean-triplet.spec.js @@ -19,19 +19,19 @@ describe('Triplet', () => { xtest('can make triplets up to 10', () => { const triplets = Triplet.where({ maxFactor: 10 }); - const products = triplets.sort().map(triplet => triplet.product()); + const products = triplets.sort().map((triplet) => triplet.product()); expect(products).toEqual([60, 480]); }); xtest('can make triplets 11 through 20', () => { const triplets = Triplet.where({ minFactor: 11, maxFactor: 20 }); - const products = triplets.sort().map(triplet => triplet.product()); + const products = triplets.sort().map((triplet) => triplet.product()); expect(products).toEqual([3840]); }); xtest('can filter on sum', () => { const triplets = Triplet.where({ sum: 180, maxFactor: 100 }); - const products = triplets.sort().map(triplet => triplet.product()); + const products = triplets.sort().map((triplet) => triplet.product()); expect(products).toEqual([118080, 168480, 202500]); }); }); diff --git a/exercises/queen-attack/babel.config.js b/exercises/queen-attack/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/queen-attack/babel.config.js +++ b/exercises/queen-attack/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/queen-attack/example.js b/exercises/queen-attack/example.js index bf93761432..55895e40b1 100644 --- a/exercises/queen-attack/example.js +++ b/exercises/queen-attack/example.js @@ -22,8 +22,8 @@ function constructBoard() { function placePieces(self) { const board = self.board; - board[(self.black[0] * W * 2) + (self.black[1] * 2)] = 'B'; - board[(self.white[0] * W * 2) + (self.white[1] * 2)] = 'W'; + board[self.black[0] * W * 2 + self.black[1] * 2] = 'B'; + board[self.white[0] * W * 2 + self.white[1] * 2] = 'W'; } export class QueenAttack { @@ -41,7 +41,10 @@ export class QueenAttack { if (this.black[0] === this.white[0] || this.black[1] === this.white[1]) { return true; } - return Math.abs(this.black[0] - this.white[0]) === Math.abs(this.black[1] - this.white[1]); + return ( + Math.abs(this.black[0] - this.white[0]) === + Math.abs(this.black[1] - this.white[1]) + ); }; this.toString = () => this.board.join(''); diff --git a/exercises/queen-attack/queen-attack.js b/exercises/queen-attack/queen-attack.js index e9573c68c5..8ea6db054b 100644 --- a/exercises/queen-attack/queen-attack.js +++ b/exercises/queen-attack/queen-attack.js @@ -4,15 +4,15 @@ // export class QueenAttack { - constructor() { - throw new Error("Remove this statement and implement this function"); - } + constructor() { + throw new Error('Remove this statement and implement this function'); + } - toString() { - throw new Error("Remove this statement and implement this function"); - } + toString() { + throw new Error('Remove this statement and implement this function'); + } - canAttack() { - throw new Error("Remove this statement and implement this function"); - } + canAttack() { + throw new Error('Remove this statement and implement this function'); + } } diff --git a/exercises/queen-attack/queen-attack.spec.js b/exercises/queen-attack/queen-attack.spec.js index 347b8c5faa..c87397aba8 100644 --- a/exercises/queen-attack/queen-attack.spec.js +++ b/exercises/queen-attack/queen-attack.spec.js @@ -22,28 +22,32 @@ describe('Queens', () => { xtest('toString representation', () => { const positioning = { white: [2, 4], black: [6, 6] }; const queens = new QueenAttack(positioning); - const board = ['_ _ _ _ _ _ _ _', + const board = [ + '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ W _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ B _', - '_ _ _ _ _ _ _ _\n'].join('\n'); + '_ _ _ _ _ _ _ _\n', + ].join('\n'); expect(queens.toString()).toEqual(board); }); xtest('toString representation edge case', () => { const positioning = { white: [7, 7], black: [0, 0] }; const queens = new QueenAttack(positioning); - const board = ['B _ _ _ _ _ _ _', + const board = [ + 'B _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', '_ _ _ _ _ _ _ _', - '_ _ _ _ _ _ _ W\n'].join('\n'); + '_ _ _ _ _ _ _ W\n', + ].join('\n'); expect(queens.toString()).toEqual(board); }); diff --git a/exercises/raindrops/README.md b/exercises/raindrops/README.md index a4b55d8450..25aded55c8 100644 --- a/exercises/raindrops/README.md +++ b/exercises/raindrops/README.md @@ -1,21 +1,19 @@ # Raindrops -Convert a number to a string, the contents of which depend on the number's factors. +Your task is to convert a number into a string that contains raindrop sounds corresponding to certain potential factors. A factor is a number that evenly divides into another number, leaving no remainder. The simplest way to test if a one number is a factor of another is to use the [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation). -- If the number has 3 as a factor, output 'Pling'. -- If the number has 5 as a factor, output 'Plang'. -- If the number has 7 as a factor, output 'Plong'. -- If the number does not have 3, 5, or 7 as a factor, - just pass the number's digits straight through. +The rules of `raindrops` are that if a given number: + +- has 3 as a factor, add 'Pling' to the result. +- has 5 as a factor, add 'Plang' to the result. +- has 7 as a factor, add 'Plong' to the result. +- _does not_ have any of 3, 5, or 7 as a factor, the result should be the digits of the number. ## Examples -- 28's factors are 1, 2, 4, **7**, 14, 28. - - In raindrop-speak, this would be a simple "Plong". -- 30's factors are 1, 2, **3**, **5**, 6, 10, 15, 30. - - In raindrop-speak, this would be a "PlingPlang". -- 34 has four factors: 1, 2, 17, and 34. - - In raindrop-speak, this would be "34". +- 28 has 7 as a factor, but not 3 or 5, so the result would be "Plong". +- 30 has both 3 and 5 as factors, but not 7, so the result would be "PlingPlang". +- 34 is not factored by 3, 5, or 7, so the result would be "34". ## Setup diff --git a/exercises/raindrops/babel.config.js b/exercises/raindrops/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/raindrops/babel.config.js +++ b/exercises/raindrops/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/raindrops/raindrops.js b/exercises/raindrops/raindrops.js index 4cd1f6e95d..fa738c0c2c 100644 --- a/exercises/raindrops/raindrops.js +++ b/exercises/raindrops/raindrops.js @@ -4,5 +4,5 @@ // export const convert = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/rational-numbers/README.md b/exercises/rational-numbers/README.md index b6f9a55496..8cc3dd8922 100644 --- a/exercises/rational-numbers/README.md +++ b/exercises/rational-numbers/README.md @@ -4,13 +4,13 @@ A rational number is defined as the quotient of two integers `a` and `b`, called The absolute value `|r|` of the rational number `r = a/b` is equal to `|a|/|b|`. -The sum of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 + r2 = a1/b1 + a2/b2 = (a1 * b2 + a2 * b1) / (b1 * b2)`. +The sum of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ + r₂ = a₁/b₁ + a₂/b₂ = (a₁ * b₂ + a₂ * b₁) / (b₁ * b₂)`. -The difference of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 - r2 = a1/b1 - a2/b2 = (a1 * b2 - a2 * b1) / (b1 * b2)`. +The difference of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ - r₂ = a₁/b₁ - a₂/b₂ = (a₁ * b₂ - a₂ * b₁) / (b₁ * b₂)`. -The product (multiplication) of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 * r2 = (a1 * a2) / (b1 * b2)`. +The product (multiplication) of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ * r₂ = (a₁ * a₂) / (b₁ * b₂)`. -Dividing a rational number `r1 = a1/b1` by another `r2 = a2/b2` is `r1 / r2 = (a1 * b2) / (a2 * b1)` if `a2 * b1` is not zero. +Dividing a rational number `r₁ = a₁/b₁` by another `r₂ = a₂/b₂` is `r₁ / r₂ = (a₁ * b₂) / (a₂ * b₁)` if `a₂` is not zero. Exponentiation of a rational number `r = a/b` to a non-negative integer power `n` is `r^n = (a^n)/(b^n)`. diff --git a/exercises/rational-numbers/babel.config.js b/exercises/rational-numbers/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/rational-numbers/babel.config.js +++ b/exercises/rational-numbers/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/rational-numbers/example.js b/exercises/rational-numbers/example.js index 30beb89661..eceb27e5da 100644 --- a/exercises/rational-numbers/example.js +++ b/exercises/rational-numbers/example.js @@ -1,5 +1,5 @@ class Rational { - constructor(numerator, denominator){ + constructor(numerator, denominator) { if (denominator === 0) { throw new Error('Denominator must not be zero.'); } @@ -10,30 +10,48 @@ class Rational { this.reduce(); this.ensureSignInNumerator(); } - add(that){ + add(that) { const commonDenominator = this.denominator * that.denominator; - return new Rational(this.numerator * that.denominator + that.numerator * this.denominator, commonDenominator); + return new Rational( + this.numerator * that.denominator + that.numerator * this.denominator, + commonDenominator + ); } - sub(that){ + sub(that) { const commonDenominator = this.denominator * that.denominator; - return new Rational(this.numerator * that.denominator - that.numerator * this.denominator, commonDenominator); + return new Rational( + this.numerator * that.denominator - that.numerator * this.denominator, + commonDenominator + ); } - mul(that){ - return new Rational(this.numerator * that.numerator, this.denominator * that.denominator); + mul(that) { + return new Rational( + this.numerator * that.numerator, + this.denominator * that.denominator + ); } - div(that){ - return new Rational(this.numerator * that.denominator, this.denominator * that.numerator); + div(that) { + return new Rational( + this.numerator * that.denominator, + this.denominator * that.numerator + ); } - abs(){ + abs() { return new Rational(Math.abs(this.numerator), Math.abs(this.denominator)); } - exprational(n){ - return new Rational(Math.pow(this.numerator, n), Math.pow(this.denominator, n)); + exprational(n) { + return new Rational( + Math.pow(this.numerator, n), + Math.pow(this.denominator, n) + ); } - expreal(base){ - return Math.pow(10.0, Math.log10(Math.pow(base, this.numerator)) / this.denominator); + expreal(base) { + return Math.pow( + 10.0, + Math.log10(Math.pow(base, this.numerator)) / this.denominator + ); } - reduce(){ + reduce() { const commonDivisor = this.gcd(this.numerator, this.denominator); this.numerator /= commonDivisor; @@ -42,7 +60,7 @@ class Rational { return this; } - gcd(a, b){ + gcd(a, b) { let localA = a; let localB = b; while (localB !== 0) { @@ -52,7 +70,7 @@ class Rational { } return localA; } - ensureSignInNumerator(){ + ensureSignInNumerator() { if (this.denominator < 0) { this.denominator = -this.denominator; this.numerator = -this.numerator; diff --git a/exercises/rational-numbers/rational-numbers.js b/exercises/rational-numbers/rational-numbers.js index 07ac5ff3e2..6d34af593f 100644 --- a/exercises/rational-numbers/rational-numbers.js +++ b/exercises/rational-numbers/rational-numbers.js @@ -5,38 +5,38 @@ export class Rational { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } add() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } sub() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } mul() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } div() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } abs() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } exprational() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } expreal() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } reduce() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/rational-numbers/rational-numbers.spec.js b/exercises/rational-numbers/rational-numbers.spec.js index 48267f73ab..73c3c01dee 100644 --- a/exercises/rational-numbers/rational-numbers.spec.js +++ b/exercises/rational-numbers/rational-numbers.spec.js @@ -1,6 +1,5 @@ import { Rational } from './rational-numbers'; - describe('Addition', () => { test('Add two positive rational numbers', () => { const expected = new Rational(7, 6); diff --git a/exercises/react/babel.config.js b/exercises/react/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/react/babel.config.js +++ b/exercises/react/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/react/example.js b/exercises/react/example.js index 382b272df7..bf6bb699ae 100644 --- a/exercises/react/example.js +++ b/exercises/react/example.js @@ -13,8 +13,8 @@ class InputCell { } notify() { - this.subscribers.forEach(sub => sub.markForUpdate()); - this.subscribers.forEach(sub => sub.update()); + this.subscribers.forEach((sub) => sub.markForUpdate()); + this.subscribers.forEach((sub) => sub.update()); } addSubscriber(sub) { @@ -22,12 +22,11 @@ class InputCell { } } - class ComputeCell { constructor(inputCells, fn) { this.fn = fn; this.inputCells = inputCells; - this.inputCells.forEach(cell => cell.addSubscriber(this)); + this.inputCells.forEach((cell) => cell.addSubscriber(this)); this.subscribers = []; this.value = fn(inputCells); this.callbacks = []; @@ -45,27 +44,28 @@ class ComputeCell { } notify() { - this.subscribers.forEach(sub => sub.markForUpdate()); - this.subscribers.forEach(sub => sub.update()); + this.subscribers.forEach((sub) => sub.markForUpdate()); + this.subscribers.forEach((sub) => sub.update()); this.runCallbacks(); } markForUpdate() { this.updated = false; - this.subscribers.forEach(sub => sub.markForUpdate()); + this.subscribers.forEach((sub) => sub.markForUpdate()); } runCallbacks() { if (this.allInputsUpdated() && this.valueChanged()) { this.lastValue = this.value; - this.callbacks.forEach(cb => cb.run(this)); + this.callbacks.forEach((cb) => cb.run(this)); } } allInputsUpdated() { - return this.inputCells - .filter(cell => cell.updated) - .length === this.inputCells.length; + return ( + this.inputCells.filter((cell) => cell.updated).length === + this.inputCells.length + ); } valueChanged() { @@ -81,11 +81,10 @@ class ComputeCell { } removeCallback(cb) { - this.callbacks = this.callbacks.filter(c => c !== cb); + this.callbacks = this.callbacks.filter((c) => c !== cb); } } - class CallbackCell { constructor(fn) { this.fn = fn; @@ -97,5 +96,4 @@ class CallbackCell { } } - export { InputCell, ComputeCell, CallbackCell }; diff --git a/exercises/react/react.js b/exercises/react/react.js index feb8b770b1..dfbd975b46 100644 --- a/exercises/react/react.js +++ b/exercises/react/react.js @@ -5,42 +5,30 @@ export class InputCell { constructor(value) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } setValue(value) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } } export class ComputeCell { constructor(inputCells, fn) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } addCallback(cb) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } removeCallback(cb) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } } export class CallbackCell { constructor(fn) { - throw new Error( - 'Remove this statement and implement this function' - ); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/react/react.spec.js b/exercises/react/react.spec.js index a57ace76e2..d59110e84b 100644 --- a/exercises/react/react.spec.js +++ b/exercises/react/react.spec.js @@ -14,20 +14,17 @@ describe('React module', () => { xtest('allows setting compute cells', () => { const inputCell = new InputCell(1); - const fn = inputCells => inputCells[0].value + 1; + const fn = (inputCells) => inputCells[0].value + 1; const computeCell = new ComputeCell([inputCell], fn); expect(computeCell.value).toEqual(2); }); xtest('compute cell takes inputs in correct order', () => { - const inputCells = [ - new InputCell(1), - new InputCell(2), - ]; + const inputCells = [new InputCell(1), new InputCell(2)]; const computeCell = new ComputeCell( inputCells, - inputs => inputs[0].value + inputs[1].value * 10, + (inputs) => inputs[0].value + inputs[1].value * 10 ); expect(computeCell.value).toEqual(21); @@ -37,28 +34,27 @@ describe('React module', () => { const inputCell = new InputCell(1); const computeCell = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); inputCell.setValue(3); expect(computeCell.value).toEqual(4); }); - xtest('compute cells can depend on other compute cells', () => { const inputCell = new InputCell(1); const timesTwo = new ComputeCell( [inputCell], - inputs => inputs[0].value * 2, + (inputs) => inputs[0].value * 2 ); const timesThirty = new ComputeCell( [inputCell], - inputs => inputs[0].value * 30, + (inputs) => inputs[0].value * 30 ); const sum = new ComputeCell( [timesTwo, timesThirty], - inputs => inputs[0].value + inputs[1].value, + (inputs) => inputs[0].value + inputs[1].value ); expect(sum.value).toEqual(32); @@ -71,10 +67,10 @@ describe('React module', () => { const inputCell = new InputCell(1); const output = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); - const callback = new CallbackCell(cell => cell.value); + const callback = new CallbackCell((cell) => cell.value); output.addCallback(callback); inputCell.setValue(3); @@ -83,12 +79,11 @@ describe('React module', () => { xtest('callbacks fire only when output values change', () => { const inputCell = new InputCell(1); - const output = new ComputeCell( - [inputCell], - inputs => (inputs[0].value < 3 ? 111 : 222), + const output = new ComputeCell([inputCell], (inputs) => + inputs[0].value < 3 ? 111 : 222 ); - const callback = new CallbackCell(cell => cell.value); + const callback = new CallbackCell((cell) => cell.value); output.addCallback(callback); inputCell.setValue(2); @@ -100,12 +95,11 @@ describe('React module', () => { xtest('static callbacks fire even if their own value has not changed', () => { const inputCell = new InputCell(1); - const output = new ComputeCell( - [inputCell], - inputs => (inputs[0].value < 3 ? 111 : 222), + const output = new ComputeCell([inputCell], (inputs) => + inputs[0].value < 3 ? 111 : 222 ); - const callback = new CallbackCell(() => "cell changed"); + const callback = new CallbackCell(() => 'cell changed'); output.addCallback(callback); inputCell.setValue(2); @@ -114,18 +108,22 @@ describe('React module', () => { inputCell.setValue(4); inputCell.setValue(2); inputCell.setValue(4); - expect(callback.values).toEqual(["cell changed","cell changed","cell changed"]); + expect(callback.values).toEqual([ + 'cell changed', + 'cell changed', + 'cell changed', + ]); }); xtest('callbacks can be added and removed', () => { const inputCell = new InputCell(1); const output = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); - const callback1 = new CallbackCell(cell => cell.value); - const callback2 = new CallbackCell(cell => cell.value); + const callback1 = new CallbackCell((cell) => cell.value); + const callback2 = new CallbackCell((cell) => cell.value); output.addCallback(callback1); output.addCallback(callback2); @@ -134,7 +132,7 @@ describe('React module', () => { output.removeCallback(callback1); - const callback3 = new CallbackCell(cell => cell.value); + const callback3 = new CallbackCell((cell) => cell.value); output.addCallback(callback3); inputCell.setValue(41); @@ -144,15 +142,15 @@ describe('React module', () => { expect(callback3.values).toEqual([42]); }); - xtest('removing a callback multiple times doesn\'t interfere with other callbacks', () => { + xtest("removing a callback multiple times doesn't interfere with other callbacks", () => { const inputCell = new InputCell(1); const output = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); - const callback1 = new CallbackCell(cell => cell.value); - const callback2 = new CallbackCell(cell => cell.value); + const callback1 = new CallbackCell((cell) => cell.value); + const callback2 = new CallbackCell((cell) => cell.value); output.addCallback(callback1); output.addCallback(callback2); @@ -171,25 +169,25 @@ describe('React module', () => { const inputCell = new InputCell(1); const plusOne = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); const minusOne1 = new ComputeCell( [inputCell], - inputs => inputs[0].value - 1, + (inputs) => inputs[0].value - 1 ); const minusOne2 = new ComputeCell( [minusOne1], - inputs => inputs[0].value - 1, + (inputs) => inputs[0].value - 1 ); const output = new ComputeCell( [plusOne, minusOne2], - inputs => inputs[0].value * inputs[1].value, + (inputs) => inputs[0].value * inputs[1].value ); - const callback1 = new CallbackCell(cell => cell.value); + const callback1 = new CallbackCell((cell) => cell.value); output.addCallback(callback1); inputCell.setValue(4); @@ -197,25 +195,24 @@ describe('React module', () => { expect(callback1.values).toEqual([10]); }); - xtest('callbacks should not be called if dependencies change but output value doesn\'t change', () => { + xtest("callbacks should not be called if dependencies change but output value doesn't change", () => { const inputCell = new InputCell(1); const plusOne = new ComputeCell( [inputCell], - inputs => inputs[0].value + 1, + (inputs) => inputs[0].value + 1 ); const minusOne = new ComputeCell( [inputCell], - inputs => inputs[0].value - 1, + (inputs) => inputs[0].value - 1 ); const alwaysTwo = new ComputeCell( [plusOne, minusOne], - inputs => inputs[0].value - inputs[1].value, + (inputs) => inputs[0].value - inputs[1].value ); - - const callback = new CallbackCell(cell => cell.value); + const callback = new CallbackCell((cell) => cell.value); alwaysTwo.addCallback(callback); inputCell.setValue(2); diff --git a/exercises/rectangles/babel.config.js b/exercises/rectangles/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/rectangles/babel.config.js +++ b/exercises/rectangles/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/rectangles/example.js b/exercises/rectangles/example.js index c7a2589e8e..2d2c20f373 100644 --- a/exercises/rectangles/example.js +++ b/exercises/rectangles/example.js @@ -13,14 +13,26 @@ export class Rectangles { for (let j = y + 1; j < rows; j += 1) { for (let i = x + 1; i < cols; i += 1) { // Check if all corners are valid - if (diagram[j].charAt(i) === '+' && diagram[y].charAt(i) === '+' && diagram[j].charAt(x) === '+') { + if ( + diagram[j].charAt(i) === '+' && + diagram[y].charAt(i) === '+' && + diagram[j].charAt(x) === '+' + ) { let validRectangle = true; // Check if all sides are valid - for (let s = x + 1; s < i; s += 1) if (!'+-'.includes(diagram[y].charAt(s))) validRectangle = false; - for (let s = x + 1; s < i; s += 1) if (!'+-'.includes(diagram[j].charAt(s))) validRectangle = false; - for (let t = y + 1; t < j; t += 1) if (!'+|'.includes(diagram[t].charAt(x))) validRectangle = false; - for (let t = y + 1; t < j; t += 1) if (!'+|'.includes(diagram[t].charAt(i))) validRectangle = false; + for (let s = x + 1; s < i; s += 1) + if (!'+-'.includes(diagram[y].charAt(s))) + validRectangle = false; + for (let s = x + 1; s < i; s += 1) + if (!'+-'.includes(diagram[j].charAt(s))) + validRectangle = false; + for (let t = y + 1; t < j; t += 1) + if (!'+|'.includes(diagram[t].charAt(x))) + validRectangle = false; + for (let t = y + 1; t < j; t += 1) + if (!'+|'.includes(diagram[t].charAt(i))) + validRectangle = false; if (validRectangle) rectangles += 1; } diff --git a/exercises/rectangles/rectangles.js b/exercises/rectangles/rectangles.js index efeb1ab988..44f7e3642c 100644 --- a/exercises/rectangles/rectangles.js +++ b/exercises/rectangles/rectangles.js @@ -5,6 +5,6 @@ export class Rectangles { static count() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/rectangles/rectangles.spec.js b/exercises/rectangles/rectangles.spec.js index 0b21eaa9e3..60da7a614c 100644 --- a/exercises/rectangles/rectangles.spec.js +++ b/exercises/rectangles/rectangles.spec.js @@ -24,11 +24,7 @@ describe('Rectangles', () => { xtest('one rectangle', () => { const expected = 1; - const actual = Rectangles.count([ - '+-+', - '| |', - '+-+', - ]); + const actual = Rectangles.count(['+-+', '| |', '+-+']); expect(actual).toEqual(expected); }); @@ -61,31 +57,21 @@ describe('Rectangles', () => { xtest('rectangle of height 1 is counted', () => { const expected = 1; - const actual = Rectangles.count([ - '+--+', - '+--+', - ]); + const actual = Rectangles.count(['+--+', '+--+']); expect(actual).toEqual(expected); }); xtest('rectangle of width 1 is counted', () => { const expected = 1; - const actual = Rectangles.count([ - '++', - '||', - '++', - ]); + const actual = Rectangles.count(['++', '||', '++']); expect(actual).toEqual(expected); }); xtest('1x1 square is counted', () => { const expected = 1; - const actual = Rectangles.count([ - '++', - '++', - ]); + const actual = Rectangles.count(['++', '++']); expect(actual).toEqual(expected); }); diff --git a/exercises/resistor-color-duo/README.md b/exercises/resistor-color-duo/README.md index ed18f8ade5..1304d21bf0 100644 --- a/exercises/resistor-color-duo/README.md +++ b/exercises/resistor-color-duo/README.md @@ -1,16 +1,32 @@ # Resistor Color Duo -If you want to build something using a Raspberry Pi, you'll probably use _resistors_. For this exercise, you need to know two things about them: +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +For this exercise, you need to know two things about them: * Each resistor has a resistance value. * Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. -To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. Each band has a position and a numeric value. For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +Each band has a position and a numeric value. -In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. The program will take color names as input and output a two digit number, even if the input is more than two colors! +The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. +For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. -The colors are mapped to the numbers from 0 to 9 in the sequence: -Black - Brown - Red - Orange - Yellow - Green - Blue - Violet - Grey - White +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. +The program will take color names as input and output a two digit number, even if the input is more than two colors! + +The band colors are encoded as follows: + +- Black: 0 +- Brown: 1 +- Red: 2 +- Orange: 3 +- Yellow: 4 +- Green: 5 +- Blue: 6 +- Violet: 7 +- Grey: 8 +- White: 9 From the example above: brown-green should return 15 diff --git a/exercises/resistor-color-duo/babel.config.js b/exercises/resistor-color-duo/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/resistor-color-duo/babel.config.js +++ b/exercises/resistor-color-duo/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/resistor-color-duo/example.js b/exercises/resistor-color-duo/example.js index 8959d2f881..6703ec1808 100644 --- a/exercises/resistor-color-duo/example.js +++ b/exercises/resistor-color-duo/example.js @@ -1,10 +1,19 @@ // resistor-color solution START const COLORS = [ - 'black', 'brown', 'red', 'orange', 'yellow', 'green', - 'blue', 'violet', 'grey', 'white', + 'black', + 'brown', + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'violet', + 'grey', + 'white', ]; -const colorCode = color => COLORS.indexOf(color) +const colorCode = (color) => COLORS.indexOf(color); // resistor-color solution END -export const decodedValue = ([tens, ones]) => colorCode(tens) * 10 + colorCode(ones); +export const decodedValue = ([tens, ones]) => + colorCode(tens) * 10 + colorCode(ones); diff --git a/exercises/resistor-color-duo/resistor-color-duo.js b/exercises/resistor-color-duo/resistor-color-duo.js index 9900ad8558..b131f9251f 100644 --- a/exercises/resistor-color-duo/resistor-color-duo.js +++ b/exercises/resistor-color-duo/resistor-color-duo.js @@ -4,5 +4,5 @@ // export const decodedValue = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/resistor-color-duo/resistor-color-duo.spec.js b/exercises/resistor-color-duo/resistor-color-duo.spec.js index 10d599dfe9..220bbd3e91 100644 --- a/exercises/resistor-color-duo/resistor-color-duo.spec.js +++ b/exercises/resistor-color-duo/resistor-color-duo.spec.js @@ -19,5 +19,5 @@ describe('Resistor Colors', () => { xtest('Ignore additional colors', () => { expect(decodedValue(['green', 'brown', 'orange'])).toEqual(51); - }) + }); }); diff --git a/exercises/resistor-color-trio/README.md b/exercises/resistor-color-trio/README.md index 984c58611d..b84da82874 100644 --- a/exercises/resistor-color-trio/README.md +++ b/exercises/resistor-color-trio/README.md @@ -4,12 +4,21 @@ If you want to build something using a Raspberry Pi, you'll probably use _resist - Each resistor has a resistance value. - Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. - To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. Each band has a position and a numeric value. For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. + To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. - Each band acts as a digit of a number. For example, if they printed a brown band (value 1) followed by a green band (value 5), it would translate to the number 15. In this exercise, you are going to create a helpful program so that you don't have to remember the values of the bands. The program will take 3 colors as input, and outputs the correct value, in ohms. - The colors are mapped to the numbers from 0 to 9 in the sequence: - -Black - Brown - Red - Orange - Yellow - Green - Blue - Violet - Grey - White + The color bands are encoded as follows: + +* Black: 0 +* Brown: 1 +* Red: 2 +* Orange: 3 +* Yellow: 4 +* Green: 5 +* Blue: 6 +* Violet: 7 +* Grey: 8 +* White: 9 In `resistor-color duo` you decoded the first two colors. For instance: orange-orange got the main value `33`. The third color stands for how many zeros need to be added to the main value. The main value plus the zeros gives us a value in ohms. diff --git a/exercises/resistor-color-trio/babel.config.js b/exercises/resistor-color-trio/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/resistor-color-trio/babel.config.js +++ b/exercises/resistor-color-trio/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/resistor-color-trio/example.js b/exercises/resistor-color-trio/example.js index 1d882978ac..b421b68d4a 100644 --- a/exercises/resistor-color-trio/example.js +++ b/exercises/resistor-color-trio/example.js @@ -1,62 +1,72 @@ const COLORS = [ - 'black', 'brown', 'red', 'orange', 'yellow', 'green', - 'blue', 'violet', 'grey', 'white', -] + 'black', + 'brown', + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'violet', + 'grey', + 'white', +]; -const ONE_KILOOHM = 1000 +const ONE_KILOOHM = 1000; class ArgumentError extends Error {} export class ResistorColorTrio { constructor([tens, ones, zeros]) { - this.tens = tens - this.ones = ones - this.zeros = zeros + this.tens = tens; + this.ones = ones; + this.zeros = zeros; } get value() { if (!this.isValid) { - throw new ArgumentError('invalid color') + throw new ArgumentError('invalid color'); } - return this.significants() * this.multiplier() + return this.significants() * this.multiplier(); } get label() { - return `Resistor value: ${this}` + return `Resistor value: ${this}`; } get isValid() { - return COLORS.indexOf(this.tens) > -1 - && COLORS.indexOf(this.ones) > -1 - && COLORS.indexOf(this.zeros) > -1 + return ( + COLORS.indexOf(this.tens) > -1 && + COLORS.indexOf(this.ones) > -1 && + COLORS.indexOf(this.zeros) > -1 + ); } toString() { - const value = this.value + const value = this.value; return value < ONE_KILOOHM ? `${value} ohms` - : `${Math.floor(value / ONE_KILOOHM)} kiloohms` + : `${Math.floor(value / ONE_KILOOHM)} kiloohms`; } /** * @private */ significants() { - return this.colorCode(this.tens) * 10 + this.colorCode(this.ones) + return this.colorCode(this.tens) * 10 + this.colorCode(this.ones); } /** * @private */ multiplier() { - return Math.pow(10, this.colorCode(this.zeros)) + return Math.pow(10, this.colorCode(this.zeros)); } /** * @private */ colorCode(color) { - return COLORS.indexOf(color) + return COLORS.indexOf(color); } } diff --git a/exercises/resistor-color-trio/resistor-color-trio.js b/exercises/resistor-color-trio/resistor-color-trio.js index 432369df25..087d1551fe 100644 --- a/exercises/resistor-color-trio/resistor-color-trio.js +++ b/exercises/resistor-color-trio/resistor-color-trio.js @@ -5,10 +5,10 @@ export class ResistorColorTrio { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } label() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/resistor-color-trio/resistor-color-trio.spec.js b/exercises/resistor-color-trio/resistor-color-trio.spec.js index 0b9f641e30..931abdabf9 100644 --- a/exercises/resistor-color-trio/resistor-color-trio.spec.js +++ b/exercises/resistor-color-trio/resistor-color-trio.spec.js @@ -1,38 +1,44 @@ import { ResistorColorTrio } from './resistor-color-trio.js'; function makeLabel({ value, unit }) { - return `Resistor value: ${value} ${unit}` + return `Resistor value: ${value} ${unit}`; } describe('Resistor Color Trio', () => { test('Orange and orange and black', () => { - expect(new ResistorColorTrio(["orange", "orange", "black"]).label) - .toEqual(makeLabel({ value: 33, unit: "ohms" })); + expect(new ResistorColorTrio(['orange', 'orange', 'black']).label).toEqual( + makeLabel({ value: 33, unit: 'ohms' }) + ); }); xtest('Blue and grey and brown', () => { - expect(new ResistorColorTrio(["blue", "grey", "brown"]).label) - .toEqual(makeLabel({ value: 680, unit: "ohms" })); + expect(new ResistorColorTrio(['blue', 'grey', 'brown']).label).toEqual( + makeLabel({ value: 680, unit: 'ohms' }) + ); }); xtest('Red and black and red', () => { - expect(new ResistorColorTrio(["red", "black", "red"]).label) - .toEqual(makeLabel({ value: 2, unit: "kiloohms" })); + expect(new ResistorColorTrio(['red', 'black', 'red']).label).toEqual( + makeLabel({ value: 2, unit: 'kiloohms' }) + ); }); xtest('Green and brown and orange', () => { - expect(new ResistorColorTrio(["green", "brown", "orange"]).label) - .toEqual(makeLabel({ value: 51, unit: "kiloohms" })); + expect(new ResistorColorTrio(['green', 'brown', 'orange']).label).toEqual( + makeLabel({ value: 51, unit: 'kiloohms' }) + ); }); xtest('Yellow and violet and yellow', () => { - expect(new ResistorColorTrio(["yellow", "violet", "yellow"]).label) - .toEqual(makeLabel({ value: 470, unit: "kiloohms" })); + expect(new ResistorColorTrio(['yellow', 'violet', 'yellow']).label).toEqual( + makeLabel({ value: 470, unit: 'kiloohms' }) + ); }); // optional: error xtest('Invalid color', () => { - expect(() => new ResistorColorTrio(["yellow", "purple", "black"]).label) - .toThrowError(/invalid color/); + expect( + () => new ResistorColorTrio(['yellow', 'purple', 'black']).label + ).toThrowError(/invalid color/); }); }); diff --git a/exercises/resistor-color/.meta/hints.md b/exercises/resistor-color/.meta/hints.md index ae3247e20c..de53572076 100644 --- a/exercises/resistor-color/.meta/hints.md +++ b/exercises/resistor-color/.meta/hints.md @@ -1 +1 @@ -Although the color names are capitalised in the description, the function colorCode will always be called with the lowercase equivalent, e.g brown instead of Brown \ No newline at end of file +Although the color names are capitalised in the description, the function colorCode will always be called with the lowercase equivalent, e.g brown instead of Brown diff --git a/exercises/resistor-color/README.md b/exercises/resistor-color/README.md index 456f8a0e46..82e352cf13 100644 --- a/exercises/resistor-color/README.md +++ b/exercises/resistor-color/README.md @@ -1,17 +1,17 @@ # Resistor Color -If you want to build something using a Raspberry Pi, you'll probably use _resistors_. +If you want to build something using a Raspberry Pi, you'll probably use _resistors_. For this exercise, you need to know two things about them: * Each resistor has a resistance value. * Resistors are small - so small in fact that if you printed the resistance value on them, it would be hard to read. -To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. +To get around this problem, manufacturers print color-coded bands onto the resistors to denote their resistance values. Each band has a position and a numeric value. The first 2 bands of a resistor have a simple encoding scheme: each color maps to a single number. -In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. +In this exercise you are going to create a helpful program so that you don't have to remember the values of the bands. These colors are encoded as follows: @@ -36,6 +36,7 @@ More information on the color encoding of resistors can be found in the [Electro Although the color names are capitalised in the description, the function colorCode will always be called with the lowercase equivalent, e.g brown instead of Brown + ## Setup Go through the setup instructions for Javascript to install the necessary diff --git a/exercises/resistor-color/babel.config.js b/exercises/resistor-color/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/resistor-color/babel.config.js +++ b/exercises/resistor-color/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/resistor-color/example.js b/exercises/resistor-color/example.js index e578ea9024..56d91e282d 100644 --- a/exercises/resistor-color/example.js +++ b/exercises/resistor-color/example.js @@ -1,6 +1,14 @@ export const COLORS = [ - 'black', 'brown', 'red', 'orange', 'yellow', 'green', - 'blue', 'violet', 'grey', 'white', + 'black', + 'brown', + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'violet', + 'grey', + 'white', ]; -export const colorCode = color => COLORS.indexOf(color) +export const colorCode = (color) => COLORS.indexOf(color); diff --git a/exercises/resistor-color/resistor-color.js b/exercises/resistor-color/resistor-color.js index acab74d0b8..867e9112d8 100644 --- a/exercises/resistor-color/resistor-color.js +++ b/exercises/resistor-color/resistor-color.js @@ -4,7 +4,7 @@ // export const colorCode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const COLORS = undefined; diff --git a/exercises/resistor-color/resistor-color.spec.js b/exercises/resistor-color/resistor-color.spec.js index 8879b3d1c4..1d3c85328a 100644 --- a/exercises/resistor-color/resistor-color.spec.js +++ b/exercises/resistor-color/resistor-color.spec.js @@ -1,21 +1,32 @@ -import { colorCode, COLORS } from './resistor-color' +import { colorCode, COLORS } from './resistor-color'; describe('ResistorColor', () => { describe('Color codes', () => { test('Black', () => { - expect(colorCode("black")).toEqual(0) - }) + expect(colorCode('black')).toEqual(0); + }); xtest('White', () => { - expect(colorCode("white")).toEqual(9) - }) + expect(colorCode('white')).toEqual(9); + }); xtest('Orange', () => { - expect(colorCode("orange")).toEqual(3) - }) - }) + expect(colorCode('orange')).toEqual(3); + }); + }); xtest('Colors', () => { - expect(COLORS).toEqual(["black","brown","red","orange","yellow","green","blue","violet","grey","white"]) - }) -}) + expect(COLORS).toEqual([ + 'black', + 'brown', + 'red', + 'orange', + 'yellow', + 'green', + 'blue', + 'violet', + 'grey', + 'white', + ]); + }); +}); diff --git a/exercises/reverse-string/babel.config.js b/exercises/reverse-string/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/reverse-string/babel.config.js +++ b/exercises/reverse-string/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/reverse-string/reverse-string.js b/exercises/reverse-string/reverse-string.js index 0d4bbed25d..c5060d2f1e 100644 --- a/exercises/reverse-string/reverse-string.js +++ b/exercises/reverse-string/reverse-string.js @@ -4,5 +4,5 @@ // export const reverseString = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/rna-transcription/babel.config.js b/exercises/rna-transcription/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/rna-transcription/babel.config.js +++ b/exercises/rna-transcription/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/rna-transcription/example.js b/exercises/rna-transcription/example.js index 8d2aa7b01a..3ab033d687 100644 --- a/exercises/rna-transcription/example.js +++ b/exercises/rna-transcription/example.js @@ -5,4 +5,5 @@ const DNA_TO_RNA = { A: 'U', }; -export const toRna = (dna) => dna.replace(/./g, nucleotide => DNA_TO_RNA[nucleotide]); +export const toRna = (dna) => + dna.replace(/./g, (nucleotide) => DNA_TO_RNA[nucleotide]); diff --git a/exercises/rna-transcription/rna-transcription.js b/exercises/rna-transcription/rna-transcription.js index 9cf4cf49be..9a8343ed4a 100644 --- a/exercises/rna-transcription/rna-transcription.js +++ b/exercises/rna-transcription/rna-transcription.js @@ -4,5 +4,5 @@ // export const toRna = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/rna-transcription/rna-transcription.spec.js b/exercises/rna-transcription/rna-transcription.spec.js index 8709609b83..97b71faf9b 100644 --- a/exercises/rna-transcription/rna-transcription.spec.js +++ b/exercises/rna-transcription/rna-transcription.spec.js @@ -1,4 +1,4 @@ -import { toRna } from './rna-transcription' +import { toRna } from './rna-transcription'; describe('Transcription', () => { test('empty rna sequence', () => { @@ -24,4 +24,4 @@ describe('Transcription', () => { xtest('transcribes all dna nucleotides to their rna complements', () => { expect(toRna('ACGTGGTCTTAA')).toEqual('UGCACCAGAAUU'); }); -}) +}); diff --git a/exercises/robot-name/README.md b/exercises/robot-name/README.md index 018e13f45a..3f8c95700c 100644 --- a/exercises/robot-name/README.md +++ b/exercises/robot-name/README.md @@ -2,17 +2,17 @@ Manage robot factory settings. -When robots come off the factory floor, they have no name. +When a robot comes off the factory floor, it has no name. -The first time you boot them up, a random name is generated in the format +The first time you turn on a robot, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811. Every once in a while we need to reset a robot to its factory settings, -which means that their name gets wiped. The next time you ask, it will +which means that its name gets wiped. The next time you ask, that robot will respond with a new random name. The names must be random: they should not follow a predictable sequence. -Random names means a risk of collisions. Your solution must ensure that +Using random names means a risk of collisions. Your solution must ensure that every existing robot has a unique name. ## Setup diff --git a/exercises/robot-name/babel.config.js b/exercises/robot-name/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/robot-name/babel.config.js +++ b/exercises/robot-name/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/robot-name/example.js b/exercises/robot-name/example.js index c69d2e8aec..22cd5e0d52 100644 --- a/exercises/robot-name/example.js +++ b/exercises/robot-name/example.js @@ -40,7 +40,9 @@ function shuffleNames() { function generateName() { shuffledPointer += 1; if (shuffledPointer > shuffled.length) { - throw new Error('Can not generate another name because all the names have been used.'); + throw new Error( + 'Can not generate another name because all the names have been used.' + ); } return shuffled[shuffledPointer]; } @@ -53,11 +55,15 @@ export class Robot { this._name = generateName(); } - get name() { return this._name; } + get name() { + return this._name; + } reset() { this._name = generateName(); } } -Robot.releaseNames = () => { shuffledPointer = -1; }; +Robot.releaseNames = () => { + shuffledPointer = -1; +}; diff --git a/exercises/robot-name/robot-name.js b/exercises/robot-name/robot-name.js index facbe1b248..0c2fbbcf88 100644 --- a/exercises/robot-name/robot-name.js +++ b/exercises/robot-name/robot-name.js @@ -1,6 +1,6 @@ // This is only a SKELETON file for the 'Robot Name' exercise. It's been // provided as a convenience to get your started writing code faster. -export class Robot { } +export class Robot {} -Robot.releaseNames = () => { }; +Robot.releaseNames = () => {}; diff --git a/exercises/robot-name/robot-name.spec.js b/exercises/robot-name/robot-name.spec.js index 7cc7238775..c4b7ff9e61 100644 --- a/exercises/robot-name/robot-name.spec.js +++ b/exercises/robot-name/robot-name.spec.js @@ -7,19 +7,21 @@ const areSequential = (name1, name2) => { const num2 = +name2.substr(2, 3); const numDiff = num2 - num1; - const alphaDiff = (alpha2.charCodeAt(0) - alpha1.charCodeAt(0)) * 26 - + (alpha2.charCodeAt(1) - alpha1.charCodeAt(1)); + const alphaDiff = + (alpha2.charCodeAt(0) - alpha1.charCodeAt(0)) * 26 + + (alpha2.charCodeAt(1) - alpha1.charCodeAt(1)); const totalDiff = alphaDiff * 1000 + numDiff; return Math.abs(totalDiff) <= 1; }; -const TOTAL_NUMBER_OF_NAMES = 26 // A-Z - * 26 // A-Z - * 10 // 0-9 - * 10 // 0-9 - * 10; // 0-9 +const TOTAL_NUMBER_OF_NAMES = + 26 * // A-Z + 26 * // A-Z + 10 * // 0-9 + 10 * // 0-9 + 10; // 0-9 describe('Robot', () => { let robot; @@ -68,15 +70,16 @@ describe('Robot', () => { }); xtest('internal name cannot be modified', () => { - const modifyInternal = () => { robot.name += 'a modification'; }; + const modifyInternal = () => { + robot.name += 'a modification'; + }; expect(modifyInternal).toThrow(); }); - xtest('new names should not be sequential', () => { const name1 = robot.name; - const name2 = (new Robot()).name; - const name3 = (new Robot()).name; + const name2 = new Robot().name; + const name3 = new Robot().name; expect(areSequential(name1, name1)).toBe(true); expect(areSequential(name1, name2)).toBe(false); expect(areSequential(name2, name3)).toBe(false); diff --git a/exercises/robot-simulator/babel.config.js b/exercises/robot-simulator/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/robot-simulator/babel.config.js +++ b/exercises/robot-simulator/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/robot-simulator/example.js b/exercises/robot-simulator/example.js index 6d31059ede..92032ee110 100644 --- a/exercises/robot-simulator/example.js +++ b/exercises/robot-simulator/example.js @@ -71,7 +71,9 @@ export class Robot { case 'A': return 'advance'; default: - throw new InvalidInputError(`${character} is not a valid instruction character.`); + throw new InvalidInputError( + `${character} is not a valid instruction character.` + ); } }); } diff --git a/exercises/robot-simulator/robot-simulator.js b/exercises/robot-simulator/robot-simulator.js index 7dfcbfa743..8b8ccd9e26 100644 --- a/exercises/robot-simulator/robot-simulator.js +++ b/exercises/robot-simulator/robot-simulator.js @@ -5,48 +5,48 @@ export class InvalidInputError extends Error { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } export class Robot { orient() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get bearing() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get coordinates() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } turnRight() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } turnLeft() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } at() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } advance() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } instructions() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } place() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } evaluate() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/robot-simulator/robot-simulator.spec.js b/exercises/robot-simulator/robot-simulator.spec.js index 18418c5d8b..8717e97518 100644 --- a/exercises/robot-simulator/robot-simulator.spec.js +++ b/exercises/robot-simulator/robot-simulator.spec.js @@ -116,8 +116,12 @@ describe('Robot', () => { }); xtest('series of instructions', () => { - expect(Robot.instructions('RAAL')) - .toEqual(['turnRight', 'advance', 'advance', 'turnLeft']); + expect(Robot.instructions('RAAL')).toEqual([ + 'turnRight', + 'advance', + 'advance', + 'turnLeft', + ]); }); xtest('instruct robot', () => { diff --git a/exercises/roman-numerals/babel.config.js b/exercises/roman-numerals/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/roman-numerals/babel.config.js +++ b/exercises/roman-numerals/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/roman-numerals/roman-numerals.js b/exercises/roman-numerals/roman-numerals.js index 2de50aeff5..de27903c7e 100644 --- a/exercises/roman-numerals/roman-numerals.js +++ b/exercises/roman-numerals/roman-numerals.js @@ -4,5 +4,5 @@ // export const toRoman = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/rotational-cipher/babel.config.js b/exercises/rotational-cipher/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/rotational-cipher/babel.config.js +++ b/exercises/rotational-cipher/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/rotational-cipher/example.js b/exercises/rotational-cipher/example.js index 50e8e8031b..95acbb783f 100644 --- a/exercises/rotational-cipher/example.js +++ b/exercises/rotational-cipher/example.js @@ -1,14 +1,17 @@ export class RotationalCipher { static rotate(text, shift) { - return [...text].map((c) => { - const isUpper = c.match(/[A-Z]/); - const isAlpha = c.match(/[a-z]/i); - const charShift = (isUpper ? 'A' : 'a').charCodeAt(0); + return [...text] + .map((c) => { + const isUpper = c.match(/[A-Z]/); + const isAlpha = c.match(/[a-z]/i); + const charShift = (isUpper ? 'A' : 'a').charCodeAt(0); - return isAlpha - ? String.fromCharCode(((( - c.charCodeAt(0) - charShift) + shift) % 26) + charShift) - : c; - }).join(''); + return isAlpha + ? String.fromCharCode( + ((c.charCodeAt(0) - charShift + shift) % 26) + charShift + ) + : c; + }) + .join(''); } } diff --git a/exercises/rotational-cipher/rotational-cipher.js b/exercises/rotational-cipher/rotational-cipher.js index 7990941506..4ef3abc604 100644 --- a/exercises/rotational-cipher/rotational-cipher.js +++ b/exercises/rotational-cipher/rotational-cipher.js @@ -5,6 +5,6 @@ export class RotationalCipher { static rotate() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/rotational-cipher/rotational-cipher.spec.js b/exercises/rotational-cipher/rotational-cipher.spec.js index 9b19a505ac..1fb8c8698b 100644 --- a/exercises/rotational-cipher/rotational-cipher.spec.js +++ b/exercises/rotational-cipher/rotational-cipher.spec.js @@ -58,15 +58,18 @@ describe('Rotational cipher', () => { }); xtest('rotate punctuation', () => { - const expected = 'Gzo\'n zvo, Bmviyhv!'; - const actual = RotationalCipher.rotate('Let\'s eat, Grandma!', 21); + const expected = "Gzo'n zvo, Bmviyhv!"; + const actual = RotationalCipher.rotate("Let's eat, Grandma!", 21); expect(actual).toEqual(expected); }); xtest('rotate all letters', () => { const expected = 'Gur dhvpx oebja sbk whzcf bire gur ynml qbt.'; - const actual = RotationalCipher.rotate('The quick brown fox jumps over the lazy dog.', 13); + const actual = RotationalCipher.rotate( + 'The quick brown fox jumps over the lazy dog.', + 13 + ); expect(actual).toEqual(expected); }); diff --git a/exercises/run-length-encoding/babel.config.js b/exercises/run-length-encoding/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/run-length-encoding/babel.config.js +++ b/exercises/run-length-encoding/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/run-length-encoding/example.js b/exercises/run-length-encoding/example.js index f77eb4c2c8..b46566b70d 100644 --- a/exercises/run-length-encoding/example.js +++ b/exercises/run-length-encoding/example.js @@ -1,13 +1,13 @@ - export const encode = (plainText) => { const consecutiveChars = /([\w\s])\1*/g; - return plainText.replace(consecutiveChars, - match => (match.length > 1 ? match.length + match[0] : match[0])); + return plainText.replace(consecutiveChars, (match) => + match.length > 1 ? match.length + match[0] : match[0] + ); }; - export const decode = (encodedText) => { const countAndChar = /(\d+)(\w|\s)/g; - return encodedText.replace(countAndChar, - (match, repeats, char) => new Array(+repeats + 1).join(char)); + return encodedText.replace(countAndChar, (match, repeats, char) => + new Array(+repeats + 1).join(char) + ); }; diff --git a/exercises/run-length-encoding/run-length-encoding.js b/exercises/run-length-encoding/run-length-encoding.js index 74db28f0e0..713839cf10 100644 --- a/exercises/run-length-encoding/run-length-encoding.js +++ b/exercises/run-length-encoding/run-length-encoding.js @@ -4,9 +4,9 @@ // export const encode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const decode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/run-length-encoding/run-length-encoding.spec.js b/exercises/run-length-encoding/run-length-encoding.spec.js index 51980e8663..6d7fdf692b 100644 --- a/exercises/run-length-encoding/run-length-encoding.spec.js +++ b/exercises/run-length-encoding/run-length-encoding.spec.js @@ -14,7 +14,9 @@ describe('run-length encode a string', () => { }); xtest('encode string with single characters mixed with repeated characters', () => { - expect(encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')).toEqual('12WB12W3B24WB'); + expect( + encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB') + ).toEqual('12WB12W3B24WB'); }); xtest('encode string with multiple whitespaces', () => { @@ -40,7 +42,9 @@ describe('run-length decode a string', () => { }); xtest('decode string with single characters mixed with repeated characters', () => { - expect(decode('12WB12W3B24WB')).toEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'); + expect(decode('12WB12W3B24WB')).toEqual( + 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB' + ); }); xtest('decode string with multiple whitespaces', () => { diff --git a/exercises/saddle-points/babel.config.js b/exercises/saddle-points/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/saddle-points/babel.config.js +++ b/exercises/saddle-points/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/saddle-points/example.js b/exercises/saddle-points/example.js index b85a246565..13e89102dc 100644 --- a/exercises/saddle-points/example.js +++ b/exercises/saddle-points/example.js @@ -1,4 +1,4 @@ -export const saddlePoints = matrix => { +export const saddlePoints = (matrix) => { const maximumRowValues = []; const minimumColumnValues = []; diff --git a/exercises/saddle-points/saddle-points.js b/exercises/saddle-points/saddle-points.js index d7772c19e8..e4b6b85341 100644 --- a/exercises/saddle-points/saddle-points.js +++ b/exercises/saddle-points/saddle-points.js @@ -4,5 +4,5 @@ // export const saddlePoints = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/saddle-points/saddle-points.spec.js b/exercises/saddle-points/saddle-points.spec.js index a0ea5a510b..546147f890 100644 --- a/exercises/saddle-points/saddle-points.spec.js +++ b/exercises/saddle-points/saddle-points.spec.js @@ -1,97 +1,97 @@ -import { saddlePoints } from "./saddle-points"; +import { saddlePoints } from './saddle-points'; -describe("Saddle Points", () => { - test("Can identify single saddle point", () => { +describe('Saddle Points', () => { + test('Can identify single saddle point', () => { const expected = [{ row: 2, column: 1 }]; expect( saddlePoints([ [9, 8, 7], [5, 3, 2], - [6, 6, 7] + [6, 6, 7], ]) ).toEqual(expected); }); - xtest("Can identify that empty matrix has no saddle points", () => { + xtest('Can identify that empty matrix has no saddle points', () => { expect(saddlePoints([[]])).toEqual([]); }); - xtest("Can identify lack of saddle points when there are none", () => { + xtest('Can identify lack of saddle points when there are none', () => { expect( saddlePoints([ [1, 2, 3], [3, 1, 2], - [2, 3, 1] + [2, 3, 1], ]) ).toEqual([]); }); - xtest("Can identify multiple saddle points in a column", () => { + xtest('Can identify multiple saddle points in a column', () => { const expected = [ { row: 1, column: 2 }, { row: 2, column: 2 }, - { row: 3, column: 2 } + { row: 3, column: 2 }, ]; expect( saddlePoints([ [4, 5, 4], [3, 5, 5], - [1, 5, 4] + [1, 5, 4], ]) ).toEqual(expected); }); - xtest("Can identify multiple saddle points in a row", () => { + xtest('Can identify multiple saddle points in a row', () => { const expected = [ { row: 2, column: 1 }, { row: 2, column: 2 }, - { row: 2, column: 3 } + { row: 2, column: 3 }, ]; expect( saddlePoints([ [6, 7, 8], [5, 5, 5], - [7, 5, 6] + [7, 5, 6], ]) ).toEqual(expected); }); - xtest("Can identify saddle point in bottom right corner", () => { + xtest('Can identify saddle point in bottom right corner', () => { const expected = [{ row: 3, column: 3 }]; expect( saddlePoints([ [8, 7, 9], [6, 7, 6], - [3, 2, 5] + [3, 2, 5], ]) ).toEqual(expected); }); - xtest("Can identify saddle points in a non square matrix", () => { + xtest('Can identify saddle points in a non square matrix', () => { const expected = [ { row: 1, column: 1 }, - { row: 1, column: 3 } + { row: 1, column: 3 }, ]; expect( saddlePoints([ [3, 1, 3], - [3, 2, 4] + [3, 2, 4], ]) ).toEqual(expected); }); - xtest("Can identify that saddle points in a single column matrix are those with the minimum value", () => { + xtest('Can identify that saddle points in a single column matrix are those with the minimum value', () => { const expected = [ { row: 2, column: 1 }, - { row: 4, column: 1 } + { row: 4, column: 1 }, ]; expect(saddlePoints([[2], [1], [4], [1]])).toEqual(expected); }); - xtest("Can identify that saddle points in a single row matrix are those with the maximum value", () => { + xtest('Can identify that saddle points in a single row matrix are those with the maximum value', () => { const expected = [ { row: 1, column: 2 }, - { row: 1, column: 4 } + { row: 1, column: 4 }, ]; expect(saddlePoints([[2, 5, 3, 5]])).toEqual(expected); }); diff --git a/exercises/say/babel.config.js b/exercises/say/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/say/babel.config.js +++ b/exercises/say/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/say/example.js b/exercises/say/example.js index e5e68165d7..909ca1a781 100644 --- a/exercises/say/example.js +++ b/exercises/say/example.js @@ -72,8 +72,11 @@ export class Say { } threeDigit(n) { - return n < 100 ? this.twoDigit(n) - : `${this.smallNumbers[Math.floor(n / 100)]} hundred ${this.twoDigit(n % 100)}`; + return n < 100 + ? this.twoDigit(n) + : `${this.smallNumbers[Math.floor(n / 100)]} hundred ${this.twoDigit( + n % 100 + )}`; } sayDecade(n) { diff --git a/exercises/say/say.js b/exercises/say/say.js index 35e33cb3e1..f022aec87f 100644 --- a/exercises/say/say.js +++ b/exercises/say/say.js @@ -5,6 +5,6 @@ export class Say { inEnglish() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/say/say.spec.js b/exercises/say/say.spec.js index 94abca7c1b..6ceab47858 100644 --- a/exercises/say/say.spec.js +++ b/exercises/say/say.spec.js @@ -47,8 +47,9 @@ describe('say', () => { }); xtest('one million two thousand three hundred forty-five', () => { - expect(say.inEnglish(1002345)) - .toBe('one million two thousand three hundred forty-five'); + expect(say.inEnglish(1002345)).toBe( + 'one million two thousand three hundred forty-five' + ); }); xtest('one billion', () => { diff --git a/exercises/scale-generator/README.md b/exercises/scale-generator/README.md index d0916e9d34..90be9444bc 100644 --- a/exercises/scale-generator/README.md +++ b/exercises/scale-generator/README.md @@ -43,10 +43,10 @@ a "whole step" or "major second" (written as an upper-case "M"). The diatonic scales are built using only these two intervals between adjacent notes. -Non-diatonic scales can contain other intervals. An "augmented first" -interval, written "A", has two interceding notes (e.g., from A to C or -Db to E). There are also smaller and larger intervals, but they will not -figure into this exercise. +Non-diatonic scales can contain other intervals. An "augmented second" +interval, written "A", has two interceding notes (e.g., from A to C or Db to E) +or a "whole step" plus a "half step". There are also smaller and larger +intervals, but they will not figure into this exercise. ## Setup diff --git a/exercises/scale-generator/babel.config.js b/exercises/scale-generator/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/scale-generator/babel.config.js +++ b/exercises/scale-generator/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/scale-generator/example.js b/exercises/scale-generator/example.js index 202fd01c5a..ec7fe6c052 100644 --- a/exercises/scale-generator/example.js +++ b/exercises/scale-generator/example.js @@ -1,33 +1,76 @@ export class Scale { constructor(tonic) { - this.INTERVAL_STEPS = ['m', 'M', 'A'] - this.SHARPS_SCALE = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#'] - this.FLATS_SCALE = ['A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab'] - this.USE_FLATS = ['F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'd', 'g', 'c', 'f', 'bb', 'eb'] + this.INTERVAL_STEPS = ['m', 'M', 'A']; + this.SHARPS_SCALE = [ + 'A', + 'A#', + 'B', + 'C', + 'C#', + 'D', + 'D#', + 'E', + 'F', + 'F#', + 'G', + 'G#', + ]; + this.FLATS_SCALE = [ + 'A', + 'Bb', + 'B', + 'C', + 'Db', + 'D', + 'Eb', + 'E', + 'F', + 'Gb', + 'G', + 'Ab', + ]; + this.USE_FLATS = [ + 'F', + 'Bb', + 'Eb', + 'Ab', + 'Db', + 'Gb', + 'd', + 'g', + 'c', + 'f', + 'bb', + 'eb', + ]; this.tonic = tonic.slice(0, 1).toUpperCase() + tonic.slice(1); // note use of original tonic argument - this.chromaticScale = this.USE_FLATS.includes(tonic) ? this.FLATS_SCALE : this.SHARPS_SCALE + this.chromaticScale = this.USE_FLATS.includes(tonic) + ? this.FLATS_SCALE + : this.SHARPS_SCALE; } chromatic() { - return this.reorderChromaticScale() + return this.reorderChromaticScale(); } interval(intervals) { - const scale = this.reorderChromaticScale() - const result = [] - let currentIndex = 0 + const scale = this.reorderChromaticScale(); + const result = []; + let currentIndex = 0; for (const step of intervals) { - result.push(scale[currentIndex]) - currentIndex = currentIndex + (this.INTERVAL_STEPS.indexOf(step) + 1) + result.push(scale[currentIndex]); + currentIndex = currentIndex + (this.INTERVAL_STEPS.indexOf(step) + 1); } - return result + return result; } reorderChromaticScale() { - const tonicIndex = this.chromaticScale.indexOf(this.tonic) - return this.chromaticScale.slice(tonicIndex).concat(this.chromaticScale.slice(0, tonicIndex)) + const tonicIndex = this.chromaticScale.indexOf(this.tonic); + return this.chromaticScale + .slice(tonicIndex) + .concat(this.chromaticScale.slice(0, tonicIndex)); } } diff --git a/exercises/scale-generator/scale-generator.js b/exercises/scale-generator/scale-generator.js index c2306b3283..6f702b0165 100644 --- a/exercises/scale-generator/scale-generator.js +++ b/exercises/scale-generator/scale-generator.js @@ -5,14 +5,14 @@ export class Scale { constructor(tonic) { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } chromatic() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } interval(intervals) { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/scale-generator/scale-generator.spec.js b/exercises/scale-generator/scale-generator.spec.js index 9102907e0e..cdf0f0cfe1 100644 --- a/exercises/scale-generator/scale-generator.spec.js +++ b/exercises/scale-generator/scale-generator.spec.js @@ -1,92 +1,118 @@ -import { Scale } from './scale-generator' +import { Scale } from './scale-generator'; describe('ScaleGenerator', () => { describe('Chromatic scales', () => { test('Chromatic scale with sharps', () => { - const expected = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] - expect(new Scale('C').chromatic()).toEqual(expected) - }) + const expected = [ + 'C', + 'C#', + 'D', + 'D#', + 'E', + 'F', + 'F#', + 'G', + 'G#', + 'A', + 'A#', + 'B', + ]; + expect(new Scale('C').chromatic()).toEqual(expected); + }); xtest('Chromatic scale with flats', () => { - const expected = ['F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E'] - expect(new Scale('F').chromatic()).toEqual(expected) - }) - }) + const expected = [ + 'F', + 'Gb', + 'G', + 'Ab', + 'A', + 'Bb', + 'B', + 'C', + 'Db', + 'D', + 'Eb', + 'E', + ]; + expect(new Scale('F').chromatic()).toEqual(expected); + }); + }); describe('Scales with specified intervals', () => { xtest('Simple major scale', () => { - const expected = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] - expect(new Scale('C').interval('MMmMMMm')).toEqual(expected) - }) + const expected = ['C', 'D', 'E', 'F', 'G', 'A', 'B']; + expect(new Scale('C').interval('MMmMMMm')).toEqual(expected); + }); xtest('Major scale with sharps', () => { - const expected = ['G', 'A', 'B', 'C', 'D', 'E', 'F#'] - expect(new Scale('G').interval('MMmMMMm')).toEqual(expected) - }) + const expected = ['G', 'A', 'B', 'C', 'D', 'E', 'F#']; + expect(new Scale('G').interval('MMmMMMm')).toEqual(expected); + }); xtest('Major scale with flats', () => { - const expected = ['F', 'G', 'A', 'Bb', 'C', 'D', 'E'] - expect(new Scale('F').interval('MMmMMMm')).toEqual(expected) - }) + const expected = ['F', 'G', 'A', 'Bb', 'C', 'D', 'E']; + expect(new Scale('F').interval('MMmMMMm')).toEqual(expected); + }); xtest('Minor scale with sharps', () => { - const expected = ['F#', 'G#', 'A', 'B', 'C#', 'D', 'E'] - expect(new Scale('f#').interval('MmMMmMM')).toEqual(expected) - }) + const expected = ['F#', 'G#', 'A', 'B', 'C#', 'D', 'E']; + expect(new Scale('f#').interval('MmMMmMM')).toEqual(expected); + }); xtest('Minor scale with flats', () => { - const expected = ['Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab'] - expect(new Scale('bb').interval('MmMMmMM')).toEqual(expected) - }) + const expected = ['Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab']; + expect(new Scale('bb').interval('MmMMmMM')).toEqual(expected); + }); xtest('Dorian mode', () => { - const expected = ['D', 'E', 'F', 'G', 'A', 'B', 'C'] - expect(new Scale('d').interval('MmMMMmM')).toEqual(expected) - }) + const expected = ['D', 'E', 'F', 'G', 'A', 'B', 'C']; + expect(new Scale('d').interval('MmMMMmM')).toEqual(expected); + }); xtest('Mixolydian mode', () => { - const expected = ['Eb', 'F', 'G', 'Ab', 'Bb', 'C', 'Db'] - expect(new Scale('Eb').interval('MMmMMmM')).toEqual(expected) - }) + const expected = ['Eb', 'F', 'G', 'Ab', 'Bb', 'C', 'Db']; + expect(new Scale('Eb').interval('MMmMMmM')).toEqual(expected); + }); xtest('Lydian mode', () => { - const expected = ['A', 'B', 'C#', 'D#', 'E', 'F#', 'G#'] - expect(new Scale('a').interval('MMMmMMm')).toEqual(expected) - }) + const expected = ['A', 'B', 'C#', 'D#', 'E', 'F#', 'G#']; + expect(new Scale('a').interval('MMMmMMm')).toEqual(expected); + }); xtest('Phrygian mode', () => { - const expected = ['E', 'F', 'G', 'A', 'B', 'C', 'D'] - expect(new Scale('e').interval('mMMMmMM')).toEqual(expected) - }) + const expected = ['E', 'F', 'G', 'A', 'B', 'C', 'D']; + expect(new Scale('e').interval('mMMMmMM')).toEqual(expected); + }); xtest('Locrian mode', () => { - const expected = ['G', 'Ab', 'Bb', 'C', 'Db', 'Eb', 'F'] - expect(new Scale('g').interval('mMMmMMM')).toEqual(expected) - }) + const expected = ['G', 'Ab', 'Bb', 'C', 'Db', 'Eb', 'F']; + expect(new Scale('g').interval('mMMmMMM')).toEqual(expected); + }); xtest('Harmonic minor', () => { - const expected = ['D', 'E', 'F', 'G', 'A', 'Bb', 'Db'] - expect(new Scale('d').interval('MmMMmAm')).toEqual(expected) - }) + const expected = ['D', 'E', 'F', 'G', 'A', 'Bb', 'Db']; + expect(new Scale('d').interval('MmMMmAm')).toEqual(expected); + }); xtest('Octatonic', () => { - const expected = ['C', 'D', 'D#', 'F', 'F#', 'G#', 'A', 'B'] - expect(new Scale('C').interval('MmMmMmMm')).toEqual(expected) - }) + const expected = ['C', 'D', 'D#', 'F', 'F#', 'G#', 'A', 'B']; + expect(new Scale('C').interval('MmMmMmMm')).toEqual(expected); + }); xtest('Hexatonic', () => { - const expected = ['Db', 'Eb', 'F', 'G', 'A', 'B'] - expect(new Scale('Db').interval('MMMMMM')).toEqual(expected) - }) + const expected = ['Db', 'Eb', 'F', 'G', 'A', 'B']; + expect(new Scale('Db').interval('MMMMMM')).toEqual(expected); + }); xtest('Pentatonic', () => { - const expected = ['A', 'B', 'C#', 'E', 'F#'] - expect(new Scale('A').interval('MMAMA')).toEqual(expected) - }) + const expected = ['A', 'B', 'C#', 'E', 'F#']; + expect(new Scale('A').interval('MMAMA')).toEqual(expected); + }); xtest('Enigmatic', () => { - const expected = ['G', 'G#', 'B', 'C#', 'D#', 'F', 'F#'] - expect(new Scale('G').interval('mAMMMmm')).toEqual(expected) - }) - }) -}) + const expected = ['G', 'G#', 'B', 'C#', 'D#', 'F', 'F#']; + expect(new Scale('G').interval('mAMMMmm')).toEqual(expected); + }); + }); +}); diff --git a/exercises/scrabble-score/README.md b/exercises/scrabble-score/README.md index b1f2164cbc..192490dd89 100644 --- a/exercises/scrabble-score/README.md +++ b/exercises/scrabble-score/README.md @@ -1,6 +1,6 @@ # Scrabble Score -Given a word, compute the scrabble score for that word. +Given a word, compute the Scrabble score for that word. ## Letter Values diff --git a/exercises/scrabble-score/babel.config.js b/exercises/scrabble-score/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/scrabble-score/babel.config.js +++ b/exercises/scrabble-score/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/scrabble-score/example.js b/exercises/scrabble-score/example.js index 53b515dfb2..e578d5304b 100644 --- a/exercises/scrabble-score/example.js +++ b/exercises/scrabble-score/example.js @@ -27,7 +27,10 @@ const letterScores = { z: 10, }; -const letterScore = letter => letterScores[letter] || 0; +const letterScore = (letter) => letterScores[letter] || 0; -export const score = word => [...word.toLowerCase()] - .reduce((sum, currChar) => sum + letterScore(currChar), 0); +export const score = (word) => + [...word.toLowerCase()].reduce( + (sum, currChar) => sum + letterScore(currChar), + 0 + ); diff --git a/exercises/scrabble-score/scrabble-score.js b/exercises/scrabble-score/scrabble-score.js index fce6a59b77..c003fa5ab4 100644 --- a/exercises/scrabble-score/scrabble-score.js +++ b/exercises/scrabble-score/scrabble-score.js @@ -4,5 +4,5 @@ // export const score = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/secret-handshake/babel.config.js b/exercises/secret-handshake/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/secret-handshake/babel.config.js +++ b/exercises/secret-handshake/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/secret-handshake/example.js b/exercises/secret-handshake/example.js index a530d4e3c4..5065ebdde5 100644 --- a/exercises/secret-handshake/example.js +++ b/exercises/secret-handshake/example.js @@ -5,12 +5,11 @@ export const commands = (handshake) => { throw new Error('Handshake must be a number'); } - const shakeWith = handshakeCommands.filter((_, i) => ( - handshake & (Math.pow(2, i)) - )); + const shakeWith = handshakeCommands.filter( + (_, i) => handshake & Math.pow(2, i) + ); - if (handshake & (Math.pow(2, 4))) - shakeWith.reverse(); + if (handshake & Math.pow(2, 4)) shakeWith.reverse(); return shakeWith; }; diff --git a/exercises/secret-handshake/secret-handshake.js b/exercises/secret-handshake/secret-handshake.js index dea50dda0d..c6af522587 100644 --- a/exercises/secret-handshake/secret-handshake.js +++ b/exercises/secret-handshake/secret-handshake.js @@ -4,5 +4,5 @@ // export const commands = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/secret-handshake/secret-handshake.spec.js b/exercises/secret-handshake/secret-handshake.spec.js index 382a46c897..0b461adacd 100644 --- a/exercises/secret-handshake/secret-handshake.spec.js +++ b/exercises/secret-handshake/secret-handshake.spec.js @@ -39,7 +39,7 @@ describe('Secret Handshake', () => { 'wink', 'double blink', 'close your eyes', - 'jump' + 'jump', ]); }); @@ -48,7 +48,7 @@ describe('Secret Handshake', () => { 'jump', 'close your eyes', 'double blink', - 'wink' + 'wink', ]); }); diff --git a/exercises/series/babel.config.js b/exercises/series/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/series/babel.config.js +++ b/exercises/series/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/series/example.js b/exercises/series/example.js index c019699dc3..c42f63352f 100644 --- a/exercises/series/example.js +++ b/exercises/series/example.js @@ -5,7 +5,7 @@ export class Series { } getDigits() { - return [...this.numberString].map(digit => parseInt(digit, 10)); + return [...this.numberString].map((digit) => parseInt(digit, 10)); } slices(sliceSize) { diff --git a/exercises/series/series.js b/exercises/series/series.js index e0ea3a6f08..e8d59c5250 100644 --- a/exercises/series/series.js +++ b/exercises/series/series.js @@ -5,14 +5,14 @@ export class Series { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get digits() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } slices() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/series/series.spec.js b/exercises/series/series.spec.js index 75a4aff58f..f8915beb9e 100644 --- a/exercises/series/series.spec.js +++ b/exercises/series/series.spec.js @@ -6,48 +6,80 @@ describe('Series', () => { }); xtest('has digits (long)', () => { - expect(new Series('0123456789').digits) - .toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + expect(new Series('0123456789').digits).toEqual([ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + ]); }); xtest('keeps the digit order if reversed', () => { - expect(new Series('9876543210').digits) - .toEqual([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]); + expect(new Series('9876543210').digits).toEqual([ + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0, + ]); }); xtest('keeps arbitrary digit order', () => { - expect(new Series('936923468').digits) - .toEqual([9, 3, 6, 9, 2, 3, 4, 6, 8]); + expect(new Series('936923468').digits).toEqual([9, 3, 6, 9, 2, 3, 4, 6, 8]); }); xtest('can slice by 1', () => { - expect(new Series('01234').slices(1)) - .toEqual([[0], [1], [2], [3], [4]]); + expect(new Series('01234').slices(1)).toEqual([[0], [1], [2], [3], [4]]); }); xtest('can slice by 2', () => { - expect(new Series('98273463').slices(2)) - .toEqual([[9, 8], [8, 2], [2, 7], [7, 3], [3, 4], [4, 6], [6, 3]]); + expect(new Series('98273463').slices(2)).toEqual([ + [9, 8], + [8, 2], + [2, 7], + [7, 3], + [3, 4], + [4, 6], + [6, 3], + ]); }); xtest('can slice by 3', () => { - expect(new Series('01234').slices(3)) - .toEqual([[0, 1, 2], [1, 2, 3], [2, 3, 4]]); + expect(new Series('01234').slices(3)).toEqual([ + [0, 1, 2], + [1, 2, 3], + [2, 3, 4], + ]); }); xtest('can slice by 3 with duplicate digits', () => { - expect(new Series('31001').slices(3)) - .toEqual([[3, 1, 0], [1, 0, 0], [0, 0, 1]]); + expect(new Series('31001').slices(3)).toEqual([ + [3, 1, 0], + [1, 0, 0], + [0, 0, 1], + ]); }); xtest('can slice by 4', () => { - expect(new Series('91274').slices(4)) - .toEqual([[9, 1, 2, 7], [1, 2, 7, 4]]); + expect(new Series('91274').slices(4)).toEqual([ + [9, 1, 2, 7], + [1, 2, 7, 4], + ]); }); xtest('can slice by 5', () => { - expect(new Series('81228').slices(5)) - .toEqual([[8, 1, 2, 2, 8]]); + expect(new Series('81228').slices(5)).toEqual([[8, 1, 2, 2, 8]]); }); xtest('throws an error if not enough digits to slice', () => { diff --git a/exercises/sieve/babel.config.js b/exercises/sieve/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/sieve/babel.config.js +++ b/exercises/sieve/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/sieve/example.js b/exercises/sieve/example.js index 1a57702d9c..9b8e45d35f 100644 --- a/exercises/sieve/example.js +++ b/exercises/sieve/example.js @@ -30,4 +30,4 @@ function sieve(n) { return primes; } -export const primes = n => sieve(n); +export const primes = (n) => sieve(n); diff --git a/exercises/sieve/sieve.js b/exercises/sieve/sieve.js index cf53a8121f..3223eaa0e4 100644 --- a/exercises/sieve/sieve.js +++ b/exercises/sieve/sieve.js @@ -4,5 +4,5 @@ // export const primes = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/sieve/sieve.spec.js b/exercises/sieve/sieve.spec.js index 2336eb0b26..c152794f3e 100644 --- a/exercises/sieve/sieve.spec.js +++ b/exercises/sieve/sieve.spec.js @@ -18,14 +18,175 @@ describe('Sieve', () => { }); xtest('finds primes up to 1000', () => { - expect(primes(1000)).toEqual([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, - 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, - 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, - 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, - 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, - 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, - 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, - 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]); + expect(primes(1000)).toEqual([ + 2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29, + 31, + 37, + 41, + 43, + 47, + 53, + 59, + 61, + 67, + 71, + 73, + 79, + 83, + 89, + 97, + 101, + 103, + 107, + 109, + 113, + 127, + 131, + 137, + 139, + 149, + 151, + 157, + 163, + 167, + 173, + 179, + 181, + 191, + 193, + 197, + 199, + 211, + 223, + 227, + 229, + 233, + 239, + 241, + 251, + 257, + 263, + 269, + 271, + 277, + 281, + 283, + 293, + 307, + 311, + 313, + 317, + 331, + 337, + 347, + 349, + 353, + 359, + 367, + 373, + 379, + 383, + 389, + 397, + 401, + 409, + 419, + 421, + 431, + 433, + 439, + 443, + 449, + 457, + 461, + 463, + 467, + 479, + 487, + 491, + 499, + 503, + 509, + 521, + 523, + 541, + 547, + 557, + 563, + 569, + 571, + 577, + 587, + 593, + 599, + 601, + 607, + 613, + 617, + 619, + 631, + 641, + 643, + 647, + 653, + 659, + 661, + 673, + 677, + 683, + 691, + 701, + 709, + 719, + 727, + 733, + 739, + 743, + 751, + 757, + 761, + 769, + 773, + 787, + 797, + 809, + 811, + 821, + 823, + 827, + 829, + 839, + 853, + 857, + 859, + 863, + 877, + 881, + 883, + 887, + 907, + 911, + 919, + 929, + 937, + 941, + 947, + 953, + 967, + 971, + 977, + 983, + 991, + 997, + ]); }); }); diff --git a/exercises/simple-cipher/README.md b/exercises/simple-cipher/README.md index f4ec0a2c8c..ce404cc416 100644 --- a/exercises/simple-cipher/README.md +++ b/exercises/simple-cipher/README.md @@ -61,7 +61,7 @@ substitution cipher a little more fault tolerant by providing a source of randomness and ensuring that the key contains only lowercase letters. If someone doesn't submit a key at all, generate a truly random key of -at least 100 alphanumeric characters in length. +at least 100 lowercase characters in length. ## Extensions diff --git a/exercises/simple-cipher/babel.config.js b/exercises/simple-cipher/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/simple-cipher/babel.config.js +++ b/exercises/simple-cipher/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/simple-cipher/example.js b/exercises/simple-cipher/example.js index 2f51e060d0..3401f03b7a 100644 --- a/exercises/simple-cipher/example.js +++ b/exercises/simple-cipher/example.js @@ -9,11 +9,10 @@ function generateKey() { const mod = (n, m) => ((n % m) + m) % m; function xCode(key, inText, sign) { - return [...inText] - .reduce((outText, letter, ii) => { - const offset = sign * ALPHA.indexOf(key[mod(ii, key.length)]); - return outText + ALPHA[mod(ALPHA.indexOf(letter) + offset, ALPHA.length)]; - }, ''); + return [...inText].reduce((outText, letter, ii) => { + const offset = sign * ALPHA.indexOf(key[mod(ii, key.length)]); + return outText + ALPHA[mod(ALPHA.indexOf(letter) + offset, ALPHA.length)]; + }, ''); } export class Cipher { diff --git a/exercises/simple-cipher/simple-cipher.js b/exercises/simple-cipher/simple-cipher.js index 2b6181fdd0..ec77b1bcb0 100644 --- a/exercises/simple-cipher/simple-cipher.js +++ b/exercises/simple-cipher/simple-cipher.js @@ -5,18 +5,18 @@ export class Cipher { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } encode() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } decode() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get key() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index d6471907f8..ed1446aa46 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -46,8 +46,9 @@ describe('Substitution cipher', () => { }); xtest('can double shift encode', () => { - expect(new Cipher('iamapandabear').encode('iamapandabear')) - .toEqual('qayaeaagaciai'); + expect(new Cipher('iamapandabear').encode('iamapandabear')).toEqual( + 'qayaeaagaciai' + ); }); xtest('can wrap on encode', () => { @@ -59,12 +60,10 @@ describe('Substitution cipher', () => { }); xtest('can encode messages longer than the key', () => { - expect(new Cipher('abc').encode('iamapandabear')) - .toEqual('iboaqcnecbfcr'); + expect(new Cipher('abc').encode('iamapandabear')).toEqual('iboaqcnecbfcr'); }); xtest('can decode messages longer than the key', () => { - expect(new Cipher('abc').decode('iboaqcnecbfcr')) - .toEqual('iamapandabear'); + expect(new Cipher('abc').decode('iboaqcnecbfcr')).toEqual('iamapandabear'); }); }); diff --git a/exercises/simple-linked-list/babel.config.js b/exercises/simple-linked-list/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/simple-linked-list/babel.config.js +++ b/exercises/simple-linked-list/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/simple-linked-list/example.js b/exercises/simple-linked-list/example.js index 1246f7f96a..2dca846a5c 100644 --- a/exercises/simple-linked-list/example.js +++ b/exercises/simple-linked-list/example.js @@ -9,7 +9,7 @@ export class List { constructor(arr) { this.head = null; if (arr) { - arr.forEach(el => this.add(new Element(el))); + arr.forEach((el) => this.add(new Element(el))); } } diff --git a/exercises/simple-linked-list/simple-linked-list.js b/exercises/simple-linked-list/simple-linked-list.js index 2efb2a724f..e51d534bc9 100644 --- a/exercises/simple-linked-list/simple-linked-list.js +++ b/exercises/simple-linked-list/simple-linked-list.js @@ -3,31 +3,42 @@ // convenience to get you started writing code faster. // -export class SimpleLinkedList { +export class Element { + constructor() { + throw new Error('Remove this statement and implement this function'); + } + get value() { + throw new Error('Remove this statement and implement this function'); + } + + get next() { + throw new Error('Remove this statement and implement this function'); + } +} + +export class List { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } add(nextValue) { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get length() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get head() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } toArray() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } reverse() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } - } - diff --git a/exercises/simple-linked-list/simple-linked-list.spec.js b/exercises/simple-linked-list/simple-linked-list.spec.js index a51d62a90b..5703459d8d 100644 --- a/exercises/simple-linked-list/simple-linked-list.spec.js +++ b/exercises/simple-linked-list/simple-linked-list.spec.js @@ -117,6 +117,17 @@ describe('Lists with multiple elements', () => { expect(list.reverse().toArray()).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); }); xtest('can reverse a reversal', () => { - expect(list.reverse().reverse().toArray()).toEqual([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); + expect(list.reverse().reverse().toArray()).toEqual([ + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + ]); }); }); diff --git a/exercises/space-age/README.md b/exercises/space-age/README.md index 662b94faa6..91b33250d4 100644 --- a/exercises/space-age/README.md +++ b/exercises/space-age/README.md @@ -4,7 +4,7 @@ Given an age in seconds, calculate how old someone would be on: - Mercury: orbital period 0.2408467 Earth years - Venus: orbital period 0.61519726 Earth years - - Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31,557,600 seconds + - Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds - Mars: orbital period 1.8808158 Earth years - Jupiter: orbital period 11.862615 Earth years - Saturn: orbital period 29.447498 Earth years diff --git a/exercises/space-age/babel.config.js b/exercises/space-age/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/space-age/babel.config.js +++ b/exercises/space-age/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/space-age/space-age.js b/exercises/space-age/space-age.js index e879c2cc26..4b53e05f4c 100644 --- a/exercises/space-age/space-age.js +++ b/exercises/space-age/space-age.js @@ -4,5 +4,5 @@ // export const age = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/spiral-matrix/babel.config.js b/exercises/spiral-matrix/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/spiral-matrix/babel.config.js +++ b/exercises/spiral-matrix/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/spiral-matrix/example.js b/exercises/spiral-matrix/example.js index 5596c8808c..6e1cbb3bd6 100644 --- a/exercises/spiral-matrix/example.js +++ b/exercises/spiral-matrix/example.js @@ -1,6 +1,8 @@ export class SpiralMatrix { static ofSize(size) { - const spiral = Array(size).fill().map(() => Array(0)); + const spiral = Array(size) + .fill() + .map(() => Array(0)); const totalNumbers = size ** 2; let currentNumber = 1; diff --git a/exercises/spiral-matrix/spiral-matrix.js b/exercises/spiral-matrix/spiral-matrix.js index b107d1c43e..bf9ab27c14 100644 --- a/exercises/spiral-matrix/spiral-matrix.js +++ b/exercises/spiral-matrix/spiral-matrix.js @@ -5,6 +5,6 @@ export class SpiralMatrix { static ofSize() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/spiral-matrix/spiral-matrix.spec.js b/exercises/spiral-matrix/spiral-matrix.spec.js index dc69bb126b..4643aeeb70 100644 --- a/exercises/spiral-matrix/spiral-matrix.spec.js +++ b/exercises/spiral-matrix/spiral-matrix.spec.js @@ -16,38 +16,46 @@ describe('Spiral Matrix', () => { }); xtest('spiral of size 2', () => { - const expected = [[1, 2], - [4, 3]]; + const expected = [ + [1, 2], + [4, 3], + ]; const actual = SpiralMatrix.ofSize(2); expect(actual).toEqual(expected); }); xtest('spiral of size 3', () => { - const expected = [[1, 2, 3], + const expected = [ + [1, 2, 3], [8, 9, 4], - [7, 6, 5]]; + [7, 6, 5], + ]; const actual = SpiralMatrix.ofSize(3); expect(actual).toEqual(expected); }); xtest('spiral of size 4', () => { - const expected = [[1, 2, 3, 4], + const expected = [ + [1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], - [10, 9, 8, 7]]; + [10, 9, 8, 7], + ]; const actual = SpiralMatrix.ofSize(4); expect(actual).toEqual(expected); }); xtest('spiral of size 5', () => { - const expected = [[1, 2, 3, 4, 5], + const expected = [ + [1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], - [13, 12, 11, 10, 9]]; + [13, 12, 11, 10, 9], + ]; const actual = SpiralMatrix.ofSize(5); expect(expected).toEqual(actual); diff --git a/exercises/strain/babel.config.js b/exercises/strain/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/strain/babel.config.js +++ b/exercises/strain/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/strain/strain.js b/exercises/strain/strain.js index 7a807be980..427b6e7a5a 100644 --- a/exercises/strain/strain.js +++ b/exercises/strain/strain.js @@ -4,9 +4,9 @@ // export const keep = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const discard = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/strain/strain.spec.js b/exercises/strain/strain.spec.js index d9a6e526e1..621db90344 100644 --- a/exercises/strain/strain.spec.js +++ b/exercises/strain/strain.spec.js @@ -2,24 +2,24 @@ import { keep, discard } from './strain'; describe('strain', () => { test('keeps on empty array returns empty array', () => { - expect(keep([], e => e < 10)).toEqual([]); + expect(keep([], (e) => e < 10)).toEqual([]); }); xtest('keeps everything ', () => { - expect(keep([1, 2, 3], e => e < 10)).toEqual([1, 2, 3]); + expect(keep([1, 2, 3], (e) => e < 10)).toEqual([1, 2, 3]); }); xtest('keeps first and last', () => { - expect(keep([1, 2, 3], e => e % 2 === 1)).toEqual([1, 3]); + expect(keep([1, 2, 3], (e) => e % 2 === 1)).toEqual([1, 3]); }); xtest('keeps neither first nor last', () => { - expect(keep([1, 2, 3, 4, 5], e => e % 2 === 0)).toEqual([2, 4]); + expect(keep([1, 2, 3, 4, 5], (e) => e % 2 === 0)).toEqual([2, 4]); }); xtest('keeps strings', () => { const words = 'apple zebra banana zombies cherimoya zelot'.split(' '); - const result = keep(words, word => word.indexOf('z') === 0); + const result = keep(words, (word) => word.indexOf('z') === 0); expect(result).toEqual('zebra zombies zelot'.split(' ')); }); @@ -33,30 +33,35 @@ describe('strain', () => { [2, 2, 1], [1, 2, 5], ]; - const result = keep(rows, row => row.indexOf(5) > -1); - expect(result).toEqual([[5, 5, 5], [5, 1, 2], [1, 5, 2], [1, 2, 5]]); + const result = keep(rows, (row) => row.indexOf(5) > -1); + expect(result).toEqual([ + [5, 5, 5], + [5, 1, 2], + [1, 5, 2], + [1, 2, 5], + ]); }); xtest('empty discard', () => { - expect(discard([], e => e < 10)).toEqual([]); + expect(discard([], (e) => e < 10)).toEqual([]); }); xtest('discards nothing', () => { - expect(discard([1, 2, 3], e => e > 10)).toEqual([1, 2, 3]); + expect(discard([1, 2, 3], (e) => e > 10)).toEqual([1, 2, 3]); }); xtest('discards first and last', () => { - expect(discard([1, 2, 3], e => e % 2 === 1)).toEqual([2]); + expect(discard([1, 2, 3], (e) => e % 2 === 1)).toEqual([2]); }); xtest('discards neither first nor last', () => { - const result = discard([1, 2, 3, 4, 5], e => e % 2 === 0); + const result = discard([1, 2, 3, 4, 5], (e) => e % 2 === 0); expect(result).toEqual([1, 3, 5]); }); xtest('discards strings', () => { const words = 'apple zebra banana zombies cherimoya zelot'.split(' '); - const result = discard(words, word => word.indexOf('z') === 0); + const result = discard(words, (word) => word.indexOf('z') === 0); expect(result).toEqual('apple banana cherimoya'.split(' ')); }); @@ -70,7 +75,11 @@ describe('strain', () => { [2, 2, 1], [1, 2, 5], ]; - const result = discard(rows, row => row.indexOf(5) > -1); - expect(result).toEqual([[1, 2, 3], [2, 1, 2], [2, 2, 1]]); + const result = discard(rows, (row) => row.indexOf(5) > -1); + expect(result).toEqual([ + [1, 2, 3], + [2, 1, 2], + [2, 2, 1], + ]); }); }); diff --git a/exercises/sublist/babel.config.js b/exercises/sublist/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/sublist/babel.config.js +++ b/exercises/sublist/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/sublist/example.js b/exercises/sublist/example.js index a5aee84163..b6ceb8fe8d 100644 --- a/exercises/sublist/example.js +++ b/exercises/sublist/example.js @@ -5,23 +5,17 @@ export class List { compare(other) { return { - '-1': isSublist(other.list, this.list) - ? 'SUBLIST' - : 'UNEQUAL', - '0': isSublist(other.list, this.list) - ? 'EQUAL' - : 'UNEQUAL', - '1': isSublist(this.list, other.list) - ? 'SUPERLIST' - : 'UNEQUAL' + '-1': isSublist(other.list, this.list) ? 'SUBLIST' : 'UNEQUAL', + 0: isSublist(other.list, this.list) ? 'EQUAL' : 'UNEQUAL', + 1: isSublist(this.list, other.list) ? 'SUPERLIST' : 'UNEQUAL', }[lengthDiff(this, other)]; } } -function lengthDiff(one, two){ +function lengthDiff(one, two) { return String(Math.sign(one.list.length - two.list.length)); } -function isSublist(one, two){ +function isSublist(one, two) { return one.join().match(two.join()); } diff --git a/exercises/sublist/sublist.js b/exercises/sublist/sublist.js index 2565082c1c..6375e7178c 100644 --- a/exercises/sublist/sublist.js +++ b/exercises/sublist/sublist.js @@ -5,10 +5,10 @@ export class List { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } compare() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/sum-of-multiples/babel.config.js b/exercises/sum-of-multiples/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/sum-of-multiples/babel.config.js +++ b/exercises/sum-of-multiples/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/sum-of-multiples/example.js b/exercises/sum-of-multiples/example.js index 51afb16abd..e51aa1eaa0 100644 --- a/exercises/sum-of-multiples/example.js +++ b/exercises/sum-of-multiples/example.js @@ -1,9 +1,9 @@ export const sum = (multiples, limit) => { let sum = 0; for (let i = 1; i < limit; i++) { - if (multiples.some(multiple => i % multiple === 0)) { - sum += i; - } + if (multiples.some((multiple) => i % multiple === 0)) { + sum += i; + } } return sum; }; diff --git a/exercises/sum-of-multiples/sum-of-multiples.js b/exercises/sum-of-multiples/sum-of-multiples.js index 0ed19ef012..601ee9f600 100644 --- a/exercises/sum-of-multiples/sum-of-multiples.js +++ b/exercises/sum-of-multiples/sum-of-multiples.js @@ -4,5 +4,5 @@ // export const sum = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/sum-of-multiples/sum-of-multiples.spec.js b/exercises/sum-of-multiples/sum-of-multiples.spec.js index 5f04bf4cfa..bd38507eee 100644 --- a/exercises/sum-of-multiples/sum-of-multiples.spec.js +++ b/exercises/sum-of-multiples/sum-of-multiples.spec.js @@ -65,4 +65,3 @@ describe('Sum Of Multiples', () => { expect(sum([2, 3, 5, 7, 11], 10000)).toEqual(39614537); }); }); - diff --git a/exercises/transpose/babel.config.js b/exercises/transpose/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/transpose/babel.config.js +++ b/exercises/transpose/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/transpose/example.js b/exercises/transpose/example.js index 54b32b76ba..00b84f7ed3 100644 --- a/exercises/transpose/example.js +++ b/exercises/transpose/example.js @@ -1,13 +1,15 @@ function trimTrailingUndefined(array) { - const trailingUndefinedCount = [...array].reverse().findIndex(x => x !== undefined); + const trailingUndefinedCount = [...array] + .reverse() + .findIndex((x) => x !== undefined); return array.slice(0, array.length - trailingUndefinedCount); } export function transpose(input) { - const maxCol = Math.max(0, ...(input.map(row => row.length))); - return [...Array(maxCol).keys()].map(col => trimTrailingUndefined( - input.map((_v, row) => input[row][col]), - ) - .map(charOrUndefined => charOrUndefined || ' ') - .join('')); + const maxCol = Math.max(0, ...input.map((row) => row.length)); + return [...Array(maxCol).keys()].map((col) => + trimTrailingUndefined(input.map((_v, row) => input[row][col])) + .map((charOrUndefined) => charOrUndefined || ' ') + .join('') + ); } diff --git a/exercises/transpose/transpose.js b/exercises/transpose/transpose.js index bfe11109a8..f29c78ece4 100644 --- a/exercises/transpose/transpose.js +++ b/exercises/transpose/transpose.js @@ -4,5 +4,5 @@ // export const transpose = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/transpose/transpose.spec.js b/exercises/transpose/transpose.spec.js index 7dcc6219e9..8613c04b5a 100644 --- a/exercises/transpose/transpose.spec.js +++ b/exercises/transpose/transpose.spec.js @@ -25,19 +25,66 @@ describe('Transpose', () => { xtest('single line', () => { const input = ['Single line.']; - const expected = ['S', 'i', 'n', 'g', 'l', 'e', ' ', 'l', 'i', 'n', 'e', '.']; + const expected = [ + 'S', + 'i', + 'n', + 'g', + 'l', + 'e', + ' ', + 'l', + 'i', + 'n', + 'e', + '.', + ]; expect(transpose(input)).toEqual(expected); }); xtest('first line longer than second line', () => { const input = ['The fourth line.', 'The fifth line.']; - const expected = ['TT', 'hh', 'ee', ' ', 'ff', 'oi', 'uf', 'rt', 'th', 'h ', ' l', 'li', 'in', 'ne', 'e.', '.']; + const expected = [ + 'TT', + 'hh', + 'ee', + ' ', + 'ff', + 'oi', + 'uf', + 'rt', + 'th', + 'h ', + ' l', + 'li', + 'in', + 'ne', + 'e.', + '.', + ]; expect(transpose(input)).toEqual(expected); }); xtest('second line longer than first line', () => { const input = ['The first line.', 'The second line.']; - const expected = ['TT', 'hh', 'ee', ' ', 'fs', 'ie', 'rc', 'so', 'tn', ' d', 'l ', 'il', 'ni', 'en', '.e', ' .']; + const expected = [ + 'TT', + 'hh', + 'ee', + ' ', + 'fs', + 'ie', + 'rc', + 'so', + 'tn', + ' d', + 'l ', + 'il', + 'ni', + 'en', + '.e', + ' .', + ]; expect(transpose(input)).toEqual(expected); }); @@ -49,18 +96,49 @@ describe('Transpose', () => { xtest('rectangle', () => { const input = ['FRACTURE', 'OUTLINED', 'BLOOMING', 'SEPTETTE']; - const expected = ['FOBS', 'RULE', 'ATOP', 'CLOT', 'TIME', 'UNIT', 'RENT', 'EDGE']; + const expected = [ + 'FOBS', + 'RULE', + 'ATOP', + 'CLOT', + 'TIME', + 'UNIT', + 'RENT', + 'EDGE', + ]; expect(transpose(input)).toEqual(expected); }); xtest('triangle', () => { const input = ['T', 'EE', 'AAA', 'SSSS', 'EEEEE', 'RRRRRR']; - const expected = ['TEASER', ' EASER', ' ASER', ' SER', ' ER', ' R']; + const expected = [ + 'TEASER', + ' EASER', + ' ASER', + ' SER', + ' ER', + ' R', + ]; expect(transpose(input)).toEqual(expected); }); xtest('many lines', () => { - const input = ['Chor. Two households, both alike in dignity,', 'In fair Verona, where we lay our scene,', 'From ancient grudge break to new mutiny,', 'Where civil blood makes civil hands unclean.', 'From forth the fatal loins of these two foes', 'A pair of star-cross\'d lovers take their life;', 'Whose misadventur\'d piteous overthrows', 'Doth with their death bury their parents\' strife.', 'The fearful passage of their death-mark\'d love,', 'And the continuance of their parents\' rage,', 'Which, but their children\'s end, naught could remove,', 'Is now the two hours\' traffic of our stage;', 'The which if you with patient ears attend,', 'What here shall miss, our toil shall strive to mend.']; + const input = [ + 'Chor. Two households, both alike in dignity,', + 'In fair Verona, where we lay our scene,', + 'From ancient grudge break to new mutiny,', + 'Where civil blood makes civil hands unclean.', + 'From forth the fatal loins of these two foes', + "A pair of star-cross'd lovers take their life;", + "Whose misadventur'd piteous overthrows", + "Doth with their death bury their parents' strife.", + "The fearful passage of their death-mark'd love,", + "And the continuance of their parents' rage,", + "Which, but their children's end, naught could remove,", + "Is now the two hours' traffic of our stage;", + 'The which if you with patient ears attend,', + 'What here shall miss, our toil shall strive to mend.', + ]; const expected = [ 'CIFWFAWDTAWITW', 'hnrhr hohnhshh', @@ -79,15 +157,15 @@ describe('Transpose', () => { 'e,ro -trsui ol', 'h uofcu sarhu ', 'owddarrdan o m', - 'lhg to\'egccuwi', + "lhg to'egccuwi", 'deemasdaeehris', 'sr als t ists', - ',ebk \'phool\'h,', + ",ebk 'phool'h,", ' reldi ffd ', 'bweso tb rtpo', 'oea ileutterau', 't kcnoorhhnatr', - 'hl isvuyee\'fi ', + "hl isvuyee'fi ", ' atv es iisfet', 'ayoior trr ino', 'l lfsoh ecti', @@ -98,11 +176,11 @@ describe('Transpose', () => { 'ismdsehphnnosa', 'ncuse ra-tau l', ' et tormsural', - 'dniuthwea\'g t ', + "dniuthwea'g t ", 'iennwesnr hsts', 'g,ycoi tkrttet', - 'n ,l r s\'a anr', - 'i ef \'dgcgdi', + "n ,l r s'a anr", + "i ef 'dgcgdi", 't aol eoe,v', 'y nei sl,u; e', ', .sf to l ', diff --git a/exercises/triangle/babel.config.js b/exercises/triangle/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/triangle/babel.config.js +++ b/exercises/triangle/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/triangle/triangle.js b/exercises/triangle/triangle.js index 85b7541283..fa6d875fd9 100644 --- a/exercises/triangle/triangle.js +++ b/exercises/triangle/triangle.js @@ -5,18 +5,18 @@ export class Triangle { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } isEquilateral() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } isIsosceles() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } isScalene() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/trinary/babel.config.js b/exercises/trinary/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/trinary/babel.config.js +++ b/exercises/trinary/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/trinary/example.js b/exercises/trinary/example.js index 818e829164..cdde2fbc40 100644 --- a/exercises/trinary/example.js +++ b/exercises/trinary/example.js @@ -10,12 +10,15 @@ export class Trinary { return 0; } - return this.digits.reduce((decimal, digit, index) => decimal + digit * (BASE ** index), 0); + return this.digits.reduce( + (decimal, digit, index) => decimal + digit * BASE ** index, + 0 + ); } someDigitIsInvalid() { - const greaterThanBase = this.digits.some(d => d >= BASE); - const notANumber = this.digits.some(d => Number(d) !== d); + const greaterThanBase = this.digits.some((d) => d >= BASE); + const notANumber = this.digits.some((d) => Number(d) !== d); return greaterThanBase || notANumber; } } diff --git a/exercises/trinary/trinary.js b/exercises/trinary/trinary.js index 8c4673f2e6..0cf1e65a29 100644 --- a/exercises/trinary/trinary.js +++ b/exercises/trinary/trinary.js @@ -5,10 +5,10 @@ export class Trinary { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } toDecimal() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/twelve-days/babel.config.js b/exercises/twelve-days/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/twelve-days/babel.config.js +++ b/exercises/twelve-days/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/twelve-days/example.js b/exercises/twelve-days/example.js index bbd67f4a81..d512cd59ee 100644 --- a/exercises/twelve-days/example.js +++ b/exercises/twelve-days/example.js @@ -30,15 +30,17 @@ const gifts = [ 'twelve Drummers Drumming', ]; -const prefix = verseNum => `On the ${ordinal[verseNum]} day of \ +const prefix = (verseNum) => `On the ${ordinal[verseNum]} day of \ Christmas my true love gave to me: `; -const giftParade = verseNum => Array.from(Array(verseNum)) - .map((_, i) => gifts[verseNum - i]).join(', '); +const giftParade = (verseNum) => + Array.from(Array(verseNum)) + .map((_, i) => gifts[verseNum - i]) + .join(', '); export function recite(startVerse, endVerse = null) { return Array.from(Array((endVerse || startVerse) - startVerse + 1)) .map((_, i) => i + startVerse) - .map(n => `${prefix(n)}${giftParade(n)}\n`.replace(': and', ':')) + .map((n) => `${prefix(n)}${giftParade(n)}\n`.replace(': and', ':')) .join('\n'); } diff --git a/exercises/twelve-days/twelve-days.js b/exercises/twelve-days/twelve-days.js index e663ae6c5d..b3ac658733 100644 --- a/exercises/twelve-days/twelve-days.js +++ b/exercises/twelve-days/twelve-days.js @@ -4,5 +4,5 @@ // export const recite = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/two-bucket/README.md b/exercises/two-bucket/README.md index 77c4f57801..e6ec844c1e 100644 --- a/exercises/two-bucket/README.md +++ b/exercises/two-bucket/README.md @@ -23,9 +23,9 @@ Example: Bucket one can hold up to 7 liters, and bucket two can hold up to 11 liters. Let's say bucket one, at a given step, is holding 7 liters, and bucket two is holding 8 liters (7,8). If you empty bucket one and make no change to bucket two, leaving you with 0 liters and 8 liters respectively (0,8), that counts as one "move". Instead, if you had poured from bucket one into bucket two until bucket two was full, leaving you with 4 liters in bucket one and 11 liters in bucket two (4,11), that would count as only one "move" as well. To conclude, the only valid moves are: -- pouring from one bucket to another -- emptying one bucket and doing nothing to the other -- filling one bucket and doing nothing to the other +- pouring from either bucket to another +- emptying either bucket and doing nothing to the other +- filling either bucket and doing nothing to the other Written with <3 at [Fullstack Academy](http://www.fullstackacademy.com/) by Lindsay Levine. diff --git a/exercises/two-bucket/babel.config.js b/exercises/two-bucket/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/two-bucket/babel.config.js +++ b/exercises/two-bucket/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 4fe7ccaa5d..fb4c4f5d76 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -39,7 +39,7 @@ export class TwoBucket { } else if (j === this.x) { j = 0; } else if (k > this.x && (j !== 0 || k > this.x) && bool) { - k -= (this.x - j); + k -= this.x - j; j = this.x; } else if (k > this.x || j === 0) { j = k; diff --git a/exercises/two-bucket/two-bucket.js b/exercises/two-bucket/two-bucket.js index 186ab6252f..c313992f16 100644 --- a/exercises/two-bucket/two-bucket.js +++ b/exercises/two-bucket/two-bucket.js @@ -5,18 +5,18 @@ export class TwoBucket { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } moves() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get goalBucket() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } get otherBucket() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/two-fer/README.md b/exercises/two-fer/README.md index 0f4dc48a50..f5e3d28145 100644 --- a/exercises/two-fer/README.md +++ b/exercises/two-fer/README.md @@ -5,10 +5,10 @@ Given a name, return a string with the message: ```text -One for X, one for me. +One for name, one for me. ``` -Where X is the given name. +Where "name" is the given name. However, if the name is missing, return the string: @@ -18,9 +18,9 @@ One for you, one for me. Here are some examples: -|Name |String to return +|Name |String to return |:-------|:------------------ -|Alice |One for Alice, one for me. +|Alice |One for Alice, one for me. |Bob |One for Bob, one for me. | |One for you, one for me. |Zaphod |One for Zaphod, one for me. diff --git a/exercises/two-fer/babel.config.js b/exercises/two-fer/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/two-fer/babel.config.js +++ b/exercises/two-fer/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/two-fer/two-fer.js b/exercises/two-fer/two-fer.js index 5d857b17b7..da86f41da3 100644 --- a/exercises/two-fer/two-fer.js +++ b/exercises/two-fer/two-fer.js @@ -4,5 +4,5 @@ // export const twoFer = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/two-fer/two-fer.spec.js b/exercises/two-fer/two-fer.spec.js index e7912e60bb..1c39a36556 100644 --- a/exercises/two-fer/two-fer.spec.js +++ b/exercises/two-fer/two-fer.spec.js @@ -1,15 +1,15 @@ -import { twoFer } from './two-fer' +import { twoFer } from './two-fer'; describe('twoFer()', () => { test('no name given', () => { - expect(twoFer()).toEqual("One for you, one for me.") - }) + expect(twoFer()).toEqual('One for you, one for me.'); + }); xtest('a name given', () => { - expect(twoFer("Alice")).toEqual("One for Alice, one for me.") - }) + expect(twoFer('Alice')).toEqual('One for Alice, one for me.'); + }); xtest('another name given', () => { - expect(twoFer("Bob")).toEqual("One for Bob, one for me.") - }) -}) + expect(twoFer('Bob')).toEqual('One for Bob, one for me.'); + }); +}); diff --git a/exercises/variable-length-quantity/babel.config.js b/exercises/variable-length-quantity/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/variable-length-quantity/babel.config.js +++ b/exercises/variable-length-quantity/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/variable-length-quantity/example.js b/exercises/variable-length-quantity/example.js index 69832cb672..6ada91bcb3 100644 --- a/exercises/variable-length-quantity/example.js +++ b/exercises/variable-length-quantity/example.js @@ -7,7 +7,7 @@ const encodeOne = (val) => { let left = val; while (left) { - const bits = left & DATA_BITS | CONT_BITS; // set continuation everywhere + const bits = (left & DATA_BITS) | CONT_BITS; // set continuation everywhere left = left >>> LENGTH; buf.push(bits); } @@ -19,7 +19,7 @@ const decodeOne = (buf) => { let val = 0; for (let i = 0; i < buf.length; i++) { - val = val << LENGTH | buf[i] & DATA_BITS; + val = (val << LENGTH) | (buf[i] & DATA_BITS); } return val >>> 0; // convert to unsigned 32-bit }; @@ -31,7 +31,7 @@ export const encode = (data) => { buf = buf.concat(encodeOne(data[i])); } return buf; -} +}; export const decode = (data) => { let start = 0; @@ -47,4 +47,4 @@ export const decode = (data) => { throw new Error('Incomplete sequence'); } return vals; -} +}; diff --git a/exercises/variable-length-quantity/variable-length-quantity.js b/exercises/variable-length-quantity/variable-length-quantity.js index 740310a2ba..62862ffa79 100644 --- a/exercises/variable-length-quantity/variable-length-quantity.js +++ b/exercises/variable-length-quantity/variable-length-quantity.js @@ -4,9 +4,9 @@ // export const encode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; export const decode = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/variable-length-quantity/variable-length-quantity.spec.js b/exercises/variable-length-quantity/variable-length-quantity.spec.js index f6dc4e2ef9..cb5fb148a6 100644 --- a/exercises/variable-length-quantity/variable-length-quantity.spec.js +++ b/exercises/variable-length-quantity/variable-length-quantity.spec.js @@ -67,12 +67,35 @@ describe('VariableLengthQuantity', () => { }); xtest('two multi-byte values', () => { - expect(encode([0x4000, 0x123456])).toEqual([0x81, 0x80, 0, 0xc8, 0xe8, 0x56]); + expect(encode([0x4000, 0x123456])).toEqual([ + 0x81, + 0x80, + 0, + 0xc8, + 0xe8, + 0x56, + ]); }); xtest('many multi-byte values', () => { const input = [0x2000, 0x123456, 0xfffffff, 0, 0x3fff, 0x4000]; - const expected = [0xc0, 0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0, 0xff, 0x7f, 0x81, 0x80, 0]; + const expected = [ + 0xc0, + 0, + 0xc8, + 0xe8, + 0x56, + 0xff, + 0xff, + 0xff, + 0x7f, + 0, + 0xff, + 0x7f, + 0x81, + 0x80, + 0, + ]; expect(encode(input)).toEqual(expected); }); }); @@ -99,15 +122,35 @@ describe('VariableLengthQuantity', () => { }); xtest('incomplete sequence causes error', () => { - expect(() => { decode([0xff]); }).toThrow(new Error('Incomplete sequence')); + expect(() => { + decode([0xff]); + }).toThrow(new Error('Incomplete sequence')); }); xtest('incomplete sequence causes error, even if value is zero', () => { - expect(() => { decode([0x80]); }).toThrow(new Error('Incomplete sequence')); + expect(() => { + decode([0x80]); + }).toThrow(new Error('Incomplete sequence')); }); xtest('multiple values', () => { - const input = [0xc0, 0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0, 0xff, 0x7f, 0x81, 0x80, 0]; + const input = [ + 0xc0, + 0, + 0xc8, + 0xe8, + 0x56, + 0xff, + 0xff, + 0xff, + 0x7f, + 0, + 0xff, + 0x7f, + 0x81, + 0x80, + 0, + ]; const expected = [0x2000, 0x123456, 0xfffffff, 0, 0x3fff, 0x4000]; expect(decode(input)).toEqual(expected); }); diff --git a/exercises/word-count/README.md b/exercises/word-count/README.md index f1525d2b65..0cd7204eea 100644 --- a/exercises/word-count/README.md +++ b/exercises/word-count/README.md @@ -1,14 +1,33 @@ # Word Count -Given a phrase, count the occurrences of each word in that phrase. +Given a phrase, count the occurrences of each _word_ in that phrase. -For example for the input `"olly olly in come free"` +For the purposes of this exercise you can expect that a _word_ will always be one of: + +1. A _number_ composed of one or more ASCII digits (ie "0" or "1234") OR +2. A _simple word_ composed of one or more ASCII letters (ie "a" or "they") OR +3. A _contraction_ of two _simple words_ joined by a single apostrophe (ie "it's" or "they're") + +When counting words you can assume the following rules: + +1. The count is _case insensitive_ (ie "You", "you", and "YOU" are 3 uses of the same word) +2. The count is _unordered_; the tests will ignore how words and counts are ordered +3. Other than the apostrophe in a _contraction_ all forms of _punctuation_ are ignored +4. The words can be separated by _any_ form of whitespace (ie "\t", "\n", " ") + +For example, for the phrase `"That's the password: 'PASSWORD 123'!", cried the Special Agent.\nSo I fled.` the count would be: ```text -olly: 2 -in: 1 -come: 1 -free: 1 +that's: 1 +the: 2 +password: 2 +123: 1 +cried: 1 +special: 1 +agent: 1 +so: 1 +i: 1 +fled: 1 ``` ## Setup diff --git a/exercises/word-count/babel.config.js b/exercises/word-count/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/word-count/babel.config.js +++ b/exercises/word-count/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/word-count/example.js b/exercises/word-count/example.js index 8cc29000b4..27b68b5832 100644 --- a/exercises/word-count/example.js +++ b/exercises/word-count/example.js @@ -1,11 +1,11 @@ -export const countWords = phrase => { +export const countWords = (phrase) => { let map = {}; phrase .trim() .toLowerCase() .split(/[ ,\n]+/g) - .forEach(element => { - element = element.replace(/[.,!:"&@$%^]|^'|'$/g, ""); + .forEach((element) => { + element = element.replace(/[.,!:"&@$%^]|^'|'$/g, ''); if (element) { if (Object.prototype.hasOwnProperty.call(map, element)) { map[element]++; diff --git a/exercises/word-count/word-count.js b/exercises/word-count/word-count.js index 9a8138ef4d..697cc32351 100644 --- a/exercises/word-count/word-count.js +++ b/exercises/word-count/word-count.js @@ -4,5 +4,5 @@ // export const countWords = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index 1297904dc3..091683ba7d 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -1,7 +1,6 @@ import { countWords } from './word-count'; describe('countWords', () => { - test('count one word', () => { const expectedCounts = { word: 1 }; expect(countWords('word')).toEqual(expectedCounts); @@ -18,7 +17,7 @@ describe('countWords', () => { fish: 4, two: 1, red: 1, - blue: 1 + blue: 1, }; expect(countWords('one fish two fish red fish blue fish')).toEqual( expectedCounts @@ -29,7 +28,7 @@ describe('countWords', () => { const expectedCounts = { one: 1, two: 1, - three: 1 + three: 1, }; expect(countWords('one,two,three')).toEqual(expectedCounts); }); @@ -38,7 +37,7 @@ describe('countWords', () => { const expectedCounts = { one: 1, two: 1, - three: 1 + three: 1, }; expect(countWords('one,\ntwo,\nthree')).toEqual(expectedCounts); }); @@ -49,7 +48,7 @@ describe('countWords', () => { carpet: 1, as: 1, java: 1, - javascript: 1 + javascript: 1, }; expect(countWords('car: carpet as java: javascript!!&@$%^&')).toEqual( expectedCounts @@ -59,8 +58,8 @@ describe('countWords', () => { xtest('include numbers', () => { const expectedCounts = { testing: 2, - '1': 1, - '2': 1 + 1: 1, + 2: 1, }; expect(countWords('testing, 1, 2 testing')).toEqual(expectedCounts); }); @@ -68,7 +67,7 @@ describe('countWords', () => { xtest('normalize case', () => { const expectedCounts = { go: 3, - stop: 2 + stop: 2, }; expect(countWords('go Go GO Stop stop')).toEqual(expectedCounts); }); @@ -76,12 +75,12 @@ describe('countWords', () => { xtest('with apostrophes', () => { const expectedCounts = { first: 1, - 'don\'t': 2, + "don't": 2, laugh: 1, then: 1, - cry: 1 + cry: 1, }; - expect(countWords('First: don\'t laugh. Then: don\'t cry.')).toEqual( + expect(countWords("First: don't laugh. Then: don't cry.")).toEqual( expectedCounts ); }); @@ -89,13 +88,13 @@ describe('countWords', () => { xtest('with quotations', () => { const expectedCounts = { joe: 1, - 'can\'t': 1, + "can't": 1, tell: 1, between: 1, large: 2, - and: 1 + and: 1, }; - expect(countWords('Joe can\'t tell between \'large\' and large.')).toEqual( + expect(countWords("Joe can't tell between 'large' and large.")).toEqual( expectedCounts ); }); @@ -103,15 +102,15 @@ describe('countWords', () => { xtest('substrings from the beginning', () => { const expectedCounts = { joe: 1, - 'can\'t': 1, + "can't": 1, tell: 1, between: 1, app: 1, apple: 1, and: 1, - a: 1 + a: 1, }; - expect(countWords('Joe can\'t tell between app, apple and a.')).toEqual( + expect(countWords("Joe can't tell between app, apple and a.")).toEqual( expectedCounts ); }); @@ -119,7 +118,7 @@ describe('countWords', () => { xtest('multiple spaces not detected as a word', () => { const expectedCounts = { multiple: 1, - whitespaces: 1 + whitespaces: 1, }; expect(countWords(' multiple whitespaces')).toEqual(expectedCounts); }); @@ -128,8 +127,8 @@ describe('countWords', () => { const expectedCounts = { one: 1, two: 1, - three: 1 + three: 1, }; - expect(countWords(',\n,one,\n ,two \n \'three\'')).toEqual(expectedCounts); + expect(countWords(",\n,one,\n ,two \n 'three'")).toEqual(expectedCounts); }); }); diff --git a/exercises/word-search/babel.config.js b/exercises/word-search/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/word-search/babel.config.js +++ b/exercises/word-search/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/word-search/example.js b/exercises/word-search/example.js index 5387e8263b..727f68fa98 100644 --- a/exercises/word-search/example.js +++ b/exercises/word-search/example.js @@ -4,9 +4,12 @@ function searchHorizontally({ word, grid }) { let start; let end; - const getCoords = () => [[rowIndex + 1, startCol], [rowIndex + 1, startCol + word.length - 1]]; + const getCoords = () => [ + [rowIndex + 1, startCol], + [rowIndex + 1, startCol + word.length - 1], + ]; - const getStartCol = currentWord => 1 + grid[rowIndex].indexOf(currentWord); + const getStartCol = (currentWord) => 1 + grid[rowIndex].indexOf(currentWord); while (rowIndex < grid.length) { startCol = getStartCol(word); @@ -39,7 +42,7 @@ function flipCoordinates(coords) { function flipGrid(grid) { return [...grid[0]] .map((col, c) => grid.map((row, r) => grid[r][c])) - .map(row => row.join('')); + .map((row) => row.join('')); } function diagonalFind(r, c, word, grid, rIncrement, outOfRange, buildCoords) { @@ -50,11 +53,15 @@ function diagonalFind(r, c, word, grid, rIncrement, outOfRange, buildCoords) { const startC = c + 1; let result; word.split('').forEach((letter) => { - if (!outOfRange(currentRow, - currentColumn, - word.length, - grid[currentRow].length, - foundLetters.length)) { + if ( + !outOfRange( + currentRow, + currentColumn, + word.length, + grid[currentRow].length, + foundLetters.length + ) + ) { const currLetterInGrid = grid[currentRow].charAt(currentColumn); currentColumn += 1; if (currLetterInGrid === letter) { @@ -71,7 +78,9 @@ function diagonalFind(r, c, word, grid, rIncrement, outOfRange, buildCoords) { function findAWordDiagonallyTopDown(r, c, word, grid) { function outOfRange(row, column, words, columns, letters) { - return row > columns - words + letters || column > columns - words + letters; + return ( + row > columns - words + letters || column > columns - words + letters + ); } function buildCoords(startR, startC, row, column) { @@ -109,18 +118,15 @@ function formatCoordinates(coords, isReversed) { }[isReversed]; } -function searchDiagonally({ - word, - grid, - isReversed = false, - fromTop = true, -}) { +function searchDiagonally({ word, grid, isReversed = false, fromTop = true }) { const rIncrement = fromTop ? 1 : -1; const startRow = fromTop ? 0 : grid.length - 1; - const endRow = fromTop ? r => r < grid.length : r => r > 0; - const findDirection = fromTop ? findAWordDiagonallyTopDown : findAWordDiagonallyBottomUp; + const endRow = fromTop ? (r) => r < grid.length : (r) => r > 0; + const findDirection = fromTop + ? findAWordDiagonallyTopDown + : findAWordDiagonallyBottomUp; - for (let r = startRow; (endRow)(r); r += rIncrement) { + for (let r = startRow; endRow(r); r += rIncrement) { for (let c = 0; c < grid[r].length; c += 1) { const possibleCoords = findDirection(r, c, word, grid); if (possibleCoords) { @@ -143,10 +149,12 @@ function searchDiagonally({ } function findWordInAnyDirection(word, grid) { - return searchHorizontally({ word, grid }) - || flipCoordinates(searchHorizontally({ word, grid: flipGrid(grid) })) - || searchDiagonally({ word, grid }) - || searchDiagonally({ word, grid, fromTop: false }); + return ( + searchHorizontally({ word, grid }) || + flipCoordinates(searchHorizontally({ word, grid: flipGrid(grid) })) || + searchDiagonally({ word, grid }) || + searchDiagonally({ word, grid, fromTop: false }) + ); } class WordSearch { @@ -156,7 +164,7 @@ class WordSearch { find(words) { return words - .map(word => ({ [word]: findWordInAnyDirection(word, this.grid) })) + .map((word) => ({ [word]: findWordInAnyDirection(word, this.grid) })) .reduce((acc, oneWord) => Object.assign(acc, oneWord), {}); } } diff --git a/exercises/word-search/word-search.js b/exercises/word-search/word-search.js index e5a862cfcb..857c5222b9 100644 --- a/exercises/word-search/word-search.js +++ b/exercises/word-search/word-search.js @@ -5,11 +5,11 @@ class WordSearch { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } find() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/word-search/word-search.spec.js b/exercises/word-search/word-search.spec.js index 957fbcdb68..f646e8f362 100644 --- a/exercises/word-search/word-search.spec.js +++ b/exercises/word-search/word-search.spec.js @@ -1,6 +1,5 @@ import WordSearch from './word-search'; - describe('single line grids', () => { test('Should accept an initial game grid', () => { const grid = ['jefblpepre']; @@ -70,10 +69,7 @@ describe('single line grids', () => { describe('multi line grids', () => { xtest('can locate a left to right word in a two line grid', () => { - const grid = [ - 'jefblpepre', - 'clojurermt', - ]; + const grid = ['jefblpepre', 'clojurermt']; const expectedResults = { clojure: { @@ -87,10 +83,7 @@ describe('multi line grids', () => { expect(wordSearch.find(['clojure'])).toEqual(expectedResults); }); xtest('can locate a left to right word in a different position in a two line grid', () => { - const grid = [ - 'jefblpepre', - 'tclojurerm', - ]; + const grid = ['jefblpepre', 'tclojurerm']; const expectedResults = { clojure: { start: [2, 2], @@ -102,11 +95,7 @@ describe('multi line grids', () => { expect(wordSearch.find(['clojure'])).toEqual(expectedResults); }); xtest('can locate a left to right word in a three line grid', () => { - const grid = [ - 'camdcimgtc', - 'jefblpepre', - 'clojurermt', - ]; + const grid = ['camdcimgtc', 'jefblpepre', 'clojurermt']; const expectedResults = { clojure: { start: [3, 1], @@ -192,7 +181,6 @@ describe('multi line grids', () => { }); }); - describe('can find multiple words', () => { xtest('can find two words written left to right', () => { const grid = [ @@ -296,7 +284,9 @@ describe('vertical directions', () => { }; const wordSearch = new WordSearch(grid); - expect(wordSearch.find(['elixir', 'clojure', 'ecmascript'])).toEqual(expectedResults); + expect(wordSearch.find(['elixir', 'clojure', 'ecmascript'])).toEqual( + expectedResults + ); }); xtest('should locate words written bottom to top', () => { const grid = [ @@ -331,7 +321,9 @@ describe('vertical directions', () => { }; const wordSearch = new WordSearch(grid); - expect(wordSearch.find(['elixir', 'clojure', 'ecmascript', 'rust'])).toEqual(expectedResults); + expect( + wordSearch.find(['elixir', 'clojure', 'ecmascript', 'rust']) + ).toEqual(expectedResults); }); xtest('should locate words written top left to bottom right', () => { const grid = [ @@ -370,13 +362,9 @@ describe('vertical directions', () => { }; const wordSearch = new WordSearch(grid); - expect(wordSearch.find([ - 'clojure', - 'elixir', - 'ecmascript', - 'rust', - 'java', - ])).toEqual(expectedResults); + expect( + wordSearch.find(['clojure', 'elixir', 'ecmascript', 'rust', 'java']) + ).toEqual(expectedResults); }); xtest('should locate words written bottom right to top left', () => { const grid = [ @@ -420,14 +408,16 @@ describe('vertical directions', () => { }; const wordSearch = new WordSearch(grid); - expect(wordSearch.find([ - 'clojure', - 'elixir', - 'ecmascript', - 'rust', - 'java', - 'lua', - ])).toEqual(expectedResults); + expect( + wordSearch.find([ + 'clojure', + 'elixir', + 'ecmascript', + 'rust', + 'java', + 'lua', + ]) + ).toEqual(expectedResults); }); xtest('should locate words written bottom left to top right', () => { const grid = [ @@ -475,15 +465,17 @@ describe('vertical directions', () => { const wordSearch = new WordSearch(grid); - expect(wordSearch.find([ - 'clojure', - 'elixir', - 'ecmascript', - 'rust', - 'java', - 'lua', - 'lisp', - ])).toEqual(expectedResults); + expect( + wordSearch.find([ + 'clojure', + 'elixir', + 'ecmascript', + 'rust', + 'java', + 'lua', + 'lisp', + ]) + ).toEqual(expectedResults); }); xtest('should locate words written top right to bottom left', () => { const grid = [ @@ -535,15 +527,17 @@ describe('vertical directions', () => { }; const wordSearch = new WordSearch(grid); - expect(wordSearch.find([ - 'clojure', - 'elixir', - 'ecmascript', - 'rust', - 'java', - 'lua', - 'lisp', - 'ruby', - ])).toEqual(expectedResults); + expect( + wordSearch.find([ + 'clojure', + 'elixir', + 'ecmascript', + 'rust', + 'java', + 'lua', + 'lisp', + 'ruby', + ]) + ).toEqual(expectedResults); }); }); diff --git a/exercises/wordy/babel.config.js b/exercises/wordy/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/wordy/babel.config.js +++ b/exercises/wordy/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/wordy/example.js b/exercises/wordy/example.js index fa68d42c68..e6d2e2893b 100644 --- a/exercises/wordy/example.js +++ b/exercises/wordy/example.js @@ -1,28 +1,28 @@ const compute = (operand1, operand2, operation) => { switch (operation) { - case "plus": + case 'plus': return operand1 + operand2; - case "minus": + case 'minus': return operand1 - operand2; - case "divided by": + case 'divided by': return operand1 / operand2; - case "multiplied by": + case 'multiplied by': return operand1 * operand2; } }; -export const answer = question => { +export const answer = (question) => { const operationsPattern = new RegExp(/plus|minus|divided by|multiplied by/g); if ( !operationsPattern.test(question) && !/^What is ?-?\d*\?$/.test(question) ) { - throw new Error("Unknown operation"); + throw new Error('Unknown operation'); } const generalPattern = /^What is -?\d+( (plus|minus|multiplied by|divided by) -?\d+)*\?$/g; if (!generalPattern.test(question)) { - throw new Error("Syntax error"); + throw new Error('Syntax error'); } const operations = question.match(operationsPattern); diff --git a/exercises/wordy/wordy.js b/exercises/wordy/wordy.js index 1b221bd127..9ee42c7703 100644 --- a/exercises/wordy/wordy.js +++ b/exercises/wordy/wordy.js @@ -4,5 +4,5 @@ // export const answer = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/yacht/babel.config.js b/exercises/yacht/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/yacht/babel.config.js +++ b/exercises/yacht/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/yacht/example.js b/exercises/yacht/example.js index fcd42b328f..01f07306b7 100644 --- a/exercises/yacht/example.js +++ b/exercises/yacht/example.js @@ -1,9 +1,9 @@ -const getScoreForTheYachtCategory = dices => { +const getScoreForTheYachtCategory = (dices) => { const isYacht = new Set(dices).size === 1; return isYacht ? 50 : 0; }; -const mapDicesToCounterArray = dices => { +const mapDicesToCounterArray = (dices) => { let counterArray = [0, 0, 0, 0, 0, 0]; for (let item of dices) { counterArray[item - 1]++; @@ -12,14 +12,14 @@ const mapDicesToCounterArray = dices => { }; const getNoOfAppearances = (dices, diceValue) => { - return dices.filter(value => value === diceValue).length; + return dices.filter((value) => value === diceValue).length; }; -const getSumOfDices = dices => { +const getSumOfDices = (dices) => { return dices.reduce((a, b) => a + b, 0); }; -const getScoreForTheFourOfAKindCategory = dices => { +const getScoreForTheFourOfAKindCategory = (dices) => { const counterArray = mapDicesToCounterArray(dices); for (let i = 0; i < counterArray.length; i++) { if (counterArray[i] >= 4) { @@ -29,15 +29,25 @@ const getScoreForTheFourOfAKindCategory = dices => { return 0; }; -const getScoreForTheLittleStraightCategory = dices => { +const getScoreForTheLittleStraightCategory = (dices) => { const counterArray = mapDicesToCounterArray(dices); - const isLittleStraight = arrayIsFilledWithValue(counterArray, 0, counterArray.length - 1, 1); + const isLittleStraight = arrayIsFilledWithValue( + counterArray, + 0, + counterArray.length - 1, + 1 + ); return isLittleStraight ? 30 : 0; }; -const getScoreForTheBigStraightCategory = dices => { +const getScoreForTheBigStraightCategory = (dices) => { const counterArray = mapDicesToCounterArray(dices); - const isBigStraight = arrayIsFilledWithValue(counterArray, 1, counterArray.length, 1); + const isBigStraight = arrayIsFilledWithValue( + counterArray, + 1, + counterArray.length, + 1 + ); return isBigStraight ? 30 : 0; }; @@ -50,7 +60,7 @@ const arrayIsFilledWithValue = (array, startPos, endPos, value) => { return true; }; -const getScoreForTheFullHouseCategory = dices => { +const getScoreForTheFullHouseCategory = (dices) => { const counterArray = mapDicesToCounterArray(dices); let hasTwoOfAKind = false; let hasThreeOfAKind = false; diff --git a/exercises/yacht/yacht.js b/exercises/yacht/yacht.js index 2923b687e3..23edbb5fad 100644 --- a/exercises/yacht/yacht.js +++ b/exercises/yacht/yacht.js @@ -4,5 +4,5 @@ // export const score = () => { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); }; diff --git a/exercises/yacht/yacht.spec.js b/exercises/yacht/yacht.spec.js index 789222070a..6c6d2417e9 100644 --- a/exercises/yacht/yacht.spec.js +++ b/exercises/yacht/yacht.spec.js @@ -1,4 +1,4 @@ -import { score } from './yacht' +import { score } from './yacht'; describe('Yacht', () => { test('Yacht', () => { diff --git a/exercises/zipper/babel.config.js b/exercises/zipper/babel.config.js index 9a037acb49..5cec97251a 100644 --- a/exercises/zipper/babel.config.js +++ b/exercises/zipper/babel.config.js @@ -1,15 +1,15 @@ module.exports = { presets: [ [ - "@babel/preset-env", + '@babel/preset-env', { targets: { - node: "current", + node: 'current', }, - useBuiltIns: "entry", + useBuiltIns: 'entry', corejs: 3, }, ], ], - plugins: ["@babel/plugin-syntax-bigint"], + plugins: ['@babel/plugin-syntax-bigint'], }; diff --git a/exercises/zipper/example.js b/exercises/zipper/example.js index 05f7a4f6b7..9aff85b7fd 100644 --- a/exercises/zipper/example.js +++ b/exercises/zipper/example.js @@ -1,5 +1,5 @@ function fromTrail(tree, last) { - if (last[0] === "left") { + if (last[0] === 'left') { return { value: last[1], left: tree, @@ -43,7 +43,7 @@ export class Zipper { return new Zipper( this.tree.left, - [["left", this.tree.value, this.tree.right]].concat(this.trail) + [['left', this.tree.value, this.tree.right]].concat(this.trail) ); } @@ -52,7 +52,7 @@ export class Zipper { return new Zipper( this.tree.right, - [["right", this.tree.value, this.tree.left]].concat(this.trail) + [['right', this.tree.value, this.tree.left]].concat(this.trail) ); } diff --git a/exercises/zipper/zipper.js b/exercises/zipper/zipper.js index 2bad09a3bd..bbd19d1dd4 100644 --- a/exercises/zipper/zipper.js +++ b/exercises/zipper/zipper.js @@ -5,42 +5,42 @@ export class Zipper { constructor() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } static fromTree() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } toTree() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } value() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } left() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } right() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } up() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } setValue() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } setLeft() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } setRight() { - throw new Error("Remove this statement and implement this function"); + throw new Error('Remove this statement and implement this function'); } } diff --git a/exercises/zipper/zipper.spec.js b/exercises/zipper/zipper.spec.js index 9c9122a6dd..d3957e5431 100644 --- a/exercises/zipper/zipper.spec.js +++ b/exercises/zipper/zipper.spec.js @@ -48,10 +48,7 @@ describe('Zipper', () => { }); xtest('left, right and up', () => { - expect(zipper.left().up().right().up() - .left() - .right() - .value()).toEqual(3); + expect(zipper.left().up().right().up().left().right().value()).toEqual(3); }); xtest('setValue', () => { @@ -59,8 +56,7 @@ describe('Zipper', () => { }); xtest('setValue after traversing up', () => { - expect(zipper.left().right().up().setValue(5) - .toTree()).toEqual(t2); + expect(zipper.left().right().up().setValue(5).toTree()).toEqual(t2); }); xtest('setLeft with leaf', () => { diff --git a/scripts/format b/scripts/format new file mode 100755 index 0000000000..ab8246ca5a --- /dev/null +++ b/scripts/format @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +/* + * Run this script (from root directory): npx babel-node scripts/format + * + * This runs `prettier` on all applicable files, FORCES using the same version + * as the CI uses to check if the files have been formatted. + */ + +const shell = require('shelljs'); +const path = require('path'); +const { basename } = require('path'); + +const basedir = path.resolve(basename(__dirname), '..'); +const workflow = path.join( + basedir, + '.github', + 'workflows', + 'verify-code-formatting.yml' +); + +const versionLine = shell + .cat(workflow) + .stdout.split('\n') + .map((line) => line.trim()) + .find((line) => line.startsWith('EXERCISM_PRETTIER_VERSION:')); + +if (!versionLine) { + shell.echo('[format] Expected workflow to contain EXERCISM_PRETTIER_VERSION'); + shell.echo(`[format] Path: ${workflow}`); + shell.exit(-1); +} + +const EXERCISM_PRETTIER_VERSION = versionLine + .split(':')[1] + .trim() + .replace(/'/g, ''); + +const command = `npx "prettier@${EXERCISM_PRETTIER_VERSION}" --write "**/*.{js,jsx,ts,tsx,css,sass,scss,html,json,md,yml}"`; +shell.echo(`[format] ${command}`); + +const result = shell.exec(command); +shell.echo(`[format] ${result}`); diff --git a/scripts/helpers.js b/scripts/helpers.js index fdef3bbe3e..b15d6de591 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -3,13 +3,13 @@ * & is NOT intended to be run as a script. */ -const shell = require("shelljs"); -const path = require("path"); +const shell = require('shelljs'); +const path = require('path'); -const exerciseDirs = shell.ls("-d", path.join("exercises", "*")); +const exerciseDirs = shell.ls('-d', path.join('exercises', '*')); -export const assignments = shell.env["ASSIGNMENT"] - ? [shell.env["ASSIGNMENT"]] +export const assignments = shell.env['ASSIGNMENT'] + ? [shell.env['ASSIGNMENT']] : exerciseDirs .map((dir) => path.basename(dir)) .filter((exercise) => !exercise.deprecated); @@ -22,8 +22,8 @@ export function findExerciseDirectory(input) { export function hasStub(assignment) { return shell.test( - "-f", - path.join("exercises", assignment, `${assignment}.js`) + '-f', + path.join('exercises', assignment, `${assignment}.js`) ); } @@ -32,21 +32,21 @@ export function envIsThruthy(key, unset = false) { return unset; } - return !["0", 0, "false", false, null, "null"].includes(shell.env[key]); + return !['0', 0, 'false', false, null, 'null'].includes(shell.env[key]); } export function shouldPrepare() { - return envIsThruthy("PREPARE"); + return envIsThruthy('PREPARE'); } export function shouldCleanup() { - return envIsThruthy("CLEANUP"); + return envIsThruthy('CLEANUP'); } // Preapre all exercises (see above) & run a given command export function prepareAndRun(command, infoStr, failureStr) { if (shouldPrepare()) { - const assignment = shell.env["ASSIGNMENT"]; + const assignment = shell.env['ASSIGNMENT']; if (assignment) { prepare(assignment); @@ -74,26 +74,26 @@ export function prepareAndRun(command, infoStr, failureStr) { // Delete tmp directory export function cleanUp() { - shell.rm("-rf", "tmp_exercises"); + shell.rm('-rf', 'tmp_exercises'); } // These packages will be skipped while performing checksum -const SKIP_PACKAGES_FOR_CHECKSUM = ["shelljs", "@babel/node"]; +const SKIP_PACKAGES_FOR_CHECKSUM = ['shelljs', '@babel/node']; // Filter out some unwanted packages and create package.json for exercises export function createExercisePackageJson(assignmentVersion) { - const packageFile = shell.cat("package.json").toString(); + const packageFile = shell.cat('package.json').toString(); const packageJson = JSON.parse(packageFile); - packageJson["version"] = assignmentVersion; + packageJson['version'] = assignmentVersion; SKIP_PACKAGES_FOR_CHECKSUM.forEach( - (pkg) => delete packageJson["devDependencies"][pkg] + (pkg) => delete packageJson['devDependencies'][pkg] ); const shellStr = new shell.ShellString( - JSON.stringify(packageJson, null, 2) + "\n" + JSON.stringify(packageJson, null, 2) + '\n' ); - shellStr.to("exercise-package.json"); + shellStr.to('exercise-package.json'); } /** @@ -101,38 +101,38 @@ export function createExercisePackageJson(assignmentVersion) { */ export function prepare(assignment) { if (!assignment) { - shell.echo("[Failure] Assignment not provided"); + shell.echo('[Failure] Assignment not provided'); shell.exit(1); } - const exampleFile = path.join("exercises", assignment, "example.js"); - const specFile = path.join("exercises", assignment, `${assignment}.spec.js`); + const exampleFile = path.join('exercises', assignment, 'example.js'); + const specFile = path.join('exercises', assignment, `${assignment}.spec.js`); const specFileDestination = path.join( - "tmp_exercises", + 'tmp_exercises', `${assignment}.spec.js` ); - shell.mkdir("-p", path.join("tmp_exercises", "lib")); - shell.cp(exampleFile, path.join("tmp_exercises", `${assignment}.js`)); + shell.mkdir('-p', path.join('tmp_exercises', 'lib')); + shell.cp(exampleFile, path.join('tmp_exercises', `${assignment}.js`)); shell.cp(specFile, specFileDestination); // Enable tests shell - .sed(/x(test|it)\(/, "test(", specFileDestination) + .sed(/x(test|it)\(/, 'test(', specFileDestination) .to(specFileDestination); shell - .sed("xdescribe", "describe", specFileDestination) + .sed('xdescribe', 'describe', specFileDestination) .to(specFileDestination); - const libDir = path.join("exercises", assignment, "lib"); - if (shell.test("-d", libDir)) { - shell.cp(path.join(libDir, "*.js"), path.join("tmp_exercises", "lib")); + const libDir = path.join('exercises', assignment, 'lib'); + if (shell.test('-d', libDir)) { + shell.cp(path.join(libDir, '*.js'), path.join('tmp_exercises', 'lib')); } - shell.mkdir("-p", path.join("tmp_exercises", "data")); - const dataDir = path.join("exercises", assignment, "data"); + shell.mkdir('-p', path.join('tmp_exercises', 'data')); + const dataDir = path.join('exercises', assignment, 'data'); - if (shell.test("-d", dataDir)) { - shell.cp(path.join(dataDir, "*"), path.join("tmp_exercises", "data")); + if (shell.test('-d', dataDir)) { + shell.cp(path.join(dataDir, '*'), path.join('tmp_exercises', 'data')); } } @@ -153,15 +153,15 @@ export function registerExitHandler() { } //do something when app is closing - process.on("exit", exitHandler.bind(null, { cleanup: true })); + process.on('exit', exitHandler.bind(null, { cleanup: true })); //catches ctrl+c event - process.on("SIGINT", exitHandler.bind(null, { exit: true })); + process.on('SIGINT', exitHandler.bind(null, { exit: true })); // catches "kill pid" (for example: nodemon restart) - process.on("SIGUSR1", exitHandler.bind(null, { exit: true })); - process.on("SIGUSR2", exitHandler.bind(null, { exit: true })); + process.on('SIGUSR1', exitHandler.bind(null, { exit: true })); + process.on('SIGUSR2', exitHandler.bind(null, { exit: true })); //catches uncaught exceptions - process.on("uncaughtException", exitHandler.bind(null, { exit: true })); + process.on('uncaughtException', exitHandler.bind(null, { exit: true })); }