trackler 2.2.1.44 → 2.2.1.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/isbn-verifier/canonical-data.json +88 -0
- data/problem-specifications/exercises/isbn-verifier/description.md +35 -0
- data/problem-specifications/exercises/isbn-verifier/metadata.yml +4 -0
- data/problem-specifications/exercises/robot-simulator/canonical-data.json +125 -32
- data/problem-specifications/exercises/sum-of-multiples/description.md +0 -3
- data/problem-specifications/exercises/two-bucket/canonical-data.json +3 -3
- data/tracks/c/config.json +235 -237
- data/tracks/c/exercises/acronym/README.md +0 -1
- data/tracks/c/exercises/all-your-base/README.md +1 -1
- data/tracks/c/exercises/allergies/README.md +0 -1
- data/tracks/c/exercises/atbash-cipher/README.md +2 -1
- data/tracks/c/exercises/beer-song/README.md +1 -1
- data/tracks/c/exercises/binary/README.md +2 -0
- data/tracks/c/exercises/grains/README.md +0 -1
- data/tracks/c/exercises/isogram/README.md +2 -1
- data/tracks/c/exercises/leap/README.md +1 -1
- data/tracks/c/exercises/meetup/README.md +1 -2
- data/tracks/c/exercises/nucleotide-count/README.md +8 -22
- data/tracks/c/exercises/palindrome-products/README.md +12 -6
- data/tracks/c/exercises/pangram/README.md +1 -1
- data/tracks/c/exercises/pascals-triangle/README.md +1 -1
- data/tracks/c/exercises/perfect-numbers/README.md +2 -2
- data/tracks/c/exercises/phone-number/README.md +3 -2
- data/tracks/c/exercises/roman-numerals/README.md +1 -1
- data/tracks/c/exercises/scrabble-score/README.md +3 -1
- data/tracks/c/exercises/space-age/README.md +2 -1
- data/tracks/c/exercises/triangle/README.md +9 -6
- data/tracks/c/exercises/word-count/README.md +1 -2
- data/tracks/csharp/exercises/accumulate/Accumulate.csproj +2 -2
- data/tracks/csharp/exercises/acronym/Acronym.csproj +2 -2
- data/tracks/csharp/exercises/all-your-base/AllYourBase.csproj +2 -2
- data/tracks/csharp/exercises/allergies/Allergies.csproj +2 -2
- data/tracks/csharp/exercises/alphametics/Alphametics.csproj +2 -2
- data/tracks/csharp/exercises/anagram/Anagram.csproj +2 -2
- data/tracks/csharp/exercises/atbash-cipher/AtbashCipher.csproj +2 -2
- data/tracks/csharp/exercises/bank-account/BankAccount.csproj +2 -2
- data/tracks/csharp/exercises/beer-song/BeerSong.csproj +2 -2
- data/tracks/csharp/exercises/binary-search/BinarySearch.csproj +2 -2
- data/tracks/csharp/exercises/binary-search-tree/BinarySearchTree.csproj +2 -2
- data/tracks/csharp/exercises/bob/Bob.csproj +2 -2
- data/tracks/csharp/exercises/book-store/BookStore.csproj +2 -2
- data/tracks/csharp/exercises/bowling/Bowling.csproj +2 -2
- data/tracks/csharp/exercises/bracket-push/BracketPush.csproj +2 -2
- data/tracks/csharp/exercises/change/Change.csproj +2 -2
- data/tracks/csharp/exercises/circular-buffer/CircularBuffer.csproj +2 -2
- data/tracks/csharp/exercises/clock/Clock.csproj +2 -2
- data/tracks/csharp/exercises/collatz-conjecture/CollatzConjecture.csproj +2 -2
- data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.csproj +2 -2
- data/tracks/csharp/exercises/connect/Connect.cs +1 -1
- data/tracks/csharp/exercises/connect/Connect.csproj +2 -2
- data/tracks/csharp/exercises/connect/ConnectTest.cs +120 -85
- data/tracks/csharp/exercises/connect/Example.cs +11 -7
- data/tracks/csharp/exercises/crypto-square/CryptoSquare.csproj +2 -2
- data/tracks/csharp/exercises/custom-set/CustomSet.csproj +2 -2
- data/tracks/csharp/exercises/diamond/Diamond.csproj +2 -2
- data/tracks/csharp/exercises/difference-of-squares/DifferenceOfSquares.csproj +2 -2
- data/tracks/csharp/exercises/diffie-hellman/DiffieHellman.csproj +2 -2
- data/tracks/csharp/exercises/dominoes/Dominoes.csproj +2 -2
- data/tracks/csharp/exercises/dot-dsl/DotDsl.csproj +2 -2
- data/tracks/csharp/exercises/error-handling/ErrorHandling.csproj +2 -2
- data/tracks/csharp/exercises/etl/Etl.csproj +2 -2
- data/tracks/csharp/exercises/flatten-array/FlattenArray.csproj +2 -2
- data/tracks/csharp/exercises/food-chain/FoodChain.csproj +2 -2
- data/tracks/csharp/exercises/forth/Forth.csproj +2 -2
- data/tracks/csharp/exercises/gigasecond/Gigasecond.csproj +2 -2
- data/tracks/csharp/exercises/go-counting/GoCounting.csproj +2 -2
- data/tracks/csharp/exercises/grade-school/GradeSchool.csproj +2 -2
- data/tracks/csharp/exercises/grains/Grains.csproj +2 -2
- data/tracks/csharp/exercises/grep/Grep.csproj +2 -2
- data/tracks/csharp/exercises/hamming/Hamming.csproj +2 -2
- data/tracks/csharp/exercises/hangman/Hangman.csproj +2 -2
- data/tracks/csharp/exercises/hello-world/HelloWorld.csproj +2 -2
- data/tracks/csharp/exercises/house/House.csproj +2 -2
- data/tracks/csharp/exercises/isogram/Isogram.csproj +2 -2
- data/tracks/csharp/exercises/kindergarten-garden/KindergartenGarden.csproj +2 -2
- data/tracks/csharp/exercises/largest-series-product/LargestSeriesProduct.csproj +2 -2
- data/tracks/csharp/exercises/leap/Leap.csproj +2 -2
- data/tracks/csharp/exercises/ledger/Ledger.csproj +2 -2
- data/tracks/csharp/exercises/linked-list/LinkedList.csproj +2 -2
- data/tracks/csharp/exercises/list-ops/ListOps.csproj +2 -2
- data/tracks/csharp/exercises/luhn/Luhn.csproj +2 -2
- data/tracks/csharp/exercises/markdown/Markdown.csproj +2 -2
- data/tracks/csharp/exercises/matrix/Matrix.csproj +2 -2
- data/tracks/csharp/exercises/meetup/Meetup.csproj +2 -2
- data/tracks/csharp/exercises/minesweeper/Minesweeper.csproj +2 -2
- data/tracks/csharp/exercises/nth-prime/NthPrime.csproj +2 -2
- data/tracks/csharp/exercises/nucleotide-count/NucleotideCount.csproj +2 -2
- data/tracks/csharp/exercises/ocr-numbers/OcrNumbers.csproj +2 -2
- data/tracks/csharp/exercises/palindrome-products/PalindromeProducts.csproj +2 -2
- data/tracks/csharp/exercises/pangram/Pangram.csproj +2 -2
- data/tracks/csharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.csproj +2 -2
- data/tracks/csharp/exercises/pascals-triangle/PascalsTriangle.csproj +2 -2
- data/tracks/csharp/exercises/perfect-numbers/PerfectNumbers.csproj +2 -2
- data/tracks/csharp/exercises/phone-number/PhoneNumber.csproj +2 -2
- data/tracks/csharp/exercises/pig-latin/PigLatin.csproj +2 -2
- data/tracks/csharp/exercises/poker/Poker.csproj +2 -2
- data/tracks/csharp/exercises/pov/Pov.csproj +2 -2
- data/tracks/csharp/exercises/prime-factors/PrimeFactors.csproj +2 -2
- data/tracks/csharp/exercises/protein-translation/ProteinTranslation.csproj +2 -2
- data/tracks/csharp/exercises/proverb/Proverb.csproj +2 -2
- data/tracks/csharp/exercises/pythagorean-triplet/PythagoreanTriplet.csproj +2 -2
- data/tracks/csharp/exercises/queen-attack/QueenAttack.csproj +2 -2
- data/tracks/csharp/exercises/rail-fence-cipher/RailFenceCipher.csproj +2 -2
- data/tracks/csharp/exercises/raindrops/Raindrops.csproj +2 -2
- data/tracks/csharp/exercises/react/React.csproj +2 -2
- data/tracks/csharp/exercises/rectangles/Rectangles.csproj +2 -2
- data/tracks/csharp/exercises/rna-transcription/RnaTranscription.csproj +2 -2
- data/tracks/csharp/exercises/robot-name/RobotName.csproj +2 -2
- data/tracks/csharp/exercises/robot-simulator/RobotSimulator.csproj +2 -2
- data/tracks/csharp/exercises/roman-numerals/RomanNumerals.csproj +2 -2
- data/tracks/csharp/exercises/rotational-cipher/RotationalCipher.csproj +2 -2
- data/tracks/csharp/exercises/run-length-encoding/RunLengthEncoding.csproj +2 -2
- data/tracks/csharp/exercises/saddle-points/SaddlePoints.csproj +2 -2
- data/tracks/csharp/exercises/say/Say.csproj +2 -2
- data/tracks/csharp/exercises/scale-generator/ScaleGenerator.csproj +2 -2
- data/tracks/csharp/exercises/scrabble-score/ScrabbleScore.csproj +2 -2
- data/tracks/csharp/exercises/secret-handshake/SecretHandshake.csproj +2 -2
- data/tracks/csharp/exercises/series/Series.csproj +2 -2
- data/tracks/csharp/exercises/series/SeriesTest.cs +17 -17
- data/tracks/csharp/exercises/sgf-parsing/SgfParsing.csproj +2 -2
- data/tracks/csharp/exercises/sieve/Sieve.csproj +2 -2
- data/tracks/csharp/exercises/simple-cipher/SimpleCipher.csproj +2 -2
- data/tracks/csharp/exercises/simple-linked-list/SimpleLinkedList.csproj +2 -2
- data/tracks/csharp/exercises/space-age/SpaceAge.csproj +2 -2
- data/tracks/csharp/exercises/spiral-matrix/SpiralMatrix.csproj +2 -2
- data/tracks/csharp/exercises/strain/Strain.csproj +2 -2
- data/tracks/csharp/exercises/sublist/Sublist.csproj +2 -2
- data/tracks/csharp/exercises/sum-of-multiples/SumOfMultiples.csproj +2 -2
- data/tracks/csharp/exercises/tournament/Tournament.csproj +2 -2
- data/tracks/csharp/exercises/transpose/Transpose.csproj +2 -2
- data/tracks/csharp/exercises/tree-building/TreeBuilding.csproj +2 -2
- data/tracks/csharp/exercises/triangle/Triangle.cs +0 -11
- data/tracks/csharp/exercises/triangle/Triangle.csproj +2 -2
- data/tracks/csharp/exercises/triangle/TriangleTest.cs +17 -17
- data/tracks/csharp/exercises/twelve-days/TwelveDays.csproj +2 -2
- data/tracks/csharp/exercises/two-bucket/TwoBucket.csproj +2 -2
- data/tracks/csharp/exercises/two-fer/TwoFer.csproj +2 -2
- data/tracks/csharp/exercises/variable-length-quantity/VariableLengthQuantity.csproj +2 -2
- data/tracks/csharp/exercises/word-count/WordCount.csproj +2 -2
- data/tracks/csharp/exercises/word-search/WordSearch.csproj +2 -2
- data/tracks/csharp/exercises/wordy/Wordy.csproj +2 -2
- data/tracks/csharp/exercises/zebra-puzzle/ZebraPuzzle.csproj +2 -2
- data/tracks/csharp/exercises/zipper/Zipper.csproj +2 -2
- data/tracks/csharp/generators/Exercises/Connect.cs +47 -0
- data/tracks/csharp/generators/Exercises/Triangle.cs +1 -1
- data/tracks/dart/config/maintainers.json +27 -1
- data/tracks/dart/pubspec.yaml +3 -0
- data/tracks/dart/tool/create-exercise +144 -5
- data/tracks/elm/.gitattributes +1 -0
- data/tracks/elm/bin/install-elm-format +9 -3
- data/tracks/elm/config.json +30 -0
- data/tracks/elm/exercises/all-your-base/AllYourBase.elm +1 -0
- data/tracks/elm/exercises/all-your-base/AllYourBase.example.elm +68 -0
- data/tracks/elm/exercises/all-your-base/README.md +65 -0
- data/tracks/elm/exercises/all-your-base/elm-package.json +15 -0
- data/tracks/elm/exercises/all-your-base/tests/Tests.elm +53 -0
- data/tracks/elm/exercises/all-your-base/tests/elm-package.json +16 -0
- data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.elm +2 -0
- data/tracks/elm/exercises/collatz-conjecture/CollatzConjecture.example.elm +19 -0
- data/tracks/elm/exercises/collatz-conjecture/elm-package.json +15 -0
- data/tracks/elm/exercises/collatz-conjecture/package.json +14 -0
- data/tracks/elm/exercises/collatz-conjecture/tests/Tests.elm +38 -0
- data/tracks/elm/exercises/collatz-conjecture/tests/elm-package.json +16 -0
- data/tracks/elm/exercises/isogram/Isogram.elm +1 -0
- data/tracks/elm/exercises/isogram/Isogram.example.elm +76 -0
- data/tracks/elm/exercises/isogram/README.md +50 -0
- data/tracks/elm/exercises/isogram/elm-package.json +14 -0
- data/tracks/elm/exercises/isogram/package.json +14 -0
- data/tracks/elm/exercises/isogram/tests/Tests.elm +46 -0
- data/tracks/elm/exercises/isogram/tests/elm-package.json +16 -0
- data/tracks/fsharp/.gitignore +2 -1
- data/tracks/fsharp/exercises/accumulate/Accumulate.fsproj +3 -2
- data/tracks/fsharp/exercises/acronym/Acronym.fs +1 -1
- data/tracks/fsharp/exercises/acronym/Acronym.fsproj +3 -2
- data/tracks/fsharp/exercises/acronym/AcronymTest.fs +13 -38
- data/tracks/fsharp/exercises/acronym/Example.fs +1 -1
- data/tracks/fsharp/exercises/all-your-base/AllYourBase.fsproj +3 -2
- data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +64 -61
- data/tracks/fsharp/exercises/all-your-base/Example.fs +4 -1
- data/tracks/fsharp/exercises/allergies/Allergies.fs +2 -2
- data/tracks/fsharp/exercises/allergies/Allergies.fsproj +3 -2
- data/tracks/fsharp/exercises/allergies/AllergiesTest.fs +28 -37
- data/tracks/fsharp/exercises/allergies/Example.fs +3 -3
- data/tracks/fsharp/exercises/alphametics/Alphametics.fsproj +3 -2
- data/tracks/fsharp/exercises/anagram/Anagram.fsproj +3 -2
- data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fs +4 -2
- data/tracks/fsharp/exercises/atbash-cipher/AtbashCipher.fsproj +3 -2
- data/tracks/fsharp/exercises/atbash-cipher/AtbashCipherTest.fs +38 -42
- data/tracks/fsharp/exercises/atbash-cipher/Example.fs +5 -3
- data/tracks/fsharp/exercises/bank-account/BankAccount.fsproj +3 -2
- data/tracks/fsharp/exercises/beer-song/BeerSong.fsproj +3 -2
- data/tracks/fsharp/exercises/beer-song/BeerSongTest.fs +36 -32
- data/tracks/fsharp/exercises/beer-song/Example.fs +2 -2
- data/tracks/fsharp/exercises/binary-search/BinarySearch.fsproj +3 -2
- data/tracks/fsharp/exercises/binary-search-tree/BinarySearchTree.fsproj +3 -2
- data/tracks/fsharp/exercises/bob/Bob.fs +1 -1
- data/tracks/fsharp/exercises/bob/Bob.fsproj +3 -2
- data/tracks/fsharp/exercises/bob/BobTest.fs +64 -20
- data/tracks/fsharp/exercises/bob/Example.fs +3 -4
- data/tracks/fsharp/exercises/book-store/BookStore.fs +1 -1
- data/tracks/fsharp/exercises/book-store/BookStore.fsproj +3 -2
- data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +32 -25
- data/tracks/fsharp/exercises/book-store/Example.fs +1 -1
- data/tracks/fsharp/exercises/bowling/Bowling.fsproj +3 -2
- data/tracks/fsharp/exercises/bracket-push/BracketPush.fs +1 -1
- data/tracks/fsharp/exercises/bracket-push/BracketPush.fsproj +3 -2
- data/tracks/fsharp/exercises/bracket-push/BracketPushTest.fs +24 -25
- data/tracks/fsharp/exercises/bracket-push/Example.fs +1 -1
- data/tracks/fsharp/exercises/change/Change.fs +1 -1
- data/tracks/fsharp/exercises/change/Change.fsproj +3 -2
- data/tracks/fsharp/exercises/change/ChangeTest.fs +42 -18
- data/tracks/fsharp/exercises/change/Example.fs +7 -4
- data/tracks/fsharp/exercises/circular-buffer/CircularBuffer.fsproj +3 -2
- data/tracks/fsharp/exercises/clock/Clock.fsproj +3 -2
- data/tracks/fsharp/exercises/connect/Connect.fsproj +3 -2
- data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fs +1 -40
- data/tracks/fsharp/exercises/crypto-square/CryptoSquare.fsproj +3 -2
- data/tracks/fsharp/exercises/crypto-square/CryptoSquareTest.fs +16 -40
- data/tracks/fsharp/exercises/crypto-square/Example.fs +13 -16
- data/tracks/fsharp/exercises/custom-set/CustomSet.fs +12 -12
- data/tracks/fsharp/exercises/custom-set/CustomSet.fsproj +3 -2
- data/tracks/fsharp/exercises/diamond/Diamond.fsproj +3 -2
- data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fs +2 -2
- data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquares.fsproj +3 -2
- data/tracks/fsharp/exercises/difference-of-squares/DifferenceOfSquaresTest.fs +24 -20
- data/tracks/fsharp/exercises/difference-of-squares/Example.fs +3 -3
- data/tracks/fsharp/exercises/diffie-hellman/DiffieHellman.fsproj +3 -2
- data/tracks/fsharp/exercises/dominoes/Dominoes.fsproj +3 -2
- data/tracks/fsharp/exercises/dot-dsl/DotDsl.fsproj +3 -2
- data/tracks/fsharp/exercises/error-handling/ErrorHandling.fsproj +3 -2
- data/tracks/fsharp/exercises/etl/Etl.fsproj +3 -2
- data/tracks/fsharp/exercises/food-chain/FoodChain.fsproj +3 -2
- data/tracks/fsharp/exercises/forth/Forth.fsproj +3 -2
- data/tracks/fsharp/exercises/gigasecond/Example.fs +1 -3
- data/tracks/fsharp/exercises/gigasecond/Gigasecond.fs +1 -1
- data/tracks/fsharp/exercises/gigasecond/Gigasecond.fsproj +3 -2
- data/tracks/fsharp/exercises/gigasecond/GigasecondTest.fs +21 -12
- data/tracks/fsharp/exercises/go-counting/GoCounting.fsproj +3 -2
- data/tracks/fsharp/exercises/grade-school/GradeSchool.fsproj +3 -2
- data/tracks/fsharp/exercises/grains/Grains.fsproj +3 -2
- data/tracks/fsharp/exercises/grep/Grep.fsproj +3 -2
- data/tracks/fsharp/exercises/hamming/Hamming.fsproj +3 -2
- data/tracks/fsharp/exercises/hangman/Hangman.fsproj +3 -2
- data/tracks/fsharp/exercises/hello-world/HelloWorld.fsproj +3 -2
- data/tracks/fsharp/exercises/hello-world/HelloWorldTest.fs +6 -3
- data/tracks/fsharp/exercises/house/House.fsproj +3 -2
- data/tracks/fsharp/exercises/isogram/Example.fs +1 -1
- data/tracks/fsharp/exercises/isogram/Isogram.fs +1 -1
- data/tracks/fsharp/exercises/isogram/Isogram.fsproj +3 -2
- data/tracks/fsharp/exercises/isogram/IsogramTest.fs +16 -40
- data/tracks/fsharp/exercises/kindergarten-garden/Example.fs +6 -4
- data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fs +3 -5
- data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGarden.fsproj +3 -2
- data/tracks/fsharp/exercises/kindergarten-garden/KindergartenGardenTest.fs +100 -47
- data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProduct.fsproj +3 -2
- data/tracks/fsharp/exercises/leap/Example.fs +2 -2
- data/tracks/fsharp/exercises/leap/Leap.fs +2 -2
- data/tracks/fsharp/exercises/leap/Leap.fsproj +3 -2
- data/tracks/fsharp/exercises/leap/LeapTest.fs +19 -15
- data/tracks/fsharp/exercises/ledger/Ledger.fsproj +3 -2
- data/tracks/fsharp/exercises/lens-person/LensPerson.fsproj +3 -2
- data/tracks/fsharp/exercises/linked-list/LinkedList.fsproj +3 -2
- data/tracks/fsharp/exercises/list-ops/ListOps.fsproj +3 -2
- data/tracks/fsharp/exercises/luhn/Luhn.fsproj +3 -2
- data/tracks/fsharp/exercises/luhn/LuhnTest.fs +30 -65
- data/tracks/fsharp/exercises/markdown/Markdown.fsproj +3 -2
- data/tracks/fsharp/exercises/matrix/Matrix.fsproj +3 -2
- data/tracks/fsharp/exercises/meetup/Meetup.fsproj +3 -2
- data/tracks/fsharp/exercises/minesweeper/Example.fs +9 -11
- data/tracks/fsharp/exercises/minesweeper/Minesweeper.fsproj +3 -2
- data/tracks/fsharp/exercises/minesweeper/MinesweeperTest.fs +117 -80
- data/tracks/fsharp/exercises/nth-prime/NthPrime.fsproj +3 -2
- data/tracks/fsharp/exercises/nucleotide-count/NucleotideCount.fsproj +3 -2
- data/tracks/fsharp/exercises/ocr-numbers/OcrNumbers.fsproj +3 -2
- data/tracks/fsharp/exercises/palindrome-products/PalindromeProducts.fsproj +3 -2
- data/tracks/fsharp/exercises/pangram/Pangram.fsproj +3 -2
- data/tracks/fsharp/exercises/pangram/PangramTest.fs +15 -27
- data/tracks/fsharp/exercises/parallel-letter-frequency/ParallelLetterFrequency.fsproj +3 -2
- data/tracks/fsharp/exercises/pascals-triangle/PascalsTriangle.fsproj +3 -2
- data/tracks/fsharp/exercises/perfect-numbers/PerfectNumbers.fsproj +3 -2
- data/tracks/fsharp/exercises/phone-number/PhoneNumber.fsproj +3 -2
- data/tracks/fsharp/exercises/pig-latin/Example.fs +1 -1
- data/tracks/fsharp/exercises/pig-latin/PigLatin.fsproj +3 -2
- data/tracks/fsharp/exercises/pig-latin/PigLatinTest.fs +64 -26
- data/tracks/fsharp/exercises/poker/Poker.fsproj +3 -2
- data/tracks/fsharp/exercises/pov/Pov.fsproj +3 -2
- data/tracks/fsharp/exercises/prime-factors/PrimeFactors.fsproj +3 -2
- data/tracks/fsharp/exercises/protein-translation/ProteinTranslation.fsproj +3 -2
- data/tracks/fsharp/exercises/proverb/Proverb.fsproj +3 -2
- data/tracks/fsharp/exercises/pythagorean-triplet/PythagoreanTriplet.fsproj +3 -2
- data/tracks/fsharp/exercises/queen-attack/Example.fs +3 -1
- data/tracks/fsharp/exercises/queen-attack/QueenAttack.fs +2 -0
- data/tracks/fsharp/exercises/queen-attack/QueenAttack.fsproj +3 -2
- data/tracks/fsharp/exercises/queen-attack/QueenAttackTest.fs +50 -20
- data/tracks/fsharp/exercises/rail-fence-cipher/RailFenceCipher.fsproj +3 -2
- data/tracks/fsharp/exercises/raindrops/Raindrops.fsproj +3 -2
- data/tracks/fsharp/exercises/raindrops/RaindropsTest.fs +77 -37
- data/tracks/fsharp/exercises/react/React.fsproj +3 -2
- data/tracks/fsharp/exercises/rectangles/Rectangles.fsproj +3 -2
- data/tracks/fsharp/exercises/rna-transcription/Example.fs +15 -7
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fs +2 -2
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscription.fsproj +3 -2
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +29 -14
- data/tracks/fsharp/exercises/robot-name/RobotName.fsproj +3 -2
- data/tracks/fsharp/exercises/robot-simulator/RobotSimulator.fsproj +3 -2
- data/tracks/fsharp/exercises/roman-numerals/Example.fs +2 -2
- data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fs +2 -2
- data/tracks/fsharp/exercises/roman-numerals/RomanNumerals.fsproj +3 -2
- data/tracks/fsharp/exercises/roman-numerals/RomanNumeralsTest.fs +79 -26
- data/tracks/fsharp/exercises/run-length-encoding/RunLengthEncoding.fsproj +3 -2
- data/tracks/fsharp/exercises/saddle-points/SaddlePoints.fsproj +3 -2
- data/tracks/fsharp/exercises/say/Say.fsproj +3 -2
- data/tracks/fsharp/exercises/scale-generator/ScaleGenerator.fsproj +3 -2
- data/tracks/fsharp/exercises/scrabble-score/ScrabbleScore.fsproj +3 -2
- data/tracks/fsharp/exercises/scrabble-score/ScrabbleScoreTest.fs +33 -17
- data/tracks/fsharp/exercises/secret-handshake/SecretHandshake.fsproj +3 -2
- data/tracks/fsharp/exercises/series/Series.fsproj +3 -2
- data/tracks/fsharp/exercises/sgf-parsing/SgfParsing.fsproj +3 -2
- data/tracks/fsharp/exercises/sieve/Sieve.fsproj +3 -2
- data/tracks/fsharp/exercises/simple-cipher/SimpleCipher.fsproj +3 -2
- data/tracks/fsharp/exercises/simple-linked-list/SimpleLinkedList.fsproj +3 -2
- data/tracks/fsharp/exercises/space-age/SpaceAge.fsproj +3 -2
- data/tracks/fsharp/exercises/strain/Strain.fsproj +3 -2
- data/tracks/fsharp/exercises/sublist/Sublist.fsproj +3 -2
- data/tracks/fsharp/exercises/sum-of-multiples/SumOfMultiples.fsproj +3 -2
- data/tracks/fsharp/exercises/tournament/Tournament.fsproj +3 -2
- data/tracks/fsharp/exercises/transpose/Transpose.fsproj +3 -2
- data/tracks/fsharp/exercises/tree-building/TreeBuilding.fsproj +3 -2
- data/tracks/fsharp/exercises/triangle/Triangle.fsproj +3 -2
- data/tracks/fsharp/exercises/twelve-days/TwelveDays.fsproj +3 -2
- data/tracks/fsharp/exercises/two-bucket/TwoBucket.fsproj +3 -2
- data/tracks/fsharp/exercises/two-fer/TwoFer.fsproj +3 -2
- data/tracks/fsharp/exercises/variable-length-quantity/VariableLengthQuantity.fsproj +3 -2
- data/tracks/fsharp/exercises/word-count/WordCount.fsproj +3 -2
- data/tracks/fsharp/exercises/word-search/WordSearch.fsproj +3 -2
- data/tracks/fsharp/exercises/wordy/Wordy.fsproj +3 -2
- data/tracks/fsharp/exercises/zebra-puzzle/ZebraPuzzle.fsproj +3 -2
- data/tracks/fsharp/exercises/zipper/Zipper.fsproj +3 -2
- data/tracks/fsharp/generators/Common.fs +96 -0
- data/tracks/fsharp/generators/Exercise.fs +250 -0
- data/tracks/fsharp/generators/Generators.fs +210 -0
- data/tracks/fsharp/generators/Generators.fsproj +32 -0
- data/tracks/fsharp/generators/Generators.sln +24 -0
- data/tracks/fsharp/generators/Input.fs +99 -0
- data/tracks/fsharp/generators/Options.fs +31 -0
- data/tracks/fsharp/generators/Output.fs +224 -0
- data/tracks/fsharp/generators/Program.fs +35 -0
- data/tracks/fsharp/generators/Properties/launchSettings.json +8 -0
- data/tracks/fsharp/generators/Templates/_AssertEmpty.liquid +1 -0
- data/tracks/fsharp/generators/Templates/_AssertEqual.liquid +1 -0
- data/tracks/fsharp/generators/Templates/_TestClass.liquid +13 -0
- data/tracks/fsharp/generators/Templates/_TestMethod.liquid +3 -0
- data/tracks/fsharp/generators/Templates/_TestMethodBody.liquid +4 -0
- data/tracks/go/.travis.yml +3 -3
- data/tracks/groovy/CONTRIBUTING.md +2 -2
- data/tracks/groovy/config.json +12 -0
- data/tracks/groovy/exercises/scrabble-score/Example.groovy +18 -0
- data/tracks/groovy/exercises/scrabble-score/README.md +63 -0
- data/tracks/groovy/exercises/scrabble-score/ScrabbleScore.groovy +7 -0
- data/tracks/groovy/exercises/scrabble-score/ScrabbleScoreSpec.groovy +45 -0
- data/tracks/groovy/exercises/two-fer/TwoFer.groovy +2 -2
- data/tracks/haskell/exercises/change/README.md +1 -1
- data/tracks/haskell/exercises/lens-person/README.md +1 -1
- data/tracks/haskell/exercises/palindrome-products/README.md +5 -12
- data/tracks/haskell/exercises/sum-of-multiples/README.md +0 -3
- data/tracks/idris/config.json +12 -0
- data/tracks/idris/exercises/accumulate/Accumulate.ipkg +5 -0
- data/tracks/idris/exercises/accumulate/Makefile +23 -0
- data/tracks/idris/exercises/accumulate/README.md +32 -0
- data/tracks/idris/exercises/accumulate/src/Example.idr +6 -0
- data/tracks/idris/exercises/accumulate/src/Test/Accumulate.idr +35 -0
- data/tracks/java/config/maintainers.json +4 -7
- data/tracks/java/config.json +99 -22
- data/tracks/java/exercises/binary-search-tree/.meta/src/reference/java/{BST.java → BinarySearchTree.java} +1 -1
- data/tracks/java/exercises/binary-search-tree/src/test/java/{BSTTest.java → BinarySearchTreeTest.java} +34 -36
- data/tracks/java/exercises/robot-simulator/src/main/java/GridPosition.java +19 -15
- data/tracks/java/exercises/saddle-points/.meta/src/reference/java/MatrixCoordinate.java +7 -1
- data/tracks/java/exercises/saddle-points/src/main/java/MatrixCoordinate.java +7 -1
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/exercises/tournament/.meta/src/reference/java/Result.java +5 -0
- data/tracks/java/exercises/tournament/.meta/src/reference/java/TeamResult.java +41 -0
- data/tracks/java/exercises/tournament/.meta/src/reference/java/Tournament.java +62 -0
- data/tracks/java/exercises/tournament/README.md +78 -0
- data/tracks/java/exercises/tournament/build.gradle +18 -0
- data/tracks/java/{.Rhistory → exercises/tournament/src/main/java/.keep} +0 -0
- data/tracks/java/exercises/tournament/src/test/java/TournamentTest.java +160 -0
- data/tracks/php/config.json +14 -0
- data/tracks/php/exercises/collatz-conjecture/collatz-conjecture_test.php +44 -0
- data/tracks/php/exercises/collatz-conjecture/example.php +18 -0
- data/tracks/python/exercises/circular-buffer/circular_buffer.py +1 -1
- data/tracks/python/exercises/clock/clock.py +1 -1
- data/tracks/python/exercises/etl/etl.py +1 -1
- data/tracks/python/exercises/grade-school/grade_school.py +1 -1
- data/tracks/python/exercises/grains/grains.py +2 -2
- data/tracks/python/exercises/kindergarten-garden/kindergarten_garden.py +1 -1
- data/tracks/python/exercises/linked-list/linked_list.py +1 -1
- data/tracks/python/exercises/rectangles/rectangles.py +1 -1
- data/tracks/python/exercises/sum-of-multiples/sum_of_multiples.py +1 -1
- data/tracks/rust/exercises/bob/tests/bob.rs +1 -0
- data/tracks/rust/exercises/crypto-square/tests/crypto-square.rs +7 -0
- data/tracks/rust/exercises/gigasecond/tests/gigasecond.rs +1 -1
- data/tracks/rust/exercises/phone-number/Cargo.lock +1 -1
- data/tracks/rust/exercises/phone-number/Cargo.toml +1 -1
- data/tracks/rust/exercises/phone-number/example.rs +17 -23
- data/tracks/rust/exercises/phone-number/tests/phone-number.rs +31 -40
- data/tracks/rust/exercises/say/tests/say.rs +2 -0
- data/tracks/rust/exercises/sum-of-multiples/README.md +0 -3
- data/tracks/scala/config.json +11 -0
- data/tracks/scala/exercises/collatz-conjecture/README.md +43 -0
- data/tracks/scala/exercises/collatz-conjecture/build.sbt +3 -0
- data/tracks/scala/exercises/collatz-conjecture/example.scala +17 -0
- data/tracks/scala/exercises/collatz-conjecture/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/collatz-conjecture/src/test/scala/CollatzConjectureTest.scala +34 -0
- data/tracks/scala/testgen/src/main/scala/CollatzConjectureTestGenerator.scala +35 -0
- data/tracks/scheme/config.json +8 -0
- data/tracks/scheme/exercises/word-count/README.md +19 -0
- data/tracks/scheme/exercises/word-count/example.scm +27 -0
- data/tracks/scheme/exercises/word-count/word-count-test.scm +90 -0
- data/tracks/scheme/exercises/word-count/word-count.scm +5 -0
- data/tracks/sml/README.md +20 -1
- data/tracks/sml/bin/generate +74 -20
- data/tracks/sml/exercises/binary/README.md +23 -5
- data/tracks/sml/exercises/binary/binary.sml +2 -0
- data/tracks/sml/exercises/binary/example.sml +10 -21
- data/tracks/sml/exercises/binary/test.sml +55 -30
- data/tracks/sml/exercises/binary/testlib.sml +159 -0
- data/tracks/sml/exercises/flatten-array/HINTS.md +8 -0
- data/tracks/sml/exercises/flatten-array/README.md +31 -6
- data/tracks/sml/exercises/flatten-array/example.sml +3 -4
- data/tracks/sml/exercises/flatten-array/flatten-array.sml +4 -5
- data/tracks/sml/exercises/flatten-array/test.sml +76 -52
- data/tracks/sml/exercises/flatten-array/testlib.sml +159 -0
- data/tracks/sml/exercises/nth-prime/HINTS.md +9 -0
- data/tracks/sml/exercises/nth-prime/README.md +32 -5
- data/tracks/sml/exercises/nth-prime/example.sml +28 -46
- data/tracks/sml/exercises/nth-prime/nth-prime.sml +1 -1
- data/tracks/sml/exercises/nth-prime/test.sml +19 -63
- data/tracks/sml/exercises/nth-prime/testlib.sml +159 -0
- data/tracks/sml/exercises/raindrops/README.md +21 -5
- data/tracks/typescript/config.json +14 -0
- data/tracks/typescript/exercises/triangle/README.md +55 -0
- data/tracks/typescript/exercises/triangle/package.json +36 -0
- data/tracks/typescript/exercises/triangle/triangle.example.ts +56 -0
- data/tracks/typescript/exercises/triangle/triangle.test.ts +79 -0
- data/tracks/typescript/exercises/triangle/triangle.ts +12 -0
- data/tracks/typescript/exercises/triangle/tsconfig.json +22 -0
- data/tracks/typescript/exercises/triangle/tslint.json +127 -0
- data/tracks/typescript/exercises/triangle/yarn.lock +2305 -0
- metadata +85 -6
- data/tracks/d/exercises/crypto-square/.dub/dub.json +0 -6
|
@@ -5,26 +5,26 @@ fn to_some_string(s: &str) -> Option<String> {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
#[test]
|
|
8
|
-
fn
|
|
9
|
-
assert_eq!(
|
|
8
|
+
fn test_cleans_the_number() {
|
|
9
|
+
assert_eq!(
|
|
10
|
+
phone::number("(223) 456-7890"),
|
|
11
|
+
to_some_string("2234567890")
|
|
12
|
+
);
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
#[test]
|
|
13
16
|
#[ignore]
|
|
14
|
-
fn
|
|
15
|
-
assert_eq!(phone::number("
|
|
17
|
+
fn test_cleans_numbers_with_dots() {
|
|
18
|
+
assert_eq!(phone::number("223.456.7890"), to_some_string("2234567890"));
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
#[test]
|
|
19
22
|
#[ignore]
|
|
20
|
-
fn
|
|
21
|
-
assert_eq!(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
#[ignore]
|
|
26
|
-
fn test_invalid_when_11_digits() {
|
|
27
|
-
assert_eq!(phone::number("21234567890"), None);
|
|
23
|
+
fn test_cleans_numbers_with_multiple_spaces() {
|
|
24
|
+
assert_eq!(
|
|
25
|
+
phone::number("223 456 7890 "),
|
|
26
|
+
to_some_string("2234567890")
|
|
27
|
+
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
#[test]
|
|
@@ -35,60 +35,51 @@ fn test_invalid_when_9_digits() {
|
|
|
35
35
|
|
|
36
36
|
#[test]
|
|
37
37
|
#[ignore]
|
|
38
|
-
fn
|
|
39
|
-
assert_eq!(phone::number(""), None);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
#[test]
|
|
43
|
-
#[ignore]
|
|
44
|
-
fn test_invalid_when_no_digits_present() {
|
|
45
|
-
assert_eq!(phone::number(" (-) "), None);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
#[test]
|
|
49
|
-
#[ignore]
|
|
50
|
-
fn test_valid_with_leading_characters() {
|
|
51
|
-
assert_eq!(phone::number("my number is 123 456 7890"), to_some_string("1234567890"));
|
|
38
|
+
fn test_invalid_when_11_digits_does_not_start_with_a_1() {
|
|
39
|
+
assert_eq!(phone::number("22234567890"), None);
|
|
52
40
|
}
|
|
53
41
|
|
|
54
42
|
#[test]
|
|
55
43
|
#[ignore]
|
|
56
|
-
fn
|
|
57
|
-
assert_eq!(phone::number("
|
|
44
|
+
fn test_valid_when_11_digits_and_starting_with_1() {
|
|
45
|
+
assert_eq!(phone::number("12234567890"), to_some_string("2234567890"));
|
|
58
46
|
}
|
|
59
47
|
|
|
60
48
|
#[test]
|
|
61
49
|
#[ignore]
|
|
62
|
-
fn
|
|
63
|
-
assert_eq!(
|
|
50
|
+
fn test_valid_when_11_digits_and_starting_with_1_even_with_punctuation() {
|
|
51
|
+
assert_eq!(
|
|
52
|
+
phone::number("+1 (223) 456-7890"),
|
|
53
|
+
to_some_string("2234567890")
|
|
54
|
+
);
|
|
64
55
|
}
|
|
65
56
|
|
|
66
57
|
#[test]
|
|
67
58
|
#[ignore]
|
|
68
|
-
fn
|
|
69
|
-
assert_eq!(phone::
|
|
59
|
+
fn test_invalid_when_more_than_11_digits() {
|
|
60
|
+
assert_eq!(phone::number("321234567890"), None);
|
|
70
61
|
}
|
|
71
62
|
|
|
72
63
|
#[test]
|
|
73
64
|
#[ignore]
|
|
74
|
-
fn
|
|
75
|
-
assert_eq!(phone::
|
|
65
|
+
fn test_invalid_with_letters() {
|
|
66
|
+
assert_eq!(phone::number("123-abc-7890"), None);
|
|
76
67
|
}
|
|
77
68
|
|
|
78
69
|
#[test]
|
|
79
70
|
#[ignore]
|
|
80
|
-
fn
|
|
81
|
-
assert_eq!(phone::
|
|
71
|
+
fn test_invalid_with_punctuations() {
|
|
72
|
+
assert_eq!(phone::number("123-@:!-7890"), None);
|
|
82
73
|
}
|
|
83
74
|
|
|
84
75
|
#[test]
|
|
85
76
|
#[ignore]
|
|
86
|
-
fn
|
|
87
|
-
assert_eq!(phone::
|
|
77
|
+
fn test_invalid_if_area_code_does_not_start_with_2_9() {
|
|
78
|
+
assert_eq!(phone::number("(123) 456-7890"), None);
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
#[test]
|
|
91
82
|
#[ignore]
|
|
92
|
-
fn
|
|
93
|
-
assert_eq!(phone::
|
|
83
|
+
fn test_invalid_if_exchange_code_does_not_start_with_2_9() {
|
|
84
|
+
assert_eq!(phone::number("(223) 056-7890"), None);
|
|
94
85
|
}
|
|
@@ -14,12 +14,14 @@ fn test_zero() {
|
|
|
14
14
|
//
|
|
15
15
|
/*
|
|
16
16
|
#[test]
|
|
17
|
+
#[ignore]
|
|
17
18
|
fn test_negative() {
|
|
18
19
|
assert_eq!(say::encode(-1), String::from("won't compile"));
|
|
19
20
|
}
|
|
20
21
|
*/
|
|
21
22
|
|
|
22
23
|
#[test]
|
|
24
|
+
#[ignore]
|
|
23
25
|
fn test_one() {
|
|
24
26
|
assert_eq!(say::encode(1), String::from("one"));
|
|
25
27
|
}
|
|
@@ -8,9 +8,6 @@ multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, 12, 15, and 18.
|
|
|
8
8
|
|
|
9
9
|
The sum of these multiples is 78.
|
|
10
10
|
|
|
11
|
-
Given a number, find the sum of the multiples of a given set of numbers,
|
|
12
|
-
up to but not including that number.
|
|
13
|
-
|
|
14
11
|
## Rust Installation
|
|
15
12
|
|
|
16
13
|
Refer to the [exercism help page][help-page] for Rust installation and learning
|
data/tracks/scala/config.json
CHANGED
|
@@ -82,6 +82,17 @@
|
|
|
82
82
|
"Transforming"
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
|
+
{
|
|
86
|
+
"uuid": "65a76aba-a485-222d-84ba-e9a445b25be6",
|
|
87
|
+
"slug": "collatz-conjecture",
|
|
88
|
+
"core": true,
|
|
89
|
+
"unlocked_by": "leap",
|
|
90
|
+
"difficulty": 2,
|
|
91
|
+
"topics": [
|
|
92
|
+
"Recursion",
|
|
93
|
+
"Mathematics"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
85
96
|
{
|
|
86
97
|
"uuid": "5a31217f-02fd-4be4-b64f-7a93f36f5140",
|
|
87
98
|
"slug": "hamming",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
## Collatz Conjecture.
|
|
2
|
+
|
|
3
|
+
The Collatz Conjecture or 3x+1 problem can be summarized as follows:
|
|
4
|
+
|
|
5
|
+
Take any positive integer n. If n is even, divide n by 2 to get n / 2. If n is
|
|
6
|
+
odd, multiply n by 3 and add 1 to get 3n + 1. Repeat the process indefinitely.
|
|
7
|
+
The conjecture states that no matter which number you start with, you will
|
|
8
|
+
always reach 1 eventually.
|
|
9
|
+
|
|
10
|
+
Given a number n, return the number of steps required to reach 1.
|
|
11
|
+
|
|
12
|
+
## Examples
|
|
13
|
+
Starting with n = 12, the steps would be as follows:
|
|
14
|
+
|
|
15
|
+
0. 12
|
|
16
|
+
1. 6
|
|
17
|
+
2. 3
|
|
18
|
+
3. 10
|
|
19
|
+
4. 5
|
|
20
|
+
5. 16
|
|
21
|
+
6. 8
|
|
22
|
+
7. 4
|
|
23
|
+
8. 2
|
|
24
|
+
9. 1
|
|
25
|
+
|
|
26
|
+
Resulting in 9 steps. So for input n = 12, the return value would be 9.
|
|
27
|
+
|
|
28
|
+
The Scala exercises assume an SBT project scheme. The exercise solution source
|
|
29
|
+
should be placed within the exercise directory/src/main/scala. The exercise
|
|
30
|
+
unit tests can be found within the exercise directory/src/test/scala.
|
|
31
|
+
|
|
32
|
+
To run the tests simply run the command `sbt test` in the exercise directory.
|
|
33
|
+
|
|
34
|
+
For more detailed info about the Scala track see the [help
|
|
35
|
+
page](http://exercism.io/languages/scala).
|
|
36
|
+
|
|
37
|
+
## Source
|
|
38
|
+
|
|
39
|
+
An unsolved problem in mathematics named after mathematician Lothar Collatz
|
|
40
|
+
see more at [collatz conjecture wikipedia](https://en.wikipedia.org/wiki/3x_%2B_1_problem)
|
|
41
|
+
|
|
42
|
+
## Submitting Incomplete Solutions
|
|
43
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
object CollatzConjecture {
|
|
2
|
+
|
|
3
|
+
def isEven( v:Int ): Boolean = v % 2 == 0
|
|
4
|
+
|
|
5
|
+
def collatz_h(n: Int, acc: Int): Option[Int] = {
|
|
6
|
+
if (n <= 0)
|
|
7
|
+
None
|
|
8
|
+
else if (n == 1){
|
|
9
|
+
Some(acc)
|
|
10
|
+
} else if (isEven(n)){
|
|
11
|
+
collatz_h(n/2, acc+1)
|
|
12
|
+
} else{
|
|
13
|
+
collatz_h(n*3 + 1, acc+1)}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def steps(n: Int): Option[Int] = collatz_h(n, 0)
|
|
17
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import org.scalatest.{Matchers, FunSuite}
|
|
2
|
+
|
|
3
|
+
/** @version 1.1.1 */
|
|
4
|
+
class CollatzConjectureTest extends FunSuite with Matchers {
|
|
5
|
+
|
|
6
|
+
test("zero steps for one") {
|
|
7
|
+
CollatzConjecture.steps(1) should be (Some(0))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
test("divide if even") {
|
|
11
|
+
pending
|
|
12
|
+
CollatzConjecture.steps(16) should be (Some(4))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
test("even and odd steps") {
|
|
16
|
+
pending
|
|
17
|
+
CollatzConjecture.steps(12) should be (Some(9))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("Large number of even and odd steps") {
|
|
21
|
+
pending
|
|
22
|
+
CollatzConjecture.steps(1000000) should be (Some(152))
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test("zero is an error") {
|
|
26
|
+
pending
|
|
27
|
+
CollatzConjecture.steps(0) should be (None)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test("negative value is an error") {
|
|
31
|
+
pending
|
|
32
|
+
CollatzConjecture.steps(-15) should be (None)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import java.io.File
|
|
2
|
+
|
|
3
|
+
import testgen.TestSuiteBuilder._
|
|
4
|
+
import testgen._
|
|
5
|
+
|
|
6
|
+
object CollatzConjectureTestGenerator {
|
|
7
|
+
def main(args: Array[String]): Unit = {
|
|
8
|
+
val file = new File("src/main/resources/collatz-conjecture.json")
|
|
9
|
+
|
|
10
|
+
def toString(expected: CanonicalDataParser.Expected): String = {
|
|
11
|
+
expected match {
|
|
12
|
+
case Left(_) => "None"
|
|
13
|
+
case Right(null) => "None"
|
|
14
|
+
case Right(n) => s"Some($n)"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def fromLabeledTest(argNames: String*): ToTestCaseData =
|
|
19
|
+
withLabeledTest { sut =>
|
|
20
|
+
labeledTest =>
|
|
21
|
+
val args = sutArgs(labeledTest.result, argNames: _*)
|
|
22
|
+
val property = labeledTest.property
|
|
23
|
+
val sutCall =
|
|
24
|
+
s"""$sut.$property($args)"""
|
|
25
|
+
val expected = toString(labeledTest.expected)
|
|
26
|
+
TestCaseData(labeledTest.description, sutCall, expected)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
val code = TestSuiteBuilder.build(file, fromLabeledTest("number"))
|
|
30
|
+
|
|
31
|
+
println(s"-------------")
|
|
32
|
+
println(code)
|
|
33
|
+
println(s"-------------")
|
|
34
|
+
}
|
|
35
|
+
}
|
data/tracks/scheme/config.json
CHANGED
|
@@ -112,6 +112,14 @@
|
|
|
112
112
|
"topics": null,
|
|
113
113
|
"unlocked_by": null,
|
|
114
114
|
"uuid": "5b44ccd4-b1f4-4b86-89c8-f1dec5905ccb"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"core": false,
|
|
118
|
+
"difficulty": 1,
|
|
119
|
+
"slug": "word-count",
|
|
120
|
+
"topics": null,
|
|
121
|
+
"unlocked_by": null,
|
|
122
|
+
"uuid": "9460b65d-dc80-4a95-8782-b395d2cc979e"
|
|
115
123
|
}
|
|
116
124
|
],
|
|
117
125
|
"foregone": [],
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Word Count
|
|
2
|
+
|
|
3
|
+
Given a phrase, count the occurrences of each word in that phrase.
|
|
4
|
+
|
|
5
|
+
For example, given the input `"olly olly in come free"`
|
|
6
|
+
|
|
7
|
+
```plain
|
|
8
|
+
olly: 2
|
|
9
|
+
in: 1
|
|
10
|
+
come: 1
|
|
11
|
+
free: 1
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Source
|
|
15
|
+
|
|
16
|
+
This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.
|
|
17
|
+
|
|
18
|
+
## Submitting Incomplete Solutions
|
|
19
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
(define-module (word-count)
|
|
2
|
+
#:use-module (srfi srfi-1)
|
|
3
|
+
#:use-module (ice-9 regex)
|
|
4
|
+
#:export (countwords))
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
(define (countword word counters)
|
|
8
|
+
(let* ((oldcount (assoc-ref counters word))
|
|
9
|
+
(newcount (if oldcount (+ oldcount 1) 1)))
|
|
10
|
+
(assoc-set! counters word newcount)))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
(define (replace text pattern replacement)
|
|
14
|
+
(regexp-substitute/global #f pattern text 'pre replacement 'post))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
(define (normalize phrase)
|
|
18
|
+
(let* ((nopuncts (replace phrase "[.,\n!&@%:^$]" " "))
|
|
19
|
+
(onespace (replace nopuncts "[ ]+" " "))
|
|
20
|
+
(endspace (replace onespace "[ ]+$" ""))
|
|
21
|
+
(noquotes (replace endspace "( ')|(' )" " ")))
|
|
22
|
+
(string-downcase noquotes)))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
(define (countwords phrase)
|
|
26
|
+
(fold countword '()
|
|
27
|
+
(string-split (normalize phrase) #\space)))
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
;; Load SRFI-64 lightweight testing specification
|
|
2
|
+
(use-modules (srfi srfi-64))
|
|
3
|
+
|
|
4
|
+
;; Suppress log file output. To write logs, comment out the following line:
|
|
5
|
+
(module-define! (resolve-module '(srfi srfi-64)) 'test-log-to-file #f)
|
|
6
|
+
|
|
7
|
+
;; Require module
|
|
8
|
+
(add-to-load-path (dirname (current-filename)))
|
|
9
|
+
(use-modules (word-count))
|
|
10
|
+
|
|
11
|
+
;; Tests for countwords
|
|
12
|
+
(test-begin "countwords")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
(test-equal "count one word"
|
|
16
|
+
(assoc-ref (countwords "word") "word") 1)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
(test-assert "count one of each word"
|
|
20
|
+
(let ((result (countwords "one of each")))
|
|
21
|
+
(and (equal? (assoc-ref result "one") 1)
|
|
22
|
+
(equal? (assoc-ref result "of") 1)
|
|
23
|
+
(equal? (assoc-ref result "each") 1))))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
(test-assert "multiple occurrences of a word"
|
|
27
|
+
(let ((result (countwords "one fish two fish red fish blue fish")))
|
|
28
|
+
(and (equal? (assoc-ref result "one") 1)
|
|
29
|
+
(equal? (assoc-ref result "fish") 4)
|
|
30
|
+
(equal? (assoc-ref result "two") 1)
|
|
31
|
+
(equal? (assoc-ref result "red") 1)
|
|
32
|
+
(equal? (assoc-ref result "blue") 1))))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
(test-assert "handles cramped lists"
|
|
36
|
+
(let ((result (countwords "one,two,three")))
|
|
37
|
+
(and (equal? (assoc-ref result "one") 1)
|
|
38
|
+
(equal? (assoc-ref result "two") 1)
|
|
39
|
+
(equal? (assoc-ref result "three") 1))))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
(test-assert "handles expanded lists"
|
|
43
|
+
(let ((result (countwords "one,\ntwo,\nthree")))
|
|
44
|
+
(and (equal? (assoc-ref result "one") 1)
|
|
45
|
+
(equal? (assoc-ref result "two") 1)
|
|
46
|
+
(equal? (assoc-ref result "three") 1))))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
(test-assert "ignore punctuation"
|
|
50
|
+
(let ((result (countwords "car: carpet as java: javascript!!&@$%^&")))
|
|
51
|
+
(and (equal? (assoc-ref result "car") 1)
|
|
52
|
+
(equal? (assoc-ref result "carpet") 1)
|
|
53
|
+
(equal? (assoc-ref result "as") 1)
|
|
54
|
+
(equal? (assoc-ref result "java") 1)
|
|
55
|
+
(equal? (assoc-ref result "javascript") 1))))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
(test-assert "include numbers"
|
|
59
|
+
(let ((result (countwords "testing, 1, 2 testing")))
|
|
60
|
+
(and (equal? (assoc-ref result "testing") 2)
|
|
61
|
+
(equal? (assoc-ref result "1") 1)
|
|
62
|
+
(equal? (assoc-ref result "2") 1))))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
(test-assert "normalize case"
|
|
66
|
+
(let ((result (countwords "go Go GO Stop stop")))
|
|
67
|
+
(and (equal? (assoc-ref result "go") 3)
|
|
68
|
+
(equal? (assoc-ref result "stop") 2))))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
(test-assert "with apostrophes"
|
|
72
|
+
(let ((result (countwords "First: don't laugh. Then: don't cry.")))
|
|
73
|
+
(and (equal? (assoc-ref result "first") 1)
|
|
74
|
+
(equal? (assoc-ref result "don't") 2)
|
|
75
|
+
(equal? (assoc-ref result "laugh") 1)
|
|
76
|
+
(equal? (assoc-ref result "then") 1)
|
|
77
|
+
(equal? (assoc-ref result "cry") 1))))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
(test-assert "with quotations"
|
|
81
|
+
(let ((result (countwords "Joe can't tell between 'large' and large.")))
|
|
82
|
+
(and (equal? (assoc-ref result "joe") 1)
|
|
83
|
+
(equal? (assoc-ref result "can't") 1)
|
|
84
|
+
(equal? (assoc-ref result "tell") 1)
|
|
85
|
+
(equal? (assoc-ref result "between") 1)
|
|
86
|
+
(equal? (assoc-ref result "large") 2)
|
|
87
|
+
(equal? (assoc-ref result "and") 1))))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
(test-end "countwords")
|
data/tracks/sml/README.md
CHANGED
|
@@ -91,11 +91,30 @@ bin/generate {{ slug }}
|
|
|
91
91
|
|
|
92
92
|
It will create the exercise directory, test and stub files.
|
|
93
93
|
|
|
94
|
+
### Generator
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
usage: generate [-h] [--force] [--test-only] [--stub-only] [--example-only]
|
|
98
|
+
exercises [exercises ...]
|
|
99
|
+
|
|
100
|
+
positional arguments:
|
|
101
|
+
exercises
|
|
102
|
+
|
|
103
|
+
optional arguments:
|
|
104
|
+
-h, --help show this help message and exit
|
|
105
|
+
--force Type inference will be disabled and "string" will be
|
|
106
|
+
assumed. Test cases will need to be modified to match the
|
|
107
|
+
right data type.
|
|
108
|
+
--test-only Generate only "test.sml"
|
|
109
|
+
--stub-only Generate only "<exercise>.sml"
|
|
110
|
+
--example-only Generate only "example.sml"
|
|
111
|
+
```
|
|
112
|
+
|
|
94
113
|
**Note:**
|
|
95
114
|
- You need Python 3.5+.
|
|
96
115
|
- It may fail with some exercises. Reasons:
|
|
97
116
|
- `canonical-data.json` does not exist
|
|
98
|
-
- type mismatch
|
|
117
|
+
- type mismatch (in these situation you can use `--force` option)
|
|
99
118
|
|
|
100
119
|
In those cases you will have to create the files manually. `testlib.sml` can be copied from `lib/testlib.sml`. When in doubt, feel free to open an issue.
|
|
101
120
|
|
data/tracks/sml/bin/generate
CHANGED
|
@@ -42,7 +42,9 @@ def camelize(s):
|
|
|
42
42
|
return re.sub('[-_](\w)', lambda x: x.group(1).upper(), s)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def sml_type(value):
|
|
45
|
+
def sml_type(value, force=False):
|
|
46
|
+
if force:
|
|
47
|
+
return 'string'
|
|
46
48
|
if value is None:
|
|
47
49
|
return 'option'
|
|
48
50
|
if isinstance(value, list):
|
|
@@ -72,7 +74,9 @@ def sml_type(value):
|
|
|
72
74
|
return types[type(value)]
|
|
73
75
|
|
|
74
76
|
|
|
75
|
-
def sml_value(value, smltype=''):
|
|
77
|
+
def sml_value(value, smltype='', force=False):
|
|
78
|
+
if force:
|
|
79
|
+
return json.dumps(value)
|
|
76
80
|
if value is None:
|
|
77
81
|
return 'NONE'
|
|
78
82
|
_value = None
|
|
@@ -104,12 +108,12 @@ def get_fn_args(case):
|
|
|
104
108
|
)
|
|
105
109
|
|
|
106
110
|
|
|
107
|
-
def extract_signatures(data):
|
|
111
|
+
def extract_signatures(data, force=False):
|
|
108
112
|
funcs = OrderedDict()
|
|
109
113
|
exercise = data['exercise']
|
|
110
114
|
|
|
111
115
|
def type_aux(values):
|
|
112
|
-
s = {sml_type(val) for val in values}
|
|
116
|
+
s = {sml_type(val, force=force) for val in values}
|
|
113
117
|
if len(s) == 1:
|
|
114
118
|
return s.pop()
|
|
115
119
|
if len(s) == 2 and 'option' in s:
|
|
@@ -136,10 +140,10 @@ def extract_signatures(data):
|
|
|
136
140
|
else:
|
|
137
141
|
# assumes there's at least one test with non "nullish" vars
|
|
138
142
|
fn = camelize(case.get('property', exercise))
|
|
139
|
-
if sml_type(case['expected']) == 'exn':
|
|
143
|
+
if sml_type(case['expected'], force=force) == 'exn':
|
|
140
144
|
continue
|
|
141
145
|
args = get_fn_args(case)
|
|
142
|
-
if not all(args.values()) or sml_type(case['expected']) == "'a list":# or not case['expected']:
|
|
146
|
+
if not all(args.values()) or sml_type(case['expected'], force=force) == "'a list":# or not case['expected']:
|
|
143
147
|
continue
|
|
144
148
|
funcs.setdefault(fn, []).append({
|
|
145
149
|
'args': args,
|
|
@@ -150,17 +154,17 @@ def extract_signatures(data):
|
|
|
150
154
|
return {fn: signature(funcs[fn]) for fn in funcs}
|
|
151
155
|
|
|
152
156
|
|
|
153
|
-
def expectation(signature, fn, args, expected):
|
|
157
|
+
def expectation(signature, fn, args, expected, force=False):
|
|
154
158
|
tmpl = '(fn _ => %s |> Expect.%s)'
|
|
155
|
-
output = sml_value(expected, signature['output'])
|
|
159
|
+
output = sml_value(expected, signature['output'], force=force)
|
|
156
160
|
invocation = '%s (%s)' % (
|
|
157
161
|
fn,
|
|
158
162
|
', '.join((
|
|
159
|
-
sml_value(val, signature['args'][arg])
|
|
163
|
+
sml_value(val, signature['args'][arg], force=force)
|
|
160
164
|
for arg, val in args.items())
|
|
161
165
|
)
|
|
162
166
|
)
|
|
163
|
-
if sml_type(expected) == 'exn':
|
|
167
|
+
if sml_type(expected, force=force) == 'exn':
|
|
164
168
|
return tmpl % (
|
|
165
169
|
'(fn _ => %s)' % invocation,
|
|
166
170
|
'error (%s)' % output
|
|
@@ -181,7 +185,7 @@ def expectation(signature, fn, args, expected):
|
|
|
181
185
|
)
|
|
182
186
|
|
|
183
187
|
|
|
184
|
-
def generate_test_content(data, signature):
|
|
188
|
+
def generate_test_content(data, signature, force=False):
|
|
185
189
|
exercise = data['exercise']
|
|
186
190
|
|
|
187
191
|
def fmt(case, depth=0):
|
|
@@ -192,7 +196,7 @@ def generate_test_content(data, signature):
|
|
|
192
196
|
args = get_fn_args(case)
|
|
193
197
|
return '\n'.join((
|
|
194
198
|
indent(depth, 'test "%s"' % case.get('description', fn)),
|
|
195
|
-
indent(depth + 2, expectation(signature[fn], fn, args, expected))
|
|
199
|
+
indent(depth + 2, expectation(signature[fn], fn, args, expected, force=force))
|
|
196
200
|
))
|
|
197
201
|
|
|
198
202
|
def traverse(cases, depth=0):
|
|
@@ -247,17 +251,33 @@ def write(path, content):
|
|
|
247
251
|
f.write(content)
|
|
248
252
|
|
|
249
253
|
|
|
250
|
-
|
|
254
|
+
# flags
|
|
255
|
+
TEST = 1
|
|
256
|
+
STUB = 2
|
|
257
|
+
EXAMPLE = 4
|
|
258
|
+
FLAGS = TEST | STUB | EXAMPLE
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def generate(exercise, flags, force=False):
|
|
251
262
|
root = Path(__file__).parent.parent.absolute()
|
|
252
263
|
path = root / 'exercises' / exercise
|
|
264
|
+
|
|
253
265
|
if not path.exists():
|
|
254
266
|
path.mkdir()
|
|
267
|
+
|
|
255
268
|
data = fetch(exercise)
|
|
256
|
-
signatures = extract_signatures(data)
|
|
257
|
-
write(path / 'test.sml', generate_test_content(data, signatures))
|
|
269
|
+
signatures = extract_signatures(data, force=force)
|
|
258
270
|
content = generate_exercise_content(signatures)
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
|
|
272
|
+
if flags & TEST:
|
|
273
|
+
write(path / 'test.sml', generate_test_content(data, signatures, force=force))
|
|
274
|
+
|
|
275
|
+
if flags & STUB:
|
|
276
|
+
write(path / ('%s.sml' % exercise), content)
|
|
277
|
+
|
|
278
|
+
if flags & EXAMPLE:
|
|
279
|
+
write(path / 'example.sml', content)
|
|
280
|
+
|
|
261
281
|
shutil.copyfile(
|
|
262
282
|
(root / 'lib/testlib.sml').as_posix(),
|
|
263
283
|
(path / 'testlib.sml').as_posix()
|
|
@@ -265,11 +285,45 @@ def generate(exercise):
|
|
|
265
285
|
|
|
266
286
|
|
|
267
287
|
if __name__ == '__main__':
|
|
268
|
-
import
|
|
288
|
+
import argparse
|
|
289
|
+
|
|
290
|
+
parser = argparse.ArgumentParser()
|
|
291
|
+
parser.add_argument('exercises', nargs='+')
|
|
292
|
+
parser.add_argument(
|
|
293
|
+
'--force',
|
|
294
|
+
action='store_true',
|
|
295
|
+
help=(
|
|
296
|
+
'Type inference will be disabled and "string" will be assumed. ' +
|
|
297
|
+
'Test cases will need to be modified to match the right data type.'
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
parser.add_argument(
|
|
301
|
+
'--test-only',
|
|
302
|
+
action='store_true',
|
|
303
|
+
help='Generate only "test.sml"'
|
|
304
|
+
)
|
|
305
|
+
parser.add_argument(
|
|
306
|
+
'--stub-only',
|
|
307
|
+
action='store_true',
|
|
308
|
+
help='Generate only "<exercise>.sml"'
|
|
309
|
+
)
|
|
310
|
+
parser.add_argument(
|
|
311
|
+
'--example-only',
|
|
312
|
+
action='store_true',
|
|
313
|
+
help='Generate only "example.sml"'
|
|
314
|
+
)
|
|
315
|
+
args = parser.parse_args()
|
|
269
316
|
|
|
270
|
-
for exercise in
|
|
317
|
+
for exercise in args.exercises:
|
|
271
318
|
try:
|
|
272
|
-
|
|
319
|
+
flags = 0
|
|
320
|
+
if args.test_only:
|
|
321
|
+
flags |= ~(STUB | EXAMPLE)
|
|
322
|
+
if args.example_only:
|
|
323
|
+
flags |= ~(STUB | TEST)
|
|
324
|
+
if args.stub_only:
|
|
325
|
+
flags |= ~(TEST | EXAMPLE)
|
|
326
|
+
generate(exercise, force=args.force, flags=flags or FLAGS)
|
|
273
327
|
except FileNotFoundError:
|
|
274
328
|
print('[%s]: canonical-data.json not found' % exercise)
|
|
275
329
|
except Exception as e:
|