diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b33276f1..20ba2a9b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: with: version: 28.2 - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.0.0 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.0.0 - name: Run exercism/emacs-lisp ci (runs tests) for all exercises run: | diff --git a/.github/workflows/configlet-sync.yml b/.github/workflows/configlet-sync.yml index 31117f00..4274bdd1 100644 --- a/.github/workflows/configlet-sync.yml +++ b/.github/workflows/configlet-sync.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.0.0 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.0.0 - name: Fetch configlet uses: exercism/github-actions/configlet-ci@main diff --git a/exercises/practice/food-chain/.docs/instructions.md b/exercises/practice/food-chain/.docs/instructions.md new file mode 100644 index 00000000..125820e3 --- /dev/null +++ b/exercises/practice/food-chain/.docs/instructions.md @@ -0,0 +1,64 @@ +# Instructions + +Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'. + +While you could copy/paste the lyrics, or read them from a file, this problem is much more interesting if you approach it algorithmically. + +This is a [cumulative song][cumulative-song] of unknown origin. + +This is one of many common variants. + +```text +I know an old lady who swallowed a fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a spider. +It wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a bird. +How absurd to swallow a bird! +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cat. +Imagine that, to swallow a cat! +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a dog. +What a hog, to swallow a dog! +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a goat. +Just opened her throat and swallowed a goat! +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a cow. +I don't know how she swallowed a cow! +She swallowed the cow to catch the goat. +She swallowed the goat to catch the dog. +She swallowed the dog to catch the cat. +She swallowed the cat to catch the bird. +She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her. +She swallowed the spider to catch the fly. +I don't know why she swallowed the fly. Perhaps she'll die. + +I know an old lady who swallowed a horse. +She's dead, of course! +``` + +[cumulative-song]: https://en.wikipedia.org/wiki/Cumulative_song diff --git a/exercises/practice/food-chain/.meta/config.json b/exercises/practice/food-chain/.meta/config.json new file mode 100644 index 00000000..cbd54696 --- /dev/null +++ b/exercises/practice/food-chain/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "kmarker1101" + ], + "files": { + "solution": [ + "food-chain.el" + ], + "test": [ + "food-chain-test.el" + ], + "example": [ + ".meta/example.el" + ] + }, + "blurb": "Generate the lyrics of the song 'I Know an Old Lady Who Swallowed a Fly'.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/There_Was_an_Old_Lady_Who_Swallowed_a_Fly" +} diff --git a/exercises/practice/food-chain/.meta/example.el b/exercises/practice/food-chain/.meta/example.el new file mode 100644 index 00000000..579526b2 --- /dev/null +++ b/exercises/practice/food-chain/.meta/example.el @@ -0,0 +1,46 @@ +;;; food-chain.el --- Food Chain (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(defvar +creatures+ ["fly" "spider" "bird" "cat" "dog" "goat" "cow" "horse"]) +(defvar +unique-lines+ ["I don't know why she swallowed the fly. Perhaps she'll die." + "It wriggled and jiggled and tickled inside her." + "How absurd to swallow a bird!" + "Imagine that, to swallow a cat!" + "What a hog, to swallow a dog!" + "Just opened her throat and swallowed a goat!" + "I don't know how she swallowed a cow!" + "She's dead, of course!"]) + +(defun verse-end-p (index) + (or (= 7 index) (zerop index))) + +(defun add-lines (index) + (if (verse-end-p index) + (list (aref +unique-lines+ index)) + (let* ((spider (if (= 2 index) " that wriggled and jiggled and tickled inside her" "")) + (creature (aref +creatures+ index)) + (next-creature (aref +creatures+ (1- index))) + (line (format "She swallowed the %s to catch the %s%s." creature next-creature spider))) + (cons line (add-lines (1- index)))))) + +(defun single-verse (index) + (let* ((start-line (format "I know an old lady who swallowed a %s." (aref +creatures+ index))) + (second-line (unless (verse-end-p index) (aref +unique-lines+ index))) + (verse-block (add-lines index))) + (if second-line + (cons start-line (cons second-line verse-block)) + (cons start-line verse-block)))) + + +(defun recite (start-verse end-verse) + (let (output) + (cl-loop for index from (1- start-verse) below end-verse + do (setq output (append output (single-verse index) '("")))) + (butlast output 1))) ;; Remove the last empty string added + +(provide 'food-chain) +;;; food-chain.el ends here + diff --git a/exercises/practice/food-chain/.meta/tests.toml b/exercises/practice/food-chain/.meta/tests.toml new file mode 100644 index 00000000..30c5b980 --- /dev/null +++ b/exercises/practice/food-chain/.meta/tests.toml @@ -0,0 +1,40 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[751dce68-9412-496e-b6e8-855998c56166] +description = "fly" + +[6c56f861-0c5e-4907-9a9d-b2efae389379] +description = "spider" + +[3edf5f33-bef1-4e39-ae67-ca5eb79203fa] +description = "bird" + +[e866a758-e1ff-400e-9f35-f27f28cc288f] +description = "cat" + +[3f02c30e-496b-4b2a-8491-bc7e2953cafb] +description = "dog" + +[4b3fd221-01ea-46e0-825b-5734634fbc59] +description = "goat" + +[1b707da9-7001-4fac-941f-22ad9c7a65d4] +description = "cow" + +[3cb10d46-ae4e-4d2c-9296-83c9ffc04cdc] +description = "horse" + +[22b863d5-17e4-4d1e-93e4-617329a5c050] +description = "multiple verses" + +[e626b32b-745c-4101-bcbd-3b13456893db] +description = "full song" diff --git a/exercises/practice/food-chain/food-chain-test.el b/exercises/practice/food-chain/food-chain-test.el new file mode 100644 index 00000000..ad394759 --- /dev/null +++ b/exercises/practice/food-chain/food-chain-test.el @@ -0,0 +1,158 @@ +;;; food-chain-test.el --- Food Chain (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + + +(load-file "food-chain.el") +(declare-function recite "food-chain.el" (start-verse end-verse)) + + +(ert-deftest fly () + (let ((expected '("I know an old lady who swallowed a fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 1 1) expected)))) + +(ert-deftest spider () + (let ((expected '("I know an old lady who swallowed a spider." + "It wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 2 2) expected)))) + + +(ert-deftest bird () + (let ((expected '("I know an old lady who swallowed a bird." + "How absurd to swallow a bird!" + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 3 3) expected)))) + + +(ert-deftest cat () + (let ((expected '("I know an old lady who swallowed a cat." + "Imagine that, to swallow a cat!" + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 4 4) expected)))) + + +(ert-deftest dog () + (let ((expected '("I know an old lady who swallowed a dog." + "What a hog, to swallow a dog!" + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 5 5) expected)))) + + +(ert-deftest goat () + (let ((expected '("I know an old lady who swallowed a goat." + "Just opened her throat and swallowed a goat!" + "She swallowed the goat to catch the dog." + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 6 6) expected)))) + + +(ert-deftest cow () + (let ((expected '("I know an old lady who swallowed a cow." + "I don't know how she swallowed a cow!" + "She swallowed the cow to catch the goat." + "She swallowed the goat to catch the dog." + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 7 7) expected)))) + + +(ert-deftest horse () + (let ((expected '("I know an old lady who swallowed a horse." + "She's dead, of course!"))) + (should (equal (recite 8 8) expected)))) + + +(ert-deftest multiple-verses () + (let ((expected '("I know an old lady who swallowed a fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a spider." + "It wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a bird." + "How absurd to swallow a bird!" + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die."))) + (should (equal (recite 1 3) expected)))) + + +(ert-deftest full-song () + (let ((expected '("I know an old lady who swallowed a fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a spider." + "It wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a bird." + "How absurd to swallow a bird!" + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a cat." + "Imagine that, to swallow a cat!" + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a dog." + "What a hog, to swallow a dog!" + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a goat." + "Just opened her throat and swallowed a goat!" + "She swallowed the goat to catch the dog." + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a cow." + "I don't know how she swallowed a cow!" + "She swallowed the cow to catch the goat." + "She swallowed the goat to catch the dog." + "She swallowed the dog to catch the cat." + "She swallowed the cat to catch the bird." + "She swallowed the bird to catch the spider that wriggled and jiggled and tickled inside her." + "She swallowed the spider to catch the fly." + "I don't know why she swallowed the fly. Perhaps she'll die." + "" + "I know an old lady who swallowed a horse." + "She's dead, of course!"))) + (should (equal (recite 1 8) expected)))) + + +(provide 'food-chain-test) +;;; food-chain-test.el ends here diff --git a/exercises/practice/food-chain/food-chain.el b/exercises/practice/food-chain/food-chain.el new file mode 100644 index 00000000..2e6df614 --- /dev/null +++ b/exercises/practice/food-chain/food-chain.el @@ -0,0 +1,14 @@ +;;; food-chain.el --- Food Chain (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + + +(defun recite (end-verse start-verse) + (error "Delete this S-Expression and write your own implementation")) + + +(provide 'food-chain) +;;; food-chain.el ends here +