trackler 2.2.0.4 → 2.2.0.5
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/tracks/bash/config.json +10 -2
- data/tracks/bash/exercises/word-count/example.awk +12 -0
- data/tracks/bash/exercises/word-count/example.sh +21 -0
- data/tracks/c/config.json +0 -2
- data/tracks/ceylon/config.json +0 -2
- data/tracks/{erlang/exercises/all-your-base/.meta/readme.go.tmpl → clojure/config/exercise_readme.go.tmpl} +0 -1
- data/tracks/clojure/exercises/accumulate/README.md +35 -0
- data/tracks/clojure/exercises/acronym/README.md +15 -0
- data/tracks/clojure/exercises/all-your-base/README.md +35 -0
- data/tracks/clojure/exercises/allergies/README.md +37 -0
- data/tracks/clojure/exercises/anagram/README.md +13 -0
- data/tracks/clojure/exercises/atbash-cipher/README.md +34 -0
- data/tracks/clojure/exercises/bank-account/README.md +30 -0
- data/tracks/clojure/exercises/beer-song/README.md +327 -0
- data/tracks/clojure/exercises/binary/README.md +35 -0
- data/tracks/clojure/exercises/binary-search/README.md +41 -0
- data/tracks/clojure/exercises/binary-search-tree/README.md +60 -0
- data/tracks/clojure/exercises/bob/README.md +18 -0
- data/tracks/clojure/exercises/bracket-push/README.md +10 -0
- data/tracks/clojure/exercises/change/README.md +23 -0
- data/tracks/clojure/exercises/clock/README.md +13 -0
- data/tracks/clojure/exercises/crypto-square/README.md +74 -0
- data/tracks/clojure/exercises/difference-of-squares/README.md +19 -0
- data/tracks/clojure/exercises/etl/README.md +51 -0
- data/tracks/clojure/exercises/flatten-array/README.md +18 -0
- data/tracks/clojure/exercises/gigasecond/README.md +11 -0
- data/tracks/clojure/exercises/grade-school/README.md +42 -0
- data/tracks/clojure/exercises/grains/README.md +34 -0
- data/tracks/clojure/exercises/hamming/README.md +42 -0
- data/tracks/clojure/exercises/hello-world/README.md +51 -0
- data/tracks/clojure/exercises/hexadecimal/README.md +14 -0
- data/tracks/clojure/exercises/isogram/README.md +19 -0
- data/tracks/clojure/exercises/kindergarten-garden/README.md +66 -0
- data/tracks/clojure/exercises/largest-series-product/README.md +20 -0
- data/tracks/clojure/exercises/leap/README.md +33 -0
- data/tracks/clojure/exercises/luhn/README.md +71 -0
- data/tracks/clojure/exercises/meetup/README.md +30 -0
- data/tracks/clojure/exercises/minesweeper/README.md +30 -0
- data/tracks/clojure/exercises/nth-prime/README.md +15 -0
- data/tracks/clojure/exercises/nucleotide-count/README.md +33 -0
- data/tracks/clojure/exercises/octal/README.md +49 -0
- data/tracks/clojure/exercises/pangram/README.md +15 -0
- data/tracks/clojure/exercises/pascals-triangle/README.md +21 -0
- data/tracks/clojure/exercises/perfect-numbers/README.md +24 -0
- data/tracks/clojure/exercises/phone-number/README.md +34 -0
- data/tracks/clojure/exercises/pig-latin/README.md +24 -0
- data/tracks/clojure/exercises/pov/README.md +46 -0
- data/tracks/clojure/exercises/prime-factors/README.md +36 -0
- data/tracks/clojure/exercises/queen-attack/README.md +33 -0
- data/tracks/clojure/exercises/raindrops/README.md +24 -0
- data/tracks/clojure/exercises/rna-transcription/README.md +25 -0
- data/tracks/clojure/exercises/robot-name/README.md +22 -0
- data/tracks/clojure/exercises/robot-simulator/README.md +34 -0
- data/tracks/clojure/exercises/roman-numerals/README.md +49 -0
- data/tracks/clojure/exercises/rotational-cipher/README.md +36 -0
- data/tracks/clojure/exercises/scrabble-score/README.md +44 -0
- data/tracks/clojure/exercises/secret-handshake/README.md +35 -0
- data/tracks/clojure/exercises/sieve/README.md +34 -0
- data/tracks/clojure/exercises/space-age/README.md +24 -0
- data/tracks/clojure/exercises/strain/README.md +40 -0
- data/tracks/clojure/exercises/sublist/README.md +21 -0
- data/tracks/clojure/exercises/sum-of-multiples/README.md +18 -0
- data/tracks/clojure/exercises/triangle/README.md +26 -0
- data/tracks/clojure/exercises/trinary/README.md +28 -0
- data/tracks/clojure/exercises/word-count/README.md +19 -0
- data/tracks/clojure/exercises/wordy/README.md +63 -0
- data/tracks/{erlang/exercises/allergies/.meta/readme.go.tmpl → crystal/config/exercise_readme.go.tmpl} +0 -1
- data/tracks/crystal/config.json +0 -2
- data/tracks/crystal/exercises/acronym/README.md +38 -0
- data/tracks/crystal/exercises/anagram/README.md +36 -0
- data/tracks/crystal/exercises/atbash-cipher/README.md +57 -0
- data/tracks/crystal/exercises/binary/README.md +58 -0
- data/tracks/crystal/exercises/binary-search-tree/README.md +83 -0
- data/tracks/crystal/exercises/bob/README.md +41 -0
- data/tracks/crystal/exercises/bracket-push/README.md +33 -0
- data/tracks/crystal/exercises/difference-of-squares/README.md +42 -0
- data/tracks/crystal/exercises/flatten-array/README.md +41 -0
- data/tracks/crystal/exercises/forth/README.md +52 -0
- data/tracks/crystal/exercises/gigasecond/README.md +34 -0
- data/tracks/crystal/exercises/hamming/README.md +65 -0
- data/tracks/crystal/exercises/hello-world/README.md +78 -0
- data/tracks/crystal/exercises/largest-series-product/README.md +43 -0
- data/tracks/crystal/exercises/leap/README.md +56 -0
- data/tracks/crystal/exercises/pangram/README.md +38 -0
- data/tracks/crystal/exercises/pascals-triangle/README.md +44 -0
- data/tracks/crystal/exercises/raindrops/README.md +47 -0
- data/tracks/crystal/exercises/react/README.md +42 -0
- data/tracks/crystal/exercises/rna-transcription/README.md +48 -0
- data/tracks/crystal/exercises/roman-numerals/README.md +72 -0
- data/tracks/crystal/exercises/run-length-encoding/README.md +53 -0
- data/tracks/crystal/exercises/sieve/README.md +57 -0
- data/tracks/csharp/config.json +0 -2
- data/tracks/delphi/config.json +0 -2
- data/tracks/ecmascript/config.json +63 -2
- data/tracks/erlang/{exercises/anagram/.meta/readme.go.tmpl → config/exercise_readme.go.tmpl} +0 -1
- data/tracks/erlang/config.json +0 -2
- data/tracks/erlang/exercises/accumulate/README.md +0 -1
- data/tracks/erlang/exercises/all-your-base/README.md +0 -1
- data/tracks/erlang/exercises/allergies/README.md +0 -1
- data/tracks/erlang/exercises/anagram/README.md +0 -1
- data/tracks/erlang/exercises/atbash-cipher/README.md +0 -1
- data/tracks/erlang/exercises/bank-account/README.md +0 -1
- data/tracks/erlang/exercises/beer-song/README.md +0 -1
- data/tracks/erlang/exercises/bob/README.md +0 -1
- data/tracks/erlang/exercises/circular-buffer/README.md +0 -1
- data/tracks/erlang/exercises/clock/README.md +0 -1
- data/tracks/erlang/exercises/collatz-conjecture/README.md +0 -1
- data/tracks/erlang/exercises/difference-of-squares/README.md +0 -1
- data/tracks/erlang/exercises/etl/README.md +0 -1
- data/tracks/erlang/exercises/gigasecond/README.md +0 -1
- data/tracks/erlang/exercises/grade-school/README.md +0 -1
- data/tracks/erlang/exercises/grains/README.md +0 -1
- data/tracks/erlang/exercises/hamming/README.md +0 -1
- data/tracks/erlang/exercises/hello-world/README.md +0 -1
- data/tracks/erlang/exercises/largest-series-product/README.md +0 -1
- data/tracks/erlang/exercises/leap/README.md +0 -1
- data/tracks/erlang/exercises/luhn/README.md +0 -1
- data/tracks/erlang/exercises/meetup/README.md +0 -1
- data/tracks/erlang/exercises/nucleotide-count/README.md +0 -1
- data/tracks/erlang/exercises/parallel-letter-frequency/README.md +0 -1
- data/tracks/erlang/exercises/phone-number/README.md +0 -1
- data/tracks/erlang/exercises/rna-transcription/README.md +0 -1
- data/tracks/erlang/exercises/robot-simulator/README.md +0 -1
- data/tracks/erlang/exercises/roman-numerals/README.md +0 -1
- data/tracks/erlang/exercises/rotational-cipher/README.md +0 -1
- data/tracks/erlang/exercises/scrabble-score/README.md +0 -1
- data/tracks/erlang/exercises/series/README.md +0 -1
- data/tracks/erlang/exercises/space-age/README.md +0 -1
- data/tracks/erlang/exercises/spiral-matrix/README.md +0 -1
- data/tracks/erlang/exercises/strain/README.md +0 -1
- data/tracks/erlang/exercises/sum-of-multiples/README.md +0 -1
- data/tracks/erlang/exercises/triangle/README.md +0 -1
- data/tracks/erlang/exercises/word-count/README.md +0 -1
- data/tracks/erlang/exercises/zipper/README.md +0 -1
- data/tracks/factor/config.json +0 -2
- data/tracks/fsharp/config.json +0 -2
- data/tracks/go/config.json +12 -6
- data/tracks/go/exercises/bank-account/bank_account_test.go +60 -1
- data/tracks/go/exercises/error-handling/common.go +17 -0
- data/tracks/go/exercises/error-handling/error_handling_test.go +37 -4
- data/tracks/haskell/config.json +0 -2
- data/tracks/java/config.json +10 -2
- data/tracks/{erlang/exercises/accumulate → java/exercises/forth}/.meta/readme.go.tmpl +0 -0
- data/tracks/java/exercises/forth/README.md +41 -0
- data/tracks/java/exercises/forth/build.gradle +18 -0
- data/tracks/java/exercises/forth/src/example/java/ForthEvaluator.java +154 -0
- data/tracks/java/exercises/forth/src/example/java/Token.java +90 -0
- data/tracks/java/exercises/forth/src/main/java/.keep +0 -0
- data/tracks/java/exercises/forth/src/test/java/ForthEvaluatorTest.java +355 -0
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/javascript/config.json +0 -2
- data/tracks/kotlin/config.json +30 -2
- data/tracks/kotlin/exercises/forth/README.md +32 -0
- data/tracks/kotlin/exercises/forth/build.gradle +28 -0
- data/tracks/kotlin/exercises/forth/src/example/kotlin/ForthEvaluator.kt +138 -0
- data/tracks/kotlin/exercises/forth/src/main/kotlin/.keep +0 -0
- data/tracks/kotlin/exercises/forth/src/test/kotlin/ForthEvaluatorTest.kt +352 -0
- data/tracks/kotlin/exercises/meetup/README.md +33 -0
- data/tracks/kotlin/exercises/meetup/build.gradle +28 -0
- data/tracks/kotlin/exercises/meetup/src/example/kotlin/Meetup.kt +45 -0
- data/tracks/kotlin/exercises/meetup/src/example/kotlin/MeetupSchedule.kt +1 -0
- data/tracks/kotlin/exercises/meetup/src/main/kotlin/MeetupSchedule.kt +5 -0
- data/tracks/kotlin/exercises/meetup/src/test/kotlin/MeetupTest.kt +771 -0
- data/tracks/kotlin/exercises/say/README.md +72 -0
- data/tracks/kotlin/exercises/say/build.gradle +28 -0
- data/tracks/kotlin/exercises/say/src/example/kotlin/NumberSpeller.kt +88 -0
- data/tracks/kotlin/exercises/say/src/main/kotlin/.keep +0 -0
- data/tracks/kotlin/exercises/say/src/test/kotlin/NumberSpellerTest.kt +138 -0
- data/tracks/kotlin/exercises/settings.gradle +3 -0
- data/tracks/lua/config.json +0 -2
- data/tracks/mips/config.json +0 -2
- data/tracks/ocaml/config.json +0 -2
- data/tracks/perl5/config.json +262 -67
- data/tracks/perl6/config.json +98 -26
- data/tracks/php/docs/INSTALLATION.md +1 -1
- data/tracks/powershell/config.json +0 -2
- data/tracks/purescript/config.json +0 -2
- data/tracks/python/README.md +2 -2
- data/tracks/python/config/exercise_readme.go.tmpl +16 -0
- data/tracks/python/config.json +280 -15
- data/tracks/python/exercises/accumulate/README.md +46 -0
- data/tracks/python/exercises/acronym/README.md +26 -0
- data/tracks/python/exercises/all-your-base/README.md +46 -0
- data/tracks/python/exercises/allergies/README.md +48 -0
- data/tracks/python/exercises/alphametics/README.md +46 -0
- data/tracks/python/exercises/anagram/README.md +24 -0
- data/tracks/python/exercises/atbash-cipher/README.md +45 -0
- data/tracks/python/exercises/beer-song/README.md +338 -0
- data/tracks/python/exercises/binary/README.md +46 -0
- data/tracks/python/exercises/binary-search/README.md +52 -0
- data/tracks/python/exercises/bob/README.md +29 -0
- data/tracks/python/exercises/book-store/README.md +85 -0
- data/tracks/python/exercises/bracket-push/README.md +21 -0
- data/tracks/python/exercises/circular-buffer/README.md +61 -0
- data/tracks/python/exercises/clock/README.md +24 -0
- data/tracks/python/exercises/crypto-square/README.md +85 -0
- data/tracks/python/exercises/diamond/README.md +70 -0
- data/tracks/python/exercises/difference-of-squares/README.md +30 -0
- data/tracks/python/exercises/etl/README.md +62 -0
- data/tracks/python/exercises/flatten-array/README.md +29 -0
- data/tracks/python/exercises/gigasecond/README.md +22 -0
- data/tracks/python/exercises/grade-school/README.md +53 -0
- data/tracks/python/exercises/grains/README.md +45 -0
- data/tracks/python/exercises/grep/README.md +82 -0
- data/tracks/python/exercises/hamming/README.md +53 -0
- data/tracks/python/exercises/hello-world/README.md +32 -0
- data/tracks/python/exercises/hexadecimal/README.md +25 -0
- data/tracks/python/exercises/house/README.md +124 -0
- data/tracks/python/exercises/isogram/README.md +30 -0
- data/tracks/python/exercises/kindergarten-garden/README.md +77 -0
- data/tracks/python/exercises/largest-series-product/README.md +31 -0
- data/tracks/python/exercises/leap/README.md +44 -0
- data/tracks/python/exercises/linked-list/README.md +45 -0
- data/tracks/python/exercises/list-ops/README.md +21 -0
- data/tracks/python/exercises/luhn/README.md +82 -0
- data/tracks/python/exercises/matrix/README.md +56 -0
- data/tracks/python/exercises/meetup/README.md +41 -0
- data/tracks/python/exercises/minesweeper/README.md +41 -0
- data/tracks/python/exercises/nth-prime/README.md +26 -0
- data/tracks/python/exercises/nucleotide-count/README.md +44 -0
- data/tracks/python/exercises/ocr-numbers/README.md +96 -0
- data/tracks/python/exercises/octal/README.md +60 -0
- data/tracks/python/exercises/palindrome-products/README.md +51 -0
- data/tracks/python/exercises/pangram/README.md +26 -0
- data/tracks/python/exercises/pascals-triangle/README.md +32 -0
- data/tracks/python/exercises/perfect-numbers/README.md +35 -0
- data/tracks/python/exercises/phone-number/README.md +45 -0
- data/tracks/python/exercises/pig-latin/README.md +35 -0
- data/tracks/python/exercises/point-mutations/README.md +52 -0
- data/tracks/python/exercises/poker/README.md +23 -0
- data/tracks/python/exercises/prime-factors/README.md +47 -0
- data/tracks/python/exercises/protein-translation/README.md +60 -0
- data/tracks/python/exercises/proverb/README.md +29 -0
- data/tracks/python/exercises/pythagorean-triplet/README.md +35 -0
- data/tracks/python/exercises/queen-attack/README.md +44 -0
- data/tracks/python/exercises/rail-fence-cipher/README.md +71 -0
- data/tracks/python/exercises/raindrops/README.md +35 -0
- data/tracks/python/exercises/rectangles/README.md +78 -0
- data/tracks/python/exercises/rna-transcription/README.md +36 -0
- data/tracks/python/exercises/robot-name/README.md +33 -0
- data/tracks/python/exercises/robot-simulator/README.md +45 -0
- data/tracks/python/exercises/roman-numerals/README.md +60 -0
- data/tracks/python/exercises/rotational-cipher/README.md +47 -0
- data/tracks/python/exercises/run-length-encoding/README.md +41 -0
- data/tracks/python/exercises/saddle-points/README.md +44 -0
- data/tracks/python/exercises/say/README.md +80 -0
- data/tracks/python/exercises/scale-generator/README.md +71 -0
- data/tracks/python/exercises/scrabble-score/README.md +55 -0
- data/tracks/python/exercises/secret-handshake/README.md +46 -0
- data/tracks/python/exercises/series/README.md +38 -0
- data/tracks/python/exercises/sieve/README.md +45 -0
- data/tracks/python/exercises/simple-cipher/README.md +101 -0
- data/tracks/python/exercises/space-age/README.md +35 -0
- data/tracks/python/exercises/strain/README.md +51 -0
- data/tracks/python/exercises/sublist/README.md +32 -0
- data/tracks/python/exercises/sum-of-multiples/README.md +29 -0
- data/tracks/python/exercises/tournament/README.md +79 -0
- data/tracks/python/exercises/transpose/README.md +76 -0
- data/tracks/python/exercises/triangle/README.md +37 -0
- data/tracks/python/exercises/trinary/README.md +39 -0
- data/tracks/python/exercises/twelve-days/README.md +46 -0
- data/tracks/python/exercises/variable-length-quantity/README.md +50 -0
- data/tracks/python/exercises/word-count/README.md +30 -0
- data/tracks/python/exercises/word-search/README.md +41 -0
- data/tracks/python/exercises/wordy/README.md +74 -0
- data/tracks/python/exercises/zebra-puzzle/README.md +43 -0
- data/tracks/python/test/check-exercises.py +2 -3
- data/tracks/r/config.json +0 -2
- data/tracks/ruby/.travis.yml +1 -1
- data/tracks/ruby/config/exercise_readme.go.tmpl +16 -0
- data/tracks/ruby/config.json +265 -4
- data/tracks/ruby/exercises/accumulate/README.md +76 -0
- data/tracks/ruby/exercises/acronym/README.md +41 -0
- data/tracks/ruby/exercises/all-your-base/README.md +61 -0
- data/tracks/ruby/exercises/allergies/README.md +63 -0
- data/tracks/ruby/exercises/alphametics/README.md +61 -0
- data/tracks/ruby/exercises/anagram/README.md +39 -0
- data/tracks/ruby/exercises/atbash-cipher/README.md +60 -0
- data/tracks/ruby/exercises/beer-song/README.md +353 -0
- data/tracks/ruby/exercises/binary/README.md +61 -0
- data/tracks/ruby/exercises/binary-search/README.md +67 -0
- data/tracks/ruby/exercises/binary-search-tree/README.md +86 -0
- data/tracks/ruby/exercises/bob/README.md +44 -0
- data/tracks/ruby/exercises/bowling/README.md +79 -0
- data/tracks/ruby/exercises/bracket-push/README.md +36 -0
- data/tracks/ruby/exercises/circular-buffer/README.md +76 -0
- data/tracks/ruby/exercises/clock/README.md +39 -0
- data/tracks/ruby/exercises/collatz-conjecture/README.md +59 -0
- data/tracks/ruby/exercises/connect/README.md +60 -0
- data/tracks/ruby/exercises/crypto-square/README.md +100 -0
- data/tracks/ruby/exercises/custom-set/README.md +37 -0
- data/tracks/ruby/exercises/diamond/README.md +85 -0
- data/tracks/ruby/exercises/difference-of-squares/README.md +45 -0
- data/tracks/ruby/exercises/dominoes/README.md +44 -0
- data/tracks/ruby/exercises/etl/README.md +77 -0
- data/tracks/ruby/exercises/flatten-array/README.md +44 -0
- data/tracks/ruby/exercises/food-chain/README.md +96 -0
- data/tracks/ruby/exercises/gigasecond/README.md +37 -0
- data/tracks/ruby/exercises/grade-school/README.md +68 -0
- data/tracks/ruby/exercises/grains/README.md +60 -0
- data/tracks/ruby/exercises/hamming/README.md +68 -0
- data/tracks/ruby/exercises/hello-world/README.md +47 -0
- data/tracks/ruby/exercises/hexadecimal/README.md +40 -0
- data/tracks/ruby/exercises/house/README.md +139 -0
- data/tracks/ruby/exercises/isogram/README.md +45 -0
- data/tracks/ruby/exercises/kindergarten-garden/README.md +92 -0
- data/tracks/ruby/exercises/largest-series-product/README.md +46 -0
- data/tracks/ruby/exercises/leap/README.md +59 -0
- data/tracks/ruby/exercises/linked-list/README.md +60 -0
- data/tracks/ruby/exercises/list-ops/README.md +36 -0
- data/tracks/ruby/exercises/luhn/README.md +97 -0
- data/tracks/ruby/exercises/matrix/README.md +71 -0
- data/tracks/ruby/exercises/meetup/README.md +56 -0
- data/tracks/ruby/exercises/minesweeper/README.md +56 -0
- data/tracks/ruby/exercises/nth-prime/README.md +41 -0
- data/tracks/ruby/exercises/nucleotide-count/README.md +59 -0
- data/tracks/ruby/exercises/ocr-numbers/README.md +111 -0
- data/tracks/ruby/exercises/octal/README.md +75 -0
- data/tracks/ruby/exercises/palindrome-products/README.md +66 -0
- data/tracks/ruby/exercises/pangram/README.md +41 -0
- data/tracks/ruby/exercises/pascals-triangle/README.md +47 -0
- data/tracks/ruby/exercises/perfect-numbers/README.md +50 -0
- data/tracks/ruby/exercises/phone-number/README.md +60 -0
- data/tracks/ruby/exercises/pig-latin/README.md +50 -0
- data/tracks/ruby/exercises/point-mutations/README.md +67 -0
- data/tracks/ruby/exercises/poker/README.md +38 -0
- data/tracks/ruby/exercises/prime-factors/README.md +62 -0
- data/tracks/ruby/exercises/protein-translation/README.md +75 -0
- data/tracks/ruby/exercises/proverb/README.md +44 -0
- data/tracks/ruby/exercises/pythagorean-triplet/README.md +50 -0
- data/tracks/ruby/exercises/queen-attack/README.md +59 -0
- data/tracks/ruby/exercises/rail-fence-cipher/README.md +86 -0
- data/tracks/ruby/exercises/raindrops/README.md +50 -0
- data/tracks/ruby/exercises/rna-transcription/README.md +51 -0
- data/tracks/ruby/exercises/robot-name/README.md +57 -0
- data/tracks/ruby/exercises/robot-simulator/README.md +60 -0
- data/tracks/ruby/exercises/roman-numerals/README.md +75 -0
- data/tracks/ruby/exercises/run-length-encoding/README.md +56 -0
- data/tracks/ruby/exercises/saddle-points/README.md +59 -0
- data/tracks/ruby/exercises/say/README.md +95 -0
- data/tracks/ruby/exercises/scale-generator/README.md +86 -0
- data/tracks/ruby/exercises/scrabble-score/README.md +70 -0
- data/tracks/ruby/exercises/secret-handshake/README.md +61 -0
- data/tracks/ruby/exercises/series/README.md +53 -0
- data/tracks/ruby/exercises/sieve/README.md +60 -0
- data/tracks/ruby/exercises/simple-cipher/README.md +116 -0
- data/tracks/ruby/exercises/simple-linked-list/README.md +54 -0
- data/tracks/ruby/exercises/space-age/README.md +50 -0
- data/tracks/ruby/exercises/strain/README.md +66 -0
- data/tracks/ruby/exercises/sum-of-multiples/README.md +44 -0
- data/tracks/ruby/exercises/tournament/README.md +94 -0
- data/tracks/ruby/exercises/transpose/README.md +91 -0
- data/tracks/ruby/exercises/triangle/README.md +52 -0
- data/tracks/ruby/exercises/trinary/README.md +54 -0
- data/tracks/ruby/exercises/twelve-days/README.md +61 -0
- data/tracks/ruby/exercises/two-bucket/README.md +62 -0
- data/tracks/ruby/exercises/word-count/README.md +45 -0
- data/tracks/ruby/exercises/wordy/README.md +89 -0
- data/tracks/rust/README.md +3 -3
- data/tracks/rust/_test/WINDOWS_README.md +44 -0
- data/tracks/rust/config.json +9 -2
- data/tracks/rust/exercises/pig-latin/Cargo-example.toml +8 -0
- data/tracks/rust/exercises/pig-latin/Cargo.lock +4 -0
- data/tracks/rust/exercises/pig-latin/Cargo.toml +6 -0
- data/tracks/rust/exercises/pig-latin/README.md +56 -0
- data/tracks/rust/exercises/pig-latin/example.rs +28 -0
- data/tracks/rust/exercises/pig-latin/tests/pig-latin.rs +120 -0
- data/tracks/rust/problem_ordering.md +2 -2
- data/tracks/sml/config.json +0 -2
- data/tracks/swift/config/exercise_readme.go.tmpl +16 -0
- data/tracks/swift/config.json +304 -79
- data/tracks/swift/exercises/accumulate/README.md +43 -0
- data/tracks/swift/exercises/acronym/README.md +23 -0
- data/tracks/swift/exercises/all-your-base/README.md +43 -0
- data/tracks/swift/exercises/allergies/README.md +45 -0
- data/tracks/swift/exercises/anagram/README.md +21 -0
- data/tracks/swift/exercises/atbash-cipher/README.md +42 -0
- data/tracks/swift/exercises/beer-song/README.md +335 -0
- data/tracks/swift/exercises/binary/README.md +43 -0
- data/tracks/swift/exercises/binary-search/README.md +49 -0
- data/tracks/swift/exercises/binary-search-tree/README.md +68 -0
- data/tracks/swift/exercises/bob/README.md +26 -0
- data/tracks/swift/exercises/bowling/README.md +61 -0
- data/tracks/swift/exercises/bracket-push/README.md +18 -0
- data/tracks/swift/exercises/clock/README.md +21 -0
- data/tracks/swift/exercises/crypto-square/README.md +82 -0
- data/tracks/swift/exercises/custom-set/README.md +19 -0
- data/tracks/swift/exercises/difference-of-squares/README.md +27 -0
- data/tracks/swift/exercises/dominoes/README.md +26 -0
- data/tracks/swift/exercises/etl/README.md +59 -0
- data/tracks/swift/exercises/flatten-array/README.md +26 -0
- data/tracks/swift/exercises/food-chain/README.md +78 -0
- data/tracks/swift/exercises/gigasecond/README.md +19 -0
- data/tracks/swift/exercises/grade-school/README.md +50 -0
- data/tracks/swift/exercises/grains/README.md +42 -0
- data/tracks/swift/exercises/hamming/README.md +50 -0
- data/tracks/swift/exercises/hello-world/README.md +29 -0
- data/tracks/swift/exercises/hexadecimal/README.md +22 -0
- data/tracks/swift/exercises/house/README.md +121 -0
- data/tracks/swift/exercises/isogram/README.md +27 -0
- data/tracks/swift/exercises/kindergarten-garden/README.md +74 -0
- data/tracks/swift/exercises/largest-series-product/README.md +28 -0
- data/tracks/swift/exercises/leap/README.md +41 -0
- data/tracks/swift/exercises/linked-list/README.md +42 -0
- data/tracks/swift/exercises/luhn/README.md +79 -0
- data/tracks/swift/exercises/matrix/README.md +53 -0
- data/tracks/swift/exercises/meetup/README.md +38 -0
- data/tracks/swift/exercises/minesweeper/README.md +38 -0
- data/tracks/swift/exercises/nth-prime/README.md +23 -0
- data/tracks/swift/exercises/nucleotide-count/README.md +41 -0
- data/tracks/swift/exercises/ocr-numbers/README.md +93 -0
- data/tracks/swift/exercises/octal/README.md +57 -0
- data/tracks/swift/exercises/palindrome-products/README.md +48 -0
- data/tracks/swift/exercises/pangram/README.md +23 -0
- data/tracks/swift/exercises/pascals-triangle/README.md +29 -0
- data/tracks/swift/exercises/perfect-numbers/README.md +32 -0
- data/tracks/swift/exercises/phone-number/README.md +42 -0
- data/tracks/swift/exercises/pig-latin/README.md +32 -0
- data/tracks/swift/exercises/poker/README.md +20 -0
- data/tracks/swift/exercises/prime-factors/README.md +44 -0
- data/tracks/swift/exercises/pythagorean-triplet/README.md +32 -0
- data/tracks/swift/exercises/queen-attack/README.md +41 -0
- data/tracks/swift/exercises/raindrops/README.md +32 -0
- data/tracks/swift/exercises/rna-transcription/README.md +33 -0
- data/tracks/swift/exercises/robot-name/README.md +30 -0
- data/tracks/swift/exercises/robot-simulator/README.md +42 -0
- data/tracks/swift/exercises/roman-numerals/README.md +57 -0
- data/tracks/swift/exercises/run-length-encoding/README.md +38 -0
- data/tracks/swift/exercises/saddle-points/README.md +41 -0
- data/tracks/swift/exercises/scrabble-score/README.md +52 -0
- data/tracks/swift/exercises/secret-handshake/README.md +43 -0
- data/tracks/swift/exercises/series/README.md +35 -0
- data/tracks/swift/exercises/sieve/README.md +42 -0
- data/tracks/swift/exercises/simple-cipher/README.md +98 -0
- data/tracks/swift/exercises/simple-linked-list/README.md +36 -0
- data/tracks/swift/exercises/space-age/README.md +32 -0
- data/tracks/swift/exercises/strain/README.md +48 -0
- data/tracks/swift/exercises/sublist/README.md +29 -0
- data/tracks/swift/exercises/sum-of-multiples/README.md +26 -0
- data/tracks/swift/exercises/tournament/README.md +76 -0
- data/tracks/swift/exercises/transpose/README.md +73 -0
- data/tracks/swift/exercises/triangle/README.md +34 -0
- data/tracks/swift/exercises/trinary/README.md +36 -0
- data/tracks/swift/exercises/twelve-days/README.md +43 -0
- data/tracks/swift/exercises/word-count/README.md +27 -0
- data/tracks/swift/exercises/wordy/README.md +71 -0
- data/tracks/typescript/README.md +1 -1
- data/tracks/typescript/config.json +63 -3
- data/tracks/vimscript/config.json +0 -2
- metadata +371 -40
- data/tracks/erlang/exercises/atbash-cipher/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/bank-account/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/beer-song/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/bob/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/circular-buffer/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/clock/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/collatz-conjecture/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/difference-of-squares/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/etl/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/gigasecond/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/grade-school/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/grains/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/hamming/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/hello-world/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/largest-series-product/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/leap/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/luhn/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/meetup/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/nucleotide-count/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/parallel-letter-frequency/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/phone-number/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/rna-transcription/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/robot-simulator/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/roman-numerals/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/rotational-cipher/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/scrabble-score/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/series/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/space-age/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/spiral-matrix/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/strain/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/sum-of-multiples/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/triangle/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/word-count/.meta/readme.go.tmpl +0 -17
- data/tracks/erlang/exercises/zipper/.meta/readme.go.tmpl +0 -17
@@ -0,0 +1,355 @@
|
|
1
|
+
import org.junit.Before;
|
2
|
+
import org.junit.Ignore;
|
3
|
+
import org.junit.Rule;
|
4
|
+
import org.junit.Test;
|
5
|
+
import org.junit.rules.ExpectedException;
|
6
|
+
|
7
|
+
import java.util.Arrays;
|
8
|
+
import java.util.Collections;
|
9
|
+
|
10
|
+
import static org.junit.Assert.assertEquals;
|
11
|
+
|
12
|
+
/*
|
13
|
+
* version: 1.2.0
|
14
|
+
*/
|
15
|
+
public class ForthEvaluatorTest {
|
16
|
+
|
17
|
+
@Rule
|
18
|
+
public ExpectedException expectedException = ExpectedException.none();
|
19
|
+
|
20
|
+
private ForthEvaluator forthEvaluator;
|
21
|
+
|
22
|
+
@Before
|
23
|
+
public void setUp() {
|
24
|
+
forthEvaluator = new ForthEvaluator();
|
25
|
+
}
|
26
|
+
|
27
|
+
@Test
|
28
|
+
public void testEmptyProgramResultsInEmptyStack() {
|
29
|
+
assertEquals(
|
30
|
+
Collections.emptyList(),
|
31
|
+
forthEvaluator.evaluateProgram(Collections.emptyList()));
|
32
|
+
}
|
33
|
+
|
34
|
+
@Ignore("Remove to run test")
|
35
|
+
@Test
|
36
|
+
public void testNumbersAreJustPushedOntoTheStack() {
|
37
|
+
assertEquals(
|
38
|
+
Arrays.asList(1, 2, 3, 4, 5),
|
39
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 4 5")));
|
40
|
+
}
|
41
|
+
|
42
|
+
@Ignore("Remove to run test")
|
43
|
+
@Test
|
44
|
+
public void testTwoNumbersCanBeAdded() {
|
45
|
+
assertEquals(
|
46
|
+
Collections.singletonList(3),
|
47
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 +")));
|
48
|
+
}
|
49
|
+
|
50
|
+
@Ignore("Remove to run test")
|
51
|
+
@Test
|
52
|
+
public void testErrorIfAdditionAttemptedWithNothingOnTheStack() {
|
53
|
+
expectedException.expect(IllegalArgumentException.class);
|
54
|
+
expectedException.expectMessage("Addition requires that the stack contain at least 2 values");
|
55
|
+
|
56
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("+"));
|
57
|
+
}
|
58
|
+
|
59
|
+
@Ignore("Remove to run test")
|
60
|
+
@Test
|
61
|
+
public void testErrorIfAdditionAttemptedWithOneNumberOnTheStack() {
|
62
|
+
expectedException.expect(IllegalArgumentException.class);
|
63
|
+
expectedException.expectMessage("Addition requires that the stack contain at least 2 values");
|
64
|
+
|
65
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 +"));
|
66
|
+
}
|
67
|
+
|
68
|
+
@Ignore("Remove to run test")
|
69
|
+
@Test
|
70
|
+
public void testTwoNumbersCanBeSubtracted() {
|
71
|
+
assertEquals(
|
72
|
+
Collections.singletonList(-1),
|
73
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("3 4 -")));
|
74
|
+
}
|
75
|
+
|
76
|
+
@Ignore("Remove to run test")
|
77
|
+
@Test
|
78
|
+
public void testErrorIfSubtractionAttemptedWithNothingOnTheStack() {
|
79
|
+
expectedException.expect(IllegalArgumentException.class);
|
80
|
+
expectedException.expectMessage("Subtraction requires that the stack contain at least 2 values");
|
81
|
+
|
82
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("-"));
|
83
|
+
}
|
84
|
+
|
85
|
+
@Ignore("Remove to run test")
|
86
|
+
@Test
|
87
|
+
public void testErrorIfSubtractionAttemptedWithOneNumberOnTheStack() {
|
88
|
+
expectedException.expect(IllegalArgumentException.class);
|
89
|
+
expectedException.expectMessage("Subtraction requires that the stack contain at least 2 values");
|
90
|
+
|
91
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 -"));
|
92
|
+
}
|
93
|
+
|
94
|
+
@Ignore("Remove to run test")
|
95
|
+
@Test
|
96
|
+
public void testTwoNumbersCanBeMultiplied() {
|
97
|
+
assertEquals(
|
98
|
+
Collections.singletonList(8),
|
99
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("2 4 *")));
|
100
|
+
}
|
101
|
+
|
102
|
+
@Ignore("Remove to run test")
|
103
|
+
@Test
|
104
|
+
public void testErrorIfMultiplicationAttemptedWithNothingOnTheStack() {
|
105
|
+
expectedException.expect(IllegalArgumentException.class);
|
106
|
+
expectedException.expectMessage("Multiplication requires that the stack contain at least 2 values");
|
107
|
+
|
108
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("*"));
|
109
|
+
}
|
110
|
+
|
111
|
+
@Ignore("Remove to run test")
|
112
|
+
@Test
|
113
|
+
public void testErrorIfMultiplicationAttemptedWithOneNumberOnTheStack() {
|
114
|
+
expectedException.expect(IllegalArgumentException.class);
|
115
|
+
expectedException.expectMessage("Multiplication requires that the stack contain at least 2 values");
|
116
|
+
|
117
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 *"));
|
118
|
+
}
|
119
|
+
|
120
|
+
@Ignore("Remove to run test")
|
121
|
+
@Test
|
122
|
+
public void testTwoNumbersCanBeDivided() {
|
123
|
+
assertEquals(
|
124
|
+
Collections.singletonList(4),
|
125
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("12 3 /")));
|
126
|
+
}
|
127
|
+
|
128
|
+
@Ignore("Remove to run test")
|
129
|
+
@Test
|
130
|
+
public void testThatIntegerDivisionIsUsed() {
|
131
|
+
assertEquals(
|
132
|
+
Collections.singletonList(2),
|
133
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("8 3 /")));
|
134
|
+
}
|
135
|
+
|
136
|
+
@Ignore("Remove to run test")
|
137
|
+
@Test
|
138
|
+
public void testErrorIfDividingByZero() {
|
139
|
+
expectedException.expect(IllegalArgumentException.class);
|
140
|
+
expectedException.expectMessage("Division by 0 is not allowed");
|
141
|
+
|
142
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("4 0 /"));
|
143
|
+
}
|
144
|
+
|
145
|
+
@Ignore("Remove to run test")
|
146
|
+
@Test
|
147
|
+
public void testErrorIfDivisionAttemptedWithNothingOnTheStack() {
|
148
|
+
expectedException.expect(IllegalArgumentException.class);
|
149
|
+
expectedException.expectMessage("Division requires that the stack contain at least 2 values");
|
150
|
+
|
151
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("/"));
|
152
|
+
}
|
153
|
+
|
154
|
+
@Ignore("Remove to run test")
|
155
|
+
@Test
|
156
|
+
public void testErrorIfDivisionAttemptedWithOneNumberOnTheStack() {
|
157
|
+
expectedException.expect(IllegalArgumentException.class);
|
158
|
+
expectedException.expectMessage("Division requires that the stack contain at least 2 values");
|
159
|
+
|
160
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 /"));
|
161
|
+
}
|
162
|
+
|
163
|
+
@Ignore("Remove to run test")
|
164
|
+
@Test
|
165
|
+
public void testCombinedAdditionAndSubtraction() {
|
166
|
+
assertEquals(
|
167
|
+
Collections.singletonList(-1),
|
168
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 + 4 -")));
|
169
|
+
}
|
170
|
+
|
171
|
+
@Ignore("Remove to run test")
|
172
|
+
@Test
|
173
|
+
public void testCombinedMultiplicationAndDivision() {
|
174
|
+
assertEquals(
|
175
|
+
Collections.singletonList(2),
|
176
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("2 4 * 3 /")));
|
177
|
+
}
|
178
|
+
|
179
|
+
@Ignore("Remove to run test")
|
180
|
+
@Test
|
181
|
+
public void testDupCopiesTheTopValueOnTheStack() {
|
182
|
+
assertEquals(
|
183
|
+
Arrays.asList(1, 1),
|
184
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 DUP")));
|
185
|
+
}
|
186
|
+
|
187
|
+
@Ignore("Remove to run test")
|
188
|
+
@Test
|
189
|
+
public void testDupParsingIsCaseInsensitive() {
|
190
|
+
assertEquals(
|
191
|
+
Arrays.asList(1, 2, 2),
|
192
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 Dup")));
|
193
|
+
}
|
194
|
+
|
195
|
+
@Ignore("Remove to run test")
|
196
|
+
@Test
|
197
|
+
public void testErrorIfDuplicatingAttemptedWithNothingOnTheStack() {
|
198
|
+
expectedException.expect(IllegalArgumentException.class);
|
199
|
+
expectedException.expectMessage("Duplicating requires that the stack contain at least 1 value");
|
200
|
+
|
201
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("dup"));
|
202
|
+
}
|
203
|
+
|
204
|
+
@Ignore("Remove to run test")
|
205
|
+
@Test
|
206
|
+
public void testDropRemovesTheTopValueOnTheStackIfItIsTheOnlyOne() {
|
207
|
+
assertEquals(
|
208
|
+
Collections.emptyList(),
|
209
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 drop")));
|
210
|
+
}
|
211
|
+
|
212
|
+
@Ignore("Remove to run test")
|
213
|
+
@Test
|
214
|
+
public void testDropRemovesTheTopValueOnTheStackIfItIsNotTheOnlyOne() {
|
215
|
+
assertEquals(
|
216
|
+
Collections.singletonList(1),
|
217
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 drop")));
|
218
|
+
}
|
219
|
+
|
220
|
+
@Ignore("Remove to run test")
|
221
|
+
@Test
|
222
|
+
public void testErrorIfDroppingAttemptedWithNothingOnTheStack() {
|
223
|
+
expectedException.expect(IllegalArgumentException.class);
|
224
|
+
expectedException.expectMessage("Dropping requires that the stack contain at least 1 value");
|
225
|
+
|
226
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("drop"));
|
227
|
+
}
|
228
|
+
|
229
|
+
@Ignore("Remove to run test")
|
230
|
+
@Test
|
231
|
+
public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreTheOnlyOnes() {
|
232
|
+
assertEquals(
|
233
|
+
Arrays.asList(2, 1),
|
234
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 swap")));
|
235
|
+
}
|
236
|
+
|
237
|
+
@Ignore("Remove to run test")
|
238
|
+
@Test
|
239
|
+
public void testSwapSwapsTheTopTwosValueOnTheStackIfTheyAreNotTheOnlyOnes() {
|
240
|
+
assertEquals(
|
241
|
+
Arrays.asList(1, 3, 2),
|
242
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 swap")));
|
243
|
+
}
|
244
|
+
|
245
|
+
@Ignore("Remove to run test")
|
246
|
+
@Test
|
247
|
+
public void testErrorIfSwappingAttemptedWithNothingOnTheStack() {
|
248
|
+
expectedException.expect(IllegalArgumentException.class);
|
249
|
+
expectedException.expectMessage("Swapping requires that the stack contain at least 2 values");
|
250
|
+
|
251
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("swap"));
|
252
|
+
}
|
253
|
+
|
254
|
+
@Ignore("Remove to run test")
|
255
|
+
@Test
|
256
|
+
public void testErrorIfSwappingAttemptedWithOneNumberOnTheStack() {
|
257
|
+
expectedException.expect(IllegalArgumentException.class);
|
258
|
+
expectedException.expectMessage("Swapping requires that the stack contain at least 2 values");
|
259
|
+
|
260
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 swap"));
|
261
|
+
}
|
262
|
+
|
263
|
+
@Ignore("Remove to run test")
|
264
|
+
@Test
|
265
|
+
public void testOverCopiesTheSecondElementIfThereAreOnlyTwo() {
|
266
|
+
assertEquals(
|
267
|
+
Arrays.asList(1, 2, 1),
|
268
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 over")));
|
269
|
+
}
|
270
|
+
|
271
|
+
@Ignore("Remove to run test")
|
272
|
+
@Test
|
273
|
+
public void testOverCopiesTheSecondElementIfThereAreMoreThanTwo() {
|
274
|
+
assertEquals(
|
275
|
+
Arrays.asList(1, 2, 3, 2),
|
276
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 2 3 over")));
|
277
|
+
}
|
278
|
+
|
279
|
+
@Ignore("Remove to run test")
|
280
|
+
@Test
|
281
|
+
public void testErrorIfOveringAttemptedWithNothingOnTheStack() {
|
282
|
+
expectedException.expect(IllegalArgumentException.class);
|
283
|
+
expectedException.expectMessage("Overing requires that the stack contain at least 2 values");
|
284
|
+
|
285
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("over"));
|
286
|
+
}
|
287
|
+
|
288
|
+
@Ignore("Remove to run test")
|
289
|
+
@Test
|
290
|
+
public void testErrorIfOveringAttemptedWithOneNumberOnTheStack() {
|
291
|
+
expectedException.expect(IllegalArgumentException.class);
|
292
|
+
expectedException.expectMessage("Overing requires that the stack contain at least 2 values");
|
293
|
+
|
294
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("1 over"));
|
295
|
+
}
|
296
|
+
|
297
|
+
@Ignore("Remove to run test")
|
298
|
+
@Test
|
299
|
+
public void testUserDefinedOperatorsCanConsistOfBuiltInOperators() {
|
300
|
+
assertEquals(
|
301
|
+
Arrays.asList(1, 1, 1),
|
302
|
+
forthEvaluator.evaluateProgram(Arrays.asList(": dup-twice dup dup ;", "1 dup-twice")));
|
303
|
+
}
|
304
|
+
|
305
|
+
@Ignore("Remove to run test")
|
306
|
+
@Test
|
307
|
+
public void testUserDefinedOperatorsAreEvaluatedInTheCorrectOrder() {
|
308
|
+
assertEquals(
|
309
|
+
Arrays.asList(1, 2, 3),
|
310
|
+
forthEvaluator.evaluateProgram(Arrays.asList(": countup 1 2 3 ;", "countup")));
|
311
|
+
}
|
312
|
+
|
313
|
+
@Ignore("Remove to run test")
|
314
|
+
@Test
|
315
|
+
public void testCanRedefineAUserDefinedOperator() {
|
316
|
+
assertEquals(
|
317
|
+
Arrays.asList(1, 1, 1),
|
318
|
+
forthEvaluator.evaluateProgram(Arrays.asList(": foo dup ;", ": foo dup dup ;", "1 foo")));
|
319
|
+
}
|
320
|
+
|
321
|
+
@Ignore("Remove to run test")
|
322
|
+
@Test
|
323
|
+
public void testCanOverrideBuiltInWordOperators() {
|
324
|
+
assertEquals(
|
325
|
+
Arrays.asList(1, 1),
|
326
|
+
forthEvaluator.evaluateProgram(Arrays.asList(": swap dup ;", "1 swap")));
|
327
|
+
}
|
328
|
+
|
329
|
+
@Ignore("Remove to run test")
|
330
|
+
@Test
|
331
|
+
public void testCanOverrideBuiltInArithmeticOperators() {
|
332
|
+
assertEquals(
|
333
|
+
Collections.singletonList(12),
|
334
|
+
forthEvaluator.evaluateProgram(Arrays.asList(": + * ;", "3 4 +")));
|
335
|
+
}
|
336
|
+
|
337
|
+
@Ignore("Remove to run test")
|
338
|
+
@Test
|
339
|
+
public void testCannotRedefineNumbers() {
|
340
|
+
expectedException.expect(IllegalArgumentException.class);
|
341
|
+
expectedException.expectMessage("Cannot redefine numbers");
|
342
|
+
|
343
|
+
forthEvaluator.evaluateProgram(Collections.singletonList(": 1 2 ;"));
|
344
|
+
}
|
345
|
+
|
346
|
+
@Ignore("Remove to run test")
|
347
|
+
@Test
|
348
|
+
public void testErrorIfEvaluatingAnUndefinedOperator() {
|
349
|
+
expectedException.expect(IllegalArgumentException.class);
|
350
|
+
expectedException.expectMessage("No definition available for operator \"foo\"");
|
351
|
+
|
352
|
+
forthEvaluator.evaluateProgram(Collections.singletonList("foo"));
|
353
|
+
}
|
354
|
+
|
355
|
+
}
|
data/tracks/kotlin/config.json
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"slug": "kotlin",
|
3
2
|
"language": "Kotlin",
|
4
|
-
"repository": "https://github.com/exercism/kotlin",
|
5
3
|
"active": true,
|
6
4
|
"foregone": [
|
7
5
|
|
@@ -479,6 +477,16 @@
|
|
479
477
|
|
480
478
|
]
|
481
479
|
},
|
480
|
+
{
|
481
|
+
"uuid": "5607dae5-13aa-4cd4-8b4c-d270516182d7",
|
482
|
+
"slug": "say",
|
483
|
+
"core": false,
|
484
|
+
"unlocked_by": null,
|
485
|
+
"difficulty": 6,
|
486
|
+
"topics": [
|
487
|
+
|
488
|
+
]
|
489
|
+
},
|
482
490
|
{
|
483
491
|
"uuid": "f754e1cc-cb88-4776-ab11-3e6ae8362d5a",
|
484
492
|
"slug": "anagram",
|
@@ -499,6 +507,16 @@
|
|
499
507
|
|
500
508
|
]
|
501
509
|
},
|
510
|
+
{
|
511
|
+
"uuid": "d617987e-64b8-4c21-89a9-66a932c4668d",
|
512
|
+
"slug": "meetup",
|
513
|
+
"core": false,
|
514
|
+
"unlocked_by": null,
|
515
|
+
"difficulty": 7,
|
516
|
+
"topics": [
|
517
|
+
|
518
|
+
]
|
519
|
+
},
|
502
520
|
{
|
503
521
|
"uuid": "1dcefdea-5447-4622-a064-079aad781398",
|
504
522
|
"slug": "clock",
|
@@ -539,6 +557,16 @@
|
|
539
557
|
|
540
558
|
]
|
541
559
|
},
|
560
|
+
{
|
561
|
+
"uuid": "eecd4f8b-eedc-49a3-adad-49747521ef66",
|
562
|
+
"slug": "forth",
|
563
|
+
"core": false,
|
564
|
+
"unlocked_by": null,
|
565
|
+
"difficulty": 9,
|
566
|
+
"topics": [
|
567
|
+
|
568
|
+
]
|
569
|
+
},
|
542
570
|
{
|
543
571
|
"uuid": "240788cd-afa5-4fd6-8df0-a158239c0610",
|
544
572
|
"slug": "react",
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Forth
|
2
|
+
|
3
|
+
Implement an evaluator for a very simple subset of Forth.
|
4
|
+
|
5
|
+
[Forth](https://en.wikipedia.org/wiki/Forth_%28programming_language%29)
|
6
|
+
is a stack-based programming language. Implement a very basic evaluator
|
7
|
+
for a small subset of Forth.
|
8
|
+
|
9
|
+
Your evaluator has to support the following words:
|
10
|
+
|
11
|
+
- `+`, `-`, `*`, `/` (integer arithmetic)
|
12
|
+
- `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation)
|
13
|
+
|
14
|
+
Your evaluator also has to support defining new words using the
|
15
|
+
customary syntax: `: word-name definition ;`.
|
16
|
+
|
17
|
+
To keep things simple the only data type you need to support is signed
|
18
|
+
integers of at least 16 bits size.
|
19
|
+
|
20
|
+
You should use the following rules for the syntax: a number is a
|
21
|
+
sequence of one or more (ASCII) digits, a word is a sequence of one or
|
22
|
+
more letters, digits, symbols or punctuation that is not a number.
|
23
|
+
(Forth probably uses slightly different rules, but this is close
|
24
|
+
enough.)
|
25
|
+
|
26
|
+
Words are case-insensitive.
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
## Submitting Incomplete Solutions
|
32
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
buildscript {
|
2
|
+
ext.kotlin_version = '1.1.1'
|
3
|
+
repositories {
|
4
|
+
mavenCentral()
|
5
|
+
}
|
6
|
+
dependencies {
|
7
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
apply plugin: 'kotlin'
|
12
|
+
|
13
|
+
repositories {
|
14
|
+
mavenCentral()
|
15
|
+
}
|
16
|
+
|
17
|
+
dependencies {
|
18
|
+
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
19
|
+
|
20
|
+
testCompile 'junit:junit:4.12'
|
21
|
+
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
|
22
|
+
}
|
23
|
+
test {
|
24
|
+
testLogging {
|
25
|
+
exceptionFormat = 'full'
|
26
|
+
events = ["passed", "failed", "skipped"]
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
import java.util.*
|
2
|
+
|
3
|
+
sealed class Token {
|
4
|
+
|
5
|
+
data class OpDefToken(val newOp: String, val newOpDefTokens: List<Token>): Token() {
|
6
|
+
|
7
|
+
companion object {
|
8
|
+
fun fromString(string: String): OpDefToken {
|
9
|
+
val trimmedLine = string.substring(2..string.lastIndex - 2)
|
10
|
+
val newOpEnd = trimmedLine.indexOf(" ")
|
11
|
+
|
12
|
+
require(newOpEnd >= 0) { "Incomplete operation definition" }
|
13
|
+
|
14
|
+
val newOpToken = Token.fromString(trimmedLine.substring(0 until newOpEnd)).first()
|
15
|
+
|
16
|
+
require(newOpToken is OpToken) { "Cannot redefine numbers" }
|
17
|
+
|
18
|
+
val newOpDefTokens = Token.fromString(trimmedLine.substring(newOpEnd + 1))
|
19
|
+
return OpDefToken((newOpToken as OpToken).op, newOpDefTokens)
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
}
|
24
|
+
|
25
|
+
data class OpToken(val op: String): Token()
|
26
|
+
data class IntToken(val rawValue: Int): Token()
|
27
|
+
|
28
|
+
companion object {
|
29
|
+
val opChars = "A-z+/*\\-"
|
30
|
+
|
31
|
+
fun fromString(string: String): List<Token> {
|
32
|
+
return when {
|
33
|
+
string.startsWith(':') -> listOf(OpDefToken.fromString(string))
|
34
|
+
string.matches(Regex("[$opChars]+(?:-[$opChars]+)*")) -> listOf(OpToken(string.toLowerCase()))
|
35
|
+
string.matches(Regex("\\d+")) -> listOf(IntToken(string.toInt()))
|
36
|
+
else -> string.split(delimiters = " ").flatMap { Token.fromString(it) }
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
}
|
42
|
+
|
43
|
+
class ForthEvaluator {
|
44
|
+
|
45
|
+
companion object {
|
46
|
+
private val builtInOps = mapOf<String, (Deque<Int>) -> Any>(
|
47
|
+
Pair("+") { values ->
|
48
|
+
require(values.size >= 2) { "Addition requires that the stack contain at least 2 values" }
|
49
|
+
values.push(values.pop() + values.pop())
|
50
|
+
},
|
51
|
+
|
52
|
+
Pair("-") { values ->
|
53
|
+
require(values.size >= 2) { "Subtraction requires that the stack contain at least 2 values" }
|
54
|
+
val topValue = values.pop()
|
55
|
+
val secondValue = values.pop()
|
56
|
+
values.push(secondValue - topValue)
|
57
|
+
},
|
58
|
+
|
59
|
+
Pair("*") { values ->
|
60
|
+
require(values.size >= 2) { "Multiplication requires that the stack contain at least 2 values" }
|
61
|
+
values.push(values.pop() * values.pop())
|
62
|
+
},
|
63
|
+
|
64
|
+
Pair("/") { values ->
|
65
|
+
require(values.size >= 2) { "Division requires that the stack contain at least 2 values" }
|
66
|
+
val topValue = values.pop()
|
67
|
+
val secondValue = values.pop()
|
68
|
+
require(topValue != 0) { "Division by 0 is not allowed" }
|
69
|
+
values.push(secondValue / topValue)
|
70
|
+
},
|
71
|
+
|
72
|
+
Pair("dup") { values ->
|
73
|
+
require(values.isNotEmpty()) { "Duplicating requires that the stack contain at least 1 value" }
|
74
|
+
values.push(values.peek())
|
75
|
+
},
|
76
|
+
|
77
|
+
Pair("drop") { values ->
|
78
|
+
require(values.isNotEmpty()) { "Dropping requires that the stack contain at least 1 value" }
|
79
|
+
values.pop()
|
80
|
+
},
|
81
|
+
|
82
|
+
Pair("swap") { values ->
|
83
|
+
require(values.size >= 2) { "Swapping requires that the stack contain at least 2 values" }
|
84
|
+
val topValue = values.pop()
|
85
|
+
val secondValue = values.pop()
|
86
|
+
values.push(topValue)
|
87
|
+
values.push(secondValue)
|
88
|
+
},
|
89
|
+
|
90
|
+
Pair("over") { values ->
|
91
|
+
require(values.size >= 2) { "Overing requires that the stack contain at least 2 values" }
|
92
|
+
val topValue = values.pop()
|
93
|
+
val secondValue = values.peek()
|
94
|
+
values.push(topValue)
|
95
|
+
values.push(secondValue)
|
96
|
+
}
|
97
|
+
)
|
98
|
+
}
|
99
|
+
|
100
|
+
private val values = ArrayDeque<Int>()
|
101
|
+
|
102
|
+
private val tokens = mutableListOf<Token>()
|
103
|
+
|
104
|
+
private val userOps = mutableMapOf<String, List<Token>>()
|
105
|
+
|
106
|
+
fun evaluateProgram(program: List<String>): List<Int> {
|
107
|
+
parse(program)
|
108
|
+
evaluate()
|
109
|
+
return values.toList().asReversed()
|
110
|
+
}
|
111
|
+
|
112
|
+
private fun parse(program: List<String>) = tokens.addAll(program.flatMap(Token.Companion::fromString))
|
113
|
+
|
114
|
+
private fun evaluate() {
|
115
|
+
while (tokens.isNotEmpty()) {
|
116
|
+
val token = tokens.removeAt(0)
|
117
|
+
|
118
|
+
when (token) {
|
119
|
+
is Token.OpDefToken -> userOps.put(token.newOp.toLowerCase(), token.newOpDefTokens)
|
120
|
+
is Token.OpToken -> evaluateOpToken(token)
|
121
|
+
is Token.IntToken -> values.push(token.rawValue)
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
private fun evaluateOpToken(opToken: Token.OpToken) {
|
127
|
+
val op = opToken.op
|
128
|
+
|
129
|
+
if (userOps.containsKey(op)) {
|
130
|
+
userOps[op]!!.asReversed().forEach { token -> tokens.add(index = 0, element = token) }
|
131
|
+
} else if (builtInOps.containsKey(op)) {
|
132
|
+
builtInOps[op]!!.invoke(values)
|
133
|
+
} else {
|
134
|
+
throw IllegalArgumentException("No definition available for operator \"$op\"")
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
}
|
File without changes
|