From 6d053b51aa192407aee4b111d0b018a27742be7a Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 17:43:59 +0100 Subject: [PATCH 01/14] added nucleotide-count exercise --- config.json | 10 +++++++- .../nucleotide-count/.docs/instructions.md | 23 +++++++++++++++++ .../nucleotide-count/.meta/config.json | 19 ++++++++++++++ .../nucleotide-count/.meta/example.nu | 22 ++++++++++++++++ .../nucleotide-count/.meta/tests.toml | 25 +++++++++++++++++++ .../nucleotide-count/nucleotide-count.nu | 3 +++ exercises/practice/nucleotide-count/tests.nu | 10 ++++++++ 7 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 exercises/practice/nucleotide-count/.docs/instructions.md create mode 100644 exercises/practice/nucleotide-count/.meta/config.json create mode 100644 exercises/practice/nucleotide-count/.meta/example.nu create mode 100644 exercises/practice/nucleotide-count/.meta/tests.toml create mode 100644 exercises/practice/nucleotide-count/nucleotide-count.nu create mode 100644 exercises/practice/nucleotide-count/tests.nu diff --git a/config.json b/config.json index 6c35fea..0222b2c 100644 --- a/config.json +++ b/config.json @@ -149,6 +149,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "nucleotide-count", + "name": "Nucleotide Count", + "uuid": "f02a6a6d-f0c8-428c-b30d-b1d805ed0c5d", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, @@ -162,4 +170,4 @@ "typing/static", "used_for/scripts" ] -} \ No newline at end of file +} diff --git a/exercises/practice/nucleotide-count/.docs/instructions.md b/exercises/practice/nucleotide-count/.docs/instructions.md new file mode 100644 index 0000000..548d9ba --- /dev/null +++ b/exercises/practice/nucleotide-count/.docs/instructions.md @@ -0,0 +1,23 @@ +# Instructions + +Each of us inherits from our biological parents a set of chemical instructions known as DNA that influence how our bodies are constructed. +All known life depends on DNA! + +> Note: You do not need to understand anything about nucleotides or DNA to complete this exercise. + +DNA is a long chain of other chemicals and the most important are the four nucleotides, adenine, cytosine, guanine and thymine. +A single DNA chain can contain billions of these four nucleotides and the order in which they occur is important! +We call the order of these nucleotides in a bit of DNA a "DNA sequence". + +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. +'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' for thymine. + +Given a string representing a DNA sequence, count how many of each nucleotide is present. +If the string contains characters that aren't A, C, G, or T then it is invalid and you should signal an error. + +For example: + +```text +"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2 +"INVALID" -> error +``` diff --git a/exercises/practice/nucleotide-count/.meta/config.json b/exercises/practice/nucleotide-count/.meta/config.json new file mode 100644 index 0000000..90c4b6c --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "nucleotide-count.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", + "source": "The Calculating DNA Nucleotides_problem at Rosalind", + "source_url": "https://rosalind.info/problems/dna/" +} diff --git a/exercises/practice/nucleotide-count/.meta/example.nu b/exercises/practice/nucleotide-count/.meta/example.nu new file mode 100644 index 0000000..65f6e6f --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/example.nu @@ -0,0 +1,22 @@ +export def nucleotideCounts [strand: string] { + let chars = $strand + | split chars + + if ($chars | any {|c| not ($c in [A C G T])}) { + error make {msg: "Invalid nucleotide in strand"} + } + + let data = $chars + | uniq -c + + let counts = $data.value + | zip $data.count + | into record + + { + A: 0 + C: 0 + G: 0 + T: 0 + } | merge $counts +} diff --git a/exercises/practice/nucleotide-count/.meta/tests.toml b/exercises/practice/nucleotide-count/.meta/tests.toml new file mode 100644 index 0000000..7c55e53 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/tests.toml @@ -0,0 +1,25 @@ +# 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. + +[3e5c30a8-87e2-4845-a815-a49671ade970] +description = "empty strand" + +[a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] +description = "can count one nucleotide in single-character input" + +[eca0d565-ed8c-43e7-9033-6cefbf5115b5] +description = "strand with repeated nucleotide" + +[40a45eac-c83f-4740-901a-20b22d15a39f] +description = "strand with multiple nucleotides" + +[b4c47851-ee9e-4b0a-be70-a86e343bd851] +description = "strand with invalid nucleotides" diff --git a/exercises/practice/nucleotide-count/nucleotide-count.nu b/exercises/practice/nucleotide-count/nucleotide-count.nu new file mode 100644 index 0000000..da35bea --- /dev/null +++ b/exercises/practice/nucleotide-count/nucleotide-count.nu @@ -0,0 +1,3 @@ +export def nucleotideCounts [strand: string] { + error make {msg: "Please implement nucleotideCounts"} +} diff --git a/exercises/practice/nucleotide-count/tests.nu b/exercises/practice/nucleotide-count/tests.nu new file mode 100644 index 0000000..b389215 --- /dev/null +++ b/exercises/practice/nucleotide-count/tests.nu @@ -0,0 +1,10 @@ +use nucleotide-count.nu nucleotideCounts +use std/assert + +assert equal (nucleotideCounts "") {A: 0, C: 0, G: 0, T: 0} +assert equal (nucleotideCounts "G") {A: 0, C: 0, G: 1, T: 0} +assert equal (nucleotideCounts "GGGGGGG") {A: 0, C: 0, G: 7, T: 0} +assert equal ( + nucleotideCounts "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC" +) {A: 20, C: 12, G: 17, T: 21} +assert error {|| (nucleotideCounts "AGXXACT")} From 8e78ae99ff8d9c69e4a2f5f4b483a78cc5aac61f Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 18:12:21 +0100 Subject: [PATCH 02/14] added allergies exercise also corrected difficulty for nucleotide-count --- config.json | 10 +- .../practice/allergies/.docs/instructions.md | 27 +++ .../practice/allergies/.meta/config.json | 19 +++ exercises/practice/allergies/.meta/example.nu | 27 +++ exercises/practice/allergies/.meta/tests.toml | 160 ++++++++++++++++++ exercises/practice/allergies/allergies.nu | 7 + exercises/practice/allergies/tests.nu | 105 ++++++++++++ 7 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 exercises/practice/allergies/.docs/instructions.md create mode 100644 exercises/practice/allergies/.meta/config.json create mode 100644 exercises/practice/allergies/.meta/example.nu create mode 100644 exercises/practice/allergies/.meta/tests.toml create mode 100644 exercises/practice/allergies/allergies.nu create mode 100644 exercises/practice/allergies/tests.nu diff --git a/config.json b/config.json index 0222b2c..3f614c1 100644 --- a/config.json +++ b/config.json @@ -156,7 +156,15 @@ "uuid": "f02a6a6d-f0c8-428c-b30d-b1d805ed0c5d", "practices": [], "prerequisites": [], - "difficulty": 1 + "difficulty": 2 + }, + { + "slug": "allergies", + "name": "Allergies", + "uuid": "af02524b-1972-4c50-b91b-e0ee0355ca07", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/allergies/.docs/instructions.md b/exercises/practice/allergies/.docs/instructions.md new file mode 100644 index 0000000..daf8cfd --- /dev/null +++ b/exercises/practice/allergies/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies. + +An allergy test produces a single numeric score which contains the information about all the allergies the person has (that they were tested for). + +The list of items (and their value) that were tested are: + +- eggs (1) +- peanuts (2) +- shellfish (4) +- strawberries (8) +- tomatoes (16) +- chocolate (32) +- pollen (64) +- cats (128) + +So if Tom is allergic to peanuts and chocolate, he gets a score of 34. + +Now, given just that score of 34, your program should be able to say: + +- Whether Tom is allergic to any one of those allergens listed above. +- All the allergens Tom is allergic to. + +Note: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.). +Your program should ignore those components of the score. +For example, if the allergy score is 257, your program should only report the eggs (1) allergy. diff --git a/exercises/practice/allergies/.meta/config.json b/exercises/practice/allergies/.meta/config.json new file mode 100644 index 0000000..a30052e --- /dev/null +++ b/exercises/practice/allergies/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "allergies.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.", + "source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.", + "source_url": "https://www.turing.edu/" +} diff --git a/exercises/practice/allergies/.meta/example.nu b/exercises/practice/allergies/.meta/example.nu new file mode 100644 index 0000000..10137a7 --- /dev/null +++ b/exercises/practice/allergies/.meta/example.nu @@ -0,0 +1,27 @@ +const ALLERGENS = [ + eggs + peanuts + shellfish + strawberries + tomatoes + chocolate + pollen + cats +] + +def get_value [item: string] { + $ALLERGENS + | enumerate + | where {|row| $row.item == $item} + | 2 ** ($in.index.0) +} + +export def allergicTo [item: string, score: int] { + let value = get_value $item + ($score bit-and $value) != 0 +} + +export def list [score: int] { + $ALLERGENS + | where {|allergen| allergicTo $allergen $score} +} diff --git a/exercises/practice/allergies/.meta/tests.toml b/exercises/practice/allergies/.meta/tests.toml new file mode 100644 index 0000000..799ab85 --- /dev/null +++ b/exercises/practice/allergies/.meta/tests.toml @@ -0,0 +1,160 @@ +# 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. + +[17fc7296-2440-4ac4-ad7b-d07c321bc5a0] +description = "testing for eggs allergy -> not allergic to anything" + +[07ced27b-1da5-4c2e-8ae2-cb2791437546] +description = "testing for eggs allergy -> allergic only to eggs" + +[5035b954-b6fa-4b9b-a487-dae69d8c5f96] +description = "testing for eggs allergy -> allergic to eggs and something else" + +[64a6a83a-5723-4b5b-a896-663307403310] +description = "testing for eggs allergy -> allergic to something, but not eggs" + +[90c8f484-456b-41c4-82ba-2d08d93231c6] +description = "testing for eggs allergy -> allergic to everything" + +[d266a59a-fccc-413b-ac53-d57cb1f0db9d] +description = "testing for peanuts allergy -> not allergic to anything" + +[ea210a98-860d-46b2-a5bf-50d8995b3f2a] +description = "testing for peanuts allergy -> allergic only to peanuts" + +[eac69ae9-8d14-4291-ac4b-7fd2c73d3a5b] +description = "testing for peanuts allergy -> allergic to peanuts and something else" + +[9152058c-ce39-4b16-9b1d-283ec6d25085] +description = "testing for peanuts allergy -> allergic to something, but not peanuts" + +[d2d71fd8-63d5-40f9-a627-fbdaf88caeab] +description = "testing for peanuts allergy -> allergic to everything" + +[b948b0a1-cbf7-4b28-a244-73ff56687c80] +description = "testing for shellfish allergy -> not allergic to anything" + +[9ce9a6f3-53e9-4923-85e0-73019047c567] +description = "testing for shellfish allergy -> allergic only to shellfish" + +[b272fca5-57ba-4b00-bd0c-43a737ab2131] +description = "testing for shellfish allergy -> allergic to shellfish and something else" + +[21ef8e17-c227-494e-8e78-470a1c59c3d8] +description = "testing for shellfish allergy -> allergic to something, but not shellfish" + +[cc789c19-2b5e-4c67-b146-625dc8cfa34e] +description = "testing for shellfish allergy -> allergic to everything" + +[651bde0a-2a74-46c4-ab55-02a0906ca2f5] +description = "testing for strawberries allergy -> not allergic to anything" + +[b649a750-9703-4f5f-b7f7-91da2c160ece] +description = "testing for strawberries allergy -> allergic only to strawberries" + +[50f5f8f3-3bac-47e6-8dba-2d94470a4bc6] +description = "testing for strawberries allergy -> allergic to strawberries and something else" + +[23dd6952-88c9-48d7-a7d5-5d0343deb18d] +description = "testing for strawberries allergy -> allergic to something, but not strawberries" + +[74afaae2-13b6-43a2-837a-286cd42e7d7e] +description = "testing for strawberries allergy -> allergic to everything" + +[c49a91ef-6252-415e-907e-a9d26ef61723] +description = "testing for tomatoes allergy -> not allergic to anything" + +[b69c5131-b7d0-41ad-a32c-e1b2cc632df8] +description = "testing for tomatoes allergy -> allergic only to tomatoes" + +[1ca50eb1-f042-4ccf-9050-341521b929ec] +description = "testing for tomatoes allergy -> allergic to tomatoes and something else" + +[e9846baa-456b-4eff-8025-034b9f77bd8e] +description = "testing for tomatoes allergy -> allergic to something, but not tomatoes" + +[b2414f01-f3ad-4965-8391-e65f54dad35f] +description = "testing for tomatoes allergy -> allergic to everything" + +[978467ab-bda4-49f7-b004-1d011ead947c] +description = "testing for chocolate allergy -> not allergic to anything" + +[59cf4e49-06ea-4139-a2c1-d7aad28f8cbc] +description = "testing for chocolate allergy -> allergic only to chocolate" + +[b0a7c07b-2db7-4f73-a180-565e07040ef1] +description = "testing for chocolate allergy -> allergic to chocolate and something else" + +[f5506893-f1ae-482a-b516-7532ba5ca9d2] +description = "testing for chocolate allergy -> allergic to something, but not chocolate" + +[02debb3d-d7e2-4376-a26b-3c974b6595c6] +description = "testing for chocolate allergy -> allergic to everything" + +[17f4a42b-c91e-41b8-8a76-4797886c2d96] +description = "testing for pollen allergy -> not allergic to anything" + +[7696eba7-1837-4488-882a-14b7b4e3e399] +description = "testing for pollen allergy -> allergic only to pollen" + +[9a49aec5-fa1f-405d-889e-4dfc420db2b6] +description = "testing for pollen allergy -> allergic to pollen and something else" + +[3cb8e79f-d108-4712-b620-aa146b1954a9] +description = "testing for pollen allergy -> allergic to something, but not pollen" + +[1dc3fe57-7c68-4043-9d51-5457128744b2] +description = "testing for pollen allergy -> allergic to everything" + +[d3f523d6-3d50-419b-a222-d4dfd62ce314] +description = "testing for cats allergy -> not allergic to anything" + +[eba541c3-c886-42d3-baef-c048cb7fcd8f] +description = "testing for cats allergy -> allergic only to cats" + +[ba718376-26e0-40b7-bbbe-060287637ea5] +description = "testing for cats allergy -> allergic to cats and something else" + +[3c6dbf4a-5277-436f-8b88-15a206f2d6c4] +description = "testing for cats allergy -> allergic to something, but not cats" + +[1faabb05-2b98-4995-9046-d83e4a48a7c1] +description = "testing for cats allergy -> allergic to everything" + +[f9c1b8e7-7dc5-4887-aa93-cebdcc29dd8f] +description = "list when: -> no allergies" + +[9e1a4364-09a6-4d94-990f-541a94a4c1e8] +description = "list when: -> just eggs" + +[8851c973-805e-4283-9e01-d0c0da0e4695] +description = "list when: -> just peanuts" + +[2c8943cb-005e-435f-ae11-3e8fb558ea98] +description = "list when: -> just strawberries" + +[6fa95d26-044c-48a9-8a7b-9ee46ec32c5c] +description = "list when: -> eggs and peanuts" + +[19890e22-f63f-4c5c-a9fb-fb6eacddfe8e] +description = "list when: -> more than eggs but not peanuts" + +[4b68f470-067c-44e4-889f-c9fe28917d2f] +description = "list when: -> lots of stuff" + +[0881b7c5-9efa-4530-91bd-68370d054bc7] +description = "list when: -> everything" + +[12ce86de-b347-42a0-ab7c-2e0570f0c65b] +description = "list when: -> no allergen score parts" + +[93c2df3e-4f55-4fed-8116-7513092819cd] +description = "list when: -> no allergen score parts without highest valid score" diff --git a/exercises/practice/allergies/allergies.nu b/exercises/practice/allergies/allergies.nu new file mode 100644 index 0000000..d9a846e --- /dev/null +++ b/exercises/practice/allergies/allergies.nu @@ -0,0 +1,7 @@ +export def allergicTo [item: string, score: int] { + error make {msg: "Please implement allergicTo"} +} + +export def list [score: int] { + error make {msg: "Please implement list"} +} diff --git a/exercises/practice/allergies/tests.nu b/exercises/practice/allergies/tests.nu new file mode 100644 index 0000000..bde44e0 --- /dev/null +++ b/exercises/practice/allergies/tests.nu @@ -0,0 +1,105 @@ +use allergies.nu [allergicTo list] +use std/assert + +# testing for eggs allergy +assert not (allergicTo eggs 0) +assert (allergicTo eggs 1) +assert (allergicTo eggs 3) +assert not (allergicTo eggs 2) +assert (allergicTo eggs 255) + +# testing for peanuts allergy +assert not (allergicTo peanuts 0) +assert (allergicTo peanuts 2) +assert (allergicTo peanuts 7) +assert not (allergicTo peanuts 5) +assert (allergicTo peanuts 255) + +# testing for shellfish allergy +assert not (allergicTo shellfish 0) +assert (allergicTo shellfish 4) +assert (allergicTo shellfish 14) +assert not (allergicTo shellfish 10) +assert (allergicTo shellfish 255) + +# testing for strawberries allergy +assert not (allergicTo strawberries 0) +assert (allergicTo strawberries 8) +assert (allergicTo strawberries 28) +assert not (allergicTo strawberries 20) +assert (allergicTo strawberries 255) + +# testing for tomatoes allergy +assert not (allergicTo tomatoes 0) +assert (allergicTo tomatoes 16) +assert (allergicTo tomatoes 56) +assert not (allergicTo tomatoes 40) +assert (allergicTo tomatoes 255) + +# testing for chocolate allergy +assert not (allergicTo chocolate 0) +assert (allergicTo chocolate 32) +assert (allergicTo chocolate 112) +assert not (allergicTo chocolate 80) +assert (allergicTo chocolate 255) + +# testing for pollen allergy +assert not (allergicTo pollen 0) +assert (allergicTo pollen 64) +assert (allergicTo pollen 224) +assert not (allergicTo pollen 160) +assert (allergicTo pollen 255) + +# testing for cats allergy +assert not (allergicTo cats 0) +assert (allergicTo cats 128) +assert (allergicTo cats 192) +assert not (allergicTo cats 64) +assert (allergicTo cats 255) + +# no allergies +assert equal (list 0) [] + +# just eggs +assert equal (list 1) [eggs] + +# just peanuts +assert equal (list 2) [peanuts] + +# just strawberries +assert equal (list 8) [strawberries] + +# eggs and peanuts +assert equal (list 3) [eggs, peanuts] + +# more than eggs but not peanuts +assert equal (list 5) [eggs, shellfish] + +# lots of stuff +assert equal (list 248) [strawberries, tomatoes, chocolate, pollen, cats] + +# everything +assert equal (list 255) [ + eggs + peanuts + shellfish + strawberries + tomatoes + chocolate + pollen + cats +] + +# no allergen score parts +assert equal (list 509) [ + eggs + shellfish + strawberries + tomatoes + chocolate + pollen + cats +] + +# no allergen score parts without highest valid score +assert equal (list 257) [eggs] From b042cc4ab27cb8940a5e86b81e798e950e19df1e Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 18:21:19 +0100 Subject: [PATCH 03/14] added leap --- config.json | 8 ++++ exercises/practice/leap/.docs/instructions.md | 3 ++ exercises/practice/leap/.docs/introduction.md | 16 ++++++++ exercises/practice/leap/.meta/config.json | 19 ++++++++++ exercises/practice/leap/.meta/example.nu | 9 +++++ exercises/practice/leap/.meta/tests.toml | 37 +++++++++++++++++++ exercises/practice/leap/leap.nu | 3 ++ exercises/practice/leap/tests.nu | 12 ++++++ 8 files changed, 107 insertions(+) create mode 100644 exercises/practice/leap/.docs/instructions.md create mode 100644 exercises/practice/leap/.docs/introduction.md create mode 100644 exercises/practice/leap/.meta/config.json create mode 100644 exercises/practice/leap/.meta/example.nu create mode 100644 exercises/practice/leap/.meta/tests.toml create mode 100644 exercises/practice/leap/leap.nu create mode 100644 exercises/practice/leap/tests.nu diff --git a/config.json b/config.json index 3f614c1..77b23f8 100644 --- a/config.json +++ b/config.json @@ -165,6 +165,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "leap", + "name": "Leap", + "uuid": "56df31c7-1f94-41d8-b69d-318c2249304e", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/leap/.docs/instructions.md b/exercises/practice/leap/.docs/instructions.md new file mode 100644 index 0000000..b14f856 --- /dev/null +++ b/exercises/practice/leap/.docs/instructions.md @@ -0,0 +1,3 @@ +# Instructions + +Your task is to determine whether a given year is a leap year. diff --git a/exercises/practice/leap/.docs/introduction.md b/exercises/practice/leap/.docs/introduction.md new file mode 100644 index 0000000..4ffd2da --- /dev/null +++ b/exercises/practice/leap/.docs/introduction.md @@ -0,0 +1,16 @@ +# Introduction + +A leap year (in the Gregorian calendar) occurs: + +- In every year that is evenly divisible by 4. +- 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. + +Some examples: + +- 1997 was not a leap year as it's not divisible by 4. +- 1900 was not a leap year as it's not divisible by 400. +- 2000 was a leap year! + +~~~~exercism/note +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). +~~~~ diff --git a/exercises/practice/leap/.meta/config.json b/exercises/practice/leap/.meta/config.json new file mode 100644 index 0000000..91c82f8 --- /dev/null +++ b/exercises/practice/leap/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "leap.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Determine whether a given year is a leap year.", + "source": "CodeRanch Cattle Drive, Assignment 3", + "source_url": "https://web.archive.org/web/20240907033714/https://coderanch.com/t/718816/Leap" +} diff --git a/exercises/practice/leap/.meta/example.nu b/exercises/practice/leap/.meta/example.nu new file mode 100644 index 0000000..438f584 --- /dev/null +++ b/exercises/practice/leap/.meta/example.nu @@ -0,0 +1,9 @@ +export def leapYear [year: int] { + if $year mod 4 != 0 { + false + } else if $year mod 100 != 0 { + true + } else { + $year mod 400 == 0 + } +} diff --git a/exercises/practice/leap/.meta/tests.toml b/exercises/practice/leap/.meta/tests.toml new file mode 100644 index 0000000..ce6ba32 --- /dev/null +++ b/exercises/practice/leap/.meta/tests.toml @@ -0,0 +1,37 @@ +# 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. + +[6466b30d-519c-438e-935d-388224ab5223] +description = "year not divisible by 4 in common year" + +[ac227e82-ee82-4a09-9eb6-4f84331ffdb0] +description = "year divisible by 2, not divisible by 4 in common year" + +[4fe9b84c-8e65-489e-970b-856d60b8b78e] +description = "year divisible by 4, not divisible by 100 in leap year" + +[7fc6aed7-e63c-48f5-ae05-5fe182f60a5d] +description = "year divisible by 4 and 5 is still a leap year" + +[78a7848f-9667-4192-ae53-87b30c9a02dd] +description = "year divisible by 100, not divisible by 400 in common year" + +[9d70f938-537c-40a6-ba19-f50739ce8bac] +description = "year divisible by 100 but not by 3 is still not a leap year" + +[42ee56ad-d3e6-48f1-8e3f-c84078d916fc] +description = "year divisible by 400 is leap year" + +[57902c77-6fe9-40de-8302-587b5c27121e] +description = "year divisible by 400 but not by 125 is still a leap year" + +[c30331f6-f9f6-4881-ad38-8ca8c12520c1] +description = "year divisible by 200, not divisible by 400 in common year" diff --git a/exercises/practice/leap/leap.nu b/exercises/practice/leap/leap.nu new file mode 100644 index 0000000..11b2cba --- /dev/null +++ b/exercises/practice/leap/leap.nu @@ -0,0 +1,3 @@ +export def leapYear [year: int] { + error make {msg: "Please implement leapYear"} +} diff --git a/exercises/practice/leap/tests.nu b/exercises/practice/leap/tests.nu new file mode 100644 index 0000000..08fcdd7 --- /dev/null +++ b/exercises/practice/leap/tests.nu @@ -0,0 +1,12 @@ +use leap.nu leapYear +use std/assert + +assert not (leapYear 2015) +assert not (leapYear 1970) +assert (leapYear 1996) +assert (leapYear 1960) +assert not (leapYear 2100) +assert not (leapYear 1900) +assert (leapYear 2000) +assert (leapYear 2400) +assert not (leapYear 1800) From 3b4e2d3093daba7ab087072a1de983da37ab44ea Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 19:35:55 +0100 Subject: [PATCH 04/14] added raindrops exercise --- config.json | 8 +++ .../practice/raindrops/.docs/instructions.md | 24 +++++++ .../practice/raindrops/.docs/introduction.md | 3 + .../practice/raindrops/.meta/config.json | 19 ++++++ exercises/practice/raindrops/.meta/example.nu | 9 +++ exercises/practice/raindrops/.meta/tests.toml | 64 +++++++++++++++++++ exercises/practice/raindrops/raindrops.nu | 3 + exercises/practice/raindrops/tests.nu | 39 +++++++++++ 8 files changed, 169 insertions(+) create mode 100644 exercises/practice/raindrops/.docs/instructions.md create mode 100644 exercises/practice/raindrops/.docs/introduction.md create mode 100644 exercises/practice/raindrops/.meta/config.json create mode 100644 exercises/practice/raindrops/.meta/example.nu create mode 100644 exercises/practice/raindrops/.meta/tests.toml create mode 100644 exercises/practice/raindrops/raindrops.nu create mode 100644 exercises/practice/raindrops/tests.nu diff --git a/config.json b/config.json index 77b23f8..ce4ab1f 100644 --- a/config.json +++ b/config.json @@ -173,6 +173,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "raindrops", + "name": "Raindrops", + "uuid": "6373b2e6-4db8-4b3b-b9f6-870b2e0b10a8", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/raindrops/.docs/instructions.md b/exercises/practice/raindrops/.docs/instructions.md new file mode 100644 index 0000000..df64410 --- /dev/null +++ b/exercises/practice/raindrops/.docs/instructions.md @@ -0,0 +1,24 @@ +# Instructions + +Your task is to convert a number into its corresponding raindrop sounds. + +If a given number: + +- is divisible by 3, add "Pling" to the result. +- is divisible by 5, add "Plang" to the result. +- is divisible by 7, add "Plong" to the result. +- **is not** divisible by 3, 5, or 7, the result should be the number as a string. + +## Examples + +- 28 is divisible by 7, but not 3 or 5, so the result would be `"Plong"`. +- 30 is divisible by 3 and 5, but not 7, so the result would be `"PlingPlang"`. +- 34 is not divisible by 3, 5, or 7, so the result would be `"34"`. + +~~~~exercism/note +A common way to test if one number is evenly divisible by another is to compare the [remainder][remainder] or [modulus][modulo] to zero. +Most languages provide operators or functions for one (or both) of these. + +[remainder]: https://exercism.org/docs/programming/operators/remainder +[modulo]: https://en.wikipedia.org/wiki/Modulo_operation +~~~~ diff --git a/exercises/practice/raindrops/.docs/introduction.md b/exercises/practice/raindrops/.docs/introduction.md new file mode 100644 index 0000000..ba12100 --- /dev/null +++ b/exercises/practice/raindrops/.docs/introduction.md @@ -0,0 +1,3 @@ +# Introduction + +Raindrops is a slightly more complex version of the FizzBuzz challenge, a classic interview question. diff --git a/exercises/practice/raindrops/.meta/config.json b/exercises/practice/raindrops/.meta/config.json new file mode 100644 index 0000000..fbbabb9 --- /dev/null +++ b/exercises/practice/raindrops/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "raindrops.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", + "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.", + "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" +} diff --git a/exercises/practice/raindrops/.meta/example.nu b/exercises/practice/raindrops/.meta/example.nu new file mode 100644 index 0000000..2b3102e --- /dev/null +++ b/exercises/practice/raindrops/.meta/example.nu @@ -0,0 +1,9 @@ +export def convert [num: int] { + [3 5 7] + | zip [Pling Plang Plong] + | where {|pair| $num mod $pair.0 == 0} + | each {|pair| $pair.1} + | if ($in | is-empty) { + $num | into string + } else { $in | str join } +} diff --git a/exercises/practice/raindrops/.meta/tests.toml b/exercises/practice/raindrops/.meta/tests.toml new file mode 100644 index 0000000..756d16c --- /dev/null +++ b/exercises/practice/raindrops/.meta/tests.toml @@ -0,0 +1,64 @@ +# 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. + +[1575d549-e502-46d4-a8e1-6b7bec6123d8] +description = "the sound for 1 is 1" + +[1f51a9f9-4895-4539-b182-d7b0a5ab2913] +description = "the sound for 3 is Pling" + +[2d9bfae5-2b21-4bcd-9629-c8c0e388f3e0] +description = "the sound for 5 is Plang" + +[d7e60daa-32ef-4c23-b688-2abff46c4806] +description = "the sound for 7 is Plong" + +[6bb4947b-a724-430c-923f-f0dc3d62e56a] +description = "the sound for 6 is Pling as it has a factor 3" + +[ce51e0e8-d9d4-446d-9949-96eac4458c2d] +description = "2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base" + +[0dd66175-e3e2-47fc-8750-d01739856671] +description = "the sound for 9 is Pling as it has a factor 3" + +[022c44d3-2182-4471-95d7-c575af225c96] +description = "the sound for 10 is Plang as it has a factor 5" + +[37ab74db-fed3-40ff-b7b9-04acdfea8edf] +description = "the sound for 14 is Plong as it has a factor of 7" + +[31f92999-6afb-40ee-9aa4-6d15e3334d0f] +description = "the sound for 15 is PlingPlang as it has factors 3 and 5" + +[ff9bb95d-6361-4602-be2c-653fe5239b54] +description = "the sound for 21 is PlingPlong as it has factors 3 and 7" + +[d2e75317-b72e-40ab-8a64-6734a21dece1] +description = "the sound for 25 is Plang as it has a factor 5" + +[a09c4c58-c662-4e32-97fe-f1501ef7125c] +description = "the sound for 27 is Pling as it has a factor 3" + +[bdf061de-8564-4899-a843-14b48b722789] +description = "the sound for 35 is PlangPlong as it has factors 5 and 7" + +[c4680bee-69ba-439d-99b5-70c5fd1a7a83] +description = "the sound for 49 is Plong as it has a factor 7" + +[17f2bc9a-b65a-4d23-8ccd-266e8c271444] +description = "the sound for 52 is 52" + +[e46677ed-ff1a-419f-a740-5c713d2830e4] +description = "the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7" + +[13c6837a-0fcd-4b86-a0eb-20572f7deb0b] +description = "the sound for 3125 is Plang as it has a factor 5" diff --git a/exercises/practice/raindrops/raindrops.nu b/exercises/practice/raindrops/raindrops.nu new file mode 100644 index 0000000..0a908e4 --- /dev/null +++ b/exercises/practice/raindrops/raindrops.nu @@ -0,0 +1,3 @@ +export def convert [num: int] { + error make {msg: "Please implement convert"} +} diff --git a/exercises/practice/raindrops/tests.nu b/exercises/practice/raindrops/tests.nu new file mode 100644 index 0000000..e29eb95 --- /dev/null +++ b/exercises/practice/raindrops/tests.nu @@ -0,0 +1,39 @@ +use raindrops.nu convert +use std/assert + +# the sound for 1 is 1 +assert equal (convert 1) "1" +# the sound for 3 is Pling +assert equal (convert 3) "Pling" +# the sound for 5 is Plang +assert equal (convert 5) "Plang" +# the sound for 7 is Plong +assert equal (convert 7) "Plong" +# the sound for 6 is Pling as it has a factor 3 +assert equal (convert 6) "Pling" +# 2 to the power 3 does not make a raindrop sound as 3 is the exponent not the base +assert equal (convert 8) "8" +# the sound for 9 is Pling as it has a factor 3 +assert equal (convert 9) "Pling" +# the sound for 10 is Plang as it has a factor 5 +assert equal (convert 10) "Plang" +# the sound for 14 is Plong as it has a factor of 7 +assert equal (convert 14) "Plong" +# the sound for 15 is PlingPlang as it has factors 3 and 5 +assert equal (convert 15) "PlingPlang" +# the sound for 21 is PlingPlong as it has factors 3 and 7 +assert equal (convert 21) "PlingPlong" +# the sound for 25 is Plang as it has a factor 5 +assert equal (convert 25) "Plang" +# the sound for 27 is Pling as it has a factor 3 +assert equal (convert 27) "Pling" +# the sound for 35 is PlangPlong as it has factors 5 and 7 +assert equal (convert 35) "PlangPlong" +# the sound for 49 is Plong as it has a factor 7 +assert equal (convert 49) "Plong" +# the sound for 52 is 52 +assert equal (convert 52) "52" +# the sound for 105 is PlingPlangPlong as it has factors 3, 5 and 7 +assert equal (convert 105) "PlingPlangPlong" +# the sound for 3125 is Plang as it has a factor 5 +assert equal (convert 3125) "Plang" From 964a1a924a80531de820d7e3347c229d2cf9f501 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 19:36:27 +0100 Subject: [PATCH 05/14] update difficulty --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index ce4ab1f..9d258c7 100644 --- a/config.json +++ b/config.json @@ -180,7 +180,7 @@ "uuid": "6373b2e6-4db8-4b3b-b9f6-870b2e0b10a8", "practices": [], "prerequisites": [], - "difficulty": 1 + "difficulty": 2 } ] }, From 4c6dcbb837c2aa53177099105bf5cbb6b98d6cfd Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 21:46:53 +0100 Subject: [PATCH 06/14] added protein-translation exercise --- config.json | 8 ++ .../protein-translation/.docs/instructions.md | 38 +++++++ .../protein-translation/.meta/config.json | 18 +++ .../protein-translation/.meta/example.nu | 37 ++++++ .../protein-translation/.meta/tests.toml | 105 ++++++++++++++++++ .../protein-translation.nu | 3 + .../practice/protein-translation/tests.nu | 65 +++++++++++ 7 files changed, 274 insertions(+) create mode 100644 exercises/practice/protein-translation/.docs/instructions.md create mode 100644 exercises/practice/protein-translation/.meta/config.json create mode 100644 exercises/practice/protein-translation/.meta/example.nu create mode 100644 exercises/practice/protein-translation/.meta/tests.toml create mode 100644 exercises/practice/protein-translation/protein-translation.nu create mode 100644 exercises/practice/protein-translation/tests.nu diff --git a/config.json b/config.json index 9d258c7..ca367f8 100644 --- a/config.json +++ b/config.json @@ -181,6 +181,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "protein-translation", + "name": "Protein Translation", + "uuid": "061e2ed2-c643-4d1f-9f62-822ef6871cc3", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/protein-translation/.docs/instructions.md b/exercises/practice/protein-translation/.docs/instructions.md new file mode 100644 index 0000000..35c953b --- /dev/null +++ b/exercises/practice/protein-translation/.docs/instructions.md @@ -0,0 +1,38 @@ +# Instructions + +Your job is to translate RNA sequences into proteins. + +RNA strands are made up of three-nucleotide sequences called **codons**. +Each codon translates to an **amino acid**. +When joined together, those amino acids make a protein. + +In the real world, there are 64 codons, which in turn correspond to 20 amino acids. +However, for this exercise, you’ll only use a few of the possible 64. +They are listed below: + +| Codon | Amino Acid | +| ------------------ | ------------- | +| AUG | Methionine | +| UUU, UUC | Phenylalanine | +| UUA, UUG | Leucine | +| UCU, UCC, UCA, UCG | Serine | +| UAU, UAC | Tyrosine | +| UGU, UGC | Cysteine | +| UGG | Tryptophan | +| UAA, UAG, UGA | STOP | + +For example, the RNA string “AUGUUUUCU” has three codons: “AUG”, “UUU” and “UCU”. +These map to Methionine, Phenylalanine, and Serine. + +## “STOP” Codons + +You’ll note from the table above that there are three **“STOP” codons**. +If you encounter any of these codons, ignore the rest of the sequence — the protein is complete. + +For example, “AUGUUUUCUUAAAUG” contains a STOP codon (“UAA”). +Once we reach that point, we stop processing. +We therefore only consider the part before it (i.e. “AUGUUUUCU”), not any further codons after it (i.e. “AUG”). + +Learn more about [protein translation on Wikipedia][protein-translation]. + +[protein-translation]: https://en.wikipedia.org/wiki/Translation_(biology) diff --git a/exercises/practice/protein-translation/.meta/config.json b/exercises/practice/protein-translation/.meta/config.json new file mode 100644 index 0000000..0097aa4 --- /dev/null +++ b/exercises/practice/protein-translation/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "protein-translation.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Translate RNA sequences into proteins.", + "source": "Tyler Long" +} diff --git a/exercises/practice/protein-translation/.meta/example.nu b/exercises/practice/protein-translation/.meta/example.nu new file mode 100644 index 0000000..24e0b2a --- /dev/null +++ b/exercises/practice/protein-translation/.meta/example.nu @@ -0,0 +1,37 @@ +def translate [codon: list] { + match $codon { + [A, U, G] => "Methionine" + [U, U, U] | [U, U, C] => "Phenylalanine" + [U, U, A] | [U, U, G] => "Leucine" + [U, C, U] | [U, C, C] | [U, C, A] | [U, C, G] => "Serine" + [U, A, U] | [U, A, C] => "Tyrosine" + [U, G, U] | [U, G, C] => "Cysteine" + [U, G, G] => "Tryptophan" + [U, A, A] | [U, A, G] | [U, G, A] => "STOP" + _ => "INVALID" + } +} + +export def proteins [strand: string] { + let codons = $strand + | split chars + | chunks 3 + let n = $codons | length + generate {|i| + if $i >= $n { + return {out: STOP} + } + let codon = $codons | get $i + let translated = translate $codon + match $translated { + STOP => {out: $translated} + INVALID => (error make {msg: "Invalid codon"}) + _ => {out: $translated, next: ($i + 1)} + } + } 0 + | if ($in | last) == STOP { + $in | drop 1 + } else { + $in + } +} diff --git a/exercises/practice/protein-translation/.meta/tests.toml b/exercises/practice/protein-translation/.meta/tests.toml new file mode 100644 index 0000000..de680e3 --- /dev/null +++ b/exercises/practice/protein-translation/.meta/tests.toml @@ -0,0 +1,105 @@ +# 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. + +[2c44f7bf-ba20-43f7-a3bf-f2219c0c3f98] +description = "Empty RNA sequence results in no proteins" + +[96d3d44f-34a2-4db4-84cd-fff523e069be] +description = "Methionine RNA sequence" + +[1b4c56d8-d69f-44eb-be0e-7b17546143d9] +description = "Phenylalanine RNA sequence 1" + +[81b53646-bd57-4732-b2cb-6b1880e36d11] +description = "Phenylalanine RNA sequence 2" + +[42f69d4f-19d2-4d2c-a8b0-f0ae9ee1b6b4] +description = "Leucine RNA sequence 1" + +[ac5edadd-08ed-40a3-b2b9-d82bb50424c4] +description = "Leucine RNA sequence 2" + +[8bc36e22-f984-44c3-9f6b-ee5d4e73f120] +description = "Serine RNA sequence 1" + +[5c3fa5da-4268-44e5-9f4b-f016ccf90131] +description = "Serine RNA sequence 2" + +[00579891-b594-42b4-96dc-7ff8bf519606] +description = "Serine RNA sequence 3" + +[08c61c3b-fa34-4950-8c4a-133945570ef6] +description = "Serine RNA sequence 4" + +[54e1e7d8-63c0-456d-91d2-062c72f8eef5] +description = "Tyrosine RNA sequence 1" + +[47bcfba2-9d72-46ad-bbce-22f7666b7eb1] +description = "Tyrosine RNA sequence 2" + +[3a691829-fe72-43a7-8c8e-1bd083163f72] +description = "Cysteine RNA sequence 1" + +[1b6f8a26-ca2f-43b8-8262-3ee446021767] +description = "Cysteine RNA sequence 2" + +[1e91c1eb-02c0-48a0-9e35-168ad0cb5f39] +description = "Tryptophan RNA sequence" + +[e547af0b-aeab-49c7-9f13-801773a73557] +description = "STOP codon RNA sequence 1" + +[67640947-ff02-4f23-a2ef-816f8a2ba72e] +description = "STOP codon RNA sequence 2" + +[9c2ad527-ebc9-4ace-808b-2b6447cb54cb] +description = "STOP codon RNA sequence 3" + +[f4d9d8ee-00a8-47bf-a1e3-1641d4428e54] +description = "Sequence of two protein codons translates into proteins" + +[dd22eef3-b4f1-4ad6-bb0b-27093c090a9d] +description = "Sequence of two different protein codons translates into proteins" + +[d0f295df-fb70-425c-946c-ec2ec185388e] +description = "Translate RNA strand into correct protein list" + +[e30e8505-97ec-4e5f-a73e-5726a1faa1f4] +description = "Translation stops if STOP codon at beginning of sequence" + +[5358a20b-6f4c-4893-bce4-f929001710f3] +description = "Translation stops if STOP codon at end of two-codon sequence" + +[ba16703a-1a55-482f-bb07-b21eef5093a3] +description = "Translation stops if STOP codon at end of three-codon sequence" + +[4089bb5a-d5b4-4e71-b79e-b8d1f14a2911] +description = "Translation stops if STOP codon in middle of three-codon sequence" + +[2c2a2a60-401f-4a80-b977-e0715b23b93d] +description = "Translation stops if STOP codon in middle of six-codon sequence" + +[f6f92714-769f-4187-9524-e353e8a41a80] +description = "Sequence of two non-STOP codons does not translate to a STOP codon" + +[1e75ea2a-f907-4994-ae5c-118632a1cb0f] +description = "Non-existing codon can't translate" +include = false + +[9eac93f3-627a-4c90-8653-6d0a0595bc6f] +description = "Unknown amino acids, not part of a codon, can't translate" +reimplements = "1e75ea2a-f907-4994-ae5c-118632a1cb0f" + +[9d73899f-e68e-4291-b1e2-7bf87c00f024] +description = "Incomplete RNA sequence can't translate" + +[43945cf7-9968-402d-ab9f-b8a28750b050] +description = "Incomplete RNA sequence can translate if valid until a STOP codon" diff --git a/exercises/practice/protein-translation/protein-translation.nu b/exercises/practice/protein-translation/protein-translation.nu new file mode 100644 index 0000000..78deba3 --- /dev/null +++ b/exercises/practice/protein-translation/protein-translation.nu @@ -0,0 +1,3 @@ +export def proteins [strand: string] { + error make {msg: "Please implement proteins"} +} diff --git a/exercises/practice/protein-translation/tests.nu b/exercises/practice/protein-translation/tests.nu new file mode 100644 index 0000000..873e487 --- /dev/null +++ b/exercises/practice/protein-translation/tests.nu @@ -0,0 +1,65 @@ +use protein-translation.nu proteins +use std/assert + +# Empty RNA sequence results in no proteins +assert equal (proteins "") [] +# Methionine RNA sequence +assert equal (proteins AUG) [Methionine] +# Phenylalanine RNA sequence 1 +assert equal (proteins UUU) [Phenylalanine] +# Phenylalanine RNA sequence 2 +assert equal (proteins UUC) [Phenylalanine] +# Leucine RNA sequence 1 +assert equal (proteins UUA) [Leucine] +# Leucine RNA sequence 2 +assert equal (proteins UUG) [Leucine] +# Serine RNA sequence 1 +assert equal (proteins UCU) [Serine] +# Serine RNA sequence 2 +assert equal (proteins UCC) [Serine] +# Serine RNA sequence 3 +assert equal (proteins UCA) [Serine] +# Serine RNA sequence 4 +assert equal (proteins UCG) [Serine] +# Tyrosine RNA sequence 1 +assert equal (proteins UAU) [Tyrosine] +# Tyrosine RNA sequence 2 +assert equal (proteins UAC) [Tyrosine] +# Cysteine RNA sequence 1 +assert equal (proteins UGU) [Cysteine] +# Cysteine RNA sequence 2 +assert equal (proteins UGC) [Cysteine] +# Tryptophan RNA sequence +assert equal (proteins UGG) [Tryptophan] +# STOP codon RNA sequence 1 +assert equal (proteins UAA) [] +# STOP codon RNA sequence 2 +assert equal (proteins UAG) [] +# STOP codon RNA sequence 3 +assert equal (proteins UGA) [] +# Sequence of two protein codons translates into proteins +assert equal (proteins UUUUUU) [Phenylalanine, Phenylalanine] +# Sequence of two different protein codons translates into proteins +assert equal (proteins UUAUUG) [Leucine, Leucine] +# Translate RNA strand into correct protein list +assert equal (proteins AUGUUUUGG) [Methionine, Phenylalanine, Tryptophan] +# Translation stops if STOP codon at beginning of sequence +assert equal (proteins UAGUGG) [] +# Translation stops if STOP codon at end of two-codon sequence +assert equal (proteins UGGUAG) [Tryptophan] +# Translation stops if STOP codon at end of three-codon sequence +assert equal (proteins AUGUUUUAA) [Methionine, Phenylalanine] +# Translation stops if STOP codon in middle of three-codon sequence +assert equal (proteins UGGUAGUGG) [Tryptophan] +# Translation stops if STOP codon in middle of six-codon sequence +assert equal (proteins UGGUGUUAUUAAUGGUUU) [Tryptophan, Cysteine, Tyrosine] +# Sequence of two non-STOP codons does not translate to a STOP codon +assert equal (proteins AUGAUG) [Methionine, Methionine] +# Incomplete RNA sequence can translate if valid until a STOP codon +assert equal (proteins UUCUUCUAAUGGU) [Phenylalanine, Phenylalanine] +# Non-existing codon can't translate +assert error {|| (proteins AAA)} +# Unknown amino acids, not part of a codon, can't translate +assert error {|| (proteins XYZ)} +# Incomplete RNA sequence can't translate +assert error {|| (proteins AUGU)} From f70707a98f8343e3ae480225facea4157e3af7cb Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 22:23:06 +0100 Subject: [PATCH 07/14] added grains exercise --- config.json | 8 ++++ .../practice/grains/.docs/instructions.md | 11 +++++ .../practice/grains/.docs/introduction.md | 6 +++ exercises/practice/grains/.meta/config.json | 19 ++++++++ exercises/practice/grains/.meta/example.nu | 10 +++++ exercises/practice/grains/.meta/tests.toml | 43 +++++++++++++++++++ exercises/practice/grains/grains.nu | 7 +++ exercises/practice/grains/tests.nu | 25 +++++++++++ 8 files changed, 129 insertions(+) create mode 100644 exercises/practice/grains/.docs/instructions.md create mode 100644 exercises/practice/grains/.docs/introduction.md create mode 100644 exercises/practice/grains/.meta/config.json create mode 100644 exercises/practice/grains/.meta/example.nu create mode 100644 exercises/practice/grains/.meta/tests.toml create mode 100644 exercises/practice/grains/grains.nu create mode 100644 exercises/practice/grains/tests.nu diff --git a/config.json b/config.json index ca367f8..b6b653c 100644 --- a/config.json +++ b/config.json @@ -189,6 +189,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "grains", + "name": "Grains", + "uuid": "d6017619-6ef0-4ad2-9d74-1075f7822f21", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/grains/.docs/instructions.md b/exercises/practice/grains/.docs/instructions.md new file mode 100644 index 0000000..f5b752a --- /dev/null +++ b/exercises/practice/grains/.docs/instructions.md @@ -0,0 +1,11 @@ +# Instructions + +Calculate the number of grains of wheat on a chessboard. + +A chessboard has 64 squares. +Square 1 has one grain, square 2 has two grains, square 3 has four grains, and so on, doubling each time. + +Write code that calculates: + +- the number of grains on a given square +- the total number of grains on the chessboard diff --git a/exercises/practice/grains/.docs/introduction.md b/exercises/practice/grains/.docs/introduction.md new file mode 100644 index 0000000..0df4f46 --- /dev/null +++ b/exercises/practice/grains/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +There once was a wise servant who saved the life of a prince. +The king promised to pay whatever the servant could dream up. +Knowing that the king loved chess, the servant told the king he would like to have grains of wheat. +One grain on the first square of a chessboard, with the number of grains doubling on each successive square. diff --git a/exercises/practice/grains/.meta/config.json b/exercises/practice/grains/.meta/config.json new file mode 100644 index 0000000..deaeb8a --- /dev/null +++ b/exercises/practice/grains/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "grains.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.", + "source": "The CodeRanch Cattle Drive, Assignment 6", + "source_url": "https://web.archive.org/web/20240908084142/https://coderanch.com/wiki/718824/Grains" +} diff --git a/exercises/practice/grains/.meta/example.nu b/exercises/practice/grains/.meta/example.nu new file mode 100644 index 0000000..b1fb799 --- /dev/null +++ b/exercises/practice/grains/.meta/example.nu @@ -0,0 +1,10 @@ +export def square [i: int] { + if ($i <= 0) or ($i > 64) { + error make {msg: "i must be an integer from 1 to 64"} + } + 2.0 ** ($i - 1) +} + +export def total [] { + (2.0 ** 64) - 1 +} diff --git a/exercises/practice/grains/.meta/tests.toml b/exercises/practice/grains/.meta/tests.toml new file mode 100644 index 0000000..6ea68bc --- /dev/null +++ b/exercises/practice/grains/.meta/tests.toml @@ -0,0 +1,43 @@ +# 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. + +[9fbde8de-36b2-49de-baf2-cd42d6f28405] +description = "returns the number of grains on the square -> grains on square 1" + +[ee1f30c2-01d8-4298-b25d-c677331b5e6d] +description = "returns the number of grains on the square -> grains on square 2" + +[10f45584-2fc3-4875-8ec6-666065d1163b] +description = "returns the number of grains on the square -> grains on square 3" + +[a7cbe01b-36f4-4601-b053-c5f6ae055170] +description = "returns the number of grains on the square -> grains on square 4" + +[c50acc89-8535-44e4-918f-b848ad2817d4] +description = "returns the number of grains on the square -> grains on square 16" + +[acd81b46-c2ad-4951-b848-80d15ed5a04f] +description = "returns the number of grains on the square -> grains on square 32" + +[c73b470a-5efb-4d53-9ac6-c5f6487f227b] +description = "returns the number of grains on the square -> grains on square 64" + +[1d47d832-3e85-4974-9466-5bd35af484e3] +description = "returns the number of grains on the square -> square 0 is invalid" + +[61974483-eeb2-465e-be54-ca5dde366453] +description = "returns the number of grains on the square -> negative square is invalid" + +[a95e4374-f32c-45a7-a10d-ffec475c012f] +description = "returns the number of grains on the square -> square greater than 64 is invalid" + +[6eb07385-3659-4b45-a6be-9dc474222750] +description = "returns the total number of grains on the board" diff --git a/exercises/practice/grains/grains.nu b/exercises/practice/grains/grains.nu new file mode 100644 index 0000000..75b9898 --- /dev/null +++ b/exercises/practice/grains/grains.nu @@ -0,0 +1,7 @@ +export def square [i: int] { + error make {msg: "Please implement square"} +} + +export def total [] { + error make {msg: "Please implement total"} +} diff --git a/exercises/practice/grains/tests.nu b/exercises/practice/grains/tests.nu new file mode 100644 index 0000000..4203a76 --- /dev/null +++ b/exercises/practice/grains/tests.nu @@ -0,0 +1,25 @@ +use grains.nu [square total] +use std/assert + +# grains on square 1 +assert equal (square 1) 1 +# grains on square 2 +assert equal (square 2) 2 +# grains on square 3 +assert equal (square 3) 4 +# grains on square 4 +assert equal (square 4) 8 +# grains on square 16 +assert equal (square 16) 32768 +# grains on square 32 +assert equal (square 32) 2147483648 +# grains on square 64 +assert equal (square 64) 9223372036854775808 +# square 0 is invalid +assert error {|| (square 0)} +# negative square is invalid +assert error {|| (square -1)} +# square greater than 64 is invalid +assert error {|| (square 65)} +# returns the total number of grains on the board +assert equal (total) 18446744073709551616 From dd85df98ad87adfde4040aa3598fa147491586d6 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 22:36:14 +0100 Subject: [PATCH 08/14] implemented gigasecond exercise --- config.json | 8 ++++++ .../practice/gigasecond/.docs/instructions.md | 8 ++++++ .../practice/gigasecond/.docs/introduction.md | 24 ++++++++++++++++ .../practice/gigasecond/.meta/config.json | 19 +++++++++++++ .../practice/gigasecond/.meta/example.nu | 3 ++ .../practice/gigasecond/.meta/tests.toml | 28 +++++++++++++++++++ exercises/practice/gigasecond/gigasecond.nu | 3 ++ exercises/practice/gigasecond/tests.nu | 13 +++++++++ 8 files changed, 106 insertions(+) create mode 100644 exercises/practice/gigasecond/.docs/instructions.md create mode 100644 exercises/practice/gigasecond/.docs/introduction.md create mode 100644 exercises/practice/gigasecond/.meta/config.json create mode 100644 exercises/practice/gigasecond/.meta/example.nu create mode 100644 exercises/practice/gigasecond/.meta/tests.toml create mode 100644 exercises/practice/gigasecond/gigasecond.nu create mode 100644 exercises/practice/gigasecond/tests.nu diff --git a/config.json b/config.json index b6b653c..7fb57da 100644 --- a/config.json +++ b/config.json @@ -197,6 +197,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "gigasecond", + "name": "Gigasecond", + "uuid": "1e3400a3-248c-43d8-828c-85db598122dd", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/gigasecond/.docs/instructions.md b/exercises/practice/gigasecond/.docs/instructions.md new file mode 100644 index 0000000..1e20f00 --- /dev/null +++ b/exercises/practice/gigasecond/.docs/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +Your task is to determine the date and time one gigasecond after a certain date. + +A gigasecond is one thousand million seconds. +That is a one with nine zeros after it. + +If you were born on _January 24th, 2015 at 22:00 (10:00:00pm)_, then you would be a gigasecond old on _October 2nd, 2046 at 23:46:40 (11:46:40pm)_. diff --git a/exercises/practice/gigasecond/.docs/introduction.md b/exercises/practice/gigasecond/.docs/introduction.md new file mode 100644 index 0000000..18a3dc2 --- /dev/null +++ b/exercises/practice/gigasecond/.docs/introduction.md @@ -0,0 +1,24 @@ +# Introduction + +The way we measure time is kind of messy. +We have 60 seconds in a minute, and 60 minutes in an hour. +This comes from ancient Babylon, where they used 60 as the basis for their number system. +We have 24 hours in a day, 7 days in a week, and how many days in a month? +Well, for days in a month it depends not only on which month it is, but also on what type of calendar is used in the country you live in. + +What if, instead, we only use seconds to express time intervals? +Then we can use metric system prefixes for writing large numbers of seconds in more easily comprehensible quantities. + +- A food recipe might explain that you need to let the brownies cook in the oven for two kiloseconds (that's two thousand seconds). +- Perhaps you and your family would travel to somewhere exotic for two megaseconds (that's two million seconds). +- And if you and your spouse were married for _a thousand million_ seconds, you would celebrate your one gigasecond anniversary. + +~~~~exercism/note +If we ever colonize Mars or some other planet, measuring time is going to get even messier. +If someone says "year" do they mean a year on Earth or a year on Mars? + +The idea for this exercise came from the science fiction novel ["A Deepness in the Sky"][vinge-novel] by author Vernor Vinge. +In it the author uses the metric system as the basis for time measurements. + +[vinge-novel]: https://www.tor.com/2017/08/03/science-fiction-with-something-for-everyone-a-deepness-in-the-sky-by-vernor-vinge/ +~~~~ diff --git a/exercises/practice/gigasecond/.meta/config.json b/exercises/practice/gigasecond/.meta/config.json new file mode 100644 index 0000000..adf2bcd --- /dev/null +++ b/exercises/practice/gigasecond/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "gigasecond.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.", + "source": "Chapter 9 in Chris Pine's online Learn to Program tutorial.", + "source_url": "https://pine.fm/LearnToProgram/chap_09.html" +} diff --git a/exercises/practice/gigasecond/.meta/example.nu b/exercises/practice/gigasecond/.meta/example.nu new file mode 100644 index 0000000..73bf8dd --- /dev/null +++ b/exercises/practice/gigasecond/.meta/example.nu @@ -0,0 +1,3 @@ +export def add [ts: datetime] { + $ts + 1_000_000_000sec +} diff --git a/exercises/practice/gigasecond/.meta/tests.toml b/exercises/practice/gigasecond/.meta/tests.toml new file mode 100644 index 0000000..a7caf00 --- /dev/null +++ b/exercises/practice/gigasecond/.meta/tests.toml @@ -0,0 +1,28 @@ +# 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. + +[92fbe71c-ea52-4fac-bd77-be38023cacf7] +description = "date only specification of time" + +[6d86dd16-6f7a-47be-9e58-bb9fb2ae1433] +description = "second test for date only specification of time" + +[77eb8502-2bca-4d92-89d9-7b39ace28dd5] +description = "third test for date only specification of time" + +[c9d89a7d-06f8-4e28-a305-64f1b2abc693] +description = "full time specified" + +[09d4e30e-728a-4b52-9005-be44a58d9eba] +description = "full time with day roll-over" + +[fcec307c-7529-49ab-b0fe-20309197618a] +description = "does not mutate the input" diff --git a/exercises/practice/gigasecond/gigasecond.nu b/exercises/practice/gigasecond/gigasecond.nu new file mode 100644 index 0000000..83210ab --- /dev/null +++ b/exercises/practice/gigasecond/gigasecond.nu @@ -0,0 +1,3 @@ +export def add [ts: datetime] { + error make {msg: "Please implement add"} +} diff --git a/exercises/practice/gigasecond/tests.nu b/exercises/practice/gigasecond/tests.nu new file mode 100644 index 0000000..45796b8 --- /dev/null +++ b/exercises/practice/gigasecond/tests.nu @@ -0,0 +1,13 @@ +use gigasecond.nu add +use std/assert + +assert equal (add 2011-04-25) 2043-01-01T01:46:40 +assert equal (add 1977-06-13) 2009-02-19T01:46:40 +assert equal (add 1959-07-19) 1991-03-27T01:46:40 +assert equal (add 2015-01-24T22:00:00) 2046-10-02T23:46:40 +assert equal (add 2015-01-24T23:59:59) 2046-10-03T01:46:39 + +# test immuatability of input +let orig_moment = 2015-01-24T23:59:59 +let new_moment = add $orig_moment +assert equal $orig_moment 2015-01-24T23:59:59 From 0da55c3fbf0539c5c7fd88423dede0a6d3e9c707 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Sun, 26 Jul 2026 23:26:58 +0100 Subject: [PATCH 09/14] implemented meetup exercise --- config.json | 8 + .../practice/meetup/.docs/instructions.md | 34 ++ .../practice/meetup/.docs/introduction.md | 29 ++ exercises/practice/meetup/.meta/config.json | 18 ++ exercises/practice/meetup/.meta/example.nu | 46 +++ exercises/practice/meetup/.meta/tests.toml | 295 ++++++++++++++++++ exercises/practice/meetup/meetup.nu | 8 + exercises/practice/meetup/tests.nu | 193 ++++++++++++ 8 files changed, 631 insertions(+) create mode 100644 exercises/practice/meetup/.docs/instructions.md create mode 100644 exercises/practice/meetup/.docs/introduction.md create mode 100644 exercises/practice/meetup/.meta/config.json create mode 100644 exercises/practice/meetup/.meta/example.nu create mode 100644 exercises/practice/meetup/.meta/tests.toml create mode 100644 exercises/practice/meetup/meetup.nu create mode 100644 exercises/practice/meetup/tests.nu diff --git a/config.json b/config.json index 7fb57da..e30869c 100644 --- a/config.json +++ b/config.json @@ -205,6 +205,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "meetup", + "name": "Meetup", + "uuid": "6712bff7-70a4-4718-b00c-59960b0135ac", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/meetup/.docs/instructions.md b/exercises/practice/meetup/.docs/instructions.md new file mode 100644 index 0000000..8b1bda5 --- /dev/null +++ b/exercises/practice/meetup/.docs/instructions.md @@ -0,0 +1,34 @@ +# Instructions + +Your task is to find the exact date of a meetup, given a month, year, weekday and week. + +There are six week values to consider: `first`, `second`, `third`, `fourth`, `last`, `teenth`. + +For example, you might be asked to find the date for the meetup on the first Monday in January 2018 (January 1, 2018). + +Similarly, you might be asked to find: + +- the third Tuesday of August 2019 (August 20, 2019) +- the teenth Wednesday of May 2020 (May 13, 2020) +- the fourth Sunday of July 2021 (July 25, 2021) +- the last Thursday of November 2022 (November 24, 2022) +- the teenth Saturday of August 1953 (August 15, 1953) + +## Teenth + +The teenth week refers to the seven days in a month that end in '-teenth' (13th, 14th, 15th, 16th, 17th, 18th and 19th). + +If asked to find the teenth Saturday of August, 1953, we check its calendar: + +```plaintext + August 1953 +Su Mo Tu We Th Fr Sa + 1 + 2 3 4 5 6 7 8 + 9 10 11 12 13 14 15 +16 17 18 19 20 21 22 +23 24 25 26 27 28 29 +30 31 +``` + +From this we find that the teenth Saturday is August 15, 1953. diff --git a/exercises/practice/meetup/.docs/introduction.md b/exercises/practice/meetup/.docs/introduction.md new file mode 100644 index 0000000..29170ef --- /dev/null +++ b/exercises/practice/meetup/.docs/introduction.md @@ -0,0 +1,29 @@ +# Introduction + +Every month, your partner meets up with their best friend. +Both of them have very busy schedules, making it challenging to find a suitable date! +Given your own busy schedule, your partner always double-checks potential meetup dates with you: + +- "Can I meet up on the first Friday of next month?" +- "What about the third Wednesday?" +- "Maybe the last Sunday?" + +In this month's call, your partner asked you this question: + +- "I'd like to meet up on the teenth Thursday; is that okay?" + +Confused, you ask what a "teenth" day is. +Your partner explains that a teenth day, a concept they made up, refers to the days in a month that end in '-teenth': + +- 13th (thirteenth) +- 14th (fourteenth) +- 15th (fifteenth) +- 16th (sixteenth) +- 17th (seventeenth) +- 18th (eighteenth) +- 19th (nineteenth) + +As there are also seven weekdays, it is guaranteed that each day of the week has _exactly one_ teenth day each month. + +Now that you understand the concept of a teenth day, you check your calendar. +You don't have anything planned on the teenth Thursday, so you happily confirm the date with your partner. diff --git a/exercises/practice/meetup/.meta/config.json b/exercises/practice/meetup/.meta/config.json new file mode 100644 index 0000000..0047ddd --- /dev/null +++ b/exercises/practice/meetup/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "YanniPapandreou" + ], + "files": { + "solution": [ + "meetup.nu" + ], + "test": [ + "tests.nu" + ], + "example": [ + ".meta/example.nu" + ] + }, + "blurb": "Calculate the date of meetups.", + "source": "Jeremy Hinegardner mentioned a Boulder meetup that happens on the Wednesteenth of every month" +} diff --git a/exercises/practice/meetup/.meta/example.nu b/exercises/practice/meetup/.meta/example.nu new file mode 100644 index 0000000..ce42f0a --- /dev/null +++ b/exercises/practice/meetup/.meta/example.nu @@ -0,0 +1,46 @@ +def convert_day_of_week [dayofweek: string] { + match ($dayofweek | str lowercase) { + sunday => "su" + monday => "mo" + tuesday => "tu" + wednesday => "we" + thursday => "th" + friday => "fr" + saturday => "sa" + _ => (error make {msg: "invalid day of week"}) + } +} + +def format_val [val: int] { + $val + | fill -a right -c '0' -w 2 +} + +export def main [ + year: int + month: int + week: string + dayofweek: string +] { + let possible_days = cal --as-table --full-year $year --month + | where month == $month + | get (convert_day_of_week $dayofweek) + | where {|x| $x | is-not-empty} + let day = match $week { + first => ($possible_days | get 0) + second => ($possible_days | get 1) + third => ($possible_days | get 2) + fourth => ($possible_days | get 3) + last => ($possible_days | last) + teenth => ($possible_days | intersect [ + 13 + 14 + 15 + 16 + 17 + 18 + 19 + ] | first) + } + $"($year)-(format_val $month)-(format_val $day)" +} diff --git a/exercises/practice/meetup/.meta/tests.toml b/exercises/practice/meetup/.meta/tests.toml new file mode 100644 index 0000000..1e5b84d --- /dev/null +++ b/exercises/practice/meetup/.meta/tests.toml @@ -0,0 +1,295 @@ +# 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. + +[d7f8eadd-d4fc-46ee-8a20-e97bd3fd01c8] +description = "when teenth Monday is the 13th, the first day of the teenth week" + +[f78373d1-cd53-4a7f-9d37-e15bf8a456b4] +description = "when teenth Monday is the 19th, the last day of the teenth week" + +[8c78bea7-a116-425b-9c6b-c9898266d92a] +description = "when teenth Monday is some day in the middle of the teenth week" + +[cfef881b-9dc9-4d0b-8de4-82d0f39fc271] +description = "when teenth Tuesday is the 19th, the last day of the teenth week" + +[69048961-3b00-41f9-97ee-eb6d83a8e92b] +description = "when teenth Tuesday is some day in the middle of the teenth week" + +[d30bade8-3622-466a-b7be-587414e0caa6] +description = "when teenth Tuesday is the 13th, the first day of the teenth week" + +[8db4b58b-92f3-4687-867b-82ee1a04f851] +description = "when teenth Wednesday is some day in the middle of the teenth week" + +[6c27a2a2-28f8-487f-ae81-35d08c4664f7] +description = "when teenth Wednesday is the 13th, the first day of the teenth week" + +[008a8674-1958-45b5-b8e6-c2c9960d973a] +description = "when teenth Wednesday is the 19th, the last day of the teenth week" + +[e4abd5e3-57cb-4091-8420-d97e955c0dbd] +description = "when teenth Thursday is some day in the middle of the teenth week" + +[85da0b0f-eace-4297-a6dd-63588d5055b4] +description = "when teenth Thursday is the 13th, the first day of the teenth week" + +[ecf64f9b-8413-489b-bf6e-128045f70bcc] +description = "when teenth Thursday is the 19th, the last day of the teenth week" + +[ac4e180c-7d0a-4d3d-b05f-f564ebb584ca] +description = "when teenth Friday is the 19th, the last day of the teenth week" + +[b79101c7-83ad-4f8f-8ec8-591683296315] +description = "when teenth Friday is some day in the middle of the teenth week" + +[6ed38b9f-0072-4901-bd97-7c8b8b0ef1b8] +description = "when teenth Friday is the 13th, the first day of the teenth week" + +[dfae03ed-9610-47de-a632-655ab01e1e7c] +description = "when teenth Saturday is some day in the middle of the teenth week" + +[ec02e3e1-fc72-4a3c-872f-a53fa8ab358e] +description = "when teenth Saturday is the 13th, the first day of the teenth week" + +[d983094b-7259-4195-b84e-5d09578c89d9] +description = "when teenth Saturday is the 19th, the last day of the teenth week" + +[d84a2a2e-f745-443a-9368-30051be60c2e] +description = "when teenth Sunday is the 19th, the last day of the teenth week" + +[0e64bc53-92a3-4f61-85b2-0b7168c7ce5a] +description = "when teenth Sunday is some day in the middle of the teenth week" + +[de87652c-185e-4854-b3ae-04cf6150eead] +description = "when teenth Sunday is the 13th, the first day of the teenth week" + +[2cbfd0f5-ba3a-46da-a8cc-0fe4966d3411] +description = "when first Monday is some day in the middle of the first week" + +[a6168c7c-ed95-4bb3-8f92-c72575fc64b0] +description = "when first Monday is the 1st, the first day of the first week" + +[1bfc620f-1c54-4bbd-931f-4a1cd1036c20] +description = "when first Tuesday is the 7th, the last day of the first week" + +[12959c10-7362-4ca0-a048-50cf1c06e3e2] +description = "when first Tuesday is some day in the middle of the first week" + +[1033dc66-8d0b-48a1-90cb-270703d59d1d] +description = "when first Wednesday is some day in the middle of the first week" + +[b89185b9-2f32-46f4-a602-de20b09058f6] +description = "when first Wednesday is the 7th, the last day of the first week" + +[53aedc4d-b2c8-4dfb-abf7-a8dc9cdceed5] +description = "when first Thursday is some day in the middle of the first week" + +[b420a7e3-a94c-4226-870a-9eb3a92647f0] +description = "when first Thursday is another day in the middle of the first week" + +[61df3270-28b4-4713-bee2-566fa27302ca] +description = "when first Friday is the 1st, the first day of the first week" + +[cad33d4d-595c-412f-85cf-3874c6e07abf] +description = "when first Friday is some day in the middle of the first week" + +[a2869b52-5bba-44f0-a863-07bd1f67eadb] +description = "when first Saturday is some day in the middle of the first week" + +[3585315a-d0db-4ea1-822e-0f22e2a645f5] +description = "when first Saturday is another day in the middle of the first week" + +[c49e9bd9-8ccf-4cf2-947a-0ccd4e4f10b1] +description = "when first Sunday is some day in the middle of the first week" + +[1513328b-df53-4714-8677-df68c4f9366c] +description = "when first Sunday is the 7th, the last day of the first week" + +[49e083af-47ec-4018-b807-62ef411efed7] +description = "when second Monday is some day in the middle of the second week" + +[6cb79a73-38fe-4475-9101-9eec36cf79e5] +description = "when second Monday is the 8th, the first day of the second week" + +[4c39b594-af7e-4445-aa03-bf4f8effd9a1] +description = "when second Tuesday is the 14th, the last day of the second week" + +[41b32c34-2e39-40e3-b790-93539aaeb6dd] +description = "when second Tuesday is some day in the middle of the second week" + +[90a160c5-b5d9-4831-927f-63a78b17843d] +description = "when second Wednesday is some day in the middle of the second week" + +[23b98ce7-8dd5-41a1-9310-ef27209741cb] +description = "when second Wednesday is the 14th, the last day of the second week" + +[447f1960-27ca-4729-bc3f-f36043f43ed0] +description = "when second Thursday is some day in the middle of the second week" + +[c9aa2687-300c-4e79-86ca-077849a81bde] +description = "when second Thursday is another day in the middle of the second week" + +[a7e11ef3-6625-4134-acda-3e7195421c09] +description = "when second Friday is the 8th, the first day of the second week" + +[8b420e5f-9290-4106-b5ae-022f3e2a3e41] +description = "when second Friday is some day in the middle of the second week" + +[80631afc-fc11-4546-8b5f-c12aaeb72b4f] +description = "when second Saturday is some day in the middle of the second week" + +[e34d43ac-f470-44c2-aa5f-e97b78ecaf83] +description = "when second Saturday is another day in the middle of the second week" + +[a57d59fd-1023-47ad-b0df-a6feb21b44fc] +description = "when second Sunday is some day in the middle of the second week" + +[a829a8b0-abdd-4ad1-b66c-5560d843c91a] +description = "when second Sunday is the 14th, the last day of the second week" + +[501a8a77-6038-4fc0-b74c-33634906c29d] +description = "when third Monday is some day in the middle of the third week" + +[49e4516e-cf32-4a58-8bbc-494b7e851c92] +description = "when third Monday is the 15th, the first day of the third week" + +[4db61095-f7c7-493c-85f1-9996ad3012c7] +description = "when third Tuesday is the 21st, the last day of the third week" + +[714fc2e3-58d0-4b91-90fd-61eefd2892c0] +description = "when third Tuesday is some day in the middle of the third week" + +[b08a051a-2c80-445b-9b0e-524171a166d1] +description = "when third Wednesday is some day in the middle of the third week" + +[80bb9eff-3905-4c61-8dc9-bb03016d8ff8] +description = "when third Wednesday is the 21st, the last day of the third week" + +[fa52a299-f77f-4784-b290-ba9189fbd9c9] +description = "when third Thursday is some day in the middle of the third week" + +[f74b1bc6-cc5c-4bf1-ba69-c554a969eb38] +description = "when third Thursday is another day in the middle of the third week" + +[8900f3b0-801a-466b-a866-f42d64667abd] +description = "when third Friday is the 15th, the first day of the third week" + +[538ac405-a091-4314-9ccd-920c4e38e85e] +description = "when third Friday is some day in the middle of the third week" + +[244db35c-2716-4fa0-88ce-afd58e5cf910] +description = "when third Saturday is some day in the middle of the third week" + +[dd28544f-f8fa-4f06-9bcd-0ad46ce68e9e] +description = "when third Saturday is another day in the middle of the third week" + +[be71dcc6-00d2-4b53-a369-cbfae55b312f] +description = "when third Sunday is some day in the middle of the third week" + +[b7d2da84-4290-4ee6-a618-ee124ae78be7] +description = "when third Sunday is the 21st, the last day of the third week" + +[4276dc06-a1bd-4fc2-b6c2-625fee90bc88] +description = "when fourth Monday is some day in the middle of the fourth week" + +[ddbd7976-2deb-4250-8a38-925ac1a8e9a2] +description = "when fourth Monday is the 22nd, the first day of the fourth week" + +[eb714ef4-1656-47cc-913c-844dba4ebddd] +description = "when fourth Tuesday is the 28th, the last day of the fourth week" + +[16648435-7937-4d2d-b118-c3e38fd084bd] +description = "when fourth Tuesday is some day in the middle of the fourth week" + +[de062bdc-9484-437a-a8c5-5253c6f6785a] +description = "when fourth Wednesday is some day in the middle of the fourth week" + +[c2ce6821-169c-4832-8d37-690ef5d9514a] +description = "when fourth Wednesday is the 28th, the last day of the fourth week" + +[d462c631-2894-4391-a8e3-dbb98b7a7303] +description = "when fourth Thursday is some day in the middle of the fourth week" + +[9ff1f7b6-1b72-427d-9ee9-82b5bb08b835] +description = "when fourth Thursday is another day in the middle of the fourth week" + +[83bae8ba-1c49-49bc-b632-b7c7e1d7e35f] +description = "when fourth Friday is the 22nd, the first day of the fourth week" + +[de752d2a-a95e-48d2-835b-93363dac3710] +description = "when fourth Friday is some day in the middle of the fourth week" + +[eedd90ad-d581-45db-8312-4c6dcf9cf560] +description = "when fourth Saturday is some day in the middle of the fourth week" + +[669fedcd-912e-48c7-a0a1-228b34af91d0] +description = "when fourth Saturday is another day in the middle of the fourth week" + +[648e3849-ea49-44a5-a8a3-9f2a43b3bf1b] +description = "when fourth Sunday is some day in the middle of the fourth week" + +[f81321b3-99ab-4db6-9267-69c5da5a7823] +description = "when fourth Sunday is the 28th, the last day of the fourth week" + +[1af5e51f-5488-4548-aee8-11d7d4a730dc] +description = "last Monday in a month with four Mondays" + +[f29999f2-235e-4ec7-9dab-26f137146526] +description = "last Monday in a month with five Mondays" + +[31b097a0-508e-48ac-bf8a-f63cdcf6dc41] +description = "last Tuesday in a month with four Tuesdays" + +[8c022150-0bb5-4a1f-80f9-88b2e2abcba4] +description = "last Tuesday in another month with four Tuesdays" + +[0e762194-672a-4bdf-8a37-1e59fdacef12] +description = "last Wednesday in a month with five Wednesdays" + +[5016386a-f24e-4bd7-b439-95358f491b66] +description = "last Wednesday in a month with four Wednesdays" + +[12ead1a5-cdf9-4192-9a56-2229e93dd149] +description = "last Thursday in a month with four Thursdays" + +[7db89e11-7fbe-4e57-ae3c-0f327fbd7cc7] +description = "last Thursday in a month with five Thursdays" + +[e47a739e-b979-460d-9c8a-75c35ca2290b] +description = "last Friday in a month with five Fridays" + +[5bed5aa9-a57a-4e5d-8997-2cc796a5b0ec] +description = "last Friday in a month with four Fridays" + +[61e54cba-76f3-4772-a2b1-bf443fda2137] +description = "last Saturday in a month with four Saturdays" + +[8b6a737b-2fa9-444c-b1a2-80ce7a2ec72f] +description = "last Saturday in another month with four Saturdays" + +[0b63e682-f429-4d19-9809-4a45bd0242dc] +description = "last Sunday in a month with five Sundays" + +[5232307e-d3e3-4afc-8ba6-4084ad987c00] +description = "last Sunday in a month with four Sundays" + +[0bbd48e8-9773-4e81-8e71-b9a51711e3c5] +description = "when last Wednesday in February in a leap year is the 29th" + +[fe0936de-7eee-4a48-88dd-66c07ab1fefc] +description = "last Wednesday in December that is also the last day of the year" + +[2ccf2488-aafc-4671-a24e-2b6effe1b0e2] +description = "when last Sunday in February in a non-leap year is not the 29th" + +[00c3ce9f-cf36-4b70-90d8-92b32be6830e] +description = "when first Friday is the 7th, the last day of the first week" diff --git a/exercises/practice/meetup/meetup.nu b/exercises/practice/meetup/meetup.nu new file mode 100644 index 0000000..138b7b5 --- /dev/null +++ b/exercises/practice/meetup/meetup.nu @@ -0,0 +1,8 @@ +export def main [ + year: int + month: int + week: string + dayofweek: string +] { + error make {msg: "Please implement meetup"} +} diff --git a/exercises/practice/meetup/tests.nu b/exercises/practice/meetup/tests.nu new file mode 100644 index 0000000..432f2dd --- /dev/null +++ b/exercises/practice/meetup/tests.nu @@ -0,0 +1,193 @@ +use meetup.nu +use std/assert + +# when teenth Monday is the 13th, the first day of the teenth week +assert equal (meetup 2013 5 teenth Monday) "2013-05-13" +# when teenth Monday is the 19th, the last day of the teenth week +assert equal (meetup 2013 8 teenth Monday) "2013-08-19" +# when teenth Monday is some day in the middle of the teenth week +assert equal (meetup 2013 9 teenth Monday) "2013-09-16" +# when teenth Tuesday is the 19th, the last day of the teenth week +assert equal (meetup 2013 3 teenth Tuesday) "2013-03-19" +# when teenth Tuesday is some day in the middle of the teenth week +assert equal (meetup 2013 4 teenth Tuesday) "2013-04-16" +# when teenth Tuesday is the 13th, the first day of the teenth week +assert equal (meetup 2013 8 teenth Tuesday) "2013-08-13" +# when teenth Wednesday is some day in the middle of the teenth week +assert equal (meetup 2013 1 teenth Wednesday) "2013-01-16" +# when teenth Wednesday is the 13th, the first day of the teenth week +assert equal (meetup 2013 2 teenth Wednesday) "2013-02-13" +# when teenth Wednesday is the 19th, the last day of the teenth week +assert equal (meetup 2013 6 teenth Wednesday) "2013-06-19" +# when teenth Thursday is some day in the middle of the teenth week +assert equal (meetup 2013 5 teenth Thursday) "2013-05-16" +# when teenth Thursday is the 13th, the first day of the teenth week +assert equal (meetup 2013 6 teenth Thursday) "2013-06-13" +# when teenth Thursday is the 19th, the last day of the teenth week +assert equal (meetup 2013 9 teenth Thursday) "2013-09-19" +# when teenth Friday is the 19th, the last day of the teenth week +assert equal (meetup 2013 4 teenth Friday) "2013-04-19" +# when teenth Friday is some day in the middle of the teenth week +assert equal (meetup 2013 8 teenth Friday) "2013-08-16" +# when teenth Friday is the 13th, the first day of the teenth week +assert equal (meetup 2013 9 teenth Friday) "2013-09-13" +# when teenth Saturday is some day in the middle of the teenth week +assert equal (meetup 2013 2 teenth Saturday) "2013-02-16" +# when teenth Saturday is the 13th, the first day of the teenth week +assert equal (meetup 2013 4 teenth Saturday) "2013-04-13" +# when teenth Saturday is the 19th, the last day of the teenth week +assert equal (meetup 2013 10 teenth Saturday) "2013-10-19" +# when teenth Sunday is the 19th, the last day of the teenth week +assert equal (meetup 2013 5 teenth Sunday) "2013-05-19" +# when teenth Sunday is some day in the middle of the teenth week +assert equal (meetup 2013 6 teenth Sunday) "2013-06-16" +# when teenth Sunday is the 13th, the first day of the teenth week +assert equal (meetup 2013 10 teenth Sunday) "2013-10-13" +# when first Monday is some day in the middle of the first week +assert equal (meetup 2013 3 first Monday) "2013-03-04" +# when first Monday is the 1st, the first day of the first week +assert equal (meetup 2013 4 first Monday) "2013-04-01" +# when first Tuesday is the 7th, the last day of the first week +assert equal (meetup 2013 5 first Tuesday) "2013-05-07" +# when first Tuesday is some day in the middle of the first week +assert equal (meetup 2013 6 first Tuesday) "2013-06-04" +# when first Wednesday is some day in the middle of the first week +assert equal (meetup 2013 7 first Wednesday) "2013-07-03" +# when first Wednesday is the 7th, the last day of the first week +assert equal (meetup 2013 8 first Wednesday) "2013-08-07" +# when first Thursday is some day in the middle of the first week +assert equal (meetup 2013 9 first Thursday) "2013-09-05" +# when first Thursday is another day in the middle of the first week +assert equal (meetup 2013 10 first Thursday) "2013-10-03" +# when first Friday is the 1st, the first day of the first week +assert equal (meetup 2013 11 first Friday) "2013-11-01" +# when first Friday is some day in the middle of the first week +assert equal (meetup 2013 12 first Friday) "2013-12-06" +# when first Saturday is some day in the middle of the first week +assert equal (meetup 2013 1 first Saturday) "2013-01-05" +# when first Saturday is another day in the middle of the first week +assert equal (meetup 2013 2 first Saturday) "2013-02-02" +# when first Sunday is some day in the middle of the first week +assert equal (meetup 2013 3 first Sunday) "2013-03-03" +# when first Sunday is the 7th, the last day of the first week +assert equal (meetup 2013 4 first Sunday) "2013-04-07" +# when second Monday is some day in the middle of the second week +assert equal (meetup 2013 3 second Monday) "2013-03-11" +# when second Monday is the 8th, the first day of the second week +assert equal (meetup 2013 4 second Monday) "2013-04-08" +# when second Tuesday is the 14th, the last day of the second week +assert equal (meetup 2013 5 second Tuesday) "2013-05-14" +# when second Tuesday is some day in the middle of the second week +assert equal (meetup 2013 6 second Tuesday) "2013-06-11" +# when second Wednesday is some day in the middle of the second week +assert equal (meetup 2013 7 second Wednesday) "2013-07-10" +# when second Wednesday is the 14th, the last day of the second week +assert equal (meetup 2013 8 second Wednesday) "2013-08-14" +# when second Thursday is some day in the middle of the second week +assert equal (meetup 2013 9 second Thursday) "2013-09-12" +# when second Thursday is another day in the middle of the second week +assert equal (meetup 2013 10 second Thursday) "2013-10-10" +# when second Friday is the 8th, the first day of the second week +assert equal (meetup 2013 11 second Friday) "2013-11-08" +# when second Friday is some day in the middle of the second week +assert equal (meetup 2013 12 second Friday) "2013-12-13" +# when second Saturday is some day in the middle of the second week +assert equal (meetup 2013 1 second Saturday) "2013-01-12" +# when second Saturday is another day in the middle of the second week +assert equal (meetup 2013 2 second Saturday) "2013-02-09" +# when second Sunday is some day in the middle of the second week +assert equal (meetup 2013 3 second Sunday) "2013-03-10" +# when second Sunday is the 14th, the last day of the second week +assert equal (meetup 2013 4 second Sunday) "2013-04-14" +# when third Monday is some day in the middle of the third week +assert equal (meetup 2013 3 third Monday) "2013-03-18" +# when third Monday is the 15th, the first day of the third week +assert equal (meetup 2013 4 third Monday) "2013-04-15" +# when third Tuesday is the 21st, the last day of the third week +assert equal (meetup 2013 5 third Tuesday) "2013-05-21" +# when third Tuesday is some day in the middle of the third week +assert equal (meetup 2013 6 third Tuesday) "2013-06-18" +# when third Wednesday is some day in the middle of the third week +assert equal (meetup 2013 7 third Wednesday) "2013-07-17" +# when third Wednesday is the 21st, the last day of the third week +assert equal (meetup 2013 8 third Wednesday) "2013-08-21" +# when third Thursday is some day in the middle of the third week +assert equal (meetup 2013 9 third Thursday) "2013-09-19" +# when third Thursday is another day in the middle of the third week +assert equal (meetup 2013 10 third Thursday) "2013-10-17" +# when third Friday is the 15th, the first day of the third week +assert equal (meetup 2013 11 third Friday) "2013-11-15" +# when third Friday is some day in the middle of the third week +assert equal (meetup 2013 12 third Friday) "2013-12-20" +# when third Saturday is some day in the middle of the third week +assert equal (meetup 2013 1 third Saturday) "2013-01-19" +# when third Saturday is another day in the middle of the third week +assert equal (meetup 2013 2 third Saturday) "2013-02-16" +# when third Sunday is some day in the middle of the third week +assert equal (meetup 2013 3 third Sunday) "2013-03-17" +# when third Sunday is the 21st, the last day of the third week +assert equal (meetup 2013 4 third Sunday) "2013-04-21" +# when fourth Monday is some day in the middle of the fourth week +assert equal (meetup 2013 3 fourth Monday) "2013-03-25" +# when fourth Monday is the 22nd, the first day of the fourth week +assert equal (meetup 2013 4 fourth Monday) "2013-04-22" +# when fourth Tuesday is the 28th, the last day of the fourth week +assert equal (meetup 2013 5 fourth Tuesday) "2013-05-28" +# when fourth Tuesday is some day in the middle of the fourth week +assert equal (meetup 2013 6 fourth Tuesday) "2013-06-25" +# when fourth Wednesday is some day in the middle of the fourth week +assert equal (meetup 2013 7 fourth Wednesday) "2013-07-24" +# when fourth Wednesday is the 28th, the last day of the fourth week +assert equal (meetup 2013 8 fourth Wednesday) "2013-08-28" +# when fourth Thursday is some day in the middle of the fourth week +assert equal (meetup 2013 9 fourth Thursday) "2013-09-26" +# when fourth Thursday is another day in the middle of the fourth week +assert equal (meetup 2013 10 fourth Thursday) "2013-10-24" +# when fourth Friday is the 22nd, the first day of the fourth week +assert equal (meetup 2013 11 fourth Friday) "2013-11-22" +# when fourth Friday is some day in the middle of the fourth week +assert equal (meetup 2013 12 fourth Friday) "2013-12-27" +# when fourth Saturday is some day in the middle of the fourth week +assert equal (meetup 2013 1 fourth Saturday) "2013-01-26" +# when fourth Saturday is another day in the middle of the fourth week +assert equal (meetup 2013 2 fourth Saturday) "2013-02-23" +# when fourth Sunday is some day in the middle of the fourth week +assert equal (meetup 2013 3 fourth Sunday) "2013-03-24" +# when fourth Sunday is the 28th, the last day of the fourth week +assert equal (meetup 2013 4 fourth Sunday) "2013-04-28" +# last Monday in a month with four Mondays +assert equal (meetup 2013 3 last Monday) "2013-03-25" +# last Monday in a month with five Mondays +assert equal (meetup 2013 4 last Monday) "2013-04-29" +# last Tuesday in a month with four Tuesdays +assert equal (meetup 2013 5 last Tuesday) "2013-05-28" +# last Tuesday in another month with four Tuesdays +assert equal (meetup 2013 6 last Tuesday) "2013-06-25" +# last Wednesday in a month with five Wednesdays +assert equal (meetup 2013 7 last Wednesday) "2013-07-31" +# last Wednesday in a month with four Wednesdays +assert equal (meetup 2013 8 last Wednesday) "2013-08-28" +# last Thursday in a month with four Thursdays +assert equal (meetup 2013 9 last Thursday) "2013-09-26" +# last Thursday in a month with five Thursdays +assert equal (meetup 2013 10 last Thursday) "2013-10-31" +# last Friday in a month with five Fridays +assert equal (meetup 2013 11 last Friday) "2013-11-29" +# last Friday in a month with four Fridays +assert equal (meetup 2013 12 last Friday) "2013-12-27" +# last Saturday in a month with four Saturdays +assert equal (meetup 2013 1 last Saturday) "2013-01-26" +# last Saturday in another month with four Saturdays +assert equal (meetup 2013 2 last Saturday) "2013-02-23" +# last Sunday in a month with five Sundays +assert equal (meetup 2013 3 last Sunday) "2013-03-31" +# last Sunday in a month with four Sundays +assert equal (meetup 2013 4 last Sunday) "2013-04-28" +# when last Wednesday in February in a leap year is the 29th +assert equal (meetup 2012 2 last Wednesday) "2012-02-29" +# last Wednesday in December that is also the last day of the year +assert equal (meetup 2014 12 last Wednesday) "2014-12-31" +# when last Sunday in February in a non-leap year is not the 29th +assert equal (meetup 2015 2 last Sunday) "2015-02-22" +# when first Friday is the 7th, the last day of the first week +assert equal (meetup 2012 12 first Friday) "2012-12-07" From 8d8096a1d518f572eaae65e680c5de6042f290c2 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Mon, 27 Jul 2026 09:25:42 +0000 Subject: [PATCH 10/14] fixed deprecation warnings in nushell version 0.114.1 --- exercises/practice/acronym/.meta/example.nu | 4 ++-- exercises/practice/forth/.meta/example.nu | 10 +++++----- exercises/practice/grep/.meta/example.nu | 4 ++-- exercises/practice/isogram/.meta/example.nu | 2 +- .../parallel-letter-frequency/.meta/example.nu | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/exercises/practice/acronym/.meta/example.nu b/exercises/practice/acronym/.meta/example.nu index 2be0215..29aecea 100644 --- a/exercises/practice/acronym/.meta/example.nu +++ b/exercises/practice/acronym/.meta/example.nu @@ -1,5 +1,5 @@ def alphabetic [c: string] { - let c = $c | str downcase + let c = $c | str lowercase $c >= a and $c <= z } export def abbreviate [phrase: string] { @@ -10,5 +10,5 @@ export def abbreviate [phrase: string] { | split row -r "[ -]" | each {|w| $w | split chars | first} | str join - | str upcase + | str uppercase } diff --git a/exercises/practice/forth/.meta/example.nu b/exercises/practice/forth/.meta/example.nu index b6aece3..5fae0bb 100644 --- a/exercises/practice/forth/.meta/example.nu +++ b/exercises/practice/forth/.meta/example.nu @@ -6,7 +6,7 @@ def macro? [item] { def parse_definition [def: string] { let parsed = ($def | parse ": {name} {body} ;") - let name = ($parsed.name | get 0 | str trim | str downcase) + let name = ($parsed.name | get 0 | str trim | str lowercase) let tokens = ($parsed.body | get 0 | str trim | split row " ") { name: $name, @@ -17,8 +17,8 @@ def parse_definition [def: string] { def replace_tokens [tokens: list, defname: string, definition: list] { mut result = [] for token in $tokens { - let token_lower = ($token | str downcase | str trim) - let name_lower = ($defname | str downcase | str trim) + let token_lower = ($token | str lowercase | str trim) + let name_lower = ($defname | str lowercase | str trim) if $token_lower == $name_lower { for deftoken in $definition { $result = ($result | append $deftoken) @@ -71,7 +71,7 @@ def expand_macros [instructions: list] { mut next = [] for token in $tokens { - let token_lower = ($token | str downcase) + let token_lower = ($token | str lowercase) let matches = ($defs | where name == $token_lower) if ($matches | length) > 0 { let match = ($matches | first) @@ -165,7 +165,7 @@ export def evaluate [instructions: list] { mut stack: list = [] for token in $tokens { - let norm = ($token | str downcase | str trim) + let norm = ($token | str lowercase | str trim) $stack = perform $stack $norm } $stack diff --git a/exercises/practice/grep/.meta/example.nu b/exercises/practice/grep/.meta/example.nu index 8270cb0..f29f6eb 100644 --- a/exercises/practice/grep/.meta/example.nu +++ b/exercises/practice/grep/.meta/example.nu @@ -22,8 +22,8 @@ def grep-single [pattern: string, options: record, file: path] { mut upcased = $line mut pattern = $pattern if $options.insensitive { - $upcased = $upcased | str upcase - $pattern = $pattern | str upcase + $upcased = $upcased | str uppercase + $pattern = $pattern | str uppercase } if $options.inverted xor (do $contains $pattern $upcased) { diff --git a/exercises/practice/isogram/.meta/example.nu b/exercises/practice/isogram/.meta/example.nu index 552d7cc..2d8bf3a 100644 --- a/exercises/practice/isogram/.meta/example.nu +++ b/exercises/practice/isogram/.meta/example.nu @@ -1,5 +1,5 @@ def clean [phrase: string] { - $phrase | str downcase | split chars | where $it in 'abcdefghijklmnopqrstuvwxyz' + $phrase | str lowercase | split chars | where $it in 'abcdefghijklmnopqrstuvwxyz' } export def is_isogram [phrase: string] { let phrase = clean $phrase diff --git a/exercises/practice/parallel-letter-frequency/.meta/example.nu b/exercises/practice/parallel-letter-frequency/.meta/example.nu index b621574..047da02 100644 --- a/exercises/practice/parallel-letter-frequency/.meta/example.nu +++ b/exercises/practice/parallel-letter-frequency/.meta/example.nu @@ -19,7 +19,7 @@ def merge_add [second] { } def make_chunks [texts: list] { - let text = $texts | str join | split chars | str downcase | where $it in "abcdefghijklmnopqrstuvwxyz" + let text = $texts | str join | split chars | str lowercase | where $it in "abcdefghijklmnopqrstuvwxyz" let n_chunks = ($text | length) // (sys cpu | length) let n_chunks = if ($n_chunks <= 0) { 1 From ce0fa2330cafefd9e101c87faf36508234300033 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Mon, 27 Jul 2026 09:46:35 +0000 Subject: [PATCH 11/14] update nushell release in workflow file --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f741004..fda149b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,11 +21,11 @@ jobs: - name: Use nushell run: | - curl -L -o nu.tar.gz https://github.com/nushell/nushell/releases/download/0.111.0/nu-0.111.0-x86_64-unknown-linux-gnu.tar.gz && \ + curl -L -o nu.tar.gz https://github.com/nushell/nushell/releases/download/0.114.1/nu-0.114.1-x86_64-unknown-linux-gnu.tar.gz && \ tar -xzf nu.tar.gz && \ - sudo mv nu-0.111.0-x86_64-unknown-linux-gnu/* /usr/bin/ && \ + sudo mv nu-0.114.1-x86_64-unknown-linux-gnu/* /usr/bin/ && \ rm nu.tar.gz && \ - rm -r nu-0.111.0-x86_64-unknown-linux-gnu + rm -r nu-0.114.1-x86_64-unknown-linux-gnu - name: Verify all exercises From 68ccb06ffd5f44df67607e470da18c9ff3d1a972 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Mon, 27 Jul 2026 10:07:25 +0000 Subject: [PATCH 12/14] rename run to move to avoid errors with existing run command --- .../practice/robot-simulator/.meta/example.nu | 2 +- .../robot-simulator/robot-simulator.nu | 4 +-- exercises/practice/robot-simulator/tests.nu | 34 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/exercises/practice/robot-simulator/.meta/example.nu b/exercises/practice/robot-simulator/.meta/example.nu index 00eda89..1b3f29d 100644 --- a/exercises/practice/robot-simulator/.meta/example.nu +++ b/exercises/practice/robot-simulator/.meta/example.nu @@ -15,7 +15,7 @@ def turnl [robot: record, direction: string>] { let idx = $directions | indexof $robot.direction $robot | update direction ($directions | get (($idx - 1) mod 4 | into cell-path)) } -export def run [instructions: string]: record, direction: string> -> record, direction: string> { +export def move [instructions: string]: record, direction: string> -> record, direction: string> { let robot = $in $instructions | split chars | reduce --fold $robot {|c, robot| match $c { diff --git a/exercises/practice/robot-simulator/robot-simulator.nu b/exercises/practice/robot-simulator/robot-simulator.nu index a45db0d..a60e76c 100644 --- a/exercises/practice/robot-simulator/robot-simulator.nu +++ b/exercises/practice/robot-simulator/robot-simulator.nu @@ -1,4 +1,4 @@ -export def run [instructions: string]: record, direction: string> -> record, direction: string> { - error make {msg: "Remove this line and implement grep"} +export def move [instructions: string]: record, direction: string> -> record, direction: string> { + error make {msg: "Remove this line and implement move"} {position: {x: 0, y: 0}, direction: north} } diff --git a/exercises/practice/robot-simulator/tests.nu b/exercises/practice/robot-simulator/tests.nu index 441dc2b..e9fb21f 100644 --- a/exercises/practice/robot-simulator/tests.nu +++ b/exercises/practice/robot-simulator/tests.nu @@ -1,49 +1,49 @@ -use robot-simulator.nu run +use robot-simulator.nu move use std/assert # changes north to east -assert equal ({position: {x: 0, y: 0}, direction: north} | run R) {position: {x: 0, y: 0}, direction: east} +assert equal ({position: {x: 0, y: 0}, direction: north} | move R) {position: {x: 0, y: 0}, direction: east} # changes east to south -assert equal ({position: {x: 0, y: 0}, direction: east} | run R) {position: {x: 0, y: 0}, direction: south} +assert equal ({position: {x: 0, y: 0}, direction: east} | move R) {position: {x: 0, y: 0}, direction: south} # changes south to west -assert equal ({position: {x: 0, y: 0}, direction: south} | run R) {position: {x: 0, y: 0}, direction: west} +assert equal ({position: {x: 0, y: 0}, direction: south} | move R) {position: {x: 0, y: 0}, direction: west} # changes west to north -assert equal ({position: {x: 0, y: 0}, direction: west} | run R) {position: {x: 0, y: 0}, direction: north} +assert equal ({position: {x: 0, y: 0}, direction: west} | move R) {position: {x: 0, y: 0}, direction: north} # changes north to west -assert equal ({position: {x: 0, y: 0}, direction: north} | run L) {position: {x: 0, y: 0}, direction: west} +assert equal ({position: {x: 0, y: 0}, direction: north} | move L) {position: {x: 0, y: 0}, direction: west} # changes west to south -assert equal ({position: {x: 0, y: 0}, direction: west} | run L) {position: {x: 0, y: 0}, direction: south} +assert equal ({position: {x: 0, y: 0}, direction: west} | move L) {position: {x: 0, y: 0}, direction: south} # changes south to east -assert equal ({position: {x: 0, y: 0}, direction: south} | run L) {position: {x: 0, y: 0}, direction: east} +assert equal ({position: {x: 0, y: 0}, direction: south} | move L) {position: {x: 0, y: 0}, direction: east} # changes east to north -assert equal ({position: {x: 0, y: 0}, direction: east} | run L) {position: {x: 0, y: 0}, direction: north} +assert equal ({position: {x: 0, y: 0}, direction: east} | move L) {position: {x: 0, y: 0}, direction: north} # facing north increments Y -assert equal ({position: {x: 0, y: 0}, direction: north} | run A) {position: {x: 0, y: 1}, direction: north} +assert equal ({position: {x: 0, y: 0}, direction: north} | move A) {position: {x: 0, y: 1}, direction: north} # facing south decrements Y -assert equal ({position: {x: 0, y: 0}, direction: south} | run A) {position: {x: 0, y: -1}, direction: south} +assert equal ({position: {x: 0, y: 0}, direction: south} | move A) {position: {x: 0, y: -1}, direction: south} # facing east increments X -assert equal ({position: {x: 0, y: 0}, direction: east} | run A) {position: {x: 1, y: 0}, direction: east} +assert equal ({position: {x: 0, y: 0}, direction: east} | move A) {position: {x: 1, y: 0}, direction: east} # facing west decrements X -assert equal ({position: {x: 0, y: 0}, direction: west} | run A) {position: {x: -1, y: 0}, direction: west} +assert equal ({position: {x: 0, y: 0}, direction: west} | move A) {position: {x: -1, y: 0}, direction: west} # moving east and north from README -assert equal ({position: {x: 7, y: 3}, direction: north} | run RAALAL) {position: {x: 9, y: 4}, direction: west} +assert equal ({position: {x: 7, y: 3}, direction: north} | move RAALAL) {position: {x: 9, y: 4}, direction: west} # moving west and north -assert equal ({position: {x: 0, y: 0}, direction: north} | run LAAARALA) {position: {x: -4, y: 1}, direction: west} +assert equal ({position: {x: 0, y: 0}, direction: north} | move LAAARALA) {position: {x: -4, y: 1}, direction: west} # moving west and south -assert equal ({position: {x: 2, y: -7}, direction: east} | run RRAAAAALA) {position: {x: -3, y: -8}, direction: south} +assert equal ({position: {x: 2, y: -7}, direction: east} | move RRAAAAALA) {position: {x: -3, y: -8}, direction: south} # moving east and north -assert equal ({position: {x: 8, y: 4}, direction: south} | run LAAARRRALLLL) {position: {x: 11, y: 5}, direction: north} +assert equal ({position: {x: 8, y: 4}, direction: south} | move LAAARRRALLLL) {position: {x: 11, y: 5}, direction: north} From 0e195ea9eda8813dc8cd82a699a8e3a51f2a0ab5 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Tue, 28 Jul 2026 22:19:24 +0100 Subject: [PATCH 13/14] Update exercises/practice/gigasecond/tests.nu Co-authored-by: J R M --- exercises/practice/gigasecond/tests.nu | 3 --- 1 file changed, 3 deletions(-) diff --git a/exercises/practice/gigasecond/tests.nu b/exercises/practice/gigasecond/tests.nu index 45796b8..a2a4ad9 100644 --- a/exercises/practice/gigasecond/tests.nu +++ b/exercises/practice/gigasecond/tests.nu @@ -8,6 +8,3 @@ assert equal (add 2015-01-24T22:00:00) 2046-10-02T23:46:40 assert equal (add 2015-01-24T23:59:59) 2046-10-03T01:46:39 # test immuatability of input -let orig_moment = 2015-01-24T23:59:59 -let new_moment = add $orig_moment -assert equal $orig_moment 2015-01-24T23:59:59 From 41e3719e0bf091f95c8801b0f92bf408e5da6668 Mon Sep 17 00:00:00 2001 From: Yanni Papandreou Date: Tue, 28 Jul 2026 22:19:36 +0100 Subject: [PATCH 14/14] Update exercises/practice/gigasecond/.meta/tests.toml Co-authored-by: J R M --- exercises/practice/gigasecond/.meta/tests.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/practice/gigasecond/.meta/tests.toml b/exercises/practice/gigasecond/.meta/tests.toml index a7caf00..7f75cf5 100644 --- a/exercises/practice/gigasecond/.meta/tests.toml +++ b/exercises/practice/gigasecond/.meta/tests.toml @@ -26,3 +26,4 @@ description = "full time with day roll-over" [fcec307c-7529-49ab-b0fe-20309197618a] description = "does not mutate the input" +include = false