trackler 2.2.0.4 → 2.2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|