From ba7707ef3a475ba2dba5c1c82c6dc6792bd816a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:52:33 -0700 Subject: [PATCH 1/2] Add pangram --- config.json | 8 + .../practice/pangram/.docs/instructions.md | 8 + .../practice/pangram/.docs/introduction.md | 16 ++ exercises/practice/pangram/.meta/config.json | 19 ++ exercises/practice/pangram/.meta/example.red | 17 ++ exercises/practice/pangram/.meta/tests.toml | 45 ++++ exercises/practice/pangram/pangram-test.red | 112 +++++++++ exercises/practice/pangram/pangram.red | 11 + exercises/practice/pangram/testlib.red | 217 ++++++++++++++++++ 9 files changed, 453 insertions(+) create mode 100644 exercises/practice/pangram/.docs/instructions.md create mode 100644 exercises/practice/pangram/.docs/introduction.md create mode 100644 exercises/practice/pangram/.meta/config.json create mode 100644 exercises/practice/pangram/.meta/example.red create mode 100644 exercises/practice/pangram/.meta/tests.toml create mode 100644 exercises/practice/pangram/pangram-test.red create mode 100644 exercises/practice/pangram/pangram.red create mode 100644 exercises/practice/pangram/testlib.red diff --git a/config.json b/config.json index 489424b..74c566a 100644 --- a/config.json +++ b/config.json @@ -125,6 +125,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "pangram", + "name": "Pangram", + "uuid": "125d167d-952f-44cf-ad56-aa81924efa7b", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "protein-translation", "name": "Protein Translation", diff --git a/exercises/practice/pangram/.docs/instructions.md b/exercises/practice/pangram/.docs/instructions.md new file mode 100644 index 0000000..817c872 --- /dev/null +++ b/exercises/practice/pangram/.docs/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +Your task is to figure out if a sentence is a pangram. + +A pangram is a sentence using every letter of the alphabet at least once. +It is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`). + +For this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet. diff --git a/exercises/practice/pangram/.docs/introduction.md b/exercises/practice/pangram/.docs/introduction.md new file mode 100644 index 0000000..32b6f1f --- /dev/null +++ b/exercises/practice/pangram/.docs/introduction.md @@ -0,0 +1,16 @@ +# Introduction + +You work for a company that sells fonts through their website. +They'd like to show a different sentence each time someone views a font on their website. +To give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet. + +They're running a competition to get suggestions for sentences that they can use. +You're in charge of checking the submissions to see if they are valid. + +~~~~exercism/note +Pangram comes from Greek, παν γράμμα, pan gramma, which means "every letter". + +The best known English pangram is: + +> The quick brown fox jumps over the lazy dog. +~~~~ diff --git a/exercises/practice/pangram/.meta/config.json b/exercises/practice/pangram/.meta/config.json new file mode 100644 index 0000000..b8103ec --- /dev/null +++ b/exercises/practice/pangram/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "pangram.red" + ], + "test": [ + "pangram-test.red" + ], + "example": [ + ".meta/example.red" + ] + }, + "blurb": "Determine if a sentence is a pangram.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Pangram" +} diff --git a/exercises/practice/pangram/.meta/example.red b/exercises/practice/pangram/.meta/example.red new file mode 100644 index 0000000..5be88bf --- /dev/null +++ b/exercises/practice/pangram/.meta/example.red @@ -0,0 +1,17 @@ +Red [ + description: {"Pangram" exercise solution for exercism platform} + author: "BNAndras" +] + +is-pangram: function [ + sentence +] [ + foreach letter "abcdefghijklmnopqrstuvwxyz" [ + if not find sentence letter [ + return false + ] + ] + + true +] + diff --git a/exercises/practice/pangram/.meta/tests.toml b/exercises/practice/pangram/.meta/tests.toml new file mode 100644 index 0000000..10b5a33 --- /dev/null +++ b/exercises/practice/pangram/.meta/tests.toml @@ -0,0 +1,45 @@ +# 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. + +[64f61791-508e-4f5c-83ab-05de042b0149] +description = "empty sentence" + +[74858f80-4a4d-478b-8a5e-c6477e4e4e84] +description = "perfect lower case" + +[61288860-35ca-4abe-ba08-f5df76ecbdcd] +description = "only lower case" + +[6564267d-8ac5-4d29-baf2-e7d2e304a743] +description = "missing the letter 'x'" + +[c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0] +description = "missing the letter 'h'" + +[d835ec38-bc8f-48e4-9e36-eb232427b1df] +description = "with underscores" + +[8cc1e080-a178-4494-b4b3-06982c9be2a8] +description = "with numbers" + +[bed96b1c-ff95-45b8-9731-fdbdcb6ede9a] +description = "missing letters replaced by numbers" + +[938bd5d8-ade5-40e2-a2d9-55a338a01030] +description = "mixed case and punctuation" + +[2577bf54-83c8-402d-a64b-a2c0f7bb213a] +description = "case insensitive" +include = false + +[7138e389-83e4-4c6e-8413-1e40a0076951] +description = "a-m and A-M are 26 different characters but not a pangram" +reimplements = "2577bf54-83c8-402d-a64b-a2c0f7bb213a" diff --git a/exercises/practice/pangram/pangram-test.red b/exercises/practice/pangram/pangram-test.red new file mode 100644 index 0000000..89239a2 --- /dev/null +++ b/exercises/practice/pangram/pangram-test.red @@ -0,0 +1,112 @@ +Red [ + description: {Tests for "Pangram" Exercism exercise} + author: "loziniak" +] + +#include %testlib.red + +test-init/limit %pangram.red 1 +; test-init/limit %.meta/example.red 1 ; test example solution + +canonical-cases: [#[ + description: "empty sentence" + input: #[ + sentence: "" + ] + expected: false + function: "is-pangram" + uuid: "64f61791-508e-4f5c-83ab-05de042b0149" +] #[ + description: "perfect lower case" + input: #[ + sentence: "abcdefghijklmnopqrstuvwxyz" + ] + expected: true + function: "is-pangram" + uuid: "74858f80-4a4d-478b-8a5e-c6477e4e4e84" +] #[ + description: "only lower case" + input: #[ + sentence: "the quick brown fox jumps over the lazy dog" + ] + expected: true + function: "is-pangram" + uuid: "61288860-35ca-4abe-ba08-f5df76ecbdcd" +] #[ + description: "missing the letter 'x'" + input: #[ + sentence: {a quick movement of the enemy will jeopardize five gunboats} + ] + expected: false + function: "is-pangram" + uuid: "6564267d-8ac5-4d29-baf2-e7d2e304a743" +] #[ + description: "missing the letter 'h'" + input: #[ + sentence: "five boxing wizards jump quickly at it" + ] + expected: false + function: "is-pangram" + uuid: "c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0" +] #[ + description: "with underscores" + input: #[ + sentence: "the_quick_brown_fox_jumps_over_the_lazy_dog" + ] + expected: true + function: "is-pangram" + uuid: "d835ec38-bc8f-48e4-9e36-eb232427b1df" +] #[ + description: "with numbers" + input: #[ + sentence: "the 1 quick brown fox jumps over the 2 lazy dogs" + ] + expected: true + function: "is-pangram" + uuid: "8cc1e080-a178-4494-b4b3-06982c9be2a8" +] #[ + description: "missing letters replaced by numbers" + input: #[ + sentence: "7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog" + ] + expected: false + function: "is-pangram" + uuid: "bed96b1c-ff95-45b8-9731-fdbdcb6ede9a" +] #[ + description: "mixed case and punctuation" + input: #[ + sentence: {"Five quacking Zephyrs jolt my wax bed."} + ] + expected: true + function: "is-pangram" + uuid: "938bd5d8-ade5-40e2-a2d9-55a338a01030" +] #[ + description: "case insensitive" + input: #[ + sentence: "the quick brown fox jumps over with lazy FX" + ] + expected: false + function: "is-pangram" + uuid: "2577bf54-83c8-402d-a64b-a2c0f7bb213a" +] #[ + description: {a-m and A-M are 26 different characters but not a pangram} + input: #[ + sentence: "abcdefghijklm ABCDEFGHIJKLM" + ] + expected: false + function: "is-pangram" + uuid: "7138e389-83e4-4c6e-8413-1e40a0076951" +]] + + +foreach c-case canonical-cases [ + case-code: reduce [ + 'expect c-case/expected compose [ + (to word! c-case/function) (values-of c-case/input) + ] + ] + + test c-case/description case-code +] + +test-results/print diff --git a/exercises/practice/pangram/pangram.red b/exercises/practice/pangram/pangram.red new file mode 100644 index 0000000..0d72a55 --- /dev/null +++ b/exercises/practice/pangram/pangram.red @@ -0,0 +1,11 @@ +Red [ + description: {"Pangram" exercise solution for exercism platform} + author: "" ; you can write your name here, in quotes +] + +is-pangram: function [ + sentence +] [ + cause-error 'user 'message "You need to implement is-pangram function." +] + diff --git a/exercises/practice/pangram/testlib.red b/exercises/practice/pangram/testlib.red new file mode 100644 index 0000000..9b0b79e --- /dev/null +++ b/exercises/practice/pangram/testlib.red @@ -0,0 +1,217 @@ +Red [ + description: {Unit testing library} + author: "loziniak" +] + + +context [ + tested: ignore-after: test-file: results: output: none + + set 'test-init function [ + file [file!] + /limit + ia [integer!] + ] [ + self/tested: 0 + self/ignore-after: either limit [ia] [none] + self/test-file: file + self/results: copy [] + self/output: copy "" + ] + + sandbox!: context [ + + assert: function [ + code [block!] + /local result + ] [ + res: last results + + set/any 'result do code + either :result = true [ + res/status: 'pass + ] [ + res/status: 'fail + throw/name none 'expect-fail + ] + + :result + ] + + expect: function [ + expectation [any-type!] + code [block!] + /local result + ] [ + res: last results + res/expected: :expectation + + set/any 'result do code + res/actual: :result + + either :result = :expectation [ + res/status: 'pass + ] [ + res/status: 'fail + throw/name none 'expect-fail + ] + + :result + ] + + expect-error: function [ + type [word!] + code [block!] + /message + msg [string!] + /local result result-or-error + ] [ + returned-error?: no + set/any 'result-or-error try [ + set/any 'result do code + returned-error?: yes + :result + ] + + res: last results + res/actual: :result-or-error + res/expected: compose [type: (type)] + if message [append res/expected compose [id: 'message arg1: (msg)]] + + either all [ + error? :result-or-error + not returned-error? + result-or-error/type = type + any [ + not message + all [ + result-or-error/id = 'message + result-or-error/arg1 = msg + ] + ] + ] [ + res/status: 'pass + ] [ + res/status: 'fail + throw/name none 'expect-fail + ] + + :result-or-error + ] + ] + + set 'test function [ + summary [string!] + code [block!] + /extern + tested + ] [ + append results result: make map! compose/only [ + summary: (summary) ;@@ [string!] + test-code: (copy code) ;@@ [block!] + status: none ;@@ [word!] : 'pass | 'fail | 'error | 'ignored + ;-- expected (optional field) + ;-- actual (optional field) + ;-- output (optional field) + ] + + either any [ + none? ignore-after + tested < ignore-after + ] [ + clear output + old-functions: override-console + + exercise: make sandbox! load test-file + code: bind code exercise + uncaught?: yes + outcome: catch [ + outcome: try [ + catch/name [ + do code + ] 'expect-fail + none + ] + uncaught?: no + outcome + ] + + case [ + error? outcome [ + result/status: 'error + result/actual: outcome + ] + uncaught? [ + result/status: 'error + result/actual: make error! [type: 'throw id: 'throw arg1: outcome] + ] + ] + + restore-console old-functions + result/output: copy output + ] [ + result/status: 'ignored + ] + + tested: tested + 1 + ] + + set 'test-results function [ + /print + ] [ + either print [ + foreach result self/results [ + system/words/print rejoin [ + pad/with result/summary 40 #"." + "... " + switch result/status [ + pass ["✓"] + fail [rejoin [ + {FAILED.} + either find result 'expected [rejoin [ + { Expected: } result/expected + either find result 'actual [rejoin [ + {, but got } result/actual + ]] [] + ]] [] + newline + result/output + ]] + error [rejoin [ + newline + result/output + form result/actual + ]] + ignored ["(ignored)"] + ] + ] + ] + ] [ + self/results + ] + ] + + + override-console: function [] [ + old-functions: reduce [:prin :print :probe] + + system/words/prin: function [value [any-type!]] [ + append self/output form :value + return () + ] + system/words/print: function [value [any-type!]] [ + append self/output reduce [form :value #"^/"] + return () + ] + system/words/probe: function [value [any-type!]] [ + append self/output reduce [mold :value #"^/"] + return :value + ] + return old-functions + ] + + restore-console: function [old-functions [block!]] [ + set [prin print probe] old-functions + ] + +] From a7e42f71568c40b2fbcc1ce5f2425228369efc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:54:47 -0700 Subject: [PATCH 2/2] Remove reimplemented test --- exercises/practice/pangram/pangram-test.red | 8 -------- 1 file changed, 8 deletions(-) diff --git a/exercises/practice/pangram/pangram-test.red b/exercises/practice/pangram/pangram-test.red index 89239a2..5cc5cea 100644 --- a/exercises/practice/pangram/pangram-test.red +++ b/exercises/practice/pangram/pangram-test.red @@ -80,14 +80,6 @@ canonical-cases: [#[ expected: true function: "is-pangram" uuid: "938bd5d8-ade5-40e2-a2d9-55a338a01030" -] #[ - description: "case insensitive" - input: #[ - sentence: "the quick brown fox jumps over with lazy FX" - ] - expected: false - function: "is-pangram" - uuid: "2577bf54-83c8-402d-a64b-a2c0f7bb213a" ] #[ description: {a-m and A-M are 26 different characters but not a pangram} input: #[