├── .appends └── .github │ └── labels.yml ├── .github ├── CODEOWNERS ├── dependabot.yml ├── labels.yml └── workflows │ ├── configlet.yml │ ├── no-important-files-changed.yml │ ├── pause-community-contributions.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── sync-labels.yml │ └── tests.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bin ├── add-practice-exercise ├── fetch-configlet ├── test-all-exercises └── test-exercise ├── config.json ├── docs ├── ABOUT.md ├── INSTALLATION.md ├── LEARNING.md ├── RESOURCES.md ├── SNIPPET.txt ├── TESTS.md └── config.json └── exercises ├── practice ├── acronym │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── acronym.d │ └── source │ │ └── acronym.d ├── affine-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── affine_cipher.d │ └── source │ │ └── affine_cipher.d ├── all-your-base │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── all_your_base.d │ └── source │ │ └── all_your_base.d ├── allergies │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── allergies.d │ └── source │ │ └── allergies.d ├── anagram │ ├── .docs │ │ ├── instructions.append.md │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── anagram.d │ └── source │ │ └── anagram.d ├── armstrong-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── armstrong_numbers.d │ └── source │ │ └── armstrong_numbers.d ├── atbash-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── atbash_cipher.d │ └── source │ │ └── atbash_cipher.d ├── binary-search │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── binary_search.d │ └── source │ │ └── binary_search.d ├── bob │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── bob.d │ └── source │ │ └── bob.d ├── book-store │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── book_store.d │ └── source │ │ └── book_store.d ├── bottle-song │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── bottle_song.d │ └── source │ │ └── bottle_song.d ├── circular-buffer │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── circular_buffer.d │ └── source │ │ └── circular_buffer.d ├── collatz-conjecture │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── collatz_conjecture.d │ └── source │ │ └── collatz_conjecture.d ├── crypto-square │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── crypto_square.d │ └── source │ │ └── crypto_square.d ├── darts │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── darts.d │ └── source │ │ └── darts.d ├── difference-of-squares │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── difference_of_squares.d │ └── source │ │ └── difference_of_squares.d ├── dnd-character │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── dnd_character.d │ └── source │ │ └── dnd_character.d ├── eliuds-eggs │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── eliuds_eggs.d │ └── source │ │ └── eliuds_eggs.d ├── etl │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── etl.d │ └── source │ │ └── etl.d ├── flower-field │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── flower_field.d │ └── source │ │ └── flower_field.d ├── food-chain │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── food_chain.d │ └── source │ │ └── food_chain.d ├── game-of-life │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── game_of_life.d │ └── source │ │ └── game_of_life.d ├── gigasecond │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── gigasecond.d │ └── source │ │ └── gigasecond.d ├── grade-school │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── grade_school.d │ └── source │ │ └── grade_school.d ├── grains │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── grains.d │ └── source │ │ └── grains.d ├── hamming │ ├── .approaches │ │ ├── config.json │ │ ├── introduction.md │ │ └── zip-count │ │ │ ├── content.md │ │ │ └── snippet.txt │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── hamming.d │ └── source │ │ └── hamming.d ├── hello-world │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── hello_world.d │ └── source │ │ └── hello_world.d ├── house │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── house.d │ └── source │ │ └── house.d ├── intergalactic-transmission │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── intergalactic_transmission.d │ └── source │ │ └── intergalactic_transmission.d ├── isbn-verifier │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── isbn_verifier.d │ └── source │ │ └── isbn_verifier.d ├── isogram │ ├── .approaches │ │ ├── config.json │ │ ├── filter-map-fold │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ ├── filter-map-foreach │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ └── introduction.md │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── isogram.d │ └── source │ │ └── isogram.d ├── kindergarten-garden │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── kindergarten_garden.d │ └── source │ │ └── kindergarten_garden.d ├── knapsack │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── knapsack.d │ └── source │ │ └── knapsack.d ├── largest-series-product │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── largest_series_product.d │ └── source │ │ └── largest_series_product.d ├── leap │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── leap.d │ └── source │ │ └── leap.d ├── luhn │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── luhn.d │ └── source │ │ └── luhn.d ├── matching-brackets │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── matching_brackets.d │ └── source │ │ └── matching_brackets.d ├── micro-blog │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── micro_blog.d │ └── source │ │ └── micro_blog.d ├── minesweeper │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── minesweeper.d │ └── source │ │ └── minesweeper.d ├── nth-prime │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── nth_prime.d │ └── source │ │ └── nth_prime.d ├── nucleotide-count │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── nucleotide_count.d │ └── source │ │ └── nucleotide_count.d ├── pangram │ ├── .approaches │ │ ├── all-find │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ ├── bitwise-filter-fold │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ ├── config.json │ │ ├── filter-sort-uniq-count │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ └── introduction.md │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── pangram.d │ └── source │ │ └── pangram.d ├── pascals-triangle │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── pascals_triangle.d │ └── source │ │ └── pascals_triangle.d ├── perfect-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── perfect_numbers.d │ └── source │ │ └── perfect_numbers.d ├── phone-number │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── phone_number.d │ └── source │ │ └── phone_number.d ├── pig-latin │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── pig_latin.d │ └── source │ │ └── pig_latin.d ├── prime-factors │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── prime_factors.d │ └── source │ │ └── prime_factors.d ├── protein-translation │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── protein_translation.d │ └── source │ │ └── protein_translation.d ├── proverb │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── proverb.d │ └── source │ │ └── proverb.d ├── pythagorean-triplet │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── pythagorean_triplet.d │ └── source │ │ └── pythagorean_triplet.d ├── raindrops │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── raindrops.d │ └── source │ │ └── raindrops.d ├── react │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── react.d │ └── source │ │ └── react.d ├── resistor-color-duo │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── resistor_color_duo.d │ └── source │ │ └── resistor_color_duo.d ├── resistor-color-trio │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── resistor_color_trio.d │ └── source │ │ └── resistor_color_trio.d ├── resistor-color │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── resistor_color.d │ └── source │ │ └── resistor_color.d ├── reverse-string │ ├── .approaches │ │ ├── bygrapheme-retro-bycodepoint-text │ │ │ ├── content.md │ │ │ └── snippet.txt │ │ ├── config.json │ │ └── introduction.md │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── reverse_string.d │ └── source │ │ └── reverse_string.d ├── rna-transcription │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── rna_transcription.d │ └── source │ │ └── rna_transcription.d ├── robot-name │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ └── config.json │ ├── dub.sdl │ ├── example │ │ └── robot_name.d │ └── source │ │ └── robot_name.d ├── robot-simulator │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── robot_simulator.d │ └── source │ │ └── robot_simulator.d ├── roman-numerals │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── roman_numerals.d │ └── source │ │ └── roman_numerals.d ├── rotational-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── rotational_cipher.d │ └── source │ │ └── rotational_cipher.d ├── run-length-encoding │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── run_length_encoding.d │ └── source │ │ └── run_length_encoding.d ├── scrabble-score │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── scrabble_score.d │ └── source │ │ └── scrabble_score.d ├── secret-handshake │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── secret_handshake.d │ └── source │ │ └── secret_handshake.d ├── series │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── series.d │ └── source │ │ └── series.d ├── sieve │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── sieve.d │ └── source │ │ └── sieve.d ├── space-age │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── space_age.d │ └── source │ │ └── space_age.d ├── square-root │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── square_root.d │ └── source │ │ └── square_root.d ├── state-of-tic-tac-toe │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── state_of_tic_tac_toe.d │ └── source │ │ └── state_of_tic_tac_toe.d ├── sum-of-multiples │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── sum_of_multiples.d │ └── source │ │ └── sum_of_multiples.d ├── triangle │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── triangle.d │ └── source │ │ └── triangle.d ├── twelve-days │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── twelve_days.d │ └── source │ │ └── twelve_days.d ├── two-bucket │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── two_bucket.d │ └── source │ │ └── two_bucket.d ├── two-fer │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── two_fer.d │ └── source │ │ └── two_fer.d ├── yacht │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── tests.toml │ ├── dub.sdl │ ├── example │ │ └── yacht.d │ └── source │ │ └── yacht.d └── zebra-puzzle │ ├── .docs │ ├── instructions.md │ └── introduction.md │ ├── .meta │ ├── config.json │ └── tests.toml │ ├── dub.sdl │ ├── example │ └── zebra_puzzle.d │ └── source │ └── zebra_puzzle.d └── shared └── .docs ├── help.md └── tests.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/pause-community-contributions.yml: -------------------------------------------------------------------------------- 1 | name: Pause Community Contributions 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request_target: 8 | types: 9 | - opened 10 | paths-ignore: 11 | - 'exercises/*/*/.approaches/**' 12 | - 'exercises/*/*/.articles/**' 13 | 14 | permissions: 15 | issues: write 16 | pull-requests: write 17 | 18 | jobs: 19 | pause: 20 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 21 | uses: exercism/github-actions/.github/workflows/community-contributions.yml@main 22 | with: 23 | forum_category: d 24 | secrets: 25 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 26 | -------------------------------------------------------------------------------- /.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 | branches: 5 | - main 6 | push: 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | jobs: 12 | exercises: 13 | name: Check exercises 14 | strategy: 15 | matrix: 16 | os: [ubuntu-24.04, windows-2022] 17 | dc: [dmd-2.109.0, ldc-1.38.0] 18 | runs-on: ${{ matrix.os }} 19 | steps: 20 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 21 | - uses: dlang-community/setup-dlang@0a7469b93f791d83f30932c6fd105796c6966e20 22 | with: 23 | compiler: ${{ matrix.dc }} 24 | - name: Run tests 25 | run: bin/test-all-exercises 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/configlet 2 | bin/configlet.exe 3 | *.o 4 | .gdb* 5 | *-test-library 6 | .dub 7 | .idea -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Exercism 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/test-all-exercises: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | test_one=$(dirname $0)/test-exercise 4 | exercises=$(dirname $(dirname $0))/exercises 5 | status=0 6 | failed_exercises="" 7 | 8 | # TODO: To be confirmed: Would use this line when there are any concept exercises 9 | #for d in $exercises/{concept,practice}/*/; do 10 | for d in $exercises/practice/*; do 11 | if ! $test_one $d; then 12 | failed_exercises="$failed_exercises\n$(basename $d)" 13 | status=1 14 | fi 15 | done 16 | 17 | if [ $status -ne 0 ]; then 18 | echo "The following exercises failed" 19 | echo $failed_exercises 20 | fi 21 | 22 | exit $status 23 | -------------------------------------------------------------------------------- /bin/test-exercise: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if (( $# == 0 )) || [[ ! -d "$1" ]]; then 4 | cat <&2 5 | usage: $0 exercise_path 6 | 7 | example: $0 ./exercises/practice/two-bucket 8 | END_HELP 9 | exit 1 10 | fi 11 | 12 | cd "$1" 13 | 14 | src=$(jq -r '.files.solution[0]' .meta/config.json) 15 | example=$(jq -r '.files.example[0]' .meta/config.json) 16 | 17 | testdir=$(mktemp -d) 18 | trap 'rm -r "$testdir"' EXIT 19 | 20 | cp ./dub.sdl "$testdir" 21 | mkdir "$testdir/source" 22 | { 23 | cat "$example" 24 | sed -nE ' 25 | /unittest/,$ { 26 | s/(int allTestsEnabled =).*/\1 1;/ 27 | p 28 | } 29 | ' "$src" 30 | } > "${testdir}/${src}" 31 | 32 | cd "$testdir" 33 | 34 | dub test 35 | status=$? 36 | 37 | ((status == 0)) || echo "$1 test has failed" >&2 38 | exit $status 39 | -------------------------------------------------------------------------------- /docs/RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | 4 | * [Books](https://wiki.dlang.org/Books) 5 | * [Tutorials](https://wiki.dlang.org/Tutorials) 6 | * [Development tools](https://wiki.dlang.org/Development_tools) 7 | * [Editors](https://wiki.dlang.org/Editors) 8 | * [IDEs](https://wiki.dlang.org/IDEs) 9 | * [D Style Guide](https://dlang.org/dstyle.html) 10 | * Internet at large 11 | 12 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | module helloworld; 2 | 3 | import std.format; 4 | 5 | string hello(const char[] s = "World") { 6 | return format("Hello, %s!", s); 7 | } 8 | -------------------------------------------------------------------------------- /docs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": [ 3 | { 4 | "uuid": "a4ab17af-e1de-4fc3-9d62-d69de96731a6", 5 | "slug": "installation", 6 | "path": "docs/INSTALLATION.md", 7 | "title": "Installing D locally", 8 | "blurb": "Learn how to install D locally to solve Exercism's exercises on your own machine" 9 | }, 10 | { 11 | "uuid": "f6327a96-80be-4955-8cb5-ab989d1cfa9b", 12 | "slug": "learning", 13 | "path": "docs/LEARNING.md", 14 | "title": "How to learn D", 15 | "blurb": "An overview of how to get started from scratch with D" 16 | }, 17 | { 18 | "uuid": "d07cbfa5-9e48-4eb2-ac43-c0b68f7a5ebc", 19 | "slug": "tests", 20 | "path": "docs/TESTS.md", 21 | "title": "Testing on the D track", 22 | "blurb": "Learn how to test your D exercises on Exercism" 23 | }, 24 | { 25 | "uuid": "062bfc44-b4b0-407a-8e08-3396db8b7949", 26 | "slug": "resources", 27 | "path": "docs/RESOURCES.md", 28 | "title": "Useful D resources", 29 | "blurb": "A collection of useful resources to help you master D" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /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 | "contributors": [ 6 | "BethanyG" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/acronym.d" 11 | ], 12 | "test": [ 13 | "source/acronym.d" 14 | ], 15 | "example": [ 16 | "example/acronym.d" 17 | ] 18 | }, 19 | "blurb": "Convert a long phrase to its acronym.", 20 | "source": "Julien Vanier", 21 | "source_url": "https://github.com/monkbroc" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/acronym/dub.sdl: -------------------------------------------------------------------------------- 1 | name "acronym" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/acronym/example/acronym.d: -------------------------------------------------------------------------------- 1 | module acronym; 2 | 3 | import std.regex; 4 | import std.string; 5 | 6 | immutable r = regex(r"(?= 2"); 10 | } 11 | if (outputBase < 2) 12 | { 13 | throw new Exception("output base must be >= 2"); 14 | } 15 | 16 | int number = 0; 17 | foreach(digit; digits) 18 | { 19 | if (digit < 0 || digit >= inputBase) 20 | { 21 | throw new Exception("all digits must satisfy 0 <= d < input base"); 22 | } 23 | number = number * inputBase + digit; 24 | } 25 | 26 | int [] result; 27 | do 28 | { 29 | result ~= number % outputBase; 30 | number /= outputBase; 31 | } while (number != 0); 32 | return result.reverse; 33 | } 34 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. 4 | 5 | An allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for). 6 | 7 | The list of items (and their value) that were tested are: 8 | 9 | - eggs (1) 10 | - peanuts (2) 11 | - shellfish (4) 12 | - strawberries (8) 13 | - tomatoes (16) 14 | - chocolate (32) 15 | - pollen (64) 16 | - cats (128) 17 | 18 | So if Tom is allergic to peanuts and chocolate, he gets a score of 34. 19 | 20 | Now, given just that score of 34, your program should be able to say: 21 | 22 | - Whether Tom is allergic to any one of those allergens listed above. 23 | - All the allergens Tom is allergic to. 24 | 25 | Note: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.). 26 | Your program should ignore those components of the score. 27 | For example, if the allergy score is 257, your program should only report the eggs (1) allergy. 28 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/allergies.d" 8 | ], 9 | "test": [ 10 | "source/allergies.d" 11 | ], 12 | "example": [ 13 | "example/allergies.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "allergies" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/allergies/example/allergies.d: -------------------------------------------------------------------------------- 1 | module allergies; 2 | 3 | import std.algorithm; 4 | import std.range; 5 | 6 | class Allergies 7 | { 8 | public: 9 | this(immutable uint score) 10 | { 11 | this.score = score; 12 | } 13 | 14 | final bool allergicTo(immutable string item) 15 | { 16 | foreach (allergen; this.list()) 17 | { 18 | if (item == allergen) { 19 | return true; 20 | } 21 | } 22 | return false; 23 | } 24 | 25 | final string[] list() 26 | { 27 | return this.allergens.enumerate 28 | .filter!(item => this.score & (1 << item.index)) 29 | .map!(item => item.value).array(); 30 | } 31 | 32 | private: 33 | immutable uint score; 34 | string[] allergens = [ 35 | "eggs", 36 | "peanuts", 37 | "shellfish", 38 | "strawberries", 39 | "tomatoes", 40 | "chocolate", 41 | "pollen", 42 | "cats" 43 | ]; 44 | } -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions Append 2 | 3 | You must return the anagrams in the same order as they are listed in the candidate words. 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 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/anagram.d" 8 | ], 9 | "test": [ 10 | "source/anagram.d" 11 | ], 12 | "example": [ 13 | "example/anagram.d" 14 | ] 15 | }, 16 | "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", 17 | "source": "Inspired by the Extreme Startup game", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/anagram/dub.sdl: -------------------------------------------------------------------------------- 1 | name "anagram" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/anagram/example/anagram.d: -------------------------------------------------------------------------------- 1 | import std.array; 2 | import std.string; 3 | import std.algorithm; 4 | 5 | pure string[] findAnagrams(immutable string subject, immutable string[] candidates) 6 | { 7 | string[] results = []; 8 | 9 | string loweredSubject = subject.toLower(); 10 | auto subjectLetters = loweredSubject.split("").sort(); 11 | 12 | foreach (candidate; candidates) 13 | { 14 | string loweredCandidate = candidate.toLower(); 15 | auto candidateLetters = loweredCandidate.split("").sort(); 16 | 17 | if (subjectLetters == candidateLetters && loweredSubject != loweredCandidate) 18 | { 19 | results ~= candidate; 20 | } 21 | } 22 | return results; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/armstrong_numbers.d" 11 | ], 12 | "test": [ 13 | "source/armstrong_numbers.d" 14 | ], 15 | "example": [ 16 | "example/armstrong_numbers.d" 17 | ] 18 | }, 19 | "blurb": "Determine if a number is an Armstrong number.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/dub.sdl: -------------------------------------------------------------------------------- 1 | name "armstrong-numbers" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/example/armstrong_numbers.d: -------------------------------------------------------------------------------- 1 | module armstrong_numbers; 2 | 3 | import std.algorithm.iteration : map, sum; 4 | import std.conv : to; 5 | 6 | pure bool isArmstrongNumber(immutable int number) 7 | { 8 | immutable string s = number.to!string; 9 | immutable auto sum = s.map!(a => a.to!string 10 | .to!int ^^ s.length).sum; 11 | return sum == number; 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/atbash_cipher.d" 8 | ], 9 | "test": [ 10 | "source/atbash_cipher.d" 11 | ], 12 | "example": [ 13 | "example/atbash_cipher.d" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Atbash" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/dub.sdl: -------------------------------------------------------------------------------- 1 | name "atbash-cipher" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/example/atbash_cipher.d: -------------------------------------------------------------------------------- 1 | module atbash_cipher; 2 | 3 | import std.ascii : isAlphaNum, isDigit, toLower; 4 | 5 | pure string encode(immutable string phrase) 6 | { 7 | size_t nextSpace = 5; 8 | string result; 9 | foreach (dchar c; phrase) { 10 | if (!isAlphaNum(c)) { 11 | continue; 12 | } 13 | if (result.length == nextSpace) { 14 | result ~= ' '; 15 | nextSpace += 6; 16 | } 17 | if (!isDigit(c)) { 18 | c = 'a' + 'z' - toLower(c); 19 | } 20 | result ~= c; 21 | } 22 | return result; 23 | } 24 | 25 | pure string decode(immutable string phrase) 26 | { 27 | string result; 28 | foreach (dchar c; phrase) { 29 | if (c == ' ') { 30 | continue; 31 | } 32 | if (!isDigit(c)) { 33 | c = 'a' + 'z' - c; 34 | } 35 | result ~= c; 36 | } 37 | return result; 38 | } 39 | -------------------------------------------------------------------------------- /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 | "source/binary_search.d" 8 | ], 9 | "test": [ 10 | "source/binary_search.d" 11 | ], 12 | "example": [ 13 | "example/binary_search.d" 14 | ] 15 | }, 16 | "blurb": "Implement a binary search algorithm.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/dub.sdl: -------------------------------------------------------------------------------- 1 | name "binary-search" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/example/binary_search.d: -------------------------------------------------------------------------------- 1 | module binary_search; 2 | 3 | class BinarySearch 4 | { 5 | public: 6 | this(immutable int[] values) 7 | { 8 | this.values = values; 9 | } 10 | 11 | final int find(immutable int value) 12 | { 13 | int start = 0; 14 | int stop = cast(int) this.values.length - 1; 15 | 16 | while (start <= stop) 17 | { 18 | int index = (start + stop) / 2; 19 | int median = this.values[index]; 20 | if (median == value) 21 | { 22 | return index; 23 | } 24 | 25 | if (median < value) 26 | { 27 | start = index + 1; 28 | } 29 | else 30 | { 31 | stop = index - 1; 32 | } 33 | } 34 | 35 | throw new Exception("value not in list"); 36 | } 37 | 38 | private: 39 | immutable int[] values; 40 | } 41 | -------------------------------------------------------------------------------- /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 | "contributors": [ 4 | "amscotti", 5 | "celavek", 6 | "kytrinyx", 7 | "petertseng", 8 | "sjwarner-bp", 9 | "tmccombs" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/bob.d" 14 | ], 15 | "test": [ 16 | "source/bob.d" 17 | ], 18 | "example": [ 19 | "example/bob.d" 20 | ] 21 | }, 22 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 23 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 24 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/bob/dub.sdl: -------------------------------------------------------------------------------- 1 | name "bob" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/book-store/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/book_store.d" 8 | ], 9 | "test": [ 10 | "source/book_store.d" 11 | ], 12 | "example": [ 13 | "example/book_store.d" 14 | ] 15 | }, 16 | "blurb": "To try and encourage more sales of different books from a popular 5 book series, a bookshop has decided to offer discounts of multiple-book purchases.", 17 | "source": "Inspired by the harry potter kata from Cyber-Dojo.", 18 | "source_url": "https://cyber-dojo.org" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/book-store/dub.sdl: -------------------------------------------------------------------------------- 1 | name "book-store" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/book-store/example/book_store.d: -------------------------------------------------------------------------------- 1 | module book_store; 2 | 3 | import std.algorithm : min; 4 | import std.algorithm.sorting : sort; 5 | 6 | pure int total(immutable int[] basket) 7 | { 8 | auto tally = [0, 0, 0, 0, 0, 0]; 9 | foreach (book; basket) { 10 | ++tally[book]; 11 | } 12 | 13 | sort(tally); 14 | 15 | int five = tally[1]; 16 | int four = tally[2] - tally[1]; 17 | int three = tally[3] - tally[2]; 18 | int two = tally[4] - tally[3]; 19 | int one = tally[5] - tally[4]; 20 | 21 | // Two groups of four are cheaper than a group of five plus a group of three. 22 | int adjustment = min(three, five); 23 | five -= adjustment; 24 | three -= adjustment; 25 | four += 2 * adjustment; 26 | 27 | return 5 * five * 600 + 4 * four * 640 + 3 * three * 720 + 2 * two * 760 + 1 * one * 800; 28 | } 29 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/bottle_song.d" 8 | ], 9 | "test": [ 10 | "source/bottle_song.d" 11 | ], 12 | "example": [ 13 | "example/bottle_song.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "bottle-song" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/example/bottle_song.d: -------------------------------------------------------------------------------- 1 | module bottle_song; 2 | 3 | import std.array : join; 4 | import std.uni : toLower; 5 | 6 | pure string bottles(int numBottles) 7 | { 8 | return (numBottles == 1) ? "bottle" : "bottles"; 9 | } 10 | 11 | pure string recite(int startBottles, int takeDown) 12 | { 13 | immutable string[] number = [ "No", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" ]; 14 | 15 | string[] lyrics; 16 | int numBottles = startBottles; 17 | int endBottles = startBottles - takeDown; 18 | while (numBottles > endBottles) 19 | { 20 | string line = number[numBottles] ~ " green " ~ bottles(numBottles) ~ " hanging on the wall,"; 21 | lyrics ~= line; 22 | lyrics ~= line; 23 | lyrics ~= "And if one green bottle should accidentally fall,"; 24 | --numBottles; 25 | lyrics ~= "There'll be " ~ toLower(number[numBottles]) ~ " green " ~ bottles(numBottles) ~ " hanging on the wall."; 26 | 27 | if (numBottles > endBottles) 28 | { 29 | lyrics ~= ""; 30 | } 31 | } 32 | 33 | return lyrics.join("\n"); 34 | } 35 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/circular_buffer.d" 13 | ], 14 | "test": [ 15 | "source/circular_buffer.d" 16 | ], 17 | "example": [ 18 | "example/circular_buffer.d" 19 | ] 20 | }, 21 | "blurb": "A data structure that uses a single, fixed-size buffer as if it were connected end-to-end.", 22 | "source": "Wikipedia", 23 | "source_url": "https://en.wikipedia.org/wiki/Circular_buffer" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/dub.sdl: -------------------------------------------------------------------------------- 1 | name "circular-buffer" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/collatz_conjecture.d" 11 | ], 12 | "test": [ 13 | "source/collatz_conjecture.d" 14 | ], 15 | "example": [ 16 | "example/collatz_conjecture.d" 17 | ] 18 | }, 19 | "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Collatz_conjecture" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/dub.sdl: -------------------------------------------------------------------------------- 1 | name "collatz-conjecture" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/example/collatz_conjecture.d: -------------------------------------------------------------------------------- 1 | module collatz_conjecture; 2 | 3 | pure int steps(immutable int number) 4 | { 5 | if (number < 1) 6 | { 7 | throw new Exception("Only positive integers are allowed"); 8 | } 9 | 10 | int result = 0; 11 | int n = number; 12 | 13 | while (n != 1) 14 | { 15 | if (n % 2 == 0) 16 | { 17 | n = (n / 2); 18 | } 19 | else 20 | { 21 | n = 3 * n + 1; 22 | } 23 | result++; 24 | } 25 | 26 | return result; 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/source/collatz_conjecture.d: -------------------------------------------------------------------------------- 1 | module collatz_conjecture; 2 | 3 | pure int steps(immutable int number) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | import std.exception : assertThrown; 11 | 12 | const int allTestsEnabled = 0; 13 | 14 | // Zero steps for one 15 | assert(steps(1) == 0); 16 | 17 | static if (allTestsEnabled) 18 | { 19 | // Divide if even 20 | assert(steps(16) == 4); 21 | 22 | // Even and odd steps 23 | assert(steps(12) == 9); 24 | 25 | // Large number of even and odd steps 26 | assert(steps(1000000) == 152); 27 | 28 | // Zero is an error 29 | assertThrown(steps(0)); 30 | 31 | // Negative value is an error 32 | assertThrown(steps(-15)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "amscotti", 5 | "AntonMeep", 6 | "kytrinyx", 7 | "petertseng", 8 | "sjwarner-bp", 9 | "tmccombs" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/crypto_square.d" 14 | ], 15 | "test": [ 16 | "source/crypto_square.d" 17 | ], 18 | "example": [ 19 | "example/crypto_square.d" 20 | ] 21 | }, 22 | "blurb": "Implement the classic method for composing secret messages called a square code.", 23 | "source": "J Dalbey's Programming Practice problems", 24 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/dub.sdl: -------------------------------------------------------------------------------- 1 | name "crypto-square" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/darts.d" 11 | ], 12 | "test": [ 13 | "source/darts.d" 14 | ], 15 | "example": [ 16 | "example/darts.d" 17 | ] 18 | }, 19 | "blurb": "Calculate the points scored in a single toss of a Darts game.", 20 | "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/darts/dub.sdl: -------------------------------------------------------------------------------- 1 | name "darts" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/darts/example/darts.d: -------------------------------------------------------------------------------- 1 | module darts; 2 | 3 | import std.math : hypot; 4 | 5 | pure int score(immutable float x, immutable float y) 6 | { 7 | immutable float hypot = hypot(x, y); 8 | 9 | if (hypot <= 1) 10 | { 11 | return 10; 12 | } 13 | else if (hypot <= 5) 14 | { 15 | return 5; 16 | } 17 | else if (hypot <= 10) 18 | { 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/difference_of_squares.d" 14 | ], 15 | "test": [ 16 | "source/difference_of_squares.d" 17 | ], 18 | "example": [ 19 | "example/difference_of_squares.d" 20 | ] 21 | }, 22 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 23 | "source": "Problem 6 at Project Euler", 24 | "source_url": "https://projecteuler.net/problem=6" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/dub.sdl: -------------------------------------------------------------------------------- 1 | name "difference-of-squares" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/example/difference_of_squares.d: -------------------------------------------------------------------------------- 1 | module difference_of_squares; 2 | 3 | import std.range : iota; 4 | import std.algorithm : sum, map; 5 | 6 | struct Squares 7 | { 8 | this(uint max) pure 9 | { 10 | end = max + 1; 11 | } 12 | 13 | @property uint squareOfSum() const pure 14 | { 15 | return iota(end).sum ^^ 2; 16 | } 17 | 18 | @property uint sumOfSquares() const pure 19 | { 20 | return iota(end).map!"a ^^ 2".sum; 21 | } 22 | 23 | @property uint difference() const pure 24 | { 25 | return squareOfSum - sumOfSquares; 26 | } 27 | 28 | private uint end; 29 | } 30 | 31 | Squares squares(uint max) pure 32 | { 33 | return Squares(max); 34 | } 35 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/source/difference_of_squares.d: -------------------------------------------------------------------------------- 1 | module difference_of_squares; 2 | 3 | unittest 4 | { 5 | immutable int allTestsEnabled = 0; 6 | 7 | // Square of sum 1 8 | assert(squares(1).squareOfSum == 1); 9 | 10 | static if (allTestsEnabled) 11 | { 12 | // Square of sum 5 13 | assert(squares(5).squareOfSum == 225); 14 | 15 | // Square of sum 100 16 | assert(squares(100).squareOfSum == 25_502_500); 17 | 18 | // Sum of squares 1 19 | assert(squares(1).sumOfSquares == 1); 20 | 21 | // Sum of squares 5 22 | assert(squares(5).sumOfSquares == 55); 23 | 24 | // Sum of squares 100 25 | assert(squares(100).sumOfSquares == 338_350); 26 | 27 | // Difference of squares 100 28 | assert(squares(100).difference == 25_164_150); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /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 | "source/dnd_character.d" 8 | ], 9 | "test": [ 10 | "source/dnd_character.d" 11 | ], 12 | "example": [ 13 | "example/dnd_character.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "dnd-character" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/dnd-character/example/dnd_character.d: -------------------------------------------------------------------------------- 1 | module dnd_character; 2 | 3 | import std.algorithm; 4 | import std.random; 5 | import std.range; 6 | import std.math; 7 | 8 | class DndCharacter 9 | { 10 | public: 11 | this() 12 | { 13 | this.strength = ability(); 14 | this.dexterity = ability(); 15 | this.constitution = ability(); 16 | this.intelligence = ability(); 17 | this.wisdom = ability(); 18 | this.charisma = ability(); 19 | this.hitpoints = 10 + modifier(this.constitution); 20 | } 21 | 22 | private: 23 | immutable int strength; 24 | immutable int dexterity; 25 | immutable int constitution; 26 | immutable int intelligence; 27 | immutable int wisdom; 28 | immutable int charisma; 29 | immutable int hitpoints; 30 | } 31 | 32 | int ability() 33 | { 34 | return iota(0, 4).map!((x) => uniform(1, 7)).takeExactly(4).array.sort!("a < b").dropExactly(1).sum(); 35 | } 36 | 37 | pure int modifier(immutable int value) 38 | { 39 | return cast(int)floor((value - 10) / 2.0); 40 | } 41 | -------------------------------------------------------------------------------- /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 | "source/eliuds_eggs.d" 8 | ], 9 | "test": [ 10 | "source/eliuds_eggs.d" 11 | ], 12 | "example": [ 13 | "example/eliuds_eggs.d" 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/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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "eliuds-eggs" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/example/eliuds_eggs.d: -------------------------------------------------------------------------------- 1 | module eliuds_eggs; 2 | 3 | pure uint eggCount(immutable uint number) 4 | { 5 | uint count = 0; 6 | uint working = number; 7 | while (working != 0) { 8 | count += working & 1; 9 | working = working >> 1; 10 | } 11 | 12 | return count; 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/source/eliuds_eggs.d: -------------------------------------------------------------------------------- 1 | module eliuds_eggs; 2 | 3 | pure int eggCount(immutable int number) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | immutable int allTestsEnabled = 0; 11 | 12 | // 0 eggs 13 | assert(eggCount(0) == 0); 14 | 15 | static if (allTestsEnabled) 16 | { 17 | // 1 egg 18 | assert(eggCount(16) == 1); 19 | 20 | // 4 eggs 21 | assert(eggCount(89) == 4); 22 | 23 | // 13 eggs 24 | assert(eggCount(2_000_000_000) == 13); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /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 | "contributors": [ 4 | "amscotti", 5 | "celavek", 6 | "kytrinyx", 7 | "petertseng", 8 | "sjwarner-bp", 9 | "TheSmartnik", 10 | "tmccombs" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "source/etl.d" 15 | ], 16 | "test": [ 17 | "source/etl.d" 18 | ], 19 | "example": [ 20 | "example/etl.d" 21 | ] 22 | }, 23 | "blurb": "Change the data format for scoring a game to more easily add other languages.", 24 | "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 25 | "source_url": "https://turing.edu" 26 | } 27 | -------------------------------------------------------------------------------- /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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "etl" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/etl/example/etl.d: -------------------------------------------------------------------------------- 1 | module etl; 2 | 3 | import std.string; 4 | import std.ascii : isUpper, isAlpha, toLower; 5 | import std.algorithm.searching : countUntil; 6 | import std.algorithm.iteration : each; 7 | import std.algorithm.comparison : equal; 8 | import std.algorithm.sorting : sort; 9 | import std.typecons; 10 | import std.array : array; 11 | 12 | pure bool allAlphaUpper(immutable string text) 13 | { 14 | auto pos = countUntil!((dchar c) => !(isAlpha(c) && isUpper(c)))(text); 15 | return pos == -1; 16 | } 17 | 18 | pure int[dchar] transform(immutable string[int] score_map) 19 | { 20 | int[dchar] new_map; 21 | 22 | foreach (entry; score_map.byKeyValue()) 23 | { 24 | if (!allAlphaUpper(entry.value)) 25 | { 26 | throw new Exception(format("Invalid input %s", entry.value)); 27 | } 28 | 29 | entry.value.each!((dchar c) => new_map[toLower(c)] = entry.key); 30 | } 31 | 32 | return new_map; 33 | } 34 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to add flower counts to empty squares in a completed Flower Field garden. 4 | The garden itself is a rectangle board composed of squares that are either empty (`' '`) or a flower (`'*'`). 5 | 6 | For each empty square, count the number of flowers adjacent to it (horizontally, vertically, diagonally). 7 | If the empty square has no adjacent flowers, leave it empty. 8 | Otherwise replace it with the count of adjacent flowers. 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/flower-field/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Flower Field][history] is a compassionate reimagining of the popular game Minesweeper. 4 | The object of the game is to find all the flowers in the garden using numeric hints that indicate how many flowers are directly adjacent (horizontally, vertically, diagonally) to a square. 5 | "Flower Field" shipped in regional versions of Microsoft Windows in Italy, Germany, South Korea, Japan and Taiwan. 6 | 7 | [history]: https://web.archive.org/web/20020409051321fw_/http://rcm.usr.dsi.unimi.it/rcmweb/fnm/ 8 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/flower_field.d" 8 | ], 9 | "test": [ 10 | "source/flower_field.d" 11 | ], 12 | "example": [ 13 | "example/flower_field.d" 14 | ] 15 | }, 16 | "blurb": "Mark all the flowers in a garden." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/flower-field/dub.sdl: -------------------------------------------------------------------------------- 1 | name "flower-field" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/food_chain.d" 8 | ], 9 | "test": [ 10 | "source/food_chain.d" 11 | ], 12 | "example": [ 13 | "example/food_chain.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "food-chain" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/game_of_life.d" 8 | ], 9 | "test": [ 10 | "source/game_of_life.d" 11 | ], 12 | "example": [ 13 | "example/game_of_life.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "game-of-life" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/example/game_of_life.d: -------------------------------------------------------------------------------- 1 | module game_of_life; 2 | 3 | import std.algorithm : max, min; 4 | 5 | pure int[][] tick(immutable int[][] matrix) 6 | { 7 | int[][] result; 8 | size_t numRows = matrix.length; 9 | if (numRows == 0) 10 | { 11 | return result; 12 | } 13 | size_t numColumns = matrix[0].length; 14 | result.length = numRows; 15 | for (size_t row = 0; row < numRows; ++row) 16 | { 17 | result[row].length = numColumns; 18 | for (size_t column = 0; column < numColumns; ++column) 19 | { 20 | int previous = matrix[row][column]; 21 | int count = -previous; 22 | for (size_t r = max(1, row) - 1; r < min(numRows, row + 2); ++r) 23 | { 24 | for (size_t c = max(1, column) - 1; c < min(numColumns, column + 2); ++c) 25 | { 26 | count += matrix[r][c]; 27 | } 28 | } 29 | 30 | if (count == 3 || (count == 2 && previous == 1)) 31 | { 32 | result[row][column] = 1; 33 | } 34 | } 35 | } 36 | return result; 37 | } 38 | -------------------------------------------------------------------------------- /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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/gigasecond.d" 14 | ], 15 | "test": [ 16 | "source/gigasecond.d" 17 | ], 18 | "example": [ 19 | "example/gigasecond.d" 20 | ] 21 | }, 22 | "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", 23 | "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", 24 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=09" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.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 | [92fbe71c-ea52-4fac-bd77-be38023cacf7] 13 | description = "date only specification of time" 14 | 15 | [6d86dd16-6f7a-47be-9e58-bb9fb2ae1433] 16 | description = "second test for date only specification of time" 17 | 18 | [77eb8502-2bca-4d92-89d9-7b39ace28dd5] 19 | description = "third test for date only specification of time" 20 | 21 | [c9d89a7d-06f8-4e28-a305-64f1b2abc693] 22 | description = "full time specified" 23 | 24 | [09d4e30e-728a-4b52-9005-be44a58d9eba] 25 | description = "full time with day roll-over" 26 | 27 | [fcec307c-7529-49ab-b0fe-20309197618a] 28 | description = "does not mutate the input" 29 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/dub.sdl: -------------------------------------------------------------------------------- 1 | name "gigasecond" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/example/gigasecond.d: -------------------------------------------------------------------------------- 1 | module gigasecond; 2 | 3 | import std.datetime; 4 | import core.time : seconds; 5 | 6 | enum Gigasecond = seconds(10 ^^ 9); 7 | 8 | DateTime add(in DateTime start) pure 9 | { 10 | return start + Gigasecond; 11 | } 12 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/source/gigasecond.d: -------------------------------------------------------------------------------- 1 | module gigasecond; 2 | 3 | import std.datetime; 4 | 5 | unittest 6 | { 7 | immutable int allTestsEnabled = 0; 8 | 9 | // Date only specification of time 10 | assert(add(DateTime(2011, 4, 25)) == DateTime(2043, 1, 1, 1, 46, 40)); 11 | 12 | static if (allTestsEnabled) 13 | { 14 | // Second test for date only specification of time" 15 | assert(add(DateTime(1977, 6, 13)) == DateTime(2009, 2, 19, 1, 46, 40)); 16 | 17 | // Third test for date only specification of time 18 | assert(add(DateTime(1959, 7, 19)) == DateTime(1991, 3, 27, 1, 46, 40)); 19 | 20 | // Full time specified 21 | assert(add(DateTime(2015, 1, 24, 22, 0, 0)) == DateTime(2046, 10, 2, 23, 46, 40)); 22 | 23 | // Full time with day roll-over 24 | assert(add(DateTime(2015, 1, 24, 23, 59, 59)) == DateTime(2046, 10, 3, 1, 46, 39)); 25 | 26 | // Does not mutate the input 27 | auto d = DateTime(2015, 1, 24, 23, 59, 59); 28 | assert(add(d) == DateTime(2046, 10, 3, 1, 46, 39)); 29 | assert(d == DateTime(2015, 1, 24, 23, 59, 59)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given students' names along with the grade they are in, create a roster for the school. 4 | 5 | In the end, you should be able to: 6 | 7 | - Add a student's name to the roster for a grade: 8 | - "Add Jim to grade 2." 9 | - "OK." 10 | - Get a list of all students enrolled in a grade: 11 | - "Which students are in grade 2?" 12 | - "We've only got Jim right now." 13 | - Get a sorted list of all students in all grades. 14 | Grades should be sorted as 1, 2, 3, etc., and students within a grade should be sorted alphabetically by name. 15 | - "Who is enrolled in school right now?" 16 | - "Let me think. 17 | We have Anna, Barb, and Charlie in grade 1, Alex, Peter, and Zoe in grade 2, and Jim in grade 5. 18 | So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe, and Jim." 19 | 20 | Note that all our students only have one name (it's a small town, what do you want?), and each student cannot be added more than once to a grade or the roster. 21 | If a test attempts to add the same student more than once, your implementation should indicate that this is incorrect. 22 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/grade_school.d" 8 | ], 9 | "test": [ 10 | "source/grade_school.d" 11 | ], 12 | "example": [ 13 | "example/grade_school.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "grade-school" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/example/grade_school.d: -------------------------------------------------------------------------------- 1 | module grade_school; 2 | 3 | import std.algorithm; 4 | import std.array; 5 | 6 | struct GradeSchool 7 | { 8 | bool add(immutable string student, immutable int grade) 9 | { 10 | if (student in students) 11 | { 12 | return false; 13 | } 14 | 15 | students[student] = grade; 16 | return true; 17 | } 18 | 19 | string[] grade(int grade) 20 | { 21 | return students 22 | .byKeyValue 23 | .filter!(kvp => kvp.value == grade) 24 | .map!(kvp => kvp.key) 25 | .array 26 | .sort 27 | .array; 28 | } 29 | 30 | string[] roster() 31 | { 32 | return students 33 | .byKeyValue 34 | .array 35 | .sort!((a, b) => a.value < b.value || (a.value == b.value && a.key < b.key)) 36 | .map!(kvp => kvp.key) 37 | .array; 38 | } 39 | 40 | private: 41 | int[string] students; 42 | } 43 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/grains.d" 11 | ], 12 | "test": [ 13 | "source/grains.d" 14 | ], 15 | "example": [ 16 | "example/grains.d" 17 | ] 18 | }, 19 | "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", 20 | "source": "The CodeRanch Cattle Drive, Assignment 6", 21 | "source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/grains/dub.sdl: -------------------------------------------------------------------------------- 1 | name "grains" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/grains/example/grains.d: -------------------------------------------------------------------------------- 1 | module grains; 2 | 3 | import std.algorithm.iteration : fold; 4 | import std.exception : enforce; 5 | import std.range : iota; 6 | import std.math : pow; 7 | 8 | pure ulong square(immutable ulong num) 9 | { 10 | enforce(num > 0 && num < 65, "square must be between 1 and 64"); 11 | return pow(2, (num - 1)); 12 | } 13 | 14 | pure ulong total() 15 | { 16 | return iota(1, 65).fold!((sum, n) => sum + square(n)); 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/grains/source/grains.d: -------------------------------------------------------------------------------- 1 | module grains; 2 | 3 | pure ulong square(immutable ulong num) 4 | { 5 | // implement this function 6 | } 7 | 8 | pure ulong total() 9 | { 10 | // implement this function 11 | } 12 | 13 | unittest 14 | { 15 | import std.exception : assertThrown; 16 | 17 | immutable int allTestsEnabled = 0; 18 | 19 | // Returns the number of grains on the square 20 | assert(square(1) == 1); 21 | 22 | static if (allTestsEnabled) 23 | { 24 | assert(square(2) == 2); 25 | assert(square(3) == 4); 26 | assert(square(4) == 8); 27 | assert(square(16) == 32_768); 28 | assert(square(32) == 2_147_483_648uL); 29 | assert(square(64) == 9_223_372_036_854_775_808uL); 30 | 31 | // Square 0 raises an exception 32 | assertThrown(square(0)); 33 | 34 | // Negative square raises an exception 35 | assertThrown(square(-1)); 36 | 37 | // Square greater than 64 raises an exception 38 | assertThrown(square(65)); 39 | 40 | // Returns the total number of grains on the board 41 | assert(total() == 18_446_744_073_709_551_615uL); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.approaches/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "introduction": { 3 | "authors": [ 4 | "bobahop" 5 | ] 6 | }, 7 | "approaches": [ 8 | { 9 | "uuid": "a8b3febf-2c8b-4ad3-8169-f5b2665a5ddd", 10 | "slug": "zip-count", 11 | "title": "zip with count", 12 | "blurb": "Use zip with count to return the answer.", 13 | "authors": [ 14 | "bobahop" 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.approaches/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | There are several ways to solve Hamming. 4 | One approach is to use the [`zip`][zip] method with the [`count`][count] method. 5 | 6 | ## Approach: `zip` with `count` 7 | 8 | ```d 9 | module hamming; 10 | 11 | import std.algorithm.searching : count; 12 | import std.exception : enforce; 13 | import std.range : zip; 14 | 15 | @safe pure ulong distance(string a, string b) 16 | { 17 | enforce(a.length == b.length, "strands must be of equal length"); 18 | return a.zip(b) 19 | .count!((strands) => strands[0] != strands[1]); 20 | } 21 | ``` 22 | 23 | For more information, check the [`zip` with `count` approach][approach-zip-count]. 24 | 25 | [approach-zip-count]: https://exercism.org/tracks/d/exercises/hamming/approaches/zip-count 26 | [zip]: https://dlang.org/phobos/std_range.html#zip 27 | [count]: https://dlang.org/phobos/std_algorithm_searching.html#count 28 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.approaches/zip-count/snippet.txt: -------------------------------------------------------------------------------- 1 | return a.zip(b) 2 | .count!((strands) => strands[0] != strands[1]); 3 | -------------------------------------------------------------------------------- /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 | "contributors": [ 4 | "amscotti", 5 | "celavek", 6 | "kytrinyx", 7 | "petertseng", 8 | "sjwarner-bp", 9 | "tmccombs" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/hamming.d" 14 | ], 15 | "test": [ 16 | "source/hamming.d" 17 | ], 18 | "example": [ 19 | "example/hamming.d" 20 | ] 21 | }, 22 | "blurb": "Calculate the Hamming distance between two DNA strands.", 23 | "source": "The Calculating Point Mutations problem at Rosalind", 24 | "source_url": "https://rosalind.info/problems/hamm/" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/hamming/dub.sdl: -------------------------------------------------------------------------------- 1 | name "hamming" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/hamming/example/hamming.d: -------------------------------------------------------------------------------- 1 | module hamming; 2 | 3 | import std.string; 4 | import std.algorithm.comparison : mismatch; 5 | import std.exception : enforce; 6 | 7 | pure int distance(immutable string lhs, immutable string rhs) 8 | { 9 | enforce(lhs.length == rhs.length, "left and right strands must be of equal length"); 10 | 11 | int count = 0; 12 | auto m = mismatch(lhs, rhs); 13 | 14 | while (!m[0].empty) 15 | { 16 | ++count; 17 | m = mismatch(m[0][1 .. $], m[1][1 .. $]); 18 | } 19 | 20 | return count; 21 | } 22 | -------------------------------------------------------------------------------- /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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp", 10 | "son1112" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "source/hello_world.d" 15 | ], 16 | "test": [ 17 | "source/hello_world.d" 18 | ], 19 | "example": [ 20 | "example/hello_world.d" 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/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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "hello-world" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/example/hello_world.d: -------------------------------------------------------------------------------- 1 | module helloworld; 2 | 3 | string hello() 4 | { 5 | return "Hello, World!"; 6 | } 7 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/source/hello_world.d: -------------------------------------------------------------------------------- 1 | module hello_world; 2 | 3 | string hello() 4 | { 5 | return "Goodbye, Mars!"; 6 | } 7 | 8 | unittest 9 | { 10 | assert(hello() == "Hello, World!"); 11 | } 12 | -------------------------------------------------------------------------------- /exercises/practice/house/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/house.d" 8 | ], 9 | "test": [ 10 | "source/house.d" 11 | ], 12 | "example": [ 13 | "example/house.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "house" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/house/example/house.d: -------------------------------------------------------------------------------- 1 | module house; 2 | 3 | import std.string; 4 | 5 | pure string reciteVerse(int verse) 6 | { 7 | immutable string lyrics = 8 | "This is the horse and the hound and the horn that belonged to the farmer sowing his corn that kept the rooster that crowed in the morn that woke the priest all shaven and shorn that married the man all tattered and torn that kissed the maiden all forlorn that milked the cow with the crumpled horn that tossed the dog that worried the cat that killed the rat that ate the malt that lay in the house that Jack built."; 9 | 10 | immutable size_t prefixLength = 8; 11 | 12 | immutable size_t[] table = [ 0, 389, 368, 351, 331, 310, 267, 232, 190, 145, 99, 62, 8 ]; 13 | 14 | return lyrics[0 .. prefixLength] ~ lyrics[table[verse] .. lyrics.length]; 15 | } 16 | 17 | pure string recite(int startVerse, int endVerse) 18 | { 19 | string result; 20 | for (int verse = startVerse; verse < endVerse; ++verse) 21 | { 22 | result ~= reciteVerse(verse); 23 | result ~= "\n"; 24 | } 25 | result ~= reciteVerse(endVerse); 26 | return result; 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/intergalactic-transmission/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/intergalactic_transmission.d" 8 | ], 9 | "test": [ 10 | "source/intergalactic_transmission.d" 11 | ], 12 | "example": [ 13 | "example/intergalactic_transmission.d" 14 | ] 15 | }, 16 | "blurb": "Add parity bits to a message for transmission", 17 | "source": "Kah Goh", 18 | "source_url": "https://github.com/exercism/problem-specifications/pull/2543" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/intergalactic-transmission/dub.sdl: -------------------------------------------------------------------------------- 1 | name "intergalactic-transmission" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/isbn_verifier.d" 8 | ], 9 | "test": [ 10 | "source/isbn_verifier.d" 11 | ], 12 | "example": [ 13 | "example/isbn_verifier.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "isbn-verifier" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/example/isbn_verifier.d: -------------------------------------------------------------------------------- 1 | module isbn_verifier; 2 | 3 | import std.ascii : isDigit; 4 | 5 | pure bool isValid(immutable string isbn) 6 | { 7 | auto total = 0; 8 | auto weightedTotal = 0; 9 | auto remainingDigits = 10; 10 | 11 | foreach (c; isbn) { 12 | if (c == '-') 13 | { 14 | continue; 15 | } 16 | 17 | --remainingDigits; 18 | 19 | if (isDigit(c)) 20 | { 21 | total += c - '0'; 22 | } 23 | else if (remainingDigits == 0 && c == 'X') 24 | { 25 | total += 10; 26 | } 27 | else 28 | { 29 | return false; 30 | } 31 | 32 | weightedTotal += total; 33 | } 34 | 35 | return remainingDigits == 0 && weightedTotal % 11 == 0; 36 | } 37 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.approaches/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "introduction": { 3 | "authors": [ 4 | "bobahop" 5 | ] 6 | }, 7 | "approaches": [ 8 | { 9 | "uuid": "dde5f357-b1f8-4079-991a-a326b0ce6e1a", 10 | "slug": "filter-map-foreach", 11 | "title": "filter and map with foreach", 12 | "blurb": "Use filter and map with foreach to return the answer.", 13 | "authors": [ 14 | "bobahop" 15 | ] 16 | }, 17 | { 18 | "uuid": "92f8d92b-9d11-45cc-bbeb-faf965d51ac0", 19 | "slug": "filter-map-fold", 20 | "title": "filter and map with fold", 21 | "blurb": "Use filter and map with fold to return the answer.", 22 | "authors": [ 23 | "bobahop" 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.approaches/filter-map-fold/snippet.txt: -------------------------------------------------------------------------------- 1 | uint letters = 0; 2 | return (phrase.filter!isAlpha 3 | .map!toLower 4 | .fold!((a, c) => 5 | a & (1 << (c - 'a')) ? a | (1 << 26) : a | (1 << (c - 'a')))(letters) & (1 << 26)) == 0; 6 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.approaches/filter-map-foreach/snippet.txt: -------------------------------------------------------------------------------- 1 | foreach (ltr; phrase.filter!isAlpha 2 | .map!toLower) 3 | { 4 | if (!(ltrs & (1 << (ltr - 'a')))) 5 | ltrs = ltrs | (1 << (ltr - 'a')); 6 | else 7 | return false; 8 | } 9 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/isogram.d" 11 | ], 12 | "test": [ 13 | "source/isogram.d" 14 | ], 15 | "example": [ 16 | "example/isogram.d" 17 | ] 18 | }, 19 | "blurb": "Determine if a word or phrase is an isogram.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Isogram" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/isogram/dub.sdl: -------------------------------------------------------------------------------- 1 | name "isogram" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/isogram/example/isogram.d: -------------------------------------------------------------------------------- 1 | module isogram; 2 | 3 | import std.algorithm : count, uniq; 4 | import std.algorithm.iteration : filter; 5 | import std.algorithm.sorting : sort; 6 | import std.ascii : isAlpha; 7 | import std.string : toLower; 8 | import std.utf : byCodeUnit; 9 | 10 | pure bool isIsogram(immutable string phrase) 11 | { 12 | char[] phraseArray = phrase.toLower.dup; 13 | auto clean = sort(phraseArray.byCodeUnit).filter!(isAlpha); 14 | return clean.count == clean.uniq.count; 15 | } 16 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/kindergarten_garden.d" 8 | ], 9 | "test": [ 10 | "source/kindergarten_garden.d" 11 | ], 12 | "example": [ 13 | "example/kindergarten_garden.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "kindergarten-garden" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/example/kindergarten_garden.d: -------------------------------------------------------------------------------- 1 | module kindergarten_garden; 2 | 3 | private pure string plant(dchar c) 4 | { 5 | switch(c) 6 | { 7 | case 'G': 8 | return "grass"; 9 | case 'C': 10 | return "clover"; 11 | case 'R': 12 | return "radishes"; 13 | case 'V': 14 | return "violets"; 15 | default: 16 | assert(0); 17 | } 18 | } 19 | 20 | pure string[4] plants(immutable string diagram, immutable string student) 21 | { 22 | auto first = 2 * (student[0] - 'A'); 23 | auto second = first + 1; 24 | auto third = (1 + diagram.length) / 2 + first; 25 | auto fourth = third + 1; 26 | return [ 27 | plant(diagram[first]), 28 | plant(diagram[second]), 29 | plant(diagram[third]), 30 | plant(diagram[fourth]), 31 | ]; 32 | } 33 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/knapsack.d" 8 | ], 9 | "test": [ 10 | "source/knapsack.d" 11 | ], 12 | "example": [ 13 | "example/knapsack.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "knapsack" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/example/knapsack.d: -------------------------------------------------------------------------------- 1 | module knapack; 2 | 3 | struct Item { 4 | uint weight; 5 | uint value; 6 | } 7 | 8 | uint maximumValue(Item[] items, uint maximumWeight) 9 | { 10 | auto table = new uint[](maximumWeight + 1); 11 | foreach (item; items) { 12 | uint index = maximumWeight + 1; 13 | while (index > item.weight) { 14 | --index; 15 | auto value = item.value + table[index - item.weight]; 16 | if (table[index] < value) { 17 | table[index] = value; 18 | } 19 | } 20 | } 21 | return table[maximumWeight]; 22 | } 23 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/largest_series_product.d" 8 | ], 9 | "test": [ 10 | "source/largest_series_product.d" 11 | ], 12 | "example": [ 13 | "example/largest_series_product.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "largest-series-product" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/example/largest_series_product.d: -------------------------------------------------------------------------------- 1 | module largest_series_product; 2 | 3 | import std.ascii : isDigit; 4 | import std.algorithm : max; 5 | import std.algorithm.iteration : reduce; 6 | 7 | pure ulong largestProduct(immutable string digits, int span) 8 | { 9 | foreach(c; digits) 10 | { 11 | if (!isDigit(c)) 12 | { 13 | throw new Exception("digits input must only contain digits"); 14 | } 15 | } 16 | 17 | if (span < 0) 18 | { 19 | throw new Exception("span must not be negative"); 20 | } 21 | 22 | if (span == 0) 23 | { 24 | return 1; 25 | } 26 | 27 | if (digits.length < span) 28 | { 29 | throw new Exception("span must be smaller than string length"); 30 | } 31 | 32 | ulong result = 0; 33 | for (size_t begin = 0; begin + span <= digits.length; ++begin) 34 | { 35 | result = max(result, reduce!((product, c) => product * (c - '0')) 36 | (1uL, digits[begin..(begin + span)])); 37 | } 38 | return result; 39 | } 40 | -------------------------------------------------------------------------------- /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 | "petertseng" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "sjwarner-bp" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/leap.d" 13 | ], 14 | "test": [ 15 | "source/leap.d" 16 | ], 17 | "example": [ 18 | "example/leap.d" 19 | ] 20 | }, 21 | "blurb": "Determine whether a given year is a leap year.", 22 | "source": "CodeRanch Cattle Drive, Assignment 3", 23 | "source_url": "https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/leap/dub.sdl: -------------------------------------------------------------------------------- 1 | name "leap" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/leap/example/leap.d: -------------------------------------------------------------------------------- 1 | module leap; 2 | 3 | pure bool isLeap(immutable uint year) 4 | { 5 | pure bool divBy(immutable uint n) 6 | { 7 | return year % n == 0; 8 | } 9 | 10 | return divBy(4) && (!divBy(100) || divBy(400)); 11 | } 12 | -------------------------------------------------------------------------------- /exercises/practice/leap/source/leap.d: -------------------------------------------------------------------------------- 1 | module leap; 2 | 3 | unittest 4 | { 5 | immutable int allTestsEnabled = 0; 6 | 7 | // Year not divisible by 4 in common year 8 | assert(!isLeap(2015)); 9 | 10 | static if (allTestsEnabled) 11 | { 12 | // Year divisible by 2, not divisible by 4 in common year 13 | assert(!isLeap(1970)); 14 | 15 | // Year divisible by 4, not divisible by 100 in leap year 16 | assert(isLeap(1996)); 17 | 18 | // Year divisible by 4 and 5 is still a leap year 19 | assert(isLeap(1960)); 20 | 21 | // Year divisible by 100, not divisible by 400 in common year 22 | assert(!isLeap(2100)); 23 | 24 | // Year divisible by 100 but not by 3 is still not a leap year 25 | assert(!isLeap(1900)); 26 | 27 | // Year divisible by 400 in leap year 28 | assert(isLeap(2000)); 29 | 30 | // Year divisible by 400 but not by 125 is still a leap year 31 | assert(isLeap(2400)); 32 | 33 | // Year divisible by 200, not divisible by 400 in common year 34 | assert(!isLeap(1800)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/luhn.d" 11 | ], 12 | "test": [ 13 | "source/luhn.d" 14 | ], 15 | "example": [ 16 | "example/luhn.d" 17 | ] 18 | }, 19 | "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", 20 | "source": "The Luhn Algorithm on Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/luhn/dub.sdl: -------------------------------------------------------------------------------- 1 | name "luhn" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/luhn/example/luhn.d: -------------------------------------------------------------------------------- 1 | import std.ascii : isDigit, isWhite; 2 | import std.algorithm; 3 | import std.algorithm.searching : all; 4 | import std.algorithm.mutation : reverse; 5 | import std.conv : to; 6 | import std.range : array; 7 | 8 | pure bool valid(immutable string input) 9 | { 10 | auto clean = input.filter!(a => !a.isWhite); 11 | if (clean.count <= 1 || !clean.all!(isDigit)) 12 | { 13 | return false; 14 | } 15 | 16 | immutable int[] arr = clean.map!(to!string) 17 | .map!(to!int) 18 | .array 19 | .reverse; 20 | 21 | int doubleEverySecond = 0; 22 | 23 | foreach (index, number; arr) 24 | { 25 | immutable int b = index % 2 != 0 ? number * 2 : number; 26 | doubleEverySecond += b > 9 ? b - 9 : b; 27 | } 28 | 29 | return doubleEverySecond % 10 == 0; 30 | } 31 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/matching_brackets.d" 11 | ], 12 | "test": [ 13 | "source/matching_brackets.d" 14 | ], 15 | "example": [ 16 | "example/matching_brackets.d" 17 | ] 18 | }, 19 | "blurb": "Make sure the brackets and braces all match.", 20 | "source": "Ginna Baker" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/dub.sdl: -------------------------------------------------------------------------------- 1 | name "matching-brackets" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/example/matching_brackets.d: -------------------------------------------------------------------------------- 1 | module matching_brackets; 2 | 3 | import std.array : array, back, empty, popBack; 4 | import std.string : indexOf; 5 | 6 | static immutable string open = "[{("; 7 | static immutable string close = "]})"; 8 | 9 | pure bool isPaired(immutable string input) 10 | { 11 | dchar[] stack; 12 | 13 | foreach (immutable c; input.array) 14 | { 15 | if (open.indexOf(c) != -1) 16 | { 17 | stack ~= c; 18 | } 19 | else if (close.indexOf(c) != -1) 20 | { 21 | if (stack.empty || open[close.indexOf(c)] != stack.back) 22 | { 23 | return false; 24 | } 25 | stack.popBack(); 26 | } 27 | } 28 | 29 | return stack.empty; 30 | } 31 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/micro_blog.d" 8 | ], 9 | "test": [ 10 | "source/micro_blog.d" 11 | ], 12 | "example": [ 13 | "example/micro_blog.d" 14 | ] 15 | }, 16 | "blurb": "Given an input string, truncate it to 5 characters." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/dub.sdl: -------------------------------------------------------------------------------- 1 | name "micro-blog" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/example/micro_blog.d: -------------------------------------------------------------------------------- 1 | module micro_blog; 2 | 3 | import std.algorithm : min; 4 | import std.conv : to; 5 | 6 | pure string truncate(immutable string phrase) 7 | { 8 | dstring str = phrase.to!dstring; 9 | return str[0..min(5, str.length)].to!string; 10 | } 11 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/minesweeper.d" 8 | ], 9 | "test": [ 10 | "source/minesweeper.d" 11 | ], 12 | "example": [ 13 | "example/minesweeper.d" 14 | ] 15 | }, 16 | "blurb": "Add the numbers to a minesweeper board." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/dub.sdl: -------------------------------------------------------------------------------- 1 | name "minesweeper" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/nth_prime.d" 11 | ], 12 | "test": [ 13 | "source/nth_prime.d" 14 | ], 15 | "example": [ 16 | "example/nth_prime.d" 17 | ] 18 | }, 19 | "blurb": "Given a number n, determine what the nth prime is.", 20 | "source": "A variation on Problem 7 at Project Euler", 21 | "source_url": "https://projecteuler.net/problem=7" 22 | } 23 | -------------------------------------------------------------------------------- /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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "nth-prime" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/example/nth_prime.d: -------------------------------------------------------------------------------- 1 | module nth_prime; 2 | 3 | import std.exception : enforce; 4 | import std.math : sqrt; 5 | import std.conv; 6 | 7 | pure int prime(immutable int number) 8 | { 9 | enforce(number > 0, "There is no zeroth prime"); 10 | 11 | int primes = 0; 12 | int i = 1; 13 | 14 | while (primes < number) 15 | { 16 | i += 1; 17 | if (isPrime(i)) 18 | { 19 | primes += 1; 20 | } 21 | } 22 | return i; 23 | } 24 | 25 | private pure bool isPrime(immutable int n) 26 | { 27 | if (n == 1) 28 | { 29 | return false; 30 | } 31 | if (n == 2) 32 | { 33 | return true; 34 | } 35 | for (int i = 2; i <= sqrt(to!double(n)); i++) 36 | { 37 | if (n % i == 0) 38 | { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/source/nth_prime.d: -------------------------------------------------------------------------------- 1 | module nth_prime; 2 | 3 | pure int prime(immutable int number) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | import std.exception : assertThrown; 11 | 12 | immutable int allTestsEnabled = 0; 13 | 14 | // First prime 15 | assert(prime(1) == 2); 16 | 17 | static if (allTestsEnabled) 18 | { 19 | // Second prime 20 | assert(prime(2) == 3); 21 | 22 | // Sixth prime 23 | assert(prime(6) == 13); 24 | 25 | // Big prime 26 | assert(prime(10_001) == 10_4743); 27 | 28 | // There is no zeroth prime 29 | assertThrown(prime(0)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/nucleotide_count.d" 13 | ], 14 | "test": [ 15 | "source/nucleotide_count.d" 16 | ], 17 | "example": [ 18 | "example/nucleotide_count.d" 19 | ] 20 | }, 21 | "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", 22 | "source": "The Calculating DNA Nucleotides_problem at Rosalind", 23 | "source_url": "https://rosalind.info/problems/dna/" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.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 | [3e5c30a8-87e2-4845-a815-a49671ade970] 13 | description = "empty strand" 14 | 15 | [a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] 16 | description = "can count one nucleotide in single-character input" 17 | 18 | [eca0d565-ed8c-43e7-9033-6cefbf5115b5] 19 | description = "strand with repeated nucleotide" 20 | 21 | [40a45eac-c83f-4740-901a-20b22d15a39f] 22 | description = "strand with multiple nucleotides" 23 | 24 | [b4c47851-ee9e-4b0a-be70-a86e343bd851] 25 | description = "strand with invalid nucleotides" 26 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/dub.sdl: -------------------------------------------------------------------------------- 1 | name "nucleotide-count" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.approaches/all-find/snippet.txt: -------------------------------------------------------------------------------- 1 | private immutable abc = "abcdefghijklmnopqrstuvwxyz"; 2 | 3 | @safe pure bool isPangram(string text) 4 | { 5 | auto textLowered = text.toLower; 6 | return abc.all!((ltr) => !textLowered.find(ltr).empty); 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.approaches/bitwise-filter-fold/snippet.txt: -------------------------------------------------------------------------------- 1 | @safe pure bool isPangram(string text) 2 | { 3 | uint letters = 0; 4 | return text.toLower 5 | .filter!isAlpha 6 | .fold!((a, b) => a | (1 << (b - 'a')))(letters) == 0b00000011_1111_1111_1111_1111_1111_1111; 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.approaches/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "introduction": { 3 | "authors": [ 4 | "bobahop" 5 | ] 6 | }, 7 | "approaches": [ 8 | { 9 | "uuid": "7a98843c-4dd0-4c30-962d-021141c43635", 10 | "slug": "bitwise-filter-fold", 11 | "title": "bitwise operations with filter and fold", 12 | "blurb": "Use bitwise operations with filter and fold to return the answer.", 13 | "authors": [ 14 | "bobahop" 15 | ] 16 | }, 17 | { 18 | "uuid": "c9807c77-adb9-49c7-9dfc-7164d69147f8", 19 | "slug": "all-find", 20 | "title": "all with find", 21 | "blurb": "Use all with find to return the answer.", 22 | "authors": [ 23 | "bobahop" 24 | ] 25 | }, 26 | { 27 | "uuid": "886a22e0-906f-4f55-95a9-76071d5f326c", 28 | "slug": "filter-sort-uniq-count", 29 | "title": "filter and sort with uniq and count", 30 | "blurb": "Use filter and sort with uniq and count to return the answer.", 31 | "authors": [ 32 | "bobahop" 33 | ] 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.approaches/filter-sort-uniq-count/snippet.txt: -------------------------------------------------------------------------------- 1 | @safe pure bool isPangram(string text) { 2 | return text.filter!isAlpha 3 | .map!toLower 4 | .array 5 | .sort 6 | .uniq 7 | .count == 26; 8 | } 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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp", 10 | "TheSmartnik" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "source/pangram.d" 15 | ], 16 | "test": [ 17 | "source/pangram.d" 18 | ], 19 | "example": [ 20 | "example/pangram.d" 21 | ] 22 | }, 23 | "blurb": "Determine if a sentence is a pangram.", 24 | "source": "Wikipedia", 25 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/pangram/dub.sdl: -------------------------------------------------------------------------------- 1 | name "pangram" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/pangram/example/pangram.d: -------------------------------------------------------------------------------- 1 | module pangram; 2 | 3 | import std.uni : toLower; 4 | 5 | pure bool isPangram(immutable string str) 6 | { 7 | bool[dchar] letters; 8 | foreach (char letter; str) 9 | { 10 | auto lower = toLower(letter); 11 | if (lower >= 'a' && lower <= 'z') 12 | { 13 | letters[lower] = true; 14 | } 15 | } 16 | return letters.length == 26; 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/pascals_triangle.d" 8 | ], 9 | "test": [ 10 | "source/pascals_triangle.d" 11 | ], 12 | "example": [ 13 | "example/pascals_triangle.d" 14 | ] 15 | }, 16 | "blurb": "Compute Pascal's triangle up to a given number of rows.", 17 | "source": "Pascal's Triangle at Wolfram Math World", 18 | "source_url": "https://www.wolframalpha.com/input/?i=Pascal%27s+triangle" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.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 | [9920ce55-9629-46d5-85d6-4201f4a4234d] 13 | description = "zero rows" 14 | 15 | [70d643ce-a46d-4e93-af58-12d88dd01f21] 16 | description = "single row" 17 | 18 | [a6e5a2a2-fc9a-4b47-9f4f-ed9ad9fbe4bd] 19 | description = "two rows" 20 | 21 | [97206a99-79ba-4b04-b1c5-3c0fa1e16925] 22 | description = "three rows" 23 | 24 | [565a0431-c797-417c-a2c8-2935e01ce306] 25 | description = "four rows" 26 | 27 | [06f9ea50-9f51-4eb2-b9a9-c00975686c27] 28 | description = "five rows" 29 | 30 | [c3912965-ddb4-46a9-848e-3363e6b00b13] 31 | description = "six rows" 32 | 33 | [6cb26c66-7b57-4161-962c-81ec8c99f16b] 34 | description = "ten rows" 35 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/dub.sdl: -------------------------------------------------------------------------------- 1 | name "pascals-triangle" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/example/pascals_triangle.d: -------------------------------------------------------------------------------- 1 | module pascals_triangle; 2 | 3 | pure int[][] rows(int count) 4 | { 5 | int[][] result = new int[][](count); 6 | int[] previous; 7 | for (int i = 0; i < count; ++i) 8 | { 9 | int[] current = new int[](i + 1); 10 | current[0] = 1; 11 | for (int j = 1; j < i; ++j) 12 | { 13 | current[j] = previous[j - 1] + previous[j]; 14 | } 15 | current[i] = 1; 16 | result[i] = current; 17 | previous = current; 18 | } 19 | return result; 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/perfect_numbers.d" 11 | ], 12 | "test": [ 13 | "source/perfect_numbers.d" 14 | ], 15 | "example": [ 16 | "example/perfect_numbers.d" 17 | ] 18 | }, 19 | "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.", 20 | "source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.", 21 | "source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/dub.sdl: -------------------------------------------------------------------------------- 1 | name "perfect-numbers" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/example/perfect_numbers.d: -------------------------------------------------------------------------------- 1 | module perfect_numbers; 2 | 3 | import std.exception : enforce; 4 | 5 | enum Classification 6 | { 7 | DEFICIENT, 8 | PERFECT, 9 | ABUNDANT 10 | } 11 | 12 | pure Classification classify(immutable int input) 13 | { 14 | enforce(input > 0, "Classification is only possible for natural numbers"); 15 | 16 | int aliquot = 0; 17 | for (int i = 1; i < input; i++) 18 | { 19 | if (input % i == 0) 20 | { 21 | aliquot += i; 22 | } 23 | } 24 | 25 | if (aliquot == input) 26 | { 27 | return Classification.PERFECT; 28 | } 29 | else if (aliquot > input) 30 | { 31 | return Classification.ABUNDANT; 32 | } 33 | else 34 | { 35 | return Classification.DEFICIENT; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/phone_number.d" 8 | ], 9 | "test": [ 10 | "source/phone_number.d" 11 | ], 12 | "example": [ 13 | "example/phone_number.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "phone-number" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/pig_latin.d" 8 | ], 9 | "test": [ 10 | "source/pig_latin.d" 11 | ], 12 | "example": [ 13 | "example/pig_latin.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "pig-latin" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/example/pig_latin.d: -------------------------------------------------------------------------------- 1 | module pig_latin; 2 | 3 | import std.array : join, split; 4 | import std.regex; 5 | 6 | string translate(immutable string input) 7 | { 8 | string[] results; 9 | string[] words = input.split(" "); 10 | 11 | auto vowelSound = regex("^([aeiou]|xr|yt)"); 12 | auto consonantSound = regex("^([^aeiou]+(?=y)|[^aeiou]?qu|[^aeiou]+)([a-z]+)"); 13 | 14 | foreach (word; words) 15 | { 16 | if (!word.matchFirst(vowelSound)) 17 | { 18 | auto m = word.matchAll(consonantSound); 19 | word = m.captures[2] ~ m.captures[1]; 20 | } 21 | 22 | results ~= word ~ "ay"; 23 | } 24 | return results.join(" "); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/prime_factors.d" 11 | ], 12 | "test": [ 13 | "source/prime_factors.d" 14 | ], 15 | "example": [ 16 | "example/prime_factors.d" 17 | ] 18 | }, 19 | "blurb": "Compute the prime factors of a given natural number.", 20 | "source": "The Prime Factors Kata by Uncle Bob", 21 | "source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/dub.sdl: -------------------------------------------------------------------------------- 1 | name "prime-factors" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/example/prime_factors.d: -------------------------------------------------------------------------------- 1 | module prime_factors; 2 | 3 | pure int[] factors(immutable long value) 4 | { 5 | long n = value; 6 | int d = 2; 7 | int[] result; 8 | 9 | while (n > 1) 10 | { 11 | while (n % d == 0) 12 | { 13 | n = n / d; 14 | result ~= d; 15 | } 16 | d++; 17 | } 18 | 19 | return result; 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/source/prime_factors.d: -------------------------------------------------------------------------------- 1 | module prime_factors; 2 | 3 | pure int[] factors(immutable long value) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | immutable int allTestsEnabled = 0; 11 | 12 | // No factors 13 | assert(factors(1) == []); 14 | 15 | static if (allTestsEnabled) 16 | { 17 | // Prime number 18 | assert(factors(2) == [2]); 19 | 20 | // Square of a prime 21 | assert(factors(9) == [3, 3]); 22 | 23 | // Cube of a prime 24 | assert(factors(8) == [2, 2, 2]); 25 | 26 | // Product of primes and non-primes 27 | assert(factors(12) == [2, 2, 3]); 28 | 29 | // Product of primes 30 | assert(factors(901_255) == [5, 17, 23, 461]); 31 | 32 | // Factors include a large prime 33 | assert(factors(93_819_012_551) == [11, 9539, 894_119]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/protein_translation.d" 8 | ], 9 | "test": [ 10 | "source/protein_translation.d" 11 | ], 12 | "example": [ 13 | "example/protein_translation.d" 14 | ] 15 | }, 16 | "blurb": "Translate RNA sequences into proteins.", 17 | "source": "Tyler Long" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/dub.sdl: -------------------------------------------------------------------------------- 1 | name "protein-translation" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/proverb.d" 8 | ], 9 | "test": [ 10 | "source/proverb.d" 11 | ], 12 | "example": [ 13 | "example/proverb.d" 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/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 | [e974b73e-7851-484f-8d6d-92e07fe742fc] 13 | description = "zero pieces" 14 | 15 | [2fcd5f5e-8b82-4e74-b51d-df28a5e0faa4] 16 | description = "one piece" 17 | 18 | [d9d0a8a1-d933-46e2-aa94-eecf679f4b0e] 19 | description = "two pieces" 20 | 21 | [c95ef757-5e94-4f0d-a6cb-d2083f5e5a83] 22 | description = "three pieces" 23 | 24 | [433fb91c-35a2-4d41-aeab-4de1e82b2126] 25 | description = "full proverb" 26 | 27 | [c1eefa5a-e8d9-41c7-91d4-99fab6d6b9f7] 28 | description = "four pieces modernized" 29 | -------------------------------------------------------------------------------- /exercises/practice/proverb/dub.sdl: -------------------------------------------------------------------------------- 1 | name "proverb" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/proverb/example/proverb.d: -------------------------------------------------------------------------------- 1 | module proverb; 2 | 3 | import std.array; 4 | 5 | pure string recite(immutable string[] strings) 6 | { 7 | if (strings.length == 0) return ""; 8 | 9 | string[] fragments; 10 | foreach (i, str; strings[0 .. strings.length - 1]) 11 | { 12 | fragments ~= "For want of a " ~ str ~ " the " ~ strings[i+1] ~ " was lost."; 13 | } 14 | 15 | fragments ~= "And all for the want of a " ~ strings[0] ~ "."; 16 | 17 | return fragments.join("\n"); 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | A Pythagorean triplet is a set of three natural numbers, {a, b, c}, for which, 4 | 5 | ```text 6 | a² + b² = c² 7 | ``` 8 | 9 | and such that, 10 | 11 | ```text 12 | a < b < c 13 | ``` 14 | 15 | For example, 16 | 17 | ```text 18 | 3² + 4² = 5². 19 | ``` 20 | 21 | Given an input integer N, find all Pythagorean triplets for which `a + b + c = N`. 22 | 23 | For example, with N = 1000, there is exactly one Pythagorean triplet for which `a + b + c = 1000`: `{200, 375, 425}`. 24 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/pythagorean_triplet.d" 8 | ], 9 | "test": [ 10 | "source/pythagorean_triplet.d" 11 | ], 12 | "example": [ 13 | "example/pythagorean_triplet.d" 14 | ] 15 | }, 16 | "blurb": "Given an integer N, find all Pythagorean triplets for which a + b + c = N.", 17 | "source": "A variation of Problem 9 from Project Euler", 18 | "source_url": "https://projecteuler.net/problem=9" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/dub.sdl: -------------------------------------------------------------------------------- 1 | name "pythagorean-triplet" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/example/pythagorean_triplet.d: -------------------------------------------------------------------------------- 1 | module pythagorean_triplet; 2 | 3 | struct Triplet { 4 | uint a; 5 | uint b; 6 | uint c; 7 | } 8 | 9 | // For every Pythagorean triplet with total a + b + c = n, 10 | // a² + b² = c² 11 | // <=> a² + b² = (n - a - b)², substituting c 12 | // <=> 0 = n² - 2*n*a - 2*n*b + 2*a*b 13 | // <=> (2*n - 2*a) b = (n² - 2*n*a) 14 | // <=> b = (n² - 2*n*a) / (2*n - 2*a) 15 | 16 | pure Triplet[] tripletsWithSum(uint n) 17 | { 18 | Triplet[] result; 19 | if (n < 2) 20 | { 21 | return result; 22 | } 23 | 24 | for (uint a = 1;;++a) 25 | { 26 | uint numerator = n * (n - 2 * a); 27 | uint denominator = 2 * (n - a); 28 | uint b = numerator / denominator; 29 | if (b <= a) 30 | { 31 | break; 32 | } 33 | if (numerator % denominator != 0) 34 | { 35 | continue; 36 | } 37 | uint c = n - a - b; 38 | result ~= Triplet(a, b, c); 39 | } 40 | return result; 41 | } 42 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to convert a number into its corresponding raindrop sounds. 4 | 5 | If a given number: 6 | 7 | - is divisible by 3, add "Pling" to the result. 8 | - is divisible by 5, add "Plang" to the result. 9 | - is divisible by 7, add "Plong" to the result. 10 | - **is not** divisible by 3, 5, or 7, the result should be the number as a string. 11 | 12 | ## Examples 13 | 14 | - 28 is divisible by 7, but not 3 or 5, so the result would be `"Plong"`. 15 | - 30 is divisible by 3 and 5, but not 7, so the result would be `"PlingPlang"`. 16 | - 34 is not divisible by 3, 5, or 7, so the result would be `"34"`. 17 | 18 | ~~~~exercism/note 19 | A common way to test if one number is evenly divisible by another is to compare the [remainder][remainder] or [modulus][modulo] to zero. 20 | Most languages provide operators or functions for one (or both) of these. 21 | 22 | [remainder]: https://exercism.org/docs/programming/operators/remainder 23 | [modulo]: https://en.wikipedia.org/wiki/Modulo_operation 24 | ~~~~ 25 | -------------------------------------------------------------------------------- /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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/raindrops.d" 14 | ], 15 | "test": [ 16 | "source/raindrops.d" 17 | ], 18 | "example": [ 19 | "example/raindrops.d" 20 | ] 21 | }, 22 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 23 | "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.", 24 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/dub.sdl: -------------------------------------------------------------------------------- 1 | name "raindrops" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/example/raindrops.d: -------------------------------------------------------------------------------- 1 | module raindrops; 2 | 3 | import std.array : appender; 4 | import std.format : formattedWrite; 5 | 6 | pure string convert(immutable int n) 7 | { 8 | auto builder = appender!string(); 9 | if (isPling(n) || isPlang(n) || isPlong(n)) 10 | { 11 | if (isPling(n)) 12 | { 13 | builder.put("Pling"); 14 | } 15 | if (isPlang(n)) 16 | { 17 | builder.put("Plang"); 18 | } 19 | if (isPlong(n)) 20 | { 21 | builder.put("Plong"); 22 | } 23 | } 24 | else 25 | { 26 | builder.formattedWrite("%s", n); 27 | } 28 | 29 | return builder.data; 30 | } 31 | 32 | private pure bool isPling(immutable int n) 33 | { 34 | return n % 3 == 0; 35 | } 36 | 37 | private pure bool isPlang(immutable int n) 38 | { 39 | return n % 5 == 0; 40 | } 41 | 42 | private pure bool isPlong(immutable int n) 43 | { 44 | return n % 7 == 0; 45 | } 46 | -------------------------------------------------------------------------------- /exercises/practice/react/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement a basic reactive system. 4 | 5 | Reactive programming is a programming paradigm that focuses on how values are computed in terms of each other to allow a change to one value to automatically propagate to other values, like in a spreadsheet. 6 | 7 | Implement a basic reactive system with cells with settable values ("input" cells) and cells with values computed in terms of other cells ("compute" cells). 8 | Implement updates so that when an input value is changed, values propagate to reach a new stable system state. 9 | 10 | In addition, compute cells should allow for registering change notification callbacks. 11 | Call a cell’s callbacks when the cell’s value in a new stable state has changed from the previous stable state. 12 | -------------------------------------------------------------------------------- /exercises/practice/react/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "petertseng" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "maxhaton", 9 | "sjwarner-bp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/react.d" 14 | ], 15 | "test": [ 16 | "source/react.d" 17 | ], 18 | "example": [ 19 | "example/react.d" 20 | ] 21 | }, 22 | "blurb": "Implement a basic reactive system." 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/react/dub.sdl: -------------------------------------------------------------------------------- 1 | name "react" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/resistor_color_duo.d" 11 | ], 12 | "test": [ 13 | "source/resistor_color_duo.d" 14 | ], 15 | "example": [ 16 | "example/resistor_color_duo.d" 17 | ] 18 | }, 19 | "blurb": "Convert color codes, as used on resistors, to a numeric value.", 20 | "source": "Maud de Vries, Erik Schierboom", 21 | "source_url": "https://github.com/exercism/problem-specifications/issues/1464" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.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 | [ce11995a-5b93-4950-a5e9-93423693b2fc] 13 | description = "Brown and black" 14 | 15 | [7bf82f7a-af23-48ba-a97d-38d59406a920] 16 | description = "Blue and grey" 17 | 18 | [f1886361-fdfd-4693-acf8-46726fe24e0c] 19 | description = "Yellow and violet" 20 | 21 | [b7a6cbd2-ae3c-470a-93eb-56670b305640] 22 | description = "White and red" 23 | 24 | [77a8293d-2a83-4016-b1af-991acc12b9fe] 25 | description = "Orange and orange" 26 | 27 | [0c4fb44f-db7c-4d03-afa8-054350f156a8] 28 | description = "Ignore additional colors" 29 | 30 | [4a8ceec5-0ab4-4904-88a4-daf953a5e818] 31 | description = "Black and brown, one-digit" 32 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/dub.sdl: -------------------------------------------------------------------------------- 1 | name "resistor-color-duo" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/example/resistor_color_duo.d: -------------------------------------------------------------------------------- 1 | module resistor_color_duo; 2 | 3 | import std.algorithm.searching : countUntil; 4 | import std.algorithm.iteration; 5 | import std.conv; 6 | 7 | class ResistorColorDuo 8 | { 9 | private static immutable colors = [ 10 | "black", "brown", "red", "orange", "yellow", "green", "blue", "violet", 11 | "grey", "white" 12 | ]; 13 | 14 | static pure long value(immutable string[] colorsInput) 15 | { 16 | return 10 * this.colors.countUntil(colorsInput[0]) + this.colors.countUntil(colorsInput[1]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/source/resistor_color_duo.d: -------------------------------------------------------------------------------- 1 | module resistor_color_duo; 2 | 3 | class ResistorColorDuo 4 | { 5 | static pure long value(immutable string[] colorsInput) 6 | { 7 | // implement this function 8 | } 9 | } 10 | 11 | unittest 12 | { 13 | immutable int allTestsEnabled = 0; 14 | 15 | // Brown and black 16 | assert(ResistorColorDuo.value(["brown", "black"]) == 10); 17 | 18 | static if (allTestsEnabled) 19 | { 20 | // Blue and grey 21 | assert(ResistorColorDuo.value(["blue", "grey"]) == 68); 22 | 23 | // Yellow and violet 24 | assert(ResistorColorDuo.value(["yellow", "violet"]) == 47); 25 | 26 | // White and red 27 | assert(ResistorColorDuo.value(["white", "red"]) == 92); 28 | 29 | // Orange and orange 30 | assert(ResistorColorDuo.value(["orange", "orange"]) == 33); 31 | 32 | // Ignore additional colors 33 | assert(ResistorColorDuo.value(["green", "brown", "orange"]) == 51); 34 | 35 | // Black and brown, one-digit 36 | assert(ResistorColorDuo.value(["black", "brown"]) == 1); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/resistor_color_trio.d" 8 | ], 9 | "test": [ 10 | "source/resistor_color_trio.d" 11 | ], 12 | "example": [ 13 | "example/resistor_color_trio.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "resistor-color-trio" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/example/resistor_color_trio.d: -------------------------------------------------------------------------------- 1 | module resistor_color_trio; 2 | 3 | import std.algorithm.searching : countUntil; 4 | import std.math.exponential : pow; 5 | import std.format : format; 6 | 7 | class ResistorColorTrio 8 | { 9 | static pure string label(immutable string[] bands) 10 | { 11 | long tens = colors.countUntil(bands[0]); 12 | long ones = colors.countUntil(bands[1]); 13 | long multiplier = colors.countUntil(bands[2]); 14 | long value = (10 * tens + ones) * pow(10, multiplier); 15 | 16 | if (value < 1_000) 17 | return format("%d ohms", value); 18 | else if (value < 1_000_000) 19 | return format("%d kiloohms", value / 1_000); 20 | else if (value < 1_000_000_000) 21 | return format("%d megaohms", value / 1_000_000); 22 | else 23 | return format("%d gigaohms", value / 1_000_000_000); 24 | } 25 | 26 | private static immutable colors = [ 27 | "black", "brown", "red", "orange", 28 | "yellow", "green", "blue", "violet", 29 | "grey", "white" 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/resistor_color.d" 11 | ], 12 | "test": [ 13 | "source/resistor_color.d" 14 | ], 15 | "example": [ 16 | "example/resistor_color.d" 17 | ] 18 | }, 19 | "blurb": "Convert a resistor band's color to its numeric representation.", 20 | "source": "Maud de Vries, Erik Schierboom", 21 | "source_url": "https://github.com/exercism/problem-specifications/issues/1458" 22 | } 23 | -------------------------------------------------------------------------------- /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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "resistor-color" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/example/resistor_color.d: -------------------------------------------------------------------------------- 1 | module resistor_color; 2 | 3 | import std.algorithm.searching : countUntil; 4 | 5 | class ResistorColor 6 | { 7 | static immutable colors = [ 8 | "black", "brown", "red", "orange", "yellow", "green", "blue", "violet", 9 | "grey", "white" 10 | ]; 11 | 12 | static pure long colorCode(immutable string color) 13 | { 14 | return this.colors.countUntil(color); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/source/resistor_color.d: -------------------------------------------------------------------------------- 1 | module resistor_color; 2 | 3 | unittest 4 | { 5 | immutable int allTestsEnabled = 0; 6 | 7 | // Black 8 | assert(ResistorColor.colorCode("black") == 0); 9 | 10 | static if (allTestsEnabled) 11 | { 12 | // White 13 | assert(ResistorColor.colorCode("white") == 9); 14 | 15 | // Orange 16 | assert(ResistorColor.colorCode("orange") == 3); 17 | 18 | // Colors 19 | assert(ResistorColor.colors == [ 20 | "black", "brown", "red", "orange", "yellow", "green", "blue", 21 | "violet", "grey", "white" 22 | ]); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.approaches/bygrapheme-retro-bycodepoint-text/snippet.txt: -------------------------------------------------------------------------------- 1 | import std.array : array; 2 | import std.conv : text; 3 | import std.range : retro; 4 | import std.uni : byCodePoint, byGrapheme; 5 | @safe pure string reverseString(string phrase) 6 | { 7 | return phrase.byGrapheme.array.retro.byCodePoint.text; 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.approaches/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "introduction": { 3 | "authors": [ 4 | "bobahop" 5 | ] 6 | }, 7 | "approaches": [ 8 | { 9 | "uuid": "82d351a0-eb04-417c-9989-bafd61114ae2", 10 | "slug": "bygrapheme-retro-bycodepoint-text", 11 | "title": "byGrapheme and retro with byCodePoint and text", 12 | "blurb": "Use byGrapheme and retro with byCodePoint and text to handle Unicode.", 13 | "authors": [ 14 | "bobahop" 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/reverse_string.d" 11 | ], 12 | "test": [ 13 | "source/reverse_string.d" 14 | ], 15 | "example": [ 16 | "example/reverse_string.d" 17 | ] 18 | }, 19 | "blurb": "Reverse a given string.", 20 | "source": "Introductory challenge to reverse an input string", 21 | "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.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 | [c3b7d806-dced-49ee-8543-933fd1719b1c] 13 | description = "an empty string" 14 | 15 | [01ebf55b-bebb-414e-9dec-06f7bb0bee3c] 16 | description = "a word" 17 | 18 | [0f7c07e4-efd1-4aaa-a07a-90b49ce0b746] 19 | description = "a capitalized word" 20 | 21 | [71854b9c-f200-4469-9f5c-1e8e5eff5614] 22 | description = "a sentence with punctuation" 23 | 24 | [1f8ed2f3-56f3-459b-8f3e-6d8d654a1f6c] 25 | description = "a palindrome" 26 | 27 | [b9e7dec1-c6df-40bd-9fa3-cd7ded010c4c] 28 | description = "an even-sized word" 29 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/dub.sdl: -------------------------------------------------------------------------------- 1 | name "reverse-string" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/example/reverse_string.d: -------------------------------------------------------------------------------- 1 | module reverse_string; 2 | 3 | import std.algorithm.mutation; 4 | 5 | pure string reverseString(immutable string value) 6 | { 7 | return value.dup.reverse; 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/source/reverse_string.d: -------------------------------------------------------------------------------- 1 | module reverse_string; 2 | 3 | pure string reverseString(immutable string value) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | immutable int allTestsEnabled = 0; 11 | 12 | // An empty string 13 | assert(reverseString("") == ""); 14 | 15 | static if (allTestsEnabled) 16 | { 17 | // A word 18 | assert(reverseString("robot") == "tobor"); 19 | 20 | // A capitalized word 21 | assert(reverseString("Ramen") == "nemaR"); 22 | 23 | // A sentence with punctuation 24 | assert(reverseString("I'm hungry!") == "!yrgnuh m'I"); 25 | 26 | // A palindrome 27 | assert(reverseString("racecar") == "racecar"); 28 | 29 | // An even-sized word 30 | assert(reverseString("drawer") == "reward"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /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 | "tmccombs" 4 | ], 5 | "contributors": [ 6 | "amscotti", 7 | "kytrinyx", 8 | "petertseng", 9 | "sjwarner-bp" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "source/rna_transcription.d" 14 | ], 15 | "test": [ 16 | "source/rna_transcription.d" 17 | ], 18 | "example": [ 19 | "example/rna_transcription.d" 20 | ] 21 | }, 22 | "blurb": "Given a DNA strand, return its RNA complement.", 23 | "source": "Hyperphysics", 24 | "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.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 | [b4631f82-c98c-4a2f-90b3-c5c2b6c6f661] 13 | description = "Empty RNA sequence" 14 | 15 | [a9558a3c-318c-4240-9256-5d5ed47005a6] 16 | description = "RNA complement of cytosine is guanine" 17 | 18 | [6eedbb5c-12cb-4c8b-9f51-f8320b4dc2e7] 19 | description = "RNA complement of guanine is cytosine" 20 | 21 | [870bd3ec-8487-471d-8d9a-a25046488d3e] 22 | description = "RNA complement of thymine is adenine" 23 | 24 | [aade8964-02e1-4073-872f-42d3ffd74c5f] 25 | description = "RNA complement of adenine is uracil" 26 | 27 | [79ed2757-f018-4f47-a1d7-34a559392dbf] 28 | description = "RNA complement" 29 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/dub.sdl: -------------------------------------------------------------------------------- 1 | name "rna-transcription" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/example/rna_transcription.d: -------------------------------------------------------------------------------- 1 | module rna_transcription; 2 | 3 | import std.string : translate; 4 | 5 | immutable dchar[dchar] rnaTransTable; 6 | 7 | shared static this() 8 | { 9 | rnaTransTable = ['C': 'G', 'G': 'C', 'T': 'A', 'A': 'U']; 10 | } 11 | 12 | pure string toRna(immutable string dna) 13 | { 14 | return dna.translate(rnaTransTable); 15 | } 16 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/source/rna_transcription.d: -------------------------------------------------------------------------------- 1 | module rna_transcription; 2 | 3 | pure string toRna(immutable string dna) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | import std.exception : assertThrown; 11 | 12 | immutable int allTestsEnabled = 0; 13 | 14 | // Empty RNA sequence 15 | assert(toRna("") == ""); 16 | 17 | static if (allTestsEnabled) 18 | { 19 | // RNA complement of cytosine is guanine 20 | assert(toRna("C") == "G"); 21 | 22 | // RNA complement of guanine is cytosine 23 | assert(toRna("G") == "C"); 24 | 25 | // RNA complement of thymine is adenine 26 | assert(toRna("T") == "A"); 27 | 28 | // RNA complement of adenine is uracil 29 | assert(toRna("A") == "U"); 30 | 31 | // RNA complement 32 | assert(toRna("ACGTGGTCTTAA") == "UGCACCAGAAUU"); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Manage robot factory settings. 4 | 5 | When a robot comes off the factory floor, it has no name. 6 | 7 | The first time you turn on a robot, a random name is generated in the format of two uppercase letters followed by three digits, such as RX837 or BC811. 8 | 9 | Every once in a while we need to reset a robot to its factory settings, which means that its name gets wiped. 10 | The next time you ask, that robot will respond with a new random name. 11 | 12 | The names must be random: they should not follow a predictable sequence. 13 | Using random names means a risk of collisions. 14 | Your solution must ensure that every existing robot has a unique name. 15 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/robot_name.d" 13 | ], 14 | "test": [ 15 | "source/robot_name.d" 16 | ], 17 | "example": [ 18 | "example/robot_name.d" 19 | ] 20 | }, 21 | "blurb": "Manage robot factory settings.", 22 | "source": "A debugging session with Paul Blackwell at gSchool." 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/dub.sdl: -------------------------------------------------------------------------------- 1 | name "robot-name" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/robot_simulator.d" 8 | ], 9 | "test": [ 10 | "source/robot_simulator.d" 11 | ], 12 | "example": [ 13 | "example/robot_simulator.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "robot-simulator" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/roman_numerals.d" 13 | ], 14 | "test": [ 15 | "source/roman_numerals.d" 16 | ], 17 | "example": [ 18 | "example/roman_numerals.d" 19 | ] 20 | }, 21 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 22 | "source": "The Roman Numeral Kata", 23 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/dub.sdl: -------------------------------------------------------------------------------- 1 | name "roman-numerals" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/example/roman_numerals.d: -------------------------------------------------------------------------------- 1 | module roman_numerals; 2 | 3 | import std.string; 4 | import std.array; 5 | import std.algorithm.sorting : sort; 6 | 7 | import std.stdio; 8 | 9 | // solution based on Kevlin Henney's ACCU talk 10 | // https://www.youtube.com/watch?v=nrVIlhtoE3Y 11 | // 12 | // solution does not scale well with big numbers in terms of memory 13 | // usage - it might even go out of memory - but it's interesting and 14 | // given the "requirement" that the number should be at most 3000 15 | // it's acceptable 16 | string convert(ulong number) 17 | { 18 | auto s = "I"; 19 | return replicate(s, number).replace("IIIII", "V").replace("IIII", "IV") 20 | .replace("VV", "X").replace("VIV", "IX").replace("XXXXX", "L") 21 | .replace("XXXX", "XL").replace("LL", "C").replace("LXL", "XC") 22 | .replace("CCCCC", "D").replace("CCCC", "CD").replace("DD", "M").replace("DCD", "CM"); 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/rotational_cipher.d" 8 | ], 9 | "test": [ 10 | "source/rotational_cipher.d" 11 | ], 12 | "example": [ 13 | "example/rotational_cipher.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "rotational-cipher" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/example/rotational_cipher.d: -------------------------------------------------------------------------------- 1 | import std; 2 | 3 | pure string rotate(immutable string text, immutable int shiftKey) 4 | { 5 | string result = ""; 6 | foreach (immutable char chr; text) 7 | { 8 | if (std.ascii.isLower(chr)) 9 | { 10 | result ~= 'a' + (chr - 'a' + shiftKey) % 26; 11 | } 12 | else if (std.ascii.isUpper(chr)) 13 | { 14 | result ~= 'A' + (chr - 'A' + shiftKey) % 26; 15 | } 16 | else 17 | { 18 | result ~= chr; 19 | } 20 | } 21 | 22 | return result; 23 | } 24 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/run_length_encoding.d" 11 | ], 12 | "test": [ 13 | "source/run_length_encoding.d" 14 | ], 15 | "example": [ 16 | "example/run_length_encoding.d" 17 | ] 18 | }, 19 | "blurb": "Implement run-length encoding and decoding.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/dub.sdl: -------------------------------------------------------------------------------- 1 | name "run-length-encoding" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/scrabble_score.d" 8 | ], 9 | "test": [ 10 | "source/scrabble_score.d" 11 | ], 12 | "example": [ 13 | "example/scrabble_score.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "scrabble-score" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/secret_handshake.d" 8 | ], 9 | "test": [ 10 | "source/secret_handshake.d" 11 | ], 12 | "example": [ 13 | "example/secret_handshake.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "secret-handshake" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/example/secret_handshake.d: -------------------------------------------------------------------------------- 1 | module secret_handshake; 2 | 3 | import std.algorithm; 4 | 5 | pure string[] commands(immutable int number) 6 | { 7 | string[] actions; 8 | 9 | if (number & 1) 10 | { 11 | actions ~= "wink"; 12 | } 13 | 14 | if (number & 2) 15 | { 16 | actions ~= "double blink"; 17 | } 18 | 19 | if (number & 4) 20 | { 21 | actions ~= "close your eyes"; 22 | } 23 | 24 | if (number & 8) 25 | { 26 | actions ~= "jump"; 27 | } 28 | 29 | if (number & 16) 30 | { 31 | actions = actions.reverse; 32 | } 33 | 34 | return actions; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /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 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/series.d" 13 | ], 14 | "test": [ 15 | "source/series.d" 16 | ], 17 | "example": [ 18 | "example/series.d" 19 | ] 20 | }, 21 | "blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.", 22 | "source": "A subset of the Problem 8 at Project Euler", 23 | "source_url": "https://projecteuler.net/problem=8" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/series/dub.sdl: -------------------------------------------------------------------------------- 1 | name "series" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/sieve.d" 8 | ], 9 | "test": [ 10 | "source/sieve.d" 11 | ], 12 | "example": [ 13 | "example/sieve.d" 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/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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "sieve" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/sieve/example/sieve.d: -------------------------------------------------------------------------------- 1 | module sieve; 2 | 3 | import std.algorithm; 4 | import std.array; 5 | import std.range; 6 | 7 | pure int[] primes(immutable int limit) 8 | { 9 | int[] results = []; 10 | int[] nums = iota(2, limit + 1).array; 11 | while (nums.length > 0) 12 | { 13 | int current = nums.front; 14 | results ~= nums.front; 15 | 16 | nums = nums.dropOne().filter!(n => n % current != 0).array; 17 | } 18 | 19 | return results; 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/space_age.d" 8 | ], 9 | "test": [ 10 | "source/space_age.d" 11 | ], 12 | "example": [ 13 | "example/space_age.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "space-age" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "source/square_root.d" 8 | ], 9 | "test": [ 10 | "source/square_root.d" 11 | ], 12 | "example": [ 13 | "example/square_root.d" 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/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 | [9b748478-7b0a-490c-b87a-609dacf631fd] 13 | description = "root of 1" 14 | 15 | [7d3aa9ba-9ac6-4e93-a18b-2e8b477139bb] 16 | description = "root of 4" 17 | 18 | [6624aabf-3659-4ae0-a1c8-25ae7f33c6ef] 19 | description = "root of 25" 20 | 21 | [93beac69-265e-4429-abb1-94506b431f81] 22 | description = "root of 81" 23 | 24 | [fbddfeda-8c4f-4bc4-87ca-6991af35360e] 25 | description = "root of 196" 26 | 27 | [c03d0532-8368-4734-a8e0-f96a9eb7fc1d] 28 | description = "root of 65025" 29 | -------------------------------------------------------------------------------- /exercises/practice/square-root/dub.sdl: -------------------------------------------------------------------------------- 1 | name "square-root" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/square-root/example/square_root.d: -------------------------------------------------------------------------------- 1 | pure int squareRoot(immutable int radicand) 2 | { 3 | int square = 0; 4 | while (square * square != radicand) 5 | { 6 | square++; 7 | } 8 | 9 | return square; 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/square-root/source/square_root.d: -------------------------------------------------------------------------------- 1 | module square_root; 2 | 3 | pure int squareRoot(immutable int radicand) 4 | { 5 | // implement this function 6 | } 7 | 8 | unittest 9 | { 10 | immutable int allTestsEnabled = 0; 11 | 12 | // root of 1 13 | assert(squareRoot(1) == 1); 14 | 15 | static if (allTestsEnabled) 16 | { 17 | // root of 4 18 | assert(squareRoot(4) == 2); 19 | 20 | // root of 25 21 | assert(squareRoot(25) == 5); 22 | 23 | // root of 81 24 | assert(squareRoot(81) == 9); 25 | 26 | // root of 196 27 | assert(squareRoot(196) == 14); 28 | 29 | // root of 65025 30 | assert(squareRoot(65025) == 255); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/state-of-tic-tac-toe/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/state_of_tic_tac_toe.d" 8 | ], 9 | "test": [ 10 | "source/state_of_tic_tac_toe.d" 11 | ], 12 | "example": [ 13 | "example/state_of_tic_tac_toe.d" 14 | ] 15 | }, 16 | "blurb": "Determine the game state of a match of Tic-Tac-Toe.", 17 | "source": "Created by Sascha Mann for the Julia track of the Exercism Research Experiment.", 18 | "source_url": "https://github.com/exercism/research_experiment_1/tree/julia-dev/exercises/julia-1-a" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/state-of-tic-tac-toe/dub.sdl: -------------------------------------------------------------------------------- 1 | name "state-of-tic-tac-toe" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/sum_of_multiples.d" 11 | ], 12 | "test": [ 13 | "source/sum_of_multiples.d" 14 | ], 15 | "example": [ 16 | "example/sum_of_multiples.d" 17 | ] 18 | }, 19 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 20 | "source": "A variation on Problem 1 at Project Euler", 21 | "source_url": "https://projecteuler.net/problem=1" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/dub.sdl: -------------------------------------------------------------------------------- 1 | name "difference-of-squares" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/example/sum_of_multiples.d: -------------------------------------------------------------------------------- 1 | module sum_of_multiples; 2 | 3 | import std.range : iota; 4 | import std.algorithm.searching : any; 5 | import std.algorithm.iteration : filter, sum; 6 | 7 | pure int calculateSum(immutable int[] factors, immutable int limit) 8 | { 9 | return iota(0, limit).filter!(num => factors.filter!(a => a != 0) 10 | .any!(t => num % t == 0)).sum; 11 | } 12 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a triangle is equilateral, isosceles, or scalene. 4 | 5 | An _equilateral_ triangle has all three sides the same length. 6 | 7 | An _isosceles_ triangle has at least two sides the same length. 8 | (It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.) 9 | 10 | A _scalene_ triangle has all sides of different lengths. 11 | 12 | ## Note 13 | 14 | For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side. 15 | 16 | In equations: 17 | 18 | Let `a`, `b`, and `c` be sides of the triangle. 19 | Then all three of the following expressions must be true: 20 | 21 | ```text 22 | a + b ≥ c 23 | b + c ≥ a 24 | a + c ≥ b 25 | ``` 26 | 27 | See [Triangle Inequality][triangle-inequality] 28 | 29 | [triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality 30 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [], 3 | "contributors": [ 4 | "amscotti", 5 | "kytrinyx", 6 | "petertseng", 7 | "sjwarner-bp", 8 | "tmccombs" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "source/triangle.d" 13 | ], 14 | "test": [ 15 | "source/triangle.d" 16 | ], 17 | "example": [ 18 | "example/triangle.d" 19 | ] 20 | }, 21 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 22 | "source": "The Ruby Koans triangle project, parts 1 & 2", 23 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/triangle/dub.sdl: -------------------------------------------------------------------------------- 1 | name "triangle" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/triangle/example/triangle.d: -------------------------------------------------------------------------------- 1 | module triangle; 2 | 3 | enum TriangleType 4 | { 5 | equilateral, 6 | isosceles, 7 | scalene 8 | }; 9 | 10 | /** 11 | * Return what kind of triangle that is. 12 | */ 13 | TriangleType kind(double a, double b, double c) 14 | { 15 | // check the triangle inequality 16 | if (a + b <= c || a + c <= b || c + b <= a) 17 | { 18 | throw new Exception("Segment lengths do not satisfy triangle inequality."); 19 | } 20 | 21 | if (a == b && b == c) 22 | return TriangleType.equilateral; 23 | else if (a == b || a == c || b == c) 24 | return TriangleType.isosceles; 25 | else 26 | return TriangleType.scalene; 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/twelve_days.d" 8 | ], 9 | "test": [ 10 | "source/twelve_days.d" 11 | ], 12 | "example": [ 13 | "example/twelve_days.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "twelve-days" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/example/twelve_days.d: -------------------------------------------------------------------------------- 1 | module twelve_days; 2 | 3 | import std.array; 4 | 5 | pure string recite(int startVerse, int endVerse) 6 | { 7 | immutable string[] ordinals = [ "", "first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth" ]; 8 | 9 | immutable string gifts = 10 | "twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."; 11 | 12 | immutable size_t[] table = [ 0, 235, 213, 194, 174, 157, 137, 113, 90, 69, 48, 26, 0 ]; 13 | 14 | string[] lyrics; 15 | for (int verse = startVerse; verse <= endVerse; ++verse) 16 | { 17 | lyrics ~= "On the " ~ ordinals[verse] ~ " day of Christmas my true love gave to me: " ~ gifts[table[verse] .. gifts.length]; 18 | } 19 | 20 | return lyrics.join("\n"); 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "glennj" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/two_bucket.d" 8 | ], 9 | "test": [ 10 | "source/two_bucket.d" 11 | ], 12 | "example": [ 13 | "example/two_bucket.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "two-bucket" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /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 | "amscotti" 4 | ], 5 | "contributors": [ 6 | "petertseng" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "source/two_fer.d" 11 | ], 12 | "test": [ 13 | "source/two_fer.d" 14 | ], 15 | "example": [ 16 | "example/two_fer.d" 17 | ] 18 | }, 19 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 20 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 21 | } 22 | -------------------------------------------------------------------------------- /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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "two-fer" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/example/two_fer.d: -------------------------------------------------------------------------------- 1 | module two_fer; 2 | 3 | import std.format : format; 4 | 5 | pure string twoFer(immutable string name = "you") 6 | { 7 | return "One for %s, one for me.".format(name); 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/source/two_fer.d: -------------------------------------------------------------------------------- 1 | module two_fer; 2 | 3 | unittest 4 | { 5 | immutable int allTestsEnabled = 0; 6 | 7 | // No name given 8 | assert(twoFer() == "One for you, one for me."); 9 | 10 | static if (allTestsEnabled) 11 | { 12 | // A name given 13 | assert(twoFer("Alice") == "One for Alice, one for me."); 14 | 15 | // Another name given 16 | assert(twoFer("Bob") == "One for Bob, one for me."); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /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 | "source/yacht.d" 8 | ], 9 | "test": [ 10 | "source/yacht.d" 11 | ], 12 | "example": [ 13 | "example/yacht.d" 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/dub.sdl: -------------------------------------------------------------------------------- 1 | name "zebra-puzzle" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The Zebra Puzzle is a famous logic puzzle in which there are five houses, each painted a different color. 4 | The houses have different inhabitants, who have different nationalities, own different pets, drink different beverages and enjoy different hobbies. 5 | 6 | To help you solve the puzzle, you're given 15 statements describing the solution. 7 | However, only by combining the information in _all_ statements will you be able to find the solution to the puzzle. 8 | 9 | ~~~~exercism/note 10 | The Zebra Puzzle is a [Constraint satisfaction problem (CSP)][constraint-satisfaction-problem]. 11 | In such a problem, you have a set of possible values and a set of constraints that limit which values are valid. 12 | Another well-known CSP is Sudoku. 13 | 14 | [constraint-satisfaction-problem]: https://en.wikipedia.org/wiki/Constraint_satisfaction_problem 15 | ~~~~ 16 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "source/zebra_puzzle.d" 8 | ], 9 | "test": [ 10 | "source/zebra_puzzle.d" 11 | ], 12 | "example": [ 13 | "example/zebra_puzzle.d" 14 | ] 15 | }, 16 | "blurb": "Solve the zebra puzzle.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Zebra_Puzzle" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/.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 | [16efb4e4-8ad7-4d5e-ba96-e5537b66fd42] 13 | description = "resident who drinks water" 14 | 15 | [084d5b8b-24e2-40e6-b008-c800da8cd257] 16 | description = "resident who owns zebra" 17 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/dub.sdl: -------------------------------------------------------------------------------- 1 | name "zebra-puzzle" 2 | buildRequirements "disallowDeprecations" 3 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/source/zebra_puzzle.d: -------------------------------------------------------------------------------- 1 | module zebra_puzzle; 2 | 3 | enum Nationality 4 | { 5 | englishman, 6 | japanese, 7 | norwegian, 8 | spaniard, 9 | ukrainian 10 | } 11 | 12 | class ZebraPuzzle 13 | { 14 | this() 15 | { 16 | // implement this function 17 | } 18 | 19 | Nationality drinksWater() 20 | { 21 | // implement this function 22 | } 23 | 24 | Nationality ownsZebra() 25 | { 26 | // implement this function 27 | } 28 | } 29 | 30 | unittest 31 | { 32 | ZebraPuzzle zebraPuzzle = new ZebraPuzzle(); 33 | assert(zebraPuzzle.drinksWater() == Nationality.norwegian); 34 | assert(zebraPuzzle.ownsZebra() == Nationality.japanese); 35 | } 36 | -------------------------------------------------------------------------------- /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 | - [DRefLanguage](https://dlang.org/spec/spec.html) contains the D language specification 6 | - [DReference](https://dlang.org/phobos/index.html) contains the D standard library documentation 7 | - [/r/dlang](https://www.reddit.com/r/dlang) is the D subreddit. 8 | - [StackOverflow](http://stackoverflow.com/questions/tagged/d) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. 9 | -------------------------------------------------------------------------------- /exercises/shared/.docs/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | You can run the tests by running the following command in the exercise's directory: 4 | 5 | ```bash 6 | dub test 7 | ``` 8 | 9 | ## Passing the Tests 10 | 11 | Get the first test compiling, linking and passing by following the [three 12 | rules of test-driven development](http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd). 13 | Create just enough structure by declaring namespaces, functions, classes, 14 | etc., to satisfy any compiler errors and get the test to fail. Then write 15 | just enough code to get the test to pass. Once you've done that, 16 | uncomment the next test by moving the following line past the next test. 17 | 18 | ```D 19 | static if (all_tests_enabled) 20 | ``` 21 | 22 | This may result in compile errors as new constructs may be invoked that 23 | you haven't yet declared or defined. Again, fix the compile errors minimally 24 | to get a failing test, then change the code minimally to pass the test, 25 | refactor your implementation for readability and expressiveness and then 26 | go on to the next test. 27 | 28 | Try to use standard D facilities in preference to writing your own 29 | low-level algorithms or facilities by hand. 30 | --------------------------------------------------------------------------------