exercism-perl5

Repository for my Perl 5 Exercism exercises
git clone git://git.samirparikh.com/exercism-perl5
Log | Files | Refs | README

commit 30bc1cb3625751ae8f43bac02610edf8faddbd97
parent 7c18d4ad56808381109d548b15a763affdad41e6
Author: Samir Parikh <noreply@samirparikh.com>
Date:   Sun, 19 Dec 2021 16:18:31 +0000

initial commit for word-count

Diffstat:
Aword-count/HELP.md | 36++++++++++++++++++++++++++++++++++++
Aword-count/README.md | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Aword-count/WordCount.pm | 24++++++++++++++++++++++++
Aword-count/word-count.t | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 303 insertions(+), 0 deletions(-)

diff --git a/word-count/HELP.md b/word-count/HELP.md @@ -0,0 +1,35 @@ +# Help + +## Running the tests + +There is a Perl 5 script with the extension `.t`, which will be used to test +your solution. You can run through the tests by using the command: + +```bash +`prove .` +``` + +## Submitting your solution + +You can submit your solution using the `exercism submit WordCount.pm` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Perl 5 track's documentation](https://exercism.org/docs/tracks/perl5) +- [Exercism's support channel on gitter](https://gitter.im/exercism/support) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +To get help if you're having trouble, you can use one of the following resources: + +- [/r/perl5](https://www.reddit.com/r/perl5) is the perl5 subreddit. +- [StackOverflow](http://stackoverflow.com/questions/tagged/perl5) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. +\ No newline at end of file diff --git a/word-count/README.md b/word-count/README.md @@ -0,0 +1,52 @@ +# Word Count + +Welcome to Word Count on Exercism's Perl 5 Track. +If you need help running the tests or submitting your code, check out `HELP.md`. + +## 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 ignored +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 +``` + +## Source + +### Created by + +- @szabgab + +### Contributed to by + +- @kytrinyx +- @m-dango +- @rfilipo + +### Based on + +This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour. +\ No newline at end of file diff --git a/word-count/WordCount.pm b/word-count/WordCount.pm @@ -0,0 +1,24 @@ +package WordCount; +use strict; +use warnings; +use v5.22; +use Exporter qw<import>; +our @EXPORT_OK = qw<count_words>; +use Data::Dumper; + +sub count_words { + my ($sentence) = @_; + #say $sentence; + my %word_count; + $sentence =~ s/(.)/\L$1/gi; + my @words = $sentence =~ m/\b{wb}(\w+)\b{wb}/gi; + foreach (@words) { + $word_count{$_}++; + #say $_; + } + #print Dumper (\%word_count); + #return undef; + return \%word_count; +} + +1; diff --git a/word-count/word-count.t b/word-count/word-count.t @@ -0,0 +1,190 @@ +#!/usr/bin/env perl +use Test2::V0; +use JSON::PP; +use constant JSON => JSON::PP->new; + +use FindBin qw<$Bin>; +use lib $Bin, "$Bin/local/lib/perl5"; + +use WordCount qw<count_words>; + +my @test_cases = do { local $/; @{ JSON->decode(<DATA>) }; }; + +imported_ok qw<count_words> or bail_out; + +for my $case (@test_cases) { + is( count_words( $case->{input}{sentence} ), + $case->{expected}, $case->{description}, ); +} + +done_testing; + +__DATA__ +[ + { + "description": "count one word", + "expected": { + "word": 1 + }, + "input": { + "sentence": "word" + }, + "property": "countWords" + }, + { + "description": "count one of each word", + "expected": { + "each": 1, + "of": 1, + "one": 1 + }, + "input": { + "sentence": "one of each" + }, + "property": "countWords" + }, + { + "description": "multiple occurrences of a word", + "expected": { + "blue": 1, + "fish": 4, + "one": 1, + "red": 1, + "two": 1 + }, + "input": { + "sentence": "one fish two fish red fish blue fish" + }, + "property": "countWords" + }, + { + "description": "handles cramped lists", + "expected": { + "one": 1, + "three": 1, + "two": 1 + }, + "input": { + "sentence": "one,two,three" + }, + "property": "countWords" + }, + { + "description": "handles expanded lists", + "expected": { + "one": 1, + "three": 1, + "two": 1 + }, + "input": { + "sentence": "one,\ntwo,\nthree" + }, + "property": "countWords" + }, + { + "description": "ignore punctuation", + "expected": { + "as": 1, + "car": 1, + "carpet": 1, + "java": 1, + "javascript": 1 + }, + "input": { + "sentence": "car: carpet as java: javascript!!&@$%^&" + }, + "property": "countWords" + }, + { + "description": "include numbers", + "expected": { + "1": 1, + "2": 1, + "testing": 2 + }, + "input": { + "sentence": "testing, 1, 2 testing" + }, + "property": "countWords" + }, + { + "description": "normalize case", + "expected": { + "go": 3, + "stop": 2 + }, + "input": { + "sentence": "go Go GO Stop stop" + }, + "property": "countWords" + }, + { + "description": "with apostrophes", + "expected": { + "cry": 1, + "don't": 2, + "first": 1, + "laugh": 1, + "then": 1 + }, + "input": { + "sentence": "First: don't laugh. Then: don't cry." + }, + "property": "countWords" + }, + { + "description": "with quotations", + "expected": { + "and": 1, + "between": 1, + "can't": 1, + "joe": 1, + "large": 2, + "tell": 1 + }, + "input": { + "sentence": "Joe can't tell between 'large' and large." + }, + "property": "countWords" + }, + { + "description": "substrings from the beginning", + "expected": { + "a": 1, + "and": 1, + "app": 1, + "apple": 1, + "between": 1, + "can't": 1, + "joe": 1, + "tell": 1 + }, + "input": { + "sentence": "Joe can't tell between app, apple and a." + }, + "property": "countWords" + }, + { + "description": "multiple spaces not detected as a word", + "expected": { + "multiple": 1, + "whitespaces": 1 + }, + "input": { + "sentence": " multiple whitespaces" + }, + "property": "countWords" + }, + { + "description": "alternating word separators not detected as a word", + "expected": { + "one": 1, + "three": 1, + "two": 1 + }, + "input": { + "sentence": ",\n,one,\n ,two \n 'three'" + }, + "property": "countWords" + } +]