├── .appends └── .github │ └── labels.yml ├── .github ├── CODEOWNERS ├── actions │ └── perform-system │ │ ├── Dockerfile │ │ ├── action.yml │ │ └── entrypoint.sh ├── configlet-sync-issue.md ├── dependabot.yml ├── labels.yml ├── pull_request_template.md ├── stale.yml └── workflows │ ├── config-checker.yml │ ├── configlet-sync.yml │ ├── configlet.yml │ ├── no-important-files-changed.yml │ ├── pause-community-contributions.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── sync-labels.yml │ └── test-exercises.yml ├── .gitignore ├── ABOUT.org ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bin ├── custom_json_encoder.py ├── fetch-configlet ├── lisp_exercise_generator.py └── sync-exercise ├── concepts ├── arithmetic │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── arrays │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── characters │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── comments │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── conditionals │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── cons │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── date-time │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── equality │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── expressions │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── filtering │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── floating-point-numbers │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── format-basics │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── functions │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── hash-tables │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── integers │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── keyword-parameters │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── lambda-list │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── lists │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── mapping │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── multiple-values │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── optional-parameters │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── reducing │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── rest-parameters │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── strings │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── symbols │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── truthy-and-falsy │ ├── .meta │ │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json └── vectors │ ├── .meta │ └── config.json │ ├── about.md │ ├── introduction.md │ └── links.json ├── config.json ├── docs ├── ABOUT.md ├── INSTALLATION.md ├── LEARNING.md ├── REPRESENTER_NORMALIZATIONS.md ├── RESOURCES.md ├── SNIPPET.txt ├── TESTS.md └── config.json ├── exercises ├── concept │ ├── character-study │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── character-study-test.lisp │ │ └── character-study.lisp │ ├── gigasecond-anniversary │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── exemplar.lisp │ │ ├── gigasecond-anniversary-test.lisp │ │ └── gigasecond-anniversary.lisp │ ├── high-scores │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── exemplar.lisp │ │ ├── high-scores-test.lisp │ │ └── high-scores.lisp │ ├── key-comparison │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── key-comparison-test.lisp │ │ └── key-comparison.lisp │ ├── larrys-winning-checker │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── larrys-winning-checker-test.lisp │ │ └── larrys-winning-checker.lisp │ ├── leslies-lists │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── leslies-lists-test.lisp │ │ └── leslies-lists.lisp │ ├── lillys-lasagna-leftovers │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── lillys-lasagna-leftovers-test.lisp │ │ └── lillys-lasagna-leftovers.lisp │ ├── lillys-lasagna │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── lillys-lasagna-test.lisp │ │ └── lillys-lasagna.lisp │ ├── log-levels │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── log-levels-test.lisp │ │ └── log-levels.lisp │ ├── logans-numeric-partition │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── exemplar.lisp │ │ ├── logans-numeric-partition-test.lisp │ │ └── logans-numeric-partition.lisp │ ├── lucys-magnificent-mapper │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── exemplar.lisp │ │ ├── lucys-magnificent-mapper-test.lisp │ │ └── lucys-magnificent-mapper.lisp │ ├── pal-picker │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── pal-picker-test.lisp │ │ └── pal-picker.lisp │ ├── pizza-pi │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── design.md │ │ │ └── exemplar.lisp │ │ ├── pizza-pi-test.lisp │ │ └── pizza-pi.lisp │ ├── reporting-for-duty │ │ ├── .docs │ │ │ ├── hints.md │ │ │ ├── instructions.md │ │ │ ├── introduction.md │ │ │ └── introduction.md.tpl │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── exemplar.lisp │ │ ├── reporting-for-duty-test.lisp │ │ └── reporting-for-duty.lisp │ └── socks-and-sexprs │ │ ├── .docs │ │ ├── hints.md │ │ ├── instructions.md │ │ ├── introduction.md │ │ └── introduction.md.tpl │ │ ├── .meta │ │ ├── config.json │ │ ├── design.md │ │ └── exemplar.lisp │ │ ├── socks-and-sexprs-test.lisp │ │ └── socks-and-sexprs.lisp ├── practice │ ├── acronym │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── acronym-test.lisp │ │ └── acronym.lisp │ ├── affine-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── affine-cipher-test.lisp │ │ └── affine-cipher.lisp │ ├── all-your-base │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── all-your-base-test.lisp │ │ └── all-your-base.lisp │ ├── allergies │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── allergies-test.lisp │ │ └── allergies.lisp │ ├── anagram │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── anagram-test.lisp │ │ └── anagram.lisp │ ├── armstrong-numbers │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── armstrong-numbers-test.lisp │ │ └── armstrong-numbers.lisp │ ├── atbash-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── atbash-cipher-test.lisp │ │ └── atbash-cipher.lisp │ ├── beer-song │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── beer-song-test.lisp │ │ └── beer-song.lisp │ ├── binary-search │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── binary-search-test.lisp │ │ └── binary-search.lisp │ ├── binary │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── binary-test.lisp │ │ └── binary.lisp │ ├── bob │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── bob-test.lisp │ │ └── bob.lisp │ ├── book-store │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── book-store-test.lisp │ │ └── book-store.lisp │ ├── bottle-song │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── bottle-song-test.lisp │ │ └── bottle-song.lisp │ ├── collatz-conjecture │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── collatz-conjecture-test.lisp │ │ └── collatz-conjecture.lisp │ ├── crypto-square │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── crypto-square-test.lisp │ │ └── crypto-square.lisp │ ├── darts │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── darts-test.lisp │ │ └── darts.lisp │ ├── diamond │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── diamond-test.lisp │ │ └── diamond.lisp │ ├── difference-of-squares │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── difference-of-squares-test.lisp │ │ └── difference-of-squares.lisp │ ├── eliuds-eggs │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── eliuds-eggs-test.lisp │ │ └── eliuds-eggs.lisp │ ├── etl │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── etl-test.lisp │ │ └── etl.lisp │ ├── flatten-array │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── flatten-array-test.lisp │ │ └── flatten-array.lisp │ ├── food-chain │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── food-chain-test.lisp │ │ └── food-chain.lisp │ ├── gigasecond │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── gigasecond-test.lisp │ │ └── gigasecond.lisp │ ├── grade-school │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── grade-school-test.lisp │ │ └── grade-school.lisp │ ├── grains │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── grains-test.lisp │ │ └── grains.lisp │ ├── hamming │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── hamming-test.lisp │ │ └── hamming.lisp │ ├── hello-world │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── hello-world-test.lisp │ │ └── hello-world.lisp │ ├── house │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── house-test.lisp │ │ └── house.lisp │ ├── isbn-verifier │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── isbn-verifier-test.lisp │ │ └── isbn-verifier.lisp │ ├── isogram │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── isogram-test.lisp │ │ └── isogram.lisp │ ├── knapsack │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── knapsack-test.lisp │ │ └── knapsack.lisp │ ├── largest-series-product │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── largest-series-product-test.lisp │ │ └── largest-series-product.lisp │ ├── leap │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── leap-test.lisp │ │ └── leap.lisp │ ├── luhn │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── luhn-test.lisp │ │ └── luhn.lisp │ ├── matching-brackets │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── matching-brackets-test.lisp │ │ └── matching-brackets.lisp │ ├── matrix │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── matrix-test.lisp │ │ └── matrix.lisp │ ├── meetup │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── meetup-test.lisp │ │ └── meetup.lisp │ ├── nth-prime │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── nth-prime-test.lisp │ │ └── nth-prime.lisp │ ├── nucleotide-count │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── nucleotide-count-test.lisp │ │ └── nucleotide-count.lisp │ ├── palindrome-products │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── palindrome-products-test.lisp │ │ └── palindrome-products.lisp │ ├── pangram │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── pangram-test.lisp │ │ └── pangram.lisp │ ├── pascals-triangle │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── pascals-triangle-test.lisp │ │ └── pascals-triangle.lisp │ ├── perfect-numbers │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── perfect-numbers-test.lisp │ │ └── perfect-numbers.lisp │ ├── phone-number │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── phone-number-test.lisp │ │ └── phone-number.lisp │ ├── pig-latin │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── pig-latin-test.lisp │ │ └── pig-latin.lisp │ ├── prime-factors │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── prime-factors-test.lisp │ │ └── prime-factors.lisp │ ├── protein-translation │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── protein-translation-test.lisp │ │ └── protein-translation.lisp │ ├── proverb │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── proverb-test.lisp │ │ └── proverb.lisp │ ├── pythagorean-triplet │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── pythagorean-triplet-test.lisp │ │ └── pythagorean-triplet.lisp │ ├── queen-attack │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── queen-attack-test.lisp │ │ └── queen-attack.lisp │ ├── rail-fence-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── rail-fence-cipher-test.lisp │ │ └── rail-fence-cipher.lisp │ ├── raindrops │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── raindrops-test.lisp │ │ └── raindrops.lisp │ ├── resistor-color-duo │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── resistor-color-duo-test.lisp │ │ └── resistor-color-duo.lisp │ ├── resistor-color-trio │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── resistor-color-trio-test.lisp │ │ └── resistor-color-trio.lisp │ ├── resistor-color │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── resistor-color-test.lisp │ │ └── resistor-color.lisp │ ├── rna-transcription │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── rna-transcription-test.lisp │ │ └── rna-transcription.lisp │ ├── robot-name │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.lisp │ │ ├── robot-name-test.lisp │ │ └── robot-name.lisp │ ├── robot-simulator │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── robot-simulator-test.lisp │ │ └── robot-simulator.lisp │ ├── roman-numerals │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── roman-numerals-test.lisp │ │ └── roman-numerals.lisp │ ├── rotational-cipher │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── rotational-cipher-test.lisp │ │ └── rotational-cipher.lisp │ ├── run-length-encoding │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── run-length-encoding-test.lisp │ │ └── run-length-encoding.lisp │ ├── saddle-points │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── saddle-points-test.lisp │ │ └── saddle-points.lisp │ ├── say │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── say-test.lisp │ │ └── say.lisp │ ├── scrabble-score │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── scrabble-score-test.lisp │ │ └── scrabble-score.lisp │ ├── secret-handshake │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── secret-handshake-test.lisp │ │ └── secret-handshake.lisp │ ├── sieve │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── sieve-test.lisp │ │ └── sieve.lisp │ ├── space-age │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── space-age-test.lisp │ │ └── space-age.lisp │ ├── spiral-matrix │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── spiral-matrix-test.lisp │ │ └── spiral-matrix.lisp │ ├── square-root │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── square-root-test.lisp │ │ └── square-root.lisp │ ├── strain │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── strain-test.lisp │ │ └── strain.lisp │ ├── sublist │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── sublist-test.lisp │ │ └── sublist.lisp │ ├── sum-of-multiples │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── sum-of-multiples-test.lisp │ │ └── sum-of-multiples.lisp │ ├── triangle │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── triangle-test.lisp │ │ └── triangle.lisp │ ├── trinary │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── trinary-test.lisp │ │ └── trinary.lisp │ ├── twelve-days │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── twelve-days-test.lisp │ │ └── twelve-days.lisp │ ├── two-bucket │ │ ├── .docs │ │ │ └── instructions.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── two-bucket-test.lisp │ │ └── two-bucket.lisp │ ├── two-fer │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── two-fer-test.lisp │ │ └── two-fer.lisp │ ├── word-count │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── .meta │ │ │ ├── config.json │ │ │ ├── example.lisp │ │ │ └── tests.toml │ │ ├── word-count-test.lisp │ │ └── word-count.lisp │ └── yacht │ │ ├── .docs │ │ ├── instructions.md │ │ └── introduction.md │ │ ├── .meta │ │ ├── config.json │ │ ├── example.lisp │ │ └── tests.toml │ │ ├── yacht-test.lisp │ │ └── yacht.lisp └── shared │ └── .docs │ ├── debug.md │ ├── help.md │ ├── representations.md │ └── tests.md ├── reference ├── exercise-concepts │ ├── anagram.md │ ├── rna-transcription.md │ ├── roman-numerals.md │ └── word-count.md ├── implementing-a-concept-exercise.md └── types │ └── cons.md └── src ├── config-checker.asd ├── config-checker ├── main.lisp ├── packages.lisp ├── track-config.lisp └── utils.lisp ├── ex-maint-utils.asd ├── ex-maint-utils ├── package.lisp └── stubs │ ├── concept-exercises.lisp │ ├── concepts.lisp │ ├── package.lisp │ └── utils.lisp ├── make-exec.lisp ├── one-off-scripts ├── practice-exercise-conversion.lisp └── v2-to-v3.lisp ├── test-exercises.asd └── test-exercises ├── exercises.lisp ├── main.lisp ├── packages.lisp ├── paths.lisp ├── report.lisp ├── run.lisp └── utils.lisp /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners 2 | .github/CODEOWNERS @exercism/maintainers-admin 3 | 4 | # Changes to `fetch-configlet` should be made in the `exercism/configlet` repo 5 | bin/fetch-configlet @exercism/maintainers-admin 6 | 7 | -------------------------------------------------------------------------------- /.github/actions/perform-system/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clfoundation/sbcl 2 | 3 | COPY entrypoint.sh /entrypoint.sh 4 | 5 | ENTRYPOINT ["/entrypoint.sh"] 6 | 7 | -------------------------------------------------------------------------------- /.github/actions/perform-system/action.yml: -------------------------------------------------------------------------------- 1 | name: perform-system 2 | description: "Perform a ASDF operation on a system" 3 | inputs: 4 | system: 5 | description: "System to operate on" 6 | required: true 7 | 8 | operation: 9 | description: "Operation to perform" 10 | required: false 11 | default: 'make' 12 | 13 | location: 14 | description: "Directory containing the system" 15 | required: false 16 | default: 'src/' 17 | 18 | runs: 19 | using: 'docker' 20 | image: Dockerfile 21 | args: 22 | - ${{inputs.location}} 23 | - ${{inputs.operation}} 24 | - ${{inputs.system}} 25 | 26 | 27 | -------------------------------------------------------------------------------- /.github/actions/perform-system/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | QUICKLISP_ADD_TO_INIT_FILE=true /usr/local/bin/install-quicklisp 4 | 5 | LOCATION=\"$1\" 6 | OPERATION=$2 7 | SYSTEM=\"$3\" 8 | 9 | /usr/local/bin/sbcl \ 10 | --noinform --non-interactive \ 11 | --eval "(push (merge-pathnames $LOCATION) asdf:*central-registry*)" \ 12 | --eval "(ql:quickload $SYSTEM)" \ 13 | --eval "(asdf:${OPERATION} $SYSTEM)" 14 | -------------------------------------------------------------------------------- /.github/configlet-sync-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Out of sync practice exercises 3 | --- 4 | 5 | Out of sync practice exercises have been detected: 6 | 7 | Command: `configlet sync --tests --docs --metadata --filepaths` 8 | 9 | Output: 10 | ``` 11 | {{ env.SYNC_OUTPUT }} 12 | ``` 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | 5 | # Keep dependencies for GitHub Actions up-to-date 6 | - package-ecosystem: 'github-actions' 7 | directory: '/' 8 | schedule: 9 | interval: 'monthly' 10 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | (Explain what this change is attempting to accomplish) 4 | 5 | 6 | ## Checklist 7 | - [ ] If docs where changed run `./bin/configlet generate` to ensure all documents are properly generated. 8 | - [ ] CI is green 9 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/common-lisp/e3d4b39fad48f48723bc4ccbfb6c26162bb91682/.github/stale.yml -------------------------------------------------------------------------------- /.github/workflows/config-checker.yml: -------------------------------------------------------------------------------- 1 | name: Config Check 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | config-check: 7 | timeout-minutes: 30 8 | runs-on: ubuntu-22.04 9 | 10 | container: 11 | image: clfoundation/sbcl 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 16 | 17 | - name: Check Config 18 | uses: ./.github/actions/perform-system 19 | with: 20 | system: config-checker 21 | operation: test-system 22 | -------------------------------------------------------------------------------- /.github/workflows/configlet.yml: -------------------------------------------------------------------------------- 1 | name: Configlet 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | workflow_dispatch: 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | configlet: 15 | uses: exercism/github-actions/.github/workflows/configlet.yml@main 16 | -------------------------------------------------------------------------------- /.github/workflows/no-important-files-changed.yml: -------------------------------------------------------------------------------- 1 | name: No important files changed 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | branches: [main] 7 | paths: 8 | - "exercises/concept/**" 9 | - "exercises/practice/**" 10 | - "!exercises/*/*/.approaches/**" 11 | - "!exercises/*/*/.articles/**" 12 | - "!exercises/*/*/.docs/**" 13 | - "!exercises/*/*/.meta/**" 14 | 15 | permissions: 16 | pull-requests: write 17 | 18 | jobs: 19 | check: 20 | uses: exercism/github-actions/.github/workflows/check-no-important-files-changed.yml@main 21 | with: 22 | repository: ${{ github.event.pull_request.head.repo.owner.login }}/${{ github.event.pull_request.head.repo.name }} 23 | ref: ${{ github.head_ref }} 24 | -------------------------------------------------------------------------------- /.github/workflows/pause-community-contributions.yml: -------------------------------------------------------------------------------- 1 | name: Pause Community Contributions 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | pull_request_target: 8 | types: 9 | - opened 10 | paths-ignore: 11 | - 'exercises/*/*/.approaches/**' 12 | - 'exercises/*/*/.articles/**' 13 | 14 | permissions: 15 | issues: write 16 | pull-requests: write 17 | 18 | jobs: 19 | pause: 20 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 21 | uses: exercism/github-actions/.github/workflows/community-contributions.yml@main 22 | with: 23 | forum_category: common-lisp 24 | secrets: 25 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/ping-cross-track-maintainers-team.yml: -------------------------------------------------------------------------------- 1 | name: Ping cross-track maintainers team 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | 8 | permissions: 9 | pull-requests: write 10 | 11 | jobs: 12 | ping: 13 | if: github.repository_owner == 'exercism' # Stops this job from running on forks 14 | uses: exercism/github-actions/.github/workflows/ping-cross-track-maintainers-team.yml@main 15 | secrets: 16 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/sync-labels.yml: -------------------------------------------------------------------------------- 1 | name: Tools 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - .github/labels.yml 9 | - .github/workflows/sync-labels.yml 10 | workflow_dispatch: 11 | schedule: 12 | - cron: 0 0 1 * * # First day of each month 13 | 14 | permissions: 15 | issues: write 16 | 17 | jobs: 18 | sync-labels: 19 | uses: exercism/github-actions/.github/workflows/labels.yml@main 20 | -------------------------------------------------------------------------------- /.github/workflows/test-exercises.yml: -------------------------------------------------------------------------------- 1 | name: Test Exercises 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | run-tests: 7 | timeout-minutes: 30 8 | runs-on: ubuntu-22.04 9 | 10 | container: 11 | image: clfoundation/sbcl 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 16 | 17 | - name: Run Tests 18 | uses: ./.github/actions/perform-system 19 | with: 20 | system: test-exercises 21 | operation: test-system 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.beam 3 | *.fasl 4 | .DS_Store 5 | tmp 6 | bin/configlet 7 | bin/configlet.exe 8 | bin/generate-exercise 9 | *~ 10 | .mailmap 11 | -------------------------------------------------------------------------------- /bin/sync-exercise: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | update="./bin/configlet sync --update --exercise $1" 4 | 5 | ${update} --yes --docs --metadata --filepaths 6 | ${update} --tests i 7 | -------------------------------------------------------------------------------- /concepts/arithmetic/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Common Lisp allows one to do various arithmetic function upon numbers.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/arithmetic/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/12_aa.htm", 4 | "description": "All numerical operations in Lisp" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/arrays/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "An array is a sequence of indexable elements that can be multi-dimensional and contain heterogeneous data.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/arrays/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/15_.htm", 4 | "description": "Arrays from the specification" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/characters/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Characters are objects representing individual tokens in text (e.g. strings or text streams)", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/characters/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/13_aa.htm", 4 | "description": "Introduction to characters from the specification" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/comments/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Useful for adding documentation or temporarily removing expressions.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/comments/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Single-line comments in Common Lisp follow a couple of conventions: 4 | 5 | ```lisp 6 | ;;;; A short title for a block of code 7 | ;;; A longer description of a block of code 8 | ;; Describe the code below this line 9 | ; Describe the code before the semi-colon (;) on this line 10 | ``` 11 | 12 | Additionally, multi-line comments are possible using `#|` and `|#`: 13 | 14 | ```lisp 15 | #| 16 | This entire block of text is a comment 17 | and can span several lines! 18 | 19 | How cool is that?! 20 | |# 21 | ``` 22 | -------------------------------------------------------------------------------- /concepts/comments/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Common Lisp allows the programmer to write "comments" that are ignored by the computer. 4 | Single-line comments begin with one or more semi-colons (`;`) and, occasionally, you may see the following: 5 | 6 | ```lisp 7 | (code...) ; => value 8 | ``` 9 | 10 | Where the comment is being used to indicate what value is returned by Common Lisp after running the code on that line. 11 | 12 | It is idiomatic to use a single semi-colon for a short comment at the end of a line, two for a longer comment above a section of code, three for long comment describing something such as a function and four for a comment such as a header at the top of a source file. 13 | -------------------------------------------------------------------------------- /concepts/comments/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/02_ddb.htm", 4 | "description": "Hyperspec reference regarding commenting conventions" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/conditionals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Branching logic", 3 | "authors": [ 4 | "TheLostLambda" 5 | ], 6 | "contributors": [] 7 | } 8 | -------------------------------------------------------------------------------- /concepts/conditionals/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://riptutorial.com/common-lisp/example/11082/conditional-constructs", 4 | "description": "A brief tutorial of some Common Lisp conditional expressions." 5 | }, 6 | { 7 | "url": "https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html", 8 | "description": "Description of the basic Common Lisp conditional expressions." 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /concepts/cons/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "An ordered pair of elements.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/cons/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | All Common Lisp objects are either "atoms" (single, indivisible values) or "conses" (built by the construct function "cons"). 4 | A cons is made up of two parts: the first element and the rest of the elements. 5 | For historical reasons these two parts are called the `car` and the `cdr`. 6 | When these conses are evaluated as code, the first element (`car`) represents the function being called while the rest of the elements 7 | (`cdr`) represent the arguments to that function: 8 | 9 | ```lisp 10 | ( ... ) 11 | ; ^ car ^ | ^ cdr ^ 12 | ``` 13 | -------------------------------------------------------------------------------- /concepts/date-time/.meta/config.json: -------------------------------------------------------------------------------- 1 | { "blurb": "Handling dates and times", "authors": ["verdammelt"] } 2 | -------------------------------------------------------------------------------- /concepts/date-time/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/25_ad.htm", 4 | "description": "Hyperspec section on Time" 5 | }, 6 | { 7 | "url": "https://lispcookbook.github.io/cl-cookbook/dates_and_times.html", 8 | "description": "Lisp Cookbook on Dates and Times" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /concepts/equality/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Common Lisp has four degrees of equality.", 3 | "authors": ["verdammelt"], 4 | "contributors": ["TheLostLambda"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/equality/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://eli.thegreenplace.net/2004/08/08/equality-in-lisp", 4 | "description": "eli-lisp-equality" 5 | }, 6 | { 7 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm", 8 | "description": "hyper-eq" 9 | }, 10 | { 11 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_eql.htm", 12 | "description": "hyper-eql" 13 | }, 14 | { 15 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_equal.htm", 16 | "description": "hyper-equal" 17 | }, 18 | { 19 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_equalp.htm", 20 | "description": "hyper-equalp" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /concepts/expressions/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Everything in Common Lisp is an expression. Either an atom or a list of expressions.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/expressions/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Everything in Common Lisp is an expression. 4 | An expression is either a single thing (called an atom) or a list of things (delimited with parenthesis: `()`). 5 | 6 | ## Quoting 7 | 8 | All S-Expressions, like symbols, can be quoted: 9 | 10 | ```lisp 11 | ;; This line is evaluated as code 12 | (gimme-foo) ; => FOO 13 | 14 | ;; This line is treated as data 15 | '(gimme-foo) ; => (GIMME-FOO) 16 | ``` 17 | 18 | This quoting prevents the evaluation of an S-expression, instead treating it like data. 19 | Here is an excellent [Stack Overflow Answer][so-quoting] discussing quoting in a bit more detail. 20 | 21 | [so-quoting]: https://stackoverflow.com/questions/134887/when-to-use-or-quote-in-lisp 22 | -------------------------------------------------------------------------------- /concepts/expressions/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | All Common Lisp code is made of S-Expressions (Symbolic Expressions). They are called sexprs for short. Every sexpr is either an atom or a cons. When S-Expressions are evaluated, they automatically return some value which takes the place of the expression. When writing your own functions (using `defun`), the last value within the body of the `defun` is automatically returned: 4 | 5 | ```lisp 6 | ;; Defining a new function 7 | (defun gimme-foo () 'foo) 8 | ;; Calling the function as an S-Expression 9 | (gimme-foo) ; => FOO 10 | ``` 11 | -------------------------------------------------------------------------------- /concepts/expressions/links.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /concepts/filtering/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Filtering is the process of creating a new sequence by copying all but some items from another sequence.", 3 | "authors": ["verdammelt"], 4 | "contributors": ["goderich"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/filtering/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_rm_rm.htm", 4 | "description": "Hyperspec page on remove and related functions." 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/floating-point-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Floating point numbers represent real numbers.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/floating-point-numbers/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Like many languages, Common Lisp contains floating point numbers. 4 | These are fractional or whole numbers including a decimal point (like `3.14`, `-1.7`, `99.99`, `2048.0`). 5 | -------------------------------------------------------------------------------- /concepts/floating-point-numbers/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://lispcookbook.github.io/cl-cookbook/numbers.html", 4 | "description": "Advanced numbers reference (Common Lisp Cookbook)" 5 | }, 6 | { 7 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/t_float.htm", 8 | "description": "HyperSpec definition of the float type" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /concepts/format-basics/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Basic information about formatting output.", 3 | "authors": ["verdammelt"] 4 | } 5 | -------------------------------------------------------------------------------- /concepts/format-basics/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://gigamonkeys.com/book/a-few-format-recipes.html#basic-formatting", 4 | "description": "Information about basic format directives." 5 | }, 6 | { 7 | "url": "https://gigamonkeys.com/book/a-few-format-recipes.html#the-format-function", 8 | "description": "Description of the format function." 9 | }, 10 | { 11 | "url": "https://gigamonkeys.com/book/a-few-format-recipes.html#format-directives", 12 | "description": "Overview of format directives." 13 | }, 14 | { 15 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm", 16 | "description": "Hyperspec chapter on formatting output." 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /concepts/functions/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "A reuable set of expressions", 3 | "authors": [ 4 | "verdammelt" 5 | ], 6 | "contributors": [] 7 | } 8 | -------------------------------------------------------------------------------- /concepts/functions/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://lispcookbook.github.io/cl-cookbook/functions.html", 4 | "description": "Lisp Cookbook on Functions" 5 | }, 6 | { 7 | "url": "http://www.gigamonkeys.com/book/functions.html", 8 | "description": "Practical Common Lisp on Functions" 9 | }, 10 | { 11 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm", 12 | "description": "Hyperspec page on defun" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /concepts/hash-tables/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "An associative data structure mapping a key to a value", 3 | "authors": ["verdammelt"] 4 | } 5 | -------------------------------------------------------------------------------- /concepts/hash-tables/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/18_.htm", 4 | "description": "Hyperspec chapter on hash tables" 5 | }, 6 | { 7 | "url": "https://gigamonkeys.com/book/collections.html#hash-tables", 8 | "description": "Practical Common Lisp on hash tables" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /concepts/integers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Integers are whole numbers without a decimal point. There is no limitation on their magnitude.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/integers/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Like many languages Common Lisp contains integers. 4 | These are whole numbers without a decimal point (like `-6`, `0`, `25`, `1234`, etc.) 5 | 6 | Common Lisp defines no limits on the magnitude of integers. 7 | Integers can be arbitrarily large (or small if negative). 8 | 9 | In general, if you are working with only whole numbers, you should prefer integers as they don't suffer from the same loss of precision as floating-point numbers do over many calculations. 10 | -------------------------------------------------------------------------------- /concepts/integers/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://lispcookbook.github.io/cl-cookbook/numbers.html", 4 | "description": "Advanced numbers reference (Common Lisp Cookbook)" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/keyword-parameters/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Keyword parameters allow one to specify arguments in any order by their names.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/keyword-parameters/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.gigamonkeys.com/book/functions.html", 4 | "description": "Practical Common Lisp chapter 5: Functions" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/lambda-list/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "The rules of parameter lists", 3 | "authors": [ 4 | "verdammelt" 5 | ], 6 | "contributors": [] 7 | } 8 | -------------------------------------------------------------------------------- /concepts/lambda-list/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_l.htm#lambda_list", 4 | "description": "Definition of Lambda List" 5 | }, 6 | { 7 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_l.htm#lambda_list_keyword", 8 | "description": "Definition of Lambda List Keyword" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /concepts/lists/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "A recursive data structure made from a head and tail.", 3 | "authors": [ 4 | "verdammelt" 5 | ], 6 | "contributors": [] 7 | } 8 | -------------------------------------------------------------------------------- /concepts/lists/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://www.tutorialspoint.com/lisp/lisp_lists.htm", 4 | "description": "Summary of functions pertaining to lists and conses" 5 | }, 6 | { 7 | "url": "http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html", 8 | "description": "Practical Common Lisp chapter on lists and conses." 9 | }, 10 | { 11 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/14_ab.htm", 12 | "description": "Hyperspec reference on conses as lists." 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /concepts/mapping/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Mapping is the repeated application of a function to a sequence to create another sequence", 3 | "authors": ["verdammelt"] 4 | } 5 | -------------------------------------------------------------------------------- /concepts/mapping/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Mapping refers to the application of a function to each element of a sequence to produce a new sequence. 4 | 5 | This can be done easily to a list with the function `mapcar`. 6 | Let us assume we have a function `double` which multiplies its argument by `2`: 7 | 8 | ```lisp 9 | (mapcar #'double '(1 2 3 4)) ; => (2 4 6 8) 10 | ``` 11 | 12 | Notice that the first argument is a function to call. The `#'` is a special quoting syntax to specify a function. 13 | 14 | `double` was first called with the first element, then with the second, etc. 15 | The results were collected into a list which is the value the expression evaluates to. 16 | 17 | -------------------------------------------------------------------------------- /concepts/mapping/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_mapc_.htm", 4 | "description": "Hyperspec reference to list mapping functions" 5 | }, 6 | 7 | { 8 | "url": "https://gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-processing.html#mapping", 9 | "description": "Practical Common Lisp on mapping across lists" 10 | }, 11 | { 12 | "url": "https://gigamonkeys.com/book/collections.html#sequence-mapping-functions", 13 | "description": "Practical Common Lisp on mapping across sequences" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /concepts/multiple-values/.meta/config.json: -------------------------------------------------------------------------------- 1 | { "blurb": "Functions can return multiple values", "authors": ["verdammelt"] } 2 | -------------------------------------------------------------------------------- /concepts/multiple-values/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://lispcookbook.github.io/cl-cookbook/functions.html#multiple-return-values-values-multiple-value-bind-and-nth-value", 4 | "description": "Lisp Cookbook on Multiple Return Values" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/optional-parameters/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Optional parameters allow some parameters to be not given and they will be assigned a default value instead.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/optional-parameters/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.gigamonkeys.com/book/functions.html", 4 | "description": "Practical Common Lisp chapter 5: Functions" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/reducing/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Reducing is the repeated application of a function to an sequence and accumulating the results", 3 | "authors": ["verdammelt"] 4 | } 5 | -------------------------------------------------------------------------------- /concepts/reducing/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/f_reduce.htm", 4 | "description": "Hyperspec reference for reduce" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/rest-parameters/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "A parameter can be specified that will be assigned all the 'rest' of the parameters provided in a list.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/rest-parameters/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | A rest parameter is designated by the `&rest` lambda list keyword in a lambda list. 4 | This parameter will be bound to a value which is a list of all the arguments provided by the caller which is not consumed by other parameters. 5 | 6 | While multiple types of parameters can be combined with other types of parameters (optional and keyword parameters) this can be be problematic and should be done carefully. 7 | See the section on ["Mixing Different Parameter Types"][pcl-function] in Practical Common Lisp. 8 | 9 | [pcl-function]: http://www.gigamonkeys.com/book/functions.html 10 | -------------------------------------------------------------------------------- /concepts/rest-parameters/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.gigamonkeys.com/book/functions.html", 4 | "description": "Practical Common Lisp chapter 5: Functions" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/strings/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Strings are vectors of characters, they are represented as characters surrounded by double-quotes.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/strings/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Since strings are [vectors][concept-vectors] which are sequences (both covered in other concepts) all functions that work on sequences will work on strings - such as `position`, `map`, `remove`, `concatenate` _etc._. 4 | 5 | There are also more string specific functions to do things such as compare strings to see which is alphabetically more or less `string<` and `string>`; functions to trim characters from the left, right or both sides of a string (`string-trim`). 6 | Refer to the [Hyperspec Section on strings][hyper-string] for full details. 7 | 8 | [concept-vectors]: /tracks/common-lisp/concepts/vectors 9 | [hyper-string]: http://www.lispworks.com/documentation/HyperSpec/Body/16_a.htm 10 | -------------------------------------------------------------------------------- /concepts/strings/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.gigamonkeys.com/book/numbers-characters-and-strings.html", 4 | "description": "Practial Common Lisp chapter covering strings" 5 | }, 6 | { 7 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/16_a.htm", 8 | "description": "Hyperspec section on strings" 9 | }, 10 | { 11 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/c_string.htm", 12 | "description": "Hyperspec string dictionary" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /concepts/symbols/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "Symbols are identifiers for values. They can be used as the name of a variable, function or other values.", 3 | "authors": ["TheLostLambda"], 4 | "contributors": ["verdammelt"] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/symbols/about.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | 3 | ```lisp 4 | ;; Returning a symbol from a `defun` 5 | (defun gimme-foo () 'foo) 6 | (gimme-foo) ; => FOO 7 | 8 | ;; The same, but as a keyword 9 | (defun gimme-bar () :bar) 10 | (gimme-bar) ; => :BAR 11 | ``` 12 | -------------------------------------------------------------------------------- /concepts/symbols/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://stackoverflow.com/questions/23969203/what-is-the-difference-between-a-keyword-symbol-and-a-quoted-symbol", 4 | "description": "Stack Overflow: Keywords & Symbols" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /concepts/truthy-and-falsy/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "True and False values", 3 | "authors": [ 4 | "TheLostLambda" 5 | ], 6 | "contributors": [] 7 | } 8 | -------------------------------------------------------------------------------- /concepts/truthy-and-falsy/about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | In Common Lisp, false values are represented by the empty list – `()` – or the symbol `nil`. 4 | These values can be quoted or unquoted. 5 | 6 | ```lisp 7 | ;; Equivalent False Values 8 | () ; => NIL 9 | nil ; => NIL 10 | '() ; => NIL 11 | 'nil ; => NIL 12 | ``` 13 | 14 | All other values in Lisp represent truth. 15 | There also exists the special constant symbol `t` that is always equal to `t` (and is therefore always true). 16 | 17 | ```lisp 18 | ;; Some Different True Values 19 | 42 ; => 42 20 | "this statement is false" ; => "this statement is false" 21 | t ; => T 22 | 't ; => T 23 | ``` 24 | -------------------------------------------------------------------------------- /concepts/truthy-and-falsy/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In Common Lisp all values are "true" except for `()` which is "false". 4 | There are two special constant symbols `t` and `nil` whose values are true and false respectively. 5 | -------------------------------------------------------------------------------- /concepts/truthy-and-falsy/links.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /concepts/vectors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "blurb": "A vector is a 1-dimensional array.", 3 | "authors": ["verdammelt"], 4 | "contributors": [] 5 | } 6 | -------------------------------------------------------------------------------- /concepts/vectors/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A vector is a 1-dimensional array. 4 | They may contain elements of different types. 5 | 6 | ## Creating Vectors 7 | 8 | Vectors can be created via the `vector` function or by using its reader form `#()` 9 | 10 | ```lisp 11 | (vector 1 t "foo" 'b) ; => #(1 t "foo" B) 12 | #(2 nil "bar" a) ; => #(2 nil "bar" A) 13 | ``` 14 | 15 | ## Accessing Elements 16 | 17 | To access elements of a vector use `aref`, the indexes are zero-based: 18 | 19 | ```lisp 20 | (aref #(1 2 3) 1) ; => 2 21 | (aref #(a b c) 0) ; => A 22 | ``` 23 | -------------------------------------------------------------------------------- /concepts/vectors/links.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "http://www.lispworks.com/documentation/HyperSpec/Body/13_aa.htm", 4 | "description": "Introduction to arrays from the specification" 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Common Lisp is an offshoot of the long-running family of Lisp programming languages. 4 | It's a multi-paradigm programming language that allows you to choose the approach and paradigm according to your application domain. 5 | 6 | Common Lisp has fast prototyping capabilities, and exceptional support for object oriented programming. 7 | It also boasts a macro system which allows you to adapt the language to your needs, and a run-time environment which allows modification of running applications. 8 | 9 | To learn more about Common Lisp, take a look at [the Common Lisp homepage][common-lisp-net] 10 | 11 | [common-lisp-net]: https://common-lisp.net/ 12 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | (defun distance (str1 str2 2 | &key (test #'char=)) 3 | "Number of positional differences in 4 | two equal length strings." 5 | (when (= (length str1) (length str2)) 6 | (count nil 7 | (map 'list test str1 str2)))) 8 | -------------------------------------------------------------------------------- /exercises/concept/character-study/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:characters} 4 | -------------------------------------------------------------------------------- /exercises/concept/character-study/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "character-study.lisp" 8 | ], 9 | "test": [ 10 | "character-study-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Learn the basics of Common Lisp characters by helping Lewis learn about Earth letters." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/character-study/character-study.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :character-study 2 | (:use :cl) 3 | (:export 4 | :compare-chars 5 | :size-of-char 6 | :change-size-of-char 7 | :type-of-char)) 8 | (in-package :character-study) 9 | 10 | (defun compare-chars (char1 char2)) 11 | 12 | (defun size-of-char (char)) 13 | 14 | (defun change-size-of-char (char wanted-size)) 15 | 16 | (defun type-of-char (char)) 17 | -------------------------------------------------------------------------------- /exercises/concept/gigasecond-anniversary/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Lisp Aliens like to celebrate anniversaries. 4 | To them an important anniversary date is the Gigasecond. 5 | That is: 1,000,000,000 seconds since the event. 6 | 7 | ## 1. Compute the Gigasecond anniversary date 8 | 9 | Write a function `from` which takes 6 parameters: `year`, `month`, `day`, `hour`, `min`, `sec` and computes the date and time of the Gigasecond anniversary. 10 | This function should return the date as a list of the same order and meaning as the parameters of the input. 11 | 12 | ``` 13 | (from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40) 14 | ``` 15 | -------------------------------------------------------------------------------- /exercises/concept/gigasecond-anniversary/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:date-time} 4 | 5 | %{concept:multiple-values} -------------------------------------------------------------------------------- /exercises/concept/gigasecond-anniversary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "gigasecond-anniversary.lisp" 8 | ], 9 | "test": [ 10 | "gigasecond-anniversary-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Learn about handling dates and times in Common Lisp by helping compute Gigasecond Anniversary dates" 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/gigasecond-anniversary/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :gigasecond-anniversary 2 | (:use :cl) 3 | (:export :from)) 4 | 5 | (in-package :gigasecond-anniversary) 6 | 7 | (defun from (year month day hour minute second) 8 | (reverse 9 | (subseq 10 | (multiple-value-list 11 | (let ((TZ 0)) 12 | (decode-universal-time 13 | (+ (encode-universal-time second minute hour day month year TZ) 14 | (expt 10 9)) 15 | TZ))) 16 | 0 6))) 17 | -------------------------------------------------------------------------------- /exercises/concept/gigasecond-anniversary/gigasecond-anniversary.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :gigasecond-anniversary 2 | (:use :cl) 3 | (:export :from)) 4 | (in-package :gigasecond-anniversary) 5 | 6 | (defun from (year month day hour minute second)) 7 | -------------------------------------------------------------------------------- /exercises/concept/high-scores/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:hash-tables} -------------------------------------------------------------------------------- /exercises/concept/high-scores/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "high-scores.lisp" 8 | ], 9 | "test": [ 10 | "high-scores-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Learn about hash tables by keeping track of the high scores in a game that Lamont wants to write." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/high-scores/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :high-scores 2 | (:use :cl) 3 | (:export :make-high-scores-table :add-player 4 | :set-score :get-score :remove-player)) 5 | 6 | (in-package :high-scores) 7 | 8 | (defun make-high-scores-table () (make-hash-table)) 9 | 10 | (defun add-player (table player) (setf (gethash player table) 0)) 11 | 12 | (defun set-score (table player score) (setf (gethash player table) score)) 13 | 14 | (defun get-score (table player) (gethash player table 0)) 15 | 16 | (defun remove-player (table player) (remhash player table)) 17 | -------------------------------------------------------------------------------- /exercises/concept/high-scores/high-scores.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :high-scores 2 | (:use :cl) 3 | (:export :make-high-scores-table :add-player 4 | :set-score :get-score :remove-player)) 5 | 6 | (in-package :high-scores) 7 | 8 | ;; Define make-high-scores-table function 9 | 10 | ;; Define add-player function 11 | 12 | ;; Define set-score function 13 | 14 | ;; Define get-score function 15 | 16 | ;; Define remove-player function 17 | -------------------------------------------------------------------------------- /exercises/concept/key-comparison/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:equality} 4 | -------------------------------------------------------------------------------- /exercises/concept/key-comparison/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt", 4 | "TheLostLambda" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "key-comparison.lisp" 9 | ], 10 | "test": [ 11 | "key-comparison-test.lisp" 12 | ], 13 | "exemplar": [ 14 | ".meta/exemplar.lisp" 15 | ] 16 | }, 17 | "icon": "minesweeper", 18 | "blurb": "Learn about equality by helping find the keys to the rooms of a maze." 19 | } 20 | -------------------------------------------------------------------------------- /exercises/concept/larrys-winning-checker/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:arrays} -------------------------------------------------------------------------------- /exercises/concept/larrys-winning-checker/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "larrys-winning-checker.lisp" 8 | ], 9 | "test": [ 10 | "larrys-winning-checker-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Learn the basics of Common Lisp arrays by helping Larry check for winner of their tic-tac-toe like game." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/larrys-winning-checker/.meta/design.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exercism/common-lisp/e3d4b39fad48f48723bc4ccbfb6c26162bb91682/exercises/concept/larrys-winning-checker/.meta/design.md -------------------------------------------------------------------------------- /exercises/concept/larrys-winning-checker/larrys-winning-checker.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :larrys-winning-checker 2 | (:use :cl) 3 | (:export 4 | :make-empty-board 5 | :make-board-from-list 6 | :all-the-same-p 7 | :row 8 | :column)) 9 | 10 | (in-package :larrys-winning-checker) 11 | 12 | (defun make-empty-board ()) 13 | 14 | (defun make-board-from-list (list)) 15 | 16 | (defun all-the-same-p (row-or-col)) 17 | 18 | (defun row (board row-num)) 19 | 20 | (defun column (board col-num)) 21 | -------------------------------------------------------------------------------- /exercises/concept/leslies-lists/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:lists} 4 | -------------------------------------------------------------------------------- /exercises/concept/leslies-lists/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "leslies-lists.lisp" 8 | ], 9 | "test": [ 10 | "leslies-lists-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "icon": "sublist", 17 | "blurb": "Learn about Lists by helping to keep track of a shopping list." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna-leftovers/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:lambda-list} 4 | 5 | %{concept:optional-parameters} 6 | 7 | %{concept:keyword-parameters} 8 | 9 | %{concept:rest-parameters} 10 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna-leftovers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "lillys-lasagna-leftovers.lisp" 8 | ], 9 | "test": [ 10 | "lillys-lasagna-leftovers-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "forked_from": [ 17 | "swift/lasagna-master" 18 | ], 19 | "icon": "lasagna", 20 | "blurb": "Learn about keyword, optional and rest arguments by again helping with lasagna." 21 | } 22 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna-leftovers/lillys-lasagna-leftovers.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :lillys-lasagna-leftovers 2 | (:use :cl) 3 | (:export 4 | :preparation-time 5 | :remaining-minutes-in-oven 6 | :split-leftovers)) 7 | 8 | (in-package :lillys-lasagna-leftovers) 9 | 10 | ;; Define function preparation-time 11 | 12 | ;; Define function remaining-minutes-in-oven 13 | 14 | ;; Define function split-leftovers 15 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:functions} 4 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "lillys-lasagna.lisp" 8 | ], 9 | "test": [ 10 | "lillys-lasagna-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "forked_from": [ 17 | "ruby/lasagna" 18 | ], 19 | "icon": "lasagna", 20 | "blurb": "Learn about functions by helping to cook lasagna." 21 | } 22 | -------------------------------------------------------------------------------- /exercises/concept/lillys-lasagna/lillys-lasagna.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :lillys-lasagna 2 | (:use :cl) 3 | (:export :expected-time-in-oven 4 | :remaining-minutes-in-oven 5 | :preparation-time-in-minutes 6 | :elapsed-time-in-minutes)) 7 | 8 | (in-package :lillys-lasagna) 9 | 10 | ;; Define function expected-time-in-oven 11 | 12 | ;; Define function remaining-minutes-in-oven 13 | 14 | ;; Define function preparation-time-in-minutes 15 | 16 | ;; Define function elapsed-time-in-minutes 17 | -------------------------------------------------------------------------------- /exercises/concept/log-levels/.docs/hints.md: -------------------------------------------------------------------------------- 1 | ## 1. Extract the message 2 | 3 | - Implement `log-message` with `subseq` 4 | - Strings are zero-indexed 5 | 6 | ## 2. Determine the severity 7 | 8 | - Implement `log-severity` with a conditional expression using `string=` 9 | 10 | ## 3. Dealing with the vagaries of reality 11 | 12 | - `string-equal` is a case-insensitive version of `string=` 13 | 14 | ## 4. Reformatting the log message according to log severity 15 | 16 | - There are three functions mentioned in the introduction to do the transformations required. 17 | -------------------------------------------------------------------------------- /exercises/concept/log-levels/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:strings} 4 | -------------------------------------------------------------------------------- /exercises/concept/log-levels/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "log-levels.lisp" 8 | ], 9 | "test": [ 10 | "log-levels-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "forked_from": [ 17 | "csharp/log-levels" 18 | ], 19 | "blurb": "Learn about Common Lisp strings by processing log messages" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/concept/log-levels/log-levels.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :log-levels 2 | (:use :cl) 3 | (:export :log-message :log-severity :log-format)) 4 | 5 | (in-package :log-levels) 6 | 7 | (defun log-message (log-string)) 8 | 9 | (defun log-severity (log-string)) 10 | 11 | (defun log-format (log-string)) 12 | -------------------------------------------------------------------------------- /exercises/concept/logans-numeric-partition/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # Hints 2 | 3 | ## 1. Categorizing a number 4 | 5 | * The functions `evenp` or `oddp` can be used to determine if a number is even or odd. 6 | * The function `append` can be used to add an item to the beginning of a list. 7 | * The functions `car` and `cdr` are useful to get the first or second item of a pair. 8 | 9 | ## 2. Categorizing lots of numbers 10 | 11 | * `reduce`'s first parameter is a function which takes two arguments - the current accumulated value and the item to process. 12 | * `reduce` takes an `:initial-value` parameter, the value of which will be the first accumulated value passed to the function. 13 | -------------------------------------------------------------------------------- /exercises/concept/logans-numeric-partition/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:reducing} -------------------------------------------------------------------------------- /exercises/concept/logans-numeric-partition/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "logans-numeric-partition.lisp" 8 | ], 9 | "test": [ 10 | "logans-numeric-partition-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Help Logan partition numbers into evens and odds by using reduce." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/logans-numeric-partition/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :logans-numeric-partition 2 | (:use :cl) 3 | (:export :categorize-number :partition-numbers)) 4 | 5 | (in-package :logans-numeric-partition) 6 | 7 | (defun categorize-number (acc n) 8 | (if (oddp n) 9 | (cons (append (list n) (car acc)) (cdr acc)) 10 | (cons (car acc) (append (list n) (cdr acc))))) 11 | 12 | (defun partition-numbers (numbers) 13 | (reduce #'categorize-number numbers :initial-value '(() . ()))) 14 | -------------------------------------------------------------------------------- /exercises/concept/logans-numeric-partition/logans-numeric-partition.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :logans-numeric-partition 2 | (:use :cl) 3 | (:export :categorize-number :partition-numbers)) 4 | 5 | (in-package :logans-numeric-partition) 6 | 7 | ;; Define categorize-number function 8 | 9 | ;; Define partition-numbers function 10 | -------------------------------------------------------------------------------- /exercises/concept/lucys-magnificent-mapper/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # Hints 2 | 3 | ## 1. Make magnificent 4 | 5 | - Mapping is correct process to apply a function to every element of a sequence. 6 | - `mapcar` is a good function to use to map a function across a list. 7 | 8 | ## 2. Only the best 9 | 10 | - Filtering is the correct process to remove one or more items from a sequence, resulting in a new sequence. 11 | - `remove` can remove values from a sequence which are equal to a specific item. 12 | - `remove-if` can remove values for which a predicate function evaluates to a true value. 13 | -------------------------------------------------------------------------------- /exercises/concept/lucys-magnificent-mapper/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:mapping} 4 | 5 | %{concept:filtering} -------------------------------------------------------------------------------- /exercises/concept/lucys-magnificent-mapper/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "lucys-magnificent-mapper.lisp" 8 | ], 9 | "test": [ 10 | "lucys-magnificent-mapper-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "icon": "numbers", 17 | "blurb": "Help Lucy try to make numbers more magnificent and keep only those that are." 18 | } 19 | -------------------------------------------------------------------------------- /exercises/concept/lucys-magnificent-mapper/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :lucys-magnificent-mapper 2 | (:use :cl) 3 | (:export :make-magnificent-maybe :only-the-best)) 4 | 5 | (in-package :lucys-magnificent-mapper) 6 | 7 | (defun make-magnificent-maybe (fn list) 8 | (mapcar fn list)) 9 | 10 | (defun only-the-best (fn list) 11 | (remove-if fn (remove 1 list))) 12 | -------------------------------------------------------------------------------- /exercises/concept/lucys-magnificent-mapper/lucys-magnificent-mapper.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :lucys-magnificent-mapper 2 | (:use :cl) 3 | (:export :make-magnificent-maybe :only-the-best)) 4 | 5 | (in-package :lucys-magnificent-mapper) 6 | 7 | ;; Define make-magnificent-maybe function 8 | 9 | ;; Define only-the-best function 10 | -------------------------------------------------------------------------------- /exercises/concept/pal-picker/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:truthy-and-falsy} 4 | 5 | %{concept:conditionals} 6 | -------------------------------------------------------------------------------- /exercises/concept/pal-picker/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "TheLostLambda" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pal-picker.lisp" 8 | ], 9 | "test": [ 10 | "pal-picker-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "blurb": "Learn about conditionals and truth and falseness by helping to choose and take care of a pet." 17 | } 18 | -------------------------------------------------------------------------------- /exercises/concept/pal-picker/pal-picker.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pal-picker 2 | (:use :cl) 3 | (:export :pal-picker :habitat-fitter :feeding-time-p 4 | :pet :play-fetch)) 5 | 6 | (in-package :pal-picker) 7 | 8 | (defun pal-picker (personality)) 9 | 10 | (defun habitat-fitter (weight)) 11 | 12 | (defun feeding-time-p (fullness)) 13 | 14 | (defun pet (pet)) 15 | 16 | (defun play-fetch (pet)) 17 | -------------------------------------------------------------------------------- /exercises/concept/pizza-pi/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In Common Lisp, like many languages, numbers come in a few of types – two of the most basic are: 4 | 5 | %{concept:integers} 6 | 7 | %{concept:floating-point-numbers} 8 | 9 | %{concept:arithmetic} 10 | 11 | -------------------------------------------------------------------------------- /exercises/concept/pizza-pi/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "TheLostLambda", 4 | "verdammelt" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "pizza-pi.lisp" 9 | ], 10 | "test": [ 11 | "pizza-pi-test.lisp" 12 | ], 13 | "exemplar": [ 14 | ".meta/exemplar.lisp" 15 | ] 16 | }, 17 | "icon": "lasagna", 18 | "blurb": "Learn about arithmetic with integers and floating-point numbers by helping to make pizza." 19 | } 20 | -------------------------------------------------------------------------------- /exercises/concept/pizza-pi/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pizza-pi 2 | (:use :cl) 3 | (:export :dough-calculator :pizzas-per-cube 4 | :size-from-sauce :fair-share-p)) 5 | 6 | (in-package :pizza-pi) 7 | 8 | (defun dough-calculator (pizzas diameter) 9 | (round (* pizzas (+ (/ (* 45 pi diameter) 20) 200)))) 10 | 11 | (defun size-from-sauce (sauce) 12 | (sqrt (/ (* 40 sauce) (* 3 pi)))) 13 | 14 | (defun pizzas-per-cube (cube-size diameter) 15 | (floor (/ (* 2 (expt cube-size 3)) (* 3 pi (expt diameter 2))))) 16 | 17 | (defun fair-share-p (pizzas friends) 18 | (= 0 (mod (* pizzas 8) friends))) 19 | -------------------------------------------------------------------------------- /exercises/concept/pizza-pi/pizza-pi.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pizza-pi 2 | (:use :cl) 3 | (:export :dough-calculator :pizzas-per-cube 4 | :size-from-sauce :fair-share-p)) 5 | 6 | (in-package :pizza-pi) 7 | 8 | (defun dough-calculator (pizzas diameter)) 9 | 10 | (defun size-from-sauce (sauce)) 11 | 12 | (defun pizzas-per-cube (cube-size diameter)) 13 | 14 | (defun fair-share-p (pizzas friends)) 15 | -------------------------------------------------------------------------------- /exercises/concept/reporting-for-duty/.docs/hints.md: -------------------------------------------------------------------------------- 1 | # Hints 2 | 3 | - The `format` function will be needed for this exercise. 4 | 5 | ## 1. Formatting quarterly values 6 | 7 | - `format` always returns `nil` unless the stream parameter is `nil`. 8 | - `~A` can be used to format a value. 9 | 10 | ## 2. The Two-Quarter report 11 | 12 | - Your previous function is perfect to create the two lines needed. 13 | - `~%` and `~&` can be used to create newlines. 14 | 15 | ## 3. Human vs. Lisp Alien readable 16 | 17 | - Your previous quarter formatting function is perfect to create the needed strings. 18 | - `~S` can be used to format values in a readable form. 19 | -------------------------------------------------------------------------------- /exercises/concept/reporting-for-duty/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:format-basics} 4 | -------------------------------------------------------------------------------- /exercises/concept/reporting-for-duty/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "reporting-for-duty.lisp" 8 | ], 9 | "test": [ 10 | "reporting-for-duty-test.lisp" 11 | ], 12 | "exemplar": [ 13 | ".meta/exemplar.lisp" 14 | ] 15 | }, 16 | "icon": "high-scores", 17 | "blurb": "Help Layla produce short reports" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/concept/reporting-for-duty/.meta/exemplar.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :reporting-for-duty 2 | (:use :cl) 3 | (:export :format-quarter-value :format-two-quarters 4 | :format-two-quarters-for-reading)) 5 | 6 | (in-package :reporting-for-duty) 7 | 8 | (defun format-quarter-value (quarter value) 9 | (format nil "The value ~A quarter: ~A" quarter value)) 10 | 11 | (defun format-two-quarters (stream quarter1 value1 quarter2 value2) 12 | (format stream "~%~A~&~A~&" 13 | (format-quarter-value quarter1 value1) 14 | (format-quarter-value quarter2 value2))) 15 | 16 | (defun format-two-quarters-for-reading (stream quarter1 value1 quarter2 value2) 17 | (format stream "(~S ~S)" 18 | (format-quarter-value quarter1 value1) 19 | (format-quarter-value quarter2 value2))) 20 | -------------------------------------------------------------------------------- /exercises/concept/reporting-for-duty/reporting-for-duty.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :reporting-for-duty 2 | (:use :cl) 3 | (:export :format-quarter-value :format-two-quarters 4 | :format-two-quarters-for-reading)) 5 | 6 | (in-package :reporting-for-duty) 7 | 8 | ;; Define format-quarter-value function. 9 | 10 | ;; Define format-two-quarters function. 11 | 12 | ;; Define format-two-quarters-for-reading function. 13 | -------------------------------------------------------------------------------- /exercises/concept/socks-and-sexprs/.docs/introduction.md.tpl: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | %{concept:comments} 4 | 5 | %{concept:cons} 6 | 7 | %{concept:expressions} 8 | 9 | %{concept:symbols} 10 | -------------------------------------------------------------------------------- /exercises/concept/socks-and-sexprs/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt", 4 | "TheLostLambda" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "socks-and-sexprs.lisp" 9 | ], 10 | "test": [ 11 | "socks-and-sexprs-test.lisp" 12 | ], 13 | "exemplar": [ 14 | ".meta/exemplar.lisp" 15 | ] 16 | }, 17 | "blurb": "Learn the basics of Common Lisp by helping your friend clean their room so they can go out and have some fun." 18 | } 19 | -------------------------------------------------------------------------------- /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 | "serialhex" 4 | ], 5 | "contributors": [ 6 | "daveyarwood", 7 | "dnmfarrell", 8 | "BNAndras" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "acronym.lisp" 13 | ], 14 | "test": [ 15 | "acronym-test.lisp" 16 | ], 17 | "example": [ 18 | ".meta/example.lisp" 19 | ] 20 | }, 21 | "blurb": "Convert a long phrase to its acronym.", 22 | "source": "Julien Vanier", 23 | "source_url": "https://github.com/monkbroc" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :acronym 2 | (:use :cl) 3 | (:export :acronym)) 4 | 5 | (in-package :acronym) 6 | 7 | (defun acronym (phrase) 8 | (let ((chars ()) 9 | (inside-word nil)) 10 | (loop for char across phrase 11 | do (cond 12 | ((eql char #\') 13 | nil) 14 | ((and (alpha-char-p char) (not inside-word)) 15 | (push (char-upcase char) chars) 16 | (setf inside-word t)) 17 | ((not (alpha-char-p char)) 18 | (setf inside-word nil)))) 19 | (format nil "~{~A~}" (reverse chars)))) -------------------------------------------------------------------------------- /exercises/practice/acronym/acronym.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :acronym 2 | (:use :cl) 3 | (:export :acronym)) 4 | 5 | (in-package :acronym) 6 | 7 | (defun acronym (phrase)) 8 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "affine-cipher.lisp" 8 | ], 9 | "test": [ 10 | "affine-cipher-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :affine-cipher 2 | (:use :cl) 3 | (:export :encode 4 | :decode)) 5 | 6 | (in-package :affine-cipher) 7 | 8 | (defun encode (plaintext a b)) 9 | 10 | (defun decode (ciphertext a b)) 11 | -------------------------------------------------------------------------------- /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 | "serialhex" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "all-your-base.lisp" 8 | ], 9 | "test": [ 10 | "all-your-base-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/all-your-base.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :all-your-base 2 | (:use :cl) 3 | (:export :rebase)) 4 | 5 | (in-package :all-your-base) 6 | 7 | (defun rebase (list-digits in-base out-base)) 8 | -------------------------------------------------------------------------------- /exercises/practice/allergies/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "allergies.lisp" 11 | ], 12 | "test": [ 13 | "allergies-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", 20 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 21 | "source_url": "https://turing.edu" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/allergies/allergies.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :allergies 2 | (:use :cl) 3 | (:shadow :list) 4 | (:export :allergic-to-p :list)) 5 | 6 | (in-package :allergies) 7 | 8 | (defun allergic-to-p (score allergen) 9 | "Returns true if given allergy score includes given allergen." 10 | ) 11 | 12 | (defun list (score) 13 | "Returns a list of allergens for a given allergy score." 14 | ) 15 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell", 7 | "spacebat" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "anagram.lisp" 12 | ], 13 | "test": [ 14 | "anagram-test.lisp" 15 | ], 16 | "example": [ 17 | ".meta/example.lisp" 18 | ] 19 | }, 20 | "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", 21 | "source": "Inspired by the Extreme Startup game", 22 | "source_url": "https://github.com/rchatley/extreme_startup" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :anagram 2 | (:use :common-lisp) 3 | (:export :anagrams-for)) 4 | 5 | (in-package :anagram) 6 | 7 | (defun anagram-equal (a b) 8 | (and 9 | (string-equal (sort (copy-seq a) #'char-lessp) 10 | (sort (copy-seq b) #'char-lessp)) 11 | (string-not-equal a b))) 12 | 13 | (defun anagrams-for (subject candidates) 14 | (remove-if-not 15 | #'(lambda (w) (anagram-equal w subject)) 16 | candidates)) 17 | -------------------------------------------------------------------------------- /exercises/practice/anagram/anagram.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :anagram 2 | (:use :cl) 3 | (:export :anagrams-for)) 4 | 5 | (in-package :anagram) 6 | 7 | (defun anagrams-for (subject candidates) 8 | "Returns a sublist of candidates which are anagrams of the subject." 9 | ) 10 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "armstrong-numbers.lisp" 8 | ], 9 | "test": [ 10 | "armstrong-numbers-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | (defpackage :armstrong-numbers 3 | (:use :cl) 4 | (:export :armstrong-number-p)) 5 | (in-package :armstrong-numbers) 6 | 7 | (defun number->digits (number) 8 | (map 'list #'digit-char-p (prin1-to-string number))) 9 | 10 | (defun sum (numbers) (reduce #'+ numbers)) 11 | 12 | (defun armstrong-number-p (number) 13 | (let ((digits (number->digits number))) 14 | (= number 15 | (sum (mapcar #'(lambda (x) (expt x (length digits))) 16 | digits))))) 17 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/armstrong-numbers.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :armstrong-numbers 2 | (:use :cl) 3 | (:export :armstrong-number-p)) 4 | (in-package :armstrong-numbers) 5 | 6 | (defun armstrong-number-p (number)) 7 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt", 4 | "PaulT89" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "atbash-cipher.lisp" 9 | ], 10 | "test": [ 11 | "atbash-cipher-test.lisp" 12 | ], 13 | "example": [ 14 | ".meta/example.lisp" 15 | ] 16 | }, 17 | "blurb": "Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Atbash" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/atbash-cipher.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :atbash-cipher 2 | (:use :cl) 3 | (:export :encode :decode)) 4 | 5 | (in-package :atbash-cipher) 6 | 7 | (defun encode (plaintext)) 8 | 9 | (defun decode (ciphertext)) 10 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "beer-song.lisp" 11 | ], 12 | "test": [ 13 | "beer-song-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.", 20 | "source": "Learn to Program by Chris Pine", 21 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/beer-song/beer-song.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :beer-song 2 | (:use :cl) 3 | (:export :verse :sing)) 4 | 5 | (in-package :beer-song) 6 | (defun verse (n) 7 | "Returns a string verse for a given number." 8 | ) 9 | 10 | (defun sing (start &optional (end 0)) 11 | "Returns a string of verses for a given range of numbers." 12 | ) 13 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wsgac" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary-search.lisp" 8 | ], 9 | "test": [ 10 | "binary-search-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | (defpackage :binary-search 3 | (:use :common-lisp) 4 | (:export :binary-find :value-error)) 5 | 6 | (in-package :binary-search) 7 | 8 | (defun binary-find (arr el) 9 | (loop 10 | with low = 0 11 | with high = (1- (length arr)) 12 | for mid = (truncate (+ low high) 2) 13 | while (<= low high) do 14 | (cond 15 | ((> (aref arr mid) el) 16 | (setf high (1- mid))) 17 | ((< (aref arr mid) el) 18 | (setf low (1+ mid))) 19 | (t (return mid))) 20 | finally (return nil))) 21 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/binary-search.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :binary-search 2 | (:use :cl) 3 | (:export :binary-find :value-error)) 4 | 5 | (in-package :binary-search) 6 | 7 | (defun binary-find (arr el) 8 | ) 9 | -------------------------------------------------------------------------------- /exercises/practice/binary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary.lisp" 8 | ], 9 | "test": [ 10 | "binary-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.", 17 | "source": "All of Computer Science", 18 | "source_url": "http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/binary/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :binary 2 | (:use :common-lisp) 3 | (:export :to-decimal)) 4 | 5 | (in-package :binary) 6 | 7 | (defun to-decimal (string) 8 | (loop with digits = (remove-if #'null (map 'list #'(lambda (c) (digit-char-p c 2)) string)) 9 | for idx below (length digits) and digit in (reverse digits) 10 | summing (* digit (expt 2 idx)))) 11 | -------------------------------------------------------------------------------- /exercises/practice/binary/binary.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :binary 2 | (:use :cl) 3 | (:export :to-decimal)) 4 | 5 | (in-package :binary) 6 | 7 | (defun to-decimal (input) 8 | ) 9 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "austinlyons" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "bob.lisp" 11 | ], 12 | "test": [ 13 | "bob-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 20 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 21 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/bob/bob.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :bob 2 | (:use :cl) 3 | (:export :response)) 4 | (in-package :bob) 5 | 6 | (defun response (hey-bob)) 7 | -------------------------------------------------------------------------------- /exercises/practice/book-store/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "book-store.lisp" 11 | ], 12 | "test": [ 13 | "book-store-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "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.", 20 | "source": "Inspired by the harry potter kata from Cyber-Dojo.", 21 | "source_url": "https://cyber-dojo.org" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/book-store/book-store.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :book-store 2 | (:use :cl) 3 | (:export :calculate-price)) 4 | 5 | (in-package :book-store) 6 | 7 | (defun calculate-price (basket)) 8 | -------------------------------------------------------------------------------- /exercises/practice/bottle-song/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "bottle-song.lisp" 8 | ], 9 | "test": [ 10 | "bottle-song-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :bottle-song 2 | (:use :common-lisp) 3 | (:export :recite)) 4 | 5 | (in-package :bottle-song) 6 | 7 | 8 | (defun recite (start-bottles take-down) 9 | "Returns the song verses from START-BOTTLES down to (- START-BOTTLES TAKE-DOWN)." 10 | ) 11 | -------------------------------------------------------------------------------- /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 | "Average-user" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "collatz-conjecture.lisp" 8 | ], 9 | "test": [ 10 | "collatz-conjecture-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :collatz-conjecture 2 | (:use :common-lisp) 3 | (:export :collatz)) 4 | 5 | (in-package :collatz-conjecture) 6 | 7 | (defun collatz-helper (a n) 8 | (cond ((= n 1) a) 9 | ((evenp n) (collatz-helper (+ 1 a) (floor n 2))) 10 | (T (collatz-helper (+ 1 a) (+ 1 (* 3 n)))))) 11 | 12 | (defun collatz (n) 13 | (when (> n 0) 14 | (collatz-helper 0 n))) 15 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :collatz-conjecture 2 | (:use :cl) 3 | (:export :collatz)) 4 | 5 | (in-package :collatz-conjecture) 6 | 7 | (defun collatz (n)) 8 | -------------------------------------------------------------------------------- /exercises/practice/crypto-square/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "crypto-square.lisp" 8 | ], 9 | "test": [ 10 | "crypto-square-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :crypto-square 2 | (:use :cl) 3 | (:export :encipher)) 4 | (in-package :crypto-square) 5 | 6 | (defun encipher (plaintext)) 7 | -------------------------------------------------------------------------------- /exercises/practice/darts/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "darts.lisp" 8 | ], 9 | "test": [ 10 | "darts-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :darts 2 | (:use :cl) 3 | (:export :score)) 4 | 5 | (in-package :darts) 6 | 7 | (defun score (x y) 8 | (let ((distance (sqrt (+ (* x x) (* y y))))) 9 | (cond 10 | ((> distance 10) 0) 11 | ((> distance 5) 1) 12 | ((> distance 1) 5) 13 | (t 10)))) 14 | -------------------------------------------------------------------------------- /exercises/practice/darts/darts.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :darts 2 | (:use :cl) 3 | (:export :score)) 4 | 5 | (in-package :darts) 6 | 7 | (defun score (x y)) 8 | -------------------------------------------------------------------------------- /exercises/practice/diamond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "diamond.lisp" 8 | ], 9 | "test": [ 10 | "diamond-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :diamond 2 | (:use :cl) 3 | (:export :rows)) 4 | 5 | (in-package :diamond) 6 | 7 | (defparameter +alphabet+ (coerce "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 'list)) 8 | 9 | (defun rows (letter) 10 | (let* ((letters (subseq +alphabet+ 0 (1+ (position letter +alphabet+)))) 11 | (columns (1- (* 2 (length letters)))) 12 | (unique-rows (loop for c in letters and idx from 0 13 | collect (let ((mid-space (abs (1- (* 2 idx))))) 14 | (format nil "~v:@<~,,v,A~:*~A~>" columns mid-space c))))) 15 | (rplaca unique-rows (format nil "~v:@" columns)) 16 | (append unique-rows (reverse (butlast unique-rows))))) 17 | -------------------------------------------------------------------------------- /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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :diamond 2 | (:use :cl) 3 | (:export :rows)) 4 | 5 | (in-package :diamond) 6 | 7 | (defun rows (letter)) 8 | -------------------------------------------------------------------------------- /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 | "wobh" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell", 7 | "Scientifica96" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "difference-of-squares.lisp" 12 | ], 13 | "test": [ 14 | "difference-of-squares-test.lisp" 15 | ], 16 | "example": [ 17 | ".meta/example.lisp" 18 | ] 19 | }, 20 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 21 | "source": "Problem 6 at Project Euler", 22 | "source_url": "https://projecteuler.net/problem=6" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :difference-of-squares 2 | (:use :cl) 3 | (:export :sum-of-squares 4 | :square-of-sum 5 | :difference)) 6 | 7 | (in-package :difference-of-squares) 8 | 9 | (defun square-of-sum (n) 10 | (expt (* 1/2 n (1+ n)) 2)) 11 | 12 | (defun sum-of-squares (n) 13 | (* 1/6 n (1+ n) (1+ (* 2 n)))) 14 | 15 | (defun difference (n) 16 | (- (square-of-sum n) 17 | (sum-of-squares n))) 18 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :difference-of-squares 2 | (:use :cl) 3 | (:export :sum-of-squares 4 | :square-of-sum 5 | :difference)) 6 | 7 | (in-package :difference-of-squares) 8 | 9 | (defun square-of-sum (n) 10 | "Calculates the square of the sum for a given number." 11 | ) 12 | 13 | (defun sum-of-squares (n) 14 | "Calculates the sum of squares for a given number." 15 | ) 16 | 17 | (defun difference (n) 18 | "Finds the diff. between the square of the sum and the sum of the squares." 19 | ) 20 | -------------------------------------------------------------------------------- /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 | "kahgoh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "eliuds-eggs.lisp" 8 | ], 9 | "test": [ 10 | "eliuds-eggs-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :eliuds-eggs 2 | (:use :cl) 3 | (:export :egg-count)) 4 | 5 | (in-package :eliuds-eggs) 6 | 7 | (defun do-egg-count (number &optional (acc 0)) 8 | (if (= number 0) 9 | acc 10 | (multiple-value-bind (quot rem) (floor number 2) 11 | (do-egg-count quot (+ acc rem))))) 12 | 13 | (defun egg-count (number) 14 | (do-egg-count number)) 15 | -------------------------------------------------------------------------------- /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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :eliuds-eggs 2 | (:use :cl) 3 | (:export :egg-count)) 4 | 5 | (in-package :eliuds-eggs) 6 | 7 | (defun egg-count (number)) 8 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "etl.lisp" 11 | ], 12 | "test": [ 13 | "etl-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Change the data format for scoring a game to more easily add other languages.", 20 | "source": "Based on an exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 21 | "source_url": "https://turing.edu" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/etl/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :etl 2 | (:use :common-lisp) 3 | (:export :transform)) 4 | 5 | (in-package :etl) 6 | 7 | (defun transform (data) 8 | (let ((old-kvs (loop 9 | for k being each hash-keys in data 10 | for v being each hash-values in data 11 | collecting (list k v)))) 12 | (reduce 13 | #'(lambda (h kv) 14 | (loop 15 | for v in (second kv) 16 | with k = (first kv) 17 | do (setf (gethash (char-downcase v) h) k) 18 | finally (return h))) 19 | old-kvs 20 | :initial-value (make-hash-table :test (hash-table-test data))))) 21 | -------------------------------------------------------------------------------- /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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :etl 2 | (:use :cl) 3 | (:export :transform)) 4 | 5 | (in-package :etl) 6 | 7 | (defun transform (data) 8 | "Transforms hash values into keys with their keys as their values." 9 | ) 10 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Take a nested array of any depth and return a fully flattened array. 4 | 5 | Note that some language tracks may include null-like values in the input array, and the way these values are represented varies by track. 6 | Such values should be excluded from the flattened array. 7 | 8 | Additionally, the input may be of a different data type and contain different types, depending on the track. 9 | 10 | Check the test suite for details. 11 | 12 | ## Example 13 | 14 | input: `[1, [2, 6, null], [[null, [4]], 5]]` 15 | 16 | output: `[1, 2, 6, 4, 5]` 17 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A shipment of emergency supplies has arrived, but there's a problem. 4 | To protect from damage, the items — flashlights, first-aid kits, blankets — are packed inside boxes, and some of those boxes are nested several layers deep inside other boxes! 5 | 6 | To be prepared for an emergency, everything must be easily accessible in one box. 7 | Can you unpack all the supplies and place them into a single box, so they're ready when needed most? 8 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89", 4 | "verdammelt" 5 | ], 6 | "files": { 7 | "solution": [ 8 | "flatten-array.lisp" 9 | ], 10 | "test": [ 11 | "flatten-array-test.lisp" 12 | ], 13 | "example": [ 14 | ".meta/example.lisp" 15 | ] 16 | }, 17 | "blurb": "Take a nested list and return a single list with all values except nil/null.", 18 | "source": "Interview Question", 19 | "source_url": "https://reference.wolfram.com/language/ref/Flatten.html" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :flatten-array 2 | (:use :cl) 3 | (:export :flatten)) 4 | 5 | (in-package :flatten-array) 6 | 7 | (defun flatten (nested) 8 | (remove nil 9 | (reduce #'(lambda (acc item) 10 | (append acc (if (atom item) (list item) (flatten item)))) 11 | nested :initial-value (list)))) 12 | -------------------------------------------------------------------------------- /exercises/practice/flatten-array/flatten-array.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :flatten-array 2 | (:use :cl) 3 | (:export :flatten)) 4 | 5 | (in-package :flatten-array) 6 | 7 | (defun flatten (nested)) 8 | -------------------------------------------------------------------------------- /exercises/practice/food-chain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "food-chain.lisp" 8 | ], 9 | "test": [ 10 | "food-chain-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :food-chain 2 | (:use :cl) 3 | (:export :recite)) 4 | 5 | (in-package :food-chain) 6 | 7 | (defun recite (start-verse end-verse)) 8 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a moment, determine the moment that would be after a gigasecond has passed. 4 | 5 | A gigasecond is 10^9 (1,000,000,000) seconds. 6 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "TatriX" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "gigasecond.lisp" 11 | ], 12 | "test": [ 13 | "gigasecond-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", 20 | "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", 21 | "source_url": "http://pine.fm/LearnToProgram/?Chapter=09" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:gigasecond 2 | (:use #:cl) 3 | (:export #:from)) 4 | 5 | (in-package #:gigasecond) 6 | 7 | (defun from (year month day hour minute second) 8 | (reverse 9 | (subseq 10 | (multiple-value-list 11 | (let ((TZ 0)) 12 | (decode-universal-time 13 | (+ (encode-universal-time second minute hour day month year TZ) 14 | (expt 10 9)) 15 | TZ))) 16 | 0 6))) 17 | -------------------------------------------------------------------------------- /exercises/practice/gigasecond/gigasecond.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :gigasecond 2 | (:use :cl) 3 | (:export :from)) 4 | (in-package :gigasecond) 5 | 6 | (defun from (year month day hour minute second)) 7 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "wobh" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "grade-school.lisp" 11 | ], 12 | "test": [ 13 | "grade-school-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given students' names along with the grade that they are in, create a roster for the school.", 20 | "source": "A pairing session with Phil Battos at gSchool" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/grade-school/grade-school.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :grade-school 2 | (:use :cl) 3 | (:export :make-school :add :roster :grade)) 4 | 5 | (in-package :grade-school) 6 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "grains.lisp" 8 | ], 9 | "test": [ 10 | "grains-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :grains 2 | (:use :cl) 3 | (:export :square :total)) 4 | 5 | (in-package :grains) 6 | 7 | (defun square (n) (expt 2 (1- n))) 8 | 9 | (defun total () 10 | (loop for n from 1 to 64 summing (square n))) 11 | -------------------------------------------------------------------------------- /exercises/practice/grains/grains.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :grains 2 | (:use :cl) 3 | (:export :square :total)) 4 | (in-package :grains) 5 | 6 | (defun square (n) ) 7 | 8 | (defun total () ) 9 | -------------------------------------------------------------------------------- /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 | "wobh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "hamming.lisp" 8 | ], 9 | "test": [ 10 | "hamming-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :hamming 2 | (:use :common-lisp) 3 | (:export :distance)) 4 | 5 | (in-package :hamming) 6 | 7 | (defun distance (str1 str2 &key (test #'char=)) 8 | "Number of positional differences in two equal length strings." 9 | (when (= (length str1) (length str2)) 10 | (count nil 11 | (map 'list test str1 str2)))) 12 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :hamming 2 | (:use :cl) 3 | (:export :distance)) 4 | 5 | (in-package :hamming) 6 | 7 | (defun distance (strand1 strand2)) 8 | -------------------------------------------------------------------------------- /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 | "serialhex" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "hello-world.lisp" 11 | ], 12 | "test": [ 13 | "hello-world-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", 20 | "source": "This is an exercise to introduce users to using Exercism", 21 | "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :hello-world 2 | (:use :cl) 3 | (:export :hello)) 4 | 5 | (in-package :hello-world) 6 | 7 | (defun hello () "Hello, World!") 8 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.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 | [af9ffe10-dc13-42d8-a742-e7bdafac449d] 6 | description = "Say Hi!" 7 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :hello-world 2 | (:use :cl) 3 | (:export :hello)) 4 | 5 | (in-package :hello-world) 6 | 7 | (defun hello () "Goodbye, Mars!") 8 | -------------------------------------------------------------------------------- /exercises/practice/house/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "house.lisp" 8 | ], 9 | "test": [ 10 | "house-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Output the nursery rhyme 'This is the House that Jack Built'.", 17 | "source": "British nursery rhyme", 18 | "source_url": "https://en.wikipedia.org/wiki/This_Is_The_House_That_Jack_Built" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/house/house.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :house 2 | (:use :cl) 3 | (:export :recite)) 4 | 5 | (in-package :house) 6 | 7 | (defun recite (start-verse end-verse)) 8 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isbn-verifier.lisp" 8 | ], 9 | "test": [ 10 | "isbn-verifier-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Check if a given string is a valid ISBN-10 number.", 17 | "source": "Converting a string into a number and some basic processing utilizing a relatable real world example.", 18 | "source_url": "https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_check_digit_calculation" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :isbn-verifier 2 | (:use :cl) 3 | (:export :validp)) 4 | 5 | (in-package :isbn-verifier) 6 | 7 | (defun char-to-num (input-char) 8 | (if (char= #\X input-char) 10 (digit-char-p input-char))) 9 | 10 | (defun validp (isbn) 11 | (let ((cleaned (remove-if-not #'alphanumericp isbn))) 12 | (when (= 10 (length cleaned)) ; Check isbn is 10 chars long 13 | (let ((num-list (map 'list #'char-to-num cleaned))) ; Map chars to numbers (or nil) 14 | ; Return nil if any nils in num-list or if any of the first 9 nums eql 10 15 | (unless (or (some #'null num-list) (member 10 (butlast num-list))) 16 | (zerop (mod (apply #'+ (mapcar #'* num-list '(10 9 8 7 6 5 4 3 2 1))) 11))))))) 17 | -------------------------------------------------------------------------------- /exercises/practice/isbn-verifier/isbn-verifier.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :isbn-verifier 2 | (:use :cl) 3 | (:export :validp)) 4 | 5 | (in-package :isbn-verifier) 6 | 7 | (defun validp (isbn)) 8 | -------------------------------------------------------------------------------- /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 | "Average-user" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "isogram.lisp" 8 | ], 9 | "test": [ 10 | "isogram-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :isogram 2 | (:use :common-lisp) 3 | (:export :isogram-p)) 4 | 5 | (in-package :isogram) 6 | 7 | (defun isogram-p (xs) 8 | (let ((chars-only (remove-if-not #'alpha-char-p xs))) 9 | (string-equal chars-only 10 | (remove-duplicates chars-only :test #'char-equal)))) 11 | -------------------------------------------------------------------------------- /exercises/practice/isogram/isogram.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :isogram 2 | (:use :cl) 3 | (:export :isogram-p)) 4 | 5 | (in-package :isogram) 6 | 7 | (defun isogram-p (string) 8 | "Is string an Isogram?") 9 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "knapsack.lisp" 11 | ], 12 | "test": [ 13 | "knapsack-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "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.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Knapsack_problem" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/knapsack.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :knapsack 2 | (:use :cl) 3 | (:export :maximum-value)) 4 | 5 | (in-package :knapsack) 6 | 7 | (defun maximum-value (maximum-weight items)) 8 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "largest-series-product.lisp" 8 | ], 9 | "test": [ 10 | "largest-series-product-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :largest-series-product 2 | (:use :cl) 3 | (:export :largest-product)) 4 | 5 | (in-package :largest-series-product) 6 | 7 | (defun windows (seq span) 8 | (loop for start from 0 to (- (length seq) span) 9 | collect (subseq seq start (+ start span)))) 10 | 11 | (defun string-to-product (seq) 12 | (apply #'* (map 'list #'digit-char-p seq))) 13 | 14 | (defun valid-input-p (digits span) 15 | (and (every #'digit-char-p digits) 16 | (not (minusp span)) 17 | (>= (length digits) span))) 18 | 19 | (defun largest-product (digits span) 20 | (when (valid-input-p digits span) 21 | (if (zerop span) 22 | 1 23 | (apply #'max (mapcar #'string-to-product (windows digits span)))))) 24 | -------------------------------------------------------------------------------- /exercises/practice/largest-series-product/largest-series-product.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :largest-series-product 2 | (:use :cl) 3 | (:export :largest-product)) 4 | 5 | (in-package :largest-series-product) 6 | 7 | (defun largest-product (digits span)) 8 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "leap.lisp" 8 | ], 9 | "test": [ 10 | "leap-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (cl:defpackage :leap 2 | (:use :common-lisp) 3 | (:export :leap-year-p)) 4 | 5 | (in-package :leap) 6 | 7 | (defun divisible-by-p (n d) (= 0 (rem n d))) 8 | 9 | (defun leap-year-p (year) 10 | (and (divisible-by-p year 4) 11 | (or (not (divisible-by-p year 100)) 12 | (divisible-by-p year 400)))) 13 | -------------------------------------------------------------------------------- /exercises/practice/leap/leap.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :leap 2 | (:use :cl) 3 | (:export :leap-year-p)) 4 | 5 | (in-package :leap) 6 | 7 | (defun leap-year-p (year)) 8 | -------------------------------------------------------------------------------- /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 | "serialhex" 4 | ], 5 | "contributors": [ 6 | "chuchana", 7 | "wobh" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "luhn.lisp" 12 | ], 13 | "test": [ 14 | "luhn-test.lisp" 15 | ], 16 | "example": [ 17 | ".meta/example.lisp" 18 | ] 19 | }, 20 | "blurb": "Given a number determine whether or not it is valid per the Luhn formula.", 21 | "source": "The Luhn Algorithm on Wikipedia", 22 | "source_url": "https://en.wikipedia.org/wiki/Luhn_algorithm" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/luhn/luhn.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :luhn 2 | (:use :cl) 3 | (:export :validp)) 4 | 5 | (in-package :luhn) 6 | 7 | (defun validp (input)) 8 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. 4 | Any other characters should be ignored. 5 | For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. 6 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. 4 | The software that runs on it is written in a proprietary language. 5 | Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. 6 | Despite the Bracketeer™ being powerful, it lacks flexibility. 7 | If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. 8 | To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. 9 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "matching-brackets.lisp" 11 | ], 12 | "test": [ 13 | "matching-brackets-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Make sure the brackets and braces all match.", 20 | "source": "Ginna Baker" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :matching-brackets 2 | (:use :cl) 3 | (:export :pairedp)) 4 | 5 | (in-package :matching-brackets) 6 | 7 | (defparameter +bracket-lookup+ '((#\( . #\)) (#\{ . #\}) (#\[ . #\]))) 8 | 9 | (defun eliminate-pairs (tracker bracket) 10 | (let ((match (rassoc bracket +bracket-lookup+))) 11 | (if (and tracker match (char= (car match) (car tracker))) 12 | (cdr tracker) 13 | (cons bracket tracker)))) 14 | 15 | (defun pairedp (value) 16 | (let* ((bracket-list (append (mapcar #'car +bracket-lookup+) (mapcar #'cdr +bracket-lookup+))) 17 | (only-brackets (remove-if-not (lambda (c) (find c bracket-list)) value))) 18 | (zerop (length (reduce #'eliminate-pairs only-brackets :initial-value '()))))) 19 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/matching-brackets.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :matching-brackets 2 | (:use :cl) 3 | (:export :pairedp)) 4 | 5 | (in-package :matching-brackets) 6 | 7 | (defun pairedp (value)) 8 | -------------------------------------------------------------------------------- /exercises/practice/matrix/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "matrix.lisp" 11 | ], 12 | "test": [ 13 | "matrix-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a string representing a matrix of numbers, return the rows and columns of that matrix.", 20 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 21 | "source_url": "https://turing.edu" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/matrix/matrix.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :matrix 2 | (:use :cl) 3 | (:export :row 4 | :column)) 5 | 6 | (in-package :matrix) 7 | 8 | (defun row (input-matrix index)) 9 | 10 | (defun column (input-matrix index)) 11 | -------------------------------------------------------------------------------- /exercises/practice/meetup/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "meetup.lisp" 11 | ], 12 | "test": [ 13 | "meetup-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Calculate the date of meetups.", 20 | "source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month" 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/meetup/meetup.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :meetup 2 | (:use :cl) 3 | (:export :meetup)) 4 | 5 | (in-package :meetup) 6 | 7 | (defun meetup (month year dayofweek week)) 8 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "nth-prime.lisp" 8 | ], 9 | "test": [ 10 | "nth-prime-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :nth-prime 2 | (:use :cl) 3 | (:export :find-prime)) 4 | 5 | (in-package :nth-prime) 6 | 7 | (defun not-prime-p (number) 8 | (loop for x from 3 to (isqrt number) 9 | when (zerop (mod number x)) return t)) 10 | 11 | (defun find-prime (number) 12 | (when (plusp number) 13 | (if (= number 1) 14 | 2 15 | (loop for x from 3 by 2 with primes = 1 16 | unless (not-prime-p x) do (incf primes) 17 | when (= number primes) return x)))) 18 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/.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 | [75c65189-8aef-471a-81de-0a90c728160c] 6 | description = "first prime" 7 | 8 | [2c38804c-295f-4701-b728-56dea34fd1a0] 9 | description = "second prime" 10 | 11 | [56692534-781e-4e8c-b1f9-3e82c1640259] 12 | description = "sixth prime" 13 | 14 | [fce1e979-0edb-412d-93aa-2c744e8f50ff] 15 | description = "big prime" 16 | 17 | [bd0a9eae-6df7-485b-a144-80e13c7d55b2] 18 | description = "there is no zeroth prime" 19 | -------------------------------------------------------------------------------- /exercises/practice/nth-prime/nth-prime.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :nth-prime 2 | (:use :cl) 3 | (:export :find-prime)) 4 | 5 | (in-package :nth-prime) 6 | 7 | (defun find-prime (number)) 8 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell", 7 | "sjakobi" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "nucleotide-count.lisp" 12 | ], 13 | "test": [ 14 | "nucleotide-count-test.lisp" 15 | ], 16 | "example": [ 17 | ".meta/example.lisp" 18 | ] 19 | }, 20 | "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", 21 | "source": "The Calculating DNA Nucleotides_problem at Rosalind", 22 | "source_url": "https://rosalind.info/problems/dna/" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :nucleotide-count 2 | (:use :common-lisp) 3 | (:export :dna-count :nucleotide-counts :invalid-nucleotide)) 4 | 5 | (in-package :nucleotide-count) 6 | 7 | (defparameter +valid-nucleotides+ (list #\A #\C #\G #\T)) 8 | 9 | (defun nucleotide-counts (strand) 10 | (when (every #'(lambda (n) (member n +valid-nucleotides+ :test #'char=)) strand) 11 | (mapcar #'(lambda (n) (cons n (count n strand :test #'char=))) +valid-nucleotides+))) 12 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.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 | [3e5c30a8-87e2-4845-a815-a49671ade970] 6 | description = "empty strand" 7 | 8 | [a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] 9 | description = "can count one nucleotide in single-character input" 10 | 11 | [eca0d565-ed8c-43e7-9033-6cefbf5115b5] 12 | description = "strand with repeated nucleotide" 13 | 14 | [40a45eac-c83f-4740-901a-20b22d15a39f] 15 | description = "strand with multiple nucleotides" 16 | 17 | [b4c47851-ee9e-4b0a-be70-a86e343bd851] 18 | description = "strand with invalid nucleotides" 19 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/nucleotide-count.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :nucleotide-count 2 | (:use :cl) 3 | (:export :nucleotide-counts)) 4 | 5 | (in-package :nucleotide-count) 6 | 7 | (defun nucleotide-counts (strand)) 8 | -------------------------------------------------------------------------------- /exercises/practice/palindrome-products/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "palindrome-products.lisp" 8 | ], 9 | "test": [ 10 | "palindrome-products-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :palindrome-products 2 | (:use :cl) 3 | (:export :smallest 4 | :largest)) 5 | 6 | (in-package :palindrome-products) 7 | 8 | (defun smallest (min-factor max-factor)) 9 | 10 | (defun largest (min-factor max-factor)) 11 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pangram.lisp" 8 | ], 9 | "test": [ 10 | "pangram-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pangram 2 | (:use :cl) 3 | (:export :pangramp)) 4 | 5 | (in-package :pangram) 6 | 7 | (defun pangramp (sentence) 8 | (let ((filtered (remove-if-not #'alpha-char-p (string-downcase sentence)))) 9 | (= 26 (length (remove-duplicates filtered))))) 10 | -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pangram 2 | (:use :cl) 3 | (:export :pangramp)) 4 | 5 | (in-package :pangram) 6 | 7 | (defun pangramp (sentence)) 8 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "daantjie" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pascals-triangle.lisp" 8 | ], 9 | "test": [ 10 | "pascals-triangle-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Compute Pascal's triangle up to a given number of rows.", 17 | "source": "Pascal's Triangle at Wolfram Math World", 18 | "source_url": "https://www.wolframalpha.com/input/?i=Pascal%27s+triangle" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pascals-triangle 2 | (:use :common-lisp) 3 | (:export :rows)) 4 | 5 | (in-package :pascals-triangle) 6 | 7 | (defun fact (n) 8 | (loop for i from 0 to n 9 | for fact = 1 then (* fact i) 10 | finally (return fact))) 11 | 12 | (defun choose (n r) 13 | (/ (fact n) 14 | (* (fact r) (fact (- n r))))) 15 | 16 | (defun rows (n) 17 | (if (> n 0) 18 | (loop for i from 0 to (1- n) 19 | collect (loop for j from 0 to i 20 | collect (choose i j))) 21 | '())) 22 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/pascals-triangle.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pascals-triangle 2 | (:use :cl) 3 | (:export :rows)) 4 | 5 | (in-package :pascals-triangle) 6 | 7 | (defun rows (count)) 8 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Perfect Numbers", 3 | "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.", 4 | "source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.", 5 | "source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/", 6 | "files": { 7 | "test": ["perfect-numbers-test.lisp"], 8 | "solution": ["perfect-numbers.lisp"], 9 | "example": [".meta/example.lisp"] 10 | }, 11 | "authors": ["Average-user"], 12 | "contributors": [] 13 | } 14 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :perfect-numbers 2 | (:use :common-lisp) 3 | (:export :classify)) 4 | 5 | (in-package :perfect-numbers) 6 | 7 | (defun divisors (number) 8 | (remove-if-not (lambda (x) (= 0 (rem number x))) 9 | (loop for x from 1 to (floor number 2) collect x))) 10 | 11 | (defun classify (number) 12 | (if (> number 0) 13 | (let ((div-sum (reduce #'+ (divisors number)))) 14 | (cond ((= number div-sum) "perfect") 15 | ((< number div-sum) "abundant") 16 | (T "deficient"))) 17 | (warn "Just defined for natural numbers"))) 18 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/perfect-numbers.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :perfect-numbers 2 | (:use :cl) 3 | (:export :classify)) 4 | 5 | (in-package :perfect-numbers) 6 | 7 | (defun classify (number)) 8 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "phone-number.lisp" 11 | ], 12 | "test": [ 13 | "phone-number-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.", 20 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 21 | "source_url": "https://turing.edu" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/phone-number.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :phone-number 2 | (:use :cl) 3 | (:export :clean)) 4 | 5 | (in-package :phone-number) 6 | 7 | (defun clean (phrase) 8 | "Converts a PHRASE string into a string of digits. 9 | Will evaluate to \"0000000000\" in case of an invalid input." 10 | ) 11 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "pig-latin.lisp" 11 | ], 12 | "test": [ 13 | "pig-latin-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Implement a program that translates from English to Pig Latin.", 20 | "source": "The Pig Latin exercise at Test First Teaching by Ultrasaurus", 21 | "source_url": "https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/pig-latin/pig-latin.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pig-latin 2 | (:use :cl) 3 | (:export :translate)) 4 | 5 | (in-package :pig-latin) 6 | 7 | (defun translate (phrase)) 8 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wobh" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "prime-factors.lisp" 8 | ], 9 | "test": [ 10 | "prime-factors-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/prime-factors.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :prime-factors 2 | (:use :cl) 3 | (:export :factors)) 4 | 5 | (in-package :prime-factors) 6 | 7 | (defun factors (n)) 8 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "protein-translation.lisp" 8 | ], 9 | "test": [ 10 | "protein-translation-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Translate RNA sequences into proteins.", 17 | "source": "Tyler Long" 18 | } 19 | -------------------------------------------------------------------------------- /exercises/practice/protein-translation/protein-translation.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :protein-translation 2 | (:use :cl) 3 | (:export :proteins 4 | :invalid-protein)) 5 | 6 | (in-package :protein-translation) 7 | 8 | (defun proteins (strand)) 9 | -------------------------------------------------------------------------------- /exercises/practice/proverb/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "proverb.lisp" 8 | ], 9 | "test": [ 10 | "proverb-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :proverb 2 | (:use :cl) 3 | (:export :recite)) 4 | 5 | (in-package :proverb) 6 | 7 | (defun recite (strings) 8 | (if strings 9 | (let* ((interleaved (apply #'append (mapcar #'list strings strings))) 10 | (without-ends (cdr (butlast interleaved))) 11 | (proverb-bulk (format nil "~{For want of a ~A the ~A was lost.~%~}" without-ends))) 12 | (format nil "~AAnd all for the want of a ~A." proverb-bulk (car strings))) 13 | "")) 14 | -------------------------------------------------------------------------------- /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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :proverb 2 | (:use :cl) 3 | (:export :recite)) 4 | 5 | (in-package :proverb) 6 | 7 | (defun recite (strings)) 8 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pythagorean-triplet.lisp" 8 | ], 9 | "test": [ 10 | "pythagorean-triplet-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/pythagorean-triplet.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :pythagorean-triplet 2 | (:use :cl) 3 | (:export :triplets-with-sum)) 4 | 5 | (in-package :pythagorean-triplet) 6 | 7 | (defun triplets-with-sum (n)) 8 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "queen-attack.lisp" 11 | ], 12 | "test": [ 13 | "queen-attack-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "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.", 20 | "source": "J Dalbey's Programming Practice problems", 21 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :queen-attack 2 | (:use :cl) 3 | (:export :valid-position-p 4 | :attackp)) 5 | 6 | (in-package :queen-attack) 7 | 8 | (defun valid-position-p (coordinates) 9 | (let ((row (car coordinates)) 10 | (column (cdr coordinates))) 11 | (not (or (> row 7) (> column 7) (minusp row) (minusp column))))) 12 | 13 | (defun attackp (white-queen black-queen) 14 | (when (and (valid-position-p white-queen) (valid-position-p black-queen)) 15 | (or (= (car white-queen) (car black-queen)) 16 | (= (cdr white-queen) (cdr black-queen)) 17 | (= (abs (- (car white-queen) (car black-queen))) 18 | (abs (- (cdr white-queen) (cdr black-queen))))))) 19 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/queen-attack.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :queen-attack 2 | (:use :cl) 3 | (:export :valid-position-p 4 | :attackp)) 5 | 6 | (in-package :queen-attack) 7 | 8 | (defun valid-position-p (coordinates)) 9 | 10 | (defun attackp (white-queen black-queen)) 11 | -------------------------------------------------------------------------------- /exercises/practice/rail-fence-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "rail-fence-cipher.lisp" 11 | ], 12 | "test": [ 13 | "rail-fence-cipher-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Implement encoding and decoding for the rail fence cipher.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Transposition_cipher#Rail_Fence_cipher" 22 | } 23 | -------------------------------------------------------------------------------- /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 with two rails" 7 | 8 | [25691697-fbd8-4278-8c38-b84068b7bc29] 9 | description = "encode with three rails" 10 | 11 | [384f0fea-1442-4f1a-a7c4-5cbc2044002c] 12 | description = "encode with ending in the middle" 13 | 14 | [cd525b17-ec34-45ef-8f0e-4f27c24a7127] 15 | description = "decode with three rails" 16 | 17 | [dd7b4a98-1a52-4e5c-9499-cbb117833507] 18 | description = "decode with five rails" 19 | 20 | [93e1ecf4-fac9-45d9-9cd2-591f47d3b8d3] 21 | description = "decode with six rails" 22 | -------------------------------------------------------------------------------- /exercises/practice/rail-fence-cipher/rail-fence-cipher.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :rail-fence-cipher 2 | (:use :cl) 3 | (:export :encode 4 | :decode)) 5 | 6 | (in-package :rail-fence-cipher) 7 | 8 | (defun encode (msg rails)) 9 | 10 | (defun decode (msg rails)) 11 | -------------------------------------------------------------------------------- /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 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "raindrops.lisp" 11 | ], 12 | "test": [ 13 | "raindrops-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 20 | "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.", 21 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :raindrops 2 | (:use :common-lisp) 3 | (:export :convert)) 4 | 5 | (in-package :raindrops) 6 | 7 | (defparameter *raindrops* 8 | '((3 . "Pling") 9 | (5 . "Plang") 10 | (7 . "Plong")) 11 | "Frequency modulus and impact sound of raindrops.") 12 | 13 | (defun convert (integer &optional (raindrops *raindrops*)) 14 | "String of integer or raindrop sound." 15 | (declare (type integer integer)) 16 | (loop 17 | for (div . sound) of-type (integer . string) in raindrops 18 | when (zerop (mod integer div)) 19 | collect sound into sounds 20 | finally 21 | (return 22 | (if sounds 23 | (format nil "~{~A~}" sounds) 24 | (write-to-string integer))))) 25 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :raindrops 2 | (:use :cl) 3 | (:export :convert)) 4 | 5 | (in-package :raindrops) 6 | 7 | (defun convert (number)) 8 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-duo.lisp" 8 | ], 9 | "test": [ 10 | "resistor-color-duo-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :resistor-color-duo 2 | (:use :cl) 3 | (:export :value)) 4 | 5 | (in-package :resistor-color-duo) 6 | 7 | (defun value (colors) 8 | (let ((tens (color-code (first colors))) 9 | (ones (color-code (second colors)))) 10 | (+ (* tens 10) ones))) 11 | 12 | (defun color-code (color) 13 | (position color (color-values) :test #'string=)) 14 | 15 | (defun color-values () 16 | '("black" "brown" "red" "orange" "yellow" "green" "blue" "violet" "grey" "white")) 17 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-duo/resistor-color-duo.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :resistor-color-duo 2 | (:use :cl) 3 | (:export :value)) 4 | 5 | (in-package :resistor-color-duo) 6 | 7 | (defun value (colors)) 8 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color-trio/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color-trio.lisp" 8 | ], 9 | "test": [ 10 | "resistor-color-trio-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :resistor-color-trio 2 | (:use :cl) 3 | (:export :label)) 4 | 5 | (in-package :resistor-color-trio) 6 | 7 | (defun label (colors)) 8 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "resistor-color.lisp" 8 | ], 9 | "test": [ 10 | "resistor-color-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :resistor-color 2 | (:use :cl) 3 | (:export :color-code 4 | :colors)) 5 | 6 | (in-package :resistor-color) 7 | 8 | (defun color-code (color) 9 | (position color (colors) :test #'string=)) 10 | 11 | (defun colors () 12 | '("black" "brown" "red" "orange" "yellow" "green" "blue" "violet" "grey" "white")) 13 | -------------------------------------------------------------------------------- /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 = "Black" 7 | 8 | [0a4df94b-92da-4579-a907-65040ce0b3fc] 9 | description = "White" 10 | 11 | [5f81608d-f36f-4190-8084-f45116b6f380] 12 | description = "Orange" 13 | 14 | [581d68fa-f968-4be2-9f9d-880f2fb73cf7] 15 | description = "Colors" 16 | -------------------------------------------------------------------------------- /exercises/practice/resistor-color/resistor-color.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :resistor-color 2 | (:use :cl) 3 | (:export :color-code 4 | :colors)) 5 | 6 | (in-package :resistor-color) 7 | 8 | (defun color-code (color)) 9 | 10 | (defun colors ()) 11 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rna-transcription.lisp" 8 | ], 9 | "test": [ 10 | "rna-transcription-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :rna-transcription 2 | (:use :common-lisp) 3 | (:export :to-rna)) 4 | 5 | (in-package :rna-transcription) 6 | 7 | (defun validate-strand (strand) 8 | (or (every #'(lambda (c) (find c "ATCGU")) 9 | (coerce strand 'list)) 10 | (signal 'error))) 11 | 12 | (defparameter dna->rna 13 | '((#\C . #\G) (#\G . #\C) (#\A . #\U) (#\T . #\A))) 14 | 15 | (defun to-rna (strand) 16 | (validate-strand strand) 17 | (map 'string #'(lambda (c) (cdr (assoc c dna->rna))) strand)) 18 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :rna-transcription 2 | (:use :cl) 3 | (:export :to-rna)) 4 | (in-package :rna-transcription) 5 | 6 | (defun to-rna (str) 7 | "Transcribe a string representing DNA nucleotides to RNA." 8 | ) 9 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "wobh" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "robot-name.lisp" 11 | ], 12 | "test": [ 13 | "robot-name-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Manage robot factory settings.", 20 | "source": "A debugging session with Paul Blackwell at gSchool." 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/robot-name.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :robot-name 2 | (:use :cl) 3 | (:export :build-robot :robot-name :reset-name)) 4 | 5 | (in-package :robot-name) 6 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wsgac" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "robot-simulator.lisp" 11 | ], 12 | "test": [ 13 | "robot-simulator-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Write a robot simulator.", 20 | "source": "Inspired by an interview question at a famous company." 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/robot-simulator/robot-simulator.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :robot-simulator 2 | (:use :cl) 3 | (:export :+north+ :+east+ :+south+ :+west+ :execute-sequence 4 | :robot :robot-position :robot-bearing :make-robot)) 5 | 6 | (in-package :robot-simulator) 7 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your task is to convert a number from Arabic numerals to Roman numerals. 4 | 5 | For this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999). 6 | 7 | ~~~~exercism/note 8 | There are lots of different ways to convert between Arabic and Roman numerals. 9 | We recommend taking a naive approach first to familiarise yourself with the concept of Roman numerals and then search for more efficient methods. 10 | 11 | Make sure to check out our Deep Dive video at the end to explore the different approaches you can take! 12 | ~~~~ 13 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wobh" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "roman-numerals.lisp" 11 | ], 12 | "test": [ 13 | "roman-numerals-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 20 | "source": "The Roman Numeral Kata", 21 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :roman-numerals 2 | (:use :cl) 3 | (:export :romanize)) 4 | 5 | (in-package :roman-numerals) 6 | 7 | (defun romanize (number) 8 | (format nil "~@R" number)) 9 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/roman-numerals.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :roman-numerals 2 | (:use :cl) 3 | (:export :romanize)) 4 | 5 | (in-package :roman-numerals) 6 | 7 | (defun romanize (number) 8 | "Returns the Roman numeral representation for a given number." 9 | ) 10 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rotational-cipher.lisp" 8 | ], 9 | "test": [ 10 | "rotational-cipher-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/rotational-cipher.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :rotational-cipher 2 | (:use :cl) 3 | (:export :rotate)) 4 | 5 | (in-package :rotational-cipher) 6 | 7 | (defun rotate (text key)) 8 | -------------------------------------------------------------------------------- /exercises/practice/run-length-encoding/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "run-length-encoding.lisp" 8 | ], 9 | "test": [ 10 | "run-length-encoding-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :run-length-encoding 2 | (:use :cl) 3 | (:export :encode 4 | :decode)) 5 | 6 | (in-package :run-length-encoding) 7 | 8 | (defun encode (plain)) 9 | 10 | (defun decode (compressed)) 11 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "saddle-points.lisp" 8 | ], 9 | "test": [ 10 | "saddle-points-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :saddle-points 2 | (:use :cl) 3 | (:export :saddle-points)) 4 | 5 | (in-package :saddle-points) 6 | 7 | (defun saddle-points (matrix)) 8 | -------------------------------------------------------------------------------- /exercises/practice/say/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "say.lisp" 8 | ], 9 | "test": [ 10 | "say-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :say 2 | (:use :cl) 3 | (:export :say)) 4 | 5 | (in-package :say) 6 | 7 | (defun say (number) 8 | (when (< -1 number (expt 10 12)) 9 | (format nil "~r" number))) 10 | -------------------------------------------------------------------------------- /exercises/practice/say/say.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :say 2 | (:use :cl) 3 | (:export :say)) 4 | 5 | (in-package :say) 6 | 7 | (defun say (number)) 8 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "scrabble-score.lisp" 11 | ], 12 | "test": [ 13 | "scrabble-score-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a word, compute the Scrabble score for that word.", 20 | "source": "Inspired by the Extreme Startup game", 21 | "source_url": "https://github.com/rchatley/extreme_startup" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :scrabble-score 2 | (:use :cl) 3 | (:export :score-word)) 4 | 5 | (in-package :scrabble-score) 6 | 7 | (defparameter *letter-scores* 8 | '((#\A . 1) (#\B . 3) (#\C . 3) (#\D . 2) (#\E . 1) (#\F . 4) 9 | (#\G . 2) (#\H . 4) (#\I . 1) (#\J . 8) (#\K . 5) (#\L . 1) 10 | (#\M . 3) (#\N . 1) (#\O . 1) (#\P . 3) (#\Q . 10) (#\R . 1) 11 | (#\S . 1) (#\T . 1) (#\U . 1) (#\V . 4) (#\W . 4) (#\X . 8) 12 | (#\Y . 4) (#\Z . 10))) 13 | 14 | (defun score-letter (letter) 15 | "Returns the score for a single letter." 16 | (or (cdr (assoc letter *letter-scores* :test #'char-equal)) 0)) 17 | 18 | (defun score-word (word) 19 | "Computes the score for an entire word" 20 | (reduce #'+ word :key #'score-letter)) 21 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/scrabble-score.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :scrabble-score 2 | (:use :cl) 3 | (:export :score-word)) 4 | 5 | (in-package :scrabble-score) 6 | 7 | (defun score-word (word)) 8 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "secret-handshake.lisp" 8 | ], 9 | "test": [ 10 | "secret-handshake-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.", 17 | "source": "Bert, in Mary Poppins", 18 | "source_url": "https://www.imdb.com/title/tt0058331/quotes/?item=qt0437047" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :secret-handshake 2 | (:use :cl) 3 | (:export :commands)) 4 | 5 | (in-package :secret-handshake) 6 | 7 | (defparameter +phrases+ #("wink" "double blink" "close your eyes" "jump")) 8 | 9 | (defun commands (number) 10 | (loop for x from 0 below 4 11 | when (plusp (logand number (expt 2 x))) 12 | collect (aref +phrases+ x) into output 13 | finally (return (if (plusp (logand number 16)) (reverse output) output)))) 14 | -------------------------------------------------------------------------------- /exercises/practice/secret-handshake/secret-handshake.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :secret-handshake 2 | (:use :cl) 3 | (:export :commands)) 4 | 5 | (in-package :secret-handshake) 6 | 7 | (defun commands (number)) 8 | -------------------------------------------------------------------------------- /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 | "wobh" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "sieve.lisp" 11 | ], 12 | "test": [ 13 | "sieve-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", 20 | "source": "Sieve of Eratosthenes at Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.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 | [88529125-c4ce-43cc-bb36-1eb4ddd7b44f] 6 | description = "no primes under two" 7 | 8 | [4afe9474-c705-4477-9923-840e1024cc2b] 9 | description = "find first prime" 10 | 11 | [974945d8-8cd9-4f00-9463-7d813c7f17b7] 12 | description = "find primes up to 10" 13 | 14 | [2e2417b7-3f3a-452a-8594-b9af08af6d82] 15 | description = "limit is prime" 16 | 17 | [92102a05-4c7c-47de-9ed0-b7d5fcd00f21] 18 | description = "find primes up to 1000" 19 | -------------------------------------------------------------------------------- /exercises/practice/sieve/sieve.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :sieve 2 | (:use :cl) 3 | (:export :primes-to) 4 | (:documentation "Generates a list of primes up to a given limit.")) 5 | 6 | (in-package :sieve) 7 | 8 | (defun primes-to (n) 9 | "List primes up to `n' using sieve of Eratosthenes." 10 | ) 11 | -------------------------------------------------------------------------------- /exercises/practice/space-age/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "space-age.lisp" 11 | ], 12 | "test": [ 13 | "space-age-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", 20 | "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", 21 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/space-age/space-age.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :space-age 2 | (:use :cl) 3 | (:export :on-mercury 4 | :on-venus 5 | :on-earth 6 | :on-mars 7 | :on-jupiter 8 | :on-saturn 9 | :on-uranus 10 | :on-neptune)) 11 | 12 | (in-package :space-age) 13 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "spiral-matrix.lisp" 8 | ], 9 | "test": [ 10 | "spiral-matrix-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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/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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :spiral-matrix 2 | (:use :cl) 3 | (:export :spiral-matrix)) 4 | 5 | (in-package :spiral-matrix) 6 | 7 | (defun spiral-matrix (size)) 8 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | We are launching a deep space exploration rocket and we need a way to make sure the navigation system stays on target. 4 | 5 | As the first step in our calculation, we take a target number and find its square root (that is, the number that when multiplied by itself equals the target number). 6 | 7 | The journey will be very long. 8 | To make the batteries last as long as possible, we had to make our rocket's onboard computer very power efficient. 9 | Unfortunately that means that we can't rely on fancy math libraries and functions, as they use more power. 10 | Instead we want to implement our own square root calculation. 11 | -------------------------------------------------------------------------------- /exercises/practice/square-root/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "BNAndras" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "square-root.lisp" 8 | ], 9 | "test": [ 10 | "square-root-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 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.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :square-root 2 | (:use :cl) 3 | (:export :square-root)) 4 | 5 | (in-package :square-root) 6 | 7 | (defun square-root (radicand) 8 | (if (= radicand 1) 9 | 1 10 | (loop with guess = (floor radicand 2) 11 | repeat 10 12 | until (= radicand (* guess guess)) 13 | do (setf guess (floor (+ guess (/ radicand guess)) 2)) 14 | finally (return (and (= radicand (* guess guess)) guess))))) 15 | -------------------------------------------------------------------------------- /exercises/practice/square-root/square-root.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :square-root 2 | (:use :cl) 3 | (:export :square-root)) 4 | 5 | (in-package :square-root) 6 | 7 | (defun square-root (radicand)) 8 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "strain.lisp" 11 | ], 12 | "test": [ 13 | "strain-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Implement the `keep` and `discard` operation on collections.", 20 | "source": "Conversation with James Edward Gray II", 21 | "source_url": "http://graysoftinc.com/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :strain 2 | (:use :common-lisp) 3 | (:export :keep :discard)) 4 | 5 | (in-package :strain) 6 | 7 | (defun keep (pred seq) 8 | (labels 9 | ((recurse (s r) 10 | (cond ((null s) (reverse r)) 11 | ((funcall pred (car s)) 12 | (recurse (cdr s) (cons (car s) r))) 13 | (t (recurse (cdr s) r))))) 14 | (recurse seq (list)))) 15 | 16 | (defun discard (pred seq) 17 | (keep (complement pred) seq)) 18 | -------------------------------------------------------------------------------- /exercises/practice/strain/strain.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :strain 2 | (:use :cl) 3 | (:export :keep :discard)) 4 | 5 | (in-package :strain) 6 | 7 | (defun keep (keep-p elements) 8 | "Returns a sublist of elements according to a given predicate." 9 | ) 10 | 11 | (defun discard (discard-p elements) 12 | "Returns a sublist of elements not matching a given predicate." 13 | ) 14 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "Average-user" 4 | ], 5 | "contributors": [ 6 | "kephas" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "sublist.lisp" 11 | ], 12 | "test": [ 13 | "sublist-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Write a function to determine if a list is a sublist of another list." 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/sublist/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :sublist 2 | (:use :common-lisp) 3 | (:export :sublist)) 4 | 5 | (in-package :sublist) 6 | 7 | (defun is-prefix-of (xs ys) 8 | (cond ((null xs) T) 9 | ((null ys) NIL) 10 | ((equal (car xs) (car ys)) (is-prefix-of (cdr xs) (cdr ys))) 11 | (T NIL))) 12 | 13 | (defun sublist-of (xs ys) 14 | (if (and xs (null ys)) 15 | nil 16 | (or (is-prefix-of xs ys) (sublist-of xs (cdr ys))))) 17 | 18 | (defun sublist (xs ys) 19 | (let ((sub (sublist-of xs ys)) 20 | (super (sublist-of ys xs))) 21 | (cond ((and sub super) :equal) 22 | (sub :sublist) 23 | (super :superlist) 24 | (T :unequal)))) 25 | -------------------------------------------------------------------------------- /exercises/practice/sublist/sublist.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :sublist 2 | (:use :cl) 3 | (:export :sublist)) 4 | 5 | (in-package :sublist) 6 | 7 | (defun sublist (list-one list-two)) 8 | -------------------------------------------------------------------------------- /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 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "sum-of-multiples.lisp" 11 | ], 12 | "test": [ 13 | "sum-of-multiples-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 20 | "source": "A variation on Problem 1 at Project Euler", 21 | "source_url": "https://projecteuler.net/problem=1" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :sum-of-multiples 2 | (:use :cl) 3 | (:export :sum)) 4 | 5 | (in-package :sum-of-multiples) 6 | 7 | (defun sum (factors limit) 8 | (loop for factor in (remove-if-not #'plusp factors) 9 | collect (loop for x from factor below limit by factor collect x) into output 10 | finally (return (apply #'+ (remove-duplicates (reduce #'append output)))))) 11 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/sum-of-multiples.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :sum-of-multiples 2 | (:use :cl) 3 | (:export :sum)) 4 | 5 | (in-package :sum-of-multiples) 6 | 7 | (defun sum (factors limit)) 8 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "triangle.lisp" 11 | ], 12 | "test": [ 13 | "triangle-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 20 | "source": "The Ruby Koans triangle project, parts 1 & 2", 21 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/triangle/triangle.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :triangle 2 | (:use :cl) 3 | (:export :triangle-type-p)) 4 | 5 | (in-package :triangle) 6 | 7 | (defun triangle-type-p (type a b c) 8 | "Deterimines if a triangle (given by side lengths A, B, C) is of the given TYPE" 9 | ) 10 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "verdammelt" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "trinary.lisp" 8 | ], 9 | "test": [ 10 | "trinary-test.lisp" 11 | ], 12 | "example": [ 13 | ".meta/example.lisp" 14 | ] 15 | }, 16 | "blurb": "Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles.", 17 | "source": "All of Computer Science", 18 | "source_url": "http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-" 19 | } 20 | -------------------------------------------------------------------------------- /exercises/practice/trinary/trinary.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :trinary 2 | (:use :cl) 3 | (:export :to-decimal)) 4 | 5 | (in-package :trinary) 6 | 7 | (defun to-decimal (str)) 8 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "serialhex" 4 | ], 5 | "contributors": [ 6 | "dnmfarrell" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "twelve-days.lisp" 11 | ], 12 | "test": [ 13 | "twelve-days-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Output the lyrics to 'The Twelve Days of Christmas'.", 20 | "source": "Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(song)" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/twelve-days/twelve-days.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :twelve-days 2 | (:use :cl) 3 | (:export :recite)) 4 | 5 | (in-package :twelve-days) 6 | 7 | (defun recite (&optional begin end) 8 | "Returns a string of the requested verses for the 12 Days of Christmas." 9 | ) 10 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PaulT89" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "two-bucket.lisp" 11 | ], 12 | "test": [ 13 | "two-bucket-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given two buckets of different size, demonstrate how to measure an exact number of liters.", 20 | "source": "Water Pouring Problem", 21 | "source_url": "https://demonstrations.wolfram.com/WaterPouringProblem/" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/two-bucket/two-bucket.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :two-bucket 2 | (:use :cl) 3 | (:export :measure)) 4 | 5 | (in-package :two-bucket) 6 | 7 | (defun measure (bucket-one bucket-two goal start-bucket) 8 | "Function to solve the two-bucket puzzle, if possible, when given the capacities 9 | of both buckets, a goal, and which bucket to start with. Returns an alist of moves 10 | required to reach the goal, the name of the bucket that reach the goal, and the 11 | amount of water left over in the other bucket." 12 | ) 13 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "OrdoFlammae", 7 | "timotheosh" 8 | ], 9 | "files": { 10 | "solution": [ 11 | "two-fer.lisp" 12 | ], 13 | "test": [ 14 | "two-fer-test.lisp" 15 | ], 16 | "example": [ 17 | ".meta/example.lisp" 18 | ] 19 | }, 20 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 21 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/example.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | (defpackage :two-fer 3 | (:use :cl) 4 | (:export :twofer)) 5 | (in-package :two-fer) 6 | 7 | (defun twofer (&optional name) 8 | (format nil "One for ~a, one for me." (or name "you"))) 9 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.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 | [1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce] 6 | description = "no name given" 7 | 8 | [b4c6dbb8-b4fb-42c2-bafd-10785abe7709] 9 | description = "a name given" 10 | 11 | [3549048d-1a6e-4653-9a79-b0bda163e8d5] 12 | description = "another name given" 13 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :two-fer 2 | (:use :cl) 3 | (:export :twofer)) 4 | (in-package :two-fer) 5 | 6 | (defun twofer (name)) 7 | -------------------------------------------------------------------------------- /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 | "verdammelt" 4 | ], 5 | "contributors": [ 6 | "spacebat" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "word-count.lisp" 11 | ], 12 | "test": [ 13 | "word-count-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Given a phrase, count the occurrences of each word in that phrase.", 20 | "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." 21 | } 22 | -------------------------------------------------------------------------------- /exercises/practice/word-count/word-count.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :word-count 2 | (:use :cl) 3 | (:export :count-words)) 4 | (in-package :word-count) 5 | 6 | (defun count-words (sentence)) 7 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Each year, something new is "all the rage" in your high school. 4 | This year it is a dice game: [Yacht][yacht]. 5 | 6 | The game of Yacht is from the same family as Poker Dice, Generala and particularly Yahtzee, of which it is a precursor. 7 | The game consists of twelve rounds. 8 | In each, five dice are rolled and the player chooses one of twelve categories. 9 | The chosen category is then used to score the throw of the dice. 10 | 11 | [yacht]: https://en.wikipedia.org/wiki/Yacht_(dice_game) 12 | -------------------------------------------------------------------------------- /exercises/practice/yacht/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "SimaDovakin" 4 | ], 5 | "contributors": [ 6 | "verdammelt" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "yacht.lisp" 11 | ], 12 | "test": [ 13 | "yacht-test.lisp" 14 | ], 15 | "example": [ 16 | ".meta/example.lisp" 17 | ] 18 | }, 19 | "blurb": "Score a single throw of dice in the game Yacht.", 20 | "source": "James Kilfiger, using Wikipedia", 21 | "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)" 22 | } 23 | -------------------------------------------------------------------------------- /exercises/practice/yacht/yacht.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :yacht 2 | (:use :cl) 3 | (:export :score)) 4 | (in-package :yacht) 5 | 6 | (defun score (scores category) 7 | "Returns the score of the dice for the given category." 8 | ) 9 | -------------------------------------------------------------------------------- /exercises/shared/.docs/debug.md: -------------------------------------------------------------------------------- 1 | # Debug 2 | 3 | To help with debugging, you can use [`print` or similar functions][cl-print] to write to standard output which will be visible in the test output. 4 | 5 | For example adding `(print "hello there")` into the function you are writing will cause it to be visible in the test runs (given that the test executes that function). 6 | 7 | One "trick": if you have several things to print out is to collect them together in a list and then print that: `(print (list :this "that" 'the-other))`. 8 | 9 | [cl-print]: http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_pr.htm 10 | 11 | -------------------------------------------------------------------------------- /src/config-checker.asd: -------------------------------------------------------------------------------- 1 | (defsystem "config-checker" 2 | :description "" 3 | :version "0.0.0" 4 | :author "Mark Simpson" 5 | :mailto "verdammelt@gmail.com" 6 | 7 | :depends-on ("yason") 8 | 9 | :pathname "config-checker" 10 | :serial t 11 | :components ((:file "packages") 12 | (:file "track-config") 13 | (:file "utils") 14 | (:file "main") 15 | (:module "checkers" 16 | :components ())) 17 | 18 | :perform (test-op (o c) 19 | (declare (ignore o c)) 20 | (uiop:symbol-call :config-checker ':check-config))) 21 | -------------------------------------------------------------------------------- /src/config-checker/main.lisp: -------------------------------------------------------------------------------- 1 | (in-package :config-checker) 2 | 3 | (define-condition config-check-failure (error) ()) 4 | 5 | (defparameter *checkers* nil) 6 | 7 | (defun check-config () 8 | (let ((config (track-config:read-config "./config.json"))) 9 | (dolist (checker *checkers*) 10 | (format *debug-io* "~&Running Checker: ~S~&" checker) 11 | (funcall checker config)))) 12 | -------------------------------------------------------------------------------- /src/config-checker/packages.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :config-checker 2 | (:use :cl) 3 | (:export :check-config 4 | :ci-check-config)) 5 | 6 | (defpackage :track-config 7 | (:use :cl) 8 | (:export :read-config 9 | :slugs 10 | :listed-concepts 11 | :concept-exercises 12 | :practice-exercises 13 | :prerequisite-concept-slugs 14 | :practiced-concept-slugs)) 15 | -------------------------------------------------------------------------------- /src/config-checker/track-config.lisp: -------------------------------------------------------------------------------- 1 | (in-package :track-config) 2 | 3 | (defun read-config (&optional (config-file "./config.json")) 4 | (yason:parse (truename config-file))) 5 | 6 | (defun slugs (items) 7 | (mapcar #'(lambda (c) (gethash "slug" c)) items)) 8 | 9 | (defun listed-concepts (config) 10 | (gethash "concepts" config)) 11 | 12 | (defun concept-exercises (config) 13 | (gethash "concept" (gethash "exercises" config))) 14 | 15 | (defun practice-exercises (config) 16 | (gethash "practice" (gethash "exercises" config))) 17 | 18 | (defun prerequisite-concept-slugs (exercise) 19 | (gethash "prerequisites" exercise)) 20 | 21 | (defun practiced-concept-slugs (exercise) 22 | (or (gethash "concepts" exercise) 23 | (gethash "practices" exercise))) 24 | -------------------------------------------------------------------------------- /src/config-checker/utils.lisp: -------------------------------------------------------------------------------- 1 | (in-package :config-checker) 2 | 3 | (defun flatten (list-of-lists) (apply #'append list-of-lists)) 4 | (defun flat-mapcar (fn &rest lists) (flatten (apply #'mapcar fn lists))) 5 | 6 | (defun slug-set-diff (slugs1 slugs2) 7 | (set-difference slugs1 slugs2 :test #'string=)) 8 | (defun slug-remove-dups (slugs) 9 | (remove-duplicates slugs :test #'string=)) 10 | -------------------------------------------------------------------------------- /src/ex-maint-utils.asd: -------------------------------------------------------------------------------- 1 | (defsystem "ex-maint-utils" 2 | :description "Exercism utilities for track maintenance" 3 | :version "0.0.1" 4 | :author "Mark Simpson" 5 | :mailto "verdammelt@gmail.com" 6 | 7 | :depends-on ("alexandria") 8 | 9 | :pathname "ex-maint-utils" 10 | :serial t 11 | :components ((:module "stubs" 12 | :components ((:file "package") 13 | (:file "utils") 14 | (:file "concepts") 15 | (:file "concept-exercises"))) 16 | (:file "package"))) 17 | -------------------------------------------------------------------------------- /src/ex-maint-utils/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :ex-maint-utils 2 | (:use :cl :stubs) 3 | (:export :stub-concept 4 | :stub-concept-exercise)) 5 | -------------------------------------------------------------------------------- /src/ex-maint-utils/stubs/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :stubs 2 | (:use :cl) 3 | (:export :stub-concept 4 | :stub-concept-exercise)) 5 | -------------------------------------------------------------------------------- /src/make-exec.lisp: -------------------------------------------------------------------------------- 1 | (load "~/.quicklisp/setup.lisp") 2 | (asdf:initialize-source-registry (uiop:getcwd)) 3 | (asdf:make 4 | (format nil "~A/executable" (first (uiop:command-line-arguments)))) 5 | -------------------------------------------------------------------------------- /src/test-exercises.asd: -------------------------------------------------------------------------------- 1 | (defsystem "test-exercises" 2 | :description "Test all exercises" 3 | :version "0.0.0" 4 | :author "Mark Simpson" 5 | :mailto "verdammelt@gmail.com" 6 | 7 | :depends-on ("yason" "fiveam" "lisp-unit") 8 | 9 | :pathname "test-exercises" 10 | :serial t 11 | :components ((:file "packages") 12 | (:file "utils") 13 | (:file "exercises") 14 | (:file "run") 15 | (:file "report") 16 | (:file "paths") 17 | (:file "main")) 18 | 19 | :perform (test-op (o c) 20 | (declare (ignore o c)) 21 | (uiop:symbol-call :test-exercises ':run-all-tests))) 22 | -------------------------------------------------------------------------------- /src/test-exercises/main.lisp: -------------------------------------------------------------------------------- 1 | (in-package :test-exercises) 2 | 3 | (defun run-all-tests () 4 | (let ((all-exercise-directories (append (list-exercise-directories "concept") 5 | (list-exercise-directories "practice")))) 6 | (let ((result-totals 7 | (report-results 8 | (nreverse 9 | (reduce #'(lambda (acc ex) (push (test-exercise ex) acc)) 10 | all-exercise-directories 11 | :initial-value (list)))))) 12 | (when (or (plusp (getf result-totals :fail)) 13 | (plusp (getf result-totals :errors))) 14 | (error "Test Failures Detected."))))) 15 | -------------------------------------------------------------------------------- /src/test-exercises/packages.lisp: -------------------------------------------------------------------------------- 1 | (defpackage :test-exercises 2 | (:use :cl) 3 | (:export :run-all-tests :test-exercise)) 4 | -------------------------------------------------------------------------------- /src/test-exercises/paths.lisp: -------------------------------------------------------------------------------- 1 | (in-package :test-exercises) 2 | 3 | (defparameter +source-directory-pathname+ 4 | (make-pathname :directory (pathname-directory 5 | #.(or *compile-file-pathname* *load-pathname*))) 6 | "Location of this source of the TEST-EXERCISES system source code. 7 | Location of other files in the common-lisp track will be found relative to this.") 8 | 9 | (defun find-exercise-directory () 10 | (merge-pathnames 11 | (make-pathname :directory (list :relative :up :up "exercises")) 12 | +source-directory-pathname+)) 13 | 14 | (defun list-exercise-directories (type) 15 | (directory (merge-pathnames 16 | (make-pathname :directory (list :relative type :wild)) 17 | (find-exercise-directory)))) 18 | -------------------------------------------------------------------------------- /src/test-exercises/utils.lisp: -------------------------------------------------------------------------------- 1 | (in-package :test-exercises) 2 | 3 | (defun aget (key alist) (cdr (assoc key alist))) 4 | 5 | (defun keywordize (str) 6 | (intern (string-upcase str) :keyword)) 7 | --------------------------------------------------------------------------------