├── .github ├── stale.yml ├── CODEOWNERS ├── dependabot.yml └── workflows │ ├── configlet.yml │ ├── sync-labels.yml │ ├── ping-cross-track-maintainers-team.yml │ ├── ci.yml │ ├── pause-community-contributions.yml │ └── no-important-files-changed.yml ├── exercises ├── practice │ ├── bob │ │ ├── .meta │ │ │ ├── version │ │ │ └── config.json │ │ ├── bob.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── Makefile │ ├── forth │ │ ├── .meta │ │ │ ├── version │ │ │ └── config.json │ │ ├── forth.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ └── Makefile │ ├── leap │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── leap.scm │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── Makefile │ │ └── test.scm │ ├── sieve │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── sieve.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── introduction.md │ ├── anagram │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── anagram.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── Makefile │ ├── change │ │ ├── .meta │ │ │ ├── version │ │ │ └── config.json │ │ ├── change.scm │ │ ├── Makefile │ │ └── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ ├── grains │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── grains.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ ├── Makefile │ │ └── test.scm │ ├── hamming │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── hamming.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ ├── Makefile │ │ └── test.scm │ ├── knapsack │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── knapsack.scm │ │ ├── Makefile │ │ └── .docs │ │ │ ├── instructions.append.md │ │ │ ├── introduction.md │ │ │ └── instructions.md │ ├── octal │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── octal.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── pangram │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── pangram.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── Makefile │ ├── raindrops │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── raindrops.scm │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── Makefile │ ├── transpose │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── transpose.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── two-fer │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── two-fer.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ ├── Makefile │ │ └── test.scm │ ├── word-count │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── word-count.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── introduction.md │ ├── accumulate │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── accumulate.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── acronym │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── acronym.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test.scm │ ├── affine-cipher │ │ ├── .meta │ │ │ ├── version │ │ │ └── config.json │ │ ├── affine-cipher.scm │ │ └── Makefile │ ├── atbash-cipher │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── atbash-cipher.scm │ │ └── Makefile │ ├── binary-search │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── binary-search.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── introduction.md │ │ └── Makefile │ ├── hello-world │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── tests.toml │ │ │ └── config.json │ │ ├── hello-world.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ ├── test.scm │ │ └── Makefile │ ├── perfect-numbers │ │ ├── .meta │ │ │ ├── version │ │ │ └── config.json │ │ ├── perfect-numbers.scm │ │ └── Makefile │ ├── phone-number │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── phone-number.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── introduction.md │ ├── prime-factors │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── prime-factors.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test.scm │ ├── queen-attack │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── queen-attack.scm │ │ ├── .docs │ │ │ ├── instructions.append.md │ │ │ └── instructions.md │ │ ├── Makefile │ │ └── test.scm │ ├── scrabble-score │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── scrabble-score.scm │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ ├── Makefile │ │ └── test.scm │ ├── triangle │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── triangle.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test.scm │ ├── trinary │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── trinary.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test.scm │ ├── collatz-conjecture │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── collatz-conjecture.scm │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── instructions.append.md │ │ ├── Makefile │ │ └── test.scm │ ├── matching-brackets │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── matching-brackets.scm │ │ ├── .docs │ │ │ ├── instructions.md │ │ │ └── introduction.md │ │ └── Makefile │ ├── nucleotide-count │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ ├── example.scm │ │ │ └── tests.toml │ │ ├── nucleotide-count.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── pascals-triangle │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── pascals-triangle.scm │ │ ├── Makefile │ │ └── test.scm │ ├── rna-transcription │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ ├── config.json │ │ │ └── tests.toml │ │ ├── rna-transcription.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ ├── introduction.md │ │ │ └── instructions.md │ │ └── test.scm │ ├── roman-numerals │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── roman-numerals.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── rotational-cipher │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── rotational-cipher.scm │ │ ├── Makefile │ │ └── test.scm │ ├── armstrong-numbers │ │ ├── .meta │ │ │ ├── version │ │ │ ├── config.json │ │ │ └── example.scm │ │ ├── armstrong-numbers.scm │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── difference-of-squares │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── difference-of-squares.scm │ │ ├── Makefile │ │ ├── .docs │ │ │ └── instructions.md │ │ └── test.scm │ ├── sum-of-multiples │ │ ├── .meta │ │ │ ├── version │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── sum-of-multiples.scm │ │ ├── .docs │ │ │ └── introduction.md │ │ └── Makefile │ ├── strain │ │ ├── strain.scm │ │ ├── .meta │ │ │ ├── example.scm │ │ │ └── config.json │ │ ├── Makefile │ │ └── .docs │ │ │ └── instructions.md │ ├── robot-name │ │ ├── robot-name.scm │ │ ├── Makefile │ │ ├── .meta │ │ │ ├── config.json │ │ │ └── example.scm │ │ └── .docs │ │ │ └── instructions.md │ └── list-ops │ │ ├── list-ops.scm │ │ ├── Makefile │ │ └── .meta │ │ └── config.json └── shared │ └── .docs │ ├── tests.md │ └── help.md ├── input ├── exercises │ ├── forth │ │ └── forth.scm │ ├── bob │ │ ├── bob.scm │ │ └── test.ss │ ├── leap │ │ ├── leap.scm │ │ ├── example.scm │ │ └── test.ss │ ├── hello-world │ │ ├── example.scm │ │ ├── hello-world.scm │ │ └── test.ss │ ├── pangram │ │ ├── pangram.scm │ │ ├── example.scm │ │ └── test.ss │ ├── anagram │ │ ├── anagram.scm │ │ ├── example.scm │ │ └── test.ss │ ├── change │ │ ├── change.scm │ │ └── test.ss │ ├── raindrops │ │ ├── raindrops.scm │ │ ├── example.scm │ │ └── test.ss │ ├── transpose │ │ ├── transpose.scm │ │ └── example.scm │ ├── two-fer │ │ ├── two-fer.scm │ │ ├── example.scm │ │ └── test.ss │ ├── perfect-numbers │ │ ├── perfect-numbers.scm │ │ └── test.ss │ ├── prime-factors │ │ ├── prime-factors.scm │ │ ├── example.scm │ │ └── test.ss │ ├── scrabble-score │ │ ├── scrabble-score.scm │ │ ├── example.scm │ │ └── test.ss │ ├── word-count │ │ ├── word-count.scm │ │ └── example.scm │ ├── collatz-conjecture │ │ ├── collatz-conjecture.scm │ │ ├── example.scm │ │ └── test.ss │ ├── matching-brackets │ │ ├── matching-brackets.scm │ │ ├── example.scm │ │ └── test.ss │ ├── phone-number │ │ ├── phone-number.scm │ │ ├── test.ss │ │ └── example.scm │ ├── binary-search │ │ ├── binary-search.scm │ │ └── example.scm │ ├── hamming │ │ ├── hamming.scm │ │ └── example.scm │ ├── knapsack │ │ └── knapsack.scm │ ├── queen-attack │ │ ├── queen-attack.scm │ │ ├── example.scm │ │ └── test.ss │ ├── rna-transcription │ │ ├── rna-transcription.scm │ │ ├── example.scm │ │ └── test.ss │ ├── rotational-cipher │ │ ├── rotational-cipher.scm │ │ ├── example.scm │ │ └── test.ss │ ├── nucleotide-count │ │ ├── nucleotide-count.scm │ │ └── example.scm │ ├── pascals-triangle │ │ ├── pascals-triangle.scm │ │ ├── example.scm │ │ └── test.ss │ ├── sieve │ │ ├── sieve.scm │ │ └── test.ss │ ├── grains │ │ ├── grains.scm │ │ └── example.scm │ ├── affine-cipher │ │ ├── affine-cipher.scm │ │ └── test.ss │ ├── atbash-cipher │ │ ├── atbash-cipher.scm │ │ ├── test.ss │ │ └── example.scm │ └── difference-of-squares │ │ ├── difference-of-squares.scm │ │ └── example.scm ├── skeleton-makefile ├── docs │ ├── ABOUT.ss │ ├── INSTALLATION.ss │ └── TESTS.ss └── tracks.txt ├── script ├── fetch-tracks.sh └── ci.ss ├── docs ├── SNIPPET.txt ├── INSTALLATION.md ├── TESTS.md ├── ABOUT.md ├── LEARNING.md └── config.json ├── .gitignore ├── load.ss ├── reference └── implementing-a-concept-exercise.md ├── LICENSE └── code └── lint.sls /.github/stale.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/version: -------------------------------------------------------------------------------- 1 | 1.6.0 -------------------------------------------------------------------------------- /exercises/practice/forth/.meta/version: -------------------------------------------------------------------------------- 1 | 1.7.1 -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/version: -------------------------------------------------------------------------------- 1 | 1.6.0 -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/version: -------------------------------------------------------------------------------- 1 | 1.5.0 -------------------------------------------------------------------------------- /exercises/practice/change/.meta/version: -------------------------------------------------------------------------------- 1 | 1.3.0 -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/version: -------------------------------------------------------------------------------- 1 | 2.3.0 -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/version: -------------------------------------------------------------------------------- 1 | 1.0.0 -------------------------------------------------------------------------------- /exercises/practice/octal/.meta/version: -------------------------------------------------------------------------------- 1 | 0.1 2 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/version: -------------------------------------------------------------------------------- 1 | 2.0.0 -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/transpose/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/version: -------------------------------------------------------------------------------- 1 | 1.4.0 -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/version: -------------------------------------------------------------------------------- 1 | 2.0.0 2 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/version: -------------------------------------------------------------------------------- 1 | 1.7.0 2 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/.meta/version: -------------------------------------------------------------------------------- 1 | 2.0.0 -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/version: -------------------------------------------------------------------------------- 1 | 1.3.0 -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/phone-number/.meta/version: -------------------------------------------------------------------------------- 1 | 1.7.0 -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/version: -------------------------------------------------------------------------------- 1 | 2.3.0 -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.1 2 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.1 -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/version: -------------------------------------------------------------------------------- 1 | 2.0.0 -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/version: -------------------------------------------------------------------------------- 1 | 1.3.0 -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/version: -------------------------------------------------------------------------------- 1 | 1.5.0 -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/version: -------------------------------------------------------------------------------- 1 | 1.3.0 -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 2 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/version: -------------------------------------------------------------------------------- 1 | 1.1.0 2 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/version: -------------------------------------------------------------------------------- 1 | 1.2.0 -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/version: -------------------------------------------------------------------------------- 1 | 1.5.0 2 | -------------------------------------------------------------------------------- /input/exercises/forth/forth.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (forth program) 3 | 'implement-me!) 4 | 5 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/accumulate.scm: -------------------------------------------------------------------------------- 1 | (define (accumulate f xs) 2 | 'implement-me!) 3 | -------------------------------------------------------------------------------- /exercises/practice/forth/forth.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (forth program) 3 | 'implement-me!) 4 | 5 | -------------------------------------------------------------------------------- /exercises/practice/octal/octal.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (to-decimal s) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/acronym/acronym.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (acronym test) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/bob/bob.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (response-for message) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/trinary/trinary.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (to-decimal s) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/bob/bob.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (response-for message) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/leap/leap.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (leap-year? year) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/leap/leap.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (leap-year? year) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/triangle/triangle.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (triangle a b c) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/hello-world/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define hello-world 4 | "Hello, World!") 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/pangram/pangram.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pangram? phrase) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/change/change.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (change amount coins) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/pangram/pangram.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pangram? phrase) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/raindrops.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (convert number) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/roman-numerals.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (roman n) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/anagram/anagram.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (anagram target words) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/change/change.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (change amount coins) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/hello-world/hello-world.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (hello-world) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/raindrops/raindrops.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (convert number) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/transpose/transpose.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (transpose matrix) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/two-fer/two-fer.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (two-fer . maybe-name) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/anagram/anagram.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (anagram target words) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define hello-world 4 | "Hello, World!") 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/hello-world.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define hello-world 4 | "Goodbye, Mars!") 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/prime-factors.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (factorize n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/transpose/transpose.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (transpose matrix) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/two-fer.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (two-fer . maybe-name) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/perfect-numbers/perfect-numbers.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (classify n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/prime-factors/prime-factors.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (factorize n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/scrabble-score/scrabble-score.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (score word) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/word-count/word-count.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (word-count sentence) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /script/fetch-tracks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | grep 'href=\"/tracks' $1 | awk -F '(=| |>|<|"|/)' '{print $11}' > $2 4 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/perfect-numbers.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (classify n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/phone-number.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (clean phone-number) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/scrabble-score.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (score word) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/word-count/word-count.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (word-count sentence) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/collatz-conjecture/collatz-conjecture.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (collatz n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/matching-brackets/matching-brackets.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (balanced? string) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/phone-number/phone-number.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (clean phone-number) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/binary-search.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (binary-search array target) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/collatz-conjecture.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (collatz n) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /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/matching-brackets/matching-brackets.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (balanced? string) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/queen-attack.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (attacking? white black) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/rna-transcription.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (dna->rna dna) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/binary-search/binary-search.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (binary-search array target) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/hamming/hamming.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (hamming-distance strand-a strand-b) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/knapsack/knapsack.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (knapsack capacity weights values) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/queen-attack/queen-attack.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (attacking? white black) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/rna-transcription/rna-transcription.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (dna->rna dna) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/rotational-cipher/rotational-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (rotate phrase dx) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/armstrong-numbers.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (armstrong-number? n) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /exercises/practice/hamming/hamming.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (hamming-distance strand-a strand-b) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/knapsack.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (knapsack capacity weights values) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/nucleotide-count.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (nucleotide-count dna) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/rotational-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (rotate phrase dx) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/nucleotide-count/nucleotide-count.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (nucleotide-count dna) 4 | 'implement-me!) 5 | 6 | -------------------------------------------------------------------------------- /input/exercises/pascals-triangle/pascals-triangle.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pascals-triangle n) 4 | 'implement-me!) 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/SNIPPET.txt: -------------------------------------------------------------------------------- 1 | 2 | (let ((quine '((lambda (q) `(,q ',q)) 3 | '(lambda (q) `(,q ',q))))) 4 | (equal? quine (eval quine))) 5 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/pascals-triangle.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pascals-triangle n) 4 | 'implement-me!) 5 | 6 | 7 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/sum-of-multiples.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (sum-of-multiples ints limit) 4 | 'implement-me!) 5 | -------------------------------------------------------------------------------- /input/exercises/sieve/sieve.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs) 2 | (rnrs arithmetic bitwise)) 3 | 4 | (define (sieve n) 5 | 'implement-me!) 6 | 7 | 8 | -------------------------------------------------------------------------------- /exercises/practice/sieve/sieve.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs) 2 | (rnrs arithmetic bitwise)) 3 | 4 | (define (sieve n) 5 | 'implement-me!) 6 | 7 | 8 | -------------------------------------------------------------------------------- /input/exercises/grains/grains.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square n) 4 | 'implement-me!) 5 | 6 | (define total 7 | 'implement-me!) 8 | 9 | -------------------------------------------------------------------------------- /exercises/practice/grains/grains.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square n) 4 | 'implement-me!) 5 | 6 | (define total 7 | 'implement-me!) 8 | 9 | -------------------------------------------------------------------------------- /input/exercises/transpose/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (transpose xs) 4 | (if (null? xs) 5 | '() 6 | (apply map list xs))) 7 | 8 | -------------------------------------------------------------------------------- /exercises/practice/strain/strain.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (keep pred seq) 4 | 'implement-me!) 5 | 6 | (define (discard pred seq) 7 | 'implement-me!) 8 | -------------------------------------------------------------------------------- /exercises/practice/transpose/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (transpose xs) 4 | (if (null? xs) 5 | '() 6 | (apply map list xs))) 7 | 8 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | See if you can clearly separate responsibilities in your code. 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /input/exercises/affine-cipher/affine-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode key text) 4 | 'implement-me!) 5 | 6 | (define (decode key text) 7 | 'implement-me!) 8 | -------------------------------------------------------------------------------- /input/exercises/atbash-cipher/atbash-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode phrase) 4 | 'implement-me!) 5 | 6 | (define (decode phrase) 7 | 'implement-me!) 8 | 9 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/affine-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode key text) 4 | 'implement-me!) 5 | 6 | (define (decode key text) 7 | 'implement-me!) 8 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/atbash-cipher.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode phrase) 4 | 'implement-me!) 5 | 6 | (define (decode phrase) 7 | 'implement-me!) 8 | 9 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | The tests expect an error to be reported for out of range inputs. 6 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (define (accumulate f xs) 2 | (cond 3 | [(null? xs) '()] 4 | [else (cons (f (car xs)) 5 | (accumulate f (cdr xs)))])) 6 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/robot-name.scm: -------------------------------------------------------------------------------- 1 | (define-module (robot) 2 | #:export (build-robot 3 | robot-name 4 | reset-name) 5 | #:autoload (srfi srfi-1) (iota)) 6 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | For scheme, you may want to look into one of `error`, `assert`, or `raise`. 6 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | Consider inputs case insensitive and allow more than one of each required char. 6 | -------------------------------------------------------------------------------- /input/exercises/collatz-conjecture/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (collatz n) 3 | (cond ((= n 1) 0) 4 | ((even? n) (+ 1 (collatz (/ n 2)))) 5 | (else (+ 1 (collatz (+ 1 (* 3 n))))))) 6 | 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | .#* 4 | bin/* 5 | _build/* 6 | closet/track-configs.fasl 7 | closet/json/* 8 | *~ 9 | *.html 10 | ci 11 | problem-specifications/* 12 | !bin/fetch-configlet 13 | -------------------------------------------------------------------------------- /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/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (collatz n) 3 | (cond ((= n 1) 0) 4 | ((even? n) (+ 1 (collatz (/ n 2)))) 5 | (else (+ 1 (collatz (+ 1 (* 3 n))))))) 6 | 7 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | 4 | ## Track Specific Notes 5 | 6 | You must return the anagrams in the same order as they are listed in the candidate words. 7 | -------------------------------------------------------------------------------- /input/exercises/leap/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (leap-year? year) 4 | (and (zero? (modulo year 4)) 5 | (or (not (zero? (modulo year 100))) 6 | (zero? (modulo year 400))))) 7 | 8 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | Don't worry about validating input for this track -- all inputs will be natural numbers. 6 | -------------------------------------------------------------------------------- /input/exercises/two-fer/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (two-fer . maybe-name) 4 | (format #f "One for ~a, one for me." 5 | (if (pair? maybe-name) 6 | (car maybe-name) 7 | "you"))) 8 | 9 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (leap-year? year) 4 | (and (zero? (modulo year 4)) 5 | (or (not (zero? (modulo year 100))) 6 | (zero? (modulo year 400))))) 7 | 8 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (two-fer . maybe-name) 4 | (format #f "One for ~a, one for me." 5 | (if (pair? maybe-name) 6 | (car maybe-name) 7 | "you"))) 8 | 9 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | Your solution may be a procedure that returns the desired string or a variable whose value is that string. 6 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "Say Hi!" equal? hello-world '() 5 | "Hello, World!"))) 6 | 7 | (run-with-cli "hello-world.scm" (list test-cases)) 8 | 9 | -------------------------------------------------------------------------------- /input/exercises/grains/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square n) 4 | (when (or (< n 1) (> n 64)) 5 | (error 'square "out of range" n)) 6 | (ash 1 (1- n))) 7 | 8 | (define total 9 | (1- (* 2 (square 64)))) 10 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | 4 | ## Track Specific Notes 5 | 6 | If the element is not present in the array, return the symbol `'not-found`. 7 | The array will be passed as a vector. 8 | -------------------------------------------------------------------------------- /exercises/practice/grains/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square n) 4 | (when (or (< n 1) (> n 64)) 5 | (error 'square "out of range" n)) 6 | (ash 1 (1- n))) 7 | 8 | (define total 9 | (1- (* 2 (square 64)))) 10 | -------------------------------------------------------------------------------- /load.ss: -------------------------------------------------------------------------------- 1 | (unless (assoc "code" (library-directories)) 2 | (library-directories (cons "code" (library-directories)))) 3 | 4 | (import (json) 5 | (outils) 6 | (lint) 7 | (markdown)) 8 | 9 | (load "code/track.ss") 10 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/list-ops.scm: -------------------------------------------------------------------------------- 1 | (define-module (list-ops) 2 | #:export (my-length 3 | my-reverse 4 | my-map 5 | my-filter 6 | my-fold 7 | my-append 8 | my-concatenate 9 | )) 10 | -------------------------------------------------------------------------------- /input/exercises/difference-of-squares/difference-of-squares.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square-of-sum n) 4 | 'implement-me!) 5 | 6 | (define (sum-of-squares n) 7 | 'implement-me!) 8 | 9 | (define (difference-of-squares n) 10 | 'implement-me!) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/difference-of-squares.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square-of-sum n) 4 | 'implement-me!) 5 | 6 | (define (sum-of-squares n) 7 | 'implement-me!) 8 | 9 | (define (difference-of-squares n) 10 | 'implement-me!) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/INSTALLATION.md: -------------------------------------------------------------------------------- 1 | 2 | ## Installing a scheme 3 | 4 | 5 | ### ChezScheme 6 | 7 | Follow the instructions at [ChezScheme](https://cisco.github.io/ChezScheme/#get)\. 8 | 9 | ### GNU Guile 10 | 11 | Follow the instructions at [GNU Guile](https://www.gnu.org/software/guile/download/)\. 12 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (use-modules (ice-9 regex)) 2 | 3 | (define (acronym text) 4 | (apply (compose string-upcase string-append) 5 | (map (lambda (ss) 6 | (string-take (match:substring ss) 1)) 7 | (list-matches "[[:alpha:]|']+" text)))) 8 | -------------------------------------------------------------------------------- /input/exercises/rna-transcription/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (dna->rna dna) 4 | (list->string 5 | (map (lambda (nucleotide) 6 | (case nucleotide 7 | ((#\G) #\C) 8 | ((#\C) #\G) 9 | ((#\T) #\A) 10 | ((#\A) #\U))) 11 | (string->list dna)))) 12 | 13 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | For this track, each queen's position will be represented as a list containing the row and the column. 6 | You should assume all inputs are valid, there's no need to report errors. 7 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | One way to get optional arguments in scheme is by specifying the arguments as a list. 6 | Two ways to do that are: `(define (two-fer . args) ...)` or `(define two-fer (lambda args ...))`. 7 | -------------------------------------------------------------------------------- /input/exercises/pascals-triangle/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pascals-triangle n) 4 | (build n '(1))) 5 | 6 | (define (build n row) 7 | (if (zero? n) 8 | '() 9 | (cons row 10 | (build (- n 1) 11 | (map + `(0 ,@row) `(,@row 0)))))) 12 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pascals-triangle n) 4 | (build n '(1))) 5 | 6 | (define (build n row) 7 | (if (zero? n) 8 | '() 9 | (cons row 10 | (build (- n 1) 11 | (map + `(0 ,@row) `(,@row 0)))))) 12 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (dna->rna dna) 4 | (list->string 5 | (map (lambda (nucleotide) 6 | (case nucleotide 7 | ((#\G) #\C) 8 | ((#\C) #\G) 9 | ((#\T) #\A) 10 | ((#\A) #\U))) 11 | (string->list dna)))) 12 | 13 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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/forth/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | The input is presented as a list of strings. 6 | Definitions are presented as `: var x ... ;` where `var` is bound to what follows. 7 | Otherwise the string represents a sequence of stack manipulations. 8 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (define (keep pred seq) 2 | (cond 3 | [(null? seq) '()] 4 | [(pred (car seq)) (cons (car seq) 5 | (keep pred (cdr seq)))] 6 | [else (keep pred (cdr seq))])) 7 | 8 | (define (discard pred seq) 9 | (keep (lambda (x) (not (pred x))) seq)) 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /input/skeleton-makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/bob/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/leap/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/shared/.docs/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | Simply type `make chez` if you're using ChezScheme or `make guile` if you're using GNU Guile. 4 | 5 | ## Using the REPL 6 | 7 | - Enter `test.scm` at the repl prompt. 8 | - Develop your solution in the file `problem.scm` reloading as you go. 9 | - Run `(test)` to check your solution. 10 | -------------------------------------------------------------------------------- /exercises/practice/acronym/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/anagram/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/change/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/forth/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/grains/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/hamming/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/octal/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/pangram/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/sieve/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/strain/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/transpose/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/triangle/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/trinary/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/instructions.append.md: -------------------------------------------------------------------------------- 1 | # Instructions append 2 | 3 | ## Track Specific Notes 4 | 5 | In the scheme version the aruguments are the `capacity` of the knapsack and a list of the `weights` and a list of the `values`. 6 | It won't be necessary to validate the input -- the test inputs have valid values and same length lists. 7 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/word-count/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /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/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/Makefile: -------------------------------------------------------------------------------- 1 | solution := 2 | 3 | chez := scheme 4 | guile := guile 5 | 6 | help : 7 | echo 'Run make chez or make guile' 8 | 9 | check-all : chez guile 10 | 11 | chez : 12 | $(chez) --script test.scm $(solution) 13 | 14 | guile : 15 | $(guile) test.scm $(solution) 16 | 17 | .PHONY : help check-all chez guile 18 | -------------------------------------------------------------------------------- /input/exercises/pangram/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pangram? phrase) 4 | (let ((phrase (string->list 5 | (string-downcase phrase)))) 6 | (let loop ((x 97)) 7 | (if (> x 122) 8 | #t 9 | (and (memq (integer->char x) 10 | phrase) 11 | (loop (1+ x))))))) 12 | 13 | -------------------------------------------------------------------------------- /input/exercises/hamming/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (hamming-distance strand-a strand-b) 4 | (when (not (= (string-length strand-a) 5 | (string-length strand-b))) 6 | (error 'hamming "unequal strands" strand-a strand-b)) 7 | (length (filter not (map char=? 8 | (string->list strand-a) 9 | (string->list strand-b))))) 10 | 11 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (pangram? phrase) 4 | (let ((phrase (string->list 5 | (string-downcase phrase)))) 6 | (let loop ((x 97)) 7 | (if (> x 122) 8 | #t 9 | (and (memq (integer->char x) 10 | phrase) 11 | (loop (1+ x))))))) 12 | 13 | -------------------------------------------------------------------------------- /reference/implementing-a-concept-exercise.md: -------------------------------------------------------------------------------- 1 | # How to implement an Scheme concept exercise 2 | 3 | TODO: describe how to implement a concept exercise for the Scheme track. For inspiration, check out the [C# version of this file][csharp-implementing]. 4 | 5 | [csharp-implementing]: https://github.com/exercism/v3/blob/main/csharp/reference/implementing-a-concept-exercise.md 6 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (hamming-distance strand-a strand-b) 4 | (when (not (= (string-length strand-a) 5 | (string-length strand-b))) 6 | (error 'hamming "unequal strands" strand-a strand-b)) 7 | (length (filter not (map char=? 8 | (string->list strand-a) 9 | (string->list strand-b))))) 10 | 11 | -------------------------------------------------------------------------------- /input/exercises/difference-of-squares/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square x) 4 | (* x x)) 5 | 6 | (define (square-of-sum n) 7 | (square (apply + (iota (1+ n))))) 8 | 9 | (define (sum-of-squares n) 10 | (apply + (map square (iota (1+ n))))) 11 | 12 | (define (difference-of-squares n) 13 | (- (square-of-sum n) 14 | (sum-of-squares n))) 15 | 16 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (square x) 4 | (* x x)) 5 | 6 | (define (square-of-sum n) 7 | (square (apply + (iota (1+ n))))) 8 | 9 | (define (sum-of-squares n) 10 | (apply + (map square (iota (1+ n))))) 11 | 12 | (define (difference-of-squares n) 13 | (- (square-of-sum n) 14 | (sum-of-squares n))) 15 | 16 | -------------------------------------------------------------------------------- /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/shared/.docs/help.md: -------------------------------------------------------------------------------- 1 | # Help 2 | 3 | To get help if you're having trouble, you can use one of the following resources: 4 | 5 | - [/r/scheme](https://www.reddit.com/r/scheme) is the Scheme subreddit. 6 | - [StackOverflow](http://stackoverflow.com/questions/tagged/scheme) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. 7 | -------------------------------------------------------------------------------- /docs/TESTS.md: -------------------------------------------------------------------------------- 1 | 2 | ## Running and testing your solutions 3 | 4 | 5 | ### From the command line 6 | 7 | Simply type `make chez` if you're using ChezScheme or `make guile` if you're using GNU Guile\. 8 | 9 | ### From a REPL 10 | 11 | * Enter `test.scm` at the repl prompt\. 12 | * Develop your solution in the file `problem.scm` reloading as you go\. 13 | * Run `(test)` to check your solution\. 14 | -------------------------------------------------------------------------------- /exercises/practice/forth/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "forth.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Implement an evaluator for a very simple subset of Forth." 18 | } 19 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /input/exercises/binary-search/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (binary-search array target) 3 | (let loop ((a 0) (b (1- (vector-length array)))) 4 | (if (> a b) 5 | 'not-found 6 | (let ((m (ash (+ a b) -1))) 7 | (cond 8 | ((< (vector-ref array m) target) (loop (1+ m) b)) 9 | ((> (vector-ref array m) target) (loop a (1- m))) 10 | (else m)))))) 11 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.meta/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (binary-search array target) 3 | (let loop ((a 0) (b (1- (vector-length array)))) 4 | (if (> a b) 5 | 'not-found 6 | (let ((m (ash (+ a b) -1))) 7 | (cond 8 | ((< (vector-ref array m) target) (loop (1+ m) b)) 9 | ((> (vector-ref array m) target) (loop a (1- m))) 10 | (else m)))))) 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 | -------------------------------------------------------------------------------- /input/exercises/raindrops/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (convert number) 4 | (let* ((rules '((3 . "Pling") (5 . "Plang") (7 . "Plong"))) 5 | (helper (lambda (k.w word) 6 | (if (zero? (modulo number (car k.w))) 7 | (string-append (cdr k.w) word) 8 | word))) 9 | (result (fold-right helper "" rules))) 10 | (if (equal? "" result) 11 | (number->string number) 12 | result))) 13 | 14 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (convert number) 4 | (let* ((rules '((3 . "Pling") (5 . "Plang") (7 . "Plong"))) 5 | (helper (lambda (k.w word) 6 | (if (zero? (modulo number (car k.w))) 7 | (string-append (cdr k.w) word) 8 | word))) 9 | (result (fold-right helper "" rules))) 10 | (if (equal? "" result) 11 | (number->string number) 12 | result))) 13 | 14 | -------------------------------------------------------------------------------- /docs/ABOUT.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | Scheme is a statically scoped and properly tail\-recursive dialect of the Lisp programming language invented by Guy Lewis Steele Jr\. and Gerald Jay Sussman\. 4 | It was designed to have an exceptionally clear and simple semantics and few different ways to form expressions\. 5 | A wide variety of programming paradigms, including functional, imperative, and message passing styles, find convenient expression in Scheme\. 6 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "matching-brackets.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Make sure the brackets and braces all match.", 18 | "source": "Ginna Baker" 19 | } 20 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "zero steps for one" = collatz '(1) 0) 5 | (test-success "divide if even" = collatz '(16) 4) 6 | (test-success "even and odd steps" = collatz '(12) 9) 7 | (test-success "large number of even and odd steps" = collatz 8 | '(1000000) 152))) 9 | 10 | (run-with-cli "collatz-conjecture.scm" (list test-cases)) 11 | 12 | -------------------------------------------------------------------------------- /exercises/practice/octal/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (define (to-decimal s) 2 | (call/cc 3 | (lambda (return) 4 | (let loop ([cs (string->list s)] 5 | [dec 0]) 6 | (cond 7 | [(null? cs) dec] 8 | [(char<=? #\0 (car cs) #\7) 9 | (loop (cdr cs) (+ (* dec 8) 10 | (- (char->integer (car cs)) 11 | (char->integer #\0))))] 12 | [else (return 0)]))))) 13 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "no name given" equal? two-fer '() 5 | "One for you, one for me.") 6 | (test-success "a name given" equal? two-fer '("Alice") 7 | "One for Alice, one for me.") 8 | (test-success "another name given" equal? two-fer '("Bob") 9 | "One for Bob, one for me."))) 10 | 11 | (run-with-cli "two-fer.scm" (list test-cases)) 12 | 13 | -------------------------------------------------------------------------------- /input/exercises/queen-attack/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (attacking? white black) 3 | (or (same-row? white black) 4 | (same-column? white black) 5 | (same-diagonal? white black))) 6 | 7 | (define (same-row? a b) 8 | (= (car a) (car b))) 9 | 10 | (define (same-column? a b) 11 | (= (cadr a) (cadr b))) 12 | 13 | (define (same-diagonal? a b) 14 | (or (= (apply + a) (apply + b)) 15 | (= (apply - a) (apply - b)))) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (attacking? white black) 3 | (or (same-row? white black) 4 | (same-column? white black) 5 | (same-diagonal? white black))) 6 | 7 | (define (same-row? a b) 8 | (= (car a) (car b))) 9 | 10 | (define (same-column? a b) 11 | (= (cadr a) (cadr b))) 12 | 13 | (define (same-diagonal? a b) 14 | (or (= (apply + a) (apply + b)) 15 | (= (apply - a) (apply - b)))) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /exercises/practice/acronym/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "acronym.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Convert a long phrase to its acronym.", 18 | "source": "Julien Vanier", 19 | "source_url": "https://github.com/monkbroc" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/pangram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "pangram.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Determine if a sentence is a pangram.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Pangram" 20 | } 21 | -------------------------------------------------------------------------------- /input/exercises/anagram/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (canonicalize word) 4 | (list-sort charlist word))) 5 | 6 | (define (anagram target words) 7 | (let ((target (string-downcase target))) 8 | (filter (lambda (word) 9 | (let ((word (string-downcase word))) 10 | (and (equal? (canonicalize word) (canonicalize target)) 11 | (not (equal? word target))))) 12 | words))) 13 | 14 | 15 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (canonicalize word) 4 | (list-sort charlist word))) 5 | 6 | (define (anagram target words) 7 | (let ((target (string-downcase target))) 8 | (filter (lambda (word) 9 | (let ((word (string-downcase word))) 10 | (and (equal? (canonicalize word) (canonicalize target)) 11 | (not (equal? word target))))) 12 | words))) 13 | 14 | 15 | -------------------------------------------------------------------------------- /input/docs/ABOUT.ss: -------------------------------------------------------------------------------- 1 | 2 | (sentence 3 | "Scheme is a statically scoped and properly tail-recursive dialect of the Lisp programming language invented by Guy Lewis Steele Jr. and Gerald Jay Sussman.") 4 | (sentence 5 | "It was designed to have an exceptionally clear and simple semantics and few different ways to form expressions.") 6 | (sentence 7 | "A wide variety of programming paradigms, including functional, imperative, and message passing styles, find convenient expression in Scheme.") 8 | 9 | -------------------------------------------------------------------------------- /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/binary-search/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "binary-search.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Implement a binary search algorithm.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Binary_search_algorithm" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/strain/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "strain.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Implement the `keep` and `discard` operation on collections.", 18 | "source": "Conversation with James Edward Gray II", 19 | "source_url": "http://graysoftinc.com/" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "armstrong-numbers.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Determine if a number is an Armstrong number.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (delete x xs) 4 | (filter (lambda (y) (not (equal? x y))) xs)) 5 | 6 | (define (any f xs) 7 | (fold-left (lambda (r x) (or r (f x))) #f xs)) 8 | 9 | (define (sum-of-multiples ints limit) 10 | (apply + (filter (lambda (n) 11 | (any (lambda (i) 12 | (zero? (remainder n i))) 13 | (delete 0 ints))) 14 | (cdr (iota limit))))) 15 | -------------------------------------------------------------------------------- /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/change/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine the fewest number of coins to give a customer so that the sum of their values equals the correct amount of change. 4 | 5 | ## Examples 6 | 7 | - An amount of 15 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5 and one coin of value 10, or [5, 10]. 8 | - An amount of 40 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5, one coin of value 10, and one coin of value 25, or [5, 10, 25]. 9 | -------------------------------------------------------------------------------- /exercises/practice/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/roman-numerals/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "roman-numerals.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Convert modern Arabic numbers into Roman numerals.", 18 | "source": "The Roman Numeral Kata", 19 | "source_url": "https://codingdojo.org/kata/RomanNumerals/" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/list-ops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "pminten" 4 | ], 5 | "contributors": [ 6 | "canweriotnow", 7 | "cyborgsphinx", 8 | "guygastineau", 9 | "jitwit", 10 | "kytrinyx" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "list-ops.scm" 15 | ], 16 | "test": [ 17 | "test.scm", 18 | "test-util.ss" 19 | ], 20 | "example": [ 21 | ".meta/example.scm" 22 | ] 23 | }, 24 | "blurb": "Implement basic list operations" 25 | } 26 | -------------------------------------------------------------------------------- /input/exercises/prime-factors/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (factorize n) 4 | (if (even? n) 5 | (cons 2 (factorize (/ n 2))) 6 | (let loop ((d 3) (n n)) 7 | (cond ((< n (square d)) 8 | (if (= n 1) '() (list n))) 9 | ((divides? d n) 10 | (cons d (loop d (/ n d)))) 11 | (else 12 | (loop (+ d 2) n)))))) 13 | 14 | (define (square x) 15 | (* x x)) 16 | 17 | (define (divides? d n) 18 | (zero? (modulo n d))) 19 | 20 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "collatz-conjecture.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Collatz_conjecture" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (factorize n) 4 | (if (even? n) 5 | (cons 2 (factorize (/ n 2))) 6 | (let loop ((d 3) (n n)) 7 | (cond ((< n (square d)) 8 | (if (= n 1) '() (list n))) 9 | ((divides? d n) 10 | (cons d (loop d (/ n d)))) 11 | (else 12 | (loop (+ d 2) n)))))) 13 | 14 | (define (square x) 15 | (* x x)) 16 | 17 | (define (divides? d n) 18 | (zero? (modulo n d))) 19 | 20 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "rotational-cipher.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.", 18 | "source": "Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sieve.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.", 18 | "source": "Sieve of Eratosthenes at Wikipedia", 19 | "source_url": "https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/armstrong-numbers/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (list-digits n) 4 | (let loop ([n n] 5 | [ms '()]) 6 | (if (zero? n) 7 | ms 8 | (let-values ([(d m) (div-and-mod n 10)]) 9 | (loop d (cons m ms)))))) 10 | 11 | (define (armstrong-number? n) 12 | (let* ([digits (list-digits n)] 13 | [number-of-digits (length digits)]) 14 | (= n 15 | (apply + (map (lambda (d) 16 | (expt d number-of-digits)) 17 | digits))))) 18 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "robot-name.scm" 14 | ], 15 | "test": [ 16 | "test.scm" 17 | ], 18 | "example": [ 19 | ".meta/example.scm" 20 | ] 21 | }, 22 | "blurb": "Manage robot factory settings.", 23 | "source": "A debugging session with Paul Blackwell at gSchool." 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "triangle.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.", 18 | "source": "The Ruby Koans triangle project, parts 1 & 2", 19 | "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com" 20 | } 21 | -------------------------------------------------------------------------------- /input/docs/INSTALLATION.ss: -------------------------------------------------------------------------------- 1 | ;;https://www.gnu.org/software/guile/download/ 2 | ;;https://cisco.github.io/ChezScheme/#get 3 | 4 | (section 5 | "Installing a scheme" 6 | (subsection "ChezScheme" 7 | (sentence 8 | "Follow the instructions at " 9 | (link "ChezScheme" "https://cisco.github.io/ChezScheme/#get") ".")) 10 | (subsection "GNU Guile" 11 | (sentence 12 | "Follow the instructions at " 13 | (link "GNU Guile" "https://www.gnu.org/software/guile/download/") "."))) 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: scheme / main 2 | 3 | on: 4 | push: 5 | branches: [master, main] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | ci: 11 | runs-on: ubuntu-24.04 12 | 13 | steps: 14 | - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 15 | 16 | - name: Install project dependencies 17 | run: | 18 | sudo apt-get update 19 | sudo apt-get install guile-3.0 chezscheme 20 | 21 | - name: Run exercism/scheme ci (runs tests) for all exercises 22 | run: make ci 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /input/exercises/matching-brackets/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (balanced? string) 3 | (null? 4 | (fold-right evolve-stack '() (filter bracket? (string->list string))))) 5 | 6 | (define (evolve-stack next stack) 7 | (cond ((null? stack) (list next)) 8 | ((closing? next (car stack)) (cdr stack)) 9 | (else (cons next stack)))) 10 | 11 | (define (bracket? char) 12 | (memq char (string->list "{}()[]"))) 13 | 14 | (define (closing? x y) 15 | (or (and (eq? x #\() (eq? y #\))) 16 | (and (eq? x #\[) (eq? y #\])) 17 | (and (eq? x #\{) (eq? y #\})))) 18 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "herwinw" 4 | ], 5 | "contributors": [ 6 | "benreyn", 7 | "guygastineau", 8 | "jitwit" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "two-fer.scm" 13 | ], 14 | "test": [ 15 | "test.scm", 16 | "test-util.ss" 17 | ], 18 | "example": [ 19 | ".meta/example.scm" 20 | ] 21 | }, 22 | "blurb": "Create a sentence of the form \"One for X, one for me.\".", 23 | "source_url": "https://github.com/exercism/problem-specifications/issues/757" 24 | } 25 | -------------------------------------------------------------------------------- /exercises/practice/matching-brackets/.meta/example.scm: -------------------------------------------------------------------------------- 1 | 2 | (define (balanced? string) 3 | (null? 4 | (fold-right evolve-stack '() (filter bracket? (string->list string))))) 5 | 6 | (define (evolve-stack next stack) 7 | (cond ((null? stack) (list next)) 8 | ((closing? next (car stack)) (cdr stack)) 9 | (else (cons next stack)))) 10 | 11 | (define (bracket? char) 12 | (memq char (string->list "{}()[]"))) 13 | 14 | (define (closing? x y) 15 | (or (and (eq? x #\() (eq? y #\))) 16 | (and (eq? x #\[) (eq? y #\])) 17 | (and (eq? x #\{) (eq? y #\})))) 18 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "prime-factors.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Compute the prime factors of a given natural number.", 18 | "source": "The Prime Factors Kata by Uncle Bob", 19 | "source_url": "https://web.archive.org/web/20221026171801/http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/sum-of-multiples/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "sum-of-multiples.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", 18 | "source": "A variation on Problem 1 at Project Euler", 19 | "source_url": "https://projecteuler.net/problem=1" 20 | } 21 | -------------------------------------------------------------------------------- /input/exercises/scrabble-score/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (score word) 4 | (define (scrabble-value char) 5 | (cond ((memq char (string->list "aeioulnrst")) 1) 6 | ((memq char (string->list "dg")) 2) 7 | ((memq char (string->list "bcmp")) 3) 8 | ((memq char (string->list "fhvwy")) 4) 9 | ((memq char (string->list "k")) 5) 10 | ((memq char (string->list "jx")) 8) 11 | ((memq char (string->list "qz")) 10) 12 | (else (error 'scrabble-value "idk" char)))) 13 | (apply + (map scrabble-value 14 | (string->list 15 | (string-downcase word))))) 16 | 17 | -------------------------------------------------------------------------------- /exercises/practice/change/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "change.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Correctly determine change to be given using the least number of coins.", 18 | "source": "Software Craftsmanship - Coin Change Kata", 19 | "source_url": "https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (score word) 4 | (define (scrabble-value char) 5 | (cond ((memq char (string->list "aeioulnrst")) 1) 6 | ((memq char (string->list "dg")) 2) 7 | ((memq char (string->list "bcmp")) 3) 8 | ((memq char (string->list "fhvwy")) 4) 9 | ((memq char (string->list "k")) 5) 10 | ((memq char (string->list "jx")) 8) 11 | ((memq char (string->list "qz")) 10) 12 | (else (error 'scrabble-value "idk" char)))) 13 | (apply + (map scrabble-value 14 | (string->list 15 | (string-downcase word))))) 16 | 17 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "trinary.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles.", 18 | "source": "All of Computer Science", 19 | "source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/affine-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "guygastineau" 4 | ], 5 | "contributors": [ 6 | "jitwit" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "affine-cipher.scm" 11 | ], 12 | "test": [ 13 | "test.scm", 14 | "test-util.ss" 15 | ], 16 | "example": [ 17 | ".meta/example.scm" 18 | ] 19 | }, 20 | "blurb": "Create an implementation of the Affine cipher, an ancient encryption algorithm from the Middle East.", 21 | "source": "Wikipedia", 22 | "source_url": "https://en.wikipedia.org/wiki/Affine_cipher" 23 | } 24 | -------------------------------------------------------------------------------- /input/tracks.txt: -------------------------------------------------------------------------------- 1 | ballerina 2 | bash 3 | c 4 | csharp 5 | cpp 6 | cfml 7 | clojure 8 | coffeescript 9 | common-lisp 10 | crystal 11 | d 12 | dart 13 | delphi 14 | elixir 15 | elm 16 | elisp 17 | erlang 18 | fsharp 19 | go 20 | groovy 21 | haskell 22 | java 23 | javascript 24 | julia 25 | kotlin 26 | lfe 27 | lua 28 | mips 29 | nim 30 | objective-c 31 | ocaml 32 | perl5 33 | perl6 34 | pharo-smalltalk 35 | php 36 | plsql 37 | prolog 38 | purescript 39 | python 40 | r 41 | racket 42 | reasonml 43 | ruby 44 | rust 45 | scala 46 | scheme 47 | sml 48 | swift 49 | typescript 50 | vimscript 51 | x86-64-assembly 52 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "contributors": [ 6 | "guygastineau" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "pascals-triangle.scm" 11 | ], 12 | "test": [ 13 | "test.scm", 14 | "test-util.ss" 15 | ], 16 | "example": [ 17 | ".meta/example.scm" 18 | ] 19 | }, 20 | "blurb": "Compute Pascal's triangle up to a given number of rows.", 21 | "source": "Pascal's Triangle at Wolfram Math World", 22 | "source_url": "https://www.wolframalpha.com/input/?i=Pascal%27s+triangle" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "wwest4" 4 | ], 5 | "contributors": [ 6 | "guygastineau", 7 | "jitwit", 8 | "yurrriq" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "word-count.scm" 13 | ], 14 | "test": [ 15 | "test.scm", 16 | "test-util.ss" 17 | ], 18 | "example": [ 19 | ".meta/example.scm" 20 | ] 21 | }, 22 | "blurb": "Given a phrase, count the occurrences of each word in that phrase.", 23 | "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." 24 | } 25 | -------------------------------------------------------------------------------- /input/exercises/leap/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | eqv? 4 | leap-year? 5 | '(,(lookup 'year (lookup 'input test))) 6 | ,(lookup 'expected test))) 7 | 8 | (let ((spec (get-test-specification 'leap))) 9 | (put-problem! 10 | 'leap 11 | `((test . ,(map parse-test (lookup 'cases spec))) 12 | (stubs leap-year?) 13 | (version . ,(lookup 'version spec)) 14 | (skeleton . ,"leap.scm") 15 | (solution . ,"example.scm") 16 | (markdown . ,(splice-exercism 'leap))))) 17 | 18 | -------------------------------------------------------------------------------- /exercises/practice/transpose/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "transpose.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Take input text and output it transposed.", 18 | "source": "Reddit r/dailyprogrammer challenge #270 [Easy].", 19 | "source_url": "https://web.archive.org/web/20230630051421/https://old.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text/" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/leap/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "leap.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Determine whether a given year is a leap year.", 24 | "source": "CodeRanch Cattle Drive, Assignment 3", 25 | "source_url": "https://coderanch.com/t/718816/Leap" 26 | } 27 | -------------------------------------------------------------------------------- /input/exercises/raindrops/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | convert 5 | '(,(lookup-spine '(input number) test)) 6 | ,(lookup 'expected test))) 7 | 8 | (let ((spec (get-test-specification 'raindrops))) 9 | (put-problem! 10 | 'raindrops 11 | `((test . ,(map parse-test (lookup 'cases spec))) 12 | (stubs convert) 13 | (version . ,(lookup 'version spec)) 14 | (skeleton . ,"raindrops.scm") 15 | (solution . ,"example.scm") 16 | (markdown . ,(splice-exercism 'raindrops))))) 17 | 18 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "contributors": [ 6 | "guygastineau" 7 | ], 8 | "files": { 9 | "solution": [ 10 | "knapsack.scm" 11 | ], 12 | "test": [ 13 | "test.scm", 14 | "test-util.ss" 15 | ], 16 | "example": [ 17 | ".meta/example.scm" 18 | ] 19 | }, 20 | "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.", 21 | "source": "Wikipedia", 22 | "source_url": "https://en.wikipedia.org/wiki/Knapsack_problem" 23 | } 24 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "queen-attack.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "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.", 18 | "source": "J Dalbey's Programming Practice problems", 19 | "source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "mattwellss" 4 | ], 5 | "contributors": [ 6 | "benreyn", 7 | "guygastineau", 8 | "jitwit" 9 | ], 10 | "files": { 11 | "solution": [ 12 | "atbash-cipher.scm" 13 | ], 14 | "test": [ 15 | "test.scm", 16 | "test-util.ss" 17 | ], 18 | "example": [ 19 | ".meta/example.scm" 20 | ] 21 | }, 22 | "blurb": "Create an implementation of the Atbash cipher, an ancient encryption system created in the Middle East.", 23 | "source": "Wikipedia", 24 | "source_url": "https://en.wikipedia.org/wiki/Atbash" 25 | } 26 | -------------------------------------------------------------------------------- /input/exercises/scrabble-score/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | = 4 | score 5 | '(,(cdar (lookup 'input test))) 6 | ,(lookup 'expected test))) 7 | 8 | (let ((spec (get-test-specification 'scrabble-score))) 9 | (put-problem! 10 | 'scrabble-score 11 | `((test . ,(map parse-test (lookup 'cases spec))) 12 | (stubs score) 13 | (version . ,(lookup 'version spec)) 14 | (skeleton . "scrabble-score.scm") 15 | (solution . "example.scm") 16 | (markdown . ,(splice-exercism 'scrabble-score))))) 17 | 18 | 19 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [af9ffe10-dc13-42d8-a742-e7bdafac449d] 13 | description = "Say Hi!" 14 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "anagram.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", 24 | "source": "Inspired by the Extreme Startup game", 25 | "source_url": "https://github.com/rchatley/extreme_startup" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/perfect-numbers/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "jitwit" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "perfect-numbers.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.", 18 | "source": "Taken from Chapter 2 of Functional Thinking by Neal Ford.", 19 | "source_url": "https://www.oreilly.com/library/view/functional-thinking/9781449365509/" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Your task is to convert a number from Arabic numerals to Roman numerals. 4 | 5 | For this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999). 6 | 7 | ~~~~exercism/note 8 | There are lots of different ways to convert between Arabic and Roman numerals. 9 | We recommend taking a naive approach first to familiarise yourself with the concept of Roman numerals and then search for more efficient methods. 10 | 11 | Make sure to check out our Deep Dive video at the end to explore the different approaches you can take! 12 | ~~~~ 13 | -------------------------------------------------------------------------------- /input/exercises/rna-transcription/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | dna->rna 5 | '(,(cdar (lookup 'input test))) 6 | ,(lookup 'expected test))) 7 | 8 | (let ((spec (get-test-specification 'rna-transcription))) 9 | (put-problem! 10 | 'rna-transcription 11 | `((test . ,(map parse-test (lookup 'cases spec))) 12 | (stubs dna->rna) 13 | (version . ,(lookup 'version spec)) 14 | (skeleton . "rna-transcription.scm") 15 | (solution . "example.scm") 16 | (markdown . ,(splice-exercism 'rna-transcription))))) 17 | 18 | -------------------------------------------------------------------------------- /exercises/practice/hamming/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "PurityControl" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx", 10 | "yurrriq" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "hamming.scm" 15 | ], 16 | "test": [ 17 | "test.scm", 18 | "test-util.ss" 19 | ], 20 | "example": [ 21 | ".meta/example.scm" 22 | ] 23 | }, 24 | "blurb": "Calculate the Hamming distance between two DNA strands.", 25 | "source": "The Calculating Point Mutations problem at Rosalind", 26 | "source_url": "https://rosalind.info/problems/hamm/" 27 | } 28 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "cyborgsphinx" 4 | ], 5 | "contributors": [ 6 | "benreyn", 7 | "guygastineau", 8 | "herwinw", 9 | "jitwit", 10 | "yurrriq" 11 | ], 12 | "files": { 13 | "solution": [ 14 | "scrabble-score.scm" 15 | ], 16 | "test": [ 17 | "test.scm", 18 | "test-util.ss" 19 | ], 20 | "example": [ 21 | ".meta/example.scm" 22 | ] 23 | }, 24 | "blurb": "Given a word, compute the Scrabble score for that word.", 25 | "source": "Inspired by the Extreme Startup game", 26 | "source_url": "https://github.com/rchatley/extreme_startup" 27 | } 28 | -------------------------------------------------------------------------------- /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/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/octal/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "octal.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Convert a octal number, represented as a string (e.g. '1735263'), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).", 18 | "source": "All of Computer Science", 19 | "source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" 20 | } 21 | -------------------------------------------------------------------------------- /docs/LEARNING.md: -------------------------------------------------------------------------------- 1 | # Learning Scheme 2 | 3 | ## Books 4 | 5 | - [Structure and Interpretation of Computer Programs](http://mitpress.mit.edu/sicp/) 6 | - [The Scheme Programming Language](https://www.scheme.com/tspl4/) 7 | 8 | ## YouTube 9 | 10 | - [Structure and Interpretation of Computer Programs](https://www.youtube.com/watch?v=-J_xL4IGhJA&list=PLE18841CABEA24090) 11 | 12 | ## Online Courses 13 | 14 | - [Structure and Interpretation of Computer Programs](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/) 15 | - [Coursera CS 341](https://www.coursera.org/learn/programming-languages-part-b) 16 | -------------------------------------------------------------------------------- /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/grains/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "grains.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", 24 | "source": "The CodeRanch Cattle Drive, Assignment 6", 25 | "source_url": "https://coderanch.com/wiki/718824/Grains" 26 | } 27 | -------------------------------------------------------------------------------- /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/accumulate/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "tongkiat" 4 | ], 5 | "files": { 6 | "solution": [ 7 | "accumulate.scm" 8 | ], 9 | "test": [ 10 | "test.scm", 11 | "test-util.ss" 12 | ], 13 | "example": [ 14 | ".meta/example.scm" 15 | ] 16 | }, 17 | "blurb": "Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.", 18 | "source": "Conversation with James Edward Gray II", 19 | "source_url": "http://graysoftinc.com/" 20 | } 21 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "nucleotide-count.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", 24 | "source": "The Calculating DNA Nucleotides_problem at Rosalind", 25 | "source_url": "https://rosalind.info/problems/dna/" 26 | } 27 | -------------------------------------------------------------------------------- /input/docs/TESTS.ss: -------------------------------------------------------------------------------- 1 | 2 | (section 3 | "Running and testing your solutions" 4 | (subsection 5 | "From the command line" 6 | (sentence "Simply type " 7 | (inline-code "make chez") 8 | " if you're using ChezScheme or " 9 | (inline-code "make guile") 10 | " if you're using GNU Guile.")) 11 | (subsection 12 | "From a REPL" 13 | (enum 14 | (item "Enter " (inline-code "test.scm") " at the repl prompt.") 15 | (item "Develop your solution in the file " 16 | (inline-code "problem.scm") 17 | " reloading as you go.") 18 | (item "Run " 19 | (inline-code "(test)") 20 | " to check your solution.")))) 21 | 22 | 23 | -------------------------------------------------------------------------------- /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/phone-number/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "phone-number.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.", 24 | "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", 25 | "source_url": "https://turing.edu" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/bob/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "bob.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.", 24 | "source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.", 25 | "source_url": "https://pine.fm/LearnToProgram/?Chapter=06" 26 | } 27 | -------------------------------------------------------------------------------- /input/exercises/nucleotide-count/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (nucleotide-count dna) 4 | (let ((table (make-eq-hashtable))) 5 | (for-each (lambda (nucleotide) 6 | (unless (memq nucleotide (string->list "ACGT")) 7 | (error 'nucleotide-count "not a nucleotide" nucleotide)) 8 | (hashtable-set! table 9 | nucleotide 10 | (1+ (hashtable-ref table nucleotide 0)))) 11 | (string->list dna)) 12 | (let-values (((neucleotides counts) 13 | (hashtable-entries table))) 14 | (vector->list 15 | (vector-map cons neucleotides counts))))) 16 | 17 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (nucleotide-count dna) 4 | (let ((table (make-eq-hashtable))) 5 | (for-each (lambda (nucleotide) 6 | (unless (memq nucleotide (string->list "ACGT")) 7 | (error 'nucleotide-count "not a nucleotide" nucleotide)) 8 | (hashtable-set! table 9 | nucleotide 10 | (1+ (hashtable-ref table nucleotide 0)))) 11 | (string->list dna)) 12 | (let-values (((neucleotides counts) 13 | (hashtable-entries table))) 14 | (vector->list 15 | (vector-map cons neucleotides counts))))) 16 | 17 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "rna-transcription.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Given a DNA strand, return its RNA Complement Transcription.", 24 | "source": "Hyperphysics", 25 | "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html" 26 | } 27 | -------------------------------------------------------------------------------- /input/exercises/matching-brackets/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | eq? 4 | balanced? 5 | '(,(cdar (lookup 'input test))) 6 | ,(lookup 'expected test))) 7 | 8 | (define (spec->tests spec) 9 | (map parse-test (lookup 'cases spec))) 10 | 11 | (let ([spec (get-test-specification 'matching-brackets)]) 12 | (put-problem! 13 | 'matching-brackets 14 | `((test . ,(spec->tests spec)) 15 | (stubs balanced?) 16 | (version . ,(lookup 'version spec)) 17 | (skeleton . "matching-brackets.scm") 18 | (solution . "example.scm") 19 | (markdown . ,(splice-exercism 'matching-brackets))))) 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /input/exercises/bob/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? response-for 4 | '(,(lookup 'heyBob (lookup 'input test))) 5 | ,(lookup 'expected test))) 6 | 7 | (define (spec->tests spec) 8 | (map parse-test (lookup 'cases spec))) 9 | 10 | (let ((spec (get-test-specification 'bob))) 11 | (put-problem! 12 | 'bob 13 | `((test . ,(spec->tests spec)) 14 | (version . ,(lookup 'version spec)) 15 | (skeleton . "bob.scm") 16 | (solution . "example.scm") 17 | (stubs response-for) 18 | (markdown . ,(splice-exercism 'bob '(sentence "See if you can 19 | clearly separate responsibilities in your code.")))))) 20 | -------------------------------------------------------------------------------- /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/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 8 | of two uppercase letters followed by three digits, such as RX837 or BC811. 9 | 10 | Every once in a while we need to reset a robot to its factory settings, 11 | which means that its name gets wiped. The next time you ask, that robot will 12 | respond with a new random name. 13 | 14 | The names must be random: they should not follow a predictable sequence. 15 | Using random names means a risk of collisions. Your solution must ensure that 16 | every existing robot has a unique name. 17 | -------------------------------------------------------------------------------- /.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: scheme 24 | secrets: 25 | github_membership_token: ${{ secrets.COMMUNITY_CONTRIBUTIONS_WORKFLOW_TOKEN }} 26 | -------------------------------------------------------------------------------- /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/difference-of-squares/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx", 10 | "Scientifica96", 11 | "yurrriq" 12 | ], 13 | "files": { 14 | "solution": [ 15 | "difference-of-squares.scm" 16 | ], 17 | "test": [ 18 | "test.scm", 19 | "test-util.ss" 20 | ], 21 | "example": [ 22 | ".meta/example.scm" 23 | ] 24 | }, 25 | "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.", 26 | "source": "Problem 6 at Project Euler", 27 | "source_url": "https://projecteuler.net/problem=6" 28 | } 29 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "Empty RNA sequence" equal? dna->rna '("") 5 | "") 6 | (test-success "RNA complement of cytosine is guanine" equal? 7 | dna->rna '("C") "G") 8 | (test-success "RNA complement of guanine is cytosine" equal? 9 | dna->rna '("G") "C") 10 | (test-success "RNA complement of thymine is adenine" equal? 11 | dna->rna '("T") "A") 12 | (test-success "RNA complement of adenine is uracil" equal? 13 | dna->rna '("A") "U") 14 | (test-success "RNA complement" equal? dna->rna 15 | '("ACGTGGTCTTAA") "UGCACCAGAAUU"))) 16 | 17 | (run-with-cli "rna-transcription.scm" (list test-cases)) 18 | 19 | -------------------------------------------------------------------------------- /exercises/practice/hello-world/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "benreyn", 7 | "cyborgsphinx", 8 | "guygastineau", 9 | "herwinw", 10 | "jitwit", 11 | "kytrinyx", 12 | "skeskali" 13 | ], 14 | "files": { 15 | "solution": [ 16 | "hello-world.scm" 17 | ], 18 | "test": [ 19 | "test.scm", 20 | "test-util.ss" 21 | ], 22 | "example": [ 23 | ".meta/example.scm" 24 | ] 25 | }, 26 | "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", 27 | "source": "This is an exercise to introduce users to using Exercism", 28 | "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" 29 | } 30 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /exercises/practice/grains/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Calculate the number of grains of wheat on a chessboard given that the number on each square doubles. 4 | 5 | There once was a wise servant who saved the life of a prince. 6 | The king promised to pay whatever the servant could dream up. 7 | Knowing that the king loved chess, the servant told the king he would like to have grains of wheat. 8 | One grain on the first square of a chess board, with the number of grains doubling on each successive square. 9 | 10 | There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on). 11 | 12 | Write code that shows: 13 | 14 | - how many grains were on a given square, and 15 | - the total number of grains on the chessboard 16 | -------------------------------------------------------------------------------- /input/exercises/rotational-cipher/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (rotate phrase dx) 4 | (list->string 5 | (map (rotate-char dx) 6 | (string->list phrase)))) 7 | 8 | (define (rotate-char dx) 9 | (lambda (char) 10 | (let ((rotate-under (lambda (base) 11 | (integer->char 12 | (+ base 13 | (modulo (+ (char->integer char) 14 | dx 15 | (- base)) 16 | 26)))))) 17 | (cond ((char-lower-case? char) 18 | (rotate-under 97)) 19 | ((char-upper-case? char) 20 | (rotate-under 65)) 21 | (else char))))) 22 | 23 | -------------------------------------------------------------------------------- /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/rotational-cipher/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (rotate phrase dx) 4 | (list->string 5 | (map (rotate-char dx) 6 | (string->list phrase)))) 7 | 8 | (define (rotate-char dx) 9 | (lambda (char) 10 | (let ((rotate-under (lambda (base) 11 | (integer->char 12 | (+ base 13 | (modulo (+ (char->integer char) 14 | dx 15 | (- base)) 16 | 26)))))) 17 | (cond ((char-lower-case? char) 18 | (rotate-under 97)) 19 | ((char-upper-case? char) 20 | (rotate-under 65)) 21 | (else char))))) 22 | 23 | -------------------------------------------------------------------------------- /input/exercises/hello-world/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | hello-world 5 | '() 6 | ,(lookup 'expected test))) 7 | 8 | (let ((spec (get-test-specification 'hello-world))) 9 | (put-problem! 10 | 'hello-world 11 | `((test . ,(map parse-test (lookup 'cases spec))) 12 | (version . ,(lookup 'version spec)) 13 | (skeleton . "hello-world.scm") 14 | (solution . "example.scm") 15 | (stubs hello-world) 16 | (markdown . ,(splice-exercism 17 | 'hello-world 18 | '(sentence "Your solution may be a procedure that 19 | returns the desired string or a variable whose value is that 20 | string.")))))) 21 | 22 | -------------------------------------------------------------------------------- /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/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/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/queen-attack/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "can not attack" eq? attacking? 5 | '((2 4) (6 6)) #f) 6 | (test-success "can attack on same row" eq? attacking? 7 | '((2 4) (2 6)) #t) 8 | (test-success "can attack on same column" eq? attacking? 9 | '((4 5) (2 5)) #t) 10 | (test-success "can attack on first diagonal" eq? attacking? 11 | '((2 2) (0 4)) #t) 12 | (test-success "can attack on second diagonal" eq? attacking? 13 | '((2 2) (3 1)) #t) 14 | (test-success "can attack on third diagonal" eq? attacking? 15 | '((2 2) (1 1)) #t) 16 | (test-success "can attack on fourth diagonal" eq? attacking? 17 | '((1 7) (0 6)) #t))) 18 | 19 | (run-with-cli "queen-attack.scm" (list test-cases)) 20 | 21 | -------------------------------------------------------------------------------- /input/exercises/rotational-cipher/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | rotate 5 | '(,(lookup-spine '(input text) test) 6 | ,(lookup-spine '(input shiftKey) test)) 7 | ,(lookup 'expected test))) 8 | 9 | (define (spec->tests spec) 10 | (map parse-test 11 | (lookup 'cases (car (lookup 'cases spec))))) 12 | 13 | (let ((spec (get-test-specification 'rotational-cipher))) 14 | (put-problem! 15 | 'rotational-cipher 16 | `((test . ,(spec->tests spec)) 17 | (stubs rotate) 18 | (version . ,(lookup 'version spec)) 19 | (skeleton . "rotational-cipher.scm") 20 | (solution . "example.scm") 21 | (markdown . ,(splice-exercism 'rotational-cipher))))) 22 | 23 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection. 4 | 5 | Given the collection of numbers: 6 | 7 | - 1, 2, 3, 4, 5 8 | 9 | And the operation: 10 | 11 | - square a number (`x => x * x`) 12 | 13 | Your code should be able to produce the collection of squares: 14 | 15 | - 1, 4, 9, 16, 25 16 | 17 | Check out the test suite to see the expected function signature. 18 | 19 | ## Restrictions 20 | 21 | Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! 22 | Solve this one yourself using other basic tools instead. 23 | -------------------------------------------------------------------------------- /exercises/practice/two-fer/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [1cf3e15a-a3d7-4a87-aeb3-ba1b43bc8dce] 13 | description = "no name given" 14 | 15 | [b4c6dbb8-b4fb-42c2-bafd-10785abe7709] 16 | description = "a name given" 17 | 18 | [3549048d-1a6e-4653-9a79-b0bda163e8d5] 19 | description = "another name given" 20 | -------------------------------------------------------------------------------- /input/exercises/pangram/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | (let ((input (cdar (lookup 'input test)))) 3 | `(test-success ,(lookup 'description test) 4 | eq? 5 | pangram? 6 | '(,input) 7 | ,(lookup 'expected test)))) 8 | 9 | (let ([spec (get-test-specification 'pangram)]) 10 | (put-problem! 11 | 'pangram 12 | `((test . ,(map parse-test (lookup 'cases spec))) 13 | (stubs pangram?) 14 | (version . ,(lookup 'version spec)) 15 | (skeleton . "pangram.scm") 16 | (solution . "example.scm") 17 | (markdown . ,(splice-exercism 'pangram 18 | '(sentence 19 | "Consider inputs case insensitive 20 | and allow more than one of each required char.")))))) 21 | 22 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to compute a word's Scrabble score by summing the values of its letters. 4 | 5 | The letters are valued as follows: 6 | 7 | | Letter | Value | 8 | | ---------------------------- | ----- | 9 | | A, E, I, O, U, L, N, R, S, T | 1 | 10 | | D, G | 2 | 11 | | B, C, M, P | 3 | 12 | | F, H, V, W, Y | 4 | 13 | | K | 5 | 14 | | J, X | 8 | 15 | | Q, Z | 10 | 16 | 17 | For example, the word "cabbage" is worth 14 points: 18 | 19 | - 3 points for C 20 | - 1 point for A 21 | - 3 points for B 22 | - 3 points for B 23 | - 1 point for A 24 | - 2 points for G 25 | - 1 point for E 26 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.meta/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | "canweriotnow" 4 | ], 5 | "contributors": [ 6 | "cyborgsphinx", 7 | "guygastineau", 8 | "jitwit", 9 | "kytrinyx" 10 | ], 11 | "files": { 12 | "solution": [ 13 | "raindrops.scm" 14 | ], 15 | "test": [ 16 | "test.scm", 17 | "test-util.ss" 18 | ], 19 | "example": [ 20 | ".meta/example.scm" 21 | ] 22 | }, 23 | "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", 24 | "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.", 25 | "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" 26 | } 27 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles. 4 | 5 | The program should consider strings specifying an invalid trinary as the value 0. 6 | 7 | Trinary numbers contain three symbols: 0, 1, and 2. 8 | 9 | The last place in a trinary number is the 1's place. 10 | The second to last is the 3's place, the third to last is the 9's place, etc. 11 | 12 | ```shell 13 | # "102012" 14 | 1 0 2 0 1 2 # the number 15 | 1*3^5 + 0*3^4 + 2*3^3 + 0*3^2 + 1*3^1 + 2*3^0 # the value 16 | 243 + 0 + 54 + 0 + 3 + 2 = 302 17 | ``` 18 | 19 | If your language provides a method in the standard library to perform the conversion, pretend it doesn't exist and implement it yourself. 20 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | At a garage sale, you find a lovely vintage typewriter at a bargain price! 4 | Excitedly, you rush home, insert a sheet of paper, and start typing away. 5 | However, your excitement wanes when you examine the output: all words are garbled! 6 | For example, it prints "stop" instead of "post" and "least" instead of "stale." 7 | Carefully, you try again, but now it prints "spot" and "slate." 8 | After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. 9 | You now understand why they sold it for so little money! 10 | 11 | You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. 12 | Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. 13 | -------------------------------------------------------------------------------- /exercises/practice/roman-numerals/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (define (roman n) 2 | (let loop ([n n] 3 | [r '((1000 . "M") 4 | (900 . "CM") 5 | (500 . "D") 6 | (400 . "CD") 7 | (100 . "C") 8 | (90 . "XC") 9 | (50 . "L") 10 | (40 . "XL") 11 | (10 . "X") 12 | (9 . "IX") 13 | (5 . "V") 14 | (4 . "IV") 15 | (1 . "I"))]) 16 | (cond 17 | [(zero? n) ""] 18 | [(>= n (caar r)) (string-append (cdar r) 19 | (loop (- n (caar r)) r))] 20 | [else (loop n (cdr r))]))) 21 | 22 | ;;; Or, alternatively ... 23 | ;; 24 | ;; (use-modules (ice-9 format)) 25 | ;; 26 | ;; (define (roman n) 27 | ;; (format #f "~@r" n)) 28 | -------------------------------------------------------------------------------- /exercises/practice/trinary/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (any f xs) 4 | (fold-left (lambda (r x) (or r (f x))) #f xs)) 5 | 6 | (define (every f xs) 7 | (fold-left (lambda (r x) (and r (f x))) #t xs)) 8 | 9 | (define (string-any f s) 10 | (any f (string->list s))) 11 | 12 | (define (string-every f s) 13 | (every f (string->list s))) 14 | 15 | (define (to-decimal s) 16 | (call/cc 17 | (lambda (fail) 18 | (unless (string-every (lambda (c) 19 | (any (lambda (d) (char=? c d)) 20 | '(#\0 #\1 #\2))) 21 | s) 22 | (fail 0)) 23 | (apply + 24 | (map (lambda (d e) 25 | (* (- (char->integer d) (char->integer #\0)) (expt 3 e))) 26 | (reverse (string->list s)) 27 | (iota (string-length s))))))) 28 | -------------------------------------------------------------------------------- /exercises/practice/bob/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine what Bob will reply to someone when they say something to him or ask him a question. 4 | 5 | Bob only ever answers one of five things: 6 | 7 | - **"Sure."** 8 | This is his response if you ask him a question, such as "How are you?" 9 | The convention used for questions is that it ends with a question mark. 10 | - **"Whoa, chill out!"** 11 | This is his answer if you YELL AT HIM. 12 | The convention used for yelling is ALL CAPITAL LETTERS. 13 | - **"Calm down, I know what I'm doing!"** 14 | This is what he says if you yell a question at him. 15 | - **"Fine. Be that way!"** 16 | This is how he responds to silence. 17 | The convention used for silence is nothing, or various combinations of whitespace characters. 18 | - **"Whatever."** 19 | This is what he answers to anything else. 20 | -------------------------------------------------------------------------------- /exercises/practice/difference-of-squares/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "square of sum 1" = square-of-sum '(1) 1) (test-success "square of sum 5" = square-of-sum '(5) 225) 5 | (test-success "square of sum 100" = square-of-sum '(100) 6 | 25502500) 7 | (test-success "sum of squares 1" = sum-of-squares '(1) 1) 8 | (test-success "sum of squares 5" = sum-of-squares '(5) 55) 9 | (test-success "sum of squares 100" = sum-of-squares '(100) 10 | 338350) 11 | (test-success "difference of squares 1" = 12 | difference-of-squares '(1) 0) 13 | (test-success "difference of squares 5" = 14 | difference-of-squares '(5) 170) 15 | (test-success "difference of squares 100" = 16 | difference-of-squares '(100) 25164150))) 17 | 18 | (run-with-cli "difference-of-squares.scm" (list test-cases)) 19 | 20 | -------------------------------------------------------------------------------- /input/exercises/prime-factors/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | (lambda (xs ys) 4 | (equal? (list-sort < xs) 5 | (list-sort < ys))) 6 | factorize 7 | '(,(cdar (lookup 'input test))) 8 | ',(lookup 'expected test))) 9 | 10 | (define (spec->tests spec) 11 | (map parse-test 12 | (lookup 'cases 13 | (car 14 | (lookup 'cases spec))))) 15 | 16 | (let ((spec (get-test-specification 'prime-factors))) 17 | (put-problem! 18 | 'prime-factors 19 | `((test . ,(spec->tests spec)) 20 | (stubs factorize) 21 | (version . ,(lookup 'version spec)) 22 | (skeleton . ,"prime-factors.scm") 23 | (solution . ,"example.scm") 24 | (markdown . ,(splice-exercism 'prime-factors))))) 25 | 26 | -------------------------------------------------------------------------------- /exercises/practice/scrabble-score/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "lowercase letter" = score '("a") 1) (test-success "uppercase letter" = score '("A") 1) 5 | (test-success "valuable letter" = score '("f") 4) 6 | (test-success "short word" = score '("at") 2) 7 | (test-success "short, valuable word" = score '("zoo") 12) 8 | (test-success "medium word" = score '("street") 6) 9 | (test-success "medium, valuable word" = score '("quirky") 10 | 22) 11 | (test-success "long, mixed-case word" = score 12 | '("OxyphenButazone") 41) 13 | (test-success "english-like word" = score '("pinata") 8) 14 | (test-success "empty input" = score '("") 0) 15 | (test-success "entire alphabet available" = score 16 | '("abcdefghijklmnopqrstuvwxyz") 87))) 17 | 18 | (run-with-cli "scrabble-score.scm" (list test-cases)) 19 | 20 | -------------------------------------------------------------------------------- /exercises/practice/binary-search/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | You have stumbled upon a group of mathematicians who are also singer-songwriters. 4 | They have written a song for each of their favorite numbers, and, as you can imagine, they have a lot of favorite numbers (like [0][zero] or [73][seventy-three] or [6174][kaprekars-constant]). 5 | 6 | You are curious to hear the song for your favorite number, but with so many songs to wade through, finding the right song could take a while. 7 | Fortunately, they have organized their songs in a playlist sorted by the title — which is simply the number that the song is about. 8 | 9 | You realize that you can use a binary search algorithm to quickly find a song given the title. 10 | 11 | [zero]: https://en.wikipedia.org/wiki/0 12 | [seventy-three]: https://en.wikipedia.org/wiki/73_(number) 13 | [kaprekars-constant]: https://en.wikipedia.org/wiki/6174_(number) 14 | -------------------------------------------------------------------------------- /input/exercises/anagram/test.ss: -------------------------------------------------------------------------------- 1 | 2 | (define (parse-test test) 3 | `(test-success ,(lookup 'description test) 4 | (lambda (xs ys) 5 | (equal? (list-sort stringtests spec) 12 | (map parse-test (lookup 'cases spec))) 13 | 14 | (let ((spec (get-test-specification 'anagram))) 15 | (put-problem! 16 | 'anagram 17 | `((test . ,(spec->tests spec)) 18 | (version . ,(lookup 'version spec)) 19 | (skeleton . "anagram.scm") 20 | (solution . "example.scm") 21 | (stubs anagram) 22 | (markdown . ,(splice-exercism 'anagram '(sentence "For purposes 23 | of this exercise, a word is not considered to be an anagram of 24 | itself.")))))) 25 | 26 | -------------------------------------------------------------------------------- /exercises/practice/grains/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success 5 | "returns the total number of grains on the board" equal? 6 | total '() 18446744073709551615) (test-success "1" equal? square '(1) 1) 7 | (test-success "2" equal? square '(2) 2) 8 | (test-success "3" equal? square '(3) 4) 9 | (test-success "4" equal? square '(4) 8) 10 | (test-success "16" equal? square '(16) 32768) 11 | (test-success "32" equal? square '(32) 2147483648) 12 | (test-success "64" equal? square '(64) 9223372036854775808) 13 | (test-error "square 0 raises an exception" square '(0)) 14 | (test-error 15 | "negative square raises an exception" 16 | square 17 | '(-1)) 18 | (test-error 19 | "square greater than 64 raises an exception" 20 | square 21 | '(65)))) 22 | 23 | (run-with-cli "grains.scm" (list test-cases)) 24 | 25 | -------------------------------------------------------------------------------- /input/exercises/atbash-cipher/test.ss: -------------------------------------------------------------------------------- 1 | 2 | (define (parse-test test) 3 | `(test-success ,(lookup 'description test) 4 | equal? 5 | ,(string->symbol 6 | (lookup 'property test)) 7 | '(,(cdar (lookup 'input test))) 8 | ;; note it's just input that needs to be list 9 | ,(lookup 'expected test))) 10 | 11 | (define (spec->tests spec) 12 | (map parse-test (apply append 13 | (map (lookup 'cases) 14 | (lookup 'cases spec))))) 15 | 16 | (let ((spec (get-test-specification 'atbash-cipher))) 17 | (put-problem! 18 | 'atbash-cipher 19 | `((test . ,(spec->tests spec)) 20 | (version . ,(lookup 'version spec)) 21 | (skeleton . "atbash-cipher.scm") 22 | (solution . "example.scm") 23 | (stubs encode decode) 24 | (markdown . ,(splice-exercism 'atbash-cipher))))) 25 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to determine which items to take so that the total value of her selection is maximized, taking into account the knapsack's carrying capacity. 4 | 5 | Items will be represented as a list of items. 6 | Each item will have a weight and value. 7 | All values given will be strictly positive. 8 | Lhakpa can take only one of each item. 9 | 10 | For example: 11 | 12 | ```text 13 | Items: [ 14 | { "weight": 5, "value": 10 }, 15 | { "weight": 4, "value": 40 }, 16 | { "weight": 6, "value": 30 }, 17 | { "weight": 4, "value": 50 } 18 | ] 19 | 20 | Knapsack Maximum Weight: 10 21 | ``` 22 | 23 | For the above, the first item has weight 5 and value 10, the second item has weight 4 and value 40, and so on. 24 | In this example, Lhakpa should take the second and fourth item to maximize her value, which, in this case, is 90. 25 | She cannot get more than 90 as her knapsack has a weight limit of 10. 26 | -------------------------------------------------------------------------------- /script/ci.ss: -------------------------------------------------------------------------------- 1 | 2 | (define (run-ci exercisms) 3 | (for-each run-tests exercisms) 4 | (system "touch ci")) 5 | 6 | (define (run-tests exercism) 7 | (display (format "running tests for ~a" exercism)) 8 | (newline) 9 | (let* ((dir (format "exercises/practice/~a" exercism)) 10 | (result (system 11 | (format "cp input/skeleton-makefile ~a/Makefile && cd ~a && make check-all solution=.meta/example.scm" 12 | dir 13 | dir)))) 14 | (unless (zero? result) 15 | (error 'run-ci "failed test" exercism)))) 16 | 17 | ;; Run tests for all directory expect for exercises named in except. 18 | (define (run-all-tests . except) 19 | (let ((blacklist 20 | (map (lambda (x) (if (symbol? x) (symbol->string x) x)) except))) 21 | (for-each run-tests 22 | (filter 23 | (lambda (x) (andmap (lambda (y) (not (equal? x y))) blacklist)) 24 | (directory-list "exercises/practice/"))))) 25 | -------------------------------------------------------------------------------- /exercises/practice/robot-name/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (define-module (robot) 2 | #:export (build-robot 3 | robot-name 4 | reset-name) 5 | #:autoload (srfi srfi-1) (iota)) 6 | 7 | (define random-alpha-char 8 | (lambda () 9 | (list-ref (map integer->char (iota 26 65)) (random 26)))) 10 | 11 | (define random-digit-char 12 | (lambda () 13 | (list-ref (map integer->char (iota 10 48)) (random 10)))) 14 | 15 | (define gen-name 16 | (lambda () 17 | (string 18 | (random-alpha-char) 19 | (random-alpha-char) 20 | (random-digit-char) 21 | (random-digit-char) 22 | (random-digit-char)))) 23 | 24 | (define build-robot 25 | (lambda () 26 | (let ((robot (make-hash-table 2))) 27 | (hashq-set! robot 'name (gen-name)) 28 | robot))) 29 | 30 | 31 | 32 | (define robot-name 33 | (lambda (robot) 34 | (hashq-ref robot 'name))) 35 | 36 | (define reset-name 37 | (lambda (robot) 38 | (set! robot (hashq-set! robot 'name (gen-name))))) 39 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Compute the prime factors of a given natural number. 4 | 5 | A prime number is only evenly divisible by itself and 1. 6 | 7 | Note that 1 is not a prime number. 8 | 9 | ## Example 10 | 11 | What are the prime factors of 60? 12 | 13 | - Our first divisor is 2. 14 | 2 goes into 60, leaving 30. 15 | - 2 goes into 30, leaving 15. 16 | - 2 doesn't go cleanly into 15. 17 | So let's move on to our next divisor, 3. 18 | - 3 goes cleanly into 15, leaving 5. 19 | - 3 does not go cleanly into 5. 20 | The next possible factor is 4. 21 | - 4 does not go cleanly into 5. 22 | The next possible factor is 5. 23 | - 5 does go cleanly into 5. 24 | - We're left only with 1, so now, we're done. 25 | 26 | Our successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5. 27 | 28 | You can check this yourself: 29 | 30 | ```text 31 | 2 * 2 * 3 * 5 32 | = 4 * 15 33 | = 60 34 | ``` 35 | 36 | Success! 37 | -------------------------------------------------------------------------------- /exercises/practice/sieve/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [88529125-c4ce-43cc-bb36-1eb4ddd7b44f] 13 | description = "no primes under two" 14 | 15 | [4afe9474-c705-4477-9923-840e1024cc2b] 16 | description = "find first prime" 17 | 18 | [974945d8-8cd9-4f00-9463-7d813c7f17b7] 19 | description = "find primes up to 10" 20 | 21 | [2e2417b7-3f3a-452a-8594-b9af08af6d82] 22 | description = "limit is prime" 23 | 24 | [92102a05-4c7c-47de-9ed0-b7d5fcd00f21] 25 | description = "find primes up to 1000" 26 | -------------------------------------------------------------------------------- /exercises/practice/anagram/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to, given a target word and a set of candidate words, to find the subset of the candidates that are anagrams of the target. 4 | 5 | An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. 6 | A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. 7 | 8 | The target and candidates are words of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). 9 | Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `StoP` is not an anagram of `sTOp`. 10 | The anagram set is the subset of the candidate set that are anagrams of the target (in any order). 11 | Words in the anagram set should have the same letter case as in the candidate set. 12 | 13 | Given the target `"stone"` and candidates `"stone"`, `"tones"`, `"banana"`, `"tons"`, `"notes"`, `"Seton"`, the anagram set is `"tones"`, `"notes"`, `"Seton"`. 14 | -------------------------------------------------------------------------------- /input/exercises/collatz-conjecture/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | = 4 | collatz 5 | '(,(cdar (lookup 'input test))) 6 | ,(lookup 'expected test))) 7 | 8 | (define success-case? 9 | (lambda (test) 10 | (number? (lookup 'expected test)))) 11 | 12 | (define (spec->tests spec) 13 | (map parse-test 14 | (filter success-case? 15 | (lookup 'cases spec)))) 16 | 17 | (let ([spec (get-test-specification 'collatz-conjecture)]) 18 | (put-problem! 19 | 'collatz-conjecture 20 | `((test . ,(spec->tests spec)) 21 | (stubs collatz) 22 | (version . ,(lookup 'version spec)) 23 | (skeleton . "collatz-conjecture.scm") 24 | (solution . "example.scm") 25 | (markdown . ,(splice-exercism 26 | 'collatz-conjecture 27 | '(sentence "Don't worry about validating input for this track -- all inputs will be natural numbers.")))))) 28 | 29 | -------------------------------------------------------------------------------- /exercises/practice/accumulate/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [64d97c14-36dd-44a8-9621-2cecebd6ed23] 13 | description = "accumulate empty" 14 | 15 | [00008ed2-4651-4929-8c08-8b4dbd70872e] 16 | description = "accumulate squares" 17 | 18 | [551016da-4396-4cae-b0ec-4c3a1a264125] 19 | description = "accumulate upcases" 20 | 21 | [cdf95597-b6ec-4eac-a838-3480d13d0d05] 22 | description = "accumulate reversed strings" 23 | 24 | [bee8e9b6-b16f-4cd2-be3b-ccf7457e50bb] 25 | description = "accumulate recursively" 26 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Determine if a triangle is equilateral, isosceles, or scalene. 4 | 5 | An _equilateral_ triangle has all three sides the same length. 6 | 7 | An _isosceles_ triangle has at least two sides the same length. 8 | (It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.) 9 | 10 | A _scalene_ triangle has all sides of different lengths. 11 | 12 | ## Note 13 | 14 | For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side. 15 | 16 | In equations: 17 | 18 | Let `a`, `b`, and `c` be sides of the triangle. 19 | Then all three of the following expressions must be true: 20 | 21 | ```text 22 | a + b ≥ c 23 | b + c ≥ a 24 | a + c ≥ b 25 | ``` 26 | 27 | See [Triangle Inequality][triangle-inequality] 28 | 29 | [triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality 30 | -------------------------------------------------------------------------------- /input/exercises/phone-number/test.ss: -------------------------------------------------------------------------------- 1 | 2 | (define (parse-test test) 3 | ;; (let ((expected (lookup 'expected test)))) 4 | (let ((expected (lookup 'expected test))) 5 | (if (string? expected) 6 | `(test-success ,(lookup 'description test) 7 | equal? 8 | clean 9 | '(,(cdar (lookup 'input test))) 10 | ,expected) 11 | `(test-error ,(lookup 'description test) 12 | clean 13 | '(,(cdar (lookup 'input test))))))) 14 | 15 | (define (spec->tests spec) 16 | (map parse-test (lookup 'cases 17 | (car (lookup 'cases spec))))) 18 | 19 | (let ((spec (get-test-specification 'phone-number))) 20 | (put-problem! 21 | 'phone-number 22 | `((test . ,(spec->tests spec)) 23 | (stubs clean) 24 | (version . ,(lookup 'version spec)) 25 | (skeleton . "phone-number.scm") 26 | (solution . "example.scm") 27 | (markdown . ,(splice-exercism 'phone-number))))) 28 | 29 | -------------------------------------------------------------------------------- /input/exercises/perfect-numbers/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | (let ((expected (lookup 'expected test))) 3 | (if (pair? expected) 4 | `(test-error ,(lookup 'description test) 5 | classify 6 | '(,(cdar (lookup 'input test)))) 7 | `(test-success ,(lookup 'description test) 8 | eq? 9 | classify 10 | '(,(cdar (lookup 'input test))) 11 | ',(string->symbol expected))))) 12 | 13 | (define (spec->tests spec) 14 | (map parse-test 15 | (apply append 16 | (map (lookup 'cases) 17 | (lookup 'cases spec))))) 18 | 19 | (let ((spec (get-test-specification 'perfect-numbers))) 20 | (put-problem! 21 | 'perfect-numbers 22 | `((test . ,(spec->tests spec)) 23 | (version . ,(lookup 'version spec)) 24 | (stubs classify) 25 | (skeleton . "perfect-numbers.scm") 26 | (solution . "example.scm") 27 | (markdown . ,(splice-exercism 'perfect-numbers))))) 28 | 29 | -------------------------------------------------------------------------------- /exercises/practice/forth/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement an evaluator for a very simple subset of Forth. 4 | 5 | [Forth][forth] 6 | is a stack-based programming language. 7 | Implement a very basic evaluator for a small subset of Forth. 8 | 9 | Your evaluator has to support the following words: 10 | 11 | - `+`, `-`, `*`, `/` (integer arithmetic) 12 | - `DUP`, `DROP`, `SWAP`, `OVER` (stack manipulation) 13 | 14 | Your evaluator also has to support defining new words using the customary syntax: `: word-name definition ;`. 15 | 16 | To keep things simple the only data type you need to support is signed integers of at least 16 bits size. 17 | 18 | You should use the following rules for the syntax: a number is a sequence of one or more (ASCII) digits, a word is a sequence of one or more letters, digits, symbols or punctuation that is not a number. 19 | (Forth probably uses slightly different rules, but this is close enough.) 20 | 21 | Words are case-insensitive. 22 | 23 | [forth]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29 24 | -------------------------------------------------------------------------------- /exercises/practice/raindrops/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Your task is to convert a number into its corresponding raindrop sounds. 4 | 5 | If a given number: 6 | 7 | - is divisible by 3, add "Pling" to the result. 8 | - is divisible by 5, add "Plang" to the result. 9 | - is divisible by 7, add "Plong" to the result. 10 | - **is not** divisible by 3, 5, or 7, the result should be the number as a string. 11 | 12 | ## Examples 13 | 14 | - 28 is divisible by 7, but not 3 or 5, so the result would be `"Plong"`. 15 | - 30 is divisible by 3 and 5, but not 7, so the result would be `"PlingPlang"`. 16 | - 34 is not divisible by 3, 5, or 7, so the result would be `"34"`. 17 | 18 | ~~~~exercism/note 19 | A common way to test if one number is evenly divisible by another is to compare the [remainder][remainder] or [modulus][modulo] to zero. 20 | Most languages provide operators or functions for one (or both) of these. 21 | 22 | [remainder]: https://exercism.org/docs/programming/operators/remainder 23 | [modulo]: https://en.wikipedia.org/wiki/Modulo_operation 24 | ~~~~ 25 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [3e5c30a8-87e2-4845-a815-a49671ade970] 13 | description = "empty strand" 14 | 15 | [a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] 16 | description = "can count one nucleotide in single-character input" 17 | 18 | [eca0d565-ed8c-43e7-9033-6cefbf5115b5] 19 | description = "strand with repeated nucleotide" 20 | 21 | [40a45eac-c83f-4740-901a-20b22d15a39f] 22 | description = "strand with multiple nucleotides" 23 | 24 | [b4c47851-ee9e-4b0a-be70-a86e343bd851] 25 | description = "strand with invalid nucleotides" 26 | -------------------------------------------------------------------------------- /exercises/practice/strain/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Implement the `keep` and `discard` operation on collections. 4 | Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false. 5 | 6 | For example, given the collection of numbers: 7 | 8 | - 1, 2, 3, 4, 5 9 | 10 | And the predicate: 11 | 12 | - is the number even? 13 | 14 | Then your keep operation should produce: 15 | 16 | - 2, 4 17 | 18 | While your discard operation should produce: 19 | 20 | - 1, 3, 5 21 | 22 | Note that the union of keep and discard is all the elements. 23 | 24 | The functions may be called `keep` and `discard`, or they may need different names in order to not clash with existing functions or concepts in your language. 25 | 26 | ## Restrictions 27 | 28 | Keep your hands off that filter/reject/whatchamacallit functionality provided by your standard library! 29 | Solve this one yourself using other basic tools instead. 30 | -------------------------------------------------------------------------------- /exercises/practice/triangle/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (any f xs) 4 | (fold-left (lambda (r x) (or r (f x))) #f xs)) 5 | 6 | (define (every f xs) 7 | (fold-left (lambda (r x) (and r (f x))) #t xs)) 8 | 9 | (define (string-any f s) 10 | (any f (string->list s))) 11 | 12 | (define (string-every f s) 13 | (every f (string->list s))) 14 | 15 | (define (nub xs) 16 | (fold-left (lambda (ys x) 17 | (if (any (lambda (y) (equal? x y)) ys) ys 18 | (cons x ys))) 19 | '() xs)) 20 | 21 | (define (impl-safe-sort f xs) 22 | (call/cc 23 | (lambda (k) 24 | (with-exception-handler 25 | (lambda (e) 26 | ;; Uh-oh, we're using Guile! 27 | (k (sort xs f))) 28 | (lambda () 29 | (sort f xs)))))) 30 | 31 | (define (triangle a b c) 32 | (let ([xs (impl-safe-sort > (list a b c))]) 33 | (if (>= (car xs) (apply + (cdr xs))) 34 | (error "Invalid triangle") 35 | (case (length (nub xs)) 36 | [(1) 'equilateral] 37 | [(2) 'isosceles] 38 | [else 'scalene])))) 39 | -------------------------------------------------------------------------------- /exercises/practice/hamming/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "empty strands" = hamming-distance '("" "") 5 | 0) 6 | (test-success "single letter identical strands" = 7 | hamming-distance '("A" "A") 0) 8 | (test-success "single letter different strands" = 9 | hamming-distance '("G" "T") 1) 10 | (test-success "long identical strands" = hamming-distance 11 | '("GGACTGAAATCTG" "GGACTGAAATCTG") 0) 12 | (test-success "long different strands" = hamming-distance 13 | '("GGACGGATTCTG" "AGGACGGATTCT") 9) 14 | (test-error 15 | "disallow first strand longer" 16 | hamming-distance 17 | '("AATG" "AAA")) 18 | (test-error 19 | "disallow second strand longer" 20 | hamming-distance 21 | '("ATA" "AGTG")) 22 | (test-error 23 | "disallow left empty strand" 24 | hamming-distance 25 | '("" "G")) 26 | (test-error 27 | "disallow right empty strand" 28 | hamming-distance 29 | '("G" "")))) 30 | 31 | (run-with-cli "hamming.scm" (list test-cases)) 32 | 33 | -------------------------------------------------------------------------------- /exercises/practice/collatz-conjecture/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [540a3d51-e7a6-47a5-92a3-4ad1838f0bfd] 13 | description = "zero steps for one" 14 | 15 | [3d76a0a6-ea84-444a-821a-f7857c2c1859] 16 | description = "divide if even" 17 | 18 | [754dea81-123c-429e-b8bc-db20b05a87b9] 19 | description = "even and odd steps" 20 | 21 | [ecfd0210-6f85-44f6-8280-f65534892ff6] 22 | description = "large number of even and odd steps" 23 | 24 | [7d4750e6-def9-4b86-aec7-9f7eb44f95a3] 25 | description = "zero is an error" 26 | 27 | [c6c795bf-a288-45e9-86a1-841359ad426d] 28 | description = "negative value is an error" 29 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "zero rows" equal? pascals-triangle '(0) 5 | '()) 6 | (test-success "single row" equal? pascals-triangle '(1) 7 | '((1))) 8 | (test-success "two rows" equal? pascals-triangle '(2) 9 | '((1) (1 1))) 10 | (test-success "three rows" equal? pascals-triangle '(3) 11 | '((1) (1 1) (1 2 1))) 12 | (test-success "four rows" equal? pascals-triangle '(4) 13 | '((1) (1 1) (1 2 1) (1 3 3 1))) 14 | (test-success "five rows" equal? pascals-triangle '(5) 15 | '((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1))) 16 | (test-success "six rows" equal? pascals-triangle '(6) 17 | '((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1))) 18 | (test-success "ten rows" equal? pascals-triangle '(10) 19 | '((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1) 20 | (1 6 15 20 15 6 1) (1 7 21 35 35 21 7 1) 21 | (1 8 28 56 70 56 28 8 1) (1 9 36 84 126 126 84 36 9 1))))) 22 | 23 | (run-with-cli "pascals-triangle.scm" (list test-cases)) 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Exercism 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /input/exercises/sieve/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | sieve 5 | '(,(cdar (lookup 'input test))) 6 | ',(lookup 'expected test))) 7 | 8 | (define (make-harder-test in-out) 9 | `(test-success ,(format "~a primes below ~a" (cdr in-out) (car in-out)) 10 | (lambda (result n) 11 | (= n (length result))) 12 | sieve 13 | '(,(car in-out)) 14 | ,(cdr in-out))) 15 | 16 | (define (spec->tests spec) 17 | (append (map parse-test (lookup 'cases spec)) 18 | (map make-harder-test '((10000 . 1229) 19 | (100000 . 9592) 20 | (1000000 . 78498))))) 21 | 22 | (let ((spec (get-test-specification 'sieve))) 23 | (put-problem! 24 | 'sieve 25 | `((test . ,(spec->tests spec)) 26 | (stubs sieve) 27 | (version . ,(lookup 'version spec)) 28 | (skeleton . "sieve.scm") 29 | (solution . "example.scm") 30 | (markdown . ,(splice-exercism 'sieve))))) 31 | 32 | -------------------------------------------------------------------------------- /input/exercises/two-fer/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | equal? 4 | two-fer 5 | ,(let ((input (cdar (lookup 'input test)))) 6 | (if (null? input) 7 | ''() 8 | `'(,input))) 9 | ,(lookup 'expected test))) 10 | 11 | (let ((spec (get-test-specification 'two-fer))) 12 | (put-problem! 13 | 'two-fer 14 | `((test . ,(map parse-test (lookup 'cases spec))) 15 | (stubs two-fer) 16 | (version . ,(lookup 'version spec)) 17 | (skeleton . "two-fer.scm") 18 | (solution . "example.scm") 19 | (markdown 20 | . 21 | ,(splice-exercism 22 | 'two-fer 23 | '((sentence "One way to get optional arguments in scheme is by specifying the arguments as a list.") 24 | (sentence "Two ways to do that are: " 25 | (inline-code "(define (two-fer . args) ...)") 26 | " or " 27 | (inline-code "(define two-fer (lambda args ...))") 28 | "."))))))) 29 | 30 | -------------------------------------------------------------------------------- /docs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": [ 3 | { 4 | "uuid": "6c5c46c6-fd05-4c1b-ae89-7dbf16b466c4", 5 | "slug": "installation", 6 | "path": "docs/INSTALLATION.md", 7 | "title": "Installing Scheme locally", 8 | "blurb": "Learn how to install Scheme locally to solve Exercism's exercises on your own machine" 9 | }, 10 | { 11 | "uuid": "d39be63c-89ea-491d-81d5-00d8d0f9bb19", 12 | "slug": "learning", 13 | "path": "docs/LEARNING.md", 14 | "title": "How to learn Scheme", 15 | "blurb": "An overview of how to get started from scratch with Scheme" 16 | }, 17 | { 18 | "uuid": "1528fa64-cf14-4310-a1be-f731c604d34e", 19 | "slug": "tests", 20 | "path": "docs/TESTS.md", 21 | "title": "Testing on the Scheme track", 22 | "blurb": "Learn how to test your Scheme exercises on Exercism" 23 | }, 24 | { 25 | "uuid": "5e72db99-3bf8-4161-8369-dfba4fdc9596", 26 | "slug": "resources", 27 | "path": "docs/RESOURCES.md", 28 | "title": "Useful Scheme resources", 29 | "blurb": "A collection of useful resources to help you master Scheme" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /code/lint.sls: -------------------------------------------------------------------------------- 1 | (library (lint) 2 | (export check-config-for) 3 | (import (outils) 4 | (chezscheme)) 5 | 6 | (define checkworthy-fields 7 | '(uuid 8 | core 9 | unlocked-by 10 | difficulty 11 | topics)) 12 | 13 | (define (check-config field problem-config) 14 | (unless (assoc field problem-config) 15 | (format #t "~a~%~%" problem-config) 16 | (error 'check-for-field "please add field" field problem-config)) 17 | 'ok) 18 | 19 | (define (check-config-for problem) 20 | (format #t "checking config for ~a~%" problem) 21 | (let ((exercisms (lookup 'exercises (load-config)))) 22 | (cond ((find (lambda (exercism) 23 | (eq? problem (lookup 'slug exercism))) 24 | exercisms) 25 | => 26 | (lambda (config) 27 | (for-all (lambda (field) 28 | (check-config field config)) 29 | checkworthy-fields))) 30 | (else 31 | (error 'check-config-for 32 | "please add problem to config/config.ss" 33 | problem))))) 34 | 35 | ) 36 | -------------------------------------------------------------------------------- /exercises/practice/transpose/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given an input text output it transposed. 4 | 5 | Roughly explained, the transpose of a matrix: 6 | 7 | ```text 8 | ABC 9 | DEF 10 | ``` 11 | 12 | is given by: 13 | 14 | ```text 15 | AD 16 | BE 17 | CF 18 | ``` 19 | 20 | Rows become columns and columns become rows. 21 | See [transpose][]. 22 | 23 | If the input has rows of different lengths, this is to be solved as follows: 24 | 25 | - Pad to the left with spaces. 26 | - Don't pad to the right. 27 | 28 | Therefore, transposing this matrix: 29 | 30 | ```text 31 | ABC 32 | DE 33 | ``` 34 | 35 | results in: 36 | 37 | ```text 38 | AD 39 | BE 40 | C 41 | ``` 42 | 43 | And transposing: 44 | 45 | ```text 46 | AB 47 | DEF 48 | ``` 49 | 50 | results in: 51 | 52 | ```text 53 | AD 54 | BE 55 | F 56 | ``` 57 | 58 | In general, all characters from the input should also be present in the transposed output. 59 | That means that if a column in the input text contains only spaces on its bottom-most row(s), the corresponding output row should contain the spaces in its right-most column(s). 60 | 61 | [transpose]: https://en.wikipedia.org/wiki/Transpose 62 | -------------------------------------------------------------------------------- /exercises/practice/rna-transcription/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [b4631f82-c98c-4a2f-90b3-c5c2b6c6f661] 13 | description = "Empty RNA sequence" 14 | 15 | [a9558a3c-318c-4240-9256-5d5ed47005a6] 16 | description = "RNA complement of cytosine is guanine" 17 | 18 | [6eedbb5c-12cb-4c8b-9f51-f8320b4dc2e7] 19 | description = "RNA complement of guanine is cytosine" 20 | 21 | [870bd3ec-8487-471d-8d9a-a25046488d3e] 22 | description = "RNA complement of thymine is adenine" 23 | 24 | [aade8964-02e1-4073-872f-42d3ffd74c5f] 25 | description = "RNA complement of adenine is uracil" 26 | 27 | [79ed2757-f018-4f47-a1d7-34a559392dbf] 28 | description = "RNA complement" 29 | -------------------------------------------------------------------------------- /input/exercises/change/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | (let ((expected (lookup 'expected test)) 3 | (input (lookup 'input test))) 4 | (if (or (null? expected) 5 | (number? (car expected))) 6 | `(test-success ,(lookup 'description test) 7 | (lambda (out expected) 8 | (equal? (list-sort < out) (list-sort < expected))) 9 | change 10 | '(,(lookup 'target input) 11 | ,(lookup 'coins input)) 12 | ',expected) 13 | `(test-error ,(lookup 'description test) 14 | change 15 | '(,(lookup 'target input) 16 | ,(lookup 'coins input)))))) 17 | 18 | (define (spec->tests spec) 19 | (map parse-test (lookup 'cases spec))) 20 | 21 | (let ((spec (get-test-specification 'change))) 22 | (put-problem! 23 | 'change 24 | `((test . ,(spec->tests spec)) 25 | (version . ,(lookup 'version spec)) 26 | (skeleton . "change.scm") 27 | (solution . "example.scm") 28 | (stubs change) 29 | (markdown . ,(splice-exercism 'change))))) 30 | 31 | -------------------------------------------------------------------------------- /input/exercises/word-count/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (ignore-char? x) 4 | (not (or (char-alphabetic? x) 5 | (char-numeric? x) 6 | (char=? x #\')))) 7 | 8 | (define (remove-quotes word) 9 | (cond ((< (string-length word) 2) word) 10 | ((and (char=? #\' (string-ref word 0)) 11 | (char=? #\' (string-ref word (1- (string-length word))))) 12 | (remove-quotes (substring word 1 (1- (string-length word))))) 13 | (else word))) 14 | 15 | (define (tokenize sentence) 16 | (let ((n (string-length sentence))) 17 | (let loop ((a 0) (b 0)) 18 | (cond ((and (= b n) (= a b)) '()) 19 | ((= b n) (list (remove-quotes (substring sentence a b)))) 20 | ((ignore-char? (string-ref sentence b)) 21 | (if (= a b) 22 | (loop (1+ a) (1+ b)) 23 | (cons (remove-quotes (substring sentence a b)) 24 | (loop (1+ b) (1+ b))))) 25 | (else (loop a (1+ b))))))) 26 | 27 | (define (word-count sentence) 28 | (let ((table (make-hashtable string-ci-hash string-ci=?))) 29 | (for-each (lambda (word) 30 | (hashtable-set! table 31 | word 32 | (1+ (hashtable-ref table word 0)))) 33 | (tokenize sentence)) 34 | table)) 35 | 36 | -------------------------------------------------------------------------------- /exercises/practice/rotational-cipher/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "rotate a by 0, same output as input" equal? 5 | rotate '("a" 0) "a") (test-success "rotate a by 1" equal? rotate '("a" 1) "b") 6 | (test-success "rotate a by 26, same output as input" equal? 7 | rotate '("a" 26) "a") 8 | (test-success "rotate m by 13" equal? rotate '("m" 13) "z") 9 | (test-success "rotate n by 13 with wrap around alphabet" 10 | equal? rotate '("n" 13) "a") 11 | (test-success "rotate capital letters" equal? rotate 12 | '("OMG" 5) "TRL") 13 | (test-success "rotate spaces" equal? rotate '("O M G" 5) 14 | "T R L") 15 | (test-success "rotate numbers" equal? rotate 16 | '("Testing 1 2 3 testing" 4) "Xiwxmrk 1 2 3 xiwxmrk") 17 | (test-success "rotate punctuation" equal? rotate 18 | '("Let's eat, Grandma!" 21) "Gzo'n zvo, Bmviyhv!") 19 | (test-success "rotate all letters" equal? rotate 20 | '("The quick brown fox jumps over the lazy dog." 13) 21 | "Gur dhvpx oebja sbk whzcf bire gur ynml qbt."))) 22 | 23 | (run-with-cli "rotational-cipher.scm" (list test-cases)) 24 | 25 | -------------------------------------------------------------------------------- /exercises/practice/triangle/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "equilateral: 2 2 2" equal? triangle 5 | '(2 2 2) 'equilateral) 6 | (test-success "equilateral: 10 10 10" equal? triangle 7 | '(10 10 10) 'equilateral) 8 | (test-success "isosceles: 3 4 4" equal? triangle '(3 4 4) 9 | 'isosceles) 10 | (test-success "isosceles: 4 3 4" equal? triangle '(4 3 4) 11 | 'isosceles) 12 | (test-success "isosceles: 4 4 3" equal? triangle '(4 4 3) 13 | 'isosceles) 14 | (test-success "isosceles: 10 10 2" equal? triangle 15 | '(10 10 2) 'isosceles) 16 | (test-success "scalene: 3 4 5" equal? triangle '(3 4 5) 17 | 'scalene) 18 | (test-success "scalene: 10 11 12" equal? triangle 19 | '(10 11 12) 'scalene) 20 | (test-success "scalene: 5 4 2" equal? triangle '(5 4 2) 21 | 'scalene) 22 | (test-error "invalid: 0 0 0" triangle '(0 0 0)) 23 | (test-error "invalid: 3 4 -5" triangle '(3 4 -5)) 24 | (test-error "invalid: 1 1 3" triangle '(1 1 3)) 25 | (test-error "invalid: 2 4 2" triangle '(2 4 2)))) 26 | 27 | (run-with-cli "triangle.scm" (list test-cases)) 28 | 29 | -------------------------------------------------------------------------------- /exercises/practice/word-count/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (ignore-char? x) 4 | (not (or (char-alphabetic? x) 5 | (char-numeric? x) 6 | (char=? x #\')))) 7 | 8 | (define (remove-quotes word) 9 | (cond ((< (string-length word) 2) word) 10 | ((and (char=? #\' (string-ref word 0)) 11 | (char=? #\' (string-ref word (1- (string-length word))))) 12 | (remove-quotes (substring word 1 (1- (string-length word))))) 13 | (else word))) 14 | 15 | (define (tokenize sentence) 16 | (let ((n (string-length sentence))) 17 | (let loop ((a 0) (b 0)) 18 | (cond ((and (= b n) (= a b)) '()) 19 | ((= b n) (list (remove-quotes (substring sentence a b)))) 20 | ((ignore-char? (string-ref sentence b)) 21 | (if (= a b) 22 | (loop (1+ a) (1+ b)) 23 | (cons (remove-quotes (substring sentence a b)) 24 | (loop (1+ b) (1+ b))))) 25 | (else (loop a (1+ b))))))) 26 | 27 | (define (word-count sentence) 28 | (let ((table (make-hashtable string-ci-hash string-ci=?))) 29 | (for-each (lambda (word) 30 | (hashtable-set! table 31 | word 32 | (1+ (hashtable-ref table word 0)))) 33 | (tokenize sentence)) 34 | table)) 35 | 36 | -------------------------------------------------------------------------------- /exercises/practice/knapsack/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [a4d7d2f0-ad8a-460c-86f3-88ba709d41a7] 13 | description = "no items" 14 | 15 | [1d39e98c-6249-4a8b-912f-87cb12e506b0] 16 | description = "one item, too heavy" 17 | 18 | [833ea310-6323-44f2-9d27-a278740ffbd8] 19 | description = "five items (cannot be greedy by weight)" 20 | 21 | [277cdc52-f835-4c7d-872b-bff17bab2456] 22 | description = "five items (cannot be greedy by value)" 23 | 24 | [81d8e679-442b-4f7a-8a59-7278083916c9] 25 | description = "example knapsack" 26 | 27 | [f23a2449-d67c-4c26-bf3e-cde020f27ecc] 28 | description = "8 items" 29 | 30 | [7c682ae9-c385-4241-a197-d2fa02c81a11] 31 | description = "15 items" 32 | -------------------------------------------------------------------------------- /exercises/practice/pascals-triangle/.meta/tests.toml: -------------------------------------------------------------------------------- 1 | # This is an auto-generated file. 2 | # 3 | # Regenerating this file via `configlet sync` will: 4 | # - Recreate every `description` key/value pair 5 | # - Recreate every `reimplements` key/value pair, where they exist in problem-specifications 6 | # - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) 7 | # - Preserve any other key/value pair 8 | # 9 | # As user-added comments (using the # character) will be removed when this file 10 | # is regenerated, comments can be added via a `comment` key. 11 | 12 | [9920ce55-9629-46d5-85d6-4201f4a4234d] 13 | description = "zero rows" 14 | 15 | [70d643ce-a46d-4e93-af58-12d88dd01f21] 16 | description = "single row" 17 | 18 | [a6e5a2a2-fc9a-4b47-9f4f-ed9ad9fbe4bd] 19 | description = "two rows" 20 | 21 | [97206a99-79ba-4b04-b1c5-3c0fa1e16925] 22 | description = "three rows" 23 | 24 | [565a0431-c797-417c-a2c8-2935e01ce306] 25 | description = "four rows" 26 | 27 | [06f9ea50-9f51-4eb2-b9a9-c00975686c27] 28 | description = "five rows" 29 | 30 | [c3912965-ddb4-46a9-848e-3363e6b00b13] 31 | description = "six rows" 32 | 33 | [6cb26c66-7b57-4161-962c-81ec8c99f16b] 34 | description = "ten rows" 35 | -------------------------------------------------------------------------------- /input/exercises/queen-attack/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | `(test-success ,(lookup 'description test) 3 | eq? 4 | attacking? 5 | '(,@(map (lambda (queen) 6 | (map cdr (cdadr queen))) 7 | (lookup 'input test))) 8 | ,(lookup 'expected test))) 9 | 10 | (define (spec->tests spec) 11 | ;; boo to error cases 12 | (lookup 'cases 13 | (cadr 14 | (lookup 'cases 15 | (get-test-specification 'queen-attack))))) 16 | 17 | (let ([spec (get-test-specification 'queen-attack)]) 18 | (put-problem! 19 | 'queen-attack 20 | `((test . ,(map parse-test (spec->tests spec))) 21 | (stubs attacking?) 22 | (version . ,(lookup 'version spec)) 23 | (skeleton . "queen-attack.scm") 24 | (solution . "example.scm") 25 | (markdown 26 | . 27 | ,(splice-exercism 28 | 'queen-attack 29 | 30 | '((sentence "For this track, each queen's position will be represented as a list 31 | containing the row and the column.") 32 | (sentence "You should assume all inputs are valid, there's no need to report errors."))))))) 33 | 34 | -------------------------------------------------------------------------------- /exercises/practice/prime-factors/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "no factors" 5 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 6 | factorize '(1) '()) 7 | (test-success "prime number" 8 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 9 | factorize '(2) '(2)) 10 | (test-success "square of a prime" 11 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 12 | factorize '(9) '(3 3)) 13 | (test-success "cube of a prime" 14 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 15 | factorize '(8) '(2 2 2)) 16 | (test-success "product of primes and non-primes" 17 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 18 | factorize '(12) '(2 2 3)) 19 | (test-success "product of primes" 20 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 21 | factorize '(901255) '(5 17 23 461)) 22 | (test-success "factors include a large prime" 23 | (lambda (xs ys) (equal? (list-sort < xs) (list-sort < ys))) 24 | factorize '(93819012551) '(11 9539 894119)))) 25 | 26 | (run-with-cli "prime-factors.scm" (list test-cases)) 27 | 28 | -------------------------------------------------------------------------------- /input/exercises/phone-number/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (clean-phone-number S) 4 | (let ((good-char? (lambda (x) 5 | (or (char-numeric? x) 6 | (memq x (string->list "()+-. ")))))) 7 | (let-values (((goods bads) 8 | (partition good-char? (string->list S)))) 9 | (if (not (null? bads)) 10 | (error 'clean "phone number has junk chars" bads) 11 | (list->string 12 | (filter char-numeric? goods)))))) 13 | 14 | (define (split-phone-number S) 15 | (let* ((S (clean-phone-number S)) 16 | (digits (string-length S))) 17 | (cond ((= 10 digits) S) 18 | ((and (= 11 digits) (char=? #\1 (string-ref S 0))) 19 | (substring S 1 11)) 20 | (else (error 'clean "bad phone number" S))))) 21 | 22 | (define (clean phone-number) 23 | (let ((cleaned (split-phone-number phone-number))) 24 | (when (or (char=? #\0 (string-ref cleaned 3)) 25 | (char=? #\1 (string-ref cleaned 3)) 26 | (char=? #\0 (string-ref cleaned 0)) 27 | (char=? #\1 (string-ref cleaned 0))) 28 | (error 'clean "exchange code begins with 0" phone-number)) 29 | cleaned)) 30 | 31 | -------------------------------------------------------------------------------- /exercises/practice/phone-number/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (clean-phone-number S) 4 | (let ((good-char? (lambda (x) 5 | (or (char-numeric? x) 6 | (memq x (string->list "()+-. ")))))) 7 | (let-values (((goods bads) 8 | (partition good-char? (string->list S)))) 9 | (if (not (null? bads)) 10 | (error 'clean "phone number has junk chars" bads) 11 | (list->string 12 | (filter char-numeric? goods)))))) 13 | 14 | (define (split-phone-number S) 15 | (let* ((S (clean-phone-number S)) 16 | (digits (string-length S))) 17 | (cond ((= 10 digits) S) 18 | ((and (= 11 digits) (char=? #\1 (string-ref S 0))) 19 | (substring S 1 11)) 20 | (else (error 'clean "bad phone number" S))))) 21 | 22 | (define (clean phone-number) 23 | (let ((cleaned (split-phone-number phone-number))) 24 | (when (or (char=? #\0 (string-ref cleaned 3)) 25 | (char=? #\1 (string-ref cleaned 3)) 26 | (char=? #\0 (string-ref cleaned 0)) 27 | (char=? #\1 (string-ref cleaned 0))) 28 | (error 'clean "exchange code begins with 0" phone-number)) 29 | cleaned)) 30 | 31 | -------------------------------------------------------------------------------- /exercises/practice/leap/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "year not divisible by 4 in common year" 5 | eqv? leap-year? '(2015) #f) 6 | (test-success 7 | "year divisible by 2, not divisible by 4 in common year" 8 | eqv? leap-year? '(1970) #f) 9 | (test-success 10 | "year divisible by 4, not divisible by 100 in leap year" 11 | eqv? leap-year? '(1996) #t) 12 | (test-success 13 | "year divisible by 4 and 5 is still a leap year" eqv? 14 | leap-year? '(1960) #t) 15 | (test-success 16 | "year divisible by 100, not divisible by 400 in common year" 17 | eqv? leap-year? '(2100) #f) 18 | (test-success 19 | "year divisible by 100 but not by 3 is still not a leap year" 20 | eqv? leap-year? '(1900) #f) 21 | (test-success "year divisible by 400 in leap year" eqv? 22 | leap-year? '(2000) #t) 23 | (test-success 24 | "year divisible by 400 but not by 125 is still a leap year" 25 | eqv? leap-year? '(2400) #t) 26 | (test-success 27 | "year divisible by 200, not divisible by 400 in common year" 28 | eqv? leap-year? '(1800) #f))) 29 | 30 | (run-with-cli "leap.scm" (list test-cases)) 31 | 32 | -------------------------------------------------------------------------------- /exercises/practice/trinary/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success 5 | "returns the decimal representation of the input trinary value" 6 | equal? to-decimal '("1") 1) 7 | (test-success "trinary 2 is decimal 2" equal? to-decimal 8 | '("2") 2) 9 | (test-success "trinary 10 is decimal 3" equal? to-decimal 10 | '("10") 3) 11 | (test-success "trinary 11 is decimal 4" equal? to-decimal 12 | '("11") 4) 13 | (test-success "trinary 100 is decimal 9" equal? to-decimal 14 | '("100") 9) 15 | (test-success "trinary 112 is decimal 14" equal? to-decimal 16 | '("112") 14) 17 | (test-success "trinary 222 is decimal 26" equal? to-decimal 18 | '("222") 26) 19 | (test-success "trinary 1122000120 is decimal 32091" equal? 20 | to-decimal '("1122000120") 32091) 21 | (test-success "invalid trinary digits returns 0" equal? 22 | to-decimal '("1234") 0) 23 | (test-success "invalid word as input returns 0" equal? 24 | to-decimal '("carrot") 0) 25 | (test-success 26 | "invalid numbers with letters as input returns 0" equal? 27 | to-decimal '("0a1b2c") 0))) 28 | 29 | (run-with-cli "trinary.scm" (list test-cases)) 30 | 31 | -------------------------------------------------------------------------------- /exercises/practice/acronym/test.scm: -------------------------------------------------------------------------------- 1 | (load "test-util.ss") 2 | 3 | (define test-cases 4 | `((test-success "basic" equal? acronym 5 | '("Portable Network Graphics") "PNG") 6 | (test-success "lowercase words" equal? acronym 7 | '("Ruby on Rails") "ROR") 8 | (test-success "punctuation" equal? acronym 9 | '("First In, First Out") "FIFO") 10 | (test-success "all caps word" equal? acronym 11 | '("GNU Image Manipulation Program") "GIMP") 12 | (test-success "colon" equal? acronym 13 | '("PHP: Hypertext Preprocessor") "PHP") 14 | (test-success "punctuation without whitespace" equal? acronym 15 | '("Complementary metal-oxide semiconductor") "CMOS") 16 | (test-success "very long abbreviation" equal? acronym 17 | '("Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me") 18 | "ROTFLSHTMDCOALM") 19 | (test-success "consecutive delimiters" equal? acronym 20 | '("Something - I made up from thin air") "SIMUFTA") 21 | (test-success "apostrophes" equal? acronym 22 | '("Halley's Comet") "HC") 23 | (test-success "underscore emphasis" equal? acronym 24 | '("The Road _Not_ Taken") "TRNT"))) 25 | 26 | (run-with-cli "acronym.scm" (list test-cases)) 27 | 28 | -------------------------------------------------------------------------------- /input/exercises/affine-cipher/test.ss: -------------------------------------------------------------------------------- 1 | (define (parse-test test) 2 | (let* ((proc (string->symbol (lookup 'property test))) 3 | (input (lookup 'input test)) 4 | (key (lookup 'key input)) 5 | (key-pair (cons (lookup 'a key) (lookup 'b key))) 6 | (phrase (lookup 'phrase input)) 7 | (expected (lookup 'expected test))) 8 | (if (string? expected) 9 | `(test-success ,(lookup 'description test) 10 | equal? 11 | ,proc 12 | '(,key-pair ,phrase) 13 | ,expected) 14 | `(test-error ,(lookup 'description test) ,proc '(,key ,phrase))))) 15 | 16 | (define (spec->tests spec) 17 | (let* ((cases (lookup 'cases spec)) 18 | (encoding (lookup 'cases (car cases))) 19 | (decoding (lookup 'cases (cadr cases)))) 20 | (map parse-test (append encoding decoding)))) 21 | 22 | (let ([spec (get-test-specification 'affine-cipher)]) 23 | (put-problem! 24 | 'affine-cipher 25 | `((test . ,(spec->tests spec)) 26 | (version . ,(lookup 'version spec)) 27 | (skeleton . ,"affine-cipher.scm") 28 | (solution . ,"example.scm") 29 | (stubs encode decode) 30 | (markdown . ,(splice-exercism 'affine-cipher))))) 31 | -------------------------------------------------------------------------------- /exercises/practice/nucleotide-count/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Each of us inherits from our biological parents a set of chemical instructions known as DNA that influence how our bodies are constructed. 4 | All known life depends on DNA! 5 | 6 | > Note: You do not need to understand anything about nucleotides or DNA to complete this exercise. 7 | 8 | DNA is a long chain of other chemicals and the most important are the four nucleotides, adenine, cytosine, guanine and thymine. 9 | A single DNA chain can contain billions of these four nucleotides and the order in which they occur is important! 10 | We call the order of these nucleotides in a bit of DNA a "DNA sequence". 11 | 12 | We represent a DNA sequence as an ordered collection of these four nucleotides and a common way to do that is with a string of characters such as "ATTACG" for a DNA sequence of 6 nucleotides. 13 | 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' for thymine. 14 | 15 | Given a string representing a DNA sequence, count how many of each nucleotide is present. 16 | If the string contains characters that aren't A, C, G, or T then it is invalid and you should signal an error. 17 | 18 | For example: 19 | 20 | ```text 21 | "GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2 22 | "INVALID" -> error 23 | ``` 24 | -------------------------------------------------------------------------------- /exercises/practice/queen-attack/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other. 4 | 5 | In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal. 6 | 7 | A chessboard can be represented by an 8 by 8 array. 8 | 9 | So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so: 10 | 11 | ![A chess board with two queens. Arrows emanating from the queen at c5 indicate possible directions of capture along file, rank and diagonal.](https://assets.exercism.org/images/exercises/queen-attack/queen-capture.svg) 12 | 13 | You are also able to answer whether the queens can attack each other. 14 | In this case, that answer would be yes, they can, because both pieces share a diagonal. 15 | 16 | ## Credit 17 | 18 | The chessboard image was made by [habere-et-dispertire][habere-et-dispertire] using LaTeX and the [chessboard package][chessboard-package] by Ulrike Fischer. 19 | 20 | [habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire 21 | [chessboard-package]: https://github.com/u-fischer/chessboard 22 | -------------------------------------------------------------------------------- /input/exercises/pascals-triangle/test.ss: -------------------------------------------------------------------------------- 1 | 2 | (define (parse-test test) 3 | `(test-success ,(lookup 'description test) 4 | equal? 5 | pascals-triangle 6 | '(,(cdar (lookup 'input test))) 7 | ',(lookup 'expected test))) 8 | 9 | (define (test-2^n n) 10 | `(test-success "all rows sum to power of 2" 11 | (lambda (n ignore) 12 | (null? 13 | (filter not 14 | (map (lambda (row) 15 | (= 1 (bitwise-bit-count (apply + row)))) 16 | (pascals-triangle n))))) 17 | (lambda (x) x) 18 | '(,n) 19 | 'ignore)) 20 | 21 | (define (spec->tests spec) 22 | (map parse-test 23 | (lookup 'cases 24 | (car 25 | (lookup 'cases spec))))) 26 | 27 | (let ((spec (get-test-specification 'pascals-triangle))) 28 | (put-problem! 29 | 'pascals-triangle 30 | `((test . ,(spec->tests spec)) 31 | (stubs pascals-triangle) 32 | (version . ,(lookup 'version spec)) 33 | (skeleton . "pascals-triangle.scm") 34 | (solution . "example.scm") 35 | (markdown . ,(splice-exercism 'pascals-triangle))))) 36 | 37 | -------------------------------------------------------------------------------- /exercises/practice/octal/.docs/instructions.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Convert an octal number, represented as a string (e.g. '1735263'), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion). 4 | 5 | Implement octal to decimal conversion. 6 | Given an octal input string, your program should produce a decimal output. 7 | 8 | ## Note 9 | 10 | - Implement the conversion yourself. 11 | Do not use something else to perform the conversion for you. 12 | - Treat invalid input as octal 0. 13 | 14 | ## About Octal (Base-8) 15 | 16 | Decimal is a base-10 system. 17 | 18 | A number 233 in base 10 notation can be understood 19 | as a linear combination of powers of 10: 20 | 21 | - The rightmost digit gets multiplied by 10^0 = 1 22 | - The next number gets multiplied by 10^1 = 10 23 | - ... 24 | - The nth number gets multiplied by 10^_(n-1)_. 25 | - All these values are summed. 26 | 27 | So: 28 | 29 | ```text 30 | 233 # decimal 31 | = 2*10^2 + 3*10^1 + 3*10^0 32 | = 2*100 + 3*10 + 3*1 33 | ``` 34 | 35 | Octal is similar, but uses powers of 8 rather than powers of 10. 36 | 37 | So: 38 | 39 | ```text 40 | 233 # octal 41 | = 2*8^2 + 3*8^1 + 3*8^0 42 | = 2*64 + 3*8 + 3*1 43 | = 128 + 24 + 3 44 | = 155 45 | ``` 46 | -------------------------------------------------------------------------------- /exercises/practice/change/.docs/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In the mystical village of Coinholt, you stand behind the counter of your bakery, arranging a fresh batch of pastries. 4 | The door creaks open, and in walks Denara, a skilled merchant with a keen eye for quality goods. 5 | After a quick meal, she slides a shimmering coin across the counter, representing a value of 100 units. 6 | 7 | You smile, taking the coin, and glance at the total cost of the meal: 88 units. 8 | That means you need to return 12 units in change. 9 | 10 | Denara holds out her hand expectantly. 11 | "Just give me the fewest coins," she says with a smile. 12 | "My pouch is already full, and I don't want to risk losing them on the road." 13 | 14 | You know you have a few options. 15 | "We have Lumis (worth 10 units), Viras (worth 5 units), and Zenth (worth 2 units) available for change." 16 | 17 | You quickly calculate the possibilities in your head: 18 | 19 | - one Lumis (1 × 10 units) + one Zenth (1 × 2 units) = 2 coins total 20 | - two Viras (2 × 5 units) + one Zenth (1 × 2 units) = 3 coins total 21 | - six Zenth (6 × 2 units) = 6 coins total 22 | 23 | "The best choice is two coins: one Lumis and one Zenth," you say, handing her the change. 24 | 25 | Denara smiles, clearly impressed. 26 | "As always, you've got it right." 27 | -------------------------------------------------------------------------------- /input/exercises/atbash-cipher/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode phrase) 4 | (apply string-append 5 | (atbash-chunks 5 6 | (map convert 7 | (filter relevant-char? 8 | (string->list 9 | (string-downcase phrase))))))) 10 | 11 | (define (decode phrase) 12 | (list->string 13 | (map convert 14 | (filter relevant-char? 15 | (string->list phrase))))) 16 | 17 | (define (convert char) 18 | (if (char-alphabetic? char) 19 | (integer->char 20 | (+ 97 (- 122 (char->integer char)))) 21 | char)) 22 | 23 | (define (relevant-char? char) 24 | (or (char-alphabetic? char) 25 | (char-numeric? char))) 26 | 27 | (define (atbash-chunks size text) 28 | (let loop ((n (length text)) (text text) (needs-space? #f)) 29 | (if (<= n 0) 30 | '() 31 | (let ((next (if needs-space? 32 | (cons #\space (list-head text (min n size))) 33 | (list-head text (min n size))))) 34 | (cons (list->string next) 35 | (loop (- n size) 36 | (list-tail text (min n size)) 37 | (or #t needs-space?))))))) 38 | 39 | 40 | -------------------------------------------------------------------------------- /exercises/practice/atbash-cipher/.meta/example.scm: -------------------------------------------------------------------------------- 1 | (import (rnrs)) 2 | 3 | (define (encode phrase) 4 | (apply string-append 5 | (atbash-chunks 5 6 | (map convert 7 | (filter relevant-char? 8 | (string->list 9 | (string-downcase phrase))))))) 10 | 11 | (define (decode phrase) 12 | (list->string 13 | (map convert 14 | (filter relevant-char? 15 | (string->list phrase))))) 16 | 17 | (define (convert char) 18 | (if (char-alphabetic? char) 19 | (integer->char 20 | (+ 97 (- 122 (char->integer char)))) 21 | char)) 22 | 23 | (define (relevant-char? char) 24 | (or (char-alphabetic? char) 25 | (char-numeric? char))) 26 | 27 | (define (atbash-chunks size text) 28 | (let loop ((n (length text)) (text text) (needs-space? #f)) 29 | (if (<= n 0) 30 | '() 31 | (let ((next (if needs-space? 32 | (cons #\space (list-head text (min n size))) 33 | (list-head text (min n size))))) 34 | (cons (list->string next) 35 | (loop (- n size) 36 | (list-tail text (min n size)) 37 | (or #t needs-space?))))))) 38 | 39 | 40 | --------------------------------------------------------------------------------