New Exercise: Word count (#90)
This commit is contained in:
10
config.json
10
config.json
@@ -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",
|
||||
|
||||
31
exercises/practice/word-count/.docs/instructions.md
Normal file
31
exercises/practice/word-count/.docs/instructions.md
Normal 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
|
||||
```
|
||||
20
exercises/practice/word-count/.meta/config.json
Normal file
20
exercises/practice/word-count/.meta/config.json
Normal 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"
|
||||
}
|
||||
55
exercises/practice/word-count/.meta/zcl_word_count.clas.abap
Normal file
55
exercises/practice/word-count/.meta/zcl_word_count.clas.abap
Normal 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.
|
||||
10
exercises/practice/word-count/package.devc.xml
Normal file
10
exercises/practice/word-count/package.devc.xml
Normal 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>
|
||||
28
exercises/practice/word-count/zcl_word_count.clas.abap
Normal file
28
exercises/practice/word-count/zcl_word_count.clas.abap
Normal 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.
|
||||
@@ -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.
|
||||
17
exercises/practice/word-count/zcl_word_count.clas.xml
Normal file
17
exercises/practice/word-count/zcl_word_count.clas.xml
Normal 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>
|
||||
Reference in New Issue
Block a user