Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
31 changes: 31 additions & 0 deletions exercises/practice/word-count/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions exercises/practice/word-count/.meta/config.json
Original file line number Diff line number Diff line change
@@ -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 changes: 55 additions & 0 deletions exercises/practice/word-count/.meta/zcl_word_count.clas.abap
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions exercises/practice/word-count/package.devc.xml
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions exercises/practice/word-count/zcl_word_count.clas.abap
Original file line number Diff line number Diff line change
@@ -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.
224 changes: 224 additions & 0 deletions exercises/practice/word-count/zcl_word_count.clas.testclasses.abap
Original file line number Diff line number Diff line change
@@ -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.
Loading