├── .appends └── .github │ └── labels.yml ├── .github ├── CODEOWNERS ├── dependabot.yml ├── labels.yml └── workflows │ ├── configlet.yml │ ├── no-important-files-changed.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── sync-labels.yml │ └── tests.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bin ├── fetch-configlet └── test-exercises.sh ├── config.json ├── docs ├── ABOUT.md ├── INSTALLATION.md ├── LEARNING.md ├── RESOURCES.md ├── SNIPPET.txt ├── TESTS.md ├── config.json └── img │ ├── AddFiles.png │ └── SolutionExplorer.png ├── exercises ├── practice │ ├── accumulate │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── accumulate.coffee │ │ └── accumulate.spec.coffee │ ├── acronym │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── acronym.coffee │ │ └── acronym.spec.coffee │ ├── all-your-base │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── all-your-base.coffee │ │ └── all-your-base.spec.coffee │ ├── allergies │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── allergies.coffee │ │ └── allergies.spec.coffee │ ├── anagram │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── anagram.coffee │ │ └── anagram.spec.coffee │ ├── armstrong-numbers │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── armstrong-numbers.coffee │ │ └── armstrong-numbers.spec.coffee │ ├── atbash-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── atbash-cipher.coffee │ │ └── atbash-cipher.spec.coffee │ ├── bank-account │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── bank-account.coffee │ │ └── bank-account.spec.coffee │ ├── beer-song │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── beer-song.coffee │ │ └── beer-song.spec.coffee │ ├── binary-search-tree │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── binary-search-tree.coffee │ │ └── binary-search-tree.spec.coffee │ ├── binary-search │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── binary-search.coffee │ │ ├── binary-search.spec.coffee │ │ └── traced-array.coffee │ ├── binary │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── binary.coffee │ │ └── binary.spec.coffee │ ├── bob │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── bob.coffee │ │ └── bob.spec.coffee │ ├── bottle-song │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── bottle-song.coffee │ │ └── bottle-song.spec.coffee │ ├── circular-buffer │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── circular-buffer.coffee │ │ └── circular-buffer.spec.coffee │ ├── clock │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── clock.coffee │ │ └── clock.spec.coffee │ ├── collatz-conjecture │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── collatz-conjecture.coffee │ │ └── collatz-conjecture.spec.coffee │ ├── custom-set │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── custom-set.coffee │ │ └── custom-set.spec.coffee │ ├── darts │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── darts.coffee │ │ └── darts.spec.coffee │ ├── diamond │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── diamond.coffee │ │ └── diamond.spec.coffee │ ├── difference-of-squares │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── difference-of-squares.coffee │ │ └── difference-of-squares.spec.coffee │ ├── dnd-character │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── dnd-character.coffee │ │ └── dnd-character.spec.coffee │ ├── eliuds-eggs │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── eliuds-eggs.coffee │ │ └── eliuds-eggs.spec.coffee │ ├── etl │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── etl.coffee │ │ └── etl.spec.coffee │ ├── flatten-array │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── flatten-array.coffee │ │ └── flatten-array.spec.coffee │ ├── food-chain │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── food-chain.coffee │ │ └── food-chain.spec.coffee │ ├── game-of-life │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── game-of-life.coffee │ │ └── game-of-life.spec.coffee │ ├── gigasecond │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── gigasecond.coffee │ │ └── gigasecond.spec.coffee │ ├── grade-school │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── grade-school.coffee │ │ └── grade-school.spec.coffee │ ├── grains │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── grains.coffee │ │ └── grains.spec.coffee │ ├── hamming │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── hamming.coffee │ │ └── hamming.spec.coffee │ ├── hello-world │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── hello-world.coffee │ │ └── hello-world.spec.coffee │ ├── hexadecimal │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.coffee │ │ ├── hexadecimal.coffee │ │ └── hexadecimal.spec.coffee │ ├── high-scores │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── high-scores.coffee │ │ └── high-scores.spec.coffee │ ├── house │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── house.coffee │ │ └── house.spec.coffee │ ├── isbn-verifier │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── isbn-verifier.coffee │ │ └── isbn-verifier.spec.coffee │ ├── isogram │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── isogram.coffee │ │ └── isogram.spec.coffee │ ├── kindergarten-garden │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── kindergarten-garden.coffee │ │ └── kindergarten-garden.spec.coffee │ ├── knapsack │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── knapsack.coffee │ │ └── knapsack.spec.coffee │ ├── largest-series-product │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── largest-series-product.coffee │ │ └── largest-series-product.spec.coffee │ ├── leap │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── leap.coffee │ │ └── leap.spec.coffee │ ├── linked-list │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── linked-list.coffee │ │ └── linked-list.spec.coffee │ ├── list-ops │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── list-ops.coffee │ │ └── list-ops.spec.coffee │ ├── luhn │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── luhn.coffee │ │ └── luhn.spec.coffee │ ├── matching-brackets │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── matching-brackets.coffee │ │ └── matching-brackets.spec.coffee │ ├── matrix │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── matrix.coffee │ │ └── matrix.spec.coffee │ ├── meetup │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── meetup.coffee │ │ └── meetup.spec.coffee │ ├── micro-blog │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── micro-blog.coffee │ │ └── micro-blog.spec.coffee │ ├── minesweeper │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── minesweeper.coffee │ │ └── minesweeper.spec.coffee │ ├── nth-prime │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── nth-prime.coffee │ │ └── nth-prime.spec.coffee │ ├── nucleotide-count │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── nucleotide-count.coffee │ │ └── nucleotide-count.spec.coffee │ ├── palindrome-products │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── palindrome-products.coffee │ │ └── palindrome-products.spec.coffee │ ├── pangram │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── pangram.coffee │ │ └── pangram.spec.coffee │ ├── pascals-triangle │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── pascals-triangle.coffee │ │ └── pascals-triangle.spec.coffee │ ├── perfect-numbers │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── perfect-numbers.coffee │ │ └── perfect-numbers.spec.coffee │ ├── phone-number │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── phone-number.coffee │ │ └── phone-number.spec.coffee │ ├── pig-latin │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── pig-latin.coffee │ │ └── pig-latin.spec.coffee │ ├── prime-factors │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── prime-factors.coffee │ │ └── prime-factors.spec.coffee │ ├── protein-translation │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── protein-translation.coffee │ │ └── protein-translation.spec.coffee │ ├── proverb │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── proverb.coffee │ │ └── proverb.spec.coffee │ ├── queen-attack │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── queen-attack.coffee │ │ └── queen-attack.spec.coffee │ ├── raindrops │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── raindrops.coffee │ │ └── raindrops.spec.coffee │ ├── relative-distance │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── relative-distance.coffee │ │ └── relative-distance.spec.coffee │ ├── resistor-color-duo │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── resistor-color-duo.coffee │ │ └── resistor-color-duo.spec.coffee │ ├── resistor-color-trio │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── resistor-color-trio.coffee │ │ └── resistor-color-trio.spec.coffee │ ├── resistor-color │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── resistor-color.coffee │ │ └── resistor-color.spec.coffee │ ├── reverse-string │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── reverse-string.coffee │ │ └── reverse-string.spec.coffee │ ├── rna-transcription │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── rna-transcription.coffee │ │ └── rna-transcription.spec.coffee │ ├── robot-simulator │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── robot-simulator.coffee │ │ └── robot-simulator.spec.coffee │ ├── roman-numerals │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── roman-numerals.coffee │ │ └── roman-numerals.spec.coffee │ ├── rotational-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── rotational-cipher.coffee │ │ └── rotational-cipher.spec.coffee │ ├── run-length-encoding │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── run-length-encoding.coffee │ │ └── run-length-encoding.spec.coffee │ ├── scrabble-score │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── scrabble-score.coffee │ │ └── scrabble-score.spec.coffee │ ├── secret-handshake │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── secret-handshake.coffee │ │ └── secret-handshake.spec.coffee │ ├── series │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── series.coffee │ │ └── series.spec.coffee │ ├── sieve │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── sieve.coffee │ │ └── sieve.spec.coffee │ ├── simple-linked-list │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.coffee │ │ ├── simple-linked-list.coffee │ │ └── simple-linked-list.spec.coffee │ ├── space-age │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── space-age.coffee │ │ └── space-age.spec.coffee │ ├── spiral-matrix │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── spiral-matrix.coffee │ │ └── spiral-matrix.spec.coffee │ ├── square-root │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── square-root.coffee │ │ └── square-root.spec.coffee │ ├── strain │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── strain.coffee │ │ └── strain.spec.coffee │ ├── sublist │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── sublist.coffee │ │ └── sublist.spec.coffee │ ├── sum-of-multiples │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── sum-of-multiples.coffee │ │ └── sum-of-multiples.spec.coffee │ ├── triangle │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── triangle.coffee │ │ └── triangle.spec.coffee │ ├── trinary │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── trinary.coffee │ │ └── trinary.spec.coffee │ ├── twelve-days │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── twelve-days.coffee │ │ └── twelve-days.spec.coffee │ ├── two-bucket │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── two-bucket.coffee │ │ └── two-bucket.spec.coffee │ ├── two-fer │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── two-fer.coffee │ │ └── two-fer.spec.coffee │ ├── word-count │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── word-count.coffee │ │ └── word-count.spec.coffee │ ├── wordy │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.coffee │ │ │ └── tests.toml │ │ ├── wordy.coffee │ │ └── wordy.spec.coffee │ └── yacht │ │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ │ ├── .meta │ │ ├── config.json │ │ ├── example.coffee │ │ └── tests.toml │ │ ├── yacht.coffee │ │ └── yacht.spec.coffee └── shared │ └── .docs │ ├── help.md │ └── tests.md └── reference └── implementing-a-concept-exercise.md /.appends/.github/labels.yml: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------------------- # 2 | # These are the repository-specific labels that augment the Exercise-wide labels defined in # 3 | # https://github.com/exercism/org-wide-files/blob/main/global-files/.github/labels.yml. # 4 | # ----------------------------------------------------------------------------------------- # 5 | 6 | - name: "bug" 7 | description: "" 8 | color: "fc2929" 9 | 10 | - name: "duplicate" 11 | description: "" 12 | color: "cccccc" 13 | 14 | - name: "enhancement" 15 | description: "" 16 | color: "84b6eb" 17 | 18 | - name: "first-timers only" 19 | description: "" 20 | color: "159818" 21 | 22 | - name: "good first patch" 23 | description: "" 24 | color: "159818" 25 | 26 | - name: "invalid" 27 | description: "" 28 | color: "e6e6e6" 29 | 30 | - name: "question" 31 | description: "" 32 | color: "cc317c" 33 | 34 | - name: "wontfix" 35 | description: "" 36 | color: "ffffff" 37 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners 2 | .github/CODEOWNERS @exercism/maintainers-admin 3 | 4 | # Changes to `fetch-configlet` should be made in the `exercism/configlet` repo 5 | bin/fetch-configlet @exercism/maintainers-admin 6 | 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | 5 | # Keep dependencies for GitHub Actions up-to-date 6 | - package-ecosystem: 'github-actions' 7 | directory: '/' 8 | schedule: 9 | interval: 'monthly' 10 | -------------------------------------------------------------------------------- /.github/workflows/configlet.yml: -------------------------------------------------------------------------------- 1 | name: Configlet 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | configlet: 15 | uses: exercism/github-actions/.github/workflows/configlet.yml@main 16 | -------------------------------------------------------------------------------- /.github/workflows/no-important-files-changed.yml: -------------------------------------------------------------------------------- 1 | name: No important files changed 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | branches: [main] 7 | paths: 8 | - "exercises/concept/**" 9 | - "exercises/practice/**" 10 | - "!exercises/*/*/.approaches/**" 11 | - "!exercises/*/*/.articles/**" 12 | - "!exercises/*/*/.docs/**" 13 | - "!exercises/*/*/.meta/**" 14 | 15 | permissions: 16 | pull-requests: write 17 | 18 | jobs: 19 | check: 20 | uses: exercism/github-actions/.github/workflows/check-no-important-files-changed.yml@main 21 | with: 22 | repository: ${{ github.event.pull_request.head.repo.owner.login }}/${{ github.event.pull_request.head.repo.name }} 23 | ref: ${{ github.head_ref }} 24 | -------------------------------------------------------------------------------- /.github/workflows/ping-cross-track-maintainers-team.yml: -------------------------------------------------------------------------------- 1 | name: Ping cross-track maintainers team 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | pull-requests: write 10 | 11 | jobs: 12 | ping: 13 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 14 | uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main 15 | secrets: 16 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | schedule: 8 | # Weekly. 9 | - cron: '0 0 * * 0' 10 | 11 | jobs: 12 | exercises: 13 | name: Check exercises 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 17 | - name: Install CoffeeScript 18 | run: npm install -g jasmine-node coffeescript 19 | - name: Run tests 20 | run: ./bin/test-exercises.sh -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | tmp 4 | bin/configlet 5 | bin/configlet.exe 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exercism CoffeeScript Track 2 | [![Configlet](https://github.com/exercism/coffeescript/actions/workflows/configlet.yml/badge.svg)](https://github.com/exercism/coffeescript/actions/workflows/configlet.yml) 3 | [![Tests](https://github.com/exercism/coffeescript/actions/workflows/tests.yml/badge.svg)](https://github.com/exercism/coffeescript/actions/workflows/tests.yml) 4 | 5 | Exercism exercises in CoffeeScript 6 | 7 | ## Contributing Guide 8 | 9 | Please see the [contributing guide](https://github.com/exercism/x-api/blob/master/CONTRIBUTING.md#the-exercise-data) 10 | 11 | 12 | ### CoffeeScript icon 13 | We were unable to find a license for the CoffeeScript logo, however we believe that it is owned by Jeremy Ashkenas, who holds the copyright on the CoffeeScript language. 14 | We are using the logo to identify the CoffeeScript language itself, not any part of Exercism, which we believe to be admissible under fair use. 15 | The version of the logo that we are using is a black/white adaptation of the logo found on coffeescript.org. 16 | -------------------------------------------------------------------------------- /bin/test-exercises.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test_run() { 4 | dic=$(mktemp -d) 5 | trap 'rm -r "$dic"' EXIT 6 | echo "Testing $1" 7 | source_file="$(jq -r '.files.solution[0]' "$1/.meta/config.json")" 8 | test_file="$(jq -r '.files.test[0]' "$1/.meta/config.json")" 9 | echo "source_file: ${source_file}" 10 | cat "$1/.meta/example.coffee" > "${dic}/${source_file}" 11 | cat "$1/${test_file}" > "${dic}/${test_file}" 12 | sed -i -e 's/xit/it/g' "${dic}/${test_file}" 13 | jasmine-node --coffee "${dic}/${test_file}" || exit 1 14 | } 15 | 16 | if [ -n "$1" ] && [ -d "$1" ]; then 17 | # test one exercise 18 | test_run "$1" 19 | else 20 | # test them all 21 | for exercise in ./exercises/practice/*; do 22 | test_run "${exercise}" 23 | done 24 | 25 | if [ -d "./exercises/concept" ]; then 26 | for exercise in ./exercises/concept/*; do 27 | test_run "${exercise}" 28 | done 29 | fi 30 | fi 31 | -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | CoffeeScript is a language which transpiles into JavaScript, used for making dynamic websites (both in the web browser, and on the server). 4 | The transpiler is used to transform CoffeeScript code into JavaScript before running, to keep compatibility and the same performance of JavaScript while providing many new features! 5 | 6 | CoffeeScript was created to provide a simplified way to write JavaScript, based on a blend of the Ruby and Python languages. 7 | One difference is the use of indentation and arrows to replace JavaScript's verbose function code, and introduces useful features from functional languages including pattern matching. 8 | 9 | CoffeeScript is one of many new languages that transpiles to JavaScript, including TypeScript and Flow - the community is growing, and these types of languages are very popular. 10 | -------------------------------------------------------------------------------- /docs/LEARNING.md: -------------------------------------------------------------------------------- 1 | # Learning 2 | 3 | ## Websites 4 | 5 | - [CoffeeScript Official Website](http://coffeescript.org) 6 | - [CoffeeScript Fundamentals on Pluralsight](https://www.pluralsight.com/courses/coffeescript-fundamentals) 7 | - [Meet CoffeeScript on Pluralsight](https://www.pluralsight.com/courses/meet-coffeescript) 8 | 9 | ## Books 10 | 11 | - [The Little Book on CoffeeScript](https://arcturo.github.io/library/coffeescript/) 12 | - [Smooth CoffeeScript](https://autotelicum.github.io/Smooth-CoffeeScript/) 13 | 14 | ## Videos 15 | - [Introduction to CoffeeScript](https://youtu.be/QgqVh_KpVKY?si=lYrIt4b4lsaUg7PD) 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | class HelloWorld 2 | hello: (name = 'World') -> 3 | "Hello, #{name}!" 4 | module.exports = HelloWorld 5 | -------------------------------------------------------------------------------- /docs/TESTS.md: -------------------------------------------------------------------------------- 1 | # Running Tests 2 | 3 | Execute the tests with: 4 | 5 | ```bash 6 | $ jasmine-node --coffee bob.spec.coffee 7 | ``` 8 | -------------------------------------------------------------------------------- /docs/img/AddFiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/coffeescript/d58142d8138afc50e63b1cf4729a9d858322b610/docs/img/AddFiles.png -------------------------------------------------------------------------------- /docs/img/SolutionExplorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/coffeescript/d58142d8138afc50e63b1cf4729a9d858322b610/docs/img/SolutionExplorer.png -------------------------------------------------------------------------------- /exercises/practice/accumulate/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection. 4 | 5 | Given the collection of numbers: 6 | 7 | - 1, 2, 3, 4, 5 8 | 9 | And the operation: 10 | 11 | - square a number (`x => x * x`) 12 | 13 | Your code should be able to produce the collection of squares: 14 | 15 | - 1, 4, 9, 16, 25 16 | 17 | Check out the test suite to see the expected function signature. 18 | 19 | ## Restrictions 20 | 21 | Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! 22 | Solve this one yourself using other basic tools instead. 23 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "kytrinyx", 6 | "rootulp", 7 | "shidel-dev" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "accumulate.coffee" 12 | ], 13 | "test": [ 14 | "accumulate.spec.coffee" 15 | ], 16 | "example": [ 17 | ".meta/example.coffee" 18 | ] 19 | }, 20 | "blurb": "Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.", 21 | "source": "Conversation with James Edward Gray II", 22 | "source_url": "https://twitter.com/jeg2" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | Array::accumulate = (accumulator) -> 2 | return this.map(accumulator) if typeof Array::map is 'function' 3 | accumulator i for i in this 4 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/accumulate.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | 3 | Array::accumulate = (args) -> 4 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a phrase to its acronym. 4 | 5 | Techies love their TLA (Three Letter Acronyms)! 6 | 7 | Help generate some jargon by writing a program that converts a long name like Portable Network Graphics to its acronym (PNG). 8 | 9 | Punctuation is handled as follows: hyphens are word separators (like whitespace); all other punctuation can be removed from the input. 10 | 11 | For example: 12 | 13 | | Input | Output | 14 | | ------------------------- | ------ | 15 | | As Soon As Possible | ASAP | 16 | | Liquid-crystal display | LCD | 17 | | Thank George It's Friday! | TGIF | 18 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "acronym.coffee" 8 | ], 9 | "test": [ 10 | "acronym.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert a long phrase to its acronym.", 17 | "source": "Julien Vanier", 18 | "source_url": "https://github.com/monkbroc" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Acronym 2 | @abbreviate: (phrase) -> 3 | phrase 4 | .replace "'", "" 5 | .match /^[A-Z]|(?<=[^A-Z])[A-Z]|\b[a-z]/g 6 | .join "" 7 | .toUpperCase() 8 | 9 | module.exports = Acronym 10 | -------------------------------------------------------------------------------- /exercises/practice/acronym/acronym.coffee: -------------------------------------------------------------------------------- 1 | class Acronym 2 | @abbreviate: (phrase) -> 3 | 4 | module.exports = Acronym 5 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a sequence of digits in one base, representing a number, into a sequence of digits in another base, representing the same number. 4 | 5 | ~~~~exercism/note 6 | Try to implement the conversion yourself. 7 | Do not use something else to perform the conversion for you. 8 | ~~~~ 9 | 10 | ## About [Positional Notation][positional-notation] 11 | 12 | In positional notation, a number in base **b** can be understood as a linear combination of powers of **b**. 13 | 14 | The number 42, _in base 10_, means: 15 | 16 | `(4 × 10¹) + (2 × 10⁰)` 17 | 18 | The number 101010, _in base 2_, means: 19 | 20 | `(1 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)` 21 | 22 | The number 1120, _in base 3_, means: 23 | 24 | `(1 × 3³) + (1 × 3²) + (2 × 3¹) + (0 × 3⁰)` 25 | 26 | _Yes. Those three numbers above are exactly the same. Congratulations!_ 27 | 28 | [positional-notation]: https://en.wikipedia.org/wiki/Positional_notation 29 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've just been hired as professor of mathematics. 4 | Your first week went well, but something is off in your second week. 5 | The problem is that every answer given by your students is wrong! 6 | Luckily, your math skills have allowed you to identify the problem: the student answers _are_ correct, but they're all in base 2 (binary)! 7 | Amazingly, it turns out that each week, the students use a different base. 8 | To help you quickly verify the student answers, you'll be building a tool to translate between bases. 9 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "all-your-base.coffee" 8 | ], 9 | "test": [ 10 | "all-your-base.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert a number, represented as a sequence of digits in one base, to any other base." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | allYourBase = ({inputBase, outputBase, digits}) -> 2 | throw new Error "input base must be >= 2" unless inputBase >= 2 3 | throw new Error "output base must be >= 2" unless outputBase >= 2 4 | 5 | if digits.some ((d) => d < 0 or d >= inputBase) 6 | throw new Error "all digits must satisfy 0 <= d < input base" 7 | 8 | decimal = digits.reduce ((dec, d) => dec * inputBase + d), 0 9 | 10 | if decimal is 0 11 | [0] 12 | else 13 | outputDigits = [] 14 | while decimal > 0 15 | outputDigits.unshift decimal % outputBase 16 | decimal //= outputBase 17 | outputDigits 18 | 19 | 20 | module.exports = allYourBase 21 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/all-your-base.coffee: -------------------------------------------------------------------------------- 1 | allYourBase = (args) -> 2 | 3 | module.exports = allYourBase 4 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "allergies.coffee" 8 | ], 9 | "test": [ 10 | "allergies.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | ALLERGENS = [ 2 | "eggs" 3 | "peanuts" 4 | "shellfish" 5 | "strawberries" 6 | "tomatoes" 7 | "chocolate" 8 | "pollen" 9 | "cats" 10 | ] 11 | 12 | class Allergies 13 | constructor: (@score) -> 14 | 15 | allergicTo: (allergen) -> 16 | @list().some (candidate) -> candidate == allergen 17 | 18 | list: () -> 19 | ALLERGENS.filter (_, i) => @score & (1 << i) 20 | 21 | module.exports = Allergies 22 | -------------------------------------------------------------------------------- /exercises/practice/allergies/allergies.coffee: -------------------------------------------------------------------------------- 1 | class Allergies 2 | constructor: (score) -> 3 | 4 | allergicTo: (candidate) -> 5 | 6 | list: () -> 7 | 8 | module.exports = Allergies 9 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions Append 2 | 3 | The anagrams can be returned in any order. 4 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a target word and one or more candidate words, your task is to find the candidates that are anagrams of the target. 4 | 5 | An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. 6 | A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. 7 | 8 | The target word and candidate words are made up of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). 9 | Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `"StoP"` is not an anagram of `"sTOp"`. 10 | The words you need to find should be taken from the candidate words, using the same letter case. 11 | 12 | Given the target `"stone"` and the candidate words `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, and `"Seton"`, the anagram words you need to find are `"tones"`, `"notes"`, and `"Seton"`. 13 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | At a garage sale, you find a lovely vintage typewriter at a bargain price! 4 | Excitedly, you rush home, insert a sheet of paper, and start typing away. 5 | However, your excitement wanes when you examine the output: all words are garbled! 6 | For example, it prints "stop" instead of "post" and "least" instead of "stale." 7 | Carefully, you try again, but now it prints "spot" and "slate." 8 | After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. 9 | You now understand why they sold it for so little money! 10 | 11 | You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. 12 | Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. 13 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Gaelan" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "markijbema", 9 | "rootulp", 10 | "meatball133" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "anagram.coffee" 15 | ], 16 | "test": [ 17 | "anagram.spec.coffee" 18 | ], 19 | "example": [ 20 | ".meta/example.coffee" 21 | ] 22 | }, 23 | "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", 24 | "source": "Inspired by the Extreme Startup game", 25 | "source_url": "https://github.com/rchatley/extreme_startup" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Anagram 2 | constructor: (source) -> 3 | @source = source 4 | 5 | match: (targets) -> 6 | (target for target in targets when areAnagrams(@source, target.toLowerCase())) 7 | 8 | areAnagrams = (word1, word2) -> 9 | return false if word1.toLowerCase() == word2.toLowerCase() 10 | 11 | standardForm(word1) == standardForm(word2) 12 | 13 | standardForm = (word) -> 14 | word.toLowerCase().split("").sort().join() 15 | 16 | module.exports = Anagram 17 | -------------------------------------------------------------------------------- /exercises/practice/anagram/anagram.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | 3 | class Anagram 4 | constructor: (source) -> 5 | 6 | match: (targets) -> 7 | 8 | module.exports = Anagram 9 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits. 4 | 5 | For example: 6 | 7 | - 9 is an Armstrong number, because `9 = 9^1 = 9` 8 | - 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1` 9 | - 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153` 10 | - 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190` 11 | 12 | Write some code to determine whether a number is an Armstrong number. 13 | 14 | [armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number 15 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "armstrong-numbers.coffee" 8 | ], 9 | "test": [ 10 | "armstrong-numbers.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Determine if a number is an Armstrong number.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ArmstrongNumbers 2 | @isArmstrongNumber: (number) -> 3 | digits = number.toString().split '' 4 | total = digits.reduce (sum, digit) -> 5 | sum + Math.pow digit, digits.length 6 | , 0 7 | 8 | total == number 9 | 10 | module.exports = ArmstrongNumbers 11 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/armstrong-numbers.coffee: -------------------------------------------------------------------------------- 1 | class ArmstrongNumbers 2 | @isArmstrongNumber: (number) -> 3 | 4 | module.exports = ArmstrongNumbers 5 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wvmitchell", 4 | "meatball133" 5 | ], 6 | "contributors": [ 7 | "aimorris", 8 | "kytrinyx", 9 | "rootulp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "atbash-cipher.coffee" 14 | ], 15 | "test": [ 16 | "atbash-cipher.spec.coffee" 17 | ], 18 | "example": [ 19 | ".meta/example.coffee" 20 | ] 21 | }, 22 | "blurb": "Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.", 23 | "source": "Wikipedia", 24 | "source_url": "https://en.wikipedia.org/wiki/Atbash" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Atbash 2 | @encode: (phrase) -> 3 | phrase = phrase.toLowerCase().replace /[^a-z0-9]/g, '' 4 | phrase = phrase.replace /[a-z]/g, (letter) -> 5 | String.fromCharCode 219 - letter.charCodeAt() 6 | phrase.replace(/(.{5})/g, "$1 ").trim() 7 | 8 | 9 | @decode: (phrase) -> 10 | phrase = phrase.replaceAll(" ", "") 11 | phrase.replace /[a-z]/g, (letter) -> 12 | String.fromCharCode 219 - letter.charCodeAt() 13 | 14 | module.exports = Atbash 15 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/atbash-cipher.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | 3 | class AtbashCipher 4 | @encode: (phrase) -> 5 | 6 | @decode: (phrase) -> 7 | 8 | module.exports = AtbashCipher 9 | -------------------------------------------------------------------------------- /exercises/practice/bank-account/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # ignore 2 | 3 | ## CoffeeScript-specific Instructions 4 | 5 | For this exercise, we will not be testing parallelism. 6 | Your task is to implement the BankAccount methods without worrying about parallel execution. 7 | -------------------------------------------------------------------------------- /exercises/practice/bank-account/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to implement bank accounts supporting opening/closing, withdrawals, and deposits of money. 4 | 5 | As bank accounts can be accessed in many different ways (internet, mobile phones, automatic charges), your bank software must allow accounts to be safely accessed from multiple threads/processes (terminology depends on your programming language) in parallel. 6 | For example, there may be many deposits and withdrawals occurring in parallel; you need to ensure there are no [race conditions][wikipedia] between when you read the account balance and set the new balance. 7 | 8 | It should be possible to close an account; operations against a closed account must fail. 9 | 10 | [wikipedia]: https://en.wikipedia.org/wiki/Race_condition#In_software 11 | -------------------------------------------------------------------------------- /exercises/practice/bank-account/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bank-account.coffee" 8 | ], 9 | "test": [ 10 | "bank-account.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Simulate a bank account supporting opening/closing, withdraws, and deposits of money. Watch out for concurrent transactions!" 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/bank-account/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class BankAccount 2 | constructor: -> 3 | @_open = false 4 | 5 | open: -> 6 | throw Error 'account already open' if @_open 7 | @_open = true 8 | @_balance = 0 9 | 10 | close: -> 11 | throw Error 'account not open' unless @_open 12 | @_open = false 13 | 14 | balance: -> 15 | throw Error 'account not open' unless @_open 16 | @_balance 17 | 18 | deposit: (money) -> 19 | throw Error 'account not open' unless @_open 20 | throw Error "amount must be greater than 0" unless money > 0 21 | @_balance += money 22 | 23 | withdraw: (money) -> 24 | throw Error 'account not open' unless @_open 25 | throw Error "amount must be greater than 0" unless money > 0 26 | throw Error "amount must be less than balance" unless money <= @_balance 27 | @_balance -= money 28 | 29 | module.exports = BankAccount 30 | -------------------------------------------------------------------------------- /exercises/practice/bank-account/bank-account.coffee: -------------------------------------------------------------------------------- 1 | class BankAccount 2 | constructor: (args) -> 3 | 4 | open: () -> 5 | 6 | close: () -> 7 | 8 | balance: () -> 9 | 10 | deposit: (args) -> 11 | 12 | withdraw: (args) -> 13 | 14 | module.exports = BankAccount 15 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Gaelan" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "rootulp" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "beer-song.coffee" 13 | ], 14 | "test": [ 15 | "beer-song.spec.coffee" 16 | ], 17 | "example": [ 18 | ".meta/example.coffee" 19 | ] 20 | }, 21 | "blurb": "Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.", 22 | "source": "Learn to Program by Chris Pine", 23 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Beer 2 | verse: (num) -> 3 | switch num # Not breaking because of return. 4 | when 0 then " 5 | No more bottles of beer on the wall, no more bottles of beer. 6 | Go to the store and buy some more, 99 bottles of beer on the wall. 7 | " 8 | else " 9 | #{ bottles(num) } of beer on the wall, #{ bottles(num) } of beer. 10 | Take #{ one(num) } down and pass it around, #{ bottles(num - 1) } of beer on the wall. 11 | " 12 | 13 | sing: (start, end = 0) -> 14 | (@verse(num) for num in [start..end]).join " " 15 | 16 | 17 | bottles = (num) -> 18 | switch num 19 | when 0 then "no more bottles" 20 | when 1 then "1 bottle" 21 | else "#{num} bottles" 22 | 23 | one = (num) -> 24 | switch num # Not breaking because of return. 25 | when 1 then "it" 26 | else "one" 27 | 28 | module.exports = Beer 29 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/beer-song.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | 3 | class BeerSong 4 | verse: (args) -> 5 | 6 | sing: (args) -> 7 | 8 | module.exports = BeerSong 9 | -------------------------------------------------------------------------------- /exercises/practice/binary-search-tree/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # ignore 2 | 3 | ## CoffeeScript specific instructions 4 | 5 | A BinarySearchTree instance must have 3 properties: `data`, `left` and `right`. 6 | 7 | An instance must have these methods: 8 | 9 | * `insert` which adds a new piece of data to the tree. This will add a new "leaf" node somewhere in the tree. 10 | * `each` that takes a "callback" argument. That is a function that will be called on _each piece of data_ in the tree **in order**. 11 | 12 | This exercise is a great place to practice **recursion**. 13 | -------------------------------------------------------------------------------- /exercises/practice/binary-search-tree/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "Gaelan", 6 | "kytrinyx", 7 | "marocchino", 8 | "rootulp", 9 | "shidel-dev" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "binary-search-tree.coffee" 14 | ], 15 | "test": [ 16 | "binary-search-tree.spec.coffee" 17 | ], 18 | "example": [ 19 | ".meta/example.coffee" 20 | ] 21 | }, 22 | "blurb": "Insert and search for numbers in a binary tree.", 23 | "source": "Josh Cheek" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/binary-search-tree/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class BinarySearchTree 2 | 3 | constructor: (@data) -> 4 | @left = undefined 5 | @right = undefined 6 | 7 | insert: (value) -> 8 | if value <= @data 9 | @insertLeft value 10 | else 11 | @insertRight value 12 | 13 | insertLeft: (value) -> 14 | if not @left 15 | @left = new BinarySearchTree value 16 | else 17 | @left.insert value 18 | 19 | insertRight: (value) -> 20 | if not @right 21 | @right = new BinarySearchTree value 22 | else 23 | @right.insert value 24 | 25 | each: (fn) -> 26 | @left.each(fn) if @left 27 | fn.call @, @data 28 | @right.each(fn) if @right 29 | 30 | -------------------------------------------------------------------------------- /exercises/practice/binary-search-tree/binary-search-tree.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | class BinarySearchTree 3 | constructor: (args) -> 4 | 5 | insert: (args) -> 6 | 7 | each: (callback) -> 8 | 9 | module.exports = BinarySearchTree 10 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You have stumbled upon a group of mathematicians who are also singer-songwriters. 4 | They have written a song for each of their favorite numbers, and, as you can imagine, they have a lot of favorite numbers (like [0][zero] or [73][seventy-three] or [6174][kaprekars-constant]). 5 | 6 | You are curious to hear the song for your favorite number, but with so many songs to wade through, finding the right song could take a while. 7 | Fortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about. 8 | 9 | You realize that you can use a binary search algorithm to quickly find a song given the title. 10 | 11 | [zero]: https://en.wikipedia.org/wiki/0 12 | [seventy-three]: https://en.wikipedia.org/wiki/73_(number) 13 | [kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number) 14 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary-search.coffee" 8 | ], 9 | "test": [ 10 | "binary-search.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ], 15 | "editor": [ 16 | "traced-array.coffee" 17 | ] 18 | }, 19 | "blurb": "Implement a binary search algorithm.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class BinarySearch 2 | constructor: (@array) -> 3 | 4 | find: (value) -> 5 | start = 0 6 | end = @array.length - 1 7 | while start <= end 8 | mid = (start + end) // 2 9 | item = @array.get mid 10 | if value == item 11 | return mid 12 | else if value <= item 13 | end = mid - 1 14 | else if value >= item 15 | start = mid + 1 16 | 17 | throw new Error 'value not in array' 18 | 19 | module.exports = BinarySearch -------------------------------------------------------------------------------- /exercises/practice/binary-search/binary-search.coffee: -------------------------------------------------------------------------------- 1 | class BinarySearch 2 | constructor: (array) -> 3 | 4 | find: (value) -> 5 | 6 | module.exports = BinarySearch 7 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/traced-array.coffee: -------------------------------------------------------------------------------- 1 | class TracedArray 2 | constructor: (values...) -> 3 | data = values 4 | @accessCount = 0 5 | 6 | @get = (index) => 7 | @accessCount += 1 8 | data[index] 9 | 10 | Object.defineProperty @, 'length', 11 | get: -> data.length 12 | 13 | module.exports = TracedArray 14 | -------------------------------------------------------------------------------- /exercises/practice/binary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "hpurmann", 6 | "kytrinyx", 7 | "markijbema", 8 | "marocchino", 9 | "rootulp", 10 | "shidel-dev" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "binary.coffee" 15 | ], 16 | "test": [ 17 | "binary.spec.coffee" 18 | ], 19 | "example": [ 20 | ".meta/example.coffee" 21 | ] 22 | }, 23 | "blurb": "Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.", 24 | "source": "All of Computer Science", 25 | "source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/binary/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Binary 2 | 3 | constructor: (binary) -> @binary = parseInt binary, 2 4 | 5 | toDecimal: -> 6 | out = Number @binary.toString 10 7 | return 0 if isNaN out 8 | out 9 | -------------------------------------------------------------------------------- /exercises/practice/binary/binary.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | 3 | class Binary 4 | constructor: (args) -> 5 | 6 | toDecimal: -> 7 | 8 | module.exports = Binary 9 | -------------------------------------------------------------------------------- /exercises/practice/binary/binary.spec.coffee: -------------------------------------------------------------------------------- 1 | Binary = require './binary' 2 | 3 | describe 'binary', -> 4 | 5 | it '1 is decimal 1', -> 6 | expect(new Binary('1').toDecimal()).toEqual 1 7 | 8 | xit '10 is decimal 2', -> 9 | expect(new Binary('10').toDecimal()).toEqual 2 10 | 11 | xit '11 is decimal 3', -> 12 | expect(new Binary('11').toDecimal()).toEqual 3 13 | 14 | xit '100 is decimal 4', -> 15 | expect(new Binary('100').toDecimal()).toEqual 4 16 | 17 | xit '1001 is decimal 9', -> 18 | expect(new Binary('1001').toDecimal()).toEqual 9 19 | 20 | xit '11010 is decimal 26', -> 21 | expect(new Binary('11010').toDecimal()).toEqual 26 22 | 23 | xit '10001101000 is decimal 1128', -> 24 | expect(new Binary('10001101000').toDecimal()).toEqual 1128 25 | 26 | xit 'carrot is decimal 0', -> 27 | expect(new Binary('carrot').toDecimal()).toEqual 0 28 | 29 | xit 'numeric but non-binary string is decimal 0', -> 30 | expect(new Binary('42').toDecimal()).toEqual 0 31 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine what Bob will reply to someone when they say something to him or ask him a question. 4 | 5 | Bob only ever answers one of five things: 6 | 7 | - **"Sure."** 8 | This is his response if you ask him a question, such as "How are you?" 9 | The convention used for questions is that it ends with a question mark. 10 | - **"Whoa, chill out!"** 11 | This is his answer if you YELL AT HIM. 12 | The convention used for yelling is ALL CAPITAL LETTERS. 13 | - **"Calm down, I know what I'm doing!"** 14 | This is what he says if you yell a question at him. 15 | - **"Fine. Be that way!"** 16 | This is how he responds to silence. 17 | The convention used for silence is nothing, or various combinations of whitespace characters. 18 | - **"Whatever."** 19 | This is what he answers to anything else. 20 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Bob is a [lackadaisical][] teenager. 4 | He likes to think that he's very cool. 5 | And he definitely doesn't get excited about things. 6 | That wouldn't be cool. 7 | 8 | When people talk to him, his responses are pretty limited. 9 | 10 | [lackadaisical]: https://www.collinsdictionary.com/dictionary/english/lackadaisical 11 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Gaelan" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "austinlyons", 8 | "bistik", 9 | "kytrinyx", 10 | "lorenzleutgeb", 11 | "rootulp" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "bob.coffee" 16 | ], 17 | "test": [ 18 | "bob.spec.coffee" 19 | ], 20 | "example": [ 21 | ".meta/example.coffee" 22 | ] 23 | }, 24 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 25 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 26 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Bob 2 | hey: (message) -> 3 | message = message.trim() 4 | switch 5 | when message == "" then "Fine. Be that way!" 6 | when message.match(/[a-zA-Z]/) and message == message.toUpperCase() and message[message.length - 1] == "?" then "Calm down, I know what I'm doing!" 7 | when message.match(/[a-zA-Z]/) and message == message.toUpperCase() then "Whoa, chill out!" 8 | when message[message.length - 1] == "?" then "Sure." 9 | else "Whatever." 10 | module.exports = Bob 11 | -------------------------------------------------------------------------------- /exercises/practice/bob/bob.coffee: -------------------------------------------------------------------------------- 1 | class Bob 2 | hey: (message) -> 3 | 4 | module.exports = Bob 5 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bottle-song.coffee" 8 | ], 9 | "test": [ 10 | "bottle-song.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/bottle-song.coffee: -------------------------------------------------------------------------------- 1 | class BottleSong 2 | recite: (start, end) -> 3 | 4 | module.exports = BottleSong 5 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "circular-buffer.coffee" 8 | ], 9 | "test": [ 10 | "circular-buffer.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "A data structure that uses a single, fixed-size buffer as if it were connected end-to-end.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Circular_buffer" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class CircularBuffer 2 | constructor: (@capacity) -> 3 | @data = [] 4 | 5 | write: (value) -> 6 | if @data.length == @capacity 7 | throw new Error "full buffer" 8 | @data.push value 9 | 10 | read: () -> 11 | if !@data.length 12 | throw new Error "empty buffer" 13 | [head, @data...] = @data 14 | head 15 | 16 | overwrite: (value) -> 17 | if @data.length == @capacity 18 | @read() 19 | @write value 20 | 21 | clear: () -> 22 | @data = [] 23 | 24 | module.exports = CircularBuffer 25 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/circular-buffer.coffee: -------------------------------------------------------------------------------- 1 | class CircularBuffer 2 | constructor: (capacity) -> 3 | 4 | write: (value) -> 5 | 6 | read: () -> 7 | 8 | overwrite: (value) -> 9 | 10 | clear: () -> 11 | 12 | module.exports = CircularBuffer 13 | -------------------------------------------------------------------------------- /exercises/practice/clock/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement a clock that handles times without dates. 4 | 5 | You should be able to add and subtract minutes to it. 6 | 7 | Two clocks that represent the same time should be equal to each other. 8 | -------------------------------------------------------------------------------- /exercises/practice/clock/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wvmitchell" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "rootulp" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "clock.coffee" 13 | ], 14 | "test": [ 15 | "clock.spec.coffee" 16 | ], 17 | "example": [ 18 | ".meta/example.coffee" 19 | ] 20 | }, 21 | "blurb": "Implement a clock that handles times without dates.", 22 | "source": "Pairing session with Erin Drummond" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/clock/clock.coffee: -------------------------------------------------------------------------------- 1 | class Clock 2 | 3 | 4 | module.exports = Clock 5 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a positive integer, return the number of steps it takes to reach 1 according to the rules of the Collatz Conjecture. 4 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "collatz-conjecture.coffee" 8 | ], 9 | "test": [ 10 | "collatz-conjecture.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Collatz_conjecture" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class CollatzConjecture 2 | @steps: (number) -> 3 | if number <= 0 4 | throw new Error('Only positive integers are allowed') 5 | 6 | step = 0 7 | while number > 1 8 | if number % 2 == 0 9 | number /= 2 10 | else 11 | number = 3 * number + 1 12 | step += 1 13 | step 14 | 15 | module.exports = CollatzConjecture 16 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.coffee: -------------------------------------------------------------------------------- 1 | class CollatzConjecture 2 | @steps: (number) -> 3 | 4 | module.exports = CollatzConjecture 5 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.spec.coffee: -------------------------------------------------------------------------------- 1 | CollatzConjecture = require './collatz-conjecture' 2 | 3 | describe 'Collatz Conjecture', -> 4 | it 'zero steps for one', -> 5 | result = CollatzConjecture.steps 1 6 | expect(result).toEqual 0 7 | 8 | xit 'divide if even', -> 9 | result = CollatzConjecture.steps 16 10 | expect(result).toEqual 4 11 | 12 | xit 'even and odd steps', -> 13 | result = CollatzConjecture.steps 12 14 | expect(result).toEqual 9 15 | 16 | xit 'large number of even and odd steps', -> 17 | result = CollatzConjecture.steps 1000000 18 | expect(result).toEqual 152 19 | 20 | xit 'zero is an error', -> 21 | expect -> 22 | CollatzConjecture.steps 0 23 | .toThrow new Error "Only positive integers are allowed" 24 | 25 | xit 'negative value is an error', -> 26 | expect -> 27 | CollatzConjecture.steps -15 28 | .toThrow new Error "Only positive integers are allowed" 29 | -------------------------------------------------------------------------------- /exercises/practice/custom-set/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Create a custom set type. 4 | 5 | Sometimes it is necessary to define a custom data structure of some type, like a set. 6 | In this exercise you will define your own set. 7 | How it works internally doesn't matter, as long as it behaves like a set of unique elements. 8 | -------------------------------------------------------------------------------- /exercises/practice/custom-set/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "custom-set.coffee" 8 | ], 9 | "test": [ 10 | "custom-set.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Create a custom set type." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/custom-set/custom-set.coffee: -------------------------------------------------------------------------------- 1 | class CustomSet 2 | constructor: (values) -> 3 | 4 | empty: -> 5 | 6 | contains: (value) -> 7 | 8 | subset: (other) -> 9 | 10 | disjoint: (other) -> 11 | 12 | equal: (other) -> 13 | 14 | add: (value) -> 15 | 16 | intersection: (other) -> 17 | 18 | difference: (other) -> 19 | 20 | union: (other) -> 21 | 22 | module.exports = CustomSet 23 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "darts.coffee" 8 | ], 9 | "test": [ 10 | "darts.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Calculate the points scored in a single toss of a Darts game.", 17 | "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Darts 2 | @score: (x, y) -> 3 | distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) 4 | if distance <= 1 5 | 10 6 | else if distance <= 5 7 | 5 8 | else if distance <= 10 9 | 1 10 | else 11 | 0 12 | 13 | module.exports = Darts 14 | -------------------------------------------------------------------------------- /exercises/practice/darts/darts.coffee: -------------------------------------------------------------------------------- 1 | class Darts 2 | @score: (x, y) -> 3 | 4 | module.exports = Darts 5 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "diamond.coffee" 8 | ], 9 | "test": [ 10 | "diamond.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.", 17 | "source": "Seb Rose", 18 | "source_url": "https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Diamond 2 | @rows: (letter) -> 3 | return 'A' if letter is 'A' 4 | 5 | start = 'A'.charCodeAt 0 6 | end = letter.charCodeAt 0 7 | size = end - start + 1 8 | diamond = [] 9 | 10 | # Down to middle of diamond 11 | for i in [0...size] 12 | currentChar = String.fromCharCode start + i 13 | outer = ' '.repeat size - 1 - i 14 | if i is 0 15 | line = outer + currentChar + outer 16 | else 17 | inner = ' '.repeat 2 * i - 1 18 | line = outer + currentChar + inner + currentChar + outer 19 | diamond.push line 20 | 21 | # flip the diamond to make the bottom half 22 | for i in [size-2..0] 23 | diamond.push diamond[i] 24 | 25 | diamond.join '\n' 26 | 27 | module.exports = Diamond 28 | -------------------------------------------------------------------------------- /exercises/practice/diamond/diamond.coffee: -------------------------------------------------------------------------------- 1 | class Diamond 2 | @rows: (letter) -> 3 | 4 | module.exports = Diamond 5 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. 4 | 5 | The square of the sum of the first ten natural numbers is 6 | (1 + 2 + ... + 10)² = 55² = 3025. 7 | 8 | The sum of the squares of the first ten natural numbers is 9 | 1² + 2² + ... + 10² = 385. 10 | 11 | Hence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is 3025 - 385 = 2640. 12 | 13 | You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. 14 | Finding the best algorithm for the problem is a key skill in software engineering. 15 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "difference-of-squares.coffee" 8 | ], 9 | "test": [ 10 | "difference-of-squares.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 17 | "source": "Problem 6 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=6" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class DifferenceOfSquares 2 | @squareOfSum: (number) -> 3 | sum = [1..number].reduce ((acc, n) -> acc + n), 0 4 | Math.pow sum, 2 5 | 6 | @sumOfSquares: (number) -> 7 | [1..number].reduce ((acc, n) -> acc + Math.pow n, 2), 0 8 | 9 | @differenceOfSquares: (number) -> 10 | (@squareOfSum number) - (@sumOfSquares number) 11 | 12 | module.exports = DifferenceOfSquares 13 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.coffee: -------------------------------------------------------------------------------- 1 | class DifferenceOfSquares 2 | @squareOfSum: (number) -> 3 | 4 | @sumOfSquares: (number) -> 5 | 6 | @differenceOfSquares: (number) -> 7 | 8 | module.exports = DifferenceOfSquares 9 | -------------------------------------------------------------------------------- /exercises/practice/dnd-character/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | After weeks of anticipation, you and your friends get together for your very first game of [Dungeons & Dragons][dnd] (D&D). 4 | Since this is the first session of the game, each player has to generate a character to play with. 5 | The character's abilities are determined by rolling 6-sided dice, but where _are_ the dice? 6 | With a shock, you realize that your friends are waiting for _you_ to produce the dice; after all it was your idea to play D&D! 7 | Panicking, you realize you forgot to bring the dice, which would mean no D&D game. 8 | As you have some basic coding skills, you quickly come up with a solution: you'll write a program to simulate dice rolls. 9 | 10 | [dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons 11 | -------------------------------------------------------------------------------- /exercises/practice/dnd-character/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "dnd-character.coffee" 8 | ], 9 | "test": [ 10 | "dnd-character.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Randomly generate Dungeons & Dragons characters.", 17 | "source": "Simon Shine, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/dnd-character/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class DndCharacter 2 | constructor: () -> 3 | @strength = @ability() 4 | @dexterity = @ability() 5 | @constitution = @ability() 6 | @intelligence = @ability() 7 | @wisdom = @ability() 8 | @charisma = @ability() 9 | @hitpoints = 10 + @modifier @constitution 10 | 11 | modifier: (score) -> 12 | (score - 10) // 2 13 | 14 | ability: () -> 15 | rolls = [0,0,0,0] 16 | .map((a) -> Math.floor(Math.random() * 6) + 1) 17 | .sort((a, b) -> a - b)[1..] 18 | .reduce((a, b) -> a + b) 19 | 20 | module.exports = DndCharacter 21 | -------------------------------------------------------------------------------- /exercises/practice/dnd-character/dnd-character.coffee: -------------------------------------------------------------------------------- 1 | class DndCharacter 2 | constructor: -> 3 | 4 | modifier: (score) -> 5 | 6 | ability: -> 7 | 8 | module.exports = DndCharacter 9 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to count the number of 1 bits in the binary representation of a number. 4 | 5 | ## Restrictions 6 | 7 | Keep your hands off that bit-count functionality provided by your standard library! 8 | Solve this one yourself using other basic tools instead. 9 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "eliuds-eggs.coffee" 8 | ], 9 | "test": [ 10 | "eliuds-eggs.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.", 17 | "source": "Christian Willner, Eric Willigers", 18 | "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class EliudsEggs 2 | @eggCount: (displayValue) -> 3 | eggs = 0 4 | while displayValue != 0 5 | eggs += displayValue % 2 6 | displayValue //= 2 7 | eggs 8 | 9 | module.exports = EliudsEggs 10 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [559e789d-07d1-4422-9004-3b699f83bca3] 13 | description = "0 eggs" 14 | 15 | [97223282-f71e-490c-92f0-b3ec9e275aba] 16 | description = "1 egg" 17 | 18 | [1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5] 19 | description = "4 eggs" 20 | 21 | [0c18be92-a498-4ef2-bcbb-28ac4b06cb81] 22 | description = "13 eggs" 23 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/eliuds-eggs.coffee: -------------------------------------------------------------------------------- 1 | class EliudsEggs 2 | @eggCount: (displayValue) -> 3 | 4 | module.exports = EliudsEggs 5 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/eliuds-eggs.spec.coffee: -------------------------------------------------------------------------------- 1 | EliudsEggs = require './eliuds-eggs' 2 | 3 | describe "Eliud's Eggs", -> 4 | it '0 eggs', -> 5 | result = EliudsEggs.eggCount 0 6 | expect(result).toEqual 0 7 | 8 | xit '1 egg', -> 9 | result = EliudsEggs.eggCount 16 10 | expect(result).toEqual 1 11 | 12 | xit '4 eggs', -> 13 | result = EliudsEggs.eggCount 89 14 | expect(result).toEqual 4 15 | 16 | xit '13 eggs', -> 17 | result = EliudsEggs.eggCount 2000000000 18 | expect(result).toEqual 13 -------------------------------------------------------------------------------- /exercises/practice/etl/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to change the data format of letters and their point values in the game. 4 | 5 | Currently, letters are stored in groups based on their score, in a one-to-many mapping. 6 | 7 | - 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T", 8 | - 2 points: "D", "G", 9 | - 3 points: "B", "C", "M", "P", 10 | - 4 points: "F", "H", "V", "W", "Y", 11 | - 5 points: "K", 12 | - 8 points: "J", "X", 13 | - 10 points: "Q", "Z", 14 | 15 | This needs to be changed to store each individual letter with its score in a one-to-one mapping. 16 | 17 | - "a" is worth 1 point. 18 | - "b" is worth 3 points. 19 | - "c" is worth 3 points. 20 | - "d" is worth 2 points. 21 | - etc. 22 | 23 | As part of this change, the team has also decided to change the letters to be lower-case rather than upper-case. 24 | 25 | ~~~~exercism/note 26 | If you want to look at how the data was previously structured and how it needs to change, take a look at the examples in the test suite. 27 | ~~~~ 28 | -------------------------------------------------------------------------------- /exercises/practice/etl/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that makes an online multiplayer game called Lexiconia. 4 | 5 | To play the game, each player is given 13 letters, which they must rearrange to create words. 6 | Different letters have different point values, since it's easier to create words with some letters than others. 7 | 8 | The game was originally launched in English, but it is very popular, and now the company wants to expand to other languages as well. 9 | 10 | Different languages need to support different point values for letters. 11 | The point values are determined by how often letters are used, compared to other letters in that language. 12 | 13 | For example, the letter 'C' is quite common in English, and is only worth 3 points. 14 | But in Norwegian it's a very rare letter, and is worth 10 points. 15 | 16 | To make it easier to add new languages, your team needs to change the way letters and their point values are stored in the game. 17 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "etl.coffee" 8 | ], 9 | "test": [ 10 | "etl.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Change the data format for scoring a game to more easily add other languages.", 17 | "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Etl 2 | @transform: (legacy) -> 3 | results = {} 4 | for score, letters of legacy 5 | for letter in letters 6 | results[letter.toLowerCase()] = +score 7 | results 8 | 9 | module.exports = Etl 10 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [78a7a9f9-4490-4a47-8ee9-5a38bb47d28f] 13 | description = "single letter" 14 | 15 | [60dbd000-451d-44c7-bdbb-97c73ac1f497] 16 | description = "single score with multiple letters" 17 | 18 | [f5c5de0c-301f-4fdd-a0e5-df97d4214f54] 19 | description = "multiple scores with multiple letters" 20 | 21 | [5db8ea89-ecb4-4dcd-902f-2b418cc87b9d] 22 | description = "multiple scores with differing numbers of letters" 23 | -------------------------------------------------------------------------------- /exercises/practice/etl/etl.coffee: -------------------------------------------------------------------------------- 1 | class Etl 2 | @transform: (legacy) -> 3 | 4 | module.exports = Etl 5 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Take a nested array of any depth and return a fully flattened array. 4 | 5 | Note that some language tracks may include null-like values in the input array, and the way these values are represented varies by track. 6 | Such values should be excluded from the flattened array. 7 | 8 | Additionally, the input may be of a different data type and contain different types, depending on the track. 9 | 10 | Check the test suite for details. 11 | 12 | ## Example 13 | 14 | input: `[1, [2, 6, null], [[null, [4]], 5]]` 15 | 16 | output: `[1, 2, 6, 4, 5]` 17 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A shipment of emergency supplies has arrived, but there's a problem. 4 | To protect from damage, the items — flashlights, first-aid kits, blankets — are packed inside boxes, and some of those boxes are nested several layers deep inside other boxes! 5 | 6 | To be prepared for an emergency, everything must be easily accessible in one box. 7 | Can you unpack all the supplies and place them into a single box, so they're ready when needed most? 8 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "flatten-array.coffee" 8 | ], 9 | "test": [ 10 | "flatten-array.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Take a nested list and return a single list with all values except nil/null.", 17 | "source": "Interview Question", 18 | "source_url": "https://reference.wolfram.com/language/ref/Flatten.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class FlattenArray 2 | @flatten: (values) -> 3 | values.filter (value) -> value != null and value != undefined 4 | .reduce (flattened, value) -> 5 | if Array.isArray value 6 | flattened.concat FlattenArray.flatten value 7 | else 8 | flattened.concat value 9 | , [] 10 | 11 | module.exports = FlattenArray 12 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/flatten-array.coffee: -------------------------------------------------------------------------------- 1 | class FlattenArray 2 | @flatten: (values) -> 3 | 4 | module.exports = FlattenArray 5 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "food-chain.coffee" 8 | ], 9 | "test": [ 10 | "food-chain.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/food-chain.coffee: -------------------------------------------------------------------------------- 1 | class FoodChain 2 | @recite: (startVerse, endVerse) -> 3 | 4 | module.exports = FoodChain 5 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | After each generation, the cells interact with their eight neighbors, which are cells adjacent horizontally, vertically, or diagonally. 4 | 5 | The following rules are applied to each cell: 6 | 7 | - Any live cell with two or three live neighbors lives on. 8 | - Any dead cell with exactly three live neighbors becomes a live cell. 9 | - All other cells die or stay dead. 10 | 11 | Given a matrix of 1s and 0s (corresponding to live and dead cells), apply the rules to each cell, and return the next generation. 12 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Conway's Game of Life][game-of-life] is a fascinating cellular automaton created by the British mathematician John Horton Conway in 1970. 4 | 5 | The game consists of a two-dimensional grid of cells that can either be "alive" or "dead." 6 | 7 | After each generation, the cells interact with their eight neighbors via a set of rules, which define the new generation. 8 | 9 | [game-of-life]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life 10 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "game-of-life.coffee" 8 | ], 9 | "test": [ 10 | "game-of-life.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Implement Conway's Game of Life.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/game-of-life.coffee: -------------------------------------------------------------------------------- 1 | class GameOfLife 2 | constructor: (matrix) -> 3 | 4 | tick: () -> 5 | 6 | module.exports = GameOfLife 7 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine the date and time one gigasecond after a certain date. 4 | 5 | A gigasecond is one thousand million seconds. 6 | That is a one with nine zeros after it. 7 | 8 | If you were born on _January 24th, 2015 at 22:00 (10:00:00pm)_, then you would be a gigasecond old on _October 2nd, 2046 at 23:46:40 (11:46:40pm)_. 9 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "gigasecond.coffee" 8 | ], 9 | "test": [ 10 | "gigasecond.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", 17 | "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=09" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | GIGASECOND_LENGTH = 1e9 2 | 3 | class Gigasecond 4 | @add: (moment) -> 5 | new Date(moment.getTime() + (GIGASECOND_LENGTH * 1e3)) 6 | 7 | module.exports = Gigasecond 8 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/gigasecond.coffee: -------------------------------------------------------------------------------- 1 | class Gigasecond 2 | @add: (moment) -> 3 | 4 | module.exports = Gigasecond 5 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grade-school.coffee" 8 | ], 9 | "test": [ 10 | "grade-school.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given students' names along with the grade that they are in, create a roster for the school.", 17 | "source": "A pairing session with Phil Battos at gSchool" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class GradeSchool 2 | constructor: () -> 3 | @students = {} 4 | 5 | add: (student, level) -> 6 | if @students[student] 7 | false 8 | else 9 | @students[student] = level 10 | true 11 | 12 | grade: (level) -> 13 | result = [] 14 | for student, grade of @students 15 | if grade is level 16 | result.push student 17 | result.sort() 18 | 19 | roster: () -> 20 | result = [] 21 | grades = (g for _, g of @students).sort() 22 | for g in grades.unique() 23 | result.push (@grade g)... 24 | result 25 | 26 | Array::unique = -> 27 | output = {} 28 | output[@[key]] = @[key] for key in [0...@length] 29 | value for key, value of output 30 | 31 | module.exports = GradeSchool 32 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/grade-school.coffee: -------------------------------------------------------------------------------- 1 | class GradeSchool 2 | constructor: () -> 3 | 4 | add: (student, level) -> 5 | 6 | grade: (level) -> 7 | 8 | roster: () -> 9 | 10 | module.exports = GradeSchool 11 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the number of grains of wheat on a chessboard. 4 | 5 | A chessboard has 64 squares. 6 | Square 1 has one grain, square 2 has two grains, square 3 has four grains, and so on, doubling each time. 7 | 8 | Write code that calculates: 9 | 10 | - the number of grains on a given square 11 | - the total number of grains on the chessboard 12 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | There once was a wise servant who saved the life of a prince. 4 | The king promised to pay whatever the servant could dream up. 5 | Knowing that the king loved chess, the servant told the king he would like to have grains of wheat. 6 | One grain on the first square of a chessboard, with the number of grains doubling on each successive square. 7 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grains.coffee" 8 | ], 9 | "test": [ 10 | "grains.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", 17 | "source": "The CodeRanch Cattle Drive, Assignment 6", 18 | "source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Grains 2 | @square: (number) -> 3 | if number not in [1..64] 4 | throw 'square must be between 1 and 64' 5 | 6 | Math.pow(2, number - 1) 7 | 8 | @total: () -> 9 | Math.pow(2, 64) - 1 10 | module.exports = Grains 11 | -------------------------------------------------------------------------------- /exercises/practice/grains/grains.coffee: -------------------------------------------------------------------------------- 1 | class Grains 2 | @square: (number) -> 3 | 4 | @total: () -> 5 | 6 | module.exports = Grains 7 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the Hamming distance between two DNA strands. 4 | 5 | We read DNA using the letters C, A, G and T. 6 | Two strands might look like this: 7 | 8 | GAGCCTACTAACGGGAT 9 | CATCGTAATGACGGCCT 10 | ^ ^ ^ ^ ^ ^^ 11 | 12 | They have 7 differences, and therefore the Hamming distance is 7. 13 | 14 | ## Implementation notes 15 | 16 | The Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work. 17 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your body is made up of cells that contain DNA. 4 | Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. 5 | In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime! 6 | 7 | When cells divide, their DNA replicates too. 8 | Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. 9 | If we compare two strands of DNA and count the differences between them, we can see how many mistakes occurred. 10 | This is known as the "Hamming distance". 11 | 12 | The Hamming distance is useful in many areas of science, not just biology, so it's a nice phrase to be familiar with :) 13 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hamming.coffee" 8 | ], 9 | "test": [ 10 | "hamming.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Calculate the Hamming distance between two DNA strands.", 17 | "source": "The Calculating Point Mutations problem at Rosalind", 18 | "source_url": "https://rosalind.info/problems/hamm/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Hamming 2 | @distance: (strand1, strand2) -> 3 | if strand1.length != strand2.length 4 | throw new Error "strands must be of equal length" 5 | 6 | strand1.split("") 7 | .filter (elem, i) -> elem != strand2[i] 8 | .length 9 | 10 | module.exports = Hamming 11 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.coffee: -------------------------------------------------------------------------------- 1 | class Hamming 2 | @distance: (strand1, strand2) -> 3 | 4 | module.exports = Hamming 5 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | The classical introductory exercise. 4 | Just say "Hello, World!". 5 | 6 | ["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment. 7 | 8 | The objectives are simple: 9 | 10 | - Modify the provided code so that it produces the string "Hello, World!". 11 | - Run the test suite and make sure that it succeeds. 12 | - Submit your solution and check it at the website. 13 | 14 | If everything goes well, you will be ready to fetch your first real exercise. 15 | 16 | [hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program 17 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "ramonh" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "rootulp", 9 | "skeskali", 10 | "son1112" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "hello-world.coffee" 15 | ], 16 | "test": [ 17 | "hello-world.spec.coffee" 18 | ], 19 | "example": [ 20 | ".meta/example.coffee" 21 | ] 22 | }, 23 | "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", 24 | "source": "This is an exercise to introduce users to using Exercism", 25 | "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class HelloWorld 2 | hello: -> 'Hello, World!' 3 | 4 | module.exports = HelloWorld 5 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [af9ffe10-dc13-42d8-a742-e7bdafac449d] 13 | description = "Say Hi!" 14 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.coffee: -------------------------------------------------------------------------------- 1 | class HelloWorld 2 | hello: -> 'Goodbye, Mars!' 3 | 4 | module.exports = HelloWorld 5 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.spec.coffee: -------------------------------------------------------------------------------- 1 | HelloWorld = require './hello-world' 2 | 3 | describe 'HelloWorld', -> 4 | hello_world = new HelloWorld() 5 | 6 | it "says 'Hello, World!'", -> 7 | result = hello_world.hello() 8 | expect(result).toEqual 'Hello, World!' 9 | -------------------------------------------------------------------------------- /exercises/practice/hexadecimal/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a hexadecimal number, represented as a string (e.g. "10af8c"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion). 4 | 5 | On the web we use hexadecimal to represent colors, e.g. green: 008000, teal: 008080, navy: 000080). 6 | 7 | The program should handle invalid hexadecimal strings. 8 | -------------------------------------------------------------------------------- /exercises/practice/hexadecimal/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kytrinyx" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "alxndr", 8 | "marocchino", 9 | "rootulp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "hexadecimal.coffee" 14 | ], 15 | "test": [ 16 | "hexadecimal.spec.coffee" 17 | ], 18 | "example": [ 19 | ".meta/example.coffee" 20 | ] 21 | }, 22 | "blurb": "Convert a hexadecimal number, represented as a string (e.g. \"10af8c\"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).", 23 | "source": "All of Computer Science", 24 | "source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/hexadecimal/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Hexadecimal 2 | constructor: (hex) -> 3 | @hex = hex 4 | 5 | toDecimal: -> 6 | for char in this.hex.split("") 7 | return 0 if /[^0-9a-fA-F]/.exec(char) 8 | 9 | parseInt(this.hex,16) 10 | -------------------------------------------------------------------------------- /exercises/practice/hexadecimal/hexadecimal.coffee: -------------------------------------------------------------------------------- 1 | # This is a stub file for the CoffeeScript track 2 | class Hexadecimal 3 | constructor: (args) -> 4 | 5 | toDecimal: (args) -> 6 | 7 | module.exports = Hexadecimal 8 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Manage a game player's High Score list. 4 | 5 | Your task is to build a high-score component of the classic Frogger game, one of the highest selling and most addictive games of all time, and a classic of the arcade era. 6 | Your task is to write methods that return the highest score from the list, the last added score and the three highest scores. 7 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "high-scores.coffee" 8 | ], 9 | "test": [ 10 | "high-scores.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Manage a player's High Score list.", 17 | "source": "Tribute to the eighties' arcade game Frogger" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class HighScores 2 | constructor: (@scores) -> 3 | 4 | latest: () -> 5 | @scores[@scores.length - 1] 6 | 7 | personalBest: () -> 8 | Math.max.apply null, @scores 9 | 10 | personalTopThree: () -> 11 | @scores.slice() 12 | .sort((a, b) => b - a) 13 | .slice 0, 3 14 | 15 | module.exports = HighScores 16 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/high-scores.coffee: -------------------------------------------------------------------------------- 1 | class HighScores 2 | constructor: (scores) -> 3 | 4 | latest: () -> 5 | 6 | personalBest: () -> 7 | 8 | personalTopThree: () -> 9 | 10 | module.exports = HighScores 11 | -------------------------------------------------------------------------------- /exercises/practice/house/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "house.coffee" 8 | ], 9 | "test": [ 10 | "house.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Output the nursery rhyme 'This is the House that Jack Built'.", 17 | "source": "British nursery rhyme", 18 | "source_url": "https://en.wikipedia.org/wiki/This_Is_The_House_That_Jack_Built" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/house/house.coffee: -------------------------------------------------------------------------------- 1 | class House 2 | 3 | @verse: (number) -> 4 | 5 | @verses: (startVerse, endVerse) -> 6 | 7 | module.exports = House -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isbn-verifier.coffee" 8 | ], 9 | "test": [ 10 | "isbn-verifier.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Check if a given string is a valid ISBN-10 number.", 17 | "source": "Converting a string into a number and some basic processing utilizing a relatable real world example.", 18 | "source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class IsbnVerifier 2 | @isValid: (isbn) -> 3 | digits = isbn.replace /-/g, '' 4 | return false if digits.length != 10 5 | 6 | sum = 0 7 | for i in [0..9] 8 | digit = digits[i] 9 | if digit == 'X' 10 | return false if i != 9 11 | digit = 10 12 | return false if /\D/.test digit 13 | 14 | sum += digit * (10 - i) 15 | sum % 11 == 0 16 | 17 | module.exports = IsbnVerifier 18 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/isbn-verifier.coffee: -------------------------------------------------------------------------------- 1 | class IsbnVerifier 2 | @isValid: (isbn) -> 3 | 4 | module.exports = IsbnVerifier 5 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a word or phrase is an isogram. 4 | 5 | An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times. 6 | 7 | Examples of isograms: 8 | 9 | - lumberjacks 10 | - background 11 | - downstream 12 | - six-year-old 13 | 14 | The word _isograms_, however, is not an isogram, because the s repeats. 15 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isogram.coffee" 8 | ], 9 | "test": [ 10 | "isogram.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Determine if a word or phrase is an isogram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Isogram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Isogram 2 | @isIsogram: (phrase) -> 3 | seen = {} 4 | for char in phrase.toLowerCase() 5 | cp = char.charCodeAt(0) 6 | if cp >= 97 && cp <= 122 7 | if char of seen 8 | return false 9 | 10 | seen[char] = true 11 | true 12 | 13 | module.exports = Isogram 14 | -------------------------------------------------------------------------------- /exercises/practice/isogram/isogram.coffee: -------------------------------------------------------------------------------- 1 | class Isogram 2 | @isIsogram: (phrase) -> 3 | 4 | module.exports = Isogram 5 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The kindergarten class is learning about growing plants. 4 | The teacher thought it would be a good idea to give the class seeds to plant and grow in the dirt. 5 | To this end, the children have put little cups along the window sills and planted one type of plant in each cup. 6 | The children got to pick their favorites from four available types of seeds: grass, clover, radishes, and violets. 7 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "kindergarten-garden.coffee" 8 | ], 9 | "test": [ 10 | "kindergarten-garden.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a diagram, determine which plants each child in the kindergarten class is responsible for.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class KindergartenGarden 2 | constructor: (diagram) -> 3 | @diagram = diagram.split('\n').map (row) -> 4 | row.split('').map (code) -> 5 | codes[code] 6 | 7 | @plots = {} 8 | students.forEach (student, index) => 9 | @plots[student] = @diagram.map (row) -> 10 | plants = [] 11 | position = 2 * index; 12 | plants.push row[position] 13 | plants.push row[position + 1] 14 | plants 15 | 16 | plants: (student) -> 17 | @plots[student].flat() 18 | 19 | students = [ 20 | 'Alice', 21 | 'Bob', 22 | 'Charlie', 23 | 'David', 24 | 'Eve', 25 | 'Fred', 26 | 'Ginny', 27 | 'Harriet', 28 | 'Ileana', 29 | 'Joseph', 30 | 'Kincaid', 31 | 'Larry' 32 | ] 33 | 34 | codes = { 35 | 'G': 'grass', 36 | 'C': 'clover', 37 | 'R': 'radishes', 38 | 'V': 'violets' 39 | } 40 | 41 | module.exports = KindergartenGarden 42 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/kindergarten-garden.coffee: -------------------------------------------------------------------------------- 1 | class KindergartenGarden 2 | constructor: (diagram) -> 3 | 4 | plants: (student) -> 5 | 6 | module.exports = KindergartenGarden 7 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine which items to take so that the total value of her selection is maximized, taking into account the knapsack's carrying capacity. 4 | 5 | Items will be represented as a list of items. 6 | Each item will have a weight and value. 7 | All values given will be strictly positive. 8 | Lhakpa can take only one of each item. 9 | 10 | For example: 11 | 12 | ```text 13 | Items: [ 14 | { "weight": 5, "value": 10 }, 15 | { "weight": 4, "value": 40 }, 16 | { "weight": 6, "value": 30 }, 17 | { "weight": 4, "value": 50 } 18 | ] 19 | 20 | Knapsack Maximum Weight: 10 21 | ``` 22 | 23 | For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on. 24 | In this example, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90. 25 | She cannot get more than 90 as her knapsack has a weight limit of 10. 26 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Lhakpa is a [Sherpa][sherpa] mountain guide and porter. 4 | After months of careful planning, the expedition Lhakpa works for is about to leave. 5 | She will be paid the value she carried to the base camp. 6 | 7 | In front of her are many items, each with a value and weight. 8 | Lhakpa would gladly take all of the items, but her knapsack can only hold so much weight. 9 | 10 | [sherpa]: https://en.wikipedia.org/wiki/Sherpa_people#Mountaineering 11 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "knapsack.coffee" 8 | ], 9 | "test": [ 10 | "knapsack.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a knapsack that can only carry a certain weight, determine which items to put in the knapsack in order to maximize their combined value.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Knapsack_problem" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | # Algorithm taken from Wikipedia: https://en.wikipedia.org/wiki/Knapsack_problem 2 | 3 | class Knapsack 4 | @maximumValue: ({maximumWeight, items}) -> 5 | return 0 if items.length is 0 6 | 7 | m = Array.from({length: items.length + 1}, -> new Array(maximumWeight + 1)) 8 | m[0].fill 0 9 | 10 | for i in [1 .. items.length] 11 | {weight, value} = items[i - 1] 12 | for w in [0 .. maximumWeight] 13 | if weight > w 14 | m[i][w] = m[i - 1][w] 15 | else 16 | m[i][w] = Math.max m[i - 1][w], m[i - 1][w - weight] + value 17 | 18 | m[items.length][maximumWeight] 19 | 20 | module.exports = Knapsack 21 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/knapsack.coffee: -------------------------------------------------------------------------------- 1 | class Knapsack 2 | @maximumValue: (args) -> 3 | 4 | module.exports = Knapsack 5 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a government agency that has intercepted a series of encrypted communication signals from a group of bank robbers. 4 | The signals contain a long sequence of digits. 5 | Your team needs to use various digital signal processing techniques to analyze the signals and identify any patterns that may indicate the planning of a heist. 6 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "largest-series-product.coffee" 8 | ], 9 | "test": [ 10 | "largest-series-product.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.", 17 | "source": "A variation on Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class LargestSeriesProduct 2 | @largestProduct: (digits, span) -> 3 | if span < 0 4 | throw new Error 'span must not be negative' 5 | if span > digits.length 6 | throw new Error 'span must not exceed string length' 7 | if digits.match(/[^0-9]/) 8 | throw new Error 'digits input must only contain digits' 9 | 10 | max = 0 11 | for i in [0...digits.length - span + 1] 12 | product = 1 13 | for j in [0...span] 14 | product *= Number digits[i + j] 15 | if product > max 16 | max = product 17 | max 18 | 19 | module.exports = LargestSeriesProduct 20 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/largest-series-product.coffee: -------------------------------------------------------------------------------- 1 | class LargestSeriesProduct 2 | @largestProduct: (digits, span) -> 3 | 4 | module.exports = LargestSeriesProduct 5 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine whether a given year is a leap year. 4 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A leap year (in the Gregorian calendar) occurs: 4 | 5 | - In every year that is evenly divisible by 4. 6 | - Unless the year is evenly divisible by 100, in which case it's only a leap year if the year is also evenly divisible by 400. 7 | 8 | Some examples: 9 | 10 | - 1997 was not a leap year as it's not divisible by 4. 11 | - 1900 was not a leap year as it's not divisible by 400. 12 | - 2000 was a leap year! 13 | 14 | ~~~~exercism/note 15 | For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE). 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "leap.coffee" 8 | ], 9 | "test": [ 10 | "leap.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Determine whether a given year is a leap year.", 17 | "source": "CodeRanch Cattle Drive, Assignment 3", 18 | "source_url": "https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Leap 2 | @leapYear: (year) -> 3 | year % 4 == 0 && (!(year % 100 == 0) || year % 400 == 0) 4 | module.exports = Leap 5 | -------------------------------------------------------------------------------- /exercises/practice/leap/leap.coffee: -------------------------------------------------------------------------------- 1 | class Leap 2 | @leapYear: (year) -> 3 | 4 | module.exports = Leap 5 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You are working on a project to develop a train scheduling system for a busy railway network. 4 | 5 | You've been asked to develop a prototype for the train routes in the scheduling system. 6 | Each route consists of a sequence of train stations that a given train stops at. 7 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "kytrinyx", 6 | "rootulp" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "linked-list.coffee" 11 | ], 12 | "test": [ 13 | "linked-list.spec.coffee" 14 | ], 15 | "example": [ 16 | ".meta/example.coffee" 17 | ] 18 | }, 19 | "blurb": "Implement a doubly linked list.", 20 | "source": "Classic computer science topic" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/linked-list.coffee: -------------------------------------------------------------------------------- 1 | class LinkedList 2 | count: -> 3 | 4 | pushNode: (args) -> 5 | 6 | popNode: (args) -> 7 | 8 | deleteNode: (args) -> 9 | 10 | shiftNode: (args) -> 11 | 12 | unshiftNode: (args) -> 13 | 14 | countNodes: -> 15 | 16 | 17 | module.exports = LinkedList 18 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "list-ops.coffee" 8 | ], 9 | "test": [ 10 | "list-ops.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Implement basic list operations." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ListOps 2 | @append: (list1, list2) -> 3 | @concat([list1, list2]) 4 | 5 | @concat: (lists) -> 6 | results = [] 7 | for list in lists 8 | for elt in list 9 | results.push elt 10 | results 11 | 12 | @filter: (list, f) -> 13 | (elt for elt in list when f(elt)) 14 | 15 | @mylength: (list) -> 16 | fn = (acc, _) -> acc + 1 17 | @foldl(list, fn, 0) 18 | 19 | @map: (list, fn) -> 20 | (fn(elt) for elt in list) 21 | 22 | @foldl: (list, fn, initial) -> 23 | results = initial 24 | for elt in list 25 | results = fn(results, elt) 26 | results 27 | 28 | @foldr: (list, fn, initial) -> 29 | if list.length == 0 30 | initial 31 | else 32 | last = list.pop() 33 | @foldr(list, fn, fn(initial, last)) 34 | 35 | @reverse: (list) -> 36 | if list.length == 0 37 | list 38 | else 39 | start = list.length - 1 40 | (list[i] for i in [start..0]) 41 | 42 | module.exports = ListOps 43 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/list-ops.coffee: -------------------------------------------------------------------------------- 1 | class ListOps 2 | @append: (list1, list2) -> 3 | 4 | @concat: (lists) -> 5 | 6 | @filter: (list, f) -> 7 | 8 | @mylength: (list) -> 9 | 10 | @map: (list, fn) -> 11 | 12 | @foldl: (list, fn, initial) -> 13 | 14 | @foldr: (list, fn, initial) -> 15 | 16 | @reverse: (list) -> 17 | 18 | module.exports = ListOps 19 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | At the Global Verification Authority, you've just been entrusted with a critical assignment. 4 | Across the city, from online purchases to secure logins, countless operations rely on the accuracy of numerical identifiers like credit card numbers, bank account numbers, transaction codes, and tracking IDs. 5 | The Luhn algorithm is a simple checksum formula used to help identify mistyped numbers. 6 | 7 | A batch of identifiers has just arrived on your desk. 8 | All of them must pass the Luhn test to ensure they're legitimate. 9 | If any fail, they'll be flagged as invalid, preventing mistakes such as incorrect transactions or failed account verifications. 10 | 11 | Can you ensure this is done right? The integrity of many services depends on you. 12 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kytrinyx" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "alxndr", 8 | "marocchino", 9 | "meientau", 10 | "rootulp", 11 | "meatball133" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "luhn.coffee" 16 | ], 17 | "test": [ 18 | "luhn.spec.coffee" 19 | ], 20 | "example": [ 21 | ".meta/example.coffee" 22 | ] 23 | }, 24 | "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", 25 | "source": "The Luhn Algorithm on Wikipedia", 26 | "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Luhn 2 | constructor: (@num) -> 3 | 4 | valid: -> 5 | @num = @num.replace /\s+/g, '' 6 | return false if @num.length < 2 7 | return false if @num.match /\D/ 8 | sum = 0 9 | for digit, i in @num.split('').reverse() 10 | digit = parseInt digit 11 | if i % 2 == 1 12 | digit *= 2 13 | digit -= 9 if digit > 9 14 | sum += digit 15 | sum % 10 == 0 16 | 17 | module.exports = Luhn 18 | -------------------------------------------------------------------------------- /exercises/practice/luhn/luhn.coffee: -------------------------------------------------------------------------------- 1 | class Luhn 2 | constructor: (args) -> 3 | 4 | valid: -> 5 | 6 | 7 | module.exports = Luhn 8 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. 4 | Any other characters should be ignored. 5 | For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. 6 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. 4 | The software that runs on it is written in a proprietary language. 5 | Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. 6 | Despite the Bracketeer™ being powerful, it lacks flexibility. 7 | If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. 8 | To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. 9 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matching-brackets.coffee" 8 | ], 9 | "test": [ 10 | "matching-brackets.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Make sure the brackets and braces all match.", 17 | "source": "Ginna Baker" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class MatchingBrackets 2 | @isPaired: (value) -> 3 | stack = [] 4 | for char in value 5 | if char in ['[', '{', '('] 6 | stack.push char 7 | else if char in [']', '}', ')'] 8 | return false if stack.length is 0 9 | 10 | last = stack.pop() 11 | return false if last == '[' and char != ']' 12 | return false if last == '{' and char != '}' 13 | return false if last == '(' and char != ')' 14 | 15 | stack.length == 0 16 | 17 | 18 | module.exports = MatchingBrackets 19 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/matching-brackets.coffee: -------------------------------------------------------------------------------- 1 | class MatchingBrackets 2 | @isPaired: (value) -> 3 | 4 | module.exports = MatchingBrackets 5 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string representing a matrix of numbers, return the rows and columns of that matrix. 4 | 5 | So given a string with embedded newlines like: 6 | 7 | ```text 8 | 9 8 7 9 | 5 3 2 10 | 6 6 7 11 | ``` 12 | 13 | representing this matrix: 14 | 15 | ```text 16 | 1 2 3 17 | |--------- 18 | 1 | 9 8 7 19 | 2 | 5 3 2 20 | 3 | 6 6 7 21 | ``` 22 | 23 | your code should be able to spit out: 24 | 25 | - A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows, 26 | - A list of the columns, reading each column top-to-bottom while moving from left-to-right. 27 | 28 | The rows for our example matrix: 29 | 30 | - 9, 8, 7 31 | - 5, 3, 2 32 | - 6, 6, 7 33 | 34 | And its columns: 35 | 36 | - 9, 5, 6 37 | - 8, 3, 6 38 | - 7, 2, 7 39 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matrix.coffee" 8 | ], 9 | "test": [ 10 | "matrix.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a string representing a matrix of numbers, return the rows and columns of that matrix.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Matrix 2 | constructor: (description) -> 3 | @rows = description.split("\n").map (row) -> 4 | row.split(" ").map (number) -> +number 5 | 6 | row: (index) -> 7 | @rows[index - 1] 8 | 9 | column: (index) -> 10 | @rows.map (row) -> row[index - 1] 11 | 12 | module.exports = Matrix 13 | -------------------------------------------------------------------------------- /exercises/practice/matrix/matrix.coffee: -------------------------------------------------------------------------------- 1 | class Matrix 2 | constructor: (description) -> 3 | 4 | row: (index) -> 5 | 6 | column: (index) -> 7 | 8 | module.exports = Matrix 9 | -------------------------------------------------------------------------------- /exercises/practice/meetup/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "meetup.coffee" 8 | ], 9 | "test": [ 10 | "meetup.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Calculate the date of meetups.", 17 | "source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/meetup/meetup.coffee: -------------------------------------------------------------------------------- 1 | # TODO fill in these objects with the needed properties 2 | Weeks = {} 3 | Weekdays = {} 4 | 5 | meetup(args) -> 6 | 7 | module.exports = {Weeks, Weekdays, meetup} 8 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "micro-blog.coffee" 8 | ], 9 | "test": [ 10 | "micro-blog.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given an input string, truncate it to 5 characters." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Microblog 2 | @truncate: (phrase) -> 3 | Array.from phrase 4 | .slice 0, 5 5 | .join '' 6 | 7 | module.exports = Microblog 8 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/micro-blog.coffee: -------------------------------------------------------------------------------- 1 | class Microblog 2 | @truncate: (phrase) -> 3 | 4 | module.exports = Microblog 5 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to add the mine counts to empty squares in a completed Minesweeper board. 4 | The board itself is a rectangle composed of squares that are either empty (`' '`) or a mine (`'*'`). 5 | 6 | For each empty square, count the number of mines adjacent to it (horizontally, vertically, diagonally). 7 | If the empty square has no adjacent mines, leave it empty. 8 | Otherwise replace it with the adjacent mines count. 9 | 10 | For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): 11 | 12 | ```text 13 | ·*·*· 14 | ··*·· 15 | ··*·· 16 | ····· 17 | ``` 18 | 19 | Which your code should transform into this: 20 | 21 | ```text 22 | 1*3*1 23 | 13*31 24 | ·2*2· 25 | ·111· 26 | ``` 27 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Minesweeper][wikipedia] is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square. 4 | 5 | [wikipedia]: https://en.wikipedia.org/wiki/Minesweeper_(video_game) 6 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "minesweeper.coffee" 8 | ], 9 | "test": [ 10 | "minesweeper.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Add the numbers to a minesweeper board." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Minesweeper 2 | @annotate: (minefield) -> 3 | if minefield.length < 1 4 | return minefield 5 | if minefield[0].length < 1 6 | return minefield 7 | 8 | board = minefield.map (row) -> row.split '' 9 | 10 | board.map (row, x) -> 11 | r = row.map (cell, y) -> 12 | if cell == '*' 13 | return cell 14 | count = 0 15 | for i in [-1..1] 16 | for j in [-1..1] 17 | if i + x >= 0 && i + x < board.length && j + y >= 0 && j + y < row.length 18 | count += 1 if board[i + x][j + y] == '*' 19 | if count == 0 20 | ' ' 21 | else 22 | count.toString() 23 | r.join '' 24 | 25 | module.exports = Minesweeper 26 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/minesweeper.coffee: -------------------------------------------------------------------------------- 1 | class Minesweeper 2 | @annotate: (minefield) -> 3 | 4 | module.exports = Minesweeper 5 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a number n, determine what the nth prime is. 4 | 5 | By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 6 | 7 | If your language provides methods in the standard library to deal with prime numbers, pretend they don't exist and implement them yourself. 8 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kytrinyx" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "alxndr", 8 | "marocchino", 9 | "rootulp", 10 | "zvkemp" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "nth-prime.coffee" 15 | ], 16 | "test": [ 17 | "nth-prime.spec.coffee" 18 | ], 19 | "example": [ 20 | ".meta/example.coffee" 21 | ] 22 | }, 23 | "blurb": "Given a number n, determine what the nth prime is.", 24 | "source": "A variation on Problem 7 at Project Euler", 25 | "source_url": "https://projecteuler.net/problem=7" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Prime 2 | @nth: (nthPrime) -> 3 | throw "Prime is not possible" if nthPrime == 0 4 | @generatePrimes(200000) 5 | @realPrimes[nthPrime - 1] 6 | 7 | @generatePrimes: (uptoNumber) -> 8 | return @realPrimes if @realPrimes 9 | 10 | possiblePrimes = [] 11 | 12 | for numberValue in [2..uptoNumber] 13 | possiblePrimes.push({ number: numberValue, prime: true }) 14 | 15 | for number in [2..Math.sqrt(possiblePrimes.length)] 16 | for currentPrime in possiblePrimes 17 | if currentPrime.number != number && currentPrime.number % number == 0 18 | currentPrime.prime = false 19 | 20 | primeCount = 0 21 | 22 | @realPrimes = possiblePrimes.filter (possiblePrime) -> possiblePrime.prime 23 | @realPrimes = @realPrimes.map (prime) -> prime.number 24 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [75c65189-8aef-471a-81de-0a90c728160c] 13 | description = "first prime" 14 | 15 | [2c38804c-295f-4701-b728-56dea34fd1a0] 16 | description = "second prime" 17 | 18 | [56692534-781e-4e8c-b1f9-3e82c1640259] 19 | description = "sixth prime" 20 | 21 | [fce1e979-0edb-412d-93aa-2c744e8f50ff] 22 | description = "big prime" 23 | 24 | [bd0a9eae-6df7-485b-a144-80e13c7d55b2] 25 | description = "there is no zeroth prime" 26 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/nth-prime.coffee: -------------------------------------------------------------------------------- 1 | class NthPrime 2 | @nth: (nthPrime) -> 3 | 4 | module.exports = NthPrime 5 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/nth-prime.spec.coffee: -------------------------------------------------------------------------------- 1 | Prime = require './nth-prime' 2 | 3 | describe 'Prime', -> 4 | 5 | it 'first prime', -> 6 | prime = Prime.nth(1) 7 | expect(prime).toEqual(2) 8 | 9 | xit 'second prime', -> 10 | prime = Prime.nth(2) 11 | expect(prime).toEqual(3) 12 | 13 | xit 'sixth prime', -> 14 | prime = Prime.nth(6) 15 | expect(prime).toEqual(13) 16 | 17 | xit 'big prime', -> 18 | prime = Prime.nth(10001) 19 | expect(prime).toEqual(104743) 20 | 21 | xit 'there is no zeroth prime', -> 22 | expect(-> Prime.nth(0)).toThrow('Prime is not possible') 23 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "songawee" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "rootulp", 9 | "sjakobi" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "nucleotide-count.coffee" 14 | ], 15 | "test": [ 16 | "nucleotide-count.spec.coffee" 17 | ], 18 | "example": [ 19 | ".meta/example.coffee" 20 | ] 21 | }, 22 | "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", 23 | "source": "The Calculating DNA Nucleotides_problem at Rosalind", 24 | "source_url": "https://rosalind.info/problems/dna/" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class DNA 2 | constructor: (@strand) -> 3 | @nucleotideCounts = 4 | A: @value 'A' 5 | T: @value 'T' 6 | C: @value 'C' 7 | G: @value 'G' 8 | 9 | value: (nucleotide) -> 10 | throw new Error('Invalid nucleotide strand') if (@strand.split("").some (n) -> not (['A', 'T', 'C', 'G'].includes(n))) 11 | @strand.split(nucleotide).length - 1 12 | 13 | count: (nucleotide) -> 14 | throw new Error('Invalid nucleotide') unless @nucleotideCounts.hasOwnProperty(nucleotide) 15 | @nucleotideCounts[nucleotide] 16 | 17 | module.exports = DNA 18 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/nucleotide-count.coffee: -------------------------------------------------------------------------------- 1 | class NucleotideCount 2 | constructor: (args) -> 3 | @nucleotideCounts = 4 | 5 | count: (args) -> 6 | 7 | module.exports = NucleotideCount 8 | -------------------------------------------------------------------------------- /exercises/practice/palindrome-products/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kytrinyx" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "alxndr", 8 | "fluxusfrequency", 9 | "marocchino", 10 | "meientau", 11 | "rootulp", 12 | "meatball133" 13 | ], 14 | "files": { 15 | "solution": [ 16 | "palindrome-products.coffee" 17 | ], 18 | "test": [ 19 | "palindrome-products.spec.coffee" 20 | ], 21 | "example": [ 22 | ".meta/example.coffee" 23 | ] 24 | }, 25 | "blurb": "Detect palindrome products in a given range.", 26 | "source": "Problem 4 at Project Euler", 27 | "source_url": "https://projecteuler.net/problem=4" 28 | } 29 | -------------------------------------------------------------------------------- /exercises/practice/palindrome-products/palindrome-products.coffee: -------------------------------------------------------------------------------- 1 | class PalindromeProducts 2 | constructor: (args) -> 3 | 4 | smallest: -> 5 | 6 | largest: -> 7 | 8 | module.exports = PalindromeProducts 9 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to figure out if a sentence is a pangram. 4 | 5 | A pangram is a sentence using every letter of the alphabet at least once. 6 | It is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`). 7 | 8 | For this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet. 9 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that sells fonts through their website. 4 | They'd like to show a different sentence each time someone views a font on their website. 5 | To give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet. 6 | 7 | They're running a competition to get suggestions for sentences that they can use. 8 | You're in charge of checking the submissions to see if they are valid. 9 | 10 | ~~~~exercism/note 11 | Pangram comes from Greek, παν γράμμα, pan gramma, which means "every letter". 12 | 13 | The best known English pangram is: 14 | 15 | > The quick brown fox jumps over the lazy dog. 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pangram.coffee" 8 | ], 9 | "test": [ 10 | "pangram.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Determine if a sentence is a pangram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Pangram 2 | @isPangram: (sentence) -> 3 | letters = new Set(sentence.replace(/[^a-z]+/gi, '').toLowerCase().split "") 4 | letters.size == 26 5 | 6 | module.exports = Pangram 7 | -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.coffee: -------------------------------------------------------------------------------- 1 | class Pangram 2 | @isPangram: (sentence) -> 3 | 4 | module.exports = Pangram 5 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "kytrinyx", 6 | "rootulp" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "pascals-triangle.coffee" 11 | ], 12 | "test": [ 13 | "pascals-triangle.spec.coffee" 14 | ], 15 | "example": [ 16 | ".meta/example.coffee" 17 | ] 18 | }, 19 | "blurb": "Compute Pascal's triangle up to a given number of rows.", 20 | "source": "Pascal's Triangle at Wolfram Math World", 21 | "source_url": "https://www.wolframalpha.com/input/?i=Pascal%27s+triangle" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class PascalsTriangle 2 | rows: (num) -> 3 | triangle = [] 4 | for i in [0...num] 5 | triangle[i] = [] 6 | for j in [0..i] 7 | triangle[i][j] = if j == 0 or j == i then 1 else triangle[i-1][j-1] + triangle[i-1][j] 8 | triangle 9 | 10 | 11 | module.exports = PascalsTriangle 12 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/pascals-triangle.coffee: -------------------------------------------------------------------------------- 1 | class PascalsTriangle 2 | rows: (num) -> 3 | 4 | module.exports = PascalsTriangle 5 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "perfect-numbers.coffee" 8 | ], 9 | "test": [ 10 | "perfect-numbers.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.", 17 | "source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.", 18 | "source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class PerfectNumbers 2 | @classify: (number) -> 3 | if number <= 0 4 | throw new Error 'Classification is only possible for positive integers.' 5 | 6 | sum = 0 7 | for i in [1...number] 8 | if number % i == 0 9 | sum += i 10 | 11 | if sum < number 12 | 'deficient' 13 | else if sum > number 14 | 'abundant' 15 | else 16 | 'perfect' 17 | 18 | module.exports = PerfectNumbers 19 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/perfect-numbers.coffee: -------------------------------------------------------------------------------- 1 | class PerfectNumbers 2 | @classify: (number) -> 3 | 4 | module.exports = PerfectNumbers 5 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've joined LinkLine, a leading communications company working to ensure reliable connections for everyone. 4 | The team faces a big challenge: users submit phone numbers in all sorts of formats — dashes, spaces, dots, parentheses, and even prefixes. 5 | Some numbers are valid, while others are impossible to use. 6 | 7 | Your mission is to turn this chaos into order. 8 | You'll clean up valid numbers, formatting them appropriately for use in the system. 9 | At the same time, you'll identify and filter out any invalid entries. 10 | 11 | The success of LinkLine's operations depends on your ability to separate the useful from the unusable. 12 | Are you ready to take on the challenge and keep the connections running smoothly? 13 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "phone-number.coffee" 8 | ], 9 | "test": [ 10 | "phone-number.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/phone-number.coffee: -------------------------------------------------------------------------------- 1 | class PhoneNumber 2 | constructor: (number) -> 3 | 4 | clean: -> 5 | 6 | module.exports = PhoneNumber 7 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your parents have challenged you and your sibling to a game of two-on-two basketball. 4 | Confident they'll win, they let you score the first couple of points, but then start taking over the game. 5 | Needing a little boost, you start speaking in [Pig Latin][pig-latin], which is a made-up children's language that's difficult for non-children to understand. 6 | This will give you the edge to prevail over your parents! 7 | 8 | [pig-latin]: https://en.wikipedia.org/wiki/Pig_latin 9 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pig-latin.coffee" 8 | ], 9 | "test": [ 10 | "pig-latin.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Implement a program that translates from English to Pig Latin.", 17 | "source": "The Pig Latin exercise at Test First Teaching by Ultrasaurus", 18 | "source_url": "https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class PigLatin 2 | @translate: (phrase) -> 3 | phrase.split ' ' 4 | .map @translateWord 5 | .join ' ' 6 | 7 | @translateWord: (word) -> 8 | VOWEL_SOUND_REGEXP = /^([aeiou]|xr|yt)/; 9 | CONSONANT_SOUND_REGEXP = /^([^aeiou]+(?=y)|[^aeiou]?qu|[^aeiou]+)([a-z]+)/; 10 | if VOWEL_SOUND_REGEXP.test word 11 | "#{word}ay" 12 | else 13 | newWord = word.replace CONSONANT_SOUND_REGEXP, '$2$1' 14 | "#{newWord}ay" 15 | 16 | module.exports = PigLatin 17 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/pig-latin.coffee: -------------------------------------------------------------------------------- 1 | class PigLatin 2 | @translate: (phrase) -> 3 | 4 | module.exports = PigLatin 5 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Compute the prime factors of a given natural number. 4 | 5 | A prime number is only evenly divisible by itself and 1. 6 | 7 | Note that 1 is not a prime number. 8 | 9 | ## Example 10 | 11 | What are the prime factors of 60? 12 | 13 | - Our first divisor is 2. 14 | 2 goes into 60, leaving 30. 15 | - 2 goes into 30, leaving 15. 16 | - 2 doesn't go cleanly into 15. 17 | So let's move on to our next divisor, 3. 18 | - 3 goes cleanly into 15, leaving 5. 19 | - 3 does not go cleanly into 5. 20 | The next possible factor is 4. 21 | - 4 does not go cleanly into 5. 22 | The next possible factor is 5. 23 | - 5 does go cleanly into 5. 24 | - We're left only with 1, so now, we're done. 25 | 26 | Our successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5. 27 | 28 | You can check this yourself: 29 | 30 | ```text 31 | 2 * 2 * 3 * 5 32 | = 4 * 15 33 | = 60 34 | ``` 35 | 36 | Success! 37 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "prime-factors.coffee" 8 | ], 9 | "test": [ 10 | "prime-factors.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Compute the prime factors of a given natural number.", 17 | "source": "The Prime Factors Kata by Uncle Bob", 18 | "source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class PrimeFactors 2 | @factors: (value) -> 3 | factors = [] 4 | divisor = 2 5 | while value > 1 6 | while value % divisor == 0 7 | factors.push divisor 8 | value /= divisor 9 | divisor += 1 10 | factors 11 | 12 | module.exports = PrimeFactors 13 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/prime-factors.coffee: -------------------------------------------------------------------------------- 1 | class PrimeFactors 2 | @factors: (value) -> 3 | 4 | module.exports = PrimeFactors 5 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "protein-translation.coffee" 8 | ], 9 | "test": [ 10 | "protein-translation.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Translate RNA sequences into proteins.", 17 | "source": "Tyler Long" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/protein-translation.coffee: -------------------------------------------------------------------------------- 1 | class ProteinTranslation 2 | @proteins: (strand) -> 3 | 4 | module.exports = ProteinTranslation 5 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | For want of a horseshoe nail, a kingdom was lost, or so the saying goes. 4 | 5 | Given a list of inputs, generate the relevant proverb. 6 | For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme: 7 | 8 | ```text 9 | For want of a nail the shoe was lost. 10 | For want of a shoe the horse was lost. 11 | For want of a horse the rider was lost. 12 | For want of a rider the message was lost. 13 | For want of a message the battle was lost. 14 | For want of a battle the kingdom was lost. 15 | And all for the want of a nail. 16 | ``` 17 | 18 | Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. 19 | No line of the output text should be a static, unchanging string; all should vary according to the input given. 20 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "proverb.coffee" 8 | ], 9 | "test": [ 10 | "proverb.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/For_Want_of_a_Nail" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Proverb 2 | @recite: (items) -> 3 | if items.length == 0 4 | return "" 5 | proverb = "" 6 | for i in [0...items.length - 1] 7 | proverb += "For want of a #{items[i]} the #{items[i + 1]} was lost.\n" 8 | proverb += "And all for the want of a #{items[0]}." 9 | proverb 10 | 11 | module.exports = Proverb 12 | -------------------------------------------------------------------------------- /exercises/practice/proverb/proverb.coffee: -------------------------------------------------------------------------------- 1 | class Proverb 2 | @recite: (items) -> 3 | 4 | module.exports = Proverb 5 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kytrinyx", 4 | "meatball133" 5 | ], 6 | "contributors": [ 7 | "aimorris", 8 | "alxndr", 9 | "marocchino", 10 | "rootulp", 11 | "zvkemp" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "queen-attack.coffee" 16 | ], 17 | "test": [ 18 | "queen-attack.spec.coffee" 19 | ], 20 | "example": [ 21 | ".meta/example.coffee" 22 | ] 23 | }, 24 | "blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.", 25 | "source": "J Dalbey's Programming Practice problems", 26 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class QueensAttack 2 | constructor: (queen) -> 3 | throw "row not positive" if queen.row < 0 4 | throw "column not positive" if queen.column < 0 5 | throw "row not on board" if queen.row > 7 6 | throw "column not on board" if queen.column > 7 7 | @row = queen.row 8 | @column = queen.column 9 | 10 | canAttack: (otherQueen) -> 11 | sameRow = @row is otherQueen.row 12 | sameColumn = @column is otherQueen.column 13 | sameDiagonal = Math.abs(@row - otherQueen.row) is Math.abs(@column - otherQueen.column) 14 | sameRow or sameColumn or sameDiagonal 15 | 16 | module.exports = QueensAttack 17 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/queen-attack.coffee: -------------------------------------------------------------------------------- 1 | class QueenAttack 2 | constructor: (queen) -> 3 | 4 | canAttack: (otherQueen) -> 5 | 6 | module.exports = QueenAttack 7 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Raindrops is a slightly more complex version of the FizzBuzz challenge, a classic interview question. 4 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "raindrops.coffee" 8 | ], 9 | "test": [ 10 | "raindrops.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 17 | "source": "A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division.", 18 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Raindrops 2 | @convert: (number) -> 3 | results = '' 4 | if number % 3 == 0 5 | results += 'Pling' 6 | if number % 5 == 0 7 | results += 'Plang' 8 | if number % 7 == 0 9 | results += 'Plong' 10 | 11 | if !!results then results else number.toString() 12 | 13 | module.exports = Raindrops 14 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.coffee: -------------------------------------------------------------------------------- 1 | class Raindrops 2 | @convert: (number) -> 3 | 4 | module.exports = Raindrops 5 | -------------------------------------------------------------------------------- /exercises/practice/relative-distance/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've been hired to develop **Noble Knots**, the hottest new dating app for nobility! 4 | With centuries of royal intermarriage, things have gotten… _complicated_. 5 | To avoid any _oops-we're-twins_ situations, your job is to build a system that checks how closely two people are related. 6 | 7 | Noble Knots is inspired by Iceland's "[Islendinga-App][islendiga-app]," which is backed up by a database that traces all known family connections between Icelanders from the time of the settlement of Iceland. 8 | Your algorithm will determine the **degree of separation** between two individuals in the royal family tree. 9 | 10 | Will your app help crown a perfect match? 11 | 12 | [islendiga-app]: http://www.islendingaapp.is/information-in-english/ 13 | -------------------------------------------------------------------------------- /exercises/practice/relative-distance/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "relative-distance.coffee" 8 | ], 9 | "test": [ 10 | "relative-distance.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a family tree, calculate the degree of separation.", 17 | "source": "vaeng", 18 | "source_url": "https://github.com/exercism/problem-specifications/pull/2537" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/relative-distance/relative-distance.coffee: -------------------------------------------------------------------------------- 1 | class RelativeDistance 2 | @degreesOfSeparation: (familyTree, personA, personB) -> 3 | 4 | module.exports = RelativeDistance 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-duo.coffee" 8 | ], 9 | "test": [ 10 | "resistor-color-duo.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert color codes, as used on resistors, to a numeric value.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1464" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColorDuo 2 | @colorBands: [ 3 | "black" 4 | "brown" 5 | "red" 6 | "orange" 7 | "yellow" 8 | "green" 9 | "blue" 10 | "violet" 11 | "grey" 12 | "white" 13 | ] 14 | 15 | @value: ([first, second]) -> 16 | 10 * @colorBands.indexOf(first) + @colorBands.indexOf(second) 17 | 18 | module.exports = ResistorColorDuo 19 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/resistor-color-duo.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColorDuo 2 | @value: (colors) -> 3 | 4 | module.exports = ResistorColorDuo 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-trio.coffee" 8 | ], 9 | "test": [ 10 | "resistor-color-trio.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert color codes, as used on resistors, to a human-readable label.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1549" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColorTrio 2 | @label: ([tens, ones, exp]) -> 3 | value = (@colorBands.indexOf(ones) + 10 * @colorBands.indexOf(tens)) * 10 ** @colorBands.indexOf(exp) 4 | 5 | if value < 1e3 6 | "#{value} ohms" 7 | else if value < 1e6 8 | "#{value / 1e3} kiloohms" 9 | else if value < 1e9 10 | "#{value / 1e6} megaohms" 11 | else 12 | "#{value / 1e9} gigaohms" 13 | 14 | @colorBands: [ 15 | "black" 16 | "brown" 17 | "red" 18 | "orange" 19 | "yellow" 20 | "green" 21 | "blue" 22 | "violet" 23 | "grey" 24 | "white" 25 | ] 26 | 27 | module.exports = ResistorColorTrio 28 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/resistor-color-trio.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColorTrio 2 | @label: (colors) -> 3 | 4 | module.exports = ResistorColorTrio 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color.coffee" 8 | ], 9 | "test": [ 10 | "resistor-color.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert a resistor band's color to its numeric representation.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1458" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColor 2 | @colorBands: [ 3 | "black" 4 | "brown" 5 | "red" 6 | "orange" 7 | "yellow" 8 | "green" 9 | "blue" 10 | "violet" 11 | "grey" 12 | "white" 13 | ] 14 | 15 | @colorCode: (color) -> 16 | @colorBands.indexOf(color) 17 | 18 | @colors: () -> 19 | @colorBands 20 | 21 | module.exports = ResistorColor 22 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [49eb31c5-10a8-4180-9f7f-fea632ab87ef] 13 | description = "Color codes -> Black" 14 | 15 | [0a4df94b-92da-4579-a907-65040ce0b3fc] 16 | description = "Color codes -> White" 17 | 18 | [5f81608d-f36f-4190-8084-f45116b6f380] 19 | description = "Color codes -> Orange" 20 | 21 | [581d68fa-f968-4be2-9f9d-880f2fb73cf7] 22 | description = "Colors" 23 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/resistor-color.coffee: -------------------------------------------------------------------------------- 1 | class ResistorColor 2 | @colorCode: (color) -> 3 | 4 | @colors: () -> 5 | 6 | module.exports = ResistorColor 7 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/resistor-color.spec.coffee: -------------------------------------------------------------------------------- 1 | ResistorColor = require './resistor-color' 2 | 3 | describe 'ResistorColor', -> 4 | it 'Black', -> 5 | results = ResistorColor.colorCode('black') 6 | expected = 0 7 | expect(results).toEqual expected 8 | 9 | xit 'White', -> 10 | results = ResistorColor.colorCode('white') 11 | expected = 9 12 | expect(results).toEqual expected 13 | 14 | xit 'Orange', -> 15 | results = ResistorColor.colorCode('orange') 16 | expected = 3 17 | expect(results).toEqual expected 18 | 19 | xit 'Colors', -> 20 | results = ResistorColor.colors() 21 | expected = [ 22 | 'black' 23 | 'brown' 24 | 'red' 25 | 'orange' 26 | 'yellow' 27 | 'green' 28 | 'blue' 29 | 'violet' 30 | 'grey' 31 | 'white' 32 | ] 33 | expect(results).toEqual expected 34 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to reverse a given string. 4 | 5 | Some examples: 6 | 7 | - Turn `"stressed"` into `"desserts"`. 8 | - Turn `"strops"` into `"sports"`. 9 | - Turn `"racecar"` into `"racecar"`. 10 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Reversing strings (reading them from right to left, rather than from left to right) is a surprisingly common task in programming. 4 | 5 | For example, in bioinformatics, reversing the sequence of DNA or RNA strings is often important for various analyses, such as finding complementary strands or identifying palindromic sequences that have biological significance. 6 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "reverse-string.coffee" 8 | ], 9 | "test": [ 10 | "reverse-string.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Reverse a given string.", 17 | "source": "Introductory challenge to reverse an input string", 18 | "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ReverseString 2 | @reverse: (str) -> 3 | str.split("").reverse().join "" 4 | 5 | module.exports = ReverseString 6 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/reverse-string.coffee: -------------------------------------------------------------------------------- 1 | class ReverseString 2 | @reverse: (str) -> 3 | 4 | module.exports = ReverseString 5 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/reverse-string.spec.coffee: -------------------------------------------------------------------------------- 1 | ReverseString = require './reverse-string' 2 | 3 | describe 'ReverseString', -> 4 | it 'An empty string', -> 5 | reversed = ReverseString.reverse("") 6 | expect(reversed).toEqual("") 7 | 8 | xit 'A word', -> 9 | reversed = ReverseString.reverse("robot") 10 | expect(reversed).toEqual("tobor") 11 | 12 | xit 'A capitalized word', -> 13 | reversed = ReverseString.reverse("Ramen") 14 | expect(reversed).toEqual("nemaR") 15 | 16 | xit 'A sentence with punctuation', -> 17 | reversed = ReverseString.reverse("I'm hungry!") 18 | expect(reversed).toEqual("!yrgnuh m'I") 19 | 20 | xit 'A palindrome', -> 21 | reversed = ReverseString.reverse("racecar") 22 | expect(reversed).toEqual("racecar") 23 | 24 | xit 'An even-sized word', -> 25 | reversed = ReverseString.reverse("drawer") 26 | expect(reversed).toEqual("reward") 27 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine the RNA complement of a given DNA sequence. 4 | 5 | Both DNA and RNA strands are a sequence of nucleotides. 6 | 7 | The four nucleotides found in DNA are adenine (**A**), cytosine (**C**), guanine (**G**), and thymine (**T**). 8 | 9 | The four nucleotides found in RNA are adenine (**A**), cytosine (**C**), guanine (**G**), and uracil (**U**). 10 | 11 | Given a DNA strand, its transcribed RNA strand is formed by replacing each nucleotide with its complement: 12 | 13 | - `G` -> `C` 14 | - `C` -> `G` 15 | - `T` -> `A` 16 | - `A` -> `U` 17 | 18 | ~~~~exercism/note 19 | If you want to look at how the inputs and outputs are structured, take a look at the examples in the test suite. 20 | ~~~~ 21 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a bioengineering company that specializes in developing therapeutic solutions. 4 | 5 | Your team has just been given a new project to develop a targeted therapy for a rare type of cancer. 6 | 7 | ~~~~exercism/note 8 | It's all very complicated, but the basic idea is that sometimes people's bodies produce too much of a given protein. 9 | That can cause all sorts of havoc. 10 | 11 | But if you can create a very specific molecule (called a micro-RNA), it can prevent the protein from being produced. 12 | 13 | This technique is called [RNA Interference][rnai]. 14 | 15 | [rnai]: https://admin.acceleratingscience.com/ask-a-scientist/what-is-rnai/ 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rna-transcription.coffee" 8 | ], 9 | "test": [ 10 | "rna-transcription.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a DNA strand, return its RNA complement.", 17 | "source": "Hyperphysics", 18 | "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class RnaTranscription 2 | constructor: (@dna) -> 3 | 4 | toRna: -> 5 | @dna.replace /./g, (nucleotide) -> 6 | switch nucleotide 7 | when 'C' then 'G' 8 | when 'G' then 'C' 9 | when 'T' then 'A' 10 | when 'A' then 'U' 11 | else throw new Error "Invalid input DNA." 12 | 13 | module.exports = RnaTranscription 14 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.coffee: -------------------------------------------------------------------------------- 1 | class RnaTranscription 2 | constructor: (dna) -> 3 | 4 | toRna: -> 5 | 6 | module.exports = RnaTranscription 7 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.spec.coffee: -------------------------------------------------------------------------------- 1 | RnaTranscription = require './rna-transcription' 2 | 3 | describe 'RnaTranscription', -> 4 | it 'Empty RNA sequence', -> 5 | dna = new RnaTranscription "" 6 | expect(dna.toRna()).toEqual("") 7 | 8 | xit 'RNA complement of cytosine is guanine', -> 9 | dna = new RnaTranscription "C" 10 | expect(dna.toRna()).toEqual("G") 11 | 12 | xit 'RNA complement of guanine is cytosine', -> 13 | dna = new RnaTranscription "G" 14 | expect(dna.toRna()).toEqual("C") 15 | 16 | xit 'RNA complement of thymine is adenine', -> 17 | dna = new RnaTranscription "T" 18 | expect(dna.toRna()).toEqual("A") 19 | 20 | xit 'RNA complement of adenine is uracil', -> 21 | dna = new RnaTranscription "A" 22 | expect(dna.toRna()).toEqual("U") 23 | 24 | xit 'RNA complement', -> 25 | dna = new RnaTranscription "ACGTGGTCTTAA" 26 | expect(dna.toRna()).toEqual("UGCACCAGAAUU") 27 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Write a robot simulator. 4 | 5 | A robot factory's test facility needs a program to verify robot movements. 6 | 7 | The robots have three possible movements: 8 | 9 | - turn right 10 | - turn left 11 | - advance 12 | 13 | Robots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates, 14 | e.g., {3,8}, with coordinates increasing to the north and east. 15 | 16 | The robot then receives a number of instructions, at which point the testing facility verifies the robot's new position, and in which direction it is pointing. 17 | 18 | - The letter-string "RAALAL" means: 19 | - Turn right 20 | - Advance twice 21 | - Turn left 22 | - Advance once 23 | - Turn left yet again 24 | - Say a robot starts at {7, 3} facing north. 25 | Then running this stream of instructions should leave it at {9, 4} facing west. 26 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "robot-simulator.coffee" 8 | ], 9 | "test": [ 10 | "robot-simulator.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Write a robot simulator.", 17 | "source": "Inspired by an interview question at a famous company." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | directions = 2 | "north": 3 | "left": "west" 4 | "right": "east" 5 | "east": 6 | "left": "north" 7 | "right": "south" 8 | "south": 9 | "left": "east" 10 | "right": "west" 11 | "west": 12 | "left": "south" 13 | "right": "north" 14 | 15 | class RobotSimulator 16 | constructor: (@x, @y, @direction) -> 17 | 18 | move: (commands) => 19 | for command in commands.split("") 20 | if command == "L" 21 | @direction = directions[@direction]["left"] 22 | else if command == "R" 23 | @direction = directions[@direction]["right"] 24 | else if command == "A" 25 | if @direction == "north" 26 | @y += 1 27 | else if @direction == "south" 28 | @y -= 1 29 | else if @direction == "east" 30 | @x += 1 31 | else if @direction == "west" 32 | @x -= 1 33 | 34 | module.exports = RobotSimulator 35 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/robot-simulator.coffee: -------------------------------------------------------------------------------- 1 | class RobotSimulator 2 | constructor: (x, y, direction) -> 3 | 4 | move: (commands) -> 5 | 6 | module.exports = RobotSimulator 7 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your task is to convert a number from Arabic numerals to Roman numerals. 4 | 5 | For this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999). 6 | 7 | ~~~~exercism/note 8 | There are lots of different ways to convert between Arabic and Roman numerals. 9 | We recommend taking a naive approach first to familiarise yourself with the concept of Roman numerals and then search for more efficient methods. 10 | 11 | Make sure to check out our Deep Dive video at the end to explore the different approaches you can take! 12 | ~~~~ 13 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "roman-numerals.coffee" 8 | ], 9 | "test": [ 10 | "roman-numerals.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 17 | "source": "The Roman Numeral Kata", 18 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class RomanNumerals 2 | mappings = 3 | 1000: "M" 4 | 900: "CM" 5 | 500: "D" 6 | 400: "CD" 7 | 100: "C" 8 | 90: "XC" 9 | 50: "L" 10 | 40: "XL" 11 | 10: "X" 12 | 9: "IX" 13 | 5: "V" 14 | 4: "IV" 15 | 1: "I" 16 | 17 | steps = Object.keys(mappings).sort (a, b) -> b - a 18 | 19 | @convert: (number) -> 20 | result = "" 21 | for step in steps 22 | numeral = mappings[step] 23 | while number >= step 24 | number -= step 25 | result += numeral 26 | result 27 | 28 | module.exports = RomanNumerals 29 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/roman-numerals.coffee: -------------------------------------------------------------------------------- 1 | class RomanNumerals 2 | @convert: (number) -> 3 | 4 | module.exports = RomanNumerals 5 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rotational-cipher.coffee" 8 | ], 9 | "test": [ 10 | "rotational-cipher.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class RotationalCipher 2 | constructor: (@shift) -> 3 | 4 | rotate: (text) -> 5 | text.split('').map((char) => 6 | if char.match(/[a-z]/) 7 | String.fromCharCode(((char.charCodeAt(0) - 97 + @shift) % 26) + 97) 8 | else if char.match(/[A-Z]/) 9 | String.fromCharCode(((char.charCodeAt(0) - 65 + @shift) % 26) + 65) 10 | else 11 | char).join '' 12 | 13 | module.exports = RotationalCipher 14 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/rotational-cipher.coffee: -------------------------------------------------------------------------------- 1 | class RotationalCipher 2 | constructor: (shift) -> 3 | 4 | rotate: (text) -> 5 | 6 | module.exports = RotationalCipher 7 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement run-length encoding and decoding. 4 | 5 | Run-length encoding (RLE) is a simple form of data compression, where runs (consecutive data elements) are replaced by just one data value and count. 6 | 7 | For example we can represent the original 53 characters with only 13. 8 | 9 | ```text 10 | "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" 11 | ``` 12 | 13 | RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression. 14 | 15 | ```text 16 | "AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" 17 | ``` 18 | 19 | For simplicity, you can assume that the unencoded string will only contain the letters A through Z (either lower or upper case) and whitespace. 20 | This way data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character. 21 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "run-length-encoding.coffee" 8 | ], 9 | "test": [ 10 | "run-length-encoding.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Implement run-length encoding and decoding.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class RunLengthEncoding 2 | @encode: (string) -> 3 | consecutiveChars = /([\w\s])\1*/g 4 | string.replace consecutiveChars, (match) -> 5 | if match.length > 1 then match.length + match[0] else match[0] 6 | 7 | @decode: (string) -> 8 | countAndChar = /(\d+)(\w|\s)/g 9 | string.replace countAndChar, (_, count, char) -> 10 | char.repeat count 11 | 12 | module.exports = RunLengthEncoding 13 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/run-length-encoding.coffee: -------------------------------------------------------------------------------- 1 | class RunLengthEncoding 2 | @encode: (string) -> 3 | 4 | @decode: (string) -> 5 | 6 | module.exports = RunLengthEncoding 7 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to compute a word's Scrabble score by summing the values of its letters. 4 | 5 | The letters are valued as follows: 6 | 7 | | Letter | Value | 8 | | ---------------------------- | ----- | 9 | | A, E, I, O, U, L, N, R, S, T | 1 | 10 | | D, G | 2 | 11 | | B, C, M, P | 3 | 12 | | F, H, V, W, Y | 4 | 13 | | K | 5 | 14 | | J, X | 8 | 15 | | Q, Z | 10 | 16 | 17 | For example, the word "cabbage" is worth 14 points: 18 | 19 | - 3 points for C 20 | - 1 point for A 21 | - 3 points for B 22 | - 3 points for B 23 | - 1 point for A 24 | - 2 points for G 25 | - 1 point for E 26 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Scrabble][wikipedia] is a word game where players place letter tiles on a board to form words. 4 | Each letter has a value. 5 | A word's score is the sum of its letters' values. 6 | 7 | [wikipedia]: https://en.wikipedia.org/wiki/Scrabble 8 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "scrabble-score.coffee" 8 | ], 9 | "test": [ 10 | "scrabble-score.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a word, compute the Scrabble score for that word.", 17 | "source": "Inspired by the Extreme Startup game", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class ScrabbleScore 2 | @score: (word) -> 3 | return 0 if word is '' 4 | word.toLowerCase().split('').reduce (sum, letter) -> 5 | sum + ScrabbleScore.letterScore(letter) 6 | , 0 7 | 8 | @letterScore: (letter) -> 9 | switch letter 10 | when 'a', 'e', 'i', 'o', 'u', 'l', 'n', 'r', 's', 't' then 1 11 | when 'd', 'g' then 2 12 | when 'b', 'c', 'm', 'p' then 3 13 | when 'f', 'h', 'v', 'w', 'y' then 4 14 | when 'k' then 5 15 | when 'j', 'x' then 8 16 | when 'q', 'z' then 10 17 | else 0 18 | 19 | module.exports = ScrabbleScore 20 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/scrabble-score.coffee: -------------------------------------------------------------------------------- 1 | class ScrabbleScore 2 | @score: (word) -> 3 | 4 | module.exports = ScrabbleScore 5 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You are starting a secret coding club with some friends and friends-of-friends. 4 | Not everyone knows each other, so you and your friends have decided to create a secret handshake that you can use to recognize that someone is a member. 5 | You don't want anyone who isn't in the know to be able to crack the code. 6 | 7 | You've designed the code so that one person says a number between 1 and 31, and the other person turns it into a series of actions. 8 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "secret-handshake.coffee" 8 | ], 9 | "test": [ 10 | "secret-handshake.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.", 17 | "source": "Bert, in Mary Poppins", 18 | "source_url": "https://www.imdb.com/title/tt0058331/quotes/?item=qt0437047" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class SecretHandshake 2 | @commands: (number) -> 3 | actions = allowed_actions.filter (_, i) -> number & Math.pow 2, i 4 | if number & Math.pow 2, 4 5 | actions.reverse() 6 | else 7 | actions 8 | 9 | allowed_actions = ["wink", "double blink", "close your eyes", "jump"] 10 | 11 | module.exports = SecretHandshake 12 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/secret-handshake.coffee: -------------------------------------------------------------------------------- 1 | class SecretHandshake 2 | @commands: (number) -> 3 | 4 | module.exports = SecretHandshake 5 | -------------------------------------------------------------------------------- /exercises/practice/series/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string of digits, output all the contiguous substrings of length `n` in that string in the order that they appear. 4 | 5 | For example, the string "49142" has the following 3-digit series: 6 | 7 | - "491" 8 | - "914" 9 | - "142" 10 | 11 | And the following 4-digit series: 12 | 13 | - "4914" 14 | - "9142" 15 | 16 | And if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get. 17 | 18 | Note that these series are only required to occupy _adjacent positions_ in the input; 19 | the digits need not be _numerically consecutive_. 20 | -------------------------------------------------------------------------------- /exercises/practice/series/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "series.coffee" 8 | ], 9 | "test": [ 10 | "series.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.", 17 | "source": "A subset of the Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/series/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Series 2 | @slices: (series, sliceLength) -> 3 | if !series 4 | throw new Error "series cannot be empty" 5 | if sliceLength == 0 6 | throw new Error "slice length cannot be zero" 7 | if sliceLength < 0 8 | throw new Error "slice length cannot be negative" 9 | if sliceLength > series.length 10 | throw new Error "slice length cannot be greater than series length" 11 | 12 | 13 | result = [] 14 | for i in [0..series.length - sliceLength] 15 | result.push series.substring(i, i + sliceLength) 16 | result 17 | 18 | module.exports = Series 19 | -------------------------------------------------------------------------------- /exercises/practice/series/series.coffee: -------------------------------------------------------------------------------- 1 | class Series 2 | @slices: (series, sliceLength) -> 3 | 4 | module.exports = Series 5 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You bought a big box of random computer parts at a garage sale. 4 | You've started putting the parts together to build custom computers. 5 | 6 | You want to test the performance of different combinations of parts, and decide to create your own benchmarking program to see how your computers compare. 7 | You choose the famous "Sieve of Eratosthenes" algorithm, an ancient algorithm, but one that should push your computers to the limits. 8 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sieve.coffee" 8 | ], 9 | "test": [ 10 | "sieve.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", 17 | "source": "Sieve of Eratosthenes at Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Sieve 2 | @primes: (limit) -> 3 | results = [] 4 | if limit == 1 5 | return [] 6 | 7 | numbers = [2..limit] 8 | while numbers.length > 0 9 | [curr, numbers...] = numbers 10 | results.push curr 11 | numbers = numbers.filter (n) -> n % curr != 0 12 | results 13 | 14 | module.exports = Sieve 15 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [88529125-c4ce-43cc-bb36-1eb4ddd7b44f] 13 | description = "no primes under two" 14 | 15 | [4afe9474-c705-4477-9923-840e1024cc2b] 16 | description = "find first prime" 17 | 18 | [974945d8-8cd9-4f00-9463-7d813c7f17b7] 19 | description = "find primes up to 10" 20 | 21 | [2e2417b7-3f3a-452a-8594-b9af08af6d82] 22 | description = "limit is prime" 23 | 24 | [92102a05-4c7c-47de-9ed0-b7d5fcd00f21] 25 | description = "find primes up to 1000" 26 | -------------------------------------------------------------------------------- /exercises/practice/sieve/sieve.coffee: -------------------------------------------------------------------------------- 1 | class Sieve 2 | @primes: (limit) -> 3 | 4 | module.exports = Sieve 5 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Write a prototype of the music player application. 4 | 5 | For the prototype, each song will simply be represented by a number. 6 | Given a range of numbers (the song IDs), create a singly linked list. 7 | 8 | Given a singly linked list, you should be able to reverse the list to play the songs in the opposite order. 9 | 10 | ~~~~exercism/note 11 | The linked list is a fundamental data structure in computer science, often used in the implementation of other data structures. 12 | 13 | The simplest kind of linked list is a **singly** linked list. 14 | That means that each element (or "node") contains data, along with something that points to the next node in the list. 15 | 16 | If you want to dig deeper into linked lists, check out [this article][intro-linked-list] that explains it using nice drawings. 17 | 18 | [intro-linked-list]: https://medium.com/basecs/whats-a-linked-list-anyway-part-1-d8b7e6508b9d 19 | ~~~~ 20 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a music streaming company. 4 | 5 | You've been tasked with creating a playlist feature for your music player application. 6 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "simple-linked-list.coffee" 8 | ], 9 | "test": [ 10 | "simple-linked-list.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Write a simple linked list implementation that uses Elements and a List.", 17 | "source": "Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists.", 18 | "source_url": "https://web.archive.org/web/20160731005714/http://brpreiss.com/books/opus8/html/page96.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Element 2 | constructor: (@value, @next = null) -> 3 | 4 | class LinkedList 5 | constructor: (values) -> 6 | @count = 0 7 | @head = null 8 | if values? 9 | for value in values 10 | @add new Element value 11 | 12 | length: -> 13 | @count 14 | 15 | add: (element) -> 16 | elt = element 17 | elt.next = @head 18 | @head = elt 19 | @count += 1 20 | 21 | toArray: -> 22 | elements = [] 23 | element = @head 24 | while element? 25 | elements.push element.value 26 | element = element.next 27 | elements 28 | 29 | reverse: (prev = null) -> 30 | if @head?.next 31 | current = @head 32 | @head = @head.next 33 | current.next = prev 34 | @reverse current 35 | else 36 | @head.next = prev 37 | @ 38 | 39 | module.exports.Element = Element 40 | module.exports.LinkedList = LinkedList 41 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/simple-linked-list.coffee: -------------------------------------------------------------------------------- 1 | class Element 2 | constructor: (value) -> 3 | 4 | class LinkedList 5 | constructor: (values) -> 6 | 7 | length: -> 8 | 9 | add: (element) -> 10 | 11 | toArray: -> 12 | 13 | reverse: -> 14 | 15 | module.exports.Element = Element 16 | module.exports.LinkedList = LinkedList 17 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "space-age.coffee" 8 | ], 9 | "test": [ 10 | "space-age.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", 17 | "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class SpaceAge 2 | EARTH_SECONDS = 31557600 3 | 4 | @onEarth: (seconds) -> 5 | seconds / EARTH_SECONDS 6 | 7 | @onMercury: (seconds) -> 8 | @onEarth seconds / 0.2408467 9 | 10 | @onVenus: (seconds) -> 11 | @onEarth seconds / 0.61519726 12 | 13 | @onMars: (seconds) -> 14 | @onEarth seconds / 1.8808158 15 | 16 | @onJupiter: (seconds) -> 17 | @onEarth seconds / 11.862615 18 | 19 | @onSaturn: (seconds) -> 20 | @onEarth seconds / 29.447498 21 | 22 | @onUranus: (seconds) -> 23 | @onEarth seconds / 84.016846 24 | 25 | @onNeptune: (seconds) -> 26 | @onEarth seconds / 164.79132 27 | 28 | module.exports = SpaceAge 29 | -------------------------------------------------------------------------------- /exercises/practice/space-age/space-age.coffee: -------------------------------------------------------------------------------- 1 | class SpaceAge 2 | @onEarth: (seconds) -> 3 | 4 | @onMercury: (seconds) -> 5 | 6 | @onMercury: (seconds) -> 7 | 8 | @onVenus: (seconds) -> 9 | 10 | @onMars: (seconds) -> 11 | 12 | @onJupiter: (seconds) -> 13 | 14 | @onSaturn: (seconds) -> 15 | 16 | @onUranus: (seconds) -> 17 | 18 | @onNeptune: (seconds) -> 19 | 20 | module.exports = SpaceAge 21 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to return a square matrix of a given size. 4 | 5 | The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples: 6 | 7 | ## Examples 8 | 9 | ### Spiral matrix of size 3 10 | 11 | ```text 12 | 1 2 3 13 | 8 9 4 14 | 7 6 5 15 | ``` 16 | 17 | ### Spiral matrix of size 4 18 | 19 | ```text 20 | 1 2 3 4 21 | 12 13 14 5 22 | 11 16 15 6 23 | 10 9 8 7 24 | ``` 25 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods. 4 | Despite numerous attempts, no one had ever succeeded in finding it. 5 | This was about to change, however, thanks to a young explorer named Elara. 6 | She had discovered an old document containing instructions on how to locate the treasure. 7 | Using these instructions, Elara was able to draw a map that revealed the path to the treasure. 8 | 9 | To her surprise, the path followed a peculiar clockwise spiral. 10 | It was no wonder no one had been able to find the treasure before! 11 | With the map in hand, Elara embarks on her journey to uncover the hidden treasure. 12 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "spiral-matrix.coffee" 8 | ], 9 | "test": [ 10 | "spiral-matrix.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given the size, return a square matrix of numbers in spiral order.", 17 | "source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.", 18 | "source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/spiral-matrix.coffee: -------------------------------------------------------------------------------- 1 | class SpiralMatrix 2 | @spiralMatrix: (size) -> 3 | 4 | module.exports = SpiralMatrix 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to calculate the square root of a given number. 4 | 5 | - Try to avoid using the pre-existing math libraries of your language. 6 | - As input you'll be given a positive whole number, i.e. 1, 2, 3, 4… 7 | - You are only required to handle cases where the result is a positive whole number. 8 | 9 | Some potential approaches: 10 | 11 | - Linear or binary search for a number that gives the input number when squared. 12 | - Successive approximation using Newton's or Heron's method. 13 | - Calculating one digit at a time or one bit at a time. 14 | 15 | You can check out the Wikipedia pages on [integer square root][integer-square-root] and [methods of computing square roots][computing-square-roots] to help with choosing a method of calculation. 16 | 17 | [integer-square-root]: https://en.wikipedia.org/wiki/Integer_square_root 18 | [computing-square-roots]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots 19 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | We are launching a deep space exploration rocket and we need a way to make sure the navigation system stays on target. 4 | 5 | As the first step in our calculation, we take a target number and find its square root (that is, the number that when multiplied by itself equals the target number). 6 | 7 | The journey will be very long. 8 | To make the batteries last as long as possible, we had to make our rocket's onboard computer very power efficient. 9 | Unfortunately that means that we can't rely on fancy math libraries and functions, as they use more power. 10 | Instead we want to implement our own square root calculation. 11 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "square-root.coffee" 8 | ], 9 | "test": [ 10 | "square-root.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a natural radicand, return its square root.", 17 | "source": "wolf99", 18 | "source_url": "https://github.com/exercism/problem-specifications/pull/1582" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class SquareRoot 2 | @squareRoot: (radicand) -> 3 | results = 0 4 | while (results * results != radicand) 5 | results += 1 6 | results 7 | 8 | module.exports = SquareRoot 9 | -------------------------------------------------------------------------------- /exercises/practice/square-root/square-root.coffee: -------------------------------------------------------------------------------- 1 | class SquareRoot 2 | @squareRoot: (radicand) -> 3 | 4 | module.exports = SquareRoot 5 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "strain.coffee" 8 | ], 9 | "test": [ 10 | "strain.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Implement the `keep` and `discard` operation on collections.", 17 | "source": "Conversation with James Edward Gray II", 18 | "source_url": "http://graysoftinc.com/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Strain 2 | @keep: (lst, predicate) -> 3 | x for x in lst when predicate(x) 4 | 5 | @discard: (lst, predicate) -> 6 | x for x in lst when !predicate(x) 7 | 8 | module.exports = Strain 9 | -------------------------------------------------------------------------------- /exercises/practice/strain/strain.coffee: -------------------------------------------------------------------------------- 1 | class Strain 2 | @keep: (lst, predicate) -> 3 | 4 | @discard: (lst, predicate) -> 5 | 6 | module.exports = Strain 7 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sublist.coffee" 8 | ], 9 | "test": [ 10 | "sublist.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Write a function to determine if a list is a sublist of another list." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | Classification = 2 | equal: 'equal' 3 | unequal: 'unequal' 4 | sublist: 'sublist' 5 | superlist: 'superlist' 6 | 7 | class Sublist 8 | @classify: (listOne, listTwo) -> 9 | if JSON.stringify(listOne) == JSON.stringify(listTwo) 10 | Classification.equal 11 | else if @is_superlist(listOne, listTwo) 12 | Classification.superlist 13 | else if @is_superlist(listTwo, listOne) 14 | Classification.sublist 15 | else 16 | Classification.unequal 17 | 18 | @is_superlist: (listOne, listTwo) -> 19 | for i in [0..listOne.length - listTwo.length] 20 | if listOne.slice(i, i + listTwo.length).join() == listTwo.join() 21 | return true 22 | false 23 | 24 | module.exports = { Sublist, Classification } 25 | -------------------------------------------------------------------------------- /exercises/practice/sublist/sublist.coffee: -------------------------------------------------------------------------------- 1 | Classification = 2 | # Replace this line with the necessary Classification object properties. 3 | 4 | class Sublist 5 | @classify: (listOne, listTwo) -> 6 | # Replace this line with your code. 7 | 8 | module.exports = { Sublist, Classification } 9 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a company that makes an online, fantasy-survival game. 4 | 5 | When a player finishes a level, they are awarded energy points. 6 | The amount of energy awarded depends on which magical items the player found while exploring that level. 7 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sum-of-multiples.coffee" 8 | ], 9 | "test": [ 10 | "sum-of-multiples.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 17 | "source": "A variation on Problem 1 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=1" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class SumOfMultiples 2 | @sum: (factors, limit) -> 3 | multiples = [] 4 | for i in [1..limit - 1] 5 | for factor in factors 6 | if i % factor is 0 7 | multiples.push i 8 | break 9 | multiples.reduce (a, b) -> 10 | a + b 11 | , 0 12 | 13 | module.exports = SumOfMultiples 14 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/sum-of-multiples.coffee: -------------------------------------------------------------------------------- 1 | class SumOfMultiples 2 | @sum: (factors, limit) -> 3 | 4 | module.exports = SumOfMultiples 5 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wvmitchell", 4 | "meatball133" 5 | ], 6 | "contributors": [ 7 | "aimorris", 8 | "alxndr", 9 | "kytrinyx", 10 | "rootulp", 11 | "zvkemp" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "triangle.coffee" 16 | ], 17 | "test": [ 18 | "triangle.spec.coffee" 19 | ], 20 | "example": [ 21 | ".meta/example.coffee" 22 | ] 23 | }, 24 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 25 | "source": "The Ruby Koans triangle project, parts 1 & 2", 26 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class Triangle 2 | 3 | constructor: (args...) -> 4 | @sides = args 5 | 6 | equilateral: -> 7 | (new Set(@sides)).size is 1 and @validTraingle() and @sides[0] isnt 0 8 | 9 | isosceles: -> 10 | (new Set(@sides)).size <= 2 and @validTraingle() 11 | 12 | scalene: -> 13 | (new Set(@sides)).size is 3 and @validTraingle() 14 | 15 | validTraingle: -> 16 | @sides[0] + @sides[1] >= @sides[2] and @sides[1] + @sides[2] >= @sides[0] and @sides[0] + @sides[2] >= @sides[1] 17 | 18 | module.exports = Triangle 19 | -------------------------------------------------------------------------------- /exercises/practice/triangle/triangle.coffee: -------------------------------------------------------------------------------- 1 | class Triangle 2 | constructor: (args) -> 3 | 4 | equilateral: -> 5 | 6 | isosceles: -> 7 | 8 | scalene: -> 9 | 10 | module.exports = Triangle 11 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles. 4 | 5 | The program should consider strings specifying an invalid trinary as the value 0. 6 | 7 | Trinary numbers contain three symbols: 0, 1, and 2. 8 | 9 | The last place in a trinary number is the 1's place. 10 | The second to last is the 3's place, the third to last is the 9's place, etc. 11 | 12 | ```shell 13 | # "102012" 14 | 1 0 2 0 1 2 # the number 15 | 1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value 16 | 243 + 0 + 54 + 0 + 3 + 2 = 302 17 | ``` 18 | 19 | If your language provides a method in the standard library to perform the conversion, pretend it doesn't exist and implement it yourself. 20 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "aimorris", 5 | "kytrinyx", 6 | "rootulp", 7 | "shidel-dev" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "trinary.coffee" 12 | ], 13 | "test": [ 14 | "trinary.spec.coffee" 15 | ], 16 | "example": [ 17 | ".meta/example.coffee" 18 | ] 19 | }, 20 | "blurb": "Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles.", 21 | "source": "All of Computer Science", 22 | "source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Trinary 2 | BASE: 3 3 | 4 | constructor: (decimal) -> 5 | @digits = decimal.split('').reverse().map Number 6 | 7 | toDecimal: -> 8 | out = this.digits.reduce this.accumulator, 0 9 | if isNaN out then 0 else out 10 | 11 | accumulator: (decimal, digit, index) => 12 | decimal += digit * Math.pow @BASE, index 13 | -------------------------------------------------------------------------------- /exercises/practice/trinary/trinary.coffee: -------------------------------------------------------------------------------- 1 | class Trinary 2 | constructor: (args) -> 3 | 4 | module.exports = Trinary 5 | -------------------------------------------------------------------------------- /exercises/practice/trinary/trinary.spec.coffee: -------------------------------------------------------------------------------- 1 | Trinary = require './trinary' 2 | 3 | describe 'Trinary', -> 4 | 5 | it '1 is decimal 1', -> 6 | expect(new Trinary('1').toDecimal()).toEqual 1 7 | 8 | xit '2 is decimal 2', -> 9 | expect(new Trinary('2').toDecimal()).toEqual 2 10 | 11 | xit '10 is decimal 3', -> 12 | expect(new Trinary('10').toDecimal()).toEqual 3 13 | 14 | xit '11 is decimal 4', -> 15 | expect(new Trinary('11').toDecimal()).toEqual 4 16 | 17 | xit '100 is decimal 9', -> 18 | expect(new Trinary('100').toDecimal()).toEqual 9 19 | 20 | xit '112 is decimal 14', -> 21 | expect(new Trinary('112').toDecimal()).toEqual 14 22 | 23 | xit '222 is 26', -> 24 | expect(new Trinary('222').toDecimal()).toEqual 26 25 | 26 | xit '1122000120 is 32091', -> 27 | expect(new Trinary('1122000120').toDecimal()).toEqual 32091 28 | 29 | xit 'invalid trinary is decimal 0', -> 30 | expect(new Trinary('carrot').toDecimal()).toEqual 0 31 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "twelve-days.coffee" 8 | ], 9 | "test": [ 10 | "twelve-days.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Output the lyrics to 'The Twelve Days of Christmas'.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/twelve-days.coffee: -------------------------------------------------------------------------------- 1 | class TwelveDays 2 | @recite: (startVerse, endVerse) -> 3 | 4 | module.exports = TwelveDays 5 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-bucket.coffee" 8 | ], 9 | "test": [ 10 | "two-bucket.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Given two buckets of different size, demonstrate how to measure an exact number of liters.", 17 | "source": "Water Pouring Problem", 18 | "source_url": "https://demonstrations.wolfram.com/WaterPouringProblem/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/two-bucket.coffee: -------------------------------------------------------------------------------- 1 | class TwoBucket 2 | constructor: ({bucketOne, bucketTwo, goal, startBucket}) -> 3 | 4 | measure: -> 5 | 6 | module.exports = TwoBucket 7 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine what you will say as you give away the extra cookie. 4 | 5 | If you know the person's name (e.g. if they're named Do-yun), then you will say: 6 | 7 | ```text 8 | One for Do-yun, one for me. 9 | ``` 10 | 11 | If you don't know the person's name, you will say _you_ instead. 12 | 13 | ```text 14 | One for you, one for me. 15 | ``` 16 | 17 | Here are some examples: 18 | 19 | | Name | Dialogue | 20 | | :----- | :-------------------------- | 21 | | Alice | One for Alice, one for me. | 22 | | Bohdan | One for Bohdan, one for me. | 23 | | | One for you, one for me. | 24 | | Zaphod | One for Zaphod, one for me. | 25 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In some English accents, when you say "two for" quickly, it sounds like "two fer". 4 | Two-for-one is a way of saying that if you buy one, you also get one for free. 5 | So the phrase "two-fer" often implies a two-for-one offer. 6 | 7 | Imagine a bakery that has a holiday offer where you can buy two cookies for the price of one ("two-fer one!"). 8 | You take the offer and (very generously) decide to give the extra cookie to someone else in the queue. 9 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-fer.coffee" 8 | ], 9 | "test": [ 10 | "two-fer.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 17 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | class TwoFer 2 | @twoFer: (name = "you") -> 3 | "One for #{name}, one for me." 4 | 5 | module.exports = TwoFer 6 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce] 13 | description = "no name given" 14 | 15 | [b4c6dbb8-b4fb-42c2-bafd-10785abe7709] 16 | description = "a name given" 17 | 18 | [3549048d-1a6e-4653-9a79-b0bda163e8d5] 19 | description = "another name given" 20 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.coffee: -------------------------------------------------------------------------------- 1 | class TwoFer 2 | 3 | module.exports = TwoFer 4 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.spec.coffee: -------------------------------------------------------------------------------- 1 | TwoFer = require './two-fer' 2 | 3 | describe 'TwoFer', -> 4 | it 'no name give', -> 5 | expect(TwoFer.twoFer()).toEqual("One for you, one for me.") 6 | 7 | xit 'a name given', -> 8 | expect(TwoFer.twoFer("Alice")).toEqual("One for Alice, one for me.") 9 | 10 | xit 'another name given', -> 11 | expect(TwoFer.twoFer("Bob")).toEqual("One for Bob, one for me.") 12 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You teach English as a foreign language to high school students. 4 | 5 | You've decided to base your entire curriculum on TV shows. 6 | You need to analyze which words are used, and how often they're repeated. 7 | 8 | This will let you choose the simplest shows to start with, and to gradually increase the difficulty as time passes. 9 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Gaelan" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "kytrinyx", 8 | "rootulp", 9 | "meatball133" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "word-count.coffee" 14 | ], 15 | "test": [ 16 | "word-count.spec.coffee" 17 | ], 18 | "example": [ 19 | ".meta/example.coffee" 20 | ] 21 | }, 22 | "blurb": "Given a phrase, count the occurrences of each word in that phrase.", 23 | "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/example.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class Words 2 | constructor: (input) -> 3 | @input = input.trim().toLowerCase().match(/\w+('\w+)?/g); 4 | 5 | count: -> 6 | counts = {} 7 | for word in @input 8 | counts[word] = if counts[word] then counts[word] + 1 else 1 9 | counts 10 | -------------------------------------------------------------------------------- /exercises/practice/word-count/word-count.coffee: -------------------------------------------------------------------------------- 1 | class WordCount 2 | constructor: (args) -> 3 | 4 | count: -> 5 | 6 | 7 | module.exports = WordCount 8 | -------------------------------------------------------------------------------- /exercises/practice/wordy/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "meatball133" 4 | ], 5 | "contributors": [ 6 | "aimorris", 7 | "Gaelan", 8 | "kytrinyx", 9 | "marocchino", 10 | "rootulp", 11 | "shidel-dev" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "wordy.coffee" 16 | ], 17 | "test": [ 18 | "wordy.spec.coffee" 19 | ], 20 | "example": [ 21 | ".meta/example.coffee" 22 | ] 23 | }, 24 | "blurb": "Parse and evaluate simple math word problems returning the answer as an integer.", 25 | "source": "Inspired by one of the generated questions in the Extreme Startup game.", 26 | "source_url": "https://github.com/rchatley/extreme_startup" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/wordy/wordy.coffee: -------------------------------------------------------------------------------- 1 | class Wordy 2 | constructor: (question) -> 3 | 4 | answer: -> 5 | 6 | module.exports = Wordy 7 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Each year, something new is "all the rage" in your high school. 4 | This year it is a dice game: [Yacht][yacht]. 5 | 6 | The game of Yacht is from the same family as Poker Dice, Generala and particularly Yahtzee, of which it is a precursor. 7 | The game consists of twelve rounds. 8 | In each, five dice are rolled and the player chooses one of twelve categories. 9 | The chosen category is then used to score the throw of the dice. 10 | 11 | [yacht]: https://en.wikipedia.org/wiki/Yacht_(dice_game) 12 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "yacht.coffee" 8 | ], 9 | "test": [ 10 | "yacht.spec.coffee" 11 | ], 12 | "example": [ 13 | ".meta/example.coffee" 14 | ] 15 | }, 16 | "blurb": "Score a single throw of dice in the game Yacht.", 17 | "source": "James Kilfiger, using Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/yacht/yacht.coffee: -------------------------------------------------------------------------------- 1 | class Yacht 2 | @score: (dice, category) -> 3 | 4 | module.exports = Yacht 5 | -------------------------------------------------------------------------------- /exercises/shared/.docs/help.md: -------------------------------------------------------------------------------- 1 | # Help 2 | 3 | To get help if you're having trouble, you can use one of the following resources: 4 | 5 | - [CoffeeScript Website](http://coffeescript.org) 6 | - [/r/coffeescript](https://www.reddit.com/r/coffeescript) is the CoffeeScript subreddit. 7 | - [StackOverflow](http://stackoverflow.com/questions/tagged/coffeescript) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. 8 | -------------------------------------------------------------------------------- /exercises/shared/.docs/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | In order to run the test, you can run the test file from the exercise directory: 4 | 5 | ```bash 6 | jasmine-node --coffee . 7 | ``` 8 | -------------------------------------------------------------------------------- /reference/implementing-a-concept-exercise.md: -------------------------------------------------------------------------------- 1 | # How to implement a CoffeeScript concept exercise 2 | 3 | TODO: describe how to implement a concept exercise for the CoffeeScript track. For inspiration, check out the [C# version of this file][csharp-implementing]. 4 | 5 | [csharp-implementing]: https://github.com/exercism/v3/blob/main/csharp/reference/implementing-a-concept-exercise.md 6 | --------------------------------------------------------------------------------