From f38d80dcd0a5a77dc902ff4ec3068cf811f99299 Mon Sep 17 00:00:00 2001 From: Abdullah Alger Date: Fri, 23 Oct 2015 13:06:22 +0200 Subject: [PATCH 001/272] Removed "test" from spec files to make it consistent with the ECMAScript repo tests. modified Makefile merged removed "test" from spec and the modification of Makefile --- Makefile | 2 +- accumulate/{accumulate-test.spec.js => accumulate.spec.js} | 0 allergies/{allergies-test.spec.js => allergies.spec.js} | 0 anagram/{anagram-test.spec.js => anagram.spec.js} | 0 .../{atbash-cipher-test.spec.js => atbash-cipher.spec.js} | 0 beer-song/{beer-song-test.spec.js => beer-song.spec.js} | 0 ...nary-search-tree-test.spec.js => binary-search-tree.spec.js} | 0 .../{binary-search-test.spec.js => binary-search.spec.js} | 0 binary/{binary-test.spec.js => binary.spec.js} | 0 bob/{bob-test.spec.js => bob.spec.js} | 0 .../{bracket-push-test.spec.js => bracket-push.spec.js} | 0 .../{circular-buffer-test.spec.js => circular-buffer.spec.js} | 0 clock/{clock-test.spec.js => clock.spec.js} | 0 .../{crypto-square-test.spec.js => crypto-square.spec.js} | 0 custom-set/{custom-set-test.spec.js => custom-set.spec.js} | 0 ...ce-of-squares-test.spec.js => difference-of-squares.spec.js} | 0 docs/TOOLS.md | 2 +- docs/WORKFLOW.md | 2 +- etl/{etl-test.spec.js => etl.spec.js} | 0 food-chain/{food-chain-test.spec.js => food-chain.spec.js} | 0 gigasecond/{gigasecond-test.spec.js => gigasecond.spec.js} | 0 .../{grade-school-test.spec.js => grade-school.spec.js} | 0 grains/{big-integer-test.spec.js => big-integer.spec.js} | 0 grains/{grains-test.spec.js => grains.spec.js} | 0 hamming/{hamming-test.spec.js => hamming.spec.js} | 0 hello-world/{hello-world-test.spec.js => hello-world.spec.js} | 0 hexadecimal/{hexadecimal-test.spec.js => hexadecimal.spec.js} | 0 ...ergarten-garden-test.spec.js => kindergarten-garden.spec.js} | 0 ...ries-product-test.spec.js => largest-series-product.spec.js} | 0 leap/{leap-test.spec.js => leap.spec.js} | 0 linked-list/{linked-list-test.spec.js => linked-list.spec.js} | 0 luhn/{luhn-test.spec.js => luhn.spec.js} | 0 matrix/{matrix-test.spec.js => matrix.spec.js} | 0 meetup/{meetup-test.spec.js => meetup.spec.js} | 0 nth-prime/{nth-prime-test.spec.js => nth-prime.spec.js} | 0 .../{nucleotide-count-test.spec.js => nucleotide-count.spec.js} | 0 ocr-numbers/{ocr-numbers-test.spec.js => ocr-numbers.spec.js} | 0 octal/{octal-test.spec.js => octal.spec.js} | 0 ...ndrome-products-test.spec.js => palindrome-products.spec.js} | 0 .../{pascals-triangle-test.spec.js => pascals-triangle.spec.js} | 0 .../{phone-number-test.spec.js => phone-number.spec.js} | 0 pig-latin/{pig-latin-test.spec.js => pig-latin.spec.js} | 0 .../{point-mutations-test.spec.js => point-mutations.spec.js} | 0 .../{prime-factors-test.spec.js => prime-factors.spec.js} | 0 ...agorean-triplet-test.spec.js => pythagorean-triplet.spec.js} | 0 .../{queen-attack-test.spec.js => queen-attack.spec.js} | 0 raindrops/{raindrops-test.spec.js => raindrops.spec.js} | 0 ...rna-transcription-test.spec.js => rna-transcription.spec.js} | 0 robot-name/{robot-name-test.spec.js => robot-name.spec.js} | 0 .../{robot-simulator-test.spec.js => robot-simulator.spec.js} | 0 .../{roman-numerals-test.spec.js => roman-numerals.spec.js} | 0 .../{saddle-points-test.spec.js => saddle-points.spec.js} | 0 say/{say-test.spec.js => say.spec.js} | 0 .../{scrabble-score-test.spec.js => scrabble-score.spec.js} | 0 .../{secret-handshake-test.spec.js => secret-handshake.spec.js} | 0 series/{series-test.spec.js => series.spec.js} | 0 sieve/{sieve-test.spec.js => sieve.spec.js} | 0 .../{simple-cipher-test.spec.js => simple-cipher.spec.js} | 0 space-age/{space-age-test.spec.js => space-age.spec.js} | 0 strain/{strain-test.spec.js => strain.spec.js} | 0 .../{sum-of-multiples-test.spec.js => sum-of-multiples.spec.js} | 0 triangle/{triangle-test.spec.js => triangle.spec.js} | 0 trinary/{trinary-test.spec.js => trinary.spec.js} | 0 two-bucket/{two-bucket-test.spec.js => two-bucket.spec.js} | 0 word-count/{word-count-test.spec.js => word-count.spec.js} | 0 wordy/{wordy-test.spec.js => wordy.spec.js} | 0 66 files changed, 3 insertions(+), 3 deletions(-) rename accumulate/{accumulate-test.spec.js => accumulate.spec.js} (100%) rename allergies/{allergies-test.spec.js => allergies.spec.js} (100%) rename anagram/{anagram-test.spec.js => anagram.spec.js} (100%) rename atbash-cipher/{atbash-cipher-test.spec.js => atbash-cipher.spec.js} (100%) rename beer-song/{beer-song-test.spec.js => beer-song.spec.js} (100%) rename binary-search-tree/{binary-search-tree-test.spec.js => binary-search-tree.spec.js} (100%) rename binary-search/{binary-search-test.spec.js => binary-search.spec.js} (100%) rename binary/{binary-test.spec.js => binary.spec.js} (100%) rename bob/{bob-test.spec.js => bob.spec.js} (100%) rename bracket-push/{bracket-push-test.spec.js => bracket-push.spec.js} (100%) rename circular-buffer/{circular-buffer-test.spec.js => circular-buffer.spec.js} (100%) rename clock/{clock-test.spec.js => clock.spec.js} (100%) rename crypto-square/{crypto-square-test.spec.js => crypto-square.spec.js} (100%) rename custom-set/{custom-set-test.spec.js => custom-set.spec.js} (100%) rename difference-of-squares/{difference-of-squares-test.spec.js => difference-of-squares.spec.js} (100%) rename etl/{etl-test.spec.js => etl.spec.js} (100%) rename food-chain/{food-chain-test.spec.js => food-chain.spec.js} (100%) rename gigasecond/{gigasecond-test.spec.js => gigasecond.spec.js} (100%) rename grade-school/{grade-school-test.spec.js => grade-school.spec.js} (100%) rename grains/{big-integer-test.spec.js => big-integer.spec.js} (100%) rename grains/{grains-test.spec.js => grains.spec.js} (100%) rename hamming/{hamming-test.spec.js => hamming.spec.js} (100%) rename hello-world/{hello-world-test.spec.js => hello-world.spec.js} (100%) rename hexadecimal/{hexadecimal-test.spec.js => hexadecimal.spec.js} (100%) rename kindergarten-garden/{kindergarten-garden-test.spec.js => kindergarten-garden.spec.js} (100%) rename largest-series-product/{largest-series-product-test.spec.js => largest-series-product.spec.js} (100%) rename leap/{leap-test.spec.js => leap.spec.js} (100%) rename linked-list/{linked-list-test.spec.js => linked-list.spec.js} (100%) rename luhn/{luhn-test.spec.js => luhn.spec.js} (100%) rename matrix/{matrix-test.spec.js => matrix.spec.js} (100%) rename meetup/{meetup-test.spec.js => meetup.spec.js} (100%) rename nth-prime/{nth-prime-test.spec.js => nth-prime.spec.js} (100%) rename nucleotide-count/{nucleotide-count-test.spec.js => nucleotide-count.spec.js} (100%) rename ocr-numbers/{ocr-numbers-test.spec.js => ocr-numbers.spec.js} (100%) rename octal/{octal-test.spec.js => octal.spec.js} (100%) rename palindrome-products/{palindrome-products-test.spec.js => palindrome-products.spec.js} (100%) rename pascals-triangle/{pascals-triangle-test.spec.js => pascals-triangle.spec.js} (100%) rename phone-number/{phone-number-test.spec.js => phone-number.spec.js} (100%) rename pig-latin/{pig-latin-test.spec.js => pig-latin.spec.js} (100%) rename point-mutations/{point-mutations-test.spec.js => point-mutations.spec.js} (100%) rename prime-factors/{prime-factors-test.spec.js => prime-factors.spec.js} (100%) rename pythagorean-triplet/{pythagorean-triplet-test.spec.js => pythagorean-triplet.spec.js} (100%) rename queen-attack/{queen-attack-test.spec.js => queen-attack.spec.js} (100%) rename raindrops/{raindrops-test.spec.js => raindrops.spec.js} (100%) rename rna-transcription/{rna-transcription-test.spec.js => rna-transcription.spec.js} (100%) rename robot-name/{robot-name-test.spec.js => robot-name.spec.js} (100%) rename robot-simulator/{robot-simulator-test.spec.js => robot-simulator.spec.js} (100%) rename roman-numerals/{roman-numerals-test.spec.js => roman-numerals.spec.js} (100%) rename saddle-points/{saddle-points-test.spec.js => saddle-points.spec.js} (100%) rename say/{say-test.spec.js => say.spec.js} (100%) rename scrabble-score/{scrabble-score-test.spec.js => scrabble-score.spec.js} (100%) rename secret-handshake/{secret-handshake-test.spec.js => secret-handshake.spec.js} (100%) rename series/{series-test.spec.js => series.spec.js} (100%) rename sieve/{sieve-test.spec.js => sieve.spec.js} (100%) rename simple-cipher/{simple-cipher-test.spec.js => simple-cipher.spec.js} (100%) rename space-age/{space-age-test.spec.js => space-age.spec.js} (100%) rename strain/{strain-test.spec.js => strain.spec.js} (100%) rename sum-of-multiples/{sum-of-multiples-test.spec.js => sum-of-multiples.spec.js} (100%) rename triangle/{triangle-test.spec.js => triangle.spec.js} (100%) rename trinary/{trinary-test.spec.js => trinary.spec.js} (100%) rename two-bucket/{two-bucket-test.spec.js => two-bucket.spec.js} (100%) rename word-count/{word-count-test.spec.js => word-count.spec.js} (100%) rename wordy/{wordy-test.spec.js => wordy.spec.js} (100%) diff --git a/Makefile b/Makefile index eca60e80..ade205df 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ OUTDIR := $(shell mktemp -d "$(TMPDIR)/$(ASSIGNMENT).XXXXXXXXXX") # language specific config (tweakable per language) FILEEXT := "js" EXAMPLE := "example.$(FILEEXT)" -TSTFILE := "$(subst _,-,$(ASSIGNMENT))-test.spec.$(FILEEXT)" +TSTFILE := "$(subst _,-,$(ASSIGNMENT)).spec.$(FILEEXT)" # development dependencies node_modules: package.json diff --git a/accumulate/accumulate-test.spec.js b/accumulate/accumulate.spec.js similarity index 100% rename from accumulate/accumulate-test.spec.js rename to accumulate/accumulate.spec.js diff --git a/allergies/allergies-test.spec.js b/allergies/allergies.spec.js similarity index 100% rename from allergies/allergies-test.spec.js rename to allergies/allergies.spec.js diff --git a/anagram/anagram-test.spec.js b/anagram/anagram.spec.js similarity index 100% rename from anagram/anagram-test.spec.js rename to anagram/anagram.spec.js diff --git a/atbash-cipher/atbash-cipher-test.spec.js b/atbash-cipher/atbash-cipher.spec.js similarity index 100% rename from atbash-cipher/atbash-cipher-test.spec.js rename to atbash-cipher/atbash-cipher.spec.js diff --git a/beer-song/beer-song-test.spec.js b/beer-song/beer-song.spec.js similarity index 100% rename from beer-song/beer-song-test.spec.js rename to beer-song/beer-song.spec.js diff --git a/binary-search-tree/binary-search-tree-test.spec.js b/binary-search-tree/binary-search-tree.spec.js similarity index 100% rename from binary-search-tree/binary-search-tree-test.spec.js rename to binary-search-tree/binary-search-tree.spec.js diff --git a/binary-search/binary-search-test.spec.js b/binary-search/binary-search.spec.js similarity index 100% rename from binary-search/binary-search-test.spec.js rename to binary-search/binary-search.spec.js diff --git a/binary/binary-test.spec.js b/binary/binary.spec.js similarity index 100% rename from binary/binary-test.spec.js rename to binary/binary.spec.js diff --git a/bob/bob-test.spec.js b/bob/bob.spec.js similarity index 100% rename from bob/bob-test.spec.js rename to bob/bob.spec.js diff --git a/bracket-push/bracket-push-test.spec.js b/bracket-push/bracket-push.spec.js similarity index 100% rename from bracket-push/bracket-push-test.spec.js rename to bracket-push/bracket-push.spec.js diff --git a/circular-buffer/circular-buffer-test.spec.js b/circular-buffer/circular-buffer.spec.js similarity index 100% rename from circular-buffer/circular-buffer-test.spec.js rename to circular-buffer/circular-buffer.spec.js diff --git a/clock/clock-test.spec.js b/clock/clock.spec.js similarity index 100% rename from clock/clock-test.spec.js rename to clock/clock.spec.js diff --git a/crypto-square/crypto-square-test.spec.js b/crypto-square/crypto-square.spec.js similarity index 100% rename from crypto-square/crypto-square-test.spec.js rename to crypto-square/crypto-square.spec.js diff --git a/custom-set/custom-set-test.spec.js b/custom-set/custom-set.spec.js similarity index 100% rename from custom-set/custom-set-test.spec.js rename to custom-set/custom-set.spec.js diff --git a/difference-of-squares/difference-of-squares-test.spec.js b/difference-of-squares/difference-of-squares.spec.js similarity index 100% rename from difference-of-squares/difference-of-squares-test.spec.js rename to difference-of-squares/difference-of-squares.spec.js diff --git a/docs/TOOLS.md b/docs/TOOLS.md index af718e4c..57ea9f69 100644 --- a/docs/TOOLS.md +++ b/docs/TOOLS.md @@ -26,7 +26,7 @@ If you have a paid version of Visual Studio, you should install the [Web Essenti You can run the unit tests from a node.js command line using the batch file in the project. ``` -C:\Src\exercises\javascript>test example\bob-test.spec.js +C:\Src\exercises\javascript>test example\bob.spec.js ................. Finished in 0.02 seconds diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md index 1690f72a..7e3a6419 100644 --- a/docs/WORKFLOW.md +++ b/docs/WORKFLOW.md @@ -3,5 +3,5 @@ Execute the tests with: ```bash -$ jasmine-node bob-test.spec.js +$ jasmine-node bob.spec.js ``` diff --git a/etl/etl-test.spec.js b/etl/etl.spec.js similarity index 100% rename from etl/etl-test.spec.js rename to etl/etl.spec.js diff --git a/food-chain/food-chain-test.spec.js b/food-chain/food-chain.spec.js similarity index 100% rename from food-chain/food-chain-test.spec.js rename to food-chain/food-chain.spec.js diff --git a/gigasecond/gigasecond-test.spec.js b/gigasecond/gigasecond.spec.js similarity index 100% rename from gigasecond/gigasecond-test.spec.js rename to gigasecond/gigasecond.spec.js diff --git a/grade-school/grade-school-test.spec.js b/grade-school/grade-school.spec.js similarity index 100% rename from grade-school/grade-school-test.spec.js rename to grade-school/grade-school.spec.js diff --git a/grains/big-integer-test.spec.js b/grains/big-integer.spec.js similarity index 100% rename from grains/big-integer-test.spec.js rename to grains/big-integer.spec.js diff --git a/grains/grains-test.spec.js b/grains/grains.spec.js similarity index 100% rename from grains/grains-test.spec.js rename to grains/grains.spec.js diff --git a/hamming/hamming-test.spec.js b/hamming/hamming.spec.js similarity index 100% rename from hamming/hamming-test.spec.js rename to hamming/hamming.spec.js diff --git a/hello-world/hello-world-test.spec.js b/hello-world/hello-world.spec.js similarity index 100% rename from hello-world/hello-world-test.spec.js rename to hello-world/hello-world.spec.js diff --git a/hexadecimal/hexadecimal-test.spec.js b/hexadecimal/hexadecimal.spec.js similarity index 100% rename from hexadecimal/hexadecimal-test.spec.js rename to hexadecimal/hexadecimal.spec.js diff --git a/kindergarten-garden/kindergarten-garden-test.spec.js b/kindergarten-garden/kindergarten-garden.spec.js similarity index 100% rename from kindergarten-garden/kindergarten-garden-test.spec.js rename to kindergarten-garden/kindergarten-garden.spec.js diff --git a/largest-series-product/largest-series-product-test.spec.js b/largest-series-product/largest-series-product.spec.js similarity index 100% rename from largest-series-product/largest-series-product-test.spec.js rename to largest-series-product/largest-series-product.spec.js diff --git a/leap/leap-test.spec.js b/leap/leap.spec.js similarity index 100% rename from leap/leap-test.spec.js rename to leap/leap.spec.js diff --git a/linked-list/linked-list-test.spec.js b/linked-list/linked-list.spec.js similarity index 100% rename from linked-list/linked-list-test.spec.js rename to linked-list/linked-list.spec.js diff --git a/luhn/luhn-test.spec.js b/luhn/luhn.spec.js similarity index 100% rename from luhn/luhn-test.spec.js rename to luhn/luhn.spec.js diff --git a/matrix/matrix-test.spec.js b/matrix/matrix.spec.js similarity index 100% rename from matrix/matrix-test.spec.js rename to matrix/matrix.spec.js diff --git a/meetup/meetup-test.spec.js b/meetup/meetup.spec.js similarity index 100% rename from meetup/meetup-test.spec.js rename to meetup/meetup.spec.js diff --git a/nth-prime/nth-prime-test.spec.js b/nth-prime/nth-prime.spec.js similarity index 100% rename from nth-prime/nth-prime-test.spec.js rename to nth-prime/nth-prime.spec.js diff --git a/nucleotide-count/nucleotide-count-test.spec.js b/nucleotide-count/nucleotide-count.spec.js similarity index 100% rename from nucleotide-count/nucleotide-count-test.spec.js rename to nucleotide-count/nucleotide-count.spec.js diff --git a/ocr-numbers/ocr-numbers-test.spec.js b/ocr-numbers/ocr-numbers.spec.js similarity index 100% rename from ocr-numbers/ocr-numbers-test.spec.js rename to ocr-numbers/ocr-numbers.spec.js diff --git a/octal/octal-test.spec.js b/octal/octal.spec.js similarity index 100% rename from octal/octal-test.spec.js rename to octal/octal.spec.js diff --git a/palindrome-products/palindrome-products-test.spec.js b/palindrome-products/palindrome-products.spec.js similarity index 100% rename from palindrome-products/palindrome-products-test.spec.js rename to palindrome-products/palindrome-products.spec.js diff --git a/pascals-triangle/pascals-triangle-test.spec.js b/pascals-triangle/pascals-triangle.spec.js similarity index 100% rename from pascals-triangle/pascals-triangle-test.spec.js rename to pascals-triangle/pascals-triangle.spec.js diff --git a/phone-number/phone-number-test.spec.js b/phone-number/phone-number.spec.js similarity index 100% rename from phone-number/phone-number-test.spec.js rename to phone-number/phone-number.spec.js diff --git a/pig-latin/pig-latin-test.spec.js b/pig-latin/pig-latin.spec.js similarity index 100% rename from pig-latin/pig-latin-test.spec.js rename to pig-latin/pig-latin.spec.js diff --git a/point-mutations/point-mutations-test.spec.js b/point-mutations/point-mutations.spec.js similarity index 100% rename from point-mutations/point-mutations-test.spec.js rename to point-mutations/point-mutations.spec.js diff --git a/prime-factors/prime-factors-test.spec.js b/prime-factors/prime-factors.spec.js similarity index 100% rename from prime-factors/prime-factors-test.spec.js rename to prime-factors/prime-factors.spec.js diff --git a/pythagorean-triplet/pythagorean-triplet-test.spec.js b/pythagorean-triplet/pythagorean-triplet.spec.js similarity index 100% rename from pythagorean-triplet/pythagorean-triplet-test.spec.js rename to pythagorean-triplet/pythagorean-triplet.spec.js diff --git a/queen-attack/queen-attack-test.spec.js b/queen-attack/queen-attack.spec.js similarity index 100% rename from queen-attack/queen-attack-test.spec.js rename to queen-attack/queen-attack.spec.js diff --git a/raindrops/raindrops-test.spec.js b/raindrops/raindrops.spec.js similarity index 100% rename from raindrops/raindrops-test.spec.js rename to raindrops/raindrops.spec.js diff --git a/rna-transcription/rna-transcription-test.spec.js b/rna-transcription/rna-transcription.spec.js similarity index 100% rename from rna-transcription/rna-transcription-test.spec.js rename to rna-transcription/rna-transcription.spec.js diff --git a/robot-name/robot-name-test.spec.js b/robot-name/robot-name.spec.js similarity index 100% rename from robot-name/robot-name-test.spec.js rename to robot-name/robot-name.spec.js diff --git a/robot-simulator/robot-simulator-test.spec.js b/robot-simulator/robot-simulator.spec.js similarity index 100% rename from robot-simulator/robot-simulator-test.spec.js rename to robot-simulator/robot-simulator.spec.js diff --git a/roman-numerals/roman-numerals-test.spec.js b/roman-numerals/roman-numerals.spec.js similarity index 100% rename from roman-numerals/roman-numerals-test.spec.js rename to roman-numerals/roman-numerals.spec.js diff --git a/saddle-points/saddle-points-test.spec.js b/saddle-points/saddle-points.spec.js similarity index 100% rename from saddle-points/saddle-points-test.spec.js rename to saddle-points/saddle-points.spec.js diff --git a/say/say-test.spec.js b/say/say.spec.js similarity index 100% rename from say/say-test.spec.js rename to say/say.spec.js diff --git a/scrabble-score/scrabble-score-test.spec.js b/scrabble-score/scrabble-score.spec.js similarity index 100% rename from scrabble-score/scrabble-score-test.spec.js rename to scrabble-score/scrabble-score.spec.js diff --git a/secret-handshake/secret-handshake-test.spec.js b/secret-handshake/secret-handshake.spec.js similarity index 100% rename from secret-handshake/secret-handshake-test.spec.js rename to secret-handshake/secret-handshake.spec.js diff --git a/series/series-test.spec.js b/series/series.spec.js similarity index 100% rename from series/series-test.spec.js rename to series/series.spec.js diff --git a/sieve/sieve-test.spec.js b/sieve/sieve.spec.js similarity index 100% rename from sieve/sieve-test.spec.js rename to sieve/sieve.spec.js diff --git a/simple-cipher/simple-cipher-test.spec.js b/simple-cipher/simple-cipher.spec.js similarity index 100% rename from simple-cipher/simple-cipher-test.spec.js rename to simple-cipher/simple-cipher.spec.js diff --git a/space-age/space-age-test.spec.js b/space-age/space-age.spec.js similarity index 100% rename from space-age/space-age-test.spec.js rename to space-age/space-age.spec.js diff --git a/strain/strain-test.spec.js b/strain/strain.spec.js similarity index 100% rename from strain/strain-test.spec.js rename to strain/strain.spec.js diff --git a/sum-of-multiples/sum-of-multiples-test.spec.js b/sum-of-multiples/sum-of-multiples.spec.js similarity index 100% rename from sum-of-multiples/sum-of-multiples-test.spec.js rename to sum-of-multiples/sum-of-multiples.spec.js diff --git a/triangle/triangle-test.spec.js b/triangle/triangle.spec.js similarity index 100% rename from triangle/triangle-test.spec.js rename to triangle/triangle.spec.js diff --git a/trinary/trinary-test.spec.js b/trinary/trinary.spec.js similarity index 100% rename from trinary/trinary-test.spec.js rename to trinary/trinary.spec.js diff --git a/two-bucket/two-bucket-test.spec.js b/two-bucket/two-bucket.spec.js similarity index 100% rename from two-bucket/two-bucket-test.spec.js rename to two-bucket/two-bucket.spec.js diff --git a/word-count/word-count-test.spec.js b/word-count/word-count.spec.js similarity index 100% rename from word-count/word-count-test.spec.js rename to word-count/word-count.spec.js diff --git a/wordy/wordy-test.spec.js b/wordy/wordy.spec.js similarity index 100% rename from wordy/wordy-test.spec.js rename to wordy/wordy.spec.js From 301dd0069e5cd60f336c6a622fac1ea9f3fd1357 Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Fri, 23 Oct 2015 00:52:39 -0700 Subject: [PATCH 002/272] circular-buffer: Test forced writes on non-full buffer Other language tracks have been adding this: Ruby: https://github.com/exercism/xruby/commit/5560b7a0e032bdf4bca753d4aba4625340853d1c Go: https://github.com/exercism/xgo/commit/6b41d2f925a7b35140701a8290e7d9a6155ac315 Rust: https://github.com/exercism/xrust/commit/e4990f1b0e8c9d16053012b13aaaeb03ac141383 Seems prudent for Javascript to test it as well. This will see if any solutions are unconditionally dropping when overwriting (that would drop elements from non-full buffers) In addition, the example solution has to be fixed in light of this new test. The example solution was checking for buffer full *after* a force write was performed rather than *before*. Checking for full after a write incorrectly updates the read point on a buffer that was non-full but fills due to the forced write. --- circular-buffer/circular-buffer.spec.js | 9 +++++++++ circular-buffer/example.js | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/circular-buffer/circular-buffer.spec.js b/circular-buffer/circular-buffer.spec.js index 5aa6197b..fa9b6dfc 100644 --- a/circular-buffer/circular-buffer.spec.js +++ b/circular-buffer/circular-buffer.spec.js @@ -82,6 +82,15 @@ describe('CircularBuffer', function() { expect(buffer.read).toThrow(bufferEmptyException()); }); + xit('forced writes act like write in a non-full buffer', function() { + var buffer = circularBuffer(2); + buffer.write('1'); + buffer.forceWrite('2'); + expect(buffer.read()).toBe('1'); + expect(buffer.read()).toBe('2'); + expect(buffer.read).toThrow(bufferEmptyException()); + }); + xit('alternate force write and read into full buffer', function() { var buffer = circularBuffer(5); [1,2,3].map(function(i) { buffer.write(i.toString()); }); diff --git a/circular-buffer/example.js b/circular-buffer/example.js index 2c9588b6..c289472d 100644 --- a/circular-buffer/example.js +++ b/circular-buffer/example.js @@ -22,8 +22,8 @@ function CircularBuffer(capacity) { forceWrite: function(data) { updateBuffer(data, function(){ - buffer[writePoint] = data; if (isBufferFull()) { updateReadPoint(); } + buffer[writePoint] = data; }); }, From 40b3813f8f31c16d1905c94ce5312f9c305b3c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Sun, 25 Oct 2015 16:33:11 +0100 Subject: [PATCH 003/272] Ignore all tests but first --- grains/grains.spec.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/grains/grains.spec.js b/grains/grains.spec.js index 69b39c10..a66a97c4 100644 --- a/grains/grains.spec.js +++ b/grains/grains.spec.js @@ -37,31 +37,31 @@ describe('Grains', function () { expect(grains.square(1)).toBe('1'); }); - it('square 2', function () { + xit('square 2', function () { expect(grains.square(2)).toBe('2'); }); - it('square 3', function () { + xit('square 3', function () { expect(grains.square(3)).toBe('4'); }); - it('square 4', function () { + xit('square 4', function () { expect(grains.square(4)).toBe('8'); }); - it('square 16', function () { + xit('square 16', function () { expect(grains.square(16)).toBe('32768'); }); - it('square 32', function () { + xit('square 32', function () { expect(grains.square(32)).toBe('2147483648'); }); - it('square 64', function () { + xit('square 64', function () { expect(grains.square(64)).toBe('9223372036854775808'); }); - it('total', function () { + xit('total', function () { expect(grains.total()).toBe('18446744073709551615'); }); }); From f4662b58b0da566d3eb0a133d2c0cef80a048fa6 Mon Sep 17 00:00:00 2001 From: Alex Pounds Date: Tue, 20 Oct 2015 23:30:51 -0400 Subject: [PATCH 004/272] Extra tests for the 'binary' exercise, as discussed in https://github.com/exercism/x-common/issues/95 This expands the JavaScript test for the 'binary' exercise to include the same examples as the Ruby equivalent. The example solution has also been updated so it passes the new tests. --- binary/binary.spec.js | 16 +++++++++++++--- binary/example.js | 6 +++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/binary/binary.spec.js b/binary/binary.spec.js index c674b074..63ed387c 100644 --- a/binary/binary.spec.js +++ b/binary/binary.spec.js @@ -1,8 +1,11 @@ var Binary = require('./binary'); describe('binary', function() { + it('0 is decimal 0', function() { + expect(new Binary('0').toDecimal()).toEqual(0); + }); - it('1 is decimal 1', function() { + xit('1 is decimal 1', function() { expect(new Binary('1').toDecimal()).toEqual(1); }); @@ -30,8 +33,15 @@ describe('binary', function() { expect(new Binary('10001101000').toDecimal()).toEqual(1128); }); - xit('carrot is decimal 0', function() { + xit('00011111 is decimal 31', function() { + expect(new Binary('00011111').toDecimal()).toEqual(31); + }); + + xit('invalid inputs are decimal 0', function() { expect(new Binary('carrot').toDecimal()).toEqual(0); + expect(new Binary('012').toDecimal()).toEqual(0); + expect(new Binary('10nope').toDecimal()).toEqual(0); + expect(new Binary('nope10').toDecimal()).toEqual(0); }); -}); \ No newline at end of file +}); diff --git a/binary/example.js b/binary/example.js index e4c24002..8174186e 100644 --- a/binary/example.js +++ b/binary/example.js @@ -3,7 +3,11 @@ module.exports = Binary; function Binary(binary) { - this.binary = parseInt(binary, 2); + if (binary.match(/^[01]*$/)) { + this.binary = parseInt(binary, 2); + } else { + this.binary = 0; + } } Binary.prototype.toDecimal = function () { From 5f2dcd8bf03ec21cf65f0451641dc62d904b2af7 Mon Sep 17 00:00:00 2001 From: Thomas Farla Date: Fri, 30 Oct 2015 09:05:43 +0100 Subject: [PATCH 005/272] Test immutability of the gigasecond I have seen submissions which mutate the original date and return that. This works for the current test suite. However, when the `date` method gets called multiple times. That solution adds another gigasecond on a date where one is already applied. For example. One might implement the date function like this: ``` Gigasecond.prototype.date = function() { b = new Date(this.birthday.setSeconds(this.birthday.getSeconds() + 1000000000 )); return new Date(b.getFullYear(), b.getMonth(), b.getDate()); }; ``` ``` var d = new Gigasecond(new Date(1995, 8, 27)) d.date() // Sat Jun 05 2027 00:00:00 GMT+0200 (CEST) d.date() // Tue Feb 11 2059 00:00:00 GMT+0100 (CET) ``` --- gigasecond/gigasecond.spec.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gigasecond/gigasecond.spec.js b/gigasecond/gigasecond.spec.js index d1b643b4..a426764b 100644 --- a/gigasecond/gigasecond.spec.js +++ b/gigasecond/gigasecond.spec.js @@ -20,4 +20,10 @@ describe('Gigasecond', function() { expect(gs.date()).toEqual(expectedDate); }); -}); \ No newline at end of file + xit('test 4', function() { + var gs = new Gigasecond(new Date(1959, 6, 19)); + var expectedDate = new Date(1991, 2, 27); + gs.date(); + expect(gs.date()).toEqual(expectedDate); + }); +}); From 301796afd7f3e4e7a3f71f52edf9ae9f12165d17 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Tue, 3 Nov 2015 07:22:10 -0500 Subject: [PATCH 006/272] removed BigInt import in grains --- grains/grains.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/grains/grains.spec.js b/grains/grains.spec.js index a66a97c4..774de4bb 100644 --- a/grains/grains.spec.js +++ b/grains/grains.spec.js @@ -27,7 +27,6 @@ * See its tests in this folder for a quick primer on how to use it! ( : */ -var BigInt = require('./big-integer'); var Grains = require('./grains'); describe('Grains', function () { From b984811bcd8b53a7845bb792a99f1c4b23a55fb9 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sun, 15 Nov 2015 12:40:17 -0500 Subject: [PATCH 007/272] fixed gigasecond example and test to conform to metadata-- dont round dates down --- Makefile | 2 +- gigasecond/example.js | 11 ++--------- gigasecond/gigasecond.spec.js | 26 ++++++++++++++------------ 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index ade205df..53d05b05 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # assignments ASSIGNMENT ?= "" -IGNOREDIRS := "^(\.git|docs|bin|node_modules)$$" +IGNOREDIRS := "^(\.git|docs|bin|node_modules|.idea)$$" ASSIGNMENTS = $(shell find . -maxdepth 1 -mindepth 1 -type d | cut -d'/' -f2 | sort | grep -Ev $(IGNOREDIRS)) # output directories diff --git a/gigasecond/example.js b/gigasecond/example.js index 9ddfb7dd..f36189f8 100644 --- a/gigasecond/example.js +++ b/gigasecond/example.js @@ -5,15 +5,8 @@ function Gigasecond(dateOfBirth) { this.date = function() { var gigasecondDate = new Date(this.dateOfBirth.getTime() + 1000000000000); - return this.roundDownToDay(gigasecondDate); - }; - - this.roundDownToDay = function(date) { - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - return date; + return gigasecondDate; }; } -module.exports = Gigasecond; \ No newline at end of file +module.exports = Gigasecond; diff --git a/gigasecond/gigasecond.spec.js b/gigasecond/gigasecond.spec.js index a426764b..5cf3384c 100644 --- a/gigasecond/gigasecond.spec.js +++ b/gigasecond/gigasecond.spec.js @@ -2,28 +2,30 @@ var Gigasecond = require('./gigasecond'); describe('Gigasecond', function() { - it('test 1', function() { - var gs = new Gigasecond(new Date(2011, 3, 25)); - var expectedDate = new Date(2043, 0, 1); + it('tells a gigasecond anniversary since midnight', function() { + var gs = new Gigasecond(new Date(Date.UTC(2015, 8, 14))); + var expectedDate = new Date(Date.UTC(2047, 4, 23, 1, 46, 40)); expect(gs.date()).toEqual(expectedDate); }); - xit('test 2', function() { - var gs = new Gigasecond(new Date(1977, 5, 13)); - var expectedDate = new Date(2009, 1, 19); + xit('tells the anniversary is next day when you are born at night', function() { + var gs = new Gigasecond(new Date(Date.UTC(2015, 8, 14, 23, 59, 59))); + var expectedDate = new Date(Date.UTC(2047, 4, 24, 1, 46, 39)); expect(gs.date()).toEqual(expectedDate); }); - xit('test 3', function() { - var gs = new Gigasecond(new Date(1959, 6, 19)); - var expectedDate = new Date(1991, 2, 27); + xit('even works before 1970 (beginning of Unix epoch)', function() { + var gs = new Gigasecond(new Date(Date.UTC(1959, 6, 19, 5, 13, 45))); + var expectedDate = new Date(Date.UTC(1991, 2, 27, 7, 0, 25)); expect(gs.date()).toEqual(expectedDate); }); - xit('test 4', function() { - var gs = new Gigasecond(new Date(1959, 6, 19)); - var expectedDate = new Date(1991, 2, 27); + xit('make sure calling "date" doesn\'t mutate value', function() { + var gs = new Gigasecond(new Date(Date.UTC(1959, 6, 19, 5, 13, 45))); + var expectedDate = new Date(Date.UTC(1991, 2, 27, 7, 0, 25)); gs.date(); expect(gs.date()).toEqual(expectedDate); }); }); + + From 052ebf1fec72261c8522f007f5f869065df8104c Mon Sep 17 00:00:00 2001 From: "Zachary R. Smith" Date: Fri, 2 Oct 2015 00:14:39 -0400 Subject: [PATCH 008/272] JS crypto_square: delete 2 tests The README has nothing about `normalizeCiphertext()`. Also, the first of these tests makes no sense...where did the expect "s" come from? --- crypto-square/crypto-square.spec.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/crypto-square/crypto-square.spec.js b/crypto-square/crypto-square.spec.js index b184febe..2682339a 100644 --- a/crypto-square/crypto-square.spec.js +++ b/crypto-square/crypto-square.spec.js @@ -50,15 +50,4 @@ describe('Crypto',function() { var crypto = new Crypto('We all know interspecies romance is weird.'); expect(crypto.ciphertext()).toEqual('wneiaweoreneawssciliprerlneoidktcms'); }); - - xit('normalized cipher text',function() { - var crypto = new Crypto('Madness, and then illumination.'); - expect(crypto.normalizeCiphertext()).toEqual('msemoa anindn inndla etltsh ui'); - }); - - xit('more normalized cipher text',function() { - var crypto = new Crypto('Vampires are people too!'); - expect(crypto.normalizeCiphertext()).toEqual('vrela epems etpao oirpo'); - }); - }); From 246b53ce6efb93f0c4ed3d7d33a4c2f73a3f7338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 24 Nov 2015 22:35:01 +0100 Subject: [PATCH 009/272] Make tests require the solution to export a classy function --- anagram/anagram.spec.js | 24 ++++++++++++------------ anagram/example.js | 18 ++++++++---------- beer-song/beer-song.spec.js | 15 ++++++++------- beer-song/example.js | 10 +++++++--- etl/etl.spec.js | 11 ++++++----- etl/example.js | 7 ++++++- food-chain/example.js | 17 +++++++++-------- food-chain/food-chain.spec.js | 3 ++- hamming/example.js | 7 ++++++- hamming/hamming.spec.js | 19 ++++++++++--------- leap/example.js | 16 ++++++++++++---- leap/leap.spec.js | 26 +++++++++++++++++--------- word-count/example.js | 7 ++++++- word-count/word-count.spec.js | 30 ++++++++++++++++-------------- 14 files changed, 125 insertions(+), 85 deletions(-) diff --git a/anagram/anagram.spec.js b/anagram/anagram.spec.js index 9dc5d11b..ca71bd97 100644 --- a/anagram/anagram.spec.js +++ b/anagram/anagram.spec.js @@ -1,79 +1,79 @@ -var anagram = require('./anagram'); +var Anagram = require('./anagram'); describe('Anagram', function() { it('no matches',function() { - var subject = anagram('diaper'); + var subject = new Anagram('diaper'); var matches = subject.matches([ 'hello', 'world', 'zombies', 'pants']); expect(matches).toEqual([]); }); xit('detects simple anagram',function() { - var subject = anagram('ant'); + var subject = new Anagram('ant'); var matches = subject.matches(['tan', 'stand', 'at']); expect(matches).toEqual(['tan']); }); xit('does not detect false positives',function() { - var subject = anagram('galea'); + var subject = new Anagram('galea'); var matches = subject.matches(['eagle']); expect(matches).toEqual([]); }); xit('detects multiple anagrams',function() { - var subject = anagram('master'); + var subject = new Anagram('master'); var matches = subject.matches(['stream', 'pigeon', 'maters']); expect(matches).toEqual(['stream', 'maters']); }); xit('does not detect anagram subsets',function() { - var subject = anagram('good'); + var subject = new Anagram('good'); var matches = subject.matches(['dog', 'goody']); expect(matches).toEqual([]); }); xit('detects anagram',function() { - var subject = anagram('listen'); + var subject = new Anagram('listen'); var matches = subject.matches(['enlists', 'google', 'inlets', 'banana']); expect(matches).toEqual(['inlets']); }); xit('detects multiple anagrams',function() { - var subject = anagram('allergy'); + var subject = new Anagram('allergy'); var matches = subject.matches(['gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading']); expect(matches).toEqual(['gallery', 'regally', 'largely']); }); xit('detects anagrams case-insensitively',function() { - var subject = anagram('Orchestra'); + var subject = new Anagram('Orchestra'); var matches = subject.matches(['cashregister', 'Carthorse', 'radishes']); expect(matches).toEqual(['Carthorse']); }); xit('does not detect a word as its own anagram',function() { - var subject = anagram('banana'); + var subject = new Anagram('banana'); var matches = subject.matches(['Banana']); expect(matches).toEqual([]); }); xit('matches() accepts string arguments',function() { - var subject = anagram('ant'); + var subject = new Anagram('ant'); var matches = subject.matches('stand', 'tan', 'at'); expect(matches).toEqual(['tan']); }); xit('matches() accepts single string argument',function() { - var subject = anagram('ant'); + var subject = new Anagram('ant'); var matches = subject.matches('tan'); expect(matches).toEqual(['tan']); diff --git a/anagram/example.js b/anagram/example.js index 55a8ffc5..daddd20c 100644 --- a/anagram/example.js +++ b/anagram/example.js @@ -1,19 +1,15 @@ 'use strict'; -module.exports = anagram; -function anagram(word) { - return { - // public API - matches: matches.bind(this, word) - }; +function Anagram(word) { + this.word = word; } -function matches(word, words) { - words = Array.isArray(words) ? words : [].slice.call(arguments, 1); +Anagram.prototype.matches = function (words) { + words = Array.isArray(words) ? words : [].slice.call(arguments, 0); return words.filter(function (candidate) { - return !sameWord(word, candidate) && isAnagram(word, candidate); - }); + return !sameWord(this.word, candidate) && isAnagram(this.word, candidate); + }, this); } function sameWord(word, candidate) { @@ -28,3 +24,5 @@ function normalize(string) { return string.toLowerCase().split('').sort().toString(); } +module.exports = Anagram; + diff --git a/beer-song/beer-song.spec.js b/beer-song/beer-song.spec.js index 98349b20..f009c620 100644 --- a/beer-song/beer-song.spec.js +++ b/beer-song/beer-song.spec.js @@ -1,29 +1,30 @@ -var Beer = require('./beer-song'); +var BeerSong = require('./beer-song'); -describe('Beer', function() { +describe('BeerSong', function() { + var song = new BeerSong(); it('prints an arbitrary verse', function() { var expected = '8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n'; - expect(Beer.verse(8)).toEqual(expected); + expect(song.verse(8)).toEqual(expected); }); xit('handles 1 bottle', function() { var expected = '1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n'; - expect(Beer.verse(1)).toEqual(expected); + expect(song.verse(1)).toEqual(expected); }); xit('handles 0 bottles', function() { var expected = 'No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n'; - expect(Beer.verse(0)).toEqual(expected); + expect(song.verse(0)).toEqual(expected); }); xit('sings several verses', function() { var expected = '8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n'; - expect(Beer.sing(8, 6)).toEqual(expected); + expect(song.sing(8, 6)).toEqual(expected); }); xit('sings the rest of the verses', function() { var expected = '3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n'; - expect(Beer.sing(3)).toEqual(expected); + expect(song.sing(3)).toEqual(expected); }); }); diff --git a/beer-song/example.js b/beer-song/example.js index bbcb1284..26e7299d 100644 --- a/beer-song/example.js +++ b/beer-song/example.js @@ -36,7 +36,9 @@ return current_verse === 0 ? 99 : (current_verse - 1); } - exports.sing = function(first, last) { + function BeerSong() {} + + BeerSong.prototype.sing = function(first, last) { if (typeof(first) === 'undefined') { first = 99; } @@ -52,7 +54,7 @@ return verses.join('\n'); }; - exports.verse = function(number) { + BeerSong.prototype.verse = function(number) { var line1 = bottles(number) + ' of beer on the wall, '; var line2 = bottles(number).toLowerCase() + ' of beer.\n'; var line3 = action(number); @@ -60,4 +62,6 @@ return [line1, line2, line3, line4].join(''); }; -})(); \ No newline at end of file + + module.exports = BeerSong; +})(); diff --git a/etl/etl.spec.js b/etl/etl.spec.js index 688762de..f2132843 100644 --- a/etl/etl.spec.js +++ b/etl/etl.spec.js @@ -1,26 +1,27 @@ -var transform = require('./etl'); +var ETL = require('./etl'); describe('Transform', function() { + var etl = new ETL(); it('transforms one value', function() { var old = { 1: ['A'] }; var expected = { a: 1 }; - expect(transform(old)).toEqual(expected); + expect(etl.transform(old)).toEqual(expected); }); xit('transforms more values', function() { var old = { 1: ['A', 'E', 'I', 'O', 'U'] }; var expected = { a: 1, e: 1, i: 1, o: 1, u: 1 }; - expect(transform(old)).toEqual(expected); + expect(etl.transform(old)).toEqual(expected); }); xit('transforms more keys', function() { var old = { 1: ['A', 'E'], 2: ['D', 'G'] }; var expected = { a: 1, e: 1, d: 2, g: 2 }; - expect(transform(old)).toEqual(expected); + expect(etl.transform(old)).toEqual(expected); }); xit('transforms a full dataset', function() { @@ -42,7 +43,7 @@ describe('Transform', function() { z: 10 }; - expect(transform(old)).toEqual(expected); + expect(etl.transform(old)).toEqual(expected); }); }); diff --git a/etl/example.js b/etl/example.js index 5dafbee2..e0a51bf6 100644 --- a/etl/example.js +++ b/etl/example.js @@ -1,6 +1,8 @@ 'use strict'; -module.exports = function(input) { +function ETL() {} + +ETL.prototype.transform = function(input) { var output = {}; var object = Object.keys(input); @@ -17,3 +19,6 @@ module.exports = function(input) { return output; }; + +module.exports = ETL; + diff --git a/food-chain/example.js b/food-chain/example.js index 9f0c46c7..ab719fce 100644 --- a/food-chain/example.js +++ b/food-chain/example.js @@ -1,6 +1,6 @@ -exports.verses = verses; -exports.verse = verse; -exports.sing = verses.bind(null, 1, 8); +'use strict'; + +function FoodChain() {} /** * Return portion of song corresponding to requested verse number range (inclusive). @@ -14,14 +14,13 @@ exports.sing = verses.bind(null, 1, 8); * @return {String} * corresponding portion of song */ - -function verses(first, last) { +FoodChain.prototype.verses = function (first, last) { var idx = first - 1; var end = last; var str = []; while (++idx <= end) { - str.push(verse(idx)); + str.push(this.verse(idx)); } return str.join('\n') + '\n'; @@ -36,8 +35,7 @@ function verses(first, last) { * @return {String} * song verse */ - -function verse(number) { +FoodChain.prototype.verse = function (number) { switch (number) { case 1: return '' + 'I know an old lady who swallowed a fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; @@ -78,3 +76,6 @@ function verse(number) { }; }; +FoodChain.prototype.sing = FoodChain.prototype.verses.bind(null, 1, 8); + +module.exports = FoodChain; diff --git a/food-chain/food-chain.spec.js b/food-chain/food-chain.spec.js index 946ce8db..382e26b9 100644 --- a/food-chain/food-chain.spec.js +++ b/food-chain/food-chain.spec.js @@ -1,6 +1,7 @@ -var song = require('./food-chain'); +var FoodChain = require('./food-chain'); describe('Food Chain', function () { + var song = new FoodChain(); it('fly', function () { var expected = 'I know an old lady who swallowed a fly.\nI don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; diff --git a/hamming/example.js b/hamming/example.js index 087f5403..69a83516 100644 --- a/hamming/example.js +++ b/hamming/example.js @@ -1,4 +1,6 @@ -module.exports = function (strand1, strand2) { +function Hamming() {} + +Hamming.prototype.compute = function (strand1, strand2) { var len1 = strand1.length; var len2 = strand2.length; @@ -16,3 +18,6 @@ module.exports = function (strand1, strand2) { return out; }; + +module.exports = Hamming; + diff --git a/hamming/hamming.spec.js b/hamming/hamming.spec.js index ab009336..0a8ad582 100644 --- a/hamming/hamming.spec.js +++ b/hamming/hamming.spec.js @@ -1,37 +1,38 @@ -var compute = require('./hamming'); +var Hamming = require('./hamming'); describe('Hamming', function () { + var hamming = new Hamming(); it('no difference between identical strands', function () { - expect(compute('A', 'A')).toEqual(0); + expect(hamming.compute('A', 'A')).toEqual(0); }); xit('complete hamming distance for single nucleotide strand', function () { - expect(compute('A','G')).toEqual(1); + expect(hamming.compute('A','G')).toEqual(1); }); xit('complete hamming distance for small strand', function () { - expect(compute('AG','CT')).toEqual(2); + expect(hamming.compute('AG','CT')).toEqual(2); }); xit('small hamming distance', function () { - expect(compute('AT','CT')).toEqual(1); + expect(hamming.compute('AT','CT')).toEqual(1); }); xit('small hamming distance in longer strand', function () { - expect(compute('GGACG', 'GGTCG')).toEqual(1); + expect(hamming.compute('GGACG', 'GGTCG')).toEqual(1); }); xit('large hamming distance', function () { - expect(compute('GATACA', 'GCATAA')).toEqual(4); + expect(hamming.compute('GATACA', 'GCATAA')).toEqual(4); }); xit('hamming distance in very long strand', function () { - expect(compute('GGACGGATTCTG', 'AGGACGGATTCT')).toEqual(9); + expect(hamming.compute('GGACGGATTCTG', 'AGGACGGATTCT')).toEqual(9); }); xit('throws error when strands are not equal length', function() { - expect(function() { compute('GGACGGATTCTG', 'AGGAC'); }).toThrow( + expect(function() { hamming.compute('GGACGGATTCTG', 'AGGAC'); }).toThrow( new Error('DNA strands must be of equal length.') ); }); diff --git a/leap/example.js b/leap/example.js index 1abed4c4..ad2eba7f 100644 --- a/leap/example.js +++ b/leap/example.js @@ -1,16 +1,24 @@ 'use strict'; /** - * Whether given year is a leap year. + * Represents a year to check whether is leap or not * * @param {number} year * Numeric year. + */ +function Year(year) { + this.year = year; +} + +/** + * Whether given year is a leap year. * * @return {boolean} * Whether given year is a leap year. */ +Year.prototype.isLeap = function () { + return (this.year % 400 == 0) || ((this.year % 4 == 0) && (this.year % 100 != 0)); +} -module.exports = function (year) { - return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)); -}; +module.exports = Year; diff --git a/leap/leap.spec.js b/leap/leap.spec.js index 9c5d8a2c..604d1f61 100644 --- a/leap/leap.spec.js +++ b/leap/leap.spec.js @@ -1,40 +1,48 @@ -var isLeapYear = require('./leap'); +var Year = require('./leap'); describe('Leap year', function() { it('is not very common', function() { - expect(isLeapYear(2015)).toBe(false); + var year = new Year(2015); + expect(year.isLeap()).toBe(false); }); xit('is introduced every 4 years to adjust about a day', function() { - expect(isLeapYear(2016)).toBe(true); + var year = new Year(2016); + expect(year.isLeap()).toBe(true); }); xit('is skipped every 100 years to remove an extra day', function() { - expect(isLeapYear(1900)).toBe(false); + var year = new Year(1900); + expect(year.isLeap()).toBe(false); }); xit('is reintroduced every 400 years to adjust another day', function() { - expect(isLeapYear(2000)).toBe(true); + var year = new Year(2000); + expect(year.isLeap()).toBe(true); }); // Feel free to enable the following tests to check some more examples xdescribe('Additional example of a leap year that', function () { it('is not a leap year', function () { - expect(isLeapYear(1978)).toBe(false); + var year = new Year(1978); + expect(year.isLeap()).toBe(false); }); it('is a common leap year', function () { - expect(isLeapYear(1992)).toBe(true); + var year = new Year(1992); + expect(year.isLeap()).toBe(true); }); it('is skipped every 100 years', function () { - expect(isLeapYear(2100)).toBe(false); + var year = new Year(2100); + expect(year.isLeap()).toBe(false); }); it('is reintroduced every 400 years', function () { - expect(isLeapYear(2400)).toBe(true); + var year = new Year(2400); + expect(year.isLeap()).toBe(true); }); }); diff --git a/word-count/example.js b/word-count/example.js index 0fed8f66..7b7a27dc 100644 --- a/word-count/example.js +++ b/word-count/example.js @@ -1,6 +1,8 @@ 'use strict'; -module.exports = function (input) { +function Words() {} + +Words.prototype.count = function (input) { var counts = {}; var words = input.match(/\S+/g); @@ -10,3 +12,6 @@ module.exports = function (input) { return counts; }; + +module.exports = Words; + diff --git a/word-count/word-count.spec.js b/word-count/word-count.spec.js index c575ebd2..cc1e37ab 100644 --- a/word-count/word-count.spec.js +++ b/word-count/word-count.spec.js @@ -1,63 +1,65 @@ -var words = require('./word-count'); +var Words = require('./word-count'); + +describe('count()', function() { + var words = new Words(); -describe('words()', function() { it('counts one word', function() { var expectedCounts = { word: 1 }; - expect(words('word')).toEqual(expectedCounts); + expect(words.count('word')).toEqual(expectedCounts); }); xit('counts one of each', function() { var expectedCounts = { one: 1, of: 1, each: 1 }; - expect(words('one of each')).toEqual(expectedCounts); + expect(words.count('one of each')).toEqual(expectedCounts); }); xit('counts multiple occurrences', function() { var expectedCounts = { one: 1, fish: 4, two: 1, red: 1, blue: 1 }; - expect(words('one fish two fish red fish blue fish')).toEqual(expectedCounts); + expect(words.count('one fish two fish red fish blue fish')).toEqual(expectedCounts); }); xit('includes punctuation', function() { var expectedCounts = { car: 1, ':': 2, carpet: 1, as: 1, java: 1, 'javascript!!&@$%^&': 1 }; - expect(words('car : carpet as java : javascript!!&@$%^&')).toEqual(expectedCounts); + expect(words.count('car : carpet as java : javascript!!&@$%^&')).toEqual(expectedCounts); }); xit('includes numbers', function() { var expectedCounts = { testing: 2, 1: 1, 2: 1 }; - expect(words('testing 1 2 testing')).toEqual(expectedCounts); + expect(words.count('testing 1 2 testing')).toEqual(expectedCounts); }); xit('respects case', function() { var expectedCounts = { go: 1, Go:1, GO:1 }; - expect(words('go Go GO')).toEqual(expectedCounts); + expect(words.count('go Go GO')).toEqual(expectedCounts); }); xit('counts properly international characters', function() { var expectedCounts = { '¡Hola!': 1, '¿Qué': 1, 'tal?': 1, 'Привет!': 1 }; - expect(words('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); + expect(words.count('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); }); xit('counts multiline', function() { var expectedCounts = { hello: 1, world: 1 }; - expect(words('hello\nworld')).toEqual(expectedCounts); + expect(words.count('hello\nworld')).toEqual(expectedCounts); }); xit('counts tabs', function() { var expectedCounts = { hello: 1, world: 1 }; - expect(words('hello\tworld')).toEqual(expectedCounts); + expect(words.count('hello\tworld')).toEqual(expectedCounts); }); xit('counts multiple spaces as one', function() { var expectedCounts = { hello: 1, world: 1 }; - expect(words('hello world')).toEqual(expectedCounts); + expect(words.count('hello world')).toEqual(expectedCounts); }); xit('does not count leading or trailing whitespace', function() { var expectedCounts = { Introductory: 1, Course: 1 }; - expect(words('\t\tIntroductory Course ')).toEqual(expectedCounts); + expect(words.count('\t\tIntroductory Course ')).toEqual(expectedCounts); }); xit('handles properties that exist on Object’s prototype', function() { var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, toString: 1, 'ok?': 1}; - expect(words('reserved words like prototype and toString ok?')).toEqual(expectedCounts); + expect(words.count('reserved words like prototype and toString ok?')).toEqual(expectedCounts); }); }); From 0c35158bb0017ddc69c17bd3218714e943551344 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Wed, 25 Nov 2015 05:38:53 -0500 Subject: [PATCH 010/272] Modify Makefile sed command for OSX --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 53d05b05..808e0097 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,8 @@ test-assignment: node_modules @cp big-integer.$(FILEEXT) $(OUTDIR) @cp $(ASSIGNMENT)/$(TSTFILE) $(OUTDIR) @cp $(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(subst _,-,$(ASSIGNMENT)).$(FILEEXT) - @sed -i.original 's/\bxit\b/it/g' $(OUTDIR)/*spec.$(FILEEXT) + #@sed -i.original 's/\bxit\b/it/g' $(OUTDIR)/*spec.$(FILEEXT) + @sed 's/xit/it/g' $(ASSIGNMENT)/$(TSTFILE) > $(OUTDIR)/$(TSTFILE) @./node_modules/.bin/jasmine-node --captureExceptions $(OUTDIR)/$(TSTFILE) test: From 315e8b67f72067ff36e6e555fa56deb3915767d9 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Wed, 25 Nov 2015 10:31:38 -0700 Subject: [PATCH 011/272] Clean up docs for x-api v3 --- docs/HELLO.md | 17 ----------- docs/INSTALLATION.md | 9 ++---- docs/LEARNING.md | 4 +++ docs/RESOURCES.md | 7 ----- docs/TESTS.md | 70 ++++++++++++++++++++++++++++++++++++++++++++ docs/TOOLS.md | 36 ----------------------- docs/WORKFLOW.md | 7 ----- 7 files changed, 77 insertions(+), 73 deletions(-) delete mode 100644 docs/HELLO.md create mode 100644 docs/LEARNING.md create mode 100644 docs/TESTS.md delete mode 100644 docs/TOOLS.md delete mode 100644 docs/WORKFLOW.md diff --git a/docs/HELLO.md b/docs/HELLO.md deleted file mode 100644 index de83fcc2..00000000 --- a/docs/HELLO.md +++ /dev/null @@ -1,17 +0,0 @@ -## Making Your First Node Module - -To create a module that can be loaded with `var Bob = require('./bob.js');`, put this code in `bob.js`: - -```javascript -var Bob = function() {}; - -Bob.prototype.hey = function(what) { -// -// Your solution to the exercise goes here -// -}; - -module.exports = Bob; -``` - -You can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). To make it easier to get started, there's a "skeleton" bob.js file in the directory for the first exercise. diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index da3cc7f6..b60dd031 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,5 +1,4 @@ -**Windows and OS X users**: Install [Node.js](http://nodejs.org/) [via package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager). Windows users can use Visua -l Studio, see below. +**Windows and OS X users**: Install [Node.js](http://nodejs.org/) [via package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager). Windows users can use Visual Studio, see below. **Linux users**: [Joyent maintains a document][linstall] that details how to get Node.js installed for a wide range of distributions and package managers. @@ -11,15 +10,13 @@ Install `jasmine-node`: $ npm install jasmine-node -g ``` -Depending on your setup, you may need super user privileges to install an NPM module globally. This is the case if you've used the official installer linked to above. If NPM gives you an error - saying you don't have access, add `sudo` to the command above: +Depending on your setup, you may need super user privileges to install an NPM module globally. This is the case if you've used the official installer linked to above. If NPM gives you an error saying you don't have access, add `sudo` to the command above: ```bash $ sudo npm install jasmine-node -g ```` -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 your `PATH` to include the `npm` binaries by adding the following to either `~/.bash_profile` or `~/.zshrc`: +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 your `PATH` to include the `npm` binaries by adding the following to either `~/.bash_profile` or `~/.zshrc`: ```bash $ export PATH=/usr/local/share/npm/bin:$PATH diff --git a/docs/LEARNING.md b/docs/LEARNING.md new file mode 100644 index 00000000..0e0322cb --- /dev/null +++ b/docs/LEARNING.md @@ -0,0 +1,4 @@ +* [Eloquent JavaScript: A Modern Introduction to Programming (2nd Ed.)](http://eloquentjavascript.net) +* [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) +* [Crockford on JavaScript](http://javascript.crockford.com/) +* [idiomatic.js: Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js) diff --git a/docs/RESOURCES.md b/docs/RESOURCES.md index bae515d6..cc2a0996 100644 --- a/docs/RESOURCES.md +++ b/docs/RESOURCES.md @@ -1,10 +1,3 @@ -## Recommended Learning Resources - -* [Eloquent JavaScript: A Modern Introduction to Programming (2nd Ed.)](http://eloquentjavascript.net) -* [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) -* [Crockford on JavaScript](http://javascript.crockford.com/) -* [idiomatic.js: Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js) - ## Recommended References * [Mozilla JavaScript Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference) diff --git a/docs/TESTS.md b/docs/TESTS.md new file mode 100644 index 00000000..d0d68626 --- /dev/null +++ b/docs/TESTS.md @@ -0,0 +1,70 @@ +Execute the tests with: + +```bash +$ jasmine-node bob_test.spec.js +``` + +## Making Your First Node Module + +To create a module that can be loaded with `var Bob = require('./bob.js');`, put this code in `bob.js`: + +```javascript +var Bob = function() {}; + +Bob.prototype.hey = function(what) { + // + // Your solution to the exercise goes here + // +}; + +module.exports = Bob; +``` + +You can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). To make it easier to get started, there's a "skeleton" bob.js file in the directory +for the first exercise. + +## Visual Studio on Windows + +Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx). This will include the IDE and web development tools. + +To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. + +![Solution Explorer](/img/setup/visualstudio/SolutionExplorer.png) + +1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. +2. Unzip the template into your exercises directory, for example `C:\src\exercises` +2. Install the [Exercism CLI](http://help.exercism.io/installing-the-cli.html) +3. Open a command prompt to your exercise directory +4. Add your API key to exercism `exercism configure --key=YOUR_API_KEY` +5. Configure your source directory in exercism `exercism configure --dir=C:\src\exercises` +6. [Fetch your first exercise](http://help.exercism.io/fetching-exercises.html) `exercism fetch javascript` +7. Open the Exercism solution in Visual Studio +8. Expand the Exercism.javascript project +9. Click on **Show All Files** in Solution Explorer (See below) +10. The exercise you just fetched will appear greyed out. Right click on the folder and **Include In Project** +11. Get coding... + +![Add files](/img/setup/visualstudio/AddFiles.png) + +If you have a paid version of Visual Studio, you should install the [Web Essentials](http://vswebessentials.com/) extension. It will make working with Javascript much easier. + +You can run the unit tests from a node.js command line using the batch file in the project. + +``` +C:\Src\exercises\javascript>test example\bob_test.spec.js +................. + +Finished in 0.02 seconds +17 tests, 17 assertions, 0 failures, 0 skipped +``` + +If you do not see any output from running the tests, you are likely not in a Node.js command prompt. + +## Setting Up a Linter + +A linter is like a tester for your code's style and formatting. In some languages there are many acceptable styles, and using a linter allows you to be internally consistent (e.g. Ruby), or adhere to one of many common styles. In other languages there are fewer choices, and a linter allows programmers to look at code from a great variety of sources and still feel at home (e.g. Go). You can read more [here](https://en.wikipedia.org/wiki/Lint_(software)). + +The old standard linter for JavaScript is [JSLint](JSLint.com). However, it is controversially picky. [JSHint](JSHint.com) is another popular linter. We suggest using [ESLint](ESLint.org), which is more customizable than either JSLint or JSHint, and is well-run. + +To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple ```eslint [options] [file|dir]*``` command. Eg, if you're in the hello-world directory, ```eslint .``` would lint all files in that directory. + diff --git a/docs/TOOLS.md b/docs/TOOLS.md deleted file mode 100644 index 57ea9f69..00000000 --- a/docs/TOOLS.md +++ /dev/null @@ -1,36 +0,0 @@ -## Visual Studio on Windows - -Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx). This will include the IDE and web development tools. - -To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. - -![Solution Explorer](/img/SolutionExplorer.png) - -1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. -2. Unzip the template into your exercises directory, for example `C:\src\exercises` -2. Install the [Exercism CLI](http://help.exercism.io/installing-the-cli.html) -3. Open a command prompt to your exercise directory -4. Add your API key to exercism `exercism configure --key=YOUR_API_KEY` -5. Configure your source directory in exercism `exercism configure --dir=C:\src\exercises` -6. [Fetch your first exercise](http://help.exercism.io/fetching-exercises.html) `exercism fetch javascript` -7. Open the Exercism solution in Visual Studio -8. Expand the Exercism.javascript project -9. Click on **Show All Files** in Solution Explorer (See below) -10. The exercise you just fetched will appear greyed out. Right click on the folder and **Include In Project** -11. Get coding... - -![Add files](/img/AddFiles.png) - -If you have a paid version of Visual Studio, you should install the [Web Essentials](http://vswebessentials.com/) extension. It will make working with Javascript much easier. - -You can run the unit tests from a node.js command line using the batch file in the project. - -``` -C:\Src\exercises\javascript>test example\bob.spec.js -................. - -Finished in 0.02 seconds -17 tests, 17 assertions, 0 failures, 0 skipped -``` - -If you do not see any output from running the tests, you are likely not in a Node.js command prompt. diff --git a/docs/WORKFLOW.md b/docs/WORKFLOW.md deleted file mode 100644 index 7e3a6419..00000000 --- a/docs/WORKFLOW.md +++ /dev/null @@ -1,7 +0,0 @@ -## Running Tests - -Execute the tests with: - -```bash -$ jasmine-node bob.spec.js -``` From 4f879b2e326287e3086e790efa5dd1a0f3777c62 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Wed, 25 Nov 2015 05:46:19 -0500 Subject: [PATCH 012/272] Disable all tests but first by default in meetup assignment --- meetup/meetup.spec.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/meetup/meetup.spec.js b/meetup/meetup.spec.js index ce492ada..47eb9024 100644 --- a/meetup/meetup.spec.js +++ b/meetup/meetup.spec.js @@ -11,51 +11,51 @@ describe('meetupDay()', function() { expect(meetupDay(2013, 4, 'Monday', 'teenth')).toEqual(new Date(2013, 4, 13)); }); - it('test_saturteenth_of_february_2013', function() { + xit('test_saturteenth_of_february_2013', function() { expect(meetupDay(2013, 1, 'Saturday', 'teenth')).toEqual(new Date(2013, 1, 16)); }); - it('test_first_tuesday_of_may_2013', function() { + xit('test_first_tuesday_of_may_2013', function() { expect(meetupDay(2013, 4, 'Tuesday', '1st')).toEqual(new Date(2013, 4, 7)); }); - it('test_second_monday_of_april_2013', function() { + xit('test_second_monday_of_april_2013', function() { expect(meetupDay(2013, 3, 'Monday', '2nd')).toEqual(new Date(2013, 3, 8)); }); - it('test_third_thursday_of_september_2013', function() { + xit('test_third_thursday_of_september_2013', function() { expect(meetupDay(2013, 8, 'Thursday', '3rd')).toEqual(new Date(2013, 8, 19)); }); - it('test_fourth_sunday_of_march_2013', function() { + xit('test_fourth_sunday_of_march_2013', function() { expect(meetupDay(2013, 2, 'Sunday', '4th')).toEqual(new Date(2013, 2, 24)); }); - it('test_last_thursday_of_october_2013', function() { + xit('test_last_thursday_of_october_2013', function() { expect(meetupDay(2013, 9, 'Thursday', 'last')).toEqual(new Date(2013, 9, 31)); }); - it('test_last_wednesday_of_february_2012', function() { + xit('test_last_wednesday_of_february_2012', function() { expect(meetupDay(2012, 1, 'Wednesday', 'last')).toEqual(new Date(2012, 1, 29)); }); - it('test_last_wednesday_of_december_2014', function() { + xit('test_last_wednesday_of_december_2014', function() { expect(meetupDay(2014, 11, 'Wednesday', 'last')).toEqual(new Date(2014, 11, 31)); }); - it('test_last_sunday_of_only_four_week_february_2015', function() { + xit('test_last_sunday_of_only_four_week_february_2015', function() { expect(meetupDay(2015, 1, 'Sunday', 'last')).toEqual(new Date(2015, 1, 22)); }); - it('test_first_friday_of_december_2012', function() { + xit('test_first_friday_of_december_2012', function() { expect(meetupDay(2012, 11, 'Friday', '1st')).toEqual(new Date(2012, 11, 7)); }); - it('test_fifth_monday_of_march_2015', function() { + xit('test_fifth_monday_of_march_2015', function() { expect(meetupDay(2015, 2, 'Monday', '5th')).toEqual(new Date(2015, 2, 30)); }); - it('test_nonexistent_fifth_monday_of_february_2015', function() { + xit('test_nonexistent_fifth_monday_of_february_2015', function() { expect(function () { meetupDay(2015, 1, 'Monday', '5th'); }).toThrow(); }); }); From b40a5731ffe3bd0c4e4660c12c1d85c3ce752c3e Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Wed, 25 Nov 2015 05:51:43 -0500 Subject: [PATCH 013/272] Disable all but first test by default on two-bucket --- two-bucket/two-bucket.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/two-bucket/two-bucket.spec.js b/two-bucket/two-bucket.spec.js index c3ca98e1..3cd89428 100644 --- a/two-bucket/two-bucket.spec.js +++ b/two-bucket/two-bucket.spec.js @@ -14,7 +14,7 @@ describe('TwoBucket', function(){ expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached }); - it('starting with bucket two', function(){ + xit('starting with bucket two', function(){ var starterBuck = 'two'; var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); expect(twoBucket.moves()).toEqual(8); @@ -28,7 +28,7 @@ describe('TwoBucket', function(){ var buckTwo = 11; var goal = 2; - it('starting with bucket one', function(){ + xit('starting with bucket one', function(){ var starterBuck = 'one'; var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); expect(twoBucket.moves()).toEqual(14); @@ -36,7 +36,7 @@ describe('TwoBucket', function(){ expect(twoBucket.otherBucket).toEqual(11); }); - it('starting with bucket two', function(){ + xit('starting with bucket two', function(){ var starterBuck = 'two'; var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); expect(twoBucket.moves()).toEqual(18); From 847ba7310384287169fede4f1dc782d87e39dcce Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 27 Nov 2015 12:24:53 -0700 Subject: [PATCH 014/272] Edit documentation image paths --- docs/TESTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index d0d68626..ebcbaf76 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -29,7 +29,7 @@ Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/p To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. -![Solution Explorer](/img/setup/visualstudio/SolutionExplorer.png) +![Solution Explorer](http://x.exercism.io/v3/tracks/javascript/docs/img/SolutionExplorer.png) 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` @@ -44,7 +44,7 @@ To get started, you can download a Visual Studio solution that is already set up 10. The exercise you just fetched will appear greyed out. Right click on the folder and **Include In Project** 11. Get coding... -![Add files](/img/setup/visualstudio/AddFiles.png) +![Add files](http://x.exercism.io/v3/tracks/javascript/docs/img/AddFiles.png) If you have a paid version of Visual Studio, you should install the [Web Essentials](http://vswebessentials.com/) extension. It will make working with Javascript much easier. From b9f1a9ac9dc00af0612503ebecfcb03bfa0f5273 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sun, 29 Nov 2015 16:07:12 -0500 Subject: [PATCH 015/272] Fix linter links in docs --- docs/TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index ebcbaf76..1b169248 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -64,7 +64,7 @@ If you do not see any output from running the tests, you are likely not in a Nod A linter is like a tester for your code's style and formatting. In some languages there are many acceptable styles, and using a linter allows you to be internally consistent (e.g. Ruby), or adhere to one of many common styles. In other languages there are fewer choices, and a linter allows programmers to look at code from a great variety of sources and still feel at home (e.g. Go). You can read more [here](https://en.wikipedia.org/wiki/Lint_(software)). -The old standard linter for JavaScript is [JSLint](JSLint.com). However, it is controversially picky. [JSHint](JSHint.com) is another popular linter. We suggest using [ESLint](ESLint.org), which is more customizable than either JSLint or JSHint, and is well-run. +The old standard linter for JavaScript is [JSLint](http://jslint.com). However, it is controversially picky. [JSHint](http://jshint.com) is another popular linter. We suggest using [ESLint](http://eslint.org), which is more customizable than either JSLint or JSHint, and is well-run. To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple ```eslint [options] [file|dir]*``` command. Eg, if you're in the hello-world directory, ```eslint .``` would lint all files in that directory. From 1bfaf0e838ca08e6d5011a3ca13c3f01f5ca0362 Mon Sep 17 00:00:00 2001 From: Evan Moore Date: Sun, 29 Nov 2015 18:56:28 -0700 Subject: [PATCH 016/272] add missing test to sum-of-multiples --- sum-of-multiples/sum-of-multiples.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sum-of-multiples/sum-of-multiples.spec.js b/sum-of-multiples/sum-of-multiples.spec.js index fdb4ab09..de952cca 100644 --- a/sum-of-multiples/sum-of-multiples.spec.js +++ b/sum-of-multiples/sum-of-multiples.spec.js @@ -13,6 +13,10 @@ describe('SumOfMultiples', function () { expect(SumOfMultiples().to(10)).toBe(23); }); + xit('to 100', function () { + expect(SumOfMultiples().to(100)).toBe(2318); + }); + xit('to 1000', function () { expect(SumOfMultiples().to(1000)).toBe(233168); }); From 2e80ea853bab18d4b746bc21aab3bc47a343904a Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Thu, 26 Nov 2015 11:01:44 -0500 Subject: [PATCH 017/272] Add new exercise pangram --- config.json | 1 + pangram/example.js | 20 ++++++++++++++++++++ pangram/pangram.spec.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 pangram/example.js create mode 100644 pangram/pangram.spec.js diff --git a/config.json b/config.json index 4976756b..ac93518b 100644 --- a/config.json +++ b/config.json @@ -11,6 +11,7 @@ "bob", "gigasecond", "word-count", + "pangram", "beer-song", "phone-number", "anagram", diff --git a/pangram/example.js b/pangram/example.js new file mode 100644 index 00000000..c61cfdb9 --- /dev/null +++ b/pangram/example.js @@ -0,0 +1,20 @@ +var notAlpha = /[^a-z]+/gi, + ALPHA_LENGTH = 26, + cleaned, + unique; + +var Pangram = function(candidate) { + unique = {}; + cleaned = (candidate.replace(notAlpha, '')).toLowerCase(); + cleaned.split('').forEach(function (el) { + unique[el] = true; + }); + + return { + isPangram: function () { + return Object.keys(unique).length === ALPHA_LENGTH; + } + }; +}; + +module.exports = Pangram; diff --git a/pangram/pangram.spec.js b/pangram/pangram.spec.js new file mode 100644 index 00000000..efc6e797 --- /dev/null +++ b/pangram/pangram.spec.js @@ -0,0 +1,30 @@ +var Pangram = require('./pangram'); + +describe('Pangram()', function() { + + it('empty sentence', function() { + var pangram = new Pangram(''); + expect(pangram.isPangram()).toBe(false); + }); + + xit('pangram with only lower case', function() { + var pangram = new Pangram("the quick brown fox jumps over the lazy dog"); + expect(pangram.isPangram()).toBe(true); + }); + + xit("missing character 'x'", function() { + var pangram = new Pangram("a quick movement of the enemy will jeopardize five gunboats"); + expect(pangram.isPangram()).toBe(false); + }); + + xit('pangram with mixed case and punctuation', function() { + var pangram = new Pangram("\"Five quacking Zephyrs jolt my wax bed.\""); + expect(pangram.isPangram()).toBe(true); + }); + + xit('pangram with non-ascii characters', function() { + var pangram = new Pangram("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."); + expect(pangram.isPangram()).toBe(true); + }); + +}); From 723112984b496eac518f98149daa799853a06f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 1 Dec 2015 22:37:38 +0100 Subject: [PATCH 018/272] Add test to help implement Robot with smaller steps --- robot-name/robot-name.spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/robot-name/robot-name.spec.js b/robot-name/robot-name.spec.js index d9ce5017..2f9b4776 100644 --- a/robot-name/robot-name.spec.js +++ b/robot-name/robot-name.spec.js @@ -22,6 +22,11 @@ describe('Robot', function() { }); xit('different robots have different names', function() { + var differentRobot = new Robot(); + expect(differentRobot.name).not.toEqual(robot.name); + }); + + xit('there can be lots of robots with different names each', function() { var i, numRobots = 10000, usedNames = {}; From 7cd721d6395c20998c0f37194e853a77c7ed8bf3 Mon Sep 17 00:00:00 2001 From: Jonatas Miguel Date: Tue, 1 Dec 2015 22:30:01 -0500 Subject: [PATCH 019/272] Corrected test descriptions Some of the test were describing the 'toRna' features when they should have been describing the 'toDna' features. --- rna-transcription/rna-transcription.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rna-transcription/rna-transcription.spec.js b/rna-transcription/rna-transcription.spec.js index 77836cee..5c2df6fa 100644 --- a/rna-transcription/rna-transcription.spec.js +++ b/rna-transcription/rna-transcription.spec.js @@ -34,15 +34,15 @@ xdescribe('toDna()', function() { expect(dnaTranscriber.toDna('G')).toEqual('C'); }); - xit('transcribes adenine to uracil', function() { + xit('transcribes uracil to adenine', function() { expect(dnaTranscriber.toDna('U')).toEqual('A'); }); - xit('transcribes thymine to adenine', function() { + xit('transcribes adenine to thymine', function() { expect(dnaTranscriber.toDna('A')).toEqual('T'); }); - xit('transcribes all dna nucleotides to their rna complements', function() { + xit('transcribes all rna nucleotides to their dna complements', function() { expect(dnaTranscriber.toDna('UGAACCCGACAUG')) .toEqual('ACTTGGGCTGTAC'); }); From b0088db6445838fca06de403da6e2f6eadc63267 Mon Sep 17 00:00:00 2001 From: Ankit Famyial Date: Thu, 3 Dec 2015 16:28:52 +0530 Subject: [PATCH 020/272] Add ABOUT.md file --- docs/ABOUT.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/ABOUT.md diff --git a/docs/ABOUT.md b/docs/ABOUT.md new file mode 100644 index 00000000..bab0e9c7 --- /dev/null +++ b/docs/ABOUT.md @@ -0,0 +1,14 @@ +Javascript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. Besides being fast, JavaScript provides benefits like :- +* Reducing server traffic by validating user input in the browser before it is sent to the server. +* Providing immediate feedback to the site visitors so that they don't have to reload pages just to get error messages on form validations. +* Allowing richer user interfaces with content changes on mouse hover, drag and drop gestures, and animations. + +Client-side JavaScript is interpreted in the browser without requiring compilation. This allows interactive content to be included in HTML pages which would otherwise be static. + +Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/) + +You should learn JavaScript because:- +* It's easy to learn. +* It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. +* It's Open Source. +* JavaScript programming skills are in high demand. \ No newline at end of file From f871cd7c0720f6d49a5a615e46bfea6648bec140 Mon Sep 17 00:00:00 2001 From: Max Helmetag Date: Thu, 24 Dec 2015 13:38:45 -0500 Subject: [PATCH 021/272] remove rna_to_dna logic and tests --- rna-transcription/example.js | 11 ---------- rna-transcription/rna-transcription.spec.js | 23 --------------------- 2 files changed, 34 deletions(-) diff --git a/rna-transcription/example.js b/rna-transcription/example.js index b6303305..23417842 100644 --- a/rna-transcription/example.js +++ b/rna-transcription/example.js @@ -9,13 +9,6 @@ var dnaToRna = { A: 'U' }; -var rnaToDna = { - G: 'C', - C: 'G', - U: 'A', - A: 'T' -}; - var transcribeDna = function(dna, lookupTable) { return dna.replace(/./g, function(dnaNucleotide) { return lookupTable[dnaNucleotide]; @@ -26,8 +19,4 @@ DnaTranscriber.prototype.toRna = function(dna) { return transcribeDna(dna, dnaToRna); } -DnaTranscriber.prototype.toDna = function(dna) { - return transcribeDna(dna, rnaToDna); -} - module.exports = DnaTranscriber; diff --git a/rna-transcription/rna-transcription.spec.js b/rna-transcription/rna-transcription.spec.js index 5c2df6fa..7c52aafe 100644 --- a/rna-transcription/rna-transcription.spec.js +++ b/rna-transcription/rna-transcription.spec.js @@ -24,26 +24,3 @@ describe('toRna()', function() { .toEqual('UGCACCAGAAUU'); }); }); - -xdescribe('toDna()', function() { - it('transcribes cytosine to guanine', function() { - expect(dnaTranscriber.toDna('C')).toEqual('G'); - }); - - xit('transcribes guanine to cytosine', function() { - expect(dnaTranscriber.toDna('G')).toEqual('C'); - }); - - xit('transcribes uracil to adenine', function() { - expect(dnaTranscriber.toDna('U')).toEqual('A'); - }); - - xit('transcribes adenine to thymine', function() { - expect(dnaTranscriber.toDna('A')).toEqual('T'); - }); - - xit('transcribes all rna nucleotides to their dna complements', function() { - expect(dnaTranscriber.toDna('UGAACCCGACAUG')) - .toEqual('ACTTGGGCTGTAC'); - }); -}); From 5dc68d77d946dcc79b5c8907e0fa16dfdf83b21a Mon Sep 17 00:00:00 2001 From: Carlos Corvaia Date: Wed, 30 Dec 2015 13:52:31 -0500 Subject: [PATCH 022/272] Update setup.md Updated the URL from `http://help.exercism.io/getting-started-with-javascript.html` to `http://exercism.io/languages/javascript` since http://help.exercism.io/ has been deprecated. --- SETUP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SETUP.md b/SETUP.md index bd4a5531..cbaa639b 100644 --- a/SETUP.md +++ b/SETUP.md @@ -3,7 +3,7 @@ Go through the setup instructions for JavaScript to install the necessary dependencies: -http://help.exercism.io/getting-started-with-javascript.html +http://exercism.io/languages/javascript ## Making the Test Suite Pass From 940fbfaf75ab22e8c85e23b96846e27f8157cd78 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 30 Dec 2015 20:31:55 +0100 Subject: [PATCH 023/272] Removed space on line 15. It wasn't supposed to be there and made the whole test fail. --- saddle-points/saddle-points.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saddle-points/saddle-points.spec.js b/saddle-points/saddle-points.spec.js index 4621bc08..35f5c31c 100644 --- a/saddle-points/saddle-points.spec.js +++ b/saddle-points/saddle-points.spec.js @@ -12,7 +12,7 @@ describe('Matrix', function() { }); xit('extracts a column', function() { - var matrix = new Matrix('1 2 3\n4 5 6\n7 8 9\n 8 7 6'); + var matrix = new Matrix('1 2 3\n4 5 6\n7 8 9\n8 7 6'); expect(matrix.columns[0]).toEqual([1, 4, 7, 8]); }); From ea132b969cdc4693d1c964fa91a747b8a33a32f4 Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Sat, 23 Jan 2016 12:44:03 -0800 Subject: [PATCH 024/272] largest-series-product: Test all combinations of corner cases The original tests had tests for "" and 0. This is when both inputs are the boundary condition. Now we should also test when only one input is at the boundary. So we should test a non-empty string with 0, and "" with a nonzero span. These are consistent with the values defined in https://github.com/exercism/x-common/blob/master/largest-series-product.json --- .../largest-series-product.spec.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/largest-series-product/largest-series-product.spec.js b/largest-series-product/largest-series-product.spec.js index 1be60d58..07101f36 100644 --- a/largest-series-product/largest-series-product.spec.js +++ b/largest-series-product/largest-series-product.spec.js @@ -41,14 +41,24 @@ describe('Series', function () { expect(new Series(largeNumber).largestProduct(6)).toBe(23520); }); - xit('returns 1 for no digits', function () { + xit('returns 1 for empty string and zero slice length', function () { expect(new Series('').largestProduct(0)).toBe(1); }); + xit('returns 1 for non-empty string and zero slice length', function () { + expect(new Series('123').largestProduct(0)).toBe(1); + }); + xit('throws an error for slices bigger than the number', function () { expect(function () { new Series('123').largestProduct(4); }).toThrow(new Error('Slice size is too big.')); }); + xit('throws an error for empty string and non-zero slice length', function () { + expect(function () { + new Series('').largestProduct(1); + }).toThrow(new Error('Slice size is too big.')); + }); + }); From cb29ef41945395d2934d2de91e190fcace62f570 Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Sat, 23 Jan 2016 12:45:26 -0800 Subject: [PATCH 025/272] largest-series-product: Add cases where all spans contain a 0 In these cases, the result should be 0 as well. This guards against solutions that assume the minimum is 1. --- largest-series-product/largest-series-product.spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/largest-series-product/largest-series-product.spec.js b/largest-series-product/largest-series-product.spec.js index 07101f36..9e03a0f5 100644 --- a/largest-series-product/largest-series-product.spec.js +++ b/largest-series-product/largest-series-product.spec.js @@ -41,6 +41,14 @@ describe('Series', function () { expect(new Series(largeNumber).largestProduct(6)).toBe(23520); }); + xit('returns 0 if all digits are zero', function () { + expect(new Series('0000').largestProduct(2)).toBe(0); + }); + + xit('returns 0 if all spans contain zero', function () { + expect(new Series('99099').largestProduct(3)).toBe(0); + }); + xit('returns 1 for empty string and zero slice length', function () { expect(new Series('').largestProduct(0)).toBe(1); }); From 786ea113571f018e7e02907da429ed9dee5ba8a3 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sat, 23 Jan 2016 17:24:14 -0500 Subject: [PATCH 026/272] Add new exercise acronym --- acronym/acronym.spec.js | 28 ++++++++++++++++++++++++++++ acronym/example.js | 8 ++++++++ acronym/package.json | 12 ++++++++++++ config.json | 1 + 4 files changed, 49 insertions(+) create mode 100644 acronym/acronym.spec.js create mode 100644 acronym/example.js create mode 100644 acronym/package.json diff --git a/acronym/acronym.spec.js b/acronym/acronym.spec.js new file mode 100644 index 00000000..ec5f60c2 --- /dev/null +++ b/acronym/acronym.spec.js @@ -0,0 +1,28 @@ +var Acronyms = require('./acronym'); + +describe('Acronyms are produced from', function(){ + it('title cased phrases', function() { + expect(Acronyms.parse('Portable Network Graphics')).toEqual('PNG'); + }); + + it('other title cased phrases', function(){ + expect(Acronyms.parse('Ruby on Rails')).toEqual('ROR'); + }); + + it('inconsistently cased phrases', function(){ + expect(Acronyms.parse('HyperText Markup Language')).toEqual('HTML'); + }); + + it('phrases with punctuation', function() { + expect(Acronyms.parse('First In, First Out')).toEqual('FIFO'); + }); + + it('other phrases with punctuation', function() { + expect(Acronyms.parse('PHP: Hypertext Preprocessor')).toEqual('PHP'); + }); + + it('phrases with punctuation and sentence casing', function() { + expect(Acronyms.parse('Complementary metal-oxide semiconductor')).toEqual('CMOS'); + }); +}); + diff --git a/acronym/example.js b/acronym/example.js new file mode 100644 index 00000000..ac8d5636 --- /dev/null +++ b/acronym/example.js @@ -0,0 +1,8 @@ +module.exports = { + parse: function (phrase) { + return phrase.match(/[A-Z]+[a-z]*|[a-z]+/g) + .reduce(function (acronym, word) { + return acronym += word[0].toUpperCase() + }, ''); + } +}; diff --git a/acronym/package.json b/acronym/package.json new file mode 100644 index 00000000..c909c3ce --- /dev/null +++ b/acronym/package.json @@ -0,0 +1,12 @@ +{ + "name": "javascript", + "version": "0.0.0", + "description": "JavaScript assignments", + "private": true, + "scripts": { + "test": "make test" + }, + "devDependencies": { + "jasmine-node": "*" + } +} diff --git a/config.json b/config.json index ac93518b..7e6889ee 100644 --- a/config.json +++ b/config.json @@ -23,6 +23,7 @@ "grains", "triangle", "clock", + "acronym", "scrabble-score", "roman-numerals", "circular-buffer", From 401e8cb76c71b9d7b247fca0bdcacaad59b85c01 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sat, 23 Jan 2016 18:06:45 -0500 Subject: [PATCH 027/272] Move exercises to subdirectory --- Makefile | 8 ++++---- {accumulate => exercises/accumulate}/accumulate.spec.js | 0 {accumulate => exercises/accumulate}/example.js | 0 {acronym => exercises/acronym}/acronym.spec.js | 0 {acronym => exercises/acronym}/example.js | 0 {acronym => exercises/acronym}/package.json | 0 {allergies => exercises/allergies}/allergies.spec.js | 0 {allergies => exercises/allergies}/example.js | 0 {anagram => exercises/anagram}/anagram.spec.js | 0 {anagram => exercises/anagram}/example.js | 0 .../atbash-cipher}/atbash-cipher.spec.js | 0 {atbash-cipher => exercises/atbash-cipher}/example.js | 0 {beer-song => exercises/beer-song}/beer-song.spec.js | 0 {beer-song => exercises/beer-song}/example.js | 0 .../binary-search-tree}/binary-search-tree.spec.js | 0 .../binary-search-tree}/example.js | 0 .../binary-search}/binary-search.spec.js | 0 {binary-search => exercises/binary-search}/example.js | 0 {binary => exercises/binary}/binary.spec.js | 0 {binary => exercises/binary}/example.js | 0 {bob => exercises/bob}/bob.js | 0 {bob => exercises/bob}/bob.spec.js | 0 {bob => exercises/bob}/example.js | 0 .../bracket-push}/bracket-push.spec.js | 0 {bracket-push => exercises/bracket-push}/example.js | 0 .../circular-buffer}/circular-buffer.spec.js | 0 {circular-buffer => exercises/circular-buffer}/example.js | 0 {clock => exercises/clock}/clock.spec.js | 0 {clock => exercises/clock}/example.js | 0 .../crypto-square}/crypto-square.spec.js | 0 {crypto-square => exercises/crypto-square}/example.js | 0 {custom-set => exercises/custom-set}/custom-set.spec.js | 0 {custom-set => exercises/custom-set}/example.js | 0 .../difference-of-squares}/difference-of-squares.spec.js | 0 .../difference-of-squares}/example.js | 0 {etl => exercises/etl}/etl.spec.js | 0 {etl => exercises/etl}/example.js | 0 {food-chain => exercises/food-chain}/example.js | 0 {food-chain => exercises/food-chain}/food-chain.spec.js | 0 {gigasecond => exercises/gigasecond}/example.js | 0 {gigasecond => exercises/gigasecond}/gigasecond.spec.js | 0 {grade-school => exercises/grade-school}/example.js | 0 .../grade-school}/grade-school.spec.js | 0 {grains => exercises/grains}/big-integer.js | 0 {grains => exercises/grains}/big-integer.spec.js | 0 {grains => exercises/grains}/example.js | 0 {grains => exercises/grains}/grains.spec.js | 0 {hamming => exercises/hamming}/example.js | 0 {hamming => exercises/hamming}/hamming.spec.js | 0 {hello-world => exercises/hello-world}/example.js | 0 {hello-world => exercises/hello-world}/hello-world.js | 0 .../hello-world}/hello-world.spec.js | 0 {hexadecimal => exercises/hexadecimal}/example.js | 0 .../hexadecimal}/hexadecimal.spec.js | 0 .../kindergarten-garden}/example.js | 0 .../kindergarten-garden}/kindergarten-garden.spec.js | 0 .../largest-series-product}/example.js | 0 .../largest-series-product.spec.js | 0 {leap => exercises/leap}/example.js | 0 {leap => exercises/leap}/leap.spec.js | 0 {linked-list => exercises/linked-list}/example.js | 0 .../linked-list}/linked-list.spec.js | 0 {luhn => exercises/luhn}/example.js | 0 {luhn => exercises/luhn}/luhn.spec.js | 0 {matrix => exercises/matrix}/example.js | 0 {matrix => exercises/matrix}/matrix.spec.js | 0 {meetup => exercises/meetup}/example.js | 0 {meetup => exercises/meetup}/meetup.spec.js | 0 {nth-prime => exercises/nth-prime}/example.js | 0 {nth-prime => exercises/nth-prime}/nth-prime.spec.js | 0 .../nucleotide-count}/example.js | 0 .../nucleotide-count}/nucleotide-count.spec.js | 0 {ocr-numbers => exercises/ocr-numbers}/example.js | 0 .../ocr-numbers}/ocr-numbers.spec.js | 0 {octal => exercises/octal}/example.js | 0 {octal => exercises/octal}/octal.spec.js | 0 .../palindrome-products}/example.js | 0 .../palindrome-products}/palindrome-products.spec.js | 0 {pangram => exercises/pangram}/example.js | 0 {pangram => exercises/pangram}/pangram.spec.js | 0 .../pascals-triangle}/example.js | 0 .../pascals-triangle}/pascals-triangle.spec.js | 0 {phone-number => exercises/phone-number}/example.js | 0 .../phone-number}/phone-number.spec.js | 0 {pig-latin => exercises/pig-latin}/example.js | 0 {pig-latin => exercises/pig-latin}/pig-latin.spec.js | 0 {point-mutations => exercises/point-mutations}/example.js | 0 .../point-mutations}/point-mutations.spec.js | 0 {prime-factors => exercises/prime-factors}/example.js | 0 .../prime-factors}/prime-factors.spec.js | 0 .../pythagorean-triplet}/example.js | 0 .../pythagorean-triplet}/pythagorean-triplet.spec.js | 0 {queen-attack => exercises/queen-attack}/example.js | 0 .../queen-attack}/queen-attack.spec.js | 0 {raindrops => exercises/raindrops}/example.js | 0 {raindrops => exercises/raindrops}/raindrops.spec.js | 0 .../rna-transcription}/example.js | 0 .../rna-transcription}/rna-transcription.spec.js | 0 {robot-name => exercises/robot-name}/example.js | 0 {robot-name => exercises/robot-name}/robot-name.spec.js | 0 {robot-simulator => exercises/robot-simulator}/example.js | 0 .../robot-simulator}/robot-simulator.spec.js | 0 {roman-numerals => exercises/roman-numerals}/example.js | 0 .../roman-numerals}/roman-numerals.spec.js | 0 {saddle-points => exercises/saddle-points}/example.js | 0 .../saddle-points}/saddle-points.spec.js | 0 {say => exercises/say}/example.js | 0 {say => exercises/say}/say.spec.js | 0 {scrabble-score => exercises/scrabble-score}/example.js | 0 .../scrabble-score}/scrabble-score.spec.js | 0 .../secret-handshake}/example.js | 0 .../secret-handshake}/secret-handshake.spec.js | 0 {series => exercises/series}/example.js | 0 {series => exercises/series}/series.spec.js | 0 {sieve => exercises/sieve}/example.js | 0 {sieve => exercises/sieve}/sieve.spec.js | 0 {simple-cipher => exercises/simple-cipher}/example.js | 0 .../simple-cipher}/simple-cipher.spec.js | 0 {space-age => exercises/space-age}/example.js | 0 {space-age => exercises/space-age}/space-age.spec.js | 0 {strain => exercises/strain}/example.js | 0 {strain => exercises/strain}/strain.spec.js | 0 .../sum-of-multiples}/example.js | 0 .../sum-of-multiples}/sum-of-multiples.spec.js | 0 {triangle => exercises/triangle}/example.js | 0 {triangle => exercises/triangle}/triangle.spec.js | 0 {trinary => exercises/trinary}/example.js | 0 {trinary => exercises/trinary}/trinary.spec.js | 0 {two-bucket => exercises/two-bucket}/example-2.js | 0 {two-bucket => exercises/two-bucket}/example.js | 0 {two-bucket => exercises/two-bucket}/two-bucket.spec.js | 0 {word-count => exercises/word-count}/example.js | 0 {word-count => exercises/word-count}/word-count.spec.js | 0 {wordy => exercises/wordy}/example.js | 0 {wordy => exercises/wordy}/wordy.spec.js | 0 135 files changed, 4 insertions(+), 4 deletions(-) rename {accumulate => exercises/accumulate}/accumulate.spec.js (100%) rename {accumulate => exercises/accumulate}/example.js (100%) rename {acronym => exercises/acronym}/acronym.spec.js (100%) rename {acronym => exercises/acronym}/example.js (100%) rename {acronym => exercises/acronym}/package.json (100%) rename {allergies => exercises/allergies}/allergies.spec.js (100%) rename {allergies => exercises/allergies}/example.js (100%) rename {anagram => exercises/anagram}/anagram.spec.js (100%) rename {anagram => exercises/anagram}/example.js (100%) rename {atbash-cipher => exercises/atbash-cipher}/atbash-cipher.spec.js (100%) rename {atbash-cipher => exercises/atbash-cipher}/example.js (100%) rename {beer-song => exercises/beer-song}/beer-song.spec.js (100%) rename {beer-song => exercises/beer-song}/example.js (100%) rename {binary-search-tree => exercises/binary-search-tree}/binary-search-tree.spec.js (100%) rename {binary-search-tree => exercises/binary-search-tree}/example.js (100%) rename {binary-search => exercises/binary-search}/binary-search.spec.js (100%) rename {binary-search => exercises/binary-search}/example.js (100%) rename {binary => exercises/binary}/binary.spec.js (100%) rename {binary => exercises/binary}/example.js (100%) rename {bob => exercises/bob}/bob.js (100%) rename {bob => exercises/bob}/bob.spec.js (100%) rename {bob => exercises/bob}/example.js (100%) rename {bracket-push => exercises/bracket-push}/bracket-push.spec.js (100%) rename {bracket-push => exercises/bracket-push}/example.js (100%) rename {circular-buffer => exercises/circular-buffer}/circular-buffer.spec.js (100%) rename {circular-buffer => exercises/circular-buffer}/example.js (100%) rename {clock => exercises/clock}/clock.spec.js (100%) rename {clock => exercises/clock}/example.js (100%) rename {crypto-square => exercises/crypto-square}/crypto-square.spec.js (100%) rename {crypto-square => exercises/crypto-square}/example.js (100%) rename {custom-set => exercises/custom-set}/custom-set.spec.js (100%) rename {custom-set => exercises/custom-set}/example.js (100%) rename {difference-of-squares => exercises/difference-of-squares}/difference-of-squares.spec.js (100%) rename {difference-of-squares => exercises/difference-of-squares}/example.js (100%) rename {etl => exercises/etl}/etl.spec.js (100%) rename {etl => exercises/etl}/example.js (100%) rename {food-chain => exercises/food-chain}/example.js (100%) rename {food-chain => exercises/food-chain}/food-chain.spec.js (100%) rename {gigasecond => exercises/gigasecond}/example.js (100%) rename {gigasecond => exercises/gigasecond}/gigasecond.spec.js (100%) rename {grade-school => exercises/grade-school}/example.js (100%) rename {grade-school => exercises/grade-school}/grade-school.spec.js (100%) rename {grains => exercises/grains}/big-integer.js (100%) rename {grains => exercises/grains}/big-integer.spec.js (100%) rename {grains => exercises/grains}/example.js (100%) rename {grains => exercises/grains}/grains.spec.js (100%) rename {hamming => exercises/hamming}/example.js (100%) rename {hamming => exercises/hamming}/hamming.spec.js (100%) rename {hello-world => exercises/hello-world}/example.js (100%) rename {hello-world => exercises/hello-world}/hello-world.js (100%) rename {hello-world => exercises/hello-world}/hello-world.spec.js (100%) rename {hexadecimal => exercises/hexadecimal}/example.js (100%) rename {hexadecimal => exercises/hexadecimal}/hexadecimal.spec.js (100%) rename {kindergarten-garden => exercises/kindergarten-garden}/example.js (100%) rename {kindergarten-garden => exercises/kindergarten-garden}/kindergarten-garden.spec.js (100%) rename {largest-series-product => exercises/largest-series-product}/example.js (100%) rename {largest-series-product => exercises/largest-series-product}/largest-series-product.spec.js (100%) rename {leap => exercises/leap}/example.js (100%) rename {leap => exercises/leap}/leap.spec.js (100%) rename {linked-list => exercises/linked-list}/example.js (100%) rename {linked-list => exercises/linked-list}/linked-list.spec.js (100%) rename {luhn => exercises/luhn}/example.js (100%) rename {luhn => exercises/luhn}/luhn.spec.js (100%) rename {matrix => exercises/matrix}/example.js (100%) rename {matrix => exercises/matrix}/matrix.spec.js (100%) rename {meetup => exercises/meetup}/example.js (100%) rename {meetup => exercises/meetup}/meetup.spec.js (100%) rename {nth-prime => exercises/nth-prime}/example.js (100%) rename {nth-prime => exercises/nth-prime}/nth-prime.spec.js (100%) rename {nucleotide-count => exercises/nucleotide-count}/example.js (100%) rename {nucleotide-count => exercises/nucleotide-count}/nucleotide-count.spec.js (100%) rename {ocr-numbers => exercises/ocr-numbers}/example.js (100%) rename {ocr-numbers => exercises/ocr-numbers}/ocr-numbers.spec.js (100%) rename {octal => exercises/octal}/example.js (100%) rename {octal => exercises/octal}/octal.spec.js (100%) rename {palindrome-products => exercises/palindrome-products}/example.js (100%) rename {palindrome-products => exercises/palindrome-products}/palindrome-products.spec.js (100%) rename {pangram => exercises/pangram}/example.js (100%) rename {pangram => exercises/pangram}/pangram.spec.js (100%) rename {pascals-triangle => exercises/pascals-triangle}/example.js (100%) rename {pascals-triangle => exercises/pascals-triangle}/pascals-triangle.spec.js (100%) rename {phone-number => exercises/phone-number}/example.js (100%) rename {phone-number => exercises/phone-number}/phone-number.spec.js (100%) rename {pig-latin => exercises/pig-latin}/example.js (100%) rename {pig-latin => exercises/pig-latin}/pig-latin.spec.js (100%) rename {point-mutations => exercises/point-mutations}/example.js (100%) rename {point-mutations => exercises/point-mutations}/point-mutations.spec.js (100%) rename {prime-factors => exercises/prime-factors}/example.js (100%) rename {prime-factors => exercises/prime-factors}/prime-factors.spec.js (100%) rename {pythagorean-triplet => exercises/pythagorean-triplet}/example.js (100%) rename {pythagorean-triplet => exercises/pythagorean-triplet}/pythagorean-triplet.spec.js (100%) rename {queen-attack => exercises/queen-attack}/example.js (100%) rename {queen-attack => exercises/queen-attack}/queen-attack.spec.js (100%) rename {raindrops => exercises/raindrops}/example.js (100%) rename {raindrops => exercises/raindrops}/raindrops.spec.js (100%) rename {rna-transcription => exercises/rna-transcription}/example.js (100%) rename {rna-transcription => exercises/rna-transcription}/rna-transcription.spec.js (100%) rename {robot-name => exercises/robot-name}/example.js (100%) rename {robot-name => exercises/robot-name}/robot-name.spec.js (100%) rename {robot-simulator => exercises/robot-simulator}/example.js (100%) rename {robot-simulator => exercises/robot-simulator}/robot-simulator.spec.js (100%) rename {roman-numerals => exercises/roman-numerals}/example.js (100%) rename {roman-numerals => exercises/roman-numerals}/roman-numerals.spec.js (100%) rename {saddle-points => exercises/saddle-points}/example.js (100%) rename {saddle-points => exercises/saddle-points}/saddle-points.spec.js (100%) rename {say => exercises/say}/example.js (100%) rename {say => exercises/say}/say.spec.js (100%) rename {scrabble-score => exercises/scrabble-score}/example.js (100%) rename {scrabble-score => exercises/scrabble-score}/scrabble-score.spec.js (100%) rename {secret-handshake => exercises/secret-handshake}/example.js (100%) rename {secret-handshake => exercises/secret-handshake}/secret-handshake.spec.js (100%) rename {series => exercises/series}/example.js (100%) rename {series => exercises/series}/series.spec.js (100%) rename {sieve => exercises/sieve}/example.js (100%) rename {sieve => exercises/sieve}/sieve.spec.js (100%) rename {simple-cipher => exercises/simple-cipher}/example.js (100%) rename {simple-cipher => exercises/simple-cipher}/simple-cipher.spec.js (100%) rename {space-age => exercises/space-age}/example.js (100%) rename {space-age => exercises/space-age}/space-age.spec.js (100%) rename {strain => exercises/strain}/example.js (100%) rename {strain => exercises/strain}/strain.spec.js (100%) rename {sum-of-multiples => exercises/sum-of-multiples}/example.js (100%) rename {sum-of-multiples => exercises/sum-of-multiples}/sum-of-multiples.spec.js (100%) rename {triangle => exercises/triangle}/example.js (100%) rename {triangle => exercises/triangle}/triangle.spec.js (100%) rename {trinary => exercises/trinary}/example.js (100%) rename {trinary => exercises/trinary}/trinary.spec.js (100%) rename {two-bucket => exercises/two-bucket}/example-2.js (100%) rename {two-bucket => exercises/two-bucket}/example.js (100%) rename {two-bucket => exercises/two-bucket}/two-bucket.spec.js (100%) rename {word-count => exercises/word-count}/example.js (100%) rename {word-count => exercises/word-count}/word-count.spec.js (100%) rename {wordy => exercises/wordy}/example.js (100%) rename {wordy => exercises/wordy}/wordy.spec.js (100%) diff --git a/Makefile b/Makefile index 808e0097..63579552 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # assignments ASSIGNMENT ?= "" IGNOREDIRS := "^(\.git|docs|bin|node_modules|.idea)$$" -ASSIGNMENTS = $(shell find . -maxdepth 1 -mindepth 1 -type d | cut -d'/' -f2 | sort | grep -Ev $(IGNOREDIRS)) +ASSIGNMENTS = $(shell find ./exercises -maxdepth 1 -mindepth 1 -type d | cut -d'/' -f3 | sort | grep -Ev $(IGNOREDIRS)) # output directories TMPDIR ?= "/tmp" @@ -20,10 +20,10 @@ node_modules: package.json test-assignment: node_modules @echo "running tests for: $(ASSIGNMENT)" @cp big-integer.$(FILEEXT) $(OUTDIR) - @cp $(ASSIGNMENT)/$(TSTFILE) $(OUTDIR) - @cp $(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(subst _,-,$(ASSIGNMENT)).$(FILEEXT) + @cp exercises/$(ASSIGNMENT)/$(TSTFILE) $(OUTDIR) + @cp exercises/$(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(subst _,-,$(ASSIGNMENT)).$(FILEEXT) #@sed -i.original 's/\bxit\b/it/g' $(OUTDIR)/*spec.$(FILEEXT) - @sed 's/xit/it/g' $(ASSIGNMENT)/$(TSTFILE) > $(OUTDIR)/$(TSTFILE) + @sed 's/xit/it/g' exercises/$(ASSIGNMENT)/$(TSTFILE) > $(OUTDIR)/$(TSTFILE) @./node_modules/.bin/jasmine-node --captureExceptions $(OUTDIR)/$(TSTFILE) test: diff --git a/accumulate/accumulate.spec.js b/exercises/accumulate/accumulate.spec.js similarity index 100% rename from accumulate/accumulate.spec.js rename to exercises/accumulate/accumulate.spec.js diff --git a/accumulate/example.js b/exercises/accumulate/example.js similarity index 100% rename from accumulate/example.js rename to exercises/accumulate/example.js diff --git a/acronym/acronym.spec.js b/exercises/acronym/acronym.spec.js similarity index 100% rename from acronym/acronym.spec.js rename to exercises/acronym/acronym.spec.js diff --git a/acronym/example.js b/exercises/acronym/example.js similarity index 100% rename from acronym/example.js rename to exercises/acronym/example.js diff --git a/acronym/package.json b/exercises/acronym/package.json similarity index 100% rename from acronym/package.json rename to exercises/acronym/package.json diff --git a/allergies/allergies.spec.js b/exercises/allergies/allergies.spec.js similarity index 100% rename from allergies/allergies.spec.js rename to exercises/allergies/allergies.spec.js diff --git a/allergies/example.js b/exercises/allergies/example.js similarity index 100% rename from allergies/example.js rename to exercises/allergies/example.js diff --git a/anagram/anagram.spec.js b/exercises/anagram/anagram.spec.js similarity index 100% rename from anagram/anagram.spec.js rename to exercises/anagram/anagram.spec.js diff --git a/anagram/example.js b/exercises/anagram/example.js similarity index 100% rename from anagram/example.js rename to exercises/anagram/example.js diff --git a/atbash-cipher/atbash-cipher.spec.js b/exercises/atbash-cipher/atbash-cipher.spec.js similarity index 100% rename from atbash-cipher/atbash-cipher.spec.js rename to exercises/atbash-cipher/atbash-cipher.spec.js diff --git a/atbash-cipher/example.js b/exercises/atbash-cipher/example.js similarity index 100% rename from atbash-cipher/example.js rename to exercises/atbash-cipher/example.js diff --git a/beer-song/beer-song.spec.js b/exercises/beer-song/beer-song.spec.js similarity index 100% rename from beer-song/beer-song.spec.js rename to exercises/beer-song/beer-song.spec.js diff --git a/beer-song/example.js b/exercises/beer-song/example.js similarity index 100% rename from beer-song/example.js rename to exercises/beer-song/example.js diff --git a/binary-search-tree/binary-search-tree.spec.js b/exercises/binary-search-tree/binary-search-tree.spec.js similarity index 100% rename from binary-search-tree/binary-search-tree.spec.js rename to exercises/binary-search-tree/binary-search-tree.spec.js diff --git a/binary-search-tree/example.js b/exercises/binary-search-tree/example.js similarity index 100% rename from binary-search-tree/example.js rename to exercises/binary-search-tree/example.js diff --git a/binary-search/binary-search.spec.js b/exercises/binary-search/binary-search.spec.js similarity index 100% rename from binary-search/binary-search.spec.js rename to exercises/binary-search/binary-search.spec.js diff --git a/binary-search/example.js b/exercises/binary-search/example.js similarity index 100% rename from binary-search/example.js rename to exercises/binary-search/example.js diff --git a/binary/binary.spec.js b/exercises/binary/binary.spec.js similarity index 100% rename from binary/binary.spec.js rename to exercises/binary/binary.spec.js diff --git a/binary/example.js b/exercises/binary/example.js similarity index 100% rename from binary/example.js rename to exercises/binary/example.js diff --git a/bob/bob.js b/exercises/bob/bob.js similarity index 100% rename from bob/bob.js rename to exercises/bob/bob.js diff --git a/bob/bob.spec.js b/exercises/bob/bob.spec.js similarity index 100% rename from bob/bob.spec.js rename to exercises/bob/bob.spec.js diff --git a/bob/example.js b/exercises/bob/example.js similarity index 100% rename from bob/example.js rename to exercises/bob/example.js diff --git a/bracket-push/bracket-push.spec.js b/exercises/bracket-push/bracket-push.spec.js similarity index 100% rename from bracket-push/bracket-push.spec.js rename to exercises/bracket-push/bracket-push.spec.js diff --git a/bracket-push/example.js b/exercises/bracket-push/example.js similarity index 100% rename from bracket-push/example.js rename to exercises/bracket-push/example.js diff --git a/circular-buffer/circular-buffer.spec.js b/exercises/circular-buffer/circular-buffer.spec.js similarity index 100% rename from circular-buffer/circular-buffer.spec.js rename to exercises/circular-buffer/circular-buffer.spec.js diff --git a/circular-buffer/example.js b/exercises/circular-buffer/example.js similarity index 100% rename from circular-buffer/example.js rename to exercises/circular-buffer/example.js diff --git a/clock/clock.spec.js b/exercises/clock/clock.spec.js similarity index 100% rename from clock/clock.spec.js rename to exercises/clock/clock.spec.js diff --git a/clock/example.js b/exercises/clock/example.js similarity index 100% rename from clock/example.js rename to exercises/clock/example.js diff --git a/crypto-square/crypto-square.spec.js b/exercises/crypto-square/crypto-square.spec.js similarity index 100% rename from crypto-square/crypto-square.spec.js rename to exercises/crypto-square/crypto-square.spec.js diff --git a/crypto-square/example.js b/exercises/crypto-square/example.js similarity index 100% rename from crypto-square/example.js rename to exercises/crypto-square/example.js diff --git a/custom-set/custom-set.spec.js b/exercises/custom-set/custom-set.spec.js similarity index 100% rename from custom-set/custom-set.spec.js rename to exercises/custom-set/custom-set.spec.js diff --git a/custom-set/example.js b/exercises/custom-set/example.js similarity index 100% rename from custom-set/example.js rename to exercises/custom-set/example.js diff --git a/difference-of-squares/difference-of-squares.spec.js b/exercises/difference-of-squares/difference-of-squares.spec.js similarity index 100% rename from difference-of-squares/difference-of-squares.spec.js rename to exercises/difference-of-squares/difference-of-squares.spec.js diff --git a/difference-of-squares/example.js b/exercises/difference-of-squares/example.js similarity index 100% rename from difference-of-squares/example.js rename to exercises/difference-of-squares/example.js diff --git a/etl/etl.spec.js b/exercises/etl/etl.spec.js similarity index 100% rename from etl/etl.spec.js rename to exercises/etl/etl.spec.js diff --git a/etl/example.js b/exercises/etl/example.js similarity index 100% rename from etl/example.js rename to exercises/etl/example.js diff --git a/food-chain/example.js b/exercises/food-chain/example.js similarity index 100% rename from food-chain/example.js rename to exercises/food-chain/example.js diff --git a/food-chain/food-chain.spec.js b/exercises/food-chain/food-chain.spec.js similarity index 100% rename from food-chain/food-chain.spec.js rename to exercises/food-chain/food-chain.spec.js diff --git a/gigasecond/example.js b/exercises/gigasecond/example.js similarity index 100% rename from gigasecond/example.js rename to exercises/gigasecond/example.js diff --git a/gigasecond/gigasecond.spec.js b/exercises/gigasecond/gigasecond.spec.js similarity index 100% rename from gigasecond/gigasecond.spec.js rename to exercises/gigasecond/gigasecond.spec.js diff --git a/grade-school/example.js b/exercises/grade-school/example.js similarity index 100% rename from grade-school/example.js rename to exercises/grade-school/example.js diff --git a/grade-school/grade-school.spec.js b/exercises/grade-school/grade-school.spec.js similarity index 100% rename from grade-school/grade-school.spec.js rename to exercises/grade-school/grade-school.spec.js diff --git a/grains/big-integer.js b/exercises/grains/big-integer.js similarity index 100% rename from grains/big-integer.js rename to exercises/grains/big-integer.js diff --git a/grains/big-integer.spec.js b/exercises/grains/big-integer.spec.js similarity index 100% rename from grains/big-integer.spec.js rename to exercises/grains/big-integer.spec.js diff --git a/grains/example.js b/exercises/grains/example.js similarity index 100% rename from grains/example.js rename to exercises/grains/example.js diff --git a/grains/grains.spec.js b/exercises/grains/grains.spec.js similarity index 100% rename from grains/grains.spec.js rename to exercises/grains/grains.spec.js diff --git a/hamming/example.js b/exercises/hamming/example.js similarity index 100% rename from hamming/example.js rename to exercises/hamming/example.js diff --git a/hamming/hamming.spec.js b/exercises/hamming/hamming.spec.js similarity index 100% rename from hamming/hamming.spec.js rename to exercises/hamming/hamming.spec.js diff --git a/hello-world/example.js b/exercises/hello-world/example.js similarity index 100% rename from hello-world/example.js rename to exercises/hello-world/example.js diff --git a/hello-world/hello-world.js b/exercises/hello-world/hello-world.js similarity index 100% rename from hello-world/hello-world.js rename to exercises/hello-world/hello-world.js diff --git a/hello-world/hello-world.spec.js b/exercises/hello-world/hello-world.spec.js similarity index 100% rename from hello-world/hello-world.spec.js rename to exercises/hello-world/hello-world.spec.js diff --git a/hexadecimal/example.js b/exercises/hexadecimal/example.js similarity index 100% rename from hexadecimal/example.js rename to exercises/hexadecimal/example.js diff --git a/hexadecimal/hexadecimal.spec.js b/exercises/hexadecimal/hexadecimal.spec.js similarity index 100% rename from hexadecimal/hexadecimal.spec.js rename to exercises/hexadecimal/hexadecimal.spec.js diff --git a/kindergarten-garden/example.js b/exercises/kindergarten-garden/example.js similarity index 100% rename from kindergarten-garden/example.js rename to exercises/kindergarten-garden/example.js diff --git a/kindergarten-garden/kindergarten-garden.spec.js b/exercises/kindergarten-garden/kindergarten-garden.spec.js similarity index 100% rename from kindergarten-garden/kindergarten-garden.spec.js rename to exercises/kindergarten-garden/kindergarten-garden.spec.js diff --git a/largest-series-product/example.js b/exercises/largest-series-product/example.js similarity index 100% rename from largest-series-product/example.js rename to exercises/largest-series-product/example.js diff --git a/largest-series-product/largest-series-product.spec.js b/exercises/largest-series-product/largest-series-product.spec.js similarity index 100% rename from largest-series-product/largest-series-product.spec.js rename to exercises/largest-series-product/largest-series-product.spec.js diff --git a/leap/example.js b/exercises/leap/example.js similarity index 100% rename from leap/example.js rename to exercises/leap/example.js diff --git a/leap/leap.spec.js b/exercises/leap/leap.spec.js similarity index 100% rename from leap/leap.spec.js rename to exercises/leap/leap.spec.js diff --git a/linked-list/example.js b/exercises/linked-list/example.js similarity index 100% rename from linked-list/example.js rename to exercises/linked-list/example.js diff --git a/linked-list/linked-list.spec.js b/exercises/linked-list/linked-list.spec.js similarity index 100% rename from linked-list/linked-list.spec.js rename to exercises/linked-list/linked-list.spec.js diff --git a/luhn/example.js b/exercises/luhn/example.js similarity index 100% rename from luhn/example.js rename to exercises/luhn/example.js diff --git a/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js similarity index 100% rename from luhn/luhn.spec.js rename to exercises/luhn/luhn.spec.js diff --git a/matrix/example.js b/exercises/matrix/example.js similarity index 100% rename from matrix/example.js rename to exercises/matrix/example.js diff --git a/matrix/matrix.spec.js b/exercises/matrix/matrix.spec.js similarity index 100% rename from matrix/matrix.spec.js rename to exercises/matrix/matrix.spec.js diff --git a/meetup/example.js b/exercises/meetup/example.js similarity index 100% rename from meetup/example.js rename to exercises/meetup/example.js diff --git a/meetup/meetup.spec.js b/exercises/meetup/meetup.spec.js similarity index 100% rename from meetup/meetup.spec.js rename to exercises/meetup/meetup.spec.js diff --git a/nth-prime/example.js b/exercises/nth-prime/example.js similarity index 100% rename from nth-prime/example.js rename to exercises/nth-prime/example.js diff --git a/nth-prime/nth-prime.spec.js b/exercises/nth-prime/nth-prime.spec.js similarity index 100% rename from nth-prime/nth-prime.spec.js rename to exercises/nth-prime/nth-prime.spec.js diff --git a/nucleotide-count/example.js b/exercises/nucleotide-count/example.js similarity index 100% rename from nucleotide-count/example.js rename to exercises/nucleotide-count/example.js diff --git a/nucleotide-count/nucleotide-count.spec.js b/exercises/nucleotide-count/nucleotide-count.spec.js similarity index 100% rename from nucleotide-count/nucleotide-count.spec.js rename to exercises/nucleotide-count/nucleotide-count.spec.js diff --git a/ocr-numbers/example.js b/exercises/ocr-numbers/example.js similarity index 100% rename from ocr-numbers/example.js rename to exercises/ocr-numbers/example.js diff --git a/ocr-numbers/ocr-numbers.spec.js b/exercises/ocr-numbers/ocr-numbers.spec.js similarity index 100% rename from ocr-numbers/ocr-numbers.spec.js rename to exercises/ocr-numbers/ocr-numbers.spec.js diff --git a/octal/example.js b/exercises/octal/example.js similarity index 100% rename from octal/example.js rename to exercises/octal/example.js diff --git a/octal/octal.spec.js b/exercises/octal/octal.spec.js similarity index 100% rename from octal/octal.spec.js rename to exercises/octal/octal.spec.js diff --git a/palindrome-products/example.js b/exercises/palindrome-products/example.js similarity index 100% rename from palindrome-products/example.js rename to exercises/palindrome-products/example.js diff --git a/palindrome-products/palindrome-products.spec.js b/exercises/palindrome-products/palindrome-products.spec.js similarity index 100% rename from palindrome-products/palindrome-products.spec.js rename to exercises/palindrome-products/palindrome-products.spec.js diff --git a/pangram/example.js b/exercises/pangram/example.js similarity index 100% rename from pangram/example.js rename to exercises/pangram/example.js diff --git a/pangram/pangram.spec.js b/exercises/pangram/pangram.spec.js similarity index 100% rename from pangram/pangram.spec.js rename to exercises/pangram/pangram.spec.js diff --git a/pascals-triangle/example.js b/exercises/pascals-triangle/example.js similarity index 100% rename from pascals-triangle/example.js rename to exercises/pascals-triangle/example.js diff --git a/pascals-triangle/pascals-triangle.spec.js b/exercises/pascals-triangle/pascals-triangle.spec.js similarity index 100% rename from pascals-triangle/pascals-triangle.spec.js rename to exercises/pascals-triangle/pascals-triangle.spec.js diff --git a/phone-number/example.js b/exercises/phone-number/example.js similarity index 100% rename from phone-number/example.js rename to exercises/phone-number/example.js diff --git a/phone-number/phone-number.spec.js b/exercises/phone-number/phone-number.spec.js similarity index 100% rename from phone-number/phone-number.spec.js rename to exercises/phone-number/phone-number.spec.js diff --git a/pig-latin/example.js b/exercises/pig-latin/example.js similarity index 100% rename from pig-latin/example.js rename to exercises/pig-latin/example.js diff --git a/pig-latin/pig-latin.spec.js b/exercises/pig-latin/pig-latin.spec.js similarity index 100% rename from pig-latin/pig-latin.spec.js rename to exercises/pig-latin/pig-latin.spec.js diff --git a/point-mutations/example.js b/exercises/point-mutations/example.js similarity index 100% rename from point-mutations/example.js rename to exercises/point-mutations/example.js diff --git a/point-mutations/point-mutations.spec.js b/exercises/point-mutations/point-mutations.spec.js similarity index 100% rename from point-mutations/point-mutations.spec.js rename to exercises/point-mutations/point-mutations.spec.js diff --git a/prime-factors/example.js b/exercises/prime-factors/example.js similarity index 100% rename from prime-factors/example.js rename to exercises/prime-factors/example.js diff --git a/prime-factors/prime-factors.spec.js b/exercises/prime-factors/prime-factors.spec.js similarity index 100% rename from prime-factors/prime-factors.spec.js rename to exercises/prime-factors/prime-factors.spec.js diff --git a/pythagorean-triplet/example.js b/exercises/pythagorean-triplet/example.js similarity index 100% rename from pythagorean-triplet/example.js rename to exercises/pythagorean-triplet/example.js diff --git a/pythagorean-triplet/pythagorean-triplet.spec.js b/exercises/pythagorean-triplet/pythagorean-triplet.spec.js similarity index 100% rename from pythagorean-triplet/pythagorean-triplet.spec.js rename to exercises/pythagorean-triplet/pythagorean-triplet.spec.js diff --git a/queen-attack/example.js b/exercises/queen-attack/example.js similarity index 100% rename from queen-attack/example.js rename to exercises/queen-attack/example.js diff --git a/queen-attack/queen-attack.spec.js b/exercises/queen-attack/queen-attack.spec.js similarity index 100% rename from queen-attack/queen-attack.spec.js rename to exercises/queen-attack/queen-attack.spec.js diff --git a/raindrops/example.js b/exercises/raindrops/example.js similarity index 100% rename from raindrops/example.js rename to exercises/raindrops/example.js diff --git a/raindrops/raindrops.spec.js b/exercises/raindrops/raindrops.spec.js similarity index 100% rename from raindrops/raindrops.spec.js rename to exercises/raindrops/raindrops.spec.js diff --git a/rna-transcription/example.js b/exercises/rna-transcription/example.js similarity index 100% rename from rna-transcription/example.js rename to exercises/rna-transcription/example.js diff --git a/rna-transcription/rna-transcription.spec.js b/exercises/rna-transcription/rna-transcription.spec.js similarity index 100% rename from rna-transcription/rna-transcription.spec.js rename to exercises/rna-transcription/rna-transcription.spec.js diff --git a/robot-name/example.js b/exercises/robot-name/example.js similarity index 100% rename from robot-name/example.js rename to exercises/robot-name/example.js diff --git a/robot-name/robot-name.spec.js b/exercises/robot-name/robot-name.spec.js similarity index 100% rename from robot-name/robot-name.spec.js rename to exercises/robot-name/robot-name.spec.js diff --git a/robot-simulator/example.js b/exercises/robot-simulator/example.js similarity index 100% rename from robot-simulator/example.js rename to exercises/robot-simulator/example.js diff --git a/robot-simulator/robot-simulator.spec.js b/exercises/robot-simulator/robot-simulator.spec.js similarity index 100% rename from robot-simulator/robot-simulator.spec.js rename to exercises/robot-simulator/robot-simulator.spec.js diff --git a/roman-numerals/example.js b/exercises/roman-numerals/example.js similarity index 100% rename from roman-numerals/example.js rename to exercises/roman-numerals/example.js diff --git a/roman-numerals/roman-numerals.spec.js b/exercises/roman-numerals/roman-numerals.spec.js similarity index 100% rename from roman-numerals/roman-numerals.spec.js rename to exercises/roman-numerals/roman-numerals.spec.js diff --git a/saddle-points/example.js b/exercises/saddle-points/example.js similarity index 100% rename from saddle-points/example.js rename to exercises/saddle-points/example.js diff --git a/saddle-points/saddle-points.spec.js b/exercises/saddle-points/saddle-points.spec.js similarity index 100% rename from saddle-points/saddle-points.spec.js rename to exercises/saddle-points/saddle-points.spec.js diff --git a/say/example.js b/exercises/say/example.js similarity index 100% rename from say/example.js rename to exercises/say/example.js diff --git a/say/say.spec.js b/exercises/say/say.spec.js similarity index 100% rename from say/say.spec.js rename to exercises/say/say.spec.js diff --git a/scrabble-score/example.js b/exercises/scrabble-score/example.js similarity index 100% rename from scrabble-score/example.js rename to exercises/scrabble-score/example.js diff --git a/scrabble-score/scrabble-score.spec.js b/exercises/scrabble-score/scrabble-score.spec.js similarity index 100% rename from scrabble-score/scrabble-score.spec.js rename to exercises/scrabble-score/scrabble-score.spec.js diff --git a/secret-handshake/example.js b/exercises/secret-handshake/example.js similarity index 100% rename from secret-handshake/example.js rename to exercises/secret-handshake/example.js diff --git a/secret-handshake/secret-handshake.spec.js b/exercises/secret-handshake/secret-handshake.spec.js similarity index 100% rename from secret-handshake/secret-handshake.spec.js rename to exercises/secret-handshake/secret-handshake.spec.js diff --git a/series/example.js b/exercises/series/example.js similarity index 100% rename from series/example.js rename to exercises/series/example.js diff --git a/series/series.spec.js b/exercises/series/series.spec.js similarity index 100% rename from series/series.spec.js rename to exercises/series/series.spec.js diff --git a/sieve/example.js b/exercises/sieve/example.js similarity index 100% rename from sieve/example.js rename to exercises/sieve/example.js diff --git a/sieve/sieve.spec.js b/exercises/sieve/sieve.spec.js similarity index 100% rename from sieve/sieve.spec.js rename to exercises/sieve/sieve.spec.js diff --git a/simple-cipher/example.js b/exercises/simple-cipher/example.js similarity index 100% rename from simple-cipher/example.js rename to exercises/simple-cipher/example.js diff --git a/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js similarity index 100% rename from simple-cipher/simple-cipher.spec.js rename to exercises/simple-cipher/simple-cipher.spec.js diff --git a/space-age/example.js b/exercises/space-age/example.js similarity index 100% rename from space-age/example.js rename to exercises/space-age/example.js diff --git a/space-age/space-age.spec.js b/exercises/space-age/space-age.spec.js similarity index 100% rename from space-age/space-age.spec.js rename to exercises/space-age/space-age.spec.js diff --git a/strain/example.js b/exercises/strain/example.js similarity index 100% rename from strain/example.js rename to exercises/strain/example.js diff --git a/strain/strain.spec.js b/exercises/strain/strain.spec.js similarity index 100% rename from strain/strain.spec.js rename to exercises/strain/strain.spec.js diff --git a/sum-of-multiples/example.js b/exercises/sum-of-multiples/example.js similarity index 100% rename from sum-of-multiples/example.js rename to exercises/sum-of-multiples/example.js diff --git a/sum-of-multiples/sum-of-multiples.spec.js b/exercises/sum-of-multiples/sum-of-multiples.spec.js similarity index 100% rename from sum-of-multiples/sum-of-multiples.spec.js rename to exercises/sum-of-multiples/sum-of-multiples.spec.js diff --git a/triangle/example.js b/exercises/triangle/example.js similarity index 100% rename from triangle/example.js rename to exercises/triangle/example.js diff --git a/triangle/triangle.spec.js b/exercises/triangle/triangle.spec.js similarity index 100% rename from triangle/triangle.spec.js rename to exercises/triangle/triangle.spec.js diff --git a/trinary/example.js b/exercises/trinary/example.js similarity index 100% rename from trinary/example.js rename to exercises/trinary/example.js diff --git a/trinary/trinary.spec.js b/exercises/trinary/trinary.spec.js similarity index 100% rename from trinary/trinary.spec.js rename to exercises/trinary/trinary.spec.js diff --git a/two-bucket/example-2.js b/exercises/two-bucket/example-2.js similarity index 100% rename from two-bucket/example-2.js rename to exercises/two-bucket/example-2.js diff --git a/two-bucket/example.js b/exercises/two-bucket/example.js similarity index 100% rename from two-bucket/example.js rename to exercises/two-bucket/example.js diff --git a/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js similarity index 100% rename from two-bucket/two-bucket.spec.js rename to exercises/two-bucket/two-bucket.spec.js diff --git a/word-count/example.js b/exercises/word-count/example.js similarity index 100% rename from word-count/example.js rename to exercises/word-count/example.js diff --git a/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js similarity index 100% rename from word-count/word-count.spec.js rename to exercises/word-count/word-count.spec.js diff --git a/wordy/example.js b/exercises/wordy/example.js similarity index 100% rename from wordy/example.js rename to exercises/wordy/example.js diff --git a/wordy/wordy.spec.js b/exercises/wordy/wordy.spec.js similarity index 100% rename from wordy/wordy.spec.js rename to exercises/wordy/wordy.spec.js From 7e499e80c84758cbcc9136377b78618061fb6cf3 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 25 Jan 2016 13:26:27 -0500 Subject: [PATCH 028/272] Modify config.json to add test pattern --- config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/config.json b/config.json index 7e6889ee..3da8516e 100644 --- a/config.json +++ b/config.json @@ -3,6 +3,7 @@ "language": "JavaScript", "repository": "https://github.com/exercism/xjavascript", "active": true, + "test_pattern": ".*[.]spec[.]js$", "problems": [ "hello-world", "leap", From de7278a9045655a404c95c1bf64dcec5cc1ed7cf Mon Sep 17 00:00:00 2001 From: mgmatola Date: Mon, 8 Feb 2016 19:34:36 -0500 Subject: [PATCH 029/272] Add test to catch non-numeric sorting --- exercises/triangle/triangle.spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/triangle/triangle.spec.js b/exercises/triangle/triangle.spec.js index 8b4c70b3..6105d02f 100644 --- a/exercises/triangle/triangle.spec.js +++ b/exercises/triangle/triangle.spec.js @@ -77,4 +77,9 @@ describe('Triangle', function() { expect(triangle.kind.bind(triangle)).toThrow(); }); + xit('triangles violating triangle inequality are illegal 3', function() { + var triangle = new Triangle(10,1,3); + expect(triangle.kind.bind(triangle)).toThrow(); + }); + }); From 3a61ee3d8ae8f44e37ed2f1119e06bc67f81e22e Mon Sep 17 00:00:00 2001 From: Thomas Zumsteg Date: Fri, 12 Feb 2016 09:30:54 -0800 Subject: [PATCH 030/272] Removed tabs and deleted two-bucket/example-2.js --- exercises/crypto-square/example.js | 76 ++++++------ exercises/two-bucket/example-2.js | 98 --------------- exercises/two-bucket/example.js | 154 ++++++++++++------------ exercises/two-bucket/two-bucket.spec.js | 76 ++++++------ 4 files changed, 153 insertions(+), 251 deletions(-) delete mode 100644 exercises/two-bucket/example-2.js diff --git a/exercises/crypto-square/example.js b/exercises/crypto-square/example.js index d1c39c3d..7a914a55 100644 --- a/exercises/crypto-square/example.js +++ b/exercises/crypto-square/example.js @@ -1,55 +1,55 @@ 'use strict'; module.exports = function(input) { - this.input = input; + this.input = input; - this.normalizePlaintext = function() { - return input.toLowerCase().replace(/[^a-zA-Z0-9]/g,''); - }; + this.normalizePlaintext = function() { + return input.toLowerCase().replace(/[^a-zA-Z0-9]/g,''); + }; - this.size = function() { - var realLength = Math.sqrt(this.normalizePlaintext().length); - return Math.ceil(realLength); - }; + this.size = function() { + var realLength = Math.sqrt(this.normalizePlaintext().length); + return Math.ceil(realLength); + }; - this.plaintextSegments = function() { - var plainText = this.normalizePlaintext(); - var chunkSize = this.size(); + this.plaintextSegments = function() { + var plainText = this.normalizePlaintext(); + var chunkSize = this.size(); - var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); - return plainText.match(splitRegex); - }; + var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); + return plainText.match(splitRegex); + }; - this.ciphertext = function() { - var textSegments = this.plaintextSegments(); - var i, j; - var columns = []; - var currentSegment; - var currentLetter; + this.ciphertext = function() { + var textSegments = this.plaintextSegments(); + var i, j; + var columns = []; + var currentSegment; + var currentLetter; - for (i = 0; i < this.size(); i++) { - columns.push([]); - } + for (i = 0; i < this.size(); i++) { + columns.push([]); + } - for (i = 0; i < textSegments.length; i++) { - currentSegment = textSegments[i]; + for (i = 0; i < textSegments.length; i++) { + currentSegment = textSegments[i]; - for (j = 0; j < currentSegment.length; j++) { - currentLetter = currentSegment[j]; - columns[j].push(currentLetter); - } - } + for (j = 0; j < currentSegment.length; j++) { + currentLetter = currentSegment[j]; + columns[j].push(currentLetter); + } + } - for (i = 0; i < columns.length; i++) { - columns[i] = columns[i].join(''); - } + for (i = 0; i < columns.length; i++) { + columns[i] = columns[i].join(''); + } - return columns.join(''); - }; + return columns.join(''); + }; - this.normalizeCiphertext = function() { + this.normalizeCiphertext = function() { var chunkSize = this.size(); var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); - return this.ciphertext().match(splitRegex).join(' '); - }; + return this.ciphertext().match(splitRegex).join(' '); + }; }; diff --git a/exercises/two-bucket/example-2.js b/exercises/two-bucket/example-2.js deleted file mode 100644 index 365b5cf9..00000000 --- a/exercises/two-bucket/example-2.js +++ /dev/null @@ -1,98 +0,0 @@ -//alternate solution written by Fullstack student, Griffin Telljohann -'use strict'; - -function TwoBucket(bucket1, bucket2, goal, startingBucket) { - this.b1max = bucket1; - this.b2max = bucket2; - this.goalAmount = goal; - this.states = {}; - var invalid = (startingBucket == 'one' ? 0 : this.b1max) + ',' + (startingBucket == 'two' ? 0 : this.b2max); - this.beenHere = {}; - this.beenHere[invalid] = true; - var bestSolution = this.solve((startingBucket == 'one' ? this.b1max : 0), (startingBucket == 'two' ? this.b2max : 0)); - this.goalBucket = bestSolution.goalBucket; - this.otherBucket = bestSolution.otherBucketFill; - this.minMoves = 1 + bestSolution.numMoves; -} - -TwoBucket.prototype.moves = function() { - return this.minMoves; -}; - -TwoBucket.prototype.solve = function(bucket1fill, bucket2fill) { - // if you've already been in this state, return - if (this.beenHere[bucket1fill + ',' + bucket2fill]) return {goalBucket: null}; - else this.beenHere[bucket1fill + ',' + bucket2fill] = true; - - // if either bucket is filled to the goal amount, you've found a solution - if (bucket1fill == this.goalAmount) { - return {numMoves: 0, goalBucket: 'one', otherBucketFill: bucket2fill}; - } - if (bucket2fill == this.goalAmount) { - return {numMoves: 0, goalBucket: 'two', otherBucketFill: bucket1fill}; - } - - if (this.states[bucket1fill + ',' + bucket2fill]) { - return this.states[bucket1fill + ',' + bucket2fill]; - } - - - var testObj, bestSolution = {goalBucket: null}; - // fill bucket 1 to top - if (bucket1fill !== this.b1max && bucket2fill !== this.b2max) { - testObj = this.solve(this.b1max, bucket2fill); - bestSolution = betterSolution(testObj, bestSolution); - } - - // fill bucket 2 to top - if (bucket1fill !== this.b1max && bucket2fill !== this.b2max) { - testObj = this.solve(bucket1fill, this.b2max); - bestSolution = betterSolution(testObj, bestSolution); - } - - // empty bucket 1 - if (bucket1fill !== 0 && bucket2fill !== 0) { - //console.log("empty 1"); - testObj = this.solve(0, bucket2fill); - bestSolution = betterSolution(testObj, bestSolution); - } - - // empty bucket 2 - if (bucket1fill !== 0 && bucket2fill !== 0) { - //console.log("empty 2"); - testObj = this.solve(bucket1fill, 0); - bestSolution = betterSolution(testObj, bestSolution); - } - - var totalAmount = bucket1fill + bucket2fill; - // pour bucket 1 into bucket 2 - if (bucket2fill !== this.b2max) { - if (totalAmount <= this.b2max) {testObj = this.solve(0, totalAmount);} - else {testObj = this.solve(totalAmount - this.b2max, this.b2max);} - bestSolution = betterSolution(testObj, bestSolution); - } - - // pour bucket 2 into bucket 1 - if (bucket1fill !== this.b1max) { - if (totalAmount <= this.b1max) testObj = this.solve(totalAmount, 0); - else testObj = this.solve(this.b1max, totalAmount - this.b1max); - bestSolution = betterSolution(testObj, bestSolution); - } - - this.states[bucket1fill + ',' + bucket2fill] = bestSolution; - if (typeof bestSolution.numMoves === 'number') { - bestSolution.numMoves++; - } - return bestSolution; -}; - -function betterSolution(test, currentBest) { - if (test.goalBucket) { - if (!currentBest || !currentBest.goalBucket || test.numMoves < currentBest.numMoves) { - return test; - } - } - return currentBest; -} - -module.exports = TwoBucket; diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index a1b1ce64..c6be2d57 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -1,89 +1,89 @@ 'use strict'; function TwoBucket(x,y,z,starter) { - this.starter = starter; - this.x = x; - this.y = y; + this.starter = starter; + this.x = x; + this.y = y; - this.reachedGoal = function(measurements) { - var reached = false; - if(measurements[0] == z || measurements[1] == z) { - if(measurements[0] == z) { - this.goalBucket = 'one'; - this.otherBucket = measurements[1]; - } else { - this.goalBucket = 'two'; - this.otherBucket = measurements[0]; - } - reached = true; - } - return reached; - }; + this.reachedGoal = function(measurements) { + var reached = false; + if(measurements[0] == z || measurements[1] == z) { + if(measurements[0] == z) { + this.goalBucket = 'one'; + this.otherBucket = measurements[1]; + } else { + this.goalBucket = 'two'; + this.otherBucket = measurements[0]; + } + reached = true; + } + return reached; + }; - this.bigFirst = function(measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(k > x && j == 0 && moveCount == 0) { - j = x; - k = y - j; - } else if(j == x) { - j = 0; - } else if((k > x && j !== 0) || (k > x && prBool)) { - k = k - (x-j); - j = x; - } else if(k > x || j == 0) { - j = k; - k = k - j; - } else if(k == 0) { - k = y; - } - measurements = [j,k]; - moveCount++; - prBool ? prBool = false : prBool = true; - } - return moveCount; - }; + this.bigFirst = function(measurements, moveCount, prBool) { + var j = measurements[0], k = measurements[1]; + while(true) { + if(this.reachedGoal(measurements)) break; + if(k > x && j == 0 && moveCount == 0) { + j = x; + k = y - j; + } else if(j == x) { + j = 0; + } else if((k > x && j !== 0) || (k > x && prBool)) { + k = k - (x-j); + j = x; + } else if(k > x || j == 0) { + j = k; + k = k - j; + } else if(k == 0) { + k = y; + } + measurements = [j,k]; + moveCount++; + prBool ? prBool = false : prBool = true; + } + return moveCount; + }; - this.smallFirst = function(measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(j == x && moveCount == 0) { - j = 0; - k = x; - } else if(j == 0) { - j = x; - } else if(j == x && k < y) { - var tempK = k; - k + j > y ? k = y : k = tempK + j; - tempK + j > y ? j = j - (y- tempK) : j = 0; - } else if(k == y) { - k = 0; - } else if(k == 0 && j < x) { - k = j; - j = 0; - } - measurements = [j,k]; - moveCount++; - prBool ? prBool = false : prBool = true; - } - return moveCount; - }; + this.smallFirst = function(measurements, moveCount, prBool) { + var j = measurements[0], k = measurements[1]; + while(true) { + if(this.reachedGoal(measurements)) break; + if(j == x && moveCount == 0) { + j = 0; + k = x; + } else if(j == 0) { + j = x; + } else if(j == x && k < y) { + var tempK = k; + k + j > y ? k = y : k = tempK + j; + tempK + j > y ? j = j - (y- tempK) : j = 0; + } else if(k == y) { + k = 0; + } else if(k == 0 && j < x) { + k = j; + j = 0; + } + measurements = [j,k]; + moveCount++; + prBool ? prBool = false : prBool = true; + } + return moveCount; + }; } TwoBucket.prototype.moves = function() { - var j = 0, k = 0; //j will be running val of bucket one, k = running val of bucket two - this.starter == 'one' ? j = this.x : k = this.y; - var measurements = [j,k]; - var moveCount = 0; - var prBool = true; // pour / receive boolean - need to pour or receive every other turn - if(this.starter == 'one') { - moveCount = this.smallFirst(measurements, moveCount, prBool); - } else { - moveCount = this.bigFirst(measurements, moveCount, prBool); - } - return moveCount + 1; //accounts for first move made before loop (and moveCount starts at zero before loop) + var j = 0, k = 0; //j will be running val of bucket one, k = running val of bucket two + this.starter == 'one' ? j = this.x : k = this.y; + var measurements = [j,k]; + var moveCount = 0; + var prBool = true; // pour / receive boolean - need to pour or receive every other turn + if(this.starter == 'one') { + moveCount = this.smallFirst(measurements, moveCount, prBool); + } else { + moveCount = this.bigFirst(measurements, moveCount, prBool); + } + return moveCount + 1; //accounts for first move made before loop (and moveCount starts at zero before loop) }; module.exports = TwoBucket; diff --git a/exercises/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js index 3cd89428..412a4cde 100644 --- a/exercises/two-bucket/two-bucket.spec.js +++ b/exercises/two-bucket/two-bucket.spec.js @@ -1,47 +1,47 @@ var TwoBucket = require('./two-bucket'); describe('TwoBucket', function(){ - describe('works for input of 3,5,1', function(){ - var buckOne = 3; - var buckTwo = 5; - var goal = 1; + describe('works for input of 3,5,1', function(){ + var buckOne = 3; + var buckTwo = 5; + var goal = 1; - it('starting with bucket one', function(){ - var starterBuck = 'one'; //indicates which bucket to fill first - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(4); //includes the first fill - expect(twoBucket.goalBucket).toEqual('one'); //which bucket should end up with the desired # of liters - expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached - }); + it('starting with bucket one', function(){ + var starterBuck = 'one'; //indicates which bucket to fill first + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(4); //includes the first fill + expect(twoBucket.goalBucket).toEqual('one'); //which bucket should end up with the desired # of liters + expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached + }); - xit('starting with bucket two', function(){ - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(8); - expect(twoBucket.goalBucket).toEqual('two'); - expect(twoBucket.otherBucket).toEqual(3); - }); - }); + xit('starting with bucket two', function(){ + var starterBuck = 'two'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(8); + expect(twoBucket.goalBucket).toEqual('two'); + expect(twoBucket.otherBucket).toEqual(3); + }); + }); - describe('works for input of 7,11,2', function(){ - var buckOne = 7; - var buckTwo = 11; - var goal = 2; + describe('works for input of 7,11,2', function(){ + var buckOne = 7; + var buckTwo = 11; + var goal = 2; - xit('starting with bucket one', function(){ - var starterBuck = 'one'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(14); - expect(twoBucket.goalBucket).toEqual('one'); - expect(twoBucket.otherBucket).toEqual(11); - }); + xit('starting with bucket one', function(){ + var starterBuck = 'one'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(14); + expect(twoBucket.goalBucket).toEqual('one'); + expect(twoBucket.otherBucket).toEqual(11); + }); - xit('starting with bucket two', function(){ - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(18); - expect(twoBucket.goalBucket).toEqual('two'); - expect(twoBucket.otherBucket).toEqual(7); - }); - }); + xit('starting with bucket two', function(){ + var starterBuck = 'two'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(18); + expect(twoBucket.goalBucket).toEqual('two'); + expect(twoBucket.otherBucket).toEqual(7); + }); + }); }); From 7a2af2e350ab9659aa1242351539b310b90822e9 Mon Sep 17 00:00:00 2001 From: Suzanne Hamilton Date: Sat, 13 Feb 2016 19:20:15 +0000 Subject: [PATCH 031/272] Fix markdown syntax in ABOUT.md Fixes a layout bug when this page is rendered on exercism.io: the redcarpet Markdown parser used by exercism.io requires a blank line before lists, so the lists in this file were being rendered inline rather than as a
    . --- docs/ABOUT.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index bab0e9c7..624cfb6e 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -1,14 +1,16 @@ -Javascript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. Besides being fast, JavaScript provides benefits like :- +Javascript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. Besides being fast, JavaScript provides benefits like: + * Reducing server traffic by validating user input in the browser before it is sent to the server. * Providing immediate feedback to the site visitors so that they don't have to reload pages just to get error messages on form validations. * Allowing richer user interfaces with content changes on mouse hover, drag and drop gestures, and animations. Client-side JavaScript is interpreted in the browser without requiring compilation. This allows interactive content to be included in HTML pages which would otherwise be static. -Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/) +Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/). + +You should learn JavaScript because: -You should learn JavaScript because:- * It's easy to learn. * It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. * It's Open Source. -* JavaScript programming skills are in high demand. \ No newline at end of file +* JavaScript programming skills are in high demand. From 40311fa3ded64b8e85efc25e6316c6794169a0aa Mon Sep 17 00:00:00 2001 From: Thomas Zumsteg Date: Fri, 12 Feb 2016 09:30:54 -0800 Subject: [PATCH 032/272] Removed tabs and deleted two-bucket/example-2.js --- exercises/crypto-square/example.js | 76 ++++++------ exercises/two-bucket/example-2.js | 98 --------------- exercises/two-bucket/example.js | 154 ++++++++++++------------ exercises/two-bucket/two-bucket.spec.js | 76 ++++++------ 4 files changed, 153 insertions(+), 251 deletions(-) delete mode 100644 exercises/two-bucket/example-2.js diff --git a/exercises/crypto-square/example.js b/exercises/crypto-square/example.js index d1c39c3d..7a914a55 100644 --- a/exercises/crypto-square/example.js +++ b/exercises/crypto-square/example.js @@ -1,55 +1,55 @@ 'use strict'; module.exports = function(input) { - this.input = input; + this.input = input; - this.normalizePlaintext = function() { - return input.toLowerCase().replace(/[^a-zA-Z0-9]/g,''); - }; + this.normalizePlaintext = function() { + return input.toLowerCase().replace(/[^a-zA-Z0-9]/g,''); + }; - this.size = function() { - var realLength = Math.sqrt(this.normalizePlaintext().length); - return Math.ceil(realLength); - }; + this.size = function() { + var realLength = Math.sqrt(this.normalizePlaintext().length); + return Math.ceil(realLength); + }; - this.plaintextSegments = function() { - var plainText = this.normalizePlaintext(); - var chunkSize = this.size(); + this.plaintextSegments = function() { + var plainText = this.normalizePlaintext(); + var chunkSize = this.size(); - var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); - return plainText.match(splitRegex); - }; + var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); + return plainText.match(splitRegex); + }; - this.ciphertext = function() { - var textSegments = this.plaintextSegments(); - var i, j; - var columns = []; - var currentSegment; - var currentLetter; + this.ciphertext = function() { + var textSegments = this.plaintextSegments(); + var i, j; + var columns = []; + var currentSegment; + var currentLetter; - for (i = 0; i < this.size(); i++) { - columns.push([]); - } + for (i = 0; i < this.size(); i++) { + columns.push([]); + } - for (i = 0; i < textSegments.length; i++) { - currentSegment = textSegments[i]; + for (i = 0; i < textSegments.length; i++) { + currentSegment = textSegments[i]; - for (j = 0; j < currentSegment.length; j++) { - currentLetter = currentSegment[j]; - columns[j].push(currentLetter); - } - } + for (j = 0; j < currentSegment.length; j++) { + currentLetter = currentSegment[j]; + columns[j].push(currentLetter); + } + } - for (i = 0; i < columns.length; i++) { - columns[i] = columns[i].join(''); - } + for (i = 0; i < columns.length; i++) { + columns[i] = columns[i].join(''); + } - return columns.join(''); - }; + return columns.join(''); + }; - this.normalizeCiphertext = function() { + this.normalizeCiphertext = function() { var chunkSize = this.size(); var splitRegex = new RegExp('.{1,' + chunkSize + '}','g'); - return this.ciphertext().match(splitRegex).join(' '); - }; + return this.ciphertext().match(splitRegex).join(' '); + }; }; diff --git a/exercises/two-bucket/example-2.js b/exercises/two-bucket/example-2.js deleted file mode 100644 index 365b5cf9..00000000 --- a/exercises/two-bucket/example-2.js +++ /dev/null @@ -1,98 +0,0 @@ -//alternate solution written by Fullstack student, Griffin Telljohann -'use strict'; - -function TwoBucket(bucket1, bucket2, goal, startingBucket) { - this.b1max = bucket1; - this.b2max = bucket2; - this.goalAmount = goal; - this.states = {}; - var invalid = (startingBucket == 'one' ? 0 : this.b1max) + ',' + (startingBucket == 'two' ? 0 : this.b2max); - this.beenHere = {}; - this.beenHere[invalid] = true; - var bestSolution = this.solve((startingBucket == 'one' ? this.b1max : 0), (startingBucket == 'two' ? this.b2max : 0)); - this.goalBucket = bestSolution.goalBucket; - this.otherBucket = bestSolution.otherBucketFill; - this.minMoves = 1 + bestSolution.numMoves; -} - -TwoBucket.prototype.moves = function() { - return this.minMoves; -}; - -TwoBucket.prototype.solve = function(bucket1fill, bucket2fill) { - // if you've already been in this state, return - if (this.beenHere[bucket1fill + ',' + bucket2fill]) return {goalBucket: null}; - else this.beenHere[bucket1fill + ',' + bucket2fill] = true; - - // if either bucket is filled to the goal amount, you've found a solution - if (bucket1fill == this.goalAmount) { - return {numMoves: 0, goalBucket: 'one', otherBucketFill: bucket2fill}; - } - if (bucket2fill == this.goalAmount) { - return {numMoves: 0, goalBucket: 'two', otherBucketFill: bucket1fill}; - } - - if (this.states[bucket1fill + ',' + bucket2fill]) { - return this.states[bucket1fill + ',' + bucket2fill]; - } - - - var testObj, bestSolution = {goalBucket: null}; - // fill bucket 1 to top - if (bucket1fill !== this.b1max && bucket2fill !== this.b2max) { - testObj = this.solve(this.b1max, bucket2fill); - bestSolution = betterSolution(testObj, bestSolution); - } - - // fill bucket 2 to top - if (bucket1fill !== this.b1max && bucket2fill !== this.b2max) { - testObj = this.solve(bucket1fill, this.b2max); - bestSolution = betterSolution(testObj, bestSolution); - } - - // empty bucket 1 - if (bucket1fill !== 0 && bucket2fill !== 0) { - //console.log("empty 1"); - testObj = this.solve(0, bucket2fill); - bestSolution = betterSolution(testObj, bestSolution); - } - - // empty bucket 2 - if (bucket1fill !== 0 && bucket2fill !== 0) { - //console.log("empty 2"); - testObj = this.solve(bucket1fill, 0); - bestSolution = betterSolution(testObj, bestSolution); - } - - var totalAmount = bucket1fill + bucket2fill; - // pour bucket 1 into bucket 2 - if (bucket2fill !== this.b2max) { - if (totalAmount <= this.b2max) {testObj = this.solve(0, totalAmount);} - else {testObj = this.solve(totalAmount - this.b2max, this.b2max);} - bestSolution = betterSolution(testObj, bestSolution); - } - - // pour bucket 2 into bucket 1 - if (bucket1fill !== this.b1max) { - if (totalAmount <= this.b1max) testObj = this.solve(totalAmount, 0); - else testObj = this.solve(this.b1max, totalAmount - this.b1max); - bestSolution = betterSolution(testObj, bestSolution); - } - - this.states[bucket1fill + ',' + bucket2fill] = bestSolution; - if (typeof bestSolution.numMoves === 'number') { - bestSolution.numMoves++; - } - return bestSolution; -}; - -function betterSolution(test, currentBest) { - if (test.goalBucket) { - if (!currentBest || !currentBest.goalBucket || test.numMoves < currentBest.numMoves) { - return test; - } - } - return currentBest; -} - -module.exports = TwoBucket; diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index a1b1ce64..c6be2d57 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -1,89 +1,89 @@ 'use strict'; function TwoBucket(x,y,z,starter) { - this.starter = starter; - this.x = x; - this.y = y; + this.starter = starter; + this.x = x; + this.y = y; - this.reachedGoal = function(measurements) { - var reached = false; - if(measurements[0] == z || measurements[1] == z) { - if(measurements[0] == z) { - this.goalBucket = 'one'; - this.otherBucket = measurements[1]; - } else { - this.goalBucket = 'two'; - this.otherBucket = measurements[0]; - } - reached = true; - } - return reached; - }; + this.reachedGoal = function(measurements) { + var reached = false; + if(measurements[0] == z || measurements[1] == z) { + if(measurements[0] == z) { + this.goalBucket = 'one'; + this.otherBucket = measurements[1]; + } else { + this.goalBucket = 'two'; + this.otherBucket = measurements[0]; + } + reached = true; + } + return reached; + }; - this.bigFirst = function(measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(k > x && j == 0 && moveCount == 0) { - j = x; - k = y - j; - } else if(j == x) { - j = 0; - } else if((k > x && j !== 0) || (k > x && prBool)) { - k = k - (x-j); - j = x; - } else if(k > x || j == 0) { - j = k; - k = k - j; - } else if(k == 0) { - k = y; - } - measurements = [j,k]; - moveCount++; - prBool ? prBool = false : prBool = true; - } - return moveCount; - }; + this.bigFirst = function(measurements, moveCount, prBool) { + var j = measurements[0], k = measurements[1]; + while(true) { + if(this.reachedGoal(measurements)) break; + if(k > x && j == 0 && moveCount == 0) { + j = x; + k = y - j; + } else if(j == x) { + j = 0; + } else if((k > x && j !== 0) || (k > x && prBool)) { + k = k - (x-j); + j = x; + } else if(k > x || j == 0) { + j = k; + k = k - j; + } else if(k == 0) { + k = y; + } + measurements = [j,k]; + moveCount++; + prBool ? prBool = false : prBool = true; + } + return moveCount; + }; - this.smallFirst = function(measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(j == x && moveCount == 0) { - j = 0; - k = x; - } else if(j == 0) { - j = x; - } else if(j == x && k < y) { - var tempK = k; - k + j > y ? k = y : k = tempK + j; - tempK + j > y ? j = j - (y- tempK) : j = 0; - } else if(k == y) { - k = 0; - } else if(k == 0 && j < x) { - k = j; - j = 0; - } - measurements = [j,k]; - moveCount++; - prBool ? prBool = false : prBool = true; - } - return moveCount; - }; + this.smallFirst = function(measurements, moveCount, prBool) { + var j = measurements[0], k = measurements[1]; + while(true) { + if(this.reachedGoal(measurements)) break; + if(j == x && moveCount == 0) { + j = 0; + k = x; + } else if(j == 0) { + j = x; + } else if(j == x && k < y) { + var tempK = k; + k + j > y ? k = y : k = tempK + j; + tempK + j > y ? j = j - (y- tempK) : j = 0; + } else if(k == y) { + k = 0; + } else if(k == 0 && j < x) { + k = j; + j = 0; + } + measurements = [j,k]; + moveCount++; + prBool ? prBool = false : prBool = true; + } + return moveCount; + }; } TwoBucket.prototype.moves = function() { - var j = 0, k = 0; //j will be running val of bucket one, k = running val of bucket two - this.starter == 'one' ? j = this.x : k = this.y; - var measurements = [j,k]; - var moveCount = 0; - var prBool = true; // pour / receive boolean - need to pour or receive every other turn - if(this.starter == 'one') { - moveCount = this.smallFirst(measurements, moveCount, prBool); - } else { - moveCount = this.bigFirst(measurements, moveCount, prBool); - } - return moveCount + 1; //accounts for first move made before loop (and moveCount starts at zero before loop) + var j = 0, k = 0; //j will be running val of bucket one, k = running val of bucket two + this.starter == 'one' ? j = this.x : k = this.y; + var measurements = [j,k]; + var moveCount = 0; + var prBool = true; // pour / receive boolean - need to pour or receive every other turn + if(this.starter == 'one') { + moveCount = this.smallFirst(measurements, moveCount, prBool); + } else { + moveCount = this.bigFirst(measurements, moveCount, prBool); + } + return moveCount + 1; //accounts for first move made before loop (and moveCount starts at zero before loop) }; module.exports = TwoBucket; diff --git a/exercises/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js index 3cd89428..412a4cde 100644 --- a/exercises/two-bucket/two-bucket.spec.js +++ b/exercises/two-bucket/two-bucket.spec.js @@ -1,47 +1,47 @@ var TwoBucket = require('./two-bucket'); describe('TwoBucket', function(){ - describe('works for input of 3,5,1', function(){ - var buckOne = 3; - var buckTwo = 5; - var goal = 1; + describe('works for input of 3,5,1', function(){ + var buckOne = 3; + var buckTwo = 5; + var goal = 1; - it('starting with bucket one', function(){ - var starterBuck = 'one'; //indicates which bucket to fill first - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(4); //includes the first fill - expect(twoBucket.goalBucket).toEqual('one'); //which bucket should end up with the desired # of liters - expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached - }); + it('starting with bucket one', function(){ + var starterBuck = 'one'; //indicates which bucket to fill first + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(4); //includes the first fill + expect(twoBucket.goalBucket).toEqual('one'); //which bucket should end up with the desired # of liters + expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached + }); - xit('starting with bucket two', function(){ - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(8); - expect(twoBucket.goalBucket).toEqual('two'); - expect(twoBucket.otherBucket).toEqual(3); - }); - }); + xit('starting with bucket two', function(){ + var starterBuck = 'two'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(8); + expect(twoBucket.goalBucket).toEqual('two'); + expect(twoBucket.otherBucket).toEqual(3); + }); + }); - describe('works for input of 7,11,2', function(){ - var buckOne = 7; - var buckTwo = 11; - var goal = 2; + describe('works for input of 7,11,2', function(){ + var buckOne = 7; + var buckTwo = 11; + var goal = 2; - xit('starting with bucket one', function(){ - var starterBuck = 'one'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(14); - expect(twoBucket.goalBucket).toEqual('one'); - expect(twoBucket.otherBucket).toEqual(11); - }); + xit('starting with bucket one', function(){ + var starterBuck = 'one'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(14); + expect(twoBucket.goalBucket).toEqual('one'); + expect(twoBucket.otherBucket).toEqual(11); + }); - xit('starting with bucket two', function(){ - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(18); - expect(twoBucket.goalBucket).toEqual('two'); - expect(twoBucket.otherBucket).toEqual(7); - }); - }); + xit('starting with bucket two', function(){ + var starterBuck = 'two'; + var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + expect(twoBucket.moves()).toEqual(18); + expect(twoBucket.goalBucket).toEqual('two'); + expect(twoBucket.otherBucket).toEqual(7); + }); + }); }); From 1b2cae6524568c59eb2cfd3f0d9ac024adb3bc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 16 Feb 2016 16:40:23 +0100 Subject: [PATCH 033/272] Write a message trying to make it clear the intention of this track --- docs/ABOUT.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 624cfb6e..9bad6cea 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -14,3 +14,8 @@ You should learn JavaScript because: * It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. * It's Open Source. * JavaScript programming skills are in high demand. + +--- + +_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. If you're looking for experimenting with newer features of the language try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ + From 280424d7a59d5770bd4444d6eac162d5c9efa59e Mon Sep 17 00:00:00 2001 From: Michael Gee Date: Sun, 21 Feb 2016 11:23:46 -0500 Subject: [PATCH 034/272] Adding a missing isosceles case pointed out by @plinto in http://exercism.io/submissions/1a614864d2dc44bdb18e1be9f5f6970e --- exercises/triangle/triangle.spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/triangle/triangle.spec.js b/exercises/triangle/triangle.spec.js index 6105d02f..8760d2c5 100644 --- a/exercises/triangle/triangle.spec.js +++ b/exercises/triangle/triangle.spec.js @@ -17,6 +17,11 @@ describe('Triangle', function() { expect(triangle.kind()).toEqual('isosceles'); }); + xit('isosceles triangles have first two sides equal', function() { + var triangle = new Triangle(2,2,3); + expect(triangle.kind()).toEqual('isosceles'); + }); + xit('isosceles trianges have first and last sides equal', function() { var triangle = new Triangle(4,3,4); expect(triangle.kind()).toEqual('isosceles'); From a3df7e151273ac45ead13c97d6f58430652a8e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 16 Feb 2016 16:40:23 +0100 Subject: [PATCH 035/272] Write a message trying to make it clear the intention of this track --- docs/ABOUT.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 624cfb6e..9bad6cea 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -14,3 +14,8 @@ You should learn JavaScript because: * It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. * It's Open Source. * JavaScript programming skills are in high demand. + +--- + +_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. If you're looking for experimenting with newer features of the language try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ + From c0e785851175d059c358efbf4a30ffc86a717446 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Tue, 23 Feb 2016 17:00:12 -0500 Subject: [PATCH 036/272] Remove test which allows degenerate (a+b=c) triangles --- exercises/triangle/triangle.spec.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/exercises/triangle/triangle.spec.js b/exercises/triangle/triangle.spec.js index 8760d2c5..a23c7a79 100644 --- a/exercises/triangle/triangle.spec.js +++ b/exercises/triangle/triangle.spec.js @@ -72,11 +72,6 @@ describe('Triangle', function() { expect(triangle.kind.bind(triangle)).toThrow(); }); - xit('edge cases of triangle inequality are in fact legal', function() { - var triangle = new Triangle(2,4,2); - expect(triangle.kind.bind(triangle)).not.toThrow(); - }); - xit('triangles violating triangle inequality are illegal 2', function() { var triangle = new Triangle(7,3,2); expect(triangle.kind.bind(triangle)).toThrow(); From 1e55edd7efbdc6db4e37ad4f07e98d9b27a6f00b Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Thu, 25 Feb 2016 17:33:32 -0500 Subject: [PATCH 037/272] Update node version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e0b9a5f5..88f2a9ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: node_js node_js: - - 0.10 + - 5.7 script: - "make test" From cd3d834e11cf51084dd4d8a4345e5a5ff8c69141 Mon Sep 17 00:00:00 2001 From: cebial Date: Wed, 2 Mar 2016 18:39:11 +0100 Subject: [PATCH 038/272] Removed test which did a pop() on an empty degue. The README.md states: > To keep your implementation simple, the tests will not cover error conditions. > Specifically: pop or shift will never be called on an empty Deque --- exercises/linked-list/linked-list.spec.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/exercises/linked-list/linked-list.spec.js b/exercises/linked-list/linked-list.spec.js index 95f2259e..cfe78346 100644 --- a/exercises/linked-list/linked-list.spec.js +++ b/exercises/linked-list/linked-list.spec.js @@ -42,10 +42,6 @@ describe('LinkedList', function () { expect(list.pop()).toBe(50); expect(list.shift()).toBe(30); }); - xit('pops undefined when there are no elements', function () { - var list = new LinkedList(); - expect(list.pop()).toBe(undefined); - }); xit('can count its elements', function () { var list = new LinkedList(); expect(list.count()).toBe(0); From baa6de82b115993f34053162e378805a630a386c Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Mon, 7 Mar 2016 14:11:30 -0700 Subject: [PATCH 039/272] Use containerized build on travis We don't need to use sudo, and this should (technically) be faster, overall. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 88f2a9ef..248618cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: node_js +sudo: false + node_js: - 5.7 From 82a13dc02ee9a6a50cabfef85c8281503327eb42 Mon Sep 17 00:00:00 2001 From: Peter Tseng Date: Sat, 12 Mar 2016 17:41:48 -0800 Subject: [PATCH 040/272] largest-series-product: Do not test digits/slices The digits and slices functions are internal implementation details and thus the test case for the largest-series-product problem should not be concerned with testing them. The series tests could potentially be moved to the series exercise (already implemented by this track). Their presence may cause students to falsely think that their solution has to use these two functions, instead of the alternative implementation of only iterating through the digits once. If it is desired to give hints on how to approach this problem (which was one advantage of having the digits and slices tests), then consider including a hints file and/or directory in the largest-series-product directory. This PR arises from discussion in https://github.com/exercism/x-common/issues/192 Relevant to #169: This will satisfy the first part of the issue (ensure the track does not test implementation details); the question of whether hints are necessary is uncertain (as it is not known whether students will consider this problem too hard without guidance). --- .../largest-series-product.spec.js | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/exercises/largest-series-product/largest-series-product.spec.js b/exercises/largest-series-product/largest-series-product.spec.js index 9e03a0f5..3e24873e 100644 --- a/exercises/largest-series-product/largest-series-product.spec.js +++ b/exercises/largest-series-product/largest-series-product.spec.js @@ -2,29 +2,7 @@ var Series = require('./largest-series-product'); describe('Series', function () { - it('digits', function () { - expect(new Series('0123456789').digits).toEqual([0,1,2,3,4,5,6,7,8,9]); - }); - - xit('maintains digit order', function () { - expect(new Series('9876543210').digits).toEqual([9,8,7,6,5,4,3,2,1,0]); - }); - - xit('returns empty array for no digits', function () { - expect(new Series('').digits).toEqual([]); - }); - - xit('slices by 2', function () { - expect(new Series('01234').slices(2)) - .toEqual([[0, 1], [1, 2], [2, 3], [3, 4]]); - }); - - xit('slices by 3', function () { - expect(new Series('982347').slices(3)) - .toEqual([[9, 8, 2], [8, 2, 3], [2, 3, 4], [3, 4, 7]]); - }); - - xit('can get the largest product of 2', function () { + it('can get the largest product of 2', function () { expect(new Series('0123456789').largestProduct(2)).toBe(72); }); From 3897929e3ee07b5ff8817fbc04327982baaa104c Mon Sep 17 00:00:00 2001 From: Yan Kozlovskiy Date: Mon, 21 Mar 2016 22:44:05 -0700 Subject: [PATCH 041/272] make hex characters easier to understand This update will fix the example on the hex characters by telling the reader what each hex character is in normal text format. --- exercises/bob/bob.spec.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/exercises/bob/bob.spec.js b/exercises/bob/bob.spec.js index d5c1b02a..c87a1cc0 100644 --- a/exercises/bob/bob.spec.js +++ b/exercises/bob/bob.spec.js @@ -54,7 +54,13 @@ describe('Bob', function() { }); xit('shouting with umlauts', function() { - // NOTE: "\xfcML\xe4\xdcTS" === "üMLäÜTS" + /* NOTE: \xc4 = Ä + \xe4 = ä + \xdc = Ü + \xfc = ü + "\xfcML\xe4\xdcTS" === "üMLäÜTS" + */ + var result = bob.hey('\xdcML\xc4\xdcTS!'); expect(result).toEqual('Whoa, chill out!'); }); From 05778cb9aabe84120ec19a7e52fffbd66f57320d Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 28 Mar 2016 20:37:53 -0400 Subject: [PATCH 042/272] Remove default multiples --- exercises/sum-of-multiples/example.js | 16 ++++++++-------- .../sum-of-multiples/sum-of-multiples.spec.js | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/exercises/sum-of-multiples/example.js b/exercises/sum-of-multiples/example.js index 8ba4858d..0feb4e00 100644 --- a/exercises/sum-of-multiples/example.js +++ b/exercises/sum-of-multiples/example.js @@ -4,18 +4,16 @@ function isMultiple(i) { /*jshint validthis:true */ var result = false; this.multiples.forEach(function (multiple) { - if (i % multiple === 0) { result = true; } + if (i % multiple === 0) { + result = true; + } }); return result; } function SumOfMultiples(multiples) { if (!(this instanceof SumOfMultiples)) { - if (multiples === undefined) { - return new SumOfMultiples([5, 3]); - } else { - return new SumOfMultiples(multiples); - } + return new SumOfMultiples(multiples); } this.multiples = multiples; } @@ -23,9 +21,11 @@ function SumOfMultiples(multiples) { SumOfMultiples.prototype.to = function (limit) { var sum = 0; for (var i = 1; i < limit; i++) { - if (isMultiple.call(this, i)) { sum += i; } + if (isMultiple.call(this, i)) { + sum += i; + } } return sum; }; -module.exports = SumOfMultiples; \ No newline at end of file +module.exports = SumOfMultiples; diff --git a/exercises/sum-of-multiples/sum-of-multiples.spec.js b/exercises/sum-of-multiples/sum-of-multiples.spec.js index de952cca..8866cda9 100644 --- a/exercises/sum-of-multiples/sum-of-multiples.spec.js +++ b/exercises/sum-of-multiples/sum-of-multiples.spec.js @@ -2,23 +2,23 @@ var SumOfMultiples = require('./sum-of-multiples'); describe('SumOfMultiples', function () { it('to 1', function () { - expect(SumOfMultiples().to(1)).toBe(0); + expect(SumOfMultiples([3, 5]).to(1)).toBe(0); }); xit('to 3', function () { - expect(SumOfMultiples().to(4)).toBe(3); + expect(SumOfMultiples([3, 5]).to(4)).toBe(3); }); xit('to 10', function () { - expect(SumOfMultiples().to(10)).toBe(23); + expect(SumOfMultiples([3, 5]).to(10)).toBe(23); }); xit('to 100', function () { - expect(SumOfMultiples().to(100)).toBe(2318); + expect(SumOfMultiples([3, 5]).to(100)).toBe(2318); }); xit('to 1000', function () { - expect(SumOfMultiples().to(1000)).toBe(233168); + expect(SumOfMultiples([3, 5]).to(1000)).toBe(233168); }); xit('[7, 13, 17] to 20', function () { From 29a7eea1787c9febefe9a6aa48a9c28dd7eeb1ce Mon Sep 17 00:00:00 2001 From: Nick Duffy Date: Sat, 2 Apr 2016 15:36:24 -0600 Subject: [PATCH 043/272] Update links to remove deprecated help.exercism.io --- docs/TESTS.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 1b169248..d65e0170 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -33,11 +33,11 @@ To get started, you can download a Visual Studio solution that is already set up 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` -2. Install the [Exercism CLI](http://help.exercism.io/installing-the-cli.html) -3. Open a command prompt to your exercise directory +2. Install the [Exercism CLI](http://exercism.io/cli) +3. Open a command prompt to your exercise directory 4. Add your API key to exercism `exercism configure --key=YOUR_API_KEY` 5. Configure your source directory in exercism `exercism configure --dir=C:\src\exercises` -6. [Fetch your first exercise](http://help.exercism.io/fetching-exercises.html) `exercism fetch javascript` +6. [Fetch your first exercise](http://exercism.io/languages/javascript) `exercism fetch javascript` 7. Open the Exercism solution in Visual Studio 8. Expand the Exercism.javascript project 9. Click on **Show All Files** in Solution Explorer (See below) @@ -67,4 +67,3 @@ A linter is like a tester for your code's style and formatting. In some language The old standard linter for JavaScript is [JSLint](http://jslint.com). However, it is controversially picky. [JSHint](http://jshint.com) is another popular linter. We suggest using [ESLint](http://eslint.org), which is more customizable than either JSLint or JSHint, and is well-run. To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple ```eslint [options] [file|dir]*``` command. Eg, if you're in the hello-world directory, ```eslint .``` would lint all files in that directory. - From ca4e3cf1dd28d1d2ee29c40af211afe4e6b9865b Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 4 Apr 2016 06:44:26 -0400 Subject: [PATCH 044/272] Update tests and example to be case-agnostic --- exercises/word-count/example.js | 3 ++- exercises/word-count/word-count.spec.js | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/exercises/word-count/example.js b/exercises/word-count/example.js index 7b7a27dc..02aa1d9e 100644 --- a/exercises/word-count/example.js +++ b/exercises/word-count/example.js @@ -7,7 +7,8 @@ Words.prototype.count = function (input) { var words = input.match(/\S+/g); words.forEach(function (word) { - counts[word] = counts.hasOwnProperty(word) ? counts[word] + 1 : 1; + var lcWord = word.toLowerCase(); + counts[lcWord] = counts.hasOwnProperty(lcWord) ? counts[lcWord] + 1 : 1; }); return counts; diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index cc1e37ab..f5a29069 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -29,12 +29,12 @@ describe('count()', function() { }); xit('respects case', function() { - var expectedCounts = { go: 1, Go:1, GO:1 }; + var expectedCounts = { go: 3 }; expect(words.count('go Go GO')).toEqual(expectedCounts); }); xit('counts properly international characters', function() { - var expectedCounts = { '¡Hola!': 1, '¿Qué': 1, 'tal?': 1, 'Привет!': 1 }; + var expectedCounts = { '¡hola!': 1, '¿qué': 1, 'tal?': 1, 'привет!': 1 }; expect(words.count('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); }); @@ -54,12 +54,12 @@ describe('count()', function() { }); xit('does not count leading or trailing whitespace', function() { - var expectedCounts = { Introductory: 1, Course: 1 }; + var expectedCounts = { introductory: 1, course: 1 }; expect(words.count('\t\tIntroductory Course ')).toEqual(expectedCounts); }); xit('handles properties that exist on Object’s prototype', function() { - var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, toString: 1, 'ok?': 1}; + var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, tostring: 1, 'ok?': 1}; expect(words.count('reserved words like prototype and toString ok?')).toEqual(expectedCounts); }); }); From 30b4a7e3bcfc372dac6af24490d6437dd7e1bf3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Mon, 4 Apr 2016 22:44:33 +0200 Subject: [PATCH 045/272] Improve spec description --- exercises/word-count/word-count.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index f5a29069..87117287 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -28,7 +28,7 @@ describe('count()', function() { expect(words.count('testing 1 2 testing')).toEqual(expectedCounts); }); - xit('respects case', function() { + xit('normalizes to lowercase', function() { var expectedCounts = { go: 3 }; expect(words.count('go Go GO')).toEqual(expectedCounts); }); From 5861d1cf8ed091df032502d85028f42d36010ef8 Mon Sep 17 00:00:00 2001 From: Gant Date: Mon, 4 Apr 2016 16:53:28 -0500 Subject: [PATCH 046/272] added proper declaration and spacing to grade-school spec --- exercises/grade-school/grade-school.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exercises/grade-school/grade-school.spec.js b/exercises/grade-school/grade-school.spec.js index 02425d4c..9a58167c 100644 --- a/exercises/grade-school/grade-school.spec.js +++ b/exercises/grade-school/grade-school.spec.js @@ -28,7 +28,7 @@ describe('School', function() { xit('adding students to different grades adds them to the roster', function() { school.add('Chelsea',3); school.add('Logan',7); - var expectedDb = { 3 : [ 'Chelsea' ], 7 : [ 'Logan'] }; + var expectedDb = { 3 : [ 'Chelsea' ], 7 : [ 'Logan' ] }; expect(school.roster()).toEqual(expectedDb); }); @@ -49,10 +49,10 @@ describe('School', function() { school.add('Kareem', 6); school.add('Christopher', 4); school.add('Kyle', 3); - sorted = { - 3 : ['Kyle'], - 4 : ['Christopher', 'Jennifer'], - 6 : ['Kareem'] + var sorted = { + 3 : [ 'Kyle' ], + 4 : [ 'Christopher', 'Jennifer' ], + 6 : [ 'Kareem' ] }; expect(school.roster()).toEqual(sorted); }); From a1a957577e24b2a5b4e7312e061036074a39d00f Mon Sep 17 00:00:00 2001 From: Nick Duffy Date: Sat, 2 Apr 2016 15:36:24 -0600 Subject: [PATCH 047/272] Update links to remove deprecated help.exercism.io --- docs/TESTS.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 1b169248..d65e0170 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -33,11 +33,11 @@ To get started, you can download a Visual Studio solution that is already set up 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` -2. Install the [Exercism CLI](http://help.exercism.io/installing-the-cli.html) -3. Open a command prompt to your exercise directory +2. Install the [Exercism CLI](http://exercism.io/cli) +3. Open a command prompt to your exercise directory 4. Add your API key to exercism `exercism configure --key=YOUR_API_KEY` 5. Configure your source directory in exercism `exercism configure --dir=C:\src\exercises` -6. [Fetch your first exercise](http://help.exercism.io/fetching-exercises.html) `exercism fetch javascript` +6. [Fetch your first exercise](http://exercism.io/languages/javascript) `exercism fetch javascript` 7. Open the Exercism solution in Visual Studio 8. Expand the Exercism.javascript project 9. Click on **Show All Files** in Solution Explorer (See below) @@ -67,4 +67,3 @@ A linter is like a tester for your code's style and formatting. In some language The old standard linter for JavaScript is [JSLint](http://jslint.com). However, it is controversially picky. [JSHint](http://jshint.com) is another popular linter. We suggest using [ESLint](http://eslint.org), which is more customizable than either JSLint or JSHint, and is well-run. To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple ```eslint [options] [file|dir]*``` command. Eg, if you're in the hello-world directory, ```eslint .``` would lint all files in that directory. - From 23f93e929115ce6e9f9a48fb0eeba72847c755c2 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 4 Apr 2016 06:44:26 -0400 Subject: [PATCH 048/272] Update tests and example to be case-agnostic --- exercises/word-count/example.js | 3 ++- exercises/word-count/word-count.spec.js | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/exercises/word-count/example.js b/exercises/word-count/example.js index 7b7a27dc..02aa1d9e 100644 --- a/exercises/word-count/example.js +++ b/exercises/word-count/example.js @@ -7,7 +7,8 @@ Words.prototype.count = function (input) { var words = input.match(/\S+/g); words.forEach(function (word) { - counts[word] = counts.hasOwnProperty(word) ? counts[word] + 1 : 1; + var lcWord = word.toLowerCase(); + counts[lcWord] = counts.hasOwnProperty(lcWord) ? counts[lcWord] + 1 : 1; }); return counts; diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index cc1e37ab..f5a29069 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -29,12 +29,12 @@ describe('count()', function() { }); xit('respects case', function() { - var expectedCounts = { go: 1, Go:1, GO:1 }; + var expectedCounts = { go: 3 }; expect(words.count('go Go GO')).toEqual(expectedCounts); }); xit('counts properly international characters', function() { - var expectedCounts = { '¡Hola!': 1, '¿Qué': 1, 'tal?': 1, 'Привет!': 1 }; + var expectedCounts = { '¡hola!': 1, '¿qué': 1, 'tal?': 1, 'привет!': 1 }; expect(words.count('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); }); @@ -54,12 +54,12 @@ describe('count()', function() { }); xit('does not count leading or trailing whitespace', function() { - var expectedCounts = { Introductory: 1, Course: 1 }; + var expectedCounts = { introductory: 1, course: 1 }; expect(words.count('\t\tIntroductory Course ')).toEqual(expectedCounts); }); xit('handles properties that exist on Object’s prototype', function() { - var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, toString: 1, 'ok?': 1}; + var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, tostring: 1, 'ok?': 1}; expect(words.count('reserved words like prototype and toString ok?')).toEqual(expectedCounts); }); }); From 4b78d4f8a4792281899c2ff3ca8e8cfc14e07c5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Mon, 4 Apr 2016 22:44:33 +0200 Subject: [PATCH 049/272] Improve spec description --- exercises/word-count/word-count.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index f5a29069..87117287 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -28,7 +28,7 @@ describe('count()', function() { expect(words.count('testing 1 2 testing')).toEqual(expectedCounts); }); - xit('respects case', function() { + xit('normalizes to lowercase', function() { var expectedCounts = { go: 3 }; expect(words.count('go Go GO')).toEqual(expectedCounts); }); From 1db8f0997cb0c3566714fdfb9bb99e7d9519d5db Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Thu, 7 Apr 2016 07:30:03 -0400 Subject: [PATCH 050/272] Replace "multibillionaire" with "oxyphenbutazone" --- exercises/scrabble-score/scrabble-score.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/scrabble-score/scrabble-score.spec.js b/exercises/scrabble-score/scrabble-score.spec.js index 0ebe262c..dc9a8787 100644 --- a/exercises/scrabble-score/scrabble-score.spec.js +++ b/exercises/scrabble-score/scrabble-score.spec.js @@ -22,6 +22,6 @@ describe('Scrabble', function() { }); xit('scores case insensitive words',function() { - expect(score('MULTIBILLIONAIRE')).toEqual(20); + expect(score('OXYPHENBUTAZONE')).toEqual(41); }); }); From da1db808f9cfd40990b54b7ac696f3a01444d6e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Thu, 7 Apr 2016 22:31:01 +0200 Subject: [PATCH 051/272] Binary: add missing test --- exercises/binary/binary.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/binary/binary.spec.js b/exercises/binary/binary.spec.js index 63ed387c..b90f7d0e 100644 --- a/exercises/binary/binary.spec.js +++ b/exercises/binary/binary.spec.js @@ -42,6 +42,7 @@ describe('binary', function() { expect(new Binary('012').toDecimal()).toEqual(0); expect(new Binary('10nope').toDecimal()).toEqual(0); expect(new Binary('nope10').toDecimal()).toEqual(0); + expect(new Binary('10nope10').toDecimal()).toEqual(0); }); }); From 9369b3f4a476aa73b85661f9802902333785efae Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Fri, 8 Apr 2016 05:52:23 -0400 Subject: [PATCH 052/272] Add canonical test cases --- exercises/largest-series-product/example.js | 6 +++-- .../largest-series-product.spec.js | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/exercises/largest-series-product/example.js b/exercises/largest-series-product/example.js index ce10741e..1fb9a41f 100644 --- a/exercises/largest-series-product/example.js +++ b/exercises/largest-series-product/example.js @@ -1,6 +1,7 @@ 'use strict'; function Series(numberString) { + if(numberString.match('[^0-9]')) throw new Error('Invalid input.'); this.numberString = numberString; this.digits = this.getDigits(); } @@ -12,6 +13,7 @@ Series.prototype.getDigits = function () { }; Series.prototype.largestProduct = function (size) { + if (size < 0) throw new Error('Invalid input.'); var product, max = 0; this.slices(size).forEach(function (slice) { product = slice.reduce(function(a, b) { @@ -29,7 +31,7 @@ Series.prototype.slices = function (sliceSize) { if (sliceSize > this.digits.length) { throw new Error('Slice size is too big.'); } - + for (var i = 0; i < this.digits.length - sliceSize + 1; i++) { for (var j = 0; j < sliceSize; j++) { slice.push(this.digits[i+j]); @@ -41,4 +43,4 @@ Series.prototype.slices = function (sliceSize) { return result; }; -module.exports = Series; \ No newline at end of file +module.exports = Series; diff --git a/exercises/largest-series-product/largest-series-product.spec.js b/exercises/largest-series-product/largest-series-product.spec.js index 3e24873e..8c7e181c 100644 --- a/exercises/largest-series-product/largest-series-product.spec.js +++ b/exercises/largest-series-product/largest-series-product.spec.js @@ -15,8 +15,16 @@ describe('Series', function () { }); xit('can get the largest product of a big number', function () { - var largeNumber = '73167176531330624919225119674426574742355349194934'; - expect(new Series(largeNumber).largestProduct(6)).toBe(23520); + var largeNumber = '73167176531330624919225119674426574742355349194934969835203127745063262395783180169848018694788' + + '51843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648' + + '95044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749303589072962904915604' + + '40772390713810515859307960866701724271218839987979087922749219016997208880937766572733300105336788122023542180975' + + '12545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622' + + '48283972241375657056057490261407972968652414535100474821663704844031998900088952434506585412275886668811642717147' + + '99244429282308634656748139191231628245861786645835912456652947654568284891288314260769004224219022671055626321111' + + '10937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636' + + '899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'; + expect(new Series(largeNumber).largestProduct(13)).toBe(23514624000); }); xit('returns 0 if all digits are zero', function () { @@ -27,6 +35,18 @@ describe('Series', function () { expect(new Series('99099').largestProduct(3)).toBe(0); }); + xit('rejects invalid character in input', ()=> { + expect(function () { + new Series('1234a5').largestProduct('2') + }).toThrow(new Error('Invalid input.')); + }); + + xit('rejects negative span', function () { + expect(() => { + new Series('12345').largestProduct(-1) + }).toThrow(new Error('Invalid input.')); + }); + xit('returns 1 for empty string and zero slice length', function () { expect(new Series('').largestProduct(0)).toBe(1); }); From 7c2723cb5a6bdd558745b25d240b5928cea36976 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sat, 23 Apr 2016 07:10:51 -0400 Subject: [PATCH 053/272] Update tests for Pangram --- exercises/pangram/pangram.spec.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/exercises/pangram/pangram.spec.js b/exercises/pangram/pangram.spec.js index efc6e797..d7feee37 100644 --- a/exercises/pangram/pangram.spec.js +++ b/exercises/pangram/pangram.spec.js @@ -17,6 +17,26 @@ describe('Pangram()', function() { expect(pangram.isPangram()).toBe(false); }); + xit("another missing character 'x'", function() { + var pangram = new Pangram("the quick brown fish jumps over the lazy dog"); + expect(pangram.isPangram()).toBe(false); + }); + + xit("pangram with underscores", function() { + var pangram = new Pangram("the_quick_brown_fox_jumps_over_the_lazy_dog"); + expect(pangram.isPangram()).toBe(true); + }); + + xit("pangram with numbers", function() { + var pangram = new Pangram("the 1 quick brown fox jumps over the 2 lazy dogs"); + expect(pangram.isPangram()).toBe(true); + }); + + xit('missing letters replaced by numbers', function() { + var pangram = new Pangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog"); + expect(pangram.isPangram()).toBe(false); + }); + xit('pangram with mixed case and punctuation', function() { var pangram = new Pangram("\"Five quacking Zephyrs jolt my wax bed.\""); expect(pangram.isPangram()).toBe(true); From 295ddb36c2ecf5d2d43b60cace934c8992980ea3 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 29 Apr 2016 16:54:36 -0600 Subject: [PATCH 054/272] Make the test instructions more beginner-friendly The github-flavored-markdown section of SETUP using the fenceposts is completely non-obvious if you aren't familiar with markdown. I just watched a newbie try to type in the backticks and "bash" along with the dollar-sign. This removes some of the clutter. --- SETUP.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SETUP.md b/SETUP.md index cbaa639b..65157035 100644 --- a/SETUP.md +++ b/SETUP.md @@ -9,9 +9,7 @@ http://exercism.io/languages/javascript Execute the tests with: -```bash -$ jasmine-node . -``` + jasmine-node . In many test suites all but the first test have been skipped. From b5052a144abcfe2ff3f079081f38ccd611c0ec07 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 29 Apr 2016 17:07:13 -0600 Subject: [PATCH 055/272] Clarify hello-world stub file comments I removed 'only' because it doesn't seem to serve a purpose. I switched SKELETON to stub because we don't need to shout, and we use the term stub file elsewhere on the site. Lastly, I changed the file name to match the actual file name in the exercise. --- exercises/hello-world/hello-world.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/hello-world/hello-world.js b/exercises/hello-world/hello-world.js index dfb2ad94..4968271d 100644 --- a/exercises/hello-world/hello-world.js +++ b/exercises/hello-world/hello-world.js @@ -1,7 +1,7 @@ // -// This is only a SKELETON file for the 'Hello World' exercise. It's been provided as a +// This is a stub file for the 'Hello World' exercise. It's been provided as a // convenience to get you started writing code faster. -// Make sure to look at test.script.js--that should give you some hints about what is +// Make sure to look at hello-world.spec.js--that should give you some hints about what is // expected here. var HelloWorld = function() {}; From 96a9b3fc6c1e36b7b556d80e54188ee280e10b73 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 29 Apr 2016 17:42:56 -0600 Subject: [PATCH 056/272] Add a basic tutorial for hello-world If you've only ever written javascript for the browser, and you've never done any TDD, then this exercise has a lot of barriers to success. This tutorial might help get people started. --- exercises/hello-world/HINTS.md | 102 +++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 exercises/hello-world/HINTS.md diff --git a/exercises/hello-world/HINTS.md b/exercises/hello-world/HINTS.md new file mode 100644 index 00000000..ebed1f4b --- /dev/null +++ b/exercises/hello-world/HINTS.md @@ -0,0 +1,102 @@ +## Tutorial + +This exercise has two files: + +- hello-world.js +- hello-world.spec.js + +The first file is where you will write your code. +The second is where the tests are defined. + +The tests will check whether your code is doing the right thing. +You don't need to be able to write a test suite from scratch, +but it helps to understand what a test looks like, and what +it is doing. + +Open up the test file, hello-world.spec.js. +It has three tests defined in it. + +This is the first test: + + it('says hello world with no name', function() { + expect(helloWorld.hello('')).toEqual('Hello, World!'); + }); + +Run the test now, with the following command on the command-line: + + jasmine-node . + +The test fails, which makes sense since you've not written any code yet. + +The failure looks like this: + + 1) Hello World says hello world with no name + Message: + Expected undefined to equal 'Hello, World!'. + +There's more, but this is the most important part. + +Take a look at that first line: + + 1) Hello World says hello world with no name + +Now look at the test definition again: + + it('says hello world with no name', function() { + // ... more code here ... + }); + +The text 'says hello world with no name' is repeated. +This is how you know which test failed. + +The failure message explains what is wrong: + + Expected undefined to equal 'Hello, World!'. + +This comes from the part of the test definition that says "expect": + + expect(helloWorld.hello('')).toEqual('Hello, World!'); + +It's comparing two values. It is calling + + helloWorld.hello('') + +and comparing the result to a hard-coded string. + + 'Hello, World!'. + +So if you look at the failure message again, the hello function +is returning undefined. + +Try changing the function in hello-world.js so that it says + + HelloWorld.prototype.hello = function(input) { + return "chocolate"; + }; + +Then run the tests again from the command-line: + + jasmine-node . + +Notice how it changes the failure message. + +Then change the implementation in hello-world.js again, this time to make the test pass. + +Once the test is passing, look at the second test in hello-world.spec.js. It looks like this: + + xit('says hello to bob', function() { + expect(helloWorld.hello('Bob')).toEqual('Hello, Bob!'); + }); + +This test starts with `xit` instead of `it`. +That means that when jasmine-node runs the tests, +the test will be skipped. + +Change the test so that it starts with `it`, +and run the tests again. + +Make the test pass, and then do the same with the third test. + +When you are done, submit your solution to exercism: + + exercism submit hello-world.js From c919fa87c714af6f83866c3badb465524d691979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Sat, 30 Apr 2016 21:07:46 +0200 Subject: [PATCH 057/272] Remove clutter from documentation Remove clutter from markdown text to make it simpler for beginners --- docs/INSTALLATION.md | 13 ++++--------- docs/TESTS.md | 32 +++++++++++++------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index b60dd031..02b8ba5d 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -6,18 +6,13 @@ Install `jasmine-node`: -```bash -$ npm install jasmine-node -g -``` + npm install jasmine-node -g Depending on your setup, you may need super user privileges to install an NPM module globally. This is the case if you've used the official installer linked to above. If NPM gives you an error saying you don't have access, add `sudo` to the command above: -```bash -$ sudo npm install jasmine-node -g -```` + sudo npm install jasmine-node -g 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 your `PATH` to include the `npm` binaries by adding the following to either `~/.bash_profile` or `~/.zshrc`: -```bash -$ export PATH=/usr/local/share/npm/bin:$PATH -``` + export PATH=/usr/local/share/npm/bin:$PATH + diff --git a/docs/TESTS.md b/docs/TESTS.md index d65e0170..47080fff 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,24 +1,20 @@ Execute the tests with: -```bash -$ jasmine-node bob_test.spec.js -``` + jasmine-node bob_test.spec.js ## Making Your First Node Module To create a module that can be loaded with `var Bob = require('./bob.js');`, put this code in `bob.js`: -```javascript -var Bob = function() {}; + var Bob = function() {}; -Bob.prototype.hey = function(what) { - // - // Your solution to the exercise goes here - // -}; + Bob.prototype.hey = function(what) { + // + // Your solution to the exercise goes here + // + }; -module.exports = Bob; -``` + module.exports = Bob; You can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). To make it easier to get started, there's a "skeleton" bob.js file in the directory for the first exercise. @@ -50,13 +46,11 @@ If you have a paid version of Visual Studio, you should install the [Web Essenti You can run the unit tests from a node.js command line using the batch file in the project. -``` -C:\Src\exercises\javascript>test example\bob_test.spec.js -................. + C:\Src\exercises\javascript>test example\bob_test.spec.js + ................. -Finished in 0.02 seconds -17 tests, 17 assertions, 0 failures, 0 skipped -``` + Finished in 0.02 seconds + 17 tests, 17 assertions, 0 failures, 0 skipped If you do not see any output from running the tests, you are likely not in a Node.js command prompt. @@ -66,4 +60,4 @@ A linter is like a tester for your code's style and formatting. In some language The old standard linter for JavaScript is [JSLint](http://jslint.com). However, it is controversially picky. [JSHint](http://jshint.com) is another popular linter. We suggest using [ESLint](http://eslint.org), which is more customizable than either JSLint or JSHint, and is well-run. -To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple ```eslint [options] [file|dir]*``` command. Eg, if you're in the hello-world directory, ```eslint .``` would lint all files in that directory. +To get started using ESLint, follow the instructions [here](http://eslint.org/docs/user-guide/command-line-interface.html). Once you have ESLint installed, you'll be able to lint your code with a simple `eslint [options] [file|dir]*` command. Eg, if you're in the hello-world directory, `eslint .` would lint all files in that directory. From 4483d6068daaa8ead37ec3f42fee965df13d19d6 Mon Sep 17 00:00:00 2001 From: ecrmnn Date: Thu, 5 May 2016 12:55:56 +0200 Subject: [PATCH 058/272] Isogram: Tests and example --- config.json | 15 ++++---- exercises/isogram/example.js | 11 ++++++ exercises/isogram/isogram.spec.js | 57 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 exercises/isogram/example.js create mode 100644 exercises/isogram/isogram.spec.js diff --git a/config.json b/config.json index 3da8516e..310c9bb6 100644 --- a/config.json +++ b/config.json @@ -6,14 +6,15 @@ "test_pattern": ".*[.]spec[.]js$", "problems": [ "hello-world", - "leap", + "leap", "hamming", - "rna-transcription", - "bob", - "gigasecond", - "word-count", + "rna-transcription", + "bob", + "gigasecond", + "word-count", + "isogram", "pangram", - "beer-song", + "beer-song", "phone-number", "anagram", "food-chain", @@ -69,7 +70,7 @@ "two-bucket" ], "deprecated": [ - "nucleotide-count", + "nucleotide-count", "point-mutations" ], "ignored": [ diff --git a/exercises/isogram/example.js b/exercises/isogram/example.js new file mode 100644 index 00000000..531a9248 --- /dev/null +++ b/exercises/isogram/example.js @@ -0,0 +1,11 @@ +module.exports = function (word) { + this.word = word.replace(/ |-/g, ''); + + this.isIsogram = function () { + var unique = this.word.toLowerCase().split('').filter(function (element, index, self) { + return self.indexOf(element) === index; + }); + + return unique.length === this.word.length; + } +} diff --git a/exercises/isogram/isogram.spec.js b/exercises/isogram/isogram.spec.js new file mode 100644 index 00000000..98a097c2 --- /dev/null +++ b/exercises/isogram/isogram.spec.js @@ -0,0 +1,57 @@ +var Isogram = require('./isogram'); + +describe('Isogram Test Suite', function () { + it('duplicates', function () { + var word = new Isogram('duplicates'); + + expect(word.isIsogram()).toEqual(true); + }); + + xit('eleven', function () { + var word = new Isogram('eleven'); + + expect(word.isIsogram()).toEqual(false); + }); + + xit('subdermatoglyphic', function () { + var word = new Isogram('subdermatoglyphic'); + + expect(word.isIsogram()).toEqual(true); + }); + + xit('Alphabet', function () { + var word = new Isogram('Alphabet'); + + expect(word.isIsogram()).toEqual(false); + }); + + xit('thumbscrew-japingly', function () { + var word = new Isogram('thumbscrew-japingly'); + + expect(word.isIsogram()).toEqual(true); + }); + + xit('Hjelmqvist-Gryb-Zock-Pfund-Wax', function () { + var word = new Isogram('Hjelmqvist-Gryb-Zock-Pfund-Wax'); + + expect(word.isIsogram()).toEqual(true); + }); + + xit('Heizölrückstoßabdämpfung', function () { + var word = new Isogram('Heizölrückstoßabdämpfung'); + + expect(word.isIsogram()).toEqual(true); + }); + + xit('the quick brown fox', function () { + var word = new Isogram('the quick brown fox'); + + expect(word.isIsogram()).toEqual(false); + }); + + xit('Emily Jung Schwartzkopf', function () { + var word = new Isogram('Emily Jung Schwartzkopf'); + + expect(word.isIsogram()).toEqual(true); + }); +}); From b653bcaa5ac6b277be7aaf1112aa45c03a78f994 Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Thu, 5 May 2016 17:44:43 +0100 Subject: [PATCH 059/272] word-count: use 'constructor' as a reserved word As 'prototype' isn't a standard property on an object's prototype, the test didn't actually check the case of dealing with a collision The 'constructor' property is a standard see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object and: http://www.ecma-international.org/ecma-262/5.1/#sec-15.2.4 --- exercises/word-count/word-count.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index 87117287..ab503dda 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -59,7 +59,7 @@ describe('count()', function() { }); xit('handles properties that exist on Object’s prototype', function() { - var expectedCounts = { reserved: 1, words : 1, like :1, prototype: 1, and : 1, tostring: 1, 'ok?': 1}; - expect(words.count('reserved words like prototype and toString ok?')).toEqual(expectedCounts); + var expectedCounts = { reserved: 1, words: 1, like: 1, constructor: 1, and: 1, tostring: 1, 'ok?': 1 }; + expect(words.count('reserved words like constructor and toString ok?')).toEqual(expectedCounts); }); }); From d240de12c04ccf4f61627e282d2a7e7721cf8382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Wed, 20 Apr 2016 23:26:01 +0200 Subject: [PATCH 060/272] Clock: synchronize tests with canonical ones --- exercises/clock/clock.spec.js | 244 ++++++++++++++++++++++++++++------ exercises/clock/example.js | 25 +++- 2 files changed, 220 insertions(+), 49 deletions(-) diff --git a/exercises/clock/clock.spec.js b/exercises/clock/clock.spec.js index 83933d25..0fa74872 100644 --- a/exercises/clock/clock.spec.js +++ b/exercises/clock/clock.spec.js @@ -2,60 +2,216 @@ var at = require('./clock').at; describe('Clock', function () { - it('prints the hour', function () { - expect(at(8).toString()).toEqual('08:00'); - expect(at(9).toString()).toEqual('09:00'); - }); + describe('Creating a new clock with an initial time', function () { - xit('prints past the hour', function () { - expect(at(11, 9).toString()).toEqual('11:09'); - expect(at(11, 19).toString()).toEqual('11:19'); - }); + it('on the hour', function () { + expect(at(8).toString()).toEqual('08:00'); + }); - xit('can add minutes', function () { - var clock = at(10).plus(3); - expect(clock.toString()).toEqual('10:03'); - }); + xit('past the hour', function () { + expect(at(11, 9).toString()).toEqual('11:09'); + }); - xit('can add over an hour', function () { - var clock = at(10).plus(61); - expect(clock.toString()).toEqual('11:01'); - }); + xit('midnight is zero hours', function () { + expect(at(24, 0).toString()).toEqual('00:00'); + }); - xit('wraps around midnight', function () { - var clock = at(23, 59).plus(2); - expect(clock.toString()).toEqual('00:01'); - }); + xit('hour rolls over', function () { + expect(at(25, 0).toString()).toEqual('01:00'); + }); - xit('can subtract minutes', function () { - var clock = at(10, 3).minus(3); - expect(clock.toString()).toEqual('10:00'); - }); + xit('hour rolls over continuously', function () { + expect(at(100, 0).toString()).toEqual('04:00'); + }); - xit('can subtract over an hour', function () { - var clock = at(10, 3).minus(30); - expect(clock.toString()).toEqual('09:33'); + xit('sixty minutes is next hour', function () { + expect(at(1, 60).toString()).toEqual('02:00'); + }); - var clock = at(10, 3).minus(70); - expect(clock.toString()).toEqual('08:53'); - }); + xit('minutes roll over', function () { + expect(at(0, 160).toString()).toEqual('02:40'); + }); - xit('can know if it\'s equal to another clock', function () { - var clock1 = at(10, 3); - var clock2 = at(10, 3); - expect(clock1.equals(clock2)).toBe(true); - }); + xit('minutes roll over continuously', function () { + expect(at(0, 1723).toString()).toEqual('04:43'); + }); - xit('can know if it\'s not equal to another clock', function () { - var clock1 = at(10, 3); - var clock2 = at(10, 4); - expect(clock1.equals(clock2)).toBe(false); - }); + xit('hour and minutes roll over', function () { + expect(at(25, 160).toString()).toEqual('03:40'); + }); + + xit('hour and minutes roll over continuously', function () { + expect(at(201, 3001).toString()).toEqual('11:01'); + }); + + xit('hour and minutes roll over to exactly midnight', function () { + expect(at(72, 8640).toString()).toEqual('00:00'); + }); + + xit('negative hour', function () { + expect(at(-1, 15).toString()).toEqual('23:15'); + }); + + xit('negative hour rolls over', function () { + expect(at(-25, 0).toString()).toEqual('23:00'); + }); + + xit('negative hour rolls over continuously', function () { + expect(at(-91, 0).toString()).toEqual('05:00'); + }); + + xit('negative minutes', function () { + expect(at(1, -40).toString()).toEqual('00:20'); + }); + + xit('negative minutes rolls over', function () { + expect(at(1, -160).toString()).toEqual('22:20'); + }); + + xit('negative minutes rolls over continuously', function () { + expect(at(1, -4820).toString()).toEqual('16:40'); + }); + + xit('negative hour and minutes both roll over', function () { + expect(at(-25, -160).toString()).toEqual('20:20'); + }); + + xit('negative hour and minutes both roll over continuously', function () { + expect(at(-121, -5810).toString()).toEqual('22:10'); + }); + + describe('Adding and subtracting minutes', function () { + + xit('add minutes', function () { + expect(at(10, 0).plus(3).toString()).toEqual('10:03'); + }); + + xit('add no minutes', function () { + expect(at(6, 41).plus(0).toString()).toEqual('06:41'); + }); + + xit('add to next hour', function () { + expect(at(0, 45).plus(40).toString()).toEqual('01:25'); + }); + + xit('add more than one hour', function () { + expect(at(10, 0).plus(61).toString()).toEqual('11:01'); + }); + + xit('add more than two hours with carry', function () { + expect(at(0, 45).plus(160).toString()).toEqual('03:25'); + }); + + xit('add across midnight', function () { + expect(at(23, 59).plus(2).toString()).toEqual('00:01'); + }); + + xit('add more than one day (1500 min = 25 hrs)', function () { + expect(at(5, 32).plus(1500).toString()).toEqual('06:32'); + }); + + xit('add more than two days', function () { + expect(at(1, 1).plus(3500).toString()).toEqual('11:21'); + }); + + xit('subtract minutes', function () { + expect(at(10, 3).minus(3).toString()).toEqual('10:00'); + }); + + xit('subtract to previous hour', function () { + expect(at(10, 3).minus(30).toString()).toEqual('09:33'); + }); + + xit('subtract more than an hour', function () { + expect(at(10, 3).minus(70).toString()).toEqual('08:53'); + }); + + xit('subtract across midnight', function () { + expect(at(0, 3).minus(4).toString()).toEqual('23:59'); + }); + + xit('subtract more than two hours', function () { + expect(at(0, 0).minus(160).toString()).toEqual('21:20'); + }); + + xit('subtract more than two hours with borrow', function () { + expect(at(6, 15).minus(160).toString()).toEqual('03:35'); + }); + + xit('subtract more than one day (1500 min = 25 hrs)', function () { + expect(at(5, 32).minus(1500).toString()).toEqual('04:32'); + }); + + xit('subtract more than two days', function () { + expect(at(2, 20).minus(3000).toString()).toEqual('00:20'); + }); + + }); + + describe('Construct two separate clocks, set times, test if they are equal', function () { + + it('clocks with same time', function () { + expect(at(15, 37).equals(at(15, 37))).toBeTruthy(); + }); + + xit('clocks a minute apart', function () { + expect(at(15, 36).equals(at(15, 37))).toBeFalsy(); + }); + + xit('clocks an hour apart', function () { + expect(at(14, 37).equals(at(15, 37))).toBeFalsy(); + }); + + xit('clocks with hour overflow', function () { + expect(at(10, 37).equals(at(34, 37))).toBeTruthy(); + }); + + xit('clocks with hour overflow by several days', function () { + expect(at(3, 11).equals(at(99, 11))).toBeTruthy(); + }); + + xit('clocks with negative hour', function () { + expect(at(22, 40).equals(at(-2, 40))).toBeTruthy(); + }); + + xit('clocks with negative hour that wraps', function () { + expect(at(17, 3).equals(at(-31, 3))).toBeTruthy(); + }); + + xit('clocks with negative hour that wraps multiple times', function () { + expect(at(13, 49).equals(at(-83, 49))).toBeTruthy(); + }); + + xit('clocks with minute overflow', function () { + expect(at(0, 1).equals(at(0, 1441))).toBeTruthy(); + }); + + xit('clocks with minute overflow by several days', function () { + expect(at(2, 2).equals(at(2, 4322))).toBeTruthy(); + }); + + xit('clocks with negative minute', function () { + expect(at(2, 40).equals(at(3, -20))).toBeTruthy(); + }); + + xit('clocks with negative minute that wraps', function () { + expect(at(4, 10).equals(at(5, -1490))).toBeTruthy(); + }); + + xit('clocks with negative minute that wraps multiple times', function () { + expect(at(6, 15).equals(at(6, -4305))).toBeTruthy(); + }); + + xit('clocks with negative hours and minutes', function () { + expect(at(7, 32).equals(at(-12, -268))).toBeTruthy(); + }); + + xit('clocks with negative hours and minutes that wrap', function () { + expect(at(18, 7).equals(at(-54, -11513))).toBeTruthy(); + }); + + }); - xit('wraps around midnight backwards', function () { - var clock = at(0, 3).minus(4); - expect(clock.toString()).toEqual('23:59'); }); }); - diff --git a/exercises/clock/example.js b/exercises/clock/example.js index 28100f65..857d2511 100644 --- a/exercises/clock/example.js +++ b/exercises/clock/example.js @@ -1,11 +1,26 @@ exports.at = at; +var HOURS_IN_A_DAY = 24; +var MINUTES_IN_AN_HOUR = 60; +var MINUTES_IN_A_DAY = HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR; +var MILLIS_IN_A_MINUTE = 60 * 1000; +var MILLIS_IN_AN_HOUR = MINUTES_IN_AN_HOUR * MILLIS_IN_A_MINUTE; +var MILLIS_IN_A_DAY = HOURS_IN_A_DAY * MILLIS_IN_AN_HOUR; + +function makePositive(time, maxValue) { + time %= maxValue; + time += maxValue; + return time; +} + function at(hours, minutes) { - var min = 1000 * 60; - var hr = min * 60; + minutes = minutes || 0; + hours = makePositive(hours, HOURS_IN_A_DAY); + minutes = makePositive(minutes, MINUTES_IN_A_DAY); var clock = {}; - var value = (~~hours * hr) + (~~minutes * min); + var value = (hours * MILLIS_IN_AN_HOUR) + (minutes * MILLIS_IN_A_MINUTE); + value = makePositive(value, MILLIS_IN_A_DAY); clock.valueOf = function () { return value; @@ -17,12 +32,12 @@ function at(hours, minutes) { }; clock.plus = function (minutes) { - value += ~~minutes * min; + value += minutes * MILLIS_IN_A_MINUTE; return clock; }; clock.minus = function (minutes) { - value -= ~~minutes * min; + value -= minutes * MILLIS_IN_A_MINUTE; return clock; }; From e3f2f2466b1c53dba492496b12e759b6fc3f80df Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Fri, 6 May 2016 17:29:30 +0100 Subject: [PATCH 061/272] binary-search: fix ordering of actual/expected --- exercises/binary-search/binary-search.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/binary-search/binary-search.spec.js b/exercises/binary-search/binary-search.spec.js index 82a7eb40..5433a2bd 100644 --- a/exercises/binary-search/binary-search.spec.js +++ b/exercises/binary-search/binary-search.spec.js @@ -15,15 +15,15 @@ describe('BinarySearch', function() { }); xit('should find the correct index of an included value', function() { - expect(2).toEqual(new BinarySearch(sortedArray).indexOf(3)); + expect(new BinarySearch(sortedArray).indexOf(3)).toEqual(2); }); xit('should search the middle of the array', function() { - expect(3).toEqual(new BinarySearch(sortedArrayOfOddLength).indexOf(2)); + expect(new BinarySearch(sortedArrayOfOddLength).indexOf(2)).toEqual(3); }); xit('should return -1 for a value not in the array', function() { - expect(-1).toEqual(new BinarySearch(sortedArray).indexOf(10)); + expect(new BinarySearch(sortedArray).indexOf(10)).toEqual(-1); }); }); From 63c970bd232211007e17e737e0e458b337ad4084 Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Fri, 6 May 2016 18:18:52 +0100 Subject: [PATCH 062/272] binary-search-tree: fix ordering of actual/expected --- .../binary-search-tree.spec.js | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/exercises/binary-search-tree/binary-search-tree.spec.js b/exercises/binary-search-tree/binary-search-tree.spec.js index eb48fa05..16f3c307 100644 --- a/exercises/binary-search-tree/binary-search-tree.spec.js +++ b/exercises/binary-search-tree/binary-search-tree.spec.js @@ -11,7 +11,7 @@ function recordAllData(bst) { describe('BinarySearchTree', function() { it('data is retained', function() { - expect(4).toEqual(new Bst(4).data); + expect(new Bst(4).data).toEqual(4); }); xit('inserting less', function() { @@ -20,8 +20,8 @@ describe('BinarySearchTree', function() { four = new Bst(4); four.insert(2); - expect(4).toEqual(four.data); - expect(2).toEqual(four.left.data); + expect(four.data).toEqual(4); + expect(four.left.data).toEqual(2); }); xit('inserting same', function() { @@ -30,8 +30,8 @@ describe('BinarySearchTree', function() { four = new Bst(4); four.insert(4); - expect(4).toEqual(four.data); - expect(4).toEqual(four.left.data); + expect(four.data).toEqual(4); + expect(four.left.data).toEqual(4); }); xit('inserting right', function() { @@ -40,8 +40,8 @@ describe('BinarySearchTree', function() { four = new Bst(4); four.insert(5); - expect(4).toEqual(four.data); - expect(5).toEqual(four.right.data); + expect(four.data).toEqual(4); + expect(four.right.data).toEqual(5); }); xit('complex tree', function() { @@ -55,17 +55,17 @@ describe('BinarySearchTree', function() { four.insert(7); four.insert(5); - expect(4).toEqual(four.data); - expect(2).toEqual(four.left.data); - expect(1).toEqual(four.left.left.data); - expect(3).toEqual(four.left.right.data); - expect(6).toEqual(four.right.data); - expect(5).toEqual(four.right.left.data); - expect(7).toEqual(four.right.right.data); + expect(four.data).toEqual(4); + expect(four.left.data).toEqual(2); + expect(four.left.left.data).toEqual(1); + expect(four.left.right.data).toEqual(3); + expect(four.right.data).toEqual(6); + expect(four.right.left.data).toEqual(5); + expect(four.right.right.data).toEqual(7); }); xit('iterating one element', function() { - expect([4]).toEqual(recordAllData(new Bst(4))); + expect(recordAllData(new Bst(4))).toEqual([4]); }); xit('iterating over smaller element', function() { @@ -74,7 +74,7 @@ describe('BinarySearchTree', function() { four = new Bst(4); four.insert(2); - expect([2, 4]).toEqual(recordAllData(four)); + expect(recordAllData(four)).toEqual([2, 4]); }); xit('iterating over larger element', function() { @@ -83,7 +83,7 @@ describe('BinarySearchTree', function() { four = new Bst(4); four.insert(5); - expect([4, 5]).toEqual(recordAllData(four)); + expect(recordAllData(four)).toEqual([4, 5]); }); xit('iterating over complex tree', function() { @@ -97,7 +97,7 @@ describe('BinarySearchTree', function() { four.insert(7); four.insert(5); - expect([1, 2, 3, 4, 5, 6, 7]).toEqual(recordAllData(four)); + expect(recordAllData(four)).toEqual([1, 2, 3, 4, 5, 6, 7]); }); }); From 2fb13be58c8359ed0bac1805be5d05f375322d0c Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Tue, 10 May 2016 15:10:32 +0100 Subject: [PATCH 063/272] palindrome-products: fix ordering of actual/expected The spec doesn't care about the array order, hence the original use of #toContain Jasmine doesn't ship with a #toBeIn matcher, which would fix the actual/expected ordering Sorting the array corrects the actual/expected ordering, with the added benefit of bringing the expectation in line with the others in the spec. --- exercises/palindrome-products/palindrome-products.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/exercises/palindrome-products/palindrome-products.spec.js b/exercises/palindrome-products/palindrome-products.spec.js index b16f62de..97b50a97 100644 --- a/exercises/palindrome-products/palindrome-products.spec.js +++ b/exercises/palindrome-products/palindrome-products.spec.js @@ -9,7 +9,10 @@ describe('Palindrome', function() { var largest = palindromes.largest(); expect(largest.value).toEqual(9); - expect([[[3, 3], [1, 9]], [[1, 9], [3, 3]]]).toContain(largest.factors); + var orderedLargestFactors = largest.factors.sort( + function(a, b) { return a[0] > b[0]; } + ); + expect(orderedLargestFactors).toEqual([[1, 9], [3, 3]]); }); xit('largets palindrome from double digit factors', function() { From a158ad098a5185ff8f2b9081227118efd5b5a0b2 Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Fri, 13 May 2016 14:57:20 +0100 Subject: [PATCH 064/272] linked-list: add missing expectation This is the same expectation as that on the ecmascript track --- exercises/linked-list/linked-list.spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exercises/linked-list/linked-list.spec.js b/exercises/linked-list/linked-list.spec.js index cfe78346..a7322c73 100644 --- a/exercises/linked-list/linked-list.spec.js +++ b/exercises/linked-list/linked-list.spec.js @@ -64,5 +64,7 @@ describe('LinkedList', function () { var list = new LinkedList(); list.push(10); list.delete(10); + + expect(list.count()).toBe(0); }); }); From 91fe1b39ffa66ba90a6d2d52c2a4a6c87b50c33b Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Sat, 14 May 2016 16:35:11 +0100 Subject: [PATCH 065/272] trinary: fix ordering of actual/expected --- exercises/trinary/trinary.spec.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/exercises/trinary/trinary.spec.js b/exercises/trinary/trinary.spec.js index 5dab1102..792df1c7 100644 --- a/exercises/trinary/trinary.spec.js +++ b/exercises/trinary/trinary.spec.js @@ -3,39 +3,39 @@ var Trinary = require('./trinary'); describe('Trinary', function () { it('1 is decimal 1', function() { - expect(1).toEqual(new Trinary('1').toDecimal()); + expect(new Trinary('1').toDecimal()).toEqual(1); }); xit('2 is decimal 2', function() { - expect(2).toEqual(new Trinary('2').toDecimal()); + expect(new Trinary('2').toDecimal()).toEqual(2); }); xit('10 is decimal 3', function() { - expect(3).toEqual(new Trinary('10').toDecimal()); + expect(new Trinary('10').toDecimal()).toEqual(3); }); xit('11 is decimal 4', function() { - expect(4).toEqual(new Trinary('11').toDecimal()); + expect(new Trinary('11').toDecimal()).toEqual(4); }); xit('100 is decimal 9', function() { - expect(9).toEqual(new Trinary('100').toDecimal()); + expect(new Trinary('100').toDecimal()).toEqual(9); }); xit('112 is decimal 14', function() { - expect(14).toEqual(new Trinary('112').toDecimal()); + expect(new Trinary('112').toDecimal()).toEqual(14); }); xit('222 is 26', function() { - expect(26).toEqual(new Trinary('222').toDecimal()); + expect(new Trinary('222').toDecimal()).toEqual(26); }); xit('1122000120 is 32091', function() { - expect(32091).toEqual(new Trinary('1122000120').toDecimal()); + expect(new Trinary('1122000120').toDecimal()).toEqual(32091); }); xit('invalid trinary is decimal 0', function() { - expect(0).toEqual(new Trinary('carrot').toDecimal()); + expect(new Trinary('carrot').toDecimal()).toEqual(0); }); }); From 227bf346806d7655ed573d8be310a4cd29f8de38 Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Sat, 14 May 2016 17:07:28 +0100 Subject: [PATCH 066/272] wordy: fix ordering of actual/expected --- exercises/wordy/wordy.spec.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/exercises/wordy/wordy.spec.js b/exercises/wordy/wordy.spec.js index b825496f..01d5dc4d 100644 --- a/exercises/wordy/wordy.spec.js +++ b/exercises/wordy/wordy.spec.js @@ -5,72 +5,72 @@ describe('Word Problem', function() { it('add 1', function() { var question = 'What is 1 plus 1?'; - expect(2).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(2); }); xit('add 2', function() { var question = 'What is 53 plus 2?'; - expect(55).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(55); }); xit('add negative numbers', function() { var question = 'What is -1 plus -10?'; - expect(-11).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(-11); }); xit('add more digits', function() { var question = 'What is 123 plus 45678?'; - expect(45801).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(45801); }); xit('subtract', function() { var question = 'What is 4 minus -12?'; - expect(16).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(16); }); xit('multiply', function() { var question = 'What is -3 multiplied by 25?'; - expect(-75).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(-75); }); xit('divide', function() { var question = 'What is 33 divided by -3?'; - expect(-11).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(-11); }); xit('add twice', function() { var question = 'What is 1 plus 1 plus 1?'; - expect(3).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(3); }); xit('add then subtract', function() { var question = 'What is 1 plus 5 minus -2?'; - expect(8).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(8); }); xit('subtract twice', function() { var question = 'What is 20 minus 4 minus 13?'; - expect(3).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(3); }); xit('subtract then add', function() { var question = 'What is 17 minus 6 plus 3?'; - expect(14).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(14); }); xit('multiply twice', function() { var question = 'What is 2 multiplied by -2 multiplied by 3?'; - expect(-12).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(-12); }); xit('add then multiply', function() { var question = 'What is -3 plus 7 multiplied by -2?'; - expect(-8).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(-8); }); xit('divide twice', function() { var question = 'What is -12 divided by 2 divided by -3?'; - expect(2).toEqual(new WordProblem(question).answer()); + expect(new WordProblem(question).answer()).toEqual(2); }); xit('too advanced', function() { From 9f81d4adcc7491264248842e2e73e6b8b5aaebf3 Mon Sep 17 00:00:00 2001 From: leonardo Date: Sat, 30 Apr 2016 16:46:22 -0400 Subject: [PATCH 067/272] adding flatten-array to the list with test --- config.json | 1 + docs/ABOUT.md | 1 + exercises/flatten-array/example.js | 15 +++++++++++ exercises/flatten-array/flatten-array.spec.js | 26 +++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 exercises/flatten-array/example.js create mode 100644 exercises/flatten-array/flatten-array.spec.js diff --git a/config.json b/config.json index 310c9bb6..8557c00e 100644 --- a/config.json +++ b/config.json @@ -49,6 +49,7 @@ "secret-handshake", "linked-list", "wordy", + "flatten-array", "hexadecimal", "largest-series-product", "kindergarten-garden", diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 9bad6cea..b325e92b 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -12,6 +12,7 @@ You should learn JavaScript because: * It's easy to learn. * It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. +* It can be used for the frontend and backend. * It's Open Source. * JavaScript programming skills are in high demand. diff --git a/exercises/flatten-array/example.js b/exercises/flatten-array/example.js new file mode 100644 index 00000000..fcaa8444 --- /dev/null +++ b/exercises/flatten-array/example.js @@ -0,0 +1,15 @@ +var Flattener = function(){}; + +Flattener.prototype.flatten = function(unflattenedArray, flattenedArray){ + var self = this, flattenedArray = flattenedArray || []; + unflattenedArray.forEach(function(element){ + if(Array.isArray(element)){ + return self.flatten(element, flattenedArray); + }else if( element !== null){ + flattenedArray.push(element); + } + }); + return flattenedArray; +} + +module.exports = Flattener; \ No newline at end of file diff --git a/exercises/flatten-array/flatten-array.spec.js b/exercises/flatten-array/flatten-array.spec.js new file mode 100644 index 00000000..5009a257 --- /dev/null +++ b/exercises/flatten-array/flatten-array.spec.js @@ -0,0 +1,26 @@ +var Flattener = require("./flatten-array.js"); + +describe("FlattenArray", function() { + var flattener = new Flattener(); + it('flattens a nested list', function(){ + expect(flattener.flatten([[]])).toEqual([]); + }); + xit('flattens a 2 level nested list', function(){ + expect(flattener.flatten([1,[2,3,4],5])).toEqual([1, 2, 3, 4, 5]); + }); + xit('flattens a 3 level nested list', function(){ + expect(flattener.flatten([1,[2,3,4],5,[6,[7,8]]])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + }); + xit('flattens a 5 level nested list', function(){ + expect(flattener.flatten([0, 2, [[2, 3], 8, 100, 4,[[[50]]]], -2])).toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); + }); + xit('flattens a 6 level nest list', function(){ + expect(flattener.flatten([1,[2,[[3]],[4,[[5]]],6,7],8])).toEqual([1,2,3,4,5,6,7,8]); + }); + xit('flattens a 6 level nest list with null values', function(){ + expect(flattener.flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([0,2,2,3,8,100,-2]); + }); + xit('returns an empty list if all values in nested list are null', function(){ + expect(flattener.flatten([null,[[[null]]],null,null,[[null,null],null],null])).toEqual([]); + }); +}); From e8b168490b1f3610aaee1b0670622a2623d9532c Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Fri, 13 May 2016 15:13:46 +0100 Subject: [PATCH 068/272] meetup: use standard test naming format --- exercises/meetup/meetup.spec.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/exercises/meetup/meetup.spec.js b/exercises/meetup/meetup.spec.js index 47eb9024..f4ad9ee6 100644 --- a/exercises/meetup/meetup.spec.js +++ b/exercises/meetup/meetup.spec.js @@ -7,55 +7,55 @@ function MeetupDayException(message) { } describe('meetupDay()', function() { - it('test_monteenth_of_may_2013', function() { + it('monteenth of may 2013', function() { expect(meetupDay(2013, 4, 'Monday', 'teenth')).toEqual(new Date(2013, 4, 13)); }); - xit('test_saturteenth_of_february_2013', function() { + xit('saturteenth of february 2013', function() { expect(meetupDay(2013, 1, 'Saturday', 'teenth')).toEqual(new Date(2013, 1, 16)); }); - xit('test_first_tuesday_of_may_2013', function() { + xit('first tuesday of may 2013', function() { expect(meetupDay(2013, 4, 'Tuesday', '1st')).toEqual(new Date(2013, 4, 7)); }); - xit('test_second_monday_of_april_2013', function() { + xit('second monday of april 2013', function() { expect(meetupDay(2013, 3, 'Monday', '2nd')).toEqual(new Date(2013, 3, 8)); }); - xit('test_third_thursday_of_september_2013', function() { + xit('third thursday of september 2013', function() { expect(meetupDay(2013, 8, 'Thursday', '3rd')).toEqual(new Date(2013, 8, 19)); }); - xit('test_fourth_sunday_of_march_2013', function() { + xit('fourth sunday of march 2013', function() { expect(meetupDay(2013, 2, 'Sunday', '4th')).toEqual(new Date(2013, 2, 24)); }); - xit('test_last_thursday_of_october_2013', function() { + xit('last thursday of october 2013', function() { expect(meetupDay(2013, 9, 'Thursday', 'last')).toEqual(new Date(2013, 9, 31)); }); - xit('test_last_wednesday_of_february_2012', function() { + xit('last wednesday of february 2012', function() { expect(meetupDay(2012, 1, 'Wednesday', 'last')).toEqual(new Date(2012, 1, 29)); }); - xit('test_last_wednesday_of_december_2014', function() { + xit('last wednesday of december 2014', function() { expect(meetupDay(2014, 11, 'Wednesday', 'last')).toEqual(new Date(2014, 11, 31)); }); - xit('test_last_sunday_of_only_four_week_february_2015', function() { + xit('last sunday of only four week february 2015', function() { expect(meetupDay(2015, 1, 'Sunday', 'last')).toEqual(new Date(2015, 1, 22)); }); - xit('test_first_friday_of_december_2012', function() { + xit('first friday of december 2012', function() { expect(meetupDay(2012, 11, 'Friday', '1st')).toEqual(new Date(2012, 11, 7)); }); - xit('test_fifth_monday_of_march_2015', function() { + xit('fifth monday of march 2015', function() { expect(meetupDay(2015, 2, 'Monday', '5th')).toEqual(new Date(2015, 2, 30)); }); - xit('test_nonexistent_fifth_monday_of_february_2015', function() { + xit('nonexistent fifth monday of february 2015', function() { expect(function () { meetupDay(2015, 1, 'Monday', '5th'); }).toThrow(); }); }); From b5359b7303193d4af9a8131b55d0ad6168bcd41d Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Thu, 12 May 2016 13:33:59 +0100 Subject: [PATCH 069/272] palindrome-product: fix typo in test name --- exercises/palindrome-products/palindrome-products.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/palindrome-products/palindrome-products.spec.js b/exercises/palindrome-products/palindrome-products.spec.js index 97b50a97..9f02104b 100644 --- a/exercises/palindrome-products/palindrome-products.spec.js +++ b/exercises/palindrome-products/palindrome-products.spec.js @@ -15,7 +15,7 @@ describe('Palindrome', function() { expect(orderedLargestFactors).toEqual([[1, 9], [3, 3]]); }); - xit('largets palindrome from double digit factors', function() { + xit('largest palindrome from double digit factors', function() { var palindromes = new Palindromes({ maxFactor: 99, minFactor: 10 }); palindromes.generate(); From 8d83dfd9e7fc589abf5fd43bdad69de17f231095 Mon Sep 17 00:00:00 2001 From: Ozan Onay Date: Mon, 23 May 2016 08:25:02 -0700 Subject: [PATCH 070/272] Fix typo --- exercises/luhn/luhn.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js index 352f8eac..c6c426a0 100644 --- a/exercises/luhn/luhn.spec.js +++ b/exercises/luhn/luhn.spec.js @@ -17,7 +17,7 @@ describe('Luhn',function() { expect(luhn.addends).toEqual([1, 4, 1, 4, 1]); }); - xit('too large added',function() { + xit('too large addend',function() { var luhn = new Luhn(8631); expect(luhn.addends).toEqual([7, 6, 6, 1]); }); @@ -57,4 +57,4 @@ describe('Luhn',function() { expect(number).toEqual(8372637564); }); -}); \ No newline at end of file +}); From 647fd3afc6bf0592d9517587c5fa295f91d89945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 24 May 2016 09:19:26 +0200 Subject: [PATCH 071/272] Improve instructions for Windows and Mac OS X users --- docs/INSTALLATION.md | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 02b8ba5d..5e12e440 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -1,14 +1,25 @@ -**Windows and OS X users**: Install [Node.js](http://nodejs.org/) [via package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager). Windows users can use Visual Studio, see below. +## Installing Node.js -**Linux users**: [Joyent maintains a document][linstall] that details how to get Node.js installed for a wide range of distributions and package managers. +There are at least two common options to run JavaScript code: the browsers and [Node.js](http://nodejs.org/). Here we are going to use Node.js to run our JavaScript code. Let's see how to install Node.js locally: -[linstall]: https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager +**Windows users**: find official installers on [Node.js downloads](https://nodejs.org/en/download/). Choose the LTS (long term support) version. It will install Node.js on your machine as well as `npm` (that stands for Node Package Manager), a tool that helps installing applications that run on top of Node.js. -Install `jasmine-node`: +**Mac OS X users**: same as Windows users, you will find official installers on [Node.js downloads](https://nodejs.org/en/download/). Choose the LTS version. It will install Node.js and `npm` on your machine. + +**Linux users**: there are binaries for `node` and `npm` tools on the Node.js downloads page, but the recommended way to install them on a Linux machine is via a package manager. As of writing this, the recommended version of Node.js to install is 4.x. To install it on a Debian or Ubuntu Linux distribuion just execute these commands: + + curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - + sudo apt-get install -y nodejs + +If you are using a different distribution or package manager, you can find a complete list of supported ones on the official documentation page: [Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions). + +## Installing additional tools + +The next step is to install `jasmine-node` globally so that you can run JavaScript tests: npm install jasmine-node -g -Depending on your setup, you may need super user privileges to install an NPM module globally. This is the case if you've used the official installer linked to above. If NPM gives you an error saying you don't have access, add `sudo` to the command above: +Depending on your setup, you may need super user privileges to install an `npm` module globally. This is the case if you've used the official installer linked to above. If `npm` gives you an error saying you don't have access, add `sudo` to the command above: sudo npm install jasmine-node -g From 1d6842b46a319381ed6b0e2b659aaf9e381475fc Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Thu, 9 Jun 2016 16:26:44 +0100 Subject: [PATCH 072/272] custom-set: reorder tests to improve flow The x-common canonical tests for this exercise have been updated to improve the experience of the person doing the exercise. This brings this exercise in line with the ordering, test cases and naming of the canonical tests. The names of the various set operations have been updated to match those in the canonical tests, as consistent domain language reduces confusion. Non-canonical tests have been moved to the end of the suite to keep the core tests together and keep the flow of the canonical tests. When adding the previously missing equality test, a bug in the example solution was exposed, which is fixed as part of this commit. --- exercises/custom-set/custom-set.spec.js | 199 ++++++++++++++++-------- exercises/custom-set/example.js | 16 +- 2 files changed, 146 insertions(+), 69 deletions(-) diff --git a/exercises/custom-set/custom-set.spec.js b/exercises/custom-set/custom-set.spec.js index fa2ac4be..47524f65 100644 --- a/exercises/custom-set/custom-set.spec.js +++ b/exercises/custom-set/custom-set.spec.js @@ -2,66 +2,167 @@ var CustomSet = require('./custom-set'); describe('CustomSet', function() { - it('can delete elements', function(){ - var expected = new CustomSet([1, 3]); - var actual = new CustomSet([3, 2, 1]).delete(2); - expect(actual.eql(expected)).toBe(true); + xit('can test for no members', function() { + var actual = new CustomSet().empty(); + expect(actual).toBe(true); - var expected2 = new CustomSet([1, 2, 3]); - var actual2 = new CustomSet([3, 2, 1]).delete(4); - expect(actual2.eql(expected2)).toBe(true); + var actual2 = new CustomSet([1]).empty(); + expect(actual2).toBe(false); }); - xit('can check for difference', function(){ - var expected = new CustomSet([1, 3]); - var actual = new CustomSet([3, 2, 1]).difference(new CustomSet([2, 4])); - expect(actual.eql(expected)).toBe(true); - var expected2 = new CustomSet([1, 2, 3]); - var actual2 = new CustomSet([1, 2, 3]).difference(new CustomSet([4])); - expect(actual2.eql(expected2)).toBe(true); + xit('can test for a member', function() { + var actual = new CustomSet().contains(1); + expect(actual).toBe(false); + + var actual2 = new CustomSet([1, 2, 3]).contains(1); + expect(actual2).toBe(true); + + var actual3 = new CustomSet([1, 2, 3]).contains(4); + expect(actual3).toBe(false); + }); + + xit('can test for subsets', function() { + var actual = new CustomSet().subset(new CustomSet()); + expect(actual).toBe(true); + + var actual2 = new CustomSet([1]).subset(new CustomSet()); + expect(actual2).toBe(true); + + var actual3 = new CustomSet().subset(new CustomSet([1])); + expect(actual3).toBe(false); + + var actual4 = new CustomSet([1, 2, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual4).toBe(true); + + var actual5 = new CustomSet([4, 1, 2, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual5).toBe(true); + + var actual6 = new CustomSet([4, 1, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual6).toBe(false); }); xit('can test disjoint', function() { - var actual = new CustomSet([1, 2]).disjoint(new CustomSet([3, 4])); + var actual = new CustomSet().disjoint(new CustomSet()); expect(actual).toBe(true); - var actual2 = new CustomSet([1, 2]).disjoint(new CustomSet([2, 3])); - expect(actual2).toBe(false); - var actual3 = new CustomSet().disjoint(new CustomSet()); + + var actual2 = new CustomSet().disjoint(new CustomSet([1])); + expect(actual2).toBe(true); + + var actual3 = new CustomSet([1]).disjoint(new CustomSet()); expect(actual3).toBe(true); + + var actual4 = new CustomSet([1, 2]).disjoint(new CustomSet([2, 3])); + expect(actual4).toBe(false); + + var actual5 = new CustomSet([1, 2]).disjoint(new CustomSet([3, 4])); + expect(actual5).toBe(true); }); - xit('can be emptied', function() { - var actual = new CustomSet([1, 2]).empty(); + xit('can test for equality', function () { + var actual = new CustomSet().eql(new CustomSet()); + expect(actual).toBe(true); + + var actual2 = new CustomSet().eql(new CustomSet([1, 2, 3])); + expect(actual2).toBe(false); + + var actual3 = new CustomSet([1, 2, 3]).eql(new CustomSet()); + expect(actual3).toBe(false); + + var actual4 = new CustomSet([1, 2]).eql(new CustomSet([2, 1])); + expect(actual4).toBe(true); + + var actual5 = new CustomSet([1, 2, 3]).eql(new CustomSet([1, 2, 4])); + expect(actual5).toBe(false); + }); + + xit('can add a member', function() { + var actual = new CustomSet().add(3); + var expected = new CustomSet([3]); + expect(actual.eql(expected)).toBe(true); + + var actual2 = new CustomSet([1, 2, 4]).add(3); + var expected2 = new CustomSet([1, 2, 3, 4]); + expect(actual2.eql(expected2)).toBe(true); + + var actual3 = new CustomSet([1, 2, 3]).add(3); + var expected3 = new CustomSet([1, 2, 3]); + expect(actual3.eql(expected3)).toBe(true); + }); + + xit('can check for intersection', function() { + var actual = new CustomSet().intersection(new CustomSet()); var expected = new CustomSet(); expect(actual.eql(expected)).toBe(true); - var actual2 = new CustomSet().empty(); + + var actual2 = new CustomSet().intersection(new CustomSet([3, 2, 5])); var expected2 = new CustomSet(); expect(actual2.eql(expected2)).toBe(true); + + var actual3 = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet()); + var expected3 = new CustomSet(); + expect(actual3.eql(expected3)).toBe(true); + + var actual4 = new CustomSet([1, 2, 3]).intersection(new CustomSet([4, 5, 6])); + var expected4 = new CustomSet(); + expect(actual4.eql(expected4)).toBe(true); + + var actual5 = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet([3, 2, 5])); + var expected5 = new CustomSet([2, 3]); + expect(actual5.eql(expected5)).toBe(true); }); - xit('can check for intersection', function() { - var actual = new CustomSet(['a', 'b', 'c']).intersection(new CustomSet(['a', 'c', 'd'])); - var expected = new CustomSet(['a', 'c']); + xit('can check for difference', function(){ + var actual = new CustomSet().difference(new CustomSet()); + var expected = new CustomSet(); expect(actual.eql(expected)).toBe(true); - var actual2 = new CustomSet([1, 2, 3]).intersection(new CustomSet([3, 5, 4])); - var expected2 = new CustomSet([3]); + var actual2 = new CustomSet().difference(new CustomSet([3, 2, 5])); + var expected2 = new CustomSet(); expect(actual2.eql(expected2)).toBe(true); + + var actual3 = new CustomSet([1, 2, 3, 4]).difference(new CustomSet()); + var expected3 = new CustomSet([1, 2, 3, 4]); + expect(actual3.eql(expected3)).toBe(true); + + var actual4 = new CustomSet([3, 2, 1]).difference(new CustomSet([2, 4])); + var expected4 = new CustomSet([1, 3]); + expect(actual4.eql(expected4)).toBe(true); }); - xit('can test for a member', function() { - var actual = new CustomSet([1, 2, 3]).member(2); - expect(actual).toBe(true); - var actual2 = new CustomSet([1, 2, 3]).member(4); - expect(actual2).toBe(false); + xit('can test for union', function() { + var actual = new CustomSet().union(new CustomSet()); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + + var actual2 = new CustomSet().union(new CustomSet([2])); + var expected2 = new CustomSet([2]); + expect(actual2.eql(expected2)).toBe(true); + + var actual3 = new CustomSet([1, 3]).union(new CustomSet()); + var expected3 = new CustomSet([1, 3]); + expect(actual3.eql(expected3)).toBe(true); + + var actual4 = new CustomSet([1, 3]).union(new CustomSet([2, 3])); + var expected4 = new CustomSet([3, 2, 1]); + expect(actual4.eql(expected4)).toBe(true); }); - xit('can add a member with put', function() { - var actual = new CustomSet([1, 2, 4]).put(3); - var expected = new CustomSet([1, 2, 3, 4]); + it('can delete elements', function(){ + var expected = new CustomSet([1, 3]); + var actual = new CustomSet([3, 2, 1]).delete(2); expect(actual.eql(expected)).toBe(true); - var actual2 = new CustomSet([1, 2, 3]).put(3); + var expected2 = new CustomSet([1, 2, 3]); + var actual2 = new CustomSet([3, 2, 1]).delete(4); + expect(actual2.eql(expected2)).toBe(true); + }); + + xit('can be emptied', function() { + var actual = new CustomSet([1, 2]).clear(); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + var actual2 = new CustomSet().clear(); + var expected2 = new CustomSet(); expect(actual2.eql(expected2)).toBe(true); }); @@ -74,19 +175,6 @@ describe('CustomSet', function() { expect(actual3).toBe(3); }); - xit('can test for subsets', function() { - var actual = new CustomSet([1, 2, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual).toBe(true); - var actual2 = new CustomSet([4, 1, 2, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual2).toBe(true); - var actual3 = new CustomSet([4, 1, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual3).toBe(false); - var actual4 = new CustomSet([4, 1, 3]).subset(new CustomSet()); - expect(actual4).toBe(true); - var actual5 = new CustomSet().subset(new CustomSet()); - expect(actual5).toBe(true); - }); - xit('can give back a list', function() { var actual = new CustomSet().toList(); var expected = []; @@ -99,19 +187,4 @@ describe('CustomSet', function() { expect(actual3.sort()).toEqual(expected3); }); - xit('can test for union', function() { - var actual = new CustomSet([1, 3]).union(new CustomSet([2])); - var expected = new CustomSet([3, 2, 1]); - expect(actual.eql(expected)).toBe(true); - var actual2 = new CustomSet([1, 3]).union(new CustomSet([2, 3])); - var expected2 = new CustomSet([3, 2, 1]); - expect(actual2.eql(expected2)).toBe(true); - var actual3 = new CustomSet([1, 3]).union(new CustomSet()); - var expected3 = new CustomSet([3, 1]); - expect(actual3.eql(expected3)).toBe(true); - var actual4 = new CustomSet().union(new CustomSet()); - var expected4 = new CustomSet(); - expect(actual4.eql(expected4)).toBe(true); - }); - }); diff --git a/exercises/custom-set/example.js b/exercises/custom-set/example.js index 01b063bc..a4ba69d3 100644 --- a/exercises/custom-set/example.js +++ b/exercises/custom-set/example.js @@ -6,6 +6,10 @@ this.data = inputData || []; }; + CustomSet.prototype.empty = function() { + return this.data.length === 0; + }; + CustomSet.prototype.delete = function(element) { var index = this.data.indexOf(element); if (index !== -1) { @@ -36,7 +40,7 @@ return true; }; - CustomSet.prototype.empty = function() { + CustomSet.prototype.clear = function() { return new CustomSet([]); }; @@ -52,11 +56,11 @@ return new CustomSet(result); }; - CustomSet.prototype.member = function(datum) { + CustomSet.prototype.contains = function(datum) { return this.data.indexOf(datum) !== -1; }; - CustomSet.prototype.put = function(datum) { + CustomSet.prototype.add = function(datum) { if (this.data.indexOf(datum) === -1) { this.data.push(datum); } @@ -101,8 +105,8 @@ return false; } - for (var i = 0; i < this.length; i++) { - if (thisData[i] !== otherData[i]) { + for (var i = 0; i < thisData.length; i++) { + if (thisData[i] !== thatData[i]) { return false; } } @@ -117,4 +121,4 @@ }; module.exports = CustomSet; -})(); \ No newline at end of file +})(); From 1f4401f59364db86a6da8b265da62e206f121732 Mon Sep 17 00:00:00 2001 From: Kevin Sullivan Date: Fri, 1 Jul 2016 09:53:18 -0700 Subject: [PATCH 073/272] Add track icon --- config.json | 3 ++- img/icon.png | Bin 0 -> 13011 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 img/icon.png diff --git a/config.json b/config.json index 8557c00e..fd72b262 100644 --- a/config.json +++ b/config.json @@ -76,7 +76,8 @@ ], "ignored": [ "docs", - "node_modules" + "node_modules", + "img" ], "foregone": [ diff --git a/img/icon.png b/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..34173556ed19e3b97028d74688f50867be2dea8f GIT binary patch literal 13011 zcmb7rWl$Yav+dv#EChEC1lQp18eD<}hY;M|2@>4h-CcqNcPBt_4|;HyJNa(i``)it z^@=($3_bhw+1X=ch z@ze7SM-H&@@Ta0m|Hkg<<69sd6Bi>|_xQ{|xj|#Ym0EAUcAvGx&W;i^$4m_107s=s z%t0|U@~}g732TQBgQZB)0*(kn9v%mkMcouZ7|0Bwh;TUML7xoY{`UoR1coSW4I(*~ zRuG1$zr=rE{FBQ4e~JhFd+vY4|6TmA_`i$)UH#w1zt#UE{(rwsZg(CH+5eIIA1(fO z*&p%p3c`n~YHA6r!W!zn$BV2Uy>vCws!16cPoID*b{IcmP-BiS#C$F$4V|Fs;CuXk zep8HQI*>h-SZ?~Z^eYg7T4DCds)O6OrDz?{zPtyrk#o!Z%6f{e{xVCHxgNZesQsk) z+KU;A^%l7`RRXWQd7;OqT{7du)f6QYb(v2|#he#uH7H;%Vrpv2CbD)KxO!>Ohc;wt z_AJ}Ggeub@(IW6FL$1QjMluuvR`GrHl~XiyJysg`k8WRo-nI4eFEX&_L#gP(s$L?? z1&!uI`B_H?Ixo-6uy-iFbR1zk|J76b@>T`6NHLT5A=Ny~T|ya4&#$6RD}E((6=NCG zMnT}~R^oH-NRuEr(1E66Lfa7V&K9{^1<~*P`zMKUdbfZBQvr0;nG{7=QF<2-6ynbh zMhjz%g4d?(QmZgWP47YTl$H|O{)~Oz7kYgQ)B$}6J-nZZeUxD8wk(B za=&_dVnG|C7@~|>!x|sUZQeZf=l9eFFEmTJc?F+6%us!L(Phyr}5qunRH0NOeIo8kiu>`v8PgMGNXe=Cc~I zY>k~K#r3vS%-1Iv->j!?9@S)Wn-kqG3v=EOi9-cz>xzW2|%PC^@^bI_f=V)sDA zqDjcjhs(W3EdH9Pqw`><6ODvkgr4ET=r>X`LUPN3ii8B^w>=oW4~_Bf@i-_EUCGiS zj;h-DGSL!5I2Q4eL-oAH)cwC~drTzQH;LyLTt|7hN-u8!HpwynlgeGSFR|V8<(kX_ z#xK5e{!obV*A`btAA-=z%;2UB=ozx~+l*hMuAo$t%oTjbRNiV>YOcumOF*l3`8?mi zoIR4~YR{01&lsc_YwpX7^F%c-Eb;W`>R=Ye zOiw{qw5H(eA;J+A;urriCQK4Y?$sQf*oU4Ejwaiwy%N|srR$Z#ak^z?56;1fM&aEv zdjeAeR4-3vtsf;b#E?<{^vgdCrxg*`cGc%8@35+C75Ie8O;7uDMM*M|e;>tox$-Y5 z5@FwOzBGpZItj$qcR~p}o3a()t zV!Q~=^q!g#hh!ak^Bh`~Onm0?`C&9tY_hQ1V>Z~2*4Z_vn>~ujxQ&`*@ef(9gujFp zu0{t9+4<$TU1UaoZ2Bb`?4AfBKJD_`bm~{3F8x7nr$~eW?X_2wDmj4vQgeTq_dUtt z2Y}3WjR2Wp=C0s6HK@;fa;tipoyr7v4T1c$60sb4&kqk%)?WbT^YhtO%m+7 zLd0x+44IPt5(LQ=z5;$hN*^gI2k}x(lgEN-NCGg_AL0RwzUQtUHWoUT@^a)zk(Q3l zHL-))3mV2&MBxqv_ndBu{r-y{u_1$>)7?G2#bVPWLbFmPWF7+_(HI?XEI}{Uw;}Or4(tMg|KZK3OHZxQe~_OdmdwJ^4t}vch}kXlkh! z3crWgU8PwlJRNHzGdTFumoJbY046ADN!{`fdKl8Y%a_+p_B-QT{aQKH> zK6+2BZUQj^d%3)xmTlr}rLhg=MgD|W&Xio@nRt=UQ&>hHWk3H++#2|s_S=s!uU~#!QQR{~6zqe-@Qu~t0 z)BwAEY{~g}_XCLe?aBs+W2x1Iu1V=QG`4qEDmMc8>pr1$iRvRrwG$~a_&4YAfI_Z> zAfe((;-FO38Y$aacn|drn0b4pL9BxT8v7bW_%_9zPg_25QK1AON5J*D2kmQHa^f;g zvJWnFSvGV&;DPVqS3}_R5roF@$ns+JcTAIs8}peobR*^HzH1~1Sx7&OuC>d28KBrS3?8nFOn_DWcyGE_l zBUB7y>&sd?6Crj3PMg=-Ru7kT+3U$MxyRf%JjD@SzGlo&epfH9S+0S~pk!TVD^{zc zhD6U1p`+k)|N3N|aimC|CF(qFEo_5|YjULjY}?{(g%D&f4|I`&r@a&;_|HEcX*X`; zKi~_C^&Ez3RO~r0!}>J{#!r+_)7A{(7hdBT;ApiDB8a>TxpYSzhJ*$=p_J38C!NtH z7hHGc+x8R_PL_{=>zOB<-J2C$XRr{7Qe{ED-gz3@=RA<6VG5JUv~;)v!Vle+`}1o- z8HJ%|?Z32+-4QeZHB!*p1nSy`#}|=b%}{E58{k1>(AG$=4w2NmAqGj8j#o(g3gL~9 ze5Bz0s~^Z^ToL@K@hen!=cOeW%zQkqjBtRPFOLzXK4~VI?@c9og%^}LpkU8^t2kCJ zO#h*k)_7=)fYd5yLi&Z=MsI0_-i%{~;pdv0MPoTBUdsBKvg9;Jw5o*^Ref#Dn?$5+ z=uK7N1oAbARXZFb4F_JqPMROH3}+S+{d&pEJMd+-t3TV;{~E#XGjJ?4`!0&nrz!Pl7Q$<(*c^qB-eyT%c#;!_ z$5J5NO;q!qf~`r%SNll&Txn9Zw1=W`OTg{Qs3ff;%BAGRD>4)YQDFPb<6`@}4#%bv z;G5)o#0f}uS^eqHoAbuTJ0izwWXIy<+2F-Dhv^U^>cr~S1kF$Ga(`vT$wi*{!FIYJ ztO>w8G?OCe?ma?%Q|6V)>c9kazjSdTyt}c{v3xb@z2@hzpolM=HynHWX+Ei}(5}9= z9wR{geFbQJArOb)$zjbscnX^at6ok`=EgrPzO+|d*#Bm{4P=FX3@vvhtp1n z*vS+ws|^~R<#XH-VCAGUM=GTN;j9uUm|Mz4wwjr(`+3CzkO?>=8!b#;(wwfhDXsVT z;NsyVCKtZw*&qR;kvMSui~yPIfGU<&!Jb#>%#WTE&QCKOk>Rb<+8-Ijk00(2fX@R? zGyF96uYym5z@{n+KmQ%uZME-kExkDy0BP}C6qREo&GYl;SR)-)8oJej@KOu4(kos4 zs2w&xruwYAYz4`4cCeks+qY}&2r%O=^D^z4g7S0@k1cqpH5#c;*8>_}T*1eiE_MD!nWOYvn_3T*TY3vad=tF3{41su4 zCM-^L(GsAWG5{{#*>kSqshUi#&icpn!E*B=X@}cIb8)BcUWupS>J2QIa!DY}Qbyfc znOQWV{_1=V);nJ&f8|dG*6upLY?&?;^Im!u$19TvuGL*7bmK)KNif28r-%#|4%P6F z@4je_(vKPaqOoadXk>NSt*A7A?s$cBpb?tb;$kRKQO{)jkBi;CjLmTr%T+FG77pmEyYg(M0|`T82_f*tb2#j1mADtehN8A-2_)$`ctDMm*&vc?uxQnZS=m z;k1yL& zMzB#)2`Fgc^~H{tZC!GccXUVIP^IWz6zbidvkGHn=|IV~l-g8%^Q${`sXLXy)RMYN zh%9KtiLD?7F}u3NgfQNen4K^+_nU+A*x}MT+khe|jRDl+4Xi^Equ5GXtNHWtB#y?u z-ZzzGGWDMRa^bn_pQN%CI;u+CvpHew-C7?J{qRkMlQMgD@9{-xW4H@y4AsY(J#aII zHzHZYClk%PXZdzkHU` z23;D*m@6V&+I~#oRB-;28D1>v%nese{hQyXRQ*Bi8amC(hZn5yGS&`~ha22d*3r|K z>qzDcY`^3YlD+j;lswYT?MNko&suuYVDKT6;3Ll$1Nx-ivWwCM*I7Y9(F@tY*)Q$v zJER!)bLGBoZMPZK?oBmTbIKq|1pen&pY0wGcfGP2uv;(vC|~_fKCemy%mAv0 z6*W1%F@+gzZ3RfHBmW-t$lt{&K#FFroNx%a2nTOGQ1nYaq$u9}*6!b1AEySM@+<3X z^u&q7pd&b7kJ^=<;U~~UK7G!J2pc7L)%v4XiJIZeRHmwAw|(BbvtZPDv^l}z&ULq-)< z1{A(AV>Jr+5e8}62h@s zLIIemC755KtE&~E=~<#$v+I(|2w*obD;JSie#^8704%!Wj8ij@@``dtoaZc5FNs*# z8d$tOeG?nM1a#FuthOgn*sSs&hC(eR54qbr5kJxd;i;!DOtD5at^bVN4qs+orq#C{ z*ea;Pdpi$pQwguxvVnpzWQuulZIIdnZ!Jm%6LMPjl$k-_rQDvN~=9+4Zp#LV~F5LW7N6 z#BzMUg#?{+dczHRF%e+?7SV$jh6{ve84wHX{GCxn{J=HLx1HVLx<0HlMskU<)hsBC zjf2FXBH!n8t)=W*k`{Xtj!T5lO<%QNg`Ic>O!Yo)=OPg44futoxLOsSW`>~QdSf+z z*>nXVt9wim&(lSG?x(MMr}UolJh7n&L)(?R49k+F`b!OR^7_!b1- zOM2P>EQ#t&TH>NToQeyt+eh0t#v97bn<~bo3;lht2plLvPr~ntYhDhgPsXDjX{j`ZZo8x*S>_ zrTL`wTjBQC#Rw(XY!|(M4sTESHkh`$ar}P6Ym%v8$O>f|ZU7h{(>)d6yjers;G_NX z%2E8aHUDUFEtPVwX)?Y3!_`jBh(Uut7>UF;t4AZEvWD;zm&Q)vqj4H99Lyo<||hyrxet zYz}2mN;!6d*Wq7*bN`C4=#V8Lt>7#AVy>ZOd4GvA#`EsqbpRV7I&zp2f;mdg8#)9N zJEUm>l6BGDyVdC#ETRUFJK=LT)P0n3i}V7>Ha^kD$gWYs}v>-XgA#Lcg=(e6dr1U-`~ zt6&K@4YDtWC_Uv`IaYk$p+v5Q*I6Y>i|t5Y3lA2ua8(WZ9xZj0;YRz=(q3@!)FS!9 z&>^sl)po(3=Cq^aUJK>;YZ`z5r_Ha-qog7B(nD?C42J`2V-jwq$M*F&KVot#f*i|e zvAs9MdILj^sQ=gm^V~#MH+TxOmBV`P77u(p!aL$T;2DYj! zG?1%AlVa4X7mh;9mn6qF3%nfkwe{^txVtwqS=XqiPgZ!xIv75{9uBm_D$0F2}8T!p_^D=J?Ff=e6zT743k z&sHc<#Say{NheG^YzG@rf~*GogcKi}qhMI%!hhUl4#y$*A^1TH=Xz$&N7}hpaj)K* zS`mm^r4IVVvT8sZ%H7{;0K&h@G{W^OU8VcLoqfG;)_@iU(oUI9LA z0C^Bnq{M8Zb~${~?cjPl01`e}TGxzbOIKxLgUh6%PnYQ3AbJ}l*#;>A!UIFCCyhS? zk~W@r5vOJE5@`J-L}mk^JD2}DBXLks?Lc#{j^oT!rwv%Y>fOBa%Lc43iJsU$Ku&iv zbHfyMYU|nK3nxV9E2e^20oxN=vA6-46uE!fYXu9MS(OKV%%A}(BqE&{=1loMAd;LN z!3wUQxO<5u*GgbRwLqBHjX9%A1sKY_fQ|5eAc2}0RP{g@a~WN#-T31DD8WQ@>6^HoHy-vWc%IvI)rl17zJMUS z)WR==;G+&FN_I~jc8{DDREgRZ|B>X!F$K9hbH9(Ku5&T z4BfoQ78EPey{TOwSw`*P$4b+{lKuu#X5cP}9`j{O{;rGwCuMxuYxK)Tu7RwKpMGZ- zamH8;x0|CHWpO_$FkO~u)gsgmM2?HN& ze~M!Ru`AIbg6)okck|`dy`hMNLcy?Mo>Peigbv8&O9#vG@|T9MX)piW*YLk~zw)$2 zVf))%BOq4@uTUD8bcv1&`oz;-uRtrn;05kEiO|zM^Epw$gJs%02Jh-GM@6YQ=D#&( zKd4P@#lGYJK`LIaX7-lF`|dx_mWzebT+%v7u2w0_sYack`24`HoHs9I#zlc))}?9) zmvW30U9(thcKQWAlQ3h=$Cq4o6*1^te(4~5%AGlcei_yA#U}9NxpbiHBer8*17@;s zRSpe^KEMXy)V`}i)^30QP}bFA;uOd0GCj+Hn@I_nt-AviCOPL=(RmpRgxEqR;eitT z*5>-oOTaO-HlC+eY!(7#{1Jb?l2* z4a(<3e7T06xb_^R{Oqc_fw3Yb#b+8g4ZpgM<~nPsqIjXghqAX2t&j<5K&x3OEW=k| zC>X=eiL^_LPlNkinc3MgHm<08{pBr~BFdfv>hHj<59lW!gR@$7Jig|al1}rVs=>}SJg!XlgST}y9YRB3%4zC>I|@Zg z-Zwr8x?~(buyQ#xk@f9!Vlzrs63TG?JpafuGdu~!;JT+utN*%Qjk@}0@2jGwlea?3 z#bxR#^n8Y2`bTqYqa-Dvlh=sPLZtl=Uo!^X2d@k)63pTqoIbh(cfD>cq0O5c%<%GK zSGb|w&*0>%8Zf-S1?!Xo`QvcyAtJ%gh|R7%8CBG3M)MgWzf&oCdIIXAce5{BSx1Y- z5dEL-zcQbDU6$vO(9f92sd1|@YBMrSV^_LSOSmOQ>DXIJA%4MDbX_v_QmdpWfiBX* z4u=%ZdS^q^cLz^)sMEjPBJj=i#37Icg%Csrw&JXXoR*JMexl zbz$g8s(g6Esy)-NHG{{J1P$nXv0p0m374a<=D{h+x8k9DVMk`TK;P5P6xW#y>$)VH zHP@+SPn^gv-JFuZ=8Y(7AE8btFNax{9&XYN?Rs{Q6hn8=!gt`o$4^`!YNlku<|JH`v(S<)jmv7 z2HAE8J3sH=lBibidH z-AFLeYCk!m7hIlAsmmwHe%1V<{6j)9SrA43eMbhET@C=lRQ6mn}&Qd9u-v91tjwP@|U#$zm*kU%#2s*N>MBA&;IzRF0IWnUB-s?Y8UVPW6I`O#v?C^aQd?ZZ^l!fCyzCLm@UBP<7Cn#7e^^H7VA! zrU2?f@}Y8al%~@${@i;QQy>5z6-%c8-ju5wB?P54`1!Cz;vE_c_ck^@NG)ZCY4fVz zMI~GBlka^^Rjjfxp!Qdcb8u6$SZ{H@L^ECWc=L(}*mYvvU!x8rOI%LXE% z-vLNM{$3PXvMbybihh9yZZee?^fo0=hJhQ%I4ULHNC&gI)#83!_?P9HIEZNbU%4>z|Kh&IS3LKQcP27`;8}j#+PVEV{e{fey75SStFRJSScg zXn^(e^#_n%>#E+N9>_5#^6^bj1jcd#vGAK<)6B4-+pQthAGjK1=NyWKkd`0m33n!Q zkRxJr;FF>rZ+)_dF;hgk2qMQr`mi1cO>vhUok*kmn7Jrj=8xeYKZA8fse+-u*d&$j zBbgfTDRr2PJ@AwV$0*Ip({V}YbSUGle-Hk(_n+KJOw8rQw-x4qGT02_xV&E1!_V&p zu#3Dji6rDsRETkV;LxC|G% z;SRMO=xgb_Hz@yuc1sNKECKHB&d%L#+W}r^>Zro|njioV#-ua>>RwdcH;JP6Mvir} z9VF0d(19r%R1iX=n9;^xp&pB)QC+@JxKnx_His^fr$jRx=8Yx-MSV!J0rKIj0vI7_7EzCkp<%2r8tlWR(+e^YZg!v$NN8d^KNRo@>n~N&a4YY+gU?duxSCa1M5T)(fL3gj!HS zRCcG&3y;}Ck*}V_B7ubbK5euzS8( zZBn!=>%2rPy6{y*qk*r9A!DiO)loiQFqAi{>vMOL_Md7{np=Sm#UjiNRZ>um#^pgJ z){#A*6gpcdW!AH2DqcUKvbeM*uxZ(Z|M_rO{x7%a#-^mWwGM8(A7{F*9c-MtiE=2g zXP)kR36ieZ+#*KwU+8OSXzWepik(mJLFOLUm#YngZq5fu-vs_*88=veM-HAdD>E31 zBrZK~>f=dKMyI3bqy5>bId{ArN@kA)r0B!P?;2rc(L&(`GKe&Z)7MU}eeT06_b54T zuY3K+I598_=-z+xMWF}VMIfR-prWE89929!Esgi!5z>|I^mKPlHK0{eq;4A?KW^sv z_kKUyATBNKk0HWFC@P`LBPi6Rt&BBHx}Ls~v+)z@;|jldzvGF%{Lw{at65!xx3|UR`tjB=&Hr<6{N~FDnF1;rm`c{F|enP zn<>i6uV4`q>%Aw`I{IDtDyyKNPC5gJ)Zs@TDRTykB|EKvj-Y@C?UM-QzqJ3xI{$ORY%v~qoS(3R*IFf(ReeN zmZRzE$w%wj#X`}Pl+kH?Af1n=n`-~Pe(-E_ zKEhEyf2{7f`J+>*WMX2nyPa;+cA(O}nnfcMcedYc6p1Y^E*@F5CjX?-Y_nSCC15pI z@+nhsVa%+4Tuxg0Y@}`lgD@RlxWRhqVti<5C;?aBE%!qIa<$#H`lf9xgQtFEK`aDi zGdDN4W8CaA_mXGe_Z&{9VsfMV<(}5zd>_Q=V5V?nLBQkcd&f?koaExk4JUjcd9>r& z6k!IuaLV{zmrj$lyVCwd=5p85#b}%A>*-Ndd)38xBtE-hyUlE|Qgi}UX~&Xvr&Q7| zzb|^(#i1;?=X`+S*~YKAUtzCc%#?Vo)SFMr1q1|C{Rj{DShePQBp4oe&ww+U3+f!2 zmzO6ASj=~L-lFljo}%zL>qQaqV6uUm)&zRO$)Bcgo(j6UD_G_8ZLy9%JJ3O=!Pe}W zmwV&yRUkHQ9O&gFC?x!Nkd9mZ-G$oPT0LxuR`~9zo}Qkhv?92VZBgBLk&^j)4y`wm zl9FjuG7ogj%n%H}a2~a^ej`gu7CfE(ogKUQ;kkhWrw|YRtng$E|Cwy={nM~_?_E}F zzVt@VEz86wrlsk${(8CFj{cR&>r6m7dLf&scq``ZwIwwgtW7~d(Fx;6U;Q(VSHRK( z{9wa_9y-+2)C%mW@(_49IN~=!FjG)X7OQQ}`3EQkmaQjE%Vl1xReJ5*>Elg;3=GFL zipBJKsLMjhXJ>Y-mNNy2f1st~Ijk3JPUEO5XAYc};;8OR@-86MTwE?Nz}3leGOv*3 zicW)t@_h?v%V$ao3PH2TMCh}bf#cT*Dw!UeWQw6fk5<-IIwENB9ln zWVuwg+v5*|F!Rf0hQoTjQ-Fe-`;PIC8;mV09!fh91l3KQtSd?gW4Qv4N}zT=MTCQM z1NW`ZzaDhEo}HbYU(3z5`wi4FG-A~YFhB?z@gH(tUfyIbvsVKXZ5+@y-ZWV+<-z#f zoGj0V2&YAjGItRHc1xzosBG!u_YKOAkk$aneC58rzMoj6q@-RKo=Vd3GgW$gfUvy0 zyl?)rTO^mwYlbcM+qdVwdhIUX-b_&`&-6)1B# z_pq>1{<^gaZT7>zebr^7MGVah+<-5>T}|uIH`vY_U`Kh}1%rUa2ak ziXM0nyy5WrAzf5dR1gFfET-$4zW)9&v+=ZVGKz{-KXEm6b%~q>Ma#;!`VNp?+64}_ zBAE3th>4#$gXLElG|JT*tmducz_<1MK`PYgUqCi(j9ih(RjnWG&Tz^&90Gmw0+NuBfY!X?AZPmN`d~Jcmx$bXvjG3XZ6{WW+nB** zu0&ZZATTglN?iOCS?1$Rzi85~E9kUBtP~VI9w&_p8mCBAEnCQkhCy?o@%zx;SJP7b zY-}o|*x1T<@Zf=UQvLo$`It?xRbJs-tZY<7#Xj3*gslbHYzgOvH|hjfGN}1%NsRLNE~H1xTU~ zFYj~8J_KP*aa3OL0Nr>n`$TmNVsTW`aj@D+sTe)GPP~p@g4yY;16x~LF&P;Ze0Ce% z9umrPK|!!6MBG!4$Mut^rjf)#*S18QR#;8nmL+X*a=VdD0^w1ONPX^dOC}tX89#Gv zZTt$%0xJM=W@hyM{(f3IIuRKeBsKL)M6SMp0SZCEmmLXNaF;Uq-7owPpR!sV_l=h7 vOt1DpkF;6)>F#`^^9F|@2cG(R?-lA%Z`}j33Udzr`w1W;p(tJ@Y8dcek^a{S literal 0 HcmV?d00001 From 8caa32a6bdca837fac22b8e6a8e2c7e50e6b1f3a Mon Sep 17 00:00:00 2001 From: Thomas Cheng Date: Fri, 8 Jul 2016 00:21:13 -0400 Subject: [PATCH 074/272] Add bowling exercise --- config.json | 3 +- exercises/bowling/bowling.spec.js | 128 ++++++++++++++++++++++++++++++ exercises/bowling/example.js | 69 ++++++++++++++++ 3 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 exercises/bowling/bowling.spec.js create mode 100644 exercises/bowling/example.js diff --git a/config.json b/config.json index fd72b262..72236a49 100644 --- a/config.json +++ b/config.json @@ -68,7 +68,8 @@ "ocr-numbers", "meetup", "bracket-push", - "two-bucket" + "two-bucket", + "bowling" ], "deprecated": [ "nucleotide-count", diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js new file mode 100644 index 00000000..309555c0 --- /dev/null +++ b/exercises/bowling/bowling.spec.js @@ -0,0 +1,128 @@ +var Bowling = require('./bowling'); + +describe('Bowling', function() { + describe('Check game can be scored correctly.', function() { + it('should be able to score open frame', function() { + var rolls = [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(7); + }); + + xit('should be able to score multiple frames', function() { + var rolls = [3, 4, 2, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(19); + }); + + xit('should be able to score a game with all gutterballs', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(0); + }); + + xit('should be able to score a game with all single pin rolls', function() { + var rolls = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + expect(new Bowling(rolls).score()).toEqual(20); + }); + + xit('should be able to score a game with all open frames', function() { + var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; + expect(new Bowling(rolls).score()).toEqual(90); + }); + + xit('should be able to score a strike not in the last frame', function() { + var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(26); + }); + + xit('should be able to score a spare not in the last frame', function() { + var rolls = [5, 5, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(20); + }); + + xit('should be able to score multiple strikes in a row', function() { + var rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(81); + }); + + xit('should be able to score multiple spares in a row', function() { + var rolls = [5, 5, 3, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(32); + }); + + xit('should allow fill balls when the last frame is a strike', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; + expect(new Bowling(rolls).score()).toEqual(18); + }); + + xit('should allow fill ball when the last frame is a spare', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 7]; + expect(new Bowling(rolls).score()).toEqual(17); + }); + + xit('should allow fill balls to be a strike', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; + expect(new Bowling(rolls).score()).toEqual(30); + }); + + xit('should be able to score a perfect game', function() { + var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; + expect(new Bowling(rolls).score()).toEqual(300); + }); + }); + + describe('Check game rules.', function() { + xit('should not allow rolls with negative pins', function() { + var rolls = [-1]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Pins must have a value from 0 to 10') + ); + }); + + xit('should not allow rolls better than strike', function() { + var rolls = [11]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Pins must have a value from 0 to 10') + ); + }); + + xit('should not allow two normal rolls better than strike', function() { + var rolls = [5, 6]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Pin count exceeds pins on the lane') + ); + }); + + xit('should not allow two normal rolls better than strike in last frame', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Pin count exceeds pins on the lane') + ); + }); + + xit('should not allow to take score at the beginning of the game', function() { + var rolls = []; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Score cannot be taken until the end of the game') + ); + }); + + xit('should not allow to take score before the game has ended', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Score cannot be taken until the end of the game') + ); + }); + + xit('should not allow rolls after the tenth frame', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Should not be able to roll after game is over') + ); + }); + + xit('should not calculate score before fill balls have been played', function() { + var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Score cannot be taken until the end of the game') + ); + }); + }); +}); diff --git a/exercises/bowling/example.js b/exercises/bowling/example.js new file mode 100644 index 00000000..69b71027 --- /dev/null +++ b/exercises/bowling/example.js @@ -0,0 +1,69 @@ +'use strict'; + +function Bowling(rolls) { + this.rolls = rolls; +} + +Bowling.prototype.score = function() { + var initialState = { + frameNumber: 1, + rollNumber: 1, + pinsRemaining: 10, + spareLastFrame: false, + strikeLastFrame: false, + twoStrikesInARow: false, + fillBall: false, + score: 0 + }; + + var finalState = this.rolls.reduce(function(state, roll) { + if (roll < 0 || roll > 10) { + throw new Error('Pins must have a value from 0 to 10'); + } + + if (roll > state.pinsRemaining) { + throw new Error('Pin count exceeds pins on the lane'); + } + + if (state.frameNumber > 10) { + throw new Error('Should not be able to roll after game is over') + } + + var finalFrame = state.frameNumber === 10; + var strike = state.rollNumber === 1 && roll === 10; + var spare = state.rollNumber === 2 && roll === state.pinsRemaining; + var frameOver = finalFrame + ? (!state.fillBall && !spare && state.rollNumber === 2) || state.rollNumber === 3 + : strike || spare || state.rollNumber === 2; + + var score = state.score + roll; + + if (state.strikeLastFrame && state.rollNumber < 3) { score += roll; } + if (state.spareLastFrame && state.rollNumber === 1) { score += roll; } + if (state.twoStrikesInARow && state.rollNumber === 1) { score += roll; } + + var next = {}; + + next.frameNumber = frameOver ? state.frameNumber + 1 : state.frameNumber; + next.rollNumber = frameOver ? 1 : state.rollNumber + 1; + next.pinsRemaining = finalFrame + ? ((strike || spare) ? 10 : state.pinsRemaining - roll) + : (frameOver ? 10 : state.pinsRemaining - roll); + next.spareLastFrame = frameOver ? spare : state.spareLastFrame; + next.strikeLastFrame = frameOver ? strike : state.strikeLastFrame; + next.twoStrikesInARow = frameOver ? strike && state.strikeLastFrame : state.twoStrikesInARow; + next.fillBall = next.fillBall || (finalFrame && (strike || spare)); + next.score = score; + + return next; + + }, initialState); + + if (finalState.frameNumber !== 11) { + throw new Error('Score cannot be taken until the end of the game'); + } + + return finalState.score; +}; + +module.exports = Bowling; From 24737a190935671985ab334d031738ebe1e9ca30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Thu, 7 Jul 2016 08:34:45 +0200 Subject: [PATCH 075/272] Add new test in the Isogram exercise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit éléphant is not an isogram, but some solutions using a simple regexp replace of non-word characters will fail at it. Addresses #287 --- exercises/isogram/isogram.spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/exercises/isogram/isogram.spec.js b/exercises/isogram/isogram.spec.js index 98a097c2..afc4874d 100644 --- a/exercises/isogram/isogram.spec.js +++ b/exercises/isogram/isogram.spec.js @@ -54,4 +54,11 @@ describe('Isogram Test Suite', function () { expect(word.isIsogram()).toEqual(true); }); + + xit('éléphant', function () { + var word = new Isogram('éléphant'); + + expect(word.isIsogram()).toEqual(false); + }); + }); From 2ab6acd56d7e3734d5261b4ecc1b8fc4cbf29f86 Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Fri, 22 Jul 2016 14:53:14 +0100 Subject: [PATCH 076/272] custom-set: correct initially enabled test The first test should be enabled, all others should be disabled --- exercises/custom-set/custom-set.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/custom-set/custom-set.spec.js b/exercises/custom-set/custom-set.spec.js index 47524f65..59465e63 100644 --- a/exercises/custom-set/custom-set.spec.js +++ b/exercises/custom-set/custom-set.spec.js @@ -2,7 +2,7 @@ var CustomSet = require('./custom-set'); describe('CustomSet', function() { - xit('can test for no members', function() { + it('can test for no members', function() { var actual = new CustomSet().empty(); expect(actual).toBe(true); @@ -147,7 +147,7 @@ describe('CustomSet', function() { expect(actual4.eql(expected4)).toBe(true); }); - it('can delete elements', function(){ + xit('can delete elements', function(){ var expected = new CustomSet([1, 3]); var actual = new CustomSet([3, 2, 1]).delete(2); expect(actual.eql(expected)).toBe(true); From 256c6541e3a9d4362119deea8b910275497e2eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Thu, 28 Jul 2016 22:53:52 +0200 Subject: [PATCH 077/272] Elaborate a bit more on how to run the tests for the first time This PR adds a more detailed explanation about how a user should run the tests for the first time, because some users didn't find it easy to start running them (see #284). Addresses #289 --- docs/TESTS.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 47080fff..a8f2e601 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,7 +1,10 @@ -Execute the tests with: +After configuring `exercism` command-line client and fetching your first JavaScript exercise (see [command-line interface overview](http://exercism.io/cli)) is time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine-node` command you should have installed on *Installing JavaScript* step: + cd ~/exercism/javascript/bob jasmine-node bob_test.spec.js +*Note that `~/exercism` is the default folder for `EXERCISM_HOME_DIR`. Be sure you use your configured folder for it* + ## Making Your First Node Module To create a module that can be loaded with `var Bob = require('./bob.js');`, put this code in `bob.js`: From a3f6ce176acddebdb7c7de122cfdec091536ad87 Mon Sep 17 00:00:00 2001 From: junedev Date: Mon, 8 Aug 2016 20:47:45 +0200 Subject: [PATCH 078/272] adding two more test cases --- exercises/binary-search/binary-search.spec.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/exercises/binary-search/binary-search.spec.js b/exercises/binary-search/binary-search.spec.js index 5433a2bd..773b22f3 100644 --- a/exercises/binary-search/binary-search.spec.js +++ b/exercises/binary-search/binary-search.spec.js @@ -14,10 +14,18 @@ describe('BinarySearch', function() { expect(Array.isArray(validBinarySearch.array)).toEqual(true); }); - xit('should find the correct index of an included value', function() { + xit('should find the correct index of an included value in the middle of the array', function() { expect(new BinarySearch(sortedArray).indexOf(3)).toEqual(2); }); + xit('should find the correct index of an included value at the beginning of the array', function() { + expect(new BinarySearch(sortedArray).indexOf(1)).toEqual(0); + }); + + xit('should find the correct index of an included value at the end of the array', function() { + expect(new BinarySearch(sortedArray).indexOf(6)).toEqual(5); + }); + xit('should search the middle of the array', function() { expect(new BinarySearch(sortedArrayOfOddLength).indexOf(2)).toEqual(3); }); @@ -26,4 +34,3 @@ describe('BinarySearch', function() { expect(new BinarySearch(sortedArray).indexOf(10)).toEqual(-1); }); }); - From 9885ab8aae45047dc7c8e15b813b54d34100fc44 Mon Sep 17 00:00:00 2001 From: Roshan Jossey Date: Sat, 20 Aug 2016 10:51:28 +0530 Subject: [PATCH 079/272] Update config.json to match new specification > This addresses issue #299 > https://github.com/exercism/xjavascript/issues/299 --- config.json | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) diff --git a/config.json b/config.json index 72236a49..5fe3c22e 100644 --- a/config.json +++ b/config.json @@ -71,6 +71,398 @@ "two-bucket", "bowling" ], + "exercises": [ + { + "slug": "hello-world", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "leap", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "hamming", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "rna-transcription", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "bob", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "gigasecond", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "word-count", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "isogram", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "pangram", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "beer-song", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "phone-number", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "anagram", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "food-chain", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "grade-school", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "robot-name", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "etl", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "space-age", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "grains", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "triangle", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "clock", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "acronym", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "scrabble-score", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "roman-numerals", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "circular-buffer", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "binary", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "prime-factors", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "raindrops", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "allergies", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "strain", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "atbash-cipher", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "accumulate", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "crypto-square", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "trinary", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "sieve", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "simple-cipher", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "octal", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "luhn", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "pig-latin", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "pythagorean-triplet", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "series", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "difference-of-squares", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "secret-handshake", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "linked-list", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "wordy", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "flatten-array", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "hexadecimal", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "largest-series-product", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "kindergarten-garden", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "binary-search", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "binary-search-tree", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "matrix", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "robot-simulator", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "nth-prime", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "palindrome-products", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "pascals-triangle", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "say", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "custom-set", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "sum-of-multiples", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "queen-attack", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "saddle-points", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "ocr-numbers", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "meetup", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "bracket-push", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "two-bucket", + "difficulty": 1, + "topics": [ + ] + }, + { + "slug": "bowling", + "difficulty": 1, + "topics": [ + ] + } + ], "deprecated": [ "nucleotide-count", "point-mutations" From 9f282a67d4541410b466a410aca97bf2e57d132f Mon Sep 17 00:00:00 2001 From: Santu Mahapatra Date: Sat, 20 Aug 2016 16:03:05 +0530 Subject: [PATCH 080/272] Add Diamond: tests and examples Tests and examples for Diamond exercise --- config.json | 9 +++++++- exercises/diamond/diamond.spec.js | 32 ++++++++++++++++++++++++++++ exercises/diamond/example.js | 35 +++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 exercises/diamond/diamond.spec.js create mode 100644 exercises/diamond/example.js diff --git a/config.json b/config.json index 5fe3c22e..c60390db 100644 --- a/config.json +++ b/config.json @@ -69,7 +69,8 @@ "meetup", "bracket-push", "two-bucket", - "bowling" + "bowling", + "diamond" ], "exercises": [ { @@ -461,6 +462,12 @@ "difficulty": 1, "topics": [ ] + }, + { + "slug": "diamond", + "difficulty": 1, + "topics": [ + ] } ], "deprecated": [ diff --git a/exercises/diamond/diamond.spec.js b/exercises/diamond/diamond.spec.js new file mode 100644 index 00000000..8bf43564 --- /dev/null +++ b/exercises/diamond/diamond.spec.js @@ -0,0 +1,32 @@ +var Diamond = require('./diamond'); + +describe('Diamond', function() { + var diamond = new Diamond(); + + it('test letter A', function() { + result = "A\n"; + expect(diamond.makeDiamond('A')).toEqual(result); + }); + + it('test letter C', function() { + result = [" A ", + " B B ", + "C C", + " B B ", + " A "].join("\n") + "\n"; + expect(diamond.makeDiamond('C')).toEqual(result); + }); + + it('test letter E', function() { + result = [" A ", + " B B ", + " C C ", + " D D ", + "E E", + " D D ", + " C C ", + " B B ", + " A "].join("\n") + "\n"; + expect(diamond.makeDiamond('E')).toEqual(result); + }); +}); diff --git a/exercises/diamond/example.js b/exercises/diamond/example.js new file mode 100644 index 00000000..7107827d --- /dev/null +++ b/exercises/diamond/example.js @@ -0,0 +1,35 @@ +var Diamond = function() { + this.makeDiamond = function(input){ + var inputIndex = input.charCodeAt() - 65; + var output = ""; + for(var i = 0; i <= inputIndex; i++){ + output += getLine(inputIndex, i); + } + for(var i = inputIndex - 1; i >= 0; i--){ + output += getLine(inputIndex, i); + } + return output; + } + + var getLine = function(inputIndex, index){ + var difference = inputIndex - index; + return spaceTimes(difference) + printAlphabets(index) + spaceTimes(difference) + "\n"; + } + + var printAlphabets = function(index){ + var character = 65 + index; + if(index === 0){ + return "A"; + } + else { + return String.fromCharCode(character) + spaceTimes(((index - 1) * 2) + 1) + String.fromCharCode(character); + } + + } + + var spaceTimes = function(times){ + return " ".repeat(times); + } +}; + +module.exports = Diamond; From 000b19f0760be0e37284e079899c9091fb8095b8 Mon Sep 17 00:00:00 2001 From: Lauren Nemtsev Date: Sun, 16 Oct 2016 17:17:09 -0500 Subject: [PATCH 081/272] beer-song: Add test case for 2 bottles. --- exercises/beer-song/beer-song.spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/beer-song/beer-song.spec.js b/exercises/beer-song/beer-song.spec.js index f009c620..d77d7e2d 100644 --- a/exercises/beer-song/beer-song.spec.js +++ b/exercises/beer-song/beer-song.spec.js @@ -8,6 +8,11 @@ describe('BeerSong', function() { expect(song.verse(8)).toEqual(expected); }); + xit('handles 2 bottles', function() { + var expected = '2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n'; + expect(song.verse(2)).toEqual(expected); + }); + xit('handles 1 bottle', function() { var expected = '1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n'; expect(song.verse(1)).toEqual(expected); From 3c5d9f78eaac4f330916ca76f656136b03297c8c Mon Sep 17 00:00:00 2001 From: Iain Reddick Date: Thu, 21 Jul 2016 17:09:55 +0100 Subject: [PATCH 082/272] custom-set: exercise generator The spec for this exercise is now generated from the common exercise metadata. Due to the metadata test cases being one assertion per case, there are now more tests in the suite. The existing non-canonical tests have been appended after the new generated tests. --- exercises/custom-set/custom-set.spec.js | 214 ++++++++++++++---------- exercises/custom-set/example-gen.js | 200 ++++++++++++++++++++++ 2 files changed, 330 insertions(+), 84 deletions(-) create mode 100644 exercises/custom-set/example-gen.js diff --git a/exercises/custom-set/custom-set.spec.js b/exercises/custom-set/custom-set.spec.js index 59465e63..d5615c94 100644 --- a/exercises/custom-set/custom-set.spec.js +++ b/exercises/custom-set/custom-set.spec.js @@ -2,159 +2,205 @@ var CustomSet = require('./custom-set'); describe('CustomSet', function() { - it('can test for no members', function() { + it('sets with no elements are empty', function() { var actual = new CustomSet().empty(); expect(actual).toBe(true); + }); - var actual2 = new CustomSet([1]).empty(); - expect(actual2).toBe(false); + xit('sets with elements are not empty', function() { + var actual = new CustomSet([1]).empty(); + expect(actual).toBe(false); }); - xit('can test for a member', function() { + xit('nothing is contained in an empty set', function() { var actual = new CustomSet().contains(1); expect(actual).toBe(false); + }); - var actual2 = new CustomSet([1, 2, 3]).contains(1); - expect(actual2).toBe(true); + xit('when the element is in the set', function() { + var actual = new CustomSet([1, 2, 3]).contains(1); + expect(actual).toBe(true); + }); - var actual3 = new CustomSet([1, 2, 3]).contains(4); - expect(actual3).toBe(false); + xit('when the element is not in the set', function() { + var actual = new CustomSet([1, 2, 3]).contains(4); + expect(actual).toBe(false); }); - xit('can test for subsets', function() { + xit('empty set is a subset of another empty set', function() { var actual = new CustomSet().subset(new CustomSet()); expect(actual).toBe(true); + }); - var actual2 = new CustomSet([1]).subset(new CustomSet()); - expect(actual2).toBe(true); + xit('empty set is a subset of non-empty set', function() { + var actual = new CustomSet([1]).subset(new CustomSet()); + expect(actual).toBe(true); + }); - var actual3 = new CustomSet().subset(new CustomSet([1])); - expect(actual3).toBe(false); + xit('non-empty set is not a subset of empty set', function() { + var actual = new CustomSet().subset(new CustomSet([1])); + expect(actual).toBe(false); + }); - var actual4 = new CustomSet([1, 2, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual4).toBe(true); + xit('set is a subset of set with exact same elements', function() { + var actual = new CustomSet([1, 2, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual).toBe(true); + }); - var actual5 = new CustomSet([4, 1, 2, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual5).toBe(true); + xit('set is a subset of larger set with same elements', function() { + var actual = new CustomSet([4, 1, 2, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual).toBe(true); + }); - var actual6 = new CustomSet([4, 1, 3]).subset(new CustomSet([1, 2, 3])); - expect(actual6).toBe(false); + xit('set is not a subset of set that does not contain its elements', function() { + var actual = new CustomSet([4, 1, 3]).subset(new CustomSet([1, 2, 3])); + expect(actual).toBe(false); }); - xit('can test disjoint', function() { + xit('the empty set is disjoint with itself', function() { var actual = new CustomSet().disjoint(new CustomSet()); expect(actual).toBe(true); + }); - var actual2 = new CustomSet().disjoint(new CustomSet([1])); - expect(actual2).toBe(true); + xit('empty set is disjoint with non-empty set', function() { + var actual = new CustomSet().disjoint(new CustomSet([1])); + expect(actual).toBe(true); + }); - var actual3 = new CustomSet([1]).disjoint(new CustomSet()); - expect(actual3).toBe(true); + xit('non-empty set is disjoint with empty set', function() { + var actual = new CustomSet([1]).disjoint(new CustomSet()); + expect(actual).toBe(true); + }); - var actual4 = new CustomSet([1, 2]).disjoint(new CustomSet([2, 3])); - expect(actual4).toBe(false); + xit('sets are not disjoint if they share an element', function() { + var actual = new CustomSet([1, 2]).disjoint(new CustomSet([2, 3])); + expect(actual).toBe(false); + }); - var actual5 = new CustomSet([1, 2]).disjoint(new CustomSet([3, 4])); - expect(actual5).toBe(true); + xit('sets are disjoint if they share no elements', function() { + var actual = new CustomSet([1, 2]).disjoint(new CustomSet([3, 4])); + expect(actual).toBe(true); }); - xit('can test for equality', function () { + xit('empty sets are equal', function() { var actual = new CustomSet().eql(new CustomSet()); expect(actual).toBe(true); + }); - var actual2 = new CustomSet().eql(new CustomSet([1, 2, 3])); - expect(actual2).toBe(false); + xit('empty set is not equal to non-empty set', function() { + var actual = new CustomSet().eql(new CustomSet([1, 2, 3])); + expect(actual).toBe(false); + }); - var actual3 = new CustomSet([1, 2, 3]).eql(new CustomSet()); - expect(actual3).toBe(false); + xit('non-empty set is not equal to empty set', function() { + var actual = new CustomSet([1, 2, 3]).eql(new CustomSet()); + expect(actual).toBe(false); + }); - var actual4 = new CustomSet([1, 2]).eql(new CustomSet([2, 1])); - expect(actual4).toBe(true); + xit('sets with the same elements are equal', function() { + var actual = new CustomSet([1, 2]).eql(new CustomSet([2, 1])); + expect(actual).toBe(true); + }); - var actual5 = new CustomSet([1, 2, 3]).eql(new CustomSet([1, 2, 4])); - expect(actual5).toBe(false); + xit('sets with different elements are not equal', function() { + var actual = new CustomSet([1, 2, 3]).eql(new CustomSet([1, 2, 4])); + expect(actual).toBe(false); }); - xit('can add a member', function() { + xit('add to empty set', function() { var actual = new CustomSet().add(3); var expected = new CustomSet([3]); expect(actual.eql(expected)).toBe(true); + }); - var actual2 = new CustomSet([1, 2, 4]).add(3); - var expected2 = new CustomSet([1, 2, 3, 4]); - expect(actual2.eql(expected2)).toBe(true); + xit('add to non-empty set', function() { + var actual = new CustomSet([1, 2, 4]).add(3); + var expected = new CustomSet([1, 2, 3, 4]); + expect(actual.eql(expected)).toBe(true); + }); - var actual3 = new CustomSet([1, 2, 3]).add(3); - var expected3 = new CustomSet([1, 2, 3]); - expect(actual3.eql(expected3)).toBe(true); + xit('adding an existing element does not change the set', function() { + var actual = new CustomSet([1, 2, 3]).add(3); + var expected = new CustomSet([1, 2, 3]); + expect(actual.eql(expected)).toBe(true); }); - xit('can check for intersection', function() { + xit('intersection of two empty sets is an empty set', function() { var actual = new CustomSet().intersection(new CustomSet()); var expected = new CustomSet(); expect(actual.eql(expected)).toBe(true); + }); - var actual2 = new CustomSet().intersection(new CustomSet([3, 2, 5])); - var expected2 = new CustomSet(); - expect(actual2.eql(expected2)).toBe(true); + xit('intersection of an empty set and non-empty set is an empty set', function() { + var actual = new CustomSet().intersection(new CustomSet([3, 2, 5])); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + }); - var actual3 = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet()); - var expected3 = new CustomSet(); - expect(actual3.eql(expected3)).toBe(true); + xit('intersection of a non-empty set and an empty set is an empty set', function() { + var actual = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet()); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + }); - var actual4 = new CustomSet([1, 2, 3]).intersection(new CustomSet([4, 5, 6])); - var expected4 = new CustomSet(); - expect(actual4.eql(expected4)).toBe(true); + xit('intersection of two sets with no shared elements is an empty set', function() { + var actual = new CustomSet([1, 2, 3]).intersection(new CustomSet([4, 5, 6])); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + }); - var actual5 = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet([3, 2, 5])); - var expected5 = new CustomSet([2, 3]); - expect(actual5.eql(expected5)).toBe(true); + xit('intersection of two sets with shared elements is a set of the shared elements', function() { + var actual = new CustomSet([1, 2, 3, 4]).intersection(new CustomSet([3, 2, 5])); + var expected = new CustomSet([2, 3]); + expect(actual.eql(expected)).toBe(true); }); - xit('can check for difference', function(){ + xit('difference of two empty sets is an empty set', function() { var actual = new CustomSet().difference(new CustomSet()); var expected = new CustomSet(); expect(actual.eql(expected)).toBe(true); + }); - var actual2 = new CustomSet().difference(new CustomSet([3, 2, 5])); - var expected2 = new CustomSet(); - expect(actual2.eql(expected2)).toBe(true); + xit('difference of empty set and non-empty set is an empty set', function() { + var actual = new CustomSet().difference(new CustomSet([3, 2, 5])); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + }); - var actual3 = new CustomSet([1, 2, 3, 4]).difference(new CustomSet()); - var expected3 = new CustomSet([1, 2, 3, 4]); - expect(actual3.eql(expected3)).toBe(true); + xit('difference of a non-empty set and an empty set is the non-empty set', function() { + var actual = new CustomSet([1, 2, 3, 4]).difference(new CustomSet()); + var expected = new CustomSet([1, 2, 3, 4]); + expect(actual.eql(expected)).toBe(true); + }); - var actual4 = new CustomSet([3, 2, 1]).difference(new CustomSet([2, 4])); - var expected4 = new CustomSet([1, 3]); - expect(actual4.eql(expected4)).toBe(true); + xit('difference of two non-empty sets is a set of elements that are only in the first set', function() { + var actual = new CustomSet([3, 2, 1]).difference(new CustomSet([2, 4])); + var expected = new CustomSet([1, 3]); + expect(actual.eql(expected)).toBe(true); }); - xit('can test for union', function() { + xit('union of empty sets is an empty set', function() { var actual = new CustomSet().union(new CustomSet()); var expected = new CustomSet(); expect(actual.eql(expected)).toBe(true); + }); - var actual2 = new CustomSet().union(new CustomSet([2])); - var expected2 = new CustomSet([2]); - expect(actual2.eql(expected2)).toBe(true); - - var actual3 = new CustomSet([1, 3]).union(new CustomSet()); - var expected3 = new CustomSet([1, 3]); - expect(actual3.eql(expected3)).toBe(true); - - var actual4 = new CustomSet([1, 3]).union(new CustomSet([2, 3])); - var expected4 = new CustomSet([3, 2, 1]); - expect(actual4.eql(expected4)).toBe(true); + xit('union of an empty set and non-empty set is the non-empty set', function() { + var actual = new CustomSet().union(new CustomSet([2])); + var expected = new CustomSet([2]); + expect(actual.eql(expected)).toBe(true); }); - xit('can delete elements', function(){ + xit('union of a non-empty set and empty set is the non-empty set', function() { + var actual = new CustomSet([1, 3]).union(new CustomSet()); var expected = new CustomSet([1, 3]); - var actual = new CustomSet([3, 2, 1]).delete(2); expect(actual.eql(expected)).toBe(true); + }); - var expected2 = new CustomSet([1, 2, 3]); - var actual2 = new CustomSet([3, 2, 1]).delete(4); - expect(actual2.eql(expected2)).toBe(true); + xit('union of non-empty sets contains all unique elements', function() { + var actual = new CustomSet([1, 3]).union(new CustomSet([2, 3])); + var expected = new CustomSet([3, 2, 1]); + expect(actual.eql(expected)).toBe(true); }); xit('can be emptied', function() { diff --git a/exercises/custom-set/example-gen.js b/exercises/custom-set/example-gen.js new file mode 100644 index 00000000..0170a3da --- /dev/null +++ b/exercises/custom-set/example-gen.js @@ -0,0 +1,200 @@ +/** + * README + * + * Generates the custom-set exercise spec from the test metadata in x-common + * + * Prerequisites: + * + * - Node.js v6 or higher (for destructuring and template literals) + * + * - x-common and xjavascript checked out into the same parent directory + * + * - x-common up to date + * + * Run with: + * + * node example-gen.js + */ + +var fs = require('fs'); +var path = require('path'); + +var EXERCISE_METADATA_ROOT = '../../../x-common/exercises'; +var METADATA_FILE_NAME = 'canonical-data.json'; +var METADATA_COMMENT_KEY = '#'; +var EXERCISE_DIR_NAME = 'custom-set'; +var SPEC_FILE_NAME = 'custom-set.spec.js'; + +var TEST_BODY_TEMPLATES = { + empty: function ({set, expected}) { + return ( + `var actual = new CustomSet(${array(set)}).empty(); + expect(actual).toBe(${expected});`); + }, + + contains: function ({set, element, expected}) { + return ( + `var actual = new CustomSet(${array(set)}).contains(${element}); + expect(actual).toBe(${expected});`); + }, + + subset: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set2)}).subset(new CustomSet(${array(set1)})); + expect(actual).toBe(${expected});`); + }, + + disjoint: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set1)}).disjoint(new CustomSet(${array(set2)})); + expect(actual).toBe(${expected});`); + }, + + equal: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set1)}).eql(new CustomSet(${array(set2)})); + expect(actual).toBe(${expected});`); + }, + + add: function ({set, element, expected}) { + return ( + `var actual = new CustomSet(${array(set)}).add(${element}); + var expected = new CustomSet(${array(expected)}); + expect(actual.eql(expected)).toBe(true);`); + }, + + intersection: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set1)}).intersection(new CustomSet(${array(set2)})); + var expected = new CustomSet(${array(expected)}); + expect(actual.eql(expected)).toBe(true);`); + }, + + difference: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set1)}).difference(new CustomSet(${array(set2)})); + var expected = new CustomSet(${array(expected)}); + expect(actual.eql(expected)).toBe(true);`); + }, + + union: function ({set1, set2, expected}) { + return ( + `var actual = new CustomSet(${array(set1)}).union(new CustomSet(${array(set2)})); + var expected = new CustomSet(${array(expected)}); + expect(actual.eql(expected)).toBe(true);`); + } +} + +var NON_CANONICAL_TESTS = ` + xit('can be emptied', function() { + var actual = new CustomSet([1, 2]).clear(); + var expected = new CustomSet(); + expect(actual.eql(expected)).toBe(true); + var actual2 = new CustomSet().clear(); + var expected2 = new CustomSet(); + expect(actual2.eql(expected2)).toBe(true); + }); + + xit('knows its size', function() { + var actual = new CustomSet().size(); + expect(actual).toBe(0); + var actual2 = new CustomSet([1, 2, 3]).size(); + expect(actual2).toBe(3); + var actual3 = new CustomSet([1, 2, 3, 2]).size(); + expect(actual3).toBe(3); + }); + + xit('can give back a list', function() { + var actual = new CustomSet().toList(); + var expected = []; + expect(actual.sort()).toEqual(expected); + var actual2 = new CustomSet([3, 1, 2]).toList(); + var expected2 = [1, 2, 3]; + expect(actual2.sort()).toEqual(expected2); + var actual3 = new CustomSet([3, 1, 2, 1]).toList(); + var expected3 = [1, 2, 3]; + expect(actual3.sort()).toEqual(expected3); + }); +` + +function render ({suiteData, testBodyTemplates, extraTests, suiteTemplate}) { + var testCases = extractTestCases(suiteData, testBodyTemplates); + var tests = renderTests(testCases); + + return renderSuite(tests, extraTests, suiteTemplate); +} + +function extractTestCases (suiteData, testBodyTemplates) { + var testCases = []; + + Object.keys(suiteData) + .filter(function (key) { + return key !== METADATA_COMMENT_KEY; + }) + .forEach(function (sectionName) { + suiteData[sectionName]['cases'] + .forEach(function (caseData) { + testCases.push(new TestCase(caseData, testBodyTemplates[sectionName])); + }) + }) + + return testCases; +} + +function TestCase (caseData, bodyTemplate) { + this.caseData = caseData; + this.bodyTemplate = bodyTemplate; +} + +TestCase.prototype.render = function (isEnabled) { + return testTemplate(isEnabled, this.caseData.description, this.bodyTemplate(this.caseData)); +} + +function renderTests (testCases) { + return testCases.reduce(function (output, testCase, index) { + return output + testCase.render(index === 0); + }, '') +} + +function renderSuite (tests, otherTests, suiteTemplate) { + return suiteTemplate(tests.concat(otherTests)); +} + +function suiteTemplate (tests) { + return ( +`var CustomSet = require('./custom-set'); + +describe('CustomSet', function() { +${tests} +}); +`); +} + +function testTemplate (isEnabled, description, body) { + return ( +` + ${isEnabled ? 'it' : 'xit'}('${description}', function() { + ${body} + }); +`); +} + +function array (array) { + return array.length === 0 ? '' : `[${array.join(', ')}]`; +} + +function generate () { + var exerciseFilePath = path.join(EXERCISE_METADATA_ROOT, EXERCISE_DIR_NAME, METADATA_FILE_NAME); + var suiteData = JSON.parse(fs.readFileSync(exerciseFilePath)); + + return fs.writeFileSync( + SPEC_FILE_NAME, + render({ + suiteData: suiteData, + testBodyTemplates: TEST_BODY_TEMPLATES, + extraTests: NON_CANONICAL_TESTS, + suiteTemplate: suiteTemplate + })); +} + +generate(); From 8f30a79c4d8c4420876b884339ea2d46111b01ac Mon Sep 17 00:00:00 2001 From: ldwoolley Date: Sun, 4 Dec 2016 16:36:32 -0800 Subject: [PATCH 083/272] Update word-count in xjavascript to match the x-common reference. The test now checks for the elimination of punctuation. --- exercises/word-count/example.js | 10 ++++---- exercises/word-count/word-count.spec.js | 31 ++++++++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/exercises/word-count/example.js b/exercises/word-count/example.js index 02aa1d9e..2a357994 100644 --- a/exercises/word-count/example.js +++ b/exercises/word-count/example.js @@ -4,15 +4,15 @@ function Words() {} Words.prototype.count = function (input) { var counts = {}; - var words = input.match(/\S+/g); + var words = input.toLowerCase() + .replace(/[,."\/!&@$%\^\*;:{}()¡¿?]/g, ' ') + .replace(/\s'(\w+)'\s/, ' '+'$1'+' ') + .match(/\S+/g); words.forEach(function (word) { - var lcWord = word.toLowerCase(); - counts[lcWord] = counts.hasOwnProperty(lcWord) ? counts[lcWord] + 1 : 1; + counts[word] = counts.hasOwnProperty(word) ? counts[word] + 1 : 1; }); - return counts; }; module.exports = Words; - diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index ab503dda..8b34faf0 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -8,19 +8,24 @@ describe('count()', function() { expect(words.count('word')).toEqual(expectedCounts); }); - xit('counts one of each', function() { + xit('counts one of each word', function() { var expectedCounts = { one: 1, of: 1, each: 1 }; expect(words.count('one of each')).toEqual(expectedCounts); }); - xit('counts multiple occurrences', function() { + xit('counts multiple occurrences of a word', function() { var expectedCounts = { one: 1, fish: 4, two: 1, red: 1, blue: 1 }; expect(words.count('one fish two fish red fish blue fish')).toEqual(expectedCounts); }); - xit('includes punctuation', function() { - var expectedCounts = { car: 1, ':': 2, carpet: 1, as: 1, java: 1, 'javascript!!&@$%^&': 1 }; - expect(words.count('car : carpet as java : javascript!!&@$%^&')).toEqual(expectedCounts); + xit('handles cramped lists', function() { + var expectedCounts = { one: 1, two: 1, three: 1 }; + expect(words.count('one,two,three')).toEqual(expectedCounts); + }); + + xit('ignores punctuation', function() { + var expectedCounts = { car: 1, carpet: 1, as: 1, java: 1, javascript: 1 }; + expect(words.count('car : carpet as java: javascript!!&@$%^&')).toEqual(expectedCounts); }); xit('includes numbers', function() { @@ -33,8 +38,18 @@ describe('count()', function() { expect(words.count('go Go GO')).toEqual(expectedCounts); }); + xit('counts words with apostrophes', function() { + var expectedCounts = { 'first': 1, 'don\'t': 2, 'laugh': 1, 'then': 1, 'cry': 1 }; + expect(words.count('First: don\'t laugh. Then: don\'t cry.')).toEqual(expectedCounts); + }); + + xit('counts words with quotations', function() { + var expectedCounts = { 'joe': 1, 'can\'t': 1, 'tell': 1, 'between': 1, 'large': 2, 'and': 1 }; + expect(words.count('Joe can\'t tell between \'large\' and large.')).toEqual(expectedCounts); + }); + xit('counts properly international characters', function() { - var expectedCounts = { '¡hola!': 1, '¿qué': 1, 'tal?': 1, 'привет!': 1 }; + var expectedCounts = { 'hola': 1, 'qué': 1, 'tal': 1, 'привет': 1 }; expect(words.count('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); }); @@ -43,7 +58,7 @@ describe('count()', function() { expect(words.count('hello\nworld')).toEqual(expectedCounts); }); - xit('counts tabs', function() { + xit('counts tabs as white space', function() { var expectedCounts = { hello: 1, world: 1 }; expect(words.count('hello\tworld')).toEqual(expectedCounts); }); @@ -59,7 +74,7 @@ describe('count()', function() { }); xit('handles properties that exist on Object’s prototype', function() { - var expectedCounts = { reserved: 1, words: 1, like: 1, constructor: 1, and: 1, tostring: 1, 'ok?': 1 }; + var expectedCounts = { reserved: 1, words: 1, like: 1, constructor: 1, and: 1, tostring: 1, ok: 1 }; expect(words.count('reserved words like constructor and toString ok?')).toEqual(expectedCounts); }); }); From 446d43bcd5718d2a62f57fd2dd5216d3e1b049e2 Mon Sep 17 00:00:00 2001 From: Dmitry Noranovich Date: Wed, 30 Nov 2016 16:32:57 -0500 Subject: [PATCH 084/272] Added all-your-base exercise to JavaScript track Added use strict statement to the code Renamed and moved test concerning missing inputs --- config.json | 9 +- exercises/all-your-base/all-your-base.spec.js | 141 ++++++++++++++++++ exercises/all-your-base/example.js | 59 ++++++++ 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 exercises/all-your-base/all-your-base.spec.js create mode 100644 exercises/all-your-base/example.js diff --git a/config.json b/config.json index c60390db..b30f5090 100644 --- a/config.json +++ b/config.json @@ -70,7 +70,8 @@ "bracket-push", "two-bucket", "bowling", - "diamond" + "diamond", + "all-your-base" ], "exercises": [ { @@ -468,6 +469,12 @@ "difficulty": 1, "topics": [ ] + }, + { + "slug": "all-your-base", + "difficulty": 1, + "topics": [ + ] } ], "deprecated": [ diff --git a/exercises/all-your-base/all-your-base.spec.js b/exercises/all-your-base/all-your-base.spec.js new file mode 100644 index 00000000..34d28100 --- /dev/null +++ b/exercises/all-your-base/all-your-base.spec.js @@ -0,0 +1,141 @@ +'use strict'; + +const Converter = require('./all-your-base'); + +const converter = new Converter(); + +describe('Converter', function () { + + xit('single bit one to decimal', function () { + expect(converter.convert([1], 2, 10)).toEqual([1]); + }); + + xit('binary to single decimal', function () { + expect(converter.convert([1, 0, 1], 2, 10)).toEqual([5]); + }); + + xit('single decimal to binary', function () { + expect(converter.convert([5], 10, 2)).toEqual([1, 0, 1]); + }); + + xit('binary to multiple decimal', function () { + expect(converter.convert([1, 0, 1, 0, 1, 0], 2, 10)).toEqual([4, 2]); + }); + + xit('decimal to binary', function () { + expect(converter.convert([4, 2], 10, 2)).toEqual([1, 0, 1, 0, 1, 0]); + }); + + xit('trinary to hexadecimal', function () { + expect(converter.convert([1, 1, 2, 0], 3, 16)).toEqual([2, 10]); + }); + + xit('hexadecimal to trinary', function () { + expect(converter.convert([2, 10], 16, 3)).toEqual([1, 1, 2, 0]); + }); + + xit('15-bit integer', function () { + expect(converter.convert([3, 46, 60], 97, 73)).toEqual([6, 10, 45]); + }); + + xit('empty list', function () { + expect(function () { + converter.convert([], 2, 10); + }).toThrow(new Error('Input has wrong format')); + }); + + xit('single zero', function () { + expect(converter.convert([0], 10, 2)).toEqual([0]); + }); + + xit('multiple zeros', function () { + expect(function () { + converter.convert([0, 0, 0], 10, 2); + }).toThrow(new Error('Input has wrong format')); + }); + + xit('leading zeros', function () { + expect(function () { + converter.convert([0, 6, 0], 7, 10); + }).toThrow(new Error('Input has wrong format')); + }); + + xit('negative digit', function () { + expect(function () { + converter.convert([1, -1, 1, 0, 1, 0], 2, 10); + }).toThrow(new Error('Input has wrong format')); + }); + + xit('invalid positive digit', function () { + expect(function () { + converter.convert([1, 2, 1, 0, 1, 0], 2, 10); + }).toThrow(new Error('Input has wrong format')); + }); + + xit('first base is one', function () { + expect(function () { + converter.convert([], 1, 10); + }).toThrow(new Error('Wrong input base')); + }); + + xit('second base is one', function () { + expect(function () { + converter.convert([1, 0, 1, 0, 1, 0], 2, 1); + }).toThrow(new Error('Wrong output base')); + }); + + xit('first base is zero', function () { + expect(function () { + converter.convert([], 0, 10); + }).toThrow(new Error('Wrong input base')); + }); + + xit('second base is zero', function () { + expect(function () { + converter.convert([7], 10, 0); + }).toThrow(new Error('Wrong output base')); + }); + + xit('first base is negative', function () { + expect(function () { + converter.convert([1], -2, 10); + }).toThrow(new Error('Wrong input base')); + }); + + xit('second base is negative', function () { + expect(function () { + converter.convert([1], 2, -7); + }).toThrow(new Error('Wrong output base')); + }); + + xit('both bases are negative', function () { + expect(function () { + converter.convert([1], -2, -7); + }).toThrow(new Error('Wrong input base')); + }); + + it('missing input base throws an error', function () { + expect(function () { + converter.convert([0]); + }).toThrow(new Error('Wrong input base')); + }); + + xit('wrong input_base base not integer', function () { + expect(function () { + converter.convert([0], 2.5); + }).toThrow(new Error('Wrong input base')); + }); + + xit('missing output base throws an error', function () { + expect(function () { + converter.convert([0], 2); + }).toThrow(new Error('Wrong output base')); + }); + + xit('wrong output_base base not integer', function () { + expect(function () { + converter.convert([0], 3, 2.5); + }).toThrow(new Error('Wrong output base')); + }); + +}); diff --git a/exercises/all-your-base/example.js b/exercises/all-your-base/example.js new file mode 100644 index 00000000..7dae83cc --- /dev/null +++ b/exercises/all-your-base/example.js @@ -0,0 +1,59 @@ +'use strict'; + +const Converter = function () { }; + +const isValidBase = function (base) { + return !base || base < 2 || Math.floor(base) !== base; +}; + +const isInputValid = function (array, base) { + if (!array || !array.length) { + return false; + } + const val = base - 1; + for (let i = 0, n = array.length; i < n; i++) { + const tmp = array[i]; + if (tmp > val || tmp < 0) { + return false; + } + } + return true; +}; + +const convertFromDecimalToBase = function (num, outputBase) { + let tmp = num; + const result = []; + while (tmp) { + result.unshift(tmp % outputBase); + tmp = Math.floor(tmp / outputBase); + } + return result; +}; + +Converter.prototype.convert = function (array, inputBase, outputBase) { + if (isValidBase(inputBase)) { + throw new Error('Wrong input base'); + } + if (isValidBase(outputBase)) { + throw new Error('Wrong output base'); + } + const regexp = new RegExp('^0.', 'g'); + const str = array.join(''); + if (str.match(regexp) + || !isInputValid(array, inputBase)) { + throw new Error('Input has wrong format'); + } + if (str === '0') { + return [0]; + } + if (str === '1') { + return [1]; + } + const decimalValue = array + .reduce((accumulator, value) => { + return accumulator * inputBase + value; + }, 0); + return convertFromDecimalToBase(decimalValue, outputBase); +}; + +module.exports = Converter; From e9da0f2ae1fa78d2ec75c1bc4725d3f8f29e2f49 Mon Sep 17 00:00:00 2001 From: ldwoolley Date: Sun, 4 Dec 2016 23:06:11 -0800 Subject: [PATCH 085/272] Update bowling test Adjusted test order and add tests to align with x-common reference, and set the file to the test start position. --- exercises/bowling/bowling.spec.js | 146 +++++++++++++++++------------- 1 file changed, 83 insertions(+), 63 deletions(-) diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 309555c0..2804ee5a 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -2,39 +2,44 @@ var Bowling = require('./bowling'); describe('Bowling', function() { describe('Check game can be scored correctly.', function() { - it('should be able to score open frame', function() { - var rolls = [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(7); + it('should be able to score a game with all gutterballs', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(0); }); - xit('should be able to score multiple frames', function() { - var rolls = [3, 4, 2, 3, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(19); + xit('should be able to score a game with all open frames', function() { + var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; + expect(new Bowling(rolls).score()).toEqual(90); }); - xit('should be able to score a game with all gutterballs', function() { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(0); + xit('a spare followed by zeros is worth ten points', function() { + var rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(10); }); - xit('should be able to score a game with all single pin rolls', function() { - var rolls = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - expect(new Bowling(rolls).score()).toEqual(20); + xit('points scored in the roll after a spare are counted twice', function() { + var rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(16); }); - xit('should be able to score a game with all open frames', function() { - var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; - expect(new Bowling(rolls).score()).toEqual(90); + xit('consecutive spares each get a one roll bonus', function() { + var rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(31); }); - xit('should be able to score a strike not in the last frame', function() { - var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(26); + xit('should allow fill ball when the last frame is a spare', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; + expect(new Bowling(rolls).score()).toEqual(17); }); - xit('should be able to score a spare not in the last frame', function() { - var rolls = [5, 5, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(20); + xit('a strike earns ten points in a frame with a single roll', function() { + var rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(10); + }); + + xit('points scored in the two rolls after a strike are counted twice as a bonus', function() { + var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + expect(new Bowling(rolls).score()).toEqual(26); }); xit('should be able to score multiple strikes in a row', function() { @@ -42,26 +47,26 @@ describe('Bowling', function() { expect(new Bowling(rolls).score()).toEqual(81); }); - xit('should be able to score multiple spares in a row', function() { - var rolls = [5, 5, 3, 7, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(32); - }); - xit('should allow fill balls when the last frame is a strike', function() { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; expect(new Bowling(rolls).score()).toEqual(18); }); - xit('should allow fill ball when the last frame is a spare', function() { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 7]; - expect(new Bowling(rolls).score()).toEqual(17); + xit('rolling a spare with the two roll bonus does not get a bonus roll', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; + expect(new Bowling(rolls).score()).toEqual(20); }); - xit('should allow fill balls to be a strike', function() { + xit('strikes with the two roll bonus do not get bonus rolls', function() { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(30); }); + xit('a strike with the one roll bonus after a spare in the last frame does not get a bonus', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; + expect(new Bowling(rolls).score()).toEqual(20); + }); + xit('should be able to score a perfect game', function() { var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(300); @@ -69,60 +74,75 @@ describe('Bowling', function() { }); describe('Check game rules.', function() { - xit('should not allow rolls with negative pins', function() { - var rolls = [-1]; + xit('rolls can not score negative points', function() { + var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pins must have a value from 0 to 10') - ); - }); + new Error('Pins must have a value from 0 to 10')); + }); - xit('should not allow rolls better than strike', function() { - var rolls = [11]; + xit('a roll can not score more than 10 points', function() { + var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pins must have a value from 0 to 10') - ); - }); + new Error('Pins must have a value from 0 to 10')); + }); - xit('should not allow two normal rolls better than strike', function() { - var rolls = [5, 6]; + xit('two rolls in a frame can not score more than 10 points', function() { + var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pin count exceeds pins on the lane') - ); + new Error('Pin count exceeds pins on the lane')); + }); + + xit('two bonus rolls after a strike in the last frame can not score more than 10 points', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Pin count exceeds pins on the lane')); + }); + + xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; + expect(new Bowling(rolls).score()).toEqual(26); }); - xit('should not allow two normal rolls better than strike in last frame', function() { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6]; + xit('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pin count exceeds pins on the lane') - ); + new Error('Pin count exceeds pins on the lane')); }); - xit('should not allow to take score at the beginning of the game', function() { + xit('an unstarted game can not be scored', function() { var rolls = []; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Score cannot be taken until the end of the game') - ); + new Error('Score cannot be taken until the end of the game')); }); - xit('should not allow to take score before the game has ended', function() { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + xit('an incomplete game can not be scored', function() { + var rolls = [0, 0]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Score cannot be taken until the end of the game') - ); + new Error('Score cannot be taken until the end of the game')); }); - xit('should not allow rolls after the tenth frame', function() { + xit('a game with more than ten frames and no last frame spare or strike can not be scored', function() { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Should not be able to roll after game is over') - ); + new Error('Should not be able to roll after game is over')); + }); + + xit('bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Score cannot be taken until the end of the game')); + }); + + xit('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; + expect(function() { new Bowling(rolls).score(); }).toThrow( + new Error('Score cannot be taken until the end of the game')); }); - xit('should not calculate score before fill balls have been played', function() { - var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; + xit('bonus roll for a spare in the last frame must be rolled before score can be calculated', function() { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3]; expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Score cannot be taken until the end of the game') - ); + new Error('Score cannot be taken until the end of the game')); }); }); -}); +}); \ No newline at end of file From 9701c0acca6b647247430b4de01c3bcc81043103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Mon, 19 Dec 2016 22:37:54 +0100 Subject: [PATCH 086/272] Fix typo: missing `t` --- docs/INSTALLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 5e12e440..802b696b 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -6,7 +6,7 @@ There are at least two common options to run JavaScript code: the browsers and [ **Mac OS X users**: same as Windows users, you will find official installers on [Node.js downloads](https://nodejs.org/en/download/). Choose the LTS version. It will install Node.js and `npm` on your machine. -**Linux users**: there are binaries for `node` and `npm` tools on the Node.js downloads page, but the recommended way to install them on a Linux machine is via a package manager. As of writing this, the recommended version of Node.js to install is 4.x. To install it on a Debian or Ubuntu Linux distribuion just execute these commands: +**Linux users**: there are binaries for `node` and `npm` tools on the Node.js downloads page, but the recommended way to install them on a Linux machine is via a package manager. As of writing this, the recommended version of Node.js to install is 4.x. To install it on a Debian or Ubuntu Linux distribution just execute these commands: curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - sudo apt-get install -y nodejs From 8eae4e51aca7cc99145c644062288758951c2a22 Mon Sep 17 00:00:00 2001 From: Yoni Levy Date: Mon, 26 Dec 2016 17:19:08 +0200 Subject: [PATCH 087/272] dibs: I will implement exercise run-length-encoding From b63ae22ee0e2bcde6a5340871375507894413885 Mon Sep 17 00:00:00 2001 From: Yoni Levy Date: Mon, 26 Dec 2016 17:56:55 +0200 Subject: [PATCH 088/272] rle: added example and test files --- exercises/run-length-encoding/example.js | 11 +++++ .../run-length-encoding.spec.js | 41 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 exercises/run-length-encoding/example.js create mode 100644 exercises/run-length-encoding/run-length-encoding.spec.js diff --git a/exercises/run-length-encoding/example.js b/exercises/run-length-encoding/example.js new file mode 100644 index 00000000..e626cc29 --- /dev/null +++ b/exercises/run-length-encoding/example.js @@ -0,0 +1,11 @@ +exports.encode = function encode(plaintext) { + return plaintext.replace(/([\w\s])\1*/g, function(match) { + return match.length > 1 ? match.length + match[0] : match[0] + }); +} + +exports.decode = function decode(cypher) { + return cypher.replace(/(\d+)(\w|\s)/g, function(match, repeats, char) { + return new Array(+repeats + 1).join(char) + }); +} \ No newline at end of file diff --git a/exercises/run-length-encoding/run-length-encoding.spec.js b/exercises/run-length-encoding/run-length-encoding.spec.js new file mode 100644 index 00000000..bfd56787 --- /dev/null +++ b/exercises/run-length-encoding/run-length-encoding.spec.js @@ -0,0 +1,41 @@ +var RLE = require('./run-length-encoding'); + +describe('Run-length encoding', function() { + + it('encode empty string', function() { + expect(RLE.encode('')).toEqual(''); + }); + + xit('encode single characters only', function() { + expect(RLE.encode('XYZ')).toEqual('XYZ'); + }); + + xit('decode empty string', function() { + expect(RLE.decode('')).toEqual(''); + }); + + xit('decode single characters only', function() { + expect(RLE.decode('XYZ')).toEqual('XYZ'); + }); + + xit('encode simple', function() { + expect(RLE.encode('AABBBCCCC')).toEqual('2A3B4C'); + }); + + xit('decode simple', function() { + expect(RLE.decode('2A3B4C')).toEqual('AABBBCCCC'); + }); + + xit('encode with single values', function() { + expect(RLE.encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')).toEqual('12WB12W3B24WB'); + }); + + xit('decode with single values', function() { + expect(RLE.decode('12WB12W3B24WB')).toEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'); + }); + + xit('decode(encode(...))combination', function() { + expect(RLE.decode(RLE.encode('zzz ZZ zZ'))).toEqual('zzz ZZ zZ'); + }); + +}); From bb2939387f0d0cdbbbcc28804338653e0795c951 Mon Sep 17 00:00:00 2001 From: Yoni Levy Date: Mon, 26 Dec 2016 17:56:55 +0200 Subject: [PATCH 089/272] rle: added example and test files --- config.json | 9 +++- exercises/run-length-encoding/example.js | 11 +++++ .../run-length-encoding.spec.js | 41 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 exercises/run-length-encoding/example.js create mode 100644 exercises/run-length-encoding/run-length-encoding.spec.js diff --git a/config.json b/config.json index b30f5090..41f17a67 100644 --- a/config.json +++ b/config.json @@ -71,7 +71,8 @@ "two-bucket", "bowling", "diamond", - "all-your-base" + "all-your-base", + "run-length-encoding" ], "exercises": [ { @@ -475,6 +476,12 @@ "difficulty": 1, "topics": [ ] + }, + { + "slug": "run-length-encoding", + "difficulty": 1, + "topics": [ + ] } ], "deprecated": [ diff --git a/exercises/run-length-encoding/example.js b/exercises/run-length-encoding/example.js new file mode 100644 index 00000000..e626cc29 --- /dev/null +++ b/exercises/run-length-encoding/example.js @@ -0,0 +1,11 @@ +exports.encode = function encode(plaintext) { + return plaintext.replace(/([\w\s])\1*/g, function(match) { + return match.length > 1 ? match.length + match[0] : match[0] + }); +} + +exports.decode = function decode(cypher) { + return cypher.replace(/(\d+)(\w|\s)/g, function(match, repeats, char) { + return new Array(+repeats + 1).join(char) + }); +} \ No newline at end of file diff --git a/exercises/run-length-encoding/run-length-encoding.spec.js b/exercises/run-length-encoding/run-length-encoding.spec.js new file mode 100644 index 00000000..bfd56787 --- /dev/null +++ b/exercises/run-length-encoding/run-length-encoding.spec.js @@ -0,0 +1,41 @@ +var RLE = require('./run-length-encoding'); + +describe('Run-length encoding', function() { + + it('encode empty string', function() { + expect(RLE.encode('')).toEqual(''); + }); + + xit('encode single characters only', function() { + expect(RLE.encode('XYZ')).toEqual('XYZ'); + }); + + xit('decode empty string', function() { + expect(RLE.decode('')).toEqual(''); + }); + + xit('decode single characters only', function() { + expect(RLE.decode('XYZ')).toEqual('XYZ'); + }); + + xit('encode simple', function() { + expect(RLE.encode('AABBBCCCC')).toEqual('2A3B4C'); + }); + + xit('decode simple', function() { + expect(RLE.decode('2A3B4C')).toEqual('AABBBCCCC'); + }); + + xit('encode with single values', function() { + expect(RLE.encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')).toEqual('12WB12W3B24WB'); + }); + + xit('decode with single values', function() { + expect(RLE.decode('12WB12W3B24WB')).toEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'); + }); + + xit('decode(encode(...))combination', function() { + expect(RLE.decode(RLE.encode('zzz ZZ zZ'))).toEqual('zzz ZZ zZ'); + }); + +}); From 18d423cdcd6c0c73415ed05a1342df3082f3507a Mon Sep 17 00:00:00 2001 From: Yoni Levy Date: Thu, 29 Dec 2016 18:48:36 +0200 Subject: [PATCH 090/272] rle: added missing semicolons --- exercises/run-length-encoding/example.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/run-length-encoding/example.js b/exercises/run-length-encoding/example.js index e626cc29..6a900cc4 100644 --- a/exercises/run-length-encoding/example.js +++ b/exercises/run-length-encoding/example.js @@ -1,11 +1,11 @@ exports.encode = function encode(plaintext) { return plaintext.replace(/([\w\s])\1*/g, function(match) { - return match.length > 1 ? match.length + match[0] : match[0] + return match.length > 1 ? match.length + match[0] : match[0]; }); -} +}; exports.decode = function decode(cypher) { return cypher.replace(/(\d+)(\w|\s)/g, function(match, repeats, char) { - return new Array(+repeats + 1).join(char) + return new Array(+repeats + 1).join(char); }); -} \ No newline at end of file +}; From 9d4abb02bafbc4d4bd3d5143a0d452580784f6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Thu, 19 Jan 2017 12:34:13 +0100 Subject: [PATCH 091/272] Synchronize Luhn exercise with canonical specs Canonical specs for Luhn exercise were changed, and tracks implementing that exercise should synchronize wih them. Closes #316 --- exercises/luhn/example.js | 85 ++++++++++++------------------------- exercises/luhn/luhn.spec.js | 57 +++++++------------------ 2 files changed, 44 insertions(+), 98 deletions(-) diff --git a/exercises/luhn/example.js b/exercises/luhn/example.js index dbd09c3a..b311427f 100644 --- a/exercises/luhn/example.js +++ b/exercises/luhn/example.js @@ -1,63 +1,34 @@ 'use strict'; -function Luhn(number) { - this.checkDigit = number % 10; - this.addends = this.calculateAddends(number); - this.checksum = this.calculateChecksum(this.addends); - this.valid = this.determineIfValid(this.checksum); -} - -Luhn.prototype = { - calculateAddends: function(number) { - - var numberAsString = '' + number + ''; - var numbers = numberAsString.split(''); - var addends = []; - - for (var i = 0; i < numbers.length; i++) { - var index = numbers.length - 1 - i; - - var currentAddend = parseInt(numbers[index], 10); - - if ((i + 1) % 2 === 0) { - currentAddend = currentAddend * 2; - if (currentAddend > 10) { - currentAddend = currentAddend - 9; - } +function isValid(number) { + number = number.replace(/\s/g, ''); + const digits = [...number]; + + const sum = digits + // convert to integers + .map(d => parseInt(d, 10)) + // double even positions (odd indexes) + .map((d, i) => { + if (i % 2 !== 0) { + return d * 2; } + return d; + }) + // limit to digits less than 10 + .map(d => { + if (d > 9) { + return d - 9; + } + return d; + }) + // sum all digits + .reduce((d, acc) => d + acc, 0); - addends.push(currentAddend); - } - - return addends.reverse(); - - }, - calculateChecksum: function(numbers) { - var sum = 0; - for (var i = 0; i < numbers.length; i++) { - sum += numbers[i]; - } - - return sum; - }, - determineIfValid: function(sum) { - return (sum % 10 === 0); - } -}; - -Luhn.create = function(number) { - var finalNumber = number * 10; - var luhnNumber = new Luhn(finalNumber); - var index = 0; - - while(!luhnNumber.valid) { - finalNumber = number * 10 + index; - luhnNumber = new Luhn(finalNumber); - if (luhnNumber.valid) { break; } - index += 1; - } + return sum > 0 && sum % 10 === 0; +} - return finalNumber; -}; +function Luhn(number) { + this.valid = isValid(number); +} -module.exports = Luhn; \ No newline at end of file +module.exports = Luhn; diff --git a/exercises/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js index c6c426a0..e6e4b8ef 100644 --- a/exercises/luhn/luhn.spec.js +++ b/exercises/luhn/luhn.spec.js @@ -2,59 +2,34 @@ var Luhn = require('./luhn'); describe('Luhn',function() { - it('check digit',function() { - var luhn = new Luhn(34567); - expect(luhn.checkDigit).toEqual(7); - }); - - xit('check digit again',function() { - var luhn = new Luhn(91370); - expect(luhn.checkDigit).toEqual(0); - }); - - xit('addends',function() { - var luhn = new Luhn(12121); - expect(luhn.addends).toEqual([1, 4, 1, 4, 1]); - }); - - xit('too large addend',function() { - var luhn = new Luhn(8631); - expect(luhn.addends).toEqual([7, 6, 6, 1]); - }); - - xit('checksum',function() { - var luhn = new Luhn(4913); - expect(luhn.checksum).toEqual(22); - }); - - xit('checksum again',function() { - var luhn = new Luhn(201773); - expect(luhn.checksum).toEqual(21); + it('single digit strings can not be valid', function () { + const luhn = new Luhn('1'); + expect(luhn.valid).toEqual(false); }); - xit('invalid number',function() { - var luhn = new Luhn(738); + xit('A single zero is invalid', function () { + const luhn = new Luhn('0'); expect(luhn.valid).toEqual(false); }); - xit('invalid number',function() { - var luhn = new Luhn(8739567); + xit('valid Canadian SIN', function () { + const luhn = new Luhn('046 454 286'); expect(luhn.valid).toEqual(true); }); - xit('create valid number',function() { - var number = Luhn.create(123); - expect(number).toEqual(1230); + xit('invalid Canadian SIN', function () { + const luhn = new Luhn('046 454 287'); + expect(luhn.valid).toEqual(false); }); - xit('create other valid number',function() { - var number = Luhn.create(873956); - expect(number).toEqual(8739567); + xit('invalid credit card', function () { + const luhn = new Luhn('8273 1232 7352 0569'); + expect(luhn.valid).toEqual(false); }); - xit('create yet another valid number',function() { - var number = Luhn.create(837263756); - expect(number).toEqual(8372637564); + xit('valid strings with a non-digit added become invalid', function () { + const luhn = new Luhn('046a 454 286'); + expect(luhn.valid).toEqual(false); }); }); From 86cbe9e5bfb1bbd0453d3a49ced52becf6011403 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Mon, 23 Jan 2017 11:36:04 -0500 Subject: [PATCH 092/272] update skeleton files to match exercise order --- exercises/{bob/bob.js => leap/leap.js} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename exercises/{bob/bob.js => leap/leap.js} (65%) diff --git a/exercises/bob/bob.js b/exercises/leap/leap.js similarity index 65% rename from exercises/bob/bob.js rename to exercises/leap/leap.js index cc8b471e..fff18671 100644 --- a/exercises/bob/bob.js +++ b/exercises/leap/leap.js @@ -3,12 +3,12 @@ // convenience to get you started writing code faster. // -var Bob = function() {}; +var Year = function() {}; -Bob.prototype.hey = function(input) { +Year.prototype.isLeap = function(input) { // // YOUR CODE GOES HERE // }; -module.exports = Bob; +module.exports = Year; From 0a436bc3aedcbb337d5a74ce90afd8b47d4cf6c7 Mon Sep 17 00:00:00 2001 From: Ahmed Ossama Date: Mon, 30 Jan 2017 13:05:52 +0400 Subject: [PATCH 093/272] Add 2 new test cases to check invalid input --- exercises/rna-transcription/example.js | 1 + .../rna-transcription/rna-transcription.spec.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/exercises/rna-transcription/example.js b/exercises/rna-transcription/example.js index 23417842..8198ac20 100644 --- a/exercises/rna-transcription/example.js +++ b/exercises/rna-transcription/example.js @@ -11,6 +11,7 @@ var dnaToRna = { var transcribeDna = function(dna, lookupTable) { return dna.replace(/./g, function(dnaNucleotide) { + if (!(dnaNucleotide in lookupTable)) { throw Error('Invalid input'); } return lookupTable[dnaNucleotide]; }); } diff --git a/exercises/rna-transcription/rna-transcription.spec.js b/exercises/rna-transcription/rna-transcription.spec.js index 7c52aafe..0306d2a4 100644 --- a/exercises/rna-transcription/rna-transcription.spec.js +++ b/exercises/rna-transcription/rna-transcription.spec.js @@ -23,4 +23,16 @@ describe('toRna()', function() { expect(dnaTranscriber.toRna('ACGTGGTCTTAA')) .toEqual('UGCACCAGAAUU'); }); + + xit('correctly handles completely invalid input', function () { + expect(function () { dnaTranscriber.toRna('XXX') }).toThrow( + new Error('Invalid input') + ); + }); + + xit('correctly handles partially invalid input', function () { + expect(function () { dnaTranscriber.toRna('ACGTXXXCTTAA') }).toThrow( + new Error('Invalid input') + ); + }); }); From e25738ec5e8f41e8461b5fc4d9b8b973e181a6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Wed, 1 Feb 2017 22:24:55 +0100 Subject: [PATCH 094/272] Move unicode problems up the list in `config.json` Word Count problem is moved to position 20th, because it introduces users to a Unicode complex problem. Bob problem, although likely dealing with Unicode subjects, is kept because it can be reasonably solved without knowing too much about Unicode. Pangram is moved just before Bob. Topics are configured in `config.json` for all three problems. Addresses #321 --- config.json | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/config.json b/config.json index 41f17a67..87dfd955 100644 --- a/config.json +++ b/config.json @@ -100,19 +100,32 @@ ] }, { - "slug": "bob", + "slug": "pangram", "difficulty": 1, "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Lists", + "Strings", + "Maps", + "Algorithms", + "Searching" ] }, { - "slug": "gigasecond", + "slug": "bob", "difficulty": 1, "topics": [ + "Control flow (conditionals)", + "Polymorfism", + "Strings", + "Unicode", + "Pattern recognition", + "Regular expressions" ] }, { - "slug": "word-count", + "slug": "gigasecond", "difficulty": 1, "topics": [ ] @@ -123,12 +136,6 @@ "topics": [ ] }, - { - "slug": "pangram", - "difficulty": 1, - "topics": [ - ] - }, { "slug": "beer-song", "difficulty": 1, @@ -195,6 +202,17 @@ "topics": [ ] }, + { + "slug": "word-count", + "difficulty": 1, + "topics": [ + "Control flow (loops)", + "Lists", + "Strings", + "Unicode", + "Regular expressions" + ] + }, { "slug": "acronym", "difficulty": 1, From 2ed6399267a78ba79a246eee309152dc3f8f4955 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Mon, 6 Feb 2017 06:30:27 -0500 Subject: [PATCH 095/272] Update leap comment --- exercises/leap/leap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/leap/leap.js b/exercises/leap/leap.js index fff18671..671681ed 100644 --- a/exercises/leap/leap.js +++ b/exercises/leap/leap.js @@ -1,5 +1,5 @@ // -// This is only a SKELETON file for the "Bob" exercise. It's been provided as a +// This is only a SKELETON file for the "Leap" exercise. It's been provided as a // convenience to get you started writing code faster. // From f2d8466ee6ffb53da62d27c858eb185b0e298867 Mon Sep 17 00:00:00 2001 From: Cody Tatman Date: Fri, 17 Feb 2017 10:13:19 -0800 Subject: [PATCH 096/272] Robot-simulator: require throwing exception --- exercises/robot-simulator/example.js | 9 ++++++++- exercises/robot-simulator/robot-simulator.spec.js | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/exercises/robot-simulator/example.js b/exercises/robot-simulator/example.js index 019f4b92..a6afc151 100644 --- a/exercises/robot-simulator/example.js +++ b/exercises/robot-simulator/example.js @@ -10,6 +10,13 @@ Robot.prototype.at = function (xcoord, ycoord) { }; Robot.prototype.orient = function (direction) { + if (direction != 'north' && + direction != 'south' && + direction != 'east' && + direction != 'west') { + throw 'Invalid Robot Bearing' + } + this.bearing = direction; return 'The robot is pointed ' + direction; }; @@ -78,4 +85,4 @@ Robot.prototype.evaluate = function (s) { }, this); }; -module.exports = Robot; \ No newline at end of file +module.exports = Robot; diff --git a/exercises/robot-simulator/robot-simulator.spec.js b/exercises/robot-simulator/robot-simulator.spec.js index e4338654..a94b1446 100644 --- a/exercises/robot-simulator/robot-simulator.spec.js +++ b/exercises/robot-simulator/robot-simulator.spec.js @@ -14,11 +14,11 @@ describe('Robot', function() { }); xit('invalid robot bearing', function() { - try { + var incorrectlyOrientRobot = function () { robot.orient('crood'); - } catch(exception) { - expect(exception).toEqual('Invalid Robot Bearing'); - } + }; + + expect(incorrectlyOrientRobot).toThrow(new Error('Invalid Robot Bearing')); }); xit('turn right from north', function() { From c5b3e5ab41a48d4c122dc0623026b797df717c46 Mon Sep 17 00:00:00 2001 From: Matt Baker Date: Thu, 2 Mar 2017 23:24:24 -0700 Subject: [PATCH 097/272] add more tests to drive towards complete solution --- exercises/phone-number/phone-number.spec.js | 24 +++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/exercises/phone-number/phone-number.spec.js b/exercises/phone-number/phone-number.spec.js index 3326677f..c19d4f3d 100644 --- a/exercises/phone-number/phone-number.spec.js +++ b/exercises/phone-number/phone-number.spec.js @@ -11,13 +11,23 @@ describe('PhoneNumber()', function() { expect(phone.number()).toEqual('1234567890'); }); + xit('cleans some other number with dots', function() { + var phone = new PhoneNumber('555.456.7890'); + expect(phone.number()).toEqual('5554567890'); + }); + xit('valid when 11 digits and first digit is 1', function() { var phone = new PhoneNumber('11234567890'); expect(phone.number()).toEqual('1234567890'); }); - xit('invalid when 11 digits', function() { - var phone = new PhoneNumber('21234567890'); + xit('invalid when 11 digits and the first digit is NOT 1', function() { + var phone = new PhoneNumber('2 1234567890'); + expect(phone.number()).toEqual('0000000000'); + }); + + xit('invalid when 12 digits', function() { + var phone = new PhoneNumber('991234567890'); expect(phone.number()).toEqual('0000000000'); }); @@ -31,8 +41,18 @@ describe('PhoneNumber()', function() { expect(phone.areaCode()).toEqual('123'); }); + xit('has some other area code', function() { + var phone = new PhoneNumber('5554567890'); + expect(phone.areaCode()).toEqual('555'); + }); + xit('formats a number', function() { var phone = new PhoneNumber('1234567890'); expect(phone.toString()).toEqual('(123) 456-7890'); }); + + xit('formats some other number', function() { + var phone = new PhoneNumber('5554567890'); + expect(phone.toString()).toEqual('(555) 456-7890'); + }); }); From ba516c626837e895bec4cfe662d72ee233e2de15 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 19 Mar 2017 01:12:22 +0000 Subject: [PATCH 098/272] SVG for badge instead of PNG --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d46072a5..6ab0fc05 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# xJavaScript [![Build Status](https://travis-ci.org/exercism/xjavascript.png?branch=master)](https://travis-ci.org/exercism/xjavascript) +# xJavaScript [![Build Status](https://travis-ci.org/exercism/xjavascript.svg?branch=master)](https://travis-ci.org/exercism/xjavascript) Exercism exercises in JavaScript From 8c9cd4e63503b7287c4123c1f794f698097acadd Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 19 Mar 2017 01:12:22 +0000 Subject: [PATCH 099/272] Include basic commands about how to fetch exercises This PR improves a little bit the documentation about how to run tests by including a couple of basic commands about how to fetch exercises as it was discussed on https://github.com/exercism/xjavascript/pull/297#issuecomment-237935748 Adds some changes related to #289 Fix some typos --- docs/TESTS.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index a8f2e601..d3bf65ce 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,4 +1,12 @@ -After configuring `exercism` command-line client and fetching your first JavaScript exercise (see [command-line interface overview](http://exercism.io/cli)) is time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine-node` command you should have installed on *Installing JavaScript* step: +After configuring `exercism` command-line client you can fetch the very next exercise + + exercism fetch javascript + +or you can fetch a specific exercise, passing the exercise name after the language. For example, to fetch the `bob` exercise: + + exercism fetch javascript bob + +Now, it's time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine-node` command you should have installed on the *Installing JavaScript* step: cd ~/exercism/javascript/bob jasmine-node bob_test.spec.js From ef8714549f0a42fe136be5df1694a8b797e750c6 Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Tue, 21 Mar 2017 13:21:44 -0300 Subject: [PATCH 100/272] Add exercise perfect-numbers (#332) * Implement exercise perfect-numbers * Implemented perfect-numbers exercise. * Added semicolons and curly braces. * Removed the divisors module. * Updated config.json with the 'perfect-numbers' exercise info. * Updated config.json. Solved typo 'prefect-numbers' instead of 'perfect-numbers' * Updated config.json - Reordered perfect-numbers exercise. --- config.json | 7 ++ exercises/perfect-numbers/example.js | 67 ++++++++++++++++ .../perfect-numbers/perfect-numbers.spec.js | 79 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 exercises/perfect-numbers/example.js create mode 100644 exercises/perfect-numbers/perfect-numbers.spec.js diff --git a/config.json b/config.json index 87dfd955..39b7d996 100644 --- a/config.json +++ b/config.json @@ -11,6 +11,7 @@ "rna-transcription", "bob", "gigasecond", + "perfect-numbers", "word-count", "isogram", "pangram", @@ -201,6 +202,12 @@ "difficulty": 1, "topics": [ ] + }, + { + "slug": "perfect-numbers", + "difficulty": 1, + "topics": [ + ] }, { "slug": "word-count", diff --git a/exercises/perfect-numbers/example.js b/exercises/perfect-numbers/example.js new file mode 100644 index 00000000..5e98da18 --- /dev/null +++ b/exercises/perfect-numbers/example.js @@ -0,0 +1,67 @@ +'use strict'; + +var PerfectNumbers = function() { + +}; + +/** + * Calculate all the divisors for a given number and return them as an array. + * Note: the actual number is not include in the returned array. + */ +PerfectNumbers.prototype.getDivisors = function(number) { + + var i; + var divs = new Array(); + + // Accepts only natura numbers greater than 1. + if (number <= 1) { + return divs; + } + + // 1 always divides everyone! + divs.push(1); + + // Calculate the divisors up the the half of the number + 1 + for (i = 2; i <= number / 2; i++) { + + if (number % i === 0) { + divs.push(i); + } + } + + return divs; +}; + +PerfectNumbers.prototype.classify = function(number) { + + var i, sum, result; + + // Check if the input is valid + if (number <= 0) { + return 'Classification is only possible for natural numbers.'; + } + + // Factorize the current number. + var divsArray = this.getDivisors(number); + + // Sum the factors. + sum = 0; + for (i = 0; i < divsArray.length; i++) { + sum = sum + divsArray[i]; + } + + // Check if the number is perfect. + if (sum === number) { + result = 'perfect'; + } + else if (sum > number) { + result = 'abundant'; + } + else { + result = 'deficient'; + } + + return result; +}; + +module.exports = PerfectNumbers; diff --git a/exercises/perfect-numbers/perfect-numbers.spec.js b/exercises/perfect-numbers/perfect-numbers.spec.js new file mode 100644 index 00000000..4a9fe9d7 --- /dev/null +++ b/exercises/perfect-numbers/perfect-numbers.spec.js @@ -0,0 +1,79 @@ +var PerfectNumbers = require('./perfect-numbers'); + +describe('Exercise - Perfect Numbers', function() { + + var perfectNumbers; + + beforeEach(function () { + perfectNumbers = new PerfectNumbers(); + }); + + describe('Perfect Numbers', function() { + + it('Smallest perfect number is classified correctly', function() { + expect(perfectNumbers.classify(6)).toEqual('perfect'); + }); + + it('Medium perfect number is classified correctly', function() { + expect(perfectNumbers.classify(28)).toEqual('perfect'); + }); + + it('Large perfect number is classified correctly', function() { + expect(perfectNumbers.classify(33550336)).toEqual('perfect'); + }); + + }); + + describe('Abundant Numbers', function() { + + it('Smallest abundant number is classified correctly', function() { + expect(perfectNumbers.classify(12)).toEqual('abundant'); + }); + + it('Medium abundant number is classified correctly', function() { + expect(perfectNumbers.classify(30)).toEqual('abundant'); + }); + + it('Large abundant number is classified correctly', function() { + expect(perfectNumbers.classify(33550335)).toEqual('abundant'); + }); + + }); + + describe('Deficient Numbers', function() { + + it('Smallest prime deficient number is classified correctly', function() { + expect(perfectNumbers.classify(2)).toEqual('deficient'); + }); + + it('Smallest non-prime deficient number is classified correctly', function() { + expect(perfectNumbers.classify(4)).toEqual('deficient'); + }); + + it('Medium deficient number is classified correctly', function() { + expect(perfectNumbers.classify(32)).toEqual('deficient'); + }); + + it('Large deficient number is classified correctly', function() { + expect(perfectNumbers.classify(33550337)).toEqual('deficient'); + }); + + it('Edge case (no factors other than itself) is classified correctly', function() { + expect(perfectNumbers.classify(1)).toEqual('deficient'); + }); + + }); + + describe('Invalid Inputs', function() { + + it('Zero is rejected (not a natural number)', function() { + expect(perfectNumbers.classify(0)).toEqual('Classification is only possible for natural numbers.'); + }); + + it('Negative integer is rejected (not a natural number)', function() { + expect(perfectNumbers.classify(-1)).toEqual('Classification is only possible for natural numbers.'); + }); + + }); + +}); From 7fac112e71fc18206d2ef9211f142f92b0e65936 Mon Sep 17 00:00:00 2001 From: "J. Cheyo Jimenez" Date: Sun, 9 Apr 2017 05:49:02 -0700 Subject: [PATCH 101/272] Update robot-name.spec.js (#336) https://github.com/exercism/x-common/issues/731 --- exercises/robot-name/robot-name.spec.js | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/exercises/robot-name/robot-name.spec.js b/exercises/robot-name/robot-name.spec.js index 2f9b4776..fb4de6a4 100644 --- a/exercises/robot-name/robot-name.spec.js +++ b/exercises/robot-name/robot-name.spec.js @@ -26,19 +26,6 @@ describe('Robot', function() { expect(differentRobot.name).not.toEqual(robot.name); }); - xit('there can be lots of robots with different names each', function() { - var i, - numRobots = 10000, - usedNames = {}; - - for (i = 0; i < numRobots; i++) { - var newRobot = new Robot(); - usedNames[newRobot.name] = true; - } - - expect(Object.keys(usedNames).length).toEqual(numRobots); - }); - xit('is able to reset the name', function() { var originalName = robot.name; robot.reset(); @@ -61,4 +48,18 @@ describe('Robot', function() { expect(Object.keys(usedNames).length).toEqual(numResets + 1); }); + + //This test is optional. + xit('there can be lots of robots with different names each', function() { + var i, + numRobots = 10000, + usedNames = {}; + + for (i = 0; i < numRobots; i++) { + var newRobot = new Robot(); + usedNames[newRobot.name] = true; + } + + expect(Object.keys(usedNames).length).toEqual(numRobots); + }); }); From ec7a6d39ad2d60ea23dd2824586c592037991b4f Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Tue, 11 Apr 2017 12:25:59 +0530 Subject: [PATCH 102/272] Add empty stale.yml file for probot Closes #335 --- .github/stale.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..e69de29b From 8582b9c199352aaaf53d92abff5aa87fd3ff81d6 Mon Sep 17 00:00:00 2001 From: jeffreydking04 Date: Sun, 16 Apr 2017 04:43:07 -0700 Subject: [PATCH 103/272] Edit leap year stub to be consistent with tests (#338) * Edit leap year stub to be consistent with tests * add HINT.md * Add markdown --- exercises/leap/HINT.md | 52 ++++++++++++++++++++++++++++++++++++++++++ exercises/leap/leap.js | 8 +++++-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 exercises/leap/HINT.md diff --git a/exercises/leap/HINT.md b/exercises/leap/HINT.md new file mode 100644 index 00000000..51330c1f --- /dev/null +++ b/exercises/leap/HINT.md @@ -0,0 +1,52 @@ +This is the first test for this exercise: + +```javascript + it('is not very common', function() { + var year = new Year(2015); + expect(year.isLeap()).toBe(false); + }); +``` + +Each test in the exercise follows the same pattern: + + 1. A new Year is instantiated with a value and stored in a variable: year. + 2. The test calls an instance method, isLeap(), from the variable `year`. + +The `Year` function is a constructor, which means that it is specifically designed to provide a template for new objects. + +When a new `Year` object is created: + +```javascript + var year = new Year(2015); +``` + +We expect `year` to, at the very least, have a specific value (in this case 2015) assigned to it. Otherwise it would not represent an actual year. + +This means that we must store the value passed as a parameter when the new `Year` is created (2015), so that the new `Year` can access it. + +The way a constructor stores these fundamental values (instance variables) is like this: + +```javascript + var Constructor = function(input) { + this.value = input; + }; +``` + +The `this` in the constructor refers to the newly created instance of the `Constructor`. + +Once the input (parameter) is stored in an instance variable, any instance methods, such as: + +```javascript + Constructor.prototype.instanceMethod = function() { + // this method can now access the input by calling `this.value` + }; +``` + +The instance method accesses the input using `this.value` (in this example). + +This is why code needs to be written in two separate functions: + + 1. The first function, `Year`, is a constructor that serves as a template for year objects that are created with their value (such as 2015). + This function needs to store the input when a new `Year` is created. + 2. The second function, isLeap(), is an instance method that is called from a new `year`. + This function (method) should contain the logic to determine if the given year is a leap year. \ No newline at end of file diff --git a/exercises/leap/leap.js b/exercises/leap/leap.js index 671681ed..e3795c57 100644 --- a/exercises/leap/leap.js +++ b/exercises/leap/leap.js @@ -3,9 +3,13 @@ // convenience to get you started writing code faster. // -var Year = function() {}; +var Year = function(input) { +// +// YOUR CODE GOES HERE +// +}; -Year.prototype.isLeap = function(input) { +Year.prototype.isLeap = function() { // // YOUR CODE GOES HERE // From 551ce5ae139c14973f6c23cc0ee1c309e6ce3f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Sun, 23 Apr 2017 11:05:47 -0300 Subject: [PATCH 104/272] Hamming exercise example refactoring (#343) See #342 --- exercises/hamming/example.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/exercises/hamming/example.js b/exercises/hamming/example.js index 69a83516..731d0ba9 100644 --- a/exercises/hamming/example.js +++ b/exercises/hamming/example.js @@ -1,23 +1,19 @@ function Hamming() {} Hamming.prototype.compute = function (strand1, strand2) { - var len1 = strand1.length; - var len2 = strand2.length; - - if (len1 !== len2) { + if (strand1.length !== strand2.length) { throw new Error('DNA strands must be of equal length.'); } - var out = -0; - var idx = -1; - var end = Math.max(len1, len2); + var distance = 0; - while (++idx < end) { - if (strand1[idx] !== strand2[idx]) out++; + for (var i = 0; i < strand1.length; i++) { + if (strand1[i] !== strand2[i]) { + distance++; + } } - return out; + return distance; }; module.exports = Hamming; - From 7c5f8b07614ef3437a9d7fbddc613e7d9ffe4c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Sun, 23 Apr 2017 14:52:26 -0300 Subject: [PATCH 105/272] Robot Simulator example refactoring (#344) --- exercises/robot-simulator/example.js | 145 +++++++++++++-------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/exercises/robot-simulator/example.js b/exercises/robot-simulator/example.js index a6afc151..bca213ad 100644 --- a/exercises/robot-simulator/example.js +++ b/exercises/robot-simulator/example.js @@ -1,88 +1,87 @@ -'use strict'; +var Robot = (function () { + 'use strict'; -var Robot = function () { - this.coordinates = [0, 0]; - this.bearing = 'north'; -}; - -Robot.prototype.at = function (xcoord, ycoord) { - this.coordinates = [xcoord, ycoord]; -}; - -Robot.prototype.orient = function (direction) { - if (direction != 'north' && - direction != 'south' && - direction != 'east' && - direction != 'west') { - throw 'Invalid Robot Bearing' + var VALID_DIRECTIONS = ['north', 'east', 'south', 'west'] + var INSTRUCTION_KEYS = { + A: 'advance', + L: 'turnLeft', + R: 'turnRight' } - this.bearing = direction; - return 'The robot is pointed ' + direction; -}; + function Robot () { + this.coordinates = [0, 0]; + this.bearing = 'north'; + }; -Robot.prototype.advance = function () { + Robot.prototype.at = function (x, y) { + this.coordinates = [x, y]; + }; - if (this.bearing === 'north') { - this.coordinates[1] += 1; - } else if (this.bearing === 'south') { - this.coordinates[1] -= 1; - } else if (this.bearing === 'east') { - this.coordinates[0] += 1; - } else if (this.bearing === 'west') { - this.coordinates[0] -= 1; - } -}; + Robot.prototype.orient = function (direction) { + if (VALID_DIRECTIONS.indexOf(direction) === -1) { + throw new Error('Invalid Robot Bearing'); + } -Robot.prototype.turnLeft = function () { + this.bearing = direction; + }; - if (this.bearing === 'north') { - this.orient('west'); - } else if (this.bearing === 'south') { - this.orient('east'); - } else if (this.bearing === 'east') { - this.orient('north'); - } else if (this.bearing === 'west') { - this.orient('south'); - } -}; + Robot.prototype.advance = function () { + switch (this.bearing) { + case 'north': + this.coordinates[1]++; + break; + case 'east': + this.coordinates[0]++; + break; + case 'south': + this.coordinates[1]--; + break; + case 'west': + this.coordinates[0]--; + break; + }; + }; -Robot.prototype.turnRight = function () { + Robot.prototype.turnLeft = function () { + var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); - if (this.bearing === 'north') { - this.orient('east'); - } else if (this.bearing === 'south') { - this.orient('west'); - } else if (this.bearing === 'east') { - this.orient('south'); - } else if (this.bearing === 'west') { - this.orient('north'); - } -}; + if (directionPosition > 0) { + this.orient(VALID_DIRECTIONS[--directionPosition]); + } else { + this.orient(VALID_DIRECTIONS[VALID_DIRECTIONS.length - 1]); + } + }; + + Robot.prototype.turnRight = function () { + var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); -Robot.prototype.instructions = function (s) { - var result = []; - s.split('').forEach(function (character) { - if (character === 'L') { - result.push('turnLeft'); - } else if (character === 'R') { - result.push('turnRight'); - } else if (character === 'A') { - result.push('advance'); + if (directionPosition < (VALID_DIRECTIONS.length - 1)) { + this.orient(VALID_DIRECTIONS[++directionPosition]); + } else { + this.orient(VALID_DIRECTIONS[0]); } - }); - return result; -}; + }; + + Robot.prototype.instructions = function (instructionKeys) { + return instructionKeys.split('') + .map(function (key) { + return INSTRUCTION_KEYS[key]; + }); + }; + + Robot.prototype.place = function (args) { + this.coordinates = [args.x, args.y]; + this.bearing = args.direction; + }; -Robot.prototype.place = function (args) { - this.coordinates = [args.x, args.y]; - this.bearing = args.direction; -}; + Robot.prototype.evaluate = function (instructionKeys) { + this.instructions(instructionKeys) + .forEach(function (instruction) { + this[instruction](); + }, this); + }; -Robot.prototype.evaluate = function (s) { - this.instructions(s).forEach(function (instruction) { - this[instruction](); - }, this); -}; + return Robot +})() module.exports = Robot; From 1cdbf80f6fb5c7c6f508907847cb2e5b45b1c0cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Sun, 23 Apr 2017 15:04:00 -0300 Subject: [PATCH 106/272] Update testing instructions on all exercises (#342) According to discussions in #341 we'll use Jasmine as a command line tool, globally installed through npm, and the testing command should now look like `jasmine ./test-file.spec.js`. Closes #341 --- Makefile | 3 +-- SETUP.md | 3 +-- docs/INSTALLATION.md | 7 +++---- docs/TESTS.md | 4 ++-- exercises/acronym/package.json | 2 +- exercises/hello-world/HINTS.md | 6 +++--- package.json | 2 +- 7 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 63579552..dbf00621 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,7 @@ test-assignment: node_modules @cp exercises/$(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(subst _,-,$(ASSIGNMENT)).$(FILEEXT) #@sed -i.original 's/\bxit\b/it/g' $(OUTDIR)/*spec.$(FILEEXT) @sed 's/xit/it/g' exercises/$(ASSIGNMENT)/$(TSTFILE) > $(OUTDIR)/$(TSTFILE) - @./node_modules/.bin/jasmine-node --captureExceptions $(OUTDIR)/$(TSTFILE) + @./node_modules/.bin/jasmine --captureExceptions $(OUTDIR)/$(TSTFILE) test: @for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) -s test-assignment || exit 1; done - diff --git a/SETUP.md b/SETUP.md index 65157035..e0b3166e 100644 --- a/SETUP.md +++ b/SETUP.md @@ -9,10 +9,9 @@ http://exercism.io/languages/javascript Execute the tests with: - jasmine-node . + jasmine . In many test suites all but the first test have been skipped. Once you get a test passing, you can unskip the next one by changing `xit` to `it`. - diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 802b696b..8bdd35a7 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -15,15 +15,14 @@ If you are using a different distribution or package manager, you can find a com ## Installing additional tools -The next step is to install `jasmine-node` globally so that you can run JavaScript tests: +The next step is to install [Jasmine](https://jasmine.github.io/) globally so that you can run JavaScript tests: - npm install jasmine-node -g + npm install -g jasmine Depending on your setup, you may need super user privileges to install an `npm` module globally. This is the case if you've used the official installer linked to above. If `npm` gives you an error saying you don't have access, add `sudo` to the command above: - sudo npm install jasmine-node -g + sudo npm install -g jasmine 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 your `PATH` to include the `npm` binaries by adding the following to either `~/.bash_profile` or `~/.zshrc`: export PATH=/usr/local/share/npm/bin:$PATH - diff --git a/docs/TESTS.md b/docs/TESTS.md index d3bf65ce..a87fa911 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -6,10 +6,10 @@ or you can fetch a specific exercise, passing the exercise name after the langua exercism fetch javascript bob -Now, it's time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine-node` command you should have installed on the *Installing JavaScript* step: +Now, it's time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine` command you should have installed on the *Installing JavaScript* step: cd ~/exercism/javascript/bob - jasmine-node bob_test.spec.js + jasmine bob_test.spec.js *Note that `~/exercism` is the default folder for `EXERCISM_HOME_DIR`. Be sure you use your configured folder for it* diff --git a/exercises/acronym/package.json b/exercises/acronym/package.json index c909c3ce..ed3249c4 100644 --- a/exercises/acronym/package.json +++ b/exercises/acronym/package.json @@ -7,6 +7,6 @@ "test": "make test" }, "devDependencies": { - "jasmine-node": "*" + "jasmine": "*" } } diff --git a/exercises/hello-world/HINTS.md b/exercises/hello-world/HINTS.md index ebed1f4b..ab50f8a9 100644 --- a/exercises/hello-world/HINTS.md +++ b/exercises/hello-world/HINTS.md @@ -24,7 +24,7 @@ This is the first test: Run the test now, with the following command on the command-line: - jasmine-node . + jasmine . The test fails, which makes sense since you've not written any code yet. @@ -76,7 +76,7 @@ Try changing the function in hello-world.js so that it says Then run the tests again from the command-line: - jasmine-node . + jasmine . Notice how it changes the failure message. @@ -89,7 +89,7 @@ Once the test is passing, look at the second test in hello-world.spec.js. It loo }); This test starts with `xit` instead of `it`. -That means that when jasmine-node runs the tests, +That means that when Jasmine runs the tests, the test will be skipped. Change the test so that it starts with `it`, diff --git a/package.json b/package.json index c909c3ce..ed3249c4 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,6 @@ "test": "make test" }, "devDependencies": { - "jasmine-node": "*" + "jasmine": "*" } } From 6bef13b7c09ec0a182c3d373a414aac442d4724f Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Tue, 25 Apr 2017 19:33:35 +0530 Subject: [PATCH 107/272] [ci skip] Cleanup testing doc (#345) * Mention about skipped tests in the testing doc * Remove the content about fetching and exporting modules since it does not belong to this doc. * Mention about linting section being optional * Mention about visual studio section being specific to that editor and can be skipped otherwise. --- docs/TESTS.md | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index a87fa911..34003c4b 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,37 +1,23 @@ -After configuring `exercism` command-line client you can fetch the very next exercise +With the first few exercises, you will get a skeleton file with the exported modules. +For later ones, you can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). - exercism fetch javascript - -or you can fetch a specific exercise, passing the exercise name after the language. For example, to fetch the `bob` exercise: - - exercism fetch javascript bob - -Now, it's time to run some tests. Move to the folder where that exercise's files are located (a path similar to `//`) and run the tests with the `jasmine` command you should have installed on the *Installing JavaScript* step: +For running tests, install `jasmine` as described in the [Installing Javascript section](http://exercism.io/languages/javascript/installing). +Move to the folder where that exercise's files are located (a path similar to /javascript/). cd ~/exercism/javascript/bob jasmine bob_test.spec.js -*Note that `~/exercism` is the default folder for `EXERCISM_HOME_DIR`. Be sure you use your configured folder for it* - -## Making Your First Node Module - -To create a module that can be loaded with `var Bob = require('./bob.js');`, put this code in `bob.js`: +Only the first test will be executed, all the others have been marked pending using `xit` or `xdescribe`. +As you keep solving the exercise, one by one change all `xit` and `xdescribe` to `it` and `describe` respectively to run all the tests. +See [Test Driven Development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development) to know more about this approach. +When all tests pass, you are ready to submit! - var Bob = function() {}; - - Bob.prototype.hey = function(what) { - // - // Your solution to the exercise goes here - // - }; - - module.exports = Bob; - -You can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). To make it easier to get started, there's a "skeleton" bob.js file in the directory -for the first exercise. ## Visual Studio on Windows +You can use any editor of your choice to write javascript. Here are just some instructions for using and running tests in `Visual Studio`. +You are free to skip this section if you are not using `Visual Studio` on `Windows`. + Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx). This will include the IDE and web development tools. To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. @@ -67,6 +53,8 @@ If you do not see any output from running the tests, you are likely not in a Nod ## Setting Up a Linter +** Note: This section is completely optional ** + A linter is like a tester for your code's style and formatting. In some languages there are many acceptable styles, and using a linter allows you to be internally consistent (e.g. Ruby), or adhere to one of many common styles. In other languages there are fewer choices, and a linter allows programmers to look at code from a great variety of sources and still feel at home (e.g. Go). You can read more [here](https://en.wikipedia.org/wiki/Lint_(software)). The old standard linter for JavaScript is [JSLint](http://jslint.com). However, it is controversially picky. [JSHint](http://jshint.com) is another popular linter. We suggest using [ESLint](http://eslint.org), which is more customizable than either JSLint or JSHint, and is well-run. From f4f96ab8a23006229cafe7187ebdb7e358592192 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Wed, 26 Apr 2017 17:59:35 +0530 Subject: [PATCH 108/272] Remove package.json (#347) Rely on global jasmine installation to run tests everywhere. Even in CI. --- .travis.yml | 4 +++- Makefile | 9 ++------- exercises/acronym/package.json | 12 ------------ package.json | 12 ------------ 4 files changed, 5 insertions(+), 32 deletions(-) delete mode 100644 exercises/acronym/package.json delete mode 100644 package.json diff --git a/.travis.yml b/.travis.yml index 248618cf..9312e714 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,10 @@ sudo: false node_js: - 5.7 +install: + - "npm install -g jasmine" + script: - "make test" - "./bin/fetch-configlet" - "./bin/configlet ." - diff --git a/Makefile b/Makefile index dbf00621..ff81ce3a 100644 --- a/Makefile +++ b/Makefile @@ -12,19 +12,14 @@ FILEEXT := "js" EXAMPLE := "example.$(FILEEXT)" TSTFILE := "$(subst _,-,$(ASSIGNMENT)).spec.$(FILEEXT)" -# development dependencies -node_modules: package.json - @npm prune - @npm install - -test-assignment: node_modules +test-assignment: @echo "running tests for: $(ASSIGNMENT)" @cp big-integer.$(FILEEXT) $(OUTDIR) @cp exercises/$(ASSIGNMENT)/$(TSTFILE) $(OUTDIR) @cp exercises/$(ASSIGNMENT)/$(EXAMPLE) $(OUTDIR)/$(subst _,-,$(ASSIGNMENT)).$(FILEEXT) #@sed -i.original 's/\bxit\b/it/g' $(OUTDIR)/*spec.$(FILEEXT) @sed 's/xit/it/g' exercises/$(ASSIGNMENT)/$(TSTFILE) > $(OUTDIR)/$(TSTFILE) - @./node_modules/.bin/jasmine --captureExceptions $(OUTDIR)/$(TSTFILE) + @jasmine --random=true $(OUTDIR)/$(TSTFILE) test: @for assignment in $(ASSIGNMENTS); do ASSIGNMENT=$$assignment $(MAKE) -s test-assignment || exit 1; done diff --git a/exercises/acronym/package.json b/exercises/acronym/package.json deleted file mode 100644 index ed3249c4..00000000 --- a/exercises/acronym/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "javascript", - "version": "0.0.0", - "description": "JavaScript assignments", - "private": true, - "scripts": { - "test": "make test" - }, - "devDependencies": { - "jasmine": "*" - } -} diff --git a/package.json b/package.json deleted file mode 100644 index ed3249c4..00000000 --- a/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "javascript", - "version": "0.0.0", - "description": "JavaScript assignments", - "private": true, - "scripts": { - "test": "make test" - }, - "devDependencies": { - "jasmine": "*" - } -} From 08bcf616947d542a3a567eb0851cfda1c341a7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20ARNAUD?= Date: Thu, 27 Apr 2017 14:51:41 +0200 Subject: [PATCH 109/272] Adds jasmine specs for proverb exercise (#346) Adds example solution for proverb exercise Adds proverb exercise to the config file Makes the code emphasizes ES5 --- config.json | 9 ++++ exercises/proverb/example.js | 36 ++++++++++++++ exercises/proverb/proverb.spec.js | 78 +++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 exercises/proverb/example.js create mode 100644 exercises/proverb/proverb.spec.js diff --git a/config.json b/config.json index 39b7d996..98ec8681 100644 --- a/config.json +++ b/config.json @@ -48,6 +48,7 @@ "series", "difference-of-squares", "secret-handshake", + "proverb", "linked-list", "wordy", "flatten-array", @@ -352,6 +353,14 @@ "topics": [ ] }, + { + "slug": "proverb", + "difficulty": 1, + "topics": [ + "Arrays", + "Optional values" + ] + }, { "slug": "linked-list", "difficulty": 1, diff --git a/exercises/proverb/example.js b/exercises/proverb/example.js new file mode 100644 index 00000000..1600e3e4 --- /dev/null +++ b/exercises/proverb/example.js @@ -0,0 +1,36 @@ +module.exports = function(){ + var last = arguments[arguments.length - 1]; + var chain = Array.from(arguments); + this.options = {}; + + if(typeof last == "object" && last.hasOwnProperty("qualifier")){ + this.options = chain.pop(); + } + + this.chain = chain; + this.qualifier = this.options.qualifier ? this.options.qualifier + ' ' : ''; + + this.toString = function(){ + return this.chainOfEvents() + this.conclusion(); + }.bind(this); + + this.chainOfEvents = function(){ + return this.causesAndEffects().map( function(entry){ + return "For want of a " + entry.cause + + " the " + entry.effect + " was lost.\n"; + }.bind(this) ).join(''); + }.bind(this); + + this.causesAndEffects = function(){ + return this.chain.reduce( function(array, event, index){ + if(index < this.chain.length - 1){ + array.push({ cause: event, effect: this.chain[index + 1] }); + } + return array; + }.bind(this), [] ); + }.bind(this); + + this.conclusion = function(){ + return "And all for the want of a " + this.qualifier + this.chain[0] + "."; + }.bind(this); +}; diff --git a/exercises/proverb/proverb.spec.js b/exercises/proverb/proverb.spec.js new file mode 100644 index 00000000..8ee75647 --- /dev/null +++ b/exercises/proverb/proverb.spec.js @@ -0,0 +1,78 @@ +var Proverb = require('./proverb'); + +describe('Proverb Test Suite', function() { + it('tests a single consequence', function() { + var proverb = new Proverb('nail', 'shoe'); + + expect(proverb.toString()).toEqual( + "For want of a nail the shoe was lost.\n" + + "And all for the want of a nail."); + }); + + + it('tests a short chain of consequences', function() { + var proverb = new Proverb('nail', 'shoe', 'horse'); + + expect(proverb.toString()).toEqual( + "For want of a nail the shoe was lost.\n" + + "For want of a shoe the horse was lost.\n" + + "And all for the want of a nail."); + }); + + it('tests a longer chain of consequences', function() { + var proverb = new Proverb('nail', 'shoe', 'horse', 'rider'); + + expect(proverb.toString()).toEqual( + "For want of a nail the shoe was lost.\n" + + "For want of a shoe the horse was lost.\n" + + "For want of a horse the rider was lost.\n" + + "And all for the want of a nail."); + }); + + + it('tests Proverb class does not hard code the rhyme dictionary', + function() { + var proverb = new Proverb('key', 'value'); + + expect(proverb.toString()).toEqual( + "For want of a key the value was lost.\n" + + "And all for the want of a key."); + }); + + it('tests the whole proveb', function() { + var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom'); + + expect(proverb.toString()).toEqual( + "For want of a nail the shoe was lost.\n" + + "For want of a shoe the horse was lost.\n" + + "For want of a horse the rider was lost.\n" + + "For want of a rider the message was lost.\n" + + "For want of a message the battle was lost.\n" + + "For want of a battle the kingdom was lost.\n" + + "And all for the want of a nail."); + }); + + + it('tests the use of an optional qualifier in the final consequence', + function() { + var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom', + { qualifier: 'horseshoe' }); + + expect(proverb.toString()).toEqual( + "For want of a nail the shoe was lost.\n" + + "For want of a shoe the horse was lost.\n" + + "For want of a horse the rider was lost.\n" + + "For want of a rider the message was lost.\n" + + "For want of a message the battle was lost.\n" + + "For want of a battle the kingdom was lost.\n" + + "And all for the want of a horseshoe nail."); + }); + + it('tests the proverb is the same each time', function(){ + var proverb = new Proverb('nail', 'shoe'); + + expect(proverb.toString()).toEqual(proverb.toString()); + }); +}); From e5d82cfca232c82471213aa9cb27a5a6392e6433 Mon Sep 17 00:00:00 2001 From: Alex Harms Date: Tue, 2 May 2017 06:38:08 -0400 Subject: [PATCH 110/272] Add info about how to install Javascript (#348) * Add info about how to install Javascript * Clarify why install instructions are needed. * Improve words. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6ab0fc05..ba4ec099 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ Exercism exercises in JavaScript +## Installing + +To run the tests, you'll need NodeJS and Jasmine. For information about how to install these tools, see the [Javascript](http://exercism.io/languages/javascript/about) page. + ## Running Unit Test Suite The following commands assume that you are in the 'xjavascript' directory: From 3b04fb47181a283f37ea7cf040dec6f32a0536f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Sun, 7 May 2017 10:50:29 -0300 Subject: [PATCH 111/272] Updates test instructions on Hello World's HINTS.md (#350) Closes #349 --- SETUP.md | 7 ++++++- exercises/hello-world/HINTS.md | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/SETUP.md b/SETUP.md index e0b3166e..00fd308e 100644 --- a/SETUP.md +++ b/SETUP.md @@ -9,7 +9,12 @@ http://exercism.io/languages/javascript Execute the tests with: - jasmine . + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js In many test suites all but the first test have been skipped. diff --git a/exercises/hello-world/HINTS.md b/exercises/hello-world/HINTS.md index ab50f8a9..250d97f3 100644 --- a/exercises/hello-world/HINTS.md +++ b/exercises/hello-world/HINTS.md @@ -24,7 +24,7 @@ This is the first test: Run the test now, with the following command on the command-line: - jasmine . + jasmine hello-world.spec.js The test fails, which makes sense since you've not written any code yet. @@ -76,7 +76,7 @@ Try changing the function in hello-world.js so that it says Then run the tests again from the command-line: - jasmine . + jasmine hello-world.spec.js Notice how it changes the failure message. From cbfd5144f58745da0b91a8e478a2f5d7bb93172a Mon Sep 17 00:00:00 2001 From: morrme Date: Tue, 9 May 2017 17:08:07 -0500 Subject: [PATCH 112/272] TESTS.md: make image links relative (#352) * TESTS.md: make image links relative See #313 * Update TESTS.md --- docs/TESTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 34003c4b..fb0ce9a6 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -22,7 +22,7 @@ Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/p To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. -![Solution Explorer](http://x.exercism.io/v3/tracks/javascript/docs/img/SolutionExplorer.png) +![Solution Explorer](img/SolutionExplorer.png) 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` @@ -37,7 +37,7 @@ To get started, you can download a Visual Studio solution that is already set up 10. The exercise you just fetched will appear greyed out. Right click on the folder and **Include In Project** 11. Get coding... -![Add files](http://x.exercism.io/v3/tracks/javascript/docs/img/AddFiles.png) +![Add files](img/AddFiles.png) If you have a paid version of Visual Studio, you should install the [Web Essentials](http://vswebessentials.com/) extension. It will make working with Javascript much easier. From 34eb6113f862131a35e6528638261315ccae9be5 Mon Sep 17 00:00:00 2001 From: morrme Date: Wed, 10 May 2017 06:48:14 -0500 Subject: [PATCH 113/272] requested correction for relative link (#355) * TESTS.md: make image links relative See #313 * Update TESTS.md * Update TESTS.md --- docs/TESTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index fb0ce9a6..62b52fbf 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -22,7 +22,7 @@ Install [Visual Studio Express 2013 for web](http://www.visualstudio.com/en-us/p To get started, you can download a Visual Studio solution that is already set up to work with JavaScript and the other languages that Visual Studio supports. -![Solution Explorer](img/SolutionExplorer.png) +![Solution Explorer](/docs/img/SolutionExplorer.png) 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` @@ -37,7 +37,7 @@ To get started, you can download a Visual Studio solution that is already set up 10. The exercise you just fetched will appear greyed out. Right click on the folder and **Include In Project** 11. Get coding... -![Add files](img/AddFiles.png) +![Add files](/docs/img/AddFiles.png) If you have a paid version of Visual Studio, you should install the [Web Essentials](http://vswebessentials.com/) extension. It will make working with Javascript much easier. From 4b4ee543ebc9e79b7d90f04a3d7d213abed5068a Mon Sep 17 00:00:00 2001 From: Arthur Dean Date: Fri, 12 May 2017 04:52:57 -0700 Subject: [PATCH 114/272] Add the minesweeper exercise and test (#354) * Add the minesweeper exercise and test * Refactor example to improve code * Update config.json, fix formatting --- config.json | 14 +- exercises/minesweeper/example.js | 48 ++++++ exercises/minesweeper/minesweeper.spec.js | 182 ++++++++++++++++++++++ 3 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 exercises/minesweeper/example.js create mode 100644 exercises/minesweeper/minesweeper.spec.js diff --git a/config.json b/config.json index 98ec8681..8371dee0 100644 --- a/config.json +++ b/config.json @@ -11,7 +11,7 @@ "rna-transcription", "bob", "gigasecond", - "perfect-numbers", + "perfect-numbers", "word-count", "isogram", "pangram", @@ -74,7 +74,8 @@ "bowling", "diamond", "all-your-base", - "run-length-encoding" + "run-length-encoding", + "minesweeper" ], "exercises": [ { @@ -516,6 +517,15 @@ "difficulty": 1, "topics": [ ] + }, + { + "slug": "minesweeper", + "difficulty": 7, + "topics": [ + "games", + "arrays", + "algorithms" + ] } ], "deprecated": [ diff --git a/exercises/minesweeper/example.js b/exercises/minesweeper/example.js new file mode 100644 index 00000000..7bb5dbd0 --- /dev/null +++ b/exercises/minesweeper/example.js @@ -0,0 +1,48 @@ +var Minesweeper = function() { + this.distanceXdistanceYs = [ + [-1,-1], + [-1,0], + [-1,1], + + [1,1], + [1,0], + [1,-1], + + [0,1], + [0,-1] + + ] +}; + + +Minesweeper.prototype.annotate = function(rows) { + if (rows.length === 0 || rows[0].length === 0) { + return rows; + } + var board = rows.map(function(row) { return row.split(""); }); + var outBoard = []; + for (var x = 0; x < board.length; x++) { + outBoard[x] = []; + for (var y = 0; y < board[x].length; y++) { + var spot = board[x][y]; + if (spot === "*") { + outBoard[x][y] = spot; + continue; + } + var bombCount = this.distanceXdistanceYs.map(function(dxdy) { + if (board[x + dxdy[0]] === undefined) { + return 0; + } + return board[x + dxdy[0]][y + dxdy[1]] === "*" ? 1 : 0; + }).reduce(function(total, num) { + return total + num; + }); + outBoard[x][y] = bombCount > 0 ? bombCount : " "; + } + } + return outBoard.map(function(row) { + return row.join(""); + }); +}; + +module.exports = Minesweeper; diff --git a/exercises/minesweeper/minesweeper.spec.js b/exercises/minesweeper/minesweeper.spec.js new file mode 100644 index 00000000..75ffe741 --- /dev/null +++ b/exercises/minesweeper/minesweeper.spec.js @@ -0,0 +1,182 @@ +var Minesweeper = require('./minesweeper'); + +describe('Minesweeper()', function() { + + it('handles no rows', function() { + var minesweeper = new Minesweeper(); + expect(minesweeper.annotate([])).toEqual([]); + }); + + xit('handles no columns', function() { + var minesweeper = new Minesweeper(); + expect(minesweeper.annotate([""])).toEqual([""]); + }); + + xit('handles no mines', function() { + var minesweeper = new Minesweeper(); + var input = [ + " ", + " ", + " " + ]; + var expected = [ + " ", + " ", + " " + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles board with only mines', function() { + var minesweeper = new Minesweeper(); + var input = [ + "***", + "***", + "***" + ]; + var expected = [ + "***", + "***", + "***" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles mine surrounded by spaces', function() { + var minesweeper = new Minesweeper(); + var input = [ + " ", + " * ", + " " + ]; + var expected = [ + "111", + "1*1", + "111" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles space surrounded by mines', function() { + var minesweeper = new Minesweeper(); + var input = [ + "***", + "* *", + "***" + ]; + var expected = [ + "***", + "*8*", + "***" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles space surrounded by mines', function() { + var minesweeper = new Minesweeper(); + var input = [ + "***", + "* *", + "***" + ]; + var expected = [ + "***", + "*8*", + "***" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles horizontal line', function() { + var minesweeper = new Minesweeper(); + var input = [" * * "]; + var expected = ["1*2*1"]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles horizontal line, mines at edges',function() { + var minesweeper = new Minesweeper(); + var input = ["* *"]; + var expected = ["*1 1*"]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles vertical line', function() { + var minesweeper = new Minesweeper(); + var input = [ + " ", + "*", + " ", + "*", + " " + ]; + var expected = [ + "1", + "*", + "2", + "*", + "1" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles vertical line, mines at edges', function() { + var minesweeper = new Minesweeper(); + var input = [ + "*", + " ", + " ", + " ", + "*" + ]; + var expected = [ + "*", + "1", + " ", + "1", + "*" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles cross', function() { + var minesweeper = new Minesweeper(); + var input = [ + " * ", + " * ", + "*****", + " * ", + " * " + ]; + var expected = [ + " 2*2 ", + "25*52", + "*****", + "25*52", + " 2*2 " + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + + xit('handles large board', function() { + var minesweeper = new Minesweeper(); + var input = [ + " * * ", + " * ", + " * ", + " * *", + " * * ", + " " + ]; + var expected = [ + "1*22*1", + "12*322", + " 123*2", + "112*4*", + "1*22*2", + "111111" + ]; + expect(minesweeper.annotate(input)).toEqual(expected); + }); + +}); From db4224a2c2c521903350d58bcb7ea739bd4af762 Mon Sep 17 00:00:00 2001 From: morrme Date: Tue, 16 May 2017 05:42:07 -0500 Subject: [PATCH 115/272] replace angle brackets for better rendering (#357) Closes: #353 --- docs/TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 62b52fbf..9a353ef3 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -2,7 +2,7 @@ With the first few exercises, you will get a skeleton file with the exported mod For later ones, you can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). For running tests, install `jasmine` as described in the [Installing Javascript section](http://exercism.io/languages/javascript/installing). -Move to the folder where that exercise's files are located (a path similar to /javascript/). +Move to the folder where that exercise's files are located (a path similar to {EXERCISM_HOME_DIR}/javascript/{EXERCISE}). cd ~/exercism/javascript/bob jasmine bob_test.spec.js From c89061727b061ad693eb570b4d298cbf585f410d Mon Sep 17 00:00:00 2001 From: Roshan Jossey Date: Sun, 21 May 2017 17:07:09 +0530 Subject: [PATCH 116/272] Add topics for problems (#356) Topics where added to these problems - hello-world - leap - rna-transcription - hamming - gigasecond --- config.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config.json b/config.json index 8371dee0..a63335bb 100644 --- a/config.json +++ b/config.json @@ -82,24 +82,37 @@ "slug": "hello-world", "difficulty": 1, "topics": [ + "Control-flow (conditionals)", + "Optional values", + "Strings", + "Text formatting" ] }, { "slug": "leap", "difficulty": 1, "topics": [ + "Booleans", + "Integers", + "Logic" ] }, { "slug": "hamming", "difficulty": 1, "topics": [ + "Control-flow (loops)", + "Control-flow (conditionals)", + "Equality", + "Strings" ] }, { "slug": "rna-transcription", "difficulty": 1, "topics": [ + "Strings", + "Transforming" ] }, { @@ -131,6 +144,7 @@ "slug": "gigasecond", "difficulty": 1, "topics": [ + "Time" ] }, { From 5899e726f0383a37e94ac69c1292bc9f5d757efa Mon Sep 17 00:00:00 2001 From: Roshan Jossey Date: Sun, 21 May 2017 23:47:53 +0530 Subject: [PATCH 117/272] Add topics to exercises Addresses #299 Add topics to - isogram - beer-song - phone-number - anagram - food-chain --- config.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config.json b/config.json index 8371dee0..670824a0 100644 --- a/config.json +++ b/config.json @@ -137,30 +137,41 @@ "slug": "isogram", "difficulty": 1, "topics": [ + "Strings", + "Filtering" ] }, { "slug": "beer-song", "difficulty": 1, "topics": [ + "Looping", + "Conditionals", + "Strings" ] }, { "slug": "phone-number", "difficulty": 1, "topics": [ + "Parsing", + "Transforming" ] }, { "slug": "anagram", "difficulty": 1, "topics": [ + "Strings", + "Filtering" ] }, { "slug": "food-chain", "difficulty": 1, "topics": [ + "Text formatting", + "Algorithms" ] }, { From 718935ed9784fb1d1d51ac73cc3cd030765a29d8 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Mon, 22 May 2017 16:42:00 +0530 Subject: [PATCH 118/272] Add first patch labels to probot exempt (#361) We want to keep these issues open indefinitely for first-timers. Tell probot to ignore them so that they are never closed automatically. `pinned` and `security` are default. I added `good first patch` and `first-timers only`. --- .github/stale.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/stale.yml b/.github/stale.yml index e69de29b..df77691d 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -0,0 +1,6 @@ +# Issues or Pull Requests with these labels will never be considered stale +exemptLabels: + - pinned + - security + - good first patch + - first-timers only From a22ef9861132521b3ae60cc1dcfeafdb07290b15 Mon Sep 17 00:00:00 2001 From: Arthur Dean Date: Thu, 25 May 2017 10:27:19 -0700 Subject: [PATCH 119/272] Add the alphametics exercise (#358) --- config.json | 11 ++- exercises/alphametics/alphametics.spec.js | 95 +++++++++++++++++++ exercises/alphametics/example.js | 107 ++++++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 exercises/alphametics/alphametics.spec.js create mode 100644 exercises/alphametics/example.js diff --git a/config.json b/config.json index 67b6d50e..6cbc0d4f 100644 --- a/config.json +++ b/config.json @@ -75,7 +75,8 @@ "diamond", "all-your-base", "run-length-encoding", - "minesweeper" + "minesweeper", + "alphametics" ], "exercises": [ { @@ -551,6 +552,14 @@ "arrays", "algorithms" ] + }, + { + "slug": "alphametics", + "difficulty": 7, + "topics": [ + "games", + "algorithms" + ] } ], "deprecated": [ diff --git a/exercises/alphametics/alphametics.spec.js b/exercises/alphametics/alphametics.spec.js new file mode 100644 index 00000000..4db54f1a --- /dev/null +++ b/exercises/alphametics/alphametics.spec.js @@ -0,0 +1,95 @@ +var solve = require('./alphametics'); + +describe("Solve the alphametics puzzle", function() { + + it("puzzle with three letters", function() { + var puzzle = "I + BB == ILL"; + var expected = { + "I": 1, + "B": 9, + "L": 0 + }; + expect(solve(puzzle)).toEqual(expected); + }); + + xit("solution must have unique value for each letter", function() { + var puzzle = "A == B"; + expect(solve(puzzle)).toBeNull(); + }); + + xit("leading zero solution is invalid", function() { + var puzzle = "ACA + DD == BD"; + expect(solve(puzzle)).toBeNull(); + }); + + xit("puzzle with four letters", function() { + var puzzle = "AS + A == MOM"; + var expected = { + "A": 9, + "S": 2, + "M": 1, + "O": 0 + }; + expect(solve(puzzle)).toEqual(expected); + }); + + xit("puzzle with six letters", function() { + var puzzle = "NO + NO + TOO == LATE"; + var expected = { + "N": 7, + "O": 4, + "T": 9, + "L": 1, + "A": 0, + "E": 2 + }; + expect(solve(puzzle)).toEqual(expected); + }); + + xit("puzzle with seven letters", function() { + var puzzle = "HE + SEES + THE == LIGHT"; + var expected = { + "E": 4, + "G": 2, + "H": 5, + "I": 0, + "L": 1, + "S": 9, + "T": 7 + }; + expect(solve(puzzle)).toEqual(expected); + }); + + xit("puzzle with eight letters", function() { + var puzzle = "SEND + MORE == MONEY"; + var expected = { + "S": 9, + "E": 5, + "N": 6, + "D": 7, + "M": 1, + "O": 0, + "R": 8, + "Y": 2 + }; + expect(solve(puzzle)).toEqual(expected); + }); + + xit("puzzle with ten letters", function() { + var puzzle = "AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE"; + var expected = { + "A": 5, + "D": 3, + "E": 4, + "F": 7, + "G": 8, + "N": 0, + "O": 2, + "R": 1, + "S": 6, + "T": 9 + }; + expect(solve(puzzle)).toEqual(expected); + }); + +}); diff --git a/exercises/alphametics/example.js b/exercises/alphametics/example.js new file mode 100644 index 00000000..3dc16042 --- /dev/null +++ b/exercises/alphametics/example.js @@ -0,0 +1,107 @@ +function solve(puzzle) { + var parts = puzzle + .split(/[+|==]/g) + .map(function(o) { return o.trim(); }) + .filter(function(o) { return o !== ""; }); + + if(parts.length < 3) { + return null; + } + + var uniqueLetters = getUniqueLetters(parts.join('')); + var firstLetters = getFirstLetters(parts); + + var numberCombinations = getNumberCombinations([0,1,2,3,4,5,6,7,8,9], uniqueLetters.length); + var permutations = getPermutations(Array(uniqueLetters.length).fill().map(function(_, i) {return i; })); + + while(numberCombinations.length) { + var numberCombination = numberCombinations.pop(); + for(var k = 0; k < permutations.length; k++) { + var newNumbers = assignNumbers(numberCombination, uniqueLetters, permutations[k]); + if(testNumbers(newNumbers, parts, firstLetters)) { + return newNumbers; + } + } + } + return null; +} + +function getFirstLetters(words) { + return words + .map(function(word) { return word[0]; }) + .filter(function (val, i, arr) { return arr.indexOf(val) === i; }); +} + +function assignNumbers(numbers, letters, orders) { + var output = {}; + for(var i = 0; i < letters.length; i++) { + output[letters[i]] = numbers[orders[i]]; + } + return output; +} + +function getUniqueLetters(string) { + return string.split('').filter(function (val, i, arr) { return arr.indexOf(val) === i; }); +} + +function testNumbers(numbers, puzzleParts, firstLetters) { + var keys = Object.keys(numbers); + for(var i = 0; i < keys.length; i++) { + if(numbers[keys[i]] === 0 && firstLetters.indexOf(keys[i]) !== -1) { + return false; + } + } + var replaceRegex = new RegExp('[' + keys.join('') + ']', 'g'); + + puzzleParts = puzzleParts.join(',') + .replace(replaceRegex, function(input) { return numbers[input]; }) + .split(',') + .map(function(t) {return parseInt(t);}); + + var total = puzzleParts.slice(puzzleParts.length-1)[0]; + return total === puzzleParts + .slice(0,puzzleParts.length-1) + .reduce(function(acc, val) { return acc + val; },0); +} + +function getPermutations(inputArr) { + var results = []; + function permute(arr, memo) { + var cur, memo = memo || []; + for (var i = 0; i < arr.length; i++) { + cur = arr.splice(i, 1); + if (arr.length === 0) { + results.push(memo.concat(cur)); + } + permute(arr.slice(), memo.concat(cur)); + arr.splice(i, 0, cur[0]); + } + return results; + } + return permute(inputArr); +} + +function getNumberCombinations(set, k) { + var i, j, combs, head, tailcombs; + if (k > set.length || k <= 0) { + return []; + } + if (k === 1) { + combs = []; + for (i = 0; i < set.length; i++) { + combs.push([set[i]]); + } + return combs; + } + combs = []; + for (i = 0; i < set.length - k + 1; i++) { + head = set.slice(i, i + 1); + tailcombs = getNumberCombinations(set.slice(i + 1), k - 1); + for (j = 0; j < tailcombs.length; j++) { + combs.push(head.concat(tailcombs[j])); + } + } + return combs; +} + +module.exports = solve; \ No newline at end of file From d6638dad8d8a82203c2b131b49e676996f5568e6 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Mon, 29 May 2017 08:58:42 -0600 Subject: [PATCH 120/272] Remove license info from README We don't need the duplication, especially now that the GitHub interface shows the license information on the main page of the repository when it can be detected directly from the LICENSE file. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index ba4ec099..c724b208 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,4 @@ The following commands assume that you are in the 'xjavascript' directory: Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data) -## License - -The MIT License (MIT) - -Copyright (c) 2014 Katrina Owen, _@kytrinyx.com From ed9d557201bab9743de3aafe2d178dfeb18e5b72 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Mon, 29 May 2017 08:58:42 -0600 Subject: [PATCH 121/272] Reassign copyright to Exercism legal entity --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 0dc403e5..eee993a5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2014 Katrina Owen, _@kytrinyx.com +Copyright (c) 2017 Exercism, Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 70865209400f8b563d58920378d9ad293f519af2 Mon Sep 17 00:00:00 2001 From: Leslie Heinzen Date: Thu, 1 Jun 2017 18:28:36 -0400 Subject: [PATCH 122/272] Add extended ascii character test for isogram. Tests word which includes upper and lower case of an extended ascii character. --- exercises/isogram/isogram.spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/exercises/isogram/isogram.spec.js b/exercises/isogram/isogram.spec.js index afc4874d..f5f28b73 100644 --- a/exercises/isogram/isogram.spec.js +++ b/exercises/isogram/isogram.spec.js @@ -60,5 +60,11 @@ describe('Isogram Test Suite', function () { expect(word.isIsogram()).toEqual(false); }); + + xit('Àcrobàt', function () { + var word = new Isogram('Àcrobàt'); + + expect(word.isIsogram()).toEqual(false); + }); }); From 87009a3b598a088de641518a2059d16e4c6222b8 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Thu, 1 Jun 2017 21:19:42 -0600 Subject: [PATCH 123/272] Delete deprecated key from config.json This is no longer referenced anywhere. --- config.json | 74 ----------------------------------------------------- 1 file changed, 74 deletions(-) diff --git a/config.json b/config.json index 6cbc0d4f..94738733 100644 --- a/config.json +++ b/config.json @@ -4,80 +4,6 @@ "repository": "https://github.com/exercism/xjavascript", "active": true, "test_pattern": ".*[.]spec[.]js$", - "problems": [ - "hello-world", - "leap", - "hamming", - "rna-transcription", - "bob", - "gigasecond", - "perfect-numbers", - "word-count", - "isogram", - "pangram", - "beer-song", - "phone-number", - "anagram", - "food-chain", - "grade-school", - "robot-name", - "etl", - "space-age", - "grains", - "triangle", - "clock", - "acronym", - "scrabble-score", - "roman-numerals", - "circular-buffer", - "binary", - "prime-factors", - "raindrops", - "allergies", - "strain", - "atbash-cipher", - "accumulate", - "crypto-square", - "trinary", - "sieve", - "simple-cipher", - "octal", - "luhn", - "pig-latin", - "pythagorean-triplet", - "series", - "difference-of-squares", - "secret-handshake", - "proverb", - "linked-list", - "wordy", - "flatten-array", - "hexadecimal", - "largest-series-product", - "kindergarten-garden", - "binary-search", - "binary-search-tree", - "matrix", - "robot-simulator", - "nth-prime", - "palindrome-products", - "pascals-triangle", - "say", - "custom-set", - "sum-of-multiples", - "queen-attack", - "saddle-points", - "ocr-numbers", - "meetup", - "bracket-push", - "two-bucket", - "bowling", - "diamond", - "all-your-base", - "run-length-encoding", - "minesweeper", - "alphametics" - ], "exercises": [ { "slug": "hello-world", From d63fb27cce8aa43483ae76de60588313e73b368a Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sat, 10 Jun 2017 15:20:03 -0600 Subject: [PATCH 124/272] Normalize format of config file (#367) This will let us script changes to it with less noise in the diffs. --- config.json | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 94738733..5242b845 100644 --- a/config.json +++ b/config.json @@ -119,48 +119,56 @@ "slug": "grade-school", "difficulty": 1, "topics": [ + ] }, { "slug": "robot-name", "difficulty": 1, "topics": [ + ] }, { "slug": "etl", "difficulty": 1, "topics": [ + ] }, { "slug": "space-age", "difficulty": 1, "topics": [ + ] }, { "slug": "grains", "difficulty": 1, "topics": [ + ] }, { "slug": "triangle", "difficulty": 1, "topics": [ + ] }, { "slug": "clock", "difficulty": 1, "topics": [ + ] }, - { + { "slug": "perfect-numbers", "difficulty": 1, "topics": [ + ] }, { @@ -178,132 +186,154 @@ "slug": "acronym", "difficulty": 1, "topics": [ + ] }, { "slug": "scrabble-score", "difficulty": 1, "topics": [ + ] }, { "slug": "roman-numerals", "difficulty": 1, "topics": [ + ] }, { "slug": "circular-buffer", "difficulty": 1, "topics": [ + ] }, { "slug": "binary", "difficulty": 1, "topics": [ + ] }, { "slug": "prime-factors", "difficulty": 1, "topics": [ + ] }, { "slug": "raindrops", "difficulty": 1, "topics": [ + ] }, { "slug": "allergies", "difficulty": 1, "topics": [ + ] }, { "slug": "strain", "difficulty": 1, "topics": [ + ] }, { "slug": "atbash-cipher", "difficulty": 1, "topics": [ + ] }, { "slug": "accumulate", "difficulty": 1, "topics": [ + ] }, { "slug": "crypto-square", "difficulty": 1, "topics": [ + ] }, { "slug": "trinary", "difficulty": 1, "topics": [ + ] }, { "slug": "sieve", "difficulty": 1, "topics": [ + ] }, { "slug": "simple-cipher", "difficulty": 1, "topics": [ + ] }, { "slug": "octal", "difficulty": 1, "topics": [ + ] }, { "slug": "luhn", "difficulty": 1, "topics": [ + ] }, { "slug": "pig-latin", "difficulty": 1, "topics": [ + ] }, { "slug": "pythagorean-triplet", "difficulty": 1, "topics": [ + ] }, { "slug": "series", "difficulty": 1, "topics": [ + ] }, { "slug": "difference-of-squares", "difficulty": 1, "topics": [ + ] }, { "slug": "secret-handshake", "difficulty": 1, "topics": [ + ] }, { @@ -318,156 +348,182 @@ "slug": "linked-list", "difficulty": 1, "topics": [ + ] }, { "slug": "wordy", "difficulty": 1, "topics": [ + ] }, { "slug": "flatten-array", "difficulty": 1, "topics": [ + ] }, { "slug": "hexadecimal", "difficulty": 1, "topics": [ + ] }, { "slug": "largest-series-product", "difficulty": 1, "topics": [ + ] }, { "slug": "kindergarten-garden", "difficulty": 1, "topics": [ + ] }, { "slug": "binary-search", "difficulty": 1, "topics": [ + ] }, { "slug": "binary-search-tree", "difficulty": 1, "topics": [ + ] }, { "slug": "matrix", "difficulty": 1, "topics": [ + ] }, { "slug": "robot-simulator", "difficulty": 1, "topics": [ + ] }, { "slug": "nth-prime", "difficulty": 1, "topics": [ + ] }, { "slug": "palindrome-products", "difficulty": 1, "topics": [ + ] }, { "slug": "pascals-triangle", "difficulty": 1, "topics": [ + ] }, { "slug": "say", "difficulty": 1, "topics": [ + ] }, { "slug": "custom-set", "difficulty": 1, "topics": [ + ] }, { "slug": "sum-of-multiples", "difficulty": 1, "topics": [ + ] }, { "slug": "queen-attack", "difficulty": 1, "topics": [ + ] }, { "slug": "saddle-points", "difficulty": 1, "topics": [ + ] }, { "slug": "ocr-numbers", "difficulty": 1, "topics": [ + ] }, { "slug": "meetup", "difficulty": 1, "topics": [ + ] }, { "slug": "bracket-push", "difficulty": 1, "topics": [ + ] }, { "slug": "two-bucket", "difficulty": 1, "topics": [ + ] }, { "slug": "bowling", "difficulty": 1, "topics": [ + ] }, { "slug": "diamond", "difficulty": 1, "topics": [ + ] }, { "slug": "all-your-base", "difficulty": 1, "topics": [ + ] }, { "slug": "run-length-encoding", "difficulty": 1, "topics": [ + ] }, { From 86fd070f1e05aa2848490f8fe94d15b5eb056def Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sat, 10 Jun 2017 15:20:30 -0600 Subject: [PATCH 125/272] Rename the global exercise hints file (#365) We've had some difficulty coming up with a good name for the file that gets included in all of the exercise READMEs for a given track. These are global hints, like how to run the test suite, which are relevant to all the exercises on a track. We started with SETUP.md in the root of the repository, then renamed that to exercises/TRACK_HINTS.md because SETUP.md was misleading and confusing, but then we realized that TRACK_HINTS.md was a bit ambiguous and confusing as well. Finally we settled on putting the file in the docs directory, since this is user-facing documentation, and calling the file EXERCISE_README_INSERT.md See https://github.com/exercism/meta/issues/5 for context. --- SETUP.md => docs/EXERCISE_README_INSERT.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SETUP.md => docs/EXERCISE_README_INSERT.md (100%) diff --git a/SETUP.md b/docs/EXERCISE_README_INSERT.md similarity index 100% rename from SETUP.md rename to docs/EXERCISE_README_INSERT.md From 1758ef9134d93040404aa644c9e613a75e909140 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sat, 10 Jun 2017 15:20:46 -0600 Subject: [PATCH 126/272] Delete ignored key from config.json (#366) Since the exercise implementations are all in the exercises directory we no longer need to ignore any non-exercise directories in the root of the track. --- config.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config.json b/config.json index 5242b845..ae19c1a5 100644 --- a/config.json +++ b/config.json @@ -548,11 +548,6 @@ "nucleotide-count", "point-mutations" ], - "ignored": [ - "docs", - "node_modules", - "img" - ], "foregone": [ ] From ddb5f3bf7501cfbfadfcceb507917c2449443571 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 18 Jun 2017 11:55:52 -0600 Subject: [PATCH 127/272] Remove leading 'x' from repository name (#368) The leading 'x' is kind of arbitrary. Especially now that we can set topics on the repositories, we don't need a pattern to distinguish what is a track or not. The repository itself has already been renamed. GitHub redirects from the old name to the new name, so we do not have to rush to fix links to the old repository name, though we should update them for the sake of clarity. --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index ae19c1a5..0434cb78 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "slug": "javascript", "language": "JavaScript", - "repository": "https://github.com/exercism/xjavascript", + "repository": "https://github.com/exercism/javascript", "active": true, "test_pattern": ".*[.]spec[.]js$", "exercises": [ From 996e5834991d5cf248e761a136f595ad8e0c1aac Mon Sep 17 00:00:00 2001 From: Kamil Malek Date: Sat, 24 Jun 2017 14:07:06 +0200 Subject: [PATCH 128/272] Modified Phone Number tests to fit canonical data (#371) --- exercises/phone-number/example.js | 4 +- exercises/phone-number/phone-number.spec.js | 97 +++++++++++---------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/exercises/phone-number/example.js b/exercises/phone-number/example.js index 75639c19..5278ad40 100644 --- a/exercises/phone-number/example.js +++ b/exercises/phone-number/example.js @@ -8,12 +8,12 @@ var Phone = module.exports = function Phone(number) { Phone.prototype.cleanNumber = function(number) { var num = number.replace(/\D/g,''); - if (num.length === 10) { + if (num.length === 10 && num[0]>=2&& num[3]>=2) { return num; } else if (num.length === 11 && num[0] === '1') { return num.substr(1,num.length); } else { - return '0000000000'; + return null; } }; diff --git a/exercises/phone-number/phone-number.spec.js b/exercises/phone-number/phone-number.spec.js index c19d4f3d..257ddf15 100644 --- a/exercises/phone-number/phone-number.spec.js +++ b/exercises/phone-number/phone-number.spec.js @@ -1,58 +1,63 @@ var PhoneNumber = require('./phone-number'); describe('PhoneNumber()', function() { - it('cleans the number (123) 456-7890', function() { - var phone = new PhoneNumber('(123) 456-7890'); - expect(phone.number()).toEqual('1234567890'); + it('cleans the number', function() { + var phone = new PhoneNumber('(223) 456-7890'); + expect(phone.number()).toEqual('2234567890'); }); xit('cleans numbers with dots', function() { - var phone = new PhoneNumber('123.456.7890'); - expect(phone.number()).toEqual('1234567890'); + var phone = new PhoneNumber('223.456.7890'); + expect(phone.number()).toEqual('2234567890'); }); - xit('cleans some other number with dots', function() { - var phone = new PhoneNumber('555.456.7890'); - expect(phone.number()).toEqual('5554567890'); + xit('cleans numbers with multiple spaces', function() { + var phone = new PhoneNumber('223 456 7890 '); + expect(phone.number()).toEqual('2234567890'); }); - - xit('valid when 11 digits and first digit is 1', function() { - var phone = new PhoneNumber('11234567890'); - expect(phone.number()).toEqual('1234567890'); - }); - - xit('invalid when 11 digits and the first digit is NOT 1', function() { - var phone = new PhoneNumber('2 1234567890'); - expect(phone.number()).toEqual('0000000000'); - }); - - xit('invalid when 12 digits', function() { - var phone = new PhoneNumber('991234567890'); - expect(phone.number()).toEqual('0000000000'); - }); - + xit('invalid when 9 digits', function() { var phone = new PhoneNumber('123456789'); - expect(phone.number()).toEqual('0000000000'); - }); - - xit('has an area code', function() { - var phone = new PhoneNumber('1234567890'); - expect(phone.areaCode()).toEqual('123'); - }); - - xit('has some other area code', function() { - var phone = new PhoneNumber('5554567890'); - expect(phone.areaCode()).toEqual('555'); - }); - - xit('formats a number', function() { - var phone = new PhoneNumber('1234567890'); - expect(phone.toString()).toEqual('(123) 456-7890'); - }); - - xit('formats some other number', function() { - var phone = new PhoneNumber('5554567890'); - expect(phone.toString()).toEqual('(555) 456-7890'); - }); + expect(phone.number()).toEqual(null); + }); + + xit('invalid when 11 digits does not start with a 1', function(){ + var phone = new PhoneNumber('22234567890'); + expect(phone.number()).toEqual(null); + }); + + xit('valid when 11 digits and starting with 1', function(){ + var phone = new PhoneNumber('12234567890'); + expect(phone.number()).toEqual('2234567890'); + }); + + xit('valid when 11 digits and starting with 1 even with punctuation', function(){ + var phone = new PhoneNumber('+1 (223) 456-7890'); + expect(phone.number()).toEqual('2234567890'); + }); + + xit('invalid when more than 11 digits', function(){ + var phone = new PhoneNumber('321234567890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid with letters', function(){ + var phone = new PhoneNumber('123-abc-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid with punctuations', function(){ + var phone = new PhoneNumber('123-@:!-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid if area code does not start with 2-9', function(){ + var phone = new PhoneNumber('(123) 456-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid if exchange code does not start with 2-9', function(){ + var phone = new PhoneNumber('(223) 056-7890'); + expect(phone.number()).toEqual(null); + }); }); From 7559c08e12a3fc47dbef779981eccf9cf0fcea12 Mon Sep 17 00:00:00 2001 From: Kamil Malek Date: Sat, 24 Jun 2017 14:08:22 +0200 Subject: [PATCH 129/272] Simplified the hello-world exercise (#370) * Simplified the hello-world exercise * modified HINTS.md --- exercises/hello-world/HINTS.md | 37 ++++++----------------- exercises/hello-world/hello-world.js | 2 +- exercises/hello-world/hello-world.spec.js | 12 ++------ 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/exercises/hello-world/HINTS.md b/exercises/hello-world/HINTS.md index 250d97f3..0fe9cd45 100644 --- a/exercises/hello-world/HINTS.md +++ b/exercises/hello-world/HINTS.md @@ -14,12 +14,10 @@ but it helps to understand what a test looks like, and what it is doing. Open up the test file, hello-world.spec.js. -It has three tests defined in it. +There is one test inside: -This is the first test: - - it('says hello world with no name', function() { - expect(helloWorld.hello('')).toEqual('Hello, World!'); + it('says hello world', function() { + expect(helloWorld.hello()).toEqual('Hello, World!'); }); Run the test now, with the following command on the command-line: @@ -30,7 +28,7 @@ The test fails, which makes sense since you've not written any code yet. The failure looks like this: - 1) Hello World says hello world with no name + 1) Hello World says hello world Message: Expected undefined to equal 'Hello, World!'. @@ -38,16 +36,16 @@ There's more, but this is the most important part. Take a look at that first line: - 1) Hello World says hello world with no name + 1) Hello World says hello world Now look at the test definition again: - it('says hello world with no name', function() { + it('says hello world', function() { // ... more code here ... }); -The text 'says hello world with no name' is repeated. -This is how you know which test failed. +The text 'says hello world' is repeated. +This is how you know the test failed. The failure message explains what is wrong: @@ -55,11 +53,11 @@ The failure message explains what is wrong: This comes from the part of the test definition that says "expect": - expect(helloWorld.hello('')).toEqual('Hello, World!'); + expect(helloWorld.hello()).toEqual('Hello, World!'); It's comparing two values. It is calling - helloWorld.hello('') + helloWorld.hello() and comparing the result to a hard-coded string. @@ -82,21 +80,6 @@ Notice how it changes the failure message. Then change the implementation in hello-world.js again, this time to make the test pass. -Once the test is passing, look at the second test in hello-world.spec.js. It looks like this: - - xit('says hello to bob', function() { - expect(helloWorld.hello('Bob')).toEqual('Hello, Bob!'); - }); - -This test starts with `xit` instead of `it`. -That means that when Jasmine runs the tests, -the test will be skipped. - -Change the test so that it starts with `it`, -and run the tests again. - -Make the test pass, and then do the same with the third test. - When you are done, submit your solution to exercism: exercism submit hello-world.js diff --git a/exercises/hello-world/hello-world.js b/exercises/hello-world/hello-world.js index 4968271d..4f38bdbe 100644 --- a/exercises/hello-world/hello-world.js +++ b/exercises/hello-world/hello-world.js @@ -6,7 +6,7 @@ var HelloWorld = function() {}; -HelloWorld.prototype.hello = function(input) { +HelloWorld.prototype.hello = function() { // // YOUR CODE GOES HERE // diff --git a/exercises/hello-world/hello-world.spec.js b/exercises/hello-world/hello-world.spec.js index 60d0769c..e397a6c4 100644 --- a/exercises/hello-world/hello-world.spec.js +++ b/exercises/hello-world/hello-world.spec.js @@ -3,15 +3,7 @@ var HelloWorld = require('./hello-world'); describe('Hello World', function() { var helloWorld = new HelloWorld(); - it('says hello world with no name', function() { - expect(helloWorld.hello('')).toEqual('Hello, World!'); - }); - - xit('says hello to bob', function() { - expect(helloWorld.hello('Bob')).toEqual('Hello, Bob!'); - }); - - xit('says hello to sally', function() { - expect(helloWorld.hello('Sally')).toEqual('Hello, Sally!'); + it('says hello world', function() { + expect(helloWorld.hello()).toEqual('Hello, World!'); }); }); From 12406ba75b8c6ec11b489bcbbb33893c5d1caf9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Wed, 28 Jun 2017 09:25:15 -0300 Subject: [PATCH 130/272] Adds the simple-linked-list exercise (#311) (#372) --- config.json | 7 + exercises/simple-linked-list/example.js | 119 +++++++++++++ .../simple-linked-list.spec.js | 160 ++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 exercises/simple-linked-list/example.js create mode 100644 exercises/simple-linked-list/simple-linked-list.spec.js diff --git a/config.json b/config.json index 0434cb78..433304e9 100644 --- a/config.json +++ b/config.json @@ -542,6 +542,13 @@ "games", "algorithms" ] + }, + { + "slug": "simple-linked-list", + "difficulty": 8, + "topics": [ + "data-structures" + ] } ], "deprecated": [ diff --git a/exercises/simple-linked-list/example.js b/exercises/simple-linked-list/example.js new file mode 100644 index 00000000..5d9cfed0 --- /dev/null +++ b/exercises/simple-linked-list/example.js @@ -0,0 +1,119 @@ +function Element (value, next) { + if (!(this instanceof Element)) { + throw new Error('Element is a constructor.'); + } + + if (value === undefined) { + throw new Error('Value required.'); + } + + if (next !== undefined && !(next instanceof Element)) { + throw new Error('A Element instance as next value is required.'); + } + + this.value = value; + this.next = next; +}; + +function List () {}; + +List.prototype.push = function (value) { + if (value === undefined) { + throw new Error('Argument required.'); + } + + var newEl = (value instanceof Element) + ? value + : new Element(value); + + if (!this.head) { + this.head = newEl; + return; + } + + var lastEl = this.head; + while (lastEl.next) { + lastEl = lastEl.next; + } + + lastEl.next = newEl; +}; + +List.prototype.unshift = function (value) { + if (value === undefined) { + throw new Error('Argument required.'); + } + + var newEl = (value instanceof Element) + ? value + : new Element(value); + + newEl.next = this.head; + this.head = newEl; +}; + +List.prototype.shift = function () { + if (!this.head) { + return; + } + + this.head = this.head.next; +}; + +List.prototype.pop = function () { + if (!this.head) { + return; + } + + var penultEl, lastEl = this.head; + while (lastEl.next) { + penultEl = lastEl; + lastEl = lastEl.next; + } + + if (!penultEl) { + this.head = undefined; + } + else { + penultEl.next = undefined; + } +}; + +List.prototype.reverse = function () { + if (!this.head) { + return; + } + + var current, previous; + while (this.head) { + current = this.head; + this.shift(); + current.next = previous; + previous = current; + } + + this.head = previous; +}; + +List.prototype.toArray = function () { + var array = []; + + while (this.head) { + array.push(this.head.value); + this.shift(); + } + + return array; +}; + +List.fromArray = function (array) { + var list = new List(); + array.forEach(function (item) { + list.push(new Element(item)); + }); + + return list; +}; + +exports.List = List; +exports.Element = Element; diff --git a/exercises/simple-linked-list/simple-linked-list.spec.js b/exercises/simple-linked-list/simple-linked-list.spec.js new file mode 100644 index 00000000..e1f8724e --- /dev/null +++ b/exercises/simple-linked-list/simple-linked-list.spec.js @@ -0,0 +1,160 @@ +var SimpleLinkedList = require('./simple-linked-list'); +var List = SimpleLinkedList.List; +var Element = SimpleLinkedList.Element; + +describe('simple-linked-list', function () { + + it('exports a List constructor', function () { + expect(List).toBeDefined(); + }); + + xit('exports a Element constructor', function () { + expect(Element).toBeDefined(); + }); + + describe('Element', function () { + + xit('is a constructor', function () { + var el = new Element(1); + expect(el).toBeDefined(); + + expect(function () { + var el = Element(1); + }).toThrow(); + }); + + xit('requires an argument', function () { + var el = new Element(1); + expect(el).toBeDefined(); + + expect(function () { + var el = new Element(); + }).toThrow(); + }); + + xit('has as a value', function () { + var el = new Element(1); + expect(el.value).toBe(1); + }); + + xit('reference to next is undefined by default', function () { + var el = new Element(1); + expect(el.next).toBeUndefined(); + }); + }); + + xit('accepts a reference to the next element', function () { + var elOne = new Element(1); + var elTwo = new Element(2, elOne); + expect(elTwo.next).toBe(elOne); + }); + + xit('requires an instance of Element as next element', function () { + expect(function () { + var el = new Element(1, true); + var el = new Element(1, false); + }).toThrow(); + expect(function () { + var el = new Element(1, 'lorem ipsum'); + }).toThrow(); + expect(function () { + var el = new Element(1, []); + }).toThrow(); + expect(function () { + var el = new Element(1, {}); + }).toThrow(); + }); + + describe('List', function () { + + xit('is a constructor', function () { + var ll = new List(); + expect(ll).toBeDefined(); + }); + + xit('allows you to append an element', function () { + var ll = new List(); + var el = new Element(1); + ll.push(el); + expect(ll.head).toBe(el); + + var ll2 = new List(); + var elOne = new Element(1); + var elTwo = new Element(2); + ll2.push(elOne); + ll2.push(elTwo); + expect(ll2.head.next).toBe(elTwo); + }); + + xit('allows you to prepend an element', function () { + var ll = new List(); + var el = new Element(1); + ll.unshift(el); + expect(ll.head).toBe(el); + + var ll2 = new List(); + var elOne = new Element(1); + var elTwo = new Element(2); + ll2.unshift(elOne); + ll2.unshift(elTwo); + expect(ll2.head).toBe(elTwo); + }); + + xit('allows you to remove the first element', function () { + var ll = new List(); + ll.push(new Element(1)); + ll.shift(); + expect(ll.head).toBeUndefined(); + + ll.push(new Element(2)); + ll.push(new Element(3)); + ll.shift(); + expect(ll.head.value).toBe(3); + }); + + xit('allows you to remove the last element', function () { + var ll = new List(); + ll.push(new Element(1)); + ll.pop(); + expect(ll.head).toBeUndefined(); + + ll.push(new Element(2)); + ll.push(new Element(3)); + ll.pop(); + expect(ll.head.next).toBeUndefined(); + }); + + xit('allows you to convert an array to a List', function () { + var ll = List.fromArray([1, 2]); + + expect(ll.head.value).toBe(1); + expect(ll.head.next.value).toBe(2); + }); + + xit('allows you to convert a List into an array', function () { + var ll = new List(); + ll.push(new Element(1)); + ll.push(new Element(2)); + var a = ll.toArray(); + + expect(a instanceof Array).toBe(true); + expect(a.length).toBe(2); + expect(a[0]).toBe(1); + expect(a[1]).toBe(2); + }); + + xit('allows you to reverse a List', function () { + var ll = new List(); + ll.push(new Element(1)); + ll.push(new Element(2)); + ll.push(new Element(3)); + ll.reverse(); + + expect(ll.head.value).toBe(3); + expect(ll.head.next.value).toBe(2); + expect(ll.head.next.next.value).toBe(1); + }); + + }); + +}); From 6752f73b3cb261c1216d0b627d9fc54e0abecb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Thu, 29 Jun 2017 17:02:34 -0300 Subject: [PATCH 131/272] Replace topics for simple-linked-list (#375) --- config.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 433304e9..ad801e7a 100644 --- a/config.json +++ b/config.json @@ -547,7 +547,9 @@ "slug": "simple-linked-list", "difficulty": 8, "topics": [ - "data-structures" + "Arrays", + "Data structures", + "Lists" ] } ], From e0ac5f4094b4878181fed018f802f14a0142d3a8 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sun, 2 Jul 2017 17:25:54 -0400 Subject: [PATCH 132/272] Update Bob for canonical tests --- exercises/bob/bob.spec.js | 89 ++++++++++++++++++++++++++------------- exercises/bob/example.js | 3 +- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/exercises/bob/bob.spec.js b/exercises/bob/bob.spec.js index c87a1cc0..5a008481 100644 --- a/exercises/bob/bob.spec.js +++ b/exercises/bob/bob.spec.js @@ -1,81 +1,79 @@ var Bob = require('./bob.js'); -describe('Bob', function() { +describe('Bob', function () { var bob = new Bob(); - it('stating something', function() { + it('stating something', function () { var result = bob.hey('Tom-ay-to, tom-aaaah-to.'); expect(result).toEqual('Whatever.'); }); - xit('shouting', function() { + xit('shouting', function () { var result = bob.hey('WATCH OUT!'); expect(result).toEqual('Whoa, chill out!'); }); - xit('asking a question', function() { + xit('shouting gibberish', function () { + var result = bob.hey('FCECDFCAAB'); + expect(result).toEqual('Whoa, chill out!'); + }); + + xit('asking a question', function () { var result = bob.hey('Does this cryogenic chamber make me look fat?'); expect(result).toEqual('Sure.'); }); - xit('talking forcefully', function() { + xit('asking a numeric question', function () { + var result = bob.hey('You are, what, like 15?'); + expect(result).toEqual('Sure.'); + }); + + xit('asking gibberish', function () { + var result = bob.hey('fffbbcbeab?'); + expect(result).toEqual('Sure.'); + }); + + xit('talking forcefully', function () { var result = bob.hey('Let\'s go make out behind the gym!'); expect(result).toEqual('Whatever.'); }); - xit('using acronyms in regular speech', function() { + xit('using acronyms in regular speech', function () { var result = bob.hey('It\'s OK if you don\'t want to go to the DMV.'); expect(result).toEqual('Whatever.'); }); - xit('forceful questions', function() { + xit('forceful questions', function () { var result = bob.hey('WHAT THE HELL WERE YOU THINKING?'); expect(result).toEqual('Whoa, chill out!'); }); - xit('shouting numbers', function() { + xit('shouting numbers', function () { var result = bob.hey('1, 2, 3 GO!'); expect(result).toEqual('Whoa, chill out!'); }); - xit('only numbers', function() { + xit('only numbers', function () { var result = bob.hey('1, 2, 3'); expect(result).toEqual('Whatever.'); }); - xit('question with only numbers', function() { + xit('question with only numbers', function () { var result = bob.hey('4?'); expect(result).toEqual('Sure.'); }); - xit('shouting with special characters', function() { + xit('shouting with special characters', function () { var result = bob.hey('ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!'); expect(result).toEqual('Whoa, chill out!'); }); - xit('shouting with umlauts', function() { - /* NOTE: \xc4 = Ä - \xe4 = ä - \xdc = Ü - \xfc = ü - "\xfcML\xe4\xdcTS" === "üMLäÜTS" - */ - - var result = bob.hey('\xdcML\xc4\xdcTS!'); - expect(result).toEqual('Whoa, chill out!'); - }); - - xit('calmly speaking about umlauts', function() { - var result = bob.hey('\xfcML\xe4\xdcTS'); - expect(result).toEqual('Whatever.'); - }); - xit('shouting with no exclamation mark', function () { var result = bob.hey('I HATE YOU'); expect(result).toEqual('Whoa, chill out!'); }); - xit('statement containing question mark', function() { + xit('statement containing question mark', function () { var result = bob.hey('Ending with a ? means a question.'); expect(result).toEqual('Whatever.'); }); @@ -90,8 +88,39 @@ describe('Bob', function() { expect(result).toEqual('Fine. Be that way!'); }); - xit('prolonged silence', function () { + xit('prolonged silence', function () { var result = bob.hey(' '); expect(result).toEqual('Fine. Be that way!'); }); + + xit('alternate silence', function () { + var result = bob.hey('\t\t\t\t\t\t\t\t\t\t'); + expect(result).toEqual('Fine. Be that way!'); + }); + + xit('multiple line question', function () { + var result = bob.hey('\nDoes this cryogenic chamber make me look fat?\nno'); + expect(result).toEqual('Whatever.'); + }); + + xit('starting with whitespace', function () { + var result = bob.hey(' hmmmmmmm...'); + expect(result).toEqual('Whatever.'); + }); + + xit('ending with whitespace', function () { + var result = bob.hey('Okay if like my spacebar quite a bit? '); + expect(result).toEqual('Sure.'); + }); + + xit('other whitespace', function () { + var result = bob.hey('\n\r \t'); + expect(result).toEqual('Fine. Be that way!'); + }); + + xit('non-question ending with whitespace', function () { + var result = bob.hey('This is a statement ending with whitespace '); + expect(result).toEqual('Whatever.'); + }); + }); diff --git a/exercises/bob/example.js b/exercises/bob/example.js index b6e05252..6526bd7a 100644 --- a/exercises/bob/example.js +++ b/exercises/bob/example.js @@ -13,7 +13,8 @@ function Bob() { return message[message.length - 1] === '?'; } - this.hey = function(message) { + this.hey = function(input) { + var message = input.trim(); if (isSilence(message)) { return 'Fine. Be that way!'; } else if (isShouting(message)) { From 47c9143628bdce02a450503c15f2574c44219c00 Mon Sep 17 00:00:00 2001 From: Hannah Vivian Shaw Date: Thu, 6 Jul 2017 17:14:19 -0400 Subject: [PATCH 133/272] Implement exercise list-ops, squashing 11 commits: (#378) * begin writing tests * begin writing example.js * finish implementing spec & example * refactor tests into groups, reinstate xit, and lint * lint example.js * add list-ops exercise to config.json * use a saner module.exports statement, refactor accordingly * fix missing newline at eof * remove es6 features, move to instance methods, and add test suite to catch native Array function use * relint * re-disable tests after the first one... --- config.json | 9 ++ exercises/list-ops/example.js | 76 +++++++++++++ exercises/list-ops/list-ops.spec.js | 168 ++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 exercises/list-ops/example.js create mode 100644 exercises/list-ops/list-ops.spec.js diff --git a/config.json b/config.json index ad801e7a..99ed6dd2 100644 --- a/config.json +++ b/config.json @@ -551,6 +551,15 @@ "Data structures", "Lists" ] + }, + { + "slug": "list-ops", + "difficulty": 8, + "topics": [ + "Data structures", + "Lists", + "Recursion" + ] } ], "deprecated": [ diff --git a/exercises/list-ops/example.js b/exercises/list-ops/example.js new file mode 100644 index 00000000..a1d2788a --- /dev/null +++ b/exercises/list-ops/example.js @@ -0,0 +1,76 @@ +'use strict'; + +function List(arr) { + this.values = arr || []; +} + +List.prototype = { + append: function (otherList) { + var appended = this.values; + + for (var i = 0; i < otherList.length(); i++) { + appended.push(otherList.values[i]); + } + + return new List(appended); + }, + + concat: function (otherList) { + return this.append(otherList); + }, + + cons: function (item, arr) { + var x = new List([item]); + var xs = new List(arr) + return x.append(xs).values; + }, + + foldl: function (func, start) { + var acc = start; + + for (var i = 0; i < this.length(); i++) { + acc = func(this.values[i], acc); + } + + return acc; + }, + + foldr: function (func, start) { + var acc = start; + + for (var i = this.length() - 1; i >= 0; i--) { + acc = func(this.values[i], acc); + } + + return acc; + }, + + length: function () { + var count = 0; + this.values.forEach(function () { count++; }); + + return count; + }, + + reverse: function () { + return new List(this.foldl(this.cons, [])); + }, + + map: function (func, arr) { + var applyFuncThenCons = function (x, acc) { + return this.cons(func(x), acc); + } + + return new List(this.foldr(applyFuncThenCons.bind(this), [])); + }, + + filter: function (pred) { + var consIfPred = function (x, acc) { + return pred(x) ? this.cons(x, acc) : acc; + }; + + return new List(this.foldr(consIfPred.bind(this), [])); + } +} + +module.exports = List; diff --git a/exercises/list-ops/list-ops.spec.js b/exercises/list-ops/list-ops.spec.js new file mode 100644 index 00000000..19ce09a2 --- /dev/null +++ b/exercises/list-ops/list-ops.spec.js @@ -0,0 +1,168 @@ +var List = require('./list-ops'); + +describe('List', function () { + // predicates to filter by & functions to map + var isOdd = function (x) { + return x % 2 === 1; + } + + var plusOne = function (x) { + return x + 1; + }; + + var divide = function (x, acc) { + return x / acc; + }; + + describe('append', function () { + it('appends two empty lists', function () { + var emptyList = new List(); + expect(emptyList.append(emptyList).values).toEqual([]); + }); + + xit('appends an empty list to a non-empty list', function () { + var emptyList = new List(); + var nonEmptyList = new List([1, 2, 3, 4]); + expect(emptyList.append(nonEmptyList).values).toEqual([1, 2, 3, 4]); + }); + + xit('appends two non-empty lists', function () { + var list1 = new List([1, 2]); + var list2 = new List([2, 3, 4, 5]); + expect(list1.append(list2).values).toEqual([1, 2, 2, 3, 4, 5]); + }); + }); + + describe('concat', function () { + xit('concatenates an empty list', function () { + var emptyList = new List(); + expect(emptyList.concat(emptyList).values).toEqual([]); + }); + + xit('concatenates a list of lists', function () { + var list1 = new List([1, 2]); + var list2 = new List([3]); + var list3 = new List([]); + var list4 = new List([4, 5, 6]); + expect(list1 + .concat(list2) + .concat(list3) + .concat(list4).values + ).toEqual([1, 2, 3, 4, 5, 6]); + }); + }); + + describe('filter', function () { + xit('filters an empty list by a function', function () { + var list = new List(); + expect(list.filter(isOdd).values).toEqual([]); + }); + + xit('filters a non-empty list by a function', function () { + var list = new List([1, 2, 3, 5]); + expect(list.filter(isOdd).values).toEqual([1, 3, 5]); + }); + }); + + describe('length', function () { + xit('finds the length of a empty list', function () { + var list = new List(); + expect(list.length()).toEqual(0); + }); + + xit('finds the length of a non-empty list', function () { + var list = new List([1, 2, 3, 4]); + expect(list.length()).toEqual(4); + }); + }); + + describe('map', function () { + xit('maps a function over an empty list', function () { + var list = new List([]); + expect(list.map(plusOne).values).toEqual([]); + }); + + xit('maps a function over a non-empty list', function () { + var list = new List([1, 3, 5, 7]); + expect(list.map(plusOne).values).toEqual([2, 4, 6, 8]); + }); + }); + + describe('foldl', function () { + xit('folds an empty list from the left with the given function', function () { + var list = new List([]); + expect(list.foldl(divide, 2)).toEqual(2); + }); + + xit('folds a non-empty list from the left with the given function', function () { + var list = new List([1, 2, 3, 4]); + expect(list.foldl(divide, 24)).toEqual(64); + }); + }); + + describe('foldr', function () { + xit('folds an empty list from the right with the given function', function () { + var list = new List([]); + expect(list.foldr(divide, 2)).toEqual(2); + }); + + xit('folds a non-empty list from the right with the given function', function () { + var list = new List([1, 2, 3, 4]); + expect(list.foldr(divide, 24)).toEqual(9); + }); + }); + + describe('reverse', function () { + xit('reverses an empty list', function () { + var list = new List([]); + expect(list.reverse().values).toEqual([]); + }); + + xit('reverses a non-empty list', function () { + var list = new List([1, 3, 5, 7]); + expect(list.reverse().values).toEqual([7, 5, 3, 1]); + }); + }); + + describe('must not call native Array function', function () { + var list = new List([1, 2, 3, 4]); + var list2 = new List([5, 1]); + + beforeAll(function () { + spyOn(list.values, 'map').and.callThrough(); + spyOn(list.values, 'filter').and.callThrough(); + spyOn(list.values, 'reduce').and.callThrough(); + spyOn(list.values, 'reduceRight').and.callThrough(); + spyOn(list.values, 'reverse').and.callThrough(); + spyOn(list.values, 'concat').and.callThrough(); + + list.length(); + list.append(list2); + list.concat(list2); + list.reverse(); + list.filter(isOdd); + list.map(plusOne); + list.foldl(divide, 24); + list.foldr(divide, 24); + }); + + xit('Array.prototype.map()', function () { + expect(list.values.map).not.toHaveBeenCalled(); + }); + xit('Array.prototype.filter()', function () { + expect(list.values.filter).not.toHaveBeenCalled(); + }); + xit('Array.prototype.reduce()', function () { + expect(list.values.reduce).not.toHaveBeenCalled(); + }); + xit('Array.prototype.reduceRight()', function () { + expect(list.values.reduceRight).not.toHaveBeenCalled(); + }); + xit('Array.prototype.concat()', function () { + expect(list.values.concat).not.toHaveBeenCalled(); + }); + xit('Array.prototype.reverse()', function () { + expect(list.values.reverse).not.toHaveBeenCalled(); + }); + }); +}); From 1485ceb21dc65c6a6fc5bf1a527a2dd086a2acf2 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sat, 8 Jul 2017 21:18:40 -0600 Subject: [PATCH 134/272] Call configlet subcommand on CI This changes configlet to pass a subcommand. For now, we've released a version of configlet which handles both the old command: configlet path/to/track as well as the new command: configlet lint path/to/track This will let us update all the travis files to include the subcommand before we release the version of configlet that requires the subcommand. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9312e714..e287b590 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,4 @@ install: script: - "make test" - "./bin/fetch-configlet" - - "./bin/configlet ." + - "./bin/configlet lint ." From baf5f0410bfe3e4e106613c1e43675e00a1d67db Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 14 Jul 2017 22:53:37 -0600 Subject: [PATCH 135/272] Add configuration defaults for nextercism We will be moving to a tree-shaped track rather than a linear one, as described in the [progression & learning in Exercism](https://github.com/exercism/docs/blob/master/about/conception/progression.md) design document. In order to support this, we need to expand the metadata that exercises are configured with. Note that 'core' exercises are never unlocked by any other exercises. Core exercises appear in the track in the order that they are listed in the array. Non-core exercises depend on only one exercise (unlocked_by: ). At the moment we are assuming that this is a core exercise, but there is no reason that it needs to be. Until now we have operated with a separate deprecated array. These are now being moved into the exercises array with a deprecated field. With these defaults the track in nextercism will have no core exercises, and all the exercises will be available as 'extras' from the start. If you haven't already, now would be a good time to do the following: * add a rough estimate of difficulty to each exercise (scale: 1-10) * add topics to each exercise * choose *at most 20 exercises* to be core exercises (set core: true, and delete the unlocked_by key) * for each exercise that is not core, decide which exercise is the prerequisite (max 1) If possible, leave 3 or 4 simple exercises as (core: false, unlocked_by: null), as this will provide new participants with some exercises that they can tackle even if they have not finished the first core exercise. --- config.json | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 232 insertions(+), 4 deletions(-) diff --git a/config.json b/config.json index 99ed6dd2..0ac86b85 100644 --- a/config.json +++ b/config.json @@ -6,7 +6,10 @@ "test_pattern": ".*[.]spec[.]js$", "exercises": [ { + "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256", "slug": "hello-world", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Control-flow (conditionals)", @@ -16,7 +19,10 @@ ] }, { + "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b", "slug": "leap", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Booleans", @@ -25,7 +31,10 @@ ] }, { + "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0", "slug": "hamming", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Control-flow (loops)", @@ -35,7 +44,10 @@ ] }, { + "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c", "slug": "rna-transcription", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Strings", @@ -43,7 +55,10 @@ ] }, { + "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15", "slug": "pangram", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Control flow (conditionals)", @@ -56,7 +71,10 @@ ] }, { + "uuid": "246be5d9-b361-4893-9707-f218ede2bed6", "slug": "bob", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Control flow (conditionals)", @@ -68,14 +86,20 @@ ] }, { + "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44", "slug": "gigasecond", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Time" ] }, { + "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0", "slug": "isogram", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Strings", @@ -83,7 +107,10 @@ ] }, { + "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a", "slug": "beer-song", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Looping", @@ -92,7 +119,10 @@ ] }, { + "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70", "slug": "phone-number", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Parsing", @@ -100,7 +130,10 @@ ] }, { + "uuid": "432ec2ce-c919-4142-aea2-389b67503252", "slug": "anagram", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Strings", @@ -108,7 +141,10 @@ ] }, { + "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17", "slug": "food-chain", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Text formatting", @@ -116,63 +152,90 @@ ] }, { + "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec", "slug": "grade-school", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a", "slug": "robot-name", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a", "slug": "etl", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", "slug": "space-age", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda", "slug": "grains", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d", "slug": "triangle", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "1ff85150-6c51-4758-af02-4484cf35658e", "slug": "clock", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6", "slug": "perfect-numbers", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838", "slug": "word-count", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Control flow (loops)", @@ -183,161 +246,230 @@ ] }, { + "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b", "slug": "acronym", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b", "slug": "scrabble-score", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "4226e3c6-99d4-406d-998a-bcf11845b211", "slug": "roman-numerals", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc", "slug": "circular-buffer", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e", "slug": "binary", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f", "slug": "prime-factors", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d", "slug": "raindrops", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02", "slug": "allergies", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247", "slug": "strain", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "99974454-0736-4cc0-b88f-ed5701397a97", "slug": "atbash-cipher", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9", "slug": "accumulate", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad", "slug": "crypto-square", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d", "slug": "trinary", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32", "slug": "sieve", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af", "slug": "simple-cipher", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8", "slug": "octal", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c", "slug": "luhn", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38", "slug": "pig-latin", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6", "slug": "pythagorean-triplet", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5", "slug": "series", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f", "slug": "difference-of-squares", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0", "slug": "secret-handshake", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308", "slug": "proverb", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ "Arrays", @@ -345,189 +477,270 @@ ] }, { + "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385", "slug": "linked-list", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843", "slug": "wordy", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916", "slug": "flatten-array", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870", "slug": "hexadecimal", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c", "slug": "largest-series-product", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87", "slug": "kindergarten-garden", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8", "slug": "binary-search", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85", "slug": "binary-search-tree", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "fbfe6032-c209-40bd-b485-8b2881638166", "slug": "matrix", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad", "slug": "robot-simulator", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "8fa51380-ec2c-4806-8833-cf543579de17", "slug": "nth-prime", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1", "slug": "palindrome-products", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf", "slug": "pascals-triangle", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa", "slug": "say", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659", "slug": "custom-set", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "f30463c4-9d8c-4238-a691-e594291b4425", "slug": "sum-of-multiples", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "fefcfeba-59ec-4c63-a562-374201ee39a7", "slug": "queen-attack", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb", "slug": "saddle-points", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756", "slug": "ocr-numbers", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8", "slug": "meetup", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84", "slug": "bracket-push", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1", "slug": "two-bucket", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9", "slug": "bowling", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956", "slug": "diamond", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791", "slug": "all-your-base", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac", "slug": "run-length-encoding", + "core": false, + "unlocked_by": null, "difficulty": 1, "topics": [ ] }, { + "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3", "slug": "minesweeper", + "core": false, + "unlocked_by": null, "difficulty": 7, "topics": [ "games", @@ -536,7 +749,10 @@ ] }, { + "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a", "slug": "alphametics", + "core": false, + "unlocked_by": null, "difficulty": 7, "topics": [ "games", @@ -544,7 +760,10 @@ ] }, { + "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626", "slug": "simple-linked-list", + "core": false, + "unlocked_by": null, "difficulty": 8, "topics": [ "Arrays", @@ -553,19 +772,28 @@ ] }, { + "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c", "slug": "list-ops", + "core": false, + "unlocked_by": null, "difficulty": 8, "topics": [ "Data structures", "Lists", "Recursion" ] + }, + { + "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c", + "slug": "nucleotide-count", + "deprecated": true + }, + { + "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec", + "slug": "point-mutations", + "deprecated": true } ], - "deprecated": [ - "nucleotide-count", - "point-mutations" - ], "foregone": [ ] From 5ccb8d090108a56c12c6f54d367cead9cc0b8f68 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 16 Jul 2017 17:51:08 -0600 Subject: [PATCH 136/272] Generate exercise READMEs from templates (#380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add exercise README templates We are working towards making exercises stand-alone—that is to say: no more generating READMEs on the fly. This will give maintainers more control over each individual exercise README. The template uses the Go text/template package, and the default templates generate the exact same READMEs as we have been generating on the fly. * Generate the exercise READMEs from the new template --- config/exercise_readme.go.tmpl | 16 + exercises/accumulate/README.md | 59 ++++ exercises/acronym/README.md | 39 +++ exercises/all-your-base/README.md | 59 ++++ exercises/allergies/README.md | 61 ++++ exercises/alphametics/README.md | 59 ++++ exercises/anagram/README.md | 37 +++ exercises/atbash-cipher/README.md | 58 ++++ exercises/beer-song/README.md | 351 +++++++++++++++++++++ exercises/binary-search-tree/README.md | 84 +++++ exercises/binary-search/README.md | 65 ++++ exercises/binary/README.md | 59 ++++ exercises/bob/README.md | 42 +++ exercises/bowling/README.md | 77 +++++ exercises/bracket-push/README.md | 34 ++ exercises/circular-buffer/README.md | 74 +++++ exercises/clock/README.md | 37 +++ exercises/crypto-square/README.md | 98 ++++++ exercises/custom-set/README.md | 35 ++ exercises/diamond/README.md | 83 +++++ exercises/difference-of-squares/README.md | 43 +++ exercises/etl/README.md | 75 +++++ exercises/flatten-array/README.md | 42 +++ exercises/food-chain/README.md | 94 ++++++ exercises/gigasecond/README.md | 35 ++ exercises/grade-school/README.md | 66 ++++ exercises/grains/README.md | 58 ++++ exercises/hamming/README.md | 66 ++++ exercises/hello-world/README.md | 132 ++++++++ exercises/hexadecimal/README.md | 38 +++ exercises/isogram/README.md | 43 +++ exercises/kindergarten-garden/README.md | 90 ++++++ exercises/largest-series-product/README.md | 44 +++ exercises/leap/README.md | 57 ++++ exercises/linked-list/README.md | 58 ++++ exercises/list-ops/README.md | 34 ++ exercises/luhn/README.md | 95 ++++++ exercises/matrix/README.md | 69 ++++ exercises/meetup/README.md | 54 ++++ exercises/minesweeper/README.md | 54 ++++ exercises/nth-prime/README.md | 39 +++ exercises/nucleotide-count/README.md | 57 ++++ exercises/ocr-numbers/README.md | 109 +++++++ exercises/octal/README.md | 73 +++++ exercises/palindrome-products/README.md | 64 ++++ exercises/pangram/README.md | 39 +++ exercises/pascals-triangle/README.md | 45 +++ exercises/perfect-numbers/README.md | 48 +++ exercises/phone-number/README.md | 58 ++++ exercises/pig-latin/README.md | 48 +++ exercises/point-mutations/README.md | 65 ++++ exercises/prime-factors/README.md | 60 ++++ exercises/proverb/README.md | 42 +++ exercises/pythagorean-triplet/README.md | 48 +++ exercises/queen-attack/README.md | 57 ++++ exercises/raindrops/README.md | 48 +++ exercises/rna-transcription/README.md | 49 +++ exercises/robot-name/README.md | 46 +++ exercises/robot-simulator/README.md | 58 ++++ exercises/roman-numerals/README.md | 73 +++++ exercises/run-length-encoding/README.md | 54 ++++ exercises/saddle-points/README.md | 57 ++++ exercises/say/README.md | 93 ++++++ exercises/scrabble-score/README.md | 68 ++++ exercises/secret-handshake/README.md | 59 ++++ exercises/series/README.md | 51 +++ exercises/sieve/README.md | 58 ++++ exercises/simple-cipher/README.md | 114 +++++++ exercises/simple-linked-list/README.md | 52 +++ exercises/space-age/README.md | 48 +++ exercises/strain/README.md | 64 ++++ exercises/sum-of-multiples/README.md | 42 +++ exercises/triangle/README.md | 50 +++ exercises/trinary/README.md | 52 +++ exercises/two-bucket/README.md | 60 ++++ exercises/word-count/README.md | 43 +++ exercises/wordy/README.md | 87 +++++ 77 files changed, 4852 insertions(+) create mode 100644 config/exercise_readme.go.tmpl create mode 100644 exercises/accumulate/README.md create mode 100644 exercises/acronym/README.md create mode 100644 exercises/all-your-base/README.md create mode 100644 exercises/allergies/README.md create mode 100644 exercises/alphametics/README.md create mode 100644 exercises/anagram/README.md create mode 100644 exercises/atbash-cipher/README.md create mode 100644 exercises/beer-song/README.md create mode 100644 exercises/binary-search-tree/README.md create mode 100644 exercises/binary-search/README.md create mode 100644 exercises/binary/README.md create mode 100644 exercises/bob/README.md create mode 100644 exercises/bowling/README.md create mode 100644 exercises/bracket-push/README.md create mode 100644 exercises/circular-buffer/README.md create mode 100644 exercises/clock/README.md create mode 100644 exercises/crypto-square/README.md create mode 100644 exercises/custom-set/README.md create mode 100644 exercises/diamond/README.md create mode 100644 exercises/difference-of-squares/README.md create mode 100644 exercises/etl/README.md create mode 100644 exercises/flatten-array/README.md create mode 100644 exercises/food-chain/README.md create mode 100644 exercises/gigasecond/README.md create mode 100644 exercises/grade-school/README.md create mode 100644 exercises/grains/README.md create mode 100644 exercises/hamming/README.md create mode 100644 exercises/hello-world/README.md create mode 100644 exercises/hexadecimal/README.md create mode 100644 exercises/isogram/README.md create mode 100644 exercises/kindergarten-garden/README.md create mode 100644 exercises/largest-series-product/README.md create mode 100644 exercises/leap/README.md create mode 100644 exercises/linked-list/README.md create mode 100644 exercises/list-ops/README.md create mode 100644 exercises/luhn/README.md create mode 100644 exercises/matrix/README.md create mode 100644 exercises/meetup/README.md create mode 100644 exercises/minesweeper/README.md create mode 100644 exercises/nth-prime/README.md create mode 100644 exercises/nucleotide-count/README.md create mode 100644 exercises/ocr-numbers/README.md create mode 100644 exercises/octal/README.md create mode 100644 exercises/palindrome-products/README.md create mode 100644 exercises/pangram/README.md create mode 100644 exercises/pascals-triangle/README.md create mode 100644 exercises/perfect-numbers/README.md create mode 100644 exercises/phone-number/README.md create mode 100644 exercises/pig-latin/README.md create mode 100644 exercises/point-mutations/README.md create mode 100644 exercises/prime-factors/README.md create mode 100644 exercises/proverb/README.md create mode 100644 exercises/pythagorean-triplet/README.md create mode 100644 exercises/queen-attack/README.md create mode 100644 exercises/raindrops/README.md create mode 100644 exercises/rna-transcription/README.md create mode 100644 exercises/robot-name/README.md create mode 100644 exercises/robot-simulator/README.md create mode 100644 exercises/roman-numerals/README.md create mode 100644 exercises/run-length-encoding/README.md create mode 100644 exercises/saddle-points/README.md create mode 100644 exercises/say/README.md create mode 100644 exercises/scrabble-score/README.md create mode 100644 exercises/secret-handshake/README.md create mode 100644 exercises/series/README.md create mode 100644 exercises/sieve/README.md create mode 100644 exercises/simple-cipher/README.md create mode 100644 exercises/simple-linked-list/README.md create mode 100644 exercises/space-age/README.md create mode 100644 exercises/strain/README.md create mode 100644 exercises/sum-of-multiples/README.md create mode 100644 exercises/triangle/README.md create mode 100644 exercises/trinary/README.md create mode 100644 exercises/two-bucket/README.md create mode 100644 exercises/word-count/README.md create mode 100644 exercises/wordy/README.md diff --git a/config/exercise_readme.go.tmpl b/config/exercise_readme.go.tmpl new file mode 100644 index 00000000..2b26f494 --- /dev/null +++ b/config/exercise_readme.go.tmpl @@ -0,0 +1,16 @@ +# {{ .Spec.Name }} + +{{ .Spec.Description -}} +{{- with .Hints }} +{{ . }} +{{ end }} +{{- with .TrackInsert }} +{{ . }} +{{ end }} +{{- with .Spec.Credits -}} +## Source + +{{ . }} +{{ end }} +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/accumulate/README.md b/exercises/accumulate/README.md new file mode 100644 index 00000000..1f8e999f --- /dev/null +++ b/exercises/accumulate/README.md @@ -0,0 +1,59 @@ +# Accumulate + +Implement the `accumulate` operation, which, given a collection and an +operation to perform on each element of the collection, returns a new +collection containing the result of applying that operation to each element of +the input collection. + +Given the collection of numbers: + +- 1, 2, 3, 4, 5 + +And the operation: + +- square a number (`x => x * x`) + +Your code should be able to produce the collection of squares: + +- 1, 4, 9, 16, 25 + +Check out the test suite to see the expected function signature. + +## Restrictions + +Keep your hands off that collect/map/fmap/whatchamacallit functionality +provided by your standard library! +Solve this one yourself using other basic tools instead. + +Lisp specific: it's perfectly fine to use `MAPCAR` or the equivalent, +as this is idiomatic Lisp, not a library function. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Conversation with James Edward Gray II [https://twitter.com/jeg2](https://twitter.com/jeg2) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/acronym/README.md b/exercises/acronym/README.md new file mode 100644 index 00000000..3cc46d74 --- /dev/null +++ b/exercises/acronym/README.md @@ -0,0 +1,39 @@ +# Acronym + +Convert a phrase to its acronym. + +Techies love their TLA (Three Letter Acronyms)! + +Help generate some jargon by writing a program that converts a long name +like Portable Network Graphics to its acronym (PNG). + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Julien Vanier [https://github.com/monkbroc](https://github.com/monkbroc) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/all-your-base/README.md b/exercises/all-your-base/README.md new file mode 100644 index 00000000..5971b557 --- /dev/null +++ b/exercises/all-your-base/README.md @@ -0,0 +1,59 @@ +# All Your Base + +Convert a number, represented as a sequence of digits in one base, to any other base. + +Implement general base conversion. Given a number in base **a**, +represented as a sequence of digits, convert it to base **b**. + +## Note +- Try to implement the conversion yourself. + Do not use something else to perform the conversion for you. + +## About [Positional Notation](https://en.wikipedia.org/wiki/Positional_notation) + +In positional notation, a number in base **b** can be understood as a linear +combination of powers of **b**. + +The number 42, *in base 10*, means: + +(4 * 10^1) + (2 * 10^0) + +The number 101010, *in base 2*, means: + +(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0) + +The number 1120, *in base 3*, means: + +(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0) + +I think you got the idea! + + +*Yes. Those three numbers above are exactly the same. Congratulations!* + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/allergies/README.md b/exercises/allergies/README.md new file mode 100644 index 00000000..af0072d6 --- /dev/null +++ b/exercises/allergies/README.md @@ -0,0 +1,61 @@ +# Allergies + +Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. + +An allergy test produces a single numeric score which contains the +information about all the allergies the person has (that they were +tested for). + +The list of items (and their value) that were tested are: + +* eggs (1) +* peanuts (2) +* shellfish (4) +* strawberries (8) +* tomatoes (16) +* chocolate (32) +* pollen (64) +* cats (128) + +So if Tom is allergic to peanuts and chocolate, he gets a score of 34. + +Now, given just that score of 34, your program should be able to say: + +- Whether Tom is allergic to any one of those allergens listed above. +- All the allergens Tom is allergic to. + +Note: a given score may include allergens **not** listed above (i.e. +allergens that score 256, 512, 1024, etc.). Your program should +ignore those components of the score. For example, if the allergy +score is 257, your program should only report the eggs (1) allergy. + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Jumpstart Lab Warm-up [http://jumpstartlab.com](http://jumpstartlab.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/alphametics/README.md b/exercises/alphametics/README.md new file mode 100644 index 00000000..d96936f2 --- /dev/null +++ b/exercises/alphametics/README.md @@ -0,0 +1,59 @@ +# Alphametics + +Write a function to solve alphametics puzzles. + +[Alphametics](https://en.wikipedia.org/wiki/Alphametics) is a puzzle where +letters in words are replaced with numbers. + +For example `SEND + MORE = MONEY`: + +``` + S E N D + M O R E + +----------- +M O N E Y +``` + +Replacing these with valid numbers gives: + +``` + 9 5 6 7 + 1 0 8 5 + +----------- +1 0 6 5 2 +``` + +This is correct because every letter is replaced by a different number and the +words, translated into numbers, then make a valid sum. + +Each letter must represent a different digit, and the leading digit of +a multi-digit number must not be zero. + +Write a function to solve alphametics puzzles. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/anagram/README.md b/exercises/anagram/README.md new file mode 100644 index 00000000..f9b4bf5c --- /dev/null +++ b/exercises/anagram/README.md @@ -0,0 +1,37 @@ +# Anagram + +Given a word and a list of possible anagrams, select the correct sublist. + +Given `"listen"` and a list of candidates like `"enlists" "google" +"inlets" "banana"` the program should return a list containing +`"inlets"`. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/atbash-cipher/README.md b/exercises/atbash-cipher/README.md new file mode 100644 index 00000000..57634176 --- /dev/null +++ b/exercises/atbash-cipher/README.md @@ -0,0 +1,58 @@ +# Atbash Cipher + +Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East. + +The Atbash cipher is a simple substitution cipher that relies on +transposing all the letters in the alphabet such that the resulting +alphabet is backwards. The first letter is replaced with the last +letter, the second with the second-last, and so on. + +An Atbash cipher for the Latin alphabet would be as follows: + +```plain +Plain: abcdefghijklmnopqrstuvwxyz +Cipher: zyxwvutsrqponmlkjihgfedcba +``` + +It is a very weak cipher because it only has one possible key, and it is +a simple monoalphabetic substitution cipher. However, this may not have +been an issue in the cipher's time. + +Ciphertext is written out in groups of fixed length, the traditional group size +being 5 letters, and punctuation is excluded. This is to make it harder to guess +things based on word boundaries. + +## Examples +- Encoding `test` gives `gvhg` +- Decoding `gvhg` gives `test` +- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/Atbash](http://en.wikipedia.org/wiki/Atbash) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/beer-song/README.md b/exercises/beer-song/README.md new file mode 100644 index 00000000..57089d1d --- /dev/null +++ b/exercises/beer-song/README.md @@ -0,0 +1,351 @@ +# Beer Song + +Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall. + +Note that not all verses are identical. + +```plain +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. + +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. + +97 bottles of beer on the wall, 97 bottles of beer. +Take one down and pass it around, 96 bottles of beer on the wall. + +96 bottles of beer on the wall, 96 bottles of beer. +Take one down and pass it around, 95 bottles of beer on the wall. + +95 bottles of beer on the wall, 95 bottles of beer. +Take one down and pass it around, 94 bottles of beer on the wall. + +94 bottles of beer on the wall, 94 bottles of beer. +Take one down and pass it around, 93 bottles of beer on the wall. + +93 bottles of beer on the wall, 93 bottles of beer. +Take one down and pass it around, 92 bottles of beer on the wall. + +92 bottles of beer on the wall, 92 bottles of beer. +Take one down and pass it around, 91 bottles of beer on the wall. + +91 bottles of beer on the wall, 91 bottles of beer. +Take one down and pass it around, 90 bottles of beer on the wall. + +90 bottles of beer on the wall, 90 bottles of beer. +Take one down and pass it around, 89 bottles of beer on the wall. + +89 bottles of beer on the wall, 89 bottles of beer. +Take one down and pass it around, 88 bottles of beer on the wall. + +88 bottles of beer on the wall, 88 bottles of beer. +Take one down and pass it around, 87 bottles of beer on the wall. + +87 bottles of beer on the wall, 87 bottles of beer. +Take one down and pass it around, 86 bottles of beer on the wall. + +86 bottles of beer on the wall, 86 bottles of beer. +Take one down and pass it around, 85 bottles of beer on the wall. + +85 bottles of beer on the wall, 85 bottles of beer. +Take one down and pass it around, 84 bottles of beer on the wall. + +84 bottles of beer on the wall, 84 bottles of beer. +Take one down and pass it around, 83 bottles of beer on the wall. + +83 bottles of beer on the wall, 83 bottles of beer. +Take one down and pass it around, 82 bottles of beer on the wall. + +82 bottles of beer on the wall, 82 bottles of beer. +Take one down and pass it around, 81 bottles of beer on the wall. + +81 bottles of beer on the wall, 81 bottles of beer. +Take one down and pass it around, 80 bottles of beer on the wall. + +80 bottles of beer on the wall, 80 bottles of beer. +Take one down and pass it around, 79 bottles of beer on the wall. + +79 bottles of beer on the wall, 79 bottles of beer. +Take one down and pass it around, 78 bottles of beer on the wall. + +78 bottles of beer on the wall, 78 bottles of beer. +Take one down and pass it around, 77 bottles of beer on the wall. + +77 bottles of beer on the wall, 77 bottles of beer. +Take one down and pass it around, 76 bottles of beer on the wall. + +76 bottles of beer on the wall, 76 bottles of beer. +Take one down and pass it around, 75 bottles of beer on the wall. + +75 bottles of beer on the wall, 75 bottles of beer. +Take one down and pass it around, 74 bottles of beer on the wall. + +74 bottles of beer on the wall, 74 bottles of beer. +Take one down and pass it around, 73 bottles of beer on the wall. + +73 bottles of beer on the wall, 73 bottles of beer. +Take one down and pass it around, 72 bottles of beer on the wall. + +72 bottles of beer on the wall, 72 bottles of beer. +Take one down and pass it around, 71 bottles of beer on the wall. + +71 bottles of beer on the wall, 71 bottles of beer. +Take one down and pass it around, 70 bottles of beer on the wall. + +70 bottles of beer on the wall, 70 bottles of beer. +Take one down and pass it around, 69 bottles of beer on the wall. + +69 bottles of beer on the wall, 69 bottles of beer. +Take one down and pass it around, 68 bottles of beer on the wall. + +68 bottles of beer on the wall, 68 bottles of beer. +Take one down and pass it around, 67 bottles of beer on the wall. + +67 bottles of beer on the wall, 67 bottles of beer. +Take one down and pass it around, 66 bottles of beer on the wall. + +66 bottles of beer on the wall, 66 bottles of beer. +Take one down and pass it around, 65 bottles of beer on the wall. + +65 bottles of beer on the wall, 65 bottles of beer. +Take one down and pass it around, 64 bottles of beer on the wall. + +64 bottles of beer on the wall, 64 bottles of beer. +Take one down and pass it around, 63 bottles of beer on the wall. + +63 bottles of beer on the wall, 63 bottles of beer. +Take one down and pass it around, 62 bottles of beer on the wall. + +62 bottles of beer on the wall, 62 bottles of beer. +Take one down and pass it around, 61 bottles of beer on the wall. + +61 bottles of beer on the wall, 61 bottles of beer. +Take one down and pass it around, 60 bottles of beer on the wall. + +60 bottles of beer on the wall, 60 bottles of beer. +Take one down and pass it around, 59 bottles of beer on the wall. + +59 bottles of beer on the wall, 59 bottles of beer. +Take one down and pass it around, 58 bottles of beer on the wall. + +58 bottles of beer on the wall, 58 bottles of beer. +Take one down and pass it around, 57 bottles of beer on the wall. + +57 bottles of beer on the wall, 57 bottles of beer. +Take one down and pass it around, 56 bottles of beer on the wall. + +56 bottles of beer on the wall, 56 bottles of beer. +Take one down and pass it around, 55 bottles of beer on the wall. + +55 bottles of beer on the wall, 55 bottles of beer. +Take one down and pass it around, 54 bottles of beer on the wall. + +54 bottles of beer on the wall, 54 bottles of beer. +Take one down and pass it around, 53 bottles of beer on the wall. + +53 bottles of beer on the wall, 53 bottles of beer. +Take one down and pass it around, 52 bottles of beer on the wall. + +52 bottles of beer on the wall, 52 bottles of beer. +Take one down and pass it around, 51 bottles of beer on the wall. + +51 bottles of beer on the wall, 51 bottles of beer. +Take one down and pass it around, 50 bottles of beer on the wall. + +50 bottles of beer on the wall, 50 bottles of beer. +Take one down and pass it around, 49 bottles of beer on the wall. + +49 bottles of beer on the wall, 49 bottles of beer. +Take one down and pass it around, 48 bottles of beer on the wall. + +48 bottles of beer on the wall, 48 bottles of beer. +Take one down and pass it around, 47 bottles of beer on the wall. + +47 bottles of beer on the wall, 47 bottles of beer. +Take one down and pass it around, 46 bottles of beer on the wall. + +46 bottles of beer on the wall, 46 bottles of beer. +Take one down and pass it around, 45 bottles of beer on the wall. + +45 bottles of beer on the wall, 45 bottles of beer. +Take one down and pass it around, 44 bottles of beer on the wall. + +44 bottles of beer on the wall, 44 bottles of beer. +Take one down and pass it around, 43 bottles of beer on the wall. + +43 bottles of beer on the wall, 43 bottles of beer. +Take one down and pass it around, 42 bottles of beer on the wall. + +42 bottles of beer on the wall, 42 bottles of beer. +Take one down and pass it around, 41 bottles of beer on the wall. + +41 bottles of beer on the wall, 41 bottles of beer. +Take one down and pass it around, 40 bottles of beer on the wall. + +40 bottles of beer on the wall, 40 bottles of beer. +Take one down and pass it around, 39 bottles of beer on the wall. + +39 bottles of beer on the wall, 39 bottles of beer. +Take one down and pass it around, 38 bottles of beer on the wall. + +38 bottles of beer on the wall, 38 bottles of beer. +Take one down and pass it around, 37 bottles of beer on the wall. + +37 bottles of beer on the wall, 37 bottles of beer. +Take one down and pass it around, 36 bottles of beer on the wall. + +36 bottles of beer on the wall, 36 bottles of beer. +Take one down and pass it around, 35 bottles of beer on the wall. + +35 bottles of beer on the wall, 35 bottles of beer. +Take one down and pass it around, 34 bottles of beer on the wall. + +34 bottles of beer on the wall, 34 bottles of beer. +Take one down and pass it around, 33 bottles of beer on the wall. + +33 bottles of beer on the wall, 33 bottles of beer. +Take one down and pass it around, 32 bottles of beer on the wall. + +32 bottles of beer on the wall, 32 bottles of beer. +Take one down and pass it around, 31 bottles of beer on the wall. + +31 bottles of beer on the wall, 31 bottles of beer. +Take one down and pass it around, 30 bottles of beer on the wall. + +30 bottles of beer on the wall, 30 bottles of beer. +Take one down and pass it around, 29 bottles of beer on the wall. + +29 bottles of beer on the wall, 29 bottles of beer. +Take one down and pass it around, 28 bottles of beer on the wall. + +28 bottles of beer on the wall, 28 bottles of beer. +Take one down and pass it around, 27 bottles of beer on the wall. + +27 bottles of beer on the wall, 27 bottles of beer. +Take one down and pass it around, 26 bottles of beer on the wall. + +26 bottles of beer on the wall, 26 bottles of beer. +Take one down and pass it around, 25 bottles of beer on the wall. + +25 bottles of beer on the wall, 25 bottles of beer. +Take one down and pass it around, 24 bottles of beer on the wall. + +24 bottles of beer on the wall, 24 bottles of beer. +Take one down and pass it around, 23 bottles of beer on the wall. + +23 bottles of beer on the wall, 23 bottles of beer. +Take one down and pass it around, 22 bottles of beer on the wall. + +22 bottles of beer on the wall, 22 bottles of beer. +Take one down and pass it around, 21 bottles of beer on the wall. + +21 bottles of beer on the wall, 21 bottles of beer. +Take one down and pass it around, 20 bottles of beer on the wall. + +20 bottles of beer on the wall, 20 bottles of beer. +Take one down and pass it around, 19 bottles of beer on the wall. + +19 bottles of beer on the wall, 19 bottles of beer. +Take one down and pass it around, 18 bottles of beer on the wall. + +18 bottles of beer on the wall, 18 bottles of beer. +Take one down and pass it around, 17 bottles of beer on the wall. + +17 bottles of beer on the wall, 17 bottles of beer. +Take one down and pass it around, 16 bottles of beer on the wall. + +16 bottles of beer on the wall, 16 bottles of beer. +Take one down and pass it around, 15 bottles of beer on the wall. + +15 bottles of beer on the wall, 15 bottles of beer. +Take one down and pass it around, 14 bottles of beer on the wall. + +14 bottles of beer on the wall, 14 bottles of beer. +Take one down and pass it around, 13 bottles of beer on the wall. + +13 bottles of beer on the wall, 13 bottles of beer. +Take one down and pass it around, 12 bottles of beer on the wall. + +12 bottles of beer on the wall, 12 bottles of beer. +Take one down and pass it around, 11 bottles of beer on the wall. + +11 bottles of beer on the wall, 11 bottles of beer. +Take one down and pass it around, 10 bottles of beer on the wall. + +10 bottles of beer on the wall, 10 bottles of beer. +Take one down and pass it around, 9 bottles of beer on the wall. + +9 bottles of beer on the wall, 9 bottles of beer. +Take one down and pass it around, 8 bottles of beer on the wall. + +8 bottles of beer on the wall, 8 bottles of beer. +Take one down and pass it around, 7 bottles of beer on the wall. + +7 bottles of beer on the wall, 7 bottles of beer. +Take one down and pass it around, 6 bottles of beer on the wall. + +6 bottles of beer on the wall, 6 bottles of beer. +Take one down and pass it around, 5 bottles of beer on the wall. + +5 bottles of beer on the wall, 5 bottles of beer. +Take one down and pass it around, 4 bottles of beer on the wall. + +4 bottles of beer on the wall, 4 bottles of beer. +Take one down and pass it around, 3 bottles of beer on the wall. + +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. + +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. + +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. + +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. +``` + +## For bonus points + +Did you get the tests passing and the code clean? If you want to, these +are some additional things you could try: + +* Remove as much duplication as you possibly can. +* Optimize for readability, even if it means introducing duplication. +* If you've removed all the duplication, do you have a lot of + conditionals? Try replacing the conditionals with polymorphism, if it + applies in this language. How readable is it? + +Then please share your thoughts in a comment on the submission. Did this +experiment make the code better? Worse? Did you learn anything from it? + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Learn to Program by Chris Pine [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md new file mode 100644 index 00000000..5b864ebc --- /dev/null +++ b/exercises/binary-search-tree/README.md @@ -0,0 +1,84 @@ +# Binary Search Tree + +Insert and search for numbers in a binary tree. + +When we need to represent sorted data, an array does not make a good +data structure. + +Say we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes +`[1, 3, 4, 5, 2]` now we must sort the entire array again! We can +improve on this by realizing that we only need to make space for the new +item `[1, nil, 3, 4, 5]`, and then adding the item in the space we +added. But this still requires us to shift many elements down by one. + +Binary Search Trees, however, can operate on sorted data much more +efficiently. + +A binary search tree consists of a series of connected nodes. Each node +contains a piece of data (e.g. the number 3), a variable named `left`, +and a variable named `right`. The `left` and `right` variables point at +`nil`, or other nodes. Since these other nodes in turn have other nodes +beneath them, we say that the left and right variables are pointing at +subtrees. All data in the left subtree is less than or equal to the +current node's data, and all data in the right subtree is greater than +the current node's data. + +For example, if we had a node containing the data 4, and we added the +data 2, our tree would look like this: + + 4 + / + 2 + +If we then added 6, it would look like this: + + 4 + / \ + 2 6 + +If we then added 3, it would look like this + + 4 + / \ + 2 6 + \ + 3 + +And if we then added 1, 5, and 7, it would look like this + + 4 + / \ + / \ + 2 6 + / \ / \ + 1 3 5 7 + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Josh Cheek [https://twitter.com/josh_cheek](https://twitter.com/josh_cheek) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/binary-search/README.md b/exercises/binary-search/README.md new file mode 100644 index 00000000..2aa09ad1 --- /dev/null +++ b/exercises/binary-search/README.md @@ -0,0 +1,65 @@ +# Binary Search + +Implement a binary search algorithm. + +Searching a sorted collection is a common task. A dictionary is a sorted +list of word definitions. Given a word, one can find its definition. A +telephone book is a sorted list of people's names, addresses, and +telephone numbers. Knowing someone's name allows one to quickly find +their telephone number and address. + +If the list to be searched contains more than a few items (a dozen, say) +a binary search will require far fewer comparisons than a linear search, +but it imposes the requirement that the list be sorted. + +In computer science, a binary search or half-interval search algorithm +finds the position of a specified input value (the search "key") within +an array sorted by key value. + +In each step, the algorithm compares the search key value with the key +value of the middle element of the array. + +If the keys match, then a matching element has been found and its index, +or position, is returned. + +Otherwise, if the search key is less than the middle element's key, then +the algorithm repeats its action on the sub-array to the left of the +middle element or, if the search key is greater, on the sub-array to the +right. + +If the remaining array to be searched is empty, then the key cannot be +found in the array and a special "not found" indication is returned. + +A binary search halves the number of items to check with each iteration, +so locating an item (or determining its absence) takes logarithmic time. +A binary search is a dichotomic divide and conquer search algorithm. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/Binary_search_algorithm](http://en.wikipedia.org/wiki/Binary_search_algorithm) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/binary/README.md b/exercises/binary/README.md new file mode 100644 index 00000000..c41024b0 --- /dev/null +++ b/exercises/binary/README.md @@ -0,0 +1,59 @@ +# Binary + +Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles. + +Implement binary to decimal conversion. Given a binary input +string, your program should produce a decimal output. The +program should handle invalid inputs. + +## Note +- Implement the conversion yourself. + Do not use something else to perform the conversion for you. + +## About Binary (Base-2) +Decimal is a base-10 system. + +A number 23 in base 10 notation can be understood +as a linear combination of powers of 10: + +- The rightmost digit gets multiplied by 10^0 = 1 +- The next number gets multiplied by 10^1 = 10 +- ... +- The *n*th number gets multiplied by 10^*(n-1)*. +- All these values are summed. + +So: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10` + +Binary is similar, but uses powers of 2 rather than powers of 10. + +So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/bob/README.md b/exercises/bob/README.md new file mode 100644 index 00000000..b53ec785 --- /dev/null +++ b/exercises/bob/README.md @@ -0,0 +1,42 @@ +# Bob + +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. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md new file mode 100644 index 00000000..b8342c33 --- /dev/null +++ b/exercises/bowling/README.md @@ -0,0 +1,77 @@ +# Bowling + +Score a bowling game. + +Bowling is game where players roll a heavy ball to knock down pins +arranged in a triangle. Write code to keep track of the score +of a game of bowling. + +## Scoring Bowling + +The game consists of 10 frames. A frame is composed of one or two ball throws with 10 pins standing at frame initialization. There are three cases for the tabulation of a frame. + +* An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down. + +* A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in their next throw. + +* A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in their next two throws. If a strike is immediately followed by a second strike, then we can not total the value of first strike until they throw the ball one more time. + +Here is a three frame example: + +| Frame 1 | Frame 2 | Frame 3 | +| :-------------: |:-------------:| :---------------------:| +| X (strike) | 5/ (spare) | 9 0 (open frame) | + +Frame 1 is (10 + 5 + 5) = 20 + +Frame 2 is (5 + 5 + 9) = 19 + +Frame 3 is (9 + 0) = 9 + +This means the current running total is 48. + +The tenth frame in the game is a special case. If someone throws a strike or a spare then they get a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. + +For a tenth frame of X1/ (strike and a spare), the total value is 20. + +For a tenth frame of XXX (three strikes), the total value is 30. + +## Requirements + +Write code to keep track of the score of a game of bowling. It should +support two operations: + +* `roll(pins : int)` is called each time the player rolls a ball. The + argument is the number of pins knocked down. +* `score() : int` is called only at the very end of the game. It + returns the total score for that game. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Bowling Game Kata at but UncleBob [http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata](http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/bracket-push/README.md b/exercises/bracket-push/README.md new file mode 100644 index 00000000..0496d2f1 --- /dev/null +++ b/exercises/bracket-push/README.md @@ -0,0 +1,34 @@ +# Bracket Push + +Given a string containing brackets `[]`, braces `{}` and parentheses `()`, +verify that all the pairs are matched and nested correctly. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Ginna Baker + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/circular-buffer/README.md b/exercises/circular-buffer/README.md new file mode 100644 index 00000000..14f497e5 --- /dev/null +++ b/exercises/circular-buffer/README.md @@ -0,0 +1,74 @@ +# Circular Buffer + +A circular buffer, cyclic buffer or ring buffer is a data structure that +uses a single, fixed-size buffer as if it were connected end-to-end. + +A circular buffer first starts empty and of some predefined length. For +example, this is a 7-element buffer: + + [ ][ ][ ][ ][ ][ ][ ] + +Assume that a 1 is written into the middle of the buffer (exact starting +location does not matter in a circular buffer): + + [ ][ ][ ][1][ ][ ][ ] + +Then assume that two more elements are added — 2 & 3 — which get +appended after the 1: + + [ ][ ][ ][1][2][3][ ] + +If two elements are then removed from the buffer, the oldest values +inside the buffer are removed. The two elements removed, in this case, +are 1 & 2, leaving the buffer with just a 3: + + [ ][ ][ ][ ][ ][3][ ] + +If the buffer has 7 elements then it is completely full: + + [6][7][8][9][3][4][5] + +When the buffer is full an error will be raised, alerting the client +that further writes are blocked until a slot becomes free. + +The client can opt to overwrite the oldest data with a forced write. In +this case, two more elements — A & B — are added and they overwrite the +3 & 4: + + [6][7][8][9][A][B][5] + +Finally, if two elements are now removed then what would be returned is +not 3 & 4 but 5 & 6 because A & B overwrote the 3 & the 4 yielding the +buffer with: + + [ ][7][8][9][A][B][ ] + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/Circular_buffer](http://en.wikipedia.org/wiki/Circular_buffer) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/clock/README.md b/exercises/clock/README.md new file mode 100644 index 00000000..0427655d --- /dev/null +++ b/exercises/clock/README.md @@ -0,0 +1,37 @@ +# Clock + +Implement a clock that handles times without dates. + +You should be able to add and subtract minutes to it. + +Two clocks that represent the same time should be equal to each other. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Pairing session with Erin Drummond [https://twitter.com/ebdrummond](https://twitter.com/ebdrummond) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/crypto-square/README.md b/exercises/crypto-square/README.md new file mode 100644 index 00000000..515f68f2 --- /dev/null +++ b/exercises/crypto-square/README.md @@ -0,0 +1,98 @@ +# Crypto Square + +Implement the classic method for composing secret messages called a square code. + +Given an English text, output the encoded version of that text. + +First, the input is normalized: the spaces and punctuation are removed +from the English text and the message is downcased. + +Then, the normalized characters are broken into rows. These rows can be +regarded as forming a rectangle when printed with intervening newlines. + +For example, the sentence + +> If man was meant to stay on the ground, god would have given us roots. + +is normalized to: + +> ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots + +The plaintext should be organized in to a rectangle. The size of the +rectangle (`r x c`) should be decided by the length of the message, +such that `c >= r` and `c - r <= 1`, where `c` is the number of columns +and `r` is the number of rows. + +Our normalized text is 54 characters long, dictating a rectangle with +`c = 8` and `r = 7`: + +```plain +ifmanwas +meanttos +tayonthe +groundgo +dwouldha +vegivenu +sroots +``` + +The coded message is obtained by reading down the columns going left to +right. + +The message above is coded as: + +```plain +imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau +``` + +Output the encoded text in chunks. Phrases that fill perfect squares +`(r X r)` should be output in `r`-length chunks separated by spaces. +Imperfect squares will have `n` empty spaces. Those spaces should be distributed evenly across the last `n` rows. + +```plain +imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau +``` + +Notice that were we to stack these, we could visually decode the +cyphertext back in to the original message: + +```plain +imtgdvs +fearwer +mayoogo +anouuio +ntnnlvt +wttddes +aohghn +sseoau +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +J Dalbey's Programming Practice problems [http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/custom-set/README.md b/exercises/custom-set/README.md new file mode 100644 index 00000000..765ce0be --- /dev/null +++ b/exercises/custom-set/README.md @@ -0,0 +1,35 @@ +# Custom Set + +Create a custom set type. + +Sometimes it is necessary to define a custom data structure of some +type, like a set. In this exercise you will define your own set. How it +works internally doesn't matter, as long as it behaves like a set of +unique elements. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/diamond/README.md b/exercises/diamond/README.md new file mode 100644 index 00000000..6dab43a6 --- /dev/null +++ b/exercises/diamond/README.md @@ -0,0 +1,83 @@ +# Diamond + +The diamond kata takes as its input a letter, and outputs it in a diamond +shape. Given a letter, it prints a diamond starting with 'A', with the +supplied letter at the widest point. + +## Requirements + +* The first row contains one 'A'. +* The last row contains one 'A'. +* All rows, except the first and last, have exactly two identical letters. +* All rows have as many trailing spaces as leading spaces. (This might be 0). +* The diamond is horizontally symmetric. +* The diamond is vertically symmetric. +* The diamond has a square shape (width equals height). +* The letters form a diamond shape. +* The top half has the letters in ascending order. +* The bottom half has the letters in descending order. +* The four corners (containing the spaces) are triangles. + +## Examples + +In the following examples, spaces are indicated by `·` characters. + +Diamond for letter 'A': + +```plain +A +``` + +Diamond for letter 'C': + +```plain +··A·· +·B·B· +C···C +·B·B· +··A·· +``` + +Diamond for letter 'E': + +```plain +····A···· +···B·B··· +··C···C·· +·D·····D· +E·······E +·D·····D· +··C···C·· +···B·B··· +····A···· +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Seb Rose [http://claysnow.co.uk/recycling-tests-in-tdd/](http://claysnow.co.uk/recycling-tests-in-tdd/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/difference-of-squares/README.md b/exercises/difference-of-squares/README.md new file mode 100644 index 00000000..5d05e84a --- /dev/null +++ b/exercises/difference-of-squares/README.md @@ -0,0 +1,43 @@ +# Difference Of Squares + +Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. + +The square of the sum of the first ten natural numbers is +(1 + 2 + ... + 10)² = 55² = 3025. + +The sum of the squares of the first ten natural numbers is +1² + 2² + ... + 10² = 385. + +Hence the difference between the square of the sum of the first +ten natural numbers and the sum of the squares of the first ten +natural numbers is 3025 - 385 = 2640. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Problem 6 at Project Euler [http://projecteuler.net/problem=6](http://projecteuler.net/problem=6) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/etl/README.md b/exercises/etl/README.md new file mode 100644 index 00000000..3cbb4ed5 --- /dev/null +++ b/exercises/etl/README.md @@ -0,0 +1,75 @@ +# Etl + +We are going to do the `Transform` step of an Extract-Transform-Load. + +### ETL +Extract-Transform-Load (ETL) is a fancy way of saying, "We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so +we're going to migrate this." + +(Typically, this is followed by, "We're only going to need to run this +once." That's then typically followed by much forehead slapping and +moaning about how stupid we could possibly be.) + +### The goal +We're going to extract some scrabble scores from a legacy system. + +The old system stored a list of letters per score: + +- 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T", +- 2 points: "D", "G", +- 3 points: "B", "C", "M", "P", +- 4 points: "F", "H", "V", "W", "Y", +- 5 points: "K", +- 8 points: "J", "X", +- 10 points: "Q", "Z", + +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: + +- "a" is worth 1 point. +- "b" is worth 3 points. +- "c" is worth 3 points. +- "d" is worth 2 points. +- Etc. + +Your mission, should you choose to accept it, is to transform the legacy data +format to the shiny new format. + +### Notes + +A final note about scoring, Scrabble is played around the world in a +variety of languages, each with its own unique scoring table. For +example, an "E" is scored at 2 in the Māori-language version of the +game while being scored at 4 in the Hawaiian-language version. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Jumpstart Lab team [http://jumpstartlab.com](http://jumpstartlab.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/flatten-array/README.md b/exercises/flatten-array/README.md new file mode 100644 index 00000000..bdb7ff67 --- /dev/null +++ b/exercises/flatten-array/README.md @@ -0,0 +1,42 @@ +# Flatten Array + +Take a nested list and return a single flattened list with all values except nil/null. + +The challenge is to write a function that accepts an arbitrarily-deep nested list-like structure and returns a flattened structure without any nil/null values. + +For Example + +input: [1,[2,3,null,4],[null],5] + +output: [1,2,3,4,5] + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Interview Question [https://reference.wolfram.com/language/ref/Flatten.html](https://reference.wolfram.com/language/ref/Flatten.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/food-chain/README.md b/exercises/food-chain/README.md new file mode 100644 index 00000000..9386f059 --- /dev/null +++ b/exercises/food-chain/README.md @@ -0,0 +1,94 @@ +# Food Chain + +Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'. + +While you could copy/paste the lyrics, +or read them from a file, this problem is much more +interesting if you approach it algorithmically. + +This is a [cumulative song](http://en.wikipedia.org/wiki/Cumulative_song) of unknown origin. + +This is one of many common variants. + +```plain +I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +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. + +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. + +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. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +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. +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. + +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. +She swallowed the cat to catch the 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. + +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. +She swallowed the dog to catch the 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. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a horse. +She's dead, of course! +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly](http://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/gigasecond/README.md b/exercises/gigasecond/README.md new file mode 100644 index 00000000..4c73cb89 --- /dev/null +++ b/exercises/gigasecond/README.md @@ -0,0 +1,35 @@ +# Gigasecond + +Calculate the moment when someone has lived for 10^9 seconds. + +A gigasecond is 10^9 (1,000,000,000) seconds. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Chapter 9 in Chris Pine's online Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=09](http://pine.fm/LearnToProgram/?Chapter=09) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/grade-school/README.md b/exercises/grade-school/README.md new file mode 100644 index 00000000..9a34bb7e --- /dev/null +++ b/exercises/grade-school/README.md @@ -0,0 +1,66 @@ +# Grade School + +Given students' names along with the grade that they are in, create a roster +for the school. + +In the end, you should be able to: + +- Add a student's name to the roster for a grade + - "Add Jim to grade 2." + - "OK." +- Get a list of all students enrolled in a grade + - "Which students are in grade 2?" + - "We've only got Jim just now." +- Get a sorted list of all students in all grades. Grades should sort + 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…" + +Note that all our students only have one name. (It's a small town, what +do you want?) + + +## For bonus points + +Did you get the tests passing and the code clean? If you want to, these +are some additional things you could try: + +- If you're working in a language with mutable data structures and your + implementation allows outside code to mutate the school's internal DB + directly, see if you can prevent this. Feel free to introduce additional + tests. + +Then please share your thoughts in a comment on the submission. Did this +experiment make the code better? Worse? Did you learn anything from it? + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/grains/README.md b/exercises/grains/README.md new file mode 100644 index 00000000..bac15508 --- /dev/null +++ b/exercises/grains/README.md @@ -0,0 +1,58 @@ +# Grains + +Calculate the number of grains of wheat on a chessboard given that the number +on each square doubles. + +There once was a wise servant who saved the life of a prince. The king +promised to pay whatever the servant could dream up. Knowing that the +king loved chess, the servant told the king he would like to have grains +of wheat. One grain on the first square of a chess board. Two grains on +the next. Four on the third, and so on. + +There are 64 squares on a chessboard. + +Write code that shows: +- how many grains were on each square, and +- the total number of grains + + +## For bonus points + +Did you get the tests passing and the code clean? If you want to, these +are some additional things you could try: + +- Optimize for speed. +- Optimize for readability. + +Then please share your thoughts in a comment on the submission. Did this +experiment make the code better? Worse? Did you learn anything from it? + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +JavaRanch Cattle Drive, exercise 6 [http://www.javaranch.com/grains.jsp](http://www.javaranch.com/grains.jsp) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/hamming/README.md b/exercises/hamming/README.md new file mode 100644 index 00000000..f44a9feb --- /dev/null +++ b/exercises/hamming/README.md @@ -0,0 +1,66 @@ +# Hamming + +Calculate the Hamming difference between two DNA strands. + +A mutation is simply a mistake that occurs during the creation or +copying of a nucleic acid, in particular DNA. Because nucleic acids are +vital to cellular functions, mutations tend to cause a ripple effect +throughout the cell. Although mutations are technically mistakes, a very +rare mutation may equip the cell with a beneficial attribute. In fact, +the macro effects of evolution are attributable by the accumulated +result of beneficial microscopic mutations over many generations. + +The simplest and most common type of nucleic acid mutation is a point +mutation, which replaces one base with another at a single nucleotide. + +By counting the number of differences between two homologous DNA strands +taken from different genomes with a common ancestor, we get a measure of +the minimum number of point mutations that could have occurred on the +evolutionary path between the two strands. + +This is called the 'Hamming distance'. + +It is found by comparing two DNA strands and counting how many of the +nucleotides are different from their equivalent in the other string. + + GAGCCTACTAACGGGAT + CATCGTAATGACGGCCT + ^ ^ ^ ^ ^ ^^ + +The Hamming distance between these two DNA strands is 7. + +# Implementation notes + +The Hamming distance is only defined for sequences of equal length. This means +that based on the definition, each language could deal with getting sequences +of equal length differently. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/hello-world/README.md b/exercises/hello-world/README.md new file mode 100644 index 00000000..7e71e8a7 --- /dev/null +++ b/exercises/hello-world/README.md @@ -0,0 +1,132 @@ +# Hello World + +The classical introductory exercise. Just say "Hello, World!". + +["Hello, World!"](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) is +the traditional first program for beginning programming in a new language +or environment. + +The objectives are simple: + +- Write a function that returns the string "Hello, World!". +- Run the test suite and make sure that it succeeds. +- Submit your solution and check it at the website. + +If everything goes well, you will be ready to fetch your first real exercise. + +## Tutorial + +This exercise has two files: + +- hello-world.js +- hello-world.spec.js + +The first file is where you will write your code. +The second is where the tests are defined. + +The tests will check whether your code is doing the right thing. +You don't need to be able to write a test suite from scratch, +but it helps to understand what a test looks like, and what +it is doing. + +Open up the test file, hello-world.spec.js. +There is one test inside: + + it('says hello world', function() { + expect(helloWorld.hello()).toEqual('Hello, World!'); + }); + +Run the test now, with the following command on the command-line: + + jasmine hello-world.spec.js + +The test fails, which makes sense since you've not written any code yet. + +The failure looks like this: + + 1) Hello World says hello world + Message: + Expected undefined to equal 'Hello, World!'. + +There's more, but this is the most important part. + +Take a look at that first line: + + 1) Hello World says hello world + +Now look at the test definition again: + + it('says hello world', function() { + // ... more code here ... + }); + +The text 'says hello world' is repeated. +This is how you know the test failed. + +The failure message explains what is wrong: + + Expected undefined to equal 'Hello, World!'. + +This comes from the part of the test definition that says "expect": + + expect(helloWorld.hello()).toEqual('Hello, World!'); + +It's comparing two values. It is calling + + helloWorld.hello() + +and comparing the result to a hard-coded string. + + 'Hello, World!'. + +So if you look at the failure message again, the hello function +is returning undefined. + +Try changing the function in hello-world.js so that it says + + HelloWorld.prototype.hello = function(input) { + return "chocolate"; + }; + +Then run the tests again from the command-line: + + jasmine hello-world.spec.js + +Notice how it changes the failure message. + +Then change the implementation in hello-world.js again, this time to make the test pass. + +When you are done, submit your solution to exercism: + + exercism submit hello-world.js + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +This is an exercise to introduce users to using Exercism [http://en.wikipedia.org/wiki/%22Hello,_world!%22_program](http://en.wikipedia.org/wiki/%22Hello,_world!%22_program) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/hexadecimal/README.md b/exercises/hexadecimal/README.md new file mode 100644 index 00000000..022fe2bf --- /dev/null +++ b/exercises/hexadecimal/README.md @@ -0,0 +1,38 @@ +# Hexadecimal + +Convert a hexadecimal number, represented as a string (e.g. "10af8c"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion). + +On the web we use hexadecimal to represent colors, e.g. green: 008000, +teal: 008080, navy: 000080). + +The program should handle invalid hexadecimal strings. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +All of Computer Science [http://www.wolframalpha.com/examples/NumberBases.html](http://www.wolframalpha.com/examples/NumberBases.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/isogram/README.md b/exercises/isogram/README.md new file mode 100644 index 00000000..369373af --- /dev/null +++ b/exercises/isogram/README.md @@ -0,0 +1,43 @@ +# Isogram + +Determine if a word or phrase is an isogram. + +An isogram (also known as a "nonpattern word") is a word or phrase without a repeating letter. + +Examples of isograms: + +- lumberjacks +- background +- downstream + +The word *isograms*, however, is not an isogram, because the s repeats. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Isogram](https://en.wikipedia.org/wiki/Isogram) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/kindergarten-garden/README.md b/exercises/kindergarten-garden/README.md new file mode 100644 index 00000000..15e4187d --- /dev/null +++ b/exercises/kindergarten-garden/README.md @@ -0,0 +1,90 @@ +# Kindergarten Garden + +Given a diagram, determine which plants each child in the kindergarten class is +responsible for. + +The kindergarten class is learning about growing plants. The teachers +thought it would be a good idea to give them actual seeds, plant them in +actual dirt, and grow actual plants. + +They've chosen to grow grass, clover, radishes, and violets. + +To this end, they've put little styrofoam cups along the window sills, +and planted one type of plant in each cup, choosing randomly from the +available types of seeds. + +```plain +[window][window][window] +........................ # each dot represents a styrofoam cup +........................ +``` + +There are 12 children in the class: + +- Alice, Bob, Charlie, David, +- Eve, Fred, Ginny, Harriet, +- Ileana, Joseph, Kincaid, and Larry. + +Each child gets 4 cups, two on each row. The children are assigned to +cups in alphabetical order. + +The following diagram represents Alice's plants: + +```plain +[window][window][window] +VR...................... +RG...................... +``` + +So in the row nearest the window, she has a violet and a radish; in the +row behind that, she has a radish and some grass. + +Your program will be given the plants from left-to-right starting with +the row nearest the windows. From this, it should be able to determine +which plants belong to which students. + +For example, if it's told that the garden looks like so: + +```plain +[window][window][window] +VRCGVVRVCGGCCGVRGCVCGCGV +VRCCCGCRRGVCGCRVVCVGCGCV +``` + +Then if asked for Alice's plants, it should provide: + +- Violets, radishes, violets, radishes + +While asking for Bob's plants would yield: + +- Clover, grass, clover, clover + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Random musings during airplane trip. [http://jumpstartlab.com](http://jumpstartlab.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/largest-series-product/README.md b/exercises/largest-series-product/README.md new file mode 100644 index 00000000..1d56a017 --- /dev/null +++ b/exercises/largest-series-product/README.md @@ -0,0 +1,44 @@ +# Largest Series Product + +Given a string of digits, calculate the largest product for a contiguous +substring of digits of length n. + +For example, for the input `'1027839564'`, the largest product for a +series of 3 digits is 270 (9 * 5 * 6), and the largest product for a +series of 5 digits is 7560 (7 * 8 * 3 * 9 * 5). + +Note that these series are only required to occupy *adjacent positions* +in the input; the digits need not be *numerically consecutive*. + +For the input `'73167176531330624919225119674426574742355349194934'`, +the largest product for a series of 6 digits is 23520. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A variation on Problem 8 at Project Euler [http://projecteuler.net/problem=8](http://projecteuler.net/problem=8) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/leap/README.md b/exercises/leap/README.md new file mode 100644 index 00000000..8f87cfcb --- /dev/null +++ b/exercises/leap/README.md @@ -0,0 +1,57 @@ +# Leap + +Given a year, report if it is a leap year. + +The tricky thing here is that a leap year in the Gregorian calendar occurs: + +```plain +on every year that is evenly divisible by 4 + except every year that is evenly divisible by 100 + unless the year is also evenly divisible by 400 +``` + +For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap +year, but 2000 is. + +If your language provides a method in the standard library that does +this look-up, pretend it doesn't exist and implement it yourself. + +## Notes + +Though our exercise adopts some very simple rules, there is more to +learn! + +For a delightful, four minute explanation of the whole leap year +phenomenon, go watch [this youtube video][video]. + +[video]: http://www.youtube.com/watch?v=xX96xng7sAE + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +JavaRanch Cattle Drive, exercise 3 [http://www.javaranch.com/leap.jsp](http://www.javaranch.com/leap.jsp) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/linked-list/README.md b/exercises/linked-list/README.md new file mode 100644 index 00000000..d719f252 --- /dev/null +++ b/exercises/linked-list/README.md @@ -0,0 +1,58 @@ +# Linked List + +Implement a doubly linked list. + +Like an array, a linked list is a simple linear data structure. Several +common data types can be implemented using linked lists, like queues, +stacks, and associative arrays. + +A linked list is a collection of data elements called *nodes*. In a +*singly linked list* each node holds a value and a link to the next node. +In a *doubly linked list* each node also holds a link to the previous +node. + +You will write an implementation of a doubly linked list. Implement a +Node to hold a value and pointers to the next and previous nodes. Then +implement a List which holds references to the first and last node and +offers an array-like interface for adding and removing items: + +* `push` (*insert value at back*); +* `pop` (*remove value at back*); +* `shift` (*remove value at front*). +* `unshift` (*insert value at front*); + +To keep your implementation simple, the tests will not cover error +conditions. Specifically: `pop` or `shift` will never be called on an +empty list. + +If you want to know more about linked lists, check [Wikipedia](https://en.wikipedia.org/wiki/Linked_list). + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Classic computer science topic + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/list-ops/README.md b/exercises/list-ops/README.md new file mode 100644 index 00000000..cfbf36e6 --- /dev/null +++ b/exercises/list-ops/README.md @@ -0,0 +1,34 @@ +# List Ops + +Implement basic list operations. + +In functional languages list operations like `length`, `map`, and +`reduce` are very common. Implement a series of basic list operations, +without using existing functions. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/luhn/README.md b/exercises/luhn/README.md new file mode 100644 index 00000000..217faccc --- /dev/null +++ b/exercises/luhn/README.md @@ -0,0 +1,95 @@ +# Luhn + +Given a number determine whether or not it is valid per the Luhn formula. + +The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is +a simple checksum formula used to validate a variety of identification +numbers, such as credit card numbers and Canadian Social Insurance +Numbers. + +The task is to check if a given string is valid. + +Validating a Number +------ + +Strings of length 1 or less are not valid. Spaces are allowed in the input, +but they should be stripped before checking. All other non-digit characters +are disallowed. + +## Example 1: valid credit card number + +``` +4539 1488 0343 6467 +``` + +The first step of the Luhn algorithm is to double every second digit, +starting from the right. We will be doubling + +``` +4_3_ 1_8_ 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: + +``` +8569 2478 0383 3437 +``` + +Then sum all of the digits: + +``` +8+5+6+9+2+4+7+8+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! + +## Example 2: invalid credit card number + +``` +8273 1232 7352 0569 +``` + +Double the second digits, starting from the right + +``` +7253 2262 5312 0539 +``` + +Sum the digits + +``` +7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57 +``` + +57 is not evenly divisible by 10, so this number is not valid. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Luhn Algorithm on Wikipedia [http://en.wikipedia.org/wiki/Luhn_algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/matrix/README.md b/exercises/matrix/README.md new file mode 100644 index 00000000..3b427e26 --- /dev/null +++ b/exercises/matrix/README.md @@ -0,0 +1,69 @@ +# Matrix + +Given a string representing a matrix of numbers, return the rows and columns of +that matrix. + +So given a string with embedded newlines like: + +> 9 8 7 +> 5 3 2 +> 6 6 7 + +representing this matrix: + +```plain + 0 1 2 + |--------- +0 | 9 8 7 +1 | 5 3 2 +2 | 6 6 7 +``` + +your code should be able to spit out: + +- A list of the rows, reading each row left-to-right while moving + top-to-bottom across the rows, +- A list of the columns, reading each column top-to-bottom while moving + from left-to-right. + +The rows for our example matrix: + +- 9, 8, 7 +- 5, 3, 2 +- 6, 6, 7 + +And its columns: + +- 9, 5, 6 +- 8, 3, 6 +- 7, 2, 7 + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Warmup to the `saddle-points` warmup. [http://jumpstartlab.com](http://jumpstartlab.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/meetup/README.md b/exercises/meetup/README.md new file mode 100644 index 00000000..fb20f112 --- /dev/null +++ b/exercises/meetup/README.md @@ -0,0 +1,54 @@ +# Meetup + +Calculate the date of meetups. + +Typically meetups happen on the same day of the week. In this exercise, you will take +a description of a meetup date, and return the actual meetup date. + +Examples of general descriptions are: + +- the first Monday of January 2017 +- the third Tuesday of January 2017 +- the Wednesteenth of January 2017 +- the last Thursday of January 2017 + +Note that "Monteenth", "Tuesteenth", etc are all made up words. There +was a meetup whose members realized that there are exactly 7 numbered days in a month that +end in '-teenth'. Therefore, one is guaranteed that each day of the week +(Monday, Tuesday, ...) will have exactly one date that is named with '-teenth' +in every month. + +Given examples of a meetup dates, each containing a month, day, year, and descriptor +(first, second, teenth, etc), calculate the date of the actual meetup. +For example, if given "First Monday of January 2017", the correct meetup date is 2017/1/2 + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month [https://twitter.com/copiousfreetime](https://twitter.com/copiousfreetime) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/minesweeper/README.md b/exercises/minesweeper/README.md new file mode 100644 index 00000000..6b0e55de --- /dev/null +++ b/exercises/minesweeper/README.md @@ -0,0 +1,54 @@ +# Minesweeper + +Add the numbers to a 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 | + +-----+ + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/nth-prime/README.md b/exercises/nth-prime/README.md new file mode 100644 index 00000000..84bae01d --- /dev/null +++ b/exercises/nth-prime/README.md @@ -0,0 +1,39 @@ +# Nth Prime + +Given a number n, determine what the nth prime is. + +By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that +the 6th prime is 13. + +If your language provides methods in the standard library to deal with prime +numbers, pretend they don't exist and implement them yourself. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A variation on Problem 7 at Project Euler [http://projecteuler.net/problem=7](http://projecteuler.net/problem=7) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/nucleotide-count/README.md b/exercises/nucleotide-count/README.md new file mode 100644 index 00000000..8f0622dc --- /dev/null +++ b/exercises/nucleotide-count/README.md @@ -0,0 +1,57 @@ +# Nucleotide Count + +Given a DNA string, compute how many times each nucleotide occurs in the string. + +DNA is represented by an alphabet of the following symbols: 'A', 'C', +'G', and 'T'. + +Each symbol represents a nucleotide, which is a fancy name for the +particular molecules that happen to make up a large part of DNA. + +Shortest intro to biochemistry EVAR: + +- twigs are to birds nests as +- nucleotides are to DNA and RNA as +- amino acids are to proteins as +- sugar is to starch as +- oh crap lipids + +I'm not going to talk about lipids because they're crazy complex. + +So back to nucleotides. + +DNA contains four types of them: adenine (`A`), cytosine (`C`), guanine +(`G`), and thymine (`T`). + +RNA contains a slightly different set of nucleotides, but we don't care +about that for now. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Calculating DNA Nucleotides_problem at Rosalind [http://rosalind.info/problems/dna/](http://rosalind.info/problems/dna/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/ocr-numbers/README.md b/exercises/ocr-numbers/README.md new file mode 100644 index 00000000..0a7e5338 --- /dev/null +++ b/exercises/ocr-numbers/README.md @@ -0,0 +1,109 @@ +# Ocr Numbers + +Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is +represented, or whether it is garbled. + +# Step One + +To begin with, convert a simple binary font to a string containing 0 or 1. + +The binary font uses pipes and underscores, four rows high and three columns wide. + +``` + _ # + | | # zero. + |_| # + # the fourth row is always blank +``` + +Is converted to "0" + +``` + # + | # one. + | # + # (blank fourth row) +``` + +Is converted to "1" + +If the input is the correct size, but not recognizable, your program should return '?' + +If the input is the incorrect size, your program should return an error. + +# Step Two + +Update your program to recognize multi-character binary strings, replacing garbled numbers with ? + +# Step Three + +Update your program to recognize all numbers 0 through 9, both individually and as part of a larger string. + +``` + _ + _| +|_ + +``` + +Is converted to "2" + +``` + _ _ _ _ _ _ _ _ # + | _| _||_||_ |_ ||_||_|| | # decimal numbers. + ||_ _| | _||_| ||_| _||_| # + # fourth line is always blank +``` + +Is converted to "1234567890" + +# Step Four + +Update your program to handle multiple numbers, one per line. When converting several lines, join the lines with commas. + +``` + _ _ + | _| _| + ||_ _| + + _ _ +|_||_ |_ + | _||_| + + _ _ _ + ||_||_| + ||_| _| + +``` + +Is converted to "123,456,789" + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by the Bank OCR kata [http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR](http://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/octal/README.md b/exercises/octal/README.md new file mode 100644 index 00000000..a791ac8d --- /dev/null +++ b/exercises/octal/README.md @@ -0,0 +1,73 @@ +# Octal + +Convert an octal number, represented as a string (e.g. '1735263'), to its +decimal equivalent using first principles (i.e. no, you may not use built-in or +external libraries to accomplish the conversion). + +Implement octal to decimal conversion. Given an octal input +string, your program should produce a decimal output. + +## Note +- Implement the conversion yourself. + Do not use something else to perform the conversion for you. +- Treat invalid input as octal 0. + +## About Octal (Base-8) +Decimal is a base-10 system. + +A number 233 in base 10 notation can be understood +as a linear combination of powers of 10: + +- The rightmost digit gets multiplied by 10^0 = 1 +- The next number gets multiplied by 10^1 = 10 +- ... +- The *n*th number gets multiplied by 10^*(n-1)*. +- All these values are summed. + +So: +``` + 233 # decimal + = 2*10^2 + 3*10^1 + 3*10^0 + = 2*100 + 3*10 + 3*1 +``` + +Octal is similar, but uses powers of 8 rather than powers of 10. + +So: +``` + 233 # octal + = 2*8^2 + 3*8^1 + 3*8^0 + = 2*64 + 3*8 + 3*1 + = 128 + 24 + 3 + = 155 +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +All of Computer Science [http://www.wolframalpha.com/input/?i=base+8](http://www.wolframalpha.com/input/?i=base+8) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md new file mode 100644 index 00000000..9d4d6d61 --- /dev/null +++ b/exercises/palindrome-products/README.md @@ -0,0 +1,64 @@ +# Palindrome Products + +Detect palindrome products in a given range. + +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 the definition of a palindromic number, we define a palindrome _product_ +to be the product `c`, such that `a * b = c`, where `c` is a palindromic number and + `a` and `b` are integers (possibly, but _not_ necessarily palindromic numbers). + +For example, the palindromic number 9009 can be written as the palindrome +product: `91 * 99 = 9009`. + +It's possible (and indeed common) for a palindrome product to be the product +of multiple combinations of numbers. For example, the palindrome product `9` has +the factors `(1, 9)`, `(3, 3)`, and `(9, 1)`. + +Write a program that given a range of integers, returns the smallest and largest +palindromic product within that range, along with all of it's factors. + +## Example 1 + +Given the range `[1, 9]` (both inclusive)... + +The smallest product is `1`. It's factors are `(1, 1)`. +The largest product is `9`. It's factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. + +## Example 2 + +Given the range `[10, 99]` (both inclusive)... + +The smallest palindrome product is `121`. It's factors are `(11, 11)`. +The largest palindrome product is `9009`. It's factors are `(91, 99)` and `(99, 91)`. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Problem 4 at Project Euler [http://projecteuler.net/problem=4](http://projecteuler.net/problem=4) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/pangram/README.md b/exercises/pangram/README.md new file mode 100644 index 00000000..9fceecd9 --- /dev/null +++ b/exercises/pangram/README.md @@ -0,0 +1,39 @@ +# Pangram + +Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma, +"every letter") is a sentence using every letter of the alphabet at least once. +The best known English pangram is: +> The quick brown fox jumps over the lazy dog. + +The alphabet used consists of ASCII letters `a` to `z`, inclusive, and is case +insensitive. Input will not contain non-ASCII symbols. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Pangram](https://en.wikipedia.org/wiki/Pangram) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/pascals-triangle/README.md b/exercises/pascals-triangle/README.md new file mode 100644 index 00000000..cf72686d --- /dev/null +++ b/exercises/pascals-triangle/README.md @@ -0,0 +1,45 @@ +# Pascals Triangle + +Compute Pascal's triangle up to a given number of rows. + +In Pascal's Triangle each number is computed by adding the numbers to +the right and left of the current position in the previous row. + +```plain + 1 + 1 1 + 1 2 1 + 1 3 3 1 +1 4 6 4 1 +# ... etc +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Pascal's Triangle at Wolfram Math World [http://mathworld.wolfram.com/PascalsTriangle.html](http://mathworld.wolfram.com/PascalsTriangle.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/perfect-numbers/README.md b/exercises/perfect-numbers/README.md new file mode 100644 index 00000000..4e343f53 --- /dev/null +++ b/exercises/perfect-numbers/README.md @@ -0,0 +1,48 @@ +# Perfect Numbers + +Determine if a number is perfect, abundant, or deficient based on +Nicomachus' (60 - 120 CE) classification scheme for natural numbers. + +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 + +- **Perfect**: aliquot sum = number + - 6 is a perfect number because (1 + 2 + 3) = 6 + - 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28 +- **Abundant**: aliquot sum > number + - 12 is an abundant number because (1 + 2 + 3 + 4 + 6) = 16 + - 24 is an abundant number because (1 + 2 + 3 + 4 + 6 + 8 + 12) = 36 +- **Deficient**: aliquot sum < number + - 8 is a deficient number because (1 + 2 + 4) = 7 + - Prime numbers are deficient + +Implement a way to determine whether a given number is **perfect**. Depending on your language track, you may also need to implement a way to determine whether a given number is **abundant** or **deficient**. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Taken from Chapter 2 of Functional Thinking by Neal Ford. [http://shop.oreilly.com/product/0636920029687.do](http://shop.oreilly.com/product/0636920029687.do) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/phone-number/README.md b/exercises/phone-number/README.md new file mode 100644 index 00000000..c0428ad7 --- /dev/null +++ b/exercises/phone-number/README.md @@ -0,0 +1,58 @@ +# Phone Number + +Clean up user-entered phone numbers so that they can be sent SMS messages. + +The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`. + +NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as *area code*, followed by a seven-digit local number. The first three digits of the local number represent the *exchange code*, followed by the unique four-digit number which is the *subscriber number*. + + +The format is usually represented as +``` +(NXX)-NXX-XXXX +``` +where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9. + +Your task is to clean up differently formated telephone numbers by removing punctuation and the country code (1) if present. + +For example, the inputs +- `+1 (613)-995-0253` +- `613-995-0253` +- `1 613 995 0253` +- `613.995.0253` + +should all produce the output + +`6139950253` + +**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Event Manager by JumpstartLab [http://tutorials.jumpstartlab.com/projects/eventmanager.html](http://tutorials.jumpstartlab.com/projects/eventmanager.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/pig-latin/README.md b/exercises/pig-latin/README.md new file mode 100644 index 00000000..cfd1f0e9 --- /dev/null +++ b/exercises/pig-latin/README.md @@ -0,0 +1,48 @@ +# Pig Latin + +Implement a program that translates from English to Pig Latin. + +Pig Latin is a made-up children's language that's intended to be +confusing. It obeys a few simple rules (below), but when it's spoken +quickly it's really difficult for non-children (and non-native speakers) +to understand. + +- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to + the end of the word. +- **Rule 2**: If a word begins with a consonant sound, move it to the + end of the word, and then add an "ay" sound to the end of the word. + +There are a few more rules for edge cases, and there are regional +variants too. + +See for more details. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Pig Latin exercise at Test First Teaching by Ultrasaurus [https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/](https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/point-mutations/README.md b/exercises/point-mutations/README.md new file mode 100644 index 00000000..b479abc5 --- /dev/null +++ b/exercises/point-mutations/README.md @@ -0,0 +1,65 @@ +# Point Mutations + +Calculate the Hamming difference between two DNA strands. + +A mutation is simply a mistake that occurs during the creation or +copying of a nucleic acid, in particular DNA. Because nucleic acids are +vital to cellular functions, mutations tend to cause a ripple effect +throughout the cell. Although mutations are technically mistakes, a very +rare mutation may equip the cell with a beneficial attribute. In fact, +the macro effects of evolution are attributable by the accumulated +result of beneficial microscopic mutations over many generations. + +The simplest and most common type of nucleic acid mutation is a point +mutation, which replaces one base with another at a single nucleotide. + +By counting the number of differences between two homologous DNA strands +taken from different genomes with a common ancestor, we get a measure of +the minimum number of point mutations that could have occurred on the +evolutionary path between the two strands. + +This is called the 'Hamming distance' + + GAGCCTACTAACGGGAT + CATCGTAATGACGGCCT + ^ ^ ^ ^ ^ ^^ + +The Hamming distance between these two DNA strands is 7. + +# Implementation notes + +The Hamming distance is only defined for sequences of equal length. Hence you +may assume that only sequences of equal length will be passed to your hamming +distance function. + +**Note: This problem is deprecated, replaced by the one called `hamming`.** + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Calculating Point Mutations problem at Rosalind [http://rosalind.info/problems/hamm/](http://rosalind.info/problems/hamm/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/prime-factors/README.md b/exercises/prime-factors/README.md new file mode 100644 index 00000000..eefc5599 --- /dev/null +++ b/exercises/prime-factors/README.md @@ -0,0 +1,60 @@ +# Prime Factors + +Compute the prime factors of a given natural number. + +A prime number is only evenly divisible by itself and 1. + +Note that 1 is not a prime number. + +## Example + +What are the prime factors of 60? + +- Our first divisor is 2. 2 goes into 60, leaving 30. +- 2 goes into 30, leaving 15. + - 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3. +- 3 goes cleanly into 15, leaving 5. + - 3 does not go cleanly into 5. The next possible factor is 4. + - 4 does not go cleanly into 5. The next possible factor is 5. +- 5 does go cleanly into 5. +- We're left only with 1, so now, we're done. + +Our successful divisors in that computation represent the list of prime +factors of 60: 2, 2, 3, and 5. + +You can check this yourself: + +- 2 * 2 * 3 * 5 +- = 4 * 15 +- = 60 +- Success! + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Prime Factors Kata by Uncle Bob [http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata](http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/proverb/README.md b/exercises/proverb/README.md new file mode 100644 index 00000000..51fdaac1 --- /dev/null +++ b/exercises/proverb/README.md @@ -0,0 +1,42 @@ +# Proverb + +For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output +the full text of this proverbial rhyme: + +> 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. +> 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. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/For_Want_of_a_Nail](http://en.wikipedia.org/wiki/For_Want_of_a_Nail) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/pythagorean-triplet/README.md b/exercises/pythagorean-triplet/README.md new file mode 100644 index 00000000..7165790b --- /dev/null +++ b/exercises/pythagorean-triplet/README.md @@ -0,0 +1,48 @@ +# Pythagorean Triplet + +A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for +which, + +``` +a**2 + b**2 = c**2 +``` + +For example, + +``` +3**2 + 4**2 = 9 + 16 = 25 = 5**2. +``` + +There exists exactly one Pythagorean triplet for which a + b + c = 1000. + +Find the product a * b * c. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Problem 9 at Project Euler [http://projecteuler.net/problem=9](http://projecteuler.net/problem=9) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/queen-attack/README.md b/exercises/queen-attack/README.md new file mode 100644 index 00000000..7c311f4f --- /dev/null +++ b/exercises/queen-attack/README.md @@ -0,0 +1,57 @@ +# Queen Attack + +Given the position of two queens on a chess board, indicate whether or not they +are positioned so that they can attack each other. + +In the game of chess, a queen can attack pieces which are on the same +row, column, or diagonal. + +A chessboard can be represented by an 8 by 8 array. + +So if you're told the white queen is at (2, 3) and the black queen at +(5, 6), then you'd know you've got a set-up like so: + +```plain +_ _ _ _ _ _ _ _ +_ _ _ _ _ _ _ _ +_ _ _ W _ _ _ _ +_ _ _ _ _ _ _ _ +_ _ _ _ _ _ _ _ +_ _ _ _ _ _ B _ +_ _ _ _ _ _ _ _ +_ _ _ _ _ _ _ _ +``` + +You'd also be able to answer whether the queens can attack each other. +In this case, that answer would be yes, they can, because both pieces +share a diagonal. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +J Dalbey's Programming Practice problems [http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/raindrops/README.md b/exercises/raindrops/README.md new file mode 100644 index 00000000..21754775 --- /dev/null +++ b/exercises/raindrops/README.md @@ -0,0 +1,48 @@ +# Raindrops + +Convert a number to a string, the contents of which depend on the number's factors. + +- 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. + +## 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". + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A variation on a famous interview question intended to weed out potential candidates. [http://jumpstartlab.com](http://jumpstartlab.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/rna-transcription/README.md b/exercises/rna-transcription/README.md new file mode 100644 index 00000000..53944760 --- /dev/null +++ b/exercises/rna-transcription/README.md @@ -0,0 +1,49 @@ +# Rna Transcription + +Given a DNA strand, return its RNA complement (per RNA transcription). + +Both DNA and RNA strands are a sequence of nucleotides. + +The four nucleotides found in DNA are adenine (**A**), cytosine (**C**), +guanine (**G**) and thymine (**T**). + +The four nucleotides found in RNA are adenine (**A**), cytosine (**C**), +guanine (**G**) and uracil (**U**). + +Given a DNA strand, its transcribed RNA strand is formed by replacing +each nucleotide with its complement: + +* `G` -> `C` +* `C` -> `G` +* `T` -> `A` +* `A` -> `U` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Rosalind [http://rosalind.info/problems/rna](http://rosalind.info/problems/rna) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/robot-name/README.md b/exercises/robot-name/README.md new file mode 100644 index 00000000..e679b1ad --- /dev/null +++ b/exercises/robot-name/README.md @@ -0,0 +1,46 @@ +# Robot Name + +Manage robot factory settings. + +When robots come off the factory floor, they have no name. + +The first time you boot them up, 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 +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 +every existing robot has a unique name. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A debugging session with Paul Blackwell at gSchool. [http://gschool.it](http://gschool.it) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/robot-simulator/README.md b/exercises/robot-simulator/README.md new file mode 100644 index 00000000..cf8731bf --- /dev/null +++ b/exercises/robot-simulator/README.md @@ -0,0 +1,58 @@ +# Robot Simulator + +Write a robot simulator. + +A robot factory's test facility needs a program to verify robot movements. + +The robots have three possible movements: + +- turn right +- turn left +- advance + +Robots are placed on a hypothetical infinite grid, facing a particular +direction (north, east, south, or west) at a set of {x,y} coordinates, +e.g., {3,8}, with coordinates increasing to the north and east. + +The robot then receives a number of instructions, at which point the +testing facility verifies the robot's new position, and in which +direction it is pointing. + +- The letter-string "RAALAL" means: + - Turn right + - Advance twice + - Turn left + - Advance once + - Turn left yet again +- Say a robot starts at {7, 3} facing north. Then running this stream + of instructions should leave it at {9, 4} facing west. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by an interview question at a famous company. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/roman-numerals/README.md b/exercises/roman-numerals/README.md new file mode 100644 index 00000000..77174297 --- /dev/null +++ b/exercises/roman-numerals/README.md @@ -0,0 +1,73 @@ +# Roman Numerals + +Write a function to convert from normal numbers to Roman Numerals. + +The Romans were a clever bunch. They conquered most of Europe and ruled +it for hundreds of years. They invented concrete and straight roads and +even bikinis. One thing they never discovered though was the number +zero. This made writing and dating extensive histories of their exploits +slightly more challenging, but the system of numbers they came up with +is still in use today. For example the BBC uses Roman numerals to date +their programmes. + +The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice +these letters have lots of straight lines and are hence easy to hack +into stone tablets). + +``` + 1 => I +10 => X + 7 => VII +``` + +There is no need to be able to convert numbers larger than about 3000. +(The Romans themselves didn't tend to go any higher) + +Wikipedia says: Modern Roman numerals ... are written by expressing each +digit separately starting with the left most digit and skipping any +digit with a value of zero. + +To see this in practice, consider the example of 1990. + +In Roman numerals 1990 is MCMXC: + +1000=M +900=CM +90=XC + +2008 is written as MMVIII: + +2000=MM +8=VIII + +See also: http://www.novaroma.org/via_romana/numbers.html + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Roman Numeral Kata [http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals](http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/run-length-encoding/README.md b/exercises/run-length-encoding/README.md new file mode 100644 index 00000000..e91fd159 --- /dev/null +++ b/exercises/run-length-encoding/README.md @@ -0,0 +1,54 @@ +# Run Length Encoding + +Implement run-length encoding and decoding. + +Run-length encoding (RLE) is a simple form of data compression, where runs +(consecutive data elements) are replaced by just one data value and count. + +For example we can represent the original 53 characters with only 13. + +``` +"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" +``` + +RLE allows the original data to be perfectly reconstructed from +the compressed data, which makes it a lossless data compression. + +``` +"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" +``` + +For simplicity, you can assume that the unencoded string will only contain +the letters A through Z (either lower or upper case) and whitespace. This way +data to be encoded will never contain any numbers and numbers inside data to +be decoded always represent the count for the following character. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Run-length_encoding](https://en.wikipedia.org/wiki/Run-length_encoding) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/saddle-points/README.md b/exercises/saddle-points/README.md new file mode 100644 index 00000000..24a59c28 --- /dev/null +++ b/exercises/saddle-points/README.md @@ -0,0 +1,57 @@ +# Saddle Points + +Detect saddle points in a matrix. + +So say you have a matrix like so: + +```plain + 0 1 2 + |--------- +0 | 9 8 7 +1 | 5 3 2 <--- saddle point at (1,0) +2 | 6 6 7 +``` + +It has a saddle point at (1, 0). + +It's called a "saddle point" because it is greater than or equal to +every element in its row and the less than or equal to every element in +its column. + +A matrix may have zero or more saddle points. + +Your code should be able to provide the (possibly empty) list of all the +saddle points for any given matrix. + +Note that you may find other definitions of matrix saddle points online, +but the tests for this exercise follow the above unambiguous definition. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +J Dalbey's Programming Practice problems [http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/say/README.md b/exercises/say/README.md new file mode 100644 index 00000000..7be49a95 --- /dev/null +++ b/exercises/say/README.md @@ -0,0 +1,93 @@ +# Say + +Given a number from 0 to 999,999,999,999, spell out that number in English. + +## Step 1 + +Handle the basic case of 0 through 99. + +If the input to the program is `22`, then the output should be +`'twenty-two'`. + +Your program should complain loudly if given a number outside the +blessed range. + +Some good test cases for this program are: + +- 0 +- 14 +- 50 +- 98 +- -1 +- 100 + +### Extension + +If you're on a Mac, shell out to Mac OS X's `say` program to talk out +loud. + +## Step 2 + +Implement breaking a number up into chunks of thousands. + +So `1234567890` should yield a list like 1, 234, 567, and 890, while the +far simpler `1000` should yield just 1 and 0. + +The program must also report any values that are out of range. + +## Step 3 + +Now handle inserting the appropriate scale word between those chunks. + +So `1234567890` should yield `'1 billion 234 million 567 thousand 890'` + +The program must also report any values that are out of range. It's +fine to stop at "trillion". + +## Step 4 + +Put it all together to get nothing but plain English. + +`12345` should give `twelve thousand three hundred forty-five`. + +The program must also report any values that are out of range. + +### Extensions + +Use _and_ (correctly) when spelling out the number in English: + +- 14 becomes "fourteen". +- 100 becomes "one hundred". +- 120 becomes "one hundred and twenty". +- 1002 becomes "one thousand and two". +- 1323 becomes "one thousand three hundred and twenty-three". + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A variation on JavaRanch CattleDrive, exercise 4a [http://www.javaranch.com/say.jsp](http://www.javaranch.com/say.jsp) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/scrabble-score/README.md b/exercises/scrabble-score/README.md new file mode 100644 index 00000000..b0592bef --- /dev/null +++ b/exercises/scrabble-score/README.md @@ -0,0 +1,68 @@ +# Scrabble Score + +Given a word, compute the scrabble score for that word. + +## Letter Values + +You'll need these: + +```plain +Letter Value +A, E, I, O, U, L, N, R, S, T 1 +D, G 2 +B, C, M, P 3 +F, H, V, W, Y 4 +K 5 +J, X 8 +Q, Z 10 +``` + +## Examples +"cabbage" should be scored as worth 14 points: + +- 3 points for C +- 1 point for A, twice +- 3 points for B, twice +- 2 points for G +- 1 point for E + +And to total: + +- `3 + 2*1 + 2*3 + 2 + 1` +- = `3 + 2 + 6 + 3` +- = `5 + 9` +- = 14 + +## Extensions +- You can play a double or a triple letter. +- You can play a double or a triple word. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/secret-handshake/README.md b/exercises/secret-handshake/README.md new file mode 100644 index 00000000..dfdd361c --- /dev/null +++ b/exercises/secret-handshake/README.md @@ -0,0 +1,59 @@ +# Secret Handshake + +> There are 10 types of people in the world: Those who understand +> binary, and those who don't. + +You and your fellow cohort of those in the "know" when it comes to +binary decide to come up with a secret "handshake". + +``` +1 = wink +10 = double blink +100 = close your eyes +1000 = jump + + +10000 = Reverse the order of the operations in the secret handshake. +``` + +Given a decimal number, convert it to the appropriate sequence of events for a secret handshake. + +Here's a couple of examples: + +Given the input 3, the function would return the array +["wink", "double blink"] because 3 is 11 in binary. + +Given the input 19, the function would return the array +["double blink", "wink"] because 19 is 10011 in binary. +Notice that the addition of 16 (10000 in binary) +has caused the array to be reversed. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Bert, in Mary Poppins [http://www.imdb.com/character/ch0011238/quotes](http://www.imdb.com/character/ch0011238/quotes) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/series/README.md b/exercises/series/README.md new file mode 100644 index 00000000..81133429 --- /dev/null +++ b/exercises/series/README.md @@ -0,0 +1,51 @@ +# Series + +Given a string of digits, output all the contiguous substrings of length `n` in +that string. + +For example, the string "49142" has the following 3-digit series: + +- 491 +- 914 +- 142 + +And the following 4-digit series: + +- 4914 +- 9142 + +And if you ask for a 6-digit series from a 5-digit string, you deserve +whatever you get. + +Note that these series are only required to occupy *adjacent positions* +in the input; the digits need not be *numerically consecutive*. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A subset of the Problem 8 at Project Euler [http://projecteuler.net/problem=8](http://projecteuler.net/problem=8) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/sieve/README.md b/exercises/sieve/README.md new file mode 100644 index 00000000..b64850a4 --- /dev/null +++ b/exercises/sieve/README.md @@ -0,0 +1,58 @@ +# Sieve + +Use the Sieve of Eratosthenes to find all the primes from 2 up to a given +number. + +The Sieve of Eratosthenes is a simple, ancient algorithm for finding all +prime numbers up to any given limit. It does so by iteratively marking as +composite (i.e. not prime) the multiples of each prime, +starting with the multiples of 2. + +Create your range, starting at two and continuing up to and including the given limit. (i.e. [2, limit]) + +The algorithm consists of repeating the following over and over: + +- take the next available unmarked number in your list (it is prime) +- mark all the multiples of that number (they are not prime) + +Repeat until you have processed each number in your range. + +When the algorithm terminates, all the numbers in the list that have not +been marked are prime. + +The wikipedia article has a useful graphic that explains the algorithm: +https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + +Notice that this is a very specific algorithm, and the tests don't check +that you've implemented the algorithm, only that you've come up with the +correct list of primes. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Sieve of Eratosthenes at Wikipedia [http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes](http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/simple-cipher/README.md b/exercises/simple-cipher/README.md new file mode 100644 index 00000000..4c736e7f --- /dev/null +++ b/exercises/simple-cipher/README.md @@ -0,0 +1,114 @@ +# Simple Cipher + +Implement a simple shift cipher like Caesar and a more secure substitution cipher. + +## Step 1 + +"If he had anything confidential to say, he wrote it in cipher, that is, +by so changing the order of the letters of the alphabet, that not a word +could be made out. If anyone wishes to decipher these, and get at their +meaning, he must substitute the fourth letter of the alphabet, namely D, +for A, and so with the others." +—Suetonius, Life of Julius Caesar + +Ciphers are very straight-forward algorithms that allow us to render +text less readable while still allowing easy deciphering. They are +vulnerable to many forms of cryptoanalysis, but we are lucky that +generally our little sisters are not cryptoanalysts. + +The Caesar Cipher was used for some messages from Julius Caesar that +were sent afield. Now Caesar knew that the cipher wasn't very good, but +he had one ally in that respect: almost nobody could read well. So even +being a couple letters off was sufficient so that people couldn't +recognize the few words that they did know. + +Your task is to create a simple shift cipher like the Caesar Cipher. +This image is a great example of the Caesar Cipher: + +![Caesar Cipher][1] + +For example: + +Giving "iamapandabear" as input to the encode function returns the cipher "ldpdsdqgdehdu". Obscure enough to keep our message secret in transit. + +When "ldpdsdqgdehdu" is put into the decode function it would return +the original "iamapandabear" letting your friend read your original +message. + +## Step 2 + +Shift ciphers are no fun though when your kid sister figures it out. Try +amending the code to allow us to specify a key and use that for the +shift distance. This is called a substitution cipher. + +Here's an example: + +Given the key "aaaaaaaaaaaaaaaaaa", encoding the string "iamapandabear" +would return the original "iamapandabear". + +Given the key "ddddddddddddddddd", encoding our string "iamapandabear" +would return the obscured "lpdsdqgdehdu" + +In the example above, we've set a = 0 for the key value. So when the +plaintext is added to the key, we end up with the same message coming +out. So "aaaa" is not an ideal key. But if we set the key to "dddd", we +would get the same thing as the Caesar Cipher. + +## Step 3 + +The weakest link in any cipher is the human being. Let's make your +substitution cipher a little more fault tolerant by providing a source +of randomness and ensuring that the key is not composed of numbers or +capital letters. + +If someone doesn't submit a key at all, generate a truly random key of +at least 100 characters in length, accessible via Cipher#key (the # +syntax means instance variable) + +If the key submitted has capital letters or numbers, throw an +ArgumentError with a message to that effect. + +## Extensions + +Shift ciphers work by making the text slightly odd, but are vulnerable +to frequency analysis. Substitution ciphers help that, but are still +very vulnerable when the key is short or if spaces are preserved. Later +on you'll see one solution to this problem in the exercise +"crypto-square". + +If you want to go farther in this field, the questions begin to be about +how we can exchange keys in a secure way. Take a look at [Diffie-Hellman +on Wikipedia][dh] for one of the first implementations of this scheme. + +[1]: https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Caesar_cipher_left_shift_of_3.svg/320px-Caesar_cipher_left_shift_of_3.svg.png +[dh]: http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Substitution Cipher at Wikipedia [http://en.wikipedia.org/wiki/Substitution_cipher](http://en.wikipedia.org/wiki/Substitution_cipher) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/simple-linked-list/README.md b/exercises/simple-linked-list/README.md new file mode 100644 index 00000000..f9e7ff91 --- /dev/null +++ b/exercises/simple-linked-list/README.md @@ -0,0 +1,52 @@ +# Simple Linked List + +Write a simple linked list implementation that uses Elements and a List. + +The linked list is a fundamental data structure in computer science, +often used in the implementation of other data structures. They're +pervasive in functional programming languages, such as Clojure, Erlang, +or Haskell, but far less common in imperative languages such as Ruby or +Python. + +The simplest kind of linked list is a singly linked list. Each element in the +list contains data and a "next" field pointing to the next element in the list +of elements. + +This variant of linked lists is often used to represent sequences or +push-down stacks (also called a LIFO stack; Last In, First Out). + +As a first take, lets create a singly linked list to contain the range (1..10), +and provide functions to reverse a linked list and convert to and from arrays. + +When implementing this in a language with built-in linked lists, +implement your own abstract data type. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists. [http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000](http://www.brpreiss.com/books/opus8/html/page96.html#SECTION004300000000000000000) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/space-age/README.md b/exercises/space-age/README.md new file mode 100644 index 00000000..68bc8ed3 --- /dev/null +++ b/exercises/space-age/README.md @@ -0,0 +1,48 @@ +# Space Age + +Given an age in seconds, calculate how old someone would be on: + + - Earth: orbital period 365.25 Earth days, or 31557600 seconds + - Mercury: orbital period 0.2408467 Earth years + - Venus: orbital period 0.61519726 Earth years + - Mars: orbital period 1.8808158 Earth years + - Jupiter: orbital period 11.862615 Earth years + - Saturn: orbital period 29.447498 Earth years + - Uranus: orbital period 84.016846 Earth years + - Neptune: orbital period 164.79132 Earth years + +So if you were told someone were 1,000,000,000 seconds old, you should +be able to say that they're 31 Earth-years old. + +If you're wondering why Pluto didn't make the cut, go watch [this +youtube video](http://www.youtube.com/watch?v=Z_2gbGXzFbs). + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=01](http://pine.fm/LearnToProgram/?Chapter=01) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/strain/README.md b/exercises/strain/README.md new file mode 100644 index 00000000..f726bb2f --- /dev/null +++ b/exercises/strain/README.md @@ -0,0 +1,64 @@ +# Strain + +Implement the `keep` and `discard` operation on collections. Given a collection +and a predicate on the collection's elements, `keep` returns a new collection +containing those elements where the predicate is true, while `discard` returns +a new collection containing those elements where the predicate is false. + +For example, given the collection of numbers: + +- 1, 2, 3, 4, 5 + +And the predicate: + +- is the number even? + +Then your keep operation should produce: + +- 2, 4 + +While your discard operation should produce: + +- 1, 3, 5 + +Note that the union of keep and discard is all the elements. + +The functions may be called `keep` and `discard`, or they may need different +names in order to not clash with existing functions or concepts in your +language. + +## Restrictions + +Keep your hands off that filter/reject/whatchamacallit functionality +provided by your standard library! Solve this one yourself using other +basic tools instead. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Conversation with James Edward Gray II [https://twitter.com/jeg2](https://twitter.com/jeg2) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md new file mode 100644 index 00000000..7766bd68 --- /dev/null +++ b/exercises/sum-of-multiples/README.md @@ -0,0 +1,42 @@ +# Sum Of Multiples + +Given a number, find the sum of all the multiples of particular numbers up to +but not including that number. + +If we list all the natural numbers up to but not including 20 that are +multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, 12, 15, and 18. + +The sum of these multiples is 78. + +Given a number, find the sum of the multiples of a given set of numbers, +up to but not including that number. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/triangle/README.md b/exercises/triangle/README.md new file mode 100644 index 00000000..32272340 --- /dev/null +++ b/exercises/triangle/README.md @@ -0,0 +1,50 @@ +# Triangle + +Determine if a triangle is equilateral, isosceles, or scalene. + +An _equilateral_ triangle has all three sides the same length.
    +An _isosceles_ triangle has at least two sides the same length. (It is sometimes +specified as having exactly two sides the same length, but for the purposes of +this exercise we'll say at least two.)
    +A _scalene_ triangle has all sides of different lengths. + +## Note + +For a shape to be a triangle at all, all sides have to be of length > 0, and +the sum of the lengths of any two sides must be greater than or equal to the +length of the third side. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality). + +## Dig Deeper + +The case where the sum of the lengths of two sides _equals_ that of the +third is known as a _degenerate_ triangle - it has zero area and looks like +a single line. Feel free to add your own code/tests to check for degenerate triangles. +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +The Ruby Koans triangle project, parts 1 & 2 [http://rubykoans.com](http://rubykoans.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/trinary/README.md b/exercises/trinary/README.md new file mode 100644 index 00000000..5d4fd424 --- /dev/null +++ b/exercises/trinary/README.md @@ -0,0 +1,52 @@ +# Trinary + +Convert a trinary number, represented as a string (e.g. '102012'), to its +decimal equivalent using first principles. + +The program should consider strings specifying an invalid trinary as the +value 0. + +Trinary numbers contain three symbols: 0, 1, and 2. + +The last place in a trinary number is the 1's place. The second to last +is the 3's place, the third to last is the 9's place, etc. + +```bash +# "102012" + 1 0 2 0 1 2 # the number +1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value + 243 + 0 + 54 + 0 + 3 + 2 = 302 +``` + +If your language provides a method in the standard library to perform the +conversion, pretend it doesn't exist and implement it yourself. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/two-bucket/README.md b/exercises/two-bucket/README.md new file mode 100644 index 00000000..493d70c2 --- /dev/null +++ b/exercises/two-bucket/README.md @@ -0,0 +1,60 @@ +# Two Bucket + +Given two buckets of different size, demonstrate how to measure an exact number of liters by strategically transferring liters of fluid between the buckets. + +Since this mathematical problem is fairly subject to interpretation / individual approach, the tests have been written specifically to expect one overarching solution. + +To help, the tests provide you with which bucket to fill first. That means, when starting with the larger bucket full, you are NOT allowed at any point to have the smaller bucket full and the larger bucket empty (aka, the opposite starting point); that would defeat the purpose of comparing both approaches! + +Your program will take as input: +- the size of bucket one, passed as a numeric value +- the size of bucket two, passed as a numeric value +- the desired number of liters to reach, passed as a numeric value +- which bucket to fill first, passed as a String (either 'one' or 'two') + +Your program should determine: +- the total number of "moves" it should take to reach the desired number of liters, including the first fill - expects a numeric value +- which bucket should end up with the desired number of liters (let's say this is bucket A) - expects a String (either 'one' or 'two') +- how many liters are left in the other bucket (bucket B) - expects a numeric value + +Note: any time a change is made to either or both buckets counts as one (1) move. + +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 + +Written with <3 at [Fullstack Academy](http://www.fullstackacademy.com/) by [Lindsay](http://lindsaylevine.com). + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Water Pouring Problem [http://demonstrations.wolfram.com/WaterPouringProblem/](http://demonstrations.wolfram.com/WaterPouringProblem/) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/word-count/README.md b/exercises/word-count/README.md new file mode 100644 index 00000000..ae006d10 --- /dev/null +++ b/exercises/word-count/README.md @@ -0,0 +1,43 @@ +# Word Count + +Given a phrase, count the occurrences of each word in that phrase. + +For example for the input `"olly olly in come free"` + +```plain +olly: 2 +in: 1 +come: 1 +free: 1 +``` + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour. + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/wordy/README.md b/exercises/wordy/README.md new file mode 100644 index 00000000..4186cc06 --- /dev/null +++ b/exercises/wordy/README.md @@ -0,0 +1,87 @@ +# Wordy + +Parse and evaluate simple math word problems returning the answer as an integer. + + +## Iteration 1 — Addition + +Add two numbers together. + +> What is 5 plus 13? + +Evaluates to 18. + +Handle large numbers and negative numbers. + + +## Iteration 2 — Subtraction, Multiplication and Division + +Now, perform the other three operations. + +> What is 7 minus 5? + +2 + +> What is 6 multiplied by 4? + +24 + +> What is 25 divided by 5? + +5 + + +## Iteration 3 — Multiple Operations + +Handle a set of operations, in sequence. + +Since these are verbal word problems, evaluate the expression from +left-to-right, _ignoring the typical order of operations._ + +> What is 5 plus 13 plus 6? + +24 + +> What is 3 plus 2 multiplied by 3? + +15 (i.e. not 9) + + +## Bonus — Exponentials + +If you'd like, handle exponentials. + +> What is 2 raised to the 5th power? + +32 + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Inspired by one of the generated questions in the Extreme Startup game. [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. From 70898aa1c3f9f6a8f5f8845df62762f11c587490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Wed, 19 Jul 2017 03:02:11 +0200 Subject: [PATCH 137/272] Add topics and difficulty to all exercises (#383) --- config.json | 537 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 397 insertions(+), 140 deletions(-) diff --git a/config.json b/config.json index 0ac86b85..40ade4a5 100644 --- a/config.json +++ b/config.json @@ -35,7 +35,7 @@ "slug": "hamming", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ "Control-flow (loops)", "Control-flow (conditionals)", @@ -59,7 +59,7 @@ "slug": "pangram", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ "Control flow (conditionals)", "Control flow (loops)", @@ -75,7 +75,7 @@ "slug": "bob", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ "Control flow (conditionals)", "Polymorfism", @@ -90,7 +90,7 @@ "slug": "gigasecond", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ "Time" ] @@ -100,7 +100,7 @@ "slug": "isogram", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ "Strings", "Filtering" @@ -111,10 +111,10 @@ "slug": "beer-song", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - "Looping", - "Conditionals", + "Control flow (conditionals)", + "Control flow (loops)", "Strings" ] }, @@ -123,7 +123,7 @@ "slug": "phone-number", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ "Parsing", "Transforming" @@ -145,7 +145,7 @@ "slug": "food-chain", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ "Text formatting", "Algorithms" @@ -156,9 +156,11 @@ "slug": "grade-school", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Arrays", + "Maps", + "Sorting" ] }, { @@ -166,9 +168,13 @@ "slug": "robot-name", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Exception handling", + "Sets", + "Randomness", + "Regular expressions" ] }, { @@ -176,9 +182,12 @@ "slug": "etl", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ - + "Control flow (loops)", + "Transforming", + "Maps", + "Integers" ] }, { @@ -186,9 +195,11 @@ "slug": "space-age", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Classes", + "Floating-point numbers", + "Mathematics" ] }, { @@ -196,9 +207,11 @@ "slug": "grains", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (loops)", + "Integers", + "Mathematics" ] }, { @@ -206,9 +219,13 @@ "slug": "triangle", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (loops)", + "Control flow (conditionals)", + "Exception handling", + "Integers", + "Mathematics" ] }, { @@ -216,9 +233,11 @@ "slug": "clock", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Dates", + "Time", + "Globalization" ] }, { @@ -226,9 +245,13 @@ "slug": "perfect-numbers", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Arrays", + "Integers", + "Mathematics" ] }, { @@ -250,9 +273,12 @@ "slug": "acronym", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ - + "Strings", + "Control flow (loops)", + "Regular expressions", + "Transforming" ] }, { @@ -260,9 +286,12 @@ "slug": "scrabble-score", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Maps", + "Strings" ] }, { @@ -270,9 +299,13 @@ "slug": "roman-numerals", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Pattern recognition", + "Transforming" ] }, { @@ -280,9 +313,14 @@ "slug": "circular-buffer", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 8, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Data structures", + "Lists", + "Arrays", + "Exception handling" ] }, { @@ -290,9 +328,15 @@ "slug": "binary", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Regular expressions", + "Exception handling" ] }, { @@ -300,9 +344,13 @@ "slug": "prime-factors", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Algorithms", + "Integers" ] }, { @@ -310,9 +358,12 @@ "slug": "raindrops", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ - + "Control flow (conditionals)", + "Strings", + "Integers", + "Transforming" ] }, { @@ -320,9 +371,12 @@ "slug": "allergies", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Bitwise operations", + "Arrays" ] }, { @@ -330,19 +384,30 @@ "slug": "strain", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Lists", + "Arrays", + "Callbacks", + "Filtering" ] }, { "uuid": "99974454-0736-4cc0-b88f-ed5701397a97", "slug": "atbash-cipher", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "simple-cipher", + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Arrays", + "Regular expressions", + "Text formatting" ] }, { @@ -350,39 +415,58 @@ "slug": "accumulate", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (loops)", + "Algorithms", + "Lists", + "Callbacks" ] }, { "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad", "slug": "crypto-square", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "atbash-cipher", + "difficulty": 9, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Arrays", + "Sorting", + "Text formatting", + "Regular expressions", + "Transforming" ] }, { "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d", "slug": "trinary", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "binary", + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Regular expressions" ] }, { "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32", "slug": "sieve", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "prime-factors", + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Recursion" ] }, { @@ -392,17 +476,29 @@ "unlocked_by": null, "difficulty": 1, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Mathematics", + "Strings", + "Randomness", + "Text formatting", + "Transforming" ] }, { "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8", "slug": "octal", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "binary", + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Regular expressions" ] }, { @@ -410,9 +506,13 @@ "slug": "luhn", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings" ] }, { @@ -420,9 +520,14 @@ "slug": "pig-latin", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Strings", + "Games", + "Regular expressions", + "Transforming" ] }, { @@ -430,9 +535,13 @@ "slug": "pythagorean-triplet", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Mathematics", + "Integers" ] }, { @@ -440,9 +549,12 @@ "slug": "series", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (loops)", + "Exception handling", + "Strings", + "Text formatting" ] }, { @@ -450,9 +562,12 @@ "slug": "difference-of-squares", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (loops)", + "Algorithms", + "Mathematics", + "Integers" ] }, { @@ -460,9 +575,14 @@ "slug": "secret-handshake", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Games", + "Bitwise operations", + "Arrays" ] }, { @@ -470,9 +590,13 @@ "slug": "proverb", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", "Arrays", + "Strings", + "Text formatting", "Optional values" ] }, @@ -481,9 +605,15 @@ "slug": "linked-list", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Data structures", + "Arrays", + "Lists", + "Optional values" ] }, { @@ -491,9 +621,15 @@ "slug": "wordy", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Regular expressions", + "Exception handling", + "Strings", + "Pattern recognition", + "Parsing" ] }, { @@ -503,17 +639,23 @@ "unlocked_by": null, "difficulty": 1, "topics": [ - + "Arrays", + "Recursion" ] }, { "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870", "slug": "hexadecimal", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "binary", + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Regular expressions" ] }, { @@ -521,9 +663,15 @@ "slug": "largest-series-product", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Exception handling", + "Regular expressions" ] }, { @@ -531,9 +679,13 @@ "slug": "kindergarten-garden", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Strings", + "Arrays", + "Text formatting" ] }, { @@ -541,19 +693,26 @@ "slug": "binary-search", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Recursion", + "Arrays", + "Algorithms" ] }, { "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85", "slug": "binary-search-tree", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "binary-search", + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Recursion", + "Algorithms" ] }, { @@ -561,9 +720,14 @@ "slug": "matrix", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 4, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Data structures", + "Arrays", + "Matrices", + "Text formatting" ] }, { @@ -573,27 +737,42 @@ "unlocked_by": null, "difficulty": 1, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Strings", + "Games", + "Parsing" ] }, { "uuid": "8fa51380-ec2c-4806-8833-cf543579de17", "slug": "nth-prime", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "prime-factors", + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Algorithms", + "Mathematics", + "Integers" ] }, { "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1", "slug": "palindrome-products", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "prime-factors", + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Algorithms", + "Mathematics", + "Integers" ] }, { @@ -601,9 +780,13 @@ "slug": "pascals-triangle", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Strings", + "Text formatting" ] }, { @@ -611,29 +794,45 @@ "slug": "say", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Exception handling", + "Strings", + "Text formatting" ] }, { "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659", "slug": "custom-set", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "linked-list", + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Data structures", + "Arrays", + "Lists", + "Sets", + "Equality", + "Recursion" ] }, { "uuid": "f30463c4-9d8c-4238-a691-e594291b4425", "slug": "sum-of-multiples", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "prime-factors", + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Lists", + "Integers" ] }, { @@ -641,19 +840,33 @@ "slug": "queen-attack", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 8, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Optional values", + "Exception handling", + "Equality", + "Text formatting", + "Parsing" ] }, { "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb", "slug": "saddle-points", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "matrix", + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Optional values", + "Exception handling", + "Equality", + "Parsing", + "Integers", + "Matrices", + "Mathematics" ] }, { @@ -661,9 +874,15 @@ "slug": "ocr-numbers", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Equality", + "Parsing", + "Integers", + "Text formatting" ] }, { @@ -671,9 +890,14 @@ "slug": "meetup", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 7, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Equality", + "Time", + "Dates" ] }, { @@ -681,9 +905,13 @@ "slug": "bracket-push", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 3, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Strings", + "Parsing", + "Exception handling" ] }, { @@ -691,9 +919,15 @@ "slug": "two-bucket", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 6, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Arrays", + "Parsing", + "Algorithms", + "Games", + "Exception handling" ] }, { @@ -701,29 +935,46 @@ "slug": "bowling", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 8, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Arrays", + "Parsing", + "Games", + "Exception handling", + "Text formatting" ] }, { "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956", "slug": "diamond", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "pascals-triangle", + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Arrays", + "Parsing", + "Games", + "Exception handling", + "Text formatting" ] }, { "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791", "slug": "all-your-base", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "binary", + "difficulty": 5, "topics": [ - + "Control flow (conditionals)", + "Control flow (loops)", + "Exception handling", + "Parsing", + "Mathematics", + "Integers" ] }, { @@ -731,21 +982,27 @@ "slug": "run-length-encoding", "core": false, "unlocked_by": null, - "difficulty": 1, + "difficulty": 2, "topics": [ - + "Control flow (conditionals)", + "Exception handling", + "Parsing", + "Text formatting", + "Regular expressions", + "Pattern recognition", + "Strings" ] }, { "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3", "slug": "minesweeper", "core": false, - "unlocked_by": null, + "unlocked_by": "queen-attack", "difficulty": 7, "topics": [ - "games", - "arrays", - "algorithms" + "Games", + "Arrays", + "Algorithms" ] }, { @@ -755,8 +1012,8 @@ "unlocked_by": null, "difficulty": 7, "topics": [ - "games", - "algorithms" + "Games", + "Algorithms" ] }, { From 63b4fba7998d51a6a5116b60f229e6447c9b9d41 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Fri, 21 Jul 2017 18:58:22 -0600 Subject: [PATCH 138/272] Remove redundant key/value pairs from config.json (#384) The slug is not used anywhere. We initialize a track based on knowing the Track ID. Since the repository is always named after the track ID, this field, too, is redundant, as it can be inferred. --- config.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/config.json b/config.json index 40ade4a5..46075016 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,5 @@ { - "slug": "javascript", "language": "JavaScript", - "repository": "https://github.com/exercism/javascript", "active": true, "test_pattern": ".*[.]spec[.]js$", "exercises": [ From 3472f176e988012840418e7bc9551d8ca45c35ea Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 24 Jul 2017 06:52:12 -0400 Subject: [PATCH 139/272] Add exercise sublist --- config.json | 17 +++- exercises/sublist/README.md | 50 ++++++++++++ exercises/sublist/example.js | 31 ++++++++ exercises/sublist/sublist.spec.js | 126 ++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 exercises/sublist/README.md create mode 100644 exercises/sublist/example.js create mode 100644 exercises/sublist/sublist.spec.js diff --git a/config.json b/config.json index 46075016..5226fb36 100644 --- a/config.json +++ b/config.json @@ -188,6 +188,17 @@ "Integers" ] }, + { + "uuid": "4a83a72c-db0a-45b6-b77c-1949cb24fbae", + "slug": "sublist", + "difficulty": 4, + "core": false, + "unlocked_by": "linked-list", + "topics": [ + "Lists", + "Arrays" + ] + }, { "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", "slug": "space-age", @@ -310,7 +321,7 @@ "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc", "slug": "circular-buffer", "core": false, - "unlocked_by": null, + "unlocked_by": "linked-list", "difficulty": 8, "topics": [ "Control flow (conditionals)", @@ -690,7 +701,7 @@ "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8", "slug": "binary-search", "core": false, - "unlocked_by": null, + "unlocked_by": "linked-list", "difficulty": 7, "topics": [ "Control flow (conditionals)", @@ -1018,7 +1029,7 @@ "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626", "slug": "simple-linked-list", "core": false, - "unlocked_by": null, + "unlocked_by": "linked-list", "difficulty": 8, "topics": [ "Arrays", diff --git a/exercises/sublist/README.md b/exercises/sublist/README.md new file mode 100644 index 00000000..974d3f06 --- /dev/null +++ b/exercises/sublist/README.md @@ -0,0 +1,50 @@ +# Sublist + +Given two lists determine if the first list is contained within the second +list, if the second list is contained within the first list, if both lists are +contained within each other or if none of these are true. + +Specifically, a list A is a sublist of list B if by dropping 0 or more elements +from the front of B and 0 or more elements from the back of B you get a list +that's completely equal to A. + +Examples: + + * A = [1, 2, 3], B = [1, 2, 3, 4, 5], A is a sublist of B + * A = [3, 4, 5], B = [1, 2, 3, 4, 5], A is a sublist of B + * A = [3, 4], B = [1, 2, 3, 4, 5], A is a sublist of B + * A = [1, 2, 3], B = [1, 2, 3], A is equal to B + * A = [1, 2, 3, 4, 5], B = [2, 3, 4], A is a superlist of B + * A = [1, 2, 4], B = [1, 2, 3, 4, 5], A is not a superlist of, sublist of or equal to B + +## Setup + +Go through the setup instructions for ECMAScript to +install the necessary dependencies: + +http://exercism.io/languages/ecmascript + +## Requirements + +Install assignment dependencies: + +```bash +$ npm install -g jasmine +``` + +## Making the test suite pass + +Execute the tests with: + +```bash +$ jasmine sublist.spec.js +``` + +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 `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/sublist/example.js b/exercises/sublist/example.js new file mode 100644 index 00000000..8b670af2 --- /dev/null +++ b/exercises/sublist/example.js @@ -0,0 +1,31 @@ +function List(list) { + this.list = list || []; + + return { + list: this.list, + compare: function(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' + }[lengthDiff(this, other)]; + } + } +} + +function lengthDiff(one, two){ + return String(Math.sign(one.list.length - two.list.length)); +} + +function isSublist(one, two){ + return one.join().match(two.join()); +} + + +module.exports = List; diff --git a/exercises/sublist/sublist.spec.js b/exercises/sublist/sublist.spec.js new file mode 100644 index 00000000..f080c951 --- /dev/null +++ b/exercises/sublist/sublist.spec.js @@ -0,0 +1,126 @@ +var List = require('./sublist'); + + +describe('sublist', function() { + + it('two empty lists are equal', function() { + var listOne = new List(); + var listTwo = new List(); + + expect(listOne.compare(listTwo)).toEqual('EQUAL'); + }); + + xit('an empty list is a sublist of a non-empty list', function() { + var listOne = new List(); + var listTwo = new List([1, 2, 3]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + }); + + xit('non empty list contains empty list', function() { + var listOne = new List([1, 2, 3]); + var listTwo = new List(); + + expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); + }); + + xit('a non-empty list equals itself', function() { + var listOne = new List([1, 2, 3]); + var listTwo = new List([1, 2, 3]); + + expect(listOne.compare(listTwo)).toEqual('EQUAL'); + }); + + xit('two different lists are unequal', function() { + var listOne = new List([1, 2, 3]); + var listTwo = new List([2, 3, 4]); + + expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); + }); + + xit('false start', function() { + var listOne = new List([1, 2, 5]); + var listTwo = new List([0, 1, 2, 3, 1, 2, 5, 6]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + + }); + + xit('consecutive', function() { + var listOne = new List([1, 1, 2]); + var listTwo = new List([0, 1, 1, 1, 2, 1, 2]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + }); + + xit('sublist at start', function() { + var listOne = new List([0, 1, 2]); + var listTwo = new List([0, 1, 2, 3, 4, 5]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + }); + + xit('sublist in middle', function() { + var listOne = new List([2, 3, 4]); + var listTwo = new List([0, 1, 2, 3, 4, 5]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + }); + + xit('sublist at end', function() { + var listOne = new List([3, 4, 5]); + var listTwo = new List([0, 1, 2, 3, 4, 5]); + + expect(listOne.compare(listTwo)).toEqual('SUBLIST'); + }); + + xit('at start of superlist', function() { + var listOne = new List([0, 1, 2, 3, 4, 5]); + var listTwo = new List([0, 1, 2]); + + expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); + }); + + xit('in middle of superlist', function() { + var listOne = new List([0, 1, 2, 3, 4, 5]); + var listTwo = new List([2, 3]); + + expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); + }); + + xit('at end of superlist', function() { + var listOne = new List([0, 1, 2, 3, 4, 5]); + var listTwo = new List([3, 4, 5]); + + expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); + }); + + xit('first list missing element from second list', function() { + var listOne = new List([1, 3]); + var listTwo = new List([1, 2, 3]); + + expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); + }); + + xit('second list missing element from first list', function() { + var listOne = new List([1, 2, 3]); + var listTwo = new List([1, 3]); + + expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); + }); + + xit('order matters to a list', function() { + var listOne = new List([1, 2, 3]); + var listTwo = new List([3, 2, 1]); + + expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); + }); + + xit('same digits but different numbers', function() { + var listOne = new List([1, 0, 1]); + var listTwo = new List([10, 1]); + + expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); + }); + +}); From 3c5af328f9aa87b27f3932341d234dad1f841778 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sat, 29 Jul 2017 10:07:21 -0600 Subject: [PATCH 140/272] Add default maintainers file (#388) We wish to feature the maintainers of each track on the new (nextercism) website. Ideally, the bios will be tailored to each track, giving a friendly view into each maintainer's background and interest in the language, and even (perhaps) what they enjoy most about maintaining the track, or what type of things they tend to focus on. The main reasons for including these are to: * provide a stronger basis for empathy with maintainers * give well-deserved recognition * plant a seed in people's minds that _Exercism tracks are maintained by people like me... I could do that!_ Being featured on the Exercism website is entirely optional, and we're generating all the data with show_on_website=false so that if you don't want to bother, you don't have to change anything. If you've moved on, or decide to do so, please submit and merge a PR (for visibility to the others involved) that sets **alumnus** to _true_ for your maintainer entry. I'm working on a bot that will update the GitHub team to reflect the current state of this file. We can merge this as is, and any changes can be added in subsequent pull requests. --- config/maintainers.json | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 config/maintainers.json diff --git a/config/maintainers.json b/config/maintainers.json new file mode 100644 index 00000000..15965d38 --- /dev/null +++ b/config/maintainers.json @@ -0,0 +1,85 @@ +{ + "maintainers": [ + { + "github_username": "ireddick", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "rchavarria", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "joelwallis", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "drueck", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "tejasbubane", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "matthewmorgan", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "mixolidia", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + }, + { + "github_username": "ZacharyRSmith", + "show_on_website": false, + "alumnus": false, + "name": null, + "bio": null, + "link_text": null, + "link_url": null, + "avatar_url": null + } + ], + "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md" +} From 20a712a637461ece83a9ce3f95cdd660b6a72ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Sun, 30 Jul 2017 22:21:09 +0200 Subject: [PATCH 141/272] Set core, non-core exercises and unlocking ones (#386) - There are 18 core exercises, sorted by difficulty - There are 4 exercises as non-core and without a locking exercise --- config.json | 476 +++++++++++++++++++++++++--------------------------- 1 file changed, 229 insertions(+), 247 deletions(-) diff --git a/config.json b/config.json index 5226fb36..429f6697 100644 --- a/config.json +++ b/config.json @@ -6,8 +6,7 @@ { "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256", "slug": "hello-world", - "core": false, - "unlocked_by": null, + "core": true, "difficulty": 1, "topics": [ "Control-flow (conditionals)", @@ -19,8 +18,7 @@ { "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b", "slug": "leap", - "core": false, - "unlocked_by": null, + "core": true, "difficulty": 1, "topics": [ "Booleans", @@ -29,34 +27,35 @@ ] }, { - "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0", - "slug": "hamming", - "core": false, - "unlocked_by": null, - "difficulty": 2, + "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c", + "slug": "rna-transcription", + "core": true, + "difficulty": 1, "topics": [ - "Control-flow (loops)", - "Control-flow (conditionals)", - "Equality", - "Strings" + "Strings", + "Transforming" ] }, { - "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c", - "slug": "rna-transcription", - "core": false, - "unlocked_by": null, + "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af", + "slug": "simple-cipher", + "core": true, "difficulty": 1, "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Mathematics", "Strings", + "Randomness", + "Text formatting", "Transforming" ] }, { "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15", "slug": "pangram", - "core": false, - "unlocked_by": null, + "core": true, "difficulty": 2, "topics": [ "Control flow (conditionals)", @@ -71,8 +70,7 @@ { "uuid": "246be5d9-b361-4893-9707-f218ede2bed6", "slug": "bob", - "core": false, - "unlocked_by": null, + "core": true, "difficulty": 2, "topics": [ "Control flow (conditionals)", @@ -86,18 +84,191 @@ { "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44", "slug": "gigasecond", + "core": true, + "difficulty": 2, + "topics": [ + "Time" + ] + }, + { + "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", + "slug": "space-age", + "core": true, + "difficulty": 3, + "topics": [ + "Classes", + "Floating-point numbers", + "Mathematics" + ] + }, + { + "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e", + "slug": "binary", + "core": true, + "difficulty": 4, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Integers", + "Strings", + "Regular expressions", + "Exception handling" + ] + }, + { + "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f", + "slug": "prime-factors", + "core": true, + "difficulty": 4, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Algorithms", + "Integers" + ] + }, + { + "uuid": "fbfe6032-c209-40bd-b485-8b2881638166", + "slug": "matrix", + "core": true, + "difficulty": 4, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Data structures", + "Arrays", + "Matrices", + "Text formatting" + ] + }, + { + "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385", + "slug": "linked-list", + "core": true, + "difficulty": 5, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Data structures", + "Arrays", + "Lists", + "Optional values" + ] + }, + { + "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf", + "slug": "pascals-triangle", + "core": true, + "difficulty": 5, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Mathematics", + "Strings", + "Text formatting" + ] + }, + { + "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0", + "slug": "secret-handshake", + "core": true, + "difficulty": 6, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Algorithms", + "Games", + "Bitwise operations", + "Arrays" + ] + }, + { + "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec", + "slug": "grade-school", + "core": true, + "difficulty": 6, + "topics": [ + "Arrays", + "Maps", + "Sorting" + ] + }, + { + "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a", + "slug": "robot-name", + "core": true, + "difficulty": 6, + "topics": [ + "Control flow (conditionals)", + "Exception handling", + "Sets", + "Randomness", + "Regular expressions" + ] + }, + { + "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843", + "slug": "wordy", + "core": true, + "difficulty": 7, + "topics": [ + "Control flow (conditionals)", + "Control flow (loops)", + "Regular expressions", + "Exception handling", + "Strings", + "Pattern recognition", + "Parsing" + ] + }, + { + "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c", + "slug": "list-ops", + "core": true, + "difficulty": 8, + "topics": [ + "Data structures", + "Lists", + "Recursion" + ] + }, + { + "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0", + "slug": "hamming", + "core": false, + "unlocked_by": "rna-transcription", + "difficulty": 2, + "topics": [ + "Control-flow (loops)", + "Control-flow (conditionals)", + "Equality", + "Strings" + ] + }, + { + "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac", + "slug": "run-length-encoding", "core": false, "unlocked_by": null, "difficulty": 2, "topics": [ - "Time" + "Control flow (conditionals)", + "Exception handling", + "Parsing", + "Text formatting", + "Regular expressions", + "Pattern recognition", + "Strings" ] }, { "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0", "slug": "isogram", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 2, "topics": [ "Strings", @@ -108,7 +279,7 @@ "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a", "slug": "beer-song", "core": false, - "unlocked_by": null, + "unlocked_by": "bob", "difficulty": 5, "topics": [ "Control flow (conditionals)", @@ -120,7 +291,7 @@ "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70", "slug": "phone-number", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 3, "topics": [ "Parsing", @@ -131,7 +302,7 @@ "uuid": "432ec2ce-c919-4142-aea2-389b67503252", "slug": "anagram", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 1, "topics": [ "Strings", @@ -142,44 +313,18 @@ "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17", "slug": "food-chain", "core": false, - "unlocked_by": null, + "unlocked_by": "bob", "difficulty": 4, "topics": [ "Text formatting", "Algorithms" ] }, - { - "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec", - "slug": "grade-school", - "core": false, - "unlocked_by": null, - "difficulty": 6, - "topics": [ - "Arrays", - "Maps", - "Sorting" - ] - }, - { - "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a", - "slug": "robot-name", - "core": false, - "unlocked_by": null, - "difficulty": 6, - "topics": [ - "Control flow (conditionals)", - "Exception handling", - "Sets", - "Randomness", - "Regular expressions" - ] - }, { "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a", "slug": "etl", "core": false, - "unlocked_by": null, + "unlocked_by": "rna-transcription", "difficulty": 2, "topics": [ "Control flow (loops)", @@ -199,23 +344,11 @@ "Arrays" ] }, - { - "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", - "slug": "space-age", - "core": false, - "unlocked_by": null, - "difficulty": 3, - "topics": [ - "Classes", - "Floating-point numbers", - "Mathematics" - ] - }, { "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda", "slug": "grains", "core": false, - "unlocked_by": null, + "unlocked_by": "space-age", "difficulty": 5, "topics": [ "Control flow (loops)", @@ -227,7 +360,7 @@ "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d", "slug": "triangle", "core": false, - "unlocked_by": null, + "unlocked_by": "leap", "difficulty": 3, "topics": [ "Control flow (loops)", @@ -241,7 +374,7 @@ "uuid": "1ff85150-6c51-4758-af02-4484cf35658e", "slug": "clock", "core": false, - "unlocked_by": null, + "unlocked_by": "gigasecond", "difficulty": 5, "topics": [ "Dates", @@ -253,7 +386,7 @@ "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6", "slug": "perfect-numbers", "core": false, - "unlocked_by": null, + "unlocked_by": "space-age", "difficulty": 3, "topics": [ "Control flow (conditionals)", @@ -267,7 +400,7 @@ "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838", "slug": "word-count", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 1, "topics": [ "Control flow (loops)", @@ -281,7 +414,7 @@ "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b", "slug": "acronym", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 2, "topics": [ "Strings", @@ -294,7 +427,7 @@ "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b", "slug": "scrabble-score", "core": false, - "unlocked_by": null, + "unlocked_by": "rna-transcription", "difficulty": 5, "topics": [ "Control flow (conditionals)", @@ -332,41 +465,11 @@ "Exception handling" ] }, - { - "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e", - "slug": "binary", - "core": false, - "unlocked_by": null, - "difficulty": 4, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Regular expressions", - "Exception handling" - ] - }, - { - "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f", - "slug": "prime-factors", - "core": false, - "unlocked_by": null, - "difficulty": 4, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Mathematics", - "Algorithms", - "Integers" - ] - }, { "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d", "slug": "raindrops", "core": false, - "unlocked_by": null, + "unlocked_by": "rna-transcription", "difficulty": 2, "topics": [ "Control flow (conditionals)", @@ -379,7 +482,7 @@ "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02", "slug": "allergies", "core": false, - "unlocked_by": null, + "unlocked_by": "rna-transcription", "difficulty": 6, "topics": [ "Control flow (conditionals)", @@ -392,7 +495,7 @@ "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247", "slug": "strain", "core": false, - "unlocked_by": null, + "unlocked_by": "list-ops", "difficulty": 4, "topics": [ "Control flow (conditionals)", @@ -423,7 +526,7 @@ "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9", "slug": "accumulate", "core": false, - "unlocked_by": null, + "unlocked_by": "list-ops", "difficulty": 5, "topics": [ "Control flow (loops)", @@ -478,23 +581,6 @@ "Recursion" ] }, - { - "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af", - "slug": "simple-cipher", - "core": false, - "unlocked_by": null, - "difficulty": 1, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Algorithms", - "Mathematics", - "Strings", - "Randomness", - "Text formatting", - "Transforming" - ] - }, { "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8", "slug": "octal", @@ -514,7 +600,7 @@ "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c", "slug": "luhn", "core": false, - "unlocked_by": null, + "unlocked_by": "space-age", "difficulty": 4, "topics": [ "Control flow (conditionals)", @@ -528,7 +614,7 @@ "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38", "slug": "pig-latin", "core": false, - "unlocked_by": null, + "unlocked_by": "bob", "difficulty": 4, "topics": [ "Control flow (conditionals)", @@ -543,7 +629,7 @@ "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6", "slug": "pythagorean-triplet", "core": false, - "unlocked_by": null, + "unlocked_by": "space-age", "difficulty": 5, "topics": [ "Control flow (conditionals)", @@ -557,7 +643,7 @@ "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5", "slug": "series", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 3, "topics": [ "Control flow (loops)", @@ -570,7 +656,7 @@ "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f", "slug": "difference-of-squares", "core": false, - "unlocked_by": null, + "unlocked_by": "space-age", "difficulty": 3, "topics": [ "Control flow (loops)", @@ -579,26 +665,11 @@ "Integers" ] }, - { - "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0", - "slug": "secret-handshake", - "core": false, - "unlocked_by": null, - "difficulty": 6, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Algorithms", - "Games", - "Bitwise operations", - "Arrays" - ] - }, { "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308", "slug": "proverb", "core": false, - "unlocked_by": null, + "unlocked_by": "bob", "difficulty": 4, "topics": [ "Control flow (conditionals)", @@ -609,43 +680,11 @@ "Optional values" ] }, - { - "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385", - "slug": "linked-list", - "core": false, - "unlocked_by": null, - "difficulty": 5, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Algorithms", - "Data structures", - "Arrays", - "Lists", - "Optional values" - ] - }, - { - "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843", - "slug": "wordy", - "core": false, - "unlocked_by": null, - "difficulty": 7, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Regular expressions", - "Exception handling", - "Strings", - "Pattern recognition", - "Parsing" - ] - }, { "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916", "slug": "flatten-array", "core": false, - "unlocked_by": null, + "unlocked_by": "list-ops", "difficulty": 1, "topics": [ "Arrays", @@ -671,7 +710,7 @@ "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c", "slug": "largest-series-product", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 7, "topics": [ "Control flow (conditionals)", @@ -687,7 +726,7 @@ "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87", "slug": "kindergarten-garden", "core": false, - "unlocked_by": null, + "unlocked_by": "wordy", "difficulty": 7, "topics": [ "Control flow (conditionals)", @@ -724,27 +763,12 @@ "Algorithms" ] }, - { - "uuid": "fbfe6032-c209-40bd-b485-8b2881638166", - "slug": "matrix", - "core": false, - "unlocked_by": null, - "difficulty": 4, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Data structures", - "Arrays", - "Matrices", - "Text formatting" - ] - }, { "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad", "slug": "robot-simulator", "core": false, - "unlocked_by": null, - "difficulty": 1, + "unlocked_by": "wordy", + "difficulty": 5, "topics": [ "Control flow (conditionals)", "Control flow (loops)", @@ -784,25 +808,11 @@ "Integers" ] }, - { - "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf", - "slug": "pascals-triangle", - "core": false, - "unlocked_by": null, - "difficulty": 5, - "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", - "Mathematics", - "Strings", - "Text formatting" - ] - }, { "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa", "slug": "say", "core": false, - "unlocked_by": null, + "unlocked_by": "bob", "difficulty": 6, "topics": [ "Control flow (conditionals)", @@ -882,7 +892,7 @@ "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756", "slug": "ocr-numbers", "core": false, - "unlocked_by": null, + "unlocked_by": "matrix", "difficulty": 5, "topics": [ "Control flow (conditionals)", @@ -898,7 +908,7 @@ "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8", "slug": "meetup", "core": false, - "unlocked_by": null, + "unlocked_by": "gigasecond", "difficulty": 7, "topics": [ "Control flow (conditionals)", @@ -913,7 +923,7 @@ "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84", "slug": "bracket-push", "core": false, - "unlocked_by": null, + "unlocked_by": "pangram", "difficulty": 3, "topics": [ "Control flow (conditionals)", @@ -927,7 +937,7 @@ "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1", "slug": "two-bucket", "core": false, - "unlocked_by": null, + "unlocked_by": "grade-school", "difficulty": 6, "topics": [ "Control flow (conditionals)", @@ -943,7 +953,7 @@ "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9", "slug": "bowling", "core": false, - "unlocked_by": null, + "unlocked_by": "grade-school", "difficulty": 8, "topics": [ "Control flow (conditionals)", @@ -986,27 +996,11 @@ "Integers" ] }, - { - "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac", - "slug": "run-length-encoding", - "core": false, - "unlocked_by": null, - "difficulty": 2, - "topics": [ - "Control flow (conditionals)", - "Exception handling", - "Parsing", - "Text formatting", - "Regular expressions", - "Pattern recognition", - "Strings" - ] - }, { "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3", "slug": "minesweeper", "core": false, - "unlocked_by": "queen-attack", + "unlocked_by": null, "difficulty": 7, "topics": [ "Games", @@ -1018,7 +1012,7 @@ "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a", "slug": "alphametics", "core": false, - "unlocked_by": null, + "unlocked_by": "grade-school", "difficulty": 7, "topics": [ "Games", @@ -1037,18 +1031,6 @@ "Lists" ] }, - { - "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c", - "slug": "list-ops", - "core": false, - "unlocked_by": null, - "difficulty": 8, - "topics": [ - "Data structures", - "Lists", - "Recursion" - ] - }, { "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c", "slug": "nucleotide-count", From 9c0d89c8a87b03fa5e37fc0ce6c946d481276810 Mon Sep 17 00:00:00 2001 From: SHIMADA Koji Date: Sun, 6 Aug 2017 13:42:33 +0900 Subject: [PATCH 142/272] Fix typo add missing 'd' to obscured string --- exercises/simple-cipher/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/simple-cipher/README.md b/exercises/simple-cipher/README.md index 4c736e7f..37536369 100644 --- a/exercises/simple-cipher/README.md +++ b/exercises/simple-cipher/README.md @@ -47,7 +47,7 @@ Given the key "aaaaaaaaaaaaaaaaaa", encoding the string "iamapandabear" would return the original "iamapandabear". Given the key "ddddddddddddddddd", encoding our string "iamapandabear" -would return the obscured "lpdsdqgdehdu" +would return the obscured "ldpdsdqgdehdu" In the example above, we've set a = 0 for the key value. So when the plaintext is added to the key, we end up with the same message coming From 4e337a9bf76b0920c8a76eacfd7c8f2893cc668b Mon Sep 17 00:00:00 2001 From: Sam Guo Date: Sun, 6 Aug 2017 09:42:20 -0400 Subject: [PATCH 143/272] Add a new test to circular buffer exercise --- exercises/circular-buffer/circular-buffer.spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/exercises/circular-buffer/circular-buffer.spec.js b/exercises/circular-buffer/circular-buffer.spec.js index fa9b6dfc..5ae5e358 100644 --- a/exercises/circular-buffer/circular-buffer.spec.js +++ b/exercises/circular-buffer/circular-buffer.spec.js @@ -109,4 +109,12 @@ describe('CircularBuffer', function() { expect(buffer.read).toThrow(bufferEmptyException()); }); + xit('multiple buffers don\'t interfere with each other', function() { + var buffer1 = circularBuffer(1); + var buffer2 = circularBuffer(1); + buffer1.write('1'); + expect(buffer2.read).toThrow(bufferEmptyException()); + expect(buffer1.read()).toBe('1'); + }); + }); From b0f943feda2d061d36a00091133734630fa63e43 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Wed, 23 Aug 2017 07:48:23 -0600 Subject: [PATCH 144/272] Add default introductory code example (#397) Instead of having logic for a fallback in the backend, we're choosing a default for the snippet file. For tracks that have core exercises, we pick the first core exercise. For tracks without these, we pick the first exercise listed in the config. Note that we're aiming for 10 lines and a max-width of 40 columns. This solution has a max-width of 45, so we may want to adjust it. --- docs/SNIPPET.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs/SNIPPET.txt diff --git a/docs/SNIPPET.txt b/docs/SNIPPET.txt new file mode 100644 index 00000000..0cb40c8b --- /dev/null +++ b/docs/SNIPPET.txt @@ -0,0 +1,10 @@ +'use strict'; + +var HelloWorld = function() {}; + +HelloWorld.prototype.hello = function(name) { + name = name || 'World'; + return 'Hello, ' + name + '!'; +}; + +module.exports = HelloWorld; From c5edfc6f53c2368ddff42287daaf2bf38bf19627 Mon Sep 17 00:00:00 2001 From: Tom Leen Date: Mon, 28 Aug 2017 06:28:19 -0400 Subject: [PATCH 145/272] config: Replace topic 'Control flow' with 'Control-flow' (#398) See exercism/problem-specifications#884 --- config.json | 206 ++++++++++++++++++++++++++-------------------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/config.json b/config.json index 429f6697..97056c75 100644 --- a/config.json +++ b/config.json @@ -42,8 +42,8 @@ "core": true, "difficulty": 1, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Mathematics", "Strings", @@ -58,8 +58,8 @@ "core": true, "difficulty": 2, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Lists", "Strings", "Maps", @@ -73,7 +73,7 @@ "core": true, "difficulty": 2, "topics": [ - "Control flow (conditionals)", + "Control-flow (conditionals)", "Polymorfism", "Strings", "Unicode", @@ -107,8 +107,8 @@ "core": true, "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings", @@ -122,8 +122,8 @@ "core": true, "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Algorithms", "Integers" @@ -135,8 +135,8 @@ "core": true, "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Data structures", "Arrays", "Matrices", @@ -149,8 +149,8 @@ "core": true, "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Data structures", "Arrays", @@ -164,8 +164,8 @@ "core": true, "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Strings", "Text formatting" @@ -177,8 +177,8 @@ "core": true, "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Games", "Bitwise operations", @@ -202,7 +202,7 @@ "core": true, "difficulty": 6, "topics": [ - "Control flow (conditionals)", + "Control-flow (conditionals)", "Exception handling", "Sets", "Randomness", @@ -215,8 +215,8 @@ "core": true, "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Regular expressions", "Exception handling", "Strings", @@ -255,7 +255,7 @@ "unlocked_by": null, "difficulty": 2, "topics": [ - "Control flow (conditionals)", + "Control-flow (conditionals)", "Exception handling", "Parsing", "Text formatting", @@ -282,8 +282,8 @@ "unlocked_by": "bob", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Strings" ] }, @@ -327,7 +327,7 @@ "unlocked_by": "rna-transcription", "difficulty": 2, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Transforming", "Maps", "Integers" @@ -351,7 +351,7 @@ "unlocked_by": "space-age", "difficulty": 5, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Integers", "Mathematics" ] @@ -363,8 +363,8 @@ "unlocked_by": "leap", "difficulty": 3, "topics": [ - "Control flow (loops)", - "Control flow (conditionals)", + "Control-flow (loops)", + "Control-flow (conditionals)", "Exception handling", "Integers", "Mathematics" @@ -389,8 +389,8 @@ "unlocked_by": "space-age", "difficulty": 3, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Arrays", "Integers", "Mathematics" @@ -403,7 +403,7 @@ "unlocked_by": "pangram", "difficulty": 1, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Lists", "Strings", "Unicode", @@ -418,7 +418,7 @@ "difficulty": 2, "topics": [ "Strings", - "Control flow (loops)", + "Control-flow (loops)", "Regular expressions", "Transforming" ] @@ -430,8 +430,8 @@ "unlocked_by": "rna-transcription", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Maps", "Strings" ] @@ -443,8 +443,8 @@ "unlocked_by": null, "difficulty": 3, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Pattern recognition", "Transforming" @@ -457,8 +457,8 @@ "unlocked_by": "linked-list", "difficulty": 8, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Data structures", "Lists", "Arrays", @@ -472,7 +472,7 @@ "unlocked_by": "rna-transcription", "difficulty": 2, "topics": [ - "Control flow (conditionals)", + "Control-flow (conditionals)", "Strings", "Integers", "Transforming" @@ -485,8 +485,8 @@ "unlocked_by": "rna-transcription", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Bitwise operations", "Arrays" ] @@ -498,8 +498,8 @@ "unlocked_by": "list-ops", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Lists", "Arrays", @@ -514,8 +514,8 @@ "unlocked_by": "simple-cipher", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Arrays", "Regular expressions", @@ -529,7 +529,7 @@ "unlocked_by": "list-ops", "difficulty": 5, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Algorithms", "Lists", "Callbacks" @@ -542,8 +542,8 @@ "unlocked_by": "atbash-cipher", "difficulty": 9, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Arrays", "Sorting", @@ -559,8 +559,8 @@ "unlocked_by": "binary", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings", @@ -574,8 +574,8 @@ "unlocked_by": "prime-factors", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Recursion" @@ -588,8 +588,8 @@ "unlocked_by": "binary", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings", @@ -603,8 +603,8 @@ "unlocked_by": "space-age", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings" @@ -617,8 +617,8 @@ "unlocked_by": "bob", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Strings", "Games", "Regular expressions", @@ -632,8 +632,8 @@ "unlocked_by": "space-age", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Algorithms", "Mathematics", "Integers" @@ -646,7 +646,7 @@ "unlocked_by": "pangram", "difficulty": 3, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Exception handling", "Strings", "Text formatting" @@ -659,7 +659,7 @@ "unlocked_by": "space-age", "difficulty": 3, "topics": [ - "Control flow (loops)", + "Control-flow (loops)", "Algorithms", "Mathematics", "Integers" @@ -672,8 +672,8 @@ "unlocked_by": "bob", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Arrays", "Strings", "Text formatting", @@ -698,8 +698,8 @@ "unlocked_by": "binary", "difficulty": 4, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings", @@ -713,8 +713,8 @@ "unlocked_by": "pangram", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Strings", @@ -729,8 +729,8 @@ "unlocked_by": "wordy", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Strings", "Arrays", "Text formatting" @@ -743,8 +743,8 @@ "unlocked_by": "linked-list", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Recursion", "Arrays", "Algorithms" @@ -757,8 +757,8 @@ "unlocked_by": "binary-search", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Recursion", "Algorithms" ] @@ -770,8 +770,8 @@ "unlocked_by": "wordy", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Strings", "Games", @@ -785,8 +785,8 @@ "unlocked_by": "prime-factors", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Algorithms", "Mathematics", @@ -800,8 +800,8 @@ "unlocked_by": "prime-factors", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Algorithms", "Mathematics", @@ -815,8 +815,8 @@ "unlocked_by": "bob", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Mathematics", "Integers", "Exception handling", @@ -831,8 +831,8 @@ "unlocked_by": "linked-list", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Data structures", "Arrays", "Lists", @@ -848,8 +848,8 @@ "unlocked_by": "prime-factors", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Lists", "Integers" ] @@ -861,8 +861,8 @@ "unlocked_by": null, "difficulty": 8, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Optional values", "Exception handling", "Equality", @@ -877,8 +877,8 @@ "unlocked_by": "matrix", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Optional values", "Exception handling", "Equality", @@ -895,8 +895,8 @@ "unlocked_by": "matrix", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Equality", "Parsing", @@ -911,8 +911,8 @@ "unlocked_by": "gigasecond", "difficulty": 7, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Equality", "Time", @@ -926,8 +926,8 @@ "unlocked_by": "pangram", "difficulty": 3, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Strings", "Parsing", "Exception handling" @@ -940,8 +940,8 @@ "unlocked_by": "grade-school", "difficulty": 6, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Arrays", "Parsing", "Algorithms", @@ -956,8 +956,8 @@ "unlocked_by": "grade-school", "difficulty": 8, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Arrays", "Parsing", "Games", @@ -972,8 +972,8 @@ "unlocked_by": "pascals-triangle", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Arrays", "Parsing", "Games", @@ -988,8 +988,8 @@ "unlocked_by": "binary", "difficulty": 5, "topics": [ - "Control flow (conditionals)", - "Control flow (loops)", + "Control-flow (conditionals)", + "Control-flow (loops)", "Exception handling", "Parsing", "Mathematics", From 17eedd1f48728f7db44da9d2369e3e1a5aa63799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Sat, 2 Sep 2017 08:22:48 -0300 Subject: [PATCH 146/272] Avoid mutations on List#toArray() (#400) @tejasbubane caught this on exercism/ecmascript#345, while reviewing @apapirovski's ECMAScript version of this exercise --- exercises/simple-linked-list/example.js | 7 ++++--- exercises/simple-linked-list/simple-linked-list.spec.js | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/exercises/simple-linked-list/example.js b/exercises/simple-linked-list/example.js index 5d9cfed0..6b097473 100644 --- a/exercises/simple-linked-list/example.js +++ b/exercises/simple-linked-list/example.js @@ -97,10 +97,11 @@ List.prototype.reverse = function () { List.prototype.toArray = function () { var array = []; + var current = this.head; - while (this.head) { - array.push(this.head.value); - this.shift(); + while (current) { + array.push(current.value); + current = current.next; } return array; diff --git a/exercises/simple-linked-list/simple-linked-list.spec.js b/exercises/simple-linked-list/simple-linked-list.spec.js index e1f8724e..bc104a23 100644 --- a/exercises/simple-linked-list/simple-linked-list.spec.js +++ b/exercises/simple-linked-list/simple-linked-list.spec.js @@ -141,6 +141,9 @@ describe('simple-linked-list', function () { expect(a.length).toBe(2); expect(a[0]).toBe(1); expect(a[1]).toBe(2); + + expect(ll.head.value).toBe(1); + expect(ll.head.next.value).toBe(2); }); xit('allows you to reverse a List', function () { From 1e88431c51aad9ad03da7511c72a6575e7901214 Mon Sep 17 00:00:00 2001 From: Vankog Date: Sun, 3 Sep 2017 13:16:32 +0200 Subject: [PATCH 147/272] added simple-cipher test: message > key (#401) I just saw an exercise implementation of somebody who did not account for messages longer than the key and I figured this needs to be in the spec. fixing example implementation for new case, as it does not account for this case neither. the example implementation had the issue of not being able to handle messages longer than the key. --- exercises/simple-cipher/example.js | 6 +++--- exercises/simple-cipher/simple-cipher.spec.js | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/exercises/simple-cipher/example.js b/exercises/simple-cipher/example.js index a55a265b..ecfae367 100644 --- a/exercises/simple-cipher/example.js +++ b/exercises/simple-cipher/example.js @@ -20,14 +20,14 @@ module.exports = function (userDefinedKey) { function addEncodedCharacter(character, index, array) { /*jshint validthis:true */ - var i = ALPHABET.indexOf(character) + ALPHABET.indexOf(key[index]); + var i = ALPHABET.indexOf(character) + ALPHABET.indexOf(key[index%key.length]); if (i >= ALPHABET.length) { i -= ALPHABET.length; } this.push(ALPHABET[i]); } function addDecodedCharacter(character, index, array) { /*jshint validthis:true */ - var i = ALPHABET.indexOf(character) - ALPHABET.indexOf(key[index]); + var i = ALPHABET.indexOf(character) - ALPHABET.indexOf(key[index%key.length]); if (i < 0) { i += ALPHABET.length; } this.push(ALPHABET[i]); } @@ -50,4 +50,4 @@ module.exports = function (userDefinedKey) { if (userDefinedKey === '' || key.match(/[\dA-Z]/)) { throw new Error('Bad key'); } -}; \ No newline at end of file +}; diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index 15a3d272..fa8f8218 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -72,4 +72,9 @@ describe('Substitution cipher', function () { xit('can wrap', function () { expect(cipher.encode('zzzzzzzzzz')).toEqual('zabcdefghi'); }); + + xit('can handle messages longer than the key', function() { + expect(new Cipher('abc').encode('iamapandabear')) + .toEqual('iboaqcnecbfcr'); + }); }); From b4a5a820340e2ee2cd3fd65c0f9ca05be9c8a9fc Mon Sep 17 00:00:00 2001 From: Vankog Date: Mon, 4 Sep 2017 23:53:26 +0200 Subject: [PATCH 148/272] Synchronizing EcmaScript <-> Javascript test for simple-cipher (#403) * Synchronizing EcmaScript <-> Javascript test for simple-cipher * Implement exercise nucleotide-count --- exercises/simple-cipher/simple-cipher.spec.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index fa8f8218..c2b41e81 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -4,7 +4,7 @@ describe('Random key cipher', function () { var cipher = new Cipher(); it('has a key made of letters', function () { - expect(cipher.key).toMatch(/[a-z]+/); + expect(cipher.key).toMatch(/^[a-z]+$/); }); // Here we take advantage of the fact that plaintext of "aaa..." @@ -69,10 +69,14 @@ describe('Substitution cipher', function () { .toEqual('qayaeaagaciai'); }); - xit('can wrap', function () { + xit('can wrap on encode', function () { expect(cipher.encode('zzzzzzzzzz')).toEqual('zabcdefghi'); }); - + + xit('can wrap on decode', () => { + expect(cipher.decode('zabcdefghi')).toEqual('zzzzzzzzzz'); + }); + xit('can handle messages longer than the key', function() { expect(new Cipher('abc').encode('iamapandabear')) .toEqual('iboaqcnecbfcr'); From 14096e97a544581b991ec3f5ceae9740a86da311 Mon Sep 17 00:00:00 2001 From: Vankog Date: Tue, 5 Sep 2017 15:58:48 +0200 Subject: [PATCH 149/272] ran new configlet fmt as told in the documentation: (#404) https://github.com/exercism/docs/blob/master/you-can-help/implement-an-exercise-from-specification.md#configuring-the-exercise --- config.json | 1326 +++++++++++++++++++-------------------- config/maintainers.json | 70 +-- 2 files changed, 697 insertions(+), 699 deletions(-) diff --git a/config.json b/config.json index 97056c75..536335e2 100644 --- a/config.json +++ b/config.json @@ -1,1048 +1,1046 @@ { - "language": "JavaScript", "active": true, - "test_pattern": ".*[.]spec[.]js$", "exercises": [ { - "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256", - "slug": "hello-world", "core": true, "difficulty": 1, + "slug": "hello-world", "topics": [ - "Control-flow (conditionals)", - "Optional values", - "Strings", - "Text formatting" - ] + "control-flow-(conditionals)", + "optional-values", + "strings", + "text-formatting" + ], + "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256" }, { - "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b", - "slug": "leap", "core": true, "difficulty": 1, + "slug": "leap", "topics": [ - "Booleans", - "Integers", - "Logic" - ] + "booleans", + "integers", + "logic" + ], + "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b" }, { - "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c", - "slug": "rna-transcription", "core": true, "difficulty": 1, + "slug": "rna-transcription", "topics": [ - "Strings", - "Transforming" - ] + "strings", + "transforming" + ], + "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c" }, { - "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af", - "slug": "simple-cipher", "core": true, "difficulty": 1, + "slug": "simple-cipher", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Mathematics", - "Strings", - "Randomness", - "Text formatting", - "Transforming" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "mathematics", + "randomness", + "strings", + "text-formatting", + "transforming" + ], + "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af" }, { - "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15", - "slug": "pangram", "core": true, "difficulty": 2, + "slug": "pangram", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Lists", - "Strings", - "Maps", - "Algorithms", - "Searching" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "lists", + "maps", + "searching", + "strings" + ], + "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15" }, { - "uuid": "246be5d9-b361-4893-9707-f218ede2bed6", - "slug": "bob", "core": true, "difficulty": 2, + "slug": "bob", "topics": [ - "Control-flow (conditionals)", - "Polymorfism", - "Strings", - "Unicode", - "Pattern recognition", - "Regular expressions" - ] + "control-flow-(conditionals)", + "pattern-recognition", + "polymorfism", + "regular-expressions", + "strings", + "unicode" + ], + "uuid": "246be5d9-b361-4893-9707-f218ede2bed6" }, { - "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44", - "slug": "gigasecond", "core": true, "difficulty": 2, + "slug": "gigasecond", "topics": [ - "Time" - ] + "time" + ], + "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44" }, { - "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", - "slug": "space-age", "core": true, "difficulty": 3, + "slug": "space-age", "topics": [ - "Classes", - "Floating-point numbers", - "Mathematics" - ] + "classes", + "floating-point-numbers", + "mathematics" + ], + "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8" }, { - "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e", - "slug": "binary", "core": true, "difficulty": 4, + "slug": "binary", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Regular expressions", - "Exception handling" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics", + "regular-expressions", + "strings" + ], + "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e" }, { - "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f", - "slug": "prime-factors", "core": true, "difficulty": 4, + "slug": "prime-factors", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Algorithms", - "Integers" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics" + ], + "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f" }, { - "uuid": "fbfe6032-c209-40bd-b485-8b2881638166", - "slug": "matrix", "core": true, "difficulty": 4, + "slug": "matrix", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Data structures", - "Arrays", - "Matrices", - "Text formatting" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "data-structures", + "matrices", + "text-formatting" + ], + "uuid": "fbfe6032-c209-40bd-b485-8b2881638166" }, { - "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385", - "slug": "linked-list", "core": true, "difficulty": 5, + "slug": "linked-list", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Data structures", - "Arrays", - "Lists", - "Optional values" - ] + "algorithms", + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "data-structures", + "lists", + "optional-values" + ], + "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385" }, { - "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf", - "slug": "pascals-triangle", "core": true, "difficulty": 5, + "slug": "pascals-triangle", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Strings", - "Text formatting" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "mathematics", + "strings", + "text-formatting" + ], + "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf" }, { - "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0", - "slug": "secret-handshake", "core": true, "difficulty": 6, + "slug": "secret-handshake", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Games", - "Bitwise operations", - "Arrays" - ] + "algorithms", + "arrays", + "bitwise-operations", + "control-flow-(conditionals)", + "control-flow-(loops)", + "games" + ], + "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0" }, { - "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec", - "slug": "grade-school", "core": true, "difficulty": 6, + "slug": "grade-school", "topics": [ - "Arrays", - "Maps", - "Sorting" - ] + "arrays", + "maps", + "sorting" + ], + "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec" }, { - "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a", - "slug": "robot-name", "core": true, "difficulty": 6, + "slug": "robot-name", "topics": [ - "Control-flow (conditionals)", - "Exception handling", - "Sets", - "Randomness", - "Regular expressions" - ] + "control-flow-(conditionals)", + "exception-handling", + "randomness", + "regular-expressions", + "sets" + ], + "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a" }, { - "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843", - "slug": "wordy", "core": true, "difficulty": 7, + "slug": "wordy", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Regular expressions", - "Exception handling", - "Strings", - "Pattern recognition", - "Parsing" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "parsing", + "pattern-recognition", + "regular-expressions", + "strings" + ], + "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843" }, { - "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c", - "slug": "list-ops", "core": true, "difficulty": 8, + "slug": "list-ops", "topics": [ - "Data structures", - "Lists", - "Recursion" - ] + "data-structures", + "lists", + "recursion" + ], + "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c" }, { - "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0", - "slug": "hamming", "core": false, - "unlocked_by": "rna-transcription", "difficulty": 2, + "slug": "hamming", "topics": [ - "Control-flow (loops)", - "Control-flow (conditionals)", - "Equality", - "Strings" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "equality", + "strings" + ], + "unlocked_by": "rna-transcription", + "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0" }, { - "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac", - "slug": "run-length-encoding", "core": false, - "unlocked_by": null, "difficulty": 2, + "slug": "run-length-encoding", "topics": [ - "Control-flow (conditionals)", - "Exception handling", - "Parsing", - "Text formatting", - "Regular expressions", - "Pattern recognition", - "Strings" - ] + "control-flow-(conditionals)", + "exception-handling", + "parsing", + "pattern-recognition", + "regular-expressions", + "strings", + "text-formatting" + ], + "unlocked_by": null, + "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac" }, { - "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0", - "slug": "isogram", "core": false, - "unlocked_by": "pangram", "difficulty": 2, + "slug": "isogram", "topics": [ - "Strings", - "Filtering" - ] + "filtering", + "strings" + ], + "unlocked_by": "pangram", + "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0" }, { - "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a", - "slug": "beer-song", "core": false, - "unlocked_by": "bob", "difficulty": 5, + "slug": "beer-song", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Strings" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "strings" + ], + "unlocked_by": "bob", + "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a" }, { - "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70", - "slug": "phone-number", "core": false, - "unlocked_by": "pangram", "difficulty": 3, + "slug": "phone-number", "topics": [ - "Parsing", - "Transforming" - ] + "parsing", + "transforming" + ], + "unlocked_by": "pangram", + "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70" }, { - "uuid": "432ec2ce-c919-4142-aea2-389b67503252", - "slug": "anagram", "core": false, - "unlocked_by": "pangram", "difficulty": 1, + "slug": "anagram", "topics": [ - "Strings", - "Filtering" - ] + "filtering", + "strings" + ], + "unlocked_by": "pangram", + "uuid": "432ec2ce-c919-4142-aea2-389b67503252" }, { - "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17", - "slug": "food-chain", "core": false, - "unlocked_by": "bob", "difficulty": 4, + "slug": "food-chain", "topics": [ - "Text formatting", - "Algorithms" - ] + "algorithms", + "text-formatting" + ], + "unlocked_by": "bob", + "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17" }, { - "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a", - "slug": "etl", "core": false, - "unlocked_by": "rna-transcription", "difficulty": 2, + "slug": "etl", "topics": [ - "Control-flow (loops)", - "Transforming", - "Maps", - "Integers" - ] + "control-flow-(loops)", + "integers", + "maps", + "transforming" + ], + "unlocked_by": "rna-transcription", + "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a" }, { - "uuid": "4a83a72c-db0a-45b6-b77c-1949cb24fbae", - "slug": "sublist", - "difficulty": 4, "core": false, - "unlocked_by": "linked-list", + "difficulty": 4, + "slug": "sublist", "topics": [ - "Lists", - "Arrays" - ] + "arrays", + "lists" + ], + "unlocked_by": "linked-list", + "uuid": "4a83a72c-db0a-45b6-b77c-1949cb24fbae" }, { - "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda", - "slug": "grains", "core": false, - "unlocked_by": "space-age", "difficulty": 5, + "slug": "grains", "topics": [ - "Control-flow (loops)", - "Integers", - "Mathematics" - ] + "control-flow-(loops)", + "integers", + "mathematics" + ], + "unlocked_by": "space-age", + "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda" }, { - "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d", - "slug": "triangle", "core": false, - "unlocked_by": "leap", "difficulty": 3, + "slug": "triangle", "topics": [ - "Control-flow (loops)", - "Control-flow (conditionals)", - "Exception handling", - "Integers", - "Mathematics" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics" + ], + "unlocked_by": "leap", + "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d" }, { - "uuid": "1ff85150-6c51-4758-af02-4484cf35658e", - "slug": "clock", "core": false, - "unlocked_by": "gigasecond", "difficulty": 5, + "slug": "clock", "topics": [ - "Dates", - "Time", - "Globalization" - ] + "dates", + "globalization", + "time" + ], + "unlocked_by": "gigasecond", + "uuid": "1ff85150-6c51-4758-af02-4484cf35658e" }, { - "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6", - "slug": "perfect-numbers", "core": false, - "unlocked_by": "space-age", "difficulty": 3, + "slug": "perfect-numbers", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Arrays", - "Integers", - "Mathematics" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics" + ], + "unlocked_by": "space-age", + "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6" }, { - "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838", - "slug": "word-count", "core": false, - "unlocked_by": "pangram", "difficulty": 1, + "slug": "word-count", "topics": [ - "Control-flow (loops)", - "Lists", - "Strings", - "Unicode", - "Regular expressions" - ] + "control-flow-(loops)", + "lists", + "regular-expressions", + "strings", + "unicode" + ], + "unlocked_by": "pangram", + "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838" }, { - "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b", - "slug": "acronym", "core": false, - "unlocked_by": "pangram", "difficulty": 2, + "slug": "acronym", "topics": [ - "Strings", - "Control-flow (loops)", - "Regular expressions", - "Transforming" - ] + "control-flow-(loops)", + "regular-expressions", + "strings", + "transforming" + ], + "unlocked_by": "pangram", + "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b" }, { - "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b", - "slug": "scrabble-score", "core": false, - "unlocked_by": "rna-transcription", "difficulty": 5, + "slug": "scrabble-score", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Maps", - "Strings" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "maps", + "strings" + ], + "unlocked_by": "rna-transcription", + "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b" }, { - "uuid": "4226e3c6-99d4-406d-998a-bcf11845b211", - "slug": "roman-numerals", "core": false, - "unlocked_by": null, "difficulty": 3, + "slug": "roman-numerals", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Pattern recognition", - "Transforming" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "mathematics", + "pattern-recognition", + "transforming" + ], + "unlocked_by": null, + "uuid": "4226e3c6-99d4-406d-998a-bcf11845b211" }, { - "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc", - "slug": "circular-buffer", "core": false, - "unlocked_by": "linked-list", "difficulty": 8, + "slug": "circular-buffer", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Data structures", - "Lists", - "Arrays", - "Exception handling" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "data-structures", + "exception-handling", + "lists" + ], + "unlocked_by": "linked-list", + "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc" }, { - "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d", - "slug": "raindrops", "core": false, - "unlocked_by": "rna-transcription", "difficulty": 2, + "slug": "raindrops", "topics": [ - "Control-flow (conditionals)", - "Strings", - "Integers", - "Transforming" - ] + "control-flow-(conditionals)", + "integers", + "strings", + "transforming" + ], + "unlocked_by": "rna-transcription", + "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d" }, { - "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02", - "slug": "allergies", "core": false, - "unlocked_by": "rna-transcription", "difficulty": 6, + "slug": "allergies", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Bitwise operations", - "Arrays" - ] + "arrays", + "bitwise-operations", + "control-flow-(conditionals)", + "control-flow-(loops)" + ], + "unlocked_by": "rna-transcription", + "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02" }, { - "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247", - "slug": "strain", "core": false, - "unlocked_by": "list-ops", "difficulty": 4, + "slug": "strain", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Lists", - "Arrays", - "Callbacks", - "Filtering" - ] + "algorithms", + "arrays", + "callbacks", + "control-flow-(conditionals)", + "control-flow-(loops)", + "filtering", + "lists" + ], + "unlocked_by": "list-ops", + "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247" }, { - "uuid": "99974454-0736-4cc0-b88f-ed5701397a97", - "slug": "atbash-cipher", "core": false, - "unlocked_by": "simple-cipher", "difficulty": 7, + "slug": "atbash-cipher", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Arrays", - "Regular expressions", - "Text formatting" - ] + "algorithms", + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "regular-expressions", + "text-formatting" + ], + "unlocked_by": "simple-cipher", + "uuid": "99974454-0736-4cc0-b88f-ed5701397a97" }, { - "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9", - "slug": "accumulate", "core": false, - "unlocked_by": "list-ops", "difficulty": 5, + "slug": "accumulate", "topics": [ - "Control-flow (loops)", - "Algorithms", - "Lists", - "Callbacks" - ] + "algorithms", + "callbacks", + "control-flow-(loops)", + "lists" + ], + "unlocked_by": "list-ops", + "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9" }, { - "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad", - "slug": "crypto-square", "core": false, - "unlocked_by": "atbash-cipher", "difficulty": 9, + "slug": "crypto-square", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Arrays", - "Sorting", - "Text formatting", - "Regular expressions", - "Transforming" - ] + "algorithms", + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "regular-expressions", + "sorting", + "text-formatting", + "transforming" + ], + "unlocked_by": "atbash-cipher", + "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad" }, { - "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d", - "slug": "trinary", "core": false, - "unlocked_by": "binary", "difficulty": 4, + "slug": "trinary", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Regular expressions" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics", + "regular-expressions", + "strings" + ], + "unlocked_by": "binary", + "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d" }, { - "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32", - "slug": "sieve", "core": false, - "unlocked_by": "prime-factors", "difficulty": 5, + "slug": "sieve", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Recursion" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics", + "recursion" + ], + "unlocked_by": "prime-factors", + "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32" }, { - "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8", - "slug": "octal", "core": false, - "unlocked_by": "binary", "difficulty": 4, + "slug": "octal", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Regular expressions" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics", + "regular-expressions", + "strings" + ], + "unlocked_by": "binary", + "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8" }, { - "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c", - "slug": "luhn", "core": false, - "unlocked_by": "space-age", "difficulty": 4, + "slug": "luhn", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics", + "strings" + ], + "unlocked_by": "space-age", + "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c" }, { - "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38", - "slug": "pig-latin", "core": false, - "unlocked_by": "bob", "difficulty": 4, + "slug": "pig-latin", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Strings", - "Games", - "Regular expressions", - "Transforming" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "games", + "regular-expressions", + "strings", + "transforming" + ], + "unlocked_by": "bob", + "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38" }, { - "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6", - "slug": "pythagorean-triplet", "core": false, - "unlocked_by": "space-age", "difficulty": 5, + "slug": "pythagorean-triplet", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Mathematics", - "Integers" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics" + ], + "unlocked_by": "space-age", + "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6" }, { - "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5", - "slug": "series", "core": false, - "unlocked_by": "pangram", "difficulty": 3, + "slug": "series", "topics": [ - "Control-flow (loops)", - "Exception handling", - "Strings", - "Text formatting" - ] + "control-flow-(loops)", + "exception-handling", + "strings", + "text-formatting" + ], + "unlocked_by": "pangram", + "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5" }, { - "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f", - "slug": "difference-of-squares", "core": false, - "unlocked_by": "space-age", "difficulty": 3, + "slug": "difference-of-squares", "topics": [ - "Control-flow (loops)", - "Algorithms", - "Mathematics", - "Integers" - ] + "algorithms", + "control-flow-(loops)", + "integers", + "mathematics" + ], + "unlocked_by": "space-age", + "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f" }, { - "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308", - "slug": "proverb", "core": false, - "unlocked_by": "bob", "difficulty": 4, + "slug": "proverb", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Arrays", - "Strings", - "Text formatting", - "Optional values" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "optional-values", + "strings", + "text-formatting" + ], + "unlocked_by": "bob", + "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308" }, { - "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916", - "slug": "flatten-array", "core": false, - "unlocked_by": "list-ops", "difficulty": 1, + "slug": "flatten-array", "topics": [ - "Arrays", - "Recursion" - ] + "arrays", + "recursion" + ], + "unlocked_by": "list-ops", + "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916" }, { - "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870", - "slug": "hexadecimal", "core": false, - "unlocked_by": "binary", "difficulty": 4, + "slug": "hexadecimal", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Regular expressions" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "mathematics", + "regular-expressions", + "strings" + ], + "unlocked_by": "binary", + "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870" }, { - "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c", - "slug": "largest-series-product", "core": false, - "unlocked_by": "pangram", "difficulty": 7, + "slug": "largest-series-product", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Strings", - "Exception handling", - "Regular expressions" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics", + "regular-expressions", + "strings" + ], + "unlocked_by": "pangram", + "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c" }, { - "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87", - "slug": "kindergarten-garden", "core": false, - "unlocked_by": "wordy", "difficulty": 7, + "slug": "kindergarten-garden", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Strings", - "Arrays", - "Text formatting" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "strings", + "text-formatting" + ], + "unlocked_by": "wordy", + "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87" }, { - "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8", - "slug": "binary-search", "core": false, - "unlocked_by": "linked-list", "difficulty": 7, + "slug": "binary-search", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Recursion", - "Arrays", - "Algorithms" - ] + "algorithms", + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "recursion" + ], + "unlocked_by": "linked-list", + "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8" }, { - "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85", - "slug": "binary-search-tree", "core": false, - "unlocked_by": "binary-search", "difficulty": 6, + "slug": "binary-search-tree", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Recursion", - "Algorithms" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "recursion" + ], + "unlocked_by": "binary-search", + "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85" }, { - "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad", - "slug": "robot-simulator", "core": false, - "unlocked_by": "wordy", "difficulty": 5, + "slug": "robot-simulator", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Strings", - "Games", - "Parsing" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "games", + "parsing", + "strings" + ], + "unlocked_by": "wordy", + "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad" }, { - "uuid": "8fa51380-ec2c-4806-8833-cf543579de17", - "slug": "nth-prime", "core": false, - "unlocked_by": "prime-factors", "difficulty": 5, + "slug": "nth-prime", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Algorithms", - "Mathematics", - "Integers" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics" + ], + "unlocked_by": "prime-factors", + "uuid": "8fa51380-ec2c-4806-8833-cf543579de17" }, { - "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1", - "slug": "palindrome-products", "core": false, - "unlocked_by": "prime-factors", "difficulty": 7, + "slug": "palindrome-products", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Algorithms", - "Mathematics", - "Integers" - ] + "algorithms", + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics" + ], + "unlocked_by": "prime-factors", + "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1" }, { - "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa", - "slug": "say", "core": false, - "unlocked_by": "bob", "difficulty": 6, + "slug": "say", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Mathematics", - "Integers", - "Exception handling", - "Strings", - "Text formatting" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics", + "strings", + "text-formatting" + ], + "unlocked_by": "bob", + "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa" }, { - "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659", - "slug": "custom-set", "core": false, - "unlocked_by": "linked-list", "difficulty": 6, + "slug": "custom-set", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Data structures", - "Arrays", - "Lists", - "Sets", - "Equality", - "Recursion" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "data-structures", + "equality", + "lists", + "recursion", + "sets" + ], + "unlocked_by": "linked-list", + "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659" }, { - "uuid": "f30463c4-9d8c-4238-a691-e594291b4425", - "slug": "sum-of-multiples", "core": false, - "unlocked_by": "prime-factors", "difficulty": 5, + "slug": "sum-of-multiples", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Lists", - "Integers" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "integers", + "lists" + ], + "unlocked_by": "prime-factors", + "uuid": "f30463c4-9d8c-4238-a691-e594291b4425" }, { - "uuid": "fefcfeba-59ec-4c63-a562-374201ee39a7", - "slug": "queen-attack", "core": false, - "unlocked_by": null, "difficulty": 8, + "slug": "queen-attack", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Optional values", - "Exception handling", - "Equality", - "Text formatting", - "Parsing" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "equality", + "exception-handling", + "optional-values", + "parsing", + "text-formatting" + ], + "unlocked_by": null, + "uuid": "fefcfeba-59ec-4c63-a562-374201ee39a7" }, { - "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb", - "slug": "saddle-points", "core": false, - "unlocked_by": "matrix", "difficulty": 6, + "slug": "saddle-points", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Optional values", - "Exception handling", - "Equality", - "Parsing", - "Integers", - "Matrices", - "Mathematics" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "equality", + "exception-handling", + "integers", + "mathematics", + "matrices", + "optional-values", + "parsing" + ], + "unlocked_by": "matrix", + "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb" }, { - "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756", - "slug": "ocr-numbers", "core": false, - "unlocked_by": "matrix", "difficulty": 5, + "slug": "ocr-numbers", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Equality", - "Parsing", - "Integers", - "Text formatting" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "equality", + "exception-handling", + "integers", + "parsing", + "text-formatting" + ], + "unlocked_by": "matrix", + "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756" }, { - "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8", - "slug": "meetup", "core": false, - "unlocked_by": "gigasecond", "difficulty": 7, + "slug": "meetup", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Equality", - "Time", - "Dates" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "dates", + "equality", + "exception-handling", + "time" + ], + "unlocked_by": "gigasecond", + "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8" }, { - "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84", - "slug": "bracket-push", "core": false, - "unlocked_by": "pangram", "difficulty": 3, + "slug": "bracket-push", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Strings", - "Parsing", - "Exception handling" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "parsing", + "strings" + ], + "unlocked_by": "pangram", + "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84" }, { - "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1", - "slug": "two-bucket", "core": false, - "unlocked_by": "grade-school", "difficulty": 6, + "slug": "two-bucket", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Arrays", - "Parsing", - "Algorithms", - "Games", - "Exception handling" - ] + "algorithms", + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "games", + "parsing" + ], + "unlocked_by": "grade-school", + "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1" }, { - "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9", - "slug": "bowling", "core": false, - "unlocked_by": "grade-school", "difficulty": 8, + "slug": "bowling", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Arrays", - "Parsing", - "Games", - "Exception handling", - "Text formatting" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "games", + "parsing", + "text-formatting" + ], + "unlocked_by": "grade-school", + "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9" }, { - "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956", - "slug": "diamond", "core": false, - "unlocked_by": "pascals-triangle", "difficulty": 5, + "slug": "diamond", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Arrays", - "Parsing", - "Games", - "Exception handling", - "Text formatting" - ] + "arrays", + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "games", + "parsing", + "text-formatting" + ], + "unlocked_by": "pascals-triangle", + "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956" }, { - "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791", - "slug": "all-your-base", "core": false, - "unlocked_by": "binary", "difficulty": 5, + "slug": "all-your-base", "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Exception handling", - "Parsing", - "Mathematics", - "Integers" - ] + "control-flow-(conditionals)", + "control-flow-(loops)", + "exception-handling", + "integers", + "mathematics", + "parsing" + ], + "unlocked_by": "binary", + "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791" }, { - "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3", - "slug": "minesweeper", "core": false, - "unlocked_by": null, "difficulty": 7, + "slug": "minesweeper", "topics": [ - "Games", - "Arrays", - "Algorithms" - ] + "algorithms", + "arrays", + "games" + ], + "unlocked_by": null, + "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3" }, { - "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a", - "slug": "alphametics", "core": false, - "unlocked_by": "grade-school", "difficulty": 7, + "slug": "alphametics", "topics": [ - "Games", - "Algorithms" - ] + "algorithms", + "games" + ], + "unlocked_by": "grade-school", + "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a" }, { - "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626", - "slug": "simple-linked-list", "core": false, - "unlocked_by": "linked-list", "difficulty": 8, + "slug": "simple-linked-list", "topics": [ - "Arrays", - "Data structures", - "Lists" - ] + "arrays", + "data-structures", + "lists" + ], + "unlocked_by": "linked-list", + "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626" }, { - "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c", + "deprecated": true, "slug": "nucleotide-count", - "deprecated": true + "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c" }, { - "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec", + "deprecated": true, "slug": "point-mutations", - "deprecated": true + "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec" } ], - "foregone": [ - - ] -} + "foregone": [], + "language": "JavaScript", + "test_pattern": ".*[.]spec[.]js$" +} \ No newline at end of file diff --git a/config/maintainers.json b/config/maintainers.json index 15965d38..49402a6c 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -1,85 +1,85 @@ { + "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md", "maintainers": [ { - "github_username": "ireddick", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "ireddick", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "rchavarria", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "rchavarria", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "joelwallis", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "joelwallis", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "drueck", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "drueck", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "tejasbubane", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "tejasbubane", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "matthewmorgan", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "matthewmorgan", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "mixolidia", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "mixolidia", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false }, { - "github_username": "ZacharyRSmith", - "show_on_website": false, "alumnus": false, - "name": null, + "avatar_url": null, "bio": null, + "github_username": "ZacharyRSmith", "link_text": null, "link_url": null, - "avatar_url": null + "name": null, + "show_on_website": false } - ], - "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md" -} + ] +} \ No newline at end of file From bad17566fbb5cf28274404cdbc5193e678c2f4ef Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+Radix16@users.noreply.github.com> Date: Wed, 6 Sep 2017 03:49:24 -0700 Subject: [PATCH 150/272] Add exercise change (#394) --- .gitignore | 2 + config.json | 15 ++- exercises/change/README.md | 36 ++++++ exercises/change/change.spec.js | 73 ++++++++++++ exercises/change/example.js | 204 ++++++++++++++++++++++++++++++++ 5 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 exercises/change/README.md create mode 100644 exercises/change/change.spec.js create mode 100644 exercises/change/example.js diff --git a/.gitignore b/.gitignore index ee83fc8c..7af8849c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ tmp bin/configlet bin/configlet.exe .idea + +*.js~ diff --git a/config.json b/config.json index 536335e2..503d292a 100644 --- a/config.json +++ b/config.json @@ -1029,6 +1029,19 @@ "unlocked_by": "linked-list", "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626" }, + { + "core" : false, + "difficulty" : 8, + "slug" : "change", + "topics": [ + "Algorithms", + "Mathematics", + "Performance", + "Searching" + ], + "unlocked_by": "prime-factors", + "uuid" : "910fe904-7e3c-11e7-bb31-be2e44b06b34" + }, { "deprecated": true, "slug": "nucleotide-count", @@ -1043,4 +1056,4 @@ "foregone": [], "language": "JavaScript", "test_pattern": ".*[.]spec[.]js$" -} \ No newline at end of file +} diff --git a/exercises/change/README.md b/exercises/change/README.md new file mode 100644 index 00000000..44bf1f65 --- /dev/null +++ b/exercises/change/README.md @@ -0,0 +1,36 @@ +# Change + +Correctly determine the change to be given using the least number of coins. + +The solution will need to accept a value of change to be given and an array of +coin denominations. The program returns the array of coin denominations to +produce the correct amount of change. For example, if change for 37 cents +is required from coins with the denominations of 1, 5, 10 and 25 then the +result is an array with the values: 1, 1, 10 and 25. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/change/change.spec.js b/exercises/change/change.spec.js new file mode 100644 index 00000000..b43bf9d8 --- /dev/null +++ b/exercises/change/change.spec.js @@ -0,0 +1,73 @@ + + + +var Change =require('./change'); + +describe('Change', function() { + + it('change for 1 cent',function() { + var change= new Change(); + var result = change.calculate([1,5, 10, 25],1); + expect(result).toEqual([1]); + }); + + xit('return a single coin',function() { + var change= new Change(); + var result = change.calculate([1,5, 10, 25, 100],25); + expect(result).toEqual([25]); + }); + + xit('multiple coins coin',function() { + var change= new Change(); + var result = change.calculate([1,5, 10, 25, 100],15); + expect(result).toEqual([5, 10]); + }); + + xit('test with Lillipution Currency where a greedy algorithm fails',function() { + // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method + var change= new Change(); + var result = change.calculate([1, 4, 15, 20, 50],23); + expect(result).toEqual([4,4,15]); + }); + + xit('test with lower Elbonian Currency where a greedy algorithm fails',function() { + // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method + var change= new Change(); + var result = change.calculate([1, 5, 10, 21, 25],63); + expect(result).toEqual([21, 21, 21]); + }); + + xit('test large amount of change',function() { + var change= new Change(); + var 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]); + }); + + xit('test zero change',function() { + var change= new Change(); + var result = change.calculate([1, 5, 10, 21, 25], 0); + expect(result).toEqual([]); + }); + + xit('test less than the smallest currency represented',function() { + var change= new Change(); + var message = 'The total 3 cannot be represented in the given currency.'; + var test=function(){return change.calculate([5,10],3);}; + expect(test).toThrowError(Error,message); + }); + + xit('test a large value that the currency cannot represent',function() { + var change= new Change(); + var message ='The total 94 cannot be represented in the given currency.'; + var test=function(){return change.calculate([5,10], 94);}; + expect(test).toThrowError(Error,message); + }); + + xit('negative change is rejected',function() { + var change= new Change(); + var message = 'Negative totals are not allowed.'; + var test = function(){return change.calculate([1,2,5],-5);}; + expect(test).toThrowError(Error, message); + }); + +}); diff --git a/exercises/change/example.js b/exercises/change/example.js new file mode 100644 index 00000000..cfc68763 --- /dev/null +++ b/exercises/change/example.js @@ -0,0 +1,204 @@ +"use strict" + + +var Change = function() +{ + + +} + +module.exports=Change; + + +//data structure to hold each candidate solution that is generated +var Candidate = function() +{ + + var searched=false; + var coins=[]; + + this.Searched =function() + { + searched=true; + } + + this.isSearched = function() + { + return searched; + } + + this.getCoins = function() + { + return coins; + } + + this.addCoin = function(coin) + { + function sortNum(a,b) + { + return a-b; + } + + coins.push(coin); + coins.sort(sortNum); + + } + + this.getCoinCount=function() + { + return coins.length; + } + + this.getSum=function() + { + function getSum(total, num){return total+num;} + return coins.reduce(getSum); + } + + +} + +Change.prototype.calculate=function(coinArray, target) +{ + + var candidates=[]; + //fill the array with 0 to start + candidates[target]=0; + candidates.fill(0); + + //validation checks up front + if(target==0)return []; + + if(target<0) + { + throw new Error( 'Negative totals are not allowed.'); + } + + if(targetcandidate.getCoinCount()) + { + candidates[sum]=candidate; + } + + if(candidate.getSum()<=target && + typeof(candidates[sum])=='number') + { + candidates[sum]=candidate; + } + } + + + //for the candidate, generate another candate for each of the possible coins + function branch(current) + { + for(let j=0; j Date: Wed, 6 Sep 2017 13:04:10 +0200 Subject: [PATCH 151/272] Update README.md -change the title. -change the travis build URL to use https://travis-ci.org/exercism/javascript. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c724b208..53ffbf13 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# xJavaScript [![Build Status](https://travis-ci.org/exercism/xjavascript.svg?branch=master)](https://travis-ci.org/exercism/xjavascript) +# JavaScript [![Build Status](https://travis-ci.org/exercism/javascript.svg?branch=master)](https://travis-ci.org/exercism/javascript) Exercism exercises in JavaScript @@ -8,7 +8,7 @@ To run the tests, you'll need NodeJS and Jasmine. For information about how to i ## Running Unit Test Suite -The following commands assume that you are in the 'xjavascript' directory: +The following commands assume that you are in the 'javascript' directory: ### All Assignments From 428fc962ebeddf7f00208db6210ee09380476250 Mon Sep 17 00:00:00 2001 From: kclowes Date: Thu, 7 Sep 2017 09:57:08 -0600 Subject: [PATCH 152/272] Fix Broken Link to Install Guide (#407) --- docs/TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 9a353ef3..63b72741 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,7 +1,7 @@ With the first few exercises, you will get a skeleton file with the exported modules. For later ones, you can find more information about modules in the [node documentation](http://nodejs.org/api/modules.html#modules_module_exports). -For running tests, install `jasmine` as described in the [Installing Javascript section](http://exercism.io/languages/javascript/installing). +For running tests, install `jasmine` as described in the [Installing Javascript section](http://exercism.io/languages/javascript/installation). Move to the folder where that exercise's files are located (a path similar to {EXERCISM_HOME_DIR}/javascript/{EXERCISE}). cd ~/exercism/javascript/bob From f624ecf35b09beb1277286c4379d9854702ea897 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Thu, 28 Sep 2017 21:18:14 +0100 Subject: [PATCH 153/272] ESLint with Airbnb Style Guide (#411) * yarn init package.json * yarn add eslint * eslint init w/ airbnb style guide * add lint to scripts * Instructions to check code style * eslint --fix repo * Upgrade to latest stable Node release * Revert "eslint --fix repo" This reverts commit 7fe40de7b6e0996c3aa1cc444231b70c155f9440. * Steps 1 & 2 from 1hella/eslint-config-airbnb-es5 * yarn lint-fix repo * eslint w/ jasmine * Ignore func-names * Remove & from prompt * Updated package-lock.json * Remove use of yarn --- .eslintrc.json | 10 + .travis.yml | 2 +- README.md | 17 +- big-integer.js | 2 +- exercises/accumulate/accumulate.spec.js | 26 +- exercises/acronym/acronym.spec.js | 14 +- exercises/acronym/example.js | 2 +- exercises/all-your-base/all-your-base.spec.js | 2 - exercises/allergies/allergies.spec.js | 29 +- exercises/allergies/example.js | 10 +- exercises/alphametics/alphametics.spec.js | 114 +- exercises/alphametics/example.js | 36 +- exercises/anagram/anagram.spec.js | 25 +- exercises/anagram/example.js | 2 +- exercises/atbash-cipher/atbash-cipher.spec.js | 20 +- exercises/atbash-cipher/example.js | 4 +- exercises/beer-song/beer-song.spec.js | 14 +- exercises/beer-song/example.js | 10 +- .../binary-search-tree.spec.js | 22 +- exercises/binary-search-tree/example.js | 8 +- exercises/binary-search/binary-search.spec.js | 15 +- exercises/binary-search/example.js | 11 +- exercises/binary/binary.spec.js | 23 +- exercises/bob/bob.spec.js | 1 - exercises/bob/example.js | 5 +- exercises/bowling/bowling.spec.js | 96 +- exercises/bowling/example.js | 7 +- exercises/bracket-push/bracket-push.spec.js | 18 +- exercises/bracket-push/example.js | 2 +- exercises/change/change.spec.js | 75 +- exercises/change/example.js | 300 ++- .../circular-buffer/circular-buffer.spec.js | 36 +- exercises/circular-buffer/example.js | 98 +- exercises/clock/clock.spec.js | 8 - exercises/clock/example.js | 2 +- exercises/crypto-square/crypto-square.spec.js | 22 +- exercises/crypto-square/example.js | 18 +- exercises/custom-set/custom-set.spec.js | 84 +- exercises/custom-set/example-gen.js | 54 +- exercises/custom-set/example.js | 51 +- exercises/diamond/diamond.spec.js | 38 +- exercises/diamond/example.js | 38 +- .../difference-of-squares.spec.js | 5 - exercises/difference-of-squares/example.js | 6 +- exercises/etl/etl.spec.js | 11 +- exercises/etl/example.js | 2 +- exercises/flatten-array/example.js | 24 +- exercises/flatten-array/flatten-array.spec.js | 30 +- exercises/food-chain/example.js | 18 +- exercises/food-chain/food-chain.spec.js | 3 +- exercises/gigasecond/example.js | 2 +- exercises/gigasecond/gigasecond.spec.js | 11 +- exercises/grade-school/example.js | 6 +- exercises/grade-school/grade-school.spec.js | 47 +- exercises/grains/big-integer.js | 2 +- exercises/grains/big-integer.spec.js | 21 +- exercises/grains/example.js | 2 +- exercises/hamming/hamming.spec.js | 11 +- exercises/hello-world/example.js | 4 +- exercises/hello-world/hello-world.js | 4 +- exercises/hello-world/hello-world.spec.js | 4 +- exercises/hexadecimal/example.js | 6 +- exercises/hexadecimal/hexadecimal.spec.js | 26 +- exercises/isogram/example.js | 4 +- exercises/isogram/isogram.spec.js | 3 +- exercises/kindergarten-garden/example.js | 8 +- .../kindergarten-garden.spec.js | 5 - exercises/largest-series-product/example.js | 8 +- .../largest-series-product.spec.js | 6 +- exercises/leap/example.js | 2 +- exercises/leap/leap.js | 4 +- exercises/leap/leap.spec.js | 14 +- exercises/linked-list/example.js | 11 +- exercises/linked-list/linked-list.spec.js | 2 +- exercises/list-ops/example.js | 6 +- exercises/list-ops/list-ops.spec.js | 2 +- exercises/luhn/luhn.spec.js | 4 +- exercises/matrix/example.js | 2 +- exercises/matrix/matrix.spec.js | 4 +- exercises/meetup/example.js | 28 +- exercises/meetup/meetup.spec.js | 32 +- exercises/minesweeper/example.js | 38 +- exercises/minesweeper/minesweeper.spec.js | 210 +- exercises/nth-prime/example.js | 4 +- exercises/nth-prime/nth-prime.spec.js | 16 +- .../nucleotide-count/nucleotide-count.spec.js | 20 +- exercises/ocr-numbers/example.js | 62 +- exercises/ocr-numbers/ocr-numbers.spec.js | 2 - exercises/octal/example.js | 8 +- exercises/octal/octal.spec.js | 24 +- exercises/palindrome-products/example.js | 19 +- .../palindrome-products.spec.js | 16 +- exercises/pangram/example.js | 2 +- exercises/pangram/pangram.spec.js | 38 +- exercises/pascals-triangle/example.js | 8 +- .../pascals-triangle/pascals-triangle.spec.js | 4 +- exercises/perfect-numbers/example.js | 19 +- .../perfect-numbers/perfect-numbers.spec.js | 46 +- exercises/phone-number/example.js | 27 +- exercises/phone-number/phone-number.spec.js | 92 +- exercises/pig-latin/example.js | 2 +- exercises/pig-latin/pig-latin.spec.js | 2 - exercises/point-mutations/example.js | 2 +- .../point-mutations/point-mutations.spec.js | 20 +- exercises/prime-factors/example.js | 2 +- exercises/prime-factors/prime-factors.spec.js | 26 +- exercises/proverb/example.js | 26 +- exercises/proverb/proverb.spec.js | 92 +- exercises/pythagorean-triplet/example.js | 4 +- .../pythagorean-triplet.spec.js | 2 - exercises/queen-attack/example.js | 10 +- exercises/queen-attack/queen-attack.spec.js | 42 +- exercises/raindrops/example.js | 5 +- exercises/raindrops/raindrops.spec.js | 37 +- exercises/rna-transcription/example.js | 12 +- .../rna-transcription.spec.js | 27 +- exercises/robot-name/example.js | 16 +- exercises/robot-name/robot-name.spec.js | 30 +- exercises/robot-simulator/example.js | 38 +- .../robot-simulator/robot-simulator.spec.js | 68 +- exercises/roman-numerals/example.js | 28 +- .../roman-numerals/roman-numerals.spec.js | 38 +- exercises/run-length-encoding/example.js | 12 +- .../run-length-encoding.spec.js | 74 +- exercises/saddle-points/example.js | 15 +- exercises/saddle-points/saddle-points.spec.js | 24 +- exercises/say/example.js | 40 +- exercises/say/say.spec.js | 4 +- exercises/scrabble-score/example.js | 16 +- .../scrabble-score/scrabble-score.spec.js | 14 +- exercises/secret-handshake/example.js | 11 +- .../secret-handshake/secret-handshake.spec.js | 24 +- exercises/series/example.js | 6 +- exercises/series/series.spec.js | 4 +- exercises/sieve/example.js | 2 +- exercises/sieve/sieve.spec.js | 10 +- exercises/simple-cipher/example.js | 9 +- exercises/simple-cipher/simple-cipher.spec.js | 2 +- exercises/simple-linked-list/example.js | 9 +- .../simple-linked-list.spec.js | 5 - exercises/space-age/example.js | 34 +- exercises/space-age/space-age.spec.js | 20 +- exercises/strain/example.js | 4 +- exercises/strain/strain.spec.js | 52 +- exercises/sublist/example.js | 30 +- exercises/sublist/sublist.spec.js | 39 +- exercises/sum-of-multiples/example.js | 2 +- exercises/triangle/example.js | 16 +- exercises/triangle/triangle.spec.js | 68 +- exercises/trinary/example.js | 4 +- exercises/trinary/trinary.spec.js | 20 +- exercises/two-bucket/example.js | 58 +- exercises/two-bucket/two-bucket.spec.js | 30 +- exercises/word-count/example.js | 6 +- exercises/word-count/word-count.spec.js | 32 +- exercises/wordy/example.js | 18 +- exercises/wordy/wordy.spec.js | 36 +- package-lock.json | 1842 +++++++++++++++++ package.json | 22 + 159 files changed, 3622 insertions(+), 1937 deletions(-) create mode 100644 .eslintrc.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..50b380a4 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "plugins": ["jasmine"], + "extends": "eslint-config-airbnb-es5", + "env": { + "jasmine": true + }, + "rules": { + "func-names": "off" + } +} diff --git a/.travis.yml b/.travis.yml index e287b590..9dce3c35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: false node_js: - - 5.7 + - "node" install: - "npm install -g jasmine" diff --git a/README.md b/README.md index 53ffbf13..e6c52fb4 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,23 @@ Exercism exercises in JavaScript To run the tests, you'll need NodeJS and Jasmine. For information about how to install these tools, see the [Javascript](http://exercism.io/languages/javascript/about) page. -## Running Unit Test Suite +## Tasks -The following commands assume that you are in the 'javascript' directory: +The following commands assume that you are in the `javascript` directory: -### All Assignments +### Unit Tests: All Assignments - % make test + make test -### Single Assignment +### Unit Tests: Single Assignment - % make test-assignment ASSIGNMENT=wordy + make test-assignment ASSIGNMENT=wordy + +### Code Style + + npm run lint ## Contributing Guide Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data) - diff --git a/big-integer.js b/big-integer.js index 286518df..6f21af28 100644 --- a/big-integer.js +++ b/big-integer.js @@ -1 +1 @@ -var bigInt=function(e){"use strict";function o(e,t){this.value=e,this.sign=t,this.isSmall=!1}function u(e){this.value=e,this.sign=e<0,this.isSmall=!0}function a(e){return-r0?Math.floor(e):Math.ceil(e)}function d(e,n){var r=e.length,i=n.length,s=new Array(r),o=0,u=t,a,f;for(f=0;f=u?1:0,s[f]=a-o*u;while(f0&&s.push(o),s}function v(e,t){return e.length>=t.length?d(e,t):d(t,e)}function m(e,n){var r=e.length,i=new Array(r),s=t,o,u;for(u=0;u0)i[u++]=n%s,n=Math.floor(n/s);return i}function g(e,n){var r=e.length,i=n.length,s=new Array(r),o=0,u=t,a,f;for(a=0;a=0?r=g(e,t):(r=g(t,e),n=!n),r=l(r),typeof r=="number"?(n&&(r=-r),new u(r)):new o(r,n)}function b(e,n,r){var i=e.length,s=new Array(i),a=-n,f=t,c,h;for(c=0;c0)i[a++]=o%s,o=Math.floor(o/s);return i}function S(e,t){var n=[];while(t-->0)n.push(0);return n.concat(e)}function x(e,t){var n=Math.max(e.length,t.length);if(n<=400)return w(e,t);n=Math.ceil(n/2);var r=e.slice(n),i=e.slice(0,n),s=t.slice(n),o=t.slice(0,n),u=x(i,o),a=x(r,s),f=x(v(i,r),v(o,s));return v(v(u,S(g(g(f,u),a),n)),S(a,2*n))}function T(e){var n=e.length,r=h(n+n),i=t,s,o,u,a,f;for(u=0;u=0;d--){p=s-1,p=Math.floor((f[d+i]*s+f[d+i-1])/u),v=0,m=0,y=c.length;for(g=0;gi&&(c=(c+1)*u),a=Math.ceil(c/h);do{p=E(n,a);if(A(p,o)<=0)break;a--}while(a);s.push(a),o=g(o,p)}return s.reverse(),[l(s),l(o)]}function k(e,n){var r=e.length,i=h(r),s=t,o,u,a,f;a=0;for(o=r-1;o>=0;--o)f=a*s+e[o],u=p(f/n),a=f-u*n,i[o]=u|0;return[i,a|0]}function L(e,n){var r,i=z(n),s=e.value,a=i.value,c;if(a===0)throw new Error("Cannot divide by zero");if(e.isSmall)return i.isSmall?[new u(p(s/a)),new u(s%a)]:[W[0],e];if(i.isSmall){if(a===1)return[e,W[0]];if(a==-1)return[e.negate(),W[0]];var h=Math.abs(a);if(ht.length?1:-1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return e[n]>t[n]?1:-1;return 0}function D(e){return(typeof e=="number"||typeof e=="string")&&+Math.abs(e)<=t||e instanceof o&&e.value.length<=1}function P(e,t,n){t=z(t);var r=e.isNegative(),i=t.isNegative(),s=r?e.not():e,o=i?t.not():t,u=[],a=[],f=!1,l=!1;while(!f||!l)s.isZero()?(f=!0,u.push(r?1:0)):r?u.push(s.isEven()?1:0):u.push(s.isEven()?0:1),o.isZero()?(l=!0,a.push(i?1:0)):i?a.push(o.isEven()?1:0):a.push(o.isEven()?0:1),s=s.over(2),o=o.over(2);var c=[];for(var h=0;h=0;c--){var h=f?s.value[c]:t,d=p(Math.random()*h);a.unshift(d),d"}function U(e,t){t=bigInt(t);if(t.isZero()){if(e.isZero())return"0";throw new Error("Cannot convert nonzero numbers to base 0.")}if(t.equals(-1))return e.isZero()?"0":e.isNegative()?(new Array(1-e)).join("10"):"1"+(new Array(+e)).join("01");var n="";e.isNegative()&&t.isPositive()&&(n="-",e=e.abs());if(t.equals(1))return e.isZero()?"0":n+(new Array(+e+1)).join(1);var r=[],i=e,s;while(i.isNegative()||i.compareAbs(t)>=0){s=i.divmod(t),i=s.quotient;var o=s.remainder;o.isNegative()&&(o=t.minus(o).abs(),i=i.next()),r.push(R(o))}return r.push(R(i)),n+r.reverse().join("")}function z(e){if(e instanceof o||e instanceof u)return e;if(typeof e=="number"){if(a(e))return new u(e);e=String(e)}if(typeof e=="string"){if(a(+e)){var t=+e;if(t===p(t))return new u(t);throw"Invalid integer: "+e}var r=e[0]==="-";r&&(e=e.slice(1));var i=e.split(/e/i);if(i.length>2)throw new Error("Invalid integer: "+f.join("e"));if(i.length===2){var s=i[1];s[0]==="+"&&(s=s.slice(1)),s=+s;if(s!==p(s)||!a(s))throw new Error("Invalid integer: "+s+" is not a valid exponent.");var f=i[0],l=f.indexOf(".");l>=0&&(s-=f.length-l,f=f.slice(0,l)+f.slice(l+1));if(s<0)throw new Error("Cannot include negative exponent part for integers");f+=(new Array(s+1)).join("0"),e=f}var h=/^([0-9][0-9]*)$/.test(e);if(!h)throw new Error("Invalid integer: "+e);var d=[],v=e.length,m=n,g=v-m;while(v>0)d.push(+e.slice(g,v)),g-=m,g<0&&(g=0),v-=m;return c(d),new o(d,r)}}var t=1e7,n=7,r=9007199254740992,i=f(r),s=Math.log(r);o.prototype.add=function(e){var t,n=z(e);if(this.sign!==n.sign)return this.subtract(n.negate());var r=this.value,i=n.value;return n.isSmall?new o(m(r,Math.abs(i)),this.sign):new o(v(r,i),this.sign)},o.prototype.plus=o.prototype.add,u.prototype.add=function(e){var t=z(e),n=this.value;if(n<0!==t.sign)return this.subtract(t.negate());var r=t.value;if(t.isSmall){if(a(n+r))return new u(n+r);r=f(Math.abs(r))}return new o(m(r,Math.abs(n)),n<0)},u.prototype.plus=u.prototype.add,o.prototype.subtract=function(e){var t=z(e);if(this.sign!==t.sign)return this.add(t.negate());var n=this.value,r=t.value;return t.isSmall?b(n,Math.abs(r),this.sign):y(n,r,this.sign)},o.prototype.minus=o.prototype.subtract,u.prototype.subtract=function(e){var t=z(e),n=this.value;if(n<0!==t.sign)return this.add(t.negate());var r=t.value;return t.isSmall?new u(n-r):b(r,Math.abs(n),n>=0)},u.prototype.minus=u.prototype.subtract,o.prototype.negate=function(){return new o(this.value,!this.sign)},u.prototype.negate=function(){var e=this.sign,t=new u(-this.value);return t.sign=!e,t},o.prototype.abs=function(){return new o(this.value,!1)},u.prototype.abs=function(){return new u(Math.abs(this.value))},o.prototype.multiply=function(e){var n,r=z(e),i=this.value,s=r.value,u=this.sign!==r.sign,a;if(r.isSmall){if(s===0)return W[0];if(s===1)return this;if(s===-1)return this.negate();a=Math.abs(s);if(a4e3?new o(x(i,s),u):new o(w(i,s),u)},o.prototype.times=o.prototype.multiply,u.prototype.multiply=function(e){var n=z(e),r=this.value,i=n.value;if(r===0)return W[0];if(r===1)return n;if(r===-1)return n.negate();if(n.isSmall){if(a(r*i))return new u(r*i);i=f(Math.abs(i))}var s=Math.abs(r);return sr?1:-1):-1},o.prototype.compare=function(e){var t=z(e),n=this.value,r=t.value;return this.sign!==t.sign?t.sign?1:-1:t.isSmall?this.sign?-1:1:A(n,r)*(this.sign?-1:1)},o.prototype.compareTo=o.prototype.compare,u.prototype.compare=function(e){var t=z(e),n=this.value,r=t.value;return t.isSmall?n==r?0:n>r?1:-1:n<0!==t.sign?n<0?-1:1:n<0?1:-1},u.prototype.compareTo=u.prototype.compare,o.prototype.equals=function(e){return this.compare(e)===0},u.prototype.eq=u.prototype.equals=o.prototype.eq=o.prototype.equals,o.prototype.notEquals=function(e){return this.compare(e)!==0},u.prototype.neq=u.prototype.notEquals=o.prototype.neq=o.prototype.notEquals,o.prototype.greater=function(e){return this.compare(e)>0},u.prototype.gt=u.prototype.greater=o.prototype.gt=o.prototype.greater,o.prototype.lesser=function(e){return this.compare(e)<0},u.prototype.lt=u.prototype.lesser=o.prototype.lt=o.prototype.lesser,o.prototype.greaterOrEquals=function(e){return this.compare(e)>=0},u.prototype.geq=u.prototype.greaterOrEquals=o.prototype.geq=o.prototype.greaterOrEquals,o.prototype.lesserOrEquals=function(e){return this.compare(e)<=0},u.prototype.leq=u.prototype.lesserOrEquals=o.prototype.leq=o.prototype.lesserOrEquals,o.prototype.isEven=function(){return(this.value[0]&1)===0},u.prototype.isEven=function(){return(this.value&1)===0},o.prototype.isOdd=function(){return(this.value[0]&1)===1},u.prototype.isOdd=function(){return(this.value&1)===1},o.prototype.isPositive=function(){return!this.sign},u.prototype.isPositive=function(){return this.value>0},o.prototype.isNegative=function(){return this.sign},u.prototype.isNegative=function(){return this.value<0},o.prototype.isUnit=function(){return!1},u.prototype.isUnit=function(){return Math.abs(this.value)===1},o.prototype.isZero=function(){return!1},u.prototype.isZero=function(){return this.value===0},o.prototype.isDivisibleBy=function(e){var t=z(e),n=t.value;return n===0?!1:n===1?!0:n===2?this.isEven():this.mod(t).equals(W[0])},u.prototype.isDivisibleBy=o.prototype.isDivisibleBy,o.prototype.isPrime=function(){var e=this.abs(),t=e.prev();if(e.isUnit())return!1;if(e.equals(2)||e.equals(3)||e.equals(5))return!0;if(e.isEven()||e.isDivisibleBy(3)||e.isDivisibleBy(5))return!1;if(e.lesser(25))return!0;var n=[2,3,5,7,11,13,17,19],r=t,i,s,o,u;while(r.isEven())r=r.divide(2);for(o=0;o-r?new u(e-1):new o(i,!0)};var O=[1];while(O[O.length-1]<=t)O.push(2*O[O.length-1]);var M=O.length,_=O[M-1];o.prototype.shiftLeft=function(e){if(!D(e))return e.isNegative()?this.shiftRight(e.abs()):this.times(W[2].pow(e));e=+e;if(e<0)return this.shiftRight(-e);var t=this;while(e>=M)t=t.multiply(_),e-=M-1;return t.multiply(O[e])},u.prototype.shiftLeft=o.prototype.shiftLeft,o.prototype.shiftRight=function(e){var t;if(!D(e))return e.isNegative()?this.shiftLeft(e.abs()):(t=this.divmod(W[2].pow(e)),t.remainder.isNegative()?t.quotient.prev():t.quotient);e=+e;if(e<0)return this.shiftLeft(-e);var n=this;while(e>=M){if(n.isZero())return n;t=L(n,_),n=t[1].isNegative()?t[0].prev():t[0],e-=M-1}return t=L(n,O[e]),t[1].isNegative()?t[0].prev():t[0]},u.prototype.shiftRight=o.prototype.shiftRight,o.prototype.not=function(){return this.negate().prev()},u.prototype.not=o.prototype.not,o.prototype.and=function(e){return P(this,e,function(e,t){return e&t})},u.prototype.and=o.prototype.and,o.prototype.or=function(e){return P(this,e,function(e,t){return e|t})},u.prototype.or=o.prototype.or,o.prototype.xor=function(e){return P(this,e,function(e,t){return e^t})},u.prototype.xor=o.prototype.xor;var q=function(e,t){var n=W[0],r=W[1],i=e.length;if(2<=t&&t<=36&&i<=s/Math.log(t))return new u(parseInt(e,t));t=z(t);var o=[],a,f=e[0]==="-";for(a=f?1:0;a");o.push(z(e.slice(h+1,a)))}}o.reverse();for(a=0;a=0)o=String(n[r]),i+=s.slice(o.length)+o;var u=this.sign?"-":"";return u+i},u.prototype.toString=function(t){return t===e&&(t=10),t!=10?U(this,t):String(this.value)},o.prototype.valueOf=function(){return+this.toString()},o.prototype.toJSNumber=o.prototype.valueOf,u.prototype.valueOf=function(){return this.value},u.prototype.toJSNumber=u.prototype.valueOf;var W=function(e,t){return typeof e=="undefined"?W[0]:typeof t!="undefined"?+t===10?z(e):q(e,t):z(e)};for(var X=0;X<1e3;X++)W[X]=new u(X),X>0&&(W[-X]=new u(-X));return W.one=W[1],W.zero=W[0],W.minusOne=W[-1],W.max=H,W.min=B,W.gcd=j,W.lcm=F,W.isInstance=function(e){return e instanceof o||e instanceof u},W.randBetween=I,W}();typeof module!="undefined"&&module.hasOwnProperty("exports")&&(module.exports=bigInt); \ No newline at end of file +var bigInt = (function (e) {'use strict'; function o(e, t) {this.value = e, this.sign = t, this.isSmall = !1;} function u(e) {this.value = e, this.sign = e < 0, this.isSmall = !0;} function a(e) {return -r < e && e < r;} function f(e) {return e < 1e7 ? [e] : e < 1e14 ? [e % 1e7, Math.floor(e / 1e7)] : [e % 1e7, Math.floor(e / 1e7) % 1e7, Math.floor(e / 1e14)];} function l(e) {c(e); var n = e.length; if (n < 4 && A(e, i) < 0) switch (n) {case 0:return 0; case 1:return e[0]; case 2:return e[0] + e[1] * t; default:return e[0] + (e[1] + e[2] * t) * t;} return e;} function c(e) {var t = e.length; while (e[--t] === 0);e.length = t + 1;} function h(e) {var t = new Array(e), n = -1; while (++n < e)t[n] = 0; return t;} function p(e) {return e > 0 ? Math.floor(e) : Math.ceil(e);} function d(e, n) {var r = e.length, i = n.length, s = new Array(r), o = 0, u = t, a, f; for (f = 0; f < i; f++)a = e[f] + n[f] + o, o = a >= u ? 1 : 0, s[f] = a - o * u; while (f < r)a = e[f] + o, o = a === u ? 1 : 0, s[f++] = a - o * u; return o > 0 && s.push(o), s;} function v(e, t) {return e.length >= t.length ? d(e, t) : d(t, e);} function m(e, n) {var r = e.length, i = new Array(r), s = t, o, u; for (u = 0; u < r; u++)o = e[u] - s + n, n = Math.floor(o / s), i[u] = o - n * s, n += 1; while (n > 0)i[u++] = n % s, n = Math.floor(n / s); return i;} function g(e, n) {var r = e.length, i = n.length, s = new Array(r), o = 0, u = t, a, f; for (a = 0; a < i; a++)f = e[a] - o - n[a], f < 0 ? (f += u, o = 1) : o = 0, s[a] = f; for (a = i; a < r; a++) {f = e[a] - o; if (!(f < 0)) {s[a++] = f; break;}f += u, s[a] = f;} for (;a < r; a++)s[a] = e[a]; return c(s), s;} function y(e, t, n) {var r, i; return A(e, t) >= 0 ? r = g(e, t) : (r = g(t, e), n = !n), r = l(r), typeof r === 'number' ? (n && (r = -r), new u(r)) : new o(r, n);} function b(e, n, r) {var i = e.length, s = new Array(i), a = -n, f = t, c, h; for (c = 0; c < i; c++)h = e[c] + a, a = Math.floor(h / f), s[c] = h < 0 ? h % f + f : h; return s = l(s), typeof s === 'number' ? (r && (s = -s), new u(s)) : new o(s, r);} function w(e, n) {var r = e.length, i = n.length, s = r + i, o = h(s), u = t, a, f, l, p, d; for (l = 0; l < r; ++l) {p = e[l]; for (var v = 0; v < i; ++v)d = n[v], a = p * d + o[l + v], f = Math.floor(a / u), o[l + v] = a - f * u, o[l + v + 1] += f;} return c(o), o;} function E(e, n) {var r = e.length, i = new Array(r), s = t, o = 0, u, a; for (a = 0; a < r; a++)u = e[a] * n + o, o = Math.floor(u / s), i[a] = u - o * s; while (o > 0)i[a++] = o % s, o = Math.floor(o / s); return i;} function S(e, t) {var n = []; while (t-- > 0)n.push(0); return n.concat(e);} function x(e, t) {var n = Math.max(e.length, t.length); if (n <= 400) return w(e, t); n = Math.ceil(n / 2); var r = e.slice(n), i = e.slice(0, n), s = t.slice(n), o = t.slice(0, n), u = x(i, o), a = x(r, s), f = x(v(i, r), v(o, s)); return v(v(u, S(g(g(f, u), a), n)), S(a, 2 * n));} function T(e) {var n = e.length, r = h(n + n), i = t, s, o, u, a, f; for (u = 0; u < n; u++) {a = e[u]; for (var l = 0; l < n; l++)f = e[l], s = a * f + r[u + l], o = Math.floor(s / i), r[u + l] = s - o * i, r[u + l + 1] += o;} return c(r), r;} function N(e, n) {var r = e.length, i = n.length, s = t, o = h(n.length), u = n[i - 1], a = Math.ceil(s / (2 * u)), f = E(e, a), c = E(n, a), p, d, v, m, g, y, b; f.length <= r && f.push(0), c.push(0), u = c[i - 1]; for (d = r - i; d >= 0; d--) {p = s - 1, p = Math.floor((f[d + i] * s + f[d + i - 1]) / u), v = 0, m = 0, y = c.length; for (g = 0; g < y; g++)v += p * c[g], b = Math.floor(v / s), m += f[d + g] - (v - b * s), v = b, m < 0 ? (f[d + g] = m + s, m = -1) : (f[d + g] = m, m = 0); while (m !== 0) {p -= 1, v = 0; for (g = 0; g < y; g++)v += f[d + g] - s + c[g], v < 0 ? (f[d + g] = v + s, v = 0) : (f[d + g] = v, v = 1); m += v;}o[d] = p;} return f = k(f, a)[0], [l(o), l(f)];} function C(e, n) {var r = e.length, i = n.length, s = [], o = [], u = t, a, f, c, h, p; while (r) {o.unshift(e[--r]); if (A(o, n) < 0) {s.push(0); continue;}f = o.length, c = o[f - 1] * u + o[f - 2], h = n[i - 1] * u + n[i - 2], f > i && (c = (c + 1) * u), a = Math.ceil(c / h); do {p = E(n, a); if (A(p, o) <= 0) break; a--;} while (a);s.push(a), o = g(o, p);} return s.reverse(), [l(s), l(o)];} function k(e, n) {var r = e.length, i = h(r), s = t, o, u, a, f; a = 0; for (o = r - 1; o >= 0; --o)f = a * s + e[o], u = p(f / n), a = f - u * n, i[o] = u | 0; return [i, a | 0];} function L(e, n) {var r, i = z(n), s = e.value, a = i.value, c; if (a === 0) throw new Error('Cannot divide by zero'); if (e.isSmall) return i.isSmall ? [new u(p(s / a)), new u(s % a)] : [W[0], e]; if (i.isSmall) {if (a === 1) return [e, W[0]]; if (a == -1) return [e.negate(), W[0]]; var h = Math.abs(a); if (h < t) {r = k(s, h), c = l(r[0]); var d = r[1]; return e.sign && (d = -d), typeof c === 'number' ? (e.sign !== i.sign && (c = -c), [new u(c), new u(d)]) : [new o(c, e.sign !== i.sign), new u(d)];}a = f(h);} var v = A(s, a); if (v === -1) return [W[0], e]; if (v === 0) return [W[e.sign === i.sign ? 1 : -1], W[0]]; s.length + a.length <= 200 ? r = N(s, a) : r = C(s, a), c = r[0]; var m = e.sign !== i.sign, g = r[1], y = e.sign; return typeof c === 'number' ? (m && (c = -c), c = new u(c)) : c = new o(c, m), typeof g === 'number' ? (y && (g = -g), g = new u(g)) : g = new o(g, y), [c, g];} function A(e, t) {if (e.length !== t.length) return e.length > t.length ? 1 : -1; for (var n = e.length - 1; n >= 0; n--) if (e[n] !== t[n]) return e[n] > t[n] ? 1 : -1; return 0;} function D(e) {return (typeof e === 'number' || typeof e === 'string') && +Math.abs(e) <= t || e instanceof o && e.value.length <= 1;} function P(e, t, n) {t = z(t); var r = e.isNegative(), i = t.isNegative(), s = r ? e.not() : e, o = i ? t.not() : t, u = [], a = [], f = !1, l = !1; while (!f || !l)s.isZero() ? (f = !0, u.push(r ? 1 : 0)) : r ? u.push(s.isEven() ? 1 : 0) : u.push(s.isEven() ? 0 : 1), o.isZero() ? (l = !0, a.push(i ? 1 : 0)) : i ? a.push(o.isEven() ? 1 : 0) : a.push(o.isEven() ? 0 : 1), s = s.over(2), o = o.over(2); var c = []; for (var h = 0; h < u.length; h++)c.push(n(u[h], a[h])); var p = bigInt(c.pop()).negate().times(bigInt(2).pow(c.length)); while (c.length)p = p.add(bigInt(c.pop()).times(bigInt(2).pow(c.length))); return p;} function H(e, t) {return e = z(e), t = z(t), e.greater(t) ? e : t;} function B(e, t) {return e = z(e), t = z(t), e.lesser(t) ? e : t;} function j(e, t) {return e = z(e).abs(), t = z(t).abs(), e.equals(t) ? e : e.isZero() ? t : t.isZero() ? e : e.isEven() ? t.isOdd() ? j(e.divide(2), t) : j(e.divide(2), t.divide(2)).multiply(2) : t.isEven() ? j(e, t.divide(2)) : e.greater(t) ? j(e.subtract(t).divide(2), t) : j(t.subtract(e).divide(2), e);} function F(e, t) {return e = z(e).abs(), t = z(t).abs(), e.multiply(t).divide(j(e, t));} function I(e, n) {e = z(e), n = z(n); var r = B(e, n), i = H(e, n), s = i.subtract(r); if (s.isSmall) return r.add(Math.random() * s); var u = s.value.length - 1, a = [], f = !0; for (var c = u; c >= 0; c--) {var h = f ? s.value[c] : t, d = p(Math.random() * h); a.unshift(d), d < h && (f = !1);} return a = l(a), r.add(new o(a, !1, typeof a === 'number'));} function R(e) {var t = e.value; return typeof t === 'number' && (t = [t]), t.length === 1 && t[0] <= 36 ? '0123456789abcdefghijklmnopqrstuvwxyz'.charAt(t[0]) : '<' + t + '>';} function U(e, t) {t = bigInt(t); if (t.isZero()) {if (e.isZero()) return '0'; throw new Error('Cannot convert nonzero numbers to base 0.');} if (t.equals(-1)) return e.isZero() ? '0' : e.isNegative() ? (new Array(1 - e)).join('10') : '1' + (new Array(+e)).join('01'); var n = ''; e.isNegative() && t.isPositive() && (n = '-', e = e.abs()); if (t.equals(1)) return e.isZero() ? '0' : n + (new Array(+e + 1)).join(1); var r = [], i = e, s; while (i.isNegative() || i.compareAbs(t) >= 0) {s = i.divmod(t), i = s.quotient; var o = s.remainder; o.isNegative() && (o = t.minus(o).abs(), i = i.next()), r.push(R(o));} return r.push(R(i)), n + r.reverse().join('');} function z(e) {if (e instanceof o || e instanceof u) return e; if (typeof e === 'number') {if (a(e)) return new u(e); e = String(e);} if (typeof e === 'string') {if (a(+e)) {var t = +e; if (t === p(t)) return new u(t); throw 'Invalid integer: ' + e;} var r = e[0] === '-'; r && (e = e.slice(1)); var i = e.split(/e/i); if (i.length > 2) throw new Error('Invalid integer: ' + f.join('e')); if (i.length === 2) {var s = i[1]; s[0] === '+' && (s = s.slice(1)), s = +s; if (s !== p(s) || !a(s)) throw new Error('Invalid integer: ' + s + ' is not a valid exponent.'); var f = i[0], l = f.indexOf('.'); l >= 0 && (s -= f.length - l, f = f.slice(0, l) + f.slice(l + 1)); if (s < 0) throw new Error('Cannot include negative exponent part for integers'); f += (new Array(s + 1)).join('0'), e = f;} var h = /^([0-9][0-9]*)$/.test(e); if (!h) throw new Error('Invalid integer: ' + e); var d = [], v = e.length, m = n, g = v - m; while (v > 0)d.push(+e.slice(g, v)), g -= m, g < 0 && (g = 0), v -= m; return c(d), new o(d, r);}} var t = 1e7, n = 7, r = 9007199254740992, i = f(r), s = Math.log(r); o.prototype.add = function (e) {var t, n = z(e); if (this.sign !== n.sign) return this.subtract(n.negate()); var r = this.value, i = n.value; return n.isSmall ? new o(m(r, Math.abs(i)), this.sign) : new o(v(r, i), this.sign);}, o.prototype.plus = o.prototype.add, u.prototype.add = function (e) {var t = z(e), n = this.value; if (n < 0 !== t.sign) return this.subtract(t.negate()); var r = t.value; if (t.isSmall) {if (a(n + r)) return new u(n + r); r = f(Math.abs(r));} return new o(m(r, Math.abs(n)), n < 0);}, u.prototype.plus = u.prototype.add, o.prototype.subtract = function (e) {var t = z(e); if (this.sign !== t.sign) return this.add(t.negate()); var n = this.value, r = t.value; return t.isSmall ? b(n, Math.abs(r), this.sign) : y(n, r, this.sign);}, o.prototype.minus = o.prototype.subtract, u.prototype.subtract = function (e) {var t = z(e), n = this.value; if (n < 0 !== t.sign) return this.add(t.negate()); var r = t.value; return t.isSmall ? new u(n - r) : b(r, Math.abs(n), n >= 0);}, u.prototype.minus = u.prototype.subtract, o.prototype.negate = function () {return new o(this.value, !this.sign);}, u.prototype.negate = function () {var e = this.sign, t = new u(-this.value); return t.sign = !e, t;}, o.prototype.abs = function () {return new o(this.value, !1);}, u.prototype.abs = function () {return new u(Math.abs(this.value));}, o.prototype.multiply = function (e) {var n, r = z(e), i = this.value, s = r.value, u = this.sign !== r.sign, a; if (r.isSmall) {if (s === 0) return W[0]; if (s === 1) return this; if (s === -1) return this.negate(); a = Math.abs(s); if (a < t) return new o(E(i, a), u); s = f(a);} return i.length + s.length > 4e3 ? new o(x(i, s), u) : new o(w(i, s), u);}, o.prototype.times = o.prototype.multiply, u.prototype.multiply = function (e) {var n = z(e), r = this.value, i = n.value; if (r === 0) return W[0]; if (r === 1) return n; if (r === -1) return n.negate(); if (n.isSmall) {if (a(r * i)) return new u(r * i); i = f(Math.abs(i));} var s = Math.abs(r); return s < t ? new o(E(i, s), this.sign !== n.sign) : new o(w(i, f(s)), this.sign !== n.sign);}, u.prototype.times = u.prototype.multiply, o.prototype.square = function () {return new o(T(this.value), !1);}, u.prototype.square = function () {var e = this.value * this.value; return a(e) ? new u(e) : new o(T(f(Math.abs(this.value))), !1);}, o.prototype.divmod = function (e) {var t = L(this, e); return {quotient: t[0], remainder: t[1]};}, u.prototype.divmod = o.prototype.divmod, o.prototype.divide = function (e) {return L(this, e)[0];}, u.prototype.over = u.prototype.divide = o.prototype.over = o.prototype.divide, o.prototype.mod = function (e) {return L(this, e)[1];}, u.prototype.remainder = u.prototype.mod = o.prototype.remainder = o.prototype.mod, o.prototype.pow = function (e) {var t = z(e), n = this.value, r = t.value, i, s, o; if (r === 0) return W[1]; if (n === 0) return W[0]; if (n === 1) return W[1]; if (n === -1) return t.isEven() ? W[1] : W[-1]; if (t.sign) return W[0]; if (!t.isSmall) throw new Error('The exponent ' + t.toString() + ' is too large.'); if (this.isSmall && a(i = Math.pow(n, r))) return new u(p(i)); s = this, o = W[1]; for (;;) {r & !0 && (o = o.times(s), --r); if (r === 0) break; r /= 2, s = s.square();} return o;}, u.prototype.pow = o.prototype.pow, o.prototype.modPow = function (e, t) {e = z(e), t = z(t); if (t.isZero()) throw new Error('Cannot take modPow with modulus 0'); var n = W[1], r = this.mod(t); if (r.isZero()) return W[0]; while (e.isPositive())e.isOdd() && (n = n.multiply(r).mod(t)), e = e.divide(2), r = r.square().mod(t); return n;}, u.prototype.modPow = o.prototype.modPow, o.prototype.compareAbs = function (e) {var t = z(e), n = this.value, r = t.value; return t.isSmall ? 1 : A(n, r);}, u.prototype.compareAbs = function (e) {var t = z(e), n = Math.abs(this.value), r = t.value; return t.isSmall ? (r = Math.abs(r), n === r ? 0 : n > r ? 1 : -1) : -1;}, o.prototype.compare = function (e) {var t = z(e), n = this.value, r = t.value; return this.sign !== t.sign ? t.sign ? 1 : -1 : t.isSmall ? this.sign ? -1 : 1 : A(n, r) * (this.sign ? -1 : 1);}, o.prototype.compareTo = o.prototype.compare, u.prototype.compare = function (e) {var t = z(e), n = this.value, r = t.value; return t.isSmall ? n == r ? 0 : n > r ? 1 : -1 : n < 0 !== t.sign ? n < 0 ? -1 : 1 : n < 0 ? 1 : -1;}, u.prototype.compareTo = u.prototype.compare, o.prototype.equals = function (e) {return this.compare(e) === 0;}, u.prototype.eq = u.prototype.equals = o.prototype.eq = o.prototype.equals, o.prototype.notEquals = function (e) {return this.compare(e) !== 0;}, u.prototype.neq = u.prototype.notEquals = o.prototype.neq = o.prototype.notEquals, o.prototype.greater = function (e) {return this.compare(e) > 0;}, u.prototype.gt = u.prototype.greater = o.prototype.gt = o.prototype.greater, o.prototype.lesser = function (e) {return this.compare(e) < 0;}, u.prototype.lt = u.prototype.lesser = o.prototype.lt = o.prototype.lesser, o.prototype.greaterOrEquals = function (e) {return this.compare(e) >= 0;}, u.prototype.geq = u.prototype.greaterOrEquals = o.prototype.geq = o.prototype.greaterOrEquals, o.prototype.lesserOrEquals = function (e) {return this.compare(e) <= 0;}, u.prototype.leq = u.prototype.lesserOrEquals = o.prototype.leq = o.prototype.lesserOrEquals, o.prototype.isEven = function () {return (this.value[0] & 1) === 0;}, u.prototype.isEven = function () {return (this.value & 1) === 0;}, o.prototype.isOdd = function () {return (this.value[0] & 1) === 1;}, u.prototype.isOdd = function () {return (this.value & 1) === 1;}, o.prototype.isPositive = function () {return !this.sign;}, u.prototype.isPositive = function () {return this.value > 0;}, o.prototype.isNegative = function () {return this.sign;}, u.prototype.isNegative = function () {return this.value < 0;}, o.prototype.isUnit = function () {return !1;}, u.prototype.isUnit = function () {return Math.abs(this.value) === 1;}, o.prototype.isZero = function () {return !1;}, u.prototype.isZero = function () {return this.value === 0;}, o.prototype.isDivisibleBy = function (e) {var t = z(e), n = t.value; return n === 0 ? !1 : n === 1 ? !0 : n === 2 ? this.isEven() : this.mod(t).equals(W[0]);}, u.prototype.isDivisibleBy = o.prototype.isDivisibleBy, o.prototype.isPrime = function () {var e = this.abs(), t = e.prev(); if (e.isUnit()) return !1; if (e.equals(2) || e.equals(3) || e.equals(5)) return !0; if (e.isEven() || e.isDivisibleBy(3) || e.isDivisibleBy(5)) return !1; if (e.lesser(25)) return !0; var n = [2, 3, 5, 7, 11, 13, 17, 19], r = t, i, s, o, u; while (r.isEven())r = r.divide(2); for (o = 0; o < n.length; o++) {u = bigInt(n[o]).modPow(r, e); if (u.equals(W[1]) || u.equals(t)) continue; for (s = !0, i = r; s && i.lesser(t); i = i.multiply(2))u = u.square().mod(e), u.equals(t) && (s = !1); if (s) return !1;} return !0;}, u.prototype.isPrime = o.prototype.isPrime, o.prototype.next = function () {var e = this.value; return this.sign ? b(e, 1, this.sign) : new o(m(e, 1), this.sign);}, u.prototype.next = function () {var e = this.value; return e + 1 < r ? new u(e + 1) : new o(i, !1);}, o.prototype.prev = function () {var e = this.value; return this.sign ? new o(m(e, 1), !0) : b(e, 1, this.sign);}, u.prototype.prev = function () {var e = this.value; return e - 1 > -r ? new u(e - 1) : new o(i, !0);}; var O = [1]; while (O[O.length - 1] <= t)O.push(2 * O[O.length - 1]); var M = O.length, _ = O[M - 1]; o.prototype.shiftLeft = function (e) {if (!D(e)) return e.isNegative() ? this.shiftRight(e.abs()) : this.times(W[2].pow(e)); e = +e; if (e < 0) return this.shiftRight(-e); var t = this; while (e >= M)t = t.multiply(_), e -= M - 1; return t.multiply(O[e]);}, u.prototype.shiftLeft = o.prototype.shiftLeft, o.prototype.shiftRight = function (e) {var t; if (!D(e)) return e.isNegative() ? this.shiftLeft(e.abs()) : (t = this.divmod(W[2].pow(e)), t.remainder.isNegative() ? t.quotient.prev() : t.quotient); e = +e; if (e < 0) return this.shiftLeft(-e); var n = this; while (e >= M) {if (n.isZero()) return n; t = L(n, _), n = t[1].isNegative() ? t[0].prev() : t[0], e -= M - 1;} return t = L(n, O[e]), t[1].isNegative() ? t[0].prev() : t[0];}, u.prototype.shiftRight = o.prototype.shiftRight, o.prototype.not = function () {return this.negate().prev();}, u.prototype.not = o.prototype.not, o.prototype.and = function (e) {return P(this, e, function (e, t) {return e & t;});}, u.prototype.and = o.prototype.and, o.prototype.or = function (e) {return P(this, e, function (e, t) {return e | t;});}, u.prototype.or = o.prototype.or, o.prototype.xor = function (e) {return P(this, e, function (e, t) {return e ^ t;});}, u.prototype.xor = o.prototype.xor; var q = function (e, t) {var n = W[0], r = W[1], i = e.length; if (t >= 2 && t <= 36 && i <= s / Math.log(t)) return new u(parseInt(e, t)); t = z(t); var o = [], a, f = e[0] === '-'; for (a = f ? 1 : 0; a < e.length; a++) {var l = e[a].toLowerCase(), c = l.charCodeAt(0); if (c >= 48 && c <= 57)o.push(z(l)); else if (c >= 97 && c <= 122)o.push(z(l.charCodeAt(0) - 87)); else {if (l !== '<') throw new Error(l + ' is not a valid character'); var h = a; do a++; while (e[a] !== '>');o.push(z(e.slice(h + 1, a)));}}o.reverse(); for (a = 0; a < o.length; a++)n = n.add(o[a].times(r)), r = r.times(t); return f ? n.negate() : n;}; o.prototype.toString = function (t) {t === e && (t = 10); if (t !== 10) return U(this, t); var n = this.value, r = n.length, i = String(n[--r]), s = '0000000', o; while (--r >= 0)o = String(n[r]), i += s.slice(o.length) + o; var u = this.sign ? '-' : ''; return u + i;}, u.prototype.toString = function (t) {return t === e && (t = 10), t != 10 ? U(this, t) : String(this.value);}, o.prototype.valueOf = function () {return +this.toString();}, o.prototype.toJSNumber = o.prototype.valueOf, u.prototype.valueOf = function () {return this.value;}, u.prototype.toJSNumber = u.prototype.valueOf; var W = function (e, t) {return typeof e === 'undefined' ? W[0] : typeof t !== 'undefined' ? +t === 10 ? z(e) : q(e, t) : z(e);}; for (var X = 0; X < 1e3; X++)W[X] = new u(X), X > 0 && (W[-X] = new u(-X)); return W.one = W[1], W.zero = W[0], W.minusOne = W[-1], W.max = H, W.min = B, W.gcd = j, W.lcm = F, W.isInstance = function (e) {return e instanceof o || e instanceof u;}, W.randBetween = I, W;}()); typeof module !== 'undefined' && module.hasOwnProperty('exports') && (module.exports = bigInt); diff --git a/exercises/accumulate/accumulate.spec.js b/exercises/accumulate/accumulate.spec.js index 4effd86e..2f0c7c65 100644 --- a/exercises/accumulate/accumulate.spec.js +++ b/exercises/accumulate/accumulate.spec.js @@ -1,14 +1,13 @@ var accumulate = require('./accumulate'); -describe('accumulate()', function() { - - it('accumulation empty', function() { - var accumulator = function(e) { return e * e; }; +describe('accumulate()', function () { + it('accumulation empty', function () { + var accumulator = function (e) { return e * e; }; expect(accumulate([], accumulator)).toEqual([]); }); - xit('accumulate squares', function() { - var accumulator = function(number) { + xit('accumulate squares', function () { + var accumulator = function (number) { return number * number; }; @@ -17,8 +16,8 @@ describe('accumulate()', function() { expect(result).toEqual([1, 4, 9]); }); - xit('accumulate upcases', function() { - var accumulator = function(word) { + xit('accumulate upcases', function () { + var accumulator = function (word) { return word.toUpperCase(); }; @@ -27,8 +26,8 @@ describe('accumulate()', function() { expect(result).toEqual(['HELLO', 'WORLD']); }); - xit('accumulate reversed strings', function() { - var accumulator = function(word) { + xit('accumulate reversed strings', function () { + var accumulator = function (word) { return word.split('').reverse().join(''); }; @@ -37,14 +36,13 @@ describe('accumulate()', function() { expect(result).toEqual(['eht', 'kciuq', 'nworb', 'xof', 'cte']); }); - xit('accumulate recursively', function() { - var result = accumulate('a b c'.split(/\s/), function(char) { - return accumulate('1 2 3'.split(/\s/), function(digit) { + xit('accumulate recursively', function () { + var result = accumulate('a b c'.split(/\s/), function (char) { + return accumulate('1 2 3'.split(/\s/), function (digit) { return char + digit; }); }); expect(result).toEqual([['a1', 'a2', 'a3'], ['b1', 'b2', 'b3'], ['c1', 'c2', 'c3']]); }); - }); diff --git a/exercises/acronym/acronym.spec.js b/exercises/acronym/acronym.spec.js index ec5f60c2..e5619576 100644 --- a/exercises/acronym/acronym.spec.js +++ b/exercises/acronym/acronym.spec.js @@ -1,27 +1,27 @@ var Acronyms = require('./acronym'); -describe('Acronyms are produced from', function(){ - it('title cased phrases', function() { +describe('Acronyms are produced from', function () { + it('title cased phrases', function () { expect(Acronyms.parse('Portable Network Graphics')).toEqual('PNG'); }); - it('other title cased phrases', function(){ + it('other title cased phrases', function () { expect(Acronyms.parse('Ruby on Rails')).toEqual('ROR'); }); - it('inconsistently cased phrases', function(){ + it('inconsistently cased phrases', function () { expect(Acronyms.parse('HyperText Markup Language')).toEqual('HTML'); }); - it('phrases with punctuation', function() { + it('phrases with punctuation', function () { expect(Acronyms.parse('First In, First Out')).toEqual('FIFO'); }); - it('other phrases with punctuation', function() { + it('other phrases with punctuation', function () { expect(Acronyms.parse('PHP: Hypertext Preprocessor')).toEqual('PHP'); }); - it('phrases with punctuation and sentence casing', function() { + it('phrases with punctuation and sentence casing', function () { expect(Acronyms.parse('Complementary metal-oxide semiconductor')).toEqual('CMOS'); }); }); diff --git a/exercises/acronym/example.js b/exercises/acronym/example.js index ac8d5636..d50a50a6 100644 --- a/exercises/acronym/example.js +++ b/exercises/acronym/example.js @@ -2,7 +2,7 @@ module.exports = { parse: function (phrase) { return phrase.match(/[A-Z]+[a-z]*|[a-z]+/g) .reduce(function (acronym, word) { - return acronym += word[0].toUpperCase() + return acronym += word[0].toUpperCase(); }, ''); } }; diff --git a/exercises/all-your-base/all-your-base.spec.js b/exercises/all-your-base/all-your-base.spec.js index 34d28100..eb490913 100644 --- a/exercises/all-your-base/all-your-base.spec.js +++ b/exercises/all-your-base/all-your-base.spec.js @@ -5,7 +5,6 @@ const Converter = require('./all-your-base'); const converter = new Converter(); describe('Converter', function () { - xit('single bit one to decimal', function () { expect(converter.convert([1], 2, 10)).toEqual([1]); }); @@ -137,5 +136,4 @@ describe('Converter', function () { converter.convert([0], 3, 2.5); }).toThrow(new Error('Wrong output base')); }); - }); diff --git a/exercises/allergies/allergies.spec.js b/exercises/allergies/allergies.spec.js index 40bcf72a..efce5cf9 100644 --- a/exercises/allergies/allergies.spec.js +++ b/exercises/allergies/allergies.spec.js @@ -1,66 +1,65 @@ var Allergies = require('./allergies'); -describe('Allergies',function() { - - it('no allergies at all', function() { +describe('Allergies', function () { + it('no allergies at all', function () { var allergies = new Allergies(0); expect(allergies.list()).toEqual([]); }); - xit('allergies to eggs', function() { + xit('allergies to eggs', function () { var allergies = new Allergies(1); expect(allergies.list()).toEqual([ 'eggs' ]); }); - xit('allergies to peanuts', function() { + xit('allergies to peanuts', function () { var allergies = new Allergies(2); expect(allergies.list()).toEqual([ 'peanuts' ]); }); - xit('allergies to strawberries', function() { + xit('allergies to strawberries', function () { var allergies = new Allergies(8); expect(allergies.list()).toEqual([ 'strawberries' ]); }); - xit('allergies to eggs and peanuts', function() { + xit('allergies to eggs and peanuts', function () { var allergies = new Allergies(3); expect(allergies.list()).toEqual([ 'eggs', 'peanuts' ]); }); - xit('allergies to more than eggs but not peanuts', function() { + xit('allergies to more than eggs but not peanuts', function () { var allergies = new Allergies(5); expect(allergies.list()).toEqual([ 'eggs', 'shellfish' ]); }); - xit('allergic to lots of stuff', function() { + xit('allergic to lots of stuff', function () { var allergies = new Allergies(248); expect(allergies.list()).toEqual(['strawberries', 'tomatoes', 'chocolate', 'pollen', 'cats']); }); - xit('allergic to everything', function() { + xit('allergic to everything', function () { var allergies = new Allergies(255); expect(allergies.list()).toEqual(['eggs', 'peanuts', 'shellfish', 'strawberries', 'tomatoes', 'chocolate', 'pollen', 'cats']); }); - xit('no allergic means not allergic', function() { + xit('no allergic means not allergic', function () { var allergies = new Allergies(0); expect(allergies.allergicTo('peanuts')).toEqual(false); expect(allergies.allergicTo('cats')).toEqual(false); expect(allergies.allergicTo('strawberries')).toEqual(false); }); - xit('allergic to eggs', function() { + xit('allergic to eggs', function () { var allergies = new Allergies(1); expect(allergies.allergicTo('eggs')).toEqual(true); }); - xit('allergic to eggs and other things', function() { + xit('allergic to eggs and other things', function () { var allergies = new Allergies(5); expect(allergies.allergicTo('eggs')).toEqual(true); }); - xit('ignore non allergen score parts', function() { + xit('ignore non allergen score parts', function () { var allergies = new Allergies(509); expect(allergies.list()).toEqual(['eggs', 'shellfish', 'strawberries', 'tomatoes', 'chocolate', 'pollen', 'cats']); }); -}); \ No newline at end of file +}); diff --git a/exercises/allergies/example.js b/exercises/allergies/example.js index 3ffe16b9..3fd62fe7 100644 --- a/exercises/allergies/example.js +++ b/exercises/allergies/example.js @@ -5,23 +5,23 @@ function Allergies(allergenIndex) { } Allergies.possibleAllergies = [ 'eggs', 'peanuts', 'shellfish', 'strawberries', - 'tomatoes', 'chocolate', 'pollen', 'cats']; + 'tomatoes', 'chocolate', 'pollen', 'cats']; Allergies.prototype = { - list: function() { + list: function () { var possibleAllergies = Allergies.possibleAllergies; var allergicTo = []; for (var i = 0; i < possibleAllergies.length; i++) { var allergy = possibleAllergies[i]; - if (this.allergenIndex & Math.pow(2,i)) { + if (this.allergenIndex & Math.pow(2, i)) { allergicTo.push(allergy); } } return allergicTo; }, - allergicTo: function(food) { + allergicTo: function (food) { var isAllergic = false; var allergyList = this.list(); @@ -36,4 +36,4 @@ Allergies.prototype = { } }; -module.exports = Allergies; \ No newline at end of file +module.exports = Allergies; diff --git a/exercises/alphametics/alphametics.spec.js b/exercises/alphametics/alphametics.spec.js index 4db54f1a..d175f6f9 100644 --- a/exercises/alphametics/alphametics.spec.js +++ b/exercises/alphametics/alphametics.spec.js @@ -1,95 +1,93 @@ var solve = require('./alphametics'); -describe("Solve the alphametics puzzle", function() { - - it("puzzle with three letters", function() { - var puzzle = "I + BB == ILL"; +describe('Solve the alphametics puzzle', function () { + it('puzzle with three letters', function () { + var puzzle = 'I + BB == ILL'; var expected = { - "I": 1, - "B": 9, - "L": 0 + 'I': 1, + 'B': 9, + 'L': 0 }; expect(solve(puzzle)).toEqual(expected); }); - xit("solution must have unique value for each letter", function() { - var puzzle = "A == B"; + xit('solution must have unique value for each letter', function () { + var puzzle = 'A == B'; expect(solve(puzzle)).toBeNull(); }); - xit("leading zero solution is invalid", function() { - var puzzle = "ACA + DD == BD"; + xit('leading zero solution is invalid', function () { + var puzzle = 'ACA + DD == BD'; expect(solve(puzzle)).toBeNull(); }); - xit("puzzle with four letters", function() { - var puzzle = "AS + A == MOM"; + xit('puzzle with four letters', function () { + var puzzle = 'AS + A == MOM'; var expected = { - "A": 9, - "S": 2, - "M": 1, - "O": 0 + 'A': 9, + 'S': 2, + 'M': 1, + 'O': 0 }; expect(solve(puzzle)).toEqual(expected); }); - xit("puzzle with six letters", function() { - var puzzle = "NO + NO + TOO == LATE"; + xit('puzzle with six letters', function () { + var puzzle = 'NO + NO + TOO == LATE'; var expected = { - "N": 7, - "O": 4, - "T": 9, - "L": 1, - "A": 0, - "E": 2 + 'N': 7, + 'O': 4, + 'T': 9, + 'L': 1, + 'A': 0, + 'E': 2 }; expect(solve(puzzle)).toEqual(expected); }); - xit("puzzle with seven letters", function() { - var puzzle = "HE + SEES + THE == LIGHT"; + xit('puzzle with seven letters', function () { + var puzzle = 'HE + SEES + THE == LIGHT'; var expected = { - "E": 4, - "G": 2, - "H": 5, - "I": 0, - "L": 1, - "S": 9, - "T": 7 + 'E': 4, + 'G': 2, + 'H': 5, + 'I': 0, + 'L': 1, + 'S': 9, + 'T': 7 }; expect(solve(puzzle)).toEqual(expected); }); - xit("puzzle with eight letters", function() { - var puzzle = "SEND + MORE == MONEY"; + xit('puzzle with eight letters', function () { + var puzzle = 'SEND + MORE == MONEY'; var expected = { - "S": 9, - "E": 5, - "N": 6, - "D": 7, - "M": 1, - "O": 0, - "R": 8, - "Y": 2 + 'S': 9, + 'E': 5, + 'N': 6, + 'D': 7, + 'M': 1, + 'O': 0, + 'R': 8, + 'Y': 2 }; expect(solve(puzzle)).toEqual(expected); }); - xit("puzzle with ten letters", function() { - var puzzle = "AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE"; + xit('puzzle with ten letters', function () { + var puzzle = 'AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE'; var expected = { - "A": 5, - "D": 3, - "E": 4, - "F": 7, - "G": 8, - "N": 0, - "O": 2, - "R": 1, - "S": 6, - "T": 9 + 'A': 5, + 'D': 3, + 'E': 4, + 'F': 7, + 'G': 8, + 'N': 0, + 'O': 2, + 'R': 1, + 'S': 6, + 'T': 9 }; expect(solve(puzzle)).toEqual(expected); - }); - + }); }); diff --git a/exercises/alphametics/example.js b/exercises/alphametics/example.js index 3dc16042..5467cf24 100644 --- a/exercises/alphametics/example.js +++ b/exercises/alphametics/example.js @@ -1,24 +1,24 @@ function solve(puzzle) { var parts = puzzle .split(/[+|==]/g) - .map(function(o) { return o.trim(); }) - .filter(function(o) { return o !== ""; }); + .map(function (o) { return o.trim(); }) + .filter(function (o) { return o !== ''; }); - if(parts.length < 3) { + if (parts.length < 3) { return null; } var uniqueLetters = getUniqueLetters(parts.join('')); var firstLetters = getFirstLetters(parts); - var numberCombinations = getNumberCombinations([0,1,2,3,4,5,6,7,8,9], uniqueLetters.length); - var permutations = getPermutations(Array(uniqueLetters.length).fill().map(function(_, i) {return i; })); + var numberCombinations = getNumberCombinations([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], uniqueLetters.length); + var permutations = getPermutations(Array(uniqueLetters.length).fill().map(function (_, i) {return i; })); - while(numberCombinations.length) { + while (numberCombinations.length) { var numberCombination = numberCombinations.pop(); - for(var k = 0; k < permutations.length; k++) { + for (var k = 0; k < permutations.length; k++) { var newNumbers = assignNumbers(numberCombination, uniqueLetters, permutations[k]); - if(testNumbers(newNumbers, parts, firstLetters)) { + if (testNumbers(newNumbers, parts, firstLetters)) { return newNumbers; } } @@ -28,13 +28,13 @@ function solve(puzzle) { function getFirstLetters(words) { return words - .map(function(word) { return word[0]; }) + .map(function (word) { return word[0]; }) .filter(function (val, i, arr) { return arr.indexOf(val) === i; }); } function assignNumbers(numbers, letters, orders) { var output = {}; - for(var i = 0; i < letters.length; i++) { + for (var i = 0; i < letters.length; i++) { output[letters[i]] = numbers[orders[i]]; } return output; @@ -46,22 +46,22 @@ function getUniqueLetters(string) { function testNumbers(numbers, puzzleParts, firstLetters) { var keys = Object.keys(numbers); - for(var i = 0; i < keys.length; i++) { - if(numbers[keys[i]] === 0 && firstLetters.indexOf(keys[i]) !== -1) { + for (var i = 0; i < keys.length; i++) { + if (numbers[keys[i]] === 0 && firstLetters.indexOf(keys[i]) !== -1) { return false; } } var replaceRegex = new RegExp('[' + keys.join('') + ']', 'g'); puzzleParts = puzzleParts.join(',') - .replace(replaceRegex, function(input) { return numbers[input]; }) + .replace(replaceRegex, function (input) { return numbers[input]; }) .split(',') - .map(function(t) {return parseInt(t);}); + .map(function (t) {return parseInt(t);}); - var total = puzzleParts.slice(puzzleParts.length-1)[0]; + var total = puzzleParts.slice(puzzleParts.length - 1)[0]; return total === puzzleParts - .slice(0,puzzleParts.length-1) - .reduce(function(acc, val) { return acc + val; },0); + .slice(0, puzzleParts.length - 1) + .reduce(function (acc, val) { return acc + val; }, 0); } function getPermutations(inputArr) { @@ -104,4 +104,4 @@ function getNumberCombinations(set, k) { return combs; } -module.exports = solve; \ No newline at end of file +module.exports = solve; diff --git a/exercises/anagram/anagram.spec.js b/exercises/anagram/anagram.spec.js index ca71bd97..db03ac95 100644 --- a/exercises/anagram/anagram.spec.js +++ b/exercises/anagram/anagram.spec.js @@ -1,78 +1,77 @@ var Anagram = require('./anagram'); -describe('Anagram', function() { - - it('no matches',function() { +describe('Anagram', function () { + it('no matches', function () { var subject = new Anagram('diaper'); var matches = subject.matches([ 'hello', 'world', 'zombies', 'pants']); expect(matches).toEqual([]); }); - xit('detects simple anagram',function() { + xit('detects simple anagram', function () { var subject = new Anagram('ant'); var matches = subject.matches(['tan', 'stand', 'at']); expect(matches).toEqual(['tan']); }); - xit('does not detect false positives',function() { + xit('does not detect false positives', function () { var subject = new Anagram('galea'); var matches = subject.matches(['eagle']); expect(matches).toEqual([]); }); - xit('detects multiple anagrams',function() { + xit('detects multiple anagrams', function () { var subject = new Anagram('master'); var matches = subject.matches(['stream', 'pigeon', 'maters']); expect(matches).toEqual(['stream', 'maters']); }); - xit('does not detect anagram subsets',function() { + xit('does not detect anagram subsets', function () { var subject = new Anagram('good'); var matches = subject.matches(['dog', 'goody']); expect(matches).toEqual([]); }); - xit('detects anagram',function() { + xit('detects anagram', function () { var subject = new Anagram('listen'); var matches = subject.matches(['enlists', 'google', 'inlets', 'banana']); expect(matches).toEqual(['inlets']); }); - xit('detects multiple anagrams',function() { + xit('detects multiple anagrams', function () { var subject = new Anagram('allergy'); var matches = subject.matches(['gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading']); expect(matches).toEqual(['gallery', 'regally', 'largely']); }); - xit('detects anagrams case-insensitively',function() { + xit('detects anagrams case-insensitively', function () { var subject = new Anagram('Orchestra'); var matches = subject.matches(['cashregister', 'Carthorse', 'radishes']); expect(matches).toEqual(['Carthorse']); }); - xit('does not detect a word as its own anagram',function() { + xit('does not detect a word as its own anagram', function () { var subject = new Anagram('banana'); var matches = subject.matches(['Banana']); expect(matches).toEqual([]); }); - xit('matches() accepts string arguments',function() { + xit('matches() accepts string arguments', function () { var subject = new Anagram('ant'); var matches = subject.matches('stand', 'tan', 'at'); expect(matches).toEqual(['tan']); }); - xit('matches() accepts single string argument',function() { + xit('matches() accepts single string argument', function () { var subject = new Anagram('ant'); var matches = subject.matches('tan'); diff --git a/exercises/anagram/example.js b/exercises/anagram/example.js index daddd20c..f1d77dc4 100644 --- a/exercises/anagram/example.js +++ b/exercises/anagram/example.js @@ -10,7 +10,7 @@ Anagram.prototype.matches = function (words) { return words.filter(function (candidate) { return !sameWord(this.word, candidate) && isAnagram(this.word, candidate); }, this); -} +}; function sameWord(word, candidate) { return word.toLowerCase() === candidate.toLowerCase(); diff --git a/exercises/atbash-cipher/atbash-cipher.spec.js b/exercises/atbash-cipher/atbash-cipher.spec.js index 73f73e07..07c9f554 100644 --- a/exercises/atbash-cipher/atbash-cipher.spec.js +++ b/exercises/atbash-cipher/atbash-cipher.spec.js @@ -1,39 +1,37 @@ var atbash = require('./atbash-cipher'); -describe('encode', function() { - - it('encodes no', function() { +describe('encode', function () { + it('encodes no', function () { expect(atbash.encode('no')).toEqual('ml'); }); - xit('encodes yes', function() { + xit('encodes yes', function () { expect(atbash.encode('yes')).toEqual('bvh'); }); - xit('encodes OMG', function() { + xit('encodes OMG', function () { expect(atbash.encode('OMG')).toEqual('lnt'); }); - xit('encodes O M G', function() { + xit('encodes O M G', function () { expect(atbash.encode('O M G')).toEqual('lnt'); }); - xit('encodes long words', function() { + xit('encodes long words', function () { expect(atbash.encode('mindblowingly')).toEqual('nrmwy oldrm tob'); }); - xit('encodes numbers', function() { + xit('encodes numbers', function () { expect(atbash.encode('Testing, 1 2 3, testing.')) .toEqual('gvhgr mt123 gvhgr mt'); }); - xit('encodes sentences', function() { + xit('encodes sentences', function () { expect(atbash.encode('Truth is fiction.')).toEqual('gifgs rhurx grlm'); }); - xit('encodes all the things', function() { + xit('encodes all the things', function () { expect(atbash.encode('The quick brown fox jumps over the lazy dog.')) .toEqual('gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt'); }); - }); diff --git a/exercises/atbash-cipher/example.js b/exercises/atbash-cipher/example.js index 6c301bfe..c93608fa 100644 --- a/exercises/atbash-cipher/example.js +++ b/exercises/atbash-cipher/example.js @@ -9,7 +9,7 @@ function insertSpacing(s, interval) { } function invert(character) { - /*jshint validthis: true */ + /* jshint validthis: true */ if (character.match(/\d/)) { this.push(character); } else { @@ -25,4 +25,4 @@ module.exports = { encoded = insertSpacing(characters.join(''), 5); return encoded; } -}; \ No newline at end of file +}; diff --git a/exercises/beer-song/beer-song.spec.js b/exercises/beer-song/beer-song.spec.js index d77d7e2d..b83908a1 100644 --- a/exercises/beer-song/beer-song.spec.js +++ b/exercises/beer-song/beer-song.spec.js @@ -1,34 +1,34 @@ var BeerSong = require('./beer-song'); -describe('BeerSong', function() { +describe('BeerSong', function () { var song = new BeerSong(); - it('prints an arbitrary verse', function() { + it('prints an arbitrary verse', function () { var expected = '8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n'; expect(song.verse(8)).toEqual(expected); }); - xit('handles 2 bottles', function() { + xit('handles 2 bottles', function () { var expected = '2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n'; expect(song.verse(2)).toEqual(expected); }); - xit('handles 1 bottle', function() { + xit('handles 1 bottle', function () { var expected = '1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n'; expect(song.verse(1)).toEqual(expected); }); - xit('handles 0 bottles', function() { + xit('handles 0 bottles', function () { var expected = 'No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n'; expect(song.verse(0)).toEqual(expected); }); - xit('sings several verses', function() { + xit('sings several verses', function () { var expected = '8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n'; expect(song.sing(8, 6)).toEqual(expected); }); - xit('sings the rest of the verses', function() { + xit('sings the rest of the verses', function () { var expected = '3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n'; expect(song.sing(3)).toEqual(expected); }); diff --git a/exercises/beer-song/example.js b/exercises/beer-song/example.js index 26e7299d..f50a79d5 100644 --- a/exercises/beer-song/example.js +++ b/exercises/beer-song/example.js @@ -1,4 +1,4 @@ -(function() { +(function () { 'use strict'; function bottles(number) { @@ -38,11 +38,11 @@ function BeerSong() {} - BeerSong.prototype.sing = function(first, last) { - if (typeof(first) === 'undefined') { + BeerSong.prototype.sing = function (first, last) { + if (typeof (first) === 'undefined') { first = 99; } - if (typeof(last) === 'undefined') { + if (typeof (last) === 'undefined') { last = 0; } @@ -54,7 +54,7 @@ return verses.join('\n'); }; - BeerSong.prototype.verse = function(number) { + BeerSong.prototype.verse = function (number) { var line1 = bottles(number) + ' of beer on the wall, '; var line2 = bottles(number).toLowerCase() + ' of beer.\n'; var line3 = action(number); diff --git a/exercises/binary-search-tree/binary-search-tree.spec.js b/exercises/binary-search-tree/binary-search-tree.spec.js index 16f3c307..e2a2ba2d 100644 --- a/exercises/binary-search-tree/binary-search-tree.spec.js +++ b/exercises/binary-search-tree/binary-search-tree.spec.js @@ -8,13 +8,12 @@ function recordAllData(bst) { return out; } -describe('BinarySearchTree', function() { - - it('data is retained', function() { +describe('BinarySearchTree', function () { + it('data is retained', function () { expect(new Bst(4).data).toEqual(4); }); - xit('inserting less', function() { + xit('inserting less', function () { var four; four = new Bst(4); @@ -24,7 +23,7 @@ describe('BinarySearchTree', function() { expect(four.left.data).toEqual(2); }); - xit('inserting same', function() { + xit('inserting same', function () { var four; four = new Bst(4); @@ -34,7 +33,7 @@ describe('BinarySearchTree', function() { expect(four.left.data).toEqual(4); }); - xit('inserting right', function() { + xit('inserting right', function () { var four; four = new Bst(4); @@ -44,7 +43,7 @@ describe('BinarySearchTree', function() { expect(four.right.data).toEqual(5); }); - xit('complex tree', function() { + xit('complex tree', function () { var four; four = new Bst(4); @@ -64,11 +63,11 @@ describe('BinarySearchTree', function() { expect(four.right.right.data).toEqual(7); }); - xit('iterating one element', function() { + xit('iterating one element', function () { expect(recordAllData(new Bst(4))).toEqual([4]); }); - xit('iterating over smaller element', function() { + xit('iterating over smaller element', function () { var four; four = new Bst(4); @@ -77,7 +76,7 @@ describe('BinarySearchTree', function() { expect(recordAllData(four)).toEqual([2, 4]); }); - xit('iterating over larger element', function() { + xit('iterating over larger element', function () { var four; four = new Bst(4); @@ -86,7 +85,7 @@ describe('BinarySearchTree', function() { expect(recordAllData(four)).toEqual([4, 5]); }); - xit('iterating over complex tree', function() { + xit('iterating over complex tree', function () { var four; four = new Bst(4); @@ -99,5 +98,4 @@ describe('BinarySearchTree', function() { expect(recordAllData(four)).toEqual([1, 2, 3, 4, 5, 6, 7]); }); - }); diff --git a/exercises/binary-search-tree/example.js b/exercises/binary-search-tree/example.js index 7d6f1670..6b4665b6 100644 --- a/exercises/binary-search-tree/example.js +++ b/exercises/binary-search-tree/example.js @@ -6,7 +6,7 @@ function BinarySearchTree(data) { this.right = undefined; } -BinarySearchTree.prototype.insert = function(value) { +BinarySearchTree.prototype.insert = function (value) { if (value <= this.data) { this.insertLeft(value); } else { @@ -16,7 +16,7 @@ BinarySearchTree.prototype.insert = function(value) { return this; }; -BinarySearchTree.prototype.insertLeft = function(value) { +BinarySearchTree.prototype.insertLeft = function (value) { if (!this.left) { this.left = new BinarySearchTree(value); } else { @@ -26,7 +26,7 @@ BinarySearchTree.prototype.insertLeft = function(value) { return this; }; -BinarySearchTree.prototype.insertRight = function(value) { +BinarySearchTree.prototype.insertRight = function (value) { if (!this.right) { this.right = new BinarySearchTree(value); } else { @@ -36,7 +36,7 @@ BinarySearchTree.prototype.insertRight = function(value) { return this; }; -BinarySearchTree.prototype.each = function(fn) { +BinarySearchTree.prototype.each = function (fn) { if (this.left) { this.left.each(fn); } fn.call(this, this.data); if (this.right) { this.right.each(fn); } diff --git a/exercises/binary-search/binary-search.spec.js b/exercises/binary-search/binary-search.spec.js index 773b22f3..12efc126 100644 --- a/exercises/binary-search/binary-search.spec.js +++ b/exercises/binary-search/binary-search.spec.js @@ -1,12 +1,11 @@ var BinarySearch = require('./binary-search'); -describe('BinarySearch', function() { - +describe('BinarySearch', function () { var sortedArray = [1, 2, 3, 4, 5, 6]; var sortedArrayOfOddLength = [0, 1, 2, 2, 3, 10, 12]; var unsortedArray = [10, 2, 5, 1]; - it ('should require a sorted array', function() { + it('should require a sorted array', function () { var invalidBinarySearch = new BinarySearch(unsortedArray); var validBinarySearch = new BinarySearch(sortedArray); @@ -14,23 +13,23 @@ describe('BinarySearch', function() { expect(Array.isArray(validBinarySearch.array)).toEqual(true); }); - xit('should find the correct index of an included value in the middle of the array', function() { + xit('should find the correct index of an included value in the middle of the array', function () { expect(new BinarySearch(sortedArray).indexOf(3)).toEqual(2); }); - xit('should find the correct index of an included value at the beginning of the array', function() { + xit('should find the correct index of an included value at the beginning of the array', function () { expect(new BinarySearch(sortedArray).indexOf(1)).toEqual(0); }); - xit('should find the correct index of an included value at the end of the array', function() { + xit('should find the correct index of an included value at the end of the array', function () { expect(new BinarySearch(sortedArray).indexOf(6)).toEqual(5); }); - xit('should search the middle of the array', function() { + xit('should search the middle of the array', function () { expect(new BinarySearch(sortedArrayOfOddLength).indexOf(2)).toEqual(3); }); - xit('should return -1 for a value not in the array', function() { + xit('should return -1 for a value not in the array', function () { expect(new BinarySearch(sortedArray).indexOf(10)).toEqual(-1); }); }); diff --git a/exercises/binary-search/example.js b/exercises/binary-search/example.js index 00ad0eab..a4e6095c 100644 --- a/exercises/binary-search/example.js +++ b/exercises/binary-search/example.js @@ -1,18 +1,17 @@ 'use strict'; function BinarySearch(array) { - - //check if array is sorted + // check if array is sorted var arrayIsSorted = true; for (var i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) arrayIsSorted = false; } - //instantiate the array if sorted + // instantiate the array if sorted if (arrayIsSorted) this.array = array; - //use binary search for indexOf - this.indexOf = function(value) { + // use binary search for indexOf + this.indexOf = function (value) { return recursiveSearch(this.array, value, 0, this.array.length); }; } @@ -32,4 +31,4 @@ function recursiveSearch(array, value, start, end) { return mid; } -module.exports = BinarySearch; \ No newline at end of file +module.exports = BinarySearch; diff --git a/exercises/binary/binary.spec.js b/exercises/binary/binary.spec.js index b90f7d0e..a7fe1c35 100644 --- a/exercises/binary/binary.spec.js +++ b/exercises/binary/binary.spec.js @@ -1,48 +1,47 @@ var Binary = require('./binary'); -describe('binary', function() { - it('0 is decimal 0', function() { +describe('binary', function () { + it('0 is decimal 0', function () { expect(new Binary('0').toDecimal()).toEqual(0); }); - xit('1 is decimal 1', function() { + xit('1 is decimal 1', function () { expect(new Binary('1').toDecimal()).toEqual(1); }); - xit('10 is decimal 2', function() { + xit('10 is decimal 2', function () { expect(new Binary('10').toDecimal()).toEqual(2); }); - xit('11 is decimal 3', function() { + xit('11 is decimal 3', function () { expect(new Binary('11').toDecimal()).toEqual(3); }); - xit('100 is decimal 4', function() { + xit('100 is decimal 4', function () { expect(new Binary('100').toDecimal()).toEqual(4); }); - xit('1001 is decimal 9', function() { + xit('1001 is decimal 9', function () { expect(new Binary('1001').toDecimal()).toEqual(9); }); - xit('11010 is decimal 26', function() { + xit('11010 is decimal 26', function () { expect(new Binary('11010').toDecimal()).toEqual(26); }); - xit('10001101000 is decimal 1128', function() { + xit('10001101000 is decimal 1128', function () { expect(new Binary('10001101000').toDecimal()).toEqual(1128); }); - xit('00011111 is decimal 31', function() { + xit('00011111 is decimal 31', function () { expect(new Binary('00011111').toDecimal()).toEqual(31); }); - xit('invalid inputs are decimal 0', function() { + xit('invalid inputs are decimal 0', function () { expect(new Binary('carrot').toDecimal()).toEqual(0); expect(new Binary('012').toDecimal()).toEqual(0); expect(new Binary('10nope').toDecimal()).toEqual(0); expect(new Binary('nope10').toDecimal()).toEqual(0); expect(new Binary('10nope10').toDecimal()).toEqual(0); }); - }); diff --git a/exercises/bob/bob.spec.js b/exercises/bob/bob.spec.js index 5a008481..d8555e65 100644 --- a/exercises/bob/bob.spec.js +++ b/exercises/bob/bob.spec.js @@ -122,5 +122,4 @@ describe('Bob', function () { var result = bob.hey('This is a statement ending with whitespace '); expect(result).toEqual('Whatever.'); }); - }); diff --git a/exercises/bob/example.js b/exercises/bob/example.js index 6526bd7a..7826975f 100644 --- a/exercises/bob/example.js +++ b/exercises/bob/example.js @@ -13,7 +13,7 @@ function Bob() { return message[message.length - 1] === '?'; } - this.hey = function(input) { + this.hey = function (input) { var message = input.trim(); if (isSilence(message)) { return 'Fine. Be that way!'; @@ -21,9 +21,8 @@ function Bob() { return 'Whoa, chill out!'; } else if (isAQuestion(message)) { return 'Sure.'; - } else { - return 'Whatever.'; } + return 'Whatever.'; }; } diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 2804ee5a..881b1b45 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -1,148 +1,148 @@ var Bowling = require('./bowling'); -describe('Bowling', function() { - describe('Check game can be scored correctly.', function() { - it('should be able to score a game with all gutterballs', function() { +describe('Bowling', function () { + describe('Check game can be scored correctly.', function () { + it('should be able to score a game with all gutterballs', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(0); }); - xit('should be able to score a game with all open frames', function() { + xit('should be able to score a game with all open frames', function () { var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; expect(new Bowling(rolls).score()).toEqual(90); }); - xit('a spare followed by zeros is worth ten points', function() { + xit('a spare followed by zeros is worth ten points', function () { var rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - xit('points scored in the roll after a spare are counted twice', function() { + xit('points scored in the roll after a spare are counted twice', function () { var rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(16); }); - xit('consecutive spares each get a one roll bonus', function() { + xit('consecutive spares each get a one roll bonus', function () { var rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(31); }); - xit('should allow fill ball when the last frame is a spare', function() { + xit('should allow fill ball when the last frame is a spare', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; expect(new Bowling(rolls).score()).toEqual(17); }); - xit('a strike earns ten points in a frame with a single roll', function() { + xit('a strike earns ten points in a frame with a single roll', function () { var rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - xit('points scored in the two rolls after a strike are counted twice as a bonus', function() { + xit('points scored in the two rolls after a strike are counted twice as a bonus', function () { var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(26); }); - xit('should be able to score multiple strikes in a row', function() { + xit('should be able to score multiple strikes in a row', function () { var rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(81); }); - xit('should allow fill balls when the last frame is a strike', function() { + xit('should allow fill balls when the last frame is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; expect(new Bowling(rolls).score()).toEqual(18); }); - xit('rolling a spare with the two roll bonus does not get a bonus roll', function() { + xit('rolling a spare with the two roll bonus does not get a bonus roll', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; expect(new Bowling(rolls).score()).toEqual(20); }); - xit('strikes with the two roll bonus do not get bonus rolls', function() { + xit('strikes with the two roll bonus do not get bonus rolls', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(30); }); - xit('a strike with the one roll bonus after a spare in the last frame does not get a bonus', function() { + xit('a strike with the one roll bonus after a spare in the last frame does not get a bonus', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; expect(new Bowling(rolls).score()).toEqual(20); }); - xit('should be able to score a perfect game', function() { + xit('should be able to score a perfect game', function () { var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(300); }); }); - describe('Check game rules.', function() { - xit('rolls can not score negative points', function() { + describe('Check game rules.', function () { + xit('rolls can not score negative points', function () { var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pins must have a value from 0 to 10')); - }); + expect(function () { new Bowling(rolls).score(); }).toThrow( + new Error('Pins must have a value from 0 to 10')); + }); - xit('a roll can not score more than 10 points', function() { + xit('a roll can not score more than 10 points', function () { var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pins must have a value from 0 to 10')); - }); + }); - xit('two rolls in a frame can not score more than 10 points', function() { + xit('two rolls in a frame can not score more than 10 points', function () { var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); - }); + }); - xit('two bonus rolls after a strike in the last frame can not score more than 10 points', function() { + xit('two bonus rolls after a strike in the last frame can not score more than 10 points', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6]; - expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pin count exceeds pins on the lane')); - }); + expect(function () { new Bowling(rolls).score(); }).toThrow( + new Error('Pin count exceeds pins on the lane')); + }); - xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function() { + xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; expect(new Bowling(rolls).score()).toEqual(26); }); - xit('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', function() { + xit('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10]; - expect(function() { new Bowling(rolls).score(); }).toThrow( - new Error('Pin count exceeds pins on the lane')); + expect(function () { new Bowling(rolls).score(); }).toThrow( + new Error('Pin count exceeds pins on the lane')); }); - xit('an unstarted game can not be scored', function() { + xit('an unstarted game can not be scored', function () { var rolls = []; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('an incomplete game can not be scored', function() { + xit('an incomplete game can not be scored', function () { var rolls = [0, 0]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('a game with more than ten frames and no last frame spare or strike can not be scored', function() { + xit('a game with more than ten frames and no last frame spare or strike can not be scored', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Should not be able to roll after game is over')); }); - xit('bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() { + xit('bonus rolls for a strike in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', function() { + xit('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('bonus roll for a spare in the last frame must be rolled before score can be calculated', function() { + xit('bonus roll for a spare in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3]; - expect(function() { new Bowling(rolls).score(); }).toThrow( + expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); }); -}); \ No newline at end of file +}); diff --git a/exercises/bowling/example.js b/exercises/bowling/example.js index 69b71027..66b204fd 100644 --- a/exercises/bowling/example.js +++ b/exercises/bowling/example.js @@ -4,7 +4,7 @@ function Bowling(rolls) { this.rolls = rolls; } -Bowling.prototype.score = function() { +Bowling.prototype.score = function () { var initialState = { frameNumber: 1, rollNumber: 1, @@ -16,7 +16,7 @@ Bowling.prototype.score = function() { score: 0 }; - var finalState = this.rolls.reduce(function(state, roll) { + var finalState = this.rolls.reduce(function (state, roll) { if (roll < 0 || roll > 10) { throw new Error('Pins must have a value from 0 to 10'); } @@ -26,7 +26,7 @@ Bowling.prototype.score = function() { } if (state.frameNumber > 10) { - throw new Error('Should not be able to roll after game is over') + throw new Error('Should not be able to roll after game is over'); } var finalFrame = state.frameNumber === 10; @@ -56,7 +56,6 @@ Bowling.prototype.score = function() { next.score = score; return next; - }, initialState); if (finalState.frameNumber !== 11) { diff --git a/exercises/bracket-push/bracket-push.spec.js b/exercises/bracket-push/bracket-push.spec.js index 2896d0f0..fb6ed2c5 100644 --- a/exercises/bracket-push/bracket-push.spec.js +++ b/exercises/bracket-push/bracket-push.spec.js @@ -1,35 +1,35 @@ var bracket = require('./bracket-push'); -describe('bracket push', function() { - it('checks for appropriate bracketing in a set of brackets', function() { +describe('bracket push', function () { + it('checks for appropriate bracketing in a set of brackets', function () { expect(bracket('{}')).toEqual(true); }); - xit('returns false for unclosed brackets', function() { + xit('returns false for unclosed brackets', function () { expect(bracket('{{')).toEqual(false); }); - xit('returns false if brackets are out of order', function() { + xit('returns false if brackets are out of order', function () { expect(bracket('}{')).toEqual(false); }); - xit('checks bracketing in more than one pair of brackets', function() { + xit('checks bracketing in more than one pair of brackets', function () { expect(bracket('{}[]')).toEqual(true); }); - xit('checks bracketing in nested brackets', function() { + xit('checks bracketing in nested brackets', function () { expect(bracket('{[]}')).toEqual(true); }); - xit('rejects brackets that are properly balanced but improperly nested', function() { + xit('rejects brackets that are properly balanced but improperly nested', function () { expect(bracket('{[}]')).toEqual(false); }); - xit('checks bracket closure with deeper nesting', function() { + xit('checks bracket closure with deeper nesting', function () { expect(bracket('{[)][]}')).toEqual(false); }); - xit('checks bracket closure in a long string of brackets', function() { + xit('checks bracket closure in a long string of brackets', function () { expect(bracket('{[]([()])}')).toEqual(true); }); }); diff --git a/exercises/bracket-push/example.js b/exercises/bracket-push/example.js index 2d97c0ee..ab3d22d3 100644 --- a/exercises/bracket-push/example.js +++ b/exercises/bracket-push/example.js @@ -1,6 +1,6 @@ 'use strict'; -var bracketPush = module.exports = function(input) { +var bracketPush = module.exports = function (input) { if (input.length === 0) { return true; } diff --git a/exercises/change/change.spec.js b/exercises/change/change.spec.js index b43bf9d8..25b86012 100644 --- a/exercises/change/change.spec.js +++ b/exercises/change/change.spec.js @@ -1,73 +1,70 @@ +var Change = require('./change'); -var Change =require('./change'); - -describe('Change', function() { - - it('change for 1 cent',function() { - var change= new Change(); - var result = change.calculate([1,5, 10, 25],1); - expect(result).toEqual([1]); +describe('Change', function () { + it('change for 1 cent', function () { + var change = new Change(); + var result = change.calculate([1, 5, 10, 25], 1); + expect(result).toEqual([1]); }); - xit('return a single coin',function() { - var change= new Change(); - var result = change.calculate([1,5, 10, 25, 100],25); + xit('return a single coin', function () { + var change = new Change(); + var result = change.calculate([1, 5, 10, 25, 100], 25); expect(result).toEqual([25]); }); - xit('multiple coins coin',function() { - var change= new Change(); - var result = change.calculate([1,5, 10, 25, 100],15); + xit('multiple coins coin', function () { + var change = new Change(); + var result = change.calculate([1, 5, 10, 25, 100], 15); expect(result).toEqual([5, 10]); }); - xit('test with Lillipution Currency where a greedy algorithm fails',function() { + xit('test with Lillipution Currency where a greedy algorithm fails', function () { // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method - var change= new Change(); - var result = change.calculate([1, 4, 15, 20, 50],23); - expect(result).toEqual([4,4,15]); + var change = new Change(); + var result = change.calculate([1, 4, 15, 20, 50], 23); + expect(result).toEqual([4, 4, 15]); }); - xit('test with lower Elbonian Currency where a greedy algorithm fails',function() { + xit('test with lower Elbonian Currency where a greedy algorithm fails', function () { // https://en.wikipedia.org/wiki/Change-making_problem#Greedy_method - var change= new Change(); - var result = change.calculate([1, 5, 10, 21, 25],63); + var change = new Change(); + var result = change.calculate([1, 5, 10, 21, 25], 63); expect(result).toEqual([21, 21, 21]); }); - xit('test large amount of change',function() { - var change= new Change(); - var result = change.calculate([1, 2, 5, 10, 20, 50 , 100], 999); + xit('test large amount of change', function () { + var change = new Change(); + var 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]); }); - xit('test zero change',function() { - var change= new Change(); + xit('test zero change', function () { + var change = new Change(); var result = change.calculate([1, 5, 10, 21, 25], 0); expect(result).toEqual([]); }); - xit('test less than the smallest currency represented',function() { - var change= new Change(); + xit('test less than the smallest currency represented', function () { + var change = new Change(); var message = 'The total 3 cannot be represented in the given currency.'; - var test=function(){return change.calculate([5,10],3);}; - expect(test).toThrowError(Error,message); + var test = function () {return change.calculate([5, 10], 3);}; + expect(test).toThrowError(Error, message); }); - xit('test a large value that the currency cannot represent',function() { - var change= new Change(); - var message ='The total 94 cannot be represented in the given currency.'; - var test=function(){return change.calculate([5,10], 94);}; - expect(test).toThrowError(Error,message); + xit('test a large value that the currency cannot represent', function () { + var change = new Change(); + var message = 'The total 94 cannot be represented in the given currency.'; + var test = function () {return change.calculate([5, 10], 94);}; + expect(test).toThrowError(Error, message); }); - xit('negative change is rejected',function() { - var change= new Change(); + xit('negative change is rejected', function () { + var change = new Change(); var message = 'Negative totals are not allowed.'; - var test = function(){return change.calculate([1,2,5],-5);}; + var test = function () {return change.calculate([1, 2, 5], -5);}; expect(test).toThrowError(Error, message); }); - }); diff --git a/exercises/change/example.js b/exercises/change/example.js index cfc68763..4c71005b 100644 --- a/exercises/change/example.js +++ b/exercises/change/example.js @@ -1,204 +1,162 @@ -"use strict" +'use strict'; -var Change = function() -{ +var Change = function () { -} +}; -module.exports=Change; +module.exports = Change; -//data structure to hold each candidate solution that is generated -var Candidate = function() -{ - - var searched=false; - var coins=[]; +// data structure to hold each candidate solution that is generated +var Candidate = function () { + var searched = false; + var coins = []; - this.Searched =function() - { - searched=true; - } - - this.isSearched = function() - { - return searched; - } - - this.getCoins = function() - { - return coins; - } - - this.addCoin = function(coin) - { - function sortNum(a,b) - { - return a-b; - } - - coins.push(coin); - coins.sort(sortNum); + this.Searched = function () { + searched = true; + }; - } - - this.getCoinCount=function() - { - return coins.length; - } + this.isSearched = function () { + return searched; + }; - this.getSum=function() - { - function getSum(total, num){return total+num;} - return coins.reduce(getSum); + this.getCoins = function () { + return coins; + }; + + this.addCoin = function (coin) { + function sortNum(a, b) { + return a - b; } - -} + coins.push(coin); + coins.sort(sortNum); + }; -Change.prototype.calculate=function(coinArray, target) -{ + this.getCoinCount = function () { + return coins.length; + }; - var candidates=[]; - //fill the array with 0 to start - candidates[target]=0; - candidates.fill(0); + this.getSum = function () { + function getSum(total, num) {return total + num;} + return coins.reduce(getSum); + }; +}; - //validation checks up front - if(target==0)return []; +Change.prototype.calculate = function (coinArray, target) { + var candidates = []; + // fill the array with 0 to start + candidates[target] = 0; + candidates.fill(0); - if(target<0) - { - throw new Error( 'Negative totals are not allowed.'); - } + // validation checks up front + if (target == 0) return []; - if(targetcandidate.getCoinCount()) - { - candidates[sum]=candidate; - } + if ( candidate.getSum() <= target && + typeof (candidates[sum]) !== 'number' && + candidates[sum].getCoinCount() > candidate.getCoinCount()) { + candidates[sum] = candidate; + } - if(candidate.getSum()<=target && - typeof(candidates[sum])=='number') - { - candidates[sum]=candidate; - } + if (candidate.getSum() <= target && + typeof (candidates[sum]) === 'number') { + candidates[sum] = candidate; } - + } - //for the candidate, generate another candate for each of the possible coins - function branch(current) - { - for(let j=0; j= 0; i--){ + for (var i = inputIndex - 1; i >= 0; i--) { output += getLine(inputIndex, i); } - return output; - } + return output; + }; - var getLine = function(inputIndex, index){ + var getLine = function (inputIndex, index) { var difference = inputIndex - index; - return spaceTimes(difference) + printAlphabets(index) + spaceTimes(difference) + "\n"; - } + return spaceTimes(difference) + printAlphabets(index) + spaceTimes(difference) + '\n'; + }; - var printAlphabets = function(index){ + var printAlphabets = function (index) { var character = 65 + index; - if(index === 0){ - return "A"; - } - else { - return String.fromCharCode(character) + spaceTimes(((index - 1) * 2) + 1) + String.fromCharCode(character); + if (index === 0) { + return 'A'; } - } + return String.fromCharCode(character) + spaceTimes(((index - 1) * 2) + 1) + String.fromCharCode(character); + }; - var spaceTimes = function(times){ - return " ".repeat(times); - } + var spaceTimes = function (times) { + return ' '.repeat(times); + }; }; module.exports = Diamond; diff --git a/exercises/difference-of-squares/difference-of-squares.spec.js b/exercises/difference-of-squares/difference-of-squares.spec.js index 99a188f8..4be426e0 100644 --- a/exercises/difference-of-squares/difference-of-squares.spec.js +++ b/exercises/difference-of-squares/difference-of-squares.spec.js @@ -1,7 +1,6 @@ var Squares = require('./difference-of-squares'); describe('Squares', function () { - describe('up to 5', function () { var squares = new Squares(5); @@ -16,7 +15,6 @@ describe('Squares', function () { xit('gets the difference', function () { expect(squares.difference).toBe(170); }); - }); describe('up to 10', function () { @@ -33,7 +31,6 @@ describe('Squares', function () { xit('gets the difference', function () { expect(squares.difference).toBe(2640); }); - }); describe('up to 100', function () { @@ -50,7 +47,5 @@ describe('Squares', function () { xit('gets the difference', function () { expect(squares.difference).toBe(25164150); }); - }); - }); diff --git a/exercises/difference-of-squares/example.js b/exercises/difference-of-squares/example.js index 686e4a8c..4b96fc3e 100644 --- a/exercises/difference-of-squares/example.js +++ b/exercises/difference-of-squares/example.js @@ -7,12 +7,12 @@ module.exports = function Squares(max) { for (var x = 1; x <= max; x++) { sum += x; } - return sum*sum; + return sum * sum; }, get sumOfSquares() { var sum = 0; for (var x = 1; x <= max; x++) { - sum += x*x; + sum += x * x; } return sum; }, @@ -20,4 +20,4 @@ module.exports = function Squares(max) { return this.squareOfSums - this.sumOfSquares; } }; -}; \ No newline at end of file +}; diff --git a/exercises/etl/etl.spec.js b/exercises/etl/etl.spec.js index f2132843..23076ecf 100644 --- a/exercises/etl/etl.spec.js +++ b/exercises/etl/etl.spec.js @@ -1,30 +1,30 @@ var ETL = require('./etl'); -describe('Transform', function() { +describe('Transform', function () { var etl = new ETL(); - it('transforms one value', function() { + it('transforms one value', function () { var old = { 1: ['A'] }; var expected = { a: 1 }; expect(etl.transform(old)).toEqual(expected); }); - xit('transforms more values', function() { + xit('transforms more values', function () { var old = { 1: ['A', 'E', 'I', 'O', 'U'] }; var expected = { a: 1, e: 1, i: 1, o: 1, u: 1 }; expect(etl.transform(old)).toEqual(expected); }); - xit('transforms more keys', function() { + xit('transforms more keys', function () { var old = { 1: ['A', 'E'], 2: ['D', 'G'] }; var expected = { a: 1, e: 1, d: 2, g: 2 }; expect(etl.transform(old)).toEqual(expected); }); - xit('transforms a full dataset', function() { + xit('transforms a full dataset', function () { var old = { 1: [ 'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T' ], 2: [ 'D', 'G' ], @@ -45,5 +45,4 @@ describe('Transform', function() { expect(etl.transform(old)).toEqual(expected); }); - }); diff --git a/exercises/etl/example.js b/exercises/etl/example.js index e0a51bf6..cd8df0ce 100644 --- a/exercises/etl/example.js +++ b/exercises/etl/example.js @@ -2,7 +2,7 @@ function ETL() {} -ETL.prototype.transform = function(input) { +ETL.prototype.transform = function (input) { var output = {}; var object = Object.keys(input); diff --git a/exercises/flatten-array/example.js b/exercises/flatten-array/example.js index fcaa8444..63ab232b 100644 --- a/exercises/flatten-array/example.js +++ b/exercises/flatten-array/example.js @@ -1,15 +1,15 @@ -var Flattener = function(){}; +var Flattener = function () {}; -Flattener.prototype.flatten = function(unflattenedArray, flattenedArray){ +Flattener.prototype.flatten = function (unflattenedArray, flattenedArray) { var self = this, flattenedArray = flattenedArray || []; - unflattenedArray.forEach(function(element){ - if(Array.isArray(element)){ - return self.flatten(element, flattenedArray); - }else if( element !== null){ - flattenedArray.push(element); - } - }); - return flattenedArray; -} + unflattenedArray.forEach(function (element) { + if (Array.isArray(element)) { + return self.flatten(element, flattenedArray); + } else if ( element !== null) { + flattenedArray.push(element); + } + }); + return flattenedArray; +}; -module.exports = Flattener; \ No newline at end of file +module.exports = Flattener; diff --git a/exercises/flatten-array/flatten-array.spec.js b/exercises/flatten-array/flatten-array.spec.js index 5009a257..6080fe07 100644 --- a/exercises/flatten-array/flatten-array.spec.js +++ b/exercises/flatten-array/flatten-array.spec.js @@ -1,26 +1,26 @@ -var Flattener = require("./flatten-array.js"); +var Flattener = require('./flatten-array.js'); -describe("FlattenArray", function() { +describe('FlattenArray', function () { var flattener = new Flattener(); - it('flattens a nested list', function(){ + it('flattens a nested list', function () { expect(flattener.flatten([[]])).toEqual([]); }); - xit('flattens a 2 level nested list', function(){ - expect(flattener.flatten([1,[2,3,4],5])).toEqual([1, 2, 3, 4, 5]); + xit('flattens a 2 level nested list', function () { + expect(flattener.flatten([1, [2, 3, 4], 5])).toEqual([1, 2, 3, 4, 5]); }); - xit('flattens a 3 level nested list', function(){ - expect(flattener.flatten([1,[2,3,4],5,[6,[7,8]]])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + xit('flattens a 3 level nested list', function () { + expect(flattener.flatten([1, [2, 3, 4], 5, [6, [7, 8]]])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); }); - xit('flattens a 5 level nested list', function(){ - expect(flattener.flatten([0, 2, [[2, 3], 8, 100, 4,[[[50]]]], -2])).toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); + xit('flattens a 5 level nested list', function () { + expect(flattener.flatten([0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2])).toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); }); - xit('flattens a 6 level nest list', function(){ - expect(flattener.flatten([1,[2,[[3]],[4,[[5]]],6,7],8])).toEqual([1,2,3,4,5,6,7,8]); + xit('flattens a 6 level nest list', function () { + expect(flattener.flatten([1, [2, [[3]], [4, [[5]]], 6, 7], 8])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); }); - xit('flattens a 6 level nest list with null values', function(){ - expect(flattener.flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([0,2,2,3,8,100,-2]); + xit('flattens a 6 level nest list with null values', function () { + expect(flattener.flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([0, 2, 2, 3, 8, 100, -2]); }); - xit('returns an empty list if all values in nested list are null', function(){ - expect(flattener.flatten([null,[[[null]]],null,null,[[null,null],null],null])).toEqual([]); + xit('returns an empty list if all values in nested list are null', function () { + expect(flattener.flatten([null, [[[null]]], null, null, [[null, null], null], null])).toEqual([]); }); }); diff --git a/exercises/food-chain/example.js b/exercises/food-chain/example.js index ab719fce..032bbd63 100644 --- a/exercises/food-chain/example.js +++ b/exercises/food-chain/example.js @@ -37,43 +37,43 @@ FoodChain.prototype.verses = function (first, last) { */ FoodChain.prototype.verse = function (number) { switch (number) { - case 1: return '' + + case 1: return '' + 'I know an old lady who swallowed a fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 2: return '' + + case 2: return '' + 'I know an old lady who swallowed a spider.\n' + 'It wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 3: return '' + + case 3: return '' + 'I know an old lady who swallowed a bird.\n' + 'How absurd to swallow a bird!\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 4: return '' + + case 4: return '' + 'I know an old lady who swallowed a cat.\n' + 'Imagine that, to swallow a cat!\n' + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 5: return '' + + case 5: return '' + 'I know an old lady who swallowed a dog.\n' + 'What a hog, to swallow a dog!\n' + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 6: return '' + + case 6: return '' + 'I know an old lady who swallowed a goat.\n' + 'Just opened her throat and swallowed a goat!\n' + 'She swallowed the goat to catch the dog.\n' + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 7: return '' + + case 7: return '' + 'I know an old lady who swallowed a cow.\n' + 'I don\'t know how she swallowed a cow!\n' + 'She swallowed the cow to catch the goat.\n' + 'She swallowed the goat to catch the dog.\n' + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - case 8: return '' + + case 8: return '' + 'I know an old lady who swallowed a horse.\n' + 'She\'s dead, of course!\n'; - }; + } }; FoodChain.prototype.sing = FoodChain.prototype.verses.bind(null, 1, 8); diff --git a/exercises/food-chain/food-chain.spec.js b/exercises/food-chain/food-chain.spec.js index 382e26b9..6287146e 100644 --- a/exercises/food-chain/food-chain.spec.js +++ b/exercises/food-chain/food-chain.spec.js @@ -109,7 +109,7 @@ describe('Food Chain', function () { 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n\n'; - expected += 'I know an old lady who swallowed a cat.\n' + + expected += 'I know an old lady who swallowed a cat.\n' + 'Imagine that, to swallow a cat!\n' + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + @@ -147,6 +147,5 @@ describe('Food Chain', function () { expect(song.verses(1, 8)).toEqual(expected); }); - }); diff --git a/exercises/gigasecond/example.js b/exercises/gigasecond/example.js index f36189f8..420fb0dc 100644 --- a/exercises/gigasecond/example.js +++ b/exercises/gigasecond/example.js @@ -3,7 +3,7 @@ function Gigasecond(dateOfBirth) { this.dateOfBirth = dateOfBirth; - this.date = function() { + this.date = function () { var gigasecondDate = new Date(this.dateOfBirth.getTime() + 1000000000000); return gigasecondDate; }; diff --git a/exercises/gigasecond/gigasecond.spec.js b/exercises/gigasecond/gigasecond.spec.js index 5cf3384c..0fbe7c22 100644 --- a/exercises/gigasecond/gigasecond.spec.js +++ b/exercises/gigasecond/gigasecond.spec.js @@ -1,26 +1,25 @@ var Gigasecond = require('./gigasecond'); -describe('Gigasecond', function() { - - it('tells a gigasecond anniversary since midnight', function() { +describe('Gigasecond', function () { + it('tells a gigasecond anniversary since midnight', function () { var gs = new Gigasecond(new Date(Date.UTC(2015, 8, 14))); var expectedDate = new Date(Date.UTC(2047, 4, 23, 1, 46, 40)); expect(gs.date()).toEqual(expectedDate); }); - xit('tells the anniversary is next day when you are born at night', function() { + xit('tells the anniversary is next day when you are born at night', function () { var gs = new Gigasecond(new Date(Date.UTC(2015, 8, 14, 23, 59, 59))); var expectedDate = new Date(Date.UTC(2047, 4, 24, 1, 46, 39)); expect(gs.date()).toEqual(expectedDate); }); - xit('even works before 1970 (beginning of Unix epoch)', function() { + xit('even works before 1970 (beginning of Unix epoch)', function () { var gs = new Gigasecond(new Date(Date.UTC(1959, 6, 19, 5, 13, 45))); var expectedDate = new Date(Date.UTC(1991, 2, 27, 7, 0, 25)); expect(gs.date()).toEqual(expectedDate); }); - xit('make sure calling "date" doesn\'t mutate value', function() { + xit('make sure calling "date" doesn\'t mutate value', function () { var gs = new Gigasecond(new Date(Date.UTC(1959, 6, 19, 5, 13, 45))); var expectedDate = new Date(Date.UTC(1991, 2, 27, 7, 0, 25)); gs.date(); diff --git a/exercises/grade-school/example.js b/exercises/grade-school/example.js index 34be7f87..f43c127e 100644 --- a/exercises/grade-school/example.js +++ b/exercises/grade-school/example.js @@ -1,9 +1,8 @@ module.exports = function School() { - var db = {}; function add(student, grade) { - if(db[grade]) { + if (db[grade]) { db[grade].push(student); } else { db[grade] = [student]; @@ -15,7 +14,7 @@ module.exports = function School() { } function roster() { - return sortedGrades().reduce(function(sorted, grade) { + return sortedGrades().reduce(function (sorted, grade) { sorted[grade] = clone(db[grade]).sort(); return sorted; }, {}); @@ -30,7 +29,6 @@ module.exports = function School() { add: add, grade: grade }; - }; function clone(array) { diff --git a/exercises/grade-school/grade-school.spec.js b/exercises/grade-school/grade-school.spec.js index 9a58167c..2a30c810 100644 --- a/exercises/grade-school/grade-school.spec.js +++ b/exercises/grade-school/grade-school.spec.js @@ -1,60 +1,59 @@ var School = require('./grade-school'); -describe('School', function() { +describe('School', function () { var school; - beforeEach(function() { + beforeEach(function () { school = new School(); }); - it('a new school has an empty roster', function() { + it('a new school has an empty roster', function () { expect(school.roster()).toEqual({}); }); - xit('adding a student adds them to the roster for the given grade', function() { + xit('adding a student adds them to the roster for the given grade', function () { school.add('Aimee', 2); - var expectedDb = { 2 : [ 'Aimee' ] }; + var expectedDb = { 2: [ 'Aimee' ] }; expect(school.roster()).toEqual(expectedDb); }); - xit('adding more students to the same grade adds them to the roster', function() { - school.add('Blair',2); - school.add('James',2); - school.add('Paul',2); - var expectedDb = { 2 : [ 'Blair', 'James', 'Paul' ] }; + xit('adding more students to the same grade adds them to the roster', function () { + school.add('Blair', 2); + school.add('James', 2); + school.add('Paul', 2); + var expectedDb = { 2: [ 'Blair', 'James', 'Paul' ] }; expect(school.roster()).toEqual(expectedDb); }); - xit('adding students to different grades adds them to the roster', function() { - school.add('Chelsea',3); - school.add('Logan',7); - var expectedDb = { 3 : [ 'Chelsea' ], 7 : [ 'Logan' ] }; + xit('adding students to different grades adds them to the roster', function () { + school.add('Chelsea', 3); + school.add('Logan', 7); + var expectedDb = { 3: [ 'Chelsea' ], 7: [ 'Logan' ] }; expect(school.roster()).toEqual(expectedDb); }); - xit('grade returns the students in that grade in alphabetical order', function() { - school.add('Franklin',5); - school.add('Bradley',5); - school.add('Jeff',1); + xit('grade returns the students in that grade in alphabetical order', function () { + school.add('Franklin', 5); + school.add('Bradley', 5); + school.add('Jeff', 1); var expectedStudents = [ 'Bradley', 'Franklin' ]; expect(school.grade(5)).toEqual(expectedStudents); }); - xit('grade returns an empty array if there are no students in that grade', function() { + xit('grade returns an empty array if there are no students in that grade', function () { expect(school.grade(1)).toEqual([]); }); - xit('the students names in each grade in the roster are sorted', function() { + xit('the students names in each grade in the roster are sorted', function () { school.add('Jennifer', 4); school.add('Kareem', 6); school.add('Christopher', 4); school.add('Kyle', 3); var sorted = { - 3 : [ 'Kyle' ], - 4 : [ 'Christopher', 'Jennifer' ], - 6 : [ 'Kareem' ] + 3: [ 'Kyle' ], + 4: [ 'Christopher', 'Jennifer' ], + 6: [ 'Kareem' ] }; expect(school.roster()).toEqual(sorted); }); - }); diff --git a/exercises/grains/big-integer.js b/exercises/grains/big-integer.js index 78a4338f..6f21af28 100644 --- a/exercises/grains/big-integer.js +++ b/exercises/grains/big-integer.js @@ -1 +1 @@ -var bigInt=function(e){'use strict';function o(e,t){this.value=e,this.sign=t,this.isSmall=!1;}function u(e){this.value=e,this.sign=e<0,this.isSmall=!0;}function a(e){return-r0?Math.floor(e):Math.ceil(e);}function d(e,n){var r=e.length,i=n.length,s=new Array(r),o=0,u=t,a,f;for(f=0;f=u?1:0,s[f]=a-o*u;while(f0&&s.push(o),s;}function v(e,t){return e.length>=t.length?d(e,t):d(t,e);}function m(e,n){var r=e.length,i=new Array(r),s=t,o,u;for(u=0;u0)i[u++]=n%s,n=Math.floor(n/s);return i;}function g(e,n){var r=e.length,i=n.length,s=new Array(r),o=0,u=t,a,f;for(a=0;a=0?r=g(e,t):(r=g(t,e),n=!n),r=l(r),typeof r=='number'?(n&&(r=-r),new u(r)):new o(r,n);}function b(e,n,r){var i=e.length,s=new Array(i),a=-n,f=t,c,h;for(c=0;c0)i[a++]=o%s,o=Math.floor(o/s);return i;}function S(e,t){var n=[];while(t-->0)n.push(0);return n.concat(e);}function x(e,t){var n=Math.max(e.length,t.length);if(n<=400)return w(e,t);n=Math.ceil(n/2);var r=e.slice(n),i=e.slice(0,n),s=t.slice(n),o=t.slice(0,n),u=x(i,o),a=x(r,s),f=x(v(i,r),v(o,s));return v(v(u,S(g(g(f,u),a),n)),S(a,2*n));}function T(e){var n=e.length,r=h(n+n),i=t,s,o,u,a,f;for(u=0;u=0;d--){p=s-1,p=Math.floor((f[d+i]*s+f[d+i-1])/u),v=0,m=0,y=c.length;for(g=0;gi&&(c=(c+1)*u),a=Math.ceil(c/h);do{p=E(n,a);if(A(p,o)<=0)break;a--;}while(a);s.push(a),o=g(o,p);}return s.reverse(),[l(s),l(o)];}function k(e,n){var r=e.length,i=h(r),s=t,o,u,a,f;a=0;for(o=r-1;o>=0;--o)f=a*s+e[o],u=p(f/n),a=f-u*n,i[o]=u|0;return[i,a|0];}function L(e,n){var r,i=z(n),s=e.value,a=i.value,c;if(a===0)throw new Error('Cannot divide by zero');if(e.isSmall)return i.isSmall?[new u(p(s/a)),new u(s%a)]:[W[0],e];if(i.isSmall){if(a===1)return[e,W[0]];if(a==-1)return[e.negate(),W[0]];var h=Math.abs(a);if(ht.length?1:-1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return e[n]>t[n]?1:-1;return 0;}function D(e){return(typeof e=='number'||typeof e=='string')&&+Math.abs(e)<=t||e instanceof o&&e.value.length<=1;}function P(e,t,n){t=z(t);var r=e.isNegative(),i=t.isNegative(),s=r?e.not():e,o=i?t.not():t,u=[],a=[],f=!1,l=!1;while(!f||!l)s.isZero()?(f=!0,u.push(r?1:0)):r?u.push(s.isEven()?1:0):u.push(s.isEven()?0:1),o.isZero()?(l=!0,a.push(i?1:0)):i?a.push(o.isEven()?1:0):a.push(o.isEven()?0:1),s=s.over(2),o=o.over(2);var c=[];for(var h=0;h=0;c--){var h=f?s.value[c]:t,d=p(Math.random()*h);a.unshift(d),d';}function U(e,t){t=bigInt(t);if(t.isZero()){if(e.isZero())return'0';throw new Error('Cannot convert nonzero numbers to base 0.');}if(t.equals(-1))return e.isZero()?'0':e.isNegative()?(new Array(1-e)).join('10'):'1'+(new Array(+e)).join('01');var n='';e.isNegative()&&t.isPositive()&&(n='-',e=e.abs());if(t.equals(1))return e.isZero()?'0':n+(new Array(+e+1)).join(1);var r=[],i=e,s;while(i.isNegative()||i.compareAbs(t)>=0){s=i.divmod(t),i=s.quotient;var o=s.remainder;o.isNegative()&&(o=t.minus(o).abs(),i=i.next()),r.push(R(o));}return r.push(R(i)),n+r.reverse().join('');}function z(e){if(e instanceof o||e instanceof u)return e;if(typeof e=='number'){if(a(e))return new u(e);e=String(e);}if(typeof e=='string'){if(a(+e)){var t=+e;if(t===p(t))return new u(t);throw'Invalid integer: '+e;}var r=e[0]==='-';r&&(e=e.slice(1));var i=e.split(/e/i);if(i.length>2)throw new Error('Invalid integer: '+f.join('e'));if(i.length===2){var s=i[1];s[0]==='+'&&(s=s.slice(1)),s=+s;if(s!==p(s)||!a(s))throw new Error('Invalid integer: '+s+' is not a valid exponent.');var f=i[0],l=f.indexOf('.');l>=0&&(s-=f.length-l,f=f.slice(0,l)+f.slice(l+1));if(s<0)throw new Error('Cannot include negative exponent part for integers');f+=(new Array(s+1)).join('0'),e=f;}var h=/^([0-9][0-9]*)$/.test(e);if(!h)throw new Error('Invalid integer: '+e);var d=[],v=e.length,m=n,g=v-m;while(v>0)d.push(+e.slice(g,v)),g-=m,g<0&&(g=0),v-=m;return c(d),new o(d,r);}}var t=1e7,n=7,r=9007199254740992,i=f(r),s=Math.log(r);o.prototype.add=function(e){var t,n=z(e);if(this.sign!==n.sign)return this.subtract(n.negate());var r=this.value,i=n.value;return n.isSmall?new o(m(r,Math.abs(i)),this.sign):new o(v(r,i),this.sign);},o.prototype.plus=o.prototype.add,u.prototype.add=function(e){var t=z(e),n=this.value;if(n<0!==t.sign)return this.subtract(t.negate());var r=t.value;if(t.isSmall){if(a(n+r))return new u(n+r);r=f(Math.abs(r));}return new o(m(r,Math.abs(n)),n<0);},u.prototype.plus=u.prototype.add,o.prototype.subtract=function(e){var t=z(e);if(this.sign!==t.sign)return this.add(t.negate());var n=this.value,r=t.value;return t.isSmall?b(n,Math.abs(r),this.sign):y(n,r,this.sign);},o.prototype.minus=o.prototype.subtract,u.prototype.subtract=function(e){var t=z(e),n=this.value;if(n<0!==t.sign)return this.add(t.negate());var r=t.value;return t.isSmall?new u(n-r):b(r,Math.abs(n),n>=0);},u.prototype.minus=u.prototype.subtract,o.prototype.negate=function(){return new o(this.value,!this.sign);},u.prototype.negate=function(){var e=this.sign,t=new u(-this.value);return t.sign=!e,t;},o.prototype.abs=function(){return new o(this.value,!1);},u.prototype.abs=function(){return new u(Math.abs(this.value));},o.prototype.multiply=function(e){var n,r=z(e),i=this.value,s=r.value,u=this.sign!==r.sign,a;if(r.isSmall){if(s===0)return W[0];if(s===1)return this;if(s===-1)return this.negate();a=Math.abs(s);if(a4e3?new o(x(i,s),u):new o(w(i,s),u);},o.prototype.times=o.prototype.multiply,u.prototype.multiply=function(e){var n=z(e),r=this.value,i=n.value;if(r===0)return W[0];if(r===1)return n;if(r===-1)return n.negate();if(n.isSmall){if(a(r*i))return new u(r*i);i=f(Math.abs(i));}var s=Math.abs(r);return sr?1:-1):-1;},o.prototype.compare=function(e){var t=z(e),n=this.value,r=t.value;return this.sign!==t.sign?t.sign?1:-1:t.isSmall?this.sign?-1:1:A(n,r)*(this.sign?-1:1);},o.prototype.compareTo=o.prototype.compare,u.prototype.compare=function(e){var t=z(e),n=this.value,r=t.value;return t.isSmall?n==r?0:n>r?1:-1:n<0!==t.sign?n<0?-1:1:n<0?1:-1;},u.prototype.compareTo=u.prototype.compare,o.prototype.equals=function(e){return this.compare(e)===0;},u.prototype.eq=u.prototype.equals=o.prototype.eq=o.prototype.equals,o.prototype.notEquals=function(e){return this.compare(e)!==0;},u.prototype.neq=u.prototype.notEquals=o.prototype.neq=o.prototype.notEquals,o.prototype.greater=function(e){return this.compare(e)>0;},u.prototype.gt=u.prototype.greater=o.prototype.gt=o.prototype.greater,o.prototype.lesser=function(e){return this.compare(e)<0;},u.prototype.lt=u.prototype.lesser=o.prototype.lt=o.prototype.lesser,o.prototype.greaterOrEquals=function(e){return this.compare(e)>=0;},u.prototype.geq=u.prototype.greaterOrEquals=o.prototype.geq=o.prototype.greaterOrEquals,o.prototype.lesserOrEquals=function(e){return this.compare(e)<=0;},u.prototype.leq=u.prototype.lesserOrEquals=o.prototype.leq=o.prototype.lesserOrEquals,o.prototype.isEven=function(){return(this.value[0]&1)===0;},u.prototype.isEven=function(){return(this.value&1)===0;},o.prototype.isOdd=function(){return(this.value[0]&1)===1;},u.prototype.isOdd=function(){return(this.value&1)===1;},o.prototype.isPositive=function(){return!this.sign;},u.prototype.isPositive=function(){return this.value>0;},o.prototype.isNegative=function(){return this.sign;},u.prototype.isNegative=function(){return this.value<0;},o.prototype.isUnit=function(){return!1;},u.prototype.isUnit=function(){return Math.abs(this.value)===1;},o.prototype.isZero=function(){return!1;},u.prototype.isZero=function(){return this.value===0;},o.prototype.isDivisibleBy=function(e){var t=z(e),n=t.value;return n===0?!1:n===1?!0:n===2?this.isEven():this.mod(t).equals(W[0]);},u.prototype.isDivisibleBy=o.prototype.isDivisibleBy,o.prototype.isPrime=function(){var e=this.abs(),t=e.prev();if(e.isUnit())return!1;if(e.equals(2)||e.equals(3)||e.equals(5))return!0;if(e.isEven()||e.isDivisibleBy(3)||e.isDivisibleBy(5))return!1;if(e.lesser(25))return!0;var n=[2,3,5,7,11,13,17,19],r=t,i,s,o,u;while(r.isEven())r=r.divide(2);for(o=0;o-r?new u(e-1):new o(i,!0);};var O=[1];while(O[O.length-1]<=t)O.push(2*O[O.length-1]);var M=O.length,_=O[M-1];o.prototype.shiftLeft=function(e){if(!D(e))return e.isNegative()?this.shiftRight(e.abs()):this.times(W[2].pow(e));e=+e;if(e<0)return this.shiftRight(-e);var t=this;while(e>=M)t=t.multiply(_),e-=M-1;return t.multiply(O[e]);},u.prototype.shiftLeft=o.prototype.shiftLeft,o.prototype.shiftRight=function(e){var t;if(!D(e))return e.isNegative()?this.shiftLeft(e.abs()):(t=this.divmod(W[2].pow(e)),t.remainder.isNegative()?t.quotient.prev():t.quotient);e=+e;if(e<0)return this.shiftLeft(-e);var n=this;while(e>=M){if(n.isZero())return n;t=L(n,_),n=t[1].isNegative()?t[0].prev():t[0],e-=M-1;}return t=L(n,O[e]),t[1].isNegative()?t[0].prev():t[0];},u.prototype.shiftRight=o.prototype.shiftRight,o.prototype.not=function(){return this.negate().prev();},u.prototype.not=o.prototype.not,o.prototype.and=function(e){return P(this,e,function(e,t){return e&t;});},u.prototype.and=o.prototype.and,o.prototype.or=function(e){return P(this,e,function(e,t){return e|t;});},u.prototype.or=o.prototype.or,o.prototype.xor=function(e){return P(this,e,function(e,t){return e^t;});},u.prototype.xor=o.prototype.xor;var q=function(e,t){var n=W[0],r=W[1],i=e.length;if(2<=t&&t<=36&&i<=s/Math.log(t))return new u(parseInt(e,t));t=z(t);var o=[],a,f=e[0]==='-';for(a=f?1:0;a');o.push(z(e.slice(h+1,a)));}}o.reverse();for(a=0;a=0)o=String(n[r]),i+=s.slice(o.length)+o;var u=this.sign?'-':'';return u+i;},u.prototype.toString=function(t){return t===e&&(t=10),t!=10?U(this,t):String(this.value);},o.prototype.valueOf=function(){return+this.toString();},o.prototype.toJSNumber=o.prototype.valueOf,u.prototype.valueOf=function(){return this.value;},u.prototype.toJSNumber=u.prototype.valueOf;var W=function(e,t){return typeof e=='undefined'?W[0]:typeof t!='undefined'?+t===10?z(e):q(e,t):z(e);};for(var X=0;X<1e3;X++)W[X]=new u(X),X>0&&(W[-X]=new u(-X));return W.one=W[1],W.zero=W[0],W.minusOne=W[-1],W.max=H,W.min=B,W.gcd=j,W.lcm=F,W.isInstance=function(e){return e instanceof o||e instanceof u;},W.randBetween=I,W;}();typeof module!='undefined'&&module.hasOwnProperty('exports')&&(module.exports=bigInt); \ No newline at end of file +var bigInt = (function (e) {'use strict'; function o(e, t) {this.value = e, this.sign = t, this.isSmall = !1;} function u(e) {this.value = e, this.sign = e < 0, this.isSmall = !0;} function a(e) {return -r < e && e < r;} function f(e) {return e < 1e7 ? [e] : e < 1e14 ? [e % 1e7, Math.floor(e / 1e7)] : [e % 1e7, Math.floor(e / 1e7) % 1e7, Math.floor(e / 1e14)];} function l(e) {c(e); var n = e.length; if (n < 4 && A(e, i) < 0) switch (n) {case 0:return 0; case 1:return e[0]; case 2:return e[0] + e[1] * t; default:return e[0] + (e[1] + e[2] * t) * t;} return e;} function c(e) {var t = e.length; while (e[--t] === 0);e.length = t + 1;} function h(e) {var t = new Array(e), n = -1; while (++n < e)t[n] = 0; return t;} function p(e) {return e > 0 ? Math.floor(e) : Math.ceil(e);} function d(e, n) {var r = e.length, i = n.length, s = new Array(r), o = 0, u = t, a, f; for (f = 0; f < i; f++)a = e[f] + n[f] + o, o = a >= u ? 1 : 0, s[f] = a - o * u; while (f < r)a = e[f] + o, o = a === u ? 1 : 0, s[f++] = a - o * u; return o > 0 && s.push(o), s;} function v(e, t) {return e.length >= t.length ? d(e, t) : d(t, e);} function m(e, n) {var r = e.length, i = new Array(r), s = t, o, u; for (u = 0; u < r; u++)o = e[u] - s + n, n = Math.floor(o / s), i[u] = o - n * s, n += 1; while (n > 0)i[u++] = n % s, n = Math.floor(n / s); return i;} function g(e, n) {var r = e.length, i = n.length, s = new Array(r), o = 0, u = t, a, f; for (a = 0; a < i; a++)f = e[a] - o - n[a], f < 0 ? (f += u, o = 1) : o = 0, s[a] = f; for (a = i; a < r; a++) {f = e[a] - o; if (!(f < 0)) {s[a++] = f; break;}f += u, s[a] = f;} for (;a < r; a++)s[a] = e[a]; return c(s), s;} function y(e, t, n) {var r, i; return A(e, t) >= 0 ? r = g(e, t) : (r = g(t, e), n = !n), r = l(r), typeof r === 'number' ? (n && (r = -r), new u(r)) : new o(r, n);} function b(e, n, r) {var i = e.length, s = new Array(i), a = -n, f = t, c, h; for (c = 0; c < i; c++)h = e[c] + a, a = Math.floor(h / f), s[c] = h < 0 ? h % f + f : h; return s = l(s), typeof s === 'number' ? (r && (s = -s), new u(s)) : new o(s, r);} function w(e, n) {var r = e.length, i = n.length, s = r + i, o = h(s), u = t, a, f, l, p, d; for (l = 0; l < r; ++l) {p = e[l]; for (var v = 0; v < i; ++v)d = n[v], a = p * d + o[l + v], f = Math.floor(a / u), o[l + v] = a - f * u, o[l + v + 1] += f;} return c(o), o;} function E(e, n) {var r = e.length, i = new Array(r), s = t, o = 0, u, a; for (a = 0; a < r; a++)u = e[a] * n + o, o = Math.floor(u / s), i[a] = u - o * s; while (o > 0)i[a++] = o % s, o = Math.floor(o / s); return i;} function S(e, t) {var n = []; while (t-- > 0)n.push(0); return n.concat(e);} function x(e, t) {var n = Math.max(e.length, t.length); if (n <= 400) return w(e, t); n = Math.ceil(n / 2); var r = e.slice(n), i = e.slice(0, n), s = t.slice(n), o = t.slice(0, n), u = x(i, o), a = x(r, s), f = x(v(i, r), v(o, s)); return v(v(u, S(g(g(f, u), a), n)), S(a, 2 * n));} function T(e) {var n = e.length, r = h(n + n), i = t, s, o, u, a, f; for (u = 0; u < n; u++) {a = e[u]; for (var l = 0; l < n; l++)f = e[l], s = a * f + r[u + l], o = Math.floor(s / i), r[u + l] = s - o * i, r[u + l + 1] += o;} return c(r), r;} function N(e, n) {var r = e.length, i = n.length, s = t, o = h(n.length), u = n[i - 1], a = Math.ceil(s / (2 * u)), f = E(e, a), c = E(n, a), p, d, v, m, g, y, b; f.length <= r && f.push(0), c.push(0), u = c[i - 1]; for (d = r - i; d >= 0; d--) {p = s - 1, p = Math.floor((f[d + i] * s + f[d + i - 1]) / u), v = 0, m = 0, y = c.length; for (g = 0; g < y; g++)v += p * c[g], b = Math.floor(v / s), m += f[d + g] - (v - b * s), v = b, m < 0 ? (f[d + g] = m + s, m = -1) : (f[d + g] = m, m = 0); while (m !== 0) {p -= 1, v = 0; for (g = 0; g < y; g++)v += f[d + g] - s + c[g], v < 0 ? (f[d + g] = v + s, v = 0) : (f[d + g] = v, v = 1); m += v;}o[d] = p;} return f = k(f, a)[0], [l(o), l(f)];} function C(e, n) {var r = e.length, i = n.length, s = [], o = [], u = t, a, f, c, h, p; while (r) {o.unshift(e[--r]); if (A(o, n) < 0) {s.push(0); continue;}f = o.length, c = o[f - 1] * u + o[f - 2], h = n[i - 1] * u + n[i - 2], f > i && (c = (c + 1) * u), a = Math.ceil(c / h); do {p = E(n, a); if (A(p, o) <= 0) break; a--;} while (a);s.push(a), o = g(o, p);} return s.reverse(), [l(s), l(o)];} function k(e, n) {var r = e.length, i = h(r), s = t, o, u, a, f; a = 0; for (o = r - 1; o >= 0; --o)f = a * s + e[o], u = p(f / n), a = f - u * n, i[o] = u | 0; return [i, a | 0];} function L(e, n) {var r, i = z(n), s = e.value, a = i.value, c; if (a === 0) throw new Error('Cannot divide by zero'); if (e.isSmall) return i.isSmall ? [new u(p(s / a)), new u(s % a)] : [W[0], e]; if (i.isSmall) {if (a === 1) return [e, W[0]]; if (a == -1) return [e.negate(), W[0]]; var h = Math.abs(a); if (h < t) {r = k(s, h), c = l(r[0]); var d = r[1]; return e.sign && (d = -d), typeof c === 'number' ? (e.sign !== i.sign && (c = -c), [new u(c), new u(d)]) : [new o(c, e.sign !== i.sign), new u(d)];}a = f(h);} var v = A(s, a); if (v === -1) return [W[0], e]; if (v === 0) return [W[e.sign === i.sign ? 1 : -1], W[0]]; s.length + a.length <= 200 ? r = N(s, a) : r = C(s, a), c = r[0]; var m = e.sign !== i.sign, g = r[1], y = e.sign; return typeof c === 'number' ? (m && (c = -c), c = new u(c)) : c = new o(c, m), typeof g === 'number' ? (y && (g = -g), g = new u(g)) : g = new o(g, y), [c, g];} function A(e, t) {if (e.length !== t.length) return e.length > t.length ? 1 : -1; for (var n = e.length - 1; n >= 0; n--) if (e[n] !== t[n]) return e[n] > t[n] ? 1 : -1; return 0;} function D(e) {return (typeof e === 'number' || typeof e === 'string') && +Math.abs(e) <= t || e instanceof o && e.value.length <= 1;} function P(e, t, n) {t = z(t); var r = e.isNegative(), i = t.isNegative(), s = r ? e.not() : e, o = i ? t.not() : t, u = [], a = [], f = !1, l = !1; while (!f || !l)s.isZero() ? (f = !0, u.push(r ? 1 : 0)) : r ? u.push(s.isEven() ? 1 : 0) : u.push(s.isEven() ? 0 : 1), o.isZero() ? (l = !0, a.push(i ? 1 : 0)) : i ? a.push(o.isEven() ? 1 : 0) : a.push(o.isEven() ? 0 : 1), s = s.over(2), o = o.over(2); var c = []; for (var h = 0; h < u.length; h++)c.push(n(u[h], a[h])); var p = bigInt(c.pop()).negate().times(bigInt(2).pow(c.length)); while (c.length)p = p.add(bigInt(c.pop()).times(bigInt(2).pow(c.length))); return p;} function H(e, t) {return e = z(e), t = z(t), e.greater(t) ? e : t;} function B(e, t) {return e = z(e), t = z(t), e.lesser(t) ? e : t;} function j(e, t) {return e = z(e).abs(), t = z(t).abs(), e.equals(t) ? e : e.isZero() ? t : t.isZero() ? e : e.isEven() ? t.isOdd() ? j(e.divide(2), t) : j(e.divide(2), t.divide(2)).multiply(2) : t.isEven() ? j(e, t.divide(2)) : e.greater(t) ? j(e.subtract(t).divide(2), t) : j(t.subtract(e).divide(2), e);} function F(e, t) {return e = z(e).abs(), t = z(t).abs(), e.multiply(t).divide(j(e, t));} function I(e, n) {e = z(e), n = z(n); var r = B(e, n), i = H(e, n), s = i.subtract(r); if (s.isSmall) return r.add(Math.random() * s); var u = s.value.length - 1, a = [], f = !0; for (var c = u; c >= 0; c--) {var h = f ? s.value[c] : t, d = p(Math.random() * h); a.unshift(d), d < h && (f = !1);} return a = l(a), r.add(new o(a, !1, typeof a === 'number'));} function R(e) {var t = e.value; return typeof t === 'number' && (t = [t]), t.length === 1 && t[0] <= 36 ? '0123456789abcdefghijklmnopqrstuvwxyz'.charAt(t[0]) : '<' + t + '>';} function U(e, t) {t = bigInt(t); if (t.isZero()) {if (e.isZero()) return '0'; throw new Error('Cannot convert nonzero numbers to base 0.');} if (t.equals(-1)) return e.isZero() ? '0' : e.isNegative() ? (new Array(1 - e)).join('10') : '1' + (new Array(+e)).join('01'); var n = ''; e.isNegative() && t.isPositive() && (n = '-', e = e.abs()); if (t.equals(1)) return e.isZero() ? '0' : n + (new Array(+e + 1)).join(1); var r = [], i = e, s; while (i.isNegative() || i.compareAbs(t) >= 0) {s = i.divmod(t), i = s.quotient; var o = s.remainder; o.isNegative() && (o = t.minus(o).abs(), i = i.next()), r.push(R(o));} return r.push(R(i)), n + r.reverse().join('');} function z(e) {if (e instanceof o || e instanceof u) return e; if (typeof e === 'number') {if (a(e)) return new u(e); e = String(e);} if (typeof e === 'string') {if (a(+e)) {var t = +e; if (t === p(t)) return new u(t); throw 'Invalid integer: ' + e;} var r = e[0] === '-'; r && (e = e.slice(1)); var i = e.split(/e/i); if (i.length > 2) throw new Error('Invalid integer: ' + f.join('e')); if (i.length === 2) {var s = i[1]; s[0] === '+' && (s = s.slice(1)), s = +s; if (s !== p(s) || !a(s)) throw new Error('Invalid integer: ' + s + ' is not a valid exponent.'); var f = i[0], l = f.indexOf('.'); l >= 0 && (s -= f.length - l, f = f.slice(0, l) + f.slice(l + 1)); if (s < 0) throw new Error('Cannot include negative exponent part for integers'); f += (new Array(s + 1)).join('0'), e = f;} var h = /^([0-9][0-9]*)$/.test(e); if (!h) throw new Error('Invalid integer: ' + e); var d = [], v = e.length, m = n, g = v - m; while (v > 0)d.push(+e.slice(g, v)), g -= m, g < 0 && (g = 0), v -= m; return c(d), new o(d, r);}} var t = 1e7, n = 7, r = 9007199254740992, i = f(r), s = Math.log(r); o.prototype.add = function (e) {var t, n = z(e); if (this.sign !== n.sign) return this.subtract(n.negate()); var r = this.value, i = n.value; return n.isSmall ? new o(m(r, Math.abs(i)), this.sign) : new o(v(r, i), this.sign);}, o.prototype.plus = o.prototype.add, u.prototype.add = function (e) {var t = z(e), n = this.value; if (n < 0 !== t.sign) return this.subtract(t.negate()); var r = t.value; if (t.isSmall) {if (a(n + r)) return new u(n + r); r = f(Math.abs(r));} return new o(m(r, Math.abs(n)), n < 0);}, u.prototype.plus = u.prototype.add, o.prototype.subtract = function (e) {var t = z(e); if (this.sign !== t.sign) return this.add(t.negate()); var n = this.value, r = t.value; return t.isSmall ? b(n, Math.abs(r), this.sign) : y(n, r, this.sign);}, o.prototype.minus = o.prototype.subtract, u.prototype.subtract = function (e) {var t = z(e), n = this.value; if (n < 0 !== t.sign) return this.add(t.negate()); var r = t.value; return t.isSmall ? new u(n - r) : b(r, Math.abs(n), n >= 0);}, u.prototype.minus = u.prototype.subtract, o.prototype.negate = function () {return new o(this.value, !this.sign);}, u.prototype.negate = function () {var e = this.sign, t = new u(-this.value); return t.sign = !e, t;}, o.prototype.abs = function () {return new o(this.value, !1);}, u.prototype.abs = function () {return new u(Math.abs(this.value));}, o.prototype.multiply = function (e) {var n, r = z(e), i = this.value, s = r.value, u = this.sign !== r.sign, a; if (r.isSmall) {if (s === 0) return W[0]; if (s === 1) return this; if (s === -1) return this.negate(); a = Math.abs(s); if (a < t) return new o(E(i, a), u); s = f(a);} return i.length + s.length > 4e3 ? new o(x(i, s), u) : new o(w(i, s), u);}, o.prototype.times = o.prototype.multiply, u.prototype.multiply = function (e) {var n = z(e), r = this.value, i = n.value; if (r === 0) return W[0]; if (r === 1) return n; if (r === -1) return n.negate(); if (n.isSmall) {if (a(r * i)) return new u(r * i); i = f(Math.abs(i));} var s = Math.abs(r); return s < t ? new o(E(i, s), this.sign !== n.sign) : new o(w(i, f(s)), this.sign !== n.sign);}, u.prototype.times = u.prototype.multiply, o.prototype.square = function () {return new o(T(this.value), !1);}, u.prototype.square = function () {var e = this.value * this.value; return a(e) ? new u(e) : new o(T(f(Math.abs(this.value))), !1);}, o.prototype.divmod = function (e) {var t = L(this, e); return {quotient: t[0], remainder: t[1]};}, u.prototype.divmod = o.prototype.divmod, o.prototype.divide = function (e) {return L(this, e)[0];}, u.prototype.over = u.prototype.divide = o.prototype.over = o.prototype.divide, o.prototype.mod = function (e) {return L(this, e)[1];}, u.prototype.remainder = u.prototype.mod = o.prototype.remainder = o.prototype.mod, o.prototype.pow = function (e) {var t = z(e), n = this.value, r = t.value, i, s, o; if (r === 0) return W[1]; if (n === 0) return W[0]; if (n === 1) return W[1]; if (n === -1) return t.isEven() ? W[1] : W[-1]; if (t.sign) return W[0]; if (!t.isSmall) throw new Error('The exponent ' + t.toString() + ' is too large.'); if (this.isSmall && a(i = Math.pow(n, r))) return new u(p(i)); s = this, o = W[1]; for (;;) {r & !0 && (o = o.times(s), --r); if (r === 0) break; r /= 2, s = s.square();} return o;}, u.prototype.pow = o.prototype.pow, o.prototype.modPow = function (e, t) {e = z(e), t = z(t); if (t.isZero()) throw new Error('Cannot take modPow with modulus 0'); var n = W[1], r = this.mod(t); if (r.isZero()) return W[0]; while (e.isPositive())e.isOdd() && (n = n.multiply(r).mod(t)), e = e.divide(2), r = r.square().mod(t); return n;}, u.prototype.modPow = o.prototype.modPow, o.prototype.compareAbs = function (e) {var t = z(e), n = this.value, r = t.value; return t.isSmall ? 1 : A(n, r);}, u.prototype.compareAbs = function (e) {var t = z(e), n = Math.abs(this.value), r = t.value; return t.isSmall ? (r = Math.abs(r), n === r ? 0 : n > r ? 1 : -1) : -1;}, o.prototype.compare = function (e) {var t = z(e), n = this.value, r = t.value; return this.sign !== t.sign ? t.sign ? 1 : -1 : t.isSmall ? this.sign ? -1 : 1 : A(n, r) * (this.sign ? -1 : 1);}, o.prototype.compareTo = o.prototype.compare, u.prototype.compare = function (e) {var t = z(e), n = this.value, r = t.value; return t.isSmall ? n == r ? 0 : n > r ? 1 : -1 : n < 0 !== t.sign ? n < 0 ? -1 : 1 : n < 0 ? 1 : -1;}, u.prototype.compareTo = u.prototype.compare, o.prototype.equals = function (e) {return this.compare(e) === 0;}, u.prototype.eq = u.prototype.equals = o.prototype.eq = o.prototype.equals, o.prototype.notEquals = function (e) {return this.compare(e) !== 0;}, u.prototype.neq = u.prototype.notEquals = o.prototype.neq = o.prototype.notEquals, o.prototype.greater = function (e) {return this.compare(e) > 0;}, u.prototype.gt = u.prototype.greater = o.prototype.gt = o.prototype.greater, o.prototype.lesser = function (e) {return this.compare(e) < 0;}, u.prototype.lt = u.prototype.lesser = o.prototype.lt = o.prototype.lesser, o.prototype.greaterOrEquals = function (e) {return this.compare(e) >= 0;}, u.prototype.geq = u.prototype.greaterOrEquals = o.prototype.geq = o.prototype.greaterOrEquals, o.prototype.lesserOrEquals = function (e) {return this.compare(e) <= 0;}, u.prototype.leq = u.prototype.lesserOrEquals = o.prototype.leq = o.prototype.lesserOrEquals, o.prototype.isEven = function () {return (this.value[0] & 1) === 0;}, u.prototype.isEven = function () {return (this.value & 1) === 0;}, o.prototype.isOdd = function () {return (this.value[0] & 1) === 1;}, u.prototype.isOdd = function () {return (this.value & 1) === 1;}, o.prototype.isPositive = function () {return !this.sign;}, u.prototype.isPositive = function () {return this.value > 0;}, o.prototype.isNegative = function () {return this.sign;}, u.prototype.isNegative = function () {return this.value < 0;}, o.prototype.isUnit = function () {return !1;}, u.prototype.isUnit = function () {return Math.abs(this.value) === 1;}, o.prototype.isZero = function () {return !1;}, u.prototype.isZero = function () {return this.value === 0;}, o.prototype.isDivisibleBy = function (e) {var t = z(e), n = t.value; return n === 0 ? !1 : n === 1 ? !0 : n === 2 ? this.isEven() : this.mod(t).equals(W[0]);}, u.prototype.isDivisibleBy = o.prototype.isDivisibleBy, o.prototype.isPrime = function () {var e = this.abs(), t = e.prev(); if (e.isUnit()) return !1; if (e.equals(2) || e.equals(3) || e.equals(5)) return !0; if (e.isEven() || e.isDivisibleBy(3) || e.isDivisibleBy(5)) return !1; if (e.lesser(25)) return !0; var n = [2, 3, 5, 7, 11, 13, 17, 19], r = t, i, s, o, u; while (r.isEven())r = r.divide(2); for (o = 0; o < n.length; o++) {u = bigInt(n[o]).modPow(r, e); if (u.equals(W[1]) || u.equals(t)) continue; for (s = !0, i = r; s && i.lesser(t); i = i.multiply(2))u = u.square().mod(e), u.equals(t) && (s = !1); if (s) return !1;} return !0;}, u.prototype.isPrime = o.prototype.isPrime, o.prototype.next = function () {var e = this.value; return this.sign ? b(e, 1, this.sign) : new o(m(e, 1), this.sign);}, u.prototype.next = function () {var e = this.value; return e + 1 < r ? new u(e + 1) : new o(i, !1);}, o.prototype.prev = function () {var e = this.value; return this.sign ? new o(m(e, 1), !0) : b(e, 1, this.sign);}, u.prototype.prev = function () {var e = this.value; return e - 1 > -r ? new u(e - 1) : new o(i, !0);}; var O = [1]; while (O[O.length - 1] <= t)O.push(2 * O[O.length - 1]); var M = O.length, _ = O[M - 1]; o.prototype.shiftLeft = function (e) {if (!D(e)) return e.isNegative() ? this.shiftRight(e.abs()) : this.times(W[2].pow(e)); e = +e; if (e < 0) return this.shiftRight(-e); var t = this; while (e >= M)t = t.multiply(_), e -= M - 1; return t.multiply(O[e]);}, u.prototype.shiftLeft = o.prototype.shiftLeft, o.prototype.shiftRight = function (e) {var t; if (!D(e)) return e.isNegative() ? this.shiftLeft(e.abs()) : (t = this.divmod(W[2].pow(e)), t.remainder.isNegative() ? t.quotient.prev() : t.quotient); e = +e; if (e < 0) return this.shiftLeft(-e); var n = this; while (e >= M) {if (n.isZero()) return n; t = L(n, _), n = t[1].isNegative() ? t[0].prev() : t[0], e -= M - 1;} return t = L(n, O[e]), t[1].isNegative() ? t[0].prev() : t[0];}, u.prototype.shiftRight = o.prototype.shiftRight, o.prototype.not = function () {return this.negate().prev();}, u.prototype.not = o.prototype.not, o.prototype.and = function (e) {return P(this, e, function (e, t) {return e & t;});}, u.prototype.and = o.prototype.and, o.prototype.or = function (e) {return P(this, e, function (e, t) {return e | t;});}, u.prototype.or = o.prototype.or, o.prototype.xor = function (e) {return P(this, e, function (e, t) {return e ^ t;});}, u.prototype.xor = o.prototype.xor; var q = function (e, t) {var n = W[0], r = W[1], i = e.length; if (t >= 2 && t <= 36 && i <= s / Math.log(t)) return new u(parseInt(e, t)); t = z(t); var o = [], a, f = e[0] === '-'; for (a = f ? 1 : 0; a < e.length; a++) {var l = e[a].toLowerCase(), c = l.charCodeAt(0); if (c >= 48 && c <= 57)o.push(z(l)); else if (c >= 97 && c <= 122)o.push(z(l.charCodeAt(0) - 87)); else {if (l !== '<') throw new Error(l + ' is not a valid character'); var h = a; do a++; while (e[a] !== '>');o.push(z(e.slice(h + 1, a)));}}o.reverse(); for (a = 0; a < o.length; a++)n = n.add(o[a].times(r)), r = r.times(t); return f ? n.negate() : n;}; o.prototype.toString = function (t) {t === e && (t = 10); if (t !== 10) return U(this, t); var n = this.value, r = n.length, i = String(n[--r]), s = '0000000', o; while (--r >= 0)o = String(n[r]), i += s.slice(o.length) + o; var u = this.sign ? '-' : ''; return u + i;}, u.prototype.toString = function (t) {return t === e && (t = 10), t != 10 ? U(this, t) : String(this.value);}, o.prototype.valueOf = function () {return +this.toString();}, o.prototype.toJSNumber = o.prototype.valueOf, u.prototype.valueOf = function () {return this.value;}, u.prototype.toJSNumber = u.prototype.valueOf; var W = function (e, t) {return typeof e === 'undefined' ? W[0] : typeof t !== 'undefined' ? +t === 10 ? z(e) : q(e, t) : z(e);}; for (var X = 0; X < 1e3; X++)W[X] = new u(X), X > 0 && (W[-X] = new u(-X)); return W.one = W[1], W.zero = W[0], W.minusOne = W[-1], W.max = H, W.min = B, W.gcd = j, W.lcm = F, W.isInstance = function (e) {return e instanceof o || e instanceof u;}, W.randBetween = I, W;}()); typeof module !== 'undefined' && module.hasOwnProperty('exports') && (module.exports = bigInt); diff --git a/exercises/grains/big-integer.spec.js b/exercises/grains/big-integer.spec.js index 26bea91f..865a66ae 100644 --- a/exercises/grains/big-integer.spec.js +++ b/exercises/grains/big-integer.spec.js @@ -4,11 +4,11 @@ var BigInt = require('./big-integer'); describe('The big-integer module\'s returned object', function () { var bigI; - beforeEach(function() { + beforeEach(function () { bigI = BigInt(42); }); - afterEach(function() { + afterEach(function () { bigI = null; }); @@ -19,20 +19,19 @@ describe('The big-integer module\'s returned object', function () { }); it('can be compared to a stringified number by calling \'.toString()\'', - function () { - - expect(bigI).not.toBe(42); - expect(bigI).not.toBe('42'); - expect(bigI.toString()).toBe('42'); - // NOTE: - // The '==' operator calls '.toString()' here in order to compare. - expect(bigI == '42').toBe(true); + function () { + expect(bigI).not.toBe(42); + expect(bigI).not.toBe('42'); + expect(bigI.toString()).toBe('42'); + // NOTE: + // The '==' operator calls '.toString()' here in order to compare. + expect(bigI == '42').toBe(true); // While the line above is easier to write and read, we will use the // 'expect(bigI.toString()).toBe(expected)' way so that test failure // messages will be more informative. Eg, // "Expected '84' to be '42'." instead of // "Expected false to be true." - }); + }); it('is immutable', function () { bigI.add(10); diff --git a/exercises/grains/example.js b/exercises/grains/example.js index 2e91b663..50077605 100644 --- a/exercises/grains/example.js +++ b/exercises/grains/example.js @@ -15,7 +15,7 @@ function Grains() { /** * Gets the number of grains on the nth square. */ -Grains.prototype.square = function(num) { +Grains.prototype.square = function (num) { return BigInt(2).pow(num - 1).toString(); }; diff --git a/exercises/hamming/hamming.spec.js b/exercises/hamming/hamming.spec.js index 0a8ad582..db0a31ef 100644 --- a/exercises/hamming/hamming.spec.js +++ b/exercises/hamming/hamming.spec.js @@ -8,15 +8,15 @@ describe('Hamming', function () { }); xit('complete hamming distance for single nucleotide strand', function () { - expect(hamming.compute('A','G')).toEqual(1); + expect(hamming.compute('A', 'G')).toEqual(1); }); xit('complete hamming distance for small strand', function () { - expect(hamming.compute('AG','CT')).toEqual(2); + expect(hamming.compute('AG', 'CT')).toEqual(2); }); xit('small hamming distance', function () { - expect(hamming.compute('AT','CT')).toEqual(1); + expect(hamming.compute('AT', 'CT')).toEqual(1); }); xit('small hamming distance in longer strand', function () { @@ -31,10 +31,9 @@ describe('Hamming', function () { expect(hamming.compute('GGACGGATTCTG', 'AGGACGGATTCT')).toEqual(9); }); - xit('throws error when strands are not equal length', function() { - expect(function() { hamming.compute('GGACGGATTCTG', 'AGGAC'); }).toThrow( + xit('throws error when strands are not equal length', function () { + expect(function () { hamming.compute('GGACGGATTCTG', 'AGGAC'); }).toThrow( new Error('DNA strands must be of equal length.') ); }); - }); diff --git a/exercises/hello-world/example.js b/exercises/hello-world/example.js index 0cb40c8b..4bc0926b 100644 --- a/exercises/hello-world/example.js +++ b/exercises/hello-world/example.js @@ -1,8 +1,8 @@ 'use strict'; -var HelloWorld = function() {}; +var HelloWorld = function () {}; -HelloWorld.prototype.hello = function(name) { +HelloWorld.prototype.hello = function (name) { name = name || 'World'; return 'Hello, ' + name + '!'; }; diff --git a/exercises/hello-world/hello-world.js b/exercises/hello-world/hello-world.js index 4f38bdbe..000d959a 100644 --- a/exercises/hello-world/hello-world.js +++ b/exercises/hello-world/hello-world.js @@ -4,9 +4,9 @@ // Make sure to look at hello-world.spec.js--that should give you some hints about what is // expected here. -var HelloWorld = function() {}; +var HelloWorld = function () {}; -HelloWorld.prototype.hello = function() { +HelloWorld.prototype.hello = function () { // // YOUR CODE GOES HERE // diff --git a/exercises/hello-world/hello-world.spec.js b/exercises/hello-world/hello-world.spec.js index e397a6c4..2d1a8200 100644 --- a/exercises/hello-world/hello-world.spec.js +++ b/exercises/hello-world/hello-world.spec.js @@ -1,9 +1,9 @@ var HelloWorld = require('./hello-world'); -describe('Hello World', function() { +describe('Hello World', function () { var helloWorld = new HelloWorld(); - it('says hello world', function() { + it('says hello world', function () { expect(helloWorld.hello()).toEqual('Hello, World!'); }); }); diff --git a/exercises/hexadecimal/example.js b/exercises/hexadecimal/example.js index c8a49785..9e19e38c 100644 --- a/exercises/hexadecimal/example.js +++ b/exercises/hexadecimal/example.js @@ -3,15 +3,15 @@ function Hexadecimal(hex) { this.hex = hex; - this.toDecimal = function() { + this.toDecimal = function () { var hexCharacters = this.hex.split(''); for (var i = 0; i < hexCharacters.length; i++) { if (/[^0-9a-fA-F]/.exec(hexCharacters[i])) { return 0; } } - return parseInt(this.hex,16); + return parseInt(this.hex, 16); }; } -module.exports = Hexadecimal; \ No newline at end of file +module.exports = Hexadecimal; diff --git a/exercises/hexadecimal/hexadecimal.spec.js b/exercises/hexadecimal/hexadecimal.spec.js index 5b2f49f3..dabb38d6 100644 --- a/exercises/hexadecimal/hexadecimal.spec.js +++ b/exercises/hexadecimal/hexadecimal.spec.js @@ -1,55 +1,53 @@ var Hexadecimal = require('./hexadecimal'); -describe('Hexadecimal', function() { - - it('hex 1 is decimal 1', function() { +describe('Hexadecimal', function () { + it('hex 1 is decimal 1', function () { var hex = new Hexadecimal('1'); expect(hex.toDecimal()).toEqual(1); }); - xit('hex c is decimal 12', function() { + xit('hex c is decimal 12', function () { var hex = new Hexadecimal('c'); expect(hex.toDecimal()).toEqual(12); }); - xit('hex 10 is decimal 16', function() { + xit('hex 10 is decimal 16', function () { var hex = new Hexadecimal('10'); expect(hex.toDecimal()).toEqual(16); }); - xit('hex af is decimal 175', function() { + xit('hex af is decimal 175', function () { var hex = new Hexadecimal('af'); expect(hex.toDecimal()).toEqual(175); }); - xit('hex 100 is decimal 256', function() { + xit('hex 100 is decimal 256', function () { var hex = new Hexadecimal('100'); expect(hex.toDecimal()).toEqual(256); }); - xit('hex 19ace is decimal 105166', function() { + xit('hex 19ace is decimal 105166', function () { var hex = new Hexadecimal('19ace'); expect(hex.toDecimal()).toEqual(105166); }); - xit('invalid hex is decimal 0', function() { + xit('invalid hex is decimal 0', function () { var hex = new Hexadecimal('carrot'); expect(hex.toDecimal()).toEqual(0); }); - xit('black', function() { + xit('black', function () { var hex = new Hexadecimal('000000'); expect(hex.toDecimal()).toEqual(0); }); - xit('white', function() { + xit('white', function () { var hex = new Hexadecimal('ffffff'); expect(hex.toDecimal()).toEqual(16777215); }); - xit('yellow', function() { + xit('yellow', function () { var hex = new Hexadecimal('ffff00'); expect(hex.toDecimal()).toEqual(16776960); }); - -}); \ No newline at end of file +}); diff --git a/exercises/isogram/example.js b/exercises/isogram/example.js index 531a9248..1c2f911e 100644 --- a/exercises/isogram/example.js +++ b/exercises/isogram/example.js @@ -7,5 +7,5 @@ module.exports = function (word) { }); return unique.length === this.word.length; - } -} + }; +}; diff --git a/exercises/isogram/isogram.spec.js b/exercises/isogram/isogram.spec.js index f5f28b73..f4851551 100644 --- a/exercises/isogram/isogram.spec.js +++ b/exercises/isogram/isogram.spec.js @@ -60,11 +60,10 @@ describe('Isogram Test Suite', function () { expect(word.isIsogram()).toEqual(false); }); - + xit('Àcrobàt', function () { var word = new Isogram('Àcrobàt'); expect(word.isIsogram()).toEqual(false); }); - }); diff --git a/exercises/kindergarten-garden/example.js b/exercises/kindergarten-garden/example.js index 1194e1b5..725585b1 100644 --- a/exercises/kindergarten-garden/example.js +++ b/exercises/kindergarten-garden/example.js @@ -24,11 +24,11 @@ var plants = { function getPlants(pots, index) { var plants = []; - var position = 2*index; + var position = 2 * index; plants.push(pots[0][position]); - plants.push(pots[0][position+1]); + plants.push(pots[0][position + 1]); plants.push(pots[1][position]); - plants.push(pots[1][position+1]); + plants.push(pots[1][position + 1]); return plants; } @@ -44,7 +44,7 @@ function Garden(diagram, students) { var instance = {}; students = students || defaultChildren; students.sort(); - + students.forEach(function (student, index) { instance[student.toLowerCase()] = getPlants(parse(diagram), index); }); diff --git a/exercises/kindergarten-garden/kindergarten-garden.spec.js b/exercises/kindergarten-garden/kindergarten-garden.spec.js index dcc9c7cf..4e978ae6 100644 --- a/exercises/kindergarten-garden/kindergarten-garden.spec.js +++ b/exercises/kindergarten-garden/kindergarten-garden.spec.js @@ -1,7 +1,6 @@ var Garden = require('./kindergarten-garden'); describe('Garden', function () { - it('for Alice', function () { expect(new Garden('RC\nGG').alice) .toEqual(['radishes', 'clover', 'grass', 'grass']); @@ -22,7 +21,6 @@ describe('Garden', function () { expect(garden.bob).toEqual(['clover', 'clover', 'clover', 'clover']); expect(garden.charlie).toEqual(['grass', 'grass', 'grass', 'grass']); }); - }); describe('Full garden', function () { @@ -88,7 +86,6 @@ describe('Full garden', function () { expect(garden.larry) .toEqual(['grass', 'violets', 'clover', 'violets']); }); - }); describe('Disordered class', function () { @@ -115,7 +112,6 @@ describe('Disordered class', function () { expect(garden.xander) .toEqual(['radishes', 'grass', 'clover', 'violets']); }); - }); describe('Two gardens, different students', function () { @@ -133,5 +129,4 @@ describe('Two gardens, different students', function () { expect(garden2.charlie) .toEqual(['radishes', 'radishes', 'grass', 'clover']); }); - }); diff --git a/exercises/largest-series-product/example.js b/exercises/largest-series-product/example.js index 1fb9a41f..2e074103 100644 --- a/exercises/largest-series-product/example.js +++ b/exercises/largest-series-product/example.js @@ -1,7 +1,7 @@ 'use strict'; function Series(numberString) { - if(numberString.match('[^0-9]')) throw new Error('Invalid input.'); + if (numberString.match('[^0-9]')) throw new Error('Invalid input.'); this.numberString = numberString; this.digits = this.getDigits(); } @@ -16,8 +16,8 @@ Series.prototype.largestProduct = function (size) { if (size < 0) throw new Error('Invalid input.'); var product, max = 0; this.slices(size).forEach(function (slice) { - product = slice.reduce(function(a, b) { - return a*b; + product = slice.reduce(function (a, b) { + return a * b; }, 1); if (product > max) { max = product; } }); @@ -34,7 +34,7 @@ Series.prototype.slices = function (sliceSize) { for (var i = 0; i < this.digits.length - sliceSize + 1; i++) { for (var j = 0; j < sliceSize; j++) { - slice.push(this.digits[i+j]); + slice.push(this.digits[i + j]); } result.push(slice); slice = []; diff --git a/exercises/largest-series-product/largest-series-product.spec.js b/exercises/largest-series-product/largest-series-product.spec.js index 8c7e181c..130fa5c9 100644 --- a/exercises/largest-series-product/largest-series-product.spec.js +++ b/exercises/largest-series-product/largest-series-product.spec.js @@ -1,7 +1,6 @@ var Series = require('./largest-series-product'); describe('Series', function () { - it('can get the largest product of 2', function () { expect(new Series('0123456789').largestProduct(2)).toBe(72); }); @@ -37,13 +36,13 @@ describe('Series', function () { xit('rejects invalid character in input', ()=> { expect(function () { - new Series('1234a5').largestProduct('2') + new Series('1234a5').largestProduct('2'); }).toThrow(new Error('Invalid input.')); }); xit('rejects negative span', function () { expect(() => { - new Series('12345').largestProduct(-1) + new Series('12345').largestProduct(-1); }).toThrow(new Error('Invalid input.')); }); @@ -66,5 +65,4 @@ describe('Series', function () { new Series('').largestProduct(1); }).toThrow(new Error('Slice size is too big.')); }); - }); diff --git a/exercises/leap/example.js b/exercises/leap/example.js index ad2eba7f..bbe7eceb 100644 --- a/exercises/leap/example.js +++ b/exercises/leap/example.js @@ -18,7 +18,7 @@ function Year(year) { */ Year.prototype.isLeap = function () { return (this.year % 400 == 0) || ((this.year % 4 == 0) && (this.year % 100 != 0)); -} +}; module.exports = Year; diff --git a/exercises/leap/leap.js b/exercises/leap/leap.js index e3795c57..22b6bb5c 100644 --- a/exercises/leap/leap.js +++ b/exercises/leap/leap.js @@ -3,13 +3,13 @@ // convenience to get you started writing code faster. // -var Year = function(input) { +var Year = function (input) { // // YOUR CODE GOES HERE // }; -Year.prototype.isLeap = function() { +Year.prototype.isLeap = function () { // // YOUR CODE GOES HERE // diff --git a/exercises/leap/leap.spec.js b/exercises/leap/leap.spec.js index 604d1f61..852801a4 100644 --- a/exercises/leap/leap.spec.js +++ b/exercises/leap/leap.spec.js @@ -1,30 +1,28 @@ var Year = require('./leap'); -describe('Leap year', function() { - - it('is not very common', function() { +describe('Leap year', function () { + it('is not very common', function () { var year = new Year(2015); expect(year.isLeap()).toBe(false); }); - xit('is introduced every 4 years to adjust about a day', function() { + xit('is introduced every 4 years to adjust about a day', function () { var year = new Year(2016); expect(year.isLeap()).toBe(true); }); - xit('is skipped every 100 years to remove an extra day', function() { + xit('is skipped every 100 years to remove an extra day', function () { var year = new Year(1900); expect(year.isLeap()).toBe(false); }); - xit('is reintroduced every 400 years to adjust another day', function() { + xit('is reintroduced every 400 years to adjust another day', function () { var year = new Year(2000); expect(year.isLeap()).toBe(true); }); // Feel free to enable the following tests to check some more examples xdescribe('Additional example of a leap year that', function () { - it('is not a leap year', function () { var year = new Year(1978); expect(year.isLeap()).toBe(false); @@ -44,7 +42,5 @@ describe('Leap year', function() { var year = new Year(2400); expect(year.isLeap()).toBe(true); }); - }); - }); diff --git a/exercises/linked-list/example.js b/exercises/linked-list/example.js index 627df0c7..7c288bfa 100644 --- a/exercises/linked-list/example.js +++ b/exercises/linked-list/example.js @@ -27,7 +27,7 @@ LinkedList.prototype.unshift = function LinkedList_unshift(value) { }; LinkedList.prototype.pop = function LinkedList_pop() { - if (this._front === null) {return undefined;}; + if (this._front === null) {return undefined;} this._front = this._front.prev; return this.shift(); }; @@ -46,18 +46,17 @@ LinkedList.prototype.shift = function LinkedList_shift() { return value; }; -LinkedList.prototype.count = function() { +LinkedList.prototype.count = function () { if (this._front === null) { return 0; } else if (this._front.next === this._front) { return 1; - } else { - this._front.next = this._front.next.next; - return this.count() + 1; } + this._front.next = this._front.next.next; + return this.count() + 1; }; -LinkedList.prototype.delete = function(match) { +LinkedList.prototype.delete = function (match) { if (this._front.next === this._front && this._front.value === match) { this._front = null; } else if (this._front.next.value === match) { diff --git a/exercises/linked-list/linked-list.spec.js b/exercises/linked-list/linked-list.spec.js index a7322c73..2ce5d68d 100644 --- a/exercises/linked-list/linked-list.spec.js +++ b/exercises/linked-list/linked-list.spec.js @@ -60,7 +60,7 @@ describe('LinkedList', function () { expect(list.pop()).toBe(30); expect(list.shift()).toBe(10); }); - xit('deletes the only element', function() { + xit('deletes the only element', function () { var list = new LinkedList(); list.push(10); list.delete(10); diff --git a/exercises/list-ops/example.js b/exercises/list-ops/example.js index a1d2788a..c32141e7 100644 --- a/exercises/list-ops/example.js +++ b/exercises/list-ops/example.js @@ -21,7 +21,7 @@ List.prototype = { cons: function (item, arr) { var x = new List([item]); - var xs = new List(arr) + var xs = new List(arr); return x.append(xs).values; }, @@ -59,7 +59,7 @@ List.prototype = { map: function (func, arr) { var applyFuncThenCons = function (x, acc) { return this.cons(func(x), acc); - } + }; return new List(this.foldr(applyFuncThenCons.bind(this), [])); }, @@ -71,6 +71,6 @@ List.prototype = { return new List(this.foldr(consIfPred.bind(this), [])); } -} +}; module.exports = List; diff --git a/exercises/list-ops/list-ops.spec.js b/exercises/list-ops/list-ops.spec.js index 19ce09a2..7da15220 100644 --- a/exercises/list-ops/list-ops.spec.js +++ b/exercises/list-ops/list-ops.spec.js @@ -4,7 +4,7 @@ describe('List', function () { // predicates to filter by & functions to map var isOdd = function (x) { return x % 2 === 1; - } + }; var plusOne = function (x) { return x + 1; diff --git a/exercises/luhn/luhn.spec.js b/exercises/luhn/luhn.spec.js index e6e4b8ef..058cd00a 100644 --- a/exercises/luhn/luhn.spec.js +++ b/exercises/luhn/luhn.spec.js @@ -1,7 +1,6 @@ var Luhn = require('./luhn'); -describe('Luhn',function() { - +describe('Luhn', function () { it('single digit strings can not be valid', function () { const luhn = new Luhn('1'); expect(luhn.valid).toEqual(false); @@ -31,5 +30,4 @@ describe('Luhn',function() { const luhn = new Luhn('046a 454 286'); expect(luhn.valid).toEqual(false); }); - }); diff --git a/exercises/matrix/example.js b/exercises/matrix/example.js index bfeb6996..544bb026 100644 --- a/exercises/matrix/example.js +++ b/exercises/matrix/example.js @@ -24,4 +24,4 @@ function Matrix(description) { this.columns = columnsFromRows(this.rows); } -module.exports = Matrix; \ No newline at end of file +module.exports = Matrix; diff --git a/exercises/matrix/matrix.spec.js b/exercises/matrix/matrix.spec.js index 4c17bdf2..815f870c 100644 --- a/exercises/matrix/matrix.spec.js +++ b/exercises/matrix/matrix.spec.js @@ -1,7 +1,6 @@ var Matrix = require('./matrix'); describe('Matrix', function () { - it('can extract a row', function () { expect(new Matrix('1 2\n10 20').rows[0]).toEqual([1, 2]); }); @@ -14,5 +13,4 @@ describe('Matrix', function () { expect(new Matrix('89 1903 3\n18 3 1\n9 4 800').columns[1]) .toEqual([1903, 3, 4]); }); - -}); \ No newline at end of file +}); diff --git a/exercises/meetup/example.js b/exercises/meetup/example.js index 9e76cf3a..74e77826 100644 --- a/exercises/meetup/example.js +++ b/exercises/meetup/example.js @@ -3,24 +3,22 @@ function MeetupDayException(message) { this.name = 'MeetupDayException'; } -function meetupDay (year, month, day_of_week, which) { +function meetupDay(year, month, day_of_week, which) { 'use strict'; var candidates = _getCandidates(year, month, day_of_week), - d, - i, - res; + d, + i, + res; which = which.toLowerCase(); if (which === 'teenth') { res = _find(candidates, function (d) { - return 13 <= d.getDate() && d.getDate() <= 19; + return d.getDate() >= 13 && d.getDate() <= 19; }); - } - else if (which === 'last') { + } else if (which === 'last') { res = candidates.pop(); - } - else { + } else { which = parseInt(which) - 1; res = candidates.slice(which, which + 1).pop(); } @@ -30,11 +28,11 @@ function meetupDay (year, month, day_of_week, which) { return res; } -function _getCandidates (year, month, day_of_week) { +function _getCandidates(year, month, day_of_week) { var d, - i, - numDaysInMonth = new Date(year, month + 1, 0).getDate(), - res = []; + i, + numDaysInMonth = new Date(year, month + 1, 0).getDate(), + res = []; for (i = 0; i < numDaysInMonth; i++) { d = new Date(year, month, i + 1); @@ -47,7 +45,7 @@ function _getCandidates (year, month, day_of_week) { return res; } -function _getDayIndex (day) { +function _getDayIndex(day) { var daysInd = { 'sunday': 0, 'monday': 1, @@ -69,4 +67,4 @@ function _find(ary, callback) { } } -module.exports = meetupDay; \ No newline at end of file +module.exports = meetupDay; diff --git a/exercises/meetup/meetup.spec.js b/exercises/meetup/meetup.spec.js index f4ad9ee6..054707f4 100644 --- a/exercises/meetup/meetup.spec.js +++ b/exercises/meetup/meetup.spec.js @@ -2,60 +2,60 @@ var meetupDay = require('./meetup'); function MeetupDayException(message) { - this.message = message; - this.name = 'MeetupDayException'; + this.message = message; + this.name = 'MeetupDayException'; } -describe('meetupDay()', function() { - it('monteenth of may 2013', function() { +describe('meetupDay()', function () { + it('monteenth of may 2013', function () { expect(meetupDay(2013, 4, 'Monday', 'teenth')).toEqual(new Date(2013, 4, 13)); }); - xit('saturteenth of february 2013', function() { + xit('saturteenth of february 2013', function () { expect(meetupDay(2013, 1, 'Saturday', 'teenth')).toEqual(new Date(2013, 1, 16)); }); - xit('first tuesday of may 2013', function() { + xit('first tuesday of may 2013', function () { expect(meetupDay(2013, 4, 'Tuesday', '1st')).toEqual(new Date(2013, 4, 7)); }); - xit('second monday of april 2013', function() { + xit('second monday of april 2013', function () { expect(meetupDay(2013, 3, 'Monday', '2nd')).toEqual(new Date(2013, 3, 8)); }); - xit('third thursday of september 2013', function() { + xit('third thursday of september 2013', function () { expect(meetupDay(2013, 8, 'Thursday', '3rd')).toEqual(new Date(2013, 8, 19)); }); - xit('fourth sunday of march 2013', function() { + xit('fourth sunday of march 2013', function () { expect(meetupDay(2013, 2, 'Sunday', '4th')).toEqual(new Date(2013, 2, 24)); }); - xit('last thursday of october 2013', function() { + xit('last thursday of october 2013', function () { expect(meetupDay(2013, 9, 'Thursday', 'last')).toEqual(new Date(2013, 9, 31)); }); - xit('last wednesday of february 2012', function() { + xit('last wednesday of february 2012', function () { expect(meetupDay(2012, 1, 'Wednesday', 'last')).toEqual(new Date(2012, 1, 29)); }); - xit('last wednesday of december 2014', function() { + xit('last wednesday of december 2014', function () { expect(meetupDay(2014, 11, 'Wednesday', 'last')).toEqual(new Date(2014, 11, 31)); }); - xit('last sunday of only four week february 2015', function() { + xit('last sunday of only four week february 2015', function () { expect(meetupDay(2015, 1, 'Sunday', 'last')).toEqual(new Date(2015, 1, 22)); }); - xit('first friday of december 2012', function() { + xit('first friday of december 2012', function () { expect(meetupDay(2012, 11, 'Friday', '1st')).toEqual(new Date(2012, 11, 7)); }); - xit('fifth monday of march 2015', function() { + xit('fifth monday of march 2015', function () { expect(meetupDay(2015, 2, 'Monday', '5th')).toEqual(new Date(2015, 2, 30)); }); - xit('nonexistent fifth monday of february 2015', function() { + xit('nonexistent fifth monday of february 2015', function () { expect(function () { meetupDay(2015, 1, 'Monday', '5th'); }).toThrow(); }); }); diff --git a/exercises/minesweeper/example.js b/exercises/minesweeper/example.js index 7bb5dbd0..b5d76036 100644 --- a/exercises/minesweeper/example.js +++ b/exercises/minesweeper/example.js @@ -1,47 +1,47 @@ -var Minesweeper = function() { +var Minesweeper = function () { this.distanceXdistanceYs = [ - [-1,-1], - [-1,0], - [-1,1], + [-1, -1], + [-1, 0], + [-1, 1], - [1,1], - [1,0], - [1,-1], + [1, 1], + [1, 0], + [1, -1], - [0,1], - [0,-1] + [0, 1], + [0, -1] - ] + ]; }; -Minesweeper.prototype.annotate = function(rows) { +Minesweeper.prototype.annotate = function (rows) { if (rows.length === 0 || rows[0].length === 0) { return rows; } - var board = rows.map(function(row) { return row.split(""); }); + var board = rows.map(function (row) { return row.split(''); }); var outBoard = []; for (var x = 0; x < board.length; x++) { outBoard[x] = []; for (var y = 0; y < board[x].length; y++) { var spot = board[x][y]; - if (spot === "*") { + if (spot === '*') { outBoard[x][y] = spot; continue; } - var bombCount = this.distanceXdistanceYs.map(function(dxdy) { + var bombCount = this.distanceXdistanceYs.map(function (dxdy) { if (board[x + dxdy[0]] === undefined) { return 0; } - return board[x + dxdy[0]][y + dxdy[1]] === "*" ? 1 : 0; - }).reduce(function(total, num) { + return board[x + dxdy[0]][y + dxdy[1]] === '*' ? 1 : 0; + }).reduce(function (total, num) { return total + num; }); - outBoard[x][y] = bombCount > 0 ? bombCount : " "; + outBoard[x][y] = bombCount > 0 ? bombCount : ' '; } } - return outBoard.map(function(row) { - return row.join(""); + return outBoard.map(function (row) { + return row.join(''); }); }; diff --git a/exercises/minesweeper/minesweeper.spec.js b/exercises/minesweeper/minesweeper.spec.js index 75ffe741..836ccae1 100644 --- a/exercises/minesweeper/minesweeper.spec.js +++ b/exercises/minesweeper/minesweeper.spec.js @@ -1,182 +1,180 @@ var Minesweeper = require('./minesweeper'); -describe('Minesweeper()', function() { - - it('handles no rows', function() { +describe('Minesweeper()', function () { + it('handles no rows', function () { var minesweeper = new Minesweeper(); expect(minesweeper.annotate([])).toEqual([]); }); - xit('handles no columns', function() { + xit('handles no columns', function () { var minesweeper = new Minesweeper(); - expect(minesweeper.annotate([""])).toEqual([""]); + expect(minesweeper.annotate([''])).toEqual(['']); }); - xit('handles no mines', function() { + xit('handles no mines', function () { var minesweeper = new Minesweeper(); var input = [ - " ", - " ", - " " + ' ', + ' ', + ' ' ]; var expected = [ - " ", - " ", - " " - ]; + ' ', + ' ', + ' ' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles board with only mines', function() { + xit('handles board with only mines', function () { var minesweeper = new Minesweeper(); var input = [ - "***", - "***", - "***" + '***', + '***', + '***' ]; var expected = [ - "***", - "***", - "***" + '***', + '***', + '***' ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles mine surrounded by spaces', function() { + xit('handles mine surrounded by spaces', function () { var minesweeper = new Minesweeper(); var input = [ - " ", - " * ", - " " + ' ', + ' * ', + ' ' ]; var expected = [ - "111", - "1*1", - "111" - ]; + '111', + '1*1', + '111' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles space surrounded by mines', function() { + xit('handles space surrounded by mines', function () { var minesweeper = new Minesweeper(); var input = [ - "***", - "* *", - "***" - ]; + '***', + '* *', + '***' + ]; var expected = [ - "***", - "*8*", - "***" - ]; + '***', + '*8*', + '***' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles space surrounded by mines', function() { + xit('handles space surrounded by mines', function () { var minesweeper = new Minesweeper(); var input = [ - "***", - "* *", - "***" - ]; + '***', + '* *', + '***' + ]; var expected = [ - "***", - "*8*", - "***" - ]; + '***', + '*8*', + '***' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles horizontal line', function() { + xit('handles horizontal line', function () { var minesweeper = new Minesweeper(); - var input = [" * * "]; - var expected = ["1*2*1"]; + var input = [' * * ']; + var expected = ['1*2*1']; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles horizontal line, mines at edges',function() { + xit('handles horizontal line, mines at edges', function () { var minesweeper = new Minesweeper(); - var input = ["* *"]; - var expected = ["*1 1*"]; + var input = ['* *']; + var expected = ['*1 1*']; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles vertical line', function() { + xit('handles vertical line', function () { var minesweeper = new Minesweeper(); var input = [ - " ", - "*", - " ", - "*", - " " - ]; + ' ', + '*', + ' ', + '*', + ' ' + ]; var expected = [ - "1", - "*", - "2", - "*", - "1" - ]; + '1', + '*', + '2', + '*', + '1' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles vertical line, mines at edges', function() { + xit('handles vertical line, mines at edges', function () { var minesweeper = new Minesweeper(); var input = [ - "*", - " ", - " ", - " ", - "*" - ]; + '*', + ' ', + ' ', + ' ', + '*' + ]; var expected = [ - "*", - "1", - " ", - "1", - "*" - ]; + '*', + '1', + ' ', + '1', + '*' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles cross', function() { + xit('handles cross', function () { var minesweeper = new Minesweeper(); var input = [ - " * ", - " * ", - "*****", - " * ", - " * " + ' * ', + ' * ', + '*****', + ' * ', + ' * ' ]; var expected = [ - " 2*2 ", - "25*52", - "*****", - "25*52", - " 2*2 " - ]; + ' 2*2 ', + '25*52', + '*****', + '25*52', + ' 2*2 ' + ]; expect(minesweeper.annotate(input)).toEqual(expected); }); - xit('handles large board', function() { + xit('handles large board', function () { var minesweeper = new Minesweeper(); var input = [ - " * * ", - " * ", - " * ", - " * *", - " * * ", - " " + ' * * ', + ' * ', + ' * ', + ' * *', + ' * * ', + ' ' ]; var expected = [ - "1*22*1", - "12*322", - " 123*2", - "112*4*", - "1*22*2", - "111111" - ]; + '1*22*1', + '12*322', + ' 123*2', + '112*4*', + '1*22*2', + '111111' + ]; expect(minesweeper.annotate(input)).toEqual(expected); - }); - + }); }); diff --git a/exercises/nth-prime/example.js b/exercises/nth-prime/example.js index eff9a61b..f0d824dc 100644 --- a/exercises/nth-prime/example.js +++ b/exercises/nth-prime/example.js @@ -1,12 +1,12 @@ 'use strict'; module.exports = { - nth: function(nthPrime) { + nth: function (nthPrime) { if (nthPrime === 0) { throw new Error('Prime is not possible'); } this.generatePrimes(200000); return this.realPrimes[nthPrime - 1]; }, - generatePrimes: function(uptoNumber) { + generatePrimes: function (uptoNumber) { var i, j, currentPrime, primeCount, possiblePrimes = []; if (this.realPrimes) { return this.realPrimes; } diff --git a/exercises/nth-prime/nth-prime.spec.js b/exercises/nth-prime/nth-prime.spec.js index 840d5b85..727ce507 100644 --- a/exercises/nth-prime/nth-prime.spec.js +++ b/exercises/nth-prime/nth-prime.spec.js @@ -1,27 +1,25 @@ -var prime = require ('./nth-prime'); +var prime = require('./nth-prime'); -describe('Prime',function() { - - it('first',function(){ +describe('Prime', function () { + it('first', function () { expect(prime.nth(1)).toEqual(2); }); - xit('second',function(){ + xit('second', function () { expect(prime.nth(2)).toEqual(3); }); - xit('sixth',function(){ + xit('sixth', function () { expect(prime.nth(6)).toEqual(13); }); - xit('big prime',function(){ + xit('big prime', function () { expect(prime.nth(10001)).toEqual(104743); }); - xit('weird case',function() { + xit('weird case', function () { expect( function () { prime.nth(0); }).toThrow(new Error('Prime is not possible')); }); - }); diff --git a/exercises/nucleotide-count/nucleotide-count.spec.js b/exercises/nucleotide-count/nucleotide-count.spec.js index 961d2bda..12283d17 100644 --- a/exercises/nucleotide-count/nucleotide-count.spec.js +++ b/exercises/nucleotide-count/nucleotide-count.spec.js @@ -1,44 +1,42 @@ var dna = require('./nucleotide-count'); -describe('DNA', function() { - - it('Empty DNA strand has no adenosine', function() { +describe('DNA', function () { + it('Empty DNA strand has no adenosine', function () { expect(dna().count('A')).toEqual(0); }); - xit('Repetitive cytidine gets counted', function() { + xit('Repetitive cytidine gets counted', function () { expect(dna('CCCCC').count('C')).toEqual(5); }); - xit('Counts only thymidine', function() { + xit('Counts only thymidine', function () { expect(dna('GGGGGTAACCCGG').count('T')).toEqual(1); }); - xit('Counts a nucleotide only once', function() { + xit('Counts a nucleotide only once', function () { var acid = dna('CGATTGGG'); acid.count('T'); acid.count('T'); expect(acid.count('T')).toEqual(2); }); - xit('Empty DNS strand has no nucleotides', function() { + xit('Empty DNS strand has no nucleotides', function () { var expected = {A: 0, T: 0, C: 0, G: 0}; expect(dna().histogram()).toEqual(expected); }); - xit('Repetitive sequence has only guanosine', function() { + xit('Repetitive sequence has only guanosine', function () { var expected = {A: 0, T: 0, C: 0, G: 8}; expect(dna('GGGGGGGG').histogram()).toEqual(expected); }); - xit('Counts all nucleotides', function() { + xit('Counts all nucleotides', function () { var strand = 'AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC'; var expected = {A: 20, T: 21, C: 12, G: 17}; expect(dna(strand).histogram()).toEqual(expected); }); - xit('Validates DNA', function() { + xit('Validates DNA', function () { expect(dna.bind(null, 'JOHNNYAPPLESEED')).toThrow(); }); - }); diff --git a/exercises/ocr-numbers/example.js b/exercises/ocr-numbers/example.js index 2058207d..3da59585 100644 --- a/exercises/ocr-numbers/example.js +++ b/exercises/ocr-numbers/example.js @@ -2,45 +2,45 @@ var PATTERNS = { 0: [' _ ', - '| |', - '|_|', - ' '], + '| |', + '|_|', + ' '], 1: [' ', - ' |', - ' |', - ' '], + ' |', + ' |', + ' '], 2: [' _ ', - ' _|', - '|_ ', - ' '], + ' _|', + '|_ ', + ' '], 3: [' _ ', - ' _|', - ' _|', - ' '], + ' _|', + ' _|', + ' '], 4: [' ', - '|_|', - ' |', - ' '], + '|_|', + ' |', + ' '], 5: [' _ ', - '|_ ', - ' _|', - ' '], + '|_ ', + ' _|', + ' '], 6: [' _ ', - '|_ ', - '|_|', - ' '], + '|_ ', + '|_|', + ' '], 7: [' _ ', - ' |', - ' |', - ' '], + ' |', + ' |', + ' '], 8: [' _ ', - '|_|', - '|_|', - ' '], + '|_|', + '|_|', + ' '], 9: [' _ ', - '|_|', - ' _|', - ' '] + '|_|', + ' _|', + ' '] }; function getDigit(text) { @@ -88,4 +88,4 @@ function valuesInRow(row) { exports.convert = function (text) { var rows = splitIntoRows(text); return rows.map(valuesInRow).join(','); -}; \ No newline at end of file +}; diff --git a/exercises/ocr-numbers/ocr-numbers.spec.js b/exercises/ocr-numbers/ocr-numbers.spec.js index 2acc9458..a59ec428 100644 --- a/exercises/ocr-numbers/ocr-numbers.spec.js +++ b/exercises/ocr-numbers/ocr-numbers.spec.js @@ -1,7 +1,6 @@ var ocr = require('./ocr-numbers'); describe('ocr', function () { - it('recognizes zero', function () { expect(ocr.convert( ' _ \n' + @@ -153,5 +152,4 @@ describe('ocr', function () { ' ' )).toBe('123,456,789'); }); - }); diff --git a/exercises/octal/example.js b/exercises/octal/example.js index 6aec6caa..1b66b739 100644 --- a/exercises/octal/example.js +++ b/exercises/octal/example.js @@ -6,17 +6,17 @@ function Octal(octal) { this.digits = octal.split('').reverse().map(this.digitValue); } -Octal.prototype.toDecimal = function() { +Octal.prototype.toDecimal = function () { var decimal = this.digits.reduce(this.accumulator, 0); return isNaN(decimal) ? 0 : decimal; }; -Octal.prototype.digitValue = function(value) { +Octal.prototype.digitValue = function (value) { var result = Number(value); - return (result < BASE)? result : Number.NaN; + return (result < BASE) ? result : Number.NaN; }; -Octal.prototype.accumulator = function(decimal, digit, index) { +Octal.prototype.accumulator = function (decimal, digit, index) { return decimal += digit * Math.pow(BASE, index); }; diff --git a/exercises/octal/octal.spec.js b/exercises/octal/octal.spec.js index d29f7011..b3ee50e9 100644 --- a/exercises/octal/octal.spec.js +++ b/exercises/octal/octal.spec.js @@ -1,45 +1,43 @@ var Octal = require('./octal'); -describe('octal', function() { - - it('1 is decimal 1', function() { +describe('octal', function () { + it('1 is decimal 1', function () { expect(new Octal('1').toDecimal()).toEqual(1); }); - xit('10 is decimal 8', function() { + xit('10 is decimal 8', function () { expect(new Octal('10').toDecimal()).toEqual(8); }); - xit('17 is decimal 15', function() { + xit('17 is decimal 15', function () { expect(new Octal('17').toDecimal()).toEqual(15); }); - xit('11 is decimal 9', function() { + xit('11 is decimal 9', function () { expect(new Octal('11').toDecimal()).toEqual(9); }); - xit('130 is decimal 88', function() { + xit('130 is decimal 88', function () { expect(new Octal('130').toDecimal()).toEqual(88); }); - xit('2047 is decimal 1063', function() { + xit('2047 is decimal 1063', function () { expect(new Octal('2047').toDecimal()).toEqual(1063); }); - xit('7777 is decimal 4095', function() { + xit('7777 is decimal 4095', function () { expect(new Octal('7777').toDecimal()).toEqual(4095); }); - xit('1234567 is decimal 342391', function() { + xit('1234567 is decimal 342391', function () { expect(new Octal('1234567').toDecimal()).toEqual(342391); }); - xit('invalid is decimal 0', function() { + xit('invalid is decimal 0', function () { expect(new Octal('carrot').toDecimal()).toEqual(0); }); - xit('considers the digit 8 as invalid', function() { + xit('considers the digit 8 as invalid', function () { expect(new Octal('12345678').toDecimal()).toEqual(0); }); - }); diff --git a/exercises/palindrome-products/example.js b/exercises/palindrome-products/example.js index b9fbf4f1..5928bdb2 100644 --- a/exercises/palindrome-products/example.js +++ b/exercises/palindrome-products/example.js @@ -4,7 +4,7 @@ module.exports = function Palindromes(options) { this.maxFactor = options.maxFactor; this.minFactor = options.minFactor || 1; - this.generate = function() { + this.generate = function () { var minFactor = this.minFactor; var maxFactor = this.maxFactor; @@ -13,18 +13,17 @@ module.exports = function Palindromes(options) { for (var i = minFactor; i <= maxFactor; i++) { for (var j = minFactor; j <= maxFactor; j++) { - var result = i * j; if ( ! this.isPalindrome(result) ) { continue; } - var newFactor = [i,j].sort(); + var newFactor = [i, j].sort(); if (palindromes[result] === undefined) { palindromes[result] = []; palindromeIndexes.push(result); } - if ( ! arrayContainsArray(palindromes[result],newFactor) ) { + if ( ! arrayContainsArray(palindromes[result], newFactor) ) { palindromes[result].push(newFactor); } } @@ -34,26 +33,26 @@ module.exports = function Palindromes(options) { this.palindromeIndexes = palindromeIndexes; }; - this.largest = function() { - var largestPalindrome = Math.max.apply(null,this.palindromeIndexes); + this.largest = function () { + var largestPalindrome = Math.max.apply(null, this.palindromeIndexes); var factors = this.palindromes[largestPalindrome]; return { value: largestPalindrome, factors: factors }; }; - this.smallest = function() { - var smallestPalindrome = Math.min.apply(null,this.palindromeIndexes); + this.smallest = function () { + var smallestPalindrome = Math.min.apply(null, this.palindromeIndexes); var factors = this.palindromes[smallestPalindrome]; return { value: smallestPalindrome, factors: factors }; }; - this.isPalindrome = function(number) { + this.isPalindrome = function (number) { var numberAsString = number.toString(); var reversedString = numberAsString.split('').reverse().join(''); return (numberAsString === reversedString); }; }; -function arrayContainsArray(array,element) { +function arrayContainsArray(array, element) { var containsArray = false; for (var i = 0; i < array.length; i++) { diff --git a/exercises/palindrome-products/palindrome-products.spec.js b/exercises/palindrome-products/palindrome-products.spec.js index 9f02104b..36936f29 100644 --- a/exercises/palindrome-products/palindrome-products.spec.js +++ b/exercises/palindrome-products/palindrome-products.spec.js @@ -1,21 +1,20 @@ 'use strict'; var Palindromes = require('./palindrome-products'); -describe('Palindrome', function() { - - it('largest palindrome from single digit factors', function() { +describe('Palindrome', function () { + it('largest palindrome from single digit factors', function () { var palindromes = new Palindromes({maxFactor: 9}); palindromes.generate(); var largest = palindromes.largest(); expect(largest.value).toEqual(9); var orderedLargestFactors = largest.factors.sort( - function(a, b) { return a[0] > b[0]; } + function (a, b) { return a[0] > b[0]; } ); expect(orderedLargestFactors).toEqual([[1, 9], [3, 3]]); }); - xit('largest palindrome from double digit factors', function() { + xit('largest palindrome from double digit factors', function () { var palindromes = new Palindromes({ maxFactor: 99, minFactor: 10 }); palindromes.generate(); @@ -24,7 +23,7 @@ describe('Palindrome', function() { expect(largest.factors).toEqual([[91, 99]]); }); - xit('smallest palindrome from double digit factors', function() { + xit('smallest palindrome from double digit factors', function () { var palindromes = new Palindromes({ maxFactor: 99, minFactor: 10 }); palindromes.generate(); @@ -33,7 +32,7 @@ describe('Palindrome', function() { expect(smallest.factors).toEqual([[11, 11]]); }); - xit('largest palindrome from triple digit factors', function() { + xit('largest palindrome from triple digit factors', function () { var palindromes = new Palindromes({ maxFactor: 999, minFactor: 100 }); palindromes.generate(); @@ -42,7 +41,7 @@ describe('Palindrome', function() { expect(largest.factors).toEqual([[913, 993]]); }); - xit('smallest palindrome from triple digit factors', function() { + xit('smallest palindrome from triple digit factors', function () { var palindromes = new Palindromes({ maxFactor: 999, minFactor: 100 }); palindromes.generate(); @@ -50,5 +49,4 @@ describe('Palindrome', function() { expect(smallest.value).toEqual(10201); expect(smallest.factors).toEqual([[101, 101]]); }); - }); diff --git a/exercises/pangram/example.js b/exercises/pangram/example.js index c61cfdb9..e6d8a7c6 100644 --- a/exercises/pangram/example.js +++ b/exercises/pangram/example.js @@ -3,7 +3,7 @@ var notAlpha = /[^a-z]+/gi, cleaned, unique; -var Pangram = function(candidate) { +var Pangram = function (candidate) { unique = {}; cleaned = (candidate.replace(notAlpha, '')).toLowerCase(); cleaned.split('').forEach(function (el) { diff --git a/exercises/pangram/pangram.spec.js b/exercises/pangram/pangram.spec.js index d7feee37..74197329 100644 --- a/exercises/pangram/pangram.spec.js +++ b/exercises/pangram/pangram.spec.js @@ -1,50 +1,48 @@ var Pangram = require('./pangram'); -describe('Pangram()', function() { - - it('empty sentence', function() { +describe('Pangram()', function () { + it('empty sentence', function () { var pangram = new Pangram(''); expect(pangram.isPangram()).toBe(false); }); - xit('pangram with only lower case', function() { - var pangram = new Pangram("the quick brown fox jumps over the lazy dog"); + xit('pangram with only lower case', function () { + var pangram = new Pangram('the quick brown fox jumps over the lazy dog'); expect(pangram.isPangram()).toBe(true); }); - xit("missing character 'x'", function() { - var pangram = new Pangram("a quick movement of the enemy will jeopardize five gunboats"); + xit("missing character 'x'", function () { + var pangram = new Pangram('a quick movement of the enemy will jeopardize five gunboats'); expect(pangram.isPangram()).toBe(false); }); - xit("another missing character 'x'", function() { - var pangram = new Pangram("the quick brown fish jumps over the lazy dog"); + xit("another missing character 'x'", function () { + var pangram = new Pangram('the quick brown fish jumps over the lazy dog'); expect(pangram.isPangram()).toBe(false); }); - xit("pangram with underscores", function() { - var pangram = new Pangram("the_quick_brown_fox_jumps_over_the_lazy_dog"); + xit('pangram with underscores', function () { + var pangram = new Pangram('the_quick_brown_fox_jumps_over_the_lazy_dog'); expect(pangram.isPangram()).toBe(true); }); - xit("pangram with numbers", function() { - var pangram = new Pangram("the 1 quick brown fox jumps over the 2 lazy dogs"); + xit('pangram with numbers', function () { + var pangram = new Pangram('the 1 quick brown fox jumps over the 2 lazy dogs'); expect(pangram.isPangram()).toBe(true); }); - xit('missing letters replaced by numbers', function() { - var pangram = new Pangram("7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog"); + xit('missing letters replaced by numbers', function () { + var pangram = new Pangram('7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog'); expect(pangram.isPangram()).toBe(false); }); - xit('pangram with mixed case and punctuation', function() { - var pangram = new Pangram("\"Five quacking Zephyrs jolt my wax bed.\""); + xit('pangram with mixed case and punctuation', function () { + var pangram = new Pangram('"Five quacking Zephyrs jolt my wax bed."'); expect(pangram.isPangram()).toBe(true); }); - xit('pangram with non-ascii characters', function() { - var pangram = new Pangram("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."); + xit('pangram with non-ascii characters', function () { + var pangram = new Pangram('Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.'); expect(pangram.isPangram()).toBe(true); }); - }); diff --git a/exercises/pascals-triangle/example.js b/exercises/pascals-triangle/example.js index 2962c0f3..7140f98b 100644 --- a/exercises/pascals-triangle/example.js +++ b/exercises/pascals-triangle/example.js @@ -1,15 +1,15 @@ 'use strict'; function sumElements(element, index, array) { - /*jshint validthis:true */ - this.push(element + (array[index+1] || 0)); + /* jshint validthis:true */ + this.push(element + (array[index + 1] || 0)); } function fillRows(rows) { var result = [[1]]; for (var x = 1; x < rows; x++) { var newRow = [1]; - result[x-1].forEach(sumElements, newRow); + result[x - 1].forEach(sumElements, newRow); result.push(newRow); } return result; @@ -20,4 +20,4 @@ function Triangle(rows) { this.lastRow = this.rows[this.rows.length - 1]; } -module.exports = Triangle; \ No newline at end of file +module.exports = Triangle; diff --git a/exercises/pascals-triangle/pascals-triangle.spec.js b/exercises/pascals-triangle/pascals-triangle.spec.js index 79c4aab2..eb4009ba 100644 --- a/exercises/pascals-triangle/pascals-triangle.spec.js +++ b/exercises/pascals-triangle/pascals-triangle.spec.js @@ -1,7 +1,6 @@ var Triangle = require('./pascals-triangle'); describe('Triangle', function () { - it('with one row', function () { expect(new Triangle(1).rows).toEqual([[1]]); }); @@ -19,7 +18,7 @@ describe('Triangle', function () { }); xit('fifth row', function () { - expect(new Triangle(5).lastRow).toEqual([1, 4, 6, 4 ,1]); + expect(new Triangle(5).lastRow).toEqual([1, 4, 6, 4, 1]); }); xit('twentieth row', function () { @@ -27,5 +26,4 @@ describe('Triangle', function () { expect(new Triangle(20).lastRow) .toEqual(twentieth); }); - }); diff --git a/exercises/perfect-numbers/example.js b/exercises/perfect-numbers/example.js index 5e98da18..c7fcdd76 100644 --- a/exercises/perfect-numbers/example.js +++ b/exercises/perfect-numbers/example.js @@ -1,6 +1,6 @@ 'use strict'; -var PerfectNumbers = function() { +var PerfectNumbers = function () { }; @@ -8,32 +8,29 @@ var PerfectNumbers = function() { * Calculate all the divisors for a given number and return them as an array. * Note: the actual number is not include in the returned array. */ -PerfectNumbers.prototype.getDivisors = function(number) { - +PerfectNumbers.prototype.getDivisors = function (number) { var i; var divs = new Array(); // Accepts only natura numbers greater than 1. if (number <= 1) { return divs; - } + } // 1 always divides everyone! divs.push(1); // Calculate the divisors up the the half of the number + 1 for (i = 2; i <= number / 2; i++) { - if (number % i === 0) { divs.push(i); - } + } } return divs; }; -PerfectNumbers.prototype.classify = function(number) { - +PerfectNumbers.prototype.classify = function (number) { var i, sum, result; // Check if the input is valid @@ -53,11 +50,9 @@ PerfectNumbers.prototype.classify = function(number) { // Check if the number is perfect. if (sum === number) { result = 'perfect'; - } - else if (sum > number) { + } else if (sum > number) { result = 'abundant'; - } - else { + } else { result = 'deficient'; } diff --git a/exercises/perfect-numbers/perfect-numbers.spec.js b/exercises/perfect-numbers/perfect-numbers.spec.js index 4a9fe9d7..8fba8f1d 100644 --- a/exercises/perfect-numbers/perfect-numbers.spec.js +++ b/exercises/perfect-numbers/perfect-numbers.spec.js @@ -1,79 +1,69 @@ var PerfectNumbers = require('./perfect-numbers'); -describe('Exercise - Perfect Numbers', function() { - +describe('Exercise - Perfect Numbers', function () { var perfectNumbers; beforeEach(function () { perfectNumbers = new PerfectNumbers(); }); - describe('Perfect Numbers', function() { - - it('Smallest perfect number is classified correctly', function() { + describe('Perfect Numbers', function () { + it('Smallest perfect number is classified correctly', function () { expect(perfectNumbers.classify(6)).toEqual('perfect'); }); - it('Medium perfect number is classified correctly', function() { + it('Medium perfect number is classified correctly', function () { expect(perfectNumbers.classify(28)).toEqual('perfect'); }); - it('Large perfect number is classified correctly', function() { + it('Large perfect number is classified correctly', function () { expect(perfectNumbers.classify(33550336)).toEqual('perfect'); }); - }); - describe('Abundant Numbers', function() { - - it('Smallest abundant number is classified correctly', function() { + describe('Abundant Numbers', function () { + it('Smallest abundant number is classified correctly', function () { expect(perfectNumbers.classify(12)).toEqual('abundant'); }); - it('Medium abundant number is classified correctly', function() { + it('Medium abundant number is classified correctly', function () { expect(perfectNumbers.classify(30)).toEqual('abundant'); }); - it('Large abundant number is classified correctly', function() { + it('Large abundant number is classified correctly', function () { expect(perfectNumbers.classify(33550335)).toEqual('abundant'); }); - }); - describe('Deficient Numbers', function() { - - it('Smallest prime deficient number is classified correctly', function() { + describe('Deficient Numbers', function () { + it('Smallest prime deficient number is classified correctly', function () { expect(perfectNumbers.classify(2)).toEqual('deficient'); }); - it('Smallest non-prime deficient number is classified correctly', function() { + it('Smallest non-prime deficient number is classified correctly', function () { expect(perfectNumbers.classify(4)).toEqual('deficient'); }); - it('Medium deficient number is classified correctly', function() { + it('Medium deficient number is classified correctly', function () { expect(perfectNumbers.classify(32)).toEqual('deficient'); }); - it('Large deficient number is classified correctly', function() { + it('Large deficient number is classified correctly', function () { expect(perfectNumbers.classify(33550337)).toEqual('deficient'); }); - it('Edge case (no factors other than itself) is classified correctly', function() { + it('Edge case (no factors other than itself) is classified correctly', function () { expect(perfectNumbers.classify(1)).toEqual('deficient'); }); - }); - describe('Invalid Inputs', function() { - - it('Zero is rejected (not a natural number)', function() { + describe('Invalid Inputs', function () { + it('Zero is rejected (not a natural number)', function () { expect(perfectNumbers.classify(0)).toEqual('Classification is only possible for natural numbers.'); }); - it('Negative integer is rejected (not a natural number)', function() { + it('Negative integer is rejected (not a natural number)', function () { expect(perfectNumbers.classify(-1)).toEqual('Classification is only possible for natural numbers.'); }); - }); - }); diff --git a/exercises/phone-number/example.js b/exercises/phone-number/example.js index 5278ad40..e9da676e 100644 --- a/exercises/phone-number/example.js +++ b/exercises/phone-number/example.js @@ -5,35 +5,34 @@ var Phone = module.exports = function Phone(number) { this.cleanedNumber = this.cleanNumber(number); }; -Phone.prototype.cleanNumber = function(number) { - var num = number.replace(/\D/g,''); +Phone.prototype.cleanNumber = function (number) { + var num = number.replace(/\D/g, ''); - if (num.length === 10 && num[0]>=2&& num[3]>=2) { + if (num.length === 10 && num[0] >= 2 && num[3] >= 2) { return num; } else if (num.length === 11 && num[0] === '1') { - return num.substr(1,num.length); - } else { - return null; + return num.substr(1, num.length); } + return null; }; -Phone.prototype.number = function() { +Phone.prototype.number = function () { return this.cleanedNumber; }; -Phone.prototype.areaCode = function() { - return this.number().substr(0,3); +Phone.prototype.areaCode = function () { + return this.number().substr(0, 3); }; -Phone.prototype.exchangeCode = function() { - return this.number().substr(3,3); +Phone.prototype.exchangeCode = function () { + return this.number().substr(3, 3); }; -Phone.prototype.subscriberNumber = function() { - return this.number().substr(6,4); +Phone.prototype.subscriberNumber = function () { + return this.number().substr(6, 4); }; -Phone.prototype.toString = function() { +Phone.prototype.toString = function () { return '(' + this.areaCode() + ') ' + this.exchangeCode() + '-' + this.subscriberNumber(); }; diff --git a/exercises/phone-number/phone-number.spec.js b/exercises/phone-number/phone-number.spec.js index 257ddf15..fa272bfc 100644 --- a/exercises/phone-number/phone-number.spec.js +++ b/exercises/phone-number/phone-number.spec.js @@ -1,63 +1,63 @@ var PhoneNumber = require('./phone-number'); -describe('PhoneNumber()', function() { - it('cleans the number', function() { +describe('PhoneNumber()', function () { + it('cleans the number', function () { var phone = new PhoneNumber('(223) 456-7890'); expect(phone.number()).toEqual('2234567890'); }); - xit('cleans numbers with dots', function() { + xit('cleans numbers with dots', function () { var phone = new PhoneNumber('223.456.7890'); expect(phone.number()).toEqual('2234567890'); }); - xit('cleans numbers with multiple spaces', function() { + xit('cleans numbers with multiple spaces', function () { var phone = new PhoneNumber('223 456 7890 '); expect(phone.number()).toEqual('2234567890'); }); - - xit('invalid when 9 digits', function() { + + xit('invalid when 9 digits', function () { var phone = new PhoneNumber('123456789'); expect(phone.number()).toEqual(null); }); - - xit('invalid when 11 digits does not start with a 1', function(){ - var phone = new PhoneNumber('22234567890'); - expect(phone.number()).toEqual(null); - }); - - xit('valid when 11 digits and starting with 1', function(){ - var phone = new PhoneNumber('12234567890'); - expect(phone.number()).toEqual('2234567890'); - }); - - xit('valid when 11 digits and starting with 1 even with punctuation', function(){ - var phone = new PhoneNumber('+1 (223) 456-7890'); - expect(phone.number()).toEqual('2234567890'); - }); - - xit('invalid when more than 11 digits', function(){ - var phone = new PhoneNumber('321234567890'); - expect(phone.number()).toEqual(null); - }); - - xit('invalid with letters', function(){ - var phone = new PhoneNumber('123-abc-7890'); - expect(phone.number()).toEqual(null); - }); - - xit('invalid with punctuations', function(){ - var phone = new PhoneNumber('123-@:!-7890'); - expect(phone.number()).toEqual(null); - }); - - xit('invalid if area code does not start with 2-9', function(){ - var phone = new PhoneNumber('(123) 456-7890'); - expect(phone.number()).toEqual(null); - }); - - xit('invalid if exchange code does not start with 2-9', function(){ - var phone = new PhoneNumber('(223) 056-7890'); - expect(phone.number()).toEqual(null); - }); + + xit('invalid when 11 digits does not start with a 1', function () { + var phone = new PhoneNumber('22234567890'); + expect(phone.number()).toEqual(null); + }); + + xit('valid when 11 digits and starting with 1', function () { + var phone = new PhoneNumber('12234567890'); + expect(phone.number()).toEqual('2234567890'); + }); + + xit('valid when 11 digits and starting with 1 even with punctuation', function () { + var phone = new PhoneNumber('+1 (223) 456-7890'); + expect(phone.number()).toEqual('2234567890'); + }); + + xit('invalid when more than 11 digits', function () { + var phone = new PhoneNumber('321234567890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid with letters', function () { + var phone = new PhoneNumber('123-abc-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid with punctuations', function () { + var phone = new PhoneNumber('123-@:!-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid if area code does not start with 2-9', function () { + var phone = new PhoneNumber('(123) 456-7890'); + expect(phone.number()).toEqual(null); + }); + + xit('invalid if exchange code does not start with 2-9', function () { + var phone = new PhoneNumber('(223) 056-7890'); + expect(phone.number()).toEqual(null); + }); }); diff --git a/exercises/pig-latin/example.js b/exercises/pig-latin/example.js index 7906cbbf..de800f58 100644 --- a/exercises/pig-latin/example.js +++ b/exercises/pig-latin/example.js @@ -20,4 +20,4 @@ module.exports = { words.forEach( translateWord ); return translated.join(' '); } -}; \ No newline at end of file +}; diff --git a/exercises/pig-latin/pig-latin.spec.js b/exercises/pig-latin/pig-latin.spec.js index da0c8391..0e619db0 100644 --- a/exercises/pig-latin/pig-latin.spec.js +++ b/exercises/pig-latin/pig-latin.spec.js @@ -1,7 +1,6 @@ var pigLatin = require('./pig-latin'); describe('pigLatin', function () { - it('translates a word beginning with a', function () { expect(pigLatin.translate('apple')).toEqual('appleay'); }); @@ -46,5 +45,4 @@ describe('pigLatin', function () { expect(pigLatin.translate('quick fast run')) .toEqual('ickquay astfay unray'); }); - }); diff --git a/exercises/point-mutations/example.js b/exercises/point-mutations/example.js index 0258f742..3b0a9af2 100644 --- a/exercises/point-mutations/example.js +++ b/exercises/point-mutations/example.js @@ -4,7 +4,7 @@ var DNA = module.exports = function DNA(nucleotides) { this.nucleotides = nucleotides; }; -DNA.prototype.hammingDistance = function(comparison) { +DNA.prototype.hammingDistance = function (comparison) { var distance = 0; var calculationDistance = Math.min(this.nucleotides.length, comparison.length); diff --git a/exercises/point-mutations/point-mutations.spec.js b/exercises/point-mutations/point-mutations.spec.js index b92ed05a..90ee18f4 100644 --- a/exercises/point-mutations/point-mutations.spec.js +++ b/exercises/point-mutations/point-mutations.spec.js @@ -1,45 +1,43 @@ var DNA = require('./point-mutations'); -describe('DNA', function() { - - it('no difference between empty strands', function() { +describe('DNA', function () { + it('no difference between empty strands', function () { var dna = new DNA(''); expect(dna.hammingDistance('')).toEqual(0); }); - xit('no difference between identical strands', function() { + xit('no difference between identical strands', function () { var dna = new DNA('GGACTGA'); expect(dna.hammingDistance('GGACTGA')).toEqual(0); }); - xit('complete hamming distance in small strand', function() { + xit('complete hamming distance in small strand', function () { var dna = new DNA('ACT'); expect(dna.hammingDistance('GGA')).toEqual(3); }); - xit('hamming distance in off by one strand', function() { + xit('hamming distance in off by one strand', function () { var dna = new DNA('GGACGGATTCTGACCTGGACTAATTTTGGGG'); expect(dna.hammingDistance('AGGACGGATTCTGACCTGGACTAATTTTGGGG')).toEqual(19); }); - xit('small hamming distance in middle somewhere', function() { + xit('small hamming distance in middle somewhere', function () { var dna = new DNA('GGACG'); expect(dna.hammingDistance('GGTCG')).toEqual(1); }); - xit('larger distance', function() { + xit('larger distance', function () { var dna = new DNA('ACCAGGG'); expect(dna.hammingDistance('ACTATGG')).toEqual(2); }); - xit('shortens other strand when longer', function() { + xit('shortens other strand when longer', function () { var dna = new DNA('AAACTAGGGG'); expect(dna.hammingDistance('AGGCTAGCGGTAGGAC')).toEqual(3); }); - xit('shortens original strand when longer', function() { + xit('shortens original strand when longer', function () { var dna = new DNA('GACTACGGACAGGGTAGGGAAT'); expect(dna.hammingDistance('GACATCGCACACC')).toEqual(5); }); - }); diff --git a/exercises/prime-factors/example.js b/exercises/prime-factors/example.js index 44622035..0b6d316a 100644 --- a/exercises/prime-factors/example.js +++ b/exercises/prime-factors/example.js @@ -12,4 +12,4 @@ exports.for = function (n) { } if (n > 1) { prime_factors.push(n); } return prime_factors; -}; \ No newline at end of file +}; diff --git a/exercises/prime-factors/prime-factors.spec.js b/exercises/prime-factors/prime-factors.spec.js index 62e26cdd..a0f3d6b5 100644 --- a/exercises/prime-factors/prime-factors.spec.js +++ b/exercises/prime-factors/prime-factors.spec.js @@ -1,49 +1,47 @@ var primeFactors = require('./prime-factors'); -describe('primeFactors', function() { - - it('returns an empty array for 1', function() { +describe('primeFactors', function () { + it('returns an empty array for 1', function () { expect(primeFactors.for(1)).toEqual([]); }); - xit('factors 2', function() { + xit('factors 2', function () { expect(primeFactors.for(2)).toEqual([2]); }); - xit('factors 3', function() { + xit('factors 3', function () { expect(primeFactors.for(3)).toEqual([3]); }); - xit('factors 4', function() { + xit('factors 4', function () { expect(primeFactors.for(4)).toEqual([2, 2]); }); - xit('factors 6', function() { + xit('factors 6', function () { expect(primeFactors.for(6)).toEqual([2, 3]); }); - xit('factors 8', function() { + xit('factors 8', function () { expect(primeFactors.for(8)).toEqual([2, 2, 2]); }); - xit('factors 9', function() { + xit('factors 9', function () { expect(primeFactors.for(9)).toEqual([3, 3]); }); - xit('factors 27', function() { + xit('factors 27', function () { expect(primeFactors.for(27)).toEqual([3, 3, 3]); }); - xit('factors 625', function() { + xit('factors 625', function () { expect(primeFactors.for(625)).toEqual([5, 5, 5, 5]); }); - xit('factors 901255', function() { + xit('factors 901255', function () { expect(primeFactors.for(901255)).toEqual([5, 17, 23, 461]); }); - xit('factors 93819012551', function() { + xit('factors 93819012551', function () { expect(primeFactors.for(93819012551)).toEqual([11, 9539, 894119]); }); - }); diff --git a/exercises/proverb/example.js b/exercises/proverb/example.js index 1600e3e4..729c214c 100644 --- a/exercises/proverb/example.js +++ b/exercises/proverb/example.js @@ -1,36 +1,36 @@ -module.exports = function(){ +module.exports = function () { var last = arguments[arguments.length - 1]; var chain = Array.from(arguments); this.options = {}; - if(typeof last == "object" && last.hasOwnProperty("qualifier")){ + if (typeof last === 'object' && last.hasOwnProperty('qualifier')) { this.options = chain.pop(); } this.chain = chain; this.qualifier = this.options.qualifier ? this.options.qualifier + ' ' : ''; - this.toString = function(){ + this.toString = function () { return this.chainOfEvents() + this.conclusion(); }.bind(this); - this.chainOfEvents = function(){ - return this.causesAndEffects().map( function(entry){ - return "For want of a " + entry.cause + - " the " + entry.effect + " was lost.\n"; - }.bind(this) ).join(''); + this.chainOfEvents = function () { + return this.causesAndEffects().map( function (entry) { + return 'For want of a ' + entry.cause + + ' the ' + entry.effect + ' was lost.\n'; + } ).join(''); }.bind(this); - this.causesAndEffects = function(){ - return this.chain.reduce( function(array, event, index){ - if(index < this.chain.length - 1){ + this.causesAndEffects = function () { + return this.chain.reduce( function (array, event, index) { + if (index < this.chain.length - 1) { array.push({ cause: event, effect: this.chain[index + 1] }); } return array; }.bind(this), [] ); }.bind(this); - this.conclusion = function(){ - return "And all for the want of a " + this.qualifier + this.chain[0] + "."; + this.conclusion = function () { + return 'And all for the want of a ' + this.qualifier + this.chain[0] + '.'; }.bind(this); }; diff --git a/exercises/proverb/proverb.spec.js b/exercises/proverb/proverb.spec.js index 8ee75647..50788a2c 100644 --- a/exercises/proverb/proverb.spec.js +++ b/exercises/proverb/proverb.spec.js @@ -1,76 +1,76 @@ var Proverb = require('./proverb'); -describe('Proverb Test Suite', function() { - it('tests a single consequence', function() { +describe('Proverb Test Suite', function () { + it('tests a single consequence', function () { var proverb = new Proverb('nail', 'shoe'); expect(proverb.toString()).toEqual( - "For want of a nail the shoe was lost.\n" + - "And all for the want of a nail."); + 'For want of a nail the shoe was lost.\n' + + 'And all for the want of a nail.'); }); - - it('tests a short chain of consequences', function() { + + it('tests a short chain of consequences', function () { var proverb = new Proverb('nail', 'shoe', 'horse'); expect(proverb.toString()).toEqual( - "For want of a nail the shoe was lost.\n" + - "For want of a shoe the horse was lost.\n" + - "And all for the want of a nail."); + 'For want of a nail the shoe was lost.\n' + + 'For want of a shoe the horse was lost.\n' + + 'And all for the want of a nail.'); }); - it('tests a longer chain of consequences', function() { + it('tests a longer chain of consequences', function () { var proverb = new Proverb('nail', 'shoe', 'horse', 'rider'); expect(proverb.toString()).toEqual( - "For want of a nail the shoe was lost.\n" + - "For want of a shoe the horse was lost.\n" + - "For want of a horse the rider was lost.\n" + - "And all for the want of a nail."); + 'For want of a nail the shoe was lost.\n' + + 'For want of a shoe the horse was lost.\n' + + 'For want of a horse the rider was lost.\n' + + 'And all for the want of a nail.'); }); - it('tests Proverb class does not hard code the rhyme dictionary', - function() { - var proverb = new Proverb('key', 'value'); + it('tests Proverb class does not hard code the rhyme dictionary', + function () { + var proverb = new Proverb('key', 'value'); - expect(proverb.toString()).toEqual( - "For want of a key the value was lost.\n" + - "And all for the want of a key."); - }); + expect(proverb.toString()).toEqual( + 'For want of a key the value was lost.\n' + + 'And all for the want of a key.'); + }); - it('tests the whole proveb', function() { - var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', - 'message', 'battle', 'kingdom'); + it('tests the whole proveb', function () { + var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom'); expect(proverb.toString()).toEqual( - "For want of a nail the shoe was lost.\n" + - "For want of a shoe the horse was lost.\n" + - "For want of a horse the rider was lost.\n" + - "For want of a rider the message was lost.\n" + - "For want of a message the battle was lost.\n" + - "For want of a battle the kingdom was lost.\n" + - "And all for the want of a nail."); + 'For want of a nail the shoe was lost.\n' + + 'For want of a shoe the horse was lost.\n' + + 'For want of a horse the rider was lost.\n' + + 'For want of a rider the message was lost.\n' + + 'For want of a message the battle was lost.\n' + + 'For want of a battle the kingdom was lost.\n' + + 'And all for the want of a nail.'); }); - it('tests the use of an optional qualifier in the final consequence', - function() { - var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', - 'message', 'battle', 'kingdom', - { qualifier: 'horseshoe' }); + it('tests the use of an optional qualifier in the final consequence', + function () { + var proverb = new Proverb('nail', 'shoe', 'horse', 'rider', + 'message', 'battle', 'kingdom', + { qualifier: 'horseshoe' }); - expect(proverb.toString()).toEqual( - "For want of a nail the shoe was lost.\n" + - "For want of a shoe the horse was lost.\n" + - "For want of a horse the rider was lost.\n" + - "For want of a rider the message was lost.\n" + - "For want of a message the battle was lost.\n" + - "For want of a battle the kingdom was lost.\n" + - "And all for the want of a horseshoe nail."); - }); + expect(proverb.toString()).toEqual( + 'For want of a nail the shoe was lost.\n' + + 'For want of a shoe the horse was lost.\n' + + 'For want of a horse the rider was lost.\n' + + 'For want of a rider the message was lost.\n' + + 'For want of a message the battle was lost.\n' + + 'For want of a battle the kingdom was lost.\n' + + 'And all for the want of a horseshoe nail.'); + }); - it('tests the proverb is the same each time', function(){ + it('tests the proverb is the same each time', function () { var proverb = new Proverb('nail', 'shoe'); expect(proverb.toString()).toEqual(proverb.toString()); diff --git a/exercises/pythagorean-triplet/example.js b/exercises/pythagorean-triplet/example.js index 0e7ba3f0..44f4edf4 100644 --- a/exercises/pythagorean-triplet/example.js +++ b/exercises/pythagorean-triplet/example.js @@ -15,7 +15,7 @@ function Triplets(conditions) { } Triplet.prototype.isPythagorean = function () { - return this.a*this.a + this.b*this.b === this.c*this.c; + return this.a * this.a + this.b * this.b === this.c * this.c; }; Triplet.prototype.product = function () { @@ -47,4 +47,4 @@ Triplets.prototype.toArray = function () { } } return triplets; -}; \ No newline at end of file +}; diff --git a/exercises/pythagorean-triplet/pythagorean-triplet.spec.js b/exercises/pythagorean-triplet/pythagorean-triplet.spec.js index 0dcdec3f..0ad346cd 100644 --- a/exercises/pythagorean-triplet/pythagorean-triplet.spec.js +++ b/exercises/pythagorean-triplet/pythagorean-triplet.spec.js @@ -1,7 +1,6 @@ var Triplet = require('./pythagorean-triplet'); describe('Triplet', function () { - it('calculates the sum', function () { expect(new Triplet(3, 4, 5).sum()).toBe(12); }); @@ -41,5 +40,4 @@ describe('Triplet', function () { }); expect(products).toEqual([118080, 168480, 202500]); }); - }); diff --git a/exercises/queen-attack/example.js b/exercises/queen-attack/example.js index 545b283e..50016f39 100644 --- a/exercises/queen-attack/example.js +++ b/exercises/queen-attack/example.js @@ -1,8 +1,8 @@ 'use strict'; -module.exports = function(options) { +module.exports = function (options) { if (options === undefined) { - options = { white: [0,3], black: [7,3] }; + options = { white: [0, 3], black: [7, 3] }; } if (options.white[0] === options.black[0] && options.white[1] === options.black[1]) { @@ -12,7 +12,7 @@ module.exports = function(options) { this.white = options.white; this.black = options.black; - this.canAttack = function() { + this.canAttack = function () { var canAttack = false; if (this.white[0] === this.black[0]) { @@ -36,7 +36,7 @@ module.exports = function(options) { return canAttack; }; - this.boardRepresentation = function() { + this.boardRepresentation = function () { var boardRepresentation = ''; for (var i = 0; i < 8; i++) { @@ -57,7 +57,7 @@ module.exports = function(options) { return boardRepresentation; }; - this.toString = function() { + this.toString = function () { return this.boardRepresentation(); }; }; diff --git a/exercises/queen-attack/queen-attack.spec.js b/exercises/queen-attack/queen-attack.spec.js index 69f1a151..e51205be 100644 --- a/exercises/queen-attack/queen-attack.spec.js +++ b/exercises/queen-attack/queen-attack.spec.js @@ -1,30 +1,29 @@ var Queens = require('./queen-attack'); -describe('Queens', function() { - it('has the correct default positions', function() { - var queens = new Queens; +describe('Queens', function () { + it('has the correct default positions', function () { + var queens = new Queens(); expect(queens.white).toEqual([0, 3]); expect(queens.black).toEqual([7, 3]); }); - xit('initialized with specific placement', function() { - var queens = new Queens({white: [3,7], black: [6,1]}); + xit('initialized with specific placement', function () { + var queens = new Queens({white: [3, 7], black: [6, 1]}); expect(queens.white).toEqual([3, 7]); expect(queens.black).toEqual([6, 1]); }); - xit('cannot occupy the same space', function() { - var positioning = {white: [2,4], black: [2,4]}; + xit('cannot occupy the same space', function () { + var positioning = {white: [2, 4], black: [2, 4]}; try { var queens = new Queens(positioning); - } catch(error) { + } catch (error) { expect(error).toEqual('Queens cannot share the same space'); } - }); - xit('toString representation', function() { + xit('toString representation', function () { var positioning = {white: [2, 4], black: [6, 6]}; var queens = new Queens(positioning); var board = '_ _ _ _ _ _ _ _\n\ @@ -39,44 +38,43 @@ _ _ _ _ _ _ _ _\n\ expect(queens.toString()).toEqual(board); }); - xit('queens cannot attack', function() { - var queens = new Queens({ white: [2,3], black: [4,7] }); + xit('queens cannot attack', function () { + var queens = new Queens({ white: [2, 3], black: [4, 7] }); expect(queens.canAttack()).toEqual(false); }); - xit('queens can attack when they are on the same row', function() { - var queens = new Queens({ white: [2,4], black: [2,7] }); + xit('queens can attack when they are on the same row', function () { + var queens = new Queens({ white: [2, 4], black: [2, 7] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack when they are on the same column', function() { - var queens = new Queens({ white: [5,4], black: [2,4] }); + xit('queens can attack when they are on the same column', function () { + var queens = new Queens({ white: [5, 4], black: [2, 4] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack diagonally', function() { + xit('queens can attack diagonally', function () { var queens = new Queens({ white: [1, 1], black: [6, 6] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack another diagonally', function() { + xit('queens can attack another diagonally', function () { var queens = new Queens({ white: [0, 6], black: [1, 7] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack yet another diagonally', function() { + xit('queens can attack yet another diagonally', function () { var queens = new Queens({ white: [4, 1], black: [6, 3] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack on a north-east/south-west diagonal', function() { + xit('queens can attack on a north-east/south-west diagonal', function () { var queens = new Queens({ white: [7, 0], black: [0, 7] }); expect(queens.canAttack()).toEqual(true); }); - xit('queens can attack on another ne/sw diagonal', function() { + xit('queens can attack on another ne/sw diagonal', function () { var queens = new Queens({ white: [2, 6], black: [5, 3] }); expect(queens.canAttack()).toEqual(true); }); - }); diff --git a/exercises/raindrops/example.js b/exercises/raindrops/example.js index b062b08b..ebaa473f 100644 --- a/exercises/raindrops/example.js +++ b/exercises/raindrops/example.js @@ -9,9 +9,8 @@ Raindrops.prototype.convert = function (n) { if (n % 7 === 0) { result += 'Plong'; } if (result === '') { return n.toString(); - } else { - return result; } + return result; }; -module.exports = Raindrops; \ No newline at end of file +module.exports = Raindrops; diff --git a/exercises/raindrops/raindrops.spec.js b/exercises/raindrops/raindrops.spec.js index 7e8730f3..abfa9058 100644 --- a/exercises/raindrops/raindrops.spec.js +++ b/exercises/raindrops/raindrops.spec.js @@ -1,70 +1,69 @@ var Raindrops = require('./raindrops'); -describe('Raindrops', function() { +describe('Raindrops', function () { var drops = new Raindrops(); - it('converts 1', function() { + it('converts 1', function () { expect(drops.convert(1)).toEqual('1'); }); - xit('converts 3', function() { + xit('converts 3', function () { expect(drops.convert(3)).toEqual('Pling'); }); - xit('converts 5', function() { + xit('converts 5', function () { expect(drops.convert(5)).toEqual('Plang'); }); - xit('converts 7', function() { + xit('converts 7', function () { expect(drops.convert(7)).toEqual('Plong'); }); - xit('converts 6', function() { + xit('converts 6', function () { expect(drops.convert(6)).toEqual('Pling'); }); - xit('converts 9', function() { + xit('converts 9', function () { expect(drops.convert(9)).toEqual('Pling'); }); - xit('converts 10', function() { + xit('converts 10', function () { expect(drops.convert(10)).toEqual('Plang'); }); - xit('converts 14', function() { + xit('converts 14', function () { expect(drops.convert(14)).toEqual('Plong'); }); - xit('converts 15', function() { + xit('converts 15', function () { expect(drops.convert(15)).toEqual('PlingPlang'); }); - xit('converts 21', function() { + xit('converts 21', function () { expect(drops.convert(21)).toEqual('PlingPlong'); }); - xit('converts 25', function() { + xit('converts 25', function () { expect(drops.convert(25)).toEqual('Plang'); }); - xit('converts 35', function() { + xit('converts 35', function () { expect(drops.convert(35)).toEqual('PlangPlong'); }); - xit('converts 49', function() { + xit('converts 49', function () { expect(drops.convert(49)).toEqual('Plong'); }); - xit('converts 52', function() { + xit('converts 52', function () { expect(drops.convert(52)).toEqual('52'); }); - xit('converts 105', function() { + xit('converts 105', function () { expect(drops.convert(105)).toEqual('PlingPlangPlong'); }); - xit('converts 12121', function() { + xit('converts 12121', function () { expect(drops.convert(12121)).toEqual('12121'); }); - -}); \ No newline at end of file +}); diff --git a/exercises/rna-transcription/example.js b/exercises/rna-transcription/example.js index 8198ac20..f8ad9d26 100644 --- a/exercises/rna-transcription/example.js +++ b/exercises/rna-transcription/example.js @@ -1,6 +1,6 @@ 'use strict'; -var DnaTranscriber = function(){}; +var DnaTranscriber = function () {}; var dnaToRna = { G: 'C', @@ -9,15 +9,15 @@ var dnaToRna = { A: 'U' }; -var transcribeDna = function(dna, lookupTable) { - return dna.replace(/./g, function(dnaNucleotide) { +var transcribeDna = function (dna, lookupTable) { + return dna.replace(/./g, function (dnaNucleotide) { if (!(dnaNucleotide in lookupTable)) { throw Error('Invalid input'); } return lookupTable[dnaNucleotide]; }); -} +}; -DnaTranscriber.prototype.toRna = function(dna) { +DnaTranscriber.prototype.toRna = function (dna) { return transcribeDna(dna, dnaToRna); -} +}; module.exports = DnaTranscriber; diff --git a/exercises/rna-transcription/rna-transcription.spec.js b/exercises/rna-transcription/rna-transcription.spec.js index 0306d2a4..81be79b2 100644 --- a/exercises/rna-transcription/rna-transcription.spec.js +++ b/exercises/rna-transcription/rna-transcription.spec.js @@ -1,38 +1,37 @@ var DnaTranscriber = require('./rna-transcription'); var dnaTranscriber = new DnaTranscriber(); -describe('toRna()', function() { - - it('transcribes cytosine to guanine', function() { +describe('toRna()', function () { + it('transcribes cytosine to guanine', function () { expect(dnaTranscriber.toRna('C')).toEqual('G'); }); - xit('transcribes guanine to cytosine', function() { + xit('transcribes guanine to cytosine', function () { expect(dnaTranscriber.toRna('G')).toEqual('C'); }); - xit('transcribes adenine to uracil', function() { + xit('transcribes adenine to uracil', function () { expect(dnaTranscriber.toRna('A')).toEqual('U'); }); - xit('transcribes thymine to adenine', function() { + xit('transcribes thymine to adenine', function () { expect(dnaTranscriber.toRna('T')).toEqual('A'); }); - xit('transcribes all dna nucleotides to their rna complements', function() { + xit('transcribes all dna nucleotides to their rna complements', function () { expect(dnaTranscriber.toRna('ACGTGGTCTTAA')) - .toEqual('UGCACCAGAAUU'); + .toEqual('UGCACCAGAAUU'); }); xit('correctly handles completely invalid input', function () { - expect(function () { dnaTranscriber.toRna('XXX') }).toThrow( - new Error('Invalid input') - ); + expect(function () { dnaTranscriber.toRna('XXX'); }).toThrow( + new Error('Invalid input') + ); }); xit('correctly handles partially invalid input', function () { - expect(function () { dnaTranscriber.toRna('ACGTXXXCTTAA') }).toThrow( - new Error('Invalid input') - ); + expect(function () { dnaTranscriber.toRna('ACGTXXXCTTAA'); }).toThrow( + new Error('Invalid input') + ); }); }); diff --git a/exercises/robot-name/example.js b/exercises/robot-name/example.js index 64356a8b..cb3ab616 100644 --- a/exercises/robot-name/example.js +++ b/exercises/robot-name/example.js @@ -1,4 +1,4 @@ -function randomLetter () { +function randomLetter() { var letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; return letters.charAt(Math.floor(Math.random() * letters.length)); @@ -19,10 +19,10 @@ Robot.prototype = { // This awesome err msg will never see the light of day. ;_; Checking the // length was slowing down the program too much. // -// if (Object.keys(this.constructor.usedNames).length >= 676000) { -// throw new Error("All possible names have been taken. " + -// "Our robots are taking over the world! : D"); -// } + // if (Object.keys(this.constructor.usedNames).length >= 676000) { + // throw new Error("All possible names have been taken. " + + // "Our robots are taking over the world! : D"); + // } var name = randomLetter().toUpperCase(); name += randomLetter().toUpperCase(); @@ -37,9 +37,9 @@ Robot.prototype = { return name; }, - get name () { return this._name; }, + get name() { return this._name; }, - set name (newName) { + set name(newName) { if (!(/^[A-Z]{2}\d{3}$/).test(newName)) { throw new Error('Name must be 2 capital letters followed by 3 ints.'); } @@ -47,7 +47,7 @@ Robot.prototype = { this._name = newName; }, - reset: function() { this.name = this.generateName(); } + reset: function () { this.name = this.generateName(); } }; module.exports = Robot; diff --git a/exercises/robot-name/robot-name.spec.js b/exercises/robot-name/robot-name.spec.js index fb4de6a4..810c92ab 100644 --- a/exercises/robot-name/robot-name.spec.js +++ b/exercises/robot-name/robot-name.spec.js @@ -1,32 +1,32 @@ var Robot = require('./robot-name'); -describe('Robot', function() { +describe('Robot', function () { // NOTE: The 'beforeEach()' and 'afterEach()' act as setup/teardown for this // test suite. See more: http://jasmine.github.io/2.0/introduction.html var robot; - beforeEach(function() { + beforeEach(function () { robot = new Robot(); }); - afterEach(function() { + afterEach(function () { robot = null; }); - it('has a name', function() { + it('has a name', function () { expect(robot.name).toMatch(/^[A-Z]{2}\d{3}$/); }); - xit('name is the same each time', function() { + xit('name is the same each time', function () { expect(robot.name).toEqual(robot.name); }); - xit('different robots have different names', function() { + xit('different robots have different names', function () { var differentRobot = new Robot(); expect(differentRobot.name).not.toEqual(robot.name); }); - xit('is able to reset the name', function() { + xit('is able to reset the name', function () { var originalName = robot.name; robot.reset(); var newName = robot.name; @@ -34,10 +34,10 @@ describe('Robot', function() { expect(originalName).not.toEqual(newName); }); - xit('should set a unique name after reset', function() { + xit('should set a unique name after reset', function () { var i, - numResets = 10000, - usedNames = {}; + numResets = 10000, + usedNames = {}; usedNames[robot.name] = true; @@ -48,12 +48,12 @@ describe('Robot', function() { expect(Object.keys(usedNames).length).toEqual(numResets + 1); }); - - //This test is optional. - xit('there can be lots of robots with different names each', function() { + + // This test is optional. + xit('there can be lots of robots with different names each', function () { var i, - numRobots = 10000, - usedNames = {}; + numRobots = 10000, + usedNames = {}; for (i = 0; i < numRobots; i++) { var newRobot = new Robot(); diff --git a/exercises/robot-simulator/example.js b/exercises/robot-simulator/example.js index bca213ad..769134f5 100644 --- a/exercises/robot-simulator/example.js +++ b/exercises/robot-simulator/example.js @@ -1,17 +1,17 @@ var Robot = (function () { 'use strict'; - var VALID_DIRECTIONS = ['north', 'east', 'south', 'west'] + var VALID_DIRECTIONS = ['north', 'east', 'south', 'west']; var INSTRUCTION_KEYS = { A: 'advance', L: 'turnLeft', R: 'turnRight' - } + }; - function Robot () { + function Robot() { this.coordinates = [0, 0]; this.bearing = 'north'; - }; + } Robot.prototype.at = function (x, y) { this.coordinates = [x, y]; @@ -27,19 +27,19 @@ var Robot = (function () { Robot.prototype.advance = function () { switch (this.bearing) { - case 'north': - this.coordinates[1]++; - break; - case 'east': - this.coordinates[0]++; - break; - case 'south': - this.coordinates[1]--; - break; - case 'west': - this.coordinates[0]--; - break; - }; + case 'north': + this.coordinates[1]++; + break; + case 'east': + this.coordinates[0]++; + break; + case 'south': + this.coordinates[1]--; + break; + case 'west': + this.coordinates[0]--; + break; + } }; Robot.prototype.turnLeft = function () { @@ -81,7 +81,7 @@ var Robot = (function () { }, this); }; - return Robot -})() + return Robot; +})(); module.exports = Robot; diff --git a/exercises/robot-simulator/robot-simulator.spec.js b/exercises/robot-simulator/robot-simulator.spec.js index a94b1446..f69d86f7 100644 --- a/exercises/robot-simulator/robot-simulator.spec.js +++ b/exercises/robot-simulator/robot-simulator.spec.js @@ -1,9 +1,9 @@ var Robot = require('./robot-simulator'); -describe('Robot', function() { +describe('Robot', function () { var robot = new Robot(); - it('robot bearing', function() { + it('robot bearing', function () { var directions = [ 'east', 'west', 'north', 'south' ]; for (var i = 0; i < directions.length; i++) { @@ -13,7 +13,7 @@ describe('Robot', function() { } }); - xit('invalid robot bearing', function() { + xit('invalid robot bearing', function () { var incorrectlyOrientRobot = function () { robot.orient('crood'); }; @@ -21,118 +21,118 @@ describe('Robot', function() { expect(incorrectlyOrientRobot).toThrow(new Error('Invalid Robot Bearing')); }); - xit('turn right from north', function() { + xit('turn right from north', function () { robot.orient('north'); robot.turnRight(); expect(robot.bearing).toEqual('east'); }); - xit('turn right from east', function() { + xit('turn right from east', function () { robot.orient('east'); robot.turnRight(); expect(robot.bearing).toEqual('south'); }); - xit('turn right from south', function() { + xit('turn right from south', function () { robot.orient('south'); robot.turnRight(); expect(robot.bearing).toEqual('west'); }); - xit('turn right from west', function() { + xit('turn right from west', function () { robot.orient('west'); robot.turnRight(); expect(robot.bearing).toEqual('north'); }); - xit('turn left from north', function() { + xit('turn left from north', function () { robot.orient('north'); robot.turnLeft(); expect(robot.bearing).toEqual('west'); }); - xit('turn left from east', function() { + xit('turn left from east', function () { robot.orient('east'); robot.turnLeft(); expect(robot.bearing).toEqual('north'); }); - xit('turn left from south', function() { + xit('turn left from south', function () { robot.orient('south'); robot.turnLeft(); expect(robot.bearing).toEqual('east'); }); - xit('turn left from west', function() { + xit('turn left from west', function () { robot.orient('west'); robot.turnLeft(); expect(robot.bearing).toEqual('south'); }); - xit('robot coordinates', function() { + xit('robot coordinates', function () { robot.at(3, 0); - expect(robot.coordinates).toEqual([3,0]); + expect(robot.coordinates).toEqual([3, 0]); }); - xit('other robot coordinates', function() { + xit('other robot coordinates', function () { robot.at(-2, 5); - expect(robot.coordinates).toEqual([-2,5]); + expect(robot.coordinates).toEqual([-2, 5]); }); - xit('advance when facing north', function() { - robot.at(0,0); + xit('advance when facing north', function () { + robot.at(0, 0); robot.orient('north'); robot.advance(); - expect(robot.coordinates).toEqual([0,1]); + expect(robot.coordinates).toEqual([0, 1]); }); - xit('advance when facing east', function() { - robot.at(0,0); + xit('advance when facing east', function () { + robot.at(0, 0); robot.orient('east'); robot.advance(); - expect(robot.coordinates).toEqual([1,0]); + expect(robot.coordinates).toEqual([1, 0]); }); - xit('advance when facing south', function() { - robot.at(0,0); + xit('advance when facing south', function () { + robot.at(0, 0); robot.orient('south'); robot.advance(); - expect(robot.coordinates).toEqual([0,-1]); + expect(robot.coordinates).toEqual([0, -1]); }); - xit('advance when facing west', function() { - robot.at(0,0); + xit('advance when facing west', function () { + robot.at(0, 0); robot.orient('west'); robot.advance(); - expect(robot.coordinates).toEqual([-1,0]); + expect(robot.coordinates).toEqual([-1, 0]); }); - xit('instructions for turning left', function() { + xit('instructions for turning left', function () { expect(robot.instructions('L')).toEqual(['turnLeft']); }); - xit('instructions for turning right', function() { + xit('instructions for turning right', function () { expect(robot.instructions('R')).toEqual(['turnRight']); }); - xit('instructions for advancing', function() { + xit('instructions for advancing', function () { expect(robot.instructions('A')).toEqual(['advance']); }); - xit('series of instructions', function() { + xit('series of instructions', function () { expect(robot.instructions('RAAL')) .toEqual(['turnRight', 'advance', 'advance', 'turnLeft']); }); - xit('instruct robot', function() { + xit('instruct robot', function () { robot.place({x: -2, y: 1, direction: 'east'}); robot.evaluate('RLAALAL'); - expect(robot.coordinates).toEqual([0,2]); + expect(robot.coordinates).toEqual([0, 2]); expect(robot.bearing).toEqual('west'); }); - xit('instruct many robots', function() { + xit('instruct many robots', function () { var robot1 = new Robot(); var robot2 = new Robot(); var robot3 = new Robot(); diff --git a/exercises/roman-numerals/example.js b/exercises/roman-numerals/example.js index 8ff668c4..40e8ddf0 100644 --- a/exercises/roman-numerals/example.js +++ b/exercises/roman-numerals/example.js @@ -1,24 +1,24 @@ 'use strict'; -module.exports = function(number) { +module.exports = function (number) { var result = ''; var mappings = [ {arabic: 1000, roman: 'M'}, - {arabic: 900, roman: 'CM'}, - {arabic: 500, roman: 'D'}, - {arabic: 400, roman: 'CD'}, - {arabic: 100, roman: 'C'}, - {arabic: 90, roman: 'XC'}, - {arabic: 50, roman: 'L'}, - {arabic: 40, roman: 'XL'}, - {arabic: 10, roman: 'X'}, - {arabic: 9, roman: 'IX'}, - {arabic: 5, roman: 'V'}, - {arabic: 4, roman: 'IV'}, - {arabic: 1, roman: 'I'} + {arabic: 900, roman: 'CM'}, + {arabic: 500, roman: 'D'}, + {arabic: 400, roman: 'CD'}, + {arabic: 100, roman: 'C'}, + {arabic: 90, roman: 'XC'}, + {arabic: 50, roman: 'L'}, + {arabic: 40, roman: 'XL'}, + {arabic: 10, roman: 'X'}, + {arabic: 9, roman: 'IX'}, + {arabic: 5, roman: 'V'}, + {arabic: 4, roman: 'IV'}, + {arabic: 1, roman: 'I'} ]; - for (var i=0; i < mappings.length; i++) { + for (var i = 0; i < mappings.length; i++) { var mapping = mappings[i]; while (number >= mapping.arabic) { result = result + mapping.roman; diff --git a/exercises/roman-numerals/roman-numerals.spec.js b/exercises/roman-numerals/roman-numerals.spec.js index cc81660b..539ed665 100644 --- a/exercises/roman-numerals/roman-numerals.spec.js +++ b/exercises/roman-numerals/roman-numerals.spec.js @@ -1,75 +1,75 @@ var toRoman = require('./roman-numerals'); -describe('toRoman()', function() { - it('converts 1', function() { +describe('toRoman()', function () { + it('converts 1', function () { expect(toRoman(1)).toEqual('I'); }); - xit('converts 2', function() { + xit('converts 2', function () { expect(toRoman(2)).toEqual('II'); }); - xit('converts 3', function() { + xit('converts 3', function () { expect(toRoman(3)).toEqual('III'); }); - xit('converts 4', function() { + xit('converts 4', function () { expect(toRoman(4)).toEqual('IV'); }); - xit('converts 5', function() { + xit('converts 5', function () { expect(toRoman(5)).toEqual('V'); }); - xit('converts 6', function() { + xit('converts 6', function () { expect(toRoman(6)).toEqual('VI'); }); - xit('converts 9', function() { + xit('converts 9', function () { expect(toRoman(9)).toEqual('IX'); }); - xit('converts 27', function() { + xit('converts 27', function () { expect(toRoman(27)).toEqual('XXVII'); }); - xit('converts 48', function() { + xit('converts 48', function () { expect(toRoman(48)).toEqual('XLVIII'); }); - xit('converts 59', function() { + xit('converts 59', function () { expect(toRoman(59)).toEqual('LIX'); }); - xit('converts 93', function() { + xit('converts 93', function () { expect(toRoman(93)).toEqual('XCIII'); }); - xit('converts 141', function() { + xit('converts 141', function () { expect(toRoman(141)).toEqual('CXLI'); }); - xit('converts 163', function() { + xit('converts 163', function () { expect(toRoman(163)).toEqual('CLXIII'); }); - xit('converts 402', function() { + xit('converts 402', function () { expect(toRoman(402)).toEqual('CDII'); }); - xit('converts 575', function() { + xit('converts 575', function () { expect(toRoman(575)).toEqual('DLXXV'); }); - xit('converts 911', function() { + xit('converts 911', function () { expect(toRoman(911)).toEqual('CMXI'); }); - xit('converts 1024', function() { + xit('converts 1024', function () { expect(toRoman(1024)).toEqual('MXXIV'); }); - xit('converts 3000', function() { + xit('converts 3000', function () { expect(toRoman(3000)).toEqual('MMM'); }); }); diff --git a/exercises/run-length-encoding/example.js b/exercises/run-length-encoding/example.js index 6a900cc4..4e4447d4 100644 --- a/exercises/run-length-encoding/example.js +++ b/exercises/run-length-encoding/example.js @@ -1,11 +1,11 @@ exports.encode = function encode(plaintext) { - return plaintext.replace(/([\w\s])\1*/g, function(match) { - return match.length > 1 ? match.length + match[0] : match[0]; - }); + return plaintext.replace(/([\w\s])\1*/g, function (match) { + return match.length > 1 ? match.length + match[0] : match[0]; + }); }; exports.decode = function decode(cypher) { - return cypher.replace(/(\d+)(\w|\s)/g, function(match, repeats, char) { - return new Array(+repeats + 1).join(char); - }); + return cypher.replace(/(\d+)(\w|\s)/g, function (match, repeats, char) { + return new Array(+repeats + 1).join(char); + }); }; diff --git a/exercises/run-length-encoding/run-length-encoding.spec.js b/exercises/run-length-encoding/run-length-encoding.spec.js index bfd56787..a18e61ac 100644 --- a/exercises/run-length-encoding/run-length-encoding.spec.js +++ b/exercises/run-length-encoding/run-length-encoding.spec.js @@ -1,41 +1,39 @@ var RLE = require('./run-length-encoding'); -describe('Run-length encoding', function() { - - it('encode empty string', function() { - expect(RLE.encode('')).toEqual(''); - }); - - xit('encode single characters only', function() { - expect(RLE.encode('XYZ')).toEqual('XYZ'); - }); - - xit('decode empty string', function() { - expect(RLE.decode('')).toEqual(''); - }); - - xit('decode single characters only', function() { - expect(RLE.decode('XYZ')).toEqual('XYZ'); - }); - - xit('encode simple', function() { - expect(RLE.encode('AABBBCCCC')).toEqual('2A3B4C'); - }); - - xit('decode simple', function() { - expect(RLE.decode('2A3B4C')).toEqual('AABBBCCCC'); - }); - - xit('encode with single values', function() { - expect(RLE.encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')).toEqual('12WB12W3B24WB'); - }); - - xit('decode with single values', function() { - expect(RLE.decode('12WB12W3B24WB')).toEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'); - }); - - xit('decode(encode(...))combination', function() { - expect(RLE.decode(RLE.encode('zzz ZZ zZ'))).toEqual('zzz ZZ zZ'); - }); - +describe('Run-length encoding', function () { + it('encode empty string', function () { + expect(RLE.encode('')).toEqual(''); + }); + + xit('encode single characters only', function () { + expect(RLE.encode('XYZ')).toEqual('XYZ'); + }); + + xit('decode empty string', function () { + expect(RLE.decode('')).toEqual(''); + }); + + xit('decode single characters only', function () { + expect(RLE.decode('XYZ')).toEqual('XYZ'); + }); + + xit('encode simple', function () { + expect(RLE.encode('AABBBCCCC')).toEqual('2A3B4C'); + }); + + xit('decode simple', function () { + expect(RLE.decode('2A3B4C')).toEqual('AABBBCCCC'); + }); + + xit('encode with single values', function () { + expect(RLE.encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB')).toEqual('12WB12W3B24WB'); + }); + + xit('decode with single values', function () { + expect(RLE.decode('12WB12W3B24WB')).toEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'); + }); + + xit('decode(encode(...))combination', function () { + expect(RLE.decode(RLE.encode('zzz ZZ zZ'))).toEqual('zzz ZZ zZ'); + }); }); diff --git a/exercises/saddle-points/example.js b/exercises/saddle-points/example.js index 80e562b1..81217e7c 100644 --- a/exercises/saddle-points/example.js +++ b/exercises/saddle-points/example.js @@ -12,7 +12,7 @@ module.exports = function Matrix(matrix) { var i, j, currentRow; for (i = 0; i < rows.length; i++) { - currentRow = rows[i].replace(/^\s+|\s+$/g,'').split(' ').map( toInt ); + currentRow = rows[i].replace(/^\s+|\s+$/g, '').split(' ').map( toInt ); this.rows.push(currentRow); } @@ -26,7 +26,7 @@ module.exports = function Matrix(matrix) { } } - this.indexesOfMaxValues = function(array) { + this.indexesOfMaxValues = function (array) { var i, currentElement, maxValue, indexes = []; for (i = 0; i < array.length; i++) { @@ -42,7 +42,7 @@ module.exports = function Matrix(matrix) { return indexes; }; - this.indexesOfMinValues = function(array) { + this.indexesOfMinValues = function (array) { var i, currentElement, minValue, indexes = []; for (i = 0; i < array.length; i++) { @@ -58,15 +58,13 @@ module.exports = function Matrix(matrix) { return indexes; }; - this.calculateSaddlePoints = function(rows,columns) { + this.calculateSaddlePoints = function (rows, columns) { var i, j, maxIndexes, minIndexes, currentMaxIndex, saddlePoints = []; for (i = 0; i < rows.length; i++) { - maxIndexes = this.indexesOfMaxValues(rows[i]); for (j = 0; j < maxIndexes.length; j++) { - currentMaxIndex = maxIndexes[j]; minIndexes = this.indexesOfMinValues(columns[currentMaxIndex]); @@ -74,10 +72,9 @@ module.exports = function Matrix(matrix) { saddlePoints.push([i, currentMaxIndex]); } } - } return saddlePoints; }; - this.saddlePoints = this.calculateSaddlePoints(this.rows,this.columns); -}; \ No newline at end of file + this.saddlePoints = this.calculateSaddlePoints(this.rows, this.columns); +}; diff --git a/exercises/saddle-points/saddle-points.spec.js b/exercises/saddle-points/saddle-points.spec.js index 35f5c31c..836a8cbb 100644 --- a/exercises/saddle-points/saddle-points.spec.js +++ b/exercises/saddle-points/saddle-points.spec.js @@ -1,42 +1,42 @@ var Matrix = require('./saddle-points'); -describe('Matrix', function() { - it('extracts a row', function() { +describe('Matrix', function () { + it('extracts a row', function () { var matrix = new Matrix('1 2\n10 20'); - expect(matrix.rows[0]).toEqual([1,2]); + expect(matrix.rows[0]).toEqual([1, 2]); }); - xit('extracts other row', function() { + xit('extracts other row', function () { var matrix = new Matrix('9 8 7\n19 18 17'); expect(matrix.rows[1]).toEqual([19, 18, 17]); }); - xit('extracts a column', function() { + xit('extracts a column', function () { var matrix = new Matrix('1 2 3\n4 5 6\n7 8 9\n8 7 6'); expect(matrix.columns[0]).toEqual([1, 4, 7, 8]); }); - xit('extracts another column', function() { + xit('extracts another column', function () { var matrix = new Matrix('89 1903 3\n18 3 1\n9 4 800'); expect(matrix.columns[1]).toEqual([1903, 3, 4]); }); - xit('no saddle point', function() { + xit('no saddle point', function () { var matrix = new Matrix('2 1\n1 2'); expect(matrix.saddlePoints).toEqual([]); }); - xit('a saddle point', function() { + xit('a saddle point', function () { var matrix = new Matrix('1 2\n3 4'); - expect(matrix.saddlePoints).toEqual([[0,1]]); + expect(matrix.saddlePoints).toEqual([[0, 1]]); }); - xit('another saddle point', function() { + xit('another saddle point', function () { var matrix = new Matrix('18 3 39 19 91\n38 10 8 77 320\n3 4 8 6 7'); - expect(matrix.saddlePoints).toEqual([[2,2]]); + expect(matrix.saddlePoints).toEqual([[2, 2]]); }); - xit('multiple saddle points', function() { + xit('multiple saddle points', function () { var matrix = new Matrix('4 5 4\n3 5 5\n1 5 4'); expect(matrix.saddlePoints).toEqual([[0, 1], [1, 1], [2, 1]]); }); diff --git a/exercises/say/example.js b/exercises/say/example.js index 3b00023d..4a69883b 100644 --- a/exercises/say/example.js +++ b/exercises/say/example.js @@ -1,16 +1,16 @@ 'use strict'; var smallNumbers = { - 0 : 'zero', - 1 : 'one', - 2 : 'two', - 3 : 'three', - 4 : 'four', - 5 : 'five', - 6 : 'six', - 7 : 'seven', - 8 : 'eight', - 9 : 'nine', + 0: 'zero', + 1: 'one', + 2: 'two', + 3: 'three', + 4: 'four', + 5: 'five', + 6: 'six', + 7: 'seven', + 8: 'eight', + 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', @@ -35,8 +35,8 @@ var decades = { }; var bigNumbers = { - 1000: 'thousand', - 1000000: 'million', + 1000: 'thousand', + 1000000: 'million', 1000000000: 'billion' }; @@ -44,9 +44,9 @@ function bigPart(number) { var factor, result = ''; for (var bigNumber = 1000000000; bigNumber >= 1000; bigNumber /= 1000) { if (number.current >= bigNumber) { - factor = Math.floor(number.current/bigNumber); + factor = Math.floor(number.current / bigNumber); result += threeDigit(factor) + ' ' + bigNumbers[bigNumber] + ' '; - number.current = number.current-(factor*bigNumber); + number.current = number.current - (factor * bigNumber); } } return result; @@ -55,7 +55,7 @@ function bigPart(number) { function sayDecade(n) { for (var decade = 90; decade >= 20; decade -= 10) { if (n >= decade) { - return decades[decade] + '-' + smallNumbers[n-decade]; + return decades[decade] + '-' + smallNumbers[n - decade]; } } } @@ -73,18 +73,16 @@ function twoDigit(n) { function threeDigit(n) { if (n < 100) { return twoDigit(n); - } else { - return smallNumbers[Math.floor(n/100)] + ' hundred ' + twoDigit(n%100); } + return smallNumbers[Math.floor(n / 100)] + ' hundred ' + twoDigit(n % 100); } exports.inEnglish = function (n) { var result, number = {current: n}; - if (0 <= n && n < 1000000000000) { + if (n >= 0 && n < 1000000000000) { result = bigPart(number); result += threeDigit(number.current); return result.replace(/.zero/, ''); - } else { - throw new Error('Number must be between 0 and 999,999,999,999.'); } -}; \ No newline at end of file + throw new Error('Number must be between 0 and 999,999,999,999.'); +}; diff --git a/exercises/say/say.spec.js b/exercises/say/say.spec.js index d638be89..729b6324 100644 --- a/exercises/say/say.spec.js +++ b/exercises/say/say.spec.js @@ -1,7 +1,6 @@ var say = require('./say'); describe('say', function () { - it('zero', function () { expect(say.inEnglish(0)).toBe('zero'); }); @@ -74,5 +73,4 @@ describe('say', function () { say.inEnglish(1000000000000); }).toThrow(new Error('Number must be between 0 and 999,999,999,999.')); }); - -}); \ No newline at end of file +}); diff --git a/exercises/scrabble-score/example.js b/exercises/scrabble-score/example.js index 7c116e96..28f08414 100644 --- a/exercises/scrabble-score/example.js +++ b/exercises/scrabble-score/example.js @@ -1,20 +1,20 @@ 'use strict'; var letterScores = { - 'a' : 1, 'e' : 1, 'i' : 1, 'o' : 1, - 'u' : 1, 'l' : 1, 'n' : 1, 'r' : 1, - 's' : 1, 't' : 1, 'd' : 2, 'g' : 2, - 'b' : 3, 'c' : 3, 'm' : 3, 'p' : 3, - 'f' : 4, 'h' : 4, 'v' : 4, 'w' : 4, - 'y' : 4, 'k' : 5, 'j' : 8, 'x' : 8, - 'q' : 10, 'z' : 10 + 'a': 1, 'e': 1, 'i': 1, 'o': 1, + 'u': 1, 'l': 1, 'n': 1, 'r': 1, + 's': 1, 't': 1, 'd': 2, 'g': 2, + 'b': 3, 'c': 3, 'm': 3, 'p': 3, + 'f': 4, 'h': 4, 'v': 4, 'w': 4, + 'y': 4, 'k': 5, 'j': 8, 'x': 8, + 'q': 10, 'z': 10 }; function letterScore(letter) { return letterScores[letter] || 0; } -module.exports = function(word) { +module.exports = function (word) { word || (word = ''); word = word.toLowerCase(); diff --git a/exercises/scrabble-score/scrabble-score.spec.js b/exercises/scrabble-score/scrabble-score.spec.js index dc9a8787..45c30b7e 100644 --- a/exercises/scrabble-score/scrabble-score.spec.js +++ b/exercises/scrabble-score/scrabble-score.spec.js @@ -1,27 +1,27 @@ var score = require('./scrabble-score'); -describe('Scrabble', function() { - it('scores an empty word as zero',function() { +describe('Scrabble', function () { + it('scores an empty word as zero', function () { expect(score('')).toEqual(0); }); - xit('scores a null as zero',function() { + xit('scores a null as zero', function () { expect(score(null)).toEqual(0); }); - xit('scores a very short word',function() { + xit('scores a very short word', function () { expect(score('a')).toEqual(1); }); - xit('scores the word by the number of letters',function() { + xit('scores the word by the number of letters', function () { expect(score('street')).toEqual(6); }); - xit('scores more complicated words with more',function() { + xit('scores more complicated words with more', function () { expect(score('quirky')).toEqual(22); }); - xit('scores case insensitive words',function() { + xit('scores case insensitive words', function () { expect(score('OXYPHENBUTAZONE')).toEqual(41); }); }); diff --git a/exercises/secret-handshake/example.js b/exercises/secret-handshake/example.js index b6ceb788..651a8d78 100644 --- a/exercises/secret-handshake/example.js +++ b/exercises/secret-handshake/example.js @@ -8,17 +8,17 @@ function SecretHandshake(handshake) { throw new Error('Handshake must be a number'); } - this.commands = function() { + this.commands = function () { return this.shakeWith; }; - this.calculateHandshake = function(handshake) { - /*jshint bitwise:false */ + this.calculateHandshake = function (handshake) { + /* jshint bitwise:false */ var shakeWith = []; for (var i = 0; i < handshakeCommands.length; i++) { var currentCommand = handshakeCommands[i]; - var handshakeHasCommand = (handshake & Math.pow(2,i)); + var handshakeHasCommand = (handshake & Math.pow(2, i)); if (handshakeHasCommand) { if (currentCommand === 'REVERSE') { @@ -33,7 +33,6 @@ function SecretHandshake(handshake) { }; this.shakeWith = this.calculateHandshake(handshake); - } -module.exports = SecretHandshake; \ No newline at end of file +module.exports = SecretHandshake; diff --git a/exercises/secret-handshake/secret-handshake.spec.js b/exercises/secret-handshake/secret-handshake.spec.js index dd9b0ded..6c29444a 100644 --- a/exercises/secret-handshake/secret-handshake.spec.js +++ b/exercises/secret-handshake/secret-handshake.spec.js @@ -1,42 +1,42 @@ var SecretHandshake = require('./secret-handshake'); -describe('Secret Handshake', function() { - it('1 is a wink', function() { +describe('Secret Handshake', function () { + it('1 is a wink', function () { var handshake = new SecretHandshake(1); expect(handshake.commands()).toEqual(['wink']); }); - xit('10 is a double blink', function() { + xit('10 is a double blink', function () { var handshake = new SecretHandshake(2); expect(handshake.commands()).toEqual(['double blink']); }); - xit('100 is close your eyes', function() { + xit('100 is close your eyes', function () { var handshake = new SecretHandshake(4); expect(handshake.commands()).toEqual(['close your eyes']); }); - xit('1000 is jump', function() { + xit('1000 is jump', function () { var handshake = new SecretHandshake(8); expect(handshake.commands()).toEqual(['jump']); }); - xit('11 is wink and double blink', function() { + xit('11 is wink and double blink', function () { var handshake = new SecretHandshake(3); - expect(handshake.commands()).toEqual(['wink','double blink']); + expect(handshake.commands()).toEqual(['wink', 'double blink']); }); - xit('10011 is double blink and wink', function() { + xit('10011 is double blink and wink', function () { var handshake = new SecretHandshake(19); - expect(handshake.commands()).toEqual(['double blink','wink']); + expect(handshake.commands()).toEqual(['double blink', 'wink']); }); - xit('11111 is jump, close your eyes, double blink, and wink', function() { + xit('11111 is jump, close your eyes, double blink, and wink', function () { var handshake = new SecretHandshake(31); - expect(handshake.commands()).toEqual(['jump','close your eyes','double blink','wink']); + expect(handshake.commands()).toEqual(['jump', 'close your eyes', 'double blink', 'wink']); }); - xit('text is an invalid secret handshake', function() { + xit('text is an invalid secret handshake', function () { expect( function () { var handshake = new SecretHandshake('piggies'); }).toThrow(new Error('Handshake must be a number')); diff --git a/exercises/series/example.js b/exercises/series/example.js index 448c59d5..dd05784d 100644 --- a/exercises/series/example.js +++ b/exercises/series/example.js @@ -18,10 +18,10 @@ Series.prototype.slices = function (sliceSize) { if (sliceSize > this.digits.length) { throw new Error('Slice size is too big.'); } - + for (var i = 0; i < this.digits.length - sliceSize + 1; i++) { for (var j = 0; j < sliceSize; j++) { - slice.push(this.digits[i+j]); + slice.push(this.digits[i + j]); } result.push(slice); slice = []; @@ -30,4 +30,4 @@ Series.prototype.slices = function (sliceSize) { return result; }; -module.exports = Series; \ No newline at end of file +module.exports = Series; diff --git a/exercises/series/series.spec.js b/exercises/series/series.spec.js index 6cae7a56..10b783c2 100644 --- a/exercises/series/series.spec.js +++ b/exercises/series/series.spec.js @@ -1,7 +1,6 @@ var Series = require('./series'); describe('Series', function () { - it('has digits (short)', function () { expect(new Series('01234').digits).toEqual([0, 1, 2, 3, 4]); }); @@ -56,5 +55,4 @@ describe('Series', function () { new Series('01032987583').slices(12); }).toThrow(new Error('Slice size is too big.')); }); - -}); \ No newline at end of file +}); diff --git a/exercises/sieve/example.js b/exercises/sieve/example.js index 6282ef9b..85ad948a 100644 --- a/exercises/sieve/example.js +++ b/exercises/sieve/example.js @@ -28,4 +28,4 @@ function sieve(n) { module.exports = function (n) { this.primes = sieve(n); -}; \ No newline at end of file +}; diff --git a/exercises/sieve/sieve.spec.js b/exercises/sieve/sieve.spec.js index 16a4d8b5..b5f1c299 100644 --- a/exercises/sieve/sieve.spec.js +++ b/exercises/sieve/sieve.spec.js @@ -1,17 +1,15 @@ var Sieve = require('./sieve'); -describe('Sieve', function() { - - it('finds primes up to 10', function() { +describe('Sieve', function () { + it('finds primes up to 10', function () { expect(new Sieve(10).primes).toEqual([2, 3, 5, 7]); }); - xit('finds primes up to 13, and considers the limit passed in', function() { + xit('finds primes up to 13, and considers the limit passed in', function () { expect(new Sieve(13).primes).toEqual([2, 3, 5, 7, 11, 13]); }); - xit('finds primes up to 1000', function() { + xit('finds primes up to 1000', function () { expect(new Sieve(1000).primes).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/example.js b/exercises/simple-cipher/example.js index ecfae367..b8cc5151 100644 --- a/exercises/simple-cipher/example.js +++ b/exercises/simple-cipher/example.js @@ -15,19 +15,18 @@ function randomUpTo(n) { } module.exports = function (userDefinedKey) { - var key; function addEncodedCharacter(character, index, array) { - /*jshint validthis:true */ - var i = ALPHABET.indexOf(character) + ALPHABET.indexOf(key[index%key.length]); + /* jshint validthis:true */ + var i = ALPHABET.indexOf(character) + ALPHABET.indexOf(key[index % key.length]); if (i >= ALPHABET.length) { i -= ALPHABET.length; } this.push(ALPHABET[i]); } function addDecodedCharacter(character, index, array) { - /*jshint validthis:true */ - var i = ALPHABET.indexOf(character) - ALPHABET.indexOf(key[index%key.length]); + /* jshint validthis:true */ + var i = ALPHABET.indexOf(character) - ALPHABET.indexOf(key[index % key.length]); if (i < 0) { i += ALPHABET.length; } this.push(ALPHABET[i]); } diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index c2b41e81..f3fb2b39 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -77,7 +77,7 @@ describe('Substitution cipher', function () { expect(cipher.decode('zabcdefghi')).toEqual('zzzzzzzzzz'); }); - xit('can handle messages longer than the key', function() { + xit('can handle messages longer than the key', function () { expect(new Cipher('abc').encode('iamapandabear')) .toEqual('iboaqcnecbfcr'); }); diff --git a/exercises/simple-linked-list/example.js b/exercises/simple-linked-list/example.js index 6b097473..6e1f0d05 100644 --- a/exercises/simple-linked-list/example.js +++ b/exercises/simple-linked-list/example.js @@ -1,4 +1,4 @@ -function Element (value, next) { +function Element(value, next) { if (!(this instanceof Element)) { throw new Error('Element is a constructor.'); } @@ -13,9 +13,9 @@ function Element (value, next) { this.value = value; this.next = next; -}; +} -function List () {}; +function List() {} List.prototype.push = function (value) { if (value === undefined) { @@ -73,8 +73,7 @@ List.prototype.pop = function () { if (!penultEl) { this.head = undefined; - } - else { + } else { penultEl.next = undefined; } }; diff --git a/exercises/simple-linked-list/simple-linked-list.spec.js b/exercises/simple-linked-list/simple-linked-list.spec.js index bc104a23..1254743b 100644 --- a/exercises/simple-linked-list/simple-linked-list.spec.js +++ b/exercises/simple-linked-list/simple-linked-list.spec.js @@ -3,7 +3,6 @@ var List = SimpleLinkedList.List; var Element = SimpleLinkedList.Element; describe('simple-linked-list', function () { - it('exports a List constructor', function () { expect(List).toBeDefined(); }); @@ -13,7 +12,6 @@ describe('simple-linked-list', function () { }); describe('Element', function () { - xit('is a constructor', function () { var el = new Element(1); expect(el).toBeDefined(); @@ -66,7 +64,6 @@ describe('simple-linked-list', function () { }); describe('List', function () { - xit('is a constructor', function () { var ll = new List(); expect(ll).toBeDefined(); @@ -157,7 +154,5 @@ describe('simple-linked-list', function () { expect(ll.head.next.value).toBe(2); expect(ll.head.next.next.value).toBe(1); }); - }); - }); diff --git a/exercises/space-age/example.js b/exercises/space-age/example.js index 41f9a53a..d20722cd 100644 --- a/exercises/space-age/example.js +++ b/exercises/space-age/example.js @@ -5,50 +5,50 @@ function SpaceAge(seconds) { this.earthYears = seconds / 31557600; this.earthToOtherPlanets = { - mercury : 0.2408467, - venus : 0.61519726, - earth : 1, - mars : 1.8808158, - jupiter : 11.862615, - saturn : 29.447498, - uranus : 84.016846, - neptune : 164.79132 + mercury: 0.2408467, + venus: 0.61519726, + earth: 1, + mars: 1.8808158, + jupiter: 11.862615, + saturn: 29.447498, + uranus: 84.016846, + neptune: 164.79132 }; - this.yearsOnPlanet = function(planet) { + this.yearsOnPlanet = function (planet) { var years = this.earthYears / this.earthToOtherPlanets[planet]; return parseFloat(years.toFixed(2)); }; - this.onMercury = function() { + this.onMercury = function () { return this.yearsOnPlanet('mercury'); }; - this.onVenus = function() { + this.onVenus = function () { return this.yearsOnPlanet('venus'); }; - this.onEarth = function() { + this.onEarth = function () { return this.yearsOnPlanet('earth'); }; - this.onMars = function() { + this.onMars = function () { return this.yearsOnPlanet('mars'); }; - this.onJupiter = function() { + this.onJupiter = function () { return this.yearsOnPlanet('jupiter'); }; - this.onSaturn = function() { + this.onSaturn = function () { return this.yearsOnPlanet('saturn'); }; - this.onUranus = function() { + this.onUranus = function () { return this.yearsOnPlanet('uranus'); }; - this.onNeptune = function() { + this.onNeptune = function () { return this.yearsOnPlanet('neptune'); }; } diff --git a/exercises/space-age/space-age.spec.js b/exercises/space-age/space-age.spec.js index ba6508f1..08fcb9da 100644 --- a/exercises/space-age/space-age.spec.js +++ b/exercises/space-age/space-age.spec.js @@ -1,53 +1,53 @@ var SpaceAge = require('./space-age'); -describe('Space Age', function() { - it('age in seconds', function() { +describe('Space Age', function () { + it('age in seconds', function () { var age = new SpaceAge(1000000); expect(age.seconds).toEqual(1000000); }); - xit('age in earth years', function() { + xit('age in earth years', function () { var age = new SpaceAge(1000000000); expect(age.onEarth()).toEqual(31.69); }); - xit('age in mercury years', function() { + xit('age in mercury years', function () { var age = new SpaceAge(2134835688); expect(age.onEarth()).toEqual(67.65); expect(age.onMercury()).toEqual(280.88); }); - xit('age in venus years', function() { + xit('age in venus years', function () { var age = new SpaceAge(189839836); expect(age.onEarth()).toEqual(6.02); expect(age.onVenus()).toEqual(9.78); }); - xit('age in mars years', function() { + xit('age in mars years', function () { var age = new SpaceAge(2329871239); expect(age.onEarth()).toEqual(73.83); expect(age.onMars()).toEqual(39.25); }); - xit('age in jupiter years', function() { + xit('age in jupiter years', function () { var age = new SpaceAge(901876382); expect(age.onEarth()).toEqual(28.58); expect(age.onJupiter()).toEqual(2.41); }); - xit('age in saturn years', function() { + xit('age in saturn years', function () { var age = new SpaceAge(3000000000); expect(age.onEarth()).toEqual(95.06); expect(age.onSaturn()).toEqual(3.23); }); - xit('age in uranus years', function() { + xit('age in uranus years', function () { var age = new SpaceAge(3210123456); expect(age.onEarth()).toEqual(101.72); expect(age.onUranus()).toEqual(1.21); }); - xit('age in neptune year', function() { + xit('age in neptune year', function () { var age = new SpaceAge(8210123456); expect(age.onEarth()).toEqual(260.16); expect(age.onNeptune()).toEqual(1.58); diff --git a/exercises/strain/example.js b/exercises/strain/example.js index 711d4875..4cbd75b5 100644 --- a/exercises/strain/example.js +++ b/exercises/strain/example.js @@ -1,9 +1,9 @@ 'use strict'; module.exports = { - strain: function(array, filter, keepMatches) { + strain: function (array, filter, keepMatches) { var results = []; - for (var i=0; i < array.length; i++) { + for (var i = 0; i < array.length; i++) { var item = array[i]; if (filter(item) === keepMatches) { results.push(item); diff --git a/exercises/strain/strain.spec.js b/exercises/strain/strain.spec.js index 66acc7d5..b57cf89f 100644 --- a/exercises/strain/strain.spec.js +++ b/exercises/strain/strain.spec.js @@ -1,30 +1,29 @@ var strain = require('./strain'); -describe('strain', function() { - - it('keeps on empty array returns empty array', function() { - expect(strain.keep([], function(e) { return e < 10; })).toEqual([]); +describe('strain', function () { + it('keeps on empty array returns empty array', function () { + expect(strain.keep([], function (e) { return e < 10; })).toEqual([]); }); - xit('keeps everything ', function() { - expect(strain.keep([1, 2, 3], function(e) { return e < 10; })).toEqual([1, 2, 3]); + xit('keeps everything ', function () { + expect(strain.keep([1, 2, 3], function (e) { return e < 10; })).toEqual([1, 2, 3]); }); - xit('keeps first and last', function() { - expect(strain.keep([1, 2, 3], function(e) { return (e % 2) === 1; })).toEqual([1, 3]); + xit('keeps first and last', function () { + expect(strain.keep([1, 2, 3], function (e) { return (e % 2) === 1; })).toEqual([1, 3]); }); - xit('keeps neither first nor last', function() { - expect(strain.keep([1, 2, 3, 4, 5], function(e) { return (e % 2) === 0; })).toEqual([2, 4]); + xit('keeps neither first nor last', function () { + expect(strain.keep([1, 2, 3, 4, 5], function (e) { return (e % 2) === 0; })).toEqual([2, 4]); }); - xit('keeps strings', function() { + xit('keeps strings', function () { var words = 'apple zebra banana zombies cherimoya zelot'.split(' '); - var result = strain.keep(words, function(word) { return word.indexOf('z') === 0; }); + var result = strain.keep(words, function (word) { return word.indexOf('z') === 0; }); expect(result).toEqual('zebra zombies zelot'.split(' ')); }); - xit('keeps arrays', function() { + xit('keeps arrays', function () { var rows = [ [1, 2, 3], [5, 5, 5], @@ -34,34 +33,34 @@ describe('strain', function() { [2, 2, 1], [1, 2, 5] ]; - var result = strain.keep(rows, function(row) { return row.indexOf(5) > -1; }); + var result = strain.keep(rows, function (row) { return row.indexOf(5) > -1; }); expect(result).toEqual([[5, 5, 5], [5, 1, 2], [1, 5, 2], [1, 2, 5]]); }); - xit('empty discard', function() { - expect(strain.discard([], function(e) { return e < 10;})).toEqual([]); + xit('empty discard', function () { + expect(strain.discard([], function (e) { return e < 10;})).toEqual([]); }); - xit('discards nothing', function() { - expect(strain.discard([1, 2, 3], function(e) { return e > 10; })).toEqual([1, 2, 3]); + xit('discards nothing', function () { + expect(strain.discard([1, 2, 3], function (e) { return e > 10; })).toEqual([1, 2, 3]); }); - xit('discards first and last', function() { - expect(strain.discard([1, 2, 3], function(e) { return e % 2 === 1; })).toEqual([2]); + xit('discards first and last', function () { + expect(strain.discard([1, 2, 3], function (e) { return e % 2 === 1; })).toEqual([2]); }); - xit('discards neither first nor last', function() { - var result = strain.discard([1, 2, 3, 4, 5], function(e) { return e % 2 === 0; }); + xit('discards neither first nor last', function () { + var result = strain.discard([1, 2, 3, 4, 5], function (e) { return e % 2 === 0; }); expect(result).toEqual([1, 3, 5]); }); - xit('discards strings', function() { + xit('discards strings', function () { var words = 'apple zebra banana zombies cherimoya zelot'.split(' '); - var result = strain.discard(words, function(word) { return word.indexOf('z') === 0; }); + var result = strain.discard(words, function (word) { return word.indexOf('z') === 0; }); expect(result).toEqual('apple banana cherimoya'.split(' ')); }); - xit('discards arrays', function() { + xit('discards arrays', function () { var rows = [ [1, 2, 3], [5, 5, 5], @@ -71,9 +70,8 @@ describe('strain', function() { [2, 2, 1], [1, 2, 5] ]; - var result = strain.discard(rows, function(row) { return row.indexOf(5) > -1; }); + var result = strain.discard(rows, function (row) { return row.indexOf(5) > -1; }); expect(result).toEqual([[1, 2, 3], [2, 1, 2], [2, 2, 1]]); }); - }); diff --git a/exercises/sublist/example.js b/exercises/sublist/example.js index 8b670af2..a1f041f8 100644 --- a/exercises/sublist/example.js +++ b/exercises/sublist/example.js @@ -3,27 +3,27 @@ function List(list) { return { list: this.list, - compare: function(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' - }[lengthDiff(this, other)]; + compare: function (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' + }[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.spec.js b/exercises/sublist/sublist.spec.js index f080c951..bd420bc4 100644 --- a/exercises/sublist/sublist.spec.js +++ b/exercises/sublist/sublist.spec.js @@ -1,126 +1,123 @@ var List = require('./sublist'); -describe('sublist', function() { - - it('two empty lists are equal', function() { +describe('sublist', function () { + it('two empty lists are equal', function () { var listOne = new List(); var listTwo = new List(); expect(listOne.compare(listTwo)).toEqual('EQUAL'); }); - xit('an empty list is a sublist of a non-empty list', function() { + xit('an empty list is a sublist of a non-empty list', function () { var listOne = new List(); var listTwo = new List([1, 2, 3]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); }); - xit('non empty list contains empty list', function() { + xit('non empty list contains empty list', function () { var listOne = new List([1, 2, 3]); var listTwo = new List(); expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); }); - xit('a non-empty list equals itself', function() { + xit('a non-empty list equals itself', function () { var listOne = new List([1, 2, 3]); var listTwo = new List([1, 2, 3]); expect(listOne.compare(listTwo)).toEqual('EQUAL'); }); - xit('two different lists are unequal', function() { + xit('two different lists are unequal', function () { var listOne = new List([1, 2, 3]); var listTwo = new List([2, 3, 4]); expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); }); - xit('false start', function() { + xit('false start', function () { var listOne = new List([1, 2, 5]); var listTwo = new List([0, 1, 2, 3, 1, 2, 5, 6]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); - }); - xit('consecutive', function() { + xit('consecutive', function () { var listOne = new List([1, 1, 2]); var listTwo = new List([0, 1, 1, 1, 2, 1, 2]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); }); - xit('sublist at start', function() { + xit('sublist at start', function () { var listOne = new List([0, 1, 2]); var listTwo = new List([0, 1, 2, 3, 4, 5]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); }); - xit('sublist in middle', function() { + xit('sublist in middle', function () { var listOne = new List([2, 3, 4]); var listTwo = new List([0, 1, 2, 3, 4, 5]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); }); - xit('sublist at end', function() { + xit('sublist at end', function () { var listOne = new List([3, 4, 5]); var listTwo = new List([0, 1, 2, 3, 4, 5]); expect(listOne.compare(listTwo)).toEqual('SUBLIST'); }); - xit('at start of superlist', function() { + xit('at start of superlist', function () { var listOne = new List([0, 1, 2, 3, 4, 5]); var listTwo = new List([0, 1, 2]); expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); }); - xit('in middle of superlist', function() { + xit('in middle of superlist', function () { var listOne = new List([0, 1, 2, 3, 4, 5]); var listTwo = new List([2, 3]); expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); }); - xit('at end of superlist', function() { + xit('at end of superlist', function () { var listOne = new List([0, 1, 2, 3, 4, 5]); var listTwo = new List([3, 4, 5]); expect(listOne.compare(listTwo)).toEqual('SUPERLIST'); }); - xit('first list missing element from second list', function() { + xit('first list missing element from second list', function () { var listOne = new List([1, 3]); var listTwo = new List([1, 2, 3]); expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); }); - xit('second list missing element from first list', function() { + xit('second list missing element from first list', function () { var listOne = new List([1, 2, 3]); var listTwo = new List([1, 3]); expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); }); - xit('order matters to a list', function() { + xit('order matters to a list', function () { var listOne = new List([1, 2, 3]); var listTwo = new List([3, 2, 1]); expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); }); - xit('same digits but different numbers', function() { + xit('same digits but different numbers', function () { var listOne = new List([1, 0, 1]); var listTwo = new List([10, 1]); expect(listOne.compare(listTwo)).toEqual('UNEQUAL'); }); - }); diff --git a/exercises/sum-of-multiples/example.js b/exercises/sum-of-multiples/example.js index 0feb4e00..35d90e20 100644 --- a/exercises/sum-of-multiples/example.js +++ b/exercises/sum-of-multiples/example.js @@ -1,7 +1,7 @@ 'use strict'; function isMultiple(i) { - /*jshint validthis:true */ + /* jshint validthis:true */ var result = false; this.multiples.forEach(function (multiple) { if (i % multiple === 0) { diff --git a/exercises/triangle/example.js b/exercises/triangle/example.js index 0b4fea4d..d3f5f614 100644 --- a/exercises/triangle/example.js +++ b/exercises/triangle/example.js @@ -1,9 +1,9 @@ -function Triangle(a,b,c) { +function Triangle(a, b, c) { 'use strict'; this.sides = [ a, b, c ]; - this.kind = function() { + this.kind = function () { var name = 'scalene'; if (this.isIllegal()) { @@ -17,28 +17,28 @@ function Triangle(a,b,c) { return name; }; - this.isIllegal = function() { + this.isIllegal = function () { return this.violatesInequality() || this.hasImpossibleSides(); }; - this.violatesInequality = function() { + this.violatesInequality = function () { var a = this.sides[0], b = this.sides[1], c = this.sides[2]; return (a + b < c) || (a + c < b) || (b + c < a); }; - this.hasImpossibleSides = function() { + this.hasImpossibleSides = function () { return this.sides[0] <= 0 || this.sides[1] <= 0 || this.sides[2] <= 0; }; - this.isEquilateral = function() { + this.isEquilateral = function () { return this.uniqueSides().length === 1; }; - this.isIsosceles = function() { + this.isIsosceles = function () { return this.uniqueSides().length === 2; }; - this.uniqueSides = function() { + this.uniqueSides = function () { var sides = this.sides; var uniques = {}; diff --git a/exercises/triangle/triangle.spec.js b/exercises/triangle/triangle.spec.js index a23c7a79..fd826893 100644 --- a/exercises/triangle/triangle.spec.js +++ b/exercises/triangle/triangle.spec.js @@ -1,85 +1,83 @@ var Triangle = require('./triangle'); -describe('Triangle', function() { - - it('equilateral triangles have equal sides', function() { - var triangle = new Triangle(2,2,2); +describe('Triangle', function () { + it('equilateral triangles have equal sides', function () { + var triangle = new Triangle(2, 2, 2); expect(triangle.kind()).toEqual('equilateral'); }); - xit('larger equilateral triangles also have equal sides', function() { - var triangle = new Triangle(10,10,10); + xit('larger equilateral triangles also have equal sides', function () { + var triangle = new Triangle(10, 10, 10); expect(triangle.kind()).toEqual('equilateral'); }); - xit('isosceles triangles have last two sides equal', function() { - var triangle = new Triangle(3,4,4); + xit('isosceles triangles have last two sides equal', function () { + var triangle = new Triangle(3, 4, 4); expect(triangle.kind()).toEqual('isosceles'); }); - xit('isosceles triangles have first two sides equal', function() { - var triangle = new Triangle(2,2,3); + xit('isosceles triangles have first two sides equal', function () { + var triangle = new Triangle(2, 2, 3); expect(triangle.kind()).toEqual('isosceles'); }); - xit('isosceles trianges have first and last sides equal', function() { - var triangle = new Triangle(4,3,4); + xit('isosceles trianges have first and last sides equal', function () { + var triangle = new Triangle(4, 3, 4); expect(triangle.kind()).toEqual('isosceles'); }); - xit('isosceles triangles have two first sides equal', function() { - var triangle = new Triangle(4,4,3); + xit('isosceles triangles have two first sides equal', function () { + var triangle = new Triangle(4, 4, 3); expect(triangle.kind()).toEqual('isosceles'); }); - xit('isosceles triangles have in fact exactly two sides equal', function() { - var triangle = new Triangle(10,10,2); + xit('isosceles triangles have in fact exactly two sides equal', function () { + var triangle = new Triangle(10, 10, 2); expect(triangle.kind()).toEqual('isosceles'); }); - xit('scalene triangles have no equal sides', function() { - var triangle = new Triangle(3,4,5); + xit('scalene triangles have no equal sides', function () { + var triangle = new Triangle(3, 4, 5); expect(triangle.kind()).toEqual('scalene'); }); - xit('scalene triangles have no equal sides at a larger scale too', function() { - var triangle = new Triangle(10,11,12); + xit('scalene triangles have no equal sides at a larger scale too', function () { + var triangle = new Triangle(10, 11, 12); expect(triangle.kind()).toEqual('scalene'); }); - xit('scalene triangles have no equal sides in descending order either', function() { - var triangle = new Triangle(5,4,2); + xit('scalene triangles have no equal sides in descending order either', function () { + var triangle = new Triangle(5, 4, 2); expect(triangle.kind()).toEqual('scalene'); }); - xit('very small triangles are legal', function() { - var triangle = new Triangle(0.4,0.6,0.3); + xit('very small triangles are legal', function () { + var triangle = new Triangle(0.4, 0.6, 0.3); expect(triangle.kind()).toEqual('scalene'); }); - xit('test triangles with no size are illegal', function() { - var triangle = new Triangle(0,0,0); + xit('test triangles with no size are illegal', function () { + var triangle = new Triangle(0, 0, 0); expect(triangle.kind.bind(triangle)).toThrow(); }); - xit('triangles with negative sides are illegal', function() { - var triangle = new Triangle(3,4,-5); + xit('triangles with negative sides are illegal', function () { + var triangle = new Triangle(3, 4, -5); expect(triangle.kind.bind(triangle)).toThrow(); }); - xit('triangles violating triangle inequality are illegal', function() { - var triangle = new Triangle(1,1,3); + xit('triangles violating triangle inequality are illegal', function () { + var triangle = new Triangle(1, 1, 3); expect(triangle.kind.bind(triangle)).toThrow(); }); - xit('triangles violating triangle inequality are illegal 2', function() { - var triangle = new Triangle(7,3,2); + xit('triangles violating triangle inequality are illegal 2', function () { + var triangle = new Triangle(7, 3, 2); expect(triangle.kind.bind(triangle)).toThrow(); }); - xit('triangles violating triangle inequality are illegal 3', function() { - var triangle = new Triangle(10,1,3); + xit('triangles violating triangle inequality are illegal 3', function () { + var triangle = new Triangle(10, 1, 3); expect(triangle.kind.bind(triangle)).toThrow(); }); - }); diff --git a/exercises/trinary/example.js b/exercises/trinary/example.js index d6294340..15c0c90b 100644 --- a/exercises/trinary/example.js +++ b/exercises/trinary/example.js @@ -8,11 +8,11 @@ function Trinary(decimal) { this.digits = decimal.split('').reverse().map(Number); } -Trinary.prototype.toDecimal = function() { +Trinary.prototype.toDecimal = function () { var decimal = this.digits.reduce(this.accumulator, 0); return isNaN(decimal) ? 0 : decimal; }; -Trinary.prototype.accumulator = function(decimal, digit, index) { +Trinary.prototype.accumulator = function (decimal, digit, index) { return decimal += digit * Math.pow(BASE, index); }; diff --git a/exercises/trinary/trinary.spec.js b/exercises/trinary/trinary.spec.js index 792df1c7..202fce1c 100644 --- a/exercises/trinary/trinary.spec.js +++ b/exercises/trinary/trinary.spec.js @@ -1,41 +1,39 @@ var Trinary = require('./trinary'); describe('Trinary', function () { - - it('1 is decimal 1', function() { + it('1 is decimal 1', function () { expect(new Trinary('1').toDecimal()).toEqual(1); }); - xit('2 is decimal 2', function() { + xit('2 is decimal 2', function () { expect(new Trinary('2').toDecimal()).toEqual(2); }); - xit('10 is decimal 3', function() { + xit('10 is decimal 3', function () { expect(new Trinary('10').toDecimal()).toEqual(3); }); - xit('11 is decimal 4', function() { + xit('11 is decimal 4', function () { expect(new Trinary('11').toDecimal()).toEqual(4); }); - xit('100 is decimal 9', function() { + xit('100 is decimal 9', function () { expect(new Trinary('100').toDecimal()).toEqual(9); }); - xit('112 is decimal 14', function() { + xit('112 is decimal 14', function () { expect(new Trinary('112').toDecimal()).toEqual(14); }); - xit('222 is 26', function() { + xit('222 is 26', function () { expect(new Trinary('222').toDecimal()).toEqual(26); }); - xit('1122000120 is 32091', function() { + xit('1122000120 is 32091', function () { expect(new Trinary('1122000120').toDecimal()).toEqual(32091); }); - xit('invalid trinary is decimal 0', function() { + xit('invalid trinary is decimal 0', function () { expect(new Trinary('carrot').toDecimal()).toEqual(0); }); - }); diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index c6be2d57..48ea4d08 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -1,14 +1,14 @@ 'use strict'; -function TwoBucket(x,y,z,starter) { +function TwoBucket(x, y, z, starter) { this.starter = starter; this.x = x; this.y = y; - this.reachedGoal = function(measurements) { + this.reachedGoal = function (measurements) { var reached = false; - if(measurements[0] == z || measurements[1] == z) { - if(measurements[0] == z) { + if (measurements[0] == z || measurements[1] == z) { + if (measurements[0] == z) { this.goalBucket = 'one'; this.otherBucket = measurements[1]; } else { @@ -20,51 +20,51 @@ function TwoBucket(x,y,z,starter) { return reached; }; - this.bigFirst = function(measurements, moveCount, prBool) { + this.bigFirst = function (measurements, moveCount, prBool) { var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(k > x && j == 0 && moveCount == 0) { + while (true) { + if (this.reachedGoal(measurements)) break; + if (k > x && j == 0 && moveCount == 0) { j = x; k = y - j; - } else if(j == x) { + } else if (j == x) { j = 0; - } else if((k > x && j !== 0) || (k > x && prBool)) { - k = k - (x-j); + } else if ((k > x && j !== 0) || (k > x && prBool)) { + k = k - (x - j); j = x; - } else if(k > x || j == 0) { + } else if (k > x || j == 0) { j = k; k = k - j; - } else if(k == 0) { + } else if (k == 0) { k = y; } - measurements = [j,k]; + measurements = [j, k]; moveCount++; prBool ? prBool = false : prBool = true; } return moveCount; }; - this.smallFirst = function(measurements, moveCount, prBool) { + this.smallFirst = function (measurements, moveCount, prBool) { var j = measurements[0], k = measurements[1]; - while(true) { - if(this.reachedGoal(measurements)) break; - if(j == x && moveCount == 0) { + while (true) { + if (this.reachedGoal(measurements)) break; + if (j == x && moveCount == 0) { j = 0; k = x; - } else if(j == 0) { + } else if (j == 0) { j = x; - } else if(j == x && k < y) { + } else if (j == x && k < y) { var tempK = k; k + j > y ? k = y : k = tempK + j; - tempK + j > y ? j = j - (y- tempK) : j = 0; - } else if(k == y) { + tempK + j > y ? j = j - (y - tempK) : j = 0; + } else if (k == y) { k = 0; - } else if(k == 0 && j < x) { + } else if (k == 0 && j < x) { k = j; j = 0; } - measurements = [j,k]; + measurements = [j, k]; moveCount++; prBool ? prBool = false : prBool = true; } @@ -72,18 +72,18 @@ function TwoBucket(x,y,z,starter) { }; } -TwoBucket.prototype.moves = function() { - var j = 0, k = 0; //j will be running val of bucket one, k = running val of bucket two +TwoBucket.prototype.moves = function () { + var j = 0, k = 0; // j will be running val of bucket one, k = running val of bucket two this.starter == 'one' ? j = this.x : k = this.y; - var measurements = [j,k]; + var measurements = [j, k]; var moveCount = 0; var prBool = true; // pour / receive boolean - need to pour or receive every other turn - if(this.starter == 'one') { + if (this.starter == 'one') { moveCount = this.smallFirst(measurements, moveCount, prBool); } else { moveCount = this.bigFirst(measurements, moveCount, prBool); } - return moveCount + 1; //accounts for first move made before loop (and moveCount starts at zero before loop) + return moveCount + 1; // accounts for first move made before loop (and moveCount starts at zero before loop) }; module.exports = TwoBucket; diff --git a/exercises/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js index 412a4cde..756db3f5 100644 --- a/exercises/two-bucket/two-bucket.spec.js +++ b/exercises/two-bucket/two-bucket.spec.js @@ -1,44 +1,44 @@ var TwoBucket = require('./two-bucket'); -describe('TwoBucket', function(){ - describe('works for input of 3,5,1', function(){ +describe('TwoBucket', function () { + describe('works for input of 3,5,1', function () { var buckOne = 3; var buckTwo = 5; var goal = 1; - it('starting with bucket one', function(){ - var starterBuck = 'one'; //indicates which bucket to fill first - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); - expect(twoBucket.moves()).toEqual(4); //includes the first fill - expect(twoBucket.goalBucket).toEqual('one'); //which bucket should end up with the desired # of liters - expect(twoBucket.otherBucket).toEqual(5); //leftover value in the "other" bucket once the goal has been reached + it('starting with bucket one', function () { + var starterBuck = 'one'; // indicates which bucket to fill first + var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); + expect(twoBucket.moves()).toEqual(4); // includes the first fill + expect(twoBucket.goalBucket).toEqual('one'); // which bucket should end up with the desired # of liters + expect(twoBucket.otherBucket).toEqual(5); // leftover value in the "other" bucket once the goal has been reached }); - xit('starting with bucket two', function(){ + xit('starting with bucket two', function () { var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); expect(twoBucket.moves()).toEqual(8); expect(twoBucket.goalBucket).toEqual('two'); expect(twoBucket.otherBucket).toEqual(3); }); }); - describe('works for input of 7,11,2', function(){ + describe('works for input of 7,11,2', function () { var buckOne = 7; var buckTwo = 11; var goal = 2; - xit('starting with bucket one', function(){ + xit('starting with bucket one', function () { var starterBuck = 'one'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); expect(twoBucket.moves()).toEqual(14); expect(twoBucket.goalBucket).toEqual('one'); expect(twoBucket.otherBucket).toEqual(11); }); - xit('starting with bucket two', function(){ + xit('starting with bucket two', function () { var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne,buckTwo,goal,starterBuck); + var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); expect(twoBucket.moves()).toEqual(18); expect(twoBucket.goalBucket).toEqual('two'); expect(twoBucket.otherBucket).toEqual(7); diff --git a/exercises/word-count/example.js b/exercises/word-count/example.js index 2a357994..34a07d19 100644 --- a/exercises/word-count/example.js +++ b/exercises/word-count/example.js @@ -5,9 +5,9 @@ function Words() {} Words.prototype.count = function (input) { var counts = {}; var words = input.toLowerCase() - .replace(/[,."\/!&@$%\^\*;:{}()¡¿?]/g, ' ') - .replace(/\s'(\w+)'\s/, ' '+'$1'+' ') - .match(/\S+/g); + .replace(/[,."\/!&@$%\^\*;:{}()¡¿?]/g, ' ') + .replace(/\s'(\w+)'\s/, ' ' + '$1' + ' ') + .match(/\S+/g); words.forEach(function (word) { counts[word] = counts.hasOwnProperty(word) ? counts[word] + 1 : 1; diff --git a/exercises/word-count/word-count.spec.js b/exercises/word-count/word-count.spec.js index 8b34faf0..71bb0235 100644 --- a/exercises/word-count/word-count.spec.js +++ b/exercises/word-count/word-count.spec.js @@ -1,79 +1,79 @@ var Words = require('./word-count'); -describe('count()', function() { +describe('count()', function () { var words = new Words(); - it('counts one word', function() { + it('counts one word', function () { var expectedCounts = { word: 1 }; expect(words.count('word')).toEqual(expectedCounts); }); - xit('counts one of each word', function() { + xit('counts one of each word', function () { var expectedCounts = { one: 1, of: 1, each: 1 }; expect(words.count('one of each')).toEqual(expectedCounts); }); - xit('counts multiple occurrences of a word', function() { + xit('counts multiple occurrences of a word', function () { var expectedCounts = { one: 1, fish: 4, two: 1, red: 1, blue: 1 }; expect(words.count('one fish two fish red fish blue fish')).toEqual(expectedCounts); }); - xit('handles cramped lists', function() { + xit('handles cramped lists', function () { var expectedCounts = { one: 1, two: 1, three: 1 }; expect(words.count('one,two,three')).toEqual(expectedCounts); }); - xit('ignores punctuation', function() { + xit('ignores punctuation', function () { var expectedCounts = { car: 1, carpet: 1, as: 1, java: 1, javascript: 1 }; expect(words.count('car : carpet as java: javascript!!&@$%^&')).toEqual(expectedCounts); }); - xit('includes numbers', function() { + xit('includes numbers', function () { var expectedCounts = { testing: 2, 1: 1, 2: 1 }; expect(words.count('testing 1 2 testing')).toEqual(expectedCounts); }); - xit('normalizes to lowercase', function() { + xit('normalizes to lowercase', function () { var expectedCounts = { go: 3 }; expect(words.count('go Go GO')).toEqual(expectedCounts); }); - xit('counts words with apostrophes', function() { + xit('counts words with apostrophes', function () { var expectedCounts = { 'first': 1, 'don\'t': 2, 'laugh': 1, 'then': 1, 'cry': 1 }; expect(words.count('First: don\'t laugh. Then: don\'t cry.')).toEqual(expectedCounts); }); - xit('counts words with quotations', function() { + xit('counts words with quotations', function () { var expectedCounts = { 'joe': 1, 'can\'t': 1, 'tell': 1, 'between': 1, 'large': 2, 'and': 1 }; expect(words.count('Joe can\'t tell between \'large\' and large.')).toEqual(expectedCounts); }); - xit('counts properly international characters', function() { + xit('counts properly international characters', function () { var expectedCounts = { 'hola': 1, 'qué': 1, 'tal': 1, 'привет': 1 }; expect(words.count('¡Hola! ¿Qué tal? Привет!')).toEqual(expectedCounts); }); - xit('counts multiline', function() { + xit('counts multiline', function () { var expectedCounts = { hello: 1, world: 1 }; expect(words.count('hello\nworld')).toEqual(expectedCounts); }); - xit('counts tabs as white space', function() { + xit('counts tabs as white space', function () { var expectedCounts = { hello: 1, world: 1 }; expect(words.count('hello\tworld')).toEqual(expectedCounts); }); - xit('counts multiple spaces as one', function() { + xit('counts multiple spaces as one', function () { var expectedCounts = { hello: 1, world: 1 }; expect(words.count('hello world')).toEqual(expectedCounts); }); - xit('does not count leading or trailing whitespace', function() { + xit('does not count leading or trailing whitespace', function () { var expectedCounts = { introductory: 1, course: 1 }; expect(words.count('\t\tIntroductory Course ')).toEqual(expectedCounts); }); - xit('handles properties that exist on Object’s prototype', function() { + xit('handles properties that exist on Object’s prototype', function () { var expectedCounts = { reserved: 1, words: 1, like: 1, constructor: 1, and: 1, tostring: 1, ok: 1 }; expect(words.count('reserved words like constructor and toString ok?')).toEqual(expectedCounts); }); diff --git a/exercises/wordy/example.js b/exercises/wordy/example.js index 693fb2fe..ce01bbd7 100644 --- a/exercises/wordy/example.js +++ b/exercises/wordy/example.js @@ -4,10 +4,10 @@ exports.WordProblem = WordProblem; exports.ArgumentError = ArgumentError; var BINARY_OPERATORS = { - 'plus': function(l, r) { return l + r; }, - 'minus': function(l, r) { return l - r; }, - 'multiplied by': function(l, r) { return l * r; }, - 'divided by': function(l, r) { return l / r; } + 'plus': function (l, r) { return l + r; }, + 'minus': function (l, r) { return l - r; }, + 'multiplied by': function (l, r) { return l * r; }, + 'divided by': function (l, r) { return l / r; } }; function operators() { @@ -32,18 +32,18 @@ function WordProblem(question) { this.matches = this.question.match(pattern()); } -WordProblem.prototype.tooComplicated = function() { +WordProblem.prototype.tooComplicated = function () { return this.matches === null; }; -WordProblem.prototype.answer = function() { +WordProblem.prototype.answer = function () { if (this.tooComplicated()) { throw new ArgumentError('I don\'t understand the question'); } return this.evaluate(); }; -WordProblem.prototype.evaluate = function() { +WordProblem.prototype.evaluate = function () { var out = 0; var m = this.matches; @@ -58,8 +58,8 @@ WordProblem.prototype.evaluate = function() { return out; }; -WordProblem.prototype.operate = function(operation, l, r) { - var fn = BINARY_OPERATORS[operation] || function() { return 0; }; +WordProblem.prototype.operate = function (operation, l, r) { + var fn = BINARY_OPERATORS[operation] || function () { return 0; }; return fn(Number(l), Number(r)); }; diff --git a/exercises/wordy/wordy.spec.js b/exercises/wordy/wordy.spec.js index 01d5dc4d..6e0a73af 100644 --- a/exercises/wordy/wordy.spec.js +++ b/exercises/wordy/wordy.spec.js @@ -1,90 +1,88 @@ var WordProblem = require('./wordy').WordProblem; var ArgumentError = require('./wordy').ArgumentError; -describe('Word Problem', function() { - - it('add 1', function() { +describe('Word Problem', function () { + it('add 1', function () { var question = 'What is 1 plus 1?'; expect(new WordProblem(question).answer()).toEqual(2); }); - xit('add 2', function() { + xit('add 2', function () { var question = 'What is 53 plus 2?'; expect(new WordProblem(question).answer()).toEqual(55); }); - xit('add negative numbers', function() { + xit('add negative numbers', function () { var question = 'What is -1 plus -10?'; expect(new WordProblem(question).answer()).toEqual(-11); }); - xit('add more digits', function() { + xit('add more digits', function () { var question = 'What is 123 plus 45678?'; expect(new WordProblem(question).answer()).toEqual(45801); }); - xit('subtract', function() { + xit('subtract', function () { var question = 'What is 4 minus -12?'; expect(new WordProblem(question).answer()).toEqual(16); }); - xit('multiply', function() { + xit('multiply', function () { var question = 'What is -3 multiplied by 25?'; expect(new WordProblem(question).answer()).toEqual(-75); }); - xit('divide', function() { + xit('divide', function () { var question = 'What is 33 divided by -3?'; expect(new WordProblem(question).answer()).toEqual(-11); }); - xit('add twice', function() { + xit('add twice', function () { var question = 'What is 1 plus 1 plus 1?'; expect(new WordProblem(question).answer()).toEqual(3); }); - xit('add then subtract', function() { + xit('add then subtract', function () { var question = 'What is 1 plus 5 minus -2?'; expect(new WordProblem(question).answer()).toEqual(8); }); - xit('subtract twice', function() { + xit('subtract twice', function () { var question = 'What is 20 minus 4 minus 13?'; expect(new WordProblem(question).answer()).toEqual(3); }); - xit('subtract then add', function() { + xit('subtract then add', function () { var question = 'What is 17 minus 6 plus 3?'; expect(new WordProblem(question).answer()).toEqual(14); }); - xit('multiply twice', function() { + xit('multiply twice', function () { var question = 'What is 2 multiplied by -2 multiplied by 3?'; expect(new WordProblem(question).answer()).toEqual(-12); }); - xit('add then multiply', function() { + xit('add then multiply', function () { var question = 'What is -3 plus 7 multiplied by -2?'; expect(new WordProblem(question).answer()).toEqual(-8); }); - xit('divide twice', function() { + xit('divide twice', function () { var question = 'What is -12 divided by 2 divided by -3?'; expect(new WordProblem(question).answer()).toEqual(2); }); - xit('too advanced', function() { + xit('too advanced', function () { var question = 'What is 53 cubed?'; var problem = new WordProblem(question); expect(problem.answer.bind(problem)).toThrow(new ArgumentError()); }); - xit('irrelevant', function() { + xit('irrelevant', function () { var question = 'Who is the president of the United States?'; var problem = new WordProblem(question); expect(problem.answer.bind(problem)).toThrow(new ArgumentError()); }); - }); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..5429eb3b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1842 @@ +{ + "name": "javascript", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "acorn": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", + "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", + "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "json-schema-traverse": "0.3.1", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.0" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.8.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "babel-code-frame": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz", + "integrity": "sha512-/xr1ADm5bnTjjN+xwoXb7lF4v2rnxMzNZzFU7h8SxB+qB6+IqSTOOqVcpaPTUC2Non/MbQxS3OIZnJpQ2X21aQ==", + "dev": true, + "requires": { + "chalk": "2.1.0", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-eslint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.0.1.tgz", + "integrity": "sha512-h3moF6PCTQE06UjMMG+ydZSBvZ4Q7rqPE/5WAUOvUyHYUTqxm8JVhjZRiG1avI/tGVOK4BnZLDQapyLzh8DeKg==", + "dev": true, + "requires": { + "babel-code-frame": "7.0.0-beta.0", + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22" + } + }, + "babel-helper-function-name": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz", + "integrity": "sha512-DaQccFBBWBEzMdqbKmNXamY0m1yLHJGOdbbEsNoGdJrrU7wAF3wwowtDDPzF0ZT3SqJXPgZW/P2kgBX9moMuAA==", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "7.0.0-beta.0", + "babel-template": "7.0.0-beta.0", + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0" + } + }, + "babel-helper-get-function-arity": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz", + "integrity": "sha512-csqAic15/2Vm1951nJxkkL9K8E6ojyNF/eAOjk7pqJlO8kvgrccGNFCV9eDwcGHDPe5AjvJGwVSAcQ5fit9wuA==", + "dev": true, + "requires": { + "babel-types": "7.0.0-beta.0" + } + }, + "babel-messages": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-7.0.0-beta.0.tgz", + "integrity": "sha512-eXdShsm9ZTh9AQhlIaAn6HR3xWpxCnK9ZwIDA9QyjnwTgMctGxHHflw4b4RJ3/ZjTL0Vrmvm0tQXPkp49mTAUw==", + "dev": true + }, + "babel-template": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-7.0.0-beta.0.tgz", + "integrity": "sha512-tmdH+MmmU0F6Ur8humpevSmFzYKbrN3Oru0g5Qyg4R6+sxjnzZmnvzUbsP0aKMr7tB0Ua6xhEb9arKTOsEMkyA==", + "dev": true, + "requires": { + "babel-traverse": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22", + "lodash": "4.17.4" + } + }, + "babel-traverse": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz", + "integrity": "sha512-IKzuTqUcQtMRZ0Vv5RjIrGGj33eBKmNTNeRexWSyjPPuAciyNkva1rt7WXPfHfkb+dX7coRAIUhzeTUEzhnwdA==", + "dev": true, + "requires": { + "babel-code-frame": "7.0.0-beta.0", + "babel-helper-function-name": "7.0.0-beta.0", + "babel-messages": "7.0.0-beta.0", + "babel-types": "7.0.0-beta.0", + "babylon": "7.0.0-beta.22", + "debug": "3.1.0", + "globals": "10.1.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "babel-types": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-7.0.0-beta.0.tgz", + "integrity": "sha512-rJc2kV9iPJGLlqIY71AM3nPcdkoeLRCDuR07GFgfd3lFl4TsBQq76TxYQQIZ2MONg1HpsqmuoCXr9aZ1Oa4wYw==", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "2.0.0" + } + }, + "babylon": { + "version": "7.0.0-beta.22", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.22.tgz", + "integrity": "sha512-Yl7iT8QGrS8OfR7p6R12AJexQm+brKwrryai4VWZ7NHUbPoZ5al3+klhvl/14shXZiLa7uK//OIFuZ1/RKHgoA==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", + "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.4.0" + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.8.2.tgz", + "integrity": "sha512-dvhwFL3yjQxNNsOWx6exMlaDrRHCRGMQlnx5lsXDCZ/J7G/frgIIl94zhZSp/galVAYp7VzPi1OrAHta89/yGQ==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.7.2.tgz", + "integrity": "sha1-/29fUZOEiifum2J74+c/ucteZi4=", + "dev": true, + "requires": { + "ajv": "5.2.3", + "babel-code-frame": "6.26.0", + "chalk": "2.1.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.0", + "eslint-scope": "3.7.1", + "espree": "3.5.1", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.5", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", + "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "0.1.1" + } + }, + "eslint-config-airbnb-es5": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-es5/-/eslint-config-airbnb-es5-1.2.0.tgz", + "integrity": "sha512-MaOKwNpqNZIRy+3augFj5vGHJ4F1sskPjJ/Od7K3N8Vv+8pD6t73XCL18KrHrF1m58qFxPBDl1US6bswE65IbQ==", + "dev": true, + "requires": { + "strip-json-comments": "1.0.2" + }, + "dependencies": { + "strip-json-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.2.tgz", + "integrity": "sha1-WkirlgI9usG3uND/q/b2PxZ3vp8=", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", + "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", + "dev": true, + "requires": { + "debug": "2.6.8", + "resolve": "1.4.0" + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "requires": { + "debug": "2.6.8", + "pkg-dir": "1.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", + "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "dev": true, + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.1", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + } + }, + "eslint-plugin-jasmine": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.8.4.tgz", + "integrity": "sha1-Z6VVHj0dXguMa1Sq66uVNw9dN94=", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", + "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", + "dev": true, + "requires": { + "doctrine": "2.0.0", + "has": "1.0.1", + "jsx-ast-utils": "2.0.1", + "prop-types": "15.6.0" + }, + "dependencies": { + "doctrine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", + "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", + "dev": true, + "requires": { + "acorn": "5.1.2", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "external-editor": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", + "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19", + "jschardet": "1.5.1", + "tmp": "0.0.33" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "dev": true, + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.14" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-10.1.0.tgz", + "integrity": "sha1-RCWhiBvg0za0qCOoKnvnJdXdmHw=", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", + "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.1.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.0.5", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "dev": true, + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "jschardet": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", + "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "3.0.3" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dev": true, + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "dev": true, + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", + "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "chalk": "2.1.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", + "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..223aa598 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "javascript", + "version": "1.0.0", + "description": "Exercism exercises in JavaScript.", + "main": "index.js", + "repository": "https://github.com/exercism/javascript", + "author": "Katrina Owen", + "license": "MIT", + "devDependencies": { + "babel-eslint": "^8.0.0", + "eslint": "^4.6.1", + "eslint-config-airbnb-base": "^12.0.0", + "eslint-config-airbnb-es5": "^1.2.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-jasmine": "^2.8.4", + "eslint-plugin-react": "^7.3.0" + }, + "scripts": { + "lint": "eslint .", + "lint-fix": "eslint . --fix" + } +} From f3e3a21e8c9be8d0cbc94a49c5e56f85a4c1b86a Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 18:40:00 +0100 Subject: [PATCH 154/272] Conform to terminology in canonical data https://github.com/exercism/problem-specifications/blob/master/exercises/two-bucket/canonical-data.json --- exercises/two-bucket/two-bucket.spec.js | 36 ++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/exercises/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js index 756db3f5..248b7ab4 100644 --- a/exercises/two-bucket/two-bucket.spec.js +++ b/exercises/two-bucket/two-bucket.spec.js @@ -1,44 +1,44 @@ var TwoBucket = require('./two-bucket'); describe('TwoBucket', function () { - describe('works for input of 3,5,1', function () { - var buckOne = 3; - var buckTwo = 5; + describe('Measure using bucket one of size 3 and bucket two of size 5 - ', function () { + var bucketOne = 3; + var bucketTwo = 5; var goal = 1; - it('starting with bucket one', function () { - var starterBuck = 'one'; // indicates which bucket to fill first - var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); + it('start with bucket one', function () { + var twoBucket = new TwoBucket(bucketOne, bucketTwo, goal, 'one'); + expect(twoBucket.moves()).toEqual(4); // includes the first fill expect(twoBucket.goalBucket).toEqual('one'); // which bucket should end up with the desired # of liters expect(twoBucket.otherBucket).toEqual(5); // leftover value in the "other" bucket once the goal has been reached }); - xit('starting with bucket two', function () { - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); + xit('start with bucket two', function () { + var twoBucket = new TwoBucket(bucketOne, bucketTwo, goal, 'two'); + expect(twoBucket.moves()).toEqual(8); expect(twoBucket.goalBucket).toEqual('two'); expect(twoBucket.otherBucket).toEqual(3); }); }); - describe('works for input of 7,11,2', function () { - var buckOne = 7; - var buckTwo = 11; + describe('Measure using bucket one of size 7 and bucket two of size 11 - ', function () { + var bucketOne = 7; + var bucketTwo = 11; var goal = 2; - xit('starting with bucket one', function () { - var starterBuck = 'one'; - var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); + xit('start with bucket one', function () { + var twoBucket = new TwoBucket(bucketOne, bucketTwo, goal, 'one'); + expect(twoBucket.moves()).toEqual(14); expect(twoBucket.goalBucket).toEqual('one'); expect(twoBucket.otherBucket).toEqual(11); }); - xit('starting with bucket two', function () { - var starterBuck = 'two'; - var twoBucket = new TwoBucket(buckOne, buckTwo, goal, starterBuck); + xit('start with bucket two', function () { + var twoBucket = new TwoBucket(bucketOne, bucketTwo, goal, 'two'); + expect(twoBucket.moves()).toEqual(18); expect(twoBucket.goalBucket).toEqual('two'); expect(twoBucket.otherBucket).toEqual(7); From 785994f261c50fc51a715c1d600cd1394d03b713 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 18:47:57 +0100 Subject: [PATCH 155/272] Rename variables to sane names --- exercises/two-bucket/example.js | 68 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 48ea4d08..05e8ce1f 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -1,14 +1,15 @@ 'use strict'; -function TwoBucket(x, y, z, starter) { - this.starter = starter; - this.x = x; - this.y = y; +function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { + this.startBucket = startBucket; + this.bucketOne = bucketOne; + this.bucketTwo = bucketTwo; + this.goal = goal; this.reachedGoal = function (measurements) { var reached = false; - if (measurements[0] == z || measurements[1] == z) { - if (measurements[0] == z) { + if (measurements[0] === goal || measurements[1] === goal) { + if (measurements[0] === goal) { this.goalBucket = 'one'; this.otherBucket = measurements[1]; } else { @@ -21,22 +22,23 @@ function TwoBucket(x, y, z, starter) { }; this.bigFirst = function (measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; + var j = measurements[0]; + var k = measurements[1]; while (true) { if (this.reachedGoal(measurements)) break; - if (k > x && j == 0 && moveCount == 0) { - j = x; - k = y - j; - } else if (j == x) { + if (k > bucketOne && j === 0 && moveCount === 0) { + j = bucketOne; + k = bucketTwo - j; + } else if (j === bucketOne) { j = 0; - } else if ((k > x && j !== 0) || (k > x && prBool)) { - k = k - (x - j); - j = x; - } else if (k > x || j == 0) { + } else if ((k > bucketOne && j !== 0) || (k > bucketOne && prBool)) { + k = k - (bucketOne - j); + j = bucketOne; + } else if (k > bucketOne || j === 0) { j = k; k = k - j; - } else if (k == 0) { - k = y; + } else if (k === 0) { + k = bucketTwo; } measurements = [j, k]; moveCount++; @@ -46,21 +48,22 @@ function TwoBucket(x, y, z, starter) { }; this.smallFirst = function (measurements, moveCount, prBool) { - var j = measurements[0], k = measurements[1]; + var j = measurements[0]; + var k = measurements[1]; while (true) { if (this.reachedGoal(measurements)) break; - if (j == x && moveCount == 0) { + if (j === bucketOne && moveCount === 0) { j = 0; - k = x; - } else if (j == 0) { - j = x; - } else if (j == x && k < y) { + k = bucketOne; + } else if (j === 0) { + j = bucketOne; + } else if (j === bucketOne && k < bucketTwo) { var tempK = k; - k + j > y ? k = y : k = tempK + j; - tempK + j > y ? j = j - (y - tempK) : j = 0; - } else if (k == y) { + k + j > bucketTwo ? k = bucketTwo : k = tempK + j; + tempK + j > bucketTwo ? j = j - (bucketTwo - tempK) : j = 0; + } else if (k === bucketTwo) { k = 0; - } else if (k == 0 && j < x) { + } else if (k === 0 && j < bucketOne) { k = j; j = 0; } @@ -73,17 +76,18 @@ function TwoBucket(x, y, z, starter) { } TwoBucket.prototype.moves = function () { - var j = 0, k = 0; // j will be running val of bucket one, k = running val of bucket two - this.starter == 'one' ? j = this.x : k = this.y; + var j = 0; // j will be running val of bucket one, + var k = 0; // k will be running val of bucket two + this.startBucket === 'one' ? j = this.bucketOne : k = this.bucketTwo; var measurements = [j, k]; var moveCount = 0; - var prBool = true; // pour / receive boolean - need to pour or receive every other turn - if (this.starter == 'one') { + var prBool = true; // pour / receive boolean - need to pour or receive everbucketTwo other turn + if (this.startBucket === 'one') { moveCount = this.smallFirst(measurements, moveCount, prBool); } else { moveCount = this.bigFirst(measurements, moveCount, prBool); } - return moveCount + 1; // accounts for first move made before loop (and moveCount starts at zero before loop) + return moveCount + 1; // accounts for first move made before loop (and moveCount starts at goalero before loop) }; module.exports = TwoBucket; From 2bdb9bd6b572e092aba1755eb60c545512f46caf Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 19:33:24 +0100 Subject: [PATCH 156/272] Remove unnecessary temp variables --- exercises/two-bucket/example.js | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 05e8ce1f..2d47f6ff 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -1,13 +1,12 @@ 'use strict'; function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { - this.startBucket = startBucket; this.bucketOne = bucketOne; this.bucketTwo = bucketTwo; this.goal = goal; + this.startBucket = startBucket; this.reachedGoal = function (measurements) { - var reached = false; if (measurements[0] === goal || measurements[1] === goal) { if (measurements[0] === goal) { this.goalBucket = 'one'; @@ -16,14 +15,15 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { this.goalBucket = 'two'; this.otherBucket = measurements[0]; } - reached = true; + return true; } - return reached; + return false; }; - this.bigFirst = function (measurements, moveCount, prBool) { + this.bigFirst = function (measurements, prBool) { var j = measurements[0]; var k = measurements[1]; + var moveCount = 0; while (true) { if (this.reachedGoal(measurements)) break; if (k > bucketOne && j === 0 && moveCount === 0) { @@ -47,9 +47,10 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { return moveCount; }; - this.smallFirst = function (measurements, moveCount, prBool) { + this.smallFirst = function (measurements, prBool) { var j = measurements[0]; var k = measurements[1]; + var moveCount = 0; while (true) { if (this.reachedGoal(measurements)) break; if (j === bucketOne && moveCount === 0) { @@ -73,21 +74,20 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { } return moveCount; }; -} -TwoBucket.prototype.moves = function () { - var j = 0; // j will be running val of bucket one, - var k = 0; // k will be running val of bucket two - this.startBucket === 'one' ? j = this.bucketOne : k = this.bucketTwo; - var measurements = [j, k]; - var moveCount = 0; - var prBool = true; // pour / receive boolean - need to pour or receive everbucketTwo other turn - if (this.startBucket === 'one') { - moveCount = this.smallFirst(measurements, moveCount, prBool); - } else { - moveCount = this.bigFirst(measurements, moveCount, prBool); - } - return moveCount + 1; // accounts for first move made before loop (and moveCount starts at goalero before loop) -}; + this.moves = function () { + var j = 0; // j will be running val of bucket one, + var k = 0; // k will be running val of bucket two + this.startBucket === 'one' ? j = this.bucketOne : k = this.bucketTwo; + var measurements = [j, k]; + var prBool = true; // pour / receive boolean - need to pour or receive everbucketTwo other turn + if (this.startBucket === 'one') { + measurements = [this.bucketOne, 0]; + return this.smallFirst(measurements, prBool) + 1; + } + measurements = [0, this.bucketTwo]; + return this.bigFirst(measurements, prBool) + 1; + }; +} module.exports = TwoBucket; From f37666a84b0bfd385e392b1137f3908df944341a Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 20:00:24 +0100 Subject: [PATCH 157/272] Refactor moves and recordGoal --- exercises/two-bucket/example.js | 53 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 2d47f6ff..89259d71 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -7,31 +7,35 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { this.startBucket = startBucket; this.reachedGoal = function (measurements) { - if (measurements[0] === goal || measurements[1] === goal) { - if (measurements[0] === goal) { - this.goalBucket = 'one'; - this.otherBucket = measurements[1]; - } else { - this.goalBucket = 'two'; - this.otherBucket = measurements[0]; - } - return true; + return (measurements[0] === goal || measurements[1] === goal); + }; + + this.recordGoal = function (measurements) { + if (measurements[0] === goal) { + this.goalBucket = 'one'; + this.otherBucket = measurements[1]; + } else { + this.goalBucket = 'two'; + this.otherBucket = measurements[0]; } - return false; }; - this.bigFirst = function (measurements, prBool) { + this.bigFirst = function (measurements) { var j = measurements[0]; var k = measurements[1]; var moveCount = 0; + var pourOrReceive = true; while (true) { - if (this.reachedGoal(measurements)) break; + if (this.reachedGoal(measurements)) { + this.recordGoal(measurements); + break; + } if (k > bucketOne && j === 0 && moveCount === 0) { j = bucketOne; k = bucketTwo - j; } else if (j === bucketOne) { j = 0; - } else if ((k > bucketOne && j !== 0) || (k > bucketOne && prBool)) { + } else if ((k > bucketOne && j !== 0) || (k > bucketOne && pourOrReceive)) { k = k - (bucketOne - j); j = bucketOne; } else if (k > bucketOne || j === 0) { @@ -42,17 +46,21 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { } measurements = [j, k]; moveCount++; - prBool ? prBool = false : prBool = true; + pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } return moveCount; }; - this.smallFirst = function (measurements, prBool) { + this.smallFirst = function (measurements) { var j = measurements[0]; var k = measurements[1]; var moveCount = 0; + var pourOrReceive = true; while (true) { - if (this.reachedGoal(measurements)) break; + if (this.reachedGoal(measurements)) { + this.recordGoal(measurements); + break; + } if (j === bucketOne && moveCount === 0) { j = 0; k = bucketOne; @@ -70,23 +78,16 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { } measurements = [j, k]; moveCount++; - prBool ? prBool = false : prBool = true; + pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } return moveCount; }; this.moves = function () { - var j = 0; // j will be running val of bucket one, - var k = 0; // k will be running val of bucket two - this.startBucket === 'one' ? j = this.bucketOne : k = this.bucketTwo; - var measurements = [j, k]; - var prBool = true; // pour / receive boolean - need to pour or receive everbucketTwo other turn if (this.startBucket === 'one') { - measurements = [this.bucketOne, 0]; - return this.smallFirst(measurements, prBool) + 1; + return this.smallFirst([this.bucketOne, 0]) + 1; } - measurements = [0, this.bucketTwo]; - return this.bigFirst(measurements, prBool) + 1; + return this.bigFirst([0, this.bucketTwo]) + 1; }; } From acfaf3ff780fc43889f297cdb9fd19d2941bbf8e Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 20:08:58 +0100 Subject: [PATCH 158/272] Rename j and k to currentBucket --- exercises/two-bucket/example.js | 72 ++++++++++++++++----------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 89259d71..f64cca9a 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -21,30 +21,29 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { }; this.bigFirst = function (measurements) { - var j = measurements[0]; - var k = measurements[1]; + var currentBucketOne = measurements[0]; + var currentBucketTwo = measurements[1]; var moveCount = 0; var pourOrReceive = true; while (true) { - if (this.reachedGoal(measurements)) { - this.recordGoal(measurements); + if (this.reachedGoal([currentBucketOne, currentBucketTwo])) { + this.recordGoal([currentBucketOne, currentBucketTwo]); break; } - if (k > bucketOne && j === 0 && moveCount === 0) { - j = bucketOne; - k = bucketTwo - j; - } else if (j === bucketOne) { - j = 0; - } else if ((k > bucketOne && j !== 0) || (k > bucketOne && pourOrReceive)) { - k = k - (bucketOne - j); - j = bucketOne; - } else if (k > bucketOne || j === 0) { - j = k; - k = k - j; - } else if (k === 0) { - k = bucketTwo; + if (currentBucketTwo > bucketOne && currentBucketOne === 0 && moveCount === 0) { + currentBucketOne = bucketOne; + currentBucketTwo = bucketTwo - currentBucketOne; + } else if (currentBucketOne === bucketOne) { + currentBucketOne = 0; + } else if ((currentBucketTwo > bucketOne && currentBucketOne !== 0) || (currentBucketTwo > bucketOne && pourOrReceive)) { + currentBucketTwo = currentBucketTwo - (bucketOne - currentBucketOne); + currentBucketOne = bucketOne; + } else if (currentBucketTwo > bucketOne || currentBucketOne === 0) { + currentBucketOne = currentBucketTwo; + currentBucketTwo = currentBucketTwo - currentBucketOne; + } else if (currentBucketTwo === 0) { + currentBucketTwo = bucketTwo; } - measurements = [j, k]; moveCount++; pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } @@ -52,31 +51,30 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { }; this.smallFirst = function (measurements) { - var j = measurements[0]; - var k = measurements[1]; + var currentBucketOne = measurements[0]; + var currentBucketTwo = measurements[1]; var moveCount = 0; var pourOrReceive = true; while (true) { - if (this.reachedGoal(measurements)) { - this.recordGoal(measurements); + if (this.reachedGoal([currentBucketOne, currentBucketTwo])) { + this.recordGoal([currentBucketOne, currentBucketTwo]); break; } - if (j === bucketOne && moveCount === 0) { - j = 0; - k = bucketOne; - } else if (j === 0) { - j = bucketOne; - } else if (j === bucketOne && k < bucketTwo) { - var tempK = k; - k + j > bucketTwo ? k = bucketTwo : k = tempK + j; - tempK + j > bucketTwo ? j = j - (bucketTwo - tempK) : j = 0; - } else if (k === bucketTwo) { - k = 0; - } else if (k === 0 && j < bucketOne) { - k = j; - j = 0; + if (currentBucketOne === bucketOne && moveCount === 0) { + currentBucketOne = 0; + currentBucketTwo = bucketOne; + } else if (currentBucketOne === 0) { + currentBucketOne = bucketOne; + } else if (currentBucketOne === bucketOne && currentBucketTwo < bucketTwo) { + var temp = currentBucketTwo; + currentBucketTwo + currentBucketOne > bucketTwo ? currentBucketTwo = bucketTwo : currentBucketTwo = temp + currentBucketOne; + temp + currentBucketOne > bucketTwo ? currentBucketOne = currentBucketOne - (bucketTwo - temp) : currentBucketOne = 0; + } else if (currentBucketTwo === bucketTwo) { + currentBucketTwo = 0; + } else if (currentBucketTwo === 0 && currentBucketOne < bucketOne) { + currentBucketTwo = currentBucketOne; + currentBucketOne = 0; } - measurements = [j, k]; moveCount++; pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } From d1eb307098cbb945b90c06bb0d2be440bfc93eed Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 20:15:45 +0100 Subject: [PATCH 159/272] Remove measurements --- exercises/two-bucket/example.js | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index f64cca9a..2cc03d8d 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -6,28 +6,28 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { this.goal = goal; this.startBucket = startBucket; - this.reachedGoal = function (measurements) { - return (measurements[0] === goal || measurements[1] === goal); + this.reachedGoal = function (currentBucketOne, currentBucketTwo) { + return (currentBucketOne === goal || currentBucketTwo === goal); }; - this.recordGoal = function (measurements) { - if (measurements[0] === goal) { + this.recordGoal = function (currentBucketOne, currentBucketTwo) { + if (currentBucketOne === goal) { this.goalBucket = 'one'; - this.otherBucket = measurements[1]; + this.otherBucket = currentBucketTwo; } else { this.goalBucket = 'two'; - this.otherBucket = measurements[0]; + this.otherBucket = currentBucketOne; } }; - this.bigFirst = function (measurements) { - var currentBucketOne = measurements[0]; - var currentBucketTwo = measurements[1]; + this.bigFirst = function (initialBucketOne, initialBucketTwo) { + var currentBucketOne = initialBucketOne; + var currentBucketTwo = initialBucketTwo; var moveCount = 0; var pourOrReceive = true; while (true) { - if (this.reachedGoal([currentBucketOne, currentBucketTwo])) { - this.recordGoal([currentBucketOne, currentBucketTwo]); + if (this.reachedGoal(currentBucketOne, currentBucketTwo)) { + this.recordGoal(currentBucketOne, currentBucketTwo); break; } if (currentBucketTwo > bucketOne && currentBucketOne === 0 && moveCount === 0) { @@ -50,14 +50,14 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { return moveCount; }; - this.smallFirst = function (measurements) { - var currentBucketOne = measurements[0]; - var currentBucketTwo = measurements[1]; + this.smallFirst = function (initialBucketOne, initialBucketTwo) { + var currentBucketOne = initialBucketOne; + var currentBucketTwo = initialBucketTwo; var moveCount = 0; var pourOrReceive = true; while (true) { - if (this.reachedGoal([currentBucketOne, currentBucketTwo])) { - this.recordGoal([currentBucketOne, currentBucketTwo]); + if (this.reachedGoal(currentBucketOne, currentBucketTwo)) { + this.recordGoal(currentBucketOne, currentBucketTwo); break; } if (currentBucketOne === bucketOne && moveCount === 0) { @@ -83,9 +83,9 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { this.moves = function () { if (this.startBucket === 'one') { - return this.smallFirst([this.bucketOne, 0]) + 1; + return this.smallFirst(this.bucketOne, 0) + 1; } - return this.bigFirst([0, this.bucketTwo]) + 1; + return this.bigFirst(0, this.bucketTwo) + 1; }; } From 6eb012d8d83816d0203a0e491de0ad9cf4833c52 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sun, 1 Oct 2017 20:17:41 +0100 Subject: [PATCH 160/272] Remove while(true) --- exercises/two-bucket/example.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/exercises/two-bucket/example.js b/exercises/two-bucket/example.js index 2cc03d8d..91080a15 100644 --- a/exercises/two-bucket/example.js +++ b/exercises/two-bucket/example.js @@ -25,11 +25,7 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { var currentBucketTwo = initialBucketTwo; var moveCount = 0; var pourOrReceive = true; - while (true) { - if (this.reachedGoal(currentBucketOne, currentBucketTwo)) { - this.recordGoal(currentBucketOne, currentBucketTwo); - break; - } + while (!this.reachedGoal(currentBucketOne, currentBucketTwo)) { if (currentBucketTwo > bucketOne && currentBucketOne === 0 && moveCount === 0) { currentBucketOne = bucketOne; currentBucketTwo = bucketTwo - currentBucketOne; @@ -47,6 +43,7 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { moveCount++; pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } + this.recordGoal(currentBucketOne, currentBucketTwo); return moveCount; }; @@ -55,11 +52,7 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { var currentBucketTwo = initialBucketTwo; var moveCount = 0; var pourOrReceive = true; - while (true) { - if (this.reachedGoal(currentBucketOne, currentBucketTwo)) { - this.recordGoal(currentBucketOne, currentBucketTwo); - break; - } + while (!this.reachedGoal(currentBucketOne, currentBucketTwo)) { if (currentBucketOne === bucketOne && moveCount === 0) { currentBucketOne = 0; currentBucketTwo = bucketOne; @@ -78,6 +71,7 @@ function TwoBucket(bucketOne, bucketTwo, goal, startBucket) { moveCount++; pourOrReceive ? pourOrReceive = false : pourOrReceive = true; } + this.recordGoal(currentBucketOne, currentBucketTwo); return moveCount; }; From 319b76c001bd01d487d8dc617ef2fbbc2b61e33a Mon Sep 17 00:00:00 2001 From: Adhir Ramjiawan Date: Mon, 2 Oct 2017 20:00:56 +0200 Subject: [PATCH 161/272] ported 12 days exercise, resolves issue #391 (#410) * ported 12 days exercise, resolves issue #391 * issue #391, needed to fix variable args function and remove other arrow functions * refactored code as requested * Corrected spelling error on config.json and removed extra twelve days object * Corrected spelling error on config.json and removed extra twelve days object * Corrected spelling error on config.json and removed extra twelve days object * Corrected spelling error on config.json and removed extra twelve days object * removed beforeEach function from test suite * dummy commit to force travis ci rebuild --- config.json | 15 ++++ exercises/twelve-days/README.md | 61 +++++++++++++ exercises/twelve-days/example.js | 51 +++++++++++ exercises/twelve-days/package.json | 69 +++++++++++++++ exercises/twelve-days/twelve-days.spec.js | 103 ++++++++++++++++++++++ 5 files changed, 299 insertions(+) create mode 100644 exercises/twelve-days/README.md create mode 100644 exercises/twelve-days/example.js create mode 100644 exercises/twelve-days/package.json create mode 100644 exercises/twelve-days/twelve-days.spec.js diff --git a/config.json b/config.json index 503d292a..068a4653 100644 --- a/config.json +++ b/config.json @@ -1051,6 +1051,21 @@ "deprecated": true, "slug": "point-mutations", "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec" + }, + { + "uuid": "09e10522-9853-11e7-abc4-cec278b6b50a", + "slug": "twelve-days", + "core": false, + "unlocked_by": "bob", + "difficulty": 4, + "topics": [ + "Control-flow (conditionals)", + "Control-flow (loops)", + "Polymorphism", + "Strings", + "Pattern recognition", + "Regular expressions" + ] } ], "foregone": [], diff --git a/exercises/twelve-days/README.md b/exercises/twelve-days/README.md new file mode 100644 index 00000000..749a02a4 --- /dev/null +++ b/exercises/twelve-days/README.md @@ -0,0 +1,61 @@ +# Twelve Days + +Output the lyrics to 'The Twelve Days of Christmas'. + +``` +On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree. + +On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree. + +On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. + +On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. +``` + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the test suite pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Source + +Wikipedia [http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)](http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file diff --git a/exercises/twelve-days/example.js b/exercises/twelve-days/example.js new file mode 100644 index 00000000..aa8be9ac --- /dev/null +++ b/exercises/twelve-days/example.js @@ -0,0 +1,51 @@ +var TwelveDays = function() { + this.verseList = [ + 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.', + 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + ]; + + +}; + +TwelveDays.prototype.startFromZero = function(oneIndexArray) { + var newArray = oneIndexArray.map(function(item) { return item - 1; }); + return newArray; +}; + +TwelveDays.prototype.singleVerse = function(verseIndex) { + var verse = this.verseList[verseIndex].concat('\n'); + return verse; +}; + +TwelveDays.prototype.multiVerse = function(startIndex, endIndex) { + return this.verseList + .filter(function (verse, index) { return index >= startIndex; }) + .filter(function (verse, index) { return index <= endIndex }) + .join('\n\n').concat('\n'); +}; + +TwelveDays.prototype.verse = function(args) { + var indexArray = this.startFromZero(args); + + if (args.length === 2) { + return this.multiVerse(indexArray[0], indexArray[1]); + } + return this.singleVerse(indexArray[0]); +}; + +TwelveDays.prototype.sing = function() { + var song = this.verseList.join('\n\n').concat('\n'); + return song; +}; + +module.exports = TwelveDays; diff --git a/exercises/twelve-days/package.json b/exercises/twelve-days/package.json new file mode 100644 index 00000000..895f9723 --- /dev/null +++ b/exercises/twelve-days/package.json @@ -0,0 +1,69 @@ +{ + "name": "xecmascript", + "version": "0.0.0", + "description": "Exercism exercises in ECMAScript 6.", + "author": "Katrina Owen", + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/exercism/xecmascript" + }, + "devDependencies": { + "babel-jest": "^20.0.3", + "babel-plugin-transform-builtin-extend": "^1.1.2", + "babel-preset-env": "^1.4.0", + "eslint": "^3.19.0", + "eslint-config-airbnb": "^15.0.1", + "eslint-plugin-import": "^2.2.0", + "eslint-plugin-jsx-a11y": "^5.0.1", + "eslint-plugin-react": "^7.0.1", + "jest": "^20.0.4" + }, + "jest": { + "modulePathIgnorePatterns": [ + "package.json" + ] + }, + "babel": { + "presets": [ + "env" + ], + "plugins": [ + [ + "babel-plugin-transform-builtin-extend", + { + "globals": [ + "Error" + ] + } + ], + ["transform-regenerator"] + ] +}, + "scripts": { + "test": "jest --no-cache ./*", + "watch": "jest --no-cache --watch ./*", + "lint": "eslint .", + "lint-test": "eslint . && jest --no-cache ./* " + }, + "eslintConfig": { + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "env": { + "es6": true, + "node": true, + "jest": true + }, + "extends": "airbnb", + "rules": { + "import/no-unresolved": "off", + "import/extensions": "off" + } + }, + "licenses": [ + "MIT" + ], + "dependencies": {} +} diff --git a/exercises/twelve-days/twelve-days.spec.js b/exercises/twelve-days/twelve-days.spec.js new file mode 100644 index 00000000..1541e766 --- /dev/null +++ b/exercises/twelve-days/twelve-days.spec.js @@ -0,0 +1,103 @@ +var TwelveDays = require('./twelve-days'); + + +describe('TwelveDays', function () { + var twelveDaysObject = new TwelveDays(); + + it('test verse one', function () { + var expectedVerseOne = + 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([1])).toEqual(expectedVerseOne); + }); + + xit('test verse two', function () { + var expectedVerseTwo = + 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([2])).toEqual(expectedVerseTwo); + }); + + xit('test verse three', function () { + var expectedVerseThree = + 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([3])).toEqual(expectedVerseThree); + }); + + xit('test verse four', function () { + var expectedVerseFour = + 'On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([4])).toEqual(expectedVerseFour); + }); + + xit('test verse five', function () { + var expectedVerseFive = + 'On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([5])).toEqual(expectedVerseFive); + }); + + xit('test verse six', function () { + var expectedVerseSix = + 'On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([6])).toEqual(expectedVerseSix); + }); + + xit('test verse seven', function () { + var expectedVerseSeven = + 'On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([7])).toEqual(expectedVerseSeven); + }); + + xit('test verse eight', function () { + var expectedVerseEight = + 'On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([8])).toEqual(expectedVerseEight); + }); + + xit('test verse nine', function () { + var expectedVerseNine = + 'On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([9])).toEqual(expectedVerseNine); + }); + + xit('test verse ten', function () { + var expectedVerseTen = + 'On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([10])).toEqual(expectedVerseTen); + }); + + xit('test verse eleven', function () { + var expectedVerseEleven = + 'On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([11])).toEqual(expectedVerseEleven); + }); + + xit('test verse twelve', function () { + var expectedVerseTwelve = + 'On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([12])).toEqual(expectedVerseTwelve); + }); + + xit('test multiple verse', function () { + var expectedVerseOneToThree = + 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.\n\n' + + 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.verse([1, 3])).toEqual(expectedVerseOneToThree); + }); + + xit('test sing whole song', function () { + var expectedSong = + 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.\n\n' + + 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n\n' + + 'On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.\n'; + expect(twelveDaysObject.sing()).toEqual(expectedSong); + }); +}); From 2ffe3b02079ff8a00af9d8bf041b68949bdf73c4 Mon Sep 17 00:00:00 2001 From: Linda Thompson Date: Tue, 3 Oct 2017 23:12:03 -0500 Subject: [PATCH 162/272] Update ABOUT.md to nextercism format As requested in issue #85 in the meta repo - some minor formatting changes, along with a few grammatical/wording fixes. --- docs/ABOUT.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index b325e92b..82070a35 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -1,22 +1,22 @@ -Javascript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. Besides being fast, JavaScript provides benefits like: +JavaScript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. + +Besides being fast, JavaScript provides benefits like: * Reducing server traffic by validating user input in the browser before it is sent to the server. -* Providing immediate feedback to the site visitors so that they don't have to reload pages just to get error messages on form validations. +* Providing immediate feedback to the site's visitors so that they don't have to reload pages just to get error messages on form validations. * Allowing richer user interfaces with content changes on mouse hover, drag and drop gestures, and animations. Client-side JavaScript is interpreted in the browser without requiring compilation. This allows interactive content to be included in HTML pages which would otherwise be static. -Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/). +Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/). You should learn JavaScript because: * It's easy to learn. -* It's versatile in the sense that it's multi-paradigm supporting procedural, event based, object oriented and functional programming. -* It can be used for the frontend and backend. +* It's versatile in the sense that it's multi-paradigm - supporting procedural, event based, object oriented and functional programming. +* It can be used for the front-end and back-end. * It's Open Source. * JavaScript programming skills are in high demand. ---- - -_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. If you're looking for experimenting with newer features of the language try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ +_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. If you're looking to experiment with newer features of the language, try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ From 2ba71c43d410c7fd715af10db13f99b344670416 Mon Sep 17 00:00:00 2001 From: krishna Date: Wed, 4 Oct 2017 10:33:24 +0530 Subject: [PATCH 163/272] Add exercise Collatz Conjecture --- config.json | 15 ++++++++ .../collatz-conjecture.spec.js | 37 +++++++++++++++++++ exercises/collatz-conjecture/example.js | 20 ++++++++++ 3 files changed, 72 insertions(+) create mode 100644 exercises/collatz-conjecture/collatz-conjecture.spec.js create mode 100644 exercises/collatz-conjecture/example.js diff --git a/config.json b/config.json index 503d292a..58254982 100644 --- a/config.json +++ b/config.json @@ -1042,6 +1042,21 @@ "unlocked_by": "prime-factors", "uuid" : "910fe904-7e3c-11e7-bb31-be2e44b06b34" }, + { + "core" : false, + "difficulty" : 1, + "slug" : "collatz-conjecture", + "topics": [ + "Control-flow (loops)", + "Control-flow (conditionals)", + "Recursion", + "Integers", + "Algorithms", + "Mathematics" + ], + "unlocked_by": "null", + "uuid" : "fd435dad-311a-4c40-9868-70863455831e" + }, { "deprecated": true, "slug": "nucleotide-count", diff --git a/exercises/collatz-conjecture/collatz-conjecture.spec.js b/exercises/collatz-conjecture/collatz-conjecture.spec.js new file mode 100644 index 00000000..90a29015 --- /dev/null +++ b/exercises/collatz-conjecture/collatz-conjecture.spec.js @@ -0,0 +1,37 @@ +var CollatzConjecture = require('./collatz-conjecture'); + +describe('CollatzConjecture', function () { + var collatz = new CollatzConjecture(); + + it('test zero steps for one', function () { + var expected = 0; + expect(collatz.steps(1)).toEqual(expected); + }); + + xit('test divide if even steps', function () { + var expected = 4; + expect(collatz.steps(16)).toEqual(expected); + }); + + xit('test even and odd steps', function () { + var expected = 9; + expect(collatz.steps(12)).toEqual(expected); + }); + + xit('test large number of even and odd steps', function () { + var expected = 152; + expect(collatz.steps(1000000)).toEqual(expected); + }); + + xit('test zero is an error', function () { + expect(function () { + collatz.steps(0); + }).toThrow(new Error('Only positive numbers are allowed')); + }); + + xit('test negative value is an error', function () { + expect(function () { + collatz.steps(-1); + }).toThrow(new Error('Only positive numbers are allowed')); + }); +}); diff --git a/exercises/collatz-conjecture/example.js b/exercises/collatz-conjecture/example.js new file mode 100644 index 00000000..2f51ac50 --- /dev/null +++ b/exercises/collatz-conjecture/example.js @@ -0,0 +1,20 @@ +'use strict'; + +function CollatzConjecture() {} + +CollatzConjecture.prototype.steps = function (number) { + var count = 0; + if (number < 1) { + throw new Error('Only positive numbers are allowed'); + } + getStepsCount(number); + function getStepsCount(n) { + if (n === 1) return 0; + var nextNumber = ( n % 2 === 0 ? n / 2 : 3 * n + 1); + count++; + return getStepsCount(nextNumber); + } + return count; +}; + +module.exports = CollatzConjecture; From 1970309b8e988336382f7d99c6d8eb8869334615 Mon Sep 17 00:00:00 2001 From: Adhir Ramjiawan Date: Thu, 5 Oct 2017 21:02:07 +0200 Subject: [PATCH 164/272] implemented solution for issue #390 --- config.json | 14 ++++ exercises/diffie-hellman/README.md | 73 +++++++++++++++++++ .../diffie-hellman/diffie-hellman.spec.js | 73 +++++++++++++++++++ exercises/diffie-hellman/example.js | 48 ++++++++++++ 4 files changed, 208 insertions(+) create mode 100644 exercises/diffie-hellman/README.md create mode 100644 exercises/diffie-hellman/diffie-hellman.spec.js create mode 100644 exercises/diffie-hellman/example.js diff --git a/config.json b/config.json index 503d292a..22c831ad 100644 --- a/config.json +++ b/config.json @@ -1029,6 +1029,20 @@ "unlocked_by": "linked-list", "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626" }, + { + "uuid": "833bd7c7-d3d8-45fd-a218-12dea646065d", + "slug": "diffie-hellman", + "core": false, + "unlocked_by": "simple-cipher", + "difficulty": 3, + "topics": [ + "Control-flow (conditionals)", + "Control-flow (loops)", + "Algorithms", + "Arrays", + "Exception handling" + ] + }, { "core" : false, "difficulty" : 8, diff --git a/exercises/diffie-hellman/README.md b/exercises/diffie-hellman/README.md new file mode 100644 index 00000000..2a8453fb --- /dev/null +++ b/exercises/diffie-hellman/README.md @@ -0,0 +1,73 @@ +# Diffie Hellman + +Diffie-Hellman key exchange. + +Alice and Bob use Diffie-Hellman key exchange to share secrets. They +start with prime numbers, pick private keys, generate and share public +keys, and then generate a shared secret key. + +## Step 0 + +The test program supplies prime numbers p and g. + +## Step 1 + +Alice picks a private key, a, greater than 1 and less than p. Bob does +the same to pick a private key b. + +## Step 2 + +Alice calculates a public key A. + + A = g**a mod p + +Using the same p and g, Bob similarly calculates a public key B from his +private key b. + +## Step 3 + +Alice and Bob exchange public keys. Alice calculates secret key s. + + s = B**a mod p + +Bob calculates + + s = A**b mod p + +The calculations produce the same result! Alice and Bob now share +secret s. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Requirements + + + +## Making the test suite pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Source + +Wikipedia, 1024 bit key from www.cryptopp.com/wiki. [http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange](http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/diffie-hellman/diffie-hellman.spec.js b/exercises/diffie-hellman/diffie-hellman.spec.js new file mode 100644 index 00000000..5f7faa65 --- /dev/null +++ b/exercises/diffie-hellman/diffie-hellman.spec.js @@ -0,0 +1,73 @@ +var DiffieHellman = require('./diffie-hellman'); + +describe('diffie-hellman', function(){ + var p = 23; + var g = 5; + var diffieHellman = new DiffieHellman(p, g); + + var alicePrivateKey = 6; + var alicePublicKey = 8; + + var bobPrivateKey = 15; + var bobPublicKey = 19; + + it('throws an error if the constructor arguments are out of range', function() { + expect(function() { + new DiffieHellman(0, 9999); + }).toThrow(); + }); + + xit('throws an error if the constructor arguments are not prime', function() { + expect(function() { + new DiffieHellman(10, 13); + }).toThrow(); + }); + + xit('throws an error if private key is negative', function() { + expect(function() { + diffieHellman.getPublicKeyFromPrivateKey(-1); + }).toThrow(); + }); + + xit('throws an error if private key is zero', function() { + expect(function() { + diffieHellman.getPublicKeyFromPrivateKey(0); + }).toThrow(); + }); + + xit('throws an error if private key is one', function() { + expect(function() { + diffieHellman.getPublicKeyFromPrivateKey(1); + }).toThrow(); + }); + + xit('throws an error if private key equals the modulus parameter p', function() { + expect(function() { + diffieHellman.getPublicKeyFromPrivateKey(p); + }).toThrow(); + }); + + xit('throws an error if private key is greater than the modulus parameter p', function() { + expect(function() { + diffieHellman.getPublicKeyFromPrivateKey(p + 1); + }).toThrow(); + }); + + xit('when given a private key, returns the correct public one', function() { + expect(diffieHellman.getPublicKeyFromPrivateKey(alicePrivateKey)).toEqual(alicePublicKey); + }); + + xit('when given a different private key, returns the correct public one', function() { + expect(diffieHellman.getPublicKeyFromPrivateKey(bobPrivateKey)).toEqual(bobPublicKey); + }); + + xit('can generate a shared secret from our private key and their public key', function() { + var sharedSecret = 2; + + expect(diffieHellman.getSharedSecret(alicePrivateKey, bobPublicKey)) + .toEqual(sharedSecret); + + expect(diffieHellman.getSharedSecret(bobPrivateKey, alicePublicKey)) + .toEqual(sharedSecret); + }); +}); diff --git a/exercises/diffie-hellman/example.js b/exercises/diffie-hellman/example.js new file mode 100644 index 00000000..eeb9c0fd --- /dev/null +++ b/exercises/diffie-hellman/example.js @@ -0,0 +1,48 @@ + +var DiffieHellman = function(p, g){ + this.p = p; + this.g = g; + + // array of first 1000 primes. + this.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 + ]; + + this.getPublicKeyFromPrivateKey = function (privateKey) { + if (privateKey <= 1 || privateKey > this.p - 1) { + throw Error('Private key a must be greater than one but less than modulus parameter p!'); + } + return Math.pow(this.g, privateKey) % this.p; + }; + + this.getSharedSecret = function (ourPrivateKey, theirPublicKey) { + return Math.pow(theirPublicKey, ourPrivateKey) % this.p; + }; + + this.validateInitialArguments = function (p, g){ + var BIGGEST_PRIME = this.PRIMES[this.PRIMES.length - 1]; + return p >= 2 + && g >= 2 + && p <= BIGGEST_PRIME + && g <= BIGGEST_PRIME + && arrIncludes(this.PRIMES, p) + && arrIncludes(this.PRIMES, g); + }; + + function arrIncludes(arr, a) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === a) { + return true; + } + } + return false; + } + + + if (!this.validateInitialArguments(p, g)) { + throw Error('Constructor arguments are out of range or non-prime!'); + } +}; + + +module.exports = DiffieHellman; From 9925c9357d7f3a5e7da963b09991834a865cff0c Mon Sep 17 00:00:00 2001 From: Linda Thompson Date: Fri, 6 Oct 2017 00:04:55 -0500 Subject: [PATCH 165/272] Adjusted sentences to be on their own lines The preview still looks the same to me - but the code file has each sentence on it's own line now. Hopefully this works as requested? If not let me know and I'll keep tweaking it. --- docs/ABOUT.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 82070a35..94a463da 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -1,4 +1,5 @@ -JavaScript is a scripting language used to provide dynamic and interactive content on webpages. Also, server side JS allows the use of the same language on the server and client. +JavaScript is a scripting language used to provide dynamic and interactive content on webpages. +Also, server side JS allows the use of the same language on the server and client. Besides being fast, JavaScript provides benefits like: @@ -6,9 +7,14 @@ Besides being fast, JavaScript provides benefits like: * Providing immediate feedback to the site's visitors so that they don't have to reload pages just to get error messages on form validations. * Allowing richer user interfaces with content changes on mouse hover, drag and drop gestures, and animations. -Client-side JavaScript is interpreted in the browser without requiring compilation. This allows interactive content to be included in HTML pages which would otherwise be static. +Client-side JavaScript is interpreted in the browser without requiring compilation. +This allows interactive content to be included in HTML pages which would otherwise be static. -Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. NodeJS is built on Google Chrome's JavaScript V8 Engine. NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node can be a great solution for applications requiring I/O bound operations, data streaming etc. More details can be found [here](https://nodejs.org/en/about/). +Server-Side JavaScript as run in NodeJS enables back-end access to databases, file systems, and servers. +NodeJS is built on Google Chrome's JavaScript V8 Engine. +NodeJS uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. +Node can be a great solution for applications requiring I/O bound operations, data streaming etc. +More details can be found [here](https://nodejs.org/en/about/). You should learn JavaScript because: @@ -18,5 +24,6 @@ You should learn JavaScript because: * It's Open Source. * JavaScript programming skills are in high demand. -_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. If you're looking to experiment with newer features of the language, try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ +_This track is intended for widely supported JavaScript, for code that could be executed in almost all existing browsers. +If you're looking to experiment with newer features of the language, try the [ECMAScript](http://exercism.io/languages/ecmascript) track._ From 357577661ccc307c96267d4278c4875d4b8136a0 Mon Sep 17 00:00:00 2001 From: krishna Date: Wed, 11 Oct 2017 01:20:07 +0530 Subject: [PATCH 166/272] Implementing Transpose exercise --- config.json | 15 +++++++ exercises/transpose/example.js | 15 +++++++ exercises/transpose/transpose.spec.js | 65 +++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 exercises/transpose/example.js create mode 100644 exercises/transpose/transpose.spec.js diff --git a/config.json b/config.json index 806bba80..0b55ded8 100644 --- a/config.json +++ b/config.json @@ -1080,6 +1080,21 @@ "Pattern recognition", "Regular expressions" ] + }, + { + "core": false, + "difficulty": 1, + "slug": "transpose", + "topics": [ + "loops", + "arrays", + "lists", + "matrices", + "strings", + "text_formatting" + ], + "unlocked_by": "null", + "uuid": "7c024853-0540-473d-b2d9-cad84953c00f" } ], "foregone": [], diff --git a/exercises/transpose/example.js b/exercises/transpose/example.js new file mode 100644 index 00000000..d773c974 --- /dev/null +++ b/exercises/transpose/example.js @@ -0,0 +1,15 @@ +'use strict'; + +function transpose(text) { + return text.split('\n').reduce(function (result, line, lineNo) { + line.split('').map(function (value, key) { + if (typeof result[key] === 'undefined') { + result[key] = new Array(lineNo + 1).join( ' ' ); + } + result[key] += value; + }); + return result; + }, []).join('\n'); +} + +module.exports = transpose; diff --git a/exercises/transpose/transpose.spec.js b/exercises/transpose/transpose.spec.js new file mode 100644 index 00000000..667a977c --- /dev/null +++ b/exercises/transpose/transpose.spec.js @@ -0,0 +1,65 @@ +var transpose = require('./transpose'); + +describe('Transpose', function () { + it('test empty string', function () { + expect(transpose('')).toEqual(''); + }); + + xit('test two characters in a row', function () { + var input = 'A1'; + var expected = 'A\n1'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test two characters in a column', function () { + var input = 'A\n1'; + var expected = 'A1'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test simple', function () { + var input = 'ABC\n123'; + var expected = 'A1\nB2\nC3'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test single line', function () { + var input = 'Single line.'; + var expected = 'S\ni\nn\ng\nl\ne\n \nl\ni\nn\ne\n.'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test first line longer than second line', function () { + var input = 'The fourth line.\nThe fifth line.'; + var expected = 'TT\nhh\nee\n \nff\noi\nuf\nrt\nth\nh \n l\nli\nin\nne\ne.\n.'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test second line longer than first line', function () { + var input = 'The first line.\nThe second line.'; + var expected = 'TT\nhh\nee\n \nfs\nie\nrc\nso\ntn\n d\nl \nil\nni\nen\n.e\n .'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test square', function () { + var input = 'HEART\nEMBER\nABUSE\nRESIN\nTREND'; + var expected = 'HEART\nEMBER\nABUSE\nRESIN\nTREND'; + expect(transpose(input)).toEqual(expected); + }); + + xit('test rectangle', function () { + var input = 'FRACTURE\nOUTLINED\nBLOOMING\nSEPTETTE'; + var expected = 'FOBS\nRULE\nATOP\nCLOT\nTIME\nUNIT\nRENT\nEDGE'; + expect(transpose(input)).toEqual(expected); + }); + xit('test triangle', function () { + var input = 'T\nEE\nAAA\nSSSS\nEEEEE\nRRRRRR'; + var expected = 'TEASER\n EASER\n ASER\n SER\n ER\n R'; + expect(transpose(input)).toEqual(expected); + }); + xit('test many lines', function () { + var input = 'Chor. Two households, both alike in dignity,\nIn fair Verona, where we lay our scene,\nFrom ancient grudge break to new mutiny,\nWhere civil blood makes civil hands unclean.\nFrom forth the fatal loins of these two foes\nA pair of star-cross\'d lovers take their life;\nWhose misadventur\'d piteous overthrows\nDoth with their death bury their parents\' strife.\nThe fearful passage of their death-mark\'d love,\nAnd the continuance of their parents\' rage,\nWhich, but their children\'s end, naught could remove,\nIs now the two hours\' traffic of our stage;\nThe which if you with patient ears attend,\nWhat here shall miss, our toil shall strive to mend.'; + var expected = "CIFWFAWDTAWITW\nhnrhr hohnhshh\no oeopotedi ea\nrfmrmash cn t\n.a e ie fthow \n ia fr weh,whh\nTrnco miae ie\nw ciroitr btcr\noVivtfshfcuhhe\n eeih a uote \nhrnl sdtln is\noot ttvh tttfh\nun bhaeepihw a\nsaglernianeoyl\ne,ro -trsui ol\nh uofcu sarhu \nowddarrdan o m\nlhg to'egccuwi\ndeemasdaeehris\nsr als t ists\n,ebk 'phool'h,\n reldi ffd \nbweso tb rtpo\noea ileutterau\nt kcnoorhhnatr\nhl isvuyee'fi \n atv es iisfet\nayoior trr ino\nl lfsoh ecti\nion vedpn l\nkuehtteieadoe \nerwaharrar,fas\n nekt te rh\nismdsehphnnosa\nncuse ra-tau l\n et tormsural\ndniuthwea'g t \niennwesnr hsts\ng,ycoitkrttet\nn,l rs'a anr\nief 'dgcgdi\ntaol eoe,v\nyneisl,u;e\n,.sftol \n ervdt\n ;ie o\n f,r \n eem\n .me\n on\n vd\n e.\n ,"; + expect(transpose(input)).toEqual(expected); + }); +}); From ed7ab552e6f875025b6128873f8caba159dfd6d7 Mon Sep 17 00:00:00 2001 From: Logan Stucki Date: Thu, 12 Oct 2017 13:30:02 -0500 Subject: [PATCH 167/272] protein-translation: implement exercise (#415) --- config.json | 13 ++++ exercises/protein-translation/README.md | 73 +++++++++++++++++++ exercises/protein-translation/example.js | 68 +++++++++++++++++ .../protein-translation.spec.js | 63 ++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 exercises/protein-translation/README.md create mode 100644 exercises/protein-translation/example.js create mode 100644 exercises/protein-translation/protein-translation.spec.js diff --git a/config.json b/config.json index 806bba80..e89cb8bb 100644 --- a/config.json +++ b/config.json @@ -1080,6 +1080,19 @@ "Pattern recognition", "Regular expressions" ] + }, + { + "uuid": "52c775a4-7ddb-4cba-8a78-8544220bd1b6", + "slug": "protein-translation", + "core": false, + "unlocked_by": null, + "difficulty": 1, + "topics": [ + "control-flow-(conditionals)", + "control-flow-(loops)", + "strings", + "algorithms" + ] } ], "foregone": [], diff --git a/exercises/protein-translation/README.md b/exercises/protein-translation/README.md new file mode 100644 index 00000000..0c163fe0 --- /dev/null +++ b/exercises/protein-translation/README.md @@ -0,0 +1,73 @@ +# Protein Translation + +Translate RNA sequences into proteins. + +RNA can be broken into three nucleotide sequences called codons, and then translated to a polypeptide like so: + +RNA: `"AUGUUUUCU"` => translates to + +Codons: `"AUG", "UUU", "UCU"` +=> which become a polypeptide with the following sequence => + +Protein: `"Methionine", "Phenylalanine", "Serine"` + +There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. If it works for one codon, the program should work for all of them. +However, feel free to expand the list in the test suite to include them all. + +There are also four terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated. + +All subsequent codons after are ignored, like this: + +RNA: `"AUGUUUUCUUAAAUG"` => + +Codons: `"AUG", "UUU", "UCU", "UAG", "AUG"` => + +Protein: `"Methionine", "Phenylalanine", "Serine"` + +Note the stop codon terminates the translation and the final methionine is not translated into the protein sequence. + +Below are the codons and resulting Amino Acids needed for the exercise. + +Codon | Protein +:--- | :--- +AUG | Methionine +UUU, UUC | Phenylalanine +UUA, UUG | Leucine +UCU, UCC, UCA, UCG | Serine +UAU, UAC | Tyrosine +UGU, UGC | Cysteine +UGG | Tryptophan +UAA, UAG, UGA | STOP + + +Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki/Translation_(biology)) + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Tyler Long + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/protein-translation/example.js b/exercises/protein-translation/example.js new file mode 100644 index 00000000..15d2cf99 --- /dev/null +++ b/exercises/protein-translation/example.js @@ -0,0 +1,68 @@ +'use strict'; + +module.exports = translate; + +function translate(rnaStrand) { + var proteins = []; + + if (rnaStrand) { + for (var i = 0; i < rnaStrand.length; i+=3) { + var protein = getProtein(rnaStrand.substring(i, i + 3)); + + if (protein) { + + if (protein === "STOP") { + break; + } + + if (protein === "INVALID") { + throw new Error('Invalid codon'); + } + + proteins.push(protein); + } + } + } + + return proteins; +} + +function getProtein(codon) { + switch (codon) { + case "AUG": + return "Methionine"; + + case "UUU": + case "UUC": + return "Phenylalanine"; + + case "UUA": + case "UUG": + return "Leucine"; + + case "UCU": + case "UCC": + case "UCA": + case "UCG": + return "Serine"; + + case "UAU": + case "UAC": + return "Tyrosine"; + + case "UGU": + case "UGC": + return "Cysteine"; + + case "UGG": + return "Tryptophan"; + + case "UAA": + case "UAG": + case "UGA": + return "STOP"; + + default: + return "INVALID"; + } +} diff --git a/exercises/protein-translation/protein-translation.spec.js b/exercises/protein-translation/protein-translation.spec.js new file mode 100644 index 00000000..3b3c700d --- /dev/null +++ b/exercises/protein-translation/protein-translation.spec.js @@ -0,0 +1,63 @@ +var translate = require('./protein-translation'); + +describe('ProteinTranslation', function() { + it('Empty RNA has no proteins', function() { + expect(translate()).toEqual([]); + }); + + xit('Methionine codon translates into protein', function () { + expect(translate('AUG')).toEqual(["Methionine"]); + }); + + xit('Phenylalanine codons translate into protein', function () { + expect(translate('UUUUUC')).toEqual(["Phenylalanine", "Phenylalanine"]); + }); + + xit('Leucine codons translate into protein', function () { + expect(translate('UUAUUG')).toEqual(["Leucine", "Leucine"]); + }); + + xit('Serine codons translate into protein', function () { + expect(translate('UCUUCCUCAUCG')).toEqual(["Serine", "Serine", "Serine", "Serine"]); + }); + + xit('Tyrosine codons translate into protein', function () { + expect(translate('UAUUAC')).toEqual(["Tyrosine", "Tyrosine"]); + }); + + xit('Cysteine codons translate into protein', function() { + expect(translate('UGUUGC')).toEqual(["Cysteine", "Cysteine"]); + }); + + xit('Tryptophan codon translates into protein', function () { + expect(translate('UGG')).toEqual(["Tryptophan"]); + }); + + xit('Sequence starts with stop codon 1', function () { + expect(translate('UAAUUUUUA')).toEqual([]); + }); + + xit('Sequence starts with stop codon 2', function () { + expect(translate('UAGAUGUAU')).toEqual([]); + }); + + xit('Sequence starts with stop codon 3', function () { + expect(translate('UGAUGU')).toEqual([]); + }); + + xit('Small RNA strand', function () { + expect(translate('AUGUUUUCU')).toEqual(["Methionine", "Phenylalanine", "Serine"]); + }); + + xit('Stop codon ends translation', function () { + expect(translate('AUGUUUUCUUAAAUG')).toEqual(["Methionine", "Phenylalanine", "Serine"]); + }); + + xit('Invalid codon throws error', function () { + expect( + function() { + translate('LOL') + } + ).toThrow(new Error("Invalid codon")); + }) +}); From cf1bd5af3de971457bc068ddcd8fc0c956809621 Mon Sep 17 00:00:00 2001 From: Logan Stucki Date: Sat, 14 Oct 2017 06:52:47 -0500 Subject: [PATCH 168/272] nucleotide-count: correct DNS typo to DNA (#423) --- exercises/nucleotide-count/nucleotide-count.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/nucleotide-count/nucleotide-count.spec.js b/exercises/nucleotide-count/nucleotide-count.spec.js index 12283d17..25c35ff2 100644 --- a/exercises/nucleotide-count/nucleotide-count.spec.js +++ b/exercises/nucleotide-count/nucleotide-count.spec.js @@ -20,7 +20,7 @@ describe('DNA', function () { expect(acid.count('T')).toEqual(2); }); - xit('Empty DNS strand has no nucleotides', function () { + xit('Empty DNA strand has no nucleotides', function () { var expected = {A: 0, T: 0, C: 0, G: 0}; expect(dna().histogram()).toEqual(expected); }); From 6277a8db37173b55c988cc79744c16e6760c9095 Mon Sep 17 00:00:00 2001 From: Aryan J Date: Sat, 14 Oct 2017 08:27:27 -0400 Subject: [PATCH 169/272] Delete unnecessary package.json (#422) --- exercises/twelve-days/package.json | 69 ------------------------------ 1 file changed, 69 deletions(-) delete mode 100644 exercises/twelve-days/package.json diff --git a/exercises/twelve-days/package.json b/exercises/twelve-days/package.json deleted file mode 100644 index 895f9723..00000000 --- a/exercises/twelve-days/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "xecmascript", - "version": "0.0.0", - "description": "Exercism exercises in ECMAScript 6.", - "author": "Katrina Owen", - "private": true, - "repository": { - "type": "git", - "url": "https://github.com/exercism/xecmascript" - }, - "devDependencies": { - "babel-jest": "^20.0.3", - "babel-plugin-transform-builtin-extend": "^1.1.2", - "babel-preset-env": "^1.4.0", - "eslint": "^3.19.0", - "eslint-config-airbnb": "^15.0.1", - "eslint-plugin-import": "^2.2.0", - "eslint-plugin-jsx-a11y": "^5.0.1", - "eslint-plugin-react": "^7.0.1", - "jest": "^20.0.4" - }, - "jest": { - "modulePathIgnorePatterns": [ - "package.json" - ] - }, - "babel": { - "presets": [ - "env" - ], - "plugins": [ - [ - "babel-plugin-transform-builtin-extend", - { - "globals": [ - "Error" - ] - } - ], - ["transform-regenerator"] - ] -}, - "scripts": { - "test": "jest --no-cache ./*", - "watch": "jest --no-cache --watch ./*", - "lint": "eslint .", - "lint-test": "eslint . && jest --no-cache ./* " - }, - "eslintConfig": { - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "env": { - "es6": true, - "node": true, - "jest": true - }, - "extends": "airbnb", - "rules": { - "import/no-unresolved": "off", - "import/extensions": "off" - } - }, - "licenses": [ - "MIT" - ], - "dependencies": {} -} From aef5232fb1bdf66f680c0249a55175594aa60394 Mon Sep 17 00:00:00 2001 From: Aryan J Date: Sat, 14 Oct 2017 08:31:10 -0400 Subject: [PATCH 170/272] Fix hello-world code (#421) --- exercises/hello-world/example.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/exercises/hello-world/example.js b/exercises/hello-world/example.js index 4bc0926b..51eadcf3 100644 --- a/exercises/hello-world/example.js +++ b/exercises/hello-world/example.js @@ -2,9 +2,8 @@ var HelloWorld = function () {}; -HelloWorld.prototype.hello = function (name) { - name = name || 'World'; - return 'Hello, ' + name + '!'; +HelloWorld.prototype.hello = function () { + return 'Hello, World!'; }; module.exports = HelloWorld; From 8692cc13fdb0e7472c1f433f9f5760d04e9f60a3 Mon Sep 17 00:00:00 2001 From: David Kinzer Date: Sat, 14 Oct 2017 17:09:24 -0400 Subject: [PATCH 171/272] Fix grammar/typo. (#426) --- exercises/diffie-hellman/example.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/diffie-hellman/example.js b/exercises/diffie-hellman/example.js index eeb9c0fd..bbdfe16d 100644 --- a/exercises/diffie-hellman/example.js +++ b/exercises/diffie-hellman/example.js @@ -10,7 +10,7 @@ var DiffieHellman = function(p, g){ this.getPublicKeyFromPrivateKey = function (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 must be greater than one but less than modulus parameter p!'); } return Math.pow(this.g, privateKey) % this.p; }; From 4b3cf3fe48d24c7ce7358b89f3d2ebdea7c0fb58 Mon Sep 17 00:00:00 2001 From: Hazel Seanor Date: Sat, 14 Oct 2017 22:10:27 +0100 Subject: [PATCH 172/272] Fixed link to CLI download page. (#425) It was http://exercism.io/cli, which resulted in a 404. --- docs/TESTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TESTS.md b/docs/TESTS.md index 63b72741..62985f52 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -26,7 +26,7 @@ To get started, you can download a Visual Studio solution that is already set up 1. Download the [Exercism.io Visual Studio Template](https://github.com/rprouse/Exercism.VisualStudio) from GitHub by clicking the Download Zip button on the page. 2. Unzip the template into your exercises directory, for example `C:\src\exercises` -2. Install the [Exercism CLI](http://exercism.io/cli) +2. Install the [Exercism CLI](http://exercism.io/clients/cli) 3. Open a command prompt to your exercise directory 4. Add your API key to exercism `exercism configure --key=YOUR_API_KEY` 5. Configure your source directory in exercism `exercism configure --dir=C:\src\exercises` From f852472a931f8c1e9ccdcbc0fc57ff4f879be2c8 Mon Sep 17 00:00:00 2001 From: krishna Date: Sun, 15 Oct 2017 22:00:46 +0530 Subject: [PATCH 173/272] Update code and styles --- exercises/transpose/example.js | 8 +++-- exercises/transpose/transpose.spec.js | 44 ++++++++++++++------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/exercises/transpose/example.js b/exercises/transpose/example.js index d773c974..874ccea9 100644 --- a/exercises/transpose/example.js +++ b/exercises/transpose/example.js @@ -1,15 +1,17 @@ 'use strict'; function transpose(text) { - return text.split('\n').reduce(function (result, line, lineNo) { + return text.reduce(function (result, line, lineNo) { line.split('').map(function (value, key) { if (typeof result[key] === 'undefined') { - result[key] = new Array(lineNo + 1).join( ' ' ); + result[key] = new Array(lineNo + 1).join(' '); } + result[key] += value; }); + return result; - }, []).join('\n'); + }, []); } module.exports = transpose; diff --git a/exercises/transpose/transpose.spec.js b/exercises/transpose/transpose.spec.js index 667a977c..59f7fe38 100644 --- a/exercises/transpose/transpose.spec.js +++ b/exercises/transpose/transpose.spec.js @@ -2,64 +2,66 @@ var transpose = require('./transpose'); describe('Transpose', function () { it('test empty string', function () { - expect(transpose('')).toEqual(''); + expect(transpose([])).toEqual([]); }); xit('test two characters in a row', function () { - var input = 'A1'; - var expected = 'A\n1'; + var input = ['A1']; + var expected = ['A', '1']; expect(transpose(input)).toEqual(expected); }); xit('test two characters in a column', function () { - var input = 'A\n1'; - var expected = 'A1'; + var input = ['A', '1']; + var expected = ['A1']; expect(transpose(input)).toEqual(expected); }); xit('test simple', function () { - var input = 'ABC\n123'; - var expected = 'A1\nB2\nC3'; + var input = ['ABC', '123']; + var expected = ['A1', 'B2', 'C3']; expect(transpose(input)).toEqual(expected); }); xit('test single line', function () { - var input = 'Single line.'; - var expected = 'S\ni\nn\ng\nl\ne\n \nl\ni\nn\ne\n.'; + var input = ['Single line.']; + var expected = ['S', 'i', 'n', 'g', 'l', 'e', ' ', 'l', 'i', 'n', 'e', '.']; expect(transpose(input)).toEqual(expected); }); xit('test first line longer than second line', function () { - var input = 'The fourth line.\nThe fifth line.'; - var expected = 'TT\nhh\nee\n \nff\noi\nuf\nrt\nth\nh \n l\nli\nin\nne\ne.\n.'; + var input = ['The fourth line.', 'The fifth line.']; + var expected = ['TT', 'hh', 'ee', ' ', 'ff', 'oi', 'uf', 'rt', 'th', 'h ', ' l', 'li', 'in', 'ne', 'e.', '.']; expect(transpose(input)).toEqual(expected); }); xit('test second line longer than first line', function () { - var input = 'The first line.\nThe second line.'; - var expected = 'TT\nhh\nee\n \nfs\nie\nrc\nso\ntn\n d\nl \nil\nni\nen\n.e\n .'; + var input = ['The first line.', 'The second line.']; + var expected = ['TT', 'hh', 'ee', ' ', 'fs', 'ie', 'rc', 'so', 'tn', ' d', 'l ', 'il', 'ni', 'en', '.e', ' .']; expect(transpose(input)).toEqual(expected); }); xit('test square', function () { - var input = 'HEART\nEMBER\nABUSE\nRESIN\nTREND'; - var expected = 'HEART\nEMBER\nABUSE\nRESIN\nTREND'; + var input = ['HEART', 'EMBER', 'ABUSE', 'RESIN', 'TREND']; + var expected = ['HEART', 'EMBER', 'ABUSE', 'RESIN', 'TREND']; expect(transpose(input)).toEqual(expected); }); xit('test rectangle', function () { - var input = 'FRACTURE\nOUTLINED\nBLOOMING\nSEPTETTE'; - var expected = 'FOBS\nRULE\nATOP\nCLOT\nTIME\nUNIT\nRENT\nEDGE'; + var input = ['FRACTURE', 'OUTLINED', 'BLOOMING', 'SEPTETTE']; + var expected = ['FOBS', 'RULE', 'ATOP', 'CLOT', 'TIME', 'UNIT', 'RENT', 'EDGE']; expect(transpose(input)).toEqual(expected); }); + xit('test triangle', function () { - var input = 'T\nEE\nAAA\nSSSS\nEEEEE\nRRRRRR'; - var expected = 'TEASER\n EASER\n ASER\n SER\n ER\n R'; + var input = ['T', 'EE', 'AAA', 'SSSS', 'EEEEE', 'RRRRRR']; + var expected = ['TEASER', ' EASER', ' ASER', ' SER', ' ER', ' R']; expect(transpose(input)).toEqual(expected); }); + xit('test many lines', function () { - var input = 'Chor. Two households, both alike in dignity,\nIn fair Verona, where we lay our scene,\nFrom ancient grudge break to new mutiny,\nWhere civil blood makes civil hands unclean.\nFrom forth the fatal loins of these two foes\nA pair of star-cross\'d lovers take their life;\nWhose misadventur\'d piteous overthrows\nDoth with their death bury their parents\' strife.\nThe fearful passage of their death-mark\'d love,\nAnd the continuance of their parents\' rage,\nWhich, but their children\'s end, naught could remove,\nIs now the two hours\' traffic of our stage;\nThe which if you with patient ears attend,\nWhat here shall miss, our toil shall strive to mend.'; - var expected = "CIFWFAWDTAWITW\nhnrhr hohnhshh\no oeopotedi ea\nrfmrmash cn t\n.a e ie fthow \n ia fr weh,whh\nTrnco miae ie\nw ciroitr btcr\noVivtfshfcuhhe\n eeih a uote \nhrnl sdtln is\noot ttvh tttfh\nun bhaeepihw a\nsaglernianeoyl\ne,ro -trsui ol\nh uofcu sarhu \nowddarrdan o m\nlhg to'egccuwi\ndeemasdaeehris\nsr als t ists\n,ebk 'phool'h,\n reldi ffd \nbweso tb rtpo\noea ileutterau\nt kcnoorhhnatr\nhl isvuyee'fi \n atv es iisfet\nayoior trr ino\nl lfsoh ecti\nion vedpn l\nkuehtteieadoe \nerwaharrar,fas\n nekt te rh\nismdsehphnnosa\nncuse ra-tau l\n et tormsural\ndniuthwea'g t \niennwesnr hsts\ng,ycoitkrttet\nn,l rs'a anr\nief 'dgcgdi\ntaol eoe,v\nyneisl,u;e\n,.sftol \n ervdt\n ;ie o\n f,r \n eem\n .me\n on\n vd\n e.\n ,"; + var 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.']; + var expected = ['CIFWFAWDTAWITW', 'hnrhr hohnhshh', 'o oeopotedi ea', 'rfmrmash cn t', '.a e ie fthow ', ' ia fr weh,whh', 'Trnco miae ie', 'w ciroitr btcr', 'oVivtfshfcuhhe', ' eeih a uote ', 'hrnl sdtln is', 'oot ttvh tttfh', 'un bhaeepihw a', 'saglernianeoyl', 'e,ro -trsui ol', 'h uofcu sarhu ', 'owddarrdan o m', 'lhg to\'egccuwi', 'deemasdaeehris', 'sr als t ists', ',ebk \'phool\'h,', ' reldi ffd ', 'bweso tb rtpo', 'oea ileutterau', 't kcnoorhhnatr', 'hl isvuyee\'fi ', ' atv es iisfet', 'ayoior trr ino', 'l lfsoh ecti', 'ion vedpn l', 'kuehtteieadoe ', 'erwaharrar,fas', ' nekt te rh', 'ismdsehphnnosa', 'ncuse ra-tau l', ' et tormsural', 'dniuthwea\'g t ', 'iennwesnr hsts', 'g,ycoitkrttet', 'n,l rs\'a anr', 'ief \'dgcgdi', 'taol eoe,v', 'yneisl,u;e', ',.sftol ', ' ervdt', ' ;ie o', ' f,r ', ' eem', ' .me', ' on', ' vd', ' e.', ' ,']; expect(transpose(input)).toEqual(expected); }); }); From a4b7e364d79f2dba65ab0325d3771b6e13cf5a98 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+Radix16@users.noreply.github.com> Date: Mon, 16 Oct 2017 04:03:54 -0700 Subject: [PATCH 174/272] Fix Meetup code (#427) * Correct the meetup exercise for formatting and syntax errors as indicated by the linter. * Make corrections suggested by @mathewmorgan for _find function and varaible name --- exercises/meetup/example.js | 51 ++++++++++++++++----------------- exercises/meetup/meetup.spec.js | 6 ---- 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/exercises/meetup/example.js b/exercises/meetup/example.js index 74e77826..2024d218 100644 --- a/exercises/meetup/example.js +++ b/exercises/meetup/example.js @@ -1,43 +1,40 @@ +'use strict'; + function MeetupDayException(message) { this.message = message; this.name = 'MeetupDayException'; } -function meetupDay(year, month, day_of_week, which) { - 'use strict'; - - var candidates = _getCandidates(year, month, day_of_week), - d, - i, - res; - which = which.toLowerCase(); +function meetupDay(year, month, dayOfWeek, which) { + var candidates = _getCandidates(year, month, dayOfWeek); + var res; + var day; - if (which === 'teenth') { - res = _find(candidates, function (d) { - return d.getDate() >= 13 && d.getDate() <= 19; - }); - } else if (which === 'last') { + day = which.toLowerCase(); + if (day === 'teenth') { + res = _find(candidates, function (d) {return d.getDate() >= 13 && d.getDate() <= 19; }); + } else if (day === 'last') { res = candidates.pop(); } else { - which = parseInt(which) - 1; - res = candidates.slice(which, which + 1).pop(); + day = parseInt(day, 10) - 1; + res = candidates.slice(day, day + 1).pop(); } - if (!res) { throw new MeetupDayException('Day not found! ;_;'); } + if (!res) { throw new MeetupDayException('Day not found!'); } return res; } -function _getCandidates(year, month, day_of_week) { - var d, - i, - numDaysInMonth = new Date(year, month + 1, 0).getDate(), - res = []; +function _getCandidates(year, month, dayOfWeek) { + var d; + var i; + var numDaysInMonth = new Date(year, month + 1, 0).getDate(); + var res = []; for (i = 0; i < numDaysInMonth; i++) { d = new Date(year, month, i + 1); - if (d.getDay() === _getDayIndex(day_of_week)) { + if (d.getDay() === _getDayIndex(dayOfWeek)) { res.push(d); } } @@ -55,16 +52,16 @@ function _getDayIndex(day) { 'friday': 5, 'saturday': 6 }; - - day = day.toLowerCase(); - - return daysInd[day]; + return daysInd[day.toLowerCase()]; } function _find(ary, callback) { + var foundDay; for (var i = 0; i < ary.length; i++) { - if (callback(ary[i], i, ary)) { return ary[i]; } + if (callback(ary[i], i, ary)) foundDay = ary[i]; } + return foundDay; } module.exports = meetupDay; + diff --git a/exercises/meetup/meetup.spec.js b/exercises/meetup/meetup.spec.js index 054707f4..aa4b7a5b 100644 --- a/exercises/meetup/meetup.spec.js +++ b/exercises/meetup/meetup.spec.js @@ -1,11 +1,5 @@ var meetupDay = require('./meetup'); - -function MeetupDayException(message) { - this.message = message; - this.name = 'MeetupDayException'; -} - describe('meetupDay()', function () { it('monteenth of may 2013', function () { expect(meetupDay(2013, 4, 'Monday', 'teenth')).toEqual(new Date(2013, 4, 13)); From b3926add72d9294ef3eaa29d0fa9653b5362aec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Mon, 16 Oct 2017 17:38:27 -0300 Subject: [PATCH 175/272] Shows joelwallis as maintainer in Nextercism --- config/maintainers.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/maintainers.json b/config/maintainers.json index 49402a6c..ac09ca92 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -29,7 +29,7 @@ "link_text": null, "link_url": null, "name": null, - "show_on_website": false + "show_on_website": true }, { "alumnus": false, @@ -82,4 +82,4 @@ "show_on_website": false } ] -} \ No newline at end of file +} From 38e7a54f016bf87dfb4eea55ef95fc575979bfb7 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Mon, 16 Oct 2017 20:20:00 -0700 Subject: [PATCH 176/272] fix the change exercise --- exercises/change/example.js | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/exercises/change/example.js b/exercises/change/example.js index 4c71005b..89d3cd2a 100644 --- a/exercises/change/example.js +++ b/exercises/change/example.js @@ -14,7 +14,7 @@ var Candidate = function () { var searched = false; var coins = []; - this.Searched = function () { + this.searched = function () { searched = true; }; @@ -52,7 +52,7 @@ Change.prototype.calculate = function (coinArray, target) { candidates.fill(0); // validation checks up front - if (target == 0) return []; + if (target === 0) return []; if (target < 0) { throw new Error( 'Negative totals are not allowed.'); @@ -64,34 +64,18 @@ Change.prototype.calculate = function (coinArray, target) { initialize(); - // printAll(); - // process the arrange until everything is searched - while (isDone() == false) { + while (isDone() === false) { let candidate = getNext(); branch(candidate); - candidate.Searched(); + candidate.searched(); } - // printAll(); - // print the result if (typeof (candidates[target]) !== 'number') {return candidates[target].getCoins();} throw new Error('The total ' + target + ' cannot be represented in the given currency.'); - - // print the candidate array - function printAll() { - for (let j = 0; j < candidates.length; j++) { - if (typeof (candidates[j]) === 'object') { - console.log('index: ' + j + ' ' + candidates[j].getCoins() + ' searched: ' + candidates[j].isSearched()); - } else { - console.log('index: ' + j + ' is empty ' + typeof (candidates[j])); - } - } - } - // initialize the candidate array with the given coins only function initialize() { for (let j = 0; j < coinArray.length; j++) { @@ -108,7 +92,7 @@ Change.prototype.calculate = function (coinArray, target) { for (let i = 0; i < candidates.length; i++) { let temp = candidates[i]; if (typeof (temp) !== 'number') { - if (temp.isSearched() == false) { + if (temp.isSearched() === false) { done = false; break; } @@ -122,7 +106,7 @@ Change.prototype.calculate = function (coinArray, target) { for (let i = 0; i < candidates.length; i++) { let temp = candidates[i]; if (typeof (temp) !== 'number' && - temp.isSearched() == false) return temp; + temp.isSearched() === false) return temp; } return null; } From e0d2d9fac7d1c8e6dd653d8d2d6d6cd4be2a9b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 17 Oct 2017 16:17:20 +0200 Subject: [PATCH 177/272] Add rchavarria as maintainer (#428) --- config/maintainers.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/maintainers.json b/config/maintainers.json index 49402a6c..dfaaf27f 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -14,12 +14,12 @@ { "alumnus": false, "avatar_url": null, - "bio": null, + "bio": "I'm a Web Developer with a passion for taking code that is hard to maintain and cleaning, refactoring, and bringing it back into a manageable state", "github_username": "rchavarria", - "link_text": null, - "link_url": null, - "name": null, - "show_on_website": false + "link_text": "Here is where I blog", + "link_url": "https://rchavarria.github.io/", + "name": "Rubén Chavarría", + "show_on_website": true }, { "alumnus": false, @@ -82,4 +82,4 @@ "show_on_website": false } ] -} \ No newline at end of file +} From bf28486066b48de02454f4979bf9398fc0bad758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 17 Oct 2017 16:18:36 +0200 Subject: [PATCH 178/272] Add `README` file to `collatz-conjecture` exercise (#430) --- exercises/collatz-conjecture/README.md | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 exercises/collatz-conjecture/README.md diff --git a/exercises/collatz-conjecture/README.md b/exercises/collatz-conjecture/README.md new file mode 100644 index 00000000..e79a5db2 --- /dev/null +++ b/exercises/collatz-conjecture/README.md @@ -0,0 +1,57 @@ +# Collatz Conjecture + +The Collatz Conjecture or 3x+1 problem can be summarized as follows: + +Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is +odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely. +The conjecture states that no matter which number you start with, you will +always reach 1 eventually. + +Given a number n, return the number of steps required to reach 1. + +## Examples + +Starting with n = 12, the steps would be as follows: + +0. 12 +1. 6 +2. 3 +3. 10 +4. 5 +5. 16 +6. 8 +7. 4 +8. 2 +9. 1 + +Resulting in 9 steps. So for input n = 12, the return value would be 9. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +An unsolved problem in mathematics named after mathematician Lothar Collatz [https://en.wikipedia.org/wiki/3x_%2B_1_problem](https://en.wikipedia.org/wiki/3x_%2B_1_problem) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. From b11f6adef00f912f0b0cdf77bf7fb6a41b3fb329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Tue, 17 Oct 2017 16:18:57 +0200 Subject: [PATCH 179/272] Add `README` file for `transpose` exercise (#429) --- exercises/transpose/README.md | 89 +++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 exercises/transpose/README.md diff --git a/exercises/transpose/README.md b/exercises/transpose/README.md new file mode 100644 index 00000000..45e73ca0 --- /dev/null +++ b/exercises/transpose/README.md @@ -0,0 +1,89 @@ +# Transpose + +Given an input text output it transposed. + +Roughly explained, the transpose of a matrix: + +```text +ABC +DEF +``` + +is given by: + +```text +AD +BE +CF +``` + +Rows become columns and columns become rows. See . + +If the input has rows of different lengths, this is to be solved as follows: + +- Pad to the left with spaces. +- Don't pad to the right. + +Therefore, transposing this matrix: + +```text +ABC +DE +``` + +results in: + +```text +AD +BE +C +``` + +And transposing: + +```text +AB +DEF +``` + +results in: + +```text +AD +BE + F +``` + +In general, all characters from the input should also be present in the transposed output. +That means that if a column in the input text contains only spaces on its bottom-most row(s), +the corresponding output row should contain the spaces in its right-most column(s). + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Reddit r/dailyprogrammer challenge #270 [Easy]. [https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text](https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. From 88adec3b038656fdb362b6bbbd0fd4918cd27f37 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Tue, 17 Oct 2017 19:56:47 -0700 Subject: [PATCH 180/272] fix the protein-translation exercise --- exercises/protein-translation/example.js | 61 +++++---- .../protein-translation.spec.js | 120 +++++++++--------- 2 files changed, 90 insertions(+), 91 deletions(-) diff --git a/exercises/protein-translation/example.js b/exercises/protein-translation/example.js index 15d2cf99..59e291c3 100644 --- a/exercises/protein-translation/example.js +++ b/exercises/protein-translation/example.js @@ -6,16 +6,15 @@ function translate(rnaStrand) { var proteins = []; if (rnaStrand) { - for (var i = 0; i < rnaStrand.length; i+=3) { + for (var i = 0; i < rnaStrand.length; i += 3) { var protein = getProtein(rnaStrand.substring(i, i + 3)); if (protein) { - - if (protein === "STOP") { + if (protein === 'STOP') { break; } - if (protein === "INVALID") { + if (protein === 'INVALID') { throw new Error('Invalid codon'); } @@ -29,40 +28,40 @@ function translate(rnaStrand) { function getProtein(codon) { switch (codon) { - case "AUG": - return "Methionine"; + case 'AUG': + return 'Methionine'; - case "UUU": - case "UUC": - return "Phenylalanine"; + case 'UUU': + case 'UUC': + return 'Phenylalanine'; - case "UUA": - case "UUG": - return "Leucine"; + case 'UUA': + case 'UUG': + return 'Leucine'; - case "UCU": - case "UCC": - case "UCA": - case "UCG": - return "Serine"; + case 'UCU': + case 'UCC': + case 'UCA': + case 'UCG': + return 'Serine'; - case "UAU": - case "UAC": - return "Tyrosine"; + case 'UAU': + case 'UAC': + return 'Tyrosine'; - case "UGU": - case "UGC": - return "Cysteine"; + case 'UGU': + case 'UGC': + return 'Cysteine'; - case "UGG": - return "Tryptophan"; + case 'UGG': + return 'Tryptophan'; - case "UAA": - case "UAG": - case "UGA": - return "STOP"; + case 'UAA': + case 'UAG': + case 'UGA': + return 'STOP'; - default: - return "INVALID"; + default: + return 'INVALID'; } } diff --git a/exercises/protein-translation/protein-translation.spec.js b/exercises/protein-translation/protein-translation.spec.js index 3b3c700d..39279744 100644 --- a/exercises/protein-translation/protein-translation.spec.js +++ b/exercises/protein-translation/protein-translation.spec.js @@ -1,63 +1,63 @@ var translate = require('./protein-translation'); -describe('ProteinTranslation', function() { - it('Empty RNA has no proteins', function() { - expect(translate()).toEqual([]); - }); - - xit('Methionine codon translates into protein', function () { - expect(translate('AUG')).toEqual(["Methionine"]); - }); - - xit('Phenylalanine codons translate into protein', function () { - expect(translate('UUUUUC')).toEqual(["Phenylalanine", "Phenylalanine"]); - }); - - xit('Leucine codons translate into protein', function () { - expect(translate('UUAUUG')).toEqual(["Leucine", "Leucine"]); - }); - - xit('Serine codons translate into protein', function () { - expect(translate('UCUUCCUCAUCG')).toEqual(["Serine", "Serine", "Serine", "Serine"]); - }); - - xit('Tyrosine codons translate into protein', function () { - expect(translate('UAUUAC')).toEqual(["Tyrosine", "Tyrosine"]); - }); - - xit('Cysteine codons translate into protein', function() { - expect(translate('UGUUGC')).toEqual(["Cysteine", "Cysteine"]); - }); - - xit('Tryptophan codon translates into protein', function () { - expect(translate('UGG')).toEqual(["Tryptophan"]); - }); - - xit('Sequence starts with stop codon 1', function () { - expect(translate('UAAUUUUUA')).toEqual([]); - }); - - xit('Sequence starts with stop codon 2', function () { - expect(translate('UAGAUGUAU')).toEqual([]); - }); - - xit('Sequence starts with stop codon 3', function () { - expect(translate('UGAUGU')).toEqual([]); - }); - - xit('Small RNA strand', function () { - expect(translate('AUGUUUUCU')).toEqual(["Methionine", "Phenylalanine", "Serine"]); - }); - - xit('Stop codon ends translation', function () { - expect(translate('AUGUUUUCUUAAAUG')).toEqual(["Methionine", "Phenylalanine", "Serine"]); - }); - - xit('Invalid codon throws error', function () { - expect( - function() { - translate('LOL') - } - ).toThrow(new Error("Invalid codon")); - }) +describe('ProteinTranslation', function () { + it('Empty RNA has no proteins', function () { + expect(translate()).toEqual([]); + }); + + xit('Methionine codon translates into protein', function () { + expect(translate('AUG')).toEqual(['Methionine']); + }); + + xit('Phenylalanine codons translate into protein', function () { + expect(translate('UUUUUC')).toEqual(['Phenylalanine', 'Phenylalanine']); + }); + + xit('Leucine codons translate into protein', function () { + expect(translate('UUAUUG')).toEqual(['Leucine', 'Leucine']); + }); + + xit('Serine codons translate into protein', function () { + expect(translate('UCUUCCUCAUCG')).toEqual(['Serine', 'Serine', 'Serine', 'Serine']); + }); + + xit('Tyrosine codons translate into protein', function () { + expect(translate('UAUUAC')).toEqual(['Tyrosine', 'Tyrosine']); + }); + + xit('Cysteine codons translate into protein', function () { + expect(translate('UGUUGC')).toEqual(['Cysteine', 'Cysteine']); + }); + + xit('Tryptophan codon translates into protein', function () { + expect(translate('UGG')).toEqual(['Tryptophan']); + }); + + xit('Sequence starts with stop codon 1', function () { + expect(translate('UAAUUUUUA')).toEqual([]); + }); + + xit('Sequence starts with stop codon 2', function () { + expect(translate('UAGAUGUAU')).toEqual([]); + }); + + xit('Sequence starts with stop codon 3', function () { + expect(translate('UGAUGU')).toEqual([]); + }); + + xit('Small RNA strand', function () { + expect(translate('AUGUUUUCU')).toEqual(['Methionine', 'Phenylalanine', 'Serine']); + }); + + xit('Stop codon ends translation', function () { + expect(translate('AUGUUUUCUUAAAUG')).toEqual(['Methionine', 'Phenylalanine', 'Serine']); + }); + + xit('Invalid codon throws error', function () { + expect( + function () { + translate('LOL'); + } + ).toThrow(new Error('Invalid codon')); + }); }); From 6b611c7f7aade7465082c2415416f3223652b808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Wallis=20Juc=C3=A1?= Date: Wed, 18 Oct 2017 10:52:47 -0300 Subject: [PATCH 181/272] Adds a proper bio to joelwallis at config/maintainers.json --- config/maintainers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/maintainers.json b/config/maintainers.json index ac09ca92..0ca9d5cb 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -24,7 +24,7 @@ { "alumnus": false, "avatar_url": null, - "bio": null, + "bio": "Brazilian full-stack web developer. Mentor at Thinkful", "github_username": "joelwallis", "link_text": null, "link_url": null, From 862b5f9ff26679ad08908f38f632e8c6054a68f5 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+Radix16@users.noreply.github.com> Date: Sat, 21 Oct 2017 14:42:11 -0700 Subject: [PATCH 182/272] fix the twelve-days exercise (#435) --- exercises/twelve-days/example.js | 48 +++++++++++++++----------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/exercises/twelve-days/example.js b/exercises/twelve-days/example.js index aa8be9ac..38001978 100644 --- a/exercises/twelve-days/example.js +++ b/exercises/twelve-days/example.js @@ -1,40 +1,38 @@ -var TwelveDays = function() { +var TwelveDays = function () { this.verseList = [ - 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.', - 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - 'On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', - ]; - - + 'On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree.', + 'On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.', + 'On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree.' + ]; }; -TwelveDays.prototype.startFromZero = function(oneIndexArray) { - var newArray = oneIndexArray.map(function(item) { return item - 1; }); +TwelveDays.prototype.startFromZero = function (oneIndexArray) { + var newArray = oneIndexArray.map(function (item) { return item - 1; }); return newArray; }; -TwelveDays.prototype.singleVerse = function(verseIndex) { +TwelveDays.prototype.singleVerse = function (verseIndex) { var verse = this.verseList[verseIndex].concat('\n'); return verse; }; -TwelveDays.prototype.multiVerse = function(startIndex, endIndex) { +TwelveDays.prototype.multiVerse = function (startIndex, endIndex) { return this.verseList - .filter(function (verse, index) { return index >= startIndex; }) - .filter(function (verse, index) { return index <= endIndex }) - .join('\n\n').concat('\n'); + .filter(function (verse, index) { return index >= startIndex; }) + .filter(function (verse, index) { return index <= endIndex; }) + .join('\n\n').concat('\n'); }; -TwelveDays.prototype.verse = function(args) { +TwelveDays.prototype.verse = function (args) { var indexArray = this.startFromZero(args); if (args.length === 2) { @@ -43,7 +41,7 @@ TwelveDays.prototype.verse = function(args) { return this.singleVerse(indexArray[0]); }; -TwelveDays.prototype.sing = function() { +TwelveDays.prototype.sing = function () { var song = this.verseList.join('\n\n').concat('\n'); return song; }; From 5e10804d0d27761b1cbdb1c83bd2ca6f0d9a17b6 Mon Sep 17 00:00:00 2001 From: a-dpq <25420077+a-dpq@users.noreply.github.com> Date: Sun, 22 Oct 2017 17:22:43 +0200 Subject: [PATCH 183/272] Fix grammatical errors --- exercises/palindrome-products/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md index 9d4d6d61..c324677c 100644 --- a/exercises/palindrome-products/README.md +++ b/exercises/palindrome-products/README.md @@ -16,22 +16,22 @@ It's possible (and indeed common) for a palindrome product to be the product of multiple combinations of numbers. For example, the palindrome product `9` has the factors `(1, 9)`, `(3, 3)`, and `(9, 1)`. -Write a program that given a range of integers, returns the smallest and largest -palindromic product within that range, along with all of it's factors. +Write a program that, given a range of integers, returns the smallest and largest +palindromic product within that range, along with all of its factors. ## Example 1 Given the range `[1, 9]` (both inclusive)... -The smallest product is `1`. It's factors are `(1, 1)`. -The largest product is `9`. It's factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. +The smallest product is `1`. Its factors are `(1, 1)`. +The largest product is `9`. Its factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. ## Example 2 Given the range `[10, 99]` (both inclusive)... -The smallest palindrome product is `121`. It's factors are `(11, 11)`. -The largest palindrome product is `9009`. It's factors are `(91, 99)` and `(99, 91)`. +The smallest palindrome product is `121`. Its factors are `(11, 11)`. +The largest palindrome product is `9009`. Its factors are `(91, 99)` and `(99, 91)`. ## Setup From 7b66c85b42624611202a97b2a6833c0dc293fcea Mon Sep 17 00:00:00 2001 From: a-dpq <25420077+a-dpq@users.noreply.github.com> Date: Mon, 23 Oct 2017 16:05:05 +0200 Subject: [PATCH 184/272] Fix grammatical errors (#436) --- exercises/palindrome-products/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md index 9d4d6d61..c324677c 100644 --- a/exercises/palindrome-products/README.md +++ b/exercises/palindrome-products/README.md @@ -16,22 +16,22 @@ It's possible (and indeed common) for a palindrome product to be the product of multiple combinations of numbers. For example, the palindrome product `9` has the factors `(1, 9)`, `(3, 3)`, and `(9, 1)`. -Write a program that given a range of integers, returns the smallest and largest -palindromic product within that range, along with all of it's factors. +Write a program that, given a range of integers, returns the smallest and largest +palindromic product within that range, along with all of its factors. ## Example 1 Given the range `[1, 9]` (both inclusive)... -The smallest product is `1`. It's factors are `(1, 1)`. -The largest product is `9`. It's factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. +The smallest product is `1`. Its factors are `(1, 1)`. +The largest product is `9`. Its factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. ## Example 2 Given the range `[10, 99]` (both inclusive)... -The smallest palindrome product is `121`. It's factors are `(11, 11)`. -The largest palindrome product is `9009`. It's factors are `(91, 99)` and `(99, 91)`. +The smallest palindrome product is `121`. Its factors are `(11, 11)`. +The largest palindrome product is `9009`. Its factors are `(91, 99)` and `(99, 91)`. ## Setup From 96325c669f17ef1385fe815120ca4cc53ece3a8e Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Mon, 23 Oct 2017 17:03:36 -0200 Subject: [PATCH 185/272] Implement exercise: zipper --- config.json | 12 ++++ exercises/zipper/README.md | 55 ++++++++++++++++++ exercises/zipper/example.js | 100 ++++++++++++++++++++++++++++++++ exercises/zipper/zipper.spec.js | 77 ++++++++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 exercises/zipper/README.md create mode 100644 exercises/zipper/example.js create mode 100644 exercises/zipper/zipper.spec.js diff --git a/config.json b/config.json index fb9da65b..73522338 100644 --- a/config.json +++ b/config.json @@ -1123,6 +1123,18 @@ "strings", "algorithms" ] + }, + { + "uuid": "f4a3d66a-04a8-3e80-6c9a-8a573ccb26fd9ed1d5c", + "slug": "zipper", + "core": false, + "unlocked_by": null, + "difficulty": 8, + "topics": [ + "recursion", + "searching", + "trees" + ] } ], "foregone": [], diff --git a/exercises/zipper/README.md b/exercises/zipper/README.md new file mode 100644 index 00000000..ae7adf1a --- /dev/null +++ b/exercises/zipper/README.md @@ -0,0 +1,55 @@ +# Zipper + +Creating a zipper for a binary tree. + +[Zippers](https://en.wikipedia.org/wiki/Zipper_%28data_structure%29) are +a way purely functional of navigating within a data structure and +manipulating it. They essentially contain a data structure and a +pointer into that data structure (called the focus). + +For example given a rose tree (where each node contains a value and a +list of child nodes) a zipper might support these operations: + +- `from_tree` (get a zipper out of a rose tree, the focus is on the root node) +- `to_tree` (get the rose tree out of the zipper) +- `value` (get the value of the focus node) +- `prev` (move the focus to the previous child of the same parent, + returns a new zipper) +- `next` (move the focus to the next child of the same parent, returns a + new zipper) +- `up` (move the focus to the parent, returns a new zipper) +- `set_value` (set the value of the focus node, returns a new zipper) +- `insert_before` (insert a new subtree before the focus node, it + becomes the `prev` of the focus node, returns a new zipper) +- `insert_after` (insert a new subtree after the focus node, it becomes + the `next` of the focus node, returns a new zipper) +- `delete` (removes the focus node and all subtrees, focus moves to the + `next` node if possible otherwise to the `prev` node if possible, + otherwise to the parent node, returns a new zipper) + + ## Setup + + Go through the setup instructions for JavaScript to + install the necessary dependencies: + + http://exercism.io/languages/javascript + + ## Making the Test Suite Pass + + Execute the tests with: + + jasmine .spec.js + + Replace `` with the name of the current exercise. E.g., to + test the Hello World exercise: + + jasmine hello-world.spec.js + + All but the first test have been skipped. + + Once you get a test passing, you can unskip the next one by + changing `xit` to `it`. + + + ## Submitting Incomplete Solutions + It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/zipper/example.js b/exercises/zipper/example.js new file mode 100644 index 00000000..d651c4ef --- /dev/null +++ b/exercises/zipper/example.js @@ -0,0 +1,100 @@ +'use strict'; + +function fromTrail(tree, last) { + if (last[0] === 'left') { + return { + value: last[1], + left: tree, + right: last[2] + }; + } + return { + value: last[1], + left: last[2], + right: tree + }; +} + +function rebuildTree(tree, trail) { + if (trail.length === 0) return tree; + + var last = trail[0]; + return rebuildTree(fromTrail(tree, last), trail.slice(1)); +} + +var Zipper = function (tree, trail) { + this.tree = tree; + this.trail = trail; +}; + +Zipper.fromTree = function (tree) { + return new Zipper(tree, []); +}; + +Zipper.prototype.toTree = function () { + return rebuildTree(this.tree, this.trail); +}; + +Zipper.prototype.value = function () { + return this.tree.value; +}; + +Zipper.prototype.left = function () { + if (!this.tree.left) return null; + + return new Zipper( + this.tree.left, + [['left', this.tree.value, this.tree.right]].concat(this.trail) + ); +}; + +Zipper.prototype.right = function () { + if (!this.tree.right) return null; + + return new Zipper( + this.tree.right, + [['right', this.tree.value, this.tree.left]].concat(this.trail) + ); +}; + +Zipper.prototype.up = function () { + if (this.trail.length === 0) return null; + + var last = this.trail[0]; + return new Zipper(fromTrail(this.tree, last), this.trail.slice(1)); +}; + +Zipper.prototype.setValue = function (value) { + return new Zipper( + { + value: value, + left: this.tree.left, + right: this.tree.right + }, + this.trail + ); +}; + +Zipper.prototype.setLeft = function (left) { + return new Zipper( + { + value: this.tree.value, + left: left, + right: this.tree.right + }, + this.trail + ); +}; + +Zipper.prototype.setRight = function (right) { + return new Zipper( + { + value: this.tree.value, + left: this.tree.left, + right: right + }, + this.trail + ); +}; + +module.exports = Zipper; diff --git a/exercises/zipper/zipper.spec.js b/exercises/zipper/zipper.spec.js new file mode 100644 index 00000000..c3b95d12 --- /dev/null +++ b/exercises/zipper/zipper.spec.js @@ -0,0 +1,77 @@ +var Zipper = require('./zipper'); + +// Tests adapted from `problem-specifications/zipper/canonical-data.json` @ v1.0.0 + +function bt(value, left, right) { + return { + value: value, + left: left, + right: right + }; +} + +function leaf(value) { + return bt(value, null, null); +} + +describe('Zipper', function () { + var t1 = bt(1, bt(2, null, leaf(3)), leaf(4)); + var t2 = bt(1, bt(5, null, leaf(3)), leaf(4)); + var t3 = bt(1, bt(2, leaf(5), leaf(3)), leaf(4)); + var t4 = bt(1, leaf(2), leaf(4)); + var t5 = bt(1, bt(2, null, leaf(3)), bt(6, leaf(7), leaf(8))); + var t6 = bt(1, bt(2, null, leaf(5)), leaf(4)); + var zipper; + + beforeEach(function () { + zipper = Zipper.fromTree(t1); + }); + + it('data is retained', function () { + expect(zipper.toTree(t1)).toEqual(t1); + }); + + xit('left, right and value', function () { + expect(zipper.left().right().value()).toEqual(3); + }); + + xit('dead end', function () { + expect(zipper.left().left()).toBe(null); + }); + + xit('tree from deep focus', function () { + expect(zipper.left().right().toTree()).toEqual(t1); + }); + + xit('traversing up from top', function () { + expect(zipper.up()).toEqual(null); + }); + + xit('left, right and up', function () { + expect(zipper.left().up().right().up().left().right().value()).toEqual(3); + }); + + xit('setValue', function () { + expect(zipper.left().setValue(5).toTree()).toEqual(t2); + }); + + xit('setValue after traversing up', function () { + expect(zipper.left().right().up().setValue(5).toTree()).toEqual(t2); + }); + + xit('setLeft with leaf', function () { + expect(zipper.left().setLeft(leaf(5)).toTree()).toEqual(t3); + }); + + xit('setRight with null', function () { + expect(zipper.left().setRight(null).toTree()).toEqual(t4); + }); + + xit('setRight with subtree', function () { + expect(zipper.setRight(bt(6, leaf(7), leaf(8))).toTree()).toEqual(t5); + }); + + xit('setValue on deep focus', function () { + expect(zipper.left().right().setValue(5).toTree()).toEqual(t6); + }); +}); From 9f5072147ba34c64552bdfb21d41e00adab3a729 Mon Sep 17 00:00:00 2001 From: PakkuDon Date: Tue, 24 Oct 2017 14:56:43 +1100 Subject: [PATCH 186/272] Fix eslint errors in prime-factors --- exercises/prime-factors/example.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/exercises/prime-factors/example.js b/exercises/prime-factors/example.js index 0b6d316a..74f2c150 100644 --- a/exercises/prime-factors/example.js +++ b/exercises/prime-factors/example.js @@ -1,15 +1,16 @@ 'use strict'; exports.for = function (n) { - var prime_factors = []; - var possible_factor = 2; - while (possible_factor * possible_factor <= n) { - while (n % possible_factor === 0) { - prime_factors.push(possible_factor); - n /= possible_factor; + var primeFactors = []; + var possibleFactor = 2; + var number = n; + while (possibleFactor * possibleFactor <= number) { + while (number % possibleFactor === 0) { + primeFactors.push(possibleFactor); + number /= possibleFactor; } - possible_factor += 1; + possibleFactor += 1; } - if (n > 1) { prime_factors.push(n); } - return prime_factors; + if (number > 1) { primeFactors.push(number); } + return primeFactors; }; From 39c08bcbc298b94c644baf34563ff14a8413bdc7 Mon Sep 17 00:00:00 2001 From: ardepas Date: Thu, 26 Oct 2017 15:24:37 +0200 Subject: [PATCH 187/272] Fix capitalization in titles --- exercises/difference-of-squares/README.md | 2 +- exercises/sum-of-multiples/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/difference-of-squares/README.md b/exercises/difference-of-squares/README.md index 5d05e84a..e4320442 100644 --- a/exercises/difference-of-squares/README.md +++ b/exercises/difference-of-squares/README.md @@ -1,4 +1,4 @@ -# Difference Of Squares +# Difference of Squares Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md index 7766bd68..4ce73e90 100644 --- a/exercises/sum-of-multiples/README.md +++ b/exercises/sum-of-multiples/README.md @@ -1,4 +1,4 @@ -# Sum Of Multiples +# Sum of Multiples Given a number, find the sum of all the multiples of particular numbers up to but not including that number. From 23a6a3bafb4dfd06e11fa76914455f676474fbb4 Mon Sep 17 00:00:00 2001 From: a-dpq <25420077+a-dpq@users.noreply.github.com> Date: Fri, 27 Oct 2017 01:35:47 +0200 Subject: [PATCH 188/272] Fix capitalization in headlines of readme files (#442) * Fix grammatical errors * Fix capitalization in titles --- exercises/difference-of-squares/README.md | 2 +- exercises/sum-of-multiples/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/difference-of-squares/README.md b/exercises/difference-of-squares/README.md index 5d05e84a..e4320442 100644 --- a/exercises/difference-of-squares/README.md +++ b/exercises/difference-of-squares/README.md @@ -1,4 +1,4 @@ -# Difference Of Squares +# Difference of Squares Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md index 7766bd68..4ce73e90 100644 --- a/exercises/sum-of-multiples/README.md +++ b/exercises/sum-of-multiples/README.md @@ -1,4 +1,4 @@ -# Sum Of Multiples +# Sum of Multiples Given a number, find the sum of all the multiples of particular numbers up to but not including that number. From d6c0bd8e93ed5d9c330c5fb094803682f09c299b Mon Sep 17 00:00:00 2001 From: Lougenia Date: Sun, 29 Oct 2017 03:21:58 -0400 Subject: [PATCH 189/272] Fixed lint issues in beer song example --- exercises/beer-song/example.js | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/exercises/beer-song/example.js b/exercises/beer-song/example.js index f50a79d5..89f31811 100644 --- a/exercises/beer-song/example.js +++ b/exercises/beer-song/example.js @@ -15,39 +15,43 @@ return str; } - function action(current_verse) { - var sbj, str = ''; + function action(currentVerse) { + var sbj; + var str = ''; - if (current_verse === 0) { + if (currentVerse === 0) { str = 'Go to the store and buy some more, '; } else { - sbj = (current_verse === 1 ? 'it' : 'one'); + sbj = (currentVerse === 1 ? 'it' : 'one'); str = 'Take ' + sbj + ' down and pass it around, '; } return str; } - function next_bottle(current_verse) { - return bottles(next_verse(current_verse)).toLowerCase() + ' of beer on the wall.\n'; + function nextBottle(currentVerse) { + return bottles(nextVerse(currentVerse)).toLowerCase() + ' of beer on the wall.\n'; } - function next_verse(current_verse) { - return current_verse === 0 ? 99 : (current_verse - 1); + function nextVerse(currentVerse) { + return currentVerse === 0 ? 99 : (currentVerse - 1); } function BeerSong() {} BeerSong.prototype.sing = function (first, last) { - if (typeof (first) === 'undefined') { - first = 99; + var firstVerseBottleCount = first; + var lastVerseBottleCount = last; + + if (typeof (firstVerseBottleCount) === 'undefined') { + firstVerseBottleCount = 99; } - if (typeof (last) === 'undefined') { - last = 0; + if (typeof (lastVerseBottleCount) === 'undefined') { + lastVerseBottleCount = 0; } var verses = []; - for (var i = first; i >= last; i--) { + for (var i = firstVerseBottleCount; i >= lastVerseBottleCount; i--) { verses.push(this.verse(i)); } @@ -58,7 +62,7 @@ var line1 = bottles(number) + ' of beer on the wall, '; var line2 = bottles(number).toLowerCase() + ' of beer.\n'; var line3 = action(number); - var line4 = next_bottle(number); + var line4 = nextBottle(number); return [line1, line2, line3, line4].join(''); }; From 0a1d6f50cee90a66350306977112905c8e1dccdd Mon Sep 17 00:00:00 2001 From: Evgeny Shmarnev Date: Mon, 30 Oct 2017 09:19:12 +0100 Subject: [PATCH 190/272] 447 - Fix the path to setup page for each exercise --- exercises/acronym/README.md | 2 +- exercises/all-your-base/README.md | 2 +- exercises/allergies/README.md | 2 +- exercises/alphametics/README.md | 2 +- exercises/anagram/README.md | 2 +- exercises/atbash-cipher/README.md | 2 +- exercises/beer-song/README.md | 2 +- exercises/binary-search-tree/README.md | 2 +- exercises/binary-search/README.md | 2 +- exercises/binary/README.md | 2 +- exercises/bob/README.md | 2 +- exercises/bowling/README.md | 2 +- exercises/bracket-push/README.md | 2 +- exercises/change/README.md | 2 +- exercises/circular-buffer/README.md | 2 +- exercises/clock/README.md | 2 +- exercises/collatz-conjecture/README.md | 2 +- exercises/crypto-square/README.md | 2 +- exercises/custom-set/README.md | 2 +- exercises/diamond/README.md | 2 +- exercises/difference-of-squares/README.md | 2 +- exercises/diffie-hellman/README.md | 2 +- exercises/etl/README.md | 2 +- exercises/flatten-array/README.md | 2 +- exercises/food-chain/README.md | 2 +- exercises/gigasecond/README.md | 2 +- exercises/grade-school/README.md | 2 +- exercises/grains/README.md | 2 +- exercises/hamming/README.md | 2 +- exercises/hello-world/README.md | 2 +- exercises/hexadecimal/README.md | 2 +- exercises/isogram/README.md | 2 +- exercises/kindergarten-garden/README.md | 2 +- exercises/largest-series-product/README.md | 2 +- exercises/leap/README.md | 2 +- exercises/linked-list/README.md | 2 +- exercises/list-ops/README.md | 2 +- exercises/luhn/README.md | 2 +- exercises/matrix/README.md | 2 +- exercises/meetup/README.md | 2 +- exercises/minesweeper/README.md | 2 +- exercises/nth-prime/README.md | 2 +- exercises/nucleotide-count/README.md | 2 +- exercises/ocr-numbers/README.md | 2 +- exercises/octal/README.md | 2 +- exercises/palindrome-products/README.md | 2 +- exercises/pangram/README.md | 2 +- exercises/pascals-triangle/README.md | 2 +- exercises/perfect-numbers/README.md | 2 +- exercises/phone-number/README.md | 2 +- exercises/pig-latin/README.md | 2 +- exercises/point-mutations/README.md | 2 +- exercises/prime-factors/README.md | 2 +- exercises/protein-translation/README.md | 2 +- exercises/proverb/README.md | 2 +- exercises/pythagorean-triplet/README.md | 2 +- exercises/queen-attack/README.md | 2 +- exercises/raindrops/README.md | 2 +- exercises/rna-transcription/README.md | 2 +- exercises/robot-name/README.md | 2 +- exercises/robot-simulator/README.md | 2 +- exercises/roman-numerals/README.md | 2 +- exercises/run-length-encoding/README.md | 2 +- exercises/saddle-points/README.md | 2 +- exercises/say/README.md | 2 +- exercises/scrabble-score/README.md | 2 +- exercises/secret-handshake/README.md | 2 +- exercises/series/README.md | 2 +- exercises/sieve/README.md | 2 +- exercises/simple-cipher/README.md | 2 +- exercises/simple-linked-list/README.md | 2 +- exercises/space-age/README.md | 2 +- exercises/strain/README.md | 2 +- exercises/sum-of-multiples/README.md | 2 +- exercises/transpose/README.md | 2 +- exercises/triangle/README.md | 2 +- exercises/trinary/README.md | 2 +- exercises/twelve-days/README.md | 2 +- exercises/two-bucket/README.md | 2 +- exercises/word-count/README.md | 2 +- exercises/wordy/README.md | 2 +- exercises/zipper/README.md | 2 +- 82 files changed, 82 insertions(+), 82 deletions(-) diff --git a/exercises/acronym/README.md b/exercises/acronym/README.md index 3cc46d74..cfb380f8 100644 --- a/exercises/acronym/README.md +++ b/exercises/acronym/README.md @@ -13,7 +13,7 @@ like Portable Network Graphics to its acronym (PNG). Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/all-your-base/README.md b/exercises/all-your-base/README.md index 5971b557..d6628a9c 100644 --- a/exercises/all-your-base/README.md +++ b/exercises/all-your-base/README.md @@ -36,7 +36,7 @@ I think you got the idea! Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/allergies/README.md b/exercises/allergies/README.md index af0072d6..89046315 100644 --- a/exercises/allergies/README.md +++ b/exercises/allergies/README.md @@ -35,7 +35,7 @@ score is 257, your program should only report the eggs (1) allergy. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/alphametics/README.md b/exercises/alphametics/README.md index d96936f2..d34850b4 100644 --- a/exercises/alphametics/README.md +++ b/exercises/alphametics/README.md @@ -36,7 +36,7 @@ Write a function to solve alphametics puzzles. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/anagram/README.md b/exercises/anagram/README.md index f9b4bf5c..3d99a0e6 100644 --- a/exercises/anagram/README.md +++ b/exercises/anagram/README.md @@ -11,7 +11,7 @@ Given `"listen"` and a list of candidates like `"enlists" "google" Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/atbash-cipher/README.md b/exercises/atbash-cipher/README.md index 57634176..d9d602b1 100644 --- a/exercises/atbash-cipher/README.md +++ b/exercises/atbash-cipher/README.md @@ -32,7 +32,7 @@ things based on word boundaries. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/beer-song/README.md b/exercises/beer-song/README.md index 57089d1d..490f7b52 100644 --- a/exercises/beer-song/README.md +++ b/exercises/beer-song/README.md @@ -325,7 +325,7 @@ experiment make the code better? Worse? Did you learn anything from it? Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md index 5b864ebc..5a2648eb 100644 --- a/exercises/binary-search-tree/README.md +++ b/exercises/binary-search-tree/README.md @@ -58,7 +58,7 @@ And if we then added 1, 5, and 7, it would look like this Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/binary-search/README.md b/exercises/binary-search/README.md index 2aa09ad1..a83868eb 100644 --- a/exercises/binary-search/README.md +++ b/exercises/binary-search/README.md @@ -39,7 +39,7 @@ A binary search is a dichotomic divide and conquer search algorithm. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/binary/README.md b/exercises/binary/README.md index c41024b0..9183cd4b 100644 --- a/exercises/binary/README.md +++ b/exercises/binary/README.md @@ -33,7 +33,7 @@ So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/bob/README.md b/exercises/bob/README.md index b53ec785..d26c8d06 100644 --- a/exercises/bob/README.md +++ b/exercises/bob/README.md @@ -16,7 +16,7 @@ He answers 'Whatever.' to anything else. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md index b8342c33..bed2951e 100644 --- a/exercises/bowling/README.md +++ b/exercises/bowling/README.md @@ -51,7 +51,7 @@ support two operations: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/bracket-push/README.md b/exercises/bracket-push/README.md index 0496d2f1..d4c8ffee 100644 --- a/exercises/bracket-push/README.md +++ b/exercises/bracket-push/README.md @@ -8,7 +8,7 @@ verify that all the pairs are matched and nested correctly. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/change/README.md b/exercises/change/README.md index 44bf1f65..397a10d3 100644 --- a/exercises/change/README.md +++ b/exercises/change/README.md @@ -13,7 +13,7 @@ result is an array with the values: 1, 1, 10 and 25. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/circular-buffer/README.md b/exercises/circular-buffer/README.md index 14f497e5..b2c73837 100644 --- a/exercises/circular-buffer/README.md +++ b/exercises/circular-buffer/README.md @@ -48,7 +48,7 @@ buffer with: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/clock/README.md b/exercises/clock/README.md index 0427655d..5637488c 100644 --- a/exercises/clock/README.md +++ b/exercises/clock/README.md @@ -11,7 +11,7 @@ Two clocks that represent the same time should be equal to each other. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/collatz-conjecture/README.md b/exercises/collatz-conjecture/README.md index e79a5db2..7bec9e1a 100644 --- a/exercises/collatz-conjecture/README.md +++ b/exercises/collatz-conjecture/README.md @@ -31,7 +31,7 @@ Resulting in 9 steps. So for input n = 12, the return value would be 9. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/crypto-square/README.md b/exercises/crypto-square/README.md index 515f68f2..fa464ca5 100644 --- a/exercises/crypto-square/README.md +++ b/exercises/crypto-square/README.md @@ -72,7 +72,7 @@ sseoau Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/custom-set/README.md b/exercises/custom-set/README.md index 765ce0be..4c5c5d81 100644 --- a/exercises/custom-set/README.md +++ b/exercises/custom-set/README.md @@ -12,7 +12,7 @@ unique elements. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/diamond/README.md b/exercises/diamond/README.md index 6dab43a6..606d7dda 100644 --- a/exercises/diamond/README.md +++ b/exercises/diamond/README.md @@ -57,7 +57,7 @@ E·······E Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/difference-of-squares/README.md b/exercises/difference-of-squares/README.md index e4320442..1377b5f9 100644 --- a/exercises/difference-of-squares/README.md +++ b/exercises/difference-of-squares/README.md @@ -17,7 +17,7 @@ natural numbers is 3025 - 385 = 2640. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/diffie-hellman/README.md b/exercises/diffie-hellman/README.md index 2a8453fb..5d72a84e 100644 --- a/exercises/diffie-hellman/README.md +++ b/exercises/diffie-hellman/README.md @@ -42,7 +42,7 @@ secret s. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Requirements diff --git a/exercises/etl/README.md b/exercises/etl/README.md index 3cbb4ed5..218aaeb3 100644 --- a/exercises/etl/README.md +++ b/exercises/etl/README.md @@ -49,7 +49,7 @@ game while being scored at 4 in the Hawaiian-language version. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/flatten-array/README.md b/exercises/flatten-array/README.md index bdb7ff67..d76bb103 100644 --- a/exercises/flatten-array/README.md +++ b/exercises/flatten-array/README.md @@ -16,7 +16,7 @@ output: [1,2,3,4,5] Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/food-chain/README.md b/exercises/food-chain/README.md index 9386f059..cc3874ef 100644 --- a/exercises/food-chain/README.md +++ b/exercises/food-chain/README.md @@ -68,7 +68,7 @@ She's dead, of course! Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/gigasecond/README.md b/exercises/gigasecond/README.md index 4c73cb89..ad46af02 100644 --- a/exercises/gigasecond/README.md +++ b/exercises/gigasecond/README.md @@ -9,7 +9,7 @@ A gigasecond is 10^9 (1,000,000,000) seconds. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/grade-school/README.md b/exercises/grade-school/README.md index 9a34bb7e..ac8cda81 100644 --- a/exercises/grade-school/README.md +++ b/exercises/grade-school/README.md @@ -40,7 +40,7 @@ experiment make the code better? Worse? Did you learn anything from it? Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/grains/README.md b/exercises/grains/README.md index bac15508..21a9717f 100644 --- a/exercises/grains/README.md +++ b/exercises/grains/README.md @@ -32,7 +32,7 @@ experiment make the code better? Worse? Did you learn anything from it? Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/hamming/README.md b/exercises/hamming/README.md index f44a9feb..1c91a23b 100644 --- a/exercises/hamming/README.md +++ b/exercises/hamming/README.md @@ -40,7 +40,7 @@ of equal length differently. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/hello-world/README.md b/exercises/hello-world/README.md index 7e71e8a7..2ea80dec 100644 --- a/exercises/hello-world/README.md +++ b/exercises/hello-world/README.md @@ -106,7 +106,7 @@ When you are done, submit your solution to exercism: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/hexadecimal/README.md b/exercises/hexadecimal/README.md index 022fe2bf..fd75f926 100644 --- a/exercises/hexadecimal/README.md +++ b/exercises/hexadecimal/README.md @@ -12,7 +12,7 @@ The program should handle invalid hexadecimal strings. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/isogram/README.md b/exercises/isogram/README.md index 369373af..47b1fa2a 100644 --- a/exercises/isogram/README.md +++ b/exercises/isogram/README.md @@ -17,7 +17,7 @@ The word *isograms*, however, is not an isogram, because the s repeats. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/kindergarten-garden/README.md b/exercises/kindergarten-garden/README.md index 15e4187d..508dd181 100644 --- a/exercises/kindergarten-garden/README.md +++ b/exercises/kindergarten-garden/README.md @@ -64,7 +64,7 @@ While asking for Bob's plants would yield: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/largest-series-product/README.md b/exercises/largest-series-product/README.md index 1d56a017..9fab5031 100644 --- a/exercises/largest-series-product/README.md +++ b/exercises/largest-series-product/README.md @@ -18,7 +18,7 @@ the largest product for a series of 6 digits is 23520. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/leap/README.md b/exercises/leap/README.md index 8f87cfcb..eb2d2b6f 100644 --- a/exercises/leap/README.md +++ b/exercises/leap/README.md @@ -31,7 +31,7 @@ phenomenon, go watch [this youtube video][video]. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/linked-list/README.md b/exercises/linked-list/README.md index d719f252..fbf47f55 100644 --- a/exercises/linked-list/README.md +++ b/exercises/linked-list/README.md @@ -32,7 +32,7 @@ If you want to know more about linked lists, check [Wikipedia](https://en.wikipe Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/list-ops/README.md b/exercises/list-ops/README.md index cfbf36e6..13eaa17d 100644 --- a/exercises/list-ops/README.md +++ b/exercises/list-ops/README.md @@ -11,7 +11,7 @@ without using existing functions. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/luhn/README.md b/exercises/luhn/README.md index 217faccc..0338fa3e 100644 --- a/exercises/luhn/README.md +++ b/exercises/luhn/README.md @@ -69,7 +69,7 @@ Sum the digits Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/matrix/README.md b/exercises/matrix/README.md index 3b427e26..11334675 100644 --- a/exercises/matrix/README.md +++ b/exercises/matrix/README.md @@ -43,7 +43,7 @@ And its columns: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/meetup/README.md b/exercises/meetup/README.md index fb20f112..f7b6da03 100644 --- a/exercises/meetup/README.md +++ b/exercises/meetup/README.md @@ -28,7 +28,7 @@ For example, if given "First Monday of January 2017", the correct meetup date is Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/minesweeper/README.md b/exercises/minesweeper/README.md index 6b0e55de..6d7cd2f4 100644 --- a/exercises/minesweeper/README.md +++ b/exercises/minesweeper/README.md @@ -31,7 +31,7 @@ into this: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/nth-prime/README.md b/exercises/nth-prime/README.md index 84bae01d..881b4912 100644 --- a/exercises/nth-prime/README.md +++ b/exercises/nth-prime/README.md @@ -13,7 +13,7 @@ numbers, pretend they don't exist and implement them yourself. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/nucleotide-count/README.md b/exercises/nucleotide-count/README.md index 8f0622dc..09c15876 100644 --- a/exercises/nucleotide-count/README.md +++ b/exercises/nucleotide-count/README.md @@ -31,7 +31,7 @@ about that for now. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/ocr-numbers/README.md b/exercises/ocr-numbers/README.md index 0a7e5338..e735dfdd 100644 --- a/exercises/ocr-numbers/README.md +++ b/exercises/ocr-numbers/README.md @@ -83,7 +83,7 @@ Is converted to "123,456,789" Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/octal/README.md b/exercises/octal/README.md index a791ac8d..7726a323 100644 --- a/exercises/octal/README.md +++ b/exercises/octal/README.md @@ -47,7 +47,7 @@ So: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md index c324677c..101d935c 100644 --- a/exercises/palindrome-products/README.md +++ b/exercises/palindrome-products/README.md @@ -38,7 +38,7 @@ The largest palindrome product is `9009`. Its factors are `(91, 99)` and `(99, 9 Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/pangram/README.md b/exercises/pangram/README.md index 9fceecd9..0fefa229 100644 --- a/exercises/pangram/README.md +++ b/exercises/pangram/README.md @@ -13,7 +13,7 @@ insensitive. Input will not contain non-ASCII symbols. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/pascals-triangle/README.md b/exercises/pascals-triangle/README.md index cf72686d..fbd99f84 100644 --- a/exercises/pascals-triangle/README.md +++ b/exercises/pascals-triangle/README.md @@ -19,7 +19,7 @@ the right and left of the current position in the previous row. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/perfect-numbers/README.md b/exercises/perfect-numbers/README.md index 4e343f53..39555f2a 100644 --- a/exercises/perfect-numbers/README.md +++ b/exercises/perfect-numbers/README.md @@ -22,7 +22,7 @@ Implement a way to determine whether a given number is **perfect**. Depending on Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/phone-number/README.md b/exercises/phone-number/README.md index c0428ad7..1fbcdc6b 100644 --- a/exercises/phone-number/README.md +++ b/exercises/phone-number/README.md @@ -32,7 +32,7 @@ should all produce the output Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/pig-latin/README.md b/exercises/pig-latin/README.md index cfd1f0e9..d0eb7ec7 100644 --- a/exercises/pig-latin/README.md +++ b/exercises/pig-latin/README.md @@ -22,7 +22,7 @@ See for more details. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/point-mutations/README.md b/exercises/point-mutations/README.md index b479abc5..d012497b 100644 --- a/exercises/point-mutations/README.md +++ b/exercises/point-mutations/README.md @@ -39,7 +39,7 @@ distance function. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/prime-factors/README.md b/exercises/prime-factors/README.md index eefc5599..f9bec3fd 100644 --- a/exercises/prime-factors/README.md +++ b/exercises/prime-factors/README.md @@ -34,7 +34,7 @@ You can check this yourself: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/protein-translation/README.md b/exercises/protein-translation/README.md index 0c163fe0..c863319a 100644 --- a/exercises/protein-translation/README.md +++ b/exercises/protein-translation/README.md @@ -47,7 +47,7 @@ Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/proverb/README.md b/exercises/proverb/README.md index 51fdaac1..01a7ffba 100644 --- a/exercises/proverb/README.md +++ b/exercises/proverb/README.md @@ -16,7 +16,7 @@ the full text of this proverbial rhyme: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/pythagorean-triplet/README.md b/exercises/pythagorean-triplet/README.md index 7165790b..362edc7b 100644 --- a/exercises/pythagorean-triplet/README.md +++ b/exercises/pythagorean-triplet/README.md @@ -22,7 +22,7 @@ Find the product a * b * c. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/queen-attack/README.md b/exercises/queen-attack/README.md index 7c311f4f..4c27f24b 100644 --- a/exercises/queen-attack/README.md +++ b/exercises/queen-attack/README.md @@ -31,7 +31,7 @@ share a diagonal. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/raindrops/README.md b/exercises/raindrops/README.md index 21754775..d8c20c42 100644 --- a/exercises/raindrops/README.md +++ b/exercises/raindrops/README.md @@ -22,7 +22,7 @@ Convert a number to a string, the contents of which depend on the number's facto Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/rna-transcription/README.md b/exercises/rna-transcription/README.md index 53944760..aedf7c05 100644 --- a/exercises/rna-transcription/README.md +++ b/exercises/rna-transcription/README.md @@ -23,7 +23,7 @@ each nucleotide with its complement: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/robot-name/README.md b/exercises/robot-name/README.md index e679b1ad..170285fe 100644 --- a/exercises/robot-name/README.md +++ b/exercises/robot-name/README.md @@ -20,7 +20,7 @@ every existing robot has a unique name. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/robot-simulator/README.md b/exercises/robot-simulator/README.md index cf8731bf..7bc1f6b8 100644 --- a/exercises/robot-simulator/README.md +++ b/exercises/robot-simulator/README.md @@ -32,7 +32,7 @@ direction it is pointing. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/roman-numerals/README.md b/exercises/roman-numerals/README.md index 77174297..562b98d9 100644 --- a/exercises/roman-numerals/README.md +++ b/exercises/roman-numerals/README.md @@ -47,7 +47,7 @@ See also: http://www.novaroma.org/via_romana/numbers.html Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/run-length-encoding/README.md b/exercises/run-length-encoding/README.md index e91fd159..aa54e96e 100644 --- a/exercises/run-length-encoding/README.md +++ b/exercises/run-length-encoding/README.md @@ -28,7 +28,7 @@ be decoded always represent the count for the following character. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/saddle-points/README.md b/exercises/saddle-points/README.md index 24a59c28..6e5052d6 100644 --- a/exercises/saddle-points/README.md +++ b/exercises/saddle-points/README.md @@ -31,7 +31,7 @@ but the tests for this exercise follow the above unambiguous definition. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/say/README.md b/exercises/say/README.md index 7be49a95..ccd07fa9 100644 --- a/exercises/say/README.md +++ b/exercises/say/README.md @@ -67,7 +67,7 @@ Use _and_ (correctly) when spelling out the number in English: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/scrabble-score/README.md b/exercises/scrabble-score/README.md index b0592bef..f3248bce 100644 --- a/exercises/scrabble-score/README.md +++ b/exercises/scrabble-score/README.md @@ -42,7 +42,7 @@ And to total: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/secret-handshake/README.md b/exercises/secret-handshake/README.md index dfdd361c..6184c2f8 100644 --- a/exercises/secret-handshake/README.md +++ b/exercises/secret-handshake/README.md @@ -33,7 +33,7 @@ has caused the array to be reversed. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/series/README.md b/exercises/series/README.md index 81133429..c4b2cfd4 100644 --- a/exercises/series/README.md +++ b/exercises/series/README.md @@ -25,7 +25,7 @@ in the input; the digits need not be *numerically consecutive*. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/sieve/README.md b/exercises/sieve/README.md index b64850a4..af8bf0a4 100644 --- a/exercises/sieve/README.md +++ b/exercises/sieve/README.md @@ -32,7 +32,7 @@ correct list of primes. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/simple-cipher/README.md b/exercises/simple-cipher/README.md index 37536369..bad16f5f 100644 --- a/exercises/simple-cipher/README.md +++ b/exercises/simple-cipher/README.md @@ -88,7 +88,7 @@ on Wikipedia][dh] for one of the first implementations of this scheme. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/simple-linked-list/README.md b/exercises/simple-linked-list/README.md index f9e7ff91..6c373fd5 100644 --- a/exercises/simple-linked-list/README.md +++ b/exercises/simple-linked-list/README.md @@ -26,7 +26,7 @@ implement your own abstract data type. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/space-age/README.md b/exercises/space-age/README.md index 68bc8ed3..af0d4338 100644 --- a/exercises/space-age/README.md +++ b/exercises/space-age/README.md @@ -22,7 +22,7 @@ youtube video](http://www.youtube.com/watch?v=Z_2gbGXzFbs). Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/strain/README.md b/exercises/strain/README.md index f726bb2f..dcdbf3b8 100644 --- a/exercises/strain/README.md +++ b/exercises/strain/README.md @@ -38,7 +38,7 @@ basic tools instead. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md index 4ce73e90..49c94b79 100644 --- a/exercises/sum-of-multiples/README.md +++ b/exercises/sum-of-multiples/README.md @@ -16,7 +16,7 @@ up to but not including that number. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/transpose/README.md b/exercises/transpose/README.md index 45e73ca0..20f48cad 100644 --- a/exercises/transpose/README.md +++ b/exercises/transpose/README.md @@ -63,7 +63,7 @@ the corresponding output row should contain the spaces in its right-most column( Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/triangle/README.md b/exercises/triangle/README.md index 32272340..0cf1fd1a 100644 --- a/exercises/triangle/README.md +++ b/exercises/triangle/README.md @@ -24,7 +24,7 @@ a single line. Feel free to add your own code/tests to check for degenerate tria Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/trinary/README.md b/exercises/trinary/README.md index 5d4fd424..e42df1b3 100644 --- a/exercises/trinary/README.md +++ b/exercises/trinary/README.md @@ -26,7 +26,7 @@ conversion, pretend it doesn't exist and implement it yourself. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/twelve-days/README.md b/exercises/twelve-days/README.md index 749a02a4..d5bdc3a3 100644 --- a/exercises/twelve-days/README.md +++ b/exercises/twelve-days/README.md @@ -34,7 +34,7 @@ On the twelfth day of Christmas my true love gave to me, twelve Drummers Drummin Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the test suite pass diff --git a/exercises/two-bucket/README.md b/exercises/two-bucket/README.md index 493d70c2..e2d7f15c 100644 --- a/exercises/two-bucket/README.md +++ b/exercises/two-bucket/README.md @@ -34,7 +34,7 @@ Written with <3 at [Fullstack Academy](http://www.fullstackacademy.com/) by [Lin Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/word-count/README.md b/exercises/word-count/README.md index ae006d10..b59f0e4a 100644 --- a/exercises/word-count/README.md +++ b/exercises/word-count/README.md @@ -17,7 +17,7 @@ free: 1 Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/wordy/README.md b/exercises/wordy/README.md index 4186cc06..2b64dea5 100644 --- a/exercises/wordy/README.md +++ b/exercises/wordy/README.md @@ -61,7 +61,7 @@ If you'd like, handle exponentials. Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/zipper/README.md b/exercises/zipper/README.md index ae7adf1a..d571c920 100644 --- a/exercises/zipper/README.md +++ b/exercises/zipper/README.md @@ -32,7 +32,7 @@ list of child nodes) a zipper might support these operations: Go through the setup instructions for JavaScript to install the necessary dependencies: - http://exercism.io/languages/javascript + http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass From ce735060d620a44a1fabddc8027d8a4fc334b72b Mon Sep 17 00:00:00 2001 From: PakkuDon Date: Sat, 28 Oct 2017 23:58:36 +1100 Subject: [PATCH 191/272] Add isbn-verifier exercise --- config.json | 13 ++++ exercises/isbn-verifier/README.md | 66 ++++++++++++++++++ exercises/isbn-verifier/example.js | 24 +++++++ exercises/isbn-verifier/isbn-verifier.spec.js | 68 +++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 exercises/isbn-verifier/README.md create mode 100644 exercises/isbn-verifier/example.js create mode 100644 exercises/isbn-verifier/isbn-verifier.spec.js diff --git a/config.json b/config.json index 73522338..1c840d60 100644 --- a/config.json +++ b/config.json @@ -1135,6 +1135,19 @@ "searching", "trees" ] + }, + { + "uuid": "8740af44-002c-4716-a759-a68ae4c68737", + "slug": "isbn-verifier", + "core": false, + "unlocked_by": "bob", + "difficulty": 4, + "topics": [ + "conditionals", + "loops", + "pattern_matching", + "strings" + ] } ], "foregone": [], diff --git a/exercises/isbn-verifier/README.md b/exercises/isbn-verifier/README.md new file mode 100644 index 00000000..a5260312 --- /dev/null +++ b/exercises/isbn-verifier/README.md @@ -0,0 +1,66 @@ +# ISBN Verifier + +Check if a given ISBN-10 is valid. + +## Functionality + +Given an unknown string the program should check if the provided string is a valid ISBN-10. +Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. + +The program should allow for ISBN-10 without the separating dashes to be verified as well. + +## ISBN + +Let's take a random ISBN-10 number, say `3-598-21508-8` for this. +The first digit block indicates the group where the ISBN belongs. Groups can consist of shared languages, geographic regions or countries. The leading '3' signals this ISBN is from a german speaking country. +The following number block is to identify the publisher. Since this is a three digit publisher number there is a 5 digit title number for this book. +The last digit in the ISBN is the check digit which is used to detect read errors. + +The first 9 digits in the ISBN have to be between 0 and 9. +The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well. + +A valid ISBN-10 is calculated with this formula `(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0` +So for our example ISBN this means: +(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0 + +Which proves that the ISBN is valid. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +### Submitting Exercises + +Note that, when trying to submit an exercise, make sure the solution is in the `exercism/javascript/` directory. + +For example, if you're submitting `bob.js` for the Bob exercise, the submit command would be something like `exercism submit /javascript/bob/bob.js`. + + +For more detailed information about running tests, code style and linting, +please see the [help page](http://exercism.io/languages/javascript). + +## Source + +Converting a string into a number and some basic processing utilizing a relatable real world example. [https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation](https://en.wikipedia.org/wiki/International_Standard_Book_Number) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/isbn-verifier/example.js b/exercises/isbn-verifier/example.js new file mode 100644 index 00000000..90ba4d31 --- /dev/null +++ b/exercises/isbn-verifier/example.js @@ -0,0 +1,24 @@ +'use strict'; + +function ISBN(isbn) { + this.isbn = isbn.replace(/-/g, ''); + + this.isValid = function () { + if (!this.isbn.match(/^(\d{9}[\dX])$/)) { + return false; + } + + var digits = this.isbn.split(''); + if (digits[9] === 'X') { + digits[9] = 10; + } + + var sum = digits.reduce(function (total, current, index) { + return total + ((10 - index) * parseInt(current, 10)); + }, 0); + + return sum % 11 === 0; + }; +} + +module.exports = ISBN; diff --git a/exercises/isbn-verifier/isbn-verifier.spec.js b/exercises/isbn-verifier/isbn-verifier.spec.js new file mode 100644 index 00000000..c6c4ff91 --- /dev/null +++ b/exercises/isbn-verifier/isbn-verifier.spec.js @@ -0,0 +1,68 @@ +var ISBN = require('./isbn-verifier'); + +describe('ISBN', function () { + it('valid isbn number', function () { + var isbn = new ISBN('3-598-21508-8'); + expect(isbn.isValid()).toBe(true); + }); + + it('invalid isbn check digit', function () { + var isbn = new ISBN('3-598-21508-9'); + expect(isbn.isValid()).toBe(false); + }); + + it('valid isbn number with a check digit of 10', function () { + var isbn = new ISBN('3-598-21507-X'); + expect(isbn.isValid()).toBe(true); + }); + + it('check digit is a character other than X', function () { + var isbn = new ISBN('3-598-21507-A'); + expect(isbn.isValid()).toBe(false); + }); + + it('invalid character in isbn', function () { + var isbn = new ISBN('3-598-2K507-0'); + expect(isbn.isValid()).toBe(false); + }); + + it('X is only valid as a check digit', function () { + var isbn = new ISBN('3-598-2X507-0'); + expect(isbn.isValid()).toBe(false); + }); + + it('valid isbn without separating dashes', function () { + var isbn = new ISBN('3598215088'); + expect(isbn.isValid()).toBe(true); + }); + + it('isbn without separating dashes and X as check digit', function () { + var isbn = new ISBN('359821507X'); + expect(isbn.isValid()).toBe(true); + }); + + it('isbn without check digit and dashes', function () { + var isbn = new ISBN('359821507'); + expect(isbn.isValid()).toBe(false); + }); + + it('too long isbn and no dashes', function () { + var isbn = new ISBN('3598215078X'); + expect(isbn.isValid()).toBe(false); + }); + + it('isbn without check digit', function () { + var isbn = new ISBN('3-598-21507'); + expect(isbn.isValid()).toBe(false); + }); + + it('too long isbn', function () { + var isbn = new ISBN('3-598-21507-XA'); + expect(isbn.isValid()).toBe(false); + }); + + it('check digit of X should not be used for 0', function () { + var isbn = new ISBN('3-598-21515-X'); + expect(isbn.isValid()).toBe(false); + }); +}); From 09ae5b088d1f9ad85c0a9f37790c07292a6f757c Mon Sep 17 00:00:00 2001 From: Trevor Ford Date: Tue, 31 Oct 2017 11:02:25 -0400 Subject: [PATCH 192/272] grammar and readability fixes to exercises/bowling/README.md --- exercises/bowling/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md index b8342c33..9cc97f0e 100644 --- a/exercises/bowling/README.md +++ b/exercises/bowling/README.md @@ -8,13 +8,13 @@ of a game of bowling. ## Scoring Bowling -The game consists of 10 frames. A frame is composed of one or two ball throws with 10 pins standing at frame initialization. There are three cases for the tabulation of a frame. +A game consists of 10 frames. A frame is composed of one or two balls thrown, with 10 pins standing at the start of the frame. There are three cases for the tabulation of a frame: -* An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down. +* An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down after the second throw. -* A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in their next throw. +* A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the next throw. -* A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in their next two throws. If a strike is immediately followed by a second strike, then we can not total the value of first strike until they throw the ball one more time. +* A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the next two throws. If a strike is immediately followed by another strike, then the first strike's value cannot be totalled until the next throw. Here is a three frame example: @@ -30,7 +30,7 @@ Frame 3 is (9 + 0) = 9 This means the current running total is 48. -The tenth frame in the game is a special case. If someone throws a strike or a spare then they get a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. +The tenth frame in the game is a special case. If the player throws a strike or a spare, then they get one extra throw called a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. For a tenth frame of X1/ (strike and a spare), the total value is 20. From fa68efe34b8fcc52f91ac651d41742b29071bcc5 Mon Sep 17 00:00:00 2001 From: "Sara J. Martinez" Date: Tue, 31 Oct 2017 13:23:09 -0400 Subject: [PATCH 193/272] Fix crypto square, largest series product, sieve examples --- exercises/crypto-square/example.js | 3 ++- exercises/largest-series-product/example.js | 3 ++- exercises/sieve/example.js | 7 +++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/exercises/crypto-square/example.js b/exercises/crypto-square/example.js index 173f2bff..44589d5b 100644 --- a/exercises/crypto-square/example.js +++ b/exercises/crypto-square/example.js @@ -22,7 +22,8 @@ module.exports = function (input) { this.ciphertext = function () { var textSegments = this.plaintextSegments(); - var i, j; + var i; + var j; var columns = []; var currentSegment; var currentLetter; diff --git a/exercises/largest-series-product/example.js b/exercises/largest-series-product/example.js index 2e074103..fa5e5272 100644 --- a/exercises/largest-series-product/example.js +++ b/exercises/largest-series-product/example.js @@ -14,7 +14,8 @@ Series.prototype.getDigits = function () { Series.prototype.largestProduct = function (size) { if (size < 0) throw new Error('Invalid input.'); - var product, max = 0; + var product; + var max = 0; this.slices(size).forEach(function (slice) { product = slice.reduce(function (a, b) { return a * b; diff --git a/exercises/sieve/example.js b/exercises/sieve/example.js index 85ad948a..3684753f 100644 --- a/exercises/sieve/example.js +++ b/exercises/sieve/example.js @@ -1,7 +1,8 @@ 'use strict'; function newArrayWithRange(first, last) { - var i, array = []; + var i; + var array = []; for ( i = first; i <= last; i++ ) { array.push(i); } @@ -13,7 +14,9 @@ function indivisibleBy(value) { } function sieve(n) { - var i, prime, possibilities, primes = []; + var prime; + var possibilities; + var primes = []; possibilities = newArrayWithRange(2, n); From 2fcd2095fbae27a671bcd6e20f9590280b05d1f7 Mon Sep 17 00:00:00 2001 From: lougeniaC64 Date: Thu, 2 Nov 2017 16:50:57 -0400 Subject: [PATCH 194/272] Fixed Lint Errors in Diffie-Hellman (#445) * Fixed lint errors in diffie-hellman example and spec files * Fixed constructor tests * Updated this.validateInitialArguments parameters * Fixed constructor tests * Renamed validateInitialArguments function parameters --- .../diffie-hellman/diffie-hellman.spec.js | 40 +++++++++---------- exercises/diffie-hellman/example.js | 20 +++++----- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/exercises/diffie-hellman/diffie-hellman.spec.js b/exercises/diffie-hellman/diffie-hellman.spec.js index 5f7faa65..47b4faae 100644 --- a/exercises/diffie-hellman/diffie-hellman.spec.js +++ b/exercises/diffie-hellman/diffie-hellman.spec.js @@ -1,6 +1,6 @@ var DiffieHellman = require('./diffie-hellman'); -describe('diffie-hellman', function(){ +describe('diffie-hellman', function () { var p = 23; var g = 5; var diffieHellman = new DiffieHellman(p, g); @@ -11,57 +11,57 @@ describe('diffie-hellman', function(){ var bobPrivateKey = 15; var bobPublicKey = 19; - it('throws an error if the constructor arguments are out of range', function() { - expect(function() { - new DiffieHellman(0, 9999); + it('throws an error if the constructor arguments are out of range', function () { + expect(function () { + return new DiffieHellman(0, 9999); }).toThrow(); }); - xit('throws an error if the constructor arguments are not prime', function() { - expect(function() { - new DiffieHellman(10, 13); + xit('throws an error if the constructor arguments are not prime', function () { + expect(function () { + return new DiffieHellman(10, 13); }).toThrow(); }); - xit('throws an error if private key is negative', function() { - expect(function() { + xit('throws an error if private key is negative', function () { + expect(function () { diffieHellman.getPublicKeyFromPrivateKey(-1); }).toThrow(); }); - xit('throws an error if private key is zero', function() { - expect(function() { + xit('throws an error if private key is zero', function () { + expect(function () { diffieHellman.getPublicKeyFromPrivateKey(0); }).toThrow(); }); - xit('throws an error if private key is one', function() { - expect(function() { + xit('throws an error if private key is one', function () { + expect(function () { diffieHellman.getPublicKeyFromPrivateKey(1); }).toThrow(); }); - xit('throws an error if private key equals the modulus parameter p', function() { - expect(function() { + xit('throws an error if private key equals the modulus parameter p', function () { + expect(function () { diffieHellman.getPublicKeyFromPrivateKey(p); }).toThrow(); }); - xit('throws an error if private key is greater than the modulus parameter p', function() { - expect(function() { + xit('throws an error if private key is greater than the modulus parameter p', function () { + expect(function () { diffieHellman.getPublicKeyFromPrivateKey(p + 1); }).toThrow(); }); - xit('when given a private key, returns the correct public one', function() { + xit('when given a private key, returns the correct public one', function () { expect(diffieHellman.getPublicKeyFromPrivateKey(alicePrivateKey)).toEqual(alicePublicKey); }); - xit('when given a different private key, returns the correct public one', function() { + xit('when given a different private key, returns the correct public one', function () { expect(diffieHellman.getPublicKeyFromPrivateKey(bobPrivateKey)).toEqual(bobPublicKey); }); - xit('can generate a shared secret from our private key and their public key', function() { + xit('can generate a shared secret from our private key and their public key', function () { var sharedSecret = 2; expect(diffieHellman.getSharedSecret(alicePrivateKey, bobPublicKey)) diff --git a/exercises/diffie-hellman/example.js b/exercises/diffie-hellman/example.js index bbdfe16d..ce6c9141 100644 --- a/exercises/diffie-hellman/example.js +++ b/exercises/diffie-hellman/example.js @@ -1,10 +1,10 @@ -var DiffieHellman = function(p, g){ +var DiffieHellman = function (p, g) { this.p = p; this.g = g; // array of first 1000 primes. - this.PRIMES= [ + this.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 ]; @@ -19,14 +19,14 @@ var DiffieHellman = function(p, g){ return Math.pow(theirPublicKey, ourPrivateKey) % this.p; }; - this.validateInitialArguments = function (p, g){ + this.validateInitialArguments = function (primeModulus, generator) { var BIGGEST_PRIME = this.PRIMES[this.PRIMES.length - 1]; - return p >= 2 - && g >= 2 - && p <= BIGGEST_PRIME - && g <= BIGGEST_PRIME - && arrIncludes(this.PRIMES, p) - && arrIncludes(this.PRIMES, g); + return primeModulus >= 2 + && generator >= 2 + && primeModulus <= BIGGEST_PRIME + && generator <= BIGGEST_PRIME + && arrIncludes(this.PRIMES, primeModulus) + && arrIncludes(this.PRIMES, generator); }; function arrIncludes(arr, a) { @@ -40,7 +40,7 @@ var DiffieHellman = function(p, g){ if (!this.validateInitialArguments(p, g)) { - throw Error('Constructor arguments are out of range or non-prime!'); + throw Error('Constructor arguments are out of range or non-prime!'); } }; From 0a73673e2e20f8486aa150583007fddda9c5bd29 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Wed, 1 Nov 2017 15:14:24 +0530 Subject: [PATCH 195/272] Add eslint to travis Also add jasmine to package.json so as to install jasmine, eslint and all other dependencies in CI - instead of the old global jasmine install on the CI. --- .travis.yml | 3 ++- package-lock.json | 41 ++++++++++++++++++++++++++++++++--------- package.json | 3 ++- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9dce3c35..2b97b13d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,10 @@ node_js: - "node" install: - - "npm install -g jasmine" + - "npm install" script: - "make test" - "./bin/fetch-configlet" - "./bin/configlet lint ." + - "npm run lint" diff --git a/package-lock.json b/package-lock.json index 5429eb3b..9c807997 100644 --- a/package-lock.json +++ b/package-lock.json @@ -729,6 +729,12 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, "external-editor": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", @@ -1082,6 +1088,23 @@ "whatwg-fetch": "2.0.3" } }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.8.0" + } + }, + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -1655,15 +1678,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -1674,6 +1688,15 @@ "strip-ansi": "4.0.0" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", diff --git a/package.json b/package.json index 223aa598..f63c627f 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "eslint-config-airbnb-es5": "^1.2.0", "eslint-plugin-import": "^2.7.0", "eslint-plugin-jasmine": "^2.8.4", - "eslint-plugin-react": "^7.3.0" + "eslint-plugin-react": "^7.3.0", + "jasmine": "^2.8.0" }, "scripts": { "lint": "eslint .", From 01dbaaa056a55bfccdb6aae63cd942710c66e198 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Wed, 1 Nov 2017 15:17:04 +0530 Subject: [PATCH 196/272] Add all existing eslint violation to eslintignore The idea is the remove them from ignore one-by-one as people fix the lint violations. --- .eslintignore | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..258f5a2e --- /dev/null +++ b/.eslintignore @@ -0,0 +1,47 @@ +big-integer.js +exercises/accumulate +exercises/acronym +exercises/alphametics +exercises/anagram +exercises/binary-search +exercises/binary-search-tree +exercises/bowling +exercises/bracket-push +exercises/circular-buffer +exercises/clock +exercises/crypto-square +exercises/custom-set +exercises/diamond +exercises/diffie-hellman +exercises/flatten-array +exercises/food-chain +exercises/grade-school +exercises/grains +exercises/kindergarten-garden +exercises/largest-series-product +exercises/leap +exercises/linked-list +exercises/list-ops +exercises/luhn +exercises/minesweeper +exercises/nth-prime +exercises/octal +exercises/palindrome-products +exercises/pangram +exercises/perfect-numbers +exercises/pythagorean-triplet +exercises/queen-attack +exercises/robot-name +exercises/robot-simulator +exercises/roman-numerals +exercises/saddle-points +exercises/say +exercises/scrabble-score +exercises/secret-handshake +exercises/sieve +exercises/simple-cipher +exercises/simple-linked-list +exercises/sum-of-multiples +exercises/triangle +exercises/trinary +exercises/wordy From 2f549d177e5affa20ab3b68c90a4632d709f280c Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Wed, 1 Nov 2017 15:23:26 +0530 Subject: [PATCH 197/272] Update all packages to their latest versions --- package-lock.json | 164 +++++++++++++++++++++++++++------------------- package.json | 8 +-- 2 files changed, 101 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c807997..320ca28b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", "dev": true }, "acorn-jsx": { @@ -28,21 +28,21 @@ } }, "ajv": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz", - "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", "dev": true, "requires": { "co": "4.6.0", "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "ajv-keywords": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", - "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, "ansi-escapes": { @@ -356,9 +356,9 @@ } }, "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" @@ -396,9 +396,9 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", "dev": true, "requires": { "esutils": "2.0.2", @@ -454,12 +454,12 @@ "dev": true }, "eslint": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.7.2.tgz", - "integrity": "sha1-/29fUZOEiifum2J74+c/ucteZi4=", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.10.0.tgz", + "integrity": "sha512-MMVl8P/dYUFZEvolL8PYt7qc5LNdS2lwheq9BYa5Y07FblhcZqFyaUqlS8TW5QITGex21tV4Lk0a3fK8lsJIkA==", "dev": true, "requires": { - "ajv": "5.2.3", + "ajv": "5.3.0", "babel-code-frame": "6.26.0", "chalk": "2.1.0", "concat-stream": "1.6.0", @@ -475,7 +475,7 @@ "functional-red-black-tree": "1.0.1", "glob": "7.1.2", "globals": "9.18.0", - "ignore": "3.3.5", + "ignore": "3.3.7", "imurmurhash": "0.1.4", "inquirer": "3.3.0", "is-resolvable": "1.0.0", @@ -539,25 +539,6 @@ } } }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", @@ -573,9 +554,9 @@ } }, "eslint-config-airbnb-base": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", - "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", "dev": true, "requires": { "eslint-restricted-globals": "0.1.1" @@ -604,8 +585,19 @@ "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", "dev": true, "requires": { - "debug": "2.6.8", - "resolve": "1.4.0" + "debug": "2.6.9", + "resolve": "1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "eslint-module-utils": { @@ -614,19 +606,30 @@ "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", "dev": true, "requires": { - "debug": "2.6.8", + "debug": "2.6.9", "pkg-dir": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "eslint-plugin-import": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", - "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", "dev": true, "requires": { "builtin-modules": "1.1.1", "contains-path": "0.1.0", - "debug": "2.6.8", + "debug": "2.6.9", "doctrine": "1.5.0", "eslint-import-resolver-node": "0.3.1", "eslint-module-utils": "2.1.1", @@ -634,12 +637,33 @@ "lodash.cond": "4.5.2", "minimatch": "3.0.4", "read-pkg-up": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } } }, "eslint-plugin-jasmine": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.8.4.tgz", - "integrity": "sha1-Z6VVHj0dXguMa1Sq66uVNw9dN94=", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.9.1.tgz", + "integrity": "sha1-IuGaWfFvOl9kOgSroEQ40OMEcDA=", "dev": true }, "eslint-plugin-react": { @@ -688,7 +712,7 @@ "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", "dev": true, "requires": { - "acorn": "5.1.2", + "acorn": "5.2.1", "acorn-jsx": "3.0.1" } }, @@ -742,7 +766,7 @@ "dev": true, "requires": { "iconv-lite": "0.4.19", - "jschardet": "1.5.1", + "jschardet": "1.6.0", "tmp": "0.0.33" } }, @@ -752,6 +776,12 @@ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", "dev": true }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", @@ -915,9 +945,9 @@ "dev": true }, "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", "dev": true }, "imurmurhash": { @@ -1122,9 +1152,9 @@ } }, "jschardet": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", - "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.6.0.tgz", + "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==", "dev": true }, "json-schema-traverse": { @@ -1546,9 +1576,9 @@ } }, "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", "dev": true, "requires": { "path-parse": "1.0.5" @@ -1741,8 +1771,8 @@ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "5.2.3", - "ajv-keywords": "2.1.0", + "ajv": "5.3.0", + "ajv-keywords": "2.1.1", "chalk": "2.1.0", "lodash": "4.17.4", "slice-ansi": "1.0.0", diff --git a/package.json b/package.json index f63c627f..8feba32a 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,11 @@ "license": "MIT", "devDependencies": { "babel-eslint": "^8.0.0", - "eslint": "^4.6.1", - "eslint-config-airbnb-base": "^12.0.0", + "eslint": "^4.10.0", + "eslint-config-airbnb-base": "^12.1.0", "eslint-config-airbnb-es5": "^1.2.0", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-jasmine": "^2.8.4", + "eslint-plugin-import": "^2.8.0", + "eslint-plugin-jasmine": "^2.9.1", "eslint-plugin-react": "^7.3.0", "jasmine": "^2.8.0" }, From a7fd20f654761d5f18f5daeb2f30da76ef255b62 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Fri, 3 Nov 2017 23:56:03 +0530 Subject: [PATCH 198/272] Remove some more exercises from eslintignore Since they were merged before merging this PR. --- .eslintignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 258f5a2e..bf5995ca 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,16 +9,13 @@ exercises/bowling exercises/bracket-push exercises/circular-buffer exercises/clock -exercises/crypto-square exercises/custom-set exercises/diamond -exercises/diffie-hellman exercises/flatten-array exercises/food-chain exercises/grade-school exercises/grains exercises/kindergarten-garden -exercises/largest-series-product exercises/leap exercises/linked-list exercises/list-ops @@ -38,7 +35,6 @@ exercises/saddle-points exercises/say exercises/scrabble-score exercises/secret-handshake -exercises/sieve exercises/simple-cipher exercises/simple-linked-list exercises/sum-of-multiples From fd096796e7e02cd5be726381626348fd6d2ade91 Mon Sep 17 00:00:00 2001 From: "Sara J. Martinez" Date: Tue, 31 Oct 2017 13:51:29 -0400 Subject: [PATCH 199/272] Fix Diamond and Sum of Multiples --- exercises/diamond/diamond.spec.js | 6 ++--- exercises/diamond/example.js | 2 +- .../sum-of-multiples/sum-of-multiples.spec.js | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/exercises/diamond/diamond.spec.js b/exercises/diamond/diamond.spec.js index 84ed61fc..5e52b952 100644 --- a/exercises/diamond/diamond.spec.js +++ b/exercises/diamond/diamond.spec.js @@ -4,12 +4,12 @@ describe('Diamond', function () { var diamond = new Diamond(); it('test letter A', function () { - result = 'A\n'; + var result = 'A\n'; expect(diamond.makeDiamond('A')).toEqual(result); }); it('test letter C', function () { - result = [' A ', + var result = [' A ', ' B B ', 'C C', ' B B ', @@ -18,7 +18,7 @@ describe('Diamond', function () { }); it('test letter E', function () { - result = [' A ', + var result = [' A ', ' B B ', ' C C ', ' D D ', diff --git a/exercises/diamond/example.js b/exercises/diamond/example.js index e7ffdf45..d89a65a3 100644 --- a/exercises/diamond/example.js +++ b/exercises/diamond/example.js @@ -5,7 +5,7 @@ var Diamond = function () { for (var i = 0; i <= inputIndex; i++) { output += getLine(inputIndex, i); } - for (var i = inputIndex - 1; i >= 0; i--) { + for (i = inputIndex - 1; i >= 0; i--) { output += getLine(inputIndex, i); } return output; diff --git a/exercises/sum-of-multiples/sum-of-multiples.spec.js b/exercises/sum-of-multiples/sum-of-multiples.spec.js index 8866cda9..978d3528 100644 --- a/exercises/sum-of-multiples/sum-of-multiples.spec.js +++ b/exercises/sum-of-multiples/sum-of-multiples.spec.js @@ -1,39 +1,39 @@ -var SumOfMultiples = require('./sum-of-multiples'); +var sumOfMultiples = require('./sum-of-multiples'); -describe('SumOfMultiples', function () { +describe('sumOfMultiples', function () { it('to 1', function () { - expect(SumOfMultiples([3, 5]).to(1)).toBe(0); + expect(sumOfMultiples([3, 5]).to(1)).toBe(0); }); xit('to 3', function () { - expect(SumOfMultiples([3, 5]).to(4)).toBe(3); + expect(sumOfMultiples([3, 5]).to(4)).toBe(3); }); xit('to 10', function () { - expect(SumOfMultiples([3, 5]).to(10)).toBe(23); + expect(sumOfMultiples([3, 5]).to(10)).toBe(23); }); xit('to 100', function () { - expect(SumOfMultiples([3, 5]).to(100)).toBe(2318); + expect(sumOfMultiples([3, 5]).to(100)).toBe(2318); }); xit('to 1000', function () { - expect(SumOfMultiples([3, 5]).to(1000)).toBe(233168); + expect(sumOfMultiples([3, 5]).to(1000)).toBe(233168); }); xit('[7, 13, 17] to 20', function () { - expect(SumOfMultiples([7, 13, 17]).to(20)).toBe(51); + expect(sumOfMultiples([7, 13, 17]).to(20)).toBe(51); }); xit('[4, 6] to 15', function () { - expect(SumOfMultiples([4, 6]).to(15)).toBe(30); + expect(sumOfMultiples([4, 6]).to(15)).toBe(30); }); xit('[5, 6, 8] to 150', function () { - expect(SumOfMultiples([5, 6, 8]).to(150)).toBe(4419); + expect(sumOfMultiples([5, 6, 8]).to(150)).toBe(4419); }); xit('[43, 47] to 10000', function () { - expect(SumOfMultiples([43, 47]).to(10000)).toBe(2203160); + expect(sumOfMultiples([43, 47]).to(10000)).toBe(2203160); }); }); From 3f1f58665f9af38a594c10d330774d61540cbd95 Mon Sep 17 00:00:00 2001 From: "Sara J. Martinez" Date: Fri, 3 Nov 2017 15:07:19 -0400 Subject: [PATCH 200/272] Change var name and add new to Constructor function, remove exercises from eslintignore --- .eslintignore | 2 -- exercises/diamond/example.js | 4 ++-- .../sum-of-multiples/sum-of-multiples.spec.js | 22 +++++++++---------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/.eslintignore b/.eslintignore index bf5995ca..bec7dac9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,7 +10,6 @@ exercises/bracket-push exercises/circular-buffer exercises/clock exercises/custom-set -exercises/diamond exercises/flatten-array exercises/food-chain exercises/grade-school @@ -37,7 +36,6 @@ exercises/scrabble-score exercises/secret-handshake exercises/simple-cipher exercises/simple-linked-list -exercises/sum-of-multiples exercises/triangle exercises/trinary exercises/wordy diff --git a/exercises/diamond/example.js b/exercises/diamond/example.js index d89a65a3..d535e64e 100644 --- a/exercises/diamond/example.js +++ b/exercises/diamond/example.js @@ -5,8 +5,8 @@ var Diamond = function () { for (var i = 0; i <= inputIndex; i++) { output += getLine(inputIndex, i); } - for (i = inputIndex - 1; i >= 0; i--) { - output += getLine(inputIndex, i); + for (var j = inputIndex - 1; j >= 0; j--) { + output += getLine(inputIndex, j); } return output; }; diff --git a/exercises/sum-of-multiples/sum-of-multiples.spec.js b/exercises/sum-of-multiples/sum-of-multiples.spec.js index 978d3528..8ff4a443 100644 --- a/exercises/sum-of-multiples/sum-of-multiples.spec.js +++ b/exercises/sum-of-multiples/sum-of-multiples.spec.js @@ -1,39 +1,39 @@ -var sumOfMultiples = require('./sum-of-multiples'); +var SumOfMultiples = require('./sum-of-multiples'); -describe('sumOfMultiples', function () { +describe('SumOfMultiples', function () { it('to 1', function () { - expect(sumOfMultiples([3, 5]).to(1)).toBe(0); + expect(new SumOfMultiples([3, 5]).to(1)).toBe(0); }); xit('to 3', function () { - expect(sumOfMultiples([3, 5]).to(4)).toBe(3); + expect(new SumOfMultiples([3, 5]).to(4)).toBe(3); }); xit('to 10', function () { - expect(sumOfMultiples([3, 5]).to(10)).toBe(23); + expect(new SumOfMultiples([3, 5]).to(10)).toBe(23); }); xit('to 100', function () { - expect(sumOfMultiples([3, 5]).to(100)).toBe(2318); + expect(new SumOfMultiples([3, 5]).to(100)).toBe(2318); }); xit('to 1000', function () { - expect(sumOfMultiples([3, 5]).to(1000)).toBe(233168); + expect(new SumOfMultiples([3, 5]).to(1000)).toBe(233168); }); xit('[7, 13, 17] to 20', function () { - expect(sumOfMultiples([7, 13, 17]).to(20)).toBe(51); + expect(new SumOfMultiples([7, 13, 17]).to(20)).toBe(51); }); xit('[4, 6] to 15', function () { - expect(sumOfMultiples([4, 6]).to(15)).toBe(30); + expect(new SumOfMultiples([4, 6]).to(15)).toBe(30); }); xit('[5, 6, 8] to 150', function () { - expect(sumOfMultiples([5, 6, 8]).to(150)).toBe(4419); + expect(new SumOfMultiples([5, 6, 8]).to(150)).toBe(4419); }); xit('[43, 47] to 10000', function () { - expect(sumOfMultiples([43, 47]).to(10000)).toBe(2203160); + expect(new SumOfMultiples([43, 47]).to(10000)).toBe(2203160); }); }); From 1723cba42ce3f5e1a5a7959883e444997c71f596 Mon Sep 17 00:00:00 2001 From: "Sara J. Martinez" Date: Fri, 3 Nov 2017 15:27:28 -0400 Subject: [PATCH 201/272] Fix 2 lint errors on Acronym exercise --- .eslintignore | 1 - exercises/acronym/example.js | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintignore b/.eslintignore index bf5995ca..972c0d1e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,5 @@ big-integer.js exercises/accumulate -exercises/acronym exercises/alphametics exercises/anagram exercises/binary-search diff --git a/exercises/acronym/example.js b/exercises/acronym/example.js index d50a50a6..1618d203 100644 --- a/exercises/acronym/example.js +++ b/exercises/acronym/example.js @@ -2,7 +2,8 @@ module.exports = { parse: function (phrase) { return phrase.match(/[A-Z]+[a-z]*|[a-z]+/g) .reduce(function (acronym, word) { - return acronym += word[0].toUpperCase(); + var returnAcronym = acronym + word[0].toUpperCase(); + return returnAcronym; }, ''); } }; From 5940e980d76380a8583e337a655bc27ffd6a76a5 Mon Sep 17 00:00:00 2001 From: a-dpq Date: Wed, 8 Nov 2017 00:06:03 +0100 Subject: [PATCH 202/272] Correct wording in readmes and spec files Grammar and consistency --- exercises/bowling/README.md | 14 ++++---- exercises/bowling/bowling.spec.js | 44 ++++++++++++------------- exercises/saddle-points/README.md | 2 +- exercises/sum-of-multiples/README.md | 2 +- exercises/two-bucket/two-bucket.spec.js | 4 +-- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md index b8342c33..8793acdb 100644 --- a/exercises/bowling/README.md +++ b/exercises/bowling/README.md @@ -12,11 +12,11 @@ The game consists of 10 frames. A frame is composed of one or two ball throws wi * An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down. -* A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in their next throw. +* A spare is where all 10 pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the player's next throw. -* A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in their next two throws. If a strike is immediately followed by a second strike, then we can not total the value of first strike until they throw the ball one more time. +* A strike is where all 10 pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the player's next two throws. If a strike is immediately followed by a second strike, then we cannot total the value of first strike until they throw the ball one more time. -Here is a three frame example: +Here is a three-frame example: | Frame 1 | Frame 2 | Frame 3 | | :-------------: |:-------------:| :---------------------:| @@ -30,11 +30,11 @@ Frame 3 is (9 + 0) = 9 This means the current running total is 48. -The tenth frame in the game is a special case. If someone throws a strike or a spare then they get a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. +The 10th frame in the game is a special case. If someone throws a strike or a spare, they get a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. -For a tenth frame of X1/ (strike and a spare), the total value is 20. +For a 10th frame of X1/ (strike and a spare), the total value is 20. -For a tenth frame of XXX (three strikes), the total value is 30. +For a 10th frame of XXX (three strikes), the total value is 30. ## Requirements @@ -51,7 +51,7 @@ support two operations: Go through the setup instructions for JavaScript to install the necessary dependencies: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation ## Making the Test Suite Pass diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 881b1b45..578566f6 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -7,121 +7,121 @@ describe('Bowling', function () { expect(new Bowling(rolls).score()).toEqual(0); }); - xit('should be able to score a game with all open frames', function () { + it('should be able to score a game with all open frames', function () { var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; expect(new Bowling(rolls).score()).toEqual(90); }); - xit('a spare followed by zeros is worth ten points', function () { + it('a spare followed by zeros is worth 10 points', function () { var rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - xit('points scored in the roll after a spare are counted twice', function () { + it('points scored in the roll after a spare are counted twice', function () { var rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(16); }); - xit('consecutive spares each get a one roll bonus', function () { + it('consecutive spares each get a one-roll bonus', function () { var rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(31); }); - xit('should allow fill ball when the last frame is a spare', function () { + it('should allow fill ball when the last frame is a spare', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; expect(new Bowling(rolls).score()).toEqual(17); }); - xit('a strike earns ten points in a frame with a single roll', function () { + it('a strike earns 10 points in a frame with a single roll', function () { var rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - xit('points scored in the two rolls after a strike are counted twice as a bonus', function () { + it('points scored in the two rolls after a strike are counted twice as a bonus', function () { var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(26); }); - xit('should be able to score multiple strikes in a row', function () { + it('should be able to score multiple strikes in a row', function () { var rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(81); }); - xit('should allow fill balls when the last frame is a strike', function () { + it('should allow fill balls when the last frame is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; expect(new Bowling(rolls).score()).toEqual(18); }); - xit('rolling a spare with the two roll bonus does not get a bonus roll', function () { + it('rolling a spare with the two-roll bonus does not get a bonus roll', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; expect(new Bowling(rolls).score()).toEqual(20); }); - xit('strikes with the two roll bonus do not get bonus rolls', function () { + it('strikes with the two-roll bonus do not get bonus rolls', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(30); }); - xit('a strike with the one roll bonus after a spare in the last frame does not get a bonus', function () { + it('a strike with the one-roll bonus after a spare in the last frame does not get a bonus', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; expect(new Bowling(rolls).score()).toEqual(20); }); - xit('should be able to score a perfect game', function () { + it('should be able to score a perfect game', function () { var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(300); }); }); describe('Check game rules.', function () { - xit('rolls can not score negative points', function () { + it('rolls cannot score negative points', function () { var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pins must have a value from 0 to 10')); }); - xit('a roll can not score more than 10 points', function () { + it('a roll cannot score more than 10 points', function () { var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pins must have a value from 0 to 10')); }); - xit('two rolls in a frame can not score more than 10 points', function () { + it('two rolls in a frame cannot score more than 10 points', function () { var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); - xit('two bonus rolls after a strike in the last frame can not score more than 10 points', function () { + it('two bonus rolls after a strike in the last frame cannot score more than 10 points', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); - xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { + it('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; expect(new Bowling(rolls).score()).toEqual(26); }); - xit('the second bonus rolls after a strike in the last frame can not be a strike if the first one is not a strike', function () { + xit('the second bonus roll after a strike in the last frame cannot be a strike if the first one is not a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); - xit('an unstarted game can not be scored', function () { + xit('an unstarted game cannot be scored', function () { var rolls = []; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('an incomplete game can not be scored', function () { + xit('an incomplete game cannot be scored', function () { var rolls = [0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('a game with more than ten frames and no last frame spare or strike can not be scored', function () { + xit('a game with more than 10 frames and no last frame spare or strike cannot be scored', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Should not be able to roll after game is over')); diff --git a/exercises/saddle-points/README.md b/exercises/saddle-points/README.md index 24a59c28..3539bfea 100644 --- a/exercises/saddle-points/README.md +++ b/exercises/saddle-points/README.md @@ -15,7 +15,7 @@ So say you have a matrix like so: It has a saddle point at (1, 0). It's called a "saddle point" because it is greater than or equal to -every element in its row and the less than or equal to every element in +every element in its row and less than or equal to every element in its column. A matrix may have zero or more saddle points. diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md index 4ce73e90..ea64f913 100644 --- a/exercises/sum-of-multiples/README.md +++ b/exercises/sum-of-multiples/README.md @@ -4,7 +4,7 @@ Given a number, find the sum of all the multiples of particular numbers up to but not including that number. If we list all the natural numbers up to but not including 20 that are -multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, 12, 15, and 18. +multiples of either 3 or 5, we get 3, 5, 6, 9, 10, 12, 15, and 18. The sum of these multiples is 78. diff --git a/exercises/two-bucket/two-bucket.spec.js b/exercises/two-bucket/two-bucket.spec.js index 248b7ab4..0edf78a0 100644 --- a/exercises/two-bucket/two-bucket.spec.js +++ b/exercises/two-bucket/two-bucket.spec.js @@ -1,7 +1,7 @@ var TwoBucket = require('./two-bucket'); describe('TwoBucket', function () { - describe('Measure using bucket one of size 3 and bucket two of size 5 - ', function () { + describe('Measure using bucket one of size 3 and bucket two of size 5', function () { var bucketOne = 3; var bucketTwo = 5; var goal = 1; @@ -23,7 +23,7 @@ describe('TwoBucket', function () { }); }); - describe('Measure using bucket one of size 7 and bucket two of size 11 - ', function () { + describe('Measure using bucket one of size 7 and bucket two of size 11', function () { var bucketOne = 7; var bucketTwo = 11; var goal = 2; From 65a4200b2573eb42773db17d643a90c031d0ae01 Mon Sep 17 00:00:00 2001 From: a-dpq Date: Wed, 8 Nov 2017 00:13:52 +0100 Subject: [PATCH 203/272] Fix bowling spec file Previously accidentally enabled tests that should be disabled by default --- exercises/bowling/bowling.spec.js | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 578566f6..1d6746de 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -7,98 +7,98 @@ describe('Bowling', function () { expect(new Bowling(rolls).score()).toEqual(0); }); - it('should be able to score a game with all open frames', function () { + xit('should be able to score a game with all open frames', function () { var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; expect(new Bowling(rolls).score()).toEqual(90); }); - it('a spare followed by zeros is worth 10 points', function () { + xit('a spare followed by zeros is worth 10 points', function () { var rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - it('points scored in the roll after a spare are counted twice', function () { + xit('points scored in the roll after a spare are counted twice', function () { var rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(16); }); - it('consecutive spares each get a one-roll bonus', function () { + xit('consecutive spares each get a one-roll bonus', function () { var rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(31); }); - it('should allow fill ball when the last frame is a spare', function () { + xit('should allow fill ball when the last frame is a spare', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; expect(new Bowling(rolls).score()).toEqual(17); }); - it('a strike earns 10 points in a frame with a single roll', function () { + xit('a strike earns 10 points in a frame with a single roll', function () { var rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(10); }); - it('points scored in the two rolls after a strike are counted twice as a bonus', function () { + xit('points scored in the two rolls after a strike are counted twice as a bonus', function () { var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(26); }); - it('should be able to score multiple strikes in a row', function () { + xit('should be able to score multiple strikes in a row', function () { var rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(new Bowling(rolls).score()).toEqual(81); }); - it('should allow fill balls when the last frame is a strike', function () { + xit('should allow fill balls when the last frame is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; expect(new Bowling(rolls).score()).toEqual(18); }); - it('rolling a spare with the two-roll bonus does not get a bonus roll', function () { + xit('rolling a spare with the two-roll bonus does not get a bonus roll', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; expect(new Bowling(rolls).score()).toEqual(20); }); - it('strikes with the two-roll bonus do not get bonus rolls', function () { + xit('strikes with the two-roll bonus do not get bonus rolls', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(30); }); - it('a strike with the one-roll bonus after a spare in the last frame does not get a bonus', function () { + xit('a strike with the one-roll bonus after a spare in the last frame does not get a bonus', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; expect(new Bowling(rolls).score()).toEqual(20); }); - it('should be able to score a perfect game', function () { + xit('should be able to score a perfect game', function () { var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; expect(new Bowling(rolls).score()).toEqual(300); }); }); describe('Check game rules.', function () { - it('rolls cannot score negative points', function () { + xit('rolls cannot score negative points', function () { var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pins must have a value from 0 to 10')); }); - it('a roll cannot score more than 10 points', function () { + xit('a roll cannot score more than 10 points', function () { var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pins must have a value from 0 to 10')); }); - it('two rolls in a frame cannot score more than 10 points', function () { + xit('two rolls in a frame cannot score more than 10 points', function () { var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); - it('two bonus rolls after a strike in the last frame cannot score more than 10 points', function () { + xit('two bonus rolls after a strike in the last frame cannot score more than 10 points', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6]; expect(function () { new Bowling(rolls).score(); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); - it('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { + xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; expect(new Bowling(rolls).score()).toEqual(26); }); From 5e94724b5c39050be13eee5447326494b2fc846e Mon Sep 17 00:00:00 2001 From: a-dpq Date: Wed, 8 Nov 2017 00:21:13 +0100 Subject: [PATCH 204/272] Resolve conflicts in bowling readme --- exercises/bowling/README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md index 12072e07..f766eeb4 100644 --- a/exercises/bowling/README.md +++ b/exercises/bowling/README.md @@ -12,15 +12,9 @@ A game consists of 10 frames. A frame is composed of one or two balls thrown, wi * An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down after the second throw. -<<<<<<< HEAD -* A spare is where all 10 pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the player's next throw. +* A spare is where all 10 pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the next throw. -* A strike is where all 10 pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the player's next two throws. If a strike is immediately followed by a second strike, then we cannot total the value of first strike until they throw the ball one more time. -======= -* A spare is where all ten pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the next throw. - -* A strike is where all ten pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the next two throws. If a strike is immediately followed by another strike, then the first strike's value cannot be totalled until the next throw. ->>>>>>> upstream/master +* A strike is where all 10 pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the next two throws. If a strike is immediately followed by another strike, then the first strike's value cannot be totalled until the next throw. Here is a three-frame example: @@ -36,11 +30,7 @@ Frame 3 is (9 + 0) = 9 This means the current running total is 48. -<<<<<<< HEAD -The 10th frame in the game is a special case. If someone throws a strike or a spare, they get a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. -======= -The tenth frame in the game is a special case. If the player throws a strike or a spare, then they get one extra throw called a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. ->>>>>>> upstream/master +The 10th frame in the game is a special case. If the player throws a strike or a spare, then they get one extra throw called a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. For a 10th frame of X1/ (strike and a spare), the total value is 20. From 851db6a0cc09bc914c9cda91d8efa087237e5275 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+Radix16@users.noreply.github.com> Date: Thu, 9 Nov 2017 12:28:31 -0800 Subject: [PATCH 205/272] fix grains exercise (#437) --- .eslintignore | 3 ++- exercises/grains/example.js | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 3be4259f..d4530e4d 100644 --- a/.eslintignore +++ b/.eslintignore @@ -12,7 +12,8 @@ exercises/custom-set exercises/flatten-array exercises/food-chain exercises/grade-school -exercises/grains +exercises/grains/big-integer.js +exercises/grains/big-integer.spec.js exercises/kindergarten-garden exercises/leap exercises/linked-list diff --git a/exercises/grains/example.js b/exercises/grains/example.js index 50077605..e8831fd2 100644 --- a/exercises/grains/example.js +++ b/exercises/grains/example.js @@ -4,7 +4,7 @@ var BigInt = require('./big-integer'); * @author github.com/nonsensery * @class Grains * - * Computes the number of grains on the squares of a + * @classdesc Computes the number of grains on the squares of a * chess board, starting with one grain on the first * square, and doubling with each successive square. */ @@ -14,16 +14,19 @@ function Grains() { /** * Gets the number of grains on the nth square. + * @param {number} num - the value to square + * @return {number} the square of num */ Grains.prototype.square = function (num) { - return BigInt(2).pow(num - 1).toString(); + return new BigInt(2).pow(num - 1).toString(); }; /** * Gets the total number of grains on all squares. + * @return {string} the total */ Grains.prototype.total = function () { - var total = BigInt(0); + var total = new BigInt(0); for (var squareNum = 1; squareNum <= 64; ++squareNum) { total = total.add(this.square(squareNum)); From e656e99122fd4b1ff97cb7283fb6d65f45ac1f66 Mon Sep 17 00:00:00 2001 From: "Sara J. Martinez" Date: Sat, 11 Nov 2017 08:43:45 -0500 Subject: [PATCH 206/272] Fix 'accumulate is assigned a value but never used' (#455) --- .eslintignore | 1 - exercises/accumulate/example.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index d4530e4d..8de8ccbf 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,4 @@ big-integer.js -exercises/accumulate exercises/alphametics exercises/anagram exercises/binary-search diff --git a/exercises/accumulate/example.js b/exercises/accumulate/example.js index 18274805..e36fb748 100644 --- a/exercises/accumulate/example.js +++ b/exercises/accumulate/example.js @@ -1,4 +1,4 @@ -var accumulate = module.exports = function (list, accumulator) { +module.exports = function (list, accumulator) { var out = []; var idx = -1; var end = Array.isArray(list) ? list.length : 0; @@ -9,4 +9,3 @@ var accumulate = module.exports = function (list, accumulator) { return out; }; - From 05707002f39c0cb4a669e154098206bffa70e8d7 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Mon, 20 Nov 2017 21:06:40 -0800 Subject: [PATCH 207/272] fix the wordy exercise --- .eslintignore | 3 +-- exercises/wordy/example.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 8de8ccbf..78deb7e8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -36,5 +36,4 @@ exercises/secret-handshake exercises/simple-cipher exercises/simple-linked-list exercises/triangle -exercises/trinary -exercises/wordy +exercises/trinary \ No newline at end of file diff --git a/exercises/wordy/example.js b/exercises/wordy/example.js index ce01bbd7..819cae70 100644 --- a/exercises/wordy/example.js +++ b/exercises/wordy/example.js @@ -47,11 +47,11 @@ WordProblem.prototype.evaluate = function () { var out = 0; var m = this.matches; - if (m[1] !== undefined && m[2] !== undefined && m[3] !== undefined) { + if ( (typeof m[1]) === 'string' && (typeof m[2]) === 'string' && (typeof m[3]) === 'string') { out = this.operate(m[2], m[1], m[3]); } - if (m[4] !== undefined && m[5] !== undefined) { + if ( (typeof m[4]) === 'string' && (typeof m[5]) === 'string') { out = this.operate(m[4], out, m[5]); } From 3ec810b1ffa7795856e6562c80c634cc6c137ae1 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Wed, 22 Nov 2017 06:05:05 -0800 Subject: [PATCH 208/272] fix triangle exercise --- .eslintignore | 4 +--- exercises/triangle/example.js | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.eslintignore b/.eslintignore index 8de8ccbf..9e7590bb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -35,6 +35,4 @@ exercises/scrabble-score exercises/secret-handshake exercises/simple-cipher exercises/simple-linked-list -exercises/triangle -exercises/trinary -exercises/wordy +exercises/trinary \ No newline at end of file diff --git a/exercises/triangle/example.js b/exercises/triangle/example.js index d3f5f614..eb2b9a83 100644 --- a/exercises/triangle/example.js +++ b/exercises/triangle/example.js @@ -22,7 +22,6 @@ function Triangle(a, b, c) { }; this.violatesInequality = function () { - var a = this.sides[0], b = this.sides[1], c = this.sides[2]; return (a + b < c) || (a + c < b) || (b + c < a); }; @@ -50,7 +49,9 @@ function Triangle(a, b, c) { var uniqueSides = []; for (var uniqueSide in uniques) { - uniqueSides.push(uniqueSide); + if (uniques.hasOwnProperty(uniqueSide)) { + uniqueSides.push(uniqueSide); + } } return uniqueSides; From 4bb65abb7c60b2327b741b2bd71eb705e5de0db3 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Wed, 22 Nov 2017 12:31:15 -0500 Subject: [PATCH 209/272] Fix merge conflicts, lint issues, other bugs, and use obj prototype --- config.json | 15 + exercises/connect/README.md | 59 + exercises/connect/connect.spec.js | 108 ++ exercises/connect/example.js | 105 ++ package-lock.json | 1895 ----------------------------- 5 files changed, 287 insertions(+), 1895 deletions(-) create mode 100644 exercises/connect/README.md create mode 100644 exercises/connect/connect.spec.js create mode 100644 exercises/connect/example.js delete mode 100644 package-lock.json diff --git a/config.json b/config.json index 1c840d60..510429fc 100644 --- a/config.json +++ b/config.json @@ -1056,6 +1056,21 @@ "unlocked_by": "prime-factors", "uuid" : "910fe904-7e3c-11e7-bb31-be2e44b06b34" }, + { + "uuid": "3b779cb8-9544-4e0d-a306-e5478d741be7", + "slug": "connect", + "core": false, + "unlocked_by": "grade-school", + "difficulty": 7, + "topics": [ + "Control-flow (loops)", + "Control-flow (conditionals)", + "Games", + "Parsing", + "Arrays", + "Maps" + ] + }, { "core" : false, "difficulty" : 1, diff --git a/exercises/connect/README.md b/exercises/connect/README.md new file mode 100644 index 00000000..035a100a --- /dev/null +++ b/exercises/connect/README.md @@ -0,0 +1,59 @@ +# Connect + +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 +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.) + +The boards look like this (with spaces added for readability, which won't be in +the representation passed to your code): + +``` +. O . X . + . X X O . + O O O X . + . X O X O + X O O O X +``` + +"Player `O`" plays from top to bottom, "Player `X`" plays from left to right. In +the above example `O` has made a connection from left to right but nobody has +won since `O` didn't connect top and bottom. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the test suite pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/connect/connect.spec.js b/exercises/connect/connect.spec.js new file mode 100644 index 00000000..1b926346 --- /dev/null +++ b/exercises/connect/connect.spec.js @@ -0,0 +1,108 @@ +var Board = require('./connect'); + +describe('Judging a game of connect', function () { + it('an empty board has no winner', function () { + var board = [ + '. . . . .', + ' . . . . .', + ' . . . . .', + ' . . . . .', + ' . . . . .' + ]; + expect(new Board(board).winner()).toEqual(''); + }); + + xit('X can win on a 1x1 board', function () { + var board = [ + 'X' + ]; + expect(new Board(board).winner()).toEqual('X'); + }); + + xit('O can win on a 1x1 board', function () { + var board = [ + 'O' + ]; + expect(new Board(board).winner()).toEqual('O'); + }); + + xit('only edges does not make a winner', function () { + var board = [ + 'O O O X', + ' X . . X', + ' X . . X', + ' X O O O' + ]; + expect(new Board(board).winner()).toEqual(''); + }); + + xit('illegal diagonal does not make a winner', function () { + var board = [ + 'X O . .', + ' O X X X', + ' O X O .', + ' . O X .', + ' X X O O' + ]; + expect(new Board(board).winner()).toEqual(''); + }); + + xit('nobody wins crossing adjacent angles', function () { + var board = [ + 'X . . .', + ' . X O .', + ' O . X O', + ' . O . X', + ' . . O .' + ]; + expect(new Board(board).winner()).toEqual(''); + }); + + xit('X wins crossing from left to right', function () { + var board = [ + '. O . .', + ' O X X X', + ' O X O .', + ' X X O X', + ' . O X .' + ]; + expect(new Board(board).winner()).toEqual('X'); + }); + + xit('O wins crossing from top to bottom', function () { + var board = [ + '. O . .', + ' O X X X', + ' O O O .', + ' X X O X', + ' . O X .' + ]; + expect(new Board(board).winner()).toEqual('O'); + }); + + xit('X wins using a convoluted path', function () { + var board = [ + '. X X . .', + ' X . X . X', + ' . X . X .', + ' . X X . .', + ' O O O O O' + ]; + expect(new Board(board).winner()).toEqual('X'); + }); + + xit('X wins using a spiral path', function () { + var board = [ + 'O X X X X X X X X', + ' O X O O O O O O O', + ' O X O X X X X X O', + ' O X O X O O O X O', + ' O X O X X X O X O', + ' O X O O O X O X O', + ' O X X X X X O X O', + ' O O O O O O O X O', + ' X X X X X X X X O' + ]; + expect(new Board(board).winner()).toEqual('X'); + }); +}); diff --git a/exercises/connect/example.js b/exercises/connect/example.js new file mode 100644 index 00000000..9c709a1b --- /dev/null +++ b/exercises/connect/example.js @@ -0,0 +1,105 @@ +/** + * "Player O" plays from top to bottom, "Player X" plays from left to right. + * @param {string[]} initBoard - The starting state of the board + * @returns {Object} - The board business object + */ +var Board = function (initBoard) { + this.board = initBoard.slice(); +}; + +Board.prototype.winner = function () { + var players = ['X', 'O']; + for (var i = 0; i < players.length; i++) { + if (this.checkWin(players[i])) { + return players[i]; + } + } + return ''; +}; + +Board.prototype.checkWin = function (player) { + var positions = this.startPositions(player); + for (var i = 0; i < positions.length; i++) { + if (this.search(positions[i], player, [])) { + return true; + } + } + return false; +}; + +Board.prototype.search = function (pos, XorO, isChecked) { + var self = this; + if (!this.containsPiece(pos, XorO)) { + return false; + } + if (this.winningSpot(pos, XorO)) { + return true; + } + var checked = isChecked.slice(0); + checked.push(pos); + + var matches = this.neighbors(pos) + .filter(function (cell) { + return self.containsPiece(cell, XorO) && + checked.filter( + function (spot) { + return locationMatch(spot, cell); + } + ).length === 0; + }); + + function locationMatch(spot, cell) { + return spot.x === cell.x && spot.y === cell.y; + } + + if (matches.length === 0) { + return false; + } + + return matches + .filter( + function (spot) { + return self.search(spot, XorO, checked); + } + ).length > 0; +}; + +Board.prototype.neighbors = function (cell) { + return [ + {x: cell.x, y: cell.y + 2}, + {x: cell.x, y: cell.y - 2}, + + {x: cell.x + 1, y: cell.y + 1}, + {x: cell.x - 1, y: cell.y + 1}, + + {x: cell.x + 1, y: cell.y - 1}, + {x: cell.x - 1, y: cell.y - 1} + ]; +}; + +Board.prototype.startPositions = function (XorO) { + var self = this; + return XorO === 'X' ? + this.board + .map(function (pos, i) { + return {x: i, y: i}; + }) : + Array.prototype + .map + .call(self.board[0], function (pos, i) { + return {x: 0, y: i}; + }); +}; + +Board.prototype.winningSpot = function (cell, XorO) { + return XorO === 'X' ? + cell.y === this.board[0].length - 1 + cell.x : + cell.x === this.board.length - 1; +}; + +Board.prototype.containsPiece = function (cell, XorO) { + return this.board[cell.x] && this.board[cell.x][cell.y] === XorO; +}; + + +module.exports = Board; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 320ca28b..00000000 --- a/package-lock.json +++ /dev/null @@ -1,1895 +0,0 @@ -{ - "name": "javascript", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "acorn": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", - "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", - "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "ansi-escapes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.8.2" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, - "babel-code-frame": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz", - "integrity": "sha512-/xr1ADm5bnTjjN+xwoXb7lF4v2rnxMzNZzFU7h8SxB+qB6+IqSTOOqVcpaPTUC2Non/MbQxS3OIZnJpQ2X21aQ==", - "dev": true, - "requires": { - "chalk": "2.1.0", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - } - }, - "babel-eslint": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.0.1.tgz", - "integrity": "sha512-h3moF6PCTQE06UjMMG+ydZSBvZ4Q7rqPE/5WAUOvUyHYUTqxm8JVhjZRiG1avI/tGVOK4BnZLDQapyLzh8DeKg==", - "dev": true, - "requires": { - "babel-code-frame": "7.0.0-beta.0", - "babel-traverse": "7.0.0-beta.0", - "babel-types": "7.0.0-beta.0", - "babylon": "7.0.0-beta.22" - } - }, - "babel-helper-function-name": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz", - "integrity": "sha512-DaQccFBBWBEzMdqbKmNXamY0m1yLHJGOdbbEsNoGdJrrU7wAF3wwowtDDPzF0ZT3SqJXPgZW/P2kgBX9moMuAA==", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "7.0.0-beta.0", - "babel-template": "7.0.0-beta.0", - "babel-traverse": "7.0.0-beta.0", - "babel-types": "7.0.0-beta.0" - } - }, - "babel-helper-get-function-arity": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz", - "integrity": "sha512-csqAic15/2Vm1951nJxkkL9K8E6ojyNF/eAOjk7pqJlO8kvgrccGNFCV9eDwcGHDPe5AjvJGwVSAcQ5fit9wuA==", - "dev": true, - "requires": { - "babel-types": "7.0.0-beta.0" - } - }, - "babel-messages": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-7.0.0-beta.0.tgz", - "integrity": "sha512-eXdShsm9ZTh9AQhlIaAn6HR3xWpxCnK9ZwIDA9QyjnwTgMctGxHHflw4b4RJ3/ZjTL0Vrmvm0tQXPkp49mTAUw==", - "dev": true - }, - "babel-template": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-7.0.0-beta.0.tgz", - "integrity": "sha512-tmdH+MmmU0F6Ur8humpevSmFzYKbrN3Oru0g5Qyg4R6+sxjnzZmnvzUbsP0aKMr7tB0Ua6xhEb9arKTOsEMkyA==", - "dev": true, - "requires": { - "babel-traverse": "7.0.0-beta.0", - "babel-types": "7.0.0-beta.0", - "babylon": "7.0.0-beta.22", - "lodash": "4.17.4" - } - }, - "babel-traverse": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz", - "integrity": "sha512-IKzuTqUcQtMRZ0Vv5RjIrGGj33eBKmNTNeRexWSyjPPuAciyNkva1rt7WXPfHfkb+dX7coRAIUhzeTUEzhnwdA==", - "dev": true, - "requires": { - "babel-code-frame": "7.0.0-beta.0", - "babel-helper-function-name": "7.0.0-beta.0", - "babel-messages": "7.0.0-beta.0", - "babel-types": "7.0.0-beta.0", - "babylon": "7.0.0-beta.22", - "debug": "3.1.0", - "globals": "10.1.0", - "invariant": "2.2.2", - "lodash": "4.17.4" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "babel-types": { - "version": "7.0.0-beta.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-7.0.0-beta.0.tgz", - "integrity": "sha512-rJc2kV9iPJGLlqIY71AM3nPcdkoeLRCDuR07GFgfd3lFl4TsBQq76TxYQQIZ2MONg1HpsqmuoCXr9aZ1Oa4wYw==", - "dev": true, - "requires": { - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "2.0.0" - } - }, - "babylon": { - "version": "7.0.0-beta.22", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.22.tgz", - "integrity": "sha512-Yl7iT8QGrS8OfR7p6R12AJexQm+brKwrryai4VWZ7NHUbPoZ5al3+klhvl/14shXZiLa7uK//OIFuZ1/RKHgoA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - } - }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, - "requires": { - "iconv-lite": "0.4.19" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "es-abstract": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.8.2.tgz", - "integrity": "sha512-dvhwFL3yjQxNNsOWx6exMlaDrRHCRGMQlnx5lsXDCZ/J7G/frgIIl94zhZSp/galVAYp7VzPi1OrAHta89/yGQ==", - "dev": true, - "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.10.0.tgz", - "integrity": "sha512-MMVl8P/dYUFZEvolL8PYt7qc5LNdS2lwheq9BYa5Y07FblhcZqFyaUqlS8TW5QITGex21tV4Lk0a3fK8lsJIkA==", - "dev": true, - "requires": { - "ajv": "5.3.0", - "babel-code-frame": "6.26.0", - "chalk": "2.1.0", - "concat-stream": "1.6.0", - "cross-spawn": "5.1.0", - "debug": "3.1.0", - "doctrine": "2.0.0", - "eslint-scope": "3.7.1", - "espree": "3.5.1", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.0.0", - "js-yaml": "3.10.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "require-uncached": "1.0.3", - "semver": "5.4.1", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "4.0.2", - "text-table": "0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - } - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "eslint-config-airbnb-base": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", - "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", - "dev": true, - "requires": { - "eslint-restricted-globals": "0.1.1" - } - }, - "eslint-config-airbnb-es5": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-es5/-/eslint-config-airbnb-es5-1.2.0.tgz", - "integrity": "sha512-MaOKwNpqNZIRy+3augFj5vGHJ4F1sskPjJ/Od7K3N8Vv+8pD6t73XCL18KrHrF1m58qFxPBDl1US6bswE65IbQ==", - "dev": true, - "requires": { - "strip-json-comments": "1.0.2" - }, - "dependencies": { - "strip-json-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.2.tgz", - "integrity": "sha1-WkirlgI9usG3uND/q/b2PxZ3vp8=", - "dev": true - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", - "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", - "dev": true, - "requires": { - "debug": "2.6.9", - "resolve": "1.5.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "eslint-module-utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", - "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", - "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", - "dev": true, - "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.1", - "eslint-module-utils": "2.1.1", - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - } - } - }, - "eslint-plugin-jasmine": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.9.1.tgz", - "integrity": "sha1-IuGaWfFvOl9kOgSroEQ40OMEcDA=", - "dev": true - }, - "eslint-plugin-react": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz", - "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==", - "dev": true, - "requires": { - "doctrine": "2.0.0", - "has": "1.0.1", - "jsx-ast-utils": "2.0.1", - "prop-types": "15.6.0" - }, - "dependencies": { - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - } - } - }, - "eslint-restricted-globals": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", - "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "dev": true, - "requires": { - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "espree": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz", - "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=", - "dev": true, - "requires": { - "acorn": "5.2.1", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "external-editor": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz", - "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==", - "dev": true, - "requires": { - "iconv-lite": "0.4.19", - "jschardet": "1.6.0", - "tmp": "0.0.33" - } - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fbjs": { - "version": "0.8.16", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", - "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", - "dev": true, - "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.14" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", - "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "globals": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-10.1.0.tgz", - "integrity": "sha1-RCWhiBvg0za0qCOoKnvnJdXdmHw=", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.1.0", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.0.5", - "figures": "2.0.0", - "lodash": "4.17.4", - "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" - } - }, - "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, - "requires": { - "loose-envify": "1.3.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "1.0.1" - } - }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, - "requires": { - "tryit": "1.0.3" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, - "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" - } - }, - "jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "7.1.2", - "jasmine-core": "2.8.0" - } - }, - "jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jschardet": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.6.0.tgz", - "integrity": "sha512-xYuhvQ7I9PDJIGBWev9xm0+SMSed3ZDBAmvVjbFR1ZRLAF+vlXcQu6cRI9uAlj81rzikElRVteehwV7DuX2ZmQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsx-ast-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", - "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", - "dev": true, - "requires": { - "array-includes": "3.0.3" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "3.0.2" - } - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, - "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "1.1.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "1.1.2" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "2.0.6" - } - }, - "prop-types": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", - "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", - "dev": true, - "requires": { - "fbjs": "0.8.16", - "loose-envify": "1.3.1", - "object-assign": "4.1.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - } - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "4.0.8" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0" - } - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "5.3.0", - "ajv-keywords": "2.1.1", - "chalk": "2.1.0", - "lodash": "4.17.4", - "slice-ansi": "1.0.0", - "string-width": "2.1.1" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.14", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", - "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "0.5.1" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} From 50b7337da27c701d30ead112596ee3b2845d2c01 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Mon, 27 Nov 2017 07:23:08 -0800 Subject: [PATCH 210/272] fix trinary exercise --- .eslintignore | 1 - exercises/trinary/example.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintignore b/.eslintignore index 78deb7e8..5c1f7070 100644 --- a/.eslintignore +++ b/.eslintignore @@ -36,4 +36,3 @@ exercises/secret-handshake exercises/simple-cipher exercises/simple-linked-list exercises/triangle -exercises/trinary \ No newline at end of file diff --git a/exercises/trinary/example.js b/exercises/trinary/example.js index 15c0c90b..a580034f 100644 --- a/exercises/trinary/example.js +++ b/exercises/trinary/example.js @@ -14,5 +14,5 @@ Trinary.prototype.toDecimal = function () { }; Trinary.prototype.accumulator = function (decimal, digit, index) { - return decimal += digit * Math.pow(BASE, index); + return decimal + digit * Math.pow(BASE, index); }; From 98465e7fbbb49a37b2bc86499fecafa56a59802a Mon Sep 17 00:00:00 2001 From: Anna Weber Date: Sat, 28 Oct 2017 23:00:42 +0200 Subject: [PATCH 211/272] Implementing: two-fer --- config.json | 11 +++++++++ exercises/two-fer/README.md | 41 +++++++++++++++++++++++++++++++ exercises/two-fer/example.js | 10 ++++++++ exercises/two-fer/two-fer.js | 12 +++++++++ exercises/two-fer/two-fer.spec.js | 18 ++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 exercises/two-fer/README.md create mode 100644 exercises/two-fer/example.js create mode 100644 exercises/two-fer/two-fer.js create mode 100644 exercises/two-fer/two-fer.spec.js diff --git a/config.json b/config.json index 510429fc..5faec2f4 100644 --- a/config.json +++ b/config.json @@ -13,6 +13,17 @@ ], "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256" }, + { + "core": false, + "difficulty": 1, + "slug": "two-fer", + "topics": [ + "strings", + "control-flow-(conditionals)" + ], + "unlocked_by": "hello-world", + "uuid": "5f3d1326-f0c5-44a6-b90a-6af3b7d455f1" + }, { "core": true, "difficulty": 1, diff --git a/exercises/two-fer/README.md b/exercises/two-fer/README.md new file mode 100644 index 00000000..4baeeaa5 --- /dev/null +++ b/exercises/two-fer/README.md @@ -0,0 +1,41 @@ +# Two Fer + +`Two-fer` or `2-fer` is short for two for one. One for you and one for me. + +``` +"One for X, one for me." +``` + +When X is a name or "you". + +If the given name is "Alice", the result should be "One for Alice, one for me." +If no name is given, the result should be "One for you, one for me." + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Two Fer exercise: + + jasmine two-fer.spec.js + +All tests but the first have been skipped. Once you get a test passing, +you can unskip the next one by changing `xit` to `it`. + +## Source + +This is an exercise to introduce users to basic programming constructs, just after 'Hello World'. [https://en.wikipedia.org/wiki/Two-fer](https://en.wikipedia.org/wiki/Two-fer) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. + diff --git a/exercises/two-fer/example.js b/exercises/two-fer/example.js new file mode 100644 index 00000000..5719a4cc --- /dev/null +++ b/exercises/two-fer/example.js @@ -0,0 +1,10 @@ +var TwoFer = function () {}; + +TwoFer.prototype.twoFer = function (who) { + if (who) { + return 'One for ' + who + ', one for me.'; + } + return 'One for you, one for me.'; +}; + +module.exports = TwoFer; diff --git a/exercises/two-fer/two-fer.js b/exercises/two-fer/two-fer.js new file mode 100644 index 00000000..88ab610d --- /dev/null +++ b/exercises/two-fer/two-fer.js @@ -0,0 +1,12 @@ +var TwoFer = function () {}; + +TwoFer.prototype.twoFer = function (who) { + // your code goes here + // You will have to use the parameter who + // in some way. In this example, it is just + // returned, but your solution will have to + // use a conditional. + return who; +}; + +module.exports = TwoFer; diff --git a/exercises/two-fer/two-fer.spec.js b/exercises/two-fer/two-fer.spec.js new file mode 100644 index 00000000..fe262efa --- /dev/null +++ b/exercises/two-fer/two-fer.spec.js @@ -0,0 +1,18 @@ + +var TwoFer = require('./two-fer'); + +describe('Two Fer', function () { + var twoFer = new TwoFer(); + + it('gives one to you if no parameter given', function () { + expect(twoFer.twoFer()).toEqual('One for you, one for me.'); + }); + + xit('gives one to Alice if \'Alice\' is given', function () { + expect(twoFer.twoFer('Alice')).toEqual('One for Alice, one for me.'); + }); + + xit('gives one to Bob if \'Bob\' is given', function () { + expect(twoFer.twoFer('Bob')).toEqual('One for Bob, one for me.'); + }); +}); From 753d77218138ef3b60647b4856a138b42fb2e613 Mon Sep 17 00:00:00 2001 From: Logan Stucki Date: Tue, 5 Dec 2017 09:35:19 -0600 Subject: [PATCH 212/272] alphametics: resolve eslint errors (#463) * alphametics: resolve eslint errors * alphametics: pass empty array for memo --- exercises/alphametics/example.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/exercises/alphametics/example.js b/exercises/alphametics/example.js index 5467cf24..0c4a8f7f 100644 --- a/exercises/alphametics/example.js +++ b/exercises/alphametics/example.js @@ -53,21 +53,21 @@ function testNumbers(numbers, puzzleParts, firstLetters) { } var replaceRegex = new RegExp('[' + keys.join('') + ']', 'g'); - puzzleParts = puzzleParts.join(',') + var puzzlePartsJoined = puzzleParts.join(',') .replace(replaceRegex, function (input) { return numbers[input]; }) .split(',') - .map(function (t) {return parseInt(t);}); + .map(function (t) {return parseInt(t, 10);}); - var total = puzzleParts.slice(puzzleParts.length - 1)[0]; - return total === puzzleParts - .slice(0, puzzleParts.length - 1) + var total = puzzlePartsJoined.slice(puzzlePartsJoined.length - 1)[0]; + return total === puzzlePartsJoined + .slice(0, puzzlePartsJoined.length - 1) .reduce(function (acc, val) { return acc + val; }, 0); } function getPermutations(inputArr) { var results = []; function permute(arr, memo) { - var cur, memo = memo || []; + var cur = memo; for (var i = 0; i < arr.length; i++) { cur = arr.splice(i, 1); if (arr.length === 0) { @@ -78,11 +78,15 @@ function getPermutations(inputArr) { } return results; } - return permute(inputArr); + return permute(inputArr, []); } function getNumberCombinations(set, k) { - var i, j, combs, head, tailcombs; + var i; + var j; + var combs; + var head; + var tailcombs; if (k > set.length || k <= 0) { return []; } @@ -104,4 +108,4 @@ function getNumberCombinations(set, k) { return combs; } -module.exports = solve; +module.exports = solve; From c11343a73d13a7ab923d70ba48d62bf7f21f4213 Mon Sep 17 00:00:00 2001 From: Michael Prude Date: Thu, 7 Dec 2017 17:41:40 -0500 Subject: [PATCH 213/272] =?UTF-8?q?Fix=20eslint=20errors=20for=20=E2=80=9C?= =?UTF-8?q?say=E2=80=9D=20example=20(#465)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 1 - exercises/say/example.js | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 78deb7e8..bfe47cb3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -30,7 +30,6 @@ exercises/robot-name exercises/robot-simulator exercises/roman-numerals exercises/saddle-points -exercises/say exercises/scrabble-score exercises/secret-handshake exercises/simple-cipher diff --git a/exercises/say/example.js b/exercises/say/example.js index 4a69883b..0b96b824 100644 --- a/exercises/say/example.js +++ b/exercises/say/example.js @@ -41,7 +41,8 @@ var bigNumbers = { }; function bigPart(number) { - var factor, result = ''; + var factor; + var result = ''; for (var bigNumber = 1000000000; bigNumber >= 1000; bigNumber /= 1000) { if (number.current >= bigNumber) { factor = Math.floor(number.current / bigNumber); @@ -58,6 +59,7 @@ function sayDecade(n) { return decades[decade] + '-' + smallNumbers[n - decade]; } } + throw new Error('Number must be between 10 and 99.'); } function twoDigit(n) { @@ -78,7 +80,8 @@ function threeDigit(n) { } exports.inEnglish = function (n) { - var result, number = {current: n}; + var result; + var number = {current: n}; if (n >= 0 && n < 1000000000000) { result = bigPart(number); result += threeDigit(number.current); From 46249b08afc4eca4247c512f4bba52af84d32c0f Mon Sep 17 00:00:00 2001 From: mjprude Date: Thu, 7 Dec 2017 17:44:14 -0500 Subject: [PATCH 214/272] Eslint fix for scrabble-score --- .eslintignore | 1 - exercises/scrabble-score/example.js | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 78deb7e8..e868397f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -31,7 +31,6 @@ exercises/robot-simulator exercises/roman-numerals exercises/saddle-points exercises/say -exercises/scrabble-score exercises/secret-handshake exercises/simple-cipher exercises/simple-linked-list diff --git a/exercises/scrabble-score/example.js b/exercises/scrabble-score/example.js index 28f08414..be6cd36c 100644 --- a/exercises/scrabble-score/example.js +++ b/exercises/scrabble-score/example.js @@ -14,9 +14,8 @@ function letterScore(letter) { return letterScores[letter] || 0; } -module.exports = function (word) { - word || (word = ''); - word = word.toLowerCase(); +module.exports = function (wrd) { + var word = wrd ? wrd.toLowerCase() : ''; var sum = 0; var idx = -1; From 059a55d58a3e72b7318e2f8aa928b697646e480c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Fri, 8 Dec 2017 13:21:44 +0100 Subject: [PATCH 215/272] Fix ESLint errors for `food-chain` exercise --- .eslintignore | 3 +- exercises/food-chain/example.js | 87 +++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/.eslintignore b/.eslintignore index 05dedd39..35dced80 100644 --- a/.eslintignore +++ b/.eslintignore @@ -9,7 +9,6 @@ exercises/circular-buffer exercises/clock exercises/custom-set exercises/flatten-array -exercises/food-chain exercises/grade-school exercises/grains/big-integer.js exercises/grains/big-integer.spec.js @@ -32,4 +31,4 @@ exercises/roman-numerals exercises/saddle-points exercises/secret-handshake exercises/simple-cipher -exercises/simple-linked-list \ No newline at end of file +exercises/simple-linked-list diff --git a/exercises/food-chain/example.js b/exercises/food-chain/example.js index 032bbd63..f3b567b2 100644 --- a/exercises/food-chain/example.js +++ b/exercises/food-chain/example.js @@ -29,51 +29,64 @@ FoodChain.prototype.verses = function (first, last) { /** * Return song verse by number. * - * @param {Number} verse + * @param {Number} number * verse number * * @return {String} * song verse */ FoodChain.prototype.verse = function (number) { + var verse; + switch (number) { - case 1: return '' + - 'I know an old lady who swallowed a fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 2: return '' + - 'I know an old lady who swallowed a spider.\n' + 'It wriggled and jiggled and tickled inside her.\n' + - 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 3: return '' + - 'I know an old lady who swallowed a bird.\n' + 'How absurd to swallow a bird!\n' + - 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + - 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 4: return '' + - 'I know an old lady who swallowed a cat.\n' + 'Imagine that, to swallow a cat!\n' + 'She swallowed the cat to catch the bird.\n' + - 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + - 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 5: return '' + - 'I know an old lady who swallowed a dog.\n' + 'What a hog, to swallow a dog!\n' + 'She swallowed the dog to catch the cat.\n' + - 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + - 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 6: return '' + - 'I know an old lady who swallowed a goat.\n' + 'Just opened her throat and swallowed a goat!\n' + 'She swallowed the goat to catch the dog.\n' + - 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + - 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + - 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 7: return '' + - 'I know an old lady who swallowed a cow.\n' + 'I don\'t know how she swallowed a cow!\n' + 'She swallowed the cow to catch the goat.\n' + - 'She swallowed the goat to catch the dog.\n' + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + - 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + - 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; - - case 8: return '' + - 'I know an old lady who swallowed a horse.\n' + 'She\'s dead, of course!\n'; + case 1: + verse = 'I know an old lady who swallowed a fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 2: + verse = 'I know an old lady who swallowed a spider.\n' + 'It wriggled and jiggled and tickled inside her.\n' + + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 3: + verse = 'I know an old lady who swallowed a bird.\n' + 'How absurd to swallow a bird!\n' + + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 4: + verse = 'I know an old lady who swallowed a cat.\n' + 'Imagine that, to swallow a cat!\n' + 'She swallowed the cat to catch the bird.\n' + + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 5: + verse = 'I know an old lady who swallowed a dog.\n' + 'What a hog, to swallow a dog!\n' + 'She swallowed the dog to catch the cat.\n' + + 'She swallowed the cat to catch the bird.\n' + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 6: + verse = 'I know an old lady who swallowed a goat.\n' + 'Just opened her throat and swallowed a goat!\n' + 'She swallowed the goat to catch the dog.\n' + + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + + 'She swallowed the spider to catch the fly.\n' + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 7: + verse = 'I know an old lady who swallowed a cow.\n' + 'I don\'t know how she swallowed a cow!\n' + 'She swallowed the cow to catch the goat.\n' + + 'She swallowed the goat to catch the dog.\n' + 'She swallowed the dog to catch the cat.\n' + 'She swallowed the cat to catch the bird.\n' + + 'She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her.\n' + 'She swallowed the spider to catch the fly.\n' + + 'I don\'t know why she swallowed the fly. Perhaps she\'ll die.\n'; + break; + + case 8: verse = 'I know an old lady who swallowed a horse.\n' + 'She\'s dead, of course!\n'; + break; + + default: verse = ''; } + + return verse; }; FoodChain.prototype.sing = FoodChain.prototype.verses.bind(null, 1, 8); From 8396d7d8c0c6a0de87d29f6f50ad1c4fce1ff700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Chavarr=C3=ADa?= Date: Fri, 8 Dec 2017 23:13:11 +0100 Subject: [PATCH 216/272] Fix ESLint errors for `circular-buffer` exercise (#467) --- .eslintignore | 3 +-- exercises/circular-buffer/circular-buffer.spec.js | 2 +- exercises/circular-buffer/example.js | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 05dedd39..ed2bf324 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,7 +5,6 @@ exercises/binary-search exercises/binary-search-tree exercises/bowling exercises/bracket-push -exercises/circular-buffer exercises/clock exercises/custom-set exercises/flatten-array @@ -32,4 +31,4 @@ exercises/roman-numerals exercises/saddle-points exercises/secret-handshake exercises/simple-cipher -exercises/simple-linked-list \ No newline at end of file +exercises/simple-linked-list diff --git a/exercises/circular-buffer/circular-buffer.spec.js b/exercises/circular-buffer/circular-buffer.spec.js index 6f42b7a8..36b73491 100644 --- a/exercises/circular-buffer/circular-buffer.spec.js +++ b/exercises/circular-buffer/circular-buffer.spec.js @@ -57,7 +57,7 @@ describe('CircularBuffer', function () { xit('writes of undefined or null don\'t occupy buffer', function () { var buffer = circularBuffer(3); buffer.write(null); - buffer.write(undefined); + buffer.write(undefined); // eslint-disable-line no-undefined [1, 2, 3].map(function (i) { buffer.write(i.toString()); }); expect(buffer.read()).toBe('1'); }); diff --git a/exercises/circular-buffer/example.js b/exercises/circular-buffer/example.js index 870611f7..e636d4a0 100644 --- a/exercises/circular-buffer/example.js +++ b/exercises/circular-buffer/example.js @@ -68,7 +68,7 @@ function CircularBuffer(capacity) { } function isEmpty(data) { - return data === null || data === undefined; + return !data; } } From 5e7e80040537ebafa0476573034fd63dcdd7cf8e Mon Sep 17 00:00:00 2001 From: Sam Warner <30871823+sjwarner-bp@users.noreply.github.com> Date: Fri, 8 Dec 2017 22:16:24 +0000 Subject: [PATCH 217/272] secret-handshake: fix link in README (#470) --- exercises/secret-handshake/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/secret-handshake/README.md b/exercises/secret-handshake/README.md index 6184c2f8..f2f24b8d 100644 --- a/exercises/secret-handshake/README.md +++ b/exercises/secret-handshake/README.md @@ -53,7 +53,7 @@ changing `xit` to `it`. ## Source -Bert, in Mary Poppins [http://www.imdb.com/character/ch0011238/quotes](http://www.imdb.com/character/ch0011238/quotes) +Bert, in Mary Poppins [http://www.imdb.com/title/tt0058331/quotes/qt0437047](http://www.imdb.com/title/tt0058331/quotes/qt0437047) ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. From ab1411155d0c5e986c264065bf901a54921ccc56 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Sat, 9 Dec 2017 16:51:59 -0800 Subject: [PATCH 218/272] fix anagram exercise --- .eslintignore | 1 - exercises/anagram/example.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index ed2bf324..2409d59c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,5 @@ big-integer.js exercises/alphametics -exercises/anagram exercises/binary-search exercises/binary-search-tree exercises/bowling diff --git a/exercises/anagram/example.js b/exercises/anagram/example.js index f1d77dc4..2e1cee2e 100644 --- a/exercises/anagram/example.js +++ b/exercises/anagram/example.js @@ -4,8 +4,8 @@ function Anagram(word) { this.word = word; } -Anagram.prototype.matches = function (words) { - words = Array.isArray(words) ? words : [].slice.call(arguments, 0); +Anagram.prototype.matches = function (wordList) { + var words = Array.isArray(wordList) ? wordList : [].slice.call(arguments, 0); return words.filter(function (candidate) { return !sameWord(this.word, candidate) && isAnagram(this.word, candidate); From d610f07f16e758df58c963fa8121adcd11ac986f Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Sat, 9 Dec 2017 17:27:10 -0800 Subject: [PATCH 219/272] fix pangram exercise --- .eslintignore | 1 - exercises/pangram/example.js | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.eslintignore b/.eslintignore index ed2bf324..646208e3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -21,7 +21,6 @@ exercises/minesweeper exercises/nth-prime exercises/octal exercises/palindrome-products -exercises/pangram exercises/perfect-numbers exercises/pythagorean-triplet exercises/queen-attack diff --git a/exercises/pangram/example.js b/exercises/pangram/example.js index e6d8a7c6..86922be7 100644 --- a/exercises/pangram/example.js +++ b/exercises/pangram/example.js @@ -1,9 +1,10 @@ -var notAlpha = /[^a-z]+/gi, - ALPHA_LENGTH = 26, - cleaned, - unique; var Pangram = function (candidate) { + var notAlpha = /[^a-z]+/gi; + var ALPHA_LENGTH = 26; + var cleaned; + var unique; + unique = {}; cleaned = (candidate.replace(notAlpha, '')).toLowerCase(); cleaned.split('').forEach(function (el) { From 8940f7cc512e0f267f63f2448ca1486bea5275f1 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Sun, 10 Dec 2017 09:16:18 -0800 Subject: [PATCH 220/272] fix octal exercise --- .eslintignore | 1 - exercises/octal/example.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintignore b/.eslintignore index a11a03c3..2b4aac29 100644 --- a/.eslintignore +++ b/.eslintignore @@ -18,7 +18,6 @@ exercises/list-ops exercises/luhn exercises/minesweeper exercises/nth-prime -exercises/octal exercises/palindrome-products exercises/perfect-numbers exercises/pythagorean-triplet diff --git a/exercises/octal/example.js b/exercises/octal/example.js index 1b66b739..535d0556 100644 --- a/exercises/octal/example.js +++ b/exercises/octal/example.js @@ -17,7 +17,7 @@ Octal.prototype.digitValue = function (value) { }; Octal.prototype.accumulator = function (decimal, digit, index) { - return decimal += digit * Math.pow(BASE, index); + return decimal + digit * Math.pow(BASE, index); }; module.exports = Octal; From b3e626e90cd97a1dd809aa9b895d69f70513e9d8 Mon Sep 17 00:00:00 2001 From: Radix16 <12012148+Radix16@users.noreply.github.com> Date: Sun, 10 Dec 2017 09:34:17 -0800 Subject: [PATCH 221/272] fix robot name exerise --- .eslintignore | 1 - exercises/robot-name/robot-name.spec.js | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.eslintignore b/.eslintignore index a11a03c3..4b9905e4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -23,7 +23,6 @@ exercises/palindrome-products exercises/perfect-numbers exercises/pythagorean-triplet exercises/queen-attack -exercises/robot-name exercises/robot-simulator exercises/roman-numerals exercises/saddle-points diff --git a/exercises/robot-name/robot-name.spec.js b/exercises/robot-name/robot-name.spec.js index 810c92ab..f9b244f5 100644 --- a/exercises/robot-name/robot-name.spec.js +++ b/exercises/robot-name/robot-name.spec.js @@ -35,9 +35,9 @@ describe('Robot', function () { }); xit('should set a unique name after reset', function () { - var i, - numResets = 10000, - usedNames = {}; + var i; + var numResets = 10000; + var usedNames = {}; usedNames[robot.name] = true; @@ -49,11 +49,11 @@ describe('Robot', function () { expect(Object.keys(usedNames).length).toEqual(numResets + 1); }); - // This test is optional. + // This test is optional. xit('there can be lots of robots with different names each', function () { - var i, - numRobots = 10000, - usedNames = {}; + var i; + var numRobots = 10000; + var usedNames = {}; for (i = 0; i < numRobots; i++) { var newRobot = new Robot(); From 94d2ea923e86200a3515e3d1f0d99486c91adf78 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Sat, 16 Dec 2017 20:13:45 +0530 Subject: [PATCH 222/272] Add package-lock.json to the repo Closes #477 --- package-lock.json | 1846 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1846 insertions(+) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c3c1fed5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1846 @@ +{ + "name": "javascript", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz", + "integrity": "sha512-yd7CkUughvHQoEahQqcMdrZw6o/6PwUxiRkfZuVDVHCDe77mysD/suoNyk5mK6phTnRW1kyIbPHyCJgxw++LXg==", + "dev": true, + "requires": { + "chalk": "2.3.0", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz", + "integrity": "sha512-c+DAyp8LMm2nzSs2uXEuxp4LYGSUYEyHtU3fU57avFChjsnTmmpWmXj2dv0yUxHTEydgVAv5fIzA+4KJwoqWDA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.31", + "@babel/template": "7.0.0-beta.31", + "@babel/traverse": "7.0.0-beta.31", + "@babel/types": "7.0.0-beta.31" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz", + "integrity": "sha512-m7rVVX/dMLbbB9NCzKYRrrFb0qZxgpmQ4Wv6y7zEsB6skoJHRuXVeb/hAFze79vXBbuD63ci7AVHXzAdZSk9KQ==", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.31" + } + }, + "@babel/template": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.31.tgz", + "integrity": "sha512-97IRmLvoDhIDSQkqklVt3UCxJsv0LUEVb/0DzXWtc8Lgiyxj567qZkmTG9aR21CmcJVVIvq2Y/moZj4oEpl5AA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.31", + "@babel/types": "7.0.0-beta.31", + "babylon": "7.0.0-beta.31", + "lodash": "4.17.4" + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.31.tgz", + "integrity": "sha512-3N+VJW+KlezEjFBG7WSYeMyC5kIqVLPb/PGSzCDPFcJrnArluD1GIl7Y3xC7cjKiTq2/JohaLWHVPjJWHlo9Gg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.31", + "@babel/helper-function-name": "7.0.0-beta.31", + "@babel/types": "7.0.0-beta.31", + "babylon": "7.0.0-beta.31", + "debug": "3.1.0", + "globals": "10.4.0", + "invariant": "2.2.2", + "lodash": "4.17.4" + } + }, + "@babel/types": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.31.tgz", + "integrity": "sha512-exAHB+NeFGxkfQ5dSUD03xl3zYGneeSk2Mw2ldTt/nTvYxuDiuSp3DlxgUBgzbdTFG4fbwPk0WtKWOoTXCmNGg==", + "dev": true, + "requires": { + "esutils": "2.0.2", + "lodash": "4.17.4", + "to-fast-properties": "2.0.0" + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", + "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "ansi-escapes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "1.1.2", + "es-abstract": "1.10.0" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-eslint": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.0.3.tgz", + "integrity": "sha512-7D4iUpylEiKJPGbeSAlNddGcmA41PadgZ6UAb6JVyh003h3d0EbZusYFBR/+nBgqtaVJM2J2zUVa3N0hrpMH6g==", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.31", + "@babel/traverse": "7.0.0-beta.31", + "@babel/types": "7.0.0-beta.31", + "babylon": "7.0.0-beta.31" + } + }, + "babylon": { + "version": "7.0.0-beta.31", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.31.tgz", + "integrity": "sha512-6lm2mV3S51yEnKmQQNnswoABL1U1H1KHoCCVwdwI3hvIv+W7ya4ki7Aw4o4KxtUHjNKkK5WpZb22rrMMOcJXJQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "4.5.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "2.0.5", + "object-keys": "1.0.11" + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es-abstract": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "dev": true, + "requires": { + "es-to-primitive": "1.1.1", + "function-bind": "1.1.1", + "has": "1.0.1", + "is-callable": "1.1.3", + "is-regex": "1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "1.1.3", + "is-date-object": "1.0.1", + "is-symbol": "1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.13.1.tgz", + "integrity": "sha512-UCJVV50RtLHYzBp1DZ8CMPtRSg4iVZvjgO9IJHIKyWU/AnJVjtdRikoUPLB29n5pzMB7TnsLQWf0V6VUJfoPfw==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "babel-code-frame": "6.26.0", + "chalk": "2.3.0", + "concat-stream": "1.6.0", + "cross-spawn": "5.1.0", + "debug": "3.1.0", + "doctrine": "2.0.2", + "eslint-scope": "3.7.1", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "functional-red-black-tree": "1.0.1", + "glob": "7.1.2", + "globals": "11.1.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "3.3.0", + "is-resolvable": "1.0.1", + "js-yaml": "3.10.0", + "json-stable-stringify-without-jsonify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "7.0.0", + "progress": "2.0.0", + "require-uncached": "1.0.3", + "semver": "5.4.1", + "strip-ansi": "4.0.0", + "strip-json-comments": "2.0.1", + "table": "4.0.2", + "text-table": "0.2.0" + }, + "dependencies": { + "globals": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz", + "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==", + "dev": true, + "requires": { + "eslint-restricted-globals": "0.1.1" + } + }, + "eslint-config-airbnb-es5": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-es5/-/eslint-config-airbnb-es5-1.2.0.tgz", + "integrity": "sha512-MaOKwNpqNZIRy+3augFj5vGHJ4F1sskPjJ/Od7K3N8Vv+8pD6t73XCL18KrHrF1m58qFxPBDl1US6bswE65IbQ==", + "dev": true, + "requires": { + "strip-json-comments": "1.0.2" + }, + "dependencies": { + "strip-json-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.2.tgz", + "integrity": "sha1-WkirlgI9usG3uND/q/b2PxZ3vp8=", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", + "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", + "dev": true, + "requires": { + "debug": "2.6.9", + "resolve": "1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-module-utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", + "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "pkg-dir": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "dev": true, + "requires": { + "builtin-modules": "1.1.1", + "contains-path": "0.1.0", + "debug": "2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "0.3.1", + "eslint-module-utils": "2.1.1", + "has": "1.0.1", + "lodash.cond": "4.5.2", + "minimatch": "3.0.4", + "read-pkg-up": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "2.0.2", + "isarray": "1.0.0" + } + } + } + }, + "eslint-plugin-jasmine": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.9.1.tgz", + "integrity": "sha1-IuGaWfFvOl9kOgSroEQ40OMEcDA=", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz", + "integrity": "sha512-YGSjB9Qu6QbVTroUZi66pYky3DfoIPLdHQ/wmrBGyBRnwxQsBXAov9j2rpXt/55i8nyMv6IRWJv2s4d4YnduzQ==", + "dev": true, + "requires": { + "doctrine": "2.0.2", + "has": "1.0.1", + "jsx-ast-utils": "2.0.1", + "prop-types": "15.6.0" + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "external-editor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", + "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, + "requires": { + "chardet": "0.4.2", + "iconv-lite": "0.4.19", + "tmp": "0.0.33" + } + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "dev": true, + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.17" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-10.4.0.tgz", + "integrity": "sha512-uNUtxIZpGyuaq+5BqGGQHsL4wUlJAXRqOm6g3Y48/CWNGTLONgBibI0lh6lGxjR2HljFYUfszb+mk4WkgMntsA==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "3.0.0", + "chalk": "2.3.0", + "cli-cursor": "2.1.0", + "cli-width": "2.2.0", + "external-editor": "2.1.0", + "figures": "2.0.0", + "lodash": "4.17.4", + "mute-stream": "0.0.7", + "run-async": "2.3.0", + "rx-lite": "4.0.8", + "rx-lite-aggregates": "4.0.8", + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "through": "2.3.8" + } + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.1" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "1.0.1" + } + }, + "is-resolvable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "dev": true, + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + } + }, + "jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.8.0" + } + }, + "jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "3.0.3" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dev": true, + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "1.1.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.1.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "dev": true, + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "2.0.1", + "signal-exit": "3.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "4.0.8" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "5.5.1", + "ajv-keywords": "2.1.1", + "chalk": "2.3.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", + "string-width": "2.1.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } +} From 198fe84f71f516019e0d7ce94b740c2f12c6a179 Mon Sep 17 00:00:00 2001 From: Elia Ahadi Date: Wed, 27 Dec 2017 01:54:49 +1100 Subject: [PATCH 223/272] reverse string exercise (#417) * reverse string exercise * 3 files for submission * name updates * more updates * subject.matches is a function * fixed array inputs * modified matches * spacing updates * spacing updates #2 * spacing updates #3 * spacing updates #4 * config.json reverse string * updated spec and example files * updated spec and example files v2 * updated spec and example files v3 * updated spec and example files v4 * updated spec and example files v5 * updated spec and example files v6 --- config.json | 12 +++++++ exercises/reverse-string/README.md | 36 +++++++++++++++++++ exercises/reverse-string/example.js | 11 ++++++ .../reverse-string/reverse-string.spec.js | 33 +++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 exercises/reverse-string/README.md create mode 100644 exercises/reverse-string/example.js create mode 100644 exercises/reverse-string/reverse-string.spec.js diff --git a/config.json b/config.json index 5faec2f4..ba27724f 100644 --- a/config.json +++ b/config.json @@ -35,6 +35,18 @@ ], "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b" }, + { + "core": false, + "difficulty": 2, + "slug": "reverse-string", + "topics": [ + "loops", + "for", + "strings" + ], + "unlocked_by": "leap", + "uuid": "553a6be7-eecb-45dc-9cea-05126c525f1b" + }, { "core": true, "difficulty": 1, diff --git a/exercises/reverse-string/README.md b/exercises/reverse-string/README.md new file mode 100644 index 00000000..d6d75bb9 --- /dev/null +++ b/exercises/reverse-string/README.md @@ -0,0 +1,36 @@ +# Reverse String + +For example: +input: "cool" +output: "looc" + + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Reverse String exercise: + + jasmine reverse-string.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +This is an exercise to introduce users to using Exercism and arrays and strings [https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb](https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/reverse-string/example.js b/exercises/reverse-string/example.js new file mode 100644 index 00000000..b19b8d8d --- /dev/null +++ b/exercises/reverse-string/example.js @@ -0,0 +1,11 @@ +'use strict'; + +function reverseString(string) { + var revString = ''; + for (var i = string.length - 1; i >= 0; i--) { + revString += string[i]; + } + return revString; +} + +module.exports = reverseString; diff --git a/exercises/reverse-string/reverse-string.spec.js b/exercises/reverse-string/reverse-string.spec.js new file mode 100644 index 00000000..c6d6327c --- /dev/null +++ b/exercises/reverse-string/reverse-string.spec.js @@ -0,0 +1,33 @@ +var reverseString = require('./reverse-string'); + +describe('ReverseString', function () { + it('empty string', function () { + var expected = ''; + var actual = reverseString(''); + expect(actual).toEqual(expected); + }); + + xit('a word', function () { + var expected = 'tobor'; + var actual = reverseString('robot'); + expect(actual).toEqual(expected); + }); + + xit('a capitalized word', function () { + var expected = 'nemaR'; + var actual = reverseString('Ramen'); + expect(actual).toEqual(expected); + }); + + xit('a sentence with punctuation', function () { + var expected = '!yrgnuh ma I'; + var actual = reverseString('I am hungry!'); + expect(actual).toEqual(expected); + }); + + xit('a palindrome', function () { + var expected = 'racecar'; + var actual = reverseString('racecar'); + expect(actual).toEqual(expected); + }); +}); From 5aa164fe11c02cc43d8d01b8ce5c108a3b460b43 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Thu, 28 Dec 2017 07:18:00 -0500 Subject: [PATCH 224/272] Correct Twelve Days topics "Twelve Days" is not about polymorphism, nor is it necessarily about regular expressions. I've removed those those two topics from the config. --- config.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config.json b/config.json index ba27724f..b42ecbbc 100644 --- a/config.json +++ b/config.json @@ -1128,10 +1128,8 @@ "topics": [ "Control-flow (conditionals)", "Control-flow (loops)", - "Polymorphism", "Strings", - "Pattern recognition", - "Regular expressions" + "Pattern recognition" ] }, { From 2f511ddb039ca440b71e47d6e6fb497e838a27c3 Mon Sep 17 00:00:00 2001 From: lrq Date: Fri, 29 Dec 2017 01:11:33 +0700 Subject: [PATCH 225/272] Add forth exercise --- config.json | 12 ++ exercises/forth/README.md | 56 ++++++++ exercises/forth/example.js | 66 +++++++++ exercises/forth/forth.spec.js | 259 ++++++++++++++++++++++++++++++++++ 4 files changed, 393 insertions(+) create mode 100644 exercises/forth/README.md create mode 100644 exercises/forth/example.js create mode 100644 exercises/forth/forth.spec.js diff --git a/config.json b/config.json index ba27724f..786a17a9 100644 --- a/config.json +++ b/config.json @@ -1186,6 +1186,18 @@ "pattern_matching", "strings" ] + }, + { + "uuid": "b3dbc935-536e-4910-994d-4a519b511b6a", + "slug": "forth", + "core": false, + "unlocked_by": "saddle-points", + "difficulty": 8, + "topics": [ + "stacks", + "parsing", + "domain_specific_languages" + ] } ], "foregone": [], diff --git a/exercises/forth/README.md b/exercises/forth/README.md new file mode 100644 index 00000000..f5814e3b --- /dev/null +++ b/exercises/forth/README.md @@ -0,0 +1,56 @@ +Implement an evaluator for a very simple subset of Forth. + +[Forth](https://en.wikipedia.org/wiki/Forth_%28programming_language%29) +is a stack-based programming language. Implement a very basic evaluator +for a small subset of Forth. + +Your evaluator has to support the following words: + +- `+`, `-`, `*`, `/` (integer arithmetic) +- `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation) + +Your evaluator also has to support defining new words using the +customary syntax: `: word-name definition ;`. + +To keep things simple the only data type you need to support is signed +integers of at least 16 bits size. + +You should use the following rules for the syntax: a number is a +sequence of one or more (ASCII) digits, a word is a sequence of one or +more letters, digits, symbols or punctuation that is not a number. +(Forth probably uses slightly different rules, but this is close +enough.) + +Words are case-insensitive. + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript/installation + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +Wikipedia +[Stack-oriented programming language](https://en.wikipedia.org/wiki/Stack-oriented_programming_language) +[Forth programming language](https://en.wikipedia.org/wiki/Forth_(programming_language)) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/forth/example.js b/exercises/forth/example.js new file mode 100644 index 00000000..e1bfa34b --- /dev/null +++ b/exercises/forth/example.js @@ -0,0 +1,66 @@ +var Forth = function () { + this.stack = []; + this.commands = Forth.basicCommands(); +}; + +Forth.prototype.evaluate = function (program) { + var words = program.toLowerCase().split(' '); + + for (var t = 0; t < words.length; t++) { + var word = words[t]; + + if (/^-?\d+$/.test(word)) { + // numbers + this.stack.push(Number(word)); + } else if (word === ':') { + // word definition + var semicolon = words.indexOf(';', t); + if (semicolon === -1) throw new Error('Unterminated definition'); + this.defineCommand(words[t + 1], words.slice(t + 2, semicolon).join(' ')); + t = semicolon; + } else { + // commands + var command = this.commands[word]; + if (!command) throw new Error('Unknown command'); + this.performCommand(command); + } + } +}; + +Forth.prototype.defineCommand = function (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) + }; +}; + +Forth.prototype.performCommand = function (command) { + if (command.arity > this.stack.length) throw new Error('Stack empty'); + + var args = this.stack.splice(this.stack.length - command.arity); + var vals = command.execute.apply(this, args); + this.stack.push.apply(this.stack, vals); +}; + +Forth.isKeyword = function (word) { + return word === ':' || word === ';' || /^-?\d+$/.test(word); +}; + +Forth.basicCommands = function () { + return { + '+': { arity: 2, execute: function (a, b) { return [a + b]; } }, + '-': { arity: 2, execute: function (a, b) { return [a - b]; } }, + '*': { arity: 2, execute: function (a, b) { return [a * b]; } }, + '/': { arity: 2, execute: function (a, b) { + if (b === 0) throw new Error('Division by zero'); + return [Math.floor(a / b)]; + } }, + dup: { arity: 1, execute: function (a) { return [a, a]; } }, + drop: { arity: 1, execute: function () {} }, + swap: { arity: 2, execute: function (a, b) { return [b, a]; } }, + over: { arity: 2, execute: function (a, b) { return [a, b, a]; } } + }; +}; + +module.exports = Forth; diff --git a/exercises/forth/forth.spec.js b/exercises/forth/forth.spec.js new file mode 100644 index 00000000..43bcd72a --- /dev/null +++ b/exercises/forth/forth.spec.js @@ -0,0 +1,259 @@ +var Forth = require('./forth'); + +describe('Forth', function () { + var forth; + + beforeEach(function () { + forth = new Forth(); + }); + + describe('parsing and numbers', function () { + it('just pushes numbers onto the stack', function () { + forth.evaluate('1 2 3 4 5'); + expect(forth.stack).toEqual([1, 2, 3, 4, 5]); + }); + xit('pushes negative numbers onto the stack', function () { + forth.evaluate('-1 -2 -3 -4 -5'); + expect(forth.stack).toEqual([-1, -2, -3, -4, -5]); + }); + }); + + describe('addition', function () { + xit('can add two numbers', function () { + forth.evaluate('1 2 +'); + expect(forth.stack).toEqual([3]); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 +'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('+'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('subtraction', function () { + xit('can subtract two numbers', function () { + forth.evaluate('3 4 -'); + expect(forth.stack).toEqual([-1]); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 -'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('-'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('multiplication', function () { + xit('can multiply two numbers', function () { + forth.evaluate('2 4 *'); + expect(forth.stack).toEqual([8]); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 *'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('*'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('division', function () { + xit('can divide two numbers', function () { + forth.evaluate('12 3 /'); + expect(forth.stack).toEqual([4]); + }); + xit('performs integer division', function () { + forth.evaluate('8 3 /'); + expect(forth.stack).toEqual([2]); + }); + xit('errors if dividing by zero', function () { + expect(function () { + forth.evaluate('4 0 /'); + }).toThrow(new Error('Division by zero')); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 /'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('/'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('combined arithmetic', function () { + xit('performs addition and subtraction', function () { + forth.evaluate('1 2 + 4 -'); + expect(forth.stack).toEqual([-1]); + }); + xit('performs multiplication and division', function () { + forth.evaluate('2 4 * 3 /'); + expect(forth.stack).toEqual([2]); + }); + }); + + describe('dup', function () { + xit('copies a value on the stack', function () { + forth.evaluate('1 dup'); + expect(forth.stack).toEqual([1, 1]); + }); + xit('copies the top value on the stack', function () { + forth.evaluate('1 2 dup'); + expect(forth.stack).toEqual([1, 2, 2]); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('dup'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('drop', function () { + xit('removes the top value on the stack if it is the only one', function () { + forth.evaluate('1 drop'); + expect(forth.stack).toEqual([]); + }); + xit('removes the top value on the stack if it is not the only one', function () { + forth.evaluate('1 2 drop'); + expect(forth.stack).toEqual([1]); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('drop'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('swap', function () { + xit('swaps the top two values on the stack if they are the only ones', function () { + forth.evaluate('1 2 swap'); + expect(forth.stack).toEqual([2, 1]); + }); + xit('swaps the top two values on the stack if they are not the only ones', function () { + forth.evaluate('1 2 3 swap'); + expect(forth.stack).toEqual([1, 3, 2]); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 swap'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('swap'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('over', function () { + xit('copies the second element if there are only two', function () { + forth.evaluate('1 2 over'); + expect(forth.stack).toEqual([1, 2, 1]); + }); + xit('copies the second element if there are more than two', function () { + forth.evaluate('1 2 3 over'); + expect(forth.stack).toEqual([1, 2, 3, 2]); + }); + xit('errors if there is only one value on the stack', function () { + expect(function () { + forth.evaluate('1 over'); + }).toThrow(new Error('Stack empty')); + }); + xit('errors if there is nothing on the stack', function () { + expect(function () { + forth.evaluate('over'); + }).toThrow(new Error('Stack empty')); + }); + }); + + describe('user-defined words', function () { + xit('can consist of built-in words', function () { + forth.evaluate(': dup-twice dup dup ;'); + forth.evaluate('1 dup-twice'); + expect(forth.stack).toEqual([1, 1, 1]); + }); + xit('execute in the right order', function () { + forth.evaluate(': countup 1 2 3 ;'); + forth.evaluate('countup'); + expect(forth.stack).toEqual([1, 2, 3]); + }); + xit('can override other user-defined words', function () { + forth.evaluate(': foo dup ;'); + forth.evaluate(': foo dup dup ;'); + forth.evaluate( '1 foo'); + expect(forth.stack).toEqual([1, 1, 1]); + }); + xit('can override built-in words', function () { + forth.evaluate(': swap dup ;'); + forth.evaluate('1 swap'); + expect(forth.stack).toEqual([1, 1]); + }); + xit('can override built-in operators', function () { + forth.evaluate(': + * ;'); + forth.evaluate('3 4 +'); + expect(forth.stack).toEqual([12]); + }); + xit('cannot redefine numbers', function () { + expect(function () { + forth.evaluate(': 1 2 ;'); + }).toThrow(new Error('Invalid definition')); + }); + xit('errors if executing a non-existent word', function () { + expect(function () { + forth.evaluate('foo'); + }).toThrow(new Error('Unknown command')); + }); + xit('only defines words for current instance', function () { + var first = new Forth(); + var second = new Forth(); + first.evaluate(': + - ;'); + first.evaluate('1 1 +'); + second.evaluate('1 1 +'); + expect(first.stack).toEqual([0]); + expect(second.stack).toEqual([2]); + }); + }); + + describe('case-insensitivity', function () { + xit('DUP is case-insensitive', function () { + forth.evaluate('1 DUP Dup dup'); + expect(forth.stack).toEqual([1, 1, 1, 1]); + }); + xit('DROP is case-insensitive', function () { + forth.evaluate('1 2 3 4 DROP Drop drop'); + expect(forth.stack).toEqual([1]); + }); + xit('SWAP is case-insensitive', function () { + forth.evaluate('1 2 SWAP 3 Swap 4 swap'); + expect(forth.stack).toEqual([2, 3, 4, 1]); + }); + xit('OVER is case-insensitive', function () { + forth.evaluate('1 2 OVER Over over'); + expect(forth.stack).toEqual([1, 2, 1, 2, 1]); + }); + xit('user-defined words are case-insensitive', function () { + forth.evaluate(': foo dup ;'); + forth.evaluate('1 FOO Foo foo'); + expect(forth.stack).toEqual([1, 1, 1, 1]); + }); + xit('definitions are case-insensitive', function () { + forth.evaluate(': SWAP DUP Dup dup ;'); + forth.evaluate('1 swap'); + expect(forth.stack).toEqual([1, 1, 1, 1]); + }); + }); +}); From afd6a26df5fa898fea2f086a1eca6f1cc25e25f4 Mon Sep 17 00:00:00 2001 From: danielj-jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Mon, 1 Jan 2018 10:27:10 -0800 Subject: [PATCH 226/272] fix bowling exercise --- .eslintignore | 1 - exercises/bowling/example.js | 34 ++++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/.eslintignore b/.eslintignore index d84af0a0..f33187b9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,7 +2,6 @@ big-integer.js exercises/alphametics exercises/binary-search exercises/binary-search-tree -exercises/bowling exercises/bracket-push exercises/clock exercises/custom-set diff --git a/exercises/bowling/example.js b/exercises/bowling/example.js index 66b204fd..b46142ad 100644 --- a/exercises/bowling/example.js +++ b/exercises/bowling/example.js @@ -5,6 +5,9 @@ function Bowling(rolls) { } Bowling.prototype.score = function () { + var maxFrames = 10; + var maxPins = 10; + var initialState = { frameNumber: 1, rollNumber: 1, @@ -17,7 +20,7 @@ Bowling.prototype.score = function () { }; var finalState = this.rolls.reduce(function (state, roll) { - if (roll < 0 || roll > 10) { + if (roll < 0 || roll > maxFrames ) { throw new Error('Pins must have a value from 0 to 10'); } @@ -25,11 +28,11 @@ Bowling.prototype.score = function () { throw new Error('Pin count exceeds pins on the lane'); } - if (state.frameNumber > 10) { + if (state.frameNumber > maxFrames ) { throw new Error('Should not be able to roll after game is over'); } - var finalFrame = state.frameNumber === 10; + var finalFrame = state.frameNumber === maxFrames; var strike = state.rollNumber === 1 && roll === 10; var spare = state.rollNumber === 2 && roll === state.pinsRemaining; var frameOver = finalFrame @@ -38,17 +41,19 @@ Bowling.prototype.score = function () { var score = state.score + roll; - if (state.strikeLastFrame && state.rollNumber < 3) { score += roll; } - if (state.spareLastFrame && state.rollNumber === 1) { score += roll; } - if (state.twoStrikesInARow && state.rollNumber === 1) { score += roll; } + if (state.strikeLastFrame && state.rollNumber < 3) { score = incrementScore(score, roll); } + if (state.spareLastFrame && state.rollNumber === 1) { score = incrementScore(score, roll); } + if (state.twoStrikesInARow && state.rollNumber === 1) { score = incrementScore(score, roll); } var next = {}; next.frameNumber = frameOver ? state.frameNumber + 1 : state.frameNumber; next.rollNumber = frameOver ? 1 : state.rollNumber + 1; - next.pinsRemaining = finalFrame - ? ((strike || spare) ? 10 : state.pinsRemaining - roll) - : (frameOver ? 10 : state.pinsRemaining - roll); + if ( finalFrame ) { + next.pinsRemaining = (strike || spare) ? maxPins : pinsRemaining(state.pinsRemaining, roll); + } else { + next.pinsRemaining = frameOver ? maxPins : pinsRemaining(state.pinsRemaining, roll); + } next.spareLastFrame = frameOver ? spare : state.spareLastFrame; next.strikeLastFrame = frameOver ? strike : state.strikeLastFrame; next.twoStrikesInARow = frameOver ? strike && state.strikeLastFrame : state.twoStrikesInARow; @@ -58,11 +63,20 @@ Bowling.prototype.score = function () { return next; }, initialState); - if (finalState.frameNumber !== 11) { + if (finalState.frameNumber <= maxFrames ) { throw new Error('Score cannot be taken until the end of the game'); } return finalState.score; }; +function incrementScore(score, roll) { + return score + roll; +} + +function pinsRemaining(pins, roll) { + return pins - roll; +} + + module.exports = Bowling; From 72fe585c2c121277f0d5cfcb45d94e71d0705f94 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Wed, 3 Jan 2018 15:47:10 -0800 Subject: [PATCH 227/272] fix clock exercise (#485) --- .eslintignore | 1 - exercises/clock/example.js | 19 ++++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.eslintignore b/.eslintignore index d84af0a0..716ecfeb 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,7 +4,6 @@ exercises/binary-search exercises/binary-search-tree exercises/bowling exercises/bracket-push -exercises/clock exercises/custom-set exercises/flatten-array exercises/grade-school diff --git a/exercises/clock/example.js b/exercises/clock/example.js index b0260dde..dc69700a 100644 --- a/exercises/clock/example.js +++ b/exercises/clock/example.js @@ -8,15 +8,12 @@ var MILLIS_IN_AN_HOUR = MINUTES_IN_AN_HOUR * MILLIS_IN_A_MINUTE; var MILLIS_IN_A_DAY = HOURS_IN_A_DAY * MILLIS_IN_AN_HOUR; function makePositive(time, maxValue) { - time %= maxValue; - time += maxValue; - return time; + return time % maxValue + maxValue; } -function at(hours, minutes) { - minutes = minutes || 0; - hours = makePositive(hours, HOURS_IN_A_DAY); - minutes = makePositive(minutes, MINUTES_IN_A_DAY); +function at(inputHours, inputMinutes) { + var minutes = makePositive(inputMinutes || 0, MINUTES_IN_A_DAY); + var hours = makePositive(inputHours, HOURS_IN_A_DAY); var clock = {}; var value = (hours * MILLIS_IN_AN_HOUR) + (minutes * MILLIS_IN_A_MINUTE); @@ -31,13 +28,13 @@ function at(hours, minutes) { return time[0] + ':' + time[1]; }; - clock.plus = function (minutes) { - value += minutes * MILLIS_IN_A_MINUTE; + clock.plus = function (addMinutes) { + value += addMinutes * MILLIS_IN_A_MINUTE; return clock; }; - clock.minus = function (minutes) { - value -= minutes * MILLIS_IN_A_MINUTE; + clock.minus = function (subMinutes) { + value -= subMinutes * MILLIS_IN_A_MINUTE; return clock; }; From afdaa911b00e1ddfab78018117f712a19942086a Mon Sep 17 00:00:00 2001 From: Sam Warner <30871823+sjwarner-bp@users.noreply.github.com> Date: Thu, 4 Jan 2018 12:20:49 +0000 Subject: [PATCH 228/272] readme: add gitter badge (#487) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6c52fb4..6001444c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# JavaScript [![Build Status](https://travis-ci.org/exercism/javascript.svg?branch=master)](https://travis-ci.org/exercism/javascript) +# JavaScript [![Build Status](https://travis-ci.org/exercism/javascript.svg?branch=master)](https://travis-ci.org/exercism/javascript)[![Join the chat at https://gitter.im/exercism/xecmascript](https://badges.gitter.im/exercism/xecmascript.svg)](https://gitter.im/exercism/xecmascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Exercism exercises in JavaScript From e00be74af672e21df2b4c949cfd19b67463aa470 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Sun, 7 Jan 2018 19:17:06 -0800 Subject: [PATCH 229/272] fix palindrome products exercise (#484) --- .eslintignore | 1 - exercises/palindrome-products/example.js | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index 592968ec..e3e9691a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -15,7 +15,6 @@ exercises/list-ops exercises/luhn exercises/minesweeper exercises/nth-prime -exercises/palindrome-products exercises/perfect-numbers exercises/pythagorean-triplet exercises/queen-attack diff --git a/exercises/palindrome-products/example.js b/exercises/palindrome-products/example.js index 5928bdb2..ab242849 100644 --- a/exercises/palindrome-products/example.js +++ b/exercises/palindrome-products/example.js @@ -14,16 +14,16 @@ module.exports = function Palindromes(options) { for (var i = minFactor; i <= maxFactor; i++) { for (var j = minFactor; j <= maxFactor; j++) { var result = i * j; - if ( ! this.isPalindrome(result) ) { continue; } + if (!this.isPalindrome(result)) { continue; } var newFactor = [i, j].sort(); - if (palindromes[result] === undefined) { + if (!Array.isArray(palindromes[result])) { palindromes[result] = []; palindromeIndexes.push(result); } - if ( ! arrayContainsArray(palindromes[result], newFactor) ) { + if (!arrayContainsArray(palindromes[result], newFactor)) { palindromes[result].push(newFactor); } } From a5f9807a898f117d34879858baef0701c070f2ed Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 14 Jan 2018 16:23:03 -0700 Subject: [PATCH 230/272] Inline exercise README insert into README template Since none of the exercises override the README template we don't need to keep the README insert in a separate location. This simplifies things somewhat. --- config/exercise_readme.go.tmpl | 27 +++++++++++++++++++++++---- docs/EXERCISE_README_INSERT.md | 22 ---------------------- 2 files changed, 23 insertions(+), 26 deletions(-) delete mode 100644 docs/EXERCISE_README_INSERT.md diff --git a/config/exercise_readme.go.tmpl b/config/exercise_readme.go.tmpl index 2b26f494..a7dc04c3 100644 --- a/config/exercise_readme.go.tmpl +++ b/config/exercise_readme.go.tmpl @@ -4,10 +4,29 @@ {{- with .Hints }} {{ . }} {{ end }} -{{- with .TrackInsert }} -{{ . }} -{{ end }} -{{- with .Spec.Credits -}} +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. +{{ with .Spec.Credits }} ## Source {{ . }} diff --git a/docs/EXERCISE_README_INSERT.md b/docs/EXERCISE_README_INSERT.md deleted file mode 100644 index 00fd308e..00000000 --- a/docs/EXERCISE_README_INSERT.md +++ /dev/null @@ -1,22 +0,0 @@ -## Setup - -Go through the setup instructions for JavaScript to -install the necessary dependencies: - -http://exercism.io/languages/javascript - -## Making the Test Suite Pass - -Execute the tests with: - - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: - - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. From 1babcedf8e000c4f50c5085cff7457205eb7bf8b Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 14 Jan 2018 16:38:32 -0700 Subject: [PATCH 231/272] Tweak exercise README template for clarity --- config/exercise_readme.go.tmpl | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/config/exercise_readme.go.tmpl b/config/exercise_readme.go.tmpl index a7dc04c3..730bb47c 100644 --- a/config/exercise_readme.go.tmpl +++ b/config/exercise_readme.go.tmpl @@ -6,26 +6,29 @@ {{ end }} ## 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: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine {{ .Spec.Slug }}.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. {{ with .Spec.Credits }} ## Source From 972c930c50f4870f735a11d2eee8f5d9cd9df1b2 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 14 Jan 2018 16:39:01 -0700 Subject: [PATCH 232/272] Regenerate all the exercise READMEs --- exercises/accumulate/README.md | 32 ++++----- exercises/acronym/README.md | 28 ++++---- exercises/all-your-base/README.md | 30 ++++---- exercises/allergies/README.md | 28 ++++---- exercises/alphametics/README.md | 32 +++++---- exercises/anagram/README.md | 27 ++++---- exercises/atbash-cipher/README.md | 30 ++++---- exercises/beer-song/README.md | 31 +++++---- exercises/binary-search-tree/README.md | 27 ++++---- exercises/binary-search/README.md | 27 ++++---- exercises/binary/README.md | 29 ++++---- exercises/bob/README.md | 29 ++++---- exercises/bowling/README.md | 59 ++++++++++------ exercises/bracket-push/README.md | 27 ++++---- exercises/change/README.md | 48 ++++++++----- exercises/circular-buffer/README.md | 46 ++++++++----- exercises/clock/README.md | 27 ++++---- exercises/collatz-conjecture/README.md | 27 ++++---- exercises/connect/README.md | 33 ++++----- exercises/crypto-square/README.md | 45 ++++++------ exercises/custom-set/README.md | 28 ++++---- exercises/diamond/README.md | 39 ++++++----- exercises/difference-of-squares/README.md | 29 ++++---- exercises/diffie-hellman/README.md | 32 ++++----- exercises/etl/README.md | 31 +++++---- exercises/flatten-array/README.md | 30 ++++---- exercises/food-chain/README.md | 29 ++++---- exercises/forth/README.md | 35 +++++----- exercises/gigasecond/README.md | 27 ++++---- exercises/grade-school/README.md | 28 ++++---- exercises/grains/README.md | 28 ++++---- exercises/hamming/README.md | 27 ++++---- exercises/hello-world/README.md | 27 ++++---- exercises/hexadecimal/README.md | 27 ++++---- exercises/isbn-verifier/README.md | 80 ++++++++++++---------- exercises/isogram/README.md | 30 ++++---- exercises/kindergarten-garden/README.md | 53 +++++++------- exercises/largest-series-product/README.md | 27 ++++---- exercises/leap/README.md | 29 ++++---- exercises/linked-list/README.md | 47 +++++++------ exercises/list-ops/README.md | 28 ++++---- exercises/luhn/README.md | 41 ++++++----- exercises/matrix/README.md | 37 +++++----- exercises/meetup/README.md | 56 ++++++++------- exercises/minesweeper/README.md | 28 ++++---- exercises/nth-prime/README.md | 27 ++++---- exercises/nucleotide-count/README.md | 57 +++++++-------- exercises/ocr-numbers/README.md | 39 ++++++----- exercises/octal/README.md | 35 ++++++---- exercises/palindrome-products/README.md | 56 +++++++-------- exercises/pangram/README.md | 29 ++++---- exercises/pascals-triangle/README.md | 31 +++++---- exercises/perfect-numbers/README.md | 31 +++++---- exercises/phone-number/README.md | 34 +++++---- exercises/pig-latin/README.md | 27 ++++---- exercises/point-mutations/README.md | 27 ++++---- exercises/prime-factors/README.md | 27 ++++---- exercises/protein-translation/README.md | 36 +++++----- exercises/proverb/README.md | 50 ++++++++------ exercises/pythagorean-triplet/README.md | 33 +++++---- exercises/queen-attack/README.md | 29 ++++---- exercises/raindrops/README.md | 27 ++++---- exercises/reverse-string/README.md | 34 +++++---- exercises/rna-transcription/README.md | 29 ++++---- exercises/robot-name/README.md | 27 ++++---- exercises/robot-simulator/README.md | 27 ++++---- exercises/roman-numerals/README.md | 29 ++++---- exercises/run-length-encoding/README.md | 35 +++++----- exercises/saddle-points/README.md | 29 ++++---- exercises/say/README.md | 27 ++++---- exercises/scrabble-score/README.md | 31 +++++---- exercises/secret-handshake/README.md | 29 ++++---- exercises/series/README.md | 27 ++++---- exercises/sieve/README.md | 27 ++++---- exercises/simple-cipher/README.md | 37 +++++----- exercises/simple-linked-list/README.md | 27 ++++---- exercises/space-age/README.md | 29 ++++---- exercises/strain/README.md | 27 ++++---- exercises/sublist/README.md | 31 ++++----- exercises/sum-of-multiples/README.md | 38 +++++----- exercises/transpose/README.md | 27 ++++---- exercises/triangle/README.md | 42 +++++++----- exercises/trinary/README.md | 29 ++++---- exercises/twelve-days/README.md | 33 ++++----- exercises/two-bucket/README.md | 47 +++++++------ exercises/two-fer/README.md | 33 +++++---- exercises/word-count/README.md | 30 ++++---- exercises/wordy/README.md | 32 ++++----- exercises/zipper/README.md | 38 +++++----- 89 files changed, 1629 insertions(+), 1352 deletions(-) diff --git a/exercises/accumulate/README.md b/exercises/accumulate/README.md index 1f8e999f..0588b985 100644 --- a/exercises/accumulate/README.md +++ b/exercises/accumulate/README.md @@ -25,31 +25,31 @@ Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead. -Lisp specific: it's perfectly fine to use `MAPCAR` or the equivalent, -as this is idiomatic Lisp, not a library function. - ## Setup -Go through the setup instructions for JavaScript to -install the necessary dependencies: - -http://exercism.io/languages/javascript +Go through the setup instructions for JavaScript to install the + necessary dependencies: -## Making the Test Suite Pass +http://exercism.io/languages/javascript/installation -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine accumulate.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/acronym/README.md b/exercises/acronym/README.md index cfb380f8..8fefa5b9 100644 --- a/exercises/acronym/README.md +++ b/exercises/acronym/README.md @@ -7,29 +7,31 @@ Techies love their TLA (Three Letter Acronyms)! Help generate some jargon by writing a program that converts a long name like Portable Network Graphics to its acronym (PNG). - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine acronym.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/all-your-base/README.md b/exercises/all-your-base/README.md index d6628a9c..d18b0258 100644 --- a/exercises/all-your-base/README.md +++ b/exercises/all-your-base/README.md @@ -6,6 +6,7 @@ Implement general base conversion. Given a number in base **a**, represented as a sequence of digits, convert it to base **b**. ## Note + - Try to implement the conversion yourself. Do not use something else to perform the conversion for you. @@ -28,32 +29,33 @@ The number 1120, *in base 3*, means: I think you got the idea! - *Yes. Those three numbers above are exactly the same. Congratulations!* ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: - - jasmine .spec.js +## Running the test suite -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine hello-world.spec.js +```sh +npm install -g jasmine +``` -In many test suites all but the first test have been skipped. +Run the test suite from the exercise directory with: -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine all-your-base.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/allergies/README.md b/exercises/allergies/README.md index 89046315..179a7f58 100644 --- a/exercises/allergies/README.md +++ b/exercises/allergies/README.md @@ -29,29 +29,31 @@ allergens that score 256, 512, 1024, etc.). Your program should ignore those components of the score. For example, if the allergy score is 257, your program should only report the eggs (1) allergy. - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine allergies.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/alphametics/README.md b/exercises/alphametics/README.md index d34850b4..bc3ff2ec 100644 --- a/exercises/alphametics/README.md +++ b/exercises/alphametics/README.md @@ -7,7 +7,7 @@ letters in words are replaced with numbers. For example `SEND + MORE = MONEY`: -``` +```text S E N D M O R E + ----------- @@ -16,7 +16,7 @@ M O N E Y Replacing these with valid numbers gives: -``` +```text 9 5 6 7 1 0 8 5 + ----------- @@ -33,27 +33,29 @@ Write a function to solve alphametics puzzles. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: - - jasmine hello-world.spec.js +```sh +npm install -g jasmine +``` -In many test suites all but the first test have been skipped. +Run the test suite from the exercise directory with: -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine alphametics.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/anagram/README.md b/exercises/anagram/README.md index 3d99a0e6..9473855e 100644 --- a/exercises/anagram/README.md +++ b/exercises/anagram/README.md @@ -8,26 +8,29 @@ Given `"listen"` and a list of candidates like `"enlists" "google" ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine anagram.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/atbash-cipher/README.md b/exercises/atbash-cipher/README.md index d9d602b1..a34b50ab 100644 --- a/exercises/atbash-cipher/README.md +++ b/exercises/atbash-cipher/README.md @@ -9,7 +9,7 @@ letter, the second with the second-last, and so on. An Atbash cipher for the Latin alphabet would be as follows: -```plain +```text Plain: abcdefghijklmnopqrstuvwxyz Cipher: zyxwvutsrqponmlkjihgfedcba ``` @@ -23,32 +23,36 @@ being 5 letters, and punctuation is excluded. This is to make it harder to guess things based on word boundaries. ## Examples + - Encoding `test` gives `gvhg` - Decoding `gvhg` gives `test` - Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog` ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine atbash-cipher.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/beer-song/README.md b/exercises/beer-song/README.md index 490f7b52..ffd71e31 100644 --- a/exercises/beer-song/README.md +++ b/exercises/beer-song/README.md @@ -1,10 +1,10 @@ # Beer Song -Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall. +Recite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall. Note that not all verses are identical. -```plain +```text 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. @@ -322,26 +322,29 @@ experiment make the code better? Worse? Did you learn anything from it? ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine beer-song.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md index 5a2648eb..798ea8f2 100644 --- a/exercises/binary-search-tree/README.md +++ b/exercises/binary-search-tree/README.md @@ -55,26 +55,29 @@ And if we then added 1, 5, and 7, it would look like this ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine binary-search-tree.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/binary-search/README.md b/exercises/binary-search/README.md index a83868eb..c3f4cb4c 100644 --- a/exercises/binary-search/README.md +++ b/exercises/binary-search/README.md @@ -36,26 +36,29 @@ A binary search is a dichotomic divide and conquer search algorithm. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine binary-search.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/binary/README.md b/exercises/binary/README.md index 9183cd4b..363c47bd 100644 --- a/exercises/binary/README.md +++ b/exercises/binary/README.md @@ -7,10 +7,12 @@ string, your program should produce a decimal output. The program should handle invalid inputs. ## Note + - Implement the conversion yourself. Do not use something else to perform the conversion for you. ## About Binary (Base-2) + Decimal is a base-10 system. A number 23 in base 10 notation can be understood @@ -30,26 +32,29 @@ So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine binary.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/bob/README.md b/exercises/bob/README.md index d26c8d06..ee9c8adb 100644 --- a/exercises/bob/README.md +++ b/exercises/bob/README.md @@ -6,6 +6,8 @@ Bob answers 'Sure.' if you ask him a question. He answers 'Whoa, chill out!' if you yell 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. @@ -13,26 +15,29 @@ He answers 'Whatever.' to anything else. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine bob.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/bowling/README.md b/exercises/bowling/README.md index f766eeb4..d1d52f8d 100644 --- a/exercises/bowling/README.md +++ b/exercises/bowling/README.md @@ -2,21 +2,31 @@ Score a bowling game. -Bowling is game where players roll a heavy ball to knock down pins +Bowling is a game where players roll a heavy ball to knock down pins arranged in a triangle. Write code to keep track of the score of a game of bowling. ## Scoring Bowling -A game consists of 10 frames. A frame is composed of one or two balls thrown, with 10 pins standing at the start of the frame. There are three cases for the tabulation of a frame: +The game consists of 10 frames. A frame is composed of one or two ball +throws with 10 pins standing at frame initialization. There are three +cases for the tabulation of a frame. -* An open frame is where a score of less than 10 is recorded for the frame. In this case the score for the frame is the number of pins knocked down after the second throw. +* An open frame is where a score of less than 10 is recorded for the + frame. In this case the score for the frame is the number of pins + knocked down. -* A spare is where all 10 pins are knocked down after the second throw. The total value of a spare is 10 plus the number of pins knocked down in the next throw. +* A spare is where all ten pins are knocked down by the second + throw. The total value of a spare is 10 plus the number of pins + knocked down in their next throw. -* A strike is where all 10 pins are knocked down after the first throw. The total value of a strike is 10 plus the number of pins knocked down in the next two throws. If a strike is immediately followed by another strike, then the first strike's value cannot be totalled until the next throw. +* A strike is where all ten pins are knocked down by the first + throw. The total value of a strike is 10 plus the number of pins + knocked down in the next two throws. If a strike is immediately + followed by a second strike, then the value of the first strike + cannot be determined until the ball is thrown one more time. -Here is a three-frame example: +Here is a three frame example: | Frame 1 | Frame 2 | Frame 3 | | :-------------: |:-------------:| :---------------------:| @@ -30,11 +40,15 @@ Frame 3 is (9 + 0) = 9 This means the current running total is 48. -The 10th frame in the game is a special case. If the player throws a strike or a spare, then they get one extra throw called a fill ball. Fill balls exist to calculate the total of the 10th frame. Scoring a strike or spare on the fill ball does not give the player more fill balls. The total value of the 10th frame is the total number of pins knocked down. +The tenth frame in the game is a special case. If someone throws a +strike or a spare then they get a fill ball. Fill balls exist to +calculate the total of the 10th frame. Scoring a strike or spare on +the fill ball does not give the player more fill balls. The total +value of the 10th frame is the total number of pins knocked down. -For a 10th frame of X1/ (strike and a spare), the total value is 20. +For a tenth frame of X1/ (strike and a spare), the total value is 20. -For a 10th frame of XXX (three strikes), the total value is 30. +For a tenth frame of XXX (three strikes), the total value is 30. ## Requirements @@ -48,26 +62,29 @@ support two operations: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine bowling.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/bracket-push/README.md b/exercises/bracket-push/README.md index d4c8ffee..66c336ef 100644 --- a/exercises/bracket-push/README.md +++ b/exercises/bracket-push/README.md @@ -5,26 +5,29 @@ verify that all the pairs are matched and nested correctly. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine bracket-push.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/change/README.md b/exercises/change/README.md index 397a10d3..282186fe 100644 --- a/exercises/change/README.md +++ b/exercises/change/README.md @@ -1,36 +1,50 @@ # Change -Correctly determine the change to be given using the least number of coins. +Correctly determine the fewest number of coins to be given to a customer such +that the sum of the coins' value would equal the correct amount of change. -The solution will need to accept a value of change to be given and an array of -coin denominations. The program returns the array of coin denominations to -produce the correct amount of change. For example, if change for 37 cents -is required from coins with the denominations of 1, 5, 10 and 25 then the -result is an array with the values: 1, 1, 10 and 25. +## For example + +- An input of 15 with [1, 5, 10, 25, 100] should return one nickel (5) + and one dime (10) or [0, 1, 1, 0, 0] +- An input of 40 with [1, 5, 10, 25, 100] should return one nickel (5) + and one dime (10) and one quarter (25) or [0, 1, 1, 1, 0] + +## Edge cases + +- Does your algorithm work for any given set of coins? +- Can you ask for negative change? +- Can you ask for a change value smaller than the smallest coin value? ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine change.spec.js +``` -In many test suites all but the first test have been skipped. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +## Source +Software Craftsmanship - Coin Change Kata [https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata](https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata) ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/circular-buffer/README.md b/exercises/circular-buffer/README.md index b2c73837..85243a97 100644 --- a/exercises/circular-buffer/README.md +++ b/exercises/circular-buffer/README.md @@ -31,40 +31,50 @@ If the buffer has 7 elements then it is completely full: When the buffer is full an error will be raised, alerting the client that further writes are blocked until a slot becomes free. -The client can opt to overwrite the oldest data with a forced write. In -this case, two more elements — A & B — are added and they overwrite the -3 & 4: +When the buffer is full, the client can opt to overwrite the oldest +data with a forced write. In this case, two more elements — A & B — +are added and they overwrite the 3 & 4: [6][7][8][9][A][B][5] -Finally, if two elements are now removed then what would be returned is -not 3 & 4 but 5 & 6 because A & B overwrote the 3 & the 4 yielding the -buffer with: +3 & 4 have been replaced by A & B making 5 now the oldest data in the +buffer. Finally, if two elements are removed then what would be +returned is 5 & 6 yielding the buffer: [ ][7][8][9][A][B][ ] +Because there is space available, if the client again uses overwrite +to store C & D then the space where 5 & 6 were stored previously will +be used not the location of 7 & 8. 7 is still the oldest element and +the buffer is once again full. + + [D][7][8][9][A][B][C] + ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine circular-buffer.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/clock/README.md b/exercises/clock/README.md index 5637488c..9fdc3811 100644 --- a/exercises/clock/README.md +++ b/exercises/clock/README.md @@ -8,26 +8,29 @@ Two clocks that represent the same time should be equal to each other. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine clock.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/collatz-conjecture/README.md b/exercises/collatz-conjecture/README.md index 7bec9e1a..f4dcfa8e 100644 --- a/exercises/collatz-conjecture/README.md +++ b/exercises/collatz-conjecture/README.md @@ -28,26 +28,29 @@ Resulting in 9 steps. So for input n = 12, the return value would be 9. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine collatz-conjecture.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/connect/README.md b/exercises/connect/README.md index 035a100a..8e711f2b 100644 --- a/exercises/connect/README.md +++ b/exercises/connect/README.md @@ -18,7 +18,7 @@ computes the winner (or lack thereof). Note that all games need not be "fair". The boards look like this (with spaces added for readability, which won't be in the representation passed to your code): -``` +```text . O . X . . X X O . O O O X . @@ -32,28 +32,29 @@ won since `O` didn't connect top and bottom. ## 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: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation -## Making the test suite pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: - - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. +```sh +npm install -g jasmine +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +Run the test suite from the exercise directory with: +```sh +jasmine connect.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/crypto-square/README.md b/exercises/crypto-square/README.md index fa464ca5..9fbbe98f 100644 --- a/exercises/crypto-square/README.md +++ b/exercises/crypto-square/README.md @@ -26,7 +26,7 @@ and `r` is the number of rows. Our normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`: -```plain +```text ifmanwas meanttos tayonthe @@ -41,22 +41,24 @@ right. The message above is coded as: -```plain +```text imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau ``` -Output the encoded text in chunks. Phrases that fill perfect squares -`(r X r)` should be output in `r`-length chunks separated by spaces. -Imperfect squares will have `n` empty spaces. Those spaces should be distributed evenly across the last `n` rows. +Output the encoded text in chunks. Phrases that fill perfect rectangles +`(r X c)` should be output `c` chunks of `r` length, separated by spaces. +Phrases that do not fill perfect rectangles will have `n` empty spaces. +Those spaces should be distributed evenly, added to the end of the last +`n` chunks. -```plain -imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau +```text +imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau ``` Notice that were we to stack these, we could visually decode the cyphertext back in to the original message: -```plain +```text imtgdvs fearwer mayoogo @@ -69,26 +71,29 @@ sseoau ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine crypto-square.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/custom-set/README.md b/exercises/custom-set/README.md index 4c5c5d81..9635f1e0 100644 --- a/exercises/custom-set/README.md +++ b/exercises/custom-set/README.md @@ -9,27 +9,29 @@ unique elements. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine custom-set.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/diamond/README.md b/exercises/diamond/README.md index 606d7dda..7ba94abd 100644 --- a/exercises/diamond/README.md +++ b/exercises/diamond/README.md @@ -1,7 +1,7 @@ # Diamond -The diamond kata takes as its input a letter, and outputs it in a diamond -shape. Given a letter, it prints a diamond starting with 'A', with the +The diamond kata takes as its input a letter, and outputs it in a diamond +shape. Given a letter, it prints a diamond starting with 'A', with the supplied letter at the widest point. ## Requirements @@ -15,7 +15,7 @@ supplied letter at the widest point. * The diamond has a square shape (width equals height). * The letters form a diamond shape. * The top half has the letters in ascending order. -* The bottom half has the letters in descending order. +* The bottom half has the letters in descending order. * The four corners (containing the spaces) are triangles. ## Examples @@ -24,13 +24,13 @@ In the following examples, spaces are indicated by `·` characters. Diamond for letter 'A': -```plain +```text A ``` Diamond for letter 'C': -```plain +```text ··A·· ·B·B· C···C @@ -40,7 +40,7 @@ C···C Diamond for letter 'E': -```plain +```text ····A···· ···B·B··· ··C···C·· @@ -54,26 +54,29 @@ E·······E ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine diamond.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/difference-of-squares/README.md b/exercises/difference-of-squares/README.md index 1377b5f9..5c181acf 100644 --- a/exercises/difference-of-squares/README.md +++ b/exercises/difference-of-squares/README.md @@ -1,4 +1,4 @@ -# Difference of Squares +# Difference Of Squares Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. @@ -14,26 +14,29 @@ natural numbers is 3025 - 385 = 2640. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine difference-of-squares.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/diffie-hellman/README.md b/exercises/diffie-hellman/README.md index 5d72a84e..f04f3c27 100644 --- a/exercises/diffie-hellman/README.md +++ b/exercises/diffie-hellman/README.md @@ -39,31 +39,29 @@ secret s. ## 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: http://exercism.io/languages/javascript/installation -## Requirements +## Running the test suite +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: +```sh +npm install -g jasmine +``` -## Making the test suite pass +Run the test suite from the exercise directory with: -Execute the tests with: - - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: - - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine diffie-hellman.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/etl/README.md b/exercises/etl/README.md index 218aaeb3..fad82d79 100644 --- a/exercises/etl/README.md +++ b/exercises/etl/README.md @@ -1,8 +1,9 @@ -# Etl +# ETL We are going to do the `Transform` step of an Extract-Transform-Load. ### ETL + Extract-Transform-Load (ETL) is a fancy way of saying, "We have some crufty, legacy data over in this system, and now we need it in this shiny new system over here, so we're going to migrate this." @@ -11,6 +12,7 @@ once." That's then typically followed by much forehead slapping and moaning about how stupid we could possibly be.) ### The goal + We're going to extract some scrabble scores from a legacy system. The old system stored a list of letters per score: @@ -46,26 +48,29 @@ game while being scored at 4 in the Hawaiian-language version. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine etl.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/flatten-array/README.md b/exercises/flatten-array/README.md index d76bb103..2a98a300 100644 --- a/exercises/flatten-array/README.md +++ b/exercises/flatten-array/README.md @@ -3,36 +3,38 @@ Take a nested list and return a single flattened list with all values except nil/null. The challenge is to write a function that accepts an arbitrarily-deep nested list-like structure and returns a flattened structure without any nil/null values. - + For Example input: [1,[2,3,null,4],[null],5] output: [1,2,3,4,5] - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine flatten-array.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/food-chain/README.md b/exercises/food-chain/README.md index cc3874ef..1f1cf16a 100644 --- a/exercises/food-chain/README.md +++ b/exercises/food-chain/README.md @@ -10,7 +10,7 @@ This is a [cumulative song](http://en.wikipedia.org/wiki/Cumulative_song) of unk This is one of many common variants. -```plain +```text I know an old lady who swallowed a fly. I don't know why she swallowed the fly. Perhaps she'll die. @@ -65,26 +65,29 @@ She's dead, of course! ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine food-chain.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/forth/README.md b/exercises/forth/README.md index f5814e3b..2c42e805 100644 --- a/exercises/forth/README.md +++ b/exercises/forth/README.md @@ -1,3 +1,5 @@ +# Forth + Implement an evaluator for a very simple subset of Forth. [Forth](https://en.wikipedia.org/wiki/Forth_%28programming_language%29) @@ -25,32 +27,29 @@ Words are case-insensitive. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: - - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +## Running the test suite - jasmine hello-world.spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -In many test suites all but the first test have been skipped. +```sh +npm install -g jasmine +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +Run the test suite from the exercise directory with: -## Source +```sh +jasmine forth.spec.js +``` -Wikipedia -[Stack-oriented programming language](https://en.wikipedia.org/wiki/Stack-oriented_programming_language) -[Forth programming language](https://en.wikipedia.org/wiki/Forth_(programming_language)) +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/gigasecond/README.md b/exercises/gigasecond/README.md index ad46af02..0bcf1777 100644 --- a/exercises/gigasecond/README.md +++ b/exercises/gigasecond/README.md @@ -6,26 +6,29 @@ A gigasecond is 10^9 (1,000,000,000) seconds. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine gigasecond.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/grade-school/README.md b/exercises/grade-school/README.md index ac8cda81..e9d6156a 100644 --- a/exercises/grade-school/README.md +++ b/exercises/grade-school/README.md @@ -21,7 +21,6 @@ In the end, you should be able to: Note that all our students only have one name. (It's a small town, what do you want?) - ## For bonus points Did you get the tests passing and the code clean? If you want to, these @@ -37,26 +36,29 @@ experiment make the code better? Worse? Did you learn anything from it? ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine grade-school.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/grains/README.md b/exercises/grains/README.md index 21a9717f..f5600499 100644 --- a/exercises/grains/README.md +++ b/exercises/grains/README.md @@ -15,7 +15,6 @@ Write code that shows: - how many grains were on each square, and - the total number of grains - ## For bonus points Did you get the tests passing and the code clean? If you want to, these @@ -29,26 +28,29 @@ experiment make the code better? Worse? Did you learn anything from it? ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine grains.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/hamming/README.md b/exercises/hamming/README.md index 1c91a23b..dcfd4d5b 100644 --- a/exercises/hamming/README.md +++ b/exercises/hamming/README.md @@ -37,26 +37,29 @@ of equal length differently. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine hamming.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/hello-world/README.md b/exercises/hello-world/README.md index 2ea80dec..3a36a6bd 100644 --- a/exercises/hello-world/README.md +++ b/exercises/hello-world/README.md @@ -103,26 +103,29 @@ When you are done, submit your solution to exercism: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. +```sh +jasmine hello-world.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/hexadecimal/README.md b/exercises/hexadecimal/README.md index fd75f926..06e409dd 100644 --- a/exercises/hexadecimal/README.md +++ b/exercises/hexadecimal/README.md @@ -9,26 +9,29 @@ The program should handle invalid hexadecimal strings. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine hexadecimal.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/isbn-verifier/README.md b/exercises/isbn-verifier/README.md index a5260312..da1dbccf 100644 --- a/exercises/isbn-verifier/README.md +++ b/exercises/isbn-verifier/README.md @@ -1,66 +1,74 @@ -# ISBN Verifier +# Isbn Verifier -Check if a given ISBN-10 is valid. +The [ISBN-10 verification process](https://en.wikipedia.org/wiki/International_Standard_Book_Number) is used to validate book identification +numbers. These normally contain dashes and look like: `3-598-21508-8` -## Functionality +## ISBN -Given an unknown string the program should check if the provided string is a valid ISBN-10. -Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. +The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only). In the case the check character is an X, this represents the value '10'. These may be communicated with or without hyphens, and can be checked for their validity by the following formula: -The program should allow for ISBN-10 without the separating dashes to be verified as well. +``` +(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0 +``` -## ISBN +If the result is 0, then it is a valid ISBN-10, otherwise it is invalid. -Let's take a random ISBN-10 number, say `3-598-21508-8` for this. -The first digit block indicates the group where the ISBN belongs. Groups can consist of shared languages, geographic regions or countries. The leading '3' signals this ISBN is from a german speaking country. -The following number block is to identify the publisher. Since this is a three digit publisher number there is a 5 digit title number for this book. -The last digit in the ISBN is the check digit which is used to detect read errors. +## Example -The first 9 digits in the ISBN have to be between 0 and 9. -The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well. +Let's take the ISBN-10 `3-598-21508-8`. We plug it in to the formula, and get: +``` +(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0 +``` -A valid ISBN-10 is calculated with this formula `(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0` -So for our example ISBN this means: -(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0 +Since the result is 0, this proves that our ISBN is valid. -Which proves that the ISBN is valid. +## Task -## Setup +Given a string the program should check if the provided string is a valid ISBN-10. +Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN. + +The program should be able to verify ISBN-10 both with and without separating dashes. -Go through the setup instructions for JavaScript to -install the necessary dependencies: -http://exercism.io/languages/javascript +## Caveats -## Making the Test Suite Pass +Converting from strings to numbers can be tricky in certain languages. +Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10'). For instance `3-598-21507-X` is a valid ISBN-10. -Execute the tests with: +## Bonus tasks - jasmine .spec.js +* Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier). -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +* Generate valid ISBN, maybe even from a given starting ISBN. +## Setup - jasmine hello-world.spec.js +Go through the setup instructions for JavaScript to install the + necessary dependencies: -In many test suites all but the first test have been skipped. +http://exercism.io/languages/javascript/installation -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +## Running the test suite -### Submitting Exercises +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Note that, when trying to submit an exercise, make sure the solution is in the `exercism/javascript/` directory. +```sh +npm install -g jasmine +``` -For example, if you're submitting `bob.js` for the Bob exercise, the submit command would be something like `exercism submit /javascript/bob/bob.js`. +Run the test suite from the exercise directory with: +```sh +jasmine isbn-verifier.spec.js +``` -For more detailed information about running tests, code style and linting, -please see the [help page](http://exercism.io/languages/javascript). +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source -Converting a string into a number and some basic processing utilizing a relatable real world example. [https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation](https://en.wikipedia.org/wiki/International_Standard_Book_Number) +Converting a string into a number and some basic processing utilizing a relatable real world example. [https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation](https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation) ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/isogram/README.md b/exercises/isogram/README.md index 47b1fa2a..0b5ef9eb 100644 --- a/exercises/isogram/README.md +++ b/exercises/isogram/README.md @@ -2,38 +2,42 @@ Determine if a word or phrase is an isogram. -An isogram (also known as a "nonpattern word") is a word or phrase without a repeating letter. +An isogram (also known as a "nonpattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times. Examples of isograms: - lumberjacks - background - downstream +- six-year-old The word *isograms*, however, is not an isogram, because the s repeats. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine isogram.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/kindergarten-garden/README.md b/exercises/kindergarten-garden/README.md index 508dd181..515ef3af 100644 --- a/exercises/kindergarten-garden/README.md +++ b/exercises/kindergarten-garden/README.md @@ -3,19 +3,19 @@ Given a diagram, determine which plants each child in the kindergarten class is responsible for. -The kindergarten class is learning about growing plants. The teachers +The kindergarten class is learning about growing plants. The teacher thought it would be a good idea to give them actual seeds, plant them in actual dirt, and grow actual plants. They've chosen to grow grass, clover, radishes, and violets. -To this end, they've put little styrofoam cups along the window sills, -and planted one type of plant in each cup, choosing randomly from the -available types of seeds. +To this end, the children have put little cups along the window sills, and +planted one type of plant in each cup, choosing randomly from the available +types of seeds. -```plain +```text [window][window][window] -........................ # each dot represents a styrofoam cup +........................ # each dot represents a cup ........................ ``` @@ -25,27 +25,27 @@ There are 12 children in the class: - Eve, Fred, Ginny, Harriet, - Ileana, Joseph, Kincaid, and Larry. -Each child gets 4 cups, two on each row. The children are assigned to -cups in alphabetical order. +Each child gets 4 cups, two on each row. Their teacher assigns cups to +the children alphabetically by their names. The following diagram represents Alice's plants: -```plain +```text [window][window][window] VR...................... RG...................... ``` -So in the row nearest the window, she has a violet and a radish; in the -row behind that, she has a radish and some grass. +In the first row, nearest the windows, she has a violet and a radish. In the +second row she has a radish and some grass. Your program will be given the plants from left-to-right starting with the row nearest the windows. From this, it should be able to determine -which plants belong to which students. +which plants belong to each student. For example, if it's told that the garden looks like so: -```plain +```text [window][window][window] VRCGVVRVCGGCCGVRGCVCGCGV VRCCCGCRRGVCGCRVVCVGCGCV @@ -61,26 +61,29 @@ While asking for Bob's plants would yield: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine kindergarten-garden.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/largest-series-product/README.md b/exercises/largest-series-product/README.md index 9fab5031..80ef954b 100644 --- a/exercises/largest-series-product/README.md +++ b/exercises/largest-series-product/README.md @@ -15,26 +15,29 @@ the largest product for a series of 6 digits is 23520. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine largest-series-product.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/leap/README.md b/exercises/leap/README.md index eb2d2b6f..1797b780 100644 --- a/exercises/leap/README.md +++ b/exercises/leap/README.md @@ -4,7 +4,7 @@ Given a year, report if it is a leap year. The tricky thing here is that a leap year in the Gregorian calendar occurs: -```plain +```text on every year that is evenly divisible by 4 except every year that is evenly divisible by 100 unless the year is also evenly divisible by 400 @@ -28,26 +28,29 @@ phenomenon, go watch [this youtube video][video]. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine leap.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/linked-list/README.md b/exercises/linked-list/README.md index fbf47f55..e7b5e704 100644 --- a/exercises/linked-list/README.md +++ b/exercises/linked-list/README.md @@ -2,18 +2,18 @@ Implement a doubly linked list. -Like an array, a linked list is a simple linear data structure. Several -common data types can be implemented using linked lists, like queues, +Like an array, a linked list is a simple linear data structure. Several +common data types can be implemented using linked lists, like queues, stacks, and associative arrays. -A linked list is a collection of data elements called *nodes*. In a -*singly linked list* each node holds a value and a link to the next node. -In a *doubly linked list* each node also holds a link to the previous +A linked list is a collection of data elements called *nodes*. In a +*singly linked list* each node holds a value and a link to the next node. +In a *doubly linked list* each node also holds a link to the previous node. -You will write an implementation of a doubly linked list. Implement a -Node to hold a value and pointers to the next and previous nodes. Then -implement a List which holds references to the first and last node and +You will write an implementation of a doubly linked list. Implement a +Node to hold a value and pointers to the next and previous nodes. Then +implement a List which holds references to the first and last node and offers an array-like interface for adding and removing items: * `push` (*insert value at back*); @@ -21,34 +21,37 @@ offers an array-like interface for adding and removing items: * `shift` (*remove value at front*). * `unshift` (*insert value at front*); -To keep your implementation simple, the tests will not cover error -conditions. Specifically: `pop` or `shift` will never be called on an +To keep your implementation simple, the tests will not cover error +conditions. Specifically: `pop` or `shift` will never be called on an empty list. If you want to know more about linked lists, check [Wikipedia](https://en.wikipedia.org/wiki/Linked_list). ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine linked-list.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/list-ops/README.md b/exercises/list-ops/README.md index 13eaa17d..44da25f4 100644 --- a/exercises/list-ops/README.md +++ b/exercises/list-ops/README.md @@ -8,27 +8,29 @@ without using existing functions. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine list-ops.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/luhn/README.md b/exercises/luhn/README.md index 0338fa3e..e11e1bf3 100644 --- a/exercises/luhn/README.md +++ b/exercises/luhn/README.md @@ -18,27 +18,27 @@ are disallowed. ## Example 1: valid credit card number -``` +```text 4539 1488 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_ ``` 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 ``` Then sum all of the digits: -``` +```text 8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80 ``` @@ -46,19 +46,19 @@ If the sum is evenly divisible by 10, then the number is valid. This number is v ## Example 2: invalid credit card number -``` +```text 8273 1232 7352 0569 ``` Double the second digits, starting from the right -``` +```text 7253 2262 5312 0539 ``` Sum the digits -``` +```text 7+2+5+3+2+2+6+2+5+3+1+2+0+5+3+9 = 57 ``` @@ -66,26 +66,29 @@ Sum the digits ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine luhn.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/matrix/README.md b/exercises/matrix/README.md index 11334675..dd2504ef 100644 --- a/exercises/matrix/README.md +++ b/exercises/matrix/README.md @@ -5,13 +5,15 @@ that matrix. So given a string with embedded newlines like: -> 9 8 7 -> 5 3 2 -> 6 6 7 +```text +9 8 7 +5 3 2 +6 6 7 +``` representing this matrix: -```plain +```text 0 1 2 |--------- 0 | 9 8 7 @@ -40,26 +42,29 @@ And its columns: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine matrix.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/meetup/README.md b/exercises/meetup/README.md index f7b6da03..95f902ee 100644 --- a/exercises/meetup/README.md +++ b/exercises/meetup/README.md @@ -2,49 +2,55 @@ Calculate the date of meetups. -Typically meetups happen on the same day of the week. In this exercise, you will take -a description of a meetup date, and return the actual meetup date. +Typically meetups happen on the same day of the week. In this exercise, you +will take a description of a meetup date, and return the actual meetup date. Examples of general descriptions are: -- the first Monday of January 2017 -- the third Tuesday of January 2017 -- the Wednesteenth of January 2017 -- the last Thursday of January 2017 +- The first Monday of January 2017 +- The third Tuesday of January 2017 +- The wednesteenth of January 2017 +- The last Thursday of January 2017 -Note that "Monteenth", "Tuesteenth", etc are all made up words. There -was a meetup whose members realized that there are exactly 7 numbered days in a month that -end in '-teenth'. Therefore, one is guaranteed that each day of the week +The descriptors you are expected to parse are: +first, second, third, fourth, fifth, last, monteenth, tuesteenth, wednesteenth, +thursteenth, friteenth, saturteenth, sunteenth + +Note that "monteenth", "tuesteenth", etc are all made up words. There was a +meetup whose members realized that there are exactly 7 numbered days in a month +that end in '-teenth'. Therefore, one is guaranteed that each day of the week (Monday, Tuesday, ...) will have exactly one date that is named with '-teenth' in every month. -Given examples of a meetup dates, each containing a month, day, year, and descriptor -(first, second, teenth, etc), calculate the date of the actual meetup. -For example, if given "First Monday of January 2017", the correct meetup date is 2017/1/2 - +Given examples of a meetup dates, each containing a month, day, year, and +descriptor calculate the date of the actual meetup. For example, if given +"The first Monday of January 2017", the correct meetup date is 2017/1/2. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine meetup.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/minesweeper/README.md b/exercises/minesweeper/README.md index 6d7cd2f4..f3890756 100644 --- a/exercises/minesweeper/README.md +++ b/exercises/minesweeper/README.md @@ -28,27 +28,29 @@ into this: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js - -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine minesweeper.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/nth-prime/README.md b/exercises/nth-prime/README.md index 881b4912..621e625a 100644 --- a/exercises/nth-prime/README.md +++ b/exercises/nth-prime/README.md @@ -10,26 +10,29 @@ numbers, pretend they don't exist and implement them yourself. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine nth-prime.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/nucleotide-count/README.md b/exercises/nucleotide-count/README.md index 09c15876..607c27c5 100644 --- a/exercises/nucleotide-count/README.md +++ b/exercises/nucleotide-count/README.md @@ -1,53 +1,42 @@ # Nucleotide Count -Given a DNA string, compute how many times each nucleotide occurs in the string. +Given a single stranded DNA string, compute how many times each nucleotide occurs in the string. -DNA is represented by an alphabet of the following symbols: 'A', 'C', -'G', and 'T'. - -Each symbol represents a nucleotide, which is a fancy name for the -particular molecules that happen to make up a large part of DNA. - -Shortest intro to biochemistry EVAR: +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. +Here is an analogy: - twigs are to birds nests as -- nucleotides are to DNA and RNA as -- amino acids are to proteins as -- sugar is to starch as -- oh crap lipids - -I'm not going to talk about lipids because they're crazy complex. - -So back to nucleotides. - -DNA contains four types of them: adenine (`A`), cytosine (`C`), guanine -(`G`), and thymine (`T`). - -RNA contains a slightly different set of nucleotides, but we don't care -about that for now. +- nucleotides are to DNA as +- legos are to lego houses as +- words are to sentences as... ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine nucleotide-count.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/ocr-numbers/README.md b/exercises/ocr-numbers/README.md index e735dfdd..5444b695 100644 --- a/exercises/ocr-numbers/README.md +++ b/exercises/ocr-numbers/README.md @@ -1,4 +1,4 @@ -# Ocr Numbers +# OCR Numbers Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled. @@ -9,7 +9,7 @@ To begin with, convert a simple binary font to a string containing 0 or 1. The binary font uses pipes and underscores, four rows high and three columns wide. -``` +```text _ # | | # zero. |_| # @@ -18,7 +18,7 @@ The binary font uses pipes and underscores, four rows high and three columns wid Is converted to "0" -``` +```text # | # one. | # @@ -39,7 +39,7 @@ Update your program to recognize multi-character binary strings, replacing garbl Update your program to recognize all numbers 0 through 9, both individually and as part of a larger string. -``` +```text _ _| |_ @@ -48,7 +48,7 @@ Update your program to recognize all numbers 0 through 9, both individually and Is converted to "2" -``` +```text _ _ _ _ _ _ _ _ # | _| _||_||_ |_ ||_||_|| | # decimal numbers. ||_ _| | _||_| ||_| _||_| # @@ -61,7 +61,7 @@ Is converted to "1234567890" Update your program to handle multiple numbers, one per line. When converting several lines, join the lines with commas. -``` +```text _ _ | _| _| ||_ _| @@ -80,26 +80,29 @@ Is converted to "123,456,789" ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine ocr-numbers.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/octal/README.md b/exercises/octal/README.md index 7726a323..1e906436 100644 --- a/exercises/octal/README.md +++ b/exercises/octal/README.md @@ -8,11 +8,13 @@ Implement octal to decimal conversion. Given an octal input string, your program should produce a decimal output. ## Note + - Implement the conversion yourself. Do not use something else to perform the conversion for you. - Treat invalid input as octal 0. ## About Octal (Base-8) + Decimal is a base-10 system. A number 233 in base 10 notation can be understood @@ -25,7 +27,8 @@ as a linear combination of powers of 10: - All these values are summed. So: -``` + +```text 233 # decimal = 2*10^2 + 3*10^1 + 3*10^0 = 2*100 + 3*10 + 3*1 @@ -34,7 +37,8 @@ So: Octal is similar, but uses powers of 8 rather than powers of 10. So: -``` + +```text 233 # octal = 2*8^2 + 3*8^1 + 3*8^0 = 2*64 + 3*8 + 3*1 @@ -44,26 +48,29 @@ So: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine octal.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/palindrome-products/README.md b/exercises/palindrome-products/README.md index 101d935c..29c8035b 100644 --- a/exercises/palindrome-products/README.md +++ b/exercises/palindrome-products/README.md @@ -5,56 +5,58 @@ Detect palindrome products in a given range. 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 the definition of a palindromic number, we define a palindrome _product_ -to be the product `c`, such that `a * b = c`, where `c` is a palindromic number and - `a` and `b` are integers (possibly, but _not_ necessarily palindromic numbers). +Given a range of numbers, find the largest and smallest palindromes which +are products of numbers within that range. -For example, the palindromic number 9009 can be written as the palindrome -product: `91 * 99 = 9009`. - -It's possible (and indeed common) for a palindrome product to be the product -of multiple combinations of numbers. For example, the palindrome product `9` has -the factors `(1, 9)`, `(3, 3)`, and `(9, 1)`. - -Write a program that, given a range of integers, returns the smallest and largest -palindromic product within that range, along with all of its factors. +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 +than one pair of factors within the range, then return all the pairs. ## Example 1 Given the range `[1, 9]` (both inclusive)... -The smallest product is `1`. Its factors are `(1, 1)`. -The largest product is `9`. Its factors are `(1, 9)`, `(3, 3)`, and `(9, 1)`. +And given the list of all possible products within this range: +`[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 15, 21, 24, 27, 20, 28, 32, 36, 25, 30, 35, 40, 45, 42, 48, 54, 49, 56, 63, 64, 72, 81]` + +The palindrome products are all single digit numbers (in this case): +`[1, 2, 3, 4, 5, 6, 7, 8, 9]` + +The smallest palindrome product is `1`. Its factors are `(1, 1)`. +The largest palindrome product is `9`. Its factors are `(1, 9)` and `(3, 3)`. ## Example 2 Given the range `[10, 99]` (both inclusive)... The smallest palindrome product is `121`. Its factors are `(11, 11)`. -The largest palindrome product is `9009`. Its factors are `(91, 99)` and `(99, 91)`. +The largest palindrome product is `9009`. Its factors are `(91, 99)`. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine palindrome-products.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/pangram/README.md b/exercises/pangram/README.md index 0fefa229..d94827f5 100644 --- a/exercises/pangram/README.md +++ b/exercises/pangram/README.md @@ -2,7 +2,7 @@ Determine if a sentence is a pangram. A pangram (Greek: παν γράμμα, pan gramma, "every letter") is a sentence using every letter of the alphabet at least once. -The best known English pangram is: +The best known English pangram is: > The quick brown fox jumps over the lazy dog. The alphabet used consists of ASCII letters `a` to `z`, inclusive, and is case @@ -10,26 +10,29 @@ insensitive. Input will not contain non-ASCII symbols. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine pangram.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/pascals-triangle/README.md b/exercises/pascals-triangle/README.md index fbd99f84..4011ad75 100644 --- a/exercises/pascals-triangle/README.md +++ b/exercises/pascals-triangle/README.md @@ -1,11 +1,11 @@ -# Pascals Triangle +# Pascal's Triangle Compute Pascal's triangle up to a given number of rows. In Pascal's Triangle each number is computed by adding the numbers to the right and left of the current position in the previous row. -```plain +```text 1 1 1 1 2 1 @@ -16,26 +16,29 @@ the right and left of the current position in the previous row. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine pascals-triangle.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/perfect-numbers/README.md b/exercises/perfect-numbers/README.md index 39555f2a..4f9eaabe 100644 --- a/exercises/perfect-numbers/README.md +++ b/exercises/perfect-numbers/README.md @@ -5,7 +5,7 @@ Nicomachus' (60 - 120 CE) classification scheme for natural numbers. 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 -- **Perfect**: aliquot sum = number +- **Perfect**: aliquot sum = number - 6 is a perfect number because (1 + 2 + 3) = 6 - 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28 - **Abundant**: aliquot sum > number @@ -14,31 +14,34 @@ The Greek mathematician [Nicomachus](https://en.wikipedia.org/wiki/Nicomachus) d - **Deficient**: aliquot sum < number - 8 is a deficient number because (1 + 2 + 4) = 7 - Prime numbers are deficient - + Implement a way to determine whether a given number is **perfect**. Depending on your language track, you may also need to implement a way to determine whether a given number is **abundant** or **deficient**. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine perfect-numbers.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/phone-number/README.md b/exercises/phone-number/README.md index 1fbcdc6b..12968e23 100644 --- a/exercises/phone-number/README.md +++ b/exercises/phone-number/README.md @@ -6,14 +6,15 @@ The **North American Numbering Plan (NANP)** is a telephone numbering system use NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as *area code*, followed by a seven-digit local number. The first three digits of the local number represent the *exchange code*, followed by the unique four-digit number which is the *subscriber number*. - The format is usually represented as -``` + +```text (NXX)-NXX-XXXX ``` + where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9. -Your task is to clean up differently formated telephone numbers by removing punctuation and the country code (1) if present. +Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present. For example, the inputs - `+1 (613)-995-0253` @@ -29,26 +30,29 @@ should all produce the output ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine phone-number.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/pig-latin/README.md b/exercises/pig-latin/README.md index d0eb7ec7..4a1cc7da 100644 --- a/exercises/pig-latin/README.md +++ b/exercises/pig-latin/README.md @@ -19,26 +19,29 @@ See for more details. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine pig-latin.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/point-mutations/README.md b/exercises/point-mutations/README.md index d012497b..a7136a5c 100644 --- a/exercises/point-mutations/README.md +++ b/exercises/point-mutations/README.md @@ -36,26 +36,29 @@ distance function. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine point-mutations.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/prime-factors/README.md b/exercises/prime-factors/README.md index f9bec3fd..ed083464 100644 --- a/exercises/prime-factors/README.md +++ b/exercises/prime-factors/README.md @@ -31,26 +31,29 @@ You can check this yourself: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine prime-factors.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/protein-translation/README.md b/exercises/protein-translation/README.md index c863319a..96e516e5 100644 --- a/exercises/protein-translation/README.md +++ b/exercises/protein-translation/README.md @@ -10,17 +10,17 @@ Codons: `"AUG", "UUU", "UCU"` => which become a polypeptide with the following sequence => Protein: `"Methionine", "Phenylalanine", "Serine"` - + There are 64 codons which in turn correspond to 20 amino acids; however, all of the codon sequences and resulting amino acids are not important in this exercise. If it works for one codon, the program should work for all of them. -However, feel free to expand the list in the test suite to include them all. +However, feel free to expand the list in the test suite to include them all. -There are also four terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated. +There are also three terminating codons (also known as 'STOP' codons); if any of these codons are encountered (by the ribosome), all translation ends and the protein is terminated. All subsequent codons after are ignored, like this: RNA: `"AUGUUUUCUUAAAUG"` => -Codons: `"AUG", "UUU", "UCU", "UAG", "AUG"` => +Codons: `"AUG", "UUU", "UCU", "UAG", "AUG"` => Protein: `"Methionine", "Phenylalanine", "Serine"` @@ -39,31 +39,33 @@ UGU, UGC | Cysteine UGG | Tryptophan UAA, UAG, UGA | STOP - Learn more about [protein translation on Wikipedia](http://en.wikipedia.org/wiki/Translation_(biology)) ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine protein-translation.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/proverb/README.md b/exercises/proverb/README.md index 01a7ffba..b7282a20 100644 --- a/exercises/proverb/README.md +++ b/exercises/proverb/README.md @@ -1,38 +1,46 @@ # Proverb -For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output -the full text of this proverbial rhyme: +For want of a horseshoe nail, a kingdom was lost, or so the saying goes. -> 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. -> 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. +Given a list of inputs, generate the relevant proverb. For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme: + +```text +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. +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. +``` + +Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. No line of the output text should be a static, unchanging string; all should vary according to the input given. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine proverb.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/pythagorean-triplet/README.md b/exercises/pythagorean-triplet/README.md index 362edc7b..fc3b3b94 100644 --- a/exercises/pythagorean-triplet/README.md +++ b/exercises/pythagorean-triplet/README.md @@ -3,13 +3,13 @@ A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which, -``` +```text a**2 + b**2 = c**2 ``` -For example, +For example, -``` +```text 3**2 + 4**2 = 9 + 16 = 25 = 5**2. ``` @@ -19,26 +19,29 @@ Find the product a * b * c. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine pythagorean-triplet.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/queen-attack/README.md b/exercises/queen-attack/README.md index 4c27f24b..f9c6c5bf 100644 --- a/exercises/queen-attack/README.md +++ b/exercises/queen-attack/README.md @@ -11,7 +11,7 @@ A chessboard can be represented by an 8 by 8 array. So if you're told the white queen is at (2, 3) and the black queen at (5, 6), then you'd know you've got a set-up like so: -```plain +```text _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ W _ _ _ _ @@ -28,26 +28,29 @@ share a diagonal. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine queen-attack.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/raindrops/README.md b/exercises/raindrops/README.md index d8c20c42..541b58df 100644 --- a/exercises/raindrops/README.md +++ b/exercises/raindrops/README.md @@ -19,26 +19,29 @@ Convert a number to a string, the contents of which depend on the number's facto ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine raindrops.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/reverse-string/README.md b/exercises/reverse-string/README.md index d6d75bb9..f9edf6c5 100644 --- a/exercises/reverse-string/README.md +++ b/exercises/reverse-string/README.md @@ -1,36 +1,40 @@ # Reverse String +Reverse a string + For example: input: "cool" output: "looc" - ## Setup -Go through the setup instructions for JavaScript to -install the necessary dependencies: - -http://exercism.io/languages/javascript +Go through the setup instructions for JavaScript to install the + necessary dependencies: -## Making the Test Suite Pass +http://exercism.io/languages/javascript/installation -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Reverse String exercise: +```sh +npm install -g jasmine +``` - jasmine reverse-string.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine reverse-string.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source -This is an exercise to introduce users to using Exercism and arrays and strings [https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb](https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb) +Introductory challenge to reverse an input string [https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb](https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb) ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/rna-transcription/README.md b/exercises/rna-transcription/README.md index aedf7c05..ab942a69 100644 --- a/exercises/rna-transcription/README.md +++ b/exercises/rna-transcription/README.md @@ -1,4 +1,4 @@ -# Rna Transcription +# RNA Transcription Given a DNA strand, return its RNA complement (per RNA transcription). @@ -20,26 +20,29 @@ each nucleotide with its complement: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine rna-transcription.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/robot-name/README.md b/exercises/robot-name/README.md index 170285fe..7b875976 100644 --- a/exercises/robot-name/README.md +++ b/exercises/robot-name/README.md @@ -17,26 +17,29 @@ every existing robot has a unique name. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine robot-name.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/robot-simulator/README.md b/exercises/robot-simulator/README.md index 7bc1f6b8..796b4e6e 100644 --- a/exercises/robot-simulator/README.md +++ b/exercises/robot-simulator/README.md @@ -29,26 +29,29 @@ direction it is pointing. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine robot-simulator.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/roman-numerals/README.md b/exercises/roman-numerals/README.md index 562b98d9..ab2f8dc0 100644 --- a/exercises/roman-numerals/README.md +++ b/exercises/roman-numerals/README.md @@ -14,7 +14,7 @@ The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice these letters have lots of straight lines and are hence easy to hack into stone tablets). -``` +```text 1 => I 10 => X 7 => VII @@ -44,26 +44,29 @@ See also: http://www.novaroma.org/via_romana/numbers.html ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine roman-numerals.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/run-length-encoding/README.md b/exercises/run-length-encoding/README.md index aa54e96e..e4499e71 100644 --- a/exercises/run-length-encoding/README.md +++ b/exercises/run-length-encoding/README.md @@ -7,44 +7,47 @@ Run-length encoding (RLE) is a simple form of data compression, where runs For example we can represent the original 53 characters with only 13. -``` +```text "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" ``` RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression. -``` +```text "AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" ``` For simplicity, you can assume that the unencoded string will only contain -the letters A through Z (either lower or upper case) and whitespace. This way -data to be encoded will never contain any numbers and numbers inside data to +the letters A through Z (either lower or upper case) and whitespace. This way +data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine run-length-encoding.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/saddle-points/README.md b/exercises/saddle-points/README.md index 32865cba..aa61f4cd 100644 --- a/exercises/saddle-points/README.md +++ b/exercises/saddle-points/README.md @@ -4,7 +4,7 @@ Detect saddle points in a matrix. So say you have a matrix like so: -```plain +```text 0 1 2 |--------- 0 | 9 8 7 @@ -28,26 +28,29 @@ but the tests for this exercise follow the above unambiguous definition. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine saddle-points.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/say/README.md b/exercises/say/README.md index ccd07fa9..bd67005b 100644 --- a/exercises/say/README.md +++ b/exercises/say/README.md @@ -64,26 +64,29 @@ Use _and_ (correctly) when spelling out the number in English: ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine say.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/scrabble-score/README.md b/exercises/scrabble-score/README.md index f3248bce..59b1d90d 100644 --- a/exercises/scrabble-score/README.md +++ b/exercises/scrabble-score/README.md @@ -6,7 +6,7 @@ Given a word, compute the scrabble score for that word. You'll need these: -```plain +```text Letter Value A, E, I, O, U, L, N, R, S, T 1 D, G 2 @@ -18,6 +18,7 @@ Q, Z 10 ``` ## Examples + "cabbage" should be scored as worth 14 points: - 3 points for C @@ -34,31 +35,35 @@ And to total: - = 14 ## Extensions + - You can play a double or a triple letter. - You can play a double or a triple word. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine scrabble-score.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/secret-handshake/README.md b/exercises/secret-handshake/README.md index f2f24b8d..15e4d426 100644 --- a/exercises/secret-handshake/README.md +++ b/exercises/secret-handshake/README.md @@ -6,7 +6,7 @@ You and your fellow cohort of those in the "know" when it comes to binary decide to come up with a secret "handshake". -``` +```text 1 = wink 10 = double blink 100 = close your eyes @@ -30,26 +30,29 @@ has caused the array to be reversed. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine secret-handshake.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/series/README.md b/exercises/series/README.md index c4b2cfd4..752330d4 100644 --- a/exercises/series/README.md +++ b/exercises/series/README.md @@ -22,26 +22,29 @@ in the input; the digits need not be *numerically consecutive*. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine series.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/sieve/README.md b/exercises/sieve/README.md index af8bf0a4..33f66f28 100644 --- a/exercises/sieve/README.md +++ b/exercises/sieve/README.md @@ -29,26 +29,29 @@ correct list of primes. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine sieve.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/simple-cipher/README.md b/exercises/simple-cipher/README.md index bad16f5f..e0ee4353 100644 --- a/exercises/simple-cipher/README.md +++ b/exercises/simple-cipher/README.md @@ -58,15 +58,13 @@ would get the same thing as the Caesar Cipher. The weakest link in any cipher is the human being. Let's make your substitution cipher a little more fault tolerant by providing a source -of randomness and ensuring that the key is not composed of numbers or -capital letters. +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 characters in length, accessible via Cipher#key (the # -syntax means instance variable) +at least 100 characters in length. -If the key submitted has capital letters or numbers, throw an -ArgumentError with a message to that effect. +If the key submitted is not composed only of lowercase letters, your +solution should handle the error in a language-appropriate way. ## Extensions @@ -85,26 +83,29 @@ on Wikipedia][dh] for one of the first implementations of this scheme. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine simple-cipher.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/simple-linked-list/README.md b/exercises/simple-linked-list/README.md index 6c373fd5..07e40594 100644 --- a/exercises/simple-linked-list/README.md +++ b/exercises/simple-linked-list/README.md @@ -23,26 +23,29 @@ implement your own abstract data type. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine simple-linked-list.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/space-age/README.md b/exercises/space-age/README.md index af0d4338..523cc173 100644 --- a/exercises/space-age/README.md +++ b/exercises/space-age/README.md @@ -12,33 +12,36 @@ Given an age in seconds, calculate how old someone would be on: - Neptune: orbital period 164.79132 Earth years So if you were told someone were 1,000,000,000 seconds old, you should -be able to say that they're 31 Earth-years old. +be able to say that they're 31.69 Earth-years old. If you're wondering why Pluto didn't make the cut, go watch [this youtube video](http://www.youtube.com/watch?v=Z_2gbGXzFbs). ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine space-age.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/strain/README.md b/exercises/strain/README.md index dcdbf3b8..f58e2b2d 100644 --- a/exercises/strain/README.md +++ b/exercises/strain/README.md @@ -35,26 +35,29 @@ basic tools instead. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine strain.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/sublist/README.md b/exercises/sublist/README.md index 974d3f06..0b5d6d8c 100644 --- a/exercises/sublist/README.md +++ b/exercises/sublist/README.md @@ -19,32 +19,29 @@ Examples: ## Setup -Go through the setup instructions for ECMAScript to -install the necessary dependencies: +Go through the setup instructions for JavaScript to install the + necessary dependencies: -http://exercism.io/languages/ecmascript +http://exercism.io/languages/javascript/installation -## Requirements +## Running the test suite -Install assignment dependencies: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -```bash -$ npm install -g jasmine +```sh +npm install -g jasmine ``` -## Making the test suite pass +Run the test suite from the exercise directory with: -Execute the tests with: - -```bash -$ jasmine sublist.spec.js +```sh +jasmine sublist.spec.js ``` -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 `xit` to `it`. - +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/sum-of-multiples/README.md b/exercises/sum-of-multiples/README.md index 55d9517c..ace5cad7 100644 --- a/exercises/sum-of-multiples/README.md +++ b/exercises/sum-of-multiples/README.md @@ -1,38 +1,38 @@ -# Sum of Multiples +# Sum Of Multiples -Given a number, find the sum of all the multiples of particular numbers up to +Given a number, find the sum of all the unique multiples of particular numbers up to but not including that number. -If we list all the natural numbers up to but not including 20 that are -multiples of either 3 or 5, we get 3, 5, 6, 9, 10, 12, 15, and 18. +If we list all the natural numbers below 20 that are multiples of 3 or 5, +we get 3, 5, 6, 9, 10, 12, 15, and 18. The sum of these multiples is 78. -Given a number, find the sum of the multiples of a given set of numbers, -up to but not including that number. - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine sum-of-multiples.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/transpose/README.md b/exercises/transpose/README.md index 20f48cad..05c69022 100644 --- a/exercises/transpose/README.md +++ b/exercises/transpose/README.md @@ -60,26 +60,29 @@ the corresponding output row should contain the spaces in its right-most column( ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine transpose.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/triangle/README.md b/exercises/triangle/README.md index 0cf1fd1a..10d05dd2 100644 --- a/exercises/triangle/README.md +++ b/exercises/triangle/README.md @@ -2,45 +2,51 @@ Determine if a triangle is equilateral, isosceles, or scalene. -An _equilateral_ triangle has all three sides the same length.
    +An _equilateral_ triangle has all three sides the same length. + An _isosceles_ triangle has at least two sides the same length. (It is sometimes specified as having exactly two sides the same length, but for the purposes of -this exercise we'll say at least two.)
    +this exercise we'll say at least two.) + A _scalene_ triangle has all sides of different lengths. ## Note -For a shape to be a triangle at all, all sides have to be of length > 0, and -the sum of the lengths of any two sides must be greater than or equal to the +For a shape to be a triangle at all, all sides have to be of length > 0, and +the sum of the lengths of any two sides must be greater than or equal to the length of the third side. See [Triangle Inequality](https://en.wikipedia.org/wiki/Triangle_inequality). ## Dig Deeper -The case where the sum of the lengths of two sides _equals_ that of the -third is known as a _degenerate_ triangle - it has zero area and looks like +The case where the sum of the lengths of two sides _equals_ that of the +third is known as a _degenerate_ triangle - it has zero area and looks like a single line. Feel free to add your own code/tests to check for degenerate triangles. + ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine triangle.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/trinary/README.md b/exercises/trinary/README.md index e42df1b3..16f94ea3 100644 --- a/exercises/trinary/README.md +++ b/exercises/trinary/README.md @@ -11,7 +11,7 @@ Trinary numbers contain three symbols: 0, 1, and 2. The last place in a trinary number is the 1's place. The second to last is the 3's place, the third to last is the 9's place, etc. -```bash +```shell # "102012" 1 0 2 0 1 2 # the number 1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value @@ -23,26 +23,29 @@ conversion, pretend it doesn't exist and implement it yourself. ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js - -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine trinary.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/twelve-days/README.md b/exercises/twelve-days/README.md index d5bdc3a3..9647f728 100644 --- a/exercises/twelve-days/README.md +++ b/exercises/twelve-days/README.md @@ -2,7 +2,7 @@ Output the lyrics to 'The Twelve Days of Christmas'. -``` +```text On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree. On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree. @@ -28,34 +28,35 @@ On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree. ``` - ## 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: http://exercism.io/languages/javascript/installation -## Making the test suite pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: - - jasmine hello-world.spec.js +```sh +npm install -g jasmine +``` -In many test suites all but the first test have been skipped. +Run the test suite from the exercise directory with: -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +```sh +jasmine twelve-days.spec.js +``` +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source Wikipedia [http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)](http://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)) ## Submitting Incomplete Solutions -It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/two-bucket/README.md b/exercises/two-bucket/README.md index e2d7f15c..dfa17296 100644 --- a/exercises/two-bucket/README.md +++ b/exercises/two-bucket/README.md @@ -4,22 +4,22 @@ Given two buckets of different size, demonstrate how to measure an exact number Since this mathematical problem is fairly subject to interpretation / individual approach, the tests have been written specifically to expect one overarching solution. -To help, the tests provide you with which bucket to fill first. That means, when starting with the larger bucket full, you are NOT allowed at any point to have the smaller bucket full and the larger bucket empty (aka, the opposite starting point); that would defeat the purpose of comparing both approaches! +To help, the tests provide you with which bucket to fill first. That means, when starting with the larger bucket full, you are NOT allowed at any point to have the smaller bucket full and the larger bucket empty (aka, the opposite starting point); that would defeat the purpose of comparing both approaches! Your program will take as input: -- the size of bucket one, passed as a numeric value -- the size of bucket two, passed as a numeric value -- the desired number of liters to reach, passed as a numeric value -- which bucket to fill first, passed as a String (either 'one' or 'two') +- the size of bucket one +- the size of bucket two +- the desired number of liters to reach +- which bucket to fill first, either bucket one or bucket two Your program should determine: -- the total number of "moves" it should take to reach the desired number of liters, including the first fill - expects a numeric value -- which bucket should end up with the desired number of liters (let's say this is bucket A) - expects a String (either 'one' or 'two') -- how many liters are left in the other bucket (bucket B) - expects a numeric value +- the total number of "moves" it should take to reach the desired number of liters, including the first fill +- which bucket should end up with the desired number of liters (let's say this is bucket A) - either bucket one or bucket two +- how many liters are left in the other bucket (bucket B) -Note: any time a change is made to either or both buckets counts as one (1) move. +Note: any time a change is made to either or both buckets counts as one (1) move. -Example: +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: @@ -31,26 +31,29 @@ Written with <3 at [Fullstack Academy](http://www.fullstackacademy.com/) by [Lin ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine two-bucket.spec.js +``` -In many test suites all but the first test have been skipped. - -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/two-fer/README.md b/exercises/two-fer/README.md index 4baeeaa5..868b6c46 100644 --- a/exercises/two-fer/README.md +++ b/exercises/two-fer/README.md @@ -2,7 +2,7 @@ `Two-fer` or `2-fer` is short for two for one. One for you and one for me. -``` +```text "One for X, one for me." ``` @@ -11,31 +11,36 @@ When X is a name or "you". If the given name is "Alice", the result should be "One for Alice, one for me." If no name is given, the result should be "One for you, one for me." + ## 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: -http://exercism.io/languages/javascript +http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass +## Running the test suite -Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` -Replace `` with the name of the current exercise. E.g., to -test the Two Fer exercise: +Run the test suite from the exercise directory with: - jasmine two-fer.spec.js +```sh +jasmine two-fer.spec.js +``` -All tests but the first have been skipped. Once you get a test passing, -you can unskip the next one by changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source -This is an exercise to introduce users to basic programming constructs, just after 'Hello World'. [https://en.wikipedia.org/wiki/Two-fer](https://en.wikipedia.org/wiki/Two-fer) +This is an exercise to introduce users to basic programming constructs, just after Hello World. [https://en.wikipedia.org/wiki/Two-fer](https://en.wikipedia.org/wiki/Two-fer) ## Submitting Incomplete Solutions It's possible to submit an incomplete solution so you can see how others have completed the exercise. - diff --git a/exercises/word-count/README.md b/exercises/word-count/README.md index b59f0e4a..e0bd287f 100644 --- a/exercises/word-count/README.md +++ b/exercises/word-count/README.md @@ -4,36 +4,38 @@ Given a phrase, count the occurrences of each word in that phrase. For example for the input `"olly olly in come free"` -```plain +```text olly: 2 in: 1 come: 1 free: 1 ``` - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine word-count.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/wordy/README.md b/exercises/wordy/README.md index 2b64dea5..c4950341 100644 --- a/exercises/wordy/README.md +++ b/exercises/wordy/README.md @@ -2,7 +2,6 @@ Parse and evaluate simple math word problems returning the answer as an integer. - ## Iteration 1 — Addition Add two numbers together. @@ -13,7 +12,6 @@ Evaluates to 18. Handle large numbers and negative numbers. - ## Iteration 2 — Subtraction, Multiplication and Division Now, perform the other three operations. @@ -30,7 +28,6 @@ Now, perform the other three operations. 5 - ## Iteration 3 — Multiple Operations Handle a set of operations, in sequence. @@ -46,7 +43,6 @@ left-to-right, _ignoring the typical order of operations._ 15 (i.e. not 9) - ## Bonus — Exponentials If you'd like, handle exponentials. @@ -55,29 +51,31 @@ If you'd like, handle exponentials. 32 - ## 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: http://exercism.io/languages/javascript/installation -## Making the Test Suite Pass - -Execute the tests with: +## Running the test suite - jasmine .spec.js +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: -Replace `` with the name of the current exercise. E.g., to -test the Hello World exercise: +```sh +npm install -g jasmine +``` - jasmine hello-world.spec.js +Run the test suite from the exercise directory with: -In many test suites all but the first test have been skipped. +```sh +jasmine wordy.spec.js +``` -Once you get a test passing, you can unskip the next one by -changing `xit` to `it`. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. ## Source diff --git a/exercises/zipper/README.md b/exercises/zipper/README.md index d571c920..ab780272 100644 --- a/exercises/zipper/README.md +++ b/exercises/zipper/README.md @@ -3,7 +3,7 @@ Creating a zipper for a binary tree. [Zippers](https://en.wikipedia.org/wiki/Zipper_%28data_structure%29) are -a way purely functional of navigating within a data structure and +a purely functional way of navigating within a data structure and manipulating it. They essentially contain a data structure and a pointer into that data structure (called the focus). @@ -27,29 +27,31 @@ list of child nodes) a zipper might support these operations: `next` node if possible otherwise to the `prev` node if possible, otherwise to the parent node, returns a new zipper) - ## Setup +## 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: - http://exercism.io/languages/javascript/installation +http://exercism.io/languages/javascript/installation - ## Making the Test Suite Pass +## Running the test suite - Execute the tests with: +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: - jasmine .spec.js +```sh +npm install -g jasmine +``` - Replace `` with the name of the current exercise. E.g., to - test the Hello World exercise: +Run the test suite from the exercise directory with: - jasmine hello-world.spec.js +```sh +jasmine zipper.spec.js +``` - All but the first test have been skipped. +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. - Once you get a test passing, you can unskip the next one by - changing `xit` to `it`. - - - ## Submitting Incomplete Solutions - It's possible to submit an incomplete solution so you can see how others have completed the exercise. +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. From 2fae77c0a6fc5246b7415544edfcc843fa71eff3 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 14 Jan 2018 18:14:31 -0700 Subject: [PATCH 233/272] Rename deprecated hints files The ./exercises/:slug/HINTS.md file has been deprecated in favor of the ./exercises/:slug/.meta/hints.md file. --- exercises/hello-world/{HINTS.md => .meta/hints.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename exercises/hello-world/{HINTS.md => .meta/hints.md} (100%) diff --git a/exercises/hello-world/HINTS.md b/exercises/hello-world/.meta/hints.md similarity index 100% rename from exercises/hello-world/HINTS.md rename to exercises/hello-world/.meta/hints.md From 0acf575788c0aa1079a7c872b51b0175944f5dff Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Thu, 1 Feb 2018 12:34:55 +0530 Subject: [PATCH 234/272] Use LTS version of node in travis-ci (#497) As suggested in https://github.com/exercism/javascript/issues/462. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2b97b13d..45fde31c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: node_js sudo: false node_js: - - "node" + - "lts/*" install: - "npm install" From ffbf14cf7863d6512a0a3a79317317b6dfa2e42b Mon Sep 17 00:00:00 2001 From: Ajo John Date: Mon, 12 Feb 2018 22:08:32 +0530 Subject: [PATCH 235/272] Fixes: Alphametic Lint Fixes (#499) Tested both alphametics.spec.js and example.js . Found no eslint errors in both files. Removed these files from .eslintignore. --- .eslintignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.eslintignore b/.eslintignore index e3e9691a..f3d52c45 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,4 @@ big-integer.js -exercises/alphametics exercises/binary-search exercises/binary-search-tree exercises/bracket-push From 9f6c1eb4757b085d3ae292a9d7e342ad29f98d65 Mon Sep 17 00:00:00 2001 From: Ajo John Date: Tue, 13 Feb 2018 21:53:39 +0530 Subject: [PATCH 236/272] Fix eslint errors in multiple exercises * binary-search * binary-search-tree * bracket-push * leap * list-ops * luhn * pythagorean-triplet * roman-numerals --- .eslintignore | 8 -------- exercises/binary-search-tree/example.js | 4 ++-- exercises/binary-search/example.js | 2 +- exercises/bracket-push/example.js | 2 +- exercises/leap/example.js | 10 +++++++--- exercises/leap/leap.js | 4 ++-- exercises/list-ops/example.js | 2 +- exercises/luhn/example.js | 4 ++-- exercises/pythagorean-triplet/example.js | 3 ++- exercises/roman-numerals/example.js | 5 +++-- 10 files changed, 21 insertions(+), 23 deletions(-) diff --git a/.eslintignore b/.eslintignore index f3d52c45..a6052eb7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,24 +1,16 @@ big-integer.js -exercises/binary-search -exercises/binary-search-tree -exercises/bracket-push exercises/custom-set exercises/flatten-array exercises/grade-school exercises/grains/big-integer.js exercises/grains/big-integer.spec.js exercises/kindergarten-garden -exercises/leap exercises/linked-list -exercises/list-ops -exercises/luhn exercises/minesweeper exercises/nth-prime exercises/perfect-numbers -exercises/pythagorean-triplet exercises/queen-attack exercises/robot-simulator -exercises/roman-numerals exercises/saddle-points exercises/secret-handshake exercises/simple-cipher diff --git a/exercises/binary-search-tree/example.js b/exercises/binary-search-tree/example.js index 6b4665b6..edc3af96 100644 --- a/exercises/binary-search-tree/example.js +++ b/exercises/binary-search-tree/example.js @@ -2,8 +2,8 @@ function BinarySearchTree(data) { this.data = data; - this.left = undefined; - this.right = undefined; + this.left = null; + this.right = null; } BinarySearchTree.prototype.insert = function (value) { diff --git a/exercises/binary-search/example.js b/exercises/binary-search/example.js index a4e6095c..a1fd178f 100644 --- a/exercises/binary-search/example.js +++ b/exercises/binary-search/example.js @@ -18,7 +18,7 @@ function BinarySearch(array) { function recursiveSearch(array, value, start, end) { - if (start == end) return -1; + if (start === end) return -1; var mid = Math.floor((start + end) / 2); diff --git a/exercises/bracket-push/example.js b/exercises/bracket-push/example.js index ab3d22d3..ace16508 100644 --- a/exercises/bracket-push/example.js +++ b/exercises/bracket-push/example.js @@ -28,7 +28,7 @@ var bracketPush = module.exports = function (input) { for (var k = 0; k < 3; k++) { if (bracketArray[topNumber] === openArray[k]) { - if (typeof bracketArray[(topNumber + 1)] !== undefined) { + if (typeof bracketArray[(topNumber + 1)] !== 'undefined') { if (bracketArray[(topNumber + 1)] === closeArray[k]) { bracketArray.splice(topNumber, 2); return bracketPush(bracketArray); diff --git a/exercises/leap/example.js b/exercises/leap/example.js index bbe7eceb..653dbe45 100644 --- a/exercises/leap/example.js +++ b/exercises/leap/example.js @@ -3,9 +3,11 @@ /** * Represents a year to check whether is leap or not * - * @param {number} year + * @param {number} year + * * Numeric year. */ + function Year(year) { this.year = year; } @@ -13,11 +15,13 @@ function Year(year) { /** * Whether given year is a leap year. * - * @return {boolean} + * @returns {boolean} + * * Whether given year is a leap year. */ + Year.prototype.isLeap = function () { - return (this.year % 400 == 0) || ((this.year % 4 == 0) && (this.year % 100 != 0)); + return (this.year % 400 === 0) || ((this.year % 4 === 0) && (this.year % 100 !== 0)); }; module.exports = Year; diff --git a/exercises/leap/leap.js b/exercises/leap/leap.js index 22b6bb5c..5329bf2d 100644 --- a/exercises/leap/leap.js +++ b/exercises/leap/leap.js @@ -3,10 +3,10 @@ // convenience to get you started writing code faster. // -var Year = function (input) { +var Year = function () { // // YOUR CODE GOES HERE -// +// }; Year.prototype.isLeap = function () { diff --git a/exercises/list-ops/example.js b/exercises/list-ops/example.js index c32141e7..f47d84b9 100644 --- a/exercises/list-ops/example.js +++ b/exercises/list-ops/example.js @@ -56,7 +56,7 @@ List.prototype = { return new List(this.foldl(this.cons, [])); }, - map: function (func, arr) { + map: function (func) { var applyFuncThenCons = function (x, acc) { return this.cons(func(x), acc); }; diff --git a/exercises/luhn/example.js b/exercises/luhn/example.js index b311427f..cc38e98f 100644 --- a/exercises/luhn/example.js +++ b/exercises/luhn/example.js @@ -1,8 +1,8 @@ 'use strict'; function isValid(number) { - number = number.replace(/\s/g, ''); - const digits = [...number]; + var numbers = number.replace(/\s/g, ''); + const digits = [...numbers]; const sum = digits // convert to integers diff --git a/exercises/pythagorean-triplet/example.js b/exercises/pythagorean-triplet/example.js index 44f4edf4..a30323bc 100644 --- a/exercises/pythagorean-triplet/example.js +++ b/exercises/pythagorean-triplet/example.js @@ -35,7 +35,8 @@ Triplets.prototype.isDesired = function (triplet) { }; Triplets.prototype.toArray = function () { - var triplet, triplets = []; + var triplet = []; + var triplets = []; for (var a = this.min; a < this.max - 1; a++) { for (var b = a + 1; b < this.max; b++) { for (var c = b + 1; c <= this.max; c++) { diff --git a/exercises/roman-numerals/example.js b/exercises/roman-numerals/example.js index 40e8ddf0..a39d19cc 100644 --- a/exercises/roman-numerals/example.js +++ b/exercises/roman-numerals/example.js @@ -2,6 +2,7 @@ module.exports = function (number) { var result = ''; + var numbers = number; var mappings = [ {arabic: 1000, roman: 'M'}, {arabic: 900, roman: 'CM'}, @@ -20,9 +21,9 @@ module.exports = function (number) { for (var i = 0; i < mappings.length; i++) { var mapping = mappings[i]; - while (number >= mapping.arabic) { + while (numbers >= mapping.arabic) { result = result + mapping.roman; - number = number - mapping.arabic; + numbers = numbers - mapping.arabic; } } From 124e4968d1201a206f7168c9d611b8194f389c11 Mon Sep 17 00:00:00 2001 From: Ajo John Date: Mon, 19 Feb 2018 23:51:44 +0530 Subject: [PATCH 237/272] Move eslint config to package.json And remove the `.eslintconfig.json` file. Closes #456 --- .eslintrc.json | 10 ---------- package.json | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) delete mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 50b380a4..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "plugins": ["jasmine"], - "extends": "eslint-config-airbnb-es5", - "env": { - "jasmine": true - }, - "rules": { - "func-names": "off" - } -} diff --git a/package.json b/package.json index 8feba32a..cac2593c 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,15 @@ "scripts": { "lint": "eslint .", "lint-fix": "eslint . --fix" + }, + "eslintConfig": { + "plugins": ["jasmine"], + "env": { + "jasmine": true + }, + "extends": "eslint-config-airbnb-es5", + "rules": { + "func-names": "off" + } } } From 8e151d92f82c9099359ee1d119a0143788c150eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rivas=20G=C3=B3mez?= Date: Wed, 28 Feb 2018 01:48:20 +0100 Subject: [PATCH 238/272] Add new exercise Rotational Cipher (#504) * Add new exercise Rotational Cipher * Fix linting and tests --- config.json | 12 ++++ exercises/rotational-cipher/README.md | 64 +++++++++++++++++++ exercises/rotational-cipher/example.js | 24 +++++++ .../rotational-cipher.spec.js | 55 ++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 exercises/rotational-cipher/README.md create mode 100644 exercises/rotational-cipher/example.js create mode 100644 exercises/rotational-cipher/rotational-cipher.spec.js diff --git a/config.json b/config.json index 479a7e3b..cda1f322 100644 --- a/config.json +++ b/config.json @@ -206,6 +206,18 @@ ], "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0" }, + { + "core": false, + "difficulty": 6, + "slug": "rotational-cipher", + "topics": [ + "cryptography", + "integers", + "strings" + ], + "unlocked_by": "secret-handshake", + "uuid": "7078b1a4-ef73-4c02-809d-b2de62e9af11" + }, { "core": true, "difficulty": 6, diff --git a/exercises/rotational-cipher/README.md b/exercises/rotational-cipher/README.md new file mode 100644 index 00000000..01384ca3 --- /dev/null +++ b/exercises/rotational-cipher/README.md @@ -0,0 +1,64 @@ +# Rotational Cipher + +Create an implementation of the rotational cipher, also sometimes called the Caesar cipher. + +The Caesar cipher is a simple shift cipher that relies on +transposing all the letters in the alphabet using an integer key +between `0` and `26`. Using a key of `0` or `26` will always yield +the same output due to modular arithmetic. The letter is shifted +for as many values as the value of the key. + +The general notation for rotational ciphers is `ROT + `. +The most commonly used rotational cipher is `ROT13`. + +A `ROT13` on the Latin alphabet would be as follows: + +```text +Plain: abcdefghijklmnopqrstuvwxyz +Cipher: nopqrstuvwxyzabcdefghijklm +``` + +It is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys. + +Ciphertext is written out in the same formatting as the input including spaces and punctuation. + +## Examples + +- ROT5 `omg` gives `trl` +- ROT0 `c` gives `c` +- ROT26 `Cool` gives `Cool` +- ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` +- ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.` + +## Setup + +Go through the setup instructions for JavaScript to install the + necessary dependencies: + +http://exercism.io/languages/javascript/installation + +## Running the test suite + +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: + +```sh +npm install -g jasmine +``` + +Run the test suite from the exercise directory with: + +```sh +jasmine rotational-cipher.spec.js +``` + +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Caesar_cipher](https://en.wikipedia.org/wiki/Caesar_cipher) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/rotational-cipher/example.js b/exercises/rotational-cipher/example.js new file mode 100644 index 00000000..fa3e7baa --- /dev/null +++ b/exercises/rotational-cipher/example.js @@ -0,0 +1,24 @@ +var RotationalCipher = function () {}; + +RotationalCipher.prototype.rotate = function (text, shiftKey) { + if (text.length === 1) { + if (text.charCodeAt(0) >= 97 && text.charCodeAt(0) <= 122) return this.rotateLowerCase(text, shiftKey); + if (text.charCodeAt(0) >= 65 && text.charCodeAt(0) <= 90) return this.rotateUpperCase(text, shiftKey); + return text; + } + return this.rotate(text.charAt(0), shiftKey) + this.rotate(text.slice(1), shiftKey); +}; + +RotationalCipher.prototype.rotateLowerCase = function (letter, shiftKey) { + var rotatedLowerCase = String.fromCharCode(letter.charCodeAt(0) + shiftKey); + if (rotatedLowerCase.charCodeAt(0) > 122) rotatedLowerCase = String.fromCharCode(rotatedLowerCase.charCodeAt(0) - 26); + return rotatedLowerCase; +}; + +RotationalCipher.prototype.rotateUpperCase = function (letter, shiftKey) { + var rotatedUpperCase = String.fromCharCode(letter.charCodeAt(0) + shiftKey); + if (rotatedUpperCase.charCodeAt(0) > 90) rotatedUpperCase = String.fromCharCode(rotatedUpperCase.charCodeAt(0) - 26); + return rotatedUpperCase; +}; + +module.exports = RotationalCipher; diff --git a/exercises/rotational-cipher/rotational-cipher.spec.js b/exercises/rotational-cipher/rotational-cipher.spec.js new file mode 100644 index 00000000..5e6f864d --- /dev/null +++ b/exercises/rotational-cipher/rotational-cipher.spec.js @@ -0,0 +1,55 @@ +var RotationalCipher = require('./rotational-cipher'); + +describe('RotationalCipher', function () { + var rotationalCipher = new RotationalCipher(); + + it('rotate a by 0, same output as input', function () { + var expected = 'a'; + expect(rotationalCipher.rotate('a', 0)).toEqual(expected); + }); + + xit('rotate a by 1', function () { + var expected = 'b'; + expect(rotationalCipher.rotate('a', 1)).toEqual(expected); + }); + + xit('rotate a by 26, same output as input', function () { + var expected = 'a'; + expect(rotationalCipher.rotate('a', 26)).toEqual(expected); + }); + + xit('rotate m by 13', function () { + var expected = 'z'; + expect(rotationalCipher.rotate('m', 13)).toEqual(expected); + }); + + xit('rotate n by 13 with wrap around alphabet', function () { + var expected = 'a'; + expect(rotationalCipher.rotate('n', 13)).toEqual(expected); + }); + + xit('rotate capital letters', function () { + var expected = 'TRL'; + expect(rotationalCipher.rotate('OMG', 5)).toEqual(expected); + }); + + xit('rotate spaces', function () { + var expected = 'T R L'; + expect(rotationalCipher.rotate('O M G', 5)).toEqual(expected); + }); + + xit('rotate numbers', function () { + var expected = 'Xiwxmrk 1 2 3 xiwxmrk'; + expect(rotationalCipher.rotate('Testing 1 2 3 testing', 4)).toEqual(expected); + }); + + xit('rotate punctuation', function () { + var expected = 'Gzo\'n zvo, Bmviyhv!'; + expect(rotationalCipher.rotate('Let\'s eat, Grandma!', 21)).toEqual(expected); + }); + + xit('rotate all letters', function () { + var expected = 'Gur dhvpx oebja sbk whzcf bire gur ynml qbt.'; + expect(rotationalCipher.rotate('The quick brown fox jumps over the lazy dog.', 13)).toEqual(expected); + }); +}); From 09c859b378d173ba86bae2e3116d50fde82ced82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rivas=20G=C3=B3mez?= Date: Wed, 28 Feb 2018 23:34:14 +0100 Subject: [PATCH 239/272] Add new exercise Rational Numbers (#506) * Add new exercise Rational Numbers * Rename rational.spec.js to rational-numbers.spec.js * Remove rational.spec.js * Fix module path * Fix naming * Fix difficulty estimation --- config.json | 12 ++ exercises/rational-numbers/README.md | 62 ++++++ exercises/rational-numbers/example.js | 69 ++++++ .../rational-numbers/rational-numbers.spec.js | 197 ++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 exercises/rational-numbers/README.md create mode 100644 exercises/rational-numbers/example.js create mode 100644 exercises/rational-numbers/rational-numbers.spec.js diff --git a/config.json b/config.json index cda1f322..b10b081d 100644 --- a/config.json +++ b/config.json @@ -268,6 +268,18 @@ ], "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c" }, + { + "core": false, + "difficulty": 5, + "slug": "rational-numbers", + "topics": [ + "floating_point_numbers", + "mathematics", + "algorithms" + ], + "unlocked_by": "pascals-triangle", + "uuid": "2de5677e-5759-4a21-93c7-39a3d88242e8" + }, { "core": false, "difficulty": 2, diff --git a/exercises/rational-numbers/README.md b/exercises/rational-numbers/README.md new file mode 100644 index 00000000..12cb067b --- /dev/null +++ b/exercises/rational-numbers/README.md @@ -0,0 +1,62 @@ +# Rational Numbers + +A rational number is defined as the quotient of two integers `a` and `b`, called the numerator and denominator, respectively, where `b != 0`. + +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 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 product (multiplication) of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 * r2 = (a1 * a2) / (b1 * b2)`. + +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. + +Exponentiation of a rational number `r = a/b` to a non-negative integer power `n` is `r^n = (a^n)/(b^n)`. + +Exponentiation of a rational number `r = a/b` to a negative integer power `n` is `r^n = (b^m)/(a^m)`, where `m = |n|`. + +Exponentiation of a rational number `r = a/b` to a real (floating-point) number `x` is the quotient `(a^x)/(b^x)`, which is a real number. + +Exponentiation of a real number `x` to a rational number `r = a/b` is `x^(a/b) = root(x^a, b)`, where `root(p, q)` is the `q`th root of `p`. + +Implement the following operations: + - addition, subtraction, multiplication and division of two rational numbers, + - absolute value, exponentiation of a given rational number to an integer power, exponentiation of a given rational number to a real (floating-point) power, exponentiation of a real number to a rational number. + +Your implementation of rational numbers should always be reduced to lowest terms. For example, `4/4` should reduce to `1/1`, `30/60` should reduce to `1/2`, `12/8` should reduce to `3/2`, etc. To reduce a rational number `r = a/b`, divide `a` and `b` by the greatest common divisor (gcd) of `a` and `b`. So, for example, `gcd(12, 8) = 4`, so `r = 12/8` can be reduced to `(12/4)/(8/4) = 3/2`. + +Assume that the programming language you are using does not have an implementation of rational numbers. + +## Setup + +Go through the setup instructions for JavaScript to install the + necessary dependencies: + +http://exercism.io/languages/javascript/installation + +## Running the test suite + +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: + +```sh +npm install -g jasmine +``` + +Run the test suite from the exercise directory with: + +```sh +jasmine rational-numbers.spec.js +``` + +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. + +## Source + +Wikipedia [https://en.wikipedia.org/wiki/Rational_number](https://en.wikipedia.org/wiki/Rational_number) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/rational-numbers/example.js b/exercises/rational-numbers/example.js new file mode 100644 index 00000000..cd95bdc1 --- /dev/null +++ b/exercises/rational-numbers/example.js @@ -0,0 +1,69 @@ +function Rational(numerator, denominator) { + if (denominator === 0) {throw new Error('Denominator must not be zero.');} + + this.numerator = numerator; + this.denominator = denominator; + + this.reduce(); + this.ensureSignInNumerator(); +} + +Rational.prototype.add = function (that) { + var commonDenominator = this.denominator * that.denominator; + return new Rational(this.numerator * that.denominator + that.numerator * this.denominator, commonDenominator); +}; + +Rational.prototype.sub = function (that) { + var commonDenominator = this.denominator * that.denominator; + return new Rational(this.numerator * that.denominator - that.numerator * this.denominator, commonDenominator); +}; + +Rational.prototype.mul = function (that) { + return new Rational(this.numerator * that.numerator, this.denominator * that.denominator); +}; + +Rational.prototype.div = function (that) { + return new Rational(this.numerator * that.denominator, this.denominator * that.numerator); +}; + +Rational.prototype.abs = function () { + return new Rational(Math.abs(this.numerator), Math.abs(this.denominator)); +}; + +Rational.prototype.exprational = function (n) { + return new Rational(Math.pow(this.numerator, n), Math.pow(this.denominator, n)); +}; + +Rational.prototype.expreal = function (base) { + return Math.pow(10.0, Math.log10(Math.pow(base, this.numerator)) / this.denominator); +}; + +Rational.prototype.reduce = function () { + var commonDivisor = this.gcd(this.numerator, this.denominator); + + this.numerator /= commonDivisor; + this.denominator /= commonDivisor; + this.ensureSignInNumerator(); + + return this; +}; + +Rational.prototype.gcd = function (a, b) { + var localA = a; + var localB = b; + while (localB !== 0) { + var t = localB; + localB = localA % localB; + localA = t; + } + return localA; +}; + +Rational.prototype.ensureSignInNumerator = function () { + if (this.denominator < 0) { + this.denominator = -this.denominator; + this.numerator = -this.numerator; + } +}; + +module.exports = Rational; diff --git a/exercises/rational-numbers/rational-numbers.spec.js b/exercises/rational-numbers/rational-numbers.spec.js new file mode 100644 index 00000000..b11c7ed3 --- /dev/null +++ b/exercises/rational-numbers/rational-numbers.spec.js @@ -0,0 +1,197 @@ +var Rational = require('./rational-numbers'); + +describe('Addition', function () { + it('Add two positive rational numbers', function () { + var expected = new Rational(7, 6); + expect(new Rational(1, 2).add(new Rational(2, 3))).toEqual(expected); + }); + + xit('Add a positive rational number and a negative rational number', function () { + var expected = new Rational(-1, 6); + expect(new Rational(1, 2).add(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Add two negative rational numbers', function () { + var expected = new Rational(-7, 6); + expect(new Rational(-1, 2).add(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Add a rational number to its additive inverse', function () { + var expected = new Rational(0, 1); + expect(new Rational(1, 2).add(new Rational(-1, 2))).toEqual(expected); + }); +}); + +describe('Subtraction', function () { + xit('Subtract two positive rational numbers', function () { + var expected = new Rational(-1, 6); + expect(new Rational(1, 2).sub(new Rational(2, 3))).toEqual(expected); + }); + + xit('Subtract a positive rational number and a negative rational number', function () { + var expected = new Rational(7, 6); + expect(new Rational(1, 2).sub(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Subtract two negative rational numbers', function () { + var expected = new Rational(1, 6); + expect(new Rational(-1, 2).sub(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Subtract a rational number from itself', function () { + var expected = new Rational(0, 1); + expect(new Rational(1, 2).sub(new Rational(1, 2))).toEqual(expected); + }); +}); + +describe('Multiplication', function () { + xit('Multiply two positive rational numbers', function () { + var expected = new Rational(1, 3); + expect(new Rational(1, 2).mul(new Rational(2, 3))).toEqual(expected); + }); + + xit('Multiply a negative rational number by a positive rational number', function () { + var expected = new Rational(-1, 3); + expect(new Rational(-1, 2).mul(new Rational(2, 3))).toEqual(expected); + }); + + xit('Multiply two negative rational numbers', function () { + var expected = new Rational(1, 3); + expect(new Rational(-1, 2).mul(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Multiply a rational number by its reciprocal', function () { + var expected = new Rational(1, 1); + expect(new Rational(1, 2).mul(new Rational(2, 1))).toEqual(expected); + }); + + xit('Multiply a rational number by 1', function () { + var expected = new Rational(1, 2); + expect(new Rational(1, 2).mul(new Rational(1, 1))).toEqual(expected); + }); + + xit('Multiply a rational number by 0', function () { + var expected = new Rational(0, 1); + expect(new Rational(1, 2).mul(new Rational(0, 1))).toEqual(expected); + }); +}); + +describe('Division', function () { + xit('Divide two positive rational numbers', function () { + var expected = new Rational(3, 4); + expect(new Rational(1, 2).div(new Rational(2, 3))).toEqual(expected); + }); + + xit('Divide a positive rational number by a negative rational number', function () { + var expected = new Rational(-3, 4); + expect(new Rational(1, 2).div(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Divide two negative rational numbers', function () { + var expected = new Rational(3, 4); + expect(new Rational(-1, 2).div(new Rational(-2, 3))).toEqual(expected); + }); + + xit('Divide a rational number by 1', function () { + var expected = new Rational(1, 2); + expect(new Rational(1, 2).div(new Rational(1, 1))).toEqual(expected); + }); +}); + +describe('Absolute value', function () { + xit('Absolute value of a positive rational number', function () { + var expected = new Rational(1, 2); + expect(new Rational(1, 2).abs()).toEqual(expected); + }); + + xit('Absolute value of a negative rational number', function () { + var expected = new Rational(1, 2); + expect(new Rational(-1, 2).abs()).toEqual(expected); + }); + + xit('Absolute value of zero', function () { + var expected = new Rational(0, 1); + expect(new Rational(0, 1).abs()).toEqual(expected); + }); +}); + +describe('Exponentiation of a rational number', function () { + xit('Raise a positive rational number to a positive integer power', function () { + var expected = new Rational(1, 8); + expect(new Rational(1, 2).exprational(3)).toEqual(expected); + }); + + xit('Raise a negative rational number to a positive integer power', function () { + var expected = new Rational(-1, 8); + expect(new Rational(-1, 2).exprational(3)).toEqual(expected); + }); + + xit('Raise zero to an integer power', function () { + var expected = new Rational(0, 1); + expect(new Rational(0, 1).exprational(5)).toEqual(expected); + }); + + xit('Raise one to an integer power', function () { + var expected = new Rational(1, 1); + expect(new Rational(1, 1).exprational(4)).toEqual(expected); + }); + + xit('Raise a positive rational number to the power of zero', function () { + var expected = new Rational(1, 1); + expect(new Rational(1, 2).exprational(0)).toEqual(expected); + }); + + xit('Raise a negative rational number to the power of zero', function () { + var expected = new Rational(1, 1); + expect(new Rational(-1, 2).exprational(0)).toEqual(expected); + }); +}); + +describe('Exponentiation of a real number to a rational number', function () { + xit('Raise a real number to a positive rational number', function () { + var expected = 16.0; + expect(new Rational(4, 3).expreal(8)).toEqual(expected); + }); + + xit('Raise a real number to a negative rational number', function () { + var expected = 0.3333333333333333; + expect(new Rational(-1, 2).expreal(9)).toEqual(expected); + }); + + xit('Raise a real number to a zero rational number', function () { + var expected = 1.0; + expect(new Rational(0, 1).expreal(2)).toEqual(expected); + }); +}); + +describe('Reduction to lowest terms', function () { + xit('Reduce a positive rational number to lowest terms', function () { + var expected = new Rational(1, 2); + expect(new Rational(2, 4).reduce()).toEqual(expected); + }); + + xit('Reduce a negative rational number to lowest terms', function () { + var expected = new Rational(-2, 3); + expect(new Rational(-4, 6).reduce()).toEqual(expected); + }); + + xit('Reduce a rational number with a negative denominator to lowest terms', function () { + var expected = new Rational(-1, 3); + expect(new Rational(3, -9).reduce()).toEqual(expected); + }); + + xit('Reduce zero to lowest terms', function () { + var expected = new Rational(0, 1); + expect(new Rational(0, 6).reduce()).toEqual(expected); + }); + + xit('Reduce an integer to lowest terms', function () { + var expected = new Rational(-2, 1); + expect(new Rational(-14, 7).reduce()).toEqual(expected); + }); + + xit('Reduce one to lowest terms', function () { + var expected = new Rational(1, 1); + expect(new Rational(13, 13).reduce()).toEqual(expected); + }); +}); From 1b610b8c585fb86f524e414bc47936fbba82241d Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Thu, 1 Mar 2018 02:46:03 -0800 Subject: [PATCH 240/272] redo the bowling exericse to match the canonical tests and description (#496) --- exercises/bowling/bowling.spec.js | 146 ++++++++++++++++++------- exercises/bowling/example.js | 171 +++++++++++++++++++----------- 2 files changed, 217 insertions(+), 100 deletions(-) diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index 1d6746de..a507da47 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -1,147 +1,211 @@ var Bowling = require('./bowling'); describe('Bowling', function () { + function previousRolls(bowling, rolls) { + for (var i = 0; i < rolls.length; i++) { + bowling.roll(rolls[i]); + } + } describe('Check game can be scored correctly.', function () { it('should be able to score a game with all gutterballs', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(0); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(0); }); - xit('should be able to score a game with all open frames', function () { + xit('should be able to score a game with no strikes or spares', function () { var rolls = [3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6]; - expect(new Bowling(rolls).score()).toEqual(90); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(90); }); - xit('a spare followed by zeros is worth 10 points', function () { + xit('a spare followed by zeros is worth ten points', function () { var rolls = [6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(10); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(10); }); xit('points scored in the roll after a spare are counted twice', function () { var rolls = [6, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(16); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(16); }); xit('consecutive spares each get a one-roll bonus', function () { var rolls = [5, 5, 3, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(31); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(31); }); - xit('should allow fill ball when the last frame is a spare', function () { + xit('should allow fill ball the last frame is a spare', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 7]; - expect(new Bowling(rolls).score()).toEqual(17); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(17); }); - xit('a strike earns 10 points in a frame with a single roll', function () { + xit('a strike earns ten points in a frame with a single roll', function () { var rolls = [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(10); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(10); }); xit('points scored in the two rolls after a strike are counted twice as a bonus', function () { var rolls = [10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(26); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(26); }); xit('should be able to score multiple strikes in a row', function () { var rolls = [10, 10, 10, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(new Bowling(rolls).score()).toEqual(81); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(81); }); xit('should allow fill balls when the last frame is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 1]; - expect(new Bowling(rolls).score()).toEqual(18); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(18); }); xit('rolling a spare with the two-roll bonus does not get a bonus roll', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 7, 3]; - expect(new Bowling(rolls).score()).toEqual(20); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(20); }); xit('strikes with the two-roll bonus do not get bonus rolls', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10]; - expect(new Bowling(rolls).score()).toEqual(30); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(30); }); xit('a strike with the one-roll bonus after a spare in the last frame does not get a bonus', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 10]; - expect(new Bowling(rolls).score()).toEqual(20); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(20); }); xit('should be able to score a perfect game', function () { var rolls = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]; - expect(new Bowling(rolls).score()).toEqual(300); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(300); }); }); describe('Check game rules.', function () { xit('rolls cannot score negative points', function () { - var rolls = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function () { new Bowling(rolls).score(); }).toThrow( - new Error('Pins must have a value from 0 to 10')); + var bowling = new Bowling(); + expect(function () {bowling.roll(-1);}).toThrow(new Error('Negative roll is invalid')); }); xit('a roll cannot score more than 10 points', function () { - var rolls = [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function () { new Bowling(rolls).score(); }).toThrow( - new Error('Pins must have a value from 0 to 10')); + var bowling = new Bowling(); + expect(function () {bowling.roll(11);}).toThrow( new Error('Pin count exceeds pins on the lane')); }); xit('two rolls in a frame cannot score more than 10 points', function () { - var rolls = [5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + bowling.roll(5); + expect(function () {bowling.roll(6);}).toThrow( new Error('Pin count exceeds pins on the lane')); + }); + + xit('bonus roll after a strike in the last frame cannot score more than 10 points', function () { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(11); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); xit('two bonus rolls after a strike in the last frame cannot score more than 10 points', function () { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 6]; - expect(function () { new Bowling(rolls).score(); }).toThrow( - new Error('Pin count exceeds pins on the lane')); + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () {bowling.roll(6);}).toThrow( new Error('Pin count exceeds pins on the lane')); }); xit('two bonus rolls after a strike in the last frame can score more than 10 points if one is a strike', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 6]; - expect(new Bowling(rolls).score()).toEqual(26); + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(bowling.score()).toEqual(26); }); xit('the second bonus roll after a strike in the last frame cannot be a strike if the first one is not a strike', function () { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6, 10]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 6]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(10); }).toThrow( + new Error('Pin count exceeds pins on the lane')); + }); + + xit('the second bonus roll after a strike in the last frame cannot score more than 10 points', function () { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(11); }).toThrow( new Error('Pin count exceeds pins on the lane')); }); xit('an unstarted game cannot be scored', function () { var rolls = []; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); xit('an incomplete game cannot be scored', function () { var rolls = [0, 0]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); - xit('a game with more than 10 frames and no last frame spare or strike cannot be scored', function () { - var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - expect(function () { new Bowling(rolls).score(); }).toThrow( - new Error('Should not be able to roll after game is over')); + xit('cannot roll if game already has 10 frames', function () { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(0); }).toThrow( + new Error('Cannot roll after game is over')); }); xit('bonus rolls for a strike in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); xit('both bonus rolls for a strike in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () {bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); xit('bonus roll for a spare in the last frame must be rolled before score can be calculated', function () { var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3]; - expect(function () { new Bowling(rolls).score(); }).toThrow( + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); }); diff --git a/exercises/bowling/example.js b/exercises/bowling/example.js index b46142ad..ea2a29b1 100644 --- a/exercises/bowling/example.js +++ b/exercises/bowling/example.js @@ -1,82 +1,135 @@ 'use strict'; -function Bowling(rolls) { - this.rolls = rolls; -} - -Bowling.prototype.score = function () { - var maxFrames = 10; +function Bowling() { var maxPins = 10; + var maxFrames = 10; + var frames = []; + var frameScores = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - var initialState = { - frameNumber: 1, - rollNumber: 1, - pinsRemaining: 10, - spareLastFrame: false, - strikeLastFrame: false, - twoStrikesInARow: false, - fillBall: false, - score: 0 - }; + var currentFrame = 0; + var frameRoll = 1; + var remainingPins = maxPins; - var finalState = this.rolls.reduce(function (state, roll) { - if (roll < 0 || roll > maxFrames ) { - throw new Error('Pins must have a value from 0 to 10'); - } + initializeFrame(); - if (roll > state.pinsRemaining) { - throw new Error('Pin count exceeds pins on the lane'); + function initializeFrame() { + frameRoll = 1; + remainingPins = maxPins; + currentFrame++; + } + + function incrementScore(pins) { + if (currentFrame > maxFrames) return; + frameScores[currentFrame - 1] += pins; + } + + function scoreStrike() { + frames[currentFrame - 1] = 'X'; + applyStrikeBonus(maxPins); + applySpareBonus(maxPins); + frameRoll++; + } + + function scoreFirstRoll(pins) { + remainingPins = remainingPins - pins; + applySpareBonus(pins); + applyStrikeBonus(pins); + frameRoll++; + } + + function scoreSpare(pins) { + frames[currentFrame - 1] = 'S'; + applyStrikeBonus(pins); + frameRoll++; + } + + function scoreOpenFrame(pins) { + frames[currentFrame - 1] = (maxPins - remainingPins) + pins; + applyStrikeBonus(pins); + frameRoll++; + } + + function applySpareBonus(pins) { + // pins on the first roll after a spare are counted twice (on the frame of spare) + if (frames[currentFrame - 2] === 'S' ) { + frameScores[currentFrame - 2] += pins; } + } - if (state.frameNumber > maxFrames ) { - throw new Error('Should not be able to roll after game is over'); + function applyStrikeBonus(pins) { + // on the two rolls after a strike are counted twice (on the frame of the strike) + if (frames[currentFrame - 3] === 'X' && frames[currentFrame - 2] === 'X' && + frameRoll === 1 && currentFrame <= (maxFrames + 2)) { + frameScores[currentFrame - 3] += pins; + } + if (frames[currentFrame - 2] === 'X' && currentFrame <= (maxFrames + 1)) { + frameScores[currentFrame - 2] += pins; } + } - var finalFrame = state.frameNumber === maxFrames; - var strike = state.rollNumber === 1 && roll === 10; - var spare = state.rollNumber === 2 && roll === state.pinsRemaining; - var frameOver = finalFrame - ? (!state.fillBall && !spare && state.rollNumber === 2) || state.rollNumber === 3 - : strike || spare || state.rollNumber === 2; + function isGameOver() { + if (currentFrame <= maxFrames) return false; - var score = state.score + roll; + if (frames[maxFrames - 1] !== 'X' && frames[maxFrames - 1] !== 'S') return true; - if (state.strikeLastFrame && state.rollNumber < 3) { score = incrementScore(score, roll); } - if (state.spareLastFrame && state.rollNumber === 1) { score = incrementScore(score, roll); } - if (state.twoStrikesInARow && state.rollNumber === 1) { score = incrementScore(score, roll); } + // spare in the last frame gets no more than bonus roll + if (frames[maxFrames - 1] === 'S' && frameRoll > 1) return true; - var next = {}; + // bonus roll after the spare in the last frame may get a strike but then the games ends without another roll + if (frames[maxFrames - 1] === 'S' && frames[maxFrames] === 'X') return true; - next.frameNumber = frameOver ? state.frameNumber + 1 : state.frameNumber; - next.rollNumber = frameOver ? 1 : state.rollNumber + 1; - if ( finalFrame ) { - next.pinsRemaining = (strike || spare) ? maxPins : pinsRemaining(state.pinsRemaining, roll); - } else { - next.pinsRemaining = frameOver ? maxPins : pinsRemaining(state.pinsRemaining, roll); + if (frames[maxFrames - 1] === 'X') { + // if the first bonus roll is not a strike then finish the bonus frame + if (frames[maxFrames] !== 'X' && currentFrame > maxFrames + 1) return true; + + if (frames[maxFrames] === 'X') { + // if the second bonus roll is a strike, but was still used, the game is over + if (frames[maxFrames + 1] !== 'X' && frameRoll > 1) return true; + // if the second bonus roll is a strike the game is over + if (frames[maxFrames + 1] === 'X') return true; + } } - next.spareLastFrame = frameOver ? spare : state.spareLastFrame; - next.strikeLastFrame = frameOver ? strike : state.strikeLastFrame; - next.twoStrikesInARow = frameOver ? strike && state.strikeLastFrame : state.twoStrikesInARow; - next.fillBall = next.fillBall || (finalFrame && (strike || spare)); - next.score = score; + return false; + } - return next; - }, initialState); + this.roll = function (pins) { + if (pins < 0) { + throw new Error( 'Negative roll is invalid'); + } - if (finalState.frameNumber <= maxFrames ) { - throw new Error('Score cannot be taken until the end of the game'); - } + if (pins > remainingPins) { + throw new Error('Pin count exceeds pins on the lane'); + } - return finalState.score; -}; + if (isGameOver()) { + throw new Error('Cannot roll after game is over'); + } -function incrementScore(score, roll) { - return score + roll; -} + incrementScore(pins); -function pinsRemaining(pins, roll) { - return pins - roll; -} + if (frameRoll === 1) { + if (pins === maxPins) { + scoreStrike(); + initializeFrame(); + } else { + scoreFirstRoll(pins); + } + } else { + if (pins === remainingPins) { + scoreSpare(pins); + } else { + scoreOpenFrame(pins); + } + initializeFrame(); + } + }; + this.score = function () { + if (!isGameOver()) { + throw new Error('Score cannot be taken until the end of the game'); + } + return frameScores.reduce(function (total, num) {return total + num;}); + }; +} module.exports = Bowling; From c1dc998749a10eab3cd3e94bd8a3bf516c16f92b Mon Sep 17 00:00:00 2001 From: librorumque Date: Thu, 1 Mar 2018 17:52:18 +0700 Subject: [PATCH 241/272] Add rectangles exercise (#494) --- config.json | 12 +++ exercises/rectangles/README.md | 91 ++++++++++++++++++++ exercises/rectangles/example.js | 66 +++++++++++++++ exercises/rectangles/rectangles.spec.js | 108 ++++++++++++++++++++++++ 4 files changed, 277 insertions(+) create mode 100644 exercises/rectangles/README.md create mode 100644 exercises/rectangles/example.js create mode 100644 exercises/rectangles/rectangles.spec.js diff --git a/config.json b/config.json index b10b081d..83cc3bdc 100644 --- a/config.json +++ b/config.json @@ -1220,6 +1220,18 @@ "parsing", "domain_specific_languages" ] + }, + { + "uuid": "cb09212c-f2ae-4acf-9177-6c7f42594c1d", + "slug": "rectangles", + "core": false, + "unlocked_by": "grade-school", + "difficulty": 6, + "topics": [ + "parsing", + "searching", + "pattern_recognition" + ] } ], "foregone": [], diff --git a/exercises/rectangles/README.md b/exercises/rectangles/README.md new file mode 100644 index 00000000..362ed98c --- /dev/null +++ b/exercises/rectangles/README.md @@ -0,0 +1,91 @@ +# Rectangles + +Count the rectangles in an ASCII diagram like the one below. + +```text + +--+ + ++ | ++-++--+ +| | | ++--+--+ +``` + +The above diagram contains 6 rectangles: + +```text + + ++-----+ +| | ++-----+ +``` + +```text + +--+ + | | + | | + | | + +--+ +``` + +```text + +--+ + | | + +--+ + + +``` + +```text + + + +--+ + | | + +--+ +``` + +```text + + ++--+ +| | ++--+ +``` + +```text + + ++ + ++ + + +``` + +You may assume that the input is always a proper rectangle (i.e. the length of +every line equals the length of the first line). + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/rectangles/example.js b/exercises/rectangles/example.js new file mode 100644 index 00000000..f9cb52c3 --- /dev/null +++ b/exercises/rectangles/example.js @@ -0,0 +1,66 @@ +var GLYPH = { corner: '+', edgeV: '|', edgeH: '-' }; + +var Vertex = function () { + this.right = []; + this.down = []; +}; + +// number of rectangles with given top left corner +Vertex.prototype.findRectangles = function () { + var corners = []; + var rectangles = 0; + + this.right.forEach(function (topLeft) { + topLeft.down.forEach(function (bottomRight) { + corners.push(bottomRight); + }); + }); + this.down.forEach(function (bottomLeft) { + bottomLeft.right.forEach(function (bottomRight) { + if (corners.indexOf(bottomRight) >= 0) { + rectangles++; + } + }); + }); + return rectangles; +}; + +// finds connected corners right and down from every corner +var toVertices = function (grid) { + var vertices = []; + grid.forEach(function (row, y) { + row.forEach(function (cell, x) { + if (cell === GLYPH.corner) { + var newVert = new Vertex(); + var side; + + vertices.push(newVert); + grid[y][x] = newVert; // replace glyph with the vertex + for (var u = y - 1; u >= 0; u--) { // search *up* along the side + side = grid[u][x]; + if (side instanceof Vertex) side.down.push(newVert); + else if (side !== GLYPH.edgeV) break; + } + for (var l = x - 1; l >= 0; l--) { // search *left* along the side + side = grid[y][l]; + if (side instanceof Vertex) side.right.push(newVert); + else if (side !== GLYPH.edgeH) break; + } + } + }); + }); + return vertices; +}; + +var rectangles = function (input) { + var grid; + var corners; + + grid = input.map(function (row) { return row.split(''); }); + corners = toVertices(grid); + return corners.reduce(function (total, vert) { + return total + vert.findRectangles(); + }, 0); +}; + +module.exports = rectangles; diff --git a/exercises/rectangles/rectangles.spec.js b/exercises/rectangles/rectangles.spec.js new file mode 100644 index 00000000..af89e07d --- /dev/null +++ b/exercises/rectangles/rectangles.spec.js @@ -0,0 +1,108 @@ +var rectangles = require('./rectangles'); + +describe('Rectangles', function () { + it('no rows', function () { + expect(rectangles([])).toBe(0); + }); + + xit('no columns', function () { + expect(rectangles([''])).toBe(0); + }); + + xit('no rectangles', function () { + expect(rectangles([' '])).toBe(0); + }); + + xit('one rectangle', function () { + var input = [ + '+-+', + '| |', + '+-+']; + expect(rectangles(input)).toBe(1); + }); + + xit('two rectangles without shared parts', function () { + var input = [ + ' +-+', + ' | |', + '+-+-+', + '| | ', + '+-+ ']; + expect(rectangles(input)).toBe(2); + }); + + xit('five rectangles with shared parts', function () { + var input = [ + ' +-+', + ' | |', + '+-+-+', + '| | |', + '+-+-+']; + expect(rectangles(input)).toBe(5); + }); + + xit('rectangle of height 1 is counted', function () { + var input = [ + '+--+', + '+--+']; + expect(rectangles(input)).toBe(1); + }); + + xit('rectangle of width 1 is counted', function () { + var input = [ + '++', + '||', + '++']; + expect(rectangles(input)).toBe(1); + }); + + xit('1x1 square is counted', function () { + var input = [ + '++', + '++']; + expect(rectangles(input)).toBe(1); + }); + + xit('only complete rectangles are counted', function () { + var input = [ + ' +-+', + ' |', + '+-+-+', + '| | -', + '+-+-+']; + expect(rectangles(input)).toBe(1); + }); + + xit('rectangles can be of different sizes', function () { + var input = [ + '+------+----+', + '| | |', + '+---+--+ |', + '| | |', + '+---+-------+']; + expect(rectangles(input)).toBe(3); + }); + + xit('corner is required for a rectangle to be complete', function () { + var input = [ + '+------+----+', + '| | |', + '+------+ |', + '| | |', + '+---+-------+']; + expect(rectangles(input)).toBe(2); + }); + + xit('large input with many rectangles', function () { + var input = [ + '+---+--+----+', + '| +--+----+', + '+---+--+ |', + '| +--+----+', + '+---+--+--+-+', + '+---+--+--+-+', + '+------+ | |', + ' +-+']; + expect(rectangles(input)).toBe(60); + }); +}); From 33dbffb7ae08f60aa79b6afbdf88770dc44e23da Mon Sep 17 00:00:00 2001 From: librorumque Date: Thu, 1 Mar 2018 17:59:11 +0700 Subject: [PATCH 242/272] Add variable-length-quantity exercise (#493) --- config.json | 11 ++ exercises/variable-length-quantity/README.md | 62 ++++++++++ exercises/variable-length-quantity/example.js | 51 ++++++++ .../variable-length-quantity.spec.js | 115 ++++++++++++++++++ 4 files changed, 239 insertions(+) create mode 100644 exercises/variable-length-quantity/README.md create mode 100644 exercises/variable-length-quantity/example.js create mode 100644 exercises/variable-length-quantity/variable-length-quantity.spec.js diff --git a/config.json b/config.json index 83cc3bdc..035b9e1b 100644 --- a/config.json +++ b/config.json @@ -1221,6 +1221,17 @@ "domain_specific_languages" ] }, + { + "uuid": "f82e470d-0bcc-4eba-b9b0-8a0c50a6fd19", + "slug": "variable-length-quantity", + "core": false, + "unlocked_by": "two-bucket", + "difficulty": 5, + "topics": [ + "bitwise_operations", + "transforming" + ] + }, { "uuid": "cb09212c-f2ae-4acf-9177-6c7f42594c1d", "slug": "rectangles", diff --git a/exercises/variable-length-quantity/README.md b/exercises/variable-length-quantity/README.md new file mode 100644 index 00000000..7e1203a4 --- /dev/null +++ b/exercises/variable-length-quantity/README.md @@ -0,0 +1,62 @@ +# Variable Length Quantity + +Implement variable length quantity encoding and decoding. + +The goal of this exercise is to implement [VLQ](https://en.wikipedia.org/wiki/Variable-length_quantity) encoding/decoding. + +In short, the goal of this encoding is to encode integer values in a way that would save bytes. +Only the first 7 bits of each byte is significant (right-justified; sort of like an ASCII byte). +So, if you have a 32-bit value, you have to unpack it into a series of 7-bit bytes. +Of course, you will have a variable number of bytes depending upon your integer. +To indicate which is the last byte of the series, you leave bit #7 clear. +In all of the preceding bytes, you set bit #7. + +So, if an integer is between `0-127`, it can be represented as one byte. +Although VLQ can deal with numbers of arbitrary sizes, for this exercise we will restrict ourselves to only numbers that fit in a 32-bit unsigned integer. +Here are examples of integers as 32-bit values, and the variable length quantities that they translate to: + +```text + NUMBER VARIABLE QUANTITY +00000000 00 +00000040 40 +0000007F 7F +00000080 81 00 +00002000 C0 00 +00003FFF FF 7F +00004000 81 80 00 +00100000 C0 80 00 +001FFFFF FF FF 7F +00200000 81 80 80 00 +08000000 C0 80 80 00 +0FFFFFFF FF FF FF 7F +``` + +## Setup + +Go through the setup instructions for JavaScript to +install the necessary dependencies: + +http://exercism.io/languages/javascript + +## Making the Test Suite Pass + +Execute the tests with: + + jasmine .spec.js + +Replace `` with the name of the current exercise. E.g., to +test the Hello World exercise: + + jasmine hello-world.spec.js + +In many test suites all but the first test have been skipped. + +Once you get a test passing, you can unskip the next one by +changing `xit` to `it`. + +## Source + +A poor Splice developer having to implement MIDI encoding/decoding. [https://splice.com](https://splice.com) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/variable-length-quantity/example.js b/exercises/variable-length-quantity/example.js new file mode 100644 index 00000000..9aeec820 --- /dev/null +++ b/exercises/variable-length-quantity/example.js @@ -0,0 +1,51 @@ +var LENGTH = 7; +var CONT_BITS = 1 << LENGTH; +var DATA_BITS = CONT_BITS - 1; + +var encodeOne = function (val) { + var buf = []; + var left = val; + + while (left) { + var bits = left & DATA_BITS | CONT_BITS; // set continuation everywhere + left = left >>> LENGTH; + buf.push(bits); + } + buf[0] = buf[0] & DATA_BITS; // cancel the last continuation + return buf.reverse(); +}; + +var decodeOne = function (buf) { + var val = 0; + + for (var i = 0; i < buf.length; i++) { + val = val << LENGTH | buf[i] & DATA_BITS; + } + return val >>> 0; // convert to unsigned 32-bit +}; + +module.exports = { + encode: function encode(data) { + var buf = []; + + for (var i = 0; i < data.length; i++) { + buf = buf.concat(encodeOne(data[i])); + } + return buf; + }, + decode: function decode(data) { + var start = 0; + var vals = []; + + for (var i = 0; i < data.length; i++) { + if (~data[i] & CONT_BITS) { + vals.push(decodeOne(data.slice(start, i + 1))); + start = i + 1; + } + } + if (start < data.length) { + throw new Error('Incomplete sequence'); + } + return vals; + } +}; diff --git a/exercises/variable-length-quantity/variable-length-quantity.spec.js b/exercises/variable-length-quantity/variable-length-quantity.spec.js new file mode 100644 index 00000000..43d066dc --- /dev/null +++ b/exercises/variable-length-quantity/variable-length-quantity.spec.js @@ -0,0 +1,115 @@ +var VLQ = require('./variable-length-quantity'); + +describe('VariableLengthQuantity', function () { + describe('Encode a series of integers, producing a series of bytes.', function () { + it('zero', function () { + expect(VLQ.encode([0])).toEqual([0]); + }); + + it('arbitrary single byte', function () { + expect(VLQ.encode([0x40])).toEqual([0x40]); + }); + + it('largest single byte', function () { + expect(VLQ.encode([0x7f])).toEqual([0x7f]); + }); + + it('smallest double byte', function () { + expect(VLQ.encode([0x80])).toEqual([0x81, 0]); + }); + + it('arbitrary double byte', function () { + expect(VLQ.encode([0x2000])).toEqual([0xc0, 0]); + }); + + it('largest double byte', function () { + expect(VLQ.encode([0x3fff])).toEqual([0xff, 0x7f]); + }); + + it('smallest triple byte', function () { + expect(VLQ.encode([0x4000])).toEqual([0x81, 0x80, 0]); + }); + + it('arbitrary triple byte', function () { + expect(VLQ.encode([0x100000])).toEqual([0xc0, 0x80, 0]); + }); + + it('largest triple byte', function () { + expect(VLQ.encode([0x1fffff])).toEqual([0xff, 0xff, 0x7f]); + }); + + it('smallest quadruple byte', function () { + expect(VLQ.encode([0x200000])).toEqual([0x81, 0x80, 0x80, 0]); + }); + + it('arbitrary quadruple byte', function () { + expect(VLQ.encode([0x8000000])).toEqual([0xc0, 0x80, 0x80, 0]); + }); + + it('largest quadruple byte', function () { + expect(VLQ.encode([0xfffffff])).toEqual([0xff, 0xff, 0xff, 0x7f]); + }); + + it('smallest quintuple byte', function () { + expect(VLQ.encode([0x10000000])).toEqual([0x81, 0x80, 0x80, 0x80, 0]); + }); + + it('arbitrary quintuple byte', function () { + expect(VLQ.encode([0xff000000])).toEqual([0x8f, 0xf8, 0x80, 0x80, 0]); + }); + + it('maximum 32-bit integer input', function () { + expect(VLQ.encode([0xffffffff])).toEqual([0x8f, 0xff, 0xff, 0xff, 0x7f]); + }); + + it('two single-byte values', function () { + expect(VLQ.encode([0x40, 0x7f])).toEqual([0x40, 0x7f]); + }); + + it('two multi-byte values', function () { + expect(VLQ.encode([0x4000, 0x123456])).toEqual([0x81, 0x80, 0, 0xc8, 0xe8, 0x56]); + }); + + it('many multi-byte values', function () { + var input = [0x2000, 0x123456, 0xfffffff, 0, 0x3fff, 0x4000]; + var expected = [0xc0, 0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0, 0xff, 0x7f, 0x81, 0x80, 0]; + expect(VLQ.encode(input)).toEqual(expected); + }); + }); + + describe('Decode a series of bytes, producing a series of integers.', function () { + it('one byte', function () { + expect(VLQ.decode([0x7f])).toEqual([0x7f]); + }); + + it('two bytes', function () { + expect(VLQ.decode([0xc0, 0])).toEqual([0x2000]); + }); + + it('three bytes', function () { + expect(VLQ.decode([0xff, 0xff, 0x7f])).toEqual([0x1fffff]); + }); + + it('four bytes', function () { + expect(VLQ.decode([0x81, 0x80, 0x80, 0])).toEqual([0x200000]); + }); + + it('maximum 32-bit integer', function () { + expect(VLQ.decode([0x8f, 0xff, 0xff, 0xff, 0x7f])).toEqual([0xffffffff]); + }); + + it('incomplete sequence causes error', function () { + expect(function () { VLQ.decode([0xff]); }).toThrow(new Error('Incomplete sequence')); + }); + + it('incomplete sequence causes error, even if value is zero', function () { + expect(function () { VLQ.decode([0x80]); }).toThrow(new Error('Incomplete sequence')); + }); + + it('multiple values', function () { + var input = [0xc0, 0, 0xc8, 0xe8, 0x56, 0xff, 0xff, 0xff, 0x7f, 0, 0xff, 0x7f, 0x81, 0x80, 0]; + var expected = [0x2000, 0x123456, 0xfffffff, 0, 0x3fff, 0x4000]; + expect(VLQ.decode(input)).toEqual(expected); + }); + }); +}); From 9048b56438223a1fb8154648de2a4ae411a5881d Mon Sep 17 00:00:00 2001 From: Allison Zhao Date: Thu, 1 Mar 2018 17:42:20 -0500 Subject: [PATCH 243/272] Fix flatten array (#515) * Initial commit * Fix flatten array linting error --- .eslintignore | 1 - exercises/flatten-array/example.js | 11 +++---- exercises/flatten-array/flatten-array.spec.js | 30 +++++++++---------- package.json | 6 ++-- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/.eslintignore b/.eslintignore index a6052eb7..786fb1bd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,5 @@ big-integer.js exercises/custom-set -exercises/flatten-array exercises/grade-school exercises/grains/big-integer.js exercises/grains/big-integer.spec.js diff --git a/exercises/flatten-array/example.js b/exercises/flatten-array/example.js index 63ab232b..658eb26e 100644 --- a/exercises/flatten-array/example.js +++ b/exercises/flatten-array/example.js @@ -1,11 +1,12 @@ -var Flattener = function () {}; +var Flattener = function () { }; -Flattener.prototype.flatten = function (unflattenedArray, flattenedArray) { - var self = this, flattenedArray = flattenedArray || []; +Flattener.prototype.flatten = function (unflattenedArray, inputFlattenedArray) { + var self = this; + var flattenedArray = inputFlattenedArray || []; unflattenedArray.forEach(function (element) { if (Array.isArray(element)) { - return self.flatten(element, flattenedArray); - } else if ( element !== null) { + self.flatten(element, flattenedArray); + } else if (element !== null) { flattenedArray.push(element); } }); diff --git a/exercises/flatten-array/flatten-array.spec.js b/exercises/flatten-array/flatten-array.spec.js index 6080fe07..4c5be05f 100644 --- a/exercises/flatten-array/flatten-array.spec.js +++ b/exercises/flatten-array/flatten-array.spec.js @@ -3,24 +3,24 @@ var Flattener = require('./flatten-array.js'); describe('FlattenArray', function () { var flattener = new Flattener(); it('flattens a nested list', function () { - expect(flattener.flatten([[]])).toEqual([]); - }); + expect(flattener.flatten([[]])).toEqual([]); + }); xit('flattens a 2 level nested list', function () { - expect(flattener.flatten([1, [2, 3, 4], 5])).toEqual([1, 2, 3, 4, 5]); - }); + expect(flattener.flatten([1, [2, 3, 4], 5])).toEqual([1, 2, 3, 4, 5]); + }); xit('flattens a 3 level nested list', function () { - expect(flattener.flatten([1, [2, 3, 4], 5, [6, [7, 8]]])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); - }); - xit('flattens a 5 level nested list', function () { - expect(flattener.flatten([0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2])).toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); - }); + expect(flattener.flatten([1, [2, 3, 4], 5, [6, [7, 8]]])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + }); + xit('flattens a 5 level nested list', function () { + expect(flattener.flatten([0, 2, [[2, 3], 8, 100, 4, [[[50]]]], -2])).toEqual([0, 2, 2, 3, 8, 100, 4, 50, -2]); + }); xit('flattens a 6 level nest list', function () { - expect(flattener.flatten([1, [2, [[3]], [4, [[5]]], 6, 7], 8])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); - }); + expect(flattener.flatten([1, [2, [[3]], [4, [[5]]], 6, 7], 8])).toEqual([1, 2, 3, 4, 5, 6, 7, 8]); + }); xit('flattens a 6 level nest list with null values', function () { - expect(flattener.flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([0, 2, 2, 3, 8, 100, -2]); - }); + expect(flattener.flatten([0, 2, [[2, 3], 8, [[100]], null, [[null]]], -2])).toEqual([0, 2, 2, 3, 8, 100, -2]); + }); xit('returns an empty list if all values in nested list are null', function () { - expect(flattener.flatten([null, [[[null]]], null, null, [[null, null], null], null])).toEqual([]); - }); + expect(flattener.flatten([null, [[[null]]], null, null, [[null, null], null], null])).toEqual([]); + }); }); diff --git a/package.json b/package.json index cac2593c..8ab06dbf 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,11 @@ "lint-fix": "eslint . --fix" }, "eslintConfig": { - "plugins": ["jasmine"], + "plugins": [ + "jasmine" + ], "env": { - "jasmine": true + "jasmine": true }, "extends": "eslint-config-airbnb-es5", "rules": { From e1fd38e38bdd9a9087d1a024c74a27ea56c912f2 Mon Sep 17 00:00:00 2001 From: Mina Slater Date: Thu, 1 Mar 2018 16:43:15 -0600 Subject: [PATCH 244/272] fixes linting errors for perfect numbers exercise (#508) --- .eslintignore | 1 - exercises/perfect-numbers/example.js | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 786fb1bd..0b7d3a1f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,7 +7,6 @@ exercises/kindergarten-garden exercises/linked-list exercises/minesweeper exercises/nth-prime -exercises/perfect-numbers exercises/queen-attack exercises/robot-simulator exercises/saddle-points diff --git a/exercises/perfect-numbers/example.js b/exercises/perfect-numbers/example.js index c7fcdd76..ad7c1c6e 100644 --- a/exercises/perfect-numbers/example.js +++ b/exercises/perfect-numbers/example.js @@ -7,10 +7,12 @@ var PerfectNumbers = function () { /** * Calculate all the divisors for a given number and return them as an array. * Note: the actual number is not include in the returned array. + * @param {number} number - a number input. + * @returns {array} - the array of divisors */ PerfectNumbers.prototype.getDivisors = function (number) { var i; - var divs = new Array(); + var divs = []; // Accepts only natura numbers greater than 1. if (number <= 1) { @@ -31,7 +33,9 @@ PerfectNumbers.prototype.getDivisors = function (number) { }; PerfectNumbers.prototype.classify = function (number) { - var i, sum, result; + var i; + var sum; + var result; // Check if the input is valid if (number <= 0) { From 32cf4cfc6ab61bd0a080e8cb6d1d63ce1d96173d Mon Sep 17 00:00:00 2001 From: Jeffrey Berman <30912433+twistyjeffrey@users.noreply.github.com> Date: Thu, 1 Mar 2018 16:48:57 -0600 Subject: [PATCH 245/272] fixes styling for kindergarten garden (#511) --- .eslintignore | 1 - exercises/kindergarten-garden/example.js | 18 +++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index 0b7d3a1f..327203af 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,7 +3,6 @@ exercises/custom-set exercises/grade-school exercises/grains/big-integer.js exercises/grains/big-integer.spec.js -exercises/kindergarten-garden exercises/linked-list exercises/minesweeper exercises/nth-prime diff --git a/exercises/kindergarten-garden/example.js b/exercises/kindergarten-garden/example.js index 725585b1..0fc7f6c4 100644 --- a/exercises/kindergarten-garden/example.js +++ b/exercises/kindergarten-garden/example.js @@ -23,13 +23,13 @@ var plants = { }; function getPlants(pots, index) { - var plants = []; + var plantsArr = []; var position = 2 * index; - plants.push(pots[0][position]); - plants.push(pots[0][position + 1]); - plants.push(pots[1][position]); - plants.push(pots[1][position + 1]); - return plants; + plantsArr.push(pots[0][position]); + plantsArr.push(pots[0][position + 1]); + plantsArr.push(pots[1][position]); + plantsArr.push(pots[1][position + 1]); + return plantsArr; } function parse(diagram) { @@ -42,10 +42,10 @@ function parse(diagram) { function Garden(diagram, students) { var instance = {}; - students = students || defaultChildren; - students.sort(); + var kids = students || defaultChildren; + kids.sort(); - students.forEach(function (student, index) { + kids.forEach(function (student, index) { instance[student.toLowerCase()] = getPlants(parse(diagram), index); }); From a5df83aa4b2afb498f726650dc6bf3779311fada Mon Sep 17 00:00:00 2001 From: Allison Zhao Date: Thu, 1 Mar 2018 18:01:01 -0500 Subject: [PATCH 246/272] Fix custom-set linting errors (#513) * Initial commit * Fix custom-set linting errors --- exercises/custom-set/example-gen.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/custom-set/example-gen.js b/exercises/custom-set/example-gen.js index c791c799..f27732f6 100644 --- a/exercises/custom-set/example-gen.js +++ b/exercises/custom-set/example-gen.js @@ -160,7 +160,7 @@ function renderSuite(tests, otherTests, suiteTemplate) { return suiteTemplate(tests.concat(otherTests)); } -function suiteTemplate(tests) { +function suiteTemplateFn(tests) { return ( `var CustomSet = require('./custom-set'); @@ -179,8 +179,8 @@ function testTemplate(isEnabled, description, body) { `); } -function array(array) { - return array.length === 0 ? '' : `[${array.join(', ')}]`; +function array(arr) { + return arr.length === 0 ? '' : `[${arr.join(', ')}]`; } function generate() { @@ -193,7 +193,7 @@ function generate() { suiteData: suiteData, testBodyTemplates: TEST_BODY_TEMPLATES, extraTests: NON_CANONICAL_TESTS, - suiteTemplate: suiteTemplate + suiteTemplate: suiteTemplateFn })); } From 4e2ef3eb6d40d4f8dbda274902622c5f21577c78 Mon Sep 17 00:00:00 2001 From: Samidh Desai <34141113+SamDesai333@users.noreply.github.com> Date: Fri, 2 Mar 2018 16:52:19 -0600 Subject: [PATCH 247/272] fixes styling in grade-school (#512) * fixes styling in grade-school * updates variable gradeLvl to gradeLevel --- .eslintignore | 2 +- exercises/grade-school/example.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.eslintignore b/.eslintignore index 327203af..dd2770ce 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,6 @@ big-integer.js exercises/custom-set -exercises/grade-school +exercises/flatten-array exercises/grains/big-integer.js exercises/grains/big-integer.spec.js exercises/linked-list diff --git a/exercises/grade-school/example.js b/exercises/grade-school/example.js index f43c127e..2e81015c 100644 --- a/exercises/grade-school/example.js +++ b/exercises/grade-school/example.js @@ -1,11 +1,11 @@ module.exports = function School() { var db = {}; - function add(student, grade) { - if (db[grade]) { - db[grade].push(student); + function add(student, gradeLevel) { + if (db[gradeLevel]) { + db[gradeLevel].push(student); } else { - db[grade] = [student]; + db[gradeLevel] = [student]; } } @@ -14,8 +14,8 @@ module.exports = function School() { } function roster() { - return sortedGrades().reduce(function (sorted, grade) { - sorted[grade] = clone(db[grade]).sort(); + return sortedGrades().reduce(function (sorted, gradeLevel) { + sorted[gradeLevel] = clone(db[gradeLevel]).sort(); return sorted; }, {}); } From d43f103403b7e03b19429382699016eee199099e Mon Sep 17 00:00:00 2001 From: Susan Lippa Date: Sun, 4 Mar 2018 06:01:33 -0600 Subject: [PATCH 248/272] Issue#399 queen-attack (#518) * queen-attack & linked-lists linted * Revert "queen-attack & linked-lists linted" This reverts commit 6e0aa7089d33cec19da3a8faadc427f6a4c6a391. * queen-attack linting * queen-attack revision 3/2pm * Update example.js * Update example.js * queen-attack continues * queen-attack linting * queen-attack adj for var --- exercises/queen-attack/example.js | 10 +++++----- exercises/queen-attack/queen-attack.spec.js | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/exercises/queen-attack/example.js b/exercises/queen-attack/example.js index 50016f39..ebe07a5d 100644 --- a/exercises/queen-attack/example.js +++ b/exercises/queen-attack/example.js @@ -1,12 +1,11 @@ 'use strict'; -module.exports = function (options) { - if (options === undefined) { - options = { white: [0, 3], black: [7, 3] }; - } + +module.exports = function (passedInOptions) { + var options = passedInOptions || {white: [0, 3], black: [7, 3]}; if (options.white[0] === options.black[0] && options.white[1] === options.black[1]) { - throw 'Queens cannot share the same space'; + throw String('Queens cannot share the same space'); } this.white = options.white; @@ -61,3 +60,4 @@ module.exports = function (options) { return this.boardRepresentation(); }; }; + diff --git a/exercises/queen-attack/queen-attack.spec.js b/exercises/queen-attack/queen-attack.spec.js index e51205be..b2d4525f 100644 --- a/exercises/queen-attack/queen-attack.spec.js +++ b/exercises/queen-attack/queen-attack.spec.js @@ -18,6 +18,8 @@ describe('Queens', function () { try { var queens = new Queens(positioning); + expect(queens.white).toEqual([2, 4]); + expect(queens.black).toEqual([2, 4]); } catch (error) { expect(error).toEqual('Queens cannot share the same space'); } @@ -26,15 +28,15 @@ describe('Queens', function () { xit('toString representation', function () { var positioning = {white: [2, 4], black: [6, 6]}; var queens = new Queens(positioning); - var board = '_ _ _ _ _ _ _ _\n\ -_ _ _ _ _ _ _ _\n\ -_ _ _ _ W _ _ _\n\ -_ _ _ _ _ _ _ _\n\ -_ _ _ _ _ _ _ _\n\ -_ _ _ _ _ _ _ _\n\ -_ _ _ _ _ _ B _\n\ -_ _ _ _ _ _ _ _\n\ -'; + var board = '_ _ _ _ _ _ _ _\n' + +'_ _ _ _ _ _ _ _\n' + +'_ _ _ _ W _ _ _\n' + +'_ _ _ _ _ _ _ _\n' + +'_ _ _ _ _ _ _ _\n' + +'_ _ _ _ _ _ _ _\n' + +'_ _ _ _ _ _ B _\n' + +'_ _ _ _ _ _ _ _\n' +; expect(queens.toString()).toEqual(board); }); From a4d3e8189606343235cc8c8e1fe978a4a9a7ce3f Mon Sep 17 00:00:00 2001 From: Lauren Cantlin <30631905+laurencantlin@users.noreply.github.com> Date: Mon, 5 Mar 2018 18:21:25 -0600 Subject: [PATCH 249/272] fixes nth-prime linter problems (#525) --- .eslintignore | 1 - exercises/nth-prime/example.js | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.eslintignore b/.eslintignore index dd2770ce..7b66825f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,7 +5,6 @@ exercises/grains/big-integer.js exercises/grains/big-integer.spec.js exercises/linked-list exercises/minesweeper -exercises/nth-prime exercises/queen-attack exercises/robot-simulator exercises/saddle-points diff --git a/exercises/nth-prime/example.js b/exercises/nth-prime/example.js index f0d824dc..faf7d05c 100644 --- a/exercises/nth-prime/example.js +++ b/exercises/nth-prime/example.js @@ -7,12 +7,13 @@ module.exports = { return this.realPrimes[nthPrime - 1]; }, generatePrimes: function (uptoNumber) { - var i, j, currentPrime, primeCount, possiblePrimes = []; - - if (this.realPrimes) { return this.realPrimes; } + var i; + var j; + var currentPrime; + var possiblePrimes = []; for (i = 2; i <= uptoNumber; i++) { - possiblePrimes.push({ number: i, prime: true}); + possiblePrimes.push({ number: i, prime: true }); } for (i = 2; i < Math.sqrt(possiblePrimes.length); i++) { @@ -24,8 +25,6 @@ module.exports = { } } - primeCount = 0; - this.realPrimes = []; for (i = 0; i < possiblePrimes.length; i++) { @@ -34,6 +33,7 @@ module.exports = { this.realPrimes.push(currentPrime.number); } } + return this.realPrimes; } }; From cf89157ff9f9659719648e182135667f2577ef43 Mon Sep 17 00:00:00 2001 From: Natraj Subramanian Date: Tue, 6 Mar 2018 06:02:59 -0600 Subject: [PATCH 250/272] Fix lint errors on simple-linked-list (#520) * Empty PR. Fix lint errors on simple-linked-list * Fixes most of the lint specified errors * Disabled incompatible lint rules --- .eslintignore | 1 - exercises/simple-linked-list/example.js | 16 ++++++++++------ .../simple-linked-list.spec.js | 9 ++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index 7b66825f..becfcec7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,4 +10,3 @@ exercises/robot-simulator exercises/saddle-points exercises/secret-handshake exercises/simple-cipher -exercises/simple-linked-list diff --git a/exercises/simple-linked-list/example.js b/exercises/simple-linked-list/example.js index 6e1f0d05..e8fca85f 100644 --- a/exercises/simple-linked-list/example.js +++ b/exercises/simple-linked-list/example.js @@ -3,11 +3,11 @@ function Element(value, next) { throw new Error('Element is a constructor.'); } - if (value === undefined) { + if (typeof value === 'undefined') { throw new Error('Value required.'); } - if (next !== undefined && !(next instanceof Element)) { + if (typeof next !== 'undefined' && !(next instanceof Element)) { throw new Error('A Element instance as next value is required.'); } @@ -18,7 +18,7 @@ function Element(value, next) { function List() {} List.prototype.push = function (value) { - if (value === undefined) { + if (typeof value === 'undefined') { throw new Error('Argument required.'); } @@ -40,7 +40,7 @@ List.prototype.push = function (value) { }; List.prototype.unshift = function (value) { - if (value === undefined) { + if (typeof value === 'undefined') { throw new Error('Argument required.'); } @@ -65,17 +65,20 @@ List.prototype.pop = function () { return; } - var penultEl, lastEl = this.head; + var penultEl; + var lastEl = this.head; while (lastEl.next) { penultEl = lastEl; lastEl = lastEl.next; } + /* eslint-disable no-undefined */ if (!penultEl) { this.head = undefined; } else { penultEl.next = undefined; } + /* eslint-enable no-undefined */ }; List.prototype.reverse = function () { @@ -83,7 +86,8 @@ List.prototype.reverse = function () { return; } - var current, previous; + var current; + var previous; while (this.head) { current = this.head; this.shift(); diff --git a/exercises/simple-linked-list/simple-linked-list.spec.js b/exercises/simple-linked-list/simple-linked-list.spec.js index 1254743b..75460d35 100644 --- a/exercises/simple-linked-list/simple-linked-list.spec.js +++ b/exercises/simple-linked-list/simple-linked-list.spec.js @@ -16,9 +16,11 @@ describe('simple-linked-list', function () { var el = new Element(1); expect(el).toBeDefined(); + /* eslint-disable new-cap */ expect(function () { - var el = Element(1); + el = Element(1); }).toThrow(); + /* eslint-enable new-cap */ }); xit('requires an argument', function () { @@ -26,7 +28,7 @@ describe('simple-linked-list', function () { expect(el).toBeDefined(); expect(function () { - var el = new Element(); + el = new Element(); }).toThrow(); }); @@ -47,9 +49,9 @@ describe('simple-linked-list', function () { expect(elTwo.next).toBe(elOne); }); + /* eslint-disable no-unused-vars */ xit('requires an instance of Element as next element', function () { expect(function () { - var el = new Element(1, true); var el = new Element(1, false); }).toThrow(); expect(function () { @@ -62,6 +64,7 @@ describe('simple-linked-list', function () { var el = new Element(1, {}); }).toThrow(); }); + /* eslint-enable no-unused-vars */ describe('List', function () { xit('is a constructor', function () { From c12dbfd24506e54aeb294344f42564cfeadc6caf Mon Sep 17 00:00:00 2001 From: Joe Fitzpatrick <32550334+joefitz12@users.noreply.github.com> Date: Tue, 6 Mar 2018 18:08:34 -0600 Subject: [PATCH 251/272] issue #399 - Removes lint errors from secret-handshake (#519) --- .eslintignore | 1 - exercises/secret-handshake/example.js | 3 +-- exercises/secret-handshake/secret-handshake.spec.js | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.eslintignore b/.eslintignore index becfcec7..382b8bbd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,5 +8,4 @@ exercises/minesweeper exercises/queen-attack exercises/robot-simulator exercises/saddle-points -exercises/secret-handshake exercises/simple-cipher diff --git a/exercises/secret-handshake/example.js b/exercises/secret-handshake/example.js index 651a8d78..873ccc97 100644 --- a/exercises/secret-handshake/example.js +++ b/exercises/secret-handshake/example.js @@ -12,8 +12,7 @@ function SecretHandshake(handshake) { return this.shakeWith; }; - this.calculateHandshake = function (handshake) { - /* jshint bitwise:false */ + this.calculateHandshake = function () { var shakeWith = []; for (var i = 0; i < handshakeCommands.length; i++) { diff --git a/exercises/secret-handshake/secret-handshake.spec.js b/exercises/secret-handshake/secret-handshake.spec.js index 6c29444a..bf5fc41d 100644 --- a/exercises/secret-handshake/secret-handshake.spec.js +++ b/exercises/secret-handshake/secret-handshake.spec.js @@ -38,7 +38,8 @@ describe('Secret Handshake', function () { xit('text is an invalid secret handshake', function () { expect( function () { - var handshake = new SecretHandshake('piggies'); + /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "[iI]gnored" }]*/ + var ignoredHandshake = new SecretHandshake('piggies'); }).toThrow(new Error('Handshake must be a number')); }); }); From b9bc950c365a537a7fa5b45c851b8df2639ab69d Mon Sep 17 00:00:00 2001 From: PakkuDon Date: Thu, 8 Mar 2018 22:33:47 +1100 Subject: [PATCH 252/272] Add armstrong-numbers exercise (#522) --- config.json | 11 +++++ exercises/armstrong-numbers/README.md | 46 +++++++++++++++++++ .../armstrong-numbers.spec.js | 43 +++++++++++++++++ exercises/armstrong-numbers/example.js | 11 +++++ 4 files changed, 111 insertions(+) create mode 100644 exercises/armstrong-numbers/README.md create mode 100644 exercises/armstrong-numbers/armstrong-numbers.spec.js create mode 100644 exercises/armstrong-numbers/example.js diff --git a/config.json b/config.json index 035b9e1b..b717adca 100644 --- a/config.json +++ b/config.json @@ -1243,6 +1243,17 @@ "searching", "pattern_recognition" ] + }, + { + "uuid": "0e4b628c-870d-446b-a400-3cc72457f2bc", + "slug": "armstrong-numbers", + "core": false, + "unlocked_by": null, + "difficulty": 2, + "topics": [ + "mathematics", + "algorithms" + ] } ], "foregone": [], diff --git a/exercises/armstrong-numbers/README.md b/exercises/armstrong-numbers/README.md new file mode 100644 index 00000000..f0714aa7 --- /dev/null +++ b/exercises/armstrong-numbers/README.md @@ -0,0 +1,46 @@ +# Armstrong Numbers + +An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits. + +For example: + +- 9 is an Armstrong number, because `9 = 9^1 = 9` +- 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 2` +- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153` +- 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190` + +Write some code to determine whether a number is an Armstrong number. + +## Setup + +Go through the setup instructions for JavaScript to install the + necessary dependencies: + +http://exercism.io/languages/javascript/installation + +## Running the test suite + +The provided test suite uses [Jasmine](https://jasmine.github.io/). +You can install it by opening a terminal window and running the +following command: + +```sh +npm install -g jasmine +``` + +Run the test suite from the exercise directory with: + +```sh +jasmine armstrong-numbers.spec.js +``` + +In many test suites all but the first test have been marked "pending". +Once you get a test passing, activate the next one by changing `xit` to `it`. + +## Source + +Wikipedia [Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) + +## Submitting Incomplete Solutions + +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/armstrong-numbers/armstrong-numbers.spec.js b/exercises/armstrong-numbers/armstrong-numbers.spec.js new file mode 100644 index 00000000..9f250fac --- /dev/null +++ b/exercises/armstrong-numbers/armstrong-numbers.spec.js @@ -0,0 +1,43 @@ +var ArmstrongNumber = require('./armstrong-numbers'); + +describe('ArmstrongNumber', function () { + it('Single digit numbers are Armstrong numbers', function () { + var input = 5; + expect(ArmstrongNumber.validate(input)).toBe(true); + }); + + xit('There are no 2 digit Armstrong numbers', function () { + var input = 10; + expect(ArmstrongNumber.validate(input)).toBe(false); + }); + + xit('Three digit number that is an Armstrong number', function () { + var input = 153; + expect(ArmstrongNumber.validate(input)).toBe(true); + }); + + xit('Three digit number that is not an Armstrong number', function () { + var input = 100; + expect(ArmstrongNumber.validate(input)).toBe(false); + }); + + xit('Four digit number that is an Armstrong number', function () { + var input = 9474; + expect(ArmstrongNumber.validate(input)).toBe(true); + }); + + xit('Four digit number that is not an Armstrong number', function () { + var input = 9475; + expect(ArmstrongNumber.validate(input)).toBe(false); + }); + + xit('Seven digit number that is an Armstrong number', function () { + var input = 9926315; + expect(ArmstrongNumber.validate(input)).toBe(true); + }); + + xit('Seven digit number that is not an Armstrong number', function () { + var input = 9926314; + expect(ArmstrongNumber.validate(input)).toBe(false); + }); +}); diff --git a/exercises/armstrong-numbers/example.js b/exercises/armstrong-numbers/example.js new file mode 100644 index 00000000..c0652924 --- /dev/null +++ b/exercises/armstrong-numbers/example.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = { + validate: function (input) { + var digits = String(input).split(''); + var sum = digits.reduce(function (total, current) { + return total + Math.pow(current, digits.length); + }, 0); + return sum === input; + } +}; From e76179e4c54e7b9ffc0eddac46578053120926ee Mon Sep 17 00:00:00 2001 From: Tarun Velli Date: Tue, 13 Mar 2018 18:50:13 +0530 Subject: [PATCH 253/272] fix linting for minesweeper exercise (#526) --- .eslintignore | 1 - exercises/minesweeper/example.js | 30 +++++++++++++++--------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.eslintignore b/.eslintignore index 382b8bbd..2d19a189 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,7 +4,6 @@ exercises/flatten-array exercises/grains/big-integer.js exercises/grains/big-integer.spec.js exercises/linked-list -exercises/minesweeper exercises/queen-attack exercises/robot-simulator exercises/saddle-points diff --git a/exercises/minesweeper/example.js b/exercises/minesweeper/example.js index b5d76036..a366884e 100644 --- a/exercises/minesweeper/example.js +++ b/exercises/minesweeper/example.js @@ -21,25 +21,25 @@ Minesweeper.prototype.annotate = function (rows) { } var board = rows.map(function (row) { return row.split(''); }); var outBoard = []; - for (var x = 0; x < board.length; x++) { + board.forEach(function (memberX, x) { outBoard[x] = []; - for (var y = 0; y < board[x].length; y++) { - var spot = board[x][y]; + memberX.forEach(function (memberXY, y) { + var spot = memberXY; if (spot === '*') { outBoard[x][y] = spot; - continue; + } else { + var bombCount = this.distanceXdistanceYs.map(function (dxdy) { + if (typeof board[x + dxdy[0]] === 'undefined') { + return 0; + } + return board[x + dxdy[0]][y + dxdy[1]] === '*' ? 1 : 0; + }).reduce(function (total, num) { + return total + num; + }); + outBoard[x][y] = bombCount > 0 ? bombCount : ' '; } - var bombCount = this.distanceXdistanceYs.map(function (dxdy) { - if (board[x + dxdy[0]] === undefined) { - return 0; - } - return board[x + dxdy[0]][y + dxdy[1]] === '*' ? 1 : 0; - }).reduce(function (total, num) { - return total + num; - }); - outBoard[x][y] = bombCount > 0 ? bombCount : ' '; - } - } + }, this); + }, this); return outBoard.map(function (row) { return row.join(''); }); From abd7116b282b5632201d9e1a6bde6a225a37d692 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Tue, 13 Mar 2018 19:25:22 +0530 Subject: [PATCH 254/272] Update jasmine to v3.1.0 (#507) Recently [an issue](https://github.com/exercism/javascript/issues/505) came up related to jasmine v3.0.0. And I noticed that we are using v2.8. Jasmine 3 seems to have some [breaking changes](https://github.com/jasmine/jasmine/blob/master/release_notes/3.0.md) and since many of our new users will be installing recent version of jasmine, I thought it would be better to update it so we run CI using v3. --- package-lock.json | 21 +++++++-------------- package.json | 2 +- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3c1fed5..94eab4b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -728,12 +728,6 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, "external-editor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", @@ -1091,20 +1085,19 @@ } }, "jasmine": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", - "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.1.0.tgz", + "integrity": "sha1-K9Wf1+xuwOistk4J9Fpo7SrRlSo=", "dev": true, "requires": { - "exit": "0.1.2", "glob": "7.1.2", - "jasmine-core": "2.8.0" + "jasmine-core": "3.1.0" } }, "jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.1.0.tgz", + "integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=", "dev": true }, "js-tokens": { diff --git a/package.json b/package.json index 8ab06dbf..001c8229 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "eslint-plugin-import": "^2.8.0", "eslint-plugin-jasmine": "^2.9.1", "eslint-plugin-react": "^7.3.0", - "jasmine": "^2.8.0" + "jasmine": "^3.1.0" }, "scripts": { "lint": "eslint .", From 566bab4c7262ab5c27ca020b31aaddaa2a48001a Mon Sep 17 00:00:00 2001 From: Aaditya Arvind Kulkarni Date: Fri, 16 Mar 2018 12:26:23 -0400 Subject: [PATCH 255/272] Fix linting for linked-list exercise (#529) Issue #399 --- .eslintignore | 1 - exercises/linked-list/example.js | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.eslintignore b/.eslintignore index 2d19a189..657ad2fe 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,7 +3,6 @@ exercises/custom-set exercises/flatten-array exercises/grains/big-integer.js exercises/grains/big-integer.spec.js -exercises/linked-list exercises/queen-attack exercises/robot-simulator exercises/saddle-points diff --git a/exercises/linked-list/example.js b/exercises/linked-list/example.js index 7c288bfa..672dff0c 100644 --- a/exercises/linked-list/example.js +++ b/exercises/linked-list/example.js @@ -10,7 +10,7 @@ function LinkedList() { this._front = null; } -LinkedList.prototype.push = function LinkedList_push(value) { +LinkedList.prototype.push = function (value) { if (this._front === null) { this._front = new Node(value); } else { @@ -21,18 +21,18 @@ LinkedList.prototype.push = function LinkedList_push(value) { } }; -LinkedList.prototype.unshift = function LinkedList_unshift(value) { +LinkedList.prototype.unshift = function (value) { this.push(value); this._front = this._front.prev; }; -LinkedList.prototype.pop = function LinkedList_pop() { - if (this._front === null) {return undefined;} +LinkedList.prototype.pop = function () { + if (this._front === null) {return null;} this._front = this._front.prev; return this.shift(); }; -LinkedList.prototype.shift = function LinkedList_shift() { +LinkedList.prototype.shift = function () { var value = this._front.value; var front = this._front.next; var back = this._front.prev; @@ -63,7 +63,7 @@ LinkedList.prototype.delete = function (match) { this._front.next = this._front.next.next; } else { this._front = this._front.next; - return this.delete(match); + this.delete(match); } }; From 3f1eca21fa34c04fb7044700cbeeccd25dfdc62b Mon Sep 17 00:00:00 2001 From: Tarun Velli Date: Sat, 17 Mar 2018 22:31:37 +0530 Subject: [PATCH 256/272] Fix linting for saddle points (#528) Issue #399 --- .eslintignore | 1 - exercises/saddle-points/example.js | 85 +++++++++++------------------- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/.eslintignore b/.eslintignore index 657ad2fe..14b65a23 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,5 +5,4 @@ exercises/grains/big-integer.js exercises/grains/big-integer.spec.js exercises/queen-attack exercises/robot-simulator -exercises/saddle-points exercises/simple-cipher diff --git a/exercises/saddle-points/example.js b/exercises/saddle-points/example.js index 81217e7c..ac1cde4f 100644 --- a/exercises/saddle-points/example.js +++ b/exercises/saddle-points/example.js @@ -1,78 +1,57 @@ 'use strict'; -function toInt(s) { - return parseInt(s, 10); -} - module.exports = function Matrix(matrix) { - this.rows = []; - this.columns = []; - - var rows = matrix.split('\n'); - var i, j, currentRow; - - for (i = 0; i < rows.length; i++) { - currentRow = rows[i].replace(/^\s+|\s+$/g, '').split(' ').map( toInt ); - this.rows.push(currentRow); - } - - for (i = 0; i < this.rows[0].length; i++) { - this.columns.push([]); - } + this.rows = matrix.split('\n').map(function (row) { + return row.split(' ').map(function (val) { return parseInt(val, 10); }); + }); - for (i = 0; i < this.rows.length; i++) { - for (j = 0; j < this.columns.length; j++) { - this.columns[j].push(this.rows[i][j]); - } - } + this.columns = this.rows[0].map(function () { + return []; + }).map(function (column, index) { + return this.rows.map(function (row) { return row[index]; }); + }, this); this.indexesOfMaxValues = function (array) { - var i, currentElement, maxValue, indexes = []; + var maxValue = array.reduce(function (acc, curr) { + return Math.max(acc, curr); + }); - for (i = 0; i < array.length; i++) { - currentElement = array[i]; - if (maxValue === undefined || currentElement > maxValue) { - maxValue = currentElement; - indexes = [i]; - } else if (currentElement === maxValue) { - indexes.push(i); - } - } - - return indexes; + return this.indexsOf(array, maxValue); }; this.indexesOfMinValues = function (array) { - var i, currentElement, minValue, indexes = []; + var minValue = array.reduce(function (acc, curr) { + return Math.min(acc, curr); + }); - for (i = 0; i < array.length; i++) { - currentElement = array[i]; - if (minValue === undefined || currentElement < minValue) { - minValue = currentElement; - indexes = [i]; - } else if (currentElement === minValue) { - indexes.push(i); - } - } + return this.indexsOf(array, minValue); + }; - return indexes; + this.indexsOf = function (array, value) { + return array.map(function (val, index) { + return val === value ? index : null; + }).filter(function (val) { + return val !== null; + }); }; this.calculateSaddlePoints = function (rows, columns) { - var i, j, maxIndexes, minIndexes, currentMaxIndex, saddlePoints = []; + var maxIndexes; + var minIndexes; + var saddlePoints = []; - for (i = 0; i < rows.length; i++) { - maxIndexes = this.indexesOfMaxValues(rows[i]); + rows.forEach(function (row, i) { + maxIndexes = this.indexesOfMaxValues(row); - for (j = 0; j < maxIndexes.length; j++) { - currentMaxIndex = maxIndexes[j]; + maxIndexes.forEach(function (currentMaxIndex) { minIndexes = this.indexesOfMinValues(columns[currentMaxIndex]); if (minIndexes.indexOf(i) >= 0) { saddlePoints.push([i, currentMaxIndex]); } - } - } + }, this); + }, this); + return saddlePoints; }; From 1bf6bfdad5de27334fa2e53f2321c4200f1c13f6 Mon Sep 17 00:00:00 2001 From: Tejas Bubane Date: Thu, 22 Mar 2018 04:18:06 +0530 Subject: [PATCH 257/272] Fix errors in config for configlet v3.8.0 (#530) Closes #527. configlet v3.8.0 requires unlocked_by to be core exercise. Make the required changes. --- config.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config.json b/config.json index b717adca..1139e8c6 100644 --- a/config.json +++ b/config.json @@ -594,7 +594,7 @@ "text-formatting", "transforming" ], - "unlocked_by": "atbash-cipher", + "unlocked_by": "simple-cipher", "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad" }, { @@ -805,7 +805,7 @@ "control-flow-(loops)", "recursion" ], - "unlocked_by": "binary-search", + "unlocked_by": "linked-list", "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85" }, { @@ -1130,7 +1130,7 @@ "Algorithms", "Mathematics" ], - "unlocked_by": "null", + "unlocked_by": null, "uuid" : "fd435dad-311a-4c40-9868-70863455831e" }, { @@ -1213,7 +1213,7 @@ "uuid": "b3dbc935-536e-4910-994d-4a519b511b6a", "slug": "forth", "core": false, - "unlocked_by": "saddle-points", + "unlocked_by": "matrix", "difficulty": 8, "topics": [ "stacks", @@ -1225,7 +1225,7 @@ "uuid": "f82e470d-0bcc-4eba-b9b0-8a0c50a6fd19", "slug": "variable-length-quantity", "core": false, - "unlocked_by": "two-bucket", + "unlocked_by": "grade-school", "difficulty": 5, "topics": [ "bitwise_operations", From 1f5a11c7020ffc12d73bbc28dec631d97b78f66e Mon Sep 17 00:00:00 2001 From: Tarun Velli Date: Sun, 25 Mar 2018 02:55:17 +0530 Subject: [PATCH 258/272] remove linted eercises from lint ignore (#533) --- .eslintignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.eslintignore b/.eslintignore index 14b65a23..749a0761 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,8 +1,5 @@ big-integer.js -exercises/custom-set -exercises/flatten-array exercises/grains/big-integer.js exercises/grains/big-integer.spec.js -exercises/queen-attack exercises/robot-simulator exercises/simple-cipher From 9ac0da445ba4e0c04e5e7d98a2ec2f1578f23332 Mon Sep 17 00:00:00 2001 From: Daniel Jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Sat, 24 Mar 2018 14:26:50 -0700 Subject: [PATCH 259/272] implement the two recently addeded tests from the canonical test spec (#532) --- exercises/bowling/bowling.spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/exercises/bowling/bowling.spec.js b/exercises/bowling/bowling.spec.js index a507da47..c78b2f9d 100644 --- a/exercises/bowling/bowling.spec.js +++ b/exercises/bowling/bowling.spec.js @@ -208,5 +208,21 @@ describe('Bowling', function () { expect(function () { bowling.score(); }).toThrow( new Error('Score cannot be taken until the end of the game')); }); + + xit('cannot roll after bonus roll for a spare', function () { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 2]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(2); }).toThrow( + new Error('Cannot roll after game is over')); + }); + + xit('cannot roll after bonus rolls for a strike', function () { + var rolls = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 2]; + var bowling = new Bowling(); + previousRolls(bowling, rolls); + expect(function () { bowling.roll(2); }).toThrow( + new Error('Cannot roll after game is over')); + }); }); }); From fd567086481e7b85a5bbbb406b905acab72db6bb Mon Sep 17 00:00:00 2001 From: Allison Zhao Date: Fri, 30 Mar 2018 10:47:03 -0400 Subject: [PATCH 260/272] Fix robot simulator (#535) * Initial commit * Fix robot simulator * Remove function wrapping * Update const and let to var --- .eslintignore | 1 - exercises/robot-simulator/example.js | 142 +++++++++++++-------------- 2 files changed, 70 insertions(+), 73 deletions(-) diff --git a/.eslintignore b/.eslintignore index 749a0761..04c884de 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,4 @@ big-integer.js exercises/grains/big-integer.js exercises/grains/big-integer.spec.js -exercises/robot-simulator exercises/simple-cipher diff --git a/exercises/robot-simulator/example.js b/exercises/robot-simulator/example.js index 769134f5..96bb5c90 100644 --- a/exercises/robot-simulator/example.js +++ b/exercises/robot-simulator/example.js @@ -1,87 +1,85 @@ -var Robot = (function () { - 'use strict'; +'use strict'; - var VALID_DIRECTIONS = ['north', 'east', 'south', 'west']; - var INSTRUCTION_KEYS = { - A: 'advance', - L: 'turnLeft', - R: 'turnRight' - }; +var VALID_DIRECTIONS = ['north', 'east', 'south', 'west']; +var INSTRUCTION_KEYS = { + A: 'advance', + L: 'turnLeft', + R: 'turnRight' +}; - function Robot() { - this.coordinates = [0, 0]; - this.bearing = 'north'; - } - - Robot.prototype.at = function (x, y) { - this.coordinates = [x, y]; - }; +function Robot() { + this.coordinates = [0, 0]; + this.bearing = 'north'; +} - Robot.prototype.orient = function (direction) { - if (VALID_DIRECTIONS.indexOf(direction) === -1) { - throw new Error('Invalid Robot Bearing'); - } +Robot.prototype.at = function (x, y) { + this.coordinates = [x, y]; +}; - this.bearing = direction; - }; +Robot.prototype.orient = function (direction) { + if (VALID_DIRECTIONS.indexOf(direction) === -1) { + throw new Error('Invalid Robot Bearing'); + } - Robot.prototype.advance = function () { - switch (this.bearing) { - case 'north': - this.coordinates[1]++; - break; - case 'east': - this.coordinates[0]++; - break; - case 'south': - this.coordinates[1]--; - break; - case 'west': - this.coordinates[0]--; - break; - } - }; + this.bearing = direction; +}; - Robot.prototype.turnLeft = function () { - var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); +Robot.prototype.advance = function () { + switch (this.bearing) { + case 'north': + this.coordinates[1]++; + break; + case 'east': + this.coordinates[0]++; + break; + case 'south': + this.coordinates[1]--; + break; + case 'west': + this.coordinates[0]--; + break; + default: + break; + } +}; - if (directionPosition > 0) { - this.orient(VALID_DIRECTIONS[--directionPosition]); - } else { - this.orient(VALID_DIRECTIONS[VALID_DIRECTIONS.length - 1]); - } - }; +Robot.prototype.turnLeft = function () { + var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); - Robot.prototype.turnRight = function () { - var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); + if (directionPosition > 0) { + this.orient(VALID_DIRECTIONS[--directionPosition]); + } else { + this.orient(VALID_DIRECTIONS[VALID_DIRECTIONS.length - 1]); + } +}; - if (directionPosition < (VALID_DIRECTIONS.length - 1)) { - this.orient(VALID_DIRECTIONS[++directionPosition]); - } else { - this.orient(VALID_DIRECTIONS[0]); - } - }; +Robot.prototype.turnRight = function () { + var directionPosition = VALID_DIRECTIONS.indexOf(this.bearing); - Robot.prototype.instructions = function (instructionKeys) { - return instructionKeys.split('') - .map(function (key) { - return INSTRUCTION_KEYS[key]; - }); - }; + if (directionPosition < (VALID_DIRECTIONS.length - 1)) { + this.orient(VALID_DIRECTIONS[++directionPosition]); + } else { + this.orient(VALID_DIRECTIONS[0]); + } +}; - Robot.prototype.place = function (args) { - this.coordinates = [args.x, args.y]; - this.bearing = args.direction; - }; +Robot.prototype.instructions = function (instructionKeys) { + return instructionKeys.split('') + .map(function (key) { + return INSTRUCTION_KEYS[key]; + }); +}; - Robot.prototype.evaluate = function (instructionKeys) { - this.instructions(instructionKeys) - .forEach(function (instruction) { - this[instruction](); - }, this); - }; +Robot.prototype.place = function (args) { + this.coordinates = [args.x, args.y]; + this.bearing = args.direction; +}; - return Robot; -})(); +Robot.prototype.evaluate = function (instructionKeys) { + this.instructions(instructionKeys) + .forEach(function (instruction) { + this[instruction](); + }, this); +}; module.exports = Robot; From 1524838ef16b5cea02c9cefad2944a97a2c4da04 Mon Sep 17 00:00:00 2001 From: Allison Zhao Date: Fri, 6 Apr 2018 13:29:21 -0400 Subject: [PATCH 261/272] Fix linting errors for simple-cipher (#536) --- .eslintignore | 1 - exercises/simple-cipher/example.js | 10 ++++------ exercises/simple-cipher/simple-cipher.spec.js | 10 +++++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index 04c884de..03223202 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,3 @@ big-integer.js exercises/grains/big-integer.js exercises/grains/big-integer.spec.js -exercises/simple-cipher diff --git a/exercises/simple-cipher/example.js b/exercises/simple-cipher/example.js index b8cc5151..6f0177fb 100644 --- a/exercises/simple-cipher/example.js +++ b/exercises/simple-cipher/example.js @@ -3,8 +3,8 @@ var ALPHABET = 'abcdefghijklmnopqrstuvwxyz'; function randomKey() { - var i, result = ''; - for ( i = 0; i < 100; i++ ) { + var result; + for ( var i = 0; i < 100; i++ ) { result += ALPHABET[randomUpTo(ALPHABET.length)]; } return result; @@ -17,15 +17,13 @@ function randomUpTo(n) { module.exports = function (userDefinedKey) { var key; - function addEncodedCharacter(character, index, array) { - /* jshint validthis:true */ + function addEncodedCharacter(character, index) { var i = ALPHABET.indexOf(character) + ALPHABET.indexOf(key[index % key.length]); if (i >= ALPHABET.length) { i -= ALPHABET.length; } this.push(ALPHABET[i]); } - function addDecodedCharacter(character, index, array) { - /* jshint validthis:true */ + function addDecodedCharacter(character, index) { var i = ALPHABET.indexOf(character) - ALPHABET.indexOf(key[index % key.length]); if (i < 0) { i += ALPHABET.length; } this.push(ALPHABET[i]); diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index f3fb2b39..38a08247 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -24,26 +24,30 @@ describe('Random key cipher', function () { }); }); +/* eslint-disable no-new */ + describe('Incorrect key cipher', function () { xit('throws an error with an all caps key', function () { - expect( function () { + expect(function () { new Cipher('ABCDEF'); }).toThrow(new Error('Bad key')); }); xit('throws an error with a numeric key', function () { - expect( function () { + expect(function () { new Cipher('12345'); }).toThrow(new Error('Bad key')); }); xit('throws an error with an empty key', function () { - expect( function () { + expect(function () { new Cipher(''); }).toThrow(new Error('Bad key')); }); }); +/* eslint-enable no-new */ + describe('Substitution cipher', function () { var key = 'abcdefghij'; var cipher = new Cipher(key); From 3b58a47192a80418650b85b92611987a1cbab1e0 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 9 Apr 2018 13:14:46 -0400 Subject: [PATCH 262/272] Update Bob to match README (#537) --- exercises/bob/bob.spec.js | 2 +- exercises/bob/example.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/exercises/bob/bob.spec.js b/exercises/bob/bob.spec.js index d8555e65..fc017cd1 100644 --- a/exercises/bob/bob.spec.js +++ b/exercises/bob/bob.spec.js @@ -45,7 +45,7 @@ describe('Bob', function () { xit('forceful questions', function () { var result = bob.hey('WHAT THE HELL WERE YOU THINKING?'); - expect(result).toEqual('Whoa, chill out!'); + expect(result).toEqual("Calm down, I know what I'm doing!"); }); xit('shouting numbers', function () { diff --git a/exercises/bob/example.js b/exercises/bob/example.js index 7826975f..b7fa2913 100644 --- a/exercises/bob/example.js +++ b/exercises/bob/example.js @@ -18,6 +18,9 @@ function Bob() { if (isSilence(message)) { return 'Fine. Be that way!'; } else if (isShouting(message)) { + if (isAQuestion(message)) { + return "Calm down, I know what I'm doing!"; + } return 'Whoa, chill out!'; } else if (isAQuestion(message)) { return 'Sure.'; From 025576d445b3dfc2dd045210b65c46520dba569c Mon Sep 17 00:00:00 2001 From: Dave Yarwood Date: Tue, 10 Apr 2018 09:47:45 -0400 Subject: [PATCH 263/272] add tests for random key generation, 100+ character length (#538) --- exercises/simple-cipher/simple-cipher.spec.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/exercises/simple-cipher/simple-cipher.spec.js b/exercises/simple-cipher/simple-cipher.spec.js index 38a08247..c59c16cf 100644 --- a/exercises/simple-cipher/simple-cipher.spec.js +++ b/exercises/simple-cipher/simple-cipher.spec.js @@ -1,5 +1,15 @@ var Cipher = require('./simple-cipher'); +describe('Random key generation', function () { + xit('generates keys at random', function () { + // Strictly speaking, this is difficult to test with 100% certainty. + // But, if you have a generator that generates 100-character-long + // strings of lowercase letters at random, the odds of two consecutively + // generated keys being identical are astronomically low. + expect(new Cipher().key).not.toEqual(new Cipher().key); + }); +}); + describe('Random key cipher', function () { var cipher = new Cipher(); @@ -7,6 +17,10 @@ describe('Random key cipher', function () { expect(cipher.key).toMatch(/^[a-z]+$/); }); + xit('has a key that is at least 100 characters long', function () { + expect(cipher.key.length).toBeGreaterThanOrEqual(100); + }); + // Here we take advantage of the fact that plaintext of "aaa..." // outputs the key. This is a critical problem with shift ciphers, some // characters will always output the key verbatim. From f81aef24fd9c33bbf345dcb9bb2b1d88738a1e0f Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Mon, 11 Jun 2018 01:36:18 -0600 Subject: [PATCH 264/272] Reformat config files (#549) This runs the configlet fmt command, which normalizes the contents and ordering of keys in the track config and maintainers config. This will let us script changes to the config files without having unnecessary noise in the diffs when submitting pull requests. --- config.json | 1128 ++++++++++++++++++++------------------- config/maintainers.json | 80 +-- 2 files changed, 617 insertions(+), 591 deletions(-) diff --git a/config.json b/config.json index 1139e8c6..4de97d0b 100644 --- a/config.json +++ b/config.json @@ -1,1192 +1,1221 @@ { + "language": "JavaScript", "active": true, + "blurb": "", + "test_pattern": ".*[.]spec[.]js$", "exercises": [ { + "slug": "hello-world", + "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256", "core": true, + "unlocked_by": null, "difficulty": 1, - "slug": "hello-world", "topics": [ - "control-flow-(conditionals)", - "optional-values", + "control_flow_conditionals", + "optional_values", "strings", - "text-formatting" - ], - "uuid": "4756cfc9-7509-4783-8be7-60e3376b8256" + "text_formatting" + ] }, { + "slug": "two-fer", + "uuid": "5f3d1326-f0c5-44a6-b90a-6af3b7d455f1", "core": false, + "unlocked_by": "hello-world", "difficulty": 1, - "slug": "two-fer", "topics": [ - "strings", - "control-flow-(conditionals)" - ], - "unlocked_by": "hello-world", - "uuid": "5f3d1326-f0c5-44a6-b90a-6af3b7d455f1" + "control_flow_conditionals", + "strings" + ] }, { + "slug": "leap", + "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b", "core": true, + "unlocked_by": null, "difficulty": 1, - "slug": "leap", "topics": [ "booleans", "integers", "logic" - ], - "uuid": "0c231a1c-55f7-47b6-8a54-ccae4ab0c65b" + ] }, { + "slug": "reverse-string", + "uuid": "553a6be7-eecb-45dc-9cea-05126c525f1b", "core": false, + "unlocked_by": "leap", "difficulty": 2, - "slug": "reverse-string", "topics": [ - "loops", "for", + "loops", "strings" - ], - "unlocked_by": "leap", - "uuid": "553a6be7-eecb-45dc-9cea-05126c525f1b" + ] }, { + "slug": "rna-transcription", + "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c", "core": true, + "unlocked_by": null, "difficulty": 1, - "slug": "rna-transcription", "topics": [ "strings", "transforming" - ], - "uuid": "d7f57ab9-2edb-44cb-a04e-c575c0f4be4c" + ] }, { + "slug": "simple-cipher", + "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af", "core": true, + "unlocked_by": null, "difficulty": 1, - "slug": "simple-cipher", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "mathematics", "randomness", "strings", - "text-formatting", + "text_formatting", "transforming" - ], - "uuid": "fff57c49-cde9-4a0c-b70b-2903cef212af" + ] }, { + "slug": "pangram", + "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15", "core": true, + "unlocked_by": null, "difficulty": 2, - "slug": "pangram", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "lists", "maps", "searching", "strings" - ], - "uuid": "c57bf909-130f-46e6-97ca-aeed58df1a15" + ] }, { + "slug": "bob", + "uuid": "246be5d9-b361-4893-9707-f218ede2bed6", "core": true, + "unlocked_by": null, "difficulty": 2, - "slug": "bob", "topics": [ - "control-flow-(conditionals)", - "pattern-recognition", + "control_flow_conditionals", + "pattern_recognition", "polymorfism", - "regular-expressions", + "regular_expressions", "strings", "unicode" - ], - "uuid": "246be5d9-b361-4893-9707-f218ede2bed6" + ] }, { + "slug": "gigasecond", + "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44", "core": true, + "unlocked_by": null, "difficulty": 2, - "slug": "gigasecond", "topics": [ "time" - ], - "uuid": "49e4874b-d7e2-4305-a9bc-627fab4ada44" + ] }, { + "slug": "space-age", + "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8", "core": true, + "unlocked_by": null, "difficulty": 3, - "slug": "space-age", "topics": [ "classes", - "floating-point-numbers", + "floating_point_numbers", "mathematics" - ], - "uuid": "b668e11a-a8ce-4e94-ba68-3a1f0fa3f6c8" + ] }, { + "slug": "binary", + "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e", "core": true, + "unlocked_by": null, "difficulty": 4, - "slug": "binary", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics", - "regular-expressions", + "regular_expressions", "strings" - ], - "uuid": "c3035180-ff4c-4afe-8019-f8364158b74e" + ] }, { + "slug": "prime-factors", + "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f", "core": true, + "unlocked_by": null, "difficulty": 4, - "slug": "prime-factors", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics" - ], - "uuid": "73ecd6c2-e59b-4354-b305-64e28a60433f" + ] }, { + "slug": "matrix", + "uuid": "fbfe6032-c209-40bd-b485-8b2881638166", "core": true, + "unlocked_by": null, "difficulty": 4, - "slug": "matrix", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "data-structures", + "control_flow_conditionals", + "control_flow_loops", + "data_structures", "matrices", - "text-formatting" - ], - "uuid": "fbfe6032-c209-40bd-b485-8b2881638166" + "text_formatting" + ] }, { + "slug": "linked-list", + "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385", "core": true, + "unlocked_by": null, "difficulty": 5, - "slug": "linked-list", "topics": [ "algorithms", "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "data-structures", + "control_flow_conditionals", + "control_flow_loops", + "data_structures", "lists", - "optional-values" - ], - "uuid": "ecc41237-f629-458f-873e-2cc51ba1a385" + "optional_values" + ] }, { + "slug": "pascals-triangle", + "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf", "core": true, + "unlocked_by": null, "difficulty": 5, - "slug": "pascals-triangle", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "mathematics", "strings", - "text-formatting" - ], - "uuid": "a96ab45d-10a0-42cf-a754-c2466037ceaf" + "text_formatting" + ] }, { + "slug": "secret-handshake", + "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0", "core": true, + "unlocked_by": null, "difficulty": 6, - "slug": "secret-handshake", "topics": [ "algorithms", "arrays", - "bitwise-operations", - "control-flow-(conditionals)", - "control-flow-(loops)", + "bitwise_operations", + "control_flow_conditionals", + "control_flow_loops", "games" - ], - "uuid": "0a3a452c-f734-47eb-8e65-34c8ae710ef0" + ] }, { + "slug": "rotational-cipher", + "uuid": "7078b1a4-ef73-4c02-809d-b2de62e9af11", "core": false, + "unlocked_by": "secret-handshake", "difficulty": 6, - "slug": "rotational-cipher", "topics": [ "cryptography", "integers", "strings" - ], - "unlocked_by": "secret-handshake", - "uuid": "7078b1a4-ef73-4c02-809d-b2de62e9af11" + ] }, { + "slug": "grade-school", + "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec", "core": true, + "unlocked_by": null, "difficulty": 6, - "slug": "grade-school", "topics": [ "arrays", "maps", "sorting" - ], - "uuid": "029bc3ed-772d-439b-bd0a-1ba1196a79ec" + ] }, { + "slug": "robot-name", + "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a", "core": true, + "unlocked_by": null, "difficulty": 6, - "slug": "robot-name", "topics": [ - "control-flow-(conditionals)", - "exception-handling", + "control_flow_conditionals", + "exception_handling", "randomness", - "regular-expressions", + "regular_expressions", "sets" - ], - "uuid": "3005340b-a8d6-46ac-9075-125f9adccc2a" + ] }, { + "slug": "wordy", + "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843", "core": true, + "unlocked_by": null, "difficulty": 7, - "slug": "wordy", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "parsing", - "pattern-recognition", - "regular-expressions", + "pattern_recognition", + "regular_expressions", "strings" - ], - "uuid": "bb54bf08-24ba-45e1-bdf7-08db161e5843" + ] }, { + "slug": "list-ops", + "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c", "core": true, + "unlocked_by": null, "difficulty": 8, - "slug": "list-ops", "topics": [ - "data-structures", + "data_structures", "lists", "recursion" - ], - "uuid": "e70defe4-5944-4392-956c-63cb92e7fd9c" + ] }, { + "slug": "rational-numbers", + "uuid": "2de5677e-5759-4a21-93c7-39a3d88242e8", "core": false, + "unlocked_by": "pascals-triangle", "difficulty": 5, - "slug": "rational-numbers", "topics": [ + "algorithms", "floating_point_numbers", - "mathematics", - "algorithms" - ], - "unlocked_by": "pascals-triangle", - "uuid": "2de5677e-5759-4a21-93c7-39a3d88242e8" + "mathematics" + ] }, { + "slug": "hamming", + "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0", "core": false, + "unlocked_by": "rna-transcription", "difficulty": 2, - "slug": "hamming", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "equality", "strings" - ], - "unlocked_by": "rna-transcription", - "uuid": "3e1358c8-2bea-41f9-bc9e-8277f354a4e0" + ] }, { + "slug": "run-length-encoding", + "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac", "core": false, + "unlocked_by": null, "difficulty": 2, - "slug": "run-length-encoding", "topics": [ - "control-flow-(conditionals)", - "exception-handling", + "control_flow_conditionals", + "exception_handling", "parsing", - "pattern-recognition", - "regular-expressions", + "pattern_recognition", + "regular_expressions", "strings", - "text-formatting" - ], - "unlocked_by": null, - "uuid": "d66c2b56-b465-4922-af35-ae78944c0aac" + "text_formatting" + ] }, { + "slug": "isogram", + "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0", "core": false, + "unlocked_by": "pangram", "difficulty": 2, - "slug": "isogram", "topics": [ "filtering", "strings" - ], - "unlocked_by": "pangram", - "uuid": "35821375-5c94-4d4b-aa56-e3b079a45ca0" + ] }, { + "slug": "beer-song", + "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a", "core": false, + "unlocked_by": "bob", "difficulty": 5, - "slug": "beer-song", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "strings" - ], - "unlocked_by": "bob", - "uuid": "6f315fc3-095a-4387-aefb-cc5fee97110a" + ] }, { + "slug": "phone-number", + "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70", "core": false, + "unlocked_by": "pangram", "difficulty": 3, - "slug": "phone-number", "topics": [ "parsing", "transforming" - ], - "unlocked_by": "pangram", - "uuid": "347f9f54-a0d9-469d-babf-b3edb34d9d70" + ] }, { + "slug": "anagram", + "uuid": "432ec2ce-c919-4142-aea2-389b67503252", "core": false, + "unlocked_by": "pangram", "difficulty": 1, - "slug": "anagram", "topics": [ "filtering", "strings" - ], - "unlocked_by": "pangram", - "uuid": "432ec2ce-c919-4142-aea2-389b67503252" + ] }, { + "slug": "food-chain", + "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17", "core": false, + "unlocked_by": "bob", "difficulty": 4, - "slug": "food-chain", "topics": [ "algorithms", - "text-formatting" - ], - "unlocked_by": "bob", - "uuid": "a717745f-da00-4a5f-8bf3-6876e20cdf17" + "text_formatting" + ] }, { + "slug": "etl", + "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a", "core": false, + "unlocked_by": "rna-transcription", "difficulty": 2, - "slug": "etl", "topics": [ - "control-flow-(loops)", + "control_flow_loops", "integers", "maps", "transforming" - ], - "unlocked_by": "rna-transcription", - "uuid": "a2a19f61-62ba-447a-8f57-537c8baa2e7a" + ] }, { + "slug": "sublist", + "uuid": "4a83a72c-db0a-45b6-b77c-1949cb24fbae", "core": false, + "unlocked_by": "linked-list", "difficulty": 4, - "slug": "sublist", "topics": [ "arrays", "lists" - ], - "unlocked_by": "linked-list", - "uuid": "4a83a72c-db0a-45b6-b77c-1949cb24fbae" + ] }, { + "slug": "grains", + "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda", "core": false, + "unlocked_by": "space-age", "difficulty": 5, - "slug": "grains", "topics": [ - "control-flow-(loops)", + "control_flow_loops", "integers", "mathematics" - ], - "unlocked_by": "space-age", - "uuid": "c5be6908-f45c-4278-ba99-3701024f4eda" + ] }, { + "slug": "triangle", + "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d", "core": false, + "unlocked_by": "leap", "difficulty": 3, - "slug": "triangle", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics" - ], - "unlocked_by": "leap", - "uuid": "fde792fa-84e9-4b86-8ecb-8466ad92a99d" + ] }, { + "slug": "clock", + "uuid": "1ff85150-6c51-4758-af02-4484cf35658e", "core": false, + "unlocked_by": "gigasecond", "difficulty": 5, - "slug": "clock", "topics": [ "dates", "globalization", "time" - ], - "unlocked_by": "gigasecond", - "uuid": "1ff85150-6c51-4758-af02-4484cf35658e" + ] }, { + "slug": "perfect-numbers", + "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6", "core": false, + "unlocked_by": "space-age", "difficulty": 3, - "slug": "perfect-numbers", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics" - ], - "unlocked_by": "space-age", - "uuid": "51aa5429-b2db-43ad-83cf-84e2ead22cb6" + ] }, { + "slug": "word-count", + "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838", "core": false, + "unlocked_by": "pangram", "difficulty": 1, - "slug": "word-count", "topics": [ - "control-flow-(loops)", + "control_flow_loops", "lists", - "regular-expressions", + "regular_expressions", "strings", "unicode" - ], - "unlocked_by": "pangram", - "uuid": "9a4ea3da-ad43-4850-bdf3-2c578c5de838" + ] }, { + "slug": "acronym", + "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b", "core": false, + "unlocked_by": "pangram", "difficulty": 2, - "slug": "acronym", "topics": [ - "control-flow-(loops)", - "regular-expressions", + "control_flow_loops", + "regular_expressions", "strings", "transforming" - ], - "unlocked_by": "pangram", - "uuid": "0c1c4788-0372-42e7-81c1-b090bb7ebc8b" + ] }, { + "slug": "scrabble-score", + "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b", "core": false, + "unlocked_by": "rna-transcription", "difficulty": 5, - "slug": "scrabble-score", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "maps", "strings" - ], - "unlocked_by": "rna-transcription", - "uuid": "a6bd8126-3879-4593-8380-39ebfa87801b" + ] }, { + "slug": "roman-numerals", + "uuid": "4226e3c6-99d4-406d-998a-bcf11845b211", "core": false, + "unlocked_by": null, "difficulty": 3, - "slug": "roman-numerals", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "mathematics", - "pattern-recognition", + "pattern_recognition", "transforming" - ], - "unlocked_by": null, - "uuid": "4226e3c6-99d4-406d-998a-bcf11845b211" + ] }, { + "slug": "circular-buffer", + "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc", "core": false, + "unlocked_by": "linked-list", "difficulty": 8, - "slug": "circular-buffer", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "data-structures", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "data_structures", + "exception_handling", "lists" - ], - "unlocked_by": "linked-list", - "uuid": "f1943e87-182a-44f5-a885-3d68a0c0a0dc" + ] }, { + "slug": "raindrops", + "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d", "core": false, + "unlocked_by": "rna-transcription", "difficulty": 2, - "slug": "raindrops", "topics": [ - "control-flow-(conditionals)", + "control_flow_conditionals", "integers", "strings", "transforming" - ], - "unlocked_by": "rna-transcription", - "uuid": "86b1acf1-9e2d-4b04-b8b0-e9ae6beb5f3d" + ] }, { + "slug": "allergies", + "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02", "core": false, + "unlocked_by": "rna-transcription", "difficulty": 6, - "slug": "allergies", "topics": [ "arrays", - "bitwise-operations", - "control-flow-(conditionals)", - "control-flow-(loops)" - ], - "unlocked_by": "rna-transcription", - "uuid": "23210e9e-81f6-4279-a776-00459c7ccd02" + "bitwise_operations", + "control_flow_conditionals", + "control_flow_loops" + ] }, { + "slug": "strain", + "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247", "core": false, + "unlocked_by": "list-ops", "difficulty": 4, - "slug": "strain", "topics": [ "algorithms", "arrays", "callbacks", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "filtering", "lists" - ], - "unlocked_by": "list-ops", - "uuid": "e61f3d54-55d2-4d32-9d2a-e7d6af3a3247" + ] }, { + "slug": "atbash-cipher", + "uuid": "99974454-0736-4cc0-b88f-ed5701397a97", "core": false, + "unlocked_by": "simple-cipher", "difficulty": 7, - "slug": "atbash-cipher", "topics": [ "algorithms", "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "regular-expressions", - "text-formatting" - ], - "unlocked_by": "simple-cipher", - "uuid": "99974454-0736-4cc0-b88f-ed5701397a97" + "control_flow_conditionals", + "control_flow_loops", + "regular_expressions", + "text_formatting" + ] }, { + "slug": "accumulate", + "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9", "core": false, + "unlocked_by": "list-ops", "difficulty": 5, - "slug": "accumulate", "topics": [ "algorithms", "callbacks", - "control-flow-(loops)", + "control_flow_loops", "lists" - ], - "unlocked_by": "list-ops", - "uuid": "dc9b2598-9757-4b20-82f9-8049ad081ac9" + ] }, { + "slug": "crypto-square", + "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad", "core": false, + "unlocked_by": "simple-cipher", "difficulty": 9, - "slug": "crypto-square", "topics": [ "algorithms", "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "regular-expressions", + "control_flow_conditionals", + "control_flow_loops", + "regular_expressions", "sorting", - "text-formatting", + "text_formatting", "transforming" - ], - "unlocked_by": "simple-cipher", - "uuid": "a98e3593-d5b4-4c2b-8569-ae3ae7e07dad" + ] }, { + "slug": "trinary", + "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d", "core": false, + "unlocked_by": "binary", "difficulty": 4, - "slug": "trinary", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics", - "regular-expressions", + "regular_expressions", "strings" - ], - "unlocked_by": "binary", - "uuid": "f317721d-e1f5-4e68-9fdc-f9bc7b6b004d" + ] }, { + "slug": "sieve", + "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32", "core": false, + "unlocked_by": "prime-factors", "difficulty": 5, - "slug": "sieve", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics", "recursion" - ], - "unlocked_by": "prime-factors", - "uuid": "4cad8ee8-40be-4d4d-8c14-45d8c6e29a32" + ] }, { + "slug": "octal", + "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8", "core": false, + "unlocked_by": "binary", "difficulty": 4, - "slug": "octal", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics", - "regular-expressions", + "regular_expressions", "strings" - ], - "unlocked_by": "binary", - "uuid": "9892d47d-97a0-4a2f-8284-6f84c86559e8" + ] }, { + "slug": "luhn", + "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c", "core": false, + "unlocked_by": "space-age", "difficulty": 4, - "slug": "luhn", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics", "strings" - ], - "unlocked_by": "space-age", - "uuid": "bb46e832-8c37-45ee-9ee7-5037015b965c" + ] }, { + "slug": "pig-latin", + "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38", "core": false, + "unlocked_by": "bob", "difficulty": 4, - "slug": "pig-latin", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "games", - "regular-expressions", + "regular_expressions", "strings", "transforming" - ], - "unlocked_by": "bob", - "uuid": "9a515ad0-34c7-4191-8784-5c4cd6385b38" + ] }, { + "slug": "pythagorean-triplet", + "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6", "core": false, + "unlocked_by": "space-age", "difficulty": 5, - "slug": "pythagorean-triplet", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics" - ], - "unlocked_by": "space-age", - "uuid": "26a973dd-d72e-40fb-abeb-0ba306356ed6" + ] }, { + "slug": "series", + "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5", "core": false, + "unlocked_by": "pangram", "difficulty": 3, - "slug": "series", "topics": [ - "control-flow-(loops)", - "exception-handling", + "control_flow_loops", + "exception_handling", "strings", - "text-formatting" - ], - "unlocked_by": "pangram", - "uuid": "06afdb06-8d2a-4cb0-baf1-48ae997cf1f5" + "text_formatting" + ] }, { + "slug": "difference-of-squares", + "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f", "core": false, + "unlocked_by": "space-age", "difficulty": 3, - "slug": "difference-of-squares", "topics": [ "algorithms", - "control-flow-(loops)", + "control_flow_loops", "integers", "mathematics" - ], - "unlocked_by": "space-age", - "uuid": "07110dd5-b879-40b9-9485-685cb0963d8f" + ] }, { + "slug": "proverb", + "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308", "core": false, + "unlocked_by": "bob", "difficulty": 4, - "slug": "proverb", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "optional-values", + "control_flow_conditionals", + "control_flow_loops", + "optional_values", "strings", - "text-formatting" - ], - "unlocked_by": "bob", - "uuid": "8786d591-077b-49bc-be8d-d014dc9dc308" + "text_formatting" + ] }, { + "slug": "flatten-array", + "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916", "core": false, + "unlocked_by": "list-ops", "difficulty": 1, - "slug": "flatten-array", "topics": [ "arrays", "recursion" - ], - "unlocked_by": "list-ops", - "uuid": "32a0a5fa-c7de-470c-beff-118b448b3916" + ] }, { + "slug": "hexadecimal", + "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870", "core": false, + "unlocked_by": "binary", "difficulty": 4, - "slug": "hexadecimal", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "mathematics", - "regular-expressions", + "regular_expressions", "strings" - ], - "unlocked_by": "binary", - "uuid": "33b8f4c0-3210-478a-9225-5c30ad6df870" + ] }, { + "slug": "largest-series-product", + "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c", "core": false, + "unlocked_by": "pangram", "difficulty": 7, - "slug": "largest-series-product", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics", - "regular-expressions", + "regular_expressions", "strings" - ], - "unlocked_by": "pangram", - "uuid": "44bd02a7-0e3a-4441-ab76-524e36d4661c" + ] }, { + "slug": "kindergarten-garden", + "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87", "core": false, + "unlocked_by": "wordy", "difficulty": 7, - "slug": "kindergarten-garden", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "strings", - "text-formatting" - ], - "unlocked_by": "wordy", - "uuid": "2702ac90-0be2-43a2-91b6-7256a25fec87" + "text_formatting" + ] }, { + "slug": "binary-search", + "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8", "core": false, + "unlocked_by": "linked-list", "difficulty": 7, - "slug": "binary-search", "topics": [ "algorithms", "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "recursion" - ], - "unlocked_by": "linked-list", - "uuid": "5991c379-f033-4b46-9702-6b7fd03640e8" + ] }, { + "slug": "binary-search-tree", + "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85", "core": false, + "unlocked_by": "linked-list", "difficulty": 6, - "slug": "binary-search-tree", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "recursion" - ], - "unlocked_by": "linked-list", - "uuid": "865806e0-950f-49a5-a6e5-26472b90ab85" + ] }, { + "slug": "robot-simulator", + "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad", "core": false, + "unlocked_by": "wordy", "difficulty": 5, - "slug": "robot-simulator", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "games", "parsing", "strings" - ], - "unlocked_by": "wordy", - "uuid": "00002977-ea1e-45e2-b66e-09d793b5c1ad" + ] }, { + "slug": "nth-prime", + "uuid": "8fa51380-ec2c-4806-8833-cf543579de17", "core": false, + "unlocked_by": "prime-factors", "difficulty": 5, - "slug": "nth-prime", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics" - ], - "unlocked_by": "prime-factors", - "uuid": "8fa51380-ec2c-4806-8833-cf543579de17" + ] }, { + "slug": "palindrome-products", + "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1", "core": false, + "unlocked_by": "prime-factors", "difficulty": 7, - "slug": "palindrome-products", "topics": [ "algorithms", - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics" - ], - "unlocked_by": "prime-factors", - "uuid": "fde83f66-d927-48f8-a599-efb98927f0b1" + ] }, { + "slug": "say", + "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa", "core": false, + "unlocked_by": "bob", "difficulty": 6, - "slug": "say", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics", "strings", - "text-formatting" - ], - "unlocked_by": "bob", - "uuid": "01d286f6-5f29-4d4b-a4de-e217a4833bfa" + "text_formatting" + ] }, { + "slug": "custom-set", + "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659", "core": false, + "unlocked_by": "linked-list", "difficulty": 6, - "slug": "custom-set", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "data-structures", + "control_flow_conditionals", + "control_flow_loops", + "data_structures", "equality", "lists", "recursion", "sets" - ], - "unlocked_by": "linked-list", - "uuid": "d4ec15c4-2742-493b-97fe-9d5121f0b659" + ] }, { + "slug": "sum-of-multiples", + "uuid": "f30463c4-9d8c-4238-a691-e594291b4425", "core": false, + "unlocked_by": "prime-factors", "difficulty": 5, - "slug": "sum-of-multiples", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "integers", "lists" - ], - "unlocked_by": "prime-factors", - "uuid": "f30463c4-9d8c-4238-a691-e594291b4425" + ] }, { + "slug": "queen-attack", + "uuid": "fefcfeba-59ec-4c63-a562-374201ee39a7", "core": false, + "unlocked_by": null, "difficulty": 8, - "slug": "queen-attack", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "equality", - "exception-handling", - "optional-values", + "exception_handling", + "optional_values", "parsing", - "text-formatting" - ], - "unlocked_by": null, - "uuid": "fefcfeba-59ec-4c63-a562-374201ee39a7" + "text_formatting" + ] }, { + "slug": "saddle-points", + "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb", "core": false, + "unlocked_by": "matrix", "difficulty": 6, - "slug": "saddle-points", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "equality", - "exception-handling", + "exception_handling", "integers", "mathematics", "matrices", - "optional-values", + "optional_values", "parsing" - ], - "unlocked_by": "matrix", - "uuid": "98cbae4f-78b6-4745-b922-39e8db9a12bb" + ] }, { + "slug": "ocr-numbers", + "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756", "core": false, + "unlocked_by": "matrix", "difficulty": 5, - "slug": "ocr-numbers", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "equality", - "exception-handling", + "exception_handling", "integers", "parsing", - "text-formatting" - ], - "unlocked_by": "matrix", - "uuid": "759618b1-7ccc-46cd-889d-aea58ec88756" + "text_formatting" + ] }, { + "slug": "meetup", + "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8", "core": false, + "unlocked_by": "gigasecond", "difficulty": 7, - "slug": "meetup", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", + "control_flow_conditionals", + "control_flow_loops", "dates", "equality", - "exception-handling", + "exception_handling", "time" - ], - "unlocked_by": "gigasecond", - "uuid": "86b1b6ba-c1fe-492d-a7ec-c22c525b4da8" + ] }, { + "slug": "bracket-push", + "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84", "core": false, + "unlocked_by": "pangram", "difficulty": 3, - "slug": "bracket-push", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "parsing", "strings" - ], - "unlocked_by": "pangram", - "uuid": "25099f87-5c3b-4a8a-b648-4639d1e9fa84" + ] }, { + "slug": "two-bucket", + "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1", "core": false, + "unlocked_by": "grade-school", "difficulty": 6, - "slug": "two-bucket", "topics": [ "algorithms", "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "games", "parsing" - ], - "unlocked_by": "grade-school", - "uuid": "4c857b17-33b0-47fa-b981-6b2fe4e394a1" + ] }, { + "slug": "bowling", + "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9", "core": false, + "unlocked_by": "grade-school", "difficulty": 8, - "slug": "bowling", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "games", "parsing", - "text-formatting" - ], - "unlocked_by": "grade-school", - "uuid": "c168fe1f-f84e-46e6-91fc-7553d048a4e9" + "text_formatting" + ] }, { + "slug": "diamond", + "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956", "core": false, + "unlocked_by": "pascals-triangle", "difficulty": 5, - "slug": "diamond", "topics": [ "arrays", - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "games", "parsing", - "text-formatting" - ], - "unlocked_by": "pascals-triangle", - "uuid": "04a4ef78-5b61-454f-8c37-798875fb4956" + "text_formatting" + ] }, { + "slug": "all-your-base", + "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791", "core": false, + "unlocked_by": "binary", "difficulty": 5, - "slug": "all-your-base", "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "exception-handling", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling", "integers", "mathematics", "parsing" - ], - "unlocked_by": "binary", - "uuid": "cdfcec62-f2f3-4408-ad2c-8b5e1e56e791" + ] }, { + "slug": "minesweeper", + "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3", "core": false, + "unlocked_by": null, "difficulty": 7, - "slug": "minesweeper", "topics": [ "algorithms", "arrays", "games" - ], - "unlocked_by": null, - "uuid": "22fa5ab4-935b-44cc-b055-9803214ae5f3" + ] }, { + "slug": "alphametics", + "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a", "core": false, + "unlocked_by": "grade-school", "difficulty": 7, - "slug": "alphametics", "topics": [ "algorithms", "games" - ], - "unlocked_by": "grade-school", - "uuid": "42a7fd83-4508-403c-8b5e-f0a3126fac8a" + ] }, { + "slug": "simple-linked-list", + "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626", "core": false, + "unlocked_by": "linked-list", "difficulty": 8, - "slug": "simple-linked-list", "topics": [ "arrays", - "data-structures", + "data_structures", "lists" - ], - "unlocked_by": "linked-list", - "uuid": "c21ab6e8-b845-49d0-a2f6-1c89c7a07626" + ] }, { - "uuid": "833bd7c7-d3d8-45fd-a218-12dea646065d", "slug": "diffie-hellman", + "uuid": "833bd7c7-d3d8-45fd-a218-12dea646065d", "core": false, "unlocked_by": "simple-cipher", "difficulty": 3, "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Algorithms", - "Arrays", - "Exception handling" + "algorithms", + "arrays", + "control_flow_conditionals", + "control_flow_loops", + "exception_handling" ] }, { - "core" : false, - "difficulty" : 8, - "slug" : "change", - "topics": [ - "Algorithms", - "Mathematics", - "Performance", - "Searching" - ], + "slug": "change", + "uuid": "910fe904-7e3c-11e7-bb31-be2e44b06b34", + "core": false, "unlocked_by": "prime-factors", - "uuid" : "910fe904-7e3c-11e7-bb31-be2e44b06b34" + "difficulty": 8, + "topics": [ + "algorithms", + "mathematics", + "performance", + "searching" + ] }, { - "uuid": "3b779cb8-9544-4e0d-a306-e5478d741be7", "slug": "connect", + "uuid": "3b779cb8-9544-4e0d-a306-e5478d741be7", "core": false, "unlocked_by": "grade-school", "difficulty": 7, "topics": [ - "Control-flow (loops)", - "Control-flow (conditionals)", - "Games", - "Parsing", - "Arrays", - "Maps" - ] - }, - { - "core" : false, - "difficulty" : 1, - "slug" : "collatz-conjecture", - "topics": [ - "Control-flow (loops)", - "Control-flow (conditionals)", - "Recursion", - "Integers", - "Algorithms", - "Mathematics" - ], + "arrays", + "control_flow_conditionals", + "control_flow_loops", + "games", + "maps", + "parsing" + ] + }, + { + "slug": "collatz-conjecture", + "uuid": "fd435dad-311a-4c40-9868-70863455831e", + "core": false, "unlocked_by": null, - "uuid" : "fd435dad-311a-4c40-9868-70863455831e" + "difficulty": 1, + "topics": [ + "algorithms", + "control_flow_conditionals", + "control_flow_loops", + "integers", + "mathematics", + "recursion" + ] }, { - "deprecated": true, "slug": "nucleotide-count", - "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c" + "uuid": "1b53340d-ea40-44ee-bf2e-42e516704e7c", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true }, { - "deprecated": true, "slug": "point-mutations", - "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec" + "uuid": "e9a6b2ea-a67d-4b75-800d-7b46240094ec", + "core": false, + "unlocked_by": null, + "difficulty": 0, + "topics": null, + "deprecated": true }, { - "uuid": "09e10522-9853-11e7-abc4-cec278b6b50a", "slug": "twelve-days", + "uuid": "09e10522-9853-11e7-abc4-cec278b6b50a", "core": false, "unlocked_by": "bob", "difficulty": 4, "topics": [ - "Control-flow (conditionals)", - "Control-flow (loops)", - "Strings", - "Pattern recognition" + "control_flow_conditionals", + "control_flow_loops", + "pattern_recognition", + "strings" ] }, { + "slug": "transpose", + "uuid": "7c024853-0540-473d-b2d9-cad84953c00f", "core": false, + "unlocked_by": "matrix", "difficulty": 1, - "slug": "transpose", "topics": [ - "loops", "arrays", "lists", + "loops", "matrices", "strings", "text_formatting" - ], - "unlocked_by": "matrix", - "uuid": "7c024853-0540-473d-b2d9-cad84953c00f" + ] }, { - "uuid": "52c775a4-7ddb-4cba-8a78-8544220bd1b6", "slug": "protein-translation", + "uuid": "52c775a4-7ddb-4cba-8a78-8544220bd1b6", "core": false, "unlocked_by": null, "difficulty": 1, "topics": [ - "control-flow-(conditionals)", - "control-flow-(loops)", - "strings", - "algorithms" + "algorithms", + "control_flow_conditionals", + "control_flow_loops", + "strings" ] }, { - "uuid": "f4a3d66a-04a8-3e80-6c9a-8a573ccb26fd9ed1d5c", "slug": "zipper", + "uuid": "f4a3d66a-04a8-3e80-6c9a-8a573ccb26fd9ed1d5c", "core": false, "unlocked_by": null, "difficulty": 8, @@ -1197,8 +1226,8 @@ ] }, { - "uuid": "8740af44-002c-4716-a759-a68ae4c68737", "slug": "isbn-verifier", + "uuid": "8740af44-002c-4716-a759-a68ae4c68737", "core": false, "unlocked_by": "bob", "difficulty": 4, @@ -1210,20 +1239,20 @@ ] }, { - "uuid": "b3dbc935-536e-4910-994d-4a519b511b6a", "slug": "forth", + "uuid": "b3dbc935-536e-4910-994d-4a519b511b6a", "core": false, "unlocked_by": "matrix", "difficulty": 8, "topics": [ - "stacks", + "domain_specific_languages", "parsing", - "domain_specific_languages" + "stacks" ] }, { - "uuid": "f82e470d-0bcc-4eba-b9b0-8a0c50a6fd19", "slug": "variable-length-quantity", + "uuid": "f82e470d-0bcc-4eba-b9b0-8a0c50a6fd19", "core": false, "unlocked_by": "grade-school", "difficulty": 5, @@ -1233,30 +1262,27 @@ ] }, { - "uuid": "cb09212c-f2ae-4acf-9177-6c7f42594c1d", "slug": "rectangles", + "uuid": "cb09212c-f2ae-4acf-9177-6c7f42594c1d", "core": false, "unlocked_by": "grade-school", "difficulty": 6, "topics": [ "parsing", - "searching", - "pattern_recognition" + "pattern_recognition", + "searching" ] }, { - "uuid": "0e4b628c-870d-446b-a400-3cc72457f2bc", "slug": "armstrong-numbers", + "uuid": "0e4b628c-870d-446b-a400-3cc72457f2bc", "core": false, "unlocked_by": null, "difficulty": 2, "topics": [ - "mathematics", - "algorithms" + "algorithms", + "mathematics" ] } - ], - "foregone": [], - "language": "JavaScript", - "test_pattern": ".*[.]spec[.]js$" + ] } diff --git a/config/maintainers.json b/config/maintainers.json index 59962c14..79432e03 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -2,84 +2,84 @@ "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md", "maintainers": [ { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "ireddick", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null }, { - "alumnus": false, - "avatar_url": null, - "bio": "I'm a Web Developer with a passion for taking code that is hard to maintain and cleaning, refactoring, and bringing it back into a manageable state", "github_username": "rchavarria", + "alumnus": false, + "show_on_website": true, + "name": "Rubén Chavarría", "link_text": "Here is where I blog", "link_url": "https://rchavarria.github.io/", - "name": "Rubén Chavarría", - "show_on_website": true + "avatar_url": null, + "bio": "I'm a Web Developer with a passion for taking code that is hard to maintain and cleaning, refactoring, and bringing it back into a manageable state" }, { - "alumnus": false, - "avatar_url": null, - "bio": "Brazilian full-stack web developer. Mentor at Thinkful", "github_username": "joelwallis", + "alumnus": false, + "show_on_website": true, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": true + "avatar_url": null, + "bio": "Brazilian full-stack web developer. Mentor at Thinkful" }, { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "drueck", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null }, { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "tejasbubane", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null }, { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "matthewmorgan", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null }, { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "mixolidia", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null }, { - "alumnus": false, - "avatar_url": null, - "bio": null, "github_username": "ZacharyRSmith", + "alumnus": false, + "show_on_website": false, + "name": null, "link_text": null, "link_url": null, - "name": null, - "show_on_website": false + "avatar_url": null, + "bio": null } ] } From 9aedefeaa17120caae134aff4a95aebbea977559 Mon Sep 17 00:00:00 2001 From: MadEmperorYuri Date: Mon, 11 Jun 2018 02:38:15 -0500 Subject: [PATCH 265/272] =?UTF-8?q?Removed=20outdated=20mention=20of=20Elo?= =?UTF-8?q?quent=20JavaScript=E2=80=99s=20edition=20number=20(#550)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eloquent JavaScript came out with a 3rd edition some time ago. Previously, LEARNING.md mentioned its 2nd edition instead. Now it mentions no edition. The link is thus futureproofed. --- docs/LEARNING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/LEARNING.md b/docs/LEARNING.md index 0e0322cb..462c8cb2 100644 --- a/docs/LEARNING.md +++ b/docs/LEARNING.md @@ -1,4 +1,4 @@ -* [Eloquent JavaScript: A Modern Introduction to Programming (2nd Ed.)](http://eloquentjavascript.net) +* [Eloquent JavaScript: A Modern Introduction to Programming](http://eloquentjavascript.net) * [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) * [Crockford on JavaScript](http://javascript.crockford.com/) * [idiomatic.js: Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js) From 1645af5ac21e80edffc3a5b04feff2c248a0a102 Mon Sep 17 00:00:00 2001 From: Aaditya Arvind Kulkarni Date: Tue, 12 Jun 2018 00:53:21 -0400 Subject: [PATCH 266/272] fix: pangram tests as per canonical data (#553) --- exercises/pangram/pangram.spec.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/exercises/pangram/pangram.spec.js b/exercises/pangram/pangram.spec.js index 74197329..b2bae495 100644 --- a/exercises/pangram/pangram.spec.js +++ b/exercises/pangram/pangram.spec.js @@ -1,23 +1,28 @@ var Pangram = require('./pangram'); describe('Pangram()', function () { - it('empty sentence', function () { + it('sentence empty', function () { var pangram = new Pangram(''); expect(pangram.isPangram()).toBe(false); }); + xit('recognizes a perfect lower case pangram', function () { + var pangram = new Pangram('abcdefghijklmnopqrstuvwxyz'); + expect(pangram.isPangram()).toBe(true); + }); + xit('pangram with only lower case', function () { var pangram = new Pangram('the quick brown fox jumps over the lazy dog'); expect(pangram.isPangram()).toBe(true); }); - xit("missing character 'x'", function () { + xit("missing character 'x'", function () { var pangram = new Pangram('a quick movement of the enemy will jeopardize five gunboats'); expect(pangram.isPangram()).toBe(false); }); - xit("another missing character 'x'", function () { - var pangram = new Pangram('the quick brown fish jumps over the lazy dog'); + xit("another missing character, e.g. 'h'", function () { + var pangram = new Pangram('five boxing wizards jump quickly at it'); expect(pangram.isPangram()).toBe(false); }); @@ -27,22 +32,22 @@ describe('Pangram()', function () { }); xit('pangram with numbers', function () { - var pangram = new Pangram('the 1 quick brown fox jumps over the 2 lazy dogs'); + var pangram = new Pangram('the 1 quick brown fox jumps over the 2 lazy dog'); expect(pangram.isPangram()).toBe(true); }); - xit('missing letters replaced by numbers', function () { + xit('missing letters replaced by numbers', function () { var pangram = new Pangram('7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog'); expect(pangram.isPangram()).toBe(false); }); xit('pangram with mixed case and punctuation', function () { - var pangram = new Pangram('"Five quacking Zephyrs jolt my wax bed."'); + var pangram = new Pangram('\"Five quacking Zephyrs jolt my wax bed.\"'); expect(pangram.isPangram()).toBe(true); }); - xit('pangram with non-ascii characters', function () { - var pangram = new Pangram('Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.'); - expect(pangram.isPangram()).toBe(true); + xit('upper and lower case versions of the same character should not be counted separately', function () { + var pangram = new Pangram('the quick brown fox jumps over with lazy FX'); + expect(pangram.isPangram()).toBe(false); }); }); From 12cf744172d75b004e61884cc546df878ad1b1f0 Mon Sep 17 00:00:00 2001 From: Gavin Henderson Date: Thu, 14 Jun 2018 23:46:18 +0100 Subject: [PATCH 267/272] Added more tests to nth prime and improved example (#542) --- exercises/nth-prime/example.js | 6 +++++- exercises/nth-prime/nth-prime.spec.js | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/exercises/nth-prime/example.js b/exercises/nth-prime/example.js index faf7d05c..5deed40c 100644 --- a/exercises/nth-prime/example.js +++ b/exercises/nth-prime/example.js @@ -3,7 +3,11 @@ module.exports = { nth: function (nthPrime) { if (nthPrime === 0) { throw new Error('Prime is not possible'); } - this.generatePrimes(200000); + + // Using prime number theory to approximate the prime + // See https://en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number + var upperBound = (nthPrime + 2) * Math.log((nthPrime + 2) * Math.log((nthPrime + 2))); + this.generatePrimes(upperBound); return this.realPrimes[nthPrime - 1]; }, generatePrimes: function (uptoNumber) { diff --git a/exercises/nth-prime/nth-prime.spec.js b/exercises/nth-prime/nth-prime.spec.js index 727ce507..70a326d8 100644 --- a/exercises/nth-prime/nth-prime.spec.js +++ b/exercises/nth-prime/nth-prime.spec.js @@ -17,6 +17,14 @@ describe('Prime', function () { expect(prime.nth(10001)).toEqual(104743); }); + xit('massive prime', function () { + expect(prime.nth(20000)).toEqual(224737); + }); + + xit('extreme prime', function () { + expect(prime.nth(30000)).toEqual(350377); + }); + xit('weird case', function () { expect( function () { prime.nth(0); From ae311aba2438c3ea6d28fb9b83fe300dca2b5dda Mon Sep 17 00:00:00 2001 From: Jack Hughes Date: Thu, 14 Jun 2018 23:53:17 +0100 Subject: [PATCH 268/272] Added blurb (#554) --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 4de97d0b..e909c240 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "language": "JavaScript", "active": true, - "blurb": "", + "blurb": "JavaScript is a scripting language, primarily used for creating dynamic websites and programming web servers. It's a very popular language, and supports a variety of programming paradigms.", "test_pattern": ".*[.]spec[.]js$", "exercises": [ { From 050d9e6bfbf9987bfab9ce9818b435634da8ff60 Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Sat, 23 Jun 2018 12:09:11 -0400 Subject: [PATCH 269/272] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 6001444c..503a5a02 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ +# DEPRECATION NOTICE + +This track will be deprecated as part of the migration of Exercism to V2. Going forward, the EcmaScript track will replace the JavaScript track as "the new JavaScript" track. +- User's old submissions will be migrated +- PRs unrelated to the deprecation will be closed as `wontfix` +- Issues unrelated to deprecation will be closed as `wontfix` + +Thank you to all the many invested and hardworking contributors who have helped to make this track a success!! + # JavaScript [![Build Status](https://travis-ci.org/exercism/javascript.svg?branch=master)](https://travis-ci.org/exercism/javascript)[![Join the chat at https://gitter.im/exercism/xecmascript](https://badges.gitter.im/exercism/xecmascript.svg)](https://gitter.im/exercism/xecmascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Exercism exercises in JavaScript From b3d601e5d4bb8d849dc07297bed368c0c359b7fe Mon Sep 17 00:00:00 2001 From: Matthew Morgan Date: Mon, 16 Jul 2018 09:34:30 -0400 Subject: [PATCH 270/272] Update maintainers.json --- config/maintainers.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/maintainers.json b/config/maintainers.json index 79432e03..11e72347 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -54,12 +54,12 @@ { "github_username": "matthewmorgan", "alumnus": false, - "show_on_website": false, - "name": null, + "show_on_website": true, + "name": "Matt Morgan", "link_text": null, "link_url": null, "avatar_url": null, - "bio": null + "bio": "Learn, build, teach, repeat!" }, { "github_username": "mixolidia", From 618e65dd7626603b9f5651ef5fe321e26889e509 Mon Sep 17 00:00:00 2001 From: Katrina Owen Date: Sun, 19 Aug 2018 15:31:57 -0600 Subject: [PATCH 271/272] Deprecate this track --- README.md | 36 +----------------------------------- config.json | 4 ++-- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 503a5a02..4f5bffa2 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,3 @@ # DEPRECATION NOTICE -This track will be deprecated as part of the migration of Exercism to V2. Going forward, the EcmaScript track will replace the JavaScript track as "the new JavaScript" track. -- User's old submissions will be migrated -- PRs unrelated to the deprecation will be closed as `wontfix` -- Issues unrelated to deprecation will be closed as `wontfix` - -Thank you to all the many invested and hardworking contributors who have helped to make this track a success!! - -# JavaScript [![Build Status](https://travis-ci.org/exercism/javascript.svg?branch=master)](https://travis-ci.org/exercism/javascript)[![Join the chat at https://gitter.im/exercism/xecmascript](https://badges.gitter.im/exercism/xecmascript.svg)](https://gitter.im/exercism/xecmascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Exercism exercises in JavaScript - -## Installing - -To run the tests, you'll need NodeJS and Jasmine. For information about how to install these tools, see the [Javascript](http://exercism.io/languages/javascript/about) page. - -## Tasks - -The following commands assume that you are in the `javascript` directory: - -### Unit Tests: All Assignments - - make test - -### Unit Tests: Single Assignment - - make test-assignment ASSIGNMENT=wordy - -### Code Style - - npm run lint - -## Contributing Guide - -Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data) - +This track is deprecated. Please see the https://github.com/exercism/javascript track. diff --git a/config.json b/config.json index e909c240..e11dd1f6 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { - "language": "JavaScript", - "active": true, + "language": "JavaScript (Legacy)", + "active": false, "blurb": "JavaScript is a scripting language, primarily used for creating dynamic websites and programming web servers. It's a very popular language, and supports a variety of programming paradigms.", "test_pattern": ".*[.]spec[.]js$", "exercises": [ From 1a499fa80077bc9b4c718847e0b877d6b902ff1a Mon Sep 17 00:00:00 2001 From: Jeremy Walker Date: Wed, 15 Jan 2020 16:56:51 +0000 Subject: [PATCH 272/272] Clean up maintainers.json This file needs emptying. If anyone who is in it would like to be transferred as an alumni to exercism/javascript, please open a PR there, referencing this, and I'll merge it. --- config/maintainers.json | 80 ----------------------------------------- 1 file changed, 80 deletions(-) diff --git a/config/maintainers.json b/config/maintainers.json index 11e72347..48b19c6a 100644 --- a/config/maintainers.json +++ b/config/maintainers.json @@ -1,85 +1,5 @@ { "docs_url": "https://github.com/exercism/docs/blob/master/maintaining-a-track/maintainer-configuration.md", "maintainers": [ - { - "github_username": "ireddick", - "alumnus": false, - "show_on_website": false, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": null - }, - { - "github_username": "rchavarria", - "alumnus": false, - "show_on_website": true, - "name": "Rubén Chavarría", - "link_text": "Here is where I blog", - "link_url": "https://rchavarria.github.io/", - "avatar_url": null, - "bio": "I'm a Web Developer with a passion for taking code that is hard to maintain and cleaning, refactoring, and bringing it back into a manageable state" - }, - { - "github_username": "joelwallis", - "alumnus": false, - "show_on_website": true, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": "Brazilian full-stack web developer. Mentor at Thinkful" - }, - { - "github_username": "drueck", - "alumnus": false, - "show_on_website": false, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": null - }, - { - "github_username": "tejasbubane", - "alumnus": false, - "show_on_website": false, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": null - }, - { - "github_username": "matthewmorgan", - "alumnus": false, - "show_on_website": true, - "name": "Matt Morgan", - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": "Learn, build, teach, repeat!" - }, - { - "github_username": "mixolidia", - "alumnus": false, - "show_on_website": false, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": null - }, - { - "github_username": "ZacharyRSmith", - "alumnus": false, - "show_on_website": false, - "name": null, - "link_text": null, - "link_url": null, - "avatar_url": null, - "bio": null - } ] }