├── .appends └── .github │ └── labels.yml ├── .gitattributes ├── .github ├── CODEOWNERS ├── labels.yml └── workflows │ ├── configlet.yml │ ├── no-important-files-changed.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── sync-labels.yml │ └── test.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bin ├── bootstrap_practice_exercise.sh ├── fetch-configlet ├── fetch-configlet.ps1 └── test ├── concepts └── .keep ├── config.json ├── docs ├── ABOUT.md ├── INSTALLATION.md ├── LEARNING.md ├── RESOURCES.md ├── SNIPPET.txt ├── TESTS.md └── config.json └── exercises ├── .keep ├── concept └── .keep ├── practice ├── .keep ├── accumulate │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── accumulate.v │ └── run_test.v ├── acronym │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── acronym.v │ └── run_test.v ├── affine-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── affine-cipher.v │ └── run_test.v ├── all-your-base │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── all-your-base.v │ └── run_test.v ├── allergies │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── allergies.v │ └── run_test.v ├── anagram │ ├── .docs │ │ ├── instructions.append.md │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── anagram.v │ └── run_test.v ├── armstrong-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── armstrong-numbers.v │ └── run_test.v ├── atbash-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── atbash-cipher.v │ └── run_test.v ├── binary-search │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── binary-search.v │ └── run_test.v ├── bob │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── bob.v │ └── run_test.v ├── book-store │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── book-store.v │ └── run_test.v ├── bottle-song │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── bottle-song.v │ └── run_test.v ├── bowling │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── bowling.v │ └── run_test.v ├── change │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── change.v │ └── run_test.v ├── circular-buffer │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── circular-buffer.v │ └── run_test.v ├── clock │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── clock.v │ └── run_test.v ├── collatz-conjecture │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── collatz-conjecture.v │ └── run_test.v ├── complex-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── complex-numbers.v │ └── run_test.v ├── connect │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── connect.v │ └── run_test.v ├── crypto-square │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── crypto-square.v │ └── run_test.v ├── custom-set │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── custom-set.v │ └── run_test.v ├── darts │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── darts.v │ └── run_test.v ├── diamond │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── diamond.v │ └── run_test.v ├── difference-of-squares │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── difference-of-squares.v │ └── run_test.v ├── dominoes │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── dominoes.v │ └── run_test.v ├── eliuds-eggs │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── eliuds-eggs.v │ └── run_test.v ├── etl │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── etl.v │ └── run_test.v ├── food-chain │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── food-chain.v │ └── run_test.v ├── game-of-life │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── game-of-life.v │ └── run_test.v ├── gigasecond │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── gigasecond.v │ └── run_test.v ├── grade-school │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── grade-school.v │ └── run_test.v ├── grains │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── grains.v │ └── run_test.v ├── hamming │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── hamming.v │ └── run_test.v ├── hello-world │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── hello-world.v │ └── run_test.v ├── high-scores │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── high-scores.v │ └── run_test.v ├── house │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── house.v │ └── run_test.v ├── intergalactic-transmission │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── intergalactic-transmission.v │ └── run_test.v ├── isbn-verifier │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── isbn-verifier.v │ └── run_test.v ├── isogram │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── isogram.v │ └── run_test.v ├── killer-sudoku-helper │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── killer-sudoku-helper.v │ └── run_test.v ├── kindergarten-garden │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── kindergarten-garden.v │ └── run_test.v ├── knapsack │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── knapsack.v │ └── run_test.v ├── largest-series-product │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── largest-series-product.v │ └── run_test.v ├── leap │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── leap.v │ └── run_test.v ├── linked-list │ ├── .docs │ │ ├── instructions.append.md │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── linked-list.v │ └── run_test.v ├── list-ops │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── list-ops.v │ └── run_test.v ├── luhn │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── luhn.v │ └── run_test.v ├── matching-brackets │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── matching-brackets.v │ └── run_test.v ├── matrix │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── matrix.v │ └── run_test.v ├── meetup │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── meetup.v │ └── run_test.v ├── micro-blog │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── micro-blog.v │ └── run_test.v ├── minesweeper │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── minesweeper.v │ └── run_test.v ├── nth-prime │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── nth-prime.v │ └── run_test.v ├── nucleotide-count │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── nucleotide-count.v │ └── run_test.v ├── palindrome-products │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── palindrome-products.v │ └── run_test.v ├── pangram │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── pangram.v │ └── run_test.v ├── parallel-letter-frequency │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── parallel-letter-frequency.v │ └── run_test.v ├── pascals-triangle │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── pascals-triangle.v │ └── run_test.v ├── perfect-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── perfect-numbers.v │ └── run_test.v ├── phone-number │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── phone-number.v │ └── run_test.v ├── piecing-it-together │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── piecing-it-together.v │ └── run_test.v ├── pig-latin │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── pig-latin.v │ └── run_test.v ├── prime-factors │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── prime-factors.v │ └── run_test.v ├── protein-translation │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── protein-translation.v │ └── run_test.v ├── proverb │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── proverb.v │ └── run_test.v ├── pythagorean-triplet │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── pythagorean-triplet.v │ └── run_test.v ├── queen-attack │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── queen-attack.v │ └── run_test.v ├── rail-fence-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── rail-fence-cipher.v │ └── run_test.v ├── raindrops │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── raindrops.v │ └── run_test.v ├── rational-numbers │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── rational-numbers.v │ └── run_test.v ├── rectangles │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── rectangles.v │ └── run_test.v ├── resistor-color-duo │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── resistor-color-duo.v │ └── run_test.v ├── resistor-color-trio │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── resistor-color-trio.v │ └── run_test.v ├── resistor-color │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── resistor-color.v │ └── run_test.v ├── reverse-string │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── reverse-string.v │ └── run_test.v ├── rna-transcription │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── rna-transcription.v │ └── run_test.v ├── robot-name │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ └── example.v │ ├── robot-name.v │ └── run_test.v ├── roman-numerals │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── roman-numerals.v │ └── run_test.v ├── rotational-cipher │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── rotational-cipher.v │ └── run_test.v ├── run-length-encoding │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run-length-encoding.v │ └── run_test.v ├── saddle-points │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── saddle-points.v ├── say │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── say.v ├── scrabble-score │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── scrabble-score.v ├── secret-handshake │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── secret_handshake.v ├── series │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── series.v ├── sieve │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── sieve.v ├── simple-linked-list │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ └── example.v │ ├── run_test.v │ └── simple-linked-list.v ├── space-age │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── space-age.v ├── spiral-matrix │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── spiral-matrix.v ├── square-root │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── square-root.v ├── state-of-tic-tac-toe │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── state-of-tic-tac-toe.v ├── strain │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── strain.v ├── sublist │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── sublist.v ├── sum-of-multiples │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── sum-of-multiples.v ├── transpose │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── transpose.v ├── triangle │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── triangle.v ├── twelve-days │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── twelve-days.v ├── two-bucket │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── two-bucket.v ├── two-fer │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── two-fer.v ├── variable-length-quantity │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── variable-length-quantity.v ├── word-count │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── word-count.v ├── word-search │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── word-search.v ├── wordy │ ├── .docs │ │ └── instructions.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── wordy.v ├── yacht │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ ├── .meta │ │ ├── config.json │ │ ├── example.v │ │ └── tests.toml │ ├── run_test.v │ └── yacht.v └── zebra-puzzle │ ├── .docs │ ├── instructions.md │ └── introduction.md │ ├── .meta │ ├── config.json │ ├── example.v │ └── tests.toml │ ├── run_test.v │ └── zebra-puzzle.v └── shared └── .docs ├── help.md └── tests.md /.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 | bin/fetch-configlet.ps1 @exercism/maintainers-admin 7 | -------------------------------------------------------------------------------- /.github/workflows/configlet.yml: -------------------------------------------------------------------------------- 1 | name: Configlet 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | configlet: 15 | uses: exercism/github-actions/.github/workflows/configlet.yml@main 16 | -------------------------------------------------------------------------------- /.github/workflows/no-important-files-changed.yml: -------------------------------------------------------------------------------- 1 | name: No important files changed 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | branches: [main] 7 | paths: 8 | - "exercises/concept/**" 9 | - "exercises/practice/**" 10 | - "!exercises/*/*/.approaches/**" 11 | - "!exercises/*/*/.articles/**" 12 | - "!exercises/*/*/.docs/**" 13 | - "!exercises/*/*/.meta/**" 14 | 15 | permissions: 16 | pull-requests: write 17 | 18 | jobs: 19 | check: 20 | uses: exercism/github-actions/.github/workflows/check-no-important-files-changed.yml@main 21 | with: 22 | repository: ${{ github.event.pull_request.head.repo.owner.login }}/${{ github.event.pull_request.head.repo.name }} 23 | ref: ${{ github.head_ref }} 24 | -------------------------------------------------------------------------------- /.github/workflows/ping-cross-track-maintainers-team.yml: -------------------------------------------------------------------------------- 1 | name: Ping cross-track maintainers team 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | pull-requests: write 10 | 11 | jobs: 12 | ping: 13 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 14 | uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main 15 | secrets: 16 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .DS_Store 3 | bin/configlet 4 | bin/configlet.exe 5 | temp/ 6 | -------------------------------------------------------------------------------- /bin/bootstrap_practice_exercise.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Exit if anything fails. 4 | set -euo pipefail 5 | 6 | # If argument not provided, print usage and exit 7 | if [ $# -ne 1 ]; then 8 | echo "Usage: bin/bootstrap_practice_exercise.sh " 9 | exit 1 10 | fi 11 | 12 | SLUG="$1" 13 | exercise_dir="exercises/practice/${SLUG}" 14 | 15 | # build configlet 16 | echo "Fetching latest version of configlet..." 17 | ./bin/fetch-configlet 18 | 19 | if [[ -z $author ]]; then 20 | echo 21 | read -rp "What's your github username? " author 22 | fi 23 | 24 | bin/configlet create --practice-exercise $SLUG --author "${author}" --difficulty 5 25 | 26 | # Create V files 27 | touch $exercise_dir/.meta/example.v 28 | touch $exercise_dir/$SLUG.v 29 | touch $exercise_dir/run_test.v 30 | -------------------------------------------------------------------------------- /concepts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/vlang/5ae80a79768459b279a6faa6f8e6422fa5991d7c/concepts/.keep -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | [V](https://vlang.io/) is a simple language for building maintainable programs. The syntax is similar to Go, with performance as fast as C. 4 | 5 | V is still in beta development, but already very powerful. 6 | 7 | With many built-in safety features, V helps your code run no matter what you throw at it: bounds checking, no undefined values, immutable variables by default, Option/Result types and mandatory error checks, and no null. 8 | 9 | V is written in V and compiles itself in under a second, and can call C code with no costs. It also has built-in formatting, code profiling, testing, and docs generation. 10 | 11 | The official website is [vlang.io](https://vlang.io/) and the docs are all in [this markdown file](https://github.com/vlang/v/blob/master/doc/docs.md). 12 | -------------------------------------------------------------------------------- /docs/INSTALLATION.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Installing V 4 | Please follow the [instructions in the official documentation](https://github.com/vlang/v/blob/master/README.md#installing-v-from-source) to install V on your machine. 5 | 6 | It is highly recommended that you install from source and then follow the [instructions on symlinking](https://github.com/vlang/v/blob/master/README.md#symlinking) to be able to run V anywhere. 7 | 8 | ## Using an IDE 9 | The best way to use V in an IDE is to use the [VSCodium](https://vscodium.com/) [extension](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang). There is also support for [Vim](https://github.com/ollykel/v-vim), [Emacs](https://github.com/damon-kwok/v-mode), and [Sublime](https://github.com/elliotchance/vlang-sublime). To see a full list of supported IDEs, see the [V homepage](https://vlang.io/). -------------------------------------------------------------------------------- /docs/LEARNING.md: -------------------------------------------------------------------------------- 1 | # Learning 2 | 3 | ## Forums/chatrooms 4 | - [Official Github Discussions](https://github.com/vlang/v/discussions) 5 | - [Discord](https://discord.gg/vlang) 6 | - [Telegram](https://t.me/vlang_en) 7 | - [Matrix](https://matrix.to/#/#v-chat:matrix.org) 8 | 9 | ## Videos 10 | - [Intro V videos on Odysee](https://odysee.com/@coderlyfe:9?view=content) 11 | - [V youtube channel](https://www.youtube.com/c/VLang/videos) 12 | 13 | ## Books 14 | - [Getting Started with V](https://smile.amazon.com/Getting-Started-Programming-end-end-ebook/dp/B09FKK3JL7) 15 | -------------------------------------------------------------------------------- /docs/RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | ## Social media 4 | - [V Twitter](https://twitter.com/v_language) 5 | 6 | ## Videos 7 | - [V youtube channel](https://www.youtube.com/c/VLang/videos) 8 | 9 | ## Documentation 10 | - [V Basics](https://github.com/vlang/v/blob/master/doc/docs.md) 11 | - [V Standard Libraries](https://modules.vlang.io/) 12 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn main() { 4 | names := ['learners', 'explorers', 'mentors', 'maintainers', 'contributors'] 5 | for name in names { 6 | println('Hello, Exercism ${name}!') 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/TESTS.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | ## Running tests 4 | To run tests for a specific implementation of an exercise, here are the recommended steps: 5 | 6 | 1. create your implementation in `[SLUG].v` 7 | 1. cd to the directory where `[SLUG].v` and `run_test.v` are located 8 | 1. run `v -stats test run_test.v` 9 | 10 | ## Testing in V 11 | For more information on testing in V, refer to the [official docs](https://github.com/vlang/v/blob/master/doc/docs.md#testing) -------------------------------------------------------------------------------- /exercises/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/vlang/5ae80a79768459b279a6faa6f8e6422fa5991d7c/exercises/.keep -------------------------------------------------------------------------------- /exercises/concept/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/vlang/5ae80a79768459b279a6faa6f8e6422fa5991d7c/exercises/concept/.keep -------------------------------------------------------------------------------- /exercises/practice/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/vlang/5ae80a79768459b279a6faa6f8e6422fa5991d7c/exercises/practice/.keep -------------------------------------------------------------------------------- /exercises/practice/accumulate/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection. 4 | 5 | Given the collection of numbers: 6 | 7 | - 1, 2, 3, 4, 5 8 | 9 | And the operation: 10 | 11 | - square a number (`x => x * x`) 12 | 13 | Your code should be able to produce the collection of squares: 14 | 15 | - 1, 4, 9, 16, 25 16 | 17 | Check out the test suite to see the expected function signature. 18 | 19 | ## Restrictions 20 | 21 | Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! 22 | Solve this one yourself using other basic tools instead. 23 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "accumulate.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.", 17 | "source": "Conversation with James Edward Gray II", 18 | "source_url": "http://graysoftinc.com/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn accumulate_ints(values []int, operation fn (int) int) []int { 4 | mut new_values := []int{} 5 | 6 | for value in values { 7 | new_values << operation(value) 8 | } 9 | 10 | return new_values 11 | } 12 | 13 | // Because V functions cannot be overloaded[1], let's make another 14 | // function called `accumulate_strs` that does the same thing for strings 15 | // instead of ints 16 | fn accumulate_strs(values []string, operation fn (string) string) []string { 17 | mut new_values := []string{} 18 | 19 | for value in values { 20 | new_values << operation(value) 21 | } 22 | 23 | return new_values 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/accumulate.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn accumulate_ints(values []int, operation fn (int) int) []int { 4 | } 5 | 6 | // Because V functions cannot be overloaded[1], make another function 7 | // called `accumulate_strs` that does the same thing for strings 8 | // instead of ints 9 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "acronym.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert a long phrase to its acronym.", 17 | "source": "Julien Vanier", 18 | "source_url": "https://github.com/monkbroc" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import strings 4 | 5 | fn abbreviate(phrase string) string { 6 | mut builder := strings.new_builder(10) 7 | mut in_word := false 8 | for ch in phrase.to_upper() { 9 | if `A` <= ch && ch <= `Z` { 10 | if !in_word { 11 | builder.write_u8(ch) 12 | in_word = true 13 | } 14 | } else if ch == `-` || ch.is_space() { 15 | in_word = false 16 | } 17 | } 18 | return builder.str() 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/acronym/acronym.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn abbreviate(phrase string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "affine-cipher.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the Affine cipher, an ancient encryption algorithm from the Middle East.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Affine_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/affine-cipher.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Key { 4 | a int 5 | b int 6 | } 7 | 8 | fn encode(phrase string, key Key) !string { 9 | } 10 | 11 | fn decode(phrase string, key Key) !string { 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You've just been hired as professor of mathematics. 4 | Your first week went well, but something is off in your second week. 5 | The problem is that every answer given by your students is wrong! 6 | Luckily, your math skills have allowed you to identify the problem: the student answers _are_ correct, but they're all in base 2 (binary)! 7 | Amazingly, it turns out that each week, the students use a different base. 8 | To help you quickly verify the student answers, you'll be building a tool to translate between bases. 9 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "all-your-base.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert a number, represented as a sequence of digits in one base, to any other base." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn generate_digits(output_base int, value int, mut dest []int) { 4 | last_digit := value % output_base 5 | if value >= output_base { 6 | generate_digits(output_base, value / output_base, mut &dest) 7 | } 8 | dest << last_digit 9 | } 10 | 11 | fn rebase(input_base int, digits []int, output_base int) ![]int { 12 | if input_base < 2 { 13 | return error('input base must be >= 2') 14 | } 15 | if output_base < 2 { 16 | return error('output base must be >= 2') 17 | } 18 | 19 | mut value := 0 20 | for digit in digits { 21 | if digit < 0 || digit >= input_base { 22 | return error('all digits must satisfy 0 <= d < input base') 23 | } 24 | value = value * input_base + digit 25 | } 26 | 27 | mut result := []int{} 28 | generate_digits(output_base, value, mut &result) 29 | return result 30 | } 31 | -------------------------------------------------------------------------------- /exercises/practice/all-your-base/all-your-base.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn rebase(input_base int, digits []int, output_base int) ![]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "allergies.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum Allergen as u8 { 4 | eggs = 1 5 | peanuts = 2 6 | shellfish = 4 7 | strawberries = 8 8 | tomatoes = 16 9 | chocolate = 32 10 | pollen = 64 11 | cats = 128 12 | } 13 | 14 | fn allergic_to(allergen Allergen, score u8) bool { 15 | return u8(allergen) & score > 0 16 | } 17 | 18 | fn list(score u8) []Allergen { 19 | return [Allergen.eggs, Allergen.peanuts, Allergen.shellfish, Allergen.strawberries, 20 | Allergen.tomatoes, Allergen.chocolate, Allergen.pollen, Allergen.cats].filter(score & int(it) > 0) 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/allergies/allergies.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum Allergen as u8 { 4 | eggs 5 | peanuts 6 | shellfish 7 | strawberries 8 | tomatoes 9 | chocolate 10 | pollen 11 | cats 12 | } 13 | 14 | fn allergic_to(allergen Allergen, score u8) bool { 15 | // Please implement the `allergic_to` function 16 | } 17 | 18 | fn list(score u8) []Allergen { 19 | // Please implement the `list` function 20 | } 21 | -------------------------------------------------------------------------------- /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/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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "anagram.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn find_anagrams(subject string, candidates []string) []string { 4 | mut result := []string{cap: candidates.len} 5 | mut subject_runes := subject.to_lower().runes() 6 | subject_runes.sort() 7 | for candidate in candidates { 8 | if candidate.to_lower() == subject.to_lower() { 9 | continue 10 | } 11 | mut candidate_runes := candidate.to_lower().runes() 12 | candidate_runes.sort() 13 | if candidate_runes == subject_runes { 14 | result << candidate 15 | } 16 | } 17 | return result 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/anagram/anagram.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn find_anagrams(subject string, candidates []string) []string { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "armstrong-numbers.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine if a number is an Armstrong number.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math { count_digits, powi } 4 | 5 | pub fn is_armstrong_number(number u32) bool { 6 | signed_num := i64(number) 7 | num_of_digits := count_digits(signed_num) 8 | mut sum := i64(0) 9 | 10 | for div := signed_num; div > 0; div /= 10 { 11 | sum += powi(div % 10, num_of_digits) 12 | } 13 | 14 | return sum == signed_num 15 | } 16 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/armstrong-numbers.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn is_armstrong_number(number u32) bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "atbash-cipher.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import strings 4 | 5 | fn replacement(ch u8) ?u8 { 6 | if `0` <= ch && ch <= `9` { 7 | return ch 8 | } 9 | if `A` <= ch && ch <= `Z` { 10 | return u8(`a` + `Z` - ch) 11 | } 12 | if `a` <= ch && ch <= `z` { 13 | return u8(`a` + `z` - ch) 14 | } 15 | return none 16 | } 17 | 18 | fn encode(phrase string) string { 19 | mut builder := strings.new_builder(phrase.len * 6 / 5) 20 | for ch in phrase { 21 | if encoded_ch := replacement(ch) { 22 | if builder.len % 6 == 5 { 23 | builder.write_u8(u8(` `)) 24 | } 25 | builder.write_u8(encoded_ch) 26 | } 27 | } 28 | return builder.str() 29 | } 30 | 31 | fn decode(phrase string) string { 32 | mut builder := strings.new_builder(phrase.len) 33 | for ch in phrase { 34 | if decoded_ch := replacement(ch) { 35 | builder.write_u8(decoded_ch) 36 | } 37 | } 38 | return builder.str() 39 | } 40 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/atbash-cipher.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn encode(phrase string) string { 4 | } 5 | 6 | fn decode(phrase string) string { 7 | } 8 | -------------------------------------------------------------------------------- /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 | "natanaelsirqueira" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary-search.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn find(array []int, value int) !int { 4 | return binary_search(array, value, 0, array.len - 1) 5 | } 6 | 7 | fn binary_search(array []int, value int, lower_limit int, upper_limit int) !int { 8 | if upper_limit < lower_limit { 9 | return error('value not in array') 10 | } 11 | 12 | middle_index := (lower_limit + upper_limit) / 2 13 | middle_value := array[middle_index] 14 | 15 | return match true { 16 | value < middle_value { binary_search(array, value, lower_limit, middle_index - 1)! } 17 | value > middle_value { binary_search(array, value, middle_index + 1, upper_limit)! } 18 | else { middle_index } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/binary-search.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn find(array []int, value int) !int { 4 | return 0 5 | } 6 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bob.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 17 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/bob/bob.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn response(hey_bob string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/book-store/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "book-store.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math 4 | 5 | fn total(basket []int) int { 6 | mut tally := [0, 0, 0, 0, 0] 7 | for book in basket { 8 | tally[book - 1]++ 9 | } 10 | tally.sort() 11 | 12 | mut five := tally[0] 13 | mut four := tally[1] - tally[0] 14 | mut three := tally[2] - tally[1] 15 | two := tally[3] - tally[2] 16 | one := tally[4] - tally[3] 17 | 18 | // Two groups of four are cheaper than a group of five plus a group of three. 19 | adjustment := math.min(three, five) 20 | five -= adjustment 21 | three -= adjustment 22 | four += 2 * adjustment 23 | 24 | return 5 * five * 600 + 4 * four * 640 + 3 * three * 720 + 2 * two * 760 + 1 * one * 800 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/book-store/book-store.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn total(basket []int) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bottle-song.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/bottle-song.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn recite(start_bottles int, take_down int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/bowling/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bowling.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Score a bowling game.", 17 | "source": "The Bowling Game Kata from UncleBob", 18 | "source_url": "https://web.archive.org/web/20221001111000/http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/bowling/bowling.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Game {} 4 | 5 | // build a new Game 6 | fn Game.new() Game { 7 | } 8 | 9 | pub fn (mut g Game) roll(pins int) ! { 10 | } 11 | 12 | pub fn (g Game) score() !int { 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/change/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine the fewest number of coins to give a customer so that the sum of their values equals the correct amount of change. 4 | 5 | ## Examples 6 | 7 | - An amount of 15 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5 and one coin of value 10, or [5, 10]. 8 | - An amount of 40 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5, one coin of value 10, and one coin of value 25, or [5, 10, 25]. 9 | -------------------------------------------------------------------------------- /exercises/practice/change/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "change.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Correctly determine change to be given using the least number of coins.", 17 | "source": "Software Craftsmanship - Coin Change Kata", 18 | "source_url": "https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/change/change.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn find_fewest_coins(coins []int, target int) ![]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "circular-buffer.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "A data structure that uses a single, fixed-size buffer as if it were connected end-to-end.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Circular_buffer" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct CircularBuffer[T] { 4 | capacity int 5 | mut: 6 | content []T 7 | } 8 | 9 | pub fn create_buffer[T](capacity int) CircularBuffer[T] { 10 | return CircularBuffer[T]{ 11 | capacity: capacity 12 | content: []T{} 13 | } 14 | } 15 | 16 | pub fn (mut b CircularBuffer[T]) write(value T) ! { 17 | if b.content.len >= b.capacity { 18 | return error('Buffer is full') 19 | } 20 | b.content.prepend(value) 21 | } 22 | 23 | pub fn (mut b CircularBuffer[T]) read() !T { 24 | if b.content.len == 0 { 25 | return error('Buffer is empty') 26 | } 27 | 28 | return b.content.pop() 29 | } 30 | 31 | pub fn (mut b CircularBuffer[T]) overwrite(value T) { 32 | if b.content.len >= b.capacity { 33 | b.content.pop() 34 | } 35 | 36 | b.content.prepend(value) 37 | } 38 | 39 | pub fn (mut b CircularBuffer[T]) clear() { 40 | b.content.clear() 41 | } 42 | -------------------------------------------------------------------------------- /exercises/practice/circular-buffer/circular-buffer.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct CircularBuffer[T] { 4 | // Please define the CircularBuffer struct 5 | } 6 | 7 | pub fn create_buffer[T](capacity int) CircularBuffer[T] { 8 | // Please implement the `create_buffer` function 9 | } 10 | 11 | pub fn (mut b CircularBuffer[T]) write(value T) ! { 12 | // Please implement the `write` function 13 | } 14 | 15 | pub fn (mut b CircularBuffer[T]) read() !T { 16 | // Please implement the `read` function 17 | } 18 | 19 | pub fn (mut b CircularBuffer[T]) overwrite(value T) { 20 | // Please implement the `overwrite` function 21 | } 22 | 23 | pub fn (mut b CircularBuffer[T]) clear() { 24 | // Please implement the `clear` function 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/clock/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement a clock that handles times without dates. 4 | 5 | You should be able to add and subtract minutes to it. 6 | 7 | Two clocks that represent the same time should be equal to each other. 8 | -------------------------------------------------------------------------------- /exercises/practice/clock/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "clock.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement a clock that handles times without dates.", 17 | "source": "Pairing session with Erin Drummond" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/clock/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Clock { 4 | mut: 5 | time int 6 | } 7 | 8 | fn new_clock(hour int, minute int) Clock { 9 | mut c := Clock{ 10 | time: (hour * 60 + minute) % 1440 11 | } 12 | if c.time < 0 { 13 | c.time += 1440 14 | } 15 | 16 | return c 17 | } 18 | 19 | fn (mut c Clock) add_time(minute int) { 20 | c.time = (c.time + minute) % 1440 21 | } 22 | 23 | fn (mut c Clock) subtract_time(minute int) { 24 | c.time = (c.time - minute) % 1440 25 | if c.time < 0 { 26 | c.time += 1440 27 | } 28 | } 29 | 30 | fn (c Clock) string() string { 31 | return '${c.time / 60:02}:${c.time % 60:02}' 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/clock/clock.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Clock { 4 | } 5 | 6 | fn new_clock(hour int, minute int) Clock { 7 | } 8 | 9 | fn (mut c Clock) add_time(minute int) { 10 | } 11 | 12 | fn (mut c Clock) subtract_time(minute int) { 13 | } 14 | 15 | fn (c Clock) string() string { 16 | } 17 | -------------------------------------------------------------------------------- /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 | "andrerfcsantos" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "collatz-conjecture.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Collatz_conjecture" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn collatz(number int) !int { 4 | mut n := number 5 | mut times := 0 6 | 7 | if n <= 0 { 8 | return error('zero or negative value given') 9 | } 10 | 11 | for n != 1 { 12 | if n % 2 == 0 { 13 | n = n / 2 14 | } else { 15 | n = n * 3 + 1 16 | } 17 | times += 1 18 | } 19 | 20 | return times 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn collatz(number int) !int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/complex-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "complex-numbers.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement complex numbers.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Complex_number" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/connect/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "connect.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Compute the result for a game of Hex / Polygon." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/connect/connect.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn winner(board []string) ?rune { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "crypto-square.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement the classic method for composing secret messages called a square code.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/crypto-square.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn ciphertext(plaintext string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/custom-set/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Create a custom set type. 4 | 5 | Sometimes it is necessary to define a custom data structure of some type, like a set. 6 | In this exercise you will define your own set. 7 | How it works internally doesn't matter, as long as it behaves like a set of unique elements. 8 | -------------------------------------------------------------------------------- /exercises/practice/custom-set/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "custom-set.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Create a custom set type." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "darts.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Calculate the points scored in a single toss of a Darts game.", 17 | "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math 4 | 5 | fn score(x f64, y f64) int { 6 | r := math.sqrt(x * x + y * y) 7 | if r > 10.0 { 8 | return 0 9 | } 10 | if r > 5.0 { 11 | return 1 12 | } 13 | if r > 1.0 { 14 | return 5 15 | } 16 | return 10 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/darts/darts.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn score(x f64, y f64) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "diamond.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.", 17 | "source": "Seb Rose", 18 | "source_url": "https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import strings 4 | 5 | fn generate_row(index int, n int) string { 6 | if index > n { 7 | return generate_row(2 * n - index, n) 8 | } 9 | len := 2 * n + 1 10 | mut builder := strings.new_builder(len) 11 | builder.write_string(strings.repeat(u8(` `), n - index)) 12 | builder.write_rune(`A` + index) 13 | if index > 0 { 14 | builder.write_string(strings.repeat(u8(` `), 2 * index - 1)) 15 | builder.write_rune(`A` + index) 16 | } 17 | builder.write_string(strings.repeat(u8(` `), n - index)) 18 | assert builder.len == len 19 | return builder.str() 20 | } 21 | 22 | fn rows(letter rune) []string { 23 | assert `A` <= letter && letter <= `Z` 24 | n := int(letter - `A`) 25 | len := 2 * n + 1 26 | mut result := []string{cap: len} 27 | for i in 0 .. len { 28 | result << generate_row(i, n) 29 | } 30 | return result 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [202fb4cc-6a38-4883-9193-a29d5cb92076] 6 | description = "Degenerate case with a single 'A' row" 7 | 8 | [bd6a6d78-9302-42e9-8f60-ac1461e9abae] 9 | description = "Degenerate case with no row containing 3 distinct groups of spaces" 10 | 11 | [af8efb49-14ed-447f-8944-4cc59ce3fd76] 12 | description = "Smallest non-degenerate case with odd diamond side length" 13 | 14 | [e0c19a95-9888-4d05-86a0-fa81b9e70d1d] 15 | description = "Smallest non-degenerate case with even diamond side length" 16 | 17 | [82ea9aa9-4c0e-442a-b07e-40204e925944] 18 | description = "Largest possible diamond" 19 | -------------------------------------------------------------------------------- /exercises/practice/diamond/diamond.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn rows(letter rune) []string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Find the difference between the square of the sum and the sum of the squares of the first N natural numbers. 4 | 5 | The square of the sum of the first ten natural numbers is 6 | (1 + 2 + ... + 10)² = 55² = 3025. 7 | 8 | The sum of the squares of the first ten natural numbers is 9 | 1² + 2² + ... + 10² = 385. 10 | 11 | Hence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is 3025 - 385 = 2640. 12 | 13 | You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. 14 | Finding the best algorithm for the problem is a key skill in software engineering. 15 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "difference-of-squares.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 17 | "source": "Problem 6 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=6" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | /* 4 | The summation ('sum') of a sequence is explained in 5 | 6 | https://en.wikipedia.org/wiki/0_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF 7 | */ 8 | pub fn square_of_sum(n u32) u32 { 9 | sum := (n * (n + 1)) / 2 10 | return sum * sum 11 | } 12 | 13 | /* 14 | For an explanation see: 15 | 16 | https://en.wikipedia.org/wiki/Square_pyramidal_number#Geometric_enumeration 17 | */ 18 | pub fn sum_of_squares(n u32) u32 { 19 | return n * (n + 1) * (2 * n + 1) / 6 20 | } 21 | 22 | pub fn difference(n u32) u32 { 23 | return square_of_sum(n) - sum_of_squares(n) 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn square_of_sum(n u32) u32 { 4 | } 5 | 6 | pub fn sum_of_squares(n u32) u32 { 7 | } 8 | 9 | pub fn difference(n u32) u32 { 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_square_of_sum_1() { 4 | assert square_of_sum(1) == 1 5 | } 6 | 7 | fn test_square_of_sum_5() { 8 | assert square_of_sum(5) == 225 9 | } 10 | 11 | fn test_square_of_sum_100() { 12 | assert square_of_sum(100) == 25_502_500 13 | } 14 | 15 | fn test_sum_of_squares_1() { 16 | assert sum_of_squares(1) == 1 17 | } 18 | 19 | fn test_sum_of_squares_5() { 20 | assert sum_of_squares(5) == 55 21 | } 22 | 23 | fn test_sum_of_squares_100() { 24 | assert sum_of_squares(100) == 338_350 25 | } 26 | 27 | fn test_difference_1() { 28 | assert difference(1) == 0 29 | } 30 | 31 | fn test_difference_5() { 32 | assert difference(5) == 170 33 | } 34 | 35 | fn test_difference_100() { 36 | assert difference(100) == 25_164_150 37 | } 38 | -------------------------------------------------------------------------------- /exercises/practice/dominoes/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Make a chain of dominoes. 4 | 5 | Compute a way to order a given set of domino stones so that they form a correct domino chain. 6 | In the chain, the dots on one half of a stone must match the dots on the neighboring half of an adjacent stone. 7 | Additionally, the dots on the halves of the stones without neighbors (the first and last stone) must match each other. 8 | 9 | For example given the stones `[2|1]`, `[2|3]` and `[1|3]` you should compute something 10 | like `[1|2] [2|3] [3|1]` or `[3|2] [2|1] [1|3]` or `[1|3] [3|2] [2|1]` etc, where the first and last numbers are the same. 11 | 12 | For stones `[1|2]`, `[4|1]` and `[2|3]` the resulting chain is not valid: `[4|1] [1|2] [2|3]`'s first and last numbers are not the same. 13 | 4 != 3 14 | 15 | Some test cases may use duplicate stones in a chain solution, assume that multiple Domino sets are being used. 16 | -------------------------------------------------------------------------------- /exercises/practice/dominoes/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In Toyland, the trains are always busy delivering treasures across the city, from shiny marbles to rare building blocks. 4 | The tracks they run on are made of colorful domino-shaped pieces, each marked with two numbers. 5 | For the trains to move, the dominoes must form a perfect chain where the numbers match. 6 | 7 | Today, an urgent delivery of rare toys is on hold. 8 | You've been handed a set of track pieces to inspect. 9 | If they can form a continuous chain, the train will be on its way, bringing smiles across Toyland. 10 | If not, the set will be discarded, and another will be tried. 11 | 12 | The toys are counting on you to solve this puzzle. 13 | Will the dominoes connect the tracks and send the train rolling, or will the set be left behind? 14 | -------------------------------------------------------------------------------- /exercises/practice/dominoes/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "dominoes.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Make a chain of dominoes." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/dominoes/dominoes.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | type Domino = []int 4 | 5 | fn can_chain(dominoes []Domino) bool { 6 | } 7 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "eliuds-eggs.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.", 17 | "source": "Christian Willner, Eric Willigers", 18 | "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn egg_count(number int) int { 4 | mut result := 0 5 | mut remaining := number 6 | for remaining != 0 { 7 | result++ 8 | 9 | // Clear least significant 1 bit. 10 | remaining -= remaining & (1 + ~remaining) 11 | } 12 | return result 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [559e789d-07d1-4422-9004-3b699f83bca3] 6 | description = "0 eggs" 7 | 8 | [97223282-f71e-490c-92f0-b3ec9e275aba] 9 | description = "1 egg" 10 | 11 | [1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5] 12 | description = "4 eggs" 13 | 14 | [0c18be92-a498-4ef2-bcbb-28ac4b06cb81] 15 | description = "13 eggs" 16 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/eliuds-eggs.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn egg_count(number int) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/eliuds-eggs/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_0_eggs() { 4 | assert egg_count(0) == 0 5 | } 6 | 7 | fn test_1_egg() { 8 | assert egg_count(16) == 1 9 | } 10 | 11 | fn test_4_eggs() { 12 | assert egg_count(89) == 4 13 | } 14 | 15 | fn test_13_eggs() { 16 | assert egg_count(2000000000) == 13 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "etl.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Change the data format for scoring a game to more easily add other languages.", 17 | "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn transform(legacy map[int][]rune) map[rune]int { 4 | mut result := map[rune]int{} 5 | for score, letters in legacy { 6 | for letter in letters { 7 | lower_letter := letter.str().to_lower()[0] 8 | result[lower_letter] = score 9 | } 10 | } 11 | return result 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [78a7a9f9-4490-4a47-8ee9-5a38bb47d28f] 6 | description = "single letter" 7 | 8 | [60dbd000-451d-44c7-bdbb-97c73ac1f497] 9 | description = "single score with multiple letters" 10 | 11 | [f5c5de0c-301f-4fdd-a0e5-df97d4214f54] 12 | description = "multiple scores with multiple letters" 13 | 14 | [5db8ea89-ecb4-4dcd-902f-2b418cc87b9d] 15 | description = "multiple scores with differing numbers of letters" 16 | -------------------------------------------------------------------------------- /exercises/practice/etl/etl.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn transform(legacy map[int][]rune) map[rune]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "food-chain.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/food-chain.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn recite(start_verse int, end_verse int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | After each generation, the cells interact with their eight neighbors, which are cells adjacent horizontally, vertically, or diagonally. 4 | 5 | The following rules are applied to each cell: 6 | 7 | - Any live cell with two or three live neighbors lives on. 8 | - Any dead cell with exactly three live neighbors becomes a live cell. 9 | - All other cells die or stay dead. 10 | 11 | Given a matrix of 1s and 0s (corresponding to live and dead cells), apply the rules to each cell, and return the next generation. 12 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Conway's Game of Life][game-of-life] is a fascinating cellular automaton created by the British mathematician John Horton Conway in 1970. 4 | 5 | The game consists of a two-dimensional grid of cells that can either be "alive" or "dead." 6 | 7 | After each generation, the cells interact with their eight neighbors via a set of rules, which define the new generation. 8 | 9 | [game-of-life]: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life 10 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "game-of-life.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn tick(matrix [][]int) [][]int { 4 | if matrix.len == 0 { 5 | return matrix 6 | } 7 | mut result := [][]int{len: matrix.len, init: []int{len: matrix[0].len}} 8 | for i in 0 .. matrix.len { 9 | for j in 0 .. matrix[0].len { 10 | mut live_neighbors := 0 11 | for di in -1 .. 2 { 12 | ni := i + di 13 | if ni < 0 || ni >= matrix.len { 14 | continue 15 | } 16 | for dj in -1 .. 2 { 17 | nj := j + dj 18 | if nj < 0 || nj >= matrix[0].len { 19 | continue 20 | } 21 | if di == 0 && dj == 0 { 22 | continue 23 | } 24 | if matrix[ni][nj] != 0 { 25 | live_neighbors++ 26 | } 27 | } 28 | } 29 | result[i][j] = if live_neighbors == 2 { 30 | matrix[i][j] 31 | } else if live_neighbors == 3 { 32 | 1 33 | } else { 34 | 0 35 | } 36 | } 37 | } 38 | return result 39 | } 40 | -------------------------------------------------------------------------------- /exercises/practice/game-of-life/game-of-life.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn tick(matrix [][]int) [][]int { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "gautampanchal94" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "gigasecond.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", 17 | "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=09" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import time 4 | 5 | fn add_gigasecond(t time.Time) time.Time { 6 | return t.add_seconds(1000000000) 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/gigasecond.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import time 4 | 5 | fn add_gigasecond(t time.Time) time.Time { 6 | // Add code here 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grade-school.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given students' names along with the grade that they are in, create a roster for the school.", 17 | "source": "A pairing session with Phil Battos at gSchool" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn add_student(roster map[int][]string, name string, grade int) map[int][]string { 4 | mut new_roster := roster.clone() 5 | // make sure we aren't adding the same name twice 6 | for _, names in roster { 7 | if name in names { 8 | return roster 9 | } 10 | } 11 | 12 | // append the new name and sort 13 | new_roster[grade] << name 14 | new_roster[grade].sort() 15 | return new_roster 16 | } 17 | 18 | fn get_students_in_grade(roster map[int][]string, grade int) []string { 19 | return roster[grade] 20 | } 21 | 22 | fn get_all_students(roster map[int][]string) []string { 23 | mut keys := roster.keys() 24 | keys.sort() 25 | mut all_names := []string{} 26 | for key in keys { 27 | all_names << roster[key] 28 | } 29 | return all_names 30 | } 31 | 32 | fn create_new_roster() map[int][]string { 33 | return map[int][]string{} 34 | } 35 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/grade-school.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // NOTE: there are multiple ways to accomplish this. To allow for automated 4 | // testing, please fill out whatever type you choose for the type of roster. 5 | // To make it easy to search, that has been replaced with . Good luck! :) 6 | 7 | fn add_student(roster , name string, grade int) { 8 | } 9 | 10 | fn get_students_in_grade(roster , grade int) []string { 11 | } 12 | 13 | fn get_all_students(roster ) []string { 14 | } 15 | 16 | // This is a helper function that should return an 17 | // empty roster (type of your choosing) 18 | fn create_new_roster() { 19 | return 20 | } 21 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grains.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", 17 | "source": "The CodeRanch Cattle Drive, Assignment 6", 18 | "source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn grains_on_square(square int) !u64 { 4 | if !error_if_bad_square(square) { 5 | return pow(2, square-1) 6 | } 7 | return error("square must be between 1 and 64") 8 | } 9 | 10 | fn total_grains_on_board() u64 { 11 | return 0xFFFFFFFF_FFFFFFFF 12 | } 13 | 14 | fn pow(a u64, b int) u64 { 15 | mut pow := u64(1) 16 | for _ in 0 .. b { 17 | pow *= a 18 | } 19 | return pow 20 | } 21 | 22 | fn error_if_bad_square(square int) bool { 23 | if square <= 0 || square > 64 { 24 | return true 25 | } 26 | return false 27 | } -------------------------------------------------------------------------------- /exercises/practice/grains/grains.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn grains_on_square(square int) !u64 { 4 | } 5 | 6 | fn total_grains_on_board() u64 { 7 | } 8 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hamming.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Calculate the Hamming distance between two DNA strands.", 17 | "source": "The Calculating Point Mutations problem at Rosalind", 18 | "source_url": "https://rosalind.info/problems/hamm/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn distance(a string, b string) !int { 4 | if a.len != b.len { 5 | return error('lengths must match!') 6 | } 7 | mut sum := 0 8 | for i in 0 .. a.len { 9 | if a[i] != b[i] { 10 | sum++ 11 | } 12 | } 13 | return sum 14 | } 15 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn distance(a string, b string) !int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | The classical introductory exercise. 4 | Just say "Hello, World!". 5 | 6 | ["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment. 7 | 8 | The objectives are simple: 9 | 10 | - Modify the provided code so that it produces the string "Hello, World!". 11 | - Run the test suite and make sure that it succeeds. 12 | - Submit your solution and check it at the website. 13 | 14 | If everything goes well, you will be ready to fetch your first real exercise. 15 | 16 | [hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program 17 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hello-world.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", 17 | "source": "This is an exercise to introduce users to using Exercism", 18 | "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn hello() string { 4 | return "Hello, World!" 5 | } -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [af9ffe10-dc13-42d8-a742-e7bdafac449d] 13 | description = "Say Hi!" 14 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn hello() string { 4 | return 'Goodbye, Mars!' 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_hello() { 4 | assert hello() == 'Hello, World!' 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Manage a game player's High Score list. 4 | 5 | Your task is to build a high-score component of the classic Frogger game, one of the highest selling and most addictive games of all time, and a classic of the arcade era. 6 | Your task is to write methods that return the highest score from the list, the last added score and the three highest scores. 7 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "contributors": [ 6 | "1ethanhansen" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "high-scores.v" 11 | ], 12 | "test": [ 13 | "run_test.v" 14 | ], 15 | "example": [ 16 | ".meta/example.v" 17 | ] 18 | }, 19 | "blurb": "Manage a player's High Score list.", 20 | "source": "Tribute to the eighties' arcade game Frogger" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import arrays 4 | 5 | type HighScores = []int 6 | 7 | // build a new HighScores 8 | pub fn HighScores.new(scores []int) HighScores { 9 | return scores.clone() 10 | } 11 | 12 | pub fn (mut high_scores HighScores) scores() []int { 13 | return high_scores 14 | } 15 | 16 | pub fn (mut high_scores HighScores) latest() int { 17 | return high_scores.last() 18 | } 19 | 20 | pub fn (mut high_scores HighScores) personal_best() int { 21 | return arrays.max(high_scores) or { 0 } 22 | } 23 | 24 | pub fn (mut high_scores HighScores) personal_top_three() []int { 25 | mut result := high_scores.sorted(b < a) 26 | result.trim(3) 27 | return result 28 | } 29 | -------------------------------------------------------------------------------- /exercises/practice/high-scores/high-scores.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct HighScores { 4 | } 5 | 6 | // build a new HighScores 7 | pub fn HighScores.new(scores []int) HighScores { 8 | } 9 | 10 | pub fn (mut high_scores HighScores) scores() []int { 11 | } 12 | 13 | pub fn (mut high_scores HighScores) latest() int { 14 | } 15 | 16 | pub fn (mut high_scores HighScores) personal_best() int { 17 | } 18 | 19 | pub fn (mut high_scores HighScores) personal_top_three() []int { 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/house/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "house.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import strings 4 | 5 | const lyrics = '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.\n' 6 | 7 | const table = [0, 389, 368, 351, 331, 310, 267, 232, 190, 145, 99, 62, 8] 8 | 9 | fn recite(start_verse int, end_verse int) string { 10 | mut builder := strings.new_builder(4000) 11 | for verse in start_verse .. (end_verse + 1) { 12 | builder.write_string(lyrics[0..8]) 13 | builder.write_string(lyrics[table[verse]..]) 14 | } 15 | builder.go_back(1) // Omit final newline 16 | return builder.str() 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/house/house.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn recite(start_verse int, end_verse int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/intergalactic-transmission/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "intergalactic-transmission.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/intergalactic-transmission.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn transmit_sequence(data []u8) []u8 { 4 | // Please implement the `transmit_sequence` function 5 | 6 | } 7 | 8 | fn decode_message(received []u8) ![]u8 { 9 | // Please implement the `decode_message` function 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isbn-verifier.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/isbn-verifier.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn is_valid(isbn_10 string) bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a word or phrase is an isogram. 4 | 5 | An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times. 6 | 7 | Examples of isograms: 8 | 9 | - lumberjacks 10 | - background 11 | - downstream 12 | - six-year-old 13 | 14 | The word _isograms_, however, is not an isogram, because the s repeats. 15 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isogram.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine if a word or phrase is an isogram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Isogram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/isogram/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_isogram(word string) bool { 4 | upper := word.to_upper().split('') 5 | for i, letter in upper { 6 | if letter != ' ' && letter != '-' && (letter in upper[..i] || letter in upper[i + 1..]) { 7 | return false 8 | } 9 | } 10 | return true 11 | } 12 | -------------------------------------------------------------------------------- /exercises/practice/isogram/isogram.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_isogram(word string) bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/killer-sudoku-helper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "killer-sudoku-helper.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Write a tool that makes it easier to solve Killer Sudokus", 17 | "source": "Created by Sascha Mann, Jeremy Walker, and BethanyG for the Julia track on Exercism.", 18 | "source_url": "https://github.com/exercism/julia/pull/413" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/killer-sudoku-helper/killer-sudoku-helper.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn combinations(sum int, size int, exclude []int) [][]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The kindergarten class is learning about growing plants. 4 | The teacher thought it would be a good idea to give the class seeds to plant and grow in the dirt. 5 | To this end, the children have put little cups along the window sills and planted one type of plant in each cup. 6 | The children got to pick their favorites from four available types of seeds: grass, clover, radishes, and violets. 7 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "kindergarten-garden.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a diagram, determine which plants each child in the kindergarten class is responsible for.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn plant(letter rune) string { 4 | if letter == `G` { 5 | return "grass" 6 | } 7 | if letter == `C` { 8 | return "clover" 9 | } 10 | if letter == `R` { 11 | return "radishes" 12 | } 13 | if letter == `V` { 14 | return "violets" 15 | } 16 | 17 | return "" 18 | } 19 | 20 | fn plants(diagram string, student string) []string { 21 | first := 2 * (student[0] - `A`) 22 | second := first + 1 23 | third := (diagram.len + 1) / 2 + first 24 | fourth := third + 1 25 | 26 | return [ 27 | plant(diagram[first]), 28 | plant(diagram[second]), 29 | plant(diagram[third]), 30 | plant(diagram[fourth]) 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/kindergarten-garden/kindergarten-garden.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn plants(diagram string, student string) []string { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "knapsack.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a knapsack that can only carry a certain weight, determine which items to put in the knapsack in order to maximize their combined value.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Knapsack_problem" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Item { 4 | weight int 5 | value int 6 | } 7 | 8 | fn maximum_value(maximum_weight int, items []Item) int { 9 | mut value := []int{len: maximum_weight + 1, init: 0} 10 | 11 | for item in items { 12 | // For each weight i, value[i] contains the maximum value achievable 13 | // with the items seen to date. Each item may only be used once. 14 | for i := maximum_weight; i >= item.weight; i-- { 15 | value[i] = maximum(value[i], value[i - item.weight] + item.value) 16 | } 17 | } 18 | 19 | return value[maximum_weight] 20 | } 21 | 22 | fn maximum(a int, b int) int { 23 | return if a > b { a } else { b } 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/knapsack.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Item { 4 | weight int 5 | value int 6 | } 7 | 8 | fn maximum_value(maximum_weight int, items []Item) int { 9 | } 10 | -------------------------------------------------------------------------------- /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 | "largest-series-product.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.", 17 | "source": "A variation on Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn largest_product(digits string, span int) !int { 4 | if span < 0 { 5 | return error('span must not be negative') 6 | } 7 | if span > digits.len { 8 | return error('span must be smaller than string length') 9 | } 10 | for digit in digits { 11 | if digit < `0` || `9` < digit { 12 | return error('digits input must only contain digits') 13 | } 14 | } 15 | 16 | mut result := 0 17 | for start in 0 .. (digits.len + 1 - span) { 18 | mut product := 1 19 | for index in start .. (start + span) { 20 | product *= int(digits[index] - `0`) 21 | } 22 | if result < product { 23 | result = product 24 | } 25 | } 26 | return result 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/largest-series-product.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn largest_product(digits string, span int) !int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine whether a given year is a leap year. 4 | -------------------------------------------------------------------------------- /exercises/practice/leap/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A leap year (in the Gregorian calendar) occurs: 4 | 5 | - In every year that is evenly divisible by 4. 6 | - Unless the year is evenly divisible by 100, in which case it's only a leap year if the year is also evenly divisible by 400. 7 | 8 | Some examples: 9 | 10 | - 1997 was not a leap year as it's not divisible by 4. 11 | - 1900 was not a leap year as it's not divisible by 400. 12 | - 2000 was a leap year! 13 | 14 | ~~~~exercism/note 15 | For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE). 16 | ~~~~ 17 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "leap.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine whether a given year is a leap year.", 17 | "source": "CodeRanch Cattle Drive, Assignment 3", 18 | "source_url": "https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // is_leap_year returns true if the given year is a leap year in the Gregorian calendar 4 | fn is_leap_year(year int) bool { 5 | return (if year % 100 == 0 {year % 400 == 0} else {year % 4 == 0}) 6 | } -------------------------------------------------------------------------------- /exercises/practice/leap/leap.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // is_leap_year returns true if the given year is a leap year in the Gregorian calendar 4 | fn is_leap_year(year int) bool { 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/leap/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_not_divisible_by_4() { 4 | assert !is_leap_year(2015) 5 | } 6 | 7 | fn test_divisible_by_2_not_by_4() { 8 | assert !is_leap_year(1970) 9 | } 10 | 11 | fn test_divisible_by_4_not_by_100() { 12 | assert is_leap_year(1996) 13 | } 14 | 15 | fn test_divisible_by_4_and_5() { 16 | assert is_leap_year(1960) 17 | } 18 | 19 | fn test_divisible_by_100_not_by_400() { 20 | assert !is_leap_year(2100) 21 | } 22 | 23 | fn test_divisible_by_100_not_by_3() { 24 | assert !is_leap_year(1900) 25 | } 26 | 27 | fn test_divisible_by_400() { 28 | assert is_leap_year(2000) 29 | } 30 | 31 | fn test_divisible_by_100_not_by_125() { 32 | assert is_leap_year(2400) 33 | } 34 | 35 | fn test_divisible_by_200_not_by_400() { 36 | assert !is_leap_year(1800) 37 | } 38 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | Your list must also implement the following interface: 4 | 5 | - `delete` (delete the first occurrence of a specified value) 6 | - `count` (count the number of items in the list) 7 | 8 | The stubs in `linked-list.v` provide the _minimum_ set of interfaces. You may wish to add your own definitions, such as a structure to represent an item in the list. 9 | 10 | However, do _not_ use a library to implement this exercise, and do _not_ use an array. 11 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You are working on a project to develop a train scheduling system for a busy railway network. 4 | 5 | You've been asked to develop a prototype for the train routes in the scheduling system. 6 | Each route consists of a sequence of train stations that a given train stops at. 7 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "hraftery" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "linked-list.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement a doubly linked list.", 17 | "source": "Classic computer science topic" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/linked-list/linked-list.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // define the LinkedList type here 4 | struct LinkedList { 5 | } 6 | 7 | // implement these methods as a minimum 8 | pub fn (mut l LinkedList) push(value int) { 9 | } 10 | 11 | pub fn (mut l LinkedList) pop() int { 12 | } 13 | 14 | pub fn (mut l LinkedList) unshift(value int) { 15 | } 16 | 17 | pub fn (mut l LinkedList) shift() int { 18 | } 19 | 20 | pub fn (l LinkedList) count() int { 21 | } 22 | 23 | pub fn (mut l LinkedList) delete(value int) { 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "list-ops.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement basic list operations." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/list-ops.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn append[T](front []T, back []T) []T { 4 | } 5 | 6 | pub fn concat[T](array [][]T) []T { 7 | } 8 | 9 | pub fn foldl[T, U](array []T, initial U, folder fn (acc U, e T) U) U { 10 | } 11 | 12 | pub fn foldr[T, U](array []T, initial U, folder fn (acc U, e T) U) U { 13 | } 14 | 15 | pub fn length[T](array []T) int { 16 | } 17 | 18 | pub fn reverse[T](array []T) []T { 19 | } 20 | 21 | pub fn filter[T](array []T, predicate fn (e T) bool) []T { 22 | } 23 | 24 | // renamed 'map_of' as 'map' conflicts with V 'map' datatype 25 | 26 | pub fn map_of[T, U](array []T, mapper fn (e T) U) []U { 27 | } 28 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "luhn.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", 17 | "source": "The Luhn Algorithm on Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/luhn/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn valid(value string) bool { 4 | mut count := 0 5 | mut total := 0 6 | 7 | // We traverse the string once, starting from the right. 8 | mut index := value.len 9 | for index > 0 { 10 | index-- 11 | mut ch := value[index] 12 | if ch.is_space() { 13 | continue 14 | } 15 | if !ch.is_digit() { 16 | return false 17 | } 18 | count++ 19 | 20 | mut digit := int(ch) - int(`0`) 21 | if count % 2 == 0 { 22 | digit *= 2 23 | if digit > 9 { 24 | digit -= 9 25 | } 26 | } 27 | total += digit 28 | } 29 | return count >= 2 && total % 10 == 0 30 | } 31 | -------------------------------------------------------------------------------- /exercises/practice/luhn/luhn.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn valid(value string) bool { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matching-brackets.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Make sure the brackets and braces all match.", 17 | "source": "Ginna Baker" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_paired(input string) bool { 4 | open := '[{(' 5 | close := ']})' 6 | 7 | // Brackets that have been opened but not closed. 8 | mut pending := []int{} 9 | 10 | for ch in input.bytes() { 11 | if bracket_type := open.index(ch.ascii_str()) { 12 | pending << bracket_type 13 | } else if bracket_type := close.index(ch.ascii_str()) { 14 | if pending.len == 0 || pending.pop() != bracket_type { 15 | return false 16 | } 17 | } 18 | } 19 | 20 | return pending.len == 0 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/matching-brackets.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_paired(input string) bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string representing a matrix of numbers, return the rows and columns of that matrix. 4 | 5 | So given a string with embedded newlines like: 6 | 7 | ```text 8 | 9 8 7 9 | 5 3 2 10 | 6 6 7 11 | ``` 12 | 13 | representing this matrix: 14 | 15 | ```text 16 | 1 2 3 17 | |--------- 18 | 1 | 9 8 7 19 | 2 | 5 3 2 20 | 3 | 6 6 7 21 | ``` 22 | 23 | your code should be able to spit out: 24 | 25 | - A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows, 26 | - A list of the columns, reading each column top-to-bottom while moving from left-to-right. 27 | 28 | The rows for our example matrix: 29 | 30 | - 9, 8, 7 31 | - 5, 3, 2 32 | - 6, 6, 7 33 | 34 | And its columns: 35 | 36 | - 9, 5, 6 37 | - 8, 3, 6 38 | - 7, 2, 7 39 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matrix.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a string representing a matrix of numbers, return the rows and columns of that matrix.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn row(str string, index int) []int { 4 | line := str.split_into_lines()[index - 1] 5 | return line.split(' ').map(fn (s string) int { 6 | return s.int() 7 | }) 8 | } 9 | 10 | fn column(str string, index int) []int { 11 | lines := str.split_into_lines() 12 | return lines.map(fn [index] (line string) int { 13 | return line.split(' ')[index - 1].int() 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /exercises/practice/matrix/matrix.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn row(str string, index int) []int { 4 | } 5 | 6 | fn column(str string, index int) []int { 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/meetup/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "meetup.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Calculate the date of meetups.", 17 | "source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/meetup/meetup.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn date(phrase string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "micro-blog.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given an input string, truncate it to 5 characters." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn truncate(phrase string) string { 4 | if phrase.len_utf8() <= 5 { 5 | return phrase 6 | } 7 | return phrase.runes()[0..5].string() 8 | } 9 | -------------------------------------------------------------------------------- /exercises/practice/micro-blog/micro-blog.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn truncate(phrase string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to add the mine counts to empty squares in a completed Minesweeper board. 4 | The board itself is a rectangle composed of squares that are either empty (`' '`) or a mine (`'*'`). 5 | 6 | For each empty square, count the number of mines adjacent to it (horizontally, vertically, diagonally). 7 | If the empty square has no adjacent mines, leave it empty. 8 | Otherwise replace it with the adjacent mines count. 9 | 10 | For example, you may receive a 5 x 4 board like this (empty spaces are represented here with the '·' character for display on screen): 11 | 12 | ```text 13 | ·*·*· 14 | ··*·· 15 | ··*·· 16 | ····· 17 | ``` 18 | 19 | Which your code should transform into this: 20 | 21 | ```text 22 | 1*3*1 23 | 13*31 24 | ·2*2· 25 | ·111· 26 | ``` 27 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [Minesweeper][wikipedia] is a popular game where the user has to find the mines using numeric hints that indicate how many mines are directly adjacent (horizontally, vertically, diagonally) to a square. 4 | 5 | [wikipedia]: https://en.wikipedia.org/wiki/Minesweeper_(video_game) 6 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "minesweeper.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Add the numbers to a minesweeper board." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/minesweeper/minesweeper.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn annotate(minefield []string) []string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a number n, determine what the nth prime is. 4 | 5 | By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 6 | 7 | If your language provides methods in the standard library to deal with prime numbers, pretend they don't exist and implement them yourself. 8 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "nth-prime.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a number n, determine what the nth prime is.", 17 | "source": "A variation on Problem 7 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=7" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import math 4 | 5 | fn nth_prime(n int) !int { 6 | if n < 1 { 7 | return error('n must be greater than 0') 8 | } 9 | 10 | mut n_primes := 1 11 | mut i := 3 12 | 13 | for n_primes < n { 14 | if is_prime(i) { 15 | n_primes++ 16 | } 17 | i++ 18 | } 19 | return i - 1 20 | } 21 | 22 | fn is_prime(n int) bool { 23 | for m in 2 .. int(math.ceil(math.sqrt(n))) + 1 { 24 | if n % m == 0 { 25 | return false 26 | } 27 | } 28 | return true 29 | } 30 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/nth-prime.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn nth_prime(n int) !int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_first_prime() { 4 | assert nth_prime(1)! == 2 5 | } 6 | 7 | fn test_second_prime() { 8 | assert nth_prime(2)! == 3 9 | } 10 | 11 | fn test_sixth_prime() { 12 | assert nth_prime(6)! == 13 13 | } 14 | 15 | fn test_big_prime() { 16 | assert nth_prime(10001)! == 104743 17 | } 18 | 19 | fn test_zeroth_prime() { 20 | if res := nth_prime(0) { 21 | assert false, 'there is no zeroth prime' 22 | } else { 23 | assert err.msg() == 'n must be greater than 0' 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "nucleotide-count.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", 17 | "source": "The Calculating DNA Nucleotides_problem at Rosalind", 18 | "source_url": "https://rosalind.info/problems/dna/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn count_nucleotides(strand string) !map[string]int { 4 | mut total_counts := { 5 | 'A': 0 6 | 'C': 0 7 | 'G': 0 8 | 'T': 0 9 | } 10 | for letter in strand { 11 | letter_str := letter.ascii_str() 12 | if letter_str in total_counts { 13 | total_counts[letter_str] += 1 14 | } else { 15 | return error('${letter_str} is not a valid nucleotide!') 16 | } 17 | } 18 | return total_counts 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/nucleotide-count.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn count_nucleotides(strand string) !map[string]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/palindrome-products/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "palindrome-products.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Detect palindrome products in a given range.", 17 | "source": "Problem 4 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=4" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/palindrome-products/palindrome-products.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Palindrome { 4 | value ?int 5 | factors [][]int 6 | } 7 | 8 | fn smallest(min int, max int) !Palindrome { 9 | } 10 | 11 | fn largest(min int, max int) !Palindrome { 12 | } 13 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pangram.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine if a sentence is a pangram.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_pangram(phrase string) bool { 4 | lower := phrase.to_lower().bytes() 5 | for ch in "abcdefghijklmnopqrstuvwxyz" { 6 | if ch !in lower { 7 | return false 8 | } 9 | } 10 | return true 11 | } -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_pangram(phrase string) bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/parallel-letter-frequency/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Count the frequency of letters in texts using parallel computation. 4 | 5 | Parallelism is about doing things in parallel that can also be done sequentially. 6 | A common example is counting the frequency of letters. 7 | Employ parallelism to calculate the total frequency of each letter in a list of texts. 8 | -------------------------------------------------------------------------------- /exercises/practice/parallel-letter-frequency/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "parallel-letter-frequency.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Count the frequency of letters in texts using parallel computation." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/parallel-letter-frequency/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import encoding.utf8 4 | 5 | fn count_letters(word string) map[rune]int { 6 | mut result := map[rune]int{} 7 | lower := utf8.to_lower(word) 8 | for r in 0 .. utf8.len(lower) { 9 | c := utf8.get_rune(lower, r) 10 | if utf8.is_letter(rune(c)) { 11 | result[c]++ 12 | } 13 | } 14 | return result 15 | } 16 | 17 | fn calculate_frequencies(texts []string) map[rune]int { 18 | mut tasks := []thread map[rune]int{} 19 | mut frequencies := map[rune]int{} 20 | for word in texts { 21 | tasks << spawn count_letters(word) 22 | } 23 | 24 | counts := tasks.wait() 25 | for _, entry in counts { 26 | for letter, c in entry { 27 | frequencies[letter] = frequencies[letter] + c 28 | } 29 | } 30 | return frequencies 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/parallel-letter-frequency/parallel-letter-frequency.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn calculate_frequencies(texts []string) map[rune]int { 4 | // Please implement the `calculate_frequencies` function 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pascals-triangle.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/pascals-triangle.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn rows(height int) [][]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "perfect-numbers.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.", 17 | "source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.", 18 | "source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import arrays { sum } 4 | 5 | pub enum Number { 6 | perfect 7 | abundant 8 | deficient 9 | } 10 | 11 | // all the factors of 'n' _not_ including 'n' 12 | // Example: factors(4) == [1, 2] 13 | // Example: factors(1) == [] 14 | fn factors(n int) []int { 15 | candidates := []int{len: n / 2, init: index + 1} 16 | return candidates.filter(n % it == 0) 17 | } 18 | 19 | pub fn classify(candidate int) !Number { 20 | if candidate < 1 { 21 | return error('Classification is only possible for positive integers.') 22 | } 23 | 24 | aliquot := sum(factors(candidate)) or { 0 } 25 | 26 | if aliquot > candidate { 27 | return .abundant 28 | } else if aliquot < candidate { 29 | return .deficient 30 | } 31 | 32 | return .perfect 33 | } 34 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/perfect-numbers.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub enum Number { 4 | perfect 5 | abundant 6 | deficient 7 | } 8 | 9 | // returns a `Result` type 10 | pub fn classify(candidate int) !Number { 11 | } 12 | -------------------------------------------------------------------------------- /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 | "phone-number.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.", 17 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 18 | "source_url": "https://turing.edu" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/phone-number.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn clean(phrase string) !string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/piecing-it-together/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your best friend has started collecting jigsaw puzzles and wants to build a detailed catalog of their collection — recording information such as the total number of pieces, the number of rows and columns, the number of border and inside pieces, aspect ratio, and puzzle format. 4 | Even with your powers combined, it takes multiple hours to solve a single jigsaw puzzle with one thousand pieces — and then you still need to count the rows and columns and calculate the remaining numbers manually. 5 | The even larger puzzles with thousands of pieces look quite daunting now. 6 | "There has to be a better way!" you exclaim and sit down in front of your computer to solve the problem. 7 | -------------------------------------------------------------------------------- /exercises/practice/piecing-it-together/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "piecing-it-together.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Fill in missing jigsaw puzzle details from partial data", 17 | "source": "atk just started another 1000-pieces jigsaw puzzle when this idea hit him", 18 | "source_url": "https://github.com/exercism/problem-specifications/pull/2554" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/piecing-it-together/piecing-it-together.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct PartialInformation { 4 | pieces ?int 5 | border ?int 6 | inside ?int 7 | rows ?int 8 | columns ?int 9 | aspect_ratio ?f64 10 | format ?string 11 | } 12 | 13 | struct FullInformation { 14 | pieces int 15 | border int 16 | inside int 17 | rows int 18 | columns int 19 | aspect_ratio f64 20 | format string 21 | } 22 | 23 | fn jigsaw_data(puzzle PartialInformation) !FullInformation { 24 | // Please implement the `jigsaw_data` function 25 | } 26 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pig-latin.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/pig-latin.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn translate(phrase string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "prime-factors.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Compute the prime factors of a given natural number.", 17 | "source": "The Prime Factors Kata by Uncle Bob", 18 | "source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn prime_factors(n i64) []i64 { 4 | mut factors := []i64{} 5 | mut possible_factor := 2 6 | mut num := n 7 | 8 | for possible_factor * possible_factor <= num { 9 | for num % possible_factor == 0 { 10 | factors << possible_factor 11 | num /= possible_factor 12 | } 13 | possible_factor++ 14 | } 15 | 16 | if num > 1 { 17 | factors << num 18 | } 19 | 20 | return factors 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/prime-factors.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn prime_factors(n i64) []i64 { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "protein-translation.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Translate RNA sequences into proteins.", 17 | "source": "Tyler Long" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/protein-translation.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn proteins(strand string) ![]string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | For want of a horseshoe nail, a kingdom was lost, or so the saying goes. 4 | 5 | Given a list of inputs, generate the relevant proverb. 6 | For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme: 7 | 8 | ```text 9 | For want of a nail the shoe was lost. 10 | For want of a shoe the horse was lost. 11 | For want of a horse the rider was lost. 12 | For want of a rider the message was lost. 13 | For want of a message the battle was lost. 14 | For want of a battle the kingdom was lost. 15 | And all for the want of a nail. 16 | ``` 17 | 18 | Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. 19 | No line of the output text should be a static, unchanging string; all should vary according to the input given. 20 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "proverb.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/For_Want_of_a_Nail" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import strings 4 | 5 | fn recite(inputs []string) string { 6 | if inputs.len == 0 { 7 | return '' 8 | } 9 | 10 | mut builder := strings.new_builder(4000) 11 | for i in 1 .. inputs.len { 12 | builder.write_string('For want of a ') 13 | builder.write_string(inputs[i - 1]) 14 | builder.write_string(' the ') 15 | builder.write_string(inputs[i]) 16 | builder.write_string(' was lost.\n') 17 | } 18 | builder.write_string('And all for the want of a ') 19 | builder.write_string(inputs[0]) 20 | builder.write_string('.') 21 | return builder.str() 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [e974b73e-7851-484f-8d6d-92e07fe742fc] 6 | description = "zero pieces" 7 | 8 | [2fcd5f5e-8b82-4e74-b51d-df28a5e0faa4] 9 | description = "one piece" 10 | 11 | [d9d0a8a1-d933-46e2-aa94-eecf679f4b0e] 12 | description = "two pieces" 13 | 14 | [c95ef757-5e94-4f0d-a6cb-d2083f5e5a83] 15 | description = "three pieces" 16 | 17 | [433fb91c-35a2-4d41-aeab-4de1e82b2126] 18 | description = "full proverb" 19 | 20 | [c1eefa5a-e8d9-41c7-91d4-99fab6d6b9f7] 21 | description = "four pieces modernized" 22 | -------------------------------------------------------------------------------- /exercises/practice/proverb/proverb.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn recite(inputs []string) string { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "pythagorean-triplet.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn triplets_with_sum(n int) [][]int { 4 | mut result := [][]int{} 5 | if n < 2 { 6 | return result 7 | } 8 | mut a := 0 9 | for { 10 | a++ 11 | numerator := n * (n - 2 * a) 12 | denominator := 2 * (n - a) 13 | b := numerator / denominator 14 | if b < a { 15 | break 16 | } 17 | if numerator % denominator != 0 { 18 | continue 19 | } 20 | c := n - a - b 21 | result << [a, b, c] 22 | } 23 | return result 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [a19de65d-35b8-4480-b1af-371d9541e706] 6 | description = "triplets whose sum is 12" 7 | 8 | [48b21332-0a3d-43b2-9a52-90b2a6e5c9f5] 9 | description = "triplets whose sum is 108" 10 | 11 | [dffc1266-418e-4daa-81af-54c3e95c3bb5] 12 | description = "triplets whose sum is 1000" 13 | 14 | [5f86a2d4-6383-4cce-93a5-e4489e79b186] 15 | description = "no matching triplets for 1001" 16 | 17 | [bf17ba80-1596-409a-bb13-343bdb3b2904] 18 | description = "returns all matching triplets" 19 | 20 | [9d8fb5d5-6c6f-42df-9f95-d3165963ac57] 21 | description = "several matching triplets" 22 | 23 | [f5be5734-8aa0-4bd1-99a2-02adcc4402b4] 24 | description = "triplets for large number" 25 | -------------------------------------------------------------------------------- /exercises/practice/pythagorean-triplet/pythagorean-triplet.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn triplets_with_sum(n int) [][]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "queen-attack.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/queen-attack.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn can_queen_attack(white string, black string) !bool { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/rail-fence-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rail-fence-cipher.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement encoding and decoding for the rail fence cipher.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Transposition_cipher#Rail_Fence_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rail-fence-cipher/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [46dc5c50-5538-401d-93a5-41102680d068] 6 | description = "encode -> encode with two rails" 7 | 8 | [25691697-fbd8-4278-8c38-b84068b7bc29] 9 | description = "encode -> encode with three rails" 10 | 11 | [384f0fea-1442-4f1a-a7c4-5cbc2044002c] 12 | description = "encode -> encode with ending in the middle" 13 | 14 | [cd525b17-ec34-45ef-8f0e-4f27c24a7127] 15 | description = "decode -> decode with three rails" 16 | 17 | [dd7b4a98-1a52-4e5c-9499-cbb117833507] 18 | description = "decode -> decode with five rails" 19 | 20 | [93e1ecf4-fac9-45d9-9cd2-591f47d3b8d3] 21 | description = "decode -> decode with six rails" 22 | -------------------------------------------------------------------------------- /exercises/practice/rail-fence-cipher/rail-fence-cipher.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn encode(msg string, rails int) string { 4 | } 5 | 6 | fn decode(msg string, rails int) string { 7 | } 8 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "raindrops.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 17 | "source": "A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division.", 18 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn raindrops(number int) string { 4 | mut s := '' 5 | if number % 3 == 0 { 6 | s += 'Pling' 7 | } 8 | if number % 5 == 0 { 9 | s += 'Plang' 10 | } 11 | if number % 7 == 0 { 12 | s += 'Plong' 13 | } 14 | if s == '' { 15 | s += '${number}' 16 | } 17 | return s 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn raindrops(number int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/rational-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "m-charlton" 4 | ], 5 | "contributors": [ 6 | "keiravillekode" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "rational-numbers.v" 11 | ], 12 | "test": [ 13 | "run_test.v" 14 | ], 15 | "example": [ 16 | ".meta/example.v" 17 | ] 18 | }, 19 | "blurb": "Implement rational numbers.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Rational_number" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/rational-numbers/rational-numbers.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Rational { 4 | } 5 | 6 | // build a new Rational number 7 | pub fn Rational.new(numerator i64, denominator i64) Rational { 8 | } 9 | 10 | pub fn (r Rational) abs() Rational { 11 | } 12 | 13 | pub fn (r Rational) add(other Rational) Rational { 14 | } 15 | 16 | pub fn (r Rational) div(other Rational) Rational { 17 | } 18 | 19 | pub fn (r Rational) exprational(n i64) Rational { 20 | } 21 | 22 | pub fn (r Rational) expreal(n i64) f64 { 23 | } 24 | 25 | pub fn (r Rational) mul(other Rational) Rational { 26 | } 27 | 28 | pub fn (r Rational) reduce() Rational { 29 | } 30 | 31 | pub fn (r Rational) sub(other Rational) Rational { 32 | } 33 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Count the rectangles in an ASCII diagram like the one below. 4 | 5 | ```text 6 | +--+ 7 | ++ | 8 | +-++--+ 9 | | | | 10 | +--+--+ 11 | ``` 12 | 13 | The above diagram contains these 6 rectangles: 14 | 15 | ```text 16 | 17 | 18 | +-----+ 19 | | | 20 | +-----+ 21 | ``` 22 | 23 | ```text 24 | +--+ 25 | | | 26 | | | 27 | | | 28 | +--+ 29 | ``` 30 | 31 | ```text 32 | +--+ 33 | | | 34 | +--+ 35 | 36 | 37 | ``` 38 | 39 | ```text 40 | 41 | 42 | +--+ 43 | | | 44 | +--+ 45 | ``` 46 | 47 | ```text 48 | 49 | 50 | +--+ 51 | | | 52 | +--+ 53 | ``` 54 | 55 | ```text 56 | 57 | ++ 58 | ++ 59 | 60 | 61 | ``` 62 | 63 | You may assume that the input is always a proper rectangle (i.e. the length of every line equals the length of the first line). 64 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rectangles.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Count the rectangles in an ASCII diagram." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/rectangles/rectangles.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn rectangles(strings []string) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-duo.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert color codes, as used on resistors, to a numeric value.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1464" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn value(colors []string) int { 4 | assert colors.len >= 2 5 | first := all_colors.index(colors[0]) 6 | assert first >= 0 7 | second := all_colors.index(colors[1]) 8 | assert second >= 0 9 | return first * 10 + second 10 | } 11 | 12 | const all_colors = [ 13 | 'black', 14 | 'brown', 15 | 'red', 16 | 'orange', 17 | 'yellow', 18 | 'green', 19 | 'blue', 20 | 'violet', 21 | 'grey', 22 | 'white', 23 | ] 24 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [ce11995a-5b93-4950-a5e9-93423693b2fc] 6 | description = "Brown and black" 7 | 8 | [7bf82f7a-af23-48ba-a97d-38d59406a920] 9 | description = "Blue and grey" 10 | 11 | [f1886361-fdfd-4693-acf8-46726fe24e0c] 12 | description = "Yellow and violet" 13 | 14 | [b7a6cbd2-ae3c-470a-93eb-56670b305640] 15 | description = "White and red" 16 | 17 | [77a8293d-2a83-4016-b1af-991acc12b9fe] 18 | description = "Orange and orange" 19 | 20 | [0c4fb44f-db7c-4d03-afa8-054350f156a8] 21 | description = "Ignore additional colors" 22 | 23 | [4a8ceec5-0ab4-4904-88a4-daf953a5e818] 24 | description = "Black and brown, one-digit" 25 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/resistor-color-duo.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn value(colors []string) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_brown_and_black() { 4 | assert value(['brown', 'black']) == 10 5 | } 6 | 7 | fn test_blue_and_grey() { 8 | assert value(['blue', 'grey']) == 68 9 | } 10 | 11 | fn test_yellow_and_violet() { 12 | assert value(['yellow', 'violet']) == 47 13 | } 14 | 15 | fn test_white_and_red() { 16 | assert value(['white', 'red']) == 92 17 | } 18 | 19 | fn test_orange_and_orange() { 20 | assert value(['orange', 'orange']) == 33 21 | } 22 | 23 | fn test_ignore_additional_colors() { 24 | assert value(['green', 'brown', 'orange']) == 51 25 | } 26 | 27 | fn test_black_and_brown_one_digit() { 28 | assert value(['black', 'brown']) == 1 29 | } 30 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-trio.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/resistor-color-trio.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn label(colors []string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert a resistor band's color to its numeric representation.", 17 | "source": "Maud de Vries, Erik Schierboom", 18 | "source_url": "https://github.com/exercism/problem-specifications/issues/1458" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn color_code(color string) int { 4 | return colors.index(color) 5 | } 6 | 7 | const colors = [ 8 | 'black', 9 | 'brown', 10 | 'red', 11 | 'orange', 12 | 'yellow', 13 | 'green', 14 | 'blue', 15 | 'violet', 16 | 'grey', 17 | 'white', 18 | ] 19 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [49eb31c5-10a8-4180-9f7f-fea632ab87ef] 6 | description = "Color codes -> Black" 7 | 8 | [0a4df94b-92da-4579-a907-65040ce0b3fc] 9 | description = "Color codes -> White" 10 | 11 | [5f81608d-f36f-4190-8084-f45116b6f380] 12 | description = "Color codes -> Orange" 13 | 14 | [581d68fa-f968-4be2-9f9d-880f2fb73cf7] 15 | description = "Colors" 16 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/resistor-color.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn color_code(color string) int { 4 | } 5 | 6 | const colors = []string{} 7 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_black() { 4 | assert color_code('black') == 0 5 | } 6 | 7 | fn test_white() { 8 | assert color_code('white') == 9 9 | } 10 | 11 | fn test_orange() { 12 | assert color_code('orange') == 3 13 | } 14 | 15 | fn test_colors() { 16 | assert colors == [ 17 | 'black', 18 | 'brown', 19 | 'red', 20 | 'orange', 21 | 'yellow', 22 | 'green', 23 | 'blue', 24 | 'violet', 25 | 'grey', 26 | 'white', 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "reverse-string.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Reverse a given string.", 17 | "source": "Introductory challenge to reverse an input string", 18 | "source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // reverse_string returns a given string in reverse order 4 | fn reverse_string(str string) string { 5 | return str.reverse() 6 | } -------------------------------------------------------------------------------- /exercises/practice/reverse-string/reverse-string.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // reverse_string returns a given string in reverse order 4 | fn reverse_string(str string) string { 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/reverse-string/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_empty() { 4 | assert reverse_string('') == '' 5 | } 6 | 7 | fn test_word() { 8 | assert reverse_string('robot') == 'tobor' 9 | } 10 | 11 | fn test_capitalized_word() { 12 | assert reverse_string('Ramen') == 'nemaR' 13 | } 14 | 15 | fn test_sentence_with_punctuation() { 16 | assert reverse_string("I'm hungry!") == "!yrgnuh m'I" 17 | } 18 | 19 | fn test_palindrome() { 20 | assert reverse_string('racecar') == 'racecar' 21 | } 22 | 23 | fn test_even_length_word() { 24 | assert reverse_string('drawer') == 'reward' 25 | } 26 | -------------------------------------------------------------------------------- /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 | "gautampanchal94" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rna-transcription.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a DNA strand, return its RNA complement.", 17 | "source": "Hyperphysics", 18 | "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn to_rna(dna string) string { 4 | replace_vals := ['G', 'C', 'C', 'G', 'T', 'A', 'A', 'U'] 5 | return dna.replace_each(replace_vals) 6 | } 7 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn to_rna(dna string) string { 4 | // Add code here 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_empty_rna() { 4 | assert to_rna('') == '' 5 | } 6 | 7 | fn test_cytosine_to_guanine() { 8 | assert to_rna('C') == 'G' 9 | } 10 | 11 | fn test_guanine_to_cytosine() { 12 | assert to_rna('G') == 'C' 13 | } 14 | 15 | fn test_thymine_to_adenine() { 16 | assert to_rna('T') == 'A' 17 | } 18 | 19 | fn test_adenine_to_uracial() { 20 | assert to_rna('A') == 'U' 21 | } 22 | 23 | fn test_rna_complement() { 24 | assert to_rna('ACGTGGTCTTAA') == 'UGCACCAGAAUU' 25 | } 26 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "robot-name.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Manage robot factory settings.", 17 | "source": "A debugging session with Paul Blackwell at gSchool." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/robot-name.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // you'll probably want this 4 | import rand 5 | 6 | // define the Robot struct here 7 | struct Robot { 8 | } 9 | 10 | // we need a place to store all these robots! 11 | // make sure to update all the s to match 12 | // this should probably be an array or a map ;) 13 | fn create_robot_storage() { 14 | } 15 | 16 | fn create_robot(mut robots ) Robot { 17 | } 18 | 19 | fn (mut r Robot) reset(mut robots ) { 20 | } 21 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "roman-numerals.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 17 | "source": "The Roman Numeral Kata", 18 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | const ones = [u8(`I`), `X`, `C`, `M`] 4 | 5 | const fives = [u8(`V`), `L`, `D`] 6 | 7 | fn write(mut buffer []u8, digit int, place int) { 8 | if digit % 5 == 4 { 9 | buffer << ones[place] 10 | write(mut buffer, digit + 1, place) 11 | } else if digit == 10 { 12 | write(mut buffer, 1, place + 1) 13 | } else if digit >= 5 { 14 | buffer << fives[place] 15 | write(mut buffer, digit - 5, place) 16 | } else if digit > 0 { 17 | buffer << ones[place] 18 | write(mut buffer, digit - 1, place) 19 | } 20 | } 21 | 22 | fn roman(number int) string { 23 | assert number < 4000 24 | mut buffer := []u8{} 25 | write(mut buffer, number / 1000, 3) 26 | write(mut buffer, number / 100 % 10, 2) 27 | write(mut buffer, number / 10 % 10, 1) 28 | write(mut buffer, number % 10, 0) 29 | return buffer.bytestr() 30 | } 31 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/roman-numerals.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn roman(number int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rotational-cipher.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn rotate(text string, shift_key int) string { 4 | assert 0 <= shift_key && shift_key <= 26 5 | mut buffer := []u8{cap: text.len} 6 | for ch in text { 7 | if `A` <= ch && ch <= `Z` { 8 | buffer << u8(`A` + (ch - `A` + shift_key) % 26) 9 | } else if `a` <= ch && ch <= `z` { 10 | buffer << u8(`a` + (ch - `a` + shift_key) % 26) 11 | } else { 12 | buffer << ch 13 | } 14 | } 15 | return buffer.bytestr() 16 | } 17 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/rotational-cipher.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn rotate(text string, shift_key int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "run-length-encoding.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement run-length encoding and decoding.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/run-length-encoding.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn encode(str string) string { 4 | } 5 | 6 | fn decode(str string) string { 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You plan to build a tree house in the woods near your house so that you can watch the sun rise and set. 4 | 5 | You've obtained data from a local survey company that show the height of every tree in each rectangular section of the map. 6 | You need to analyze each grid on the map to find good trees for your tree house. 7 | 8 | A good tree is both: 9 | 10 | - taller than every tree to the east and west, so that you have the best possible view of the sunrises and sunsets. 11 | - shorter than every tree to the north and south, to minimize the amount of tree climbing. 12 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "saddle-points.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Detect saddle points in a matrix.", 17 | "source": "J Dalbey's Programming Practice problems", 18 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/saddle-points/saddle-points.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct Point { 4 | row int 5 | column int 6 | } 7 | 8 | fn saddle_points(matrix [][]int) []Point { 9 | } 10 | -------------------------------------------------------------------------------- /exercises/practice/say/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "say.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.", 17 | "source": "A variation on the JavaRanch CattleDrive, Assignment 4", 18 | "source_url": "https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/say/say.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn say(number i64) !string { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "scrabble-score.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a word, compute the Scrabble score for that word.", 17 | "source": "Inspired by the Extreme Startup game", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn score(word string) int { 4 | upper := word.to_upper() 5 | mut sum := 0 6 | 7 | for letter in upper { 8 | sum += rune_to_score(letter) 9 | } 10 | 11 | return sum 12 | } 13 | 14 | fn rune_to_score(r rune) int { 15 | return match r { 16 | `A`, `E`, `I`, `O`, `U`, `L`, `N`, `R`, `S`, `T` { 1 } 17 | `D`, `G` { 2 } 18 | `B`, `C`, `M`, `P` { 3 } 19 | `F`, `H`, `V`, `W`, `Y` { 4 } 20 | `K` { 5 } 21 | `J`, `X` { 8 } 22 | `Q`, `Z` { 10 } 23 | else { panic('Invalid rune: ${r}') } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_lowercase_letter() { 4 | assert score('a') == 1 5 | } 6 | 7 | fn test_uppercase_letter() { 8 | assert score('A') == 1 9 | } 10 | 11 | fn test_valuable_letter() { 12 | assert score('f') == 4 13 | } 14 | 15 | fn test_short_word() { 16 | assert score('at') == 2 17 | } 18 | 19 | fn test_short_valuable_word() { 20 | assert score('zoo') == 12 21 | } 22 | 23 | fn test_medium_word() { 24 | assert score('street') == 6 25 | } 26 | 27 | fn test_medium_valuable_word() { 28 | assert score('quirky') == 22 29 | } 30 | 31 | fn test_long_mixed_case_word() { 32 | assert score('OxyphenButazone') == 41 33 | } 34 | 35 | fn test_english_like_word() { 36 | assert score('pinata') == 8 37 | } 38 | 39 | fn test_empty_input() { 40 | assert score('') == 0 41 | } 42 | 43 | fn test_entire_alphabet() { 44 | assert score('abcdefghijklmnopqrstuvwxyz') == 87 45 | } 46 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/scrabble-score.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn score(word string) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You are starting a secret coding club with some friends and friends-of-friends. 4 | Not everyone knows each other, so you and your friends have decided to create a secret handshake that you can use to recognize that someone is a member. 5 | You don't want anyone who isn't in the know to be able to crack the code. 6 | 7 | You've designed the code so that one person says a number between 1 and 31, and the other person turns it into a series of actions. 8 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "natanaelsirqueira" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "secret_handshake.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/secret_handshake.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum Command as u8 { 4 | wink 5 | double_blink 6 | close_your_eyes 7 | jump 8 | } 9 | 10 | pub fn commands(encoded_message int) []Command { 11 | return [] 12 | } 13 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "series.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.", 17 | "source": "A subset of the Problem 8 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=8" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/series/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn slices(series string, slice_length int) ![]string { 4 | if series.len == 0 { 5 | return error('series cannot be empty') 6 | } 7 | if slice_length > series.len { 8 | return error('slice length cannot be greater than series length') 9 | } 10 | if slice_length == 0 { 11 | return error('slice length cannot be zero') 12 | } 13 | if slice_length < 0 { 14 | return error('slice length cannot be negative') 15 | } 16 | mut result := []string{} 17 | for i in 0 .. (series.len - slice_length + 1) { 18 | result << series[i..(i + slice_length)] 19 | } 20 | return result 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/series/series.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn slices(series string, slice_length int) ![]string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You bought a big box of random computer parts at a garage sale. 4 | You've started putting the parts together to build custom computers. 5 | 6 | You want to test the performance of different combinations of parts, and decide to create your own benchmarking program to see how your computers compare. 7 | You choose the famous "Sieve of Eratosthenes" algorithm, an ancient algorithm, but one that should push your computers to the limits. 8 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sieve.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", 17 | "source": "Sieve of Eratosthenes at Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn sieve(limit int) []int { 4 | mut test := []bool{len: limit + 1, init: false} 5 | for i in 2 .. limit + 1 { 6 | if test[i] == false { 7 | mut j := i + i 8 | for j <= limit { 9 | test[j] = true 10 | j = j + i 11 | } 12 | } 13 | } 14 | mut primes := []int{} 15 | for k in 2 .. limit + 1 { 16 | if !test[k] { 17 | primes << k 18 | } 19 | } 20 | return primes 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/sieve/sieve.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn sieve(limit int) []int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You work for a music streaming company. 4 | 5 | You've been tasked with creating a playlist feature for your music player application. 6 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "natanaelsirqueira" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "simple-linked-list.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Write a simple linked list implementation that uses Elements and a List.", 17 | "source": "Inspired by 'Data Structures and Algorithms with Object-Oriented Design Patterns in Ruby', singly linked-lists.", 18 | "source_url": "https://web.archive.org/web/20160731005714/http://brpreiss.com/books/opus8/html/page96.html" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/simple-linked-list/simple-linked-list.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | struct LinkedList { 4 | mut: 5 | // define your data structure here 6 | len int // maintain the number of elements in the list in this field 7 | } 8 | 9 | fn new() LinkedList { 10 | } 11 | 12 | fn from_array(array []int) LinkedList { 13 | } 14 | 15 | fn (list LinkedList) is_empty() bool { 16 | } 17 | 18 | fn (mut list LinkedList) push(data int) { 19 | } 20 | 21 | fn (mut list LinkedList) pop() ?int { 22 | } 23 | 24 | fn (list LinkedList) peek() ?int { 25 | } 26 | 27 | fn (list LinkedList) to_array() []int { 28 | } 29 | 30 | fn (list LinkedList) reverse() LinkedList { 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "space-age.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", 17 | "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", 18 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn earth_years(seconds f64) f64 { 4 | return seconds / 31557600 5 | } 6 | 7 | fn age(seconds f64, planet string) !f64 { 8 | orbital_period := match planet { 9 | "Mercury" { 0.2408467} 10 | "Venus" { 0.61519726 } 11 | "Earth" { 1.0 } 12 | "Mars" { 1.8808158 } 13 | "Jupiter" { 11.862615 } 14 | "Saturn" { 29.447498 } 15 | "Uranus" { 84.016846 } 16 | "Neptune" { 164.79132 } 17 | else { -1 } 18 | } 19 | planet_age := earth_years(seconds) / orbital_period 20 | if planet_age < 0 { 21 | return error("$planet is not a valid planet") 22 | } 23 | return planet_age 24 | } -------------------------------------------------------------------------------- /exercises/practice/space-age/space-age.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn age(seconds f64, planet string) !f64 { 4 | // age should return an error if the planet is not one of the 8 listed 5 | } 6 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to return a square matrix of a given size. 4 | 5 | The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples: 6 | 7 | ## Examples 8 | 9 | ### Spiral matrix of size 3 10 | 11 | ```text 12 | 1 2 3 13 | 8 9 4 14 | 7 6 5 15 | ``` 16 | 17 | ### Spiral matrix of size 4 18 | 19 | ```text 20 | 1 2 3 4 21 | 12 13 14 5 22 | 11 16 15 6 23 | 10 9 8 7 24 | ``` 25 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods. 4 | Despite numerous attempts, no one had ever succeeded in finding it. 5 | This was about to change, however, thanks to a young explorer named Elara. 6 | She had discovered an old document containing instructions on how to locate the treasure. 7 | Using these instructions, Elara was able to draw a map that revealed the path to the treasure. 8 | 9 | To her surprise, the path followed a peculiar clockwise spiral. 10 | It was no wonder no one had been able to find the treasure before! 11 | With the map in hand, Elara embarks on her journey to uncover the hidden treasure. 12 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "spiral-matrix.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given the size, return a square matrix of numbers in spiral order.", 17 | "source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.", 18 | "source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn spiral_matrix(size int) [][]int { 4 | mut result := [][]int{len: size} 5 | for i in 0 .. size { 6 | result[i] = []int{len: size, init: size * size} 7 | } 8 | 9 | mut value := 1 10 | mut row := 0 11 | mut column := 0 12 | mut side_length := size - 1 13 | for side_length >= 1 { 14 | for _ in 0 .. side_length { 15 | result[row][column] = value++ 16 | column++ 17 | } 18 | for _ in 0 .. side_length { 19 | result[row][column] = value++ 20 | row++ 21 | } 22 | for _ in 0 .. side_length { 23 | result[row][column] = value++ 24 | column-- 25 | } 26 | for _ in 0 .. side_length { 27 | result[row][column] = value++ 28 | row-- 29 | } 30 | row++ 31 | column++ 32 | side_length -= 2 33 | } 34 | 35 | return result 36 | } 37 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [8f584201-b446-4bc9-b132-811c8edd9040] 6 | description = "empty spiral" 7 | 8 | [e40ae5f3-e2c9-4639-8116-8a119d632ab2] 9 | description = "trivial spiral" 10 | 11 | [cf05e42d-eb78-4098-a36e-cdaf0991bc48] 12 | description = "spiral of size 2" 13 | 14 | [1c475667-c896-4c23-82e2-e033929de939] 15 | description = "spiral of size 3" 16 | 17 | [05ccbc48-d891-44f5-9137-f4ce462a759d] 18 | description = "spiral of size 4" 19 | 20 | [f4d2165b-1738-4e0c-bed0-c459045ae50d] 21 | description = "spiral of size 5" 22 | -------------------------------------------------------------------------------- /exercises/practice/spiral-matrix/spiral-matrix.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn spiral_matrix(size int) [][]int { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "square-root.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a natural radicand, return its square root.", 17 | "source": "wolf99", 18 | "source_url": "https://github.com/exercism/problem-specifications/pull/1582" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn square_root(radicand u64) u64 { 4 | mut previous := u64(0) 5 | mut current := radicand 6 | 7 | for current != previous { 8 | previous = current 9 | current = (previous * (previous + 1) + radicand) / (2 * previous) 10 | } 11 | return current 12 | } 13 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. Regular comments will be removed when this 2 | # file is regenerated. Regenerating will not touch any manually added keys, 3 | # so comments can be added in a "comment" key. 4 | 5 | [9b748478-7b0a-490c-b87a-609dacf631fd] 6 | description = "root of 1" 7 | 8 | [7d3aa9ba-9ac6-4e93-a18b-2e8b477139bb] 9 | description = "root of 4" 10 | 11 | [6624aabf-3659-4ae0-a1c8-25ae7f33c6ef] 12 | description = "root of 25" 13 | 14 | [93beac69-265e-4429-abb1-94506b431f81] 15 | description = "root of 81" 16 | 17 | [fbddfeda-8c4f-4bc4-87ca-6991af35360e] 18 | description = "root of 196" 19 | 20 | [c03d0532-8368-4734-a8e0-f96a9eb7fc1d] 21 | description = "root of 65025" 22 | -------------------------------------------------------------------------------- /exercises/practice/square-root/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_root_of_0() { 4 | assert square_root(0) == 0 5 | } 6 | 7 | fn test_root_of_1() { 8 | assert square_root(1) == 1 9 | } 10 | 11 | fn test_root_of_4() { 12 | assert square_root(4) == 2 13 | } 14 | 15 | fn test_root_of_25() { 16 | assert square_root(25) == 5 17 | } 18 | 19 | fn test_root_of_81() { 20 | assert square_root(81) == 9 21 | } 22 | 23 | fn test_root_of_196() { 24 | assert square_root(196) == 14 25 | } 26 | 27 | fn test_root_of_65025() { 28 | assert square_root(65025) == 255 29 | } 30 | 31 | fn test_root_of_5764801() { 32 | assert square_root(5764801) == 2401 33 | } 34 | -------------------------------------------------------------------------------- /exercises/practice/square-root/square-root.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn square_root(radicand u64) u64 { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/state-of-tic-tac-toe/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "state-of-tic-tac-toe.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/state-of-tic-tac-toe.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum State as u8 { 4 | ongoing 5 | draw 6 | win 7 | } 8 | 9 | fn gamestate(board []string) !State { 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "strain.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement the `keep` and `discard` operation on collections.", 17 | "source": "Conversation with James Edward Gray II", 18 | "source_url": "http://graysoftinc.com/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn keep[T](array []T, predicate fn (e T) bool) []T { 4 | mut result := []T{cap: array.len} 5 | 6 | for element in array { 7 | if predicate(element) { 8 | result << element 9 | } 10 | } 11 | 12 | return result 13 | } 14 | 15 | pub fn discard[T](array []T, predicate fn (e T) bool) []T { 16 | mut result := []T{cap: array.len} 17 | 18 | for element in array { 19 | if !predicate(element) { 20 | result << element 21 | } 22 | } 23 | 24 | return result 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/strain/strain.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | pub fn keep[T](array []T, predicate fn (e T) bool) []T { 4 | } 5 | 6 | pub fn discard[T](array []T, predicate fn (e T) bool) []T { 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sublist.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Write a function to determine if a list is a sublist of another list." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum Relation { 4 | equal 5 | sublist 6 | superlist 7 | unequal 8 | } 9 | 10 | fn is_sublist(list_one []int, list_two []int) bool { 11 | return match true { 12 | list_two.len < list_one.len { false } 13 | list_one == list_two[0..list_one.len] { true } 14 | else { is_sublist(list_one, list_two[1..]) } 15 | } 16 | } 17 | 18 | fn compare(list_one []int, list_two []int) Relation { 19 | return match true { 20 | list_one == list_two { .equal } 21 | is_sublist(list_one, list_two) { .sublist } 22 | is_sublist(list_two, list_one) { .superlist } 23 | else { .unequal } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /exercises/practice/sublist/sublist.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum Relation { 4 | equal 5 | sublist 6 | superlist 7 | unequal 8 | } 9 | 10 | fn compare(list_one []int, list_two []int) Relation { 11 | } 12 | -------------------------------------------------------------------------------- /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 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sum-of-multiples.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 17 | "source": "A variation on Problem 1 at Project Euler", 18 | "source_url": "https://projecteuler.net/problem=1" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn sum(factors []int, limit int) int { 4 | mut result := 0 5 | for n in 1 .. limit { 6 | for factor in factors { 7 | if factor != 0 && n % factor == 0 { 8 | result += n 9 | break 10 | } 11 | } 12 | } 13 | return result 14 | } 15 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/sum-of-multiples.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn sum(factors []int, limit int) int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/transpose/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "transpose.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Take input text and output it transposed.", 17 | "source": "Reddit r/dailyprogrammer challenge #270 [Easy].", 18 | "source_url": "https://web.archive.org/web/20230630051421/https://old.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/transpose/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import arrays 4 | 5 | fn transpose(lines []string) []string { 6 | mut max_line_len := 0 7 | for line in lines { 8 | if max_line_len < line.len { 9 | max_line_len = line.len 10 | } 11 | } 12 | 13 | mut result := []string{len: max_line_len} 14 | for i in 0 .. max_line_len { 15 | mut buffer := []u8{cap: lines.len} 16 | for j in 0 .. (lines.len) { 17 | if lines[j].len <= i { 18 | continue 19 | } 20 | for buffer.len < j { 21 | buffer << ` ` 22 | } 23 | 24 | buffer << lines[j][i] 25 | } 26 | 27 | result[i] = buffer.bytestr() 28 | } 29 | 30 | return result 31 | } 32 | -------------------------------------------------------------------------------- /exercises/practice/transpose/transpose.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn transpose(lines []string) []string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "triangle.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 17 | "source": "The Ruby Koans triangle project, parts 1 & 2", 18 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_isosceles(a f64, b f64, c f64) bool { 4 | mut sides := [a, b, c] 5 | sides.sort() 6 | return is_valid_triangle(sides) && (sides[0] == sides[1] || sides[1] == sides[2]) 7 | } 8 | 9 | fn is_equilateral(a f64, b f64, c f64) bool { 10 | mut sides := [a, b, c] 11 | sides.sort() 12 | return is_valid_triangle(sides) && sides[0] == sides[1] && sides[1] == sides[2] 13 | } 14 | 15 | fn is_scalene(a f64, b f64, c f64) bool { 16 | mut sides := [a, b, c] 17 | sides.sort() 18 | return is_valid_triangle(sides) && !is_isosceles(a, b, c) && !is_equilateral(a, b, c) 19 | } 20 | 21 | fn is_valid_triangle(sides []f64) bool { 22 | if sides[0] <= 0 || sides[0]+sides[1] < sides[2] { 23 | return false 24 | } 25 | return true 26 | } -------------------------------------------------------------------------------- /exercises/practice/triangle/triangle.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn is_isosceles(a f64, b f64, c f64) bool { 4 | } 5 | 6 | fn is_equilateral(a f64, b f64, c f64) bool { 7 | } 8 | 9 | fn is_scalene(a f64, b f64, c f64) bool { 10 | } 11 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "twelve-days.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Output the lyrics to 'The Twelve Days of Christmas'.", 17 | "source": "Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/twelve-days.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn recite(start_verse int, end_verse int) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-bucket.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given two buckets of different size, demonstrate how to measure an exact number of liters.", 17 | "source": "Water Pouring Problem", 18 | "source_url": "https://demonstrations.wolfram.com/WaterPouringProblem/" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/two-bucket.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | enum BucketId { 4 | one 5 | two 6 | } 7 | 8 | struct Solution { 9 | moves int 10 | goal_bucket BucketId 11 | other_bucket int 12 | } 13 | 14 | pub fn measure(capacity_one int, capacity_two int, goal int, start_bucket BucketId) !Solution { 15 | } 16 | -------------------------------------------------------------------------------- /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 | "1ethanhansen" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "two-fer.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 17 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn two_fer(name string) string { 4 | if name == '' { 5 | return 'One for you, one for me.' 6 | } 7 | return 'One for ${name}, one for me.' 8 | } 9 | -------------------------------------------------------------------------------- /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/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_no_name() { 4 | assert two_fer('') == 'One for you, one for me.' 5 | } 6 | 7 | fn test_alice() { 8 | assert two_fer('Alice') == 'One for Alice, one for me.' 9 | } 10 | 11 | fn test_bob() { 12 | assert two_fer('Bob') == 'One for Bob, one for me.' 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn two_fer(name string) string { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/variable-length-quantity/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "variable-length-quantity.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Implement variable length quantity encoding and decoding.", 17 | "source": "A poor Splice developer having to implement MIDI encoding/decoding.", 18 | "source_url": "https://splice.com" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/variable-length-quantity/variable-length-quantity.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn encode(integers []u32) []u8 { 4 | } 5 | 6 | fn decode(integers []u8) ![]u32 { 7 | } 8 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You teach English as a foreign language to high school students. 4 | 5 | You've decided to base your entire curriculum on TV shows. 6 | You need to analyze which words are used, and how often they're repeated. 7 | 8 | This will let you choose the simplest shows to start with, and to gradually increase the difficulty as time passes. 9 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "word-count.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Given a phrase, count the occurrences of each word in that phrase.", 17 | "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/example.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn count_words(sentence string) map[string]int { 4 | mut result := map[string]int{} 5 | mut first := 0 6 | 7 | outer: for { 8 | for { 9 | if first >= sentence.len { 10 | break outer 11 | } 12 | 13 | ch := sentence[first] 14 | if ch.is_letter() || ch.is_digit() { 15 | break 16 | } 17 | 18 | first++ 19 | } 20 | 21 | mut last := first + 1 22 | for { 23 | if last == sentence.len { 24 | break 25 | } 26 | 27 | ch := sentence[last] 28 | if !ch.is_letter() && !ch.is_digit() && ch != `'` { 29 | break 30 | } 31 | 32 | last++ 33 | } 34 | 35 | for sentence[last - 1] == `'` { 36 | last-- 37 | } 38 | 39 | result[sentence[first..last].to_lower()]++ 40 | 41 | first = last + 1 42 | } 43 | 44 | return result 45 | } 46 | -------------------------------------------------------------------------------- /exercises/practice/word-count/word-count.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn count_words(sentence string) map[string]int { 4 | } 5 | -------------------------------------------------------------------------------- /exercises/practice/word-search/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | In word search puzzles you get a square of letters and have to find specific words in them. 4 | 5 | For example: 6 | 7 | ```text 8 | jefblpepre 9 | camdcimgtc 10 | oivokprjsm 11 | pbwasqroua 12 | rixilelhrs 13 | wolcqlirpc 14 | screeaumgr 15 | alxhpburyi 16 | jalaycalmp 17 | clojurermt 18 | ``` 19 | 20 | There are several programming languages hidden in the above square. 21 | 22 | Words can be hidden in all kinds of directions: left-to-right, right-to-left, vertical and diagonal. 23 | 24 | Given a puzzle and a list of words return the location of the first and last letter of each word. 25 | -------------------------------------------------------------------------------- /exercises/practice/word-search/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "word-search.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Create a program to solve a word search puzzle." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/practice/word-search/word-search.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | // Grid rows and columns are 1-indexed. 4 | struct Pair { 5 | column int 6 | row int 7 | } 8 | 9 | struct WordLocation { 10 | start Pair 11 | end Pair 12 | } 13 | 14 | fn search(grid []string, words_to_search_for []string) map[string]?WordLocation { 15 | } 16 | -------------------------------------------------------------------------------- /exercises/practice/wordy/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "keiravillekode" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "wordy.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Parse and evaluate simple math word problems returning the answer as an integer.", 17 | "source": "Inspired by one of the generated questions in the Extreme Startup game.", 18 | "source_url": "https://github.com/rchatley/extreme_startup" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/wordy/wordy.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn answer(question string) ?int { 4 | } 5 | -------------------------------------------------------------------------------- /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 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "yacht.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 14 | ] 15 | }, 16 | "blurb": "Score a single throw of dice in the game Yacht.", 17 | "source": "James Kilfiger, using Wikipedia", 18 | "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/yacht/yacht.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import arrays 4 | 5 | enum Category as u8 { 6 | yacht 7 | ones 8 | twos 9 | threes 10 | fours 11 | fives 12 | sixes 13 | full_house 14 | four_of_a_kind 15 | little_straight 16 | big_straight 17 | choice 18 | } 19 | 20 | fn score(category Category, rolls []u8) int { 21 | // Please implement the score function 22 | } 23 | -------------------------------------------------------------------------------- /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 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "zebra-puzzle.v" 8 | ], 9 | "test": [ 10 | "run_test.v" 11 | ], 12 | "example": [ 13 | ".meta/example.v" 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/run_test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn test_drinks_water() { 4 | assert drinks_water() == 'Norwegian' 5 | } 6 | 7 | fn test_owns_zebra() { 8 | assert owns_zebra() == 'Japanese' 9 | } 10 | -------------------------------------------------------------------------------- /exercises/practice/zebra-puzzle/zebra-puzzle.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | fn drinks_water() string { 4 | // Please implement the `drinks_water` function 5 | } 6 | 7 | fn owns_zebra() string { 8 | // Please implement the `owns_zebra` function 9 | } 10 | -------------------------------------------------------------------------------- /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 | - [The Exercism Forum](https://forum.exercism.org/c/programming/vlang/168) 6 | - [V Matrix](https://matrix.to/#/#v-chat:matrix.org) 7 | - [V Discord](https://discord.gg/vlang) 8 | - [V Telegram](https://t.me/vlang_en) 9 | - [Official V Github Discussions](https://github.com/vlang/v/discussions) 10 | -------------------------------------------------------------------------------- /exercises/shared/.docs/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | To run the tests run the command `v test .` from within the exercise directory. 4 | 5 | If you want to see all the tests that were run along with statistics on speed, use `v -stats test .` 6 | 7 | For more information on testing in V, please see [the documentation](https://github.com/vlang/v/blob/master/doc/docs.md#testing). --------------------------------------------------------------------------------