New Exercise: Word count (#90)

This commit is contained in:
Marian Zeis
2022-06-08 12:19:22 +02:00
committed by GitHub
parent d5f7b4bb4e
commit c0cdb04810
8 changed files with 395 additions and 0 deletions

View File

@@ -182,6 +182,16 @@
"prerequisites": [],
"difficulty": 5
},
{
"slug": "word-count",
"name": "Word Count",
"uuid": "a8f558ad-28df-46fa-9ac7-aac9afad5a67",
"practices": [],
"prerequisites": [],
"difficulty": 1,
"topics": ["loops", "lists", "regular_expressions", "strings"],
"status": "wip"
},
{
"slug": "beer-song",
"name": "Beer Song",

View File

@@ -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" is "its" )
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
thats: 1
the: 2
password: 2
123: 1
cried: 1
special: 1
agent: 1
so: 1
i: 1
fled: 1
```

View File

@@ -0,0 +1,20 @@
{
"authors": [
"marianfoo"
],
"contributors": [],
"files": {
"solution": [
"zcl_word_count.clas.abap"
],
"test": [
"zcl_word_count.clas.testclasses.abap"
],
"example": [
".meta/zcl_word_count.clas.abap"
]
},
"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.",
"source_url": "https://github.com/exercism/javascript/tree/main/exercises/practice/word-count"
}

View File

@@ -0,0 +1,55 @@
CLASS zcl_word_count DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF return_structure,
word TYPE string,
count TYPE i,
END OF return_structure,
return_table TYPE STANDARD TABLE OF return_structure WITH KEY word.
METHODS count_words
IMPORTING
!phrase TYPE string
RETURNING
VALUE(result) TYPE return_table .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_word_count IMPLEMENTATION.
METHOD count_words.
DATA(clean) = replace( val = to_lower( phrase )
sub = `'`
with = ``
occ = 0 ).
clean = replace( val = clean
sub = `\n`
with = ` `
occ = 0 ).
clean = replace( val = clean
sub = `\t`
with = ` `
occ = 0 ).
clean = replace( val = clean
regex = `[^a-z0-9]`
with = ` `
occ = 0 ).
SPLIT condense( clean ) AT ` ` INTO TABLE DATA(words).
LOOP AT words ASSIGNING FIELD-SYMBOL(<word>).
DATA(one_result) = VALUE return_structure( word = <word> count = 1 ).
READ TABLE result ASSIGNING FIELD-SYMBOL(<result>) WITH TABLE KEY word = one_result-word.
IF sy-subrc = 0.
<result>-count = <result>-count + one_result-count.
ELSE.
INSERT one_result INTO TABLE result.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>Exercism: Word Count</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>

View File

@@ -0,0 +1,28 @@
CLASS zcl_word_count DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF return_structure,
word TYPE string,
count TYPE i,
END OF return_structure,
return_table TYPE STANDARD TABLE OF return_structure WITH KEY word.
METHODS count_words
IMPORTING
!phrase TYPE string
RETURNING
VALUE(result) TYPE return_table .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_word_count IMPLEMENTATION.
METHOD count_words.
"Add solution here
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,224 @@
CLASS ltcl_word_count DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
PRIVATE SECTION.
DATA cut TYPE REF TO zcl_word_count.
METHODS setup.
METHODS test_one_word FOR TESTING RAISING cx_static_check.
METHODS test_three_words FOR TESTING RAISING cx_static_check.
METHODS test_five_words_multiple FOR TESTING RAISING cx_static_check.
METHODS test_three_words_comma FOR TESTING RAISING cx_static_check.
METHODS test_three_words_linebreak FOR TESTING RAISING cx_static_check.
METHODS test_special_character FOR TESTING RAISING cx_static_check.
METHODS test_words_number_comma FOR TESTING RAISING cx_static_check.
METHODS test_case_insensitive FOR TESTING RAISING cx_static_check.
METHODS test_colon_apostrophe FOR TESTING RAISING cx_static_check.
METHODS test_apostrophe FOR TESTING RAISING cx_static_check.
METHODS test_comma_apostroph FOR TESTING RAISING cx_static_check.
METHODS test_whitespaces FOR TESTING RAISING cx_static_check.
METHODS test_comma_linebreaks FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltcl_word_count IMPLEMENTATION.
METHOD setup.
cut = NEW zcl_word_count( ).
ENDMETHOD.
METHOD test_one_word.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'word' count = 1 ) ).
DATA(act) = cut->count_words( 'word' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_three_words.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'one' count = 1 )
( word = 'of' count = 1 )
( word = 'each' count = 1 ) ).
DATA(act) = cut->count_words( 'one of each' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_five_words_multiple.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'one' count = 1 )
( word = 'fish' count = 4 )
( word = 'two' count = 1 )
( word = 'red' count = 1 )
( word = 'blue' count = 1 ) ).
DATA(act) = cut->count_words( 'one fish two fish red fish blue fish' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_three_words_comma.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'one' count = 1 )
( word = 'three' count = 1 )
( word = 'two' count = 1 ) ).
DATA(act) = cut->count_words( 'one,two,three' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_three_words_linebreak.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'one' count = 1 )
( word = 'three' count = 1 )
( word = 'two' count = 1 ) ).
DATA(act) = cut->count_words( 'one,\ntwo,\nthree' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_special_character.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'car' count = 1 )
( word = 'carpet' count = 1 )
( word = 'as' count = 1 )
( word = 'java' count = 1 )
( word = 'javascript' count = 1 ) ).
DATA(act) = cut->count_words( 'car: carpet as java: javascript!!&@$%^&' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_words_number_comma.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'testing' count = 2 )
( word = '1' count = 1 )
( word = '2' count = 1 ) ).
DATA(act) = cut->count_words( 'testing, 1, 2 testing' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_case_insensitive.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'go' count = 3 )
( word = 'stop' count = 2 ) ).
DATA(act) = cut->count_words( 'go Go GO Stop stop' ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_colon_apostrophe.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'first' count = 1 )
( word = 'dont' count = 2 )
( word = 'laugh' count = 1 )
( word = 'then' count = 1 )
( word = 'cry' count = 1 ) ).
DATA(act) = cut->count_words( `First: don't laugh. Then: don't cry.` ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_apostrophe.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'joe' count = 1 )
( word = 'cant' count = 1 )
( word = 'tell' count = 1 )
( word = 'between' count = 1 )
( word = 'large' count = 2 )
( word = 'and' count = 1 ) ).
DATA(act) = cut->count_words( `Joe can't tell between 'large' and large.` ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_comma_apostroph.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'joe' count = 1 )
( word = 'cant' count = 1 )
( word = 'tell' count = 1 )
( word = 'between' count = 1 )
( word = 'app' count = 1 )
( word = 'apple' count = 1 )
( word = 'and' count = 1 )
( word = 'a' count = 1 ) ).
DATA(act) = cut->count_words( `Joe can't tell between app, apple and a.'` ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_whitespaces.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'multiple' count = 1 )
( word = 'whitespaces' count = 1 ) ).
DATA(act) = cut->count_words( ` multiple whitespaces` ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
METHOD test_comma_linebreaks.
DATA(exp) = VALUE zcl_word_count=>return_table(
( word = 'one' count = 1 )
( word = 'three' count = 1 )
( word = 'two' count = 1 ) ).
DATA(act) = cut->count_words( `,\n,one,\n ,two \n 'three'` ).
SORT exp BY word.
SORT act BY word.
cl_abap_unit_assert=>assert_equals(
act = act
exp = exp ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_WORD_COUNT</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Exercism: Word Count</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>