Skip to Content
Technical Articles

My learning journey with ABAP SAP Community Coding Challenge #1

When the ABAP community coding challenge was first announced, the only thing that I thought was how to write in as fewer lines as possible 😀

 

Is it good to write like that? No, I don’t think so and you all know the reason

But did I have fun writing like that? Hell yeah!!

 

And the best thing I have done is that I didn’t stop trying out new ways after I submitted my first solution, I read the documentation many times to improve my approaches and I ended up sending 5 emails with 5 different solutions.

Although I didn’t make it to finals, I really loved and enjoyed doing this challenge.

 

Now I will show the 5 different approaches I used to solve this challenge.

Solution #1

Highlights:

  • One-Line solution
  • Used REGEX
  • Used CL_ABAP_REGEX class ( 😀 )
  • Most Ugliest?
out->write( data = VALUE string_table(
    " Declaring the string & extracting the words from the string
    LET sentence = `ABАP  is excellent ` 
           words = VALUE string_table( 
   FOR rawword IN NEW cl_abap_regex( pattern = '(\b\w+\b)' 
        )->create_matcher( text = sentence )->find_all( ) 
         ( substring( val = sentence off = rawword-offset len = rawword-length ) ) )
    " Filling the below additional value using base as the below for loop will 
    " only get executed max words times,
    " But our output needs max words + 1 lines
    IN BASE VALUE string_table( ( |Number of Words: { lines( words ) }| ) )
    " Loop all the words and extract the unique characters
    FOR word IN words ( |Number of unique characters in the word: { word } - 
             { lines( NEW cl_abap_regex( pattern = '(\w)(?!.*\1)' 
               )->create_matcher( text = word )->find_all( ) ) }| )
    ) ).  

 

I really thought I cracked the SAP coding challenge after doing this solution there  😀

As I was not aware of regex compatible string functions that were available at that point in time, I tried using CL_ABAP_REGEX class, it worked surprisingly. You can see that I used create_matcher and find_all to figure out pattern matches.

And I used “FOR” to loop and fill the final string table (no concatenation) and I used a similar approach in all other solutions.

 

Solution #2

So after going through the documentation, again and again, I found that I can use String Functions that support REGEX and I now can completely remove the usage of the above classes.

Highlights:

  • One-Line Solution
  • Regex String functions
   out->write( data = VALUE string_table(
        " Data declaration & finding the total no of words
        LET sentence = `ABАP  is excellent ` 
            totalWords = count( val = sentence regex = `(\b\w+\b)` )
        " Filling the base table with Total no of words as we will loop words times
        IN BASE VALUE string_table( ( |Number of Words: { totalWords }| ) )
        " Looping total words for unique characters count
        FOR i = 1 UNTIL i > totalWords (
        " Getting the word
        CONV #( LET word = match( val = sentence regex = '(\b\w+\b)' occ = i )
        " Getting the count of unique characters
        IN |Number of unique characters in the word: { word } - 
              { count( val = word regex = `(\w)(?!.*\1)` ) } | ) ) ) ).

The usage of “Count” and “Match” replaced all that class-related code and now it became a lot cleaner.

 

Solution #3

So after that, I thought enough is enough with the “Regex” and tried to find a different solution that doesn’t use it.

Highlights:

  • Not a One-Line Solution
  • No Regex
  • Finding Unique characters using “GROUPS” that auto sorts and gives unique records
  " Get the total no of words
    SPLIT condense( sentence ) AT space INTO TABLE DATA(words).
    " Output
    out->write( data = VALUE string_table(
      " Filling the base table with Total no of words
      BASE VALUE string_table( ( |Number of Words: { lines( words ) }| ) )
        " Looping words to find individual words unique character count
        FOR word IN words ( |Number of unique characters in the word: 
           { word } - { lines( VALUE string_table(
  " Grouping characters -> group will auto sort and find the unique records
            FOR GROUPS char_group OF char IN VALUE string_table(
  " For filling character table to group it in the above statement, 
  " we need to loop string length times
                FOR char_pos = 1 UNTIL char_pos > strlen( word )
                    " Now getting individual characters
                    ( substring( val = word off = char_pos - 1 len = 1 ) ) )
            " filling the character table for grouping
            GROUP BY char ( char_group ) ) ) }| ) ) ).

