Skip to content

Commit c0cdb04

Browse files
authored
New Exercise: Word count (#90)
1 parent d5f7b4b commit c0cdb04

File tree

8 files changed

+395
-0
lines changed

8 files changed

+395
-0
lines changed

config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@
182182
"prerequisites": [],
183183
"difficulty": 5
184184
},
185+
{
186+
"slug": "word-count",
187+
"name": "Word Count",
188+
"uuid": "a8f558ad-28df-46fa-9ac7-aac9afad5a67",
189+
"practices": [],
190+
"prerequisites": [],
191+
"difficulty": 1,
192+
"topics": ["loops", "lists", "regular_expressions", "strings"],
193+
"status": "wip"
194+
},
185195
{
186196
"slug": "beer-song",
187197
"name": "Beer Song",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Instructions
2+
3+
Given a phrase, count the occurrences of each _word_ in that phrase.
4+
5+
For the purposes of this exercise you can expect that a _word_ will always be one of:
6+
7+
1. A _number_ composed of one or more ASCII digits (ie "0" or "1234") OR
8+
2. A _simple word_ composed of one or more ASCII letters (ie "a" or "they") OR
9+
3. A _contraction_ of two _simple words_ joined by a single apostrophe (ie "it's" is "its" )
10+
11+
When counting words you can assume the following rules:
12+
13+
1. The count is _case insensitive_ (ie "You", "you", and "YOU" are 3 uses of the same word)
14+
2. The count is _unordered_; the tests will ignore how words and counts are ordered
15+
3. Other than the apostrophe in a _contraction_ all forms of _punctuation_ are ignored
16+
4. The words can be separated by _any_ form of whitespace (ie "\t", "\n", " ")
17+
18+
For example, for the phrase `"That's the password: 'PASSWORD 123'!", cried the Special Agent.\nSo I fled.` the count would be:
19+
20+
```text
21+
thats: 1
22+
the: 2
23+
password: 2
24+
123: 1
25+
cried: 1
26+
special: 1
27+
agent: 1
28+
so: 1
29+
i: 1
30+
fled: 1
31+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"marianfoo"
4+
],
5+
"contributors": [],
6+
"files": {
7+
"solution": [
8+
"zcl_word_count.clas.abap"
9+
],
10+
"test": [
11+
"zcl_word_count.clas.testclasses.abap"
12+
],
13+
"example": [
14+
".meta/zcl_word_count.clas.abap"
15+
]
16+
},
17+
"blurb": "Given a phrase, count the occurrences of each word in that phrase.",
18+
"source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour.",
19+
"source_url": "https://github.com/exercism/javascript/tree/main/exercises/practice/word-count"
20+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
CLASS zcl_word_count DEFINITION
2+
PUBLIC
3+
FINAL
4+
CREATE PUBLIC .
5+
6+
PUBLIC SECTION.
7+
TYPES:
8+
BEGIN OF return_structure,
9+
word TYPE string,
10+
count TYPE i,
11+
END OF return_structure,
12+
return_table TYPE STANDARD TABLE OF return_structure WITH KEY word.
13+
METHODS count_words
14+
IMPORTING
15+
!phrase TYPE string
16+
RETURNING
17+
VALUE(result) TYPE return_table .
18+
PROTECTED SECTION.
19+
PRIVATE SECTION.
20+
ENDCLASS.
21+
22+
23+
CLASS zcl_word_count IMPLEMENTATION.
24+
25+
METHOD count_words.
26+
DATA(clean) = replace( val = to_lower( phrase )
27+
sub = `'`
28+
with = ``
29+
occ = 0 ).
30+
clean = replace( val = clean
31+
sub = `\n`
32+
with = ` `
33+
occ = 0 ).
34+
clean = replace( val = clean
35+
sub = `\t`
36+
with = ` `
37+
occ = 0 ).
38+
clean = replace( val = clean
39+
regex = `[^a-z0-9]`
40+
with = ` `
41+
occ = 0 ).
42+
43+
SPLIT condense( clean ) AT ` ` INTO TABLE DATA(words).
44+
45+
LOOP AT words ASSIGNING FIELD-SYMBOL(<word>).
46+
DATA(one_result) = VALUE return_structure( word = <word> count = 1 ).
47+
READ TABLE result ASSIGNING FIELD-SYMBOL(<result>) WITH TABLE KEY word = one_result-word.
48+
IF sy-subrc = 0.
49+
<result>-count = <result>-count + one_result-count.
50+
ELSE.
51+
INSERT one_result INTO TABLE result.
52+
ENDIF.
53+
ENDLOOP.
54+
ENDMETHOD.
55+
ENDCLASS.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
3+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
4+
<asx:values>
5+
<DEVC>
6+
<CTEXT>Exercism: Word Count</CTEXT>
7+
</DEVC>
8+
</asx:values>
9+
</asx:abap>
10+
</abapGit>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
CLASS zcl_word_count DEFINITION
2+
PUBLIC
3+
FINAL
4+
CREATE PUBLIC .
5+
6+
PUBLIC SECTION.
7+
TYPES:
8+
BEGIN OF return_structure,
9+
word TYPE string,
10+
count TYPE i,
11+
END OF return_structure,
12+
return_table TYPE STANDARD TABLE OF return_structure WITH KEY word.
13+
METHODS count_words
14+
IMPORTING
15+
!phrase TYPE string
16+
RETURNING
17+
VALUE(result) TYPE return_table .
18+
PROTECTED SECTION.
19+
PRIVATE SECTION.
20+
ENDCLASS.
21+
22+
23+
CLASS zcl_word_count IMPLEMENTATION.
24+
25+
METHOD count_words.
26+
"Add solution here
27+
ENDMETHOD.
28+
ENDCLASS.
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
CLASS ltcl_word_count DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
2+
3+
PRIVATE SECTION.
4+
5+
DATA cut TYPE REF TO zcl_word_count.
6+
METHODS setup.
7+
METHODS test_one_word FOR TESTING RAISING cx_static_check.
8+
METHODS test_three_words FOR TESTING RAISING cx_static_check.
9+
METHODS test_five_words_multiple FOR TESTING RAISING cx_static_check.
10+
METHODS test_three_words_comma FOR TESTING RAISING cx_static_check.
11+
METHODS test_three_words_linebreak FOR TESTING RAISING cx_static_check.
12+
METHODS test_special_character FOR TESTING RAISING cx_static_check.
13+
METHODS test_words_number_comma FOR TESTING RAISING cx_static_check.
14+
METHODS test_case_insensitive FOR TESTING RAISING cx_static_check.
15+
METHODS test_colon_apostrophe FOR TESTING RAISING cx_static_check.
16+
METHODS test_apostrophe FOR TESTING RAISING cx_static_check.
17+
METHODS test_comma_apostroph FOR TESTING RAISING cx_static_check.
18+
METHODS test_whitespaces FOR TESTING RAISING cx_static_check.
19+
METHODS test_comma_linebreaks FOR TESTING RAISING cx_static_check.
20+
21+
22+
ENDCLASS.
23+
24+
CLASS ltcl_word_count IMPLEMENTATION.
25+
26+
METHOD setup.
27+
cut = NEW zcl_word_count( ).
28+
ENDMETHOD.
29+
30+
31+
METHOD test_one_word.
32+
DATA(exp) = VALUE zcl_word_count=>return_table(
33+
( word = 'word' count = 1 ) ).
34+
DATA(act) = cut->count_words( 'word' ).
35+
36+
SORT exp BY word.
37+
SORT act BY word.
38+
cl_abap_unit_assert=>assert_equals(
39+
act = act
40+
exp = exp ).
41+
ENDMETHOD.
42+
43+
METHOD test_three_words.
44+
DATA(exp) = VALUE zcl_word_count=>return_table(
45+
( word = 'one' count = 1 )
46+
( word = 'of' count = 1 )
47+
( word = 'each' count = 1 ) ).
48+
DATA(act) = cut->count_words( 'one of each' ).
49+
50+
SORT exp BY word.
51+
SORT act BY word.
52+
cl_abap_unit_assert=>assert_equals(
53+
act = act
54+
exp = exp ).
55+
ENDMETHOD.
56+
57+
METHOD test_five_words_multiple.
58+
DATA(exp) = VALUE zcl_word_count=>return_table(
59+
( word = 'one' count = 1 )
60+
( word = 'fish' count = 4 )
61+
( word = 'two' count = 1 )
62+
( word = 'red' count = 1 )
63+
( word = 'blue' count = 1 ) ).
64+
DATA(act) = cut->count_words( 'one fish two fish red fish blue fish' ).
65+
66+
SORT exp BY word.
67+
SORT act BY word.
68+
cl_abap_unit_assert=>assert_equals(
69+
act = act
70+
exp = exp ).
71+
ENDMETHOD.
72+
73+
METHOD test_three_words_comma.
74+
DATA(exp) = VALUE zcl_word_count=>return_table(
75+
( word = 'one' count = 1 )
76+
( word = 'three' count = 1 )
77+
( word = 'two' count = 1 ) ).
78+
DATA(act) = cut->count_words( 'one,two,three' ).
79+
80+
SORT exp BY word.
81+
SORT act BY word.
82+
cl_abap_unit_assert=>assert_equals(
83+
act = act
84+
exp = exp ).
85+
ENDMETHOD.
86+
87+
METHOD test_three_words_linebreak.
88+
DATA(exp) = VALUE zcl_word_count=>return_table(
89+
( word = 'one' count = 1 )
90+
( word = 'three' count = 1 )
91+
( word = 'two' count = 1 ) ).
92+
DATA(act) = cut->count_words( 'one,\ntwo,\nthree' ).
93+
94+
SORT exp BY word.
95+
SORT act BY word.
96+
cl_abap_unit_assert=>assert_equals(
97+
act = act
98+
exp = exp ).
99+
ENDMETHOD.
100+
101+
METHOD test_special_character.
102+
DATA(exp) = VALUE zcl_word_count=>return_table(
103+
( word = 'car' count = 1 )
104+
( word = 'carpet' count = 1 )
105+
( word = 'as' count = 1 )
106+
( word = 'java' count = 1 )
107+
( word = 'javascript' count = 1 ) ).
108+
DATA(act) = cut->count_words( 'car: carpet as java: javascript!!&@$%^&' ).
109+
110+
SORT exp BY word.
111+
SORT act BY word.
112+
cl_abap_unit_assert=>assert_equals(
113+
act = act
114+
exp = exp ).
115+
ENDMETHOD.
116+
117+
METHOD test_words_number_comma.
118+
DATA(exp) = VALUE zcl_word_count=>return_table(
119+
( word = 'testing' count = 2 )
120+
( word = '1' count = 1 )
121+
( word = '2' count = 1 ) ).
122+
DATA(act) = cut->count_words( 'testing, 1, 2 testing' ).
123+
124+
SORT exp BY word.
125+
SORT act BY word.
126+
cl_abap_unit_assert=>assert_equals(
127+
act = act
128+
exp = exp ).
129+
ENDMETHOD.
130+
131+
METHOD test_case_insensitive.
132+
DATA(exp) = VALUE zcl_word_count=>return_table(
133+
( word = 'go' count = 3 )
134+
( word = 'stop' count = 2 ) ).
135+
DATA(act) = cut->count_words( 'go Go GO Stop stop' ).
136+
137+
SORT exp BY word.
138+
SORT act BY word.
139+
cl_abap_unit_assert=>assert_equals(
140+
act = act
141+
exp = exp ).
142+
ENDMETHOD.
143+
144+
METHOD test_colon_apostrophe.
145+
DATA(exp) = VALUE zcl_word_count=>return_table(
146+
( word = 'first' count = 1 )
147+
( word = 'dont' count = 2 )
148+
( word = 'laugh' count = 1 )
149+
( word = 'then' count = 1 )
150+
( word = 'cry' count = 1 ) ).
151+
DATA(act) = cut->count_words( `First: don't laugh. Then: don't cry.` ).
152+
153+
SORT exp BY word.
154+
SORT act BY word.
155+
cl_abap_unit_assert=>assert_equals(
156+
act = act
157+
exp = exp ).
158+
ENDMETHOD.
159+
160+
METHOD test_apostrophe.
161+
DATA(exp) = VALUE zcl_word_count=>return_table(
162+
( word = 'joe' count = 1 )
163+
( word = 'cant' count = 1 )
164+
( word = 'tell' count = 1 )
165+
( word = 'between' count = 1 )
166+
( word = 'large' count = 2 )
167+
( word = 'and' count = 1 ) ).
168+
DATA(act) = cut->count_words( `Joe can't tell between 'large' and large.` ).
169+
170+
SORT exp BY word.
171+
SORT act BY word.
172+
cl_abap_unit_assert=>assert_equals(
173+
act = act
174+
exp = exp ).
175+
ENDMETHOD.
176+
177+
METHOD test_comma_apostroph.
178+
DATA(exp) = VALUE zcl_word_count=>return_table(
179+
( word = 'joe' count = 1 )
180+
( word = 'cant' count = 1 )
181+
( word = 'tell' count = 1 )
182+
( word = 'between' count = 1 )
183+
( word = 'app' count = 1 )
184+
( word = 'apple' count = 1 )
185+
( word = 'and' count = 1 )
186+
( word = 'a' count = 1 ) ).
187+
DATA(act) = cut->count_words( `Joe can't tell between app, apple and a.'` ).
188+
189+
SORT exp BY word.
190+
SORT act BY word.
191+
cl_abap_unit_assert=>assert_equals(
192+
act = act
193+
exp = exp ).
194+
ENDMETHOD.
195+
196+
METHOD test_whitespaces.
197+
DATA(exp) = VALUE zcl_word_count=>return_table(
198+
( word = 'multiple' count = 1 )
199+
( word = 'whitespaces' count = 1 ) ).
200+
DATA(act) = cut->count_words( ` multiple whitespaces` ).
201+
202+
SORT exp BY word.
203+
SORT act BY word.
204+
cl_abap_unit_assert=>assert_equals(
205+
act = act
206+
exp = exp ).
207+
ENDMETHOD.
208+
209+
METHOD test_comma_linebreaks.
210+
DATA(exp) = VALUE zcl_word_count=>return_table(
211+
( word = 'one' count = 1 )
212+
( word = 'three' count = 1 )
213+
( word = 'two' count = 1 ) ).
214+
DATA(act) = cut->count_words( `,\n,one,\n ,two \n 'three'` ).
215+
216+
SORT exp BY word.
217+
SORT act BY word.
218+
cl_abap_unit_assert=>assert_equals(
219+
act = act
220+
exp = exp ).
221+
ENDMETHOD.
222+
223+
224+
ENDCLASS.

0 commit comments

Comments
 (0)