diff --git a/config.json b/config.json index d9b3ee0..e17e43f 100644 --- a/config.json +++ b/config.json @@ -104,6 +104,14 @@ "prerequisites": [], "difficulty": 3 }, + { + "uuid": "6d626f7b-2336-49ec-8c1e-4ee3f0fa9a56", + "slug": "word-count", + "name": "Word Count", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "uuid": "b0317cb6-adaf-4fa7-a050-ad40e1139413", "slug": "raindrops", diff --git a/exercises/practice/word-count/.docs/instructions.md b/exercises/practice/word-count/.docs/instructions.md new file mode 100644 index 0000000..8b7f03e --- /dev/null +++ b/exercises/practice/word-count/.docs/instructions.md @@ -0,0 +1,31 @@ +# Instructions + +Given a phrase, count the occurrences of each _word_ in that phrase. + +For the purposes of this exercise you can expect that a _word_ will always be one of: + +1. A _number_ composed of one or more ASCII digits (ie "0" or "1234") OR +2. A _simple word_ composed of one or more ASCII letters (ie "a" or "they") OR +3. A _contraction_ of two _simple words_ joined by a single apostrophe (ie "it's" or "they're") + +When counting words you can assume the following rules: + +1. The count is _case insensitive_ (ie "You", "you", and "YOU" are 3 uses of the same word) +2. The count is _unordered_; the tests will ignore how words and counts are ordered +3. Other than the apostrophe in a _contraction_ all forms of _punctuation_ are regarded as spaces +4. The words can be separated by _any_ form of whitespace (ie "\t", "\n", " ") + +For example, for the phrase `"That's the password: 'PASSWORD 123'!", cried the Special Agent.\nSo I fled.` the count would be: + +```text +that's: 1 +the: 2 +password: 2 +123: 1 +cried: 1 +special: 1 +agent: 1 +so: 1 +i: 1 +fled: 1 +``` diff --git a/exercises/practice/word-count/.meta/config.json b/exercises/practice/word-count/.meta/config.json new file mode 100644 index 0000000..e268e38 --- /dev/null +++ b/exercises/practice/word-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [], + "contributors": [ + "kytrinyx" + ], + "files": { + "solution": [ + "src/word-count.chpl" + ], + "test": [ + "test/tests.chpl" + ], + "example": [ + ".meta/reference.chpl" + ] + }, + "blurb": "Given a phrase, count the occurrences of each word in that phrase.", + "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour." +} diff --git a/exercises/practice/word-count/.meta/reference.chpl b/exercises/practice/word-count/.meta/reference.chpl new file mode 100644 index 0000000..19dcedb --- /dev/null +++ b/exercises/practice/word-count/.meta/reference.chpl @@ -0,0 +1,3 @@ +module WordCount { + // implement reference solution +} diff --git a/exercises/practice/word-count/.meta/tests.toml b/exercises/practice/word-count/.meta/tests.toml new file mode 100644 index 0000000..1be425b --- /dev/null +++ b/exercises/practice/word-count/.meta/tests.toml @@ -0,0 +1,57 @@ +# 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. + +[61559d5f-2cad-48fb-af53-d3973a9ee9ef] +description = "count one word" + +[5abd53a3-1aed-43a4-a15a-29f88c09cbbd] +description = "count one of each word" + +[2a3091e5-952e-4099-9fac-8f85d9655c0e] +description = "multiple occurrences of a word" + +[e81877ae-d4da-4af4-931c-d923cd621ca6] +description = "handles cramped lists" + +[7349f682-9707-47c0-a9af-be56e1e7ff30] +description = "handles expanded lists" + +[a514a0f2-8589-4279-8892-887f76a14c82] +description = "ignore punctuation" + +[d2e5cee6-d2ec-497b-bdc9-3ebe092ce55e] +description = "include numbers" + +[dac6bc6a-21ae-4954-945d-d7f716392dbf] +description = "normalize case" + +[4185a902-bdb0-4074-864c-f416e42a0f19] +description = "with apostrophes" +include = false + +[4ff6c7d7-fcfc-43ef-b8e7-34ff1837a2d3] +description = "with apostrophes" +reimplements = "4185a902-bdb0-4074-864c-f416e42a0f19" + +[be72af2b-8afe-4337-b151-b297202e4a7b] +description = "with quotations" + +[8d6815fe-8a51-4a65-96f9-2fb3f6dc6ed6] +description = "substrings from the beginning" + +[c5f4ef26-f3f7-4725-b314-855c04fb4c13] +description = "multiple spaces not detected as a word" + +[50176e8a-fe8e-4f4c-b6b6-aa9cf8f20360] +description = "alternating word separators not detected as a word" + +[6d00f1db-901c-4bec-9829-d20eb3044557] +description = "quotation for word with apostrophe" diff --git a/exercises/practice/word-count/Mason.toml b/exercises/practice/word-count/Mason.toml new file mode 100644 index 0000000..706d6d2 --- /dev/null +++ b/exercises/practice/word-count/Mason.toml @@ -0,0 +1,5 @@ +[brick] +name="word-count" +version="0.1.0" +chplVersion="1.28.0" +type="application" diff --git a/exercises/practice/word-count/src/word-count.chpl b/exercises/practice/word-count/src/word-count.chpl new file mode 100644 index 0000000..ff9a82d --- /dev/null +++ b/exercises/practice/word-count/src/word-count.chpl @@ -0,0 +1,3 @@ +module WordCount { + // write your solution here +} diff --git a/exercises/practice/word-count/test/tests.chpl b/exercises/practice/word-count/test/tests.chpl new file mode 100644 index 0000000..2cd41b5 --- /dev/null +++ b/exercises/practice/word-count/test/tests.chpl @@ -0,0 +1,61 @@ +use UnitTest; +use WordCount; + +proc testCountOneWord(test : borrowed Test) throws { + var expected = [ "word" => 1 ]; + test.assertEqual(countWords("word"), expected); +} +proc testCountOneOfEachWord(test : borrowed Test) throws { + var expected = [ "one" => 1, "of" => 1, "each" => 1 ]; + test.assertEqual(countWords("one of each"), expected); +} +proc testMultipleOccurrencesOfAWord(test : borrowed Test) throws { + var expected = [ "one" => 1, "fish" => 4, "two" => 1, "red" => 1, "blue" => 1 ]; + test.assertEqual(countWords("one fish two fish red fish blue fish"), expected); +} +proc testHandlesCrampedLists(test : borrowed Test) throws { + var expected = [ "one" => 1, "two" => 1, "three" => 1 ]; + test.assertEqual(countWords("one,two,three"), expected); +} +proc testHandlesExpandedLists(test : borrowed Test) throws { + var expected = [ "one" => 1, "two" => 1, "three" => 1 ]; + test.assertEqual(countWords("one,\ntwo,\nthree"), expected); +} +proc testIgnorePunctuation(test : borrowed Test) throws { + var expected = [ "car" => 1, "carpet" => 1, "as" => 1, "java" => 1, "javascript" => 1 ]; + test.assertEqual(countWords("car: carpet as java: javascript!!&@$%^&"), expected); +} +proc testIncludeNumbers(test : borrowed Test) throws { + var expected = [ "testing" => 2, "1" => 1, "2" => 1 ]; + test.assertEqual(countWords("testing, 1, 2 testing"), expected); +} +proc testNormalizeCase(test : borrowed Test) throws { + var expected = [ "go" => 3, "stop" => 2 ]; + test.assertEqual(countWords("go Go GO Stop stop"), expected); +} +proc testWithApostrophes(test : borrowed Test) throws { + var expected = [ "first" => 1, "don't" => 2, "laugh" => 1, "then" => 1, "cry" => 1, "you're" => 1, "getting" => 1, "it" => 1 ]; + test.assertEqual(countWords("'First: don't laugh. Then: don't cry. You're getting it.'"), expected); +} +proc testWithQuotations(test : borrowed Test) throws { + var expected = [ "joe" => 1, "can't" => 1, "tell" => 1, "between" => 1, "large" => 2, "and" => 1 ]; + test.assertEqual(countWords("Joe can't tell between 'large' and large."), expected); +} +proc testSubstringsFromTheBeginning(test : borrowed Test) throws { + var expected = [ "joe" => 1, "can't" => 1, "tell" => 1, "between" => 1, "app" => 1, "apple" => 1, "and" => 1, "a" => 1 ]; + test.assertEqual(countWords("Joe can't tell between app, apple and a."), expected); +} +proc testMultipleSpacesNotDetectedAsAWord(test : borrowed Test) throws { + var expected = [ "multiple" => 1, "whitespaces" => 1 ]; + test.assertEqual(countWords(" multiple whitespaces"), expected); +} +proc testAlternatingWordSeparatorsNotDetectedAsAWord(test : borrowed Test) throws { + var expected = [ "one" => 1, "two" => 1, "three" => 1 ]; + test.assertEqual(countWords(",\n,one,\n ,two \n 'three'"), expected); +} +proc testQuotationForWordWithApostrophe(test : borrowed Test) throws { + var expected = [ "can" => 1, "can't" => 2 ]; + test.assertEqual(countWords("can, can't, 'can't'"), expected); +} + +UnitTest.main();