As I thought, there is no other way to find the total no of words, I ended up using condense & Split to get the total no of words.

I used “GROUP BY” to find unique characters. AIthoug I used “GROUP BY” many times in my projects, but didn’t realize till that time that I could use it that way.

 

Solution #4

After Thomas Jung and few others were mentioning the importance of a clean solution and stuff, I thought I should do it in a simple readable approach. and here it is

Highlights:

  • Not a One-Line Solution
  • a simple readable approach
   DATA(sentence) = `ABАP  is excellent `.

    SPLIT condense( sentence ) AT space INTO TABLE DATA(words).
    out->write( data = |Number of Words: { lines( words ) }| ).
    LOOP AT words REFERENCE INTO DATA(word).
      DATA(characters) = VALUE string_table( FOR i = 1 UNTIL i > strlen( word->* )  
                             ( substring( val = word->* off = i - 1 len = 1 ) ) ).
      SORT characters.
      DELETE ADJACENT DUPLICATES FROM characters.
      out->write( data = |Number of unique characters in the word: { word->* } 
           - { lines( characters ) }| ).
    ENDLOOP.

 

Solution #5 (Final)

This one is the final solution that I submitted and the one that I liked the most. I found that I don’t need to split the words outside anymore and can use the “Segment” string function to get the word & count space hack to find the total number of words.

Highlights:

  • One-Line Solution
  • My Favourite one (though it’s still ugly 😀 )
  • No Regex
 out->write( data = VALUE string_table(
      LET sentence = `ABАP  is excellent `
          " Condensed sentence
          condensedSentance = condense( sentence )
          " Total no of spaces + 1 equals to total no of words
          totalNoOfWords = count( val = condensedSentance sub = ` ` ) + 1
      " Filling the base table with Total no of words
      IN BASE VALUE string_table( ( |Number of Words: { totalNoOfWords }| ) )
        " Looping words to find individual words unique character count
        FOR wordNo = 1 UNTIL wordNo > totalNoOfWords
            LET word = segment( val = condensedSentance index = wordNo sep = ` ` )
                uniqueChars = VALUE string_table(
      " Grouping characters -> group will auto sort and find the unique records
                  FOR GROUPS charGrp OF char IN VALUE string_table(
     " For filling character table to group it in the above statement
                    FOR charPos = 0 UNTIL charPos = strlen( word ) ( word+charPos(1) ) )
       " filling the character table with unique chars resulted after grouping
                  GROUP BY char ( charGrp ) )
                  " Filling the string table for showing the ouput
            IN ( |Number of unique characters in the word: { word } - { lines( uniqueChars ) }| ) ) ).

 

So at the end of this challenge, I learned a lot about the usage of Regex, string functions & many new ABAP syntaxes.

I felt very confident after doing this challenge and later I even answered some questions related to Regex, string functions & new ABAP syntax 🙂 . But still, there is so much to learn, for e.g., check this awesome solution from Sandra Rossi, I was like (Mind = Blown), and took so much time to understand that 😀

https://answers.sap.com/questions/13058395/add-a-check-or-continue-in-a-for-loop-expression.html

 

Though I was using new ABAP in my projects from long back, this challenge made me explore more possibilities with the new ABAP syntax (especially because I tried to solve this challenge in one line). I would surely have not explored all these if I would have not tried a One-Liner Solution and most importantly the fun I had doing this n:)

I also had fun doing the coding challenge #2, maybe I will share it in another blog post 🙂

 

That’s it folks and thanks for reading this 🙂

 

-Mahesh

2 Comments
You must be Logged on to comment or reply to a post.
    • Thanks Gaurav and to be frank, it was a bit difficult for me also to understand some of these while I was copy pasting from the mail to write this post 😝. Good that I have provided comments initially itself..