Skip to Content
Personal Insights
Author's profile photo Jörgen Lindqvist

Puzzles in ABAP – Starting with FizzBuzz

Hi!

ABAP is an awesome programming language, and there are often many ways to get to the same end result. But as humans, we tend to stick to habits and do the same things in the same ways as always unless we consciously tries new ways. Hopefully these ways are good, but in order to improve and evaluate we need to be challenged or challenge our ideas.

One way to try new things, to experiment, and to expand and learn, is to write one or a couple of solutions to a non-work-related programming challenge. No matter if you’re a novice to ABAP and programming or if you’ve got 30 years under your belt, you could either try to solve it at all, or in some new and obscure way.

Doing it non-work-related might release us from the constraints of requirements, guidelines, habits and routines. But hopefully it will give a positive ROI on our knowledge and will hopefully bring back value to ourselves and our employers and customers.

 

Sharing is caring

Sharing the solutions could also bring value and knowledge to fellow developers. I started a repository where I intend to collect puzzles and create demo example solutions using the various aspects of the ABAP language, and I welcome you all to join! Either by sharing puzzles or challenges that you deem fit here, or by proposing alternate solutions or comments.

The link to the repository is at the end of this post but if you would like to try it out yourselves first, without being influenced by other solutions, wait a bit until clicking that link.

 

FizzBuzz

This one is a very simple one and can be done in various ways and searching on the forum here reveals a couple of blog posts talking about it already. (For instance The SAP Technical ABAP Interview Question You Might Have Never Heard Of from as late as august of last year). I think this is bigger outside of the ABAP world that inside.

Fizz Buzz is allegedly originally a childrens game to practice division, with some simple rules.
The first player starts by saying the number 1 and players then take turn counting upwards one number at a time, but:

  • If a number is evenly divisable by 3, the player instead says ‘Fuzz’
  • If a number is evenly divisable by 5, the player instead says ‘Buzz’
  • If a number is evenly divisable by both 3 and 5, the player says ‘FizzBuzz’

So, it would start like this:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, Buzz, Fizz, 22, 23, Fizz

The challenge here is to implement this in ABAP to output the first 100 rounds of the FizzBuzz game.

Have fun!

 

And then there was the repository

I will get back to you with more puzzles in the future if you think you’d enjoy that. The central place for them will be this repository on GitHub. Currently there is only FizzBuzz with a couple of example solutions with various degrees of ‘goodness’. 😁

 

And please share your interesting solutions here in the comments or in the repository. I will gladly have additional alternate solutions added to the fizzbuzz class there (with explanations if needed). Either by a pull request, or by asking me to do it.

Assigned Tags

      14 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo S Abinath
      S Abinath

      nice info

      Author's profile photo Jorge Augusto Portilla Garcia
      Jorge Augusto Portilla Garcia

      Hi Jörgen Lindqvist,

      I accepted your "FizzBuzz" challenge today, and I used the latest ABAP trial for this:

      Get latest version of ABAP trial using BTP

      Here, I share my approach:

      CLASS zcl_fizzbuzz DEFINITION
        PUBLIC
        FINAL
        CREATE PUBLIC.
      
        PUBLIC SECTION.
          INTERFACES if_oo_adt_classrun.
          METHODS: thinking IMPORTING iv_num             TYPE int2
                            RETURNING VALUE(rv_res_word) TYPE string.
      
        PROTECTED SECTION.
        PRIVATE SECTION.
          METHODS: divider_exam IMPORTING iv_num         TYPE int2
                                RETURNING VALUE(rv_word) TYPE string,
            is_three_divider IMPORTING iV_num          TYPE int2
                             RETURNING VALUE(rv_three) TYPE string,
            is_five_divider  IMPORTING iV_num         TYPE int2
                             RETURNING VALUE(rv_five) TYPE string.
      ENDCLASS.
      
      CLASS zcl_fizzbuzz IMPLEMENTATION.
        METHOD if_oo_adt_classrun~main.
      
          DATA lv_count TYPE int2 VALUE 1.
      
          DO 100 TIMES.
            out->write( thinking( lv_count ) ).
            lv_count += 1.
          ENDDO.
        ENDMETHOD.
      
        METHOD is_three_divider.
          DATA(lv_mod) = iV_num MOD 3.
          IF lv_mod EQ 0.
            rv_three = 'Fizz'.
          ENDIF.
        ENDMETHOD.
      
        METHOD is_five_divider.
          DATA(lv_mod) = iV_num MOD 5.
          IF lv_mod EQ 0.
            rv_five = 'Buzz'.
          ENDIF.
        ENDMETHOD.
      
        METHOD divider_exam.
          rv_word = is_three_divider( iv_num ) && is_five_divider( iv_num ).
        ENDMETHOD.
      
        METHOD thinking.
          DATA(lv_result) = divider_exam( iv_num ).
          IF lv_result IS NOT INITIAL.
            rv_res_word = lv_result.
          ELSE.
            rv_res_word = iv_num.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      

      The output looks just like this:

      Author's profile photo Jörgen Lindqvist
      Jörgen Lindqvist
      Blog Post Author

      Thank you! I'm glad you shared your solution.

      Clever with the string concatenation there in the divider_exam method...

      Hope you had fun!

      Author's profile photo Jorge Augusto Portilla Garcia
      Jorge Augusto Portilla Garcia

      You're welcome. It was fun!

      Author's profile photo Martin Coetzee
      Martin Coetzee

      Hi Jörgen,

      I gave this a try, also trying to keep the code minimal. So this is what I came up with:

      REPORT zmc_test_fizzbuzz.
      
      DO 100 TIMES.
        IF sy-index MOD 3 = 0 AND sy-index MOD 5 = 0 .
          WRITE: `FizzBuzz` .
        ELSEIF sy-index MOD 3 = 0 .
          WRITE: `Fizz` .
        ELSEIF sy-index MOD 5 = 0 .
          WRITE: `Buzz` .
        ELSE .
          WRITE: sy-index .
        ENDIF.
        WRITE: `,` .
      ENDDO.

      Output:

      Fizzbuzz

      Regards, Martin.

      Author's profile photo Jörgen Lindqvist
      Jörgen Lindqvist
      Blog Post Author

      I'm happy you tried it, and thanks for sharing!

      Author's profile photo Ron Mitton
      Ron Mitton

      Hi Jorgen

      I modified Martin's solution a little:

      REPORT zfizzbuzz.
      
      do 100 times.
        data(output_string) = cond #( when sy-index mod 3 = 0 and sy-index mod 5 = 0 then 'FizzBuzz'
                                      when sy-index mod 3 = 0 then 'Fizz'
                                      when sy-index mod 5 = 0 then 'Buzz'
                                      else sy-index ).
        write / output_string.
       enddo.

       

      Author's profile photo Jörgen Lindqvist
      Jörgen Lindqvist
      Blog Post Author

      Thank you for another share! Please also have a look in the repository I linked for a couple of other solutions... 🙂

      Author's profile photo Martin Coetzee
      Martin Coetzee

      In fact I shaved off another few lines by doing it like this:

      DO 100 TIMES.
        WRITE: COND #( WHEN sy-index MOD 3 = 0 AND sy-index MOD 5 = 0 THEN 'FizzBuzz'
                                      WHEN sy-index MOD 3 = 0 THEN 'Fizz'
                                      WHEN sy-index MOD 5 = 0 THEN 'Buzz'
                                      ELSE sy-index ) && `,` .
      ENDDO.
      Author's profile photo Martin Coetzee
      Martin Coetzee

      Gave the same output as below.

      Author's profile photo Ron Mitton
      Ron Mitton

      Nice

      Author's profile photo Martin Coetzee
      Martin Coetzee

      I really like this modification. You're just missing the comma in the output to separate the items. 🙂

       

      DO 100 TIMES.
        DATA(output_string) = COND #( WHEN sy-index MOD 3 = 0 AND sy-index MOD 5 = 0 THEN 'FizzBuzz'
                                      WHEN sy-index MOD 3 = 0 THEN 'Fizz'
                                      WHEN sy-index MOD 5 = 0 THEN 'Buzz'
                                      ELSE sy-index ) && `,` .
        WRITE output_string.
      ENDDO.

      Which gives this output:

      Fizzbuzz

      Fizzbuzz

      I also remove the '/' so that it writes the items consecutively instead of each one on a new line.

      Author's profile photo Hendrik Neumann
      Hendrik Neumann

      hi Jörgen,

      once again a cool blog!!

      We did run an internal ABAP CodingDojo with some ABAP newbies last year and I published my solutions of various katas in a public Github repo. I solved most on the ABAP cloud environment, hence my namespace Z174_ in front of most objects 😉

      I used TDD with frequent commits, so that one could follow me along reading the commit history. For FizzBuzz the history on Github is a pretty good story. Even though it would have been better to store each kata in it's own package / directory for better readability.

      Loved to see your different solutions on Github and your thoughts about them! Plus it's greate to read the discussion the post sparked!

      Cheers

      Hendrik

       

       

      Author's profile photo Jörgen Lindqvist
      Jörgen Lindqvist
      Blog Post Author

      Thanks Hendrik, I love to share and I hope I inspire or teach at least something to someone...

      And also a good repository you have with other puzzles and test classes as well. I will probably peek back there later on for more inspiration myself... 🙂