Coder Social home page Coder Social logo

abap's Introduction

Exercism ABAP Track

configlet test

Exercism exercises in ABAP

This is the ABAP track, one of the many tracks on Exercism. It holds all the exercises that are currently implemented and available for students to complete. The track consists of various various practice exercises which you can find in the config.json.

Exercises for Students

With exercism, you can solve and test all exercises directly on the Exercism website.

Alternatively, you can clone this repository to your own SAP system using abapGit. Solve the exercises in your system and bring the solution back to the website.

For details, see Testing on the ABAP track

Contributing to the Track

We welcome contributions of all sorts and sizes, from reporting issues to submitting patches, or added complete new exercises.

For details, see Contribution Guidelines.

Testing

To test the exercises, run ./bin/test. This command will iterate over all exercises and check to see if their exemplar/example implementation passes all the tests.

Track Linting

configlet is an Exercism-wide tool for working with tracks. You can download it by running:

$ ./bin/fetch-configlet

Run its lint command to verify if all exercises have all the necessary files and if config files are correct:

$ ./bin/configlet lint

The lint command is under development.
Please re-run this command regularly to see if your track passes the latest linting rules.

Basic linting finished successfully:
- config.json exists and is valid JSON
- config.json has these valid fields:
    language, slug, active, blurb, version, status, online_editor, key_features, tags
- Every concept has the required .md files
- Every concept has a valid links.json file
- Every concept has a valid .meta/config.json file
- Every concept exercise has the required .md files
- Every concept exercise has a valid .meta/config.json file
- Every practice exercise has the required .md files
- Every practice exercise has a valid .meta/config.json file
- Required track docs are present
- Required shared exercise docs are present

abap's People

Contributors

ajborla avatar bau-mann avatar bnandras avatar dem4ron avatar dependabot[bot] avatar dwivedirahul44 avatar ee7 avatar erikschierboom avatar exercism-bot avatar faisalafroz avatar g-back avatar kytrinyx avatar larshp avatar marianfoo avatar mbtools avatar pokrakam avatar rich-heilman avatar schmelto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

abap's Issues

Prime Factors - The inline function frac( ) is not interpreted correctly

While developing the solution for the exercise, I noticed that when I used the frac( ) function, the result was not correct when extracting the decimal part of a decfloat34 variable.

Here is the first version of the full code I'm trying, which is not passing the unit testing on the platform:

CLASS zcl_prime_factors DEFINITION PUBLIC FINAL CREATE PUBLIC .
  PUBLIC SECTION.
    TYPES integertab TYPE STANDARD TABLE OF i WITH EMPTY KEY.
    METHODS factors
      IMPORTING
        input         TYPE int8
      RETURNING
        VALUE(result) TYPE integertab.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_prime_factors IMPLEMENTATION.
  METHOD factors.
    DATA(lv_number) = input.
    DATA(lv_factor) = 2.
    WHILE lv_number <> 1.
      DATA(lv_result) = CONV decfloat34( lv_number / lv_factor ).
      IF frac( CONV decfloat34( lv_number / lv_factor ) ) = 0.
        lv_number = lv_number / lv_factor.
        INSERT lv_factor INTO TABLE result.
        CONTINUE.
      ENDIF.
      lv_factor = lv_factor + 1.
    ENDWHILE.
  ENDMETHOD.
ENDCLASS.

If I replace the frac( ) line with a classic MOD, it works correctly.

*      IF frac( CONV decfloat34( lv_number / lv_factor ) ) = 0.
      IF lv_number MOD lv_factor = 0.

I have found that if I split the statement into two parts, frac() still fails:

*      IF frac( CONV decfloat34( lv_number / lv_factor ) ) = 0.
      DATA(lv_result) = CONV decfloat34( lv_number / lv_factor ).
      IF frac( lv_result ) = 0.

Either code variant passes the tests in a Netweaver 7.4 system.

Clock - Unspecified error but it works on NW ABAP

When I run the tests for my solution it ends without specifying the error:

image

The solution tests fine in a Netweaver 7.4 system.

Here is the code I'm trying:

CLASS zcl_clock DEFINITION PUBLIC CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        !hours   TYPE i
        !minutes TYPE i DEFAULT 0.
    METHODS get
      RETURNING
        VALUE(result) TYPE string.
    METHODS add
      IMPORTING
        !minutes TYPE i.
    METHODS sub
      IMPORTING
        !minutes TYPE i.

  PRIVATE SECTION.
    TYPES:
      BEGIN OF type_s_time,
        hours   TYPE i,
        minutes TYPE i,
      END OF type_s_time.

    DATA _time TYPE i.

    METHODS:
      _convert_in
        IMPORTING
          is_time        TYPE type_s_time
        RETURNING
          VALUE(rv_time) TYPE i,
      _convert_out
        IMPORTING
          iv_time        TYPE i
        RETURNING
          VALUE(rs_time) TYPE type_s_time.

ENDCLASS.

CLASS zcl_clock IMPLEMENTATION.
  METHOD add.
    _time = _convert_in( VALUE #( minutes = _time + minutes ) ).
  ENDMETHOD.

  METHOD constructor.
    _time = _convert_in( VALUE #( hours   = hours
                                  minutes = minutes ) ).
  ENDMETHOD.

  METHOD get.
    DATA(ls_time) = _convert_out( _time ).
    result = |{ ls_time-hours PAD = '0' WIDTH = 2 ALIGN = RIGHT }:{ ls_time-minutes PAD = '0' WIDTH = 2 ALIGN = RIGHT }|.
  ENDMETHOD.

  METHOD sub.
    _time = _convert_in( VALUE #( minutes = _time - minutes ) ).
  ENDMETHOD.

  METHOD _convert_in.
    DATA(ls_time) = is_time.

    IF ls_time-hours < 0.
      ls_time-hours = 24 + frac( CONV decfloat34( ls_time-hours / 24 ) ) * 24.
    ENDIF.

    IF ls_time-minutes < 0.
      ls_time-minutes = 1440 + frac( CONV decfloat34( ls_time-minutes / 1440 ) ) * 1440.
    ENDIF.

    rv_time = CONV decfloat34( frac( ( ls_time-hours * 60 + ls_time-minutes ) / 1440 ) ) * 1440.
  ENDMETHOD.

  METHOD _convert_out.
    rs_time-hours   = trunc( CONV decfloat34( iv_time / 60 ) ).
    rs_time-minutes = CONV decfloat34( frac( iv_time / 60 ) ) * 60.
  ENDMETHOD.
ENDCLASS.

Scrabble Score - Error in ABAPopen but not in ABAP Backend

This might be the same or a similar issue to #68 because I'm using a similar FOR loop and COND switch.
The solution tests fine in an ABAP backend system (ABAP Cloud Trial)
image

But the same in the Exercism Web Editor/Solution Validator says the statement doesn't exist in ABAPopen-abap
image

Here is the code of the solution I'm trying

    result =
  REDUCE string( INIT s = 0
                 FOR  i = 0 WHILE i < strlen( input )
                 NEXT s += COND i( LET current_val = to_upper( input+i(1) ) IN
                 WHEN contains( val = 'AEIOULNRST' sub = current_val ) THEN 1
                 WHEN contains( val = 'DG' sub = current_val ) THEN 2
                 WHEN contains( val = 'BCMP' sub = current_val ) THEN 3
                 WHEN contains( val = 'FHVWY' sub = current_val ) THEN 4
                 WHEN contains( val = 'K' sub = current_val ) THEN 5
                 WHEN contains( val = 'JX' sub = current_val ) THEN 8
                 WHEN contains( val = 'QZ' sub = current_val ) THEN 10
                 ELSE 0
                 ) ).

Kindergarten Garden: Constructor Expression REDUCE with multiple FOR not working

Hi everybody,

I'm working on making my Kindergarten Garden solution more flexible (in case the kindergarten allows more plants per kid per row or gets new windowsills and has more than two rows).

I set up a trial account with account.hana.ondemand.com to have an ABAP instance available. Unfortunately, I couldn't find out the NetWeaver or ABAP version used, because there is no SAP GUI available for me. Just an Eclipse/ADT connection.
There, I set up the kindergarten class including all test cases from the exercise.
All tests pass.

In exercism all tests fail with either:

TEST_GARDEN_SINGLE_STUDENT

TEST FAILURE

Expected table to contain '4' rows , got '1'

or:

TEST_GARDEN_THIRD_STUDENTS

TEST FAILURE

Some exception raised

Here is my source code:

CLASS zcl_kindergarten_garden DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS constructor.
    METHODS plants
      IMPORTING
        diagram        TYPE string
        student        TYPE string
      RETURNING
        VALUE(results) TYPE string_table.

  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA students TYPE string_table.

    METHODS get_plant_name
      IMPORTING code              TYPE c
      RETURNING VALUE(plant_name) TYPE string.
    DATA gv_code TYPE c.
    DATA gv_students TYPE string_table.
    DATA gv_plant_amount TYPE i.
ENDCLASS.


CLASS zcl_kindergarten_garden IMPLEMENTATION.
 METHOD constructor.
    gv_students = VALUE #( ( |Alice| ) ( |Bob| ) ( |Charlie| ) ( |David| ) ( |Eve| ) ( |Fred| )
                    ( |Ginny| ) ( |Harriet| ) ( |Ileana| ) ( |Joseph| ) ( |Kincaid| ) ( |Larry| ) ).
    gv_plant_amount = 2.
  ENDMETHOD.

  METHOD get_plant_name.
    gv_code = code.
    TRANSLATE gv_code TO UPPER CASE.
    plant_name = SWITCH #( gv_code WHEN 'V' THEN 'violets'
                                WHEN 'R' THEN 'radishes'
                                WHEN 'C' THEN 'clover'
                                WHEN 'G' THEN 'grass'
                          ).
  ENDMETHOD.

  METHOD plants.
    SPLIT diagram AT '\n' INTO TABLE DATA(window_rows).
    DATA(offset) = ( line_index( gv_students[ table_line = student ] ) - 1 ) * 2.
    results = REDUCE string_table( INIT s = VALUE string_table( )
                                   FOR r IN window_rows
                                   FOR p = 0 WHILE p < gv_plant_amount
                                   NEXT s = VALUE string_table(
                                          BASE s
                                          ( get_plant_name( substring( val = r off = offset + p len = 1 ) ) )
                                  )
              ).

  ENDMETHOD.
ENDCLASS.

The documentation says multiple FOR expressions are possible: REDUCE - Reduction Operator

To show where I changed things and for reference what already works: This is an older version, where kids could only have two plants per row. It passes all tests on exercism:

    results = REDUCE string_table( init s = VALUE string_table( )
                        for r in window_rows
                        next s = VALUE #(
                                          BASE s
                                          ( get_plant_name( substring( val = r off = offset len = 1 ) ) )
                                          ( get_plant_name( substring( val = r off = offset + 1 len = 1 ) ) )
                                        )
                      ).

I've got a wonderful mentor, who suggested to open an issue here.
Hopefully, I managed to include all information needed to look into this issue. If something is missing, please let me know. I'll be happy to help.

Hopefully you can solve this issue.

Thank you all for the wonderful exercises to learn more about ABAP.

Error in "High Scores" -> Could not resolve top CL_ABAP_ITAB_UTILITIES, resolveTypeChain (unknown_types)

When trying to run the tests for the below code

  private section.
    data SCORES_LIST type INTEGERTAB.

    methods GET_TOP_SCORE_UPTO
      importing
        HITS            type I
      returning
        value(R_RESULT) type ZCL_HIGH_SCORES=>INTEGERTAB.
...
  method PERSONALBEST.
    check SCORES_LIST is not initial.
    data(TOP_SCORES) = GET_TOP_SCORE_UPTO( 1 ).
    RESULT = TOP_SCORES[ 1 ].
  endmethod.

  method PERSONALTOPTHREE.
    RESULT = GET_TOP_SCORE_UPTO( 3 ).
  endmethod.

  method GET_TOP_SCORE_UPTO.
    data SORTED_INDICES type CL_ABAP_ITAB_UTILITIES=>VIRTUAL_SORT_INDEX.
    SORTED_INDICES  = CL_ABAP_ITAB_UTILITIES=>VIRTUAL_SORT(
                          IM_VIRTUAL_SOURCE = value #( ( SOURCE     = ref #( SCORES_LIST )
                                                         COMPONENTS = value #( ( NAME       = |TABLE_LINE|
                                                                                 DESCENDING = 'X' ) ) ) ) ).

    R_RESULT = value #( for INDEX in SORTED_INDICES to HITS
                        ( SCORES_LIST[ INDEX ] ) ).
  endmethod.

i am getting the following error:
image

I want to sort the attribute SCORES_LIST virtually, since i want to preserve the order of the constructor input SCORES.

Nth Prime - sy-tabix value is wrongly determined

When I run the test for my solution it ends with two unit tests failing:

image

But it works fine on a NW 7.4 system.
Here is the code I'm trying:

CLASS zcl_nth_prime DEFINITION FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS:
      constructor,
      prime
        IMPORTING
          input         TYPE i
        RETURNING
          VALUE(result) TYPE i
        RAISING
          cx_parameter_invalid.

  PRIVATE SECTION.
    TYPES:
      type_t_prime TYPE STANDARD TABLE OF abap_bool WITH NON-UNIQUE DEFAULT KEY.

    DATA:
      _primes TYPE type_t_prime.

    METHODS:
      _calc_primes
        IMPORTING
          iv_limit         TYPE i
        RETURNING
          VALUE(rt_primes) TYPE type_t_prime.

ENDCLASS.

CLASS zcl_nth_prime IMPLEMENTATION.
  METHOD constructor.
    _primes = _calc_primes( 151 ).
  ENDMETHOD.

  METHOD prime.
    IF input < 1.
      RAISE EXCEPTION TYPE cx_parameter_invalid.
    ENDIF.

    DATA(lv_count) = 0.
    LOOP AT _primes ASSIGNING FIELD-SYMBOL(<lv_prime>).
      IF <lv_prime> = abap_true.
        lv_count = lv_count + 1.
      ENDIF.
      IF lv_count = input.
        result = sy-tabix.
        RETURN.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD _calc_primes.
    DO iv_limit TIMES.
      IF sy-index > 1.
        INSERT abap_true INTO TABLE rt_primes.
      ELSE.
        INSERT abap_false INTO TABLE rt_primes.
      ENDIF.
    ENDDO.

    DATA(lv_number) =  2.
    WHILE ( lv_number <= trunc( sqrt( iv_limit ) ) ).
      IF ( rt_primes[ lv_number ] = abap_true ).
        DATA(lv_non_primer_number) = lv_number ** 2.
        WHILE ( lv_non_primer_number <= iv_limit ).
          rt_primes[ lv_non_primer_number ] = abap_false.
          lv_non_primer_number = ( lv_number ** 2 ) + ( sy-index * lv_number ).
        ENDWHILE.
      ENDIF.
      lv_number = lv_number + 1.
    ENDWHILE.
  ENDMETHOD.
ENDCLASS.

It seems that the sy-tabix value used in prime method is not working as expected.

Error occurred in "Scrabble Score"

check INPUT is not initial.
    RESULT = COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[AEIOULNRST]` )
             + 2 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[DG]` )
             + 3 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[BCMP]` )
             + 4 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[FHVWY]` )
             + 5 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[K]` )
             + 8 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[JX]` )
             + 10 * COUNT( VAL = INPUT CASE = ABAP_FALSE REGEX = `[QZ]` ).

I am getting an error when trying to run the tests for the above solution to the "Scrabble Score". If i understand correctly ABAP version 754 is recommended.

The above code compiles correctly on my ABAP system

Error occured in Exercise "KINDERGARTEN"

It runs without issues on my SAP system but fails in exercism editor with following errors:

We received the following error when we ran your code:
./zcl_kindergarten_garden.clas.abap[45, 9] - Statement does not exist in ABAPopen-abap(or a parser error), "temp4" (parser_error) [E]
abaplint: 1 issue(s) found

Here is my code:

CLASS zcl_kindergarten_garden DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .
  PUBLIC SECTION.
    METHODS plants
      IMPORTING
        diagram        TYPE string
        student        TYPE string
      RETURNING
        VALUE(results) TYPE string_table.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA students TYPE string_table.
ENDCLASS.
CLASS zcl_kindergarten_garden IMPLEMENTATION.
  METHOD plants.
    SPLIT diagram AT `\n` INTO TABLE DATA(lt_plants).
    DATA(lv_first_pos) = COND i( WHEN sy-abcde CS student+0(1) THEN sy-fdpos * 2 ).
    DO 2 TIMES.
      APPEND LINES OF VALUE string_table(
        FOR i = 0 UNTIL i = 2 (
         SWITCH #( substring( val = lt_plants[ sy-index ] off = lv_first_pos + i len = 1 )
          WHEN 'C' THEN 'clover'
          WHEN 'G' THEN 'grass'
          WHEN 'R' THEN 'radishes'
          WHEN 'V' THEN 'violets' ) ) ) TO results.
    ENDDO.
  ENDMETHOD.
ENDCLASS.

REDUCE with nested FOR returns a wrong answer

In 'scrabble score' exercise I use REDUCE expression with a nested for but it acts as if the second FOR and WHERE condition is not there, collects all the values in first FOR. Code below works in my local S4 system but not in exercism.

CLASS zcl_scrabble_score DEFINITION PUBLIC .

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_letter_value,
             letter(1) TYPE c,
             value     TYPE i,
           END OF ty_letter_value.

    DATA: letter_values TYPE TABLE OF ty_letter_value.

    METHODS constructor.
    METHODS score
      IMPORTING
        input         TYPE string OPTIONAL
      RETURNING
        VALUE(result) TYPE i.

  PROTECTED SECTION.
  PRIVATE SECTION.

ENDCLASS.


CLASS zcl_scrabble_score IMPLEMENTATION.
  METHOD constructor.
    letter_values = VALUE #(
        ( letter = 'A' value = 1 )
        ( letter = 'E' value = 1 )
        ( letter = 'I' value = 1 )
        ( letter = 'O' value = 1 )
        ( letter = 'U' value = 1 )
        ( letter = 'L' value = 1 )
        ( letter = 'N' value = 1 )
        ( letter = 'R' value = 1 )
        ( letter = 'S' value = 1 )
        ( letter = 'T' value = 1 )
        ( letter = 'D' value = 2 )
        ( letter = 'G' value = 2 )
        ( letter = 'B' value = 3 )
        ( letter = 'C' value = 3 )
        ( letter = 'M' value = 3 )
        ( letter = 'P' value = 3 )
        ( letter = 'F' value = 4 )
        ( letter = 'H' value = 4 )
        ( letter = 'V' value = 4 )
        ( letter = 'W' value = 4 )
        ( letter = 'Y' value = 4 )
        ( letter = 'K' value = 5 )
        ( letter = 'J' value = 8 )
        ( letter = 'X' value = 8 )
        ( letter = 'Q' value = 10 )
        ( letter = 'Z' value = 10 ) ).
  ENDMETHOD.

  METHOD score.
    DATA: char_list    TYPE table OF c,
          string       TYPE string.

    string = input.
    TRANSLATE string TO UPPER CASE .

    DO strlen( string ) TIMES.
      APPEND INITIAL LINE TO char_list ASSIGNING FIELD-SYMBOL(<c>).
      DATA(lv_index) = sy-tabix - 1.
      <c> = string+lv_index(1).
    ENDDO.

    result = REDUCE i( INIT x = 0 FOR letter_value IN letter_values
                                  FOR char IN char_list WHERE ( table_line = letter_value-letter )
                       NEXT x = x + letter_value-value ).
  ENDMETHOD.
ENDCLASS.

mod for negative number

Thanks for sharing 
it looks like in mod returns negative number js
but in abap is positive number

" 23 - in a real SAP system
data mv_minutes TYPE i VALUE -30.
write conv num2( mv_minutes div 60 mod 24 ).

" -1 - in exercism by JS emulation
TYPES num2 TYPE n LENGTH 2.
data mv_minutes TYPE i VALUE -30.
write conv num2( mv_minutes div 60 mod 24 ).

found difference in the example 

https://exercism.org/tracks/abap/exercises/clock

js
https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers

in real SAP system all test are passed

CLASS zcl_clock_314 DEFINITION
  PUBLIC
  CREATE PUBLIC.

  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !hours   TYPE i
        !minutes TYPE i DEFAULT 0.

    METHODS get
      RETURNING
        VALUE(result) TYPE string.
    METHODS add
      IMPORTING
        !minutes TYPE i.
    METHODS sub
      IMPORTING
        !minutes TYPE i.

  PRIVATE SECTION.

    DATA mv_minutes TYPE i.

ENDCLASS.



CLASS zcl_clock_314 IMPLEMENTATION.

  METHOD constructor.
    mv_minutes = ( cond #( when hours >= 0 then hours ELSE 24 + hours ) mod 24 ) * 60 + minutes.
  ENDMETHOD.

  METHOD add.
    ADD minutes TO mv_minutes.
  ENDMETHOD.

  METHOD sub.
    SUBTRACT minutes FROM mv_minutes.
  ENDMETHOD.

  METHOD get.
    TYPES num2 TYPE n LENGTH 2.
    result = conv num2( mv_minutes div 60 mod 24 ) && ':' && conv num2( mv_minutes mod 60 ).
  ENDMETHOD.
ENDCLASS.

Error in Kindergarten Garden: nested FOR expression

When trying to run the tests for the below code

  METHOD plants.
    SPLIT condense( replace(
                        val  = diagram
                        sub  = `\n`
                        with = ` `
                        occ  = 0 ) ) AT ` ` INTO TABLE DATA(garden_rows).

    DATA(student_id) = line_index( students[ table_line = to_lower( student ) ] ) - 1.

    results = VALUE #(
                FOR row IN garden_rows
                FOR seed = 0 WHILE seed <= 1
                LET offset = ( student_id * 2 ) + seed IN
                ( SWITCH #( row+offset(1)
                    WHEN 'G' THEN 'grass'
                    WHEN 'C' THEN 'clover'
                    WHEN 'R' THEN 'radishes'
                    WHEN 'V' THEN 'violets' ) ) ).  
  ENDMETHOD.

i am getting the following error
image

Built-in functions SUBSTRING and REPLACE don't throw CX_SY_RANGE_OUT_OF_BOUNDS

While working on the Minesweeper exercise i noticed, that instead of throwing the expected exception, replace just adds to the string, when the offset is out of bounds. Substring seems to ignore it.
Below is the code i was running:

CLASS zcl_minesweeper DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.

    METHODS annotate
        IMPORTING
          !input        TYPE string_table
        RETURNING
          VALUE(result) TYPE string_table.
   PRIVATE SECTION.

ENDCLASS.

CLASS zcl_minesweeper IMPLEMENTATION.

  METHOD annotate.
    FIELD-SYMBOLS <other_line> TYPE string.
    FIELD-SYMBOLS <current_line> TYPE string.
    result = input.
*   Working from each mine outwards - adding 1 to each adjacent field that is not a mine
    LOOP AT result ASSIGNING <current_line>.
      CHECK <current_line> CA '*'.
      DATA(current_row) = sy-tabix.
*     start one row up
      DO strlen( <current_line> ) TIMES.
        DATA(row) = current_row - 1.
        DATA(current_off) = sy-index - 1.
        CHECK substring( val = <current_line> off = current_off len = 1 ) EQ '*'.
        DO 3 TIMES.  
*         for each row, start one character to the left from current
          DATA(off) = current_off - 1.
*         "one row up, same row and one row down - if row exists
          READ TABLE result INDEX row ASSIGNING <other_line>.
          IF sy-subrc EQ 0.
            DO 3 TIMES.
*             except current character
              IF row NE current_row OR off NE current_off.
*               check bounds by catching exception
                try.            
*                 Expecting to throw exception, when offset out of bounds. 
                    DATA(current_field) = substring( val = <other_line> off = off len = 1 ).                       "<<<<<
                    IF current_field NE '*'.
                      DATA(cn_mines) = CONV i( substring( val = <other_line> off = off len = 1 ) ).                "<<<<<
                      cn_mines = cn_mines + 1.
                      <other_line> = replace( val = <other_line> off = off len = 1 with = |{ cn_mines }| ).        "<<<<<
                    ENDIF.
                catch CX_SY_RANGE_OUT_OF_BOUNDS.  
*                  out of bounds - nothing to do
                endtry.
              ENDIF.
              off = off + 1.
            ENDDO.
          ENDIF.
*         row does not exist - try the next
          row = row + 1.
        ENDDO.
      ENDDO.
    ENDLOOP.
  ENDMETHOD.

ENDCLASS.

High_scores - tests 4 to 8 fail for PERSONALTOPTHREE but pass in NW system

The below code passes tests 1 to 3 but fails 4 to 8 in Exercism even though it passes all tests when run in a NW 7.50 system and the logic looks fine (even if not "elegant"!) when I check it there in the debugger. Only the code in personaltopthree is relevant for this issue as far as I can tell.
grafik

The error message in EXERCISM is also a bit weird: "Expected table to contain '3' rows , got '0'" as if RESULT is empty even though I see in the debugger that the internal table gets filled properly and also contains the entries in the expected sequence, i.e. ACT and EXP are the same.

CLASS zcl_high_scores DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    TYPES integertab TYPE STANDARD TABLE OF i WITH EMPTY KEY.
    METHODS constructor
      IMPORTING
        scores TYPE integertab.

    METHODS list_scores
      RETURNING
        VALUE(result) TYPE integertab.

    METHODS latest
      RETURNING
        VALUE(result) TYPE i.

    METHODS personalbest
      RETURNING
        VALUE(result) TYPE i.

    METHODS personaltopthree
      RETURNING
        VALUE(result) TYPE integertab.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA scores_list TYPE integertab.

ENDCLASS.

CLASS zcl_high_scores IMPLEMENTATION.

  METHOD constructor.
    me->scores_list = scores.
  ENDMETHOD.

  METHOD list_scores.
    result = scores_list.
  ENDMETHOD.

  METHOD latest.
    loop at scores_list into data(score).
      result = score.
    endloop.
  ENDMETHOD.

  METHOD personalbest.
    loop at scores_list into data(score).
      if score GT result.
        result = score.
      endif.
    endloop.
  ENDMETHOD.

  METHOD personaltopthree.
    data: no_1 type i,
          no_2 type i,
          no_3 type i,
          cnt_scores type i.

    describe table scores_list lines cnt_scores.

    LOOP AT scores_list INTO DATA(score).

      IF score GE no_1.
        no_3 = no_2.
        no_2 = no_1.
        no_1 = score.
      elseIF score GE no_2 AND
             score LT no_1.
        no_3 = no_2.
        no_2 = score.
      elseIF score GE no_3 AND
             score LT no_1 AND
             score LT no_2.
        no_3 = score.
      endif.

    ENDLOOP.

    IF cnt_scores GE 1.
      append no_1 to result.
    ENDIF.

    IF cnt_scores GE 2.
      append no_2 to result.
    ENDIF.

    IF  cnt_scores GE 3.
      APPEND no_3 to result.
    ENDIF.

  ENDMETHOD.

ENDCLASS.

Atbash Cipher: 3 tests raise exception in exercism but pass in an sap system

Hi everybody,

I'm working on the atbash cipher.

I set up a trial account with account.hana.ondemand.com to have an ABAP instance available. Unfortunately, I couldn't find out the NetWeaver or ABAP version used, because there is no SAP GUI available for me. Just an Eclipse/ADT connection.
There, I set up the atbash cipher class including all test cases from the exercise.
All tests pass.

In exercism the tests encode6, encode7 and encode8 fail. All three with the same message:

FAILED

Test 6

ENCODE6

TEST FAILURE

Some exception raised

Here is my source code:

CLASS zcl_atbash_cipher DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS decode
      IMPORTING
        cipher_text TYPE string
      RETURNING
        VALUE(plain_text)  TYPE string .

METHODS encode
      IMPORTING
        plain_text        TYPE string
      RETURNING
        VALUE(cipher_text) TYPE string .

    METHODS constructor.
  PROTECTED SECTION.
  PRIVATE SECTION.
    Data plain type string.
    data cipher type string.
    METHODS translate
      IMPORTING
        original           TYPE string
      RETURNING
        VALUE(translation) TYPE string    .
ENDCLASS.



CLASS zcl_atbash_cipher IMPLEMENTATION.
  method constructor.
    plain  = |abcdefghijklmnopqrstuvwxyz0123456789|.
    cipher = |zyxwvutsrqponmlkjihgfedcba0123456789|.
  endmethod.

 METHOD decode.
    DATA(t) = cipher_text.
    CONDENSE t NO-GAPS.
    plain_text = translate( t ).
  ENDMETHOD.

  METHOD encode.
    DATA(plain_t) = replace( val = plain_text regex = '([[:punct:]])' with = ' ' occ = 0 ).
    CONDENSE plain_t NO-GAPS.
    plain_t = to_lower( plain_t ).
    DATA(cipher_string) = translate( plain_t ).
    cipher_text = condense( replace( val = cipher_string regex = '(.....)' with = `$1 ` occ = 0 ) ).
  ENDMETHOD.

  METHOD translate.
    translation = REDUCE string( INIT s TYPE string
                                  FOR r = 0 WHILE r < strlen( original )
                                  NEXT s = COND string(
                                    LET p = substring( val = original off = r len = 1 )
                                        l = find(  val = plain sub = p )
                                        c = substring( val = cipher off = l len = 1 )
                                        IN
                                        WHEN c NE '' THEN |{ s }{ c }|
                                        ELSE s
                                  )
        ).
  ENDMETHOD.
ENDCLASS.

I can make the tests on exercism pass as well, if I brute force them by adding the following lines of code to the method "encode". But that's no solution, in my humble opinion.

" special treatment for three testcases. The turn green in my abap environment but return "some exception raise" in exercism.org
" for test encode6
    if plain_text eq |Testing,1 2 3, testing.|.
      cipher_text = |gvhgr mt123 gvhgr mt|.
      exit.
" for test encode7
    elseif plain_text eq 'Truth is fiction.' .
      cipher_text = 'gifgs rhurx grlm'.
      exit.
" for test encode8
    elseif plain_text eq 'The quick brown fox jumps over the lazy dog.'.
      cipher_text = 'gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt'.
      exit.
    endif.

Hopefully, I managed to include all information needed to look into this issue. If something is missing, please let me know. I'll be happy to help.

Hopefully you can solve this issue. I'd like to solve the exercise but can't get the tests to go green.

Thank you all for the wonderful exercises to learn more about ABAP.

Beer Song - Error buildCondBody, unexpected expression

I was working through the Beer Song exercise. I built a solution that runs and passes the tests in an ABAP backend system (ABAP on SAP BTP Free Trial).
image

But when I run the same solution in Exercism in the Web Editor I receive the error: Error buildCondBody, unexpected expression
image

Here's the source code that I'm using for this exercise:

    result = VALUE string_table(
      FOR i = 0 UNTIL i = take_down_count
      (
         COND string(
         LET current_count = initial_bottles_count - i
             new_count = current_count - 1
          IN
          WHEN current_count = 1 THEN |{ current_count } bottle of beer on the wall, { current_count } bottle of beer.|
          WHEN new_count <= 0 THEN |No more bottles of beer on the wall, no more bottles of beer.|
          ELSE  |{ current_count } bottles of beer on the wall, { current_count } bottles of beer.|
          )
      )
      (
         COND string(
         LET current_count = initial_bottles_count - i
             new_count = current_count - 1
          IN
          WHEN current_count = 2 THEN |Take one down and pass it around, 1 bottle of beer on the wall.|
          WHEN current_count = 1 THEN |Take it down and pass it around, no more bottles of beer on the wall.|
          WHEN new_count <= 0 THEN |Go to the store and buy some more, 99 bottles of beer on the wall.|
          ELSE |Take one down and pass it around, { new_count } bottles of beer on the wall.|
          )
      )
      ( ||
      )
    ).
    DELETE result INDEX lines( result ).

Unit Test Error in "Resistor Color"

I am getting unit-test errors for the below code:

class ZCL_RESISTOR_COLOR definition public create public.
  public section.
    methods CONSTRUCTOR.
    methods RESISTOR_COLOR
      importing
        COLOR_CODE   type STRING
      returning
        value(VALUE) type I.
  private section.
    data COLOR_CODES type standard table of STRING with empty key.
endclass.

class ZCL_RESISTOR_COLOR implementation.

  method CONSTRUCTOR.
    COLOR_CODES = value #(
      ( |black| )
      ( |brown| )
      ( |red| )
      ( |orange| )
      ( |yellow| )
      ( |green| )
      ( |blue| )
      ( |violet| )
      ( |grey| )
      ( |white| ) ).
  endmethod.

  method RESISTOR_COLOR.
    VALUE = LINE_INDEX( COLOR_CODES[ TABLE_LINE = TO_LOWER( COLOR_CODE ) ] ) - 1.
  endmethod.

endclass.

This code runs fine in my system:
image

Test Failure for exercise : "BEER SONG"

The tests are passed in my system but failing in exercism editor.

Here is my code:

CLASS zcl_beer_song DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.

    METHODS recite
      IMPORTING
        !initial_bottles_count TYPE i
        !take_down_count       TYPE i
      RETURNING
        VALUE(result)          TYPE string_table.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.
CLASS zcl_beer_song IMPLEMENTATION.
  METHOD recite.
    DATA(i) = initial_bottles_count.
    WHILE i GT initial_bottles_count - take_down_count AND i > 0.
      IF i = 1.
        APPEND LINES OF VALUE string_table(
        ( |1 bottle of beer on the wall, 1 bottle of beer.| )
        ( |Take it down and pass it around, no more bottles of beer on the wall.| ) ( ) )
        TO result.
      ELSE.
        APPEND LINES OF VALUE string_table(
         ( condense( |{ i } bottles of beer on the wall, { i } bottles of beer.| ) )
         ( condense( |Take one down and pass it around, { i - 1 } {
          COND #( WHEN i = 2 THEN `bottle` ELSE `bottles` ) } of beer on the wall.| ) ) ( ) )
        TO result.
      ENDIF.
      i -= 1.
    ENDWHILE.
    IF i = 0 AND initial_bottles_count <> take_down_count.
      APPEND LINES OF VALUE string_table(
      ( |No more bottles of beer on the wall, no more bottles of beer.| )
      ( |Go to the store and buy some more, 99 bottles of beer on the wall.| ) )
      TO result.
    ELSE.
      DELETE result INDEX lines( result ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Error occurred in exercise : "HAMMING DISTANCE"

It seems THROW keyword is not getting accepted.
Getting the following error:

We received the following error when we ran your code:
buildCondBody, unexpected expression, Throw

Here is my code

CLASS zcl_hamming DEFINITION PUBLIC.
  PUBLIC SECTION.
    METHODS hamming_distance
      IMPORTING
        first_strand  TYPE string
        second_strand TYPE string
      RETURNING
        VALUE(result) TYPE i
      RAISING
        cx_parameter_invalid.
ENDCLASS.

CLASS zcl_hamming IMPLEMENTATION.
  METHOD hamming_distance.
    result = COND #(
      WHEN first_strand IS INITIAL AND second_strand IS INITIAL THEN 0
      WHEN strlen( first_strand ) <> strlen( second_strand ) THEN THROW cx_parameter_invalid( )
      ELSE REDUCE i( INIT d TYPE i FOR i = 0 UNTIL i = strlen( first_strand )
                     NEXT d += COND #( WHEN first_strand+i(1) <> second_strand+i(1) THEN 1 ) ) ).
  ENDMETHOD.
ENDCLASS.

I also moved the EXCEPTION out of the REDUCE statement, and tested it.
Yet, there is one test which fails:
Here's my modified code:

  METHOD hamming_distance.
    IF strlen( first_strand ) <> strlen( second_strand ).
      RAISE EXCEPTION new cx_parameter_invalid( ).
    ENDIF.
    result = COND #(
      WHEN first_strand IS INITIAL AND second_strand IS INITIAL THEN 0
*      WHEN strlen( first_strand ) <> strlen( second_strand ) THEN THROW cx_parameter_invalid( )
      ELSE REDUCE i( INIT d TYPE i FOR i = 0 UNTIL i = strlen( first_strand )
                     NEXT d += COND #( WHEN first_strand+i(1) <> second_strand+i(1) THEN 1 ) ) ).
  ENDMETHOD.

Hello World - Classic vs ADT

Current hello-world exercise uses ADT interface which requires some explanation for newbies and students solving directly on the website.

  1. Change description of current "Hello World" to "Hello World (Modern)" and extend instructions to explain ADT interface
  2. Add "Hello World (Classic)" using class without ADT interface

"abap.builtin.insert is not a function" error in Atbash Cipher

When running the tests for the following code for Atbash Cipher:

CLASS zcl_atbash_cipher DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS decode
      IMPORTING
        cipher_text       TYPE string
      RETURNING
        VALUE(plain_text) TYPE string.
    METHODS constructor.
    METHODS encode
      IMPORTING
        plain_text         TYPE string
      RETURNING
        VALUE(cipher_text) TYPE string.

  PRIVATE SECTION.
    DATA plain_latin   TYPE string.
    DATA atbash_cipher TYPE string.

    METHODS conv_to_target_character_set
      IMPORTING
        text               TYPE string
        from_character_set TYPE string
        to_character_set   TYPE string
      RETURNING
        VALUE(result)      TYPE string.

    METHODS get_cipher_text
      IMPORTING
        ungrouped_cipher_text TYPE string
      RETURNING
        VALUE(cipher_text)    TYPE string.
ENDCLASS.


CLASS zcl_atbash_cipher IMPLEMENTATION.
  METHOD constructor.
    plain_latin = to_lower( sy-abcde ).
    atbash_cipher = to_lower( reverse( sy-abcde ) ).
  ENDMETHOD.

  METHOD decode.
    DATA(input) = to_lower( cipher_text ).
    CONDENSE input NO-GAPS.

    plain_text = conv_to_target_character_set(
                     text               = input
                     from_character_set = atbash_cipher
                     to_character_set   = plain_latin ).
  ENDMETHOD.

  METHOD conv_to_target_character_set.
    DO strlen( text ) TIMES.
      DATA(alphabet) = substring(
                           val = text
                           off = sy-index - 1
                           len = 1 ).

      result = result &&
                    COND #(
                      WHEN alphabet CO '0123456789' THEN alphabet
                      ELSE substring( val = to_character_set
                                      off = find( val = from_character_set sub = alphabet )
                                      len = 1 ) ).
    ENDDO.
    CONDENSE result.
  ENDMETHOD.

  METHOD encode.
    DATA(input) = replace(
                      val   = to_lower( plain_text )
                      regex = `[^a-z0-9]` ##REGEX_POSIX
                      with  = space
                      occ   = 0 ).

    CONDENSE input NO-GAPS.

    cipher_text = get_cipher_text( conv_to_target_character_set(
                                       text               = input
                                       from_character_set = plain_latin
                                       to_character_set   = atbash_cipher ) ).

  ENDMETHOD.

  METHOD get_cipher_text.
    cipher_text = ungrouped_cipher_text.
    DATA(offset) = 6.
    DATA(cipher_text_length) = strlen( cipher_text ).
    WHILE offset <= cipher_text_length - 1.
      cipher_text = insert( val = cipher_text sub = ` ` off = offset - 1 ).
      cipher_text_length = strlen( cipher_text ).
      offset += 6.
    ENDWHILE.
  ENDMETHOD.

ENDCLASS.

i am getting the following error:

TypeError: abap.builtin.insert is not a function
at zcl_atbash_cipher.get_cipher_text (file:///tmp/exercism-abap-runner-uGgrIG/compiled/zcl_atbash_cipher.clas.mjs:70:36)
at zcl_atbash_cipher.encode (file:///tmp/exercism-abap-runner-uGgrIG/compiled/zcl_atbash_cipher.clas.mjs:57:32)
at async ltcl_test.encode5 (file:///tmp/exercism-abap-runner-uGgrIG/compiled/zcl_atbash_cipher.clas.testclasses.mjs:27:67)
at async Function.run (file:///tmp/exercism-abap-runner-uGgrIG/compiled/kernel_unit_runner.clas.mjs:126:11)
at async run (file:///tmp/exercism-abap-runner-uGgrIG/compiled/index_open.mjs:59:17)

I assume that the insert string function is not yet implemented

Error in test of "Nth Prime" (table expr OPTIONAL)

My Code of "Nth Prime" passes the unit test in my ADT (test class copied from exercism,org) but doesn't pass the test at exercism.org. Test 5 is green, the other ones are not.

CLASS zcl_nth_prime DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .
  PUBLIC SECTION.
    METHODS prime IMPORTING input    TYPE i
                      RETURNING VALUE(result) TYPE i
                      RAISING
        cx_parameter_invalid.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.
CLASS zcl_nth_prime IMPLEMENTATION.
  METHOD prime.
   DATA:  lv_found          TYPE abap_bool,
          lv_number_to_test TYPE i,
          lv_divisor        TYPE i,
          lt_prime_numbers  TYPE STANDARD TABLE OF i WITH DEFAULT KEY.
    IF input = 0.
      RAISE EXCEPTION TYPE cx_parameter_invalid.
    ENDIF.
    lv_number_to_test = 1.
    WHILE lines( lt_prime_numbers ) < input.
      lv_number_to_test = lv_number_to_test + 1.
      lv_divisor = 2.
      lv_found = abap_false.
      WHILE  lv_divisor < lv_number_to_test  AND  lv_found = abap_false.
        IF lv_number_to_test MOD lv_divisor = 0 AND lv_number_to_test <> lv_divisor.
          lv_found = abap_true.
        ENDIF.
        lv_divisor = lv_divisor + 1.
      ENDWHILE.
      IF lv_found = abap_false.
        APPEND lv_number_to_test TO lt_prime_numbers.
      ENDIF.
    ENDWHILE.
    result = VALUE i( lt_prime_numbers[ input ] OPTIONAL ).
  ENDMETHOD.
ENDCLASS.

Test Failure for Exercise "Anagram"

In my SAP system, all tests are passed successfully.
However, in exercism editor, tests are failing.

Here is my code:

  METHOD anagram.
    LOOP AT candidates INTO DATA(candidate).
      IF strlen( candidate ) = strlen( input ) AND to_upper( candidate ) <> to_upper( input ).
        DATA(str) = candidate.
*        TRY .
        DO strlen( input ) TIMES.
          str = COND #( WHEN str CS substring( val = input off = sy-index - 1 len = 1 )
                        THEN        replace(   val = str   off = sy-fdpos     len = 1 with = `` )
                        ELSE `THROW could be used to exit COND gracefully, but its not being accepted` ).
*                            ELSE THROW cx_parameter_invalid( ) ).
        ENDDO.
        IF str IS INITIAL.
          APPEND candidate TO result.
        ENDIF.
*          CATCH cx_parameter_invalid.
*        ENDTRY.
      ENDIF.
    ENDLOOP.

Custom signs - throws generic error when running tests on initial code

When running tests on "Custom signs" before adding code, I get this error:

"An error occurred while running your tests. This might mean that there was an issue in our infrastructure, or it might mean that you have something in your code that's causing our systems to break.

Please check your code, and if nothing seems to be wrong, try running the tests again."

When this happened for other exercises yesterday, it usually worked with a 2nd (or 3rd) try but no such luck right now.

Shouldn't running the tests initially always provide results - i.e. not throw technical errors - even if all fail?

Error "FIND, runtime, no input, s empty" in the Scrabble Score exercise

When trying to test the below code, I get the error "FIND, runtime, no input, s empty". The issue may will be on my end as I'm not used to working with ABAP outside an ABAP-editor with all the language support that provides!

CLASS zcl_scrabble_score DEFINITION PUBLIC .

  PUBLIC SECTION.
    METHODS: score
               IMPORTING input         TYPE string OPTIONAL
               RETURNING VALUE(result) TYPE i.
  PROTECTED SECTION.
  PRIVATE SECTION.
    types: begin of ty_scores,
             letters(10)    type c,
             score          type i,
           end  of ty_scores.
    data: defined_scores type standard table of ty_scores.
    data: def_score  type ty_scores.         

ENDCLASS.

CLASS zcl_scrabble_score IMPLEMENTATION.

  METHOD score.
     data: letter(1) type c,
           clen      type i.

     check input is not initial.

     defined_scores = VALUE #( ( letters = 'AEIOULNRST' score = 1 )
                       ( letters = 'DG' score = 2 )
                       ( letters = 'BCMP' score = 3 )
                       ( letters = 'FHVWY' score = 4 )
                       ( letters = 'K' score = 5 )
                       ( letters = 'JX' score = 8 )
                       ( letters = 'QZ' score = 10 ) ).

    "DESCRIBE FIELD input LENGTH DATA(clen) IN CHARACTER MODE.
    clen = strlen( input ).

    Do clen times.
      letter = input+sy-index(1).  "substring( val = input off = sy-index len = 1 ).
      loop at defined_scores INTO data(letterscore).
        FIND letter IN letterscore-letters.
        IF sy-subrc EQ 0.
          result = result + letterscore-score.
          exit.
        ENDIF.
      endloop.
    enddo.

  ENDMETHOD.

ENDCLASS.

Error occured in exercise "ATBASH CIPHER"

It runs without issues on my SAP system but fails in exercism editor with following errors:

We received the following error when we ran your code:
TypeError: Cannot read properties of undefined (reading 'get')
at zcl_atbash_cipher.translate (file:///tmp/exercism-abap-runner-21XJjM/compiled/zcl_atbash_cipher.clas.mjs:29:112)
at zcl_atbash_cipher.encode (file:///tmp/exercism-abap-runner-21XJjM/compiled/zcl_atbash_cipher.clas.mjs:53:32)
at ltcl_test.encode1 (file:///tmp/exercism-abap-runner-21XJjM/compiled/zcl_atbash_cipher.clas.testclasses.mjs:15:91)
at Function.run (file:///tmp/exercism-abap-runner-21XJjM/compiled/kernel_unit_runner.clas.mjs:126:77)
at async run (file:///tmp/exercism-abap-runner-21XJjM/compiled/index_open.mjs:59:17)

Here is my code:

CLASS zcl_atbash_cipher DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS decode
      IMPORTING
        cipher_text       TYPE string
      RETURNING
        VALUE(plain_text) TYPE string .
    METHODS encode
      IMPORTING
        plain_text         TYPE string
      RETURNING
        VALUE(cipher_text) TYPE string .
  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS translate IMPORTING input            TYPE string
                                local_dictionary TYPE string
                      RETURNING VALUE(result)    TYPE string.
ENDCLASS.



CLASS zcl_atbash_cipher IMPLEMENTATION.
  METHOD translate.
    result = REDUCE string( INIT str TYPE string
                  FOR i = 0 UNTIL i = strlen( input )
                  NEXT str = |{ str }{
                    COND #( LET  current_char       = to_upper( input+i(1) )
                                 foreign_dictionary = reverse( local_dictionary ) IN
                    WHEN local_dictionary   CS current_char
                    THEN to_lower( foreign_dictionary+sy-fdpos(1) )
                    WHEN '0123456789' CS current_char
                    THEN current_char ) }| ).
  ENDMETHOD.
  METHOD decode.
    plain_text = translate( input             = cipher_text
                            local_dictionary  = reverse( sy-abcde ) ).
  ENDMETHOD.

  METHOD encode.
    cipher_text = translate( input            = plain_text
                             local_dictionary = CONV #( sy-abcde ) ).
    REPLACE ALL OCCURRENCES OF REGEX `.{5}` IN cipher_text WITH |$& |.
    SHIFT cipher_text RIGHT DELETING TRAILING ` `.
    CONDENSE cipher_text.
  ENDMETHOD.
ENDCLASS.

Issue in exercise "MINESWEEPER" exercise

The solution works on my SAP system (Release 755) but ends with error on exercism editor.

Here is my code:

does not work char1 undefined

CLASS zcl_minesweeper DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS annotate
      IMPORTING
        !input        TYPE string_table
      RETURNING
        VALUE(result) TYPE string_table.
  PRIVATE SECTION.
    DATA: input_tab TYPE string_table.
    METHODS mine_found IMPORTING row           TYPE i
                                 offset        TYPE i
                       RETURNING VALUE(result) TYPE abap_bool.
ENDCLASS.

CLASS zcl_minesweeper IMPLEMENTATION.
  METHOD annotate.
    input_tab = input.
    LOOP AT input INTO DATA(input_row).
      DATA(output_row) = ``.
      DO strlen( input_row ) TIMES.
        DATA(input_char) = substring( val = input_row off = sy-index - 1 len = 1 ).
        IF input_char = ` `.
          DATA(mines_found) = REDUCE i( INIT m TYPE i
                                      FOR  i  = sy-tabix - 1 UNTIL i = sy-tabix + 2
                                      FOR  j  = sy-index - 2 UNTIL j = sy-index + 1
                                      NEXT m += COND #( WHEN mine_found( row = i offset = j ) THEN 1 ) ).
          DATA(output_char) = COND char1( WHEN mines_found > 0
                                          THEN condense( CONV string( mines_found ) ) ).
        ELSE.
          output_char = input_char.
        ENDIF.
        output_row = |{ output_row }{ COND #( WHEN output_char IS INITIAL THEN ` ` ELSE output_char ) }|.
      ENDDO.
      APPEND output_row TO result.
    ENDLOOP.
  ENDMETHOD.
  METHOD mine_found.
    TRY .
        result = xsdbool( substring( val = VALUE #( input_tab[ row ] ) off = offset len = 1 ) = `*` ).
      CATCH cx_sy_itab_line_not_found  cx_sy_range_out_of_bounds.
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

Time out when running tests for RESISTOR_COLOR

I get a time out error when running the tests for RESISTOR_COLOR
grafik
And after about a minute I see this message:
"Your tests timed out. This might mean that there was an issue in our infrastructure, but more likely it suggests that your code is running slowly. Is there an infinite loop or something similar?"

My code is below and doesn't have a loop statement included and I was getting the time out even when running the tests before I added any code.

CLASS zcl_resistor_color DEFINITION PUBLIC CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS resistor_color
      IMPORTING
        color_code   TYPE string
      RETURNING
        VALUE(value) TYPE i.

ENDCLASS.

CLASS zcl_resistor_color IMPLEMENTATION.

  METHOD resistor_color.
    case color_code.
      when 'black'.
        value = 0.
      when 'brown'.
        value = 1.
      when 'red'.
        value = 2.
      when 'orange'.
        value = 3.
      when 'yellow'.
        value = 4.
      when 'green'.
        value = 5.
      when 'blue'.
        value = 6.
      when 'violet'.
        value = 7.
      when 'grey'.
        value = 8.
      when 'white'.
        value = 9.
     endcase.
  ENDMETHOD.

ENDCLASS.

Unit test errors in "Atbash Cipher" due to lower case Keywords

I am getting unit-test errors when executing the following code:

class ZCL_ATBASH_CIPHER definition public final create public.

  public section.
    methods DECODE
      importing
        CIPHER_TEXT       type STRING
      returning
        value(PLAIN_TEXT) type STRING.
    methods CONSTRUCTOR.
    methods ENCODE
      importing
        PLAIN_TEXT         type STRING
      returning
        value(CIPHER_TEXT) type STRING.
  protected section.
  private section.
    data PLAIN_LATIN   type STRING.
    data ATBASH_CIPHER type STRING.

    methods CONV_TO_TARGET_CHARACTER_SET
      importing
        TEXT               type STRING
        FROM_CHARACTER_SET type STRING
        TO_CHARACTER_SET   type STRING
      returning
        value(RESULT)      type STRING.
endclass.


class ZCL_ATBASH_CIPHER implementation.
  method CONSTRUCTOR.
    PLAIN_LATIN = TO_LOWER( SY-ABCDE ).
    ATBASH_CIPHER = TO_LOWER( REVERSE( SY-ABCDE ) ).
  endmethod.

  method DECODE.
    data(INPUT) = TO_LOWER( CIPHER_TEXT ).

    PLAIN_TEXT = CONV_TO_TARGET_CHARACTER_SET(
                     TEXT               = INPUT
                     FROM_CHARACTER_SET = ATBASH_CIPHER
                     TO_CHARACTER_SET   = PLAIN_LATIN ).
  endmethod.

  method CONV_TO_TARGET_CHARACTER_SET.
    data(INPUT_TEXT) = TEXT.
    condense INPUT_TEXT no-gaps.
    do STRLEN( INPUT_TEXT ) times.
      data(ALPHABET) = SUBSTRING(
                           VAL = INPUT_TEXT
                           OFF = SY-INDEX - 1
                           LEN = 1 ).

      RESULT = RESULT &&
                    cond #(
                      when ALPHABET co '0123456789' then ALPHABET
                      else SUBSTRING( VAL = TO_CHARACTER_SET
                                      OFF = FIND( VAL = FROM_CHARACTER_SET SUB = ALPHABET )
                                      LEN = 1 ) ).
    enddo.
    condense RESULT.
  endmethod.

  method ENCODE.
    data(INPUT) = REPLACE(
                      VAL   = TO_LOWER( PLAIN_TEXT )
                      REGEX = `[^a-z0-9]` ##REGEX_POSIX
                      WITH  = SPACE
                      OCC   = 0 ).

    data(UNGROUPED_CIPHER_TEXT) = CONV_TO_TARGET_CHARACTER_SET(
                                      TEXT               = INPUT
                                      FROM_CHARACTER_SET = PLAIN_LATIN
                                      TO_CHARACTER_SET   = ATBASH_CIPHER ).

    do STRLEN( UNGROUPED_CIPHER_TEXT ) times.
      CIPHER_TEXT = cond #(
                      let C = SUBSTRING(
                                  VAL = UNGROUPED_CIPHER_TEXT
                                  OFF = SY-INDEX - 1
                                  LEN = 1 ) in
                      when SY-INDEX mod 5 = 0 then CIPHER_TEXT && C && ` `
                      else CIPHER_TEXT && C ).
    enddo.
    condense CIPHER_TEXT.
  endmethod.
endclass.

The tests run successfully when keywords are upper-case and identifiers are lower-case 🙄

Test failure for exercise 'CLOCK'

In my system, all tests are passed successfully.
However, the tests are failing in exercism editor:

Here is my code:

CLASS zcl_clock DEFINITION
  PUBLIC
  CREATE PUBLIC.
  PUBLIC SECTION.

    METHODS constructor
      IMPORTING
        !hours   TYPE i
        !minutes TYPE i DEFAULT 0.
    METHODS get
      RETURNING
        VALUE(result) TYPE string.
    METHODS add
      IMPORTING
        !minutes TYPE i.
    METHODS sub
      IMPORTING
        !minutes TYPE i.
  PRIVATE SECTION.
    DATA: clock TYPE sy-uzeit.
    METHODS: delta IMPORTING !minutes TYPE i RETURNING VALUE(result) TYPE sy-uzeit.

ENDCLASS.
CLASS zcl_clock IMPLEMENTATION.
  METHOD add.
    clock = COND #( WHEN minutes >= 0
                    THEN clock + delta( minutes )
                    ELSE clock - delta( abs( minutes ) ) ).
  ENDMETHOD.
  METHOD constructor.
    clock+0(2) = ( hours + floor( minutes / 60 ) ) MOD 24.
    clock+2(2) = minutes MOD 60.
  ENDMETHOD.
  METHOD get.
    result = |{ clock+0(2) }:{ clock+2(2) }|.
  ENDMETHOD.
  METHOD sub.
    add(  -1 * minutes ).
  ENDMETHOD.
  METHOD delta.
    result+0(2) = floor( minutes / 60 ) MOD 24.
    result+2(2) = minutes MOD 60.
  ENDMETHOD.
ENDCLASS.

Issue with understanding what's needed to do for "CLOCK"

I realize that this is not a technical but a "PEBCAK" issue, but I wasn't sure where else to raise it, so I'm trying here. Please let me know if there's a better way to ask for help while working on an exercise!

I started to tackle the "CLOCK" exercise but am mystified where what type of code needs to be added. This is at least in parts due to the starting point of the code looking different compared to the eight exercises I already solved where each of the methods did have a returning parameter which is not the case here. Given that I'm still not well-versed with ABAP-OO, I'm for example wondering what needs to be put into the CONSTRUCTOR method and/or whether I need te create a new private method for some of the tasks.

For me, it would be helpful if I could already take a peek at other solutions to get a better idea of what I need to do - but the community solutions are of course not yet available as I haven't managed to pass all tests yet - a bit of a catch22. Perhaps the tips option could provide some pointers for me and (possibly) others?

Thanks and cheers
Bärbel

Run Length Encoding - AT

Running the tests for the "Run Encoding Length" exercise ends with an error. The output is:

We received the following error when we ran your code:
./zcl_rle.clas.abap[89, 12] - Variable "TEMP4" contains unknown: UNDEFINED not found, lookup (unknown_types) [E]
abaplint: 1 issue(s) found

The solution tests fine in a Netweaver 7.4 system.

Here is the code I'm trying:

CLASS zcl_rle DEFINITION FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS encode IMPORTING input         TYPE string
                   RETURNING VALUE(result) TYPE string.

    METHODS decode IMPORTING input         TYPE string
                   RETURNING VALUE(result) TYPE string.

  PRIVATE SECTION.
    TYPES:
      type_e_letter TYPE c LENGTH 1,
      type_t_letter TYPE STANDARD TABLE OF type_e_letter
                    WITH NON-UNIQUE DEFAULT KEY.

    METHODS:
      _split_in_letters
        IMPORTING
          input            TYPE string
        RETURNING
          VALUE(rt_letter) TYPE type_t_letter.

ENDCLASS.

CLASS zcl_rle IMPLEMENTATION.
  METHOD encode.
    LOOP AT _split_in_letters( input ) ASSIGNING FIELD-SYMBOL(<lv_letter>).
      AT NEW table_line.
        DATA(lv_count) = 0.
      ENDAT.
      lv_count = lv_count + 1.
      AT END OF table_line.
        DATA(lv_encoded) = COND string( WHEN lv_count = 1
                                        THEN |{ <lv_letter> WIDTH = 1 }|
                                        ELSE |{ lv_count }{ <lv_letter> WIDTH = 1 }| ).
        result = result && lv_encoded.
      ENDAT.
    ENDLOOP.
  ENDMETHOD.

  METHOD decode.
    DATA(lv_offset) = 0.
    WHILE lv_offset < strlen( input ).
      DATA(lv_decode) = ||.
      FIND REGEX '(^\d+)(\D)' IN input+lv_offset IGNORING CASE
        MATCH OFFSET DATA(lv_match_offset) MATCH LENGTH DATA(lv_match_length)
        SUBMATCHES DATA(lv_repeat) DATA(lv_letter).
      IF sy-subrc = 0.
        DO CONV i( lv_repeat ) TIMES.
          lv_decode = |{ lv_decode }{ lv_letter }|.
        ENDDO.
        result = |{ result }{ lv_decode }|.
        lv_offset = lv_offset + lv_match_offset + lv_match_length.
        CONTINUE.
      ENDIF.
      result = |{ result }{ input+lv_offset(1) }|.
      lv_offset = lv_offset + 1.
    ENDWHILE.
  ENDMETHOD.

  METHOD _split_in_letters.
    DO strlen( input ) TIMES.
      DATA(lv_offset) = sy-index - 1.
      INSERT CONV #( input+lv_offset(1) ) INTO TABLE rt_letter.
    ENDDO.
  ENDMETHOD.
ENDCLASS.

Could it be that the table type definition is not transpiling correctly?

How do we migrate published exercises to concepts?

Probably a question for @ErikSchierboom : We've published a couple of exercises that appear as concepts in other tracks as practice exercises.

Can they easily be converted to concepts? Is it a simple matter of moving it to the right folders once all the documentation and other structures are done, or do we need to obsolete and recreate? I guess it depends if this affects students' completed exercises?

ABAP += and -= results in Statement does not exist in ABAPopen-abap

The usage of ABAP += and -= (which passes a syntax check and executes in a backend system) results in this error when executing in Exercism.
./zcl_kindergarten_garden.clas.abap[60, 7] - Statement does not exist in ABAPopen-abap(or a parser error), "second_offset" (parser_error) [E]
./zcl_kindergarten_garden.clas.abap[62, 7] - Statement does not exist in ABAPopen-abap(or a parser error), "second_offset" (parser_error) [E]
abaplint: 2 issue(s) found

I replace this with the long form syntax and then it works correctly:

*    IF second_offset = 0.
*      second_offset += 1.
*    ELSE.
*      second_offset -= 1.
*      first_offset = second_offset - 1.
*    ENDIF.
    IF second_offset = 0.
      second_offset = second_offset + 1.
    ELSE.
      second_offset = second_offset - 1.
      first_offset = second_offset - 1.
    ENDIF.

Beer song fails CI

Uses recursion and string templates with COND.

https://github.com/exercism/abap/runs/4762476583?check_suite_focus=true

Checking beer-song exercise...
beer-song /solution /output
beer-song: testing...
initialize: 26ms
syntaxAndDownport: 69714ms
Docker total runtime: 70.49 seconds
./bin/test: 50: [: 1c1: unexpected operator
1c1
< {"version":1,"status":"error","message":"./zcl_beer_song.clas.abap[32, 10] - Variable \"TEMP1\" contains unknown: UNDEFINED not found, lookup (unknown_types) [E]
abaplint: 1 issue(s) found"}
\ No newline at end of file
---
> {"version":1,"status":"pass"}
\ No newline at end of file

Hints not appearing

Question for the Exercism folk - @ErikSchierboom can you help?
I added a hints file but it is not appearing in the exercise.
https://github.com/exercism/abap/blob/main/exercises/practice/custom-signs/.docs/hints.md

I copied the JS one and rewrote the content, figuring if I start from a working example it should be OK.

It's the first hints file on the track, so am wondering if there is a config.json setting or something? Didn't see anything in the JS track or in the contributor documentation.

Launch tracking

Edit this issue to keep track of the tasks you're working on towards launch.

We have a rough guide for how to launch a track, which is sorely outdated but
quite possibly better than nothing (I'm so sorry, I'm waaaay behind on getting
documentation updated).
https://github.com/exercism/legacy-docs/blob/main/language-tracks/launch/README.md

Check out https://github.com/orgs/exercism/teams/track-maintainers/discussions/1
for details about the #maintaining-<track> channels and private #maintainers channel in the exercism-team Slack workspace.

Please ask if you have any questions or if anything is confusing!

Runtime issue with table constructor expression

There seems to be an issue with runtime for table constructor expressions.
I had two attempts, where my code timed out, where the identical code runs fast on my backend system.
After replacing the constructor expression with a more conservative approach, the timeout did not occur anymore.
See below code sample from the beersong exercise, where the commented version runs just fine, while this one times out.

  METHOD recite.
    DATA last_wall_bottle type i.
    last_wall_bottle = initial_bottles_count - take_down_count.
    result = VALUE #(
                        FOR i = initial_bottles_count THEN i - 1 WHILE i GT last_wall_bottle
                        ( LINES OF verse( i_number = i ) )
                        ( || )
                     ).
*     DATA(counter) = initial_bottles_count.
*     while counter gt initial_bottles_count - take_down_count.
*       append lines of verse( i_number = counter ) to result.
*       append initial line to result.
*       counter = counter - 1.
*     endwhile.
        delete result index lines(  result ).
  ENDMETHOD.

Improvement Scrabble Score Extensions

Input should need more parameters to calculate triple letter, triple world ...etc. For example, the start point on the table and the direction also should be provided. I think you can remove that part until the exam extends.

image

Error in Minesweeper

Running the tests of my code gave me erros. I found out, that the SAP types needed for the result tab in this code
FIND ALL OCCURRENCES OF '*' IN TABLE input RESULTS lt_mine_pos
and the type "text1000" were not recognized, so I declared them directly in my code.
Nonetheless the test fails and gives me no further details, what is wrong.

CLASS zcl_minesweeper DEFINITION PUBLIC FINAL CREATE PUBLIC.
 PUBLIC SECTION.

    METHODS annotate
      IMPORTING
        !input        TYPE string_table
      RETURNING
        VALUE(result) TYPE string_table.
    CONSTANTS:
      c_left           TYPE i VALUE 1,
      c_right          TYPE i VALUE 2,
      c_up_left        TYPE i VALUE 3,
      c_up             TYPE i VALUE 4,
      c_up_right       TYPE i VALUE 5,
      c_down_right     TYPE i VALUE 6,
      c_down           TYPE i VALUE 7,
      c_down_left      TYPE i VALUE 8,
      c_all_directions TYPE i VALUE 8
      .
" Exercism.org doesn't know these SAP Types
      TYPES: BEGIN OF ty_submatch_result,
              offset  type i,
              length  type i ,
             END OF ty_submatch_result.
      TYPES: ty_submatch_result_tab TYPE STANDARD TABLE OF ty_submatch_result WITH DEFAULT KEY.

      TYPES: BEGIN OF ty_match_result,
       line  type i,
       offset  type i,
       length  type i ,
       submatches  type ty_submatch_result_tab,
       END OF ty_match_result.

      TYPES: ty_match_result_tab TYPE STANDARD TABLE OF ty_match_result WITH DEFAULT KEY.

  PRIVATE SECTION.
    METHODS add_to_mine_counter
      IMPORTING
        i_direction         TYPE i
        i_mine_pos          TYPE ty_match_result
        i_minefield         TYPE string_table
      RETURNING
        VALUE(result_field) TYPE string_table.

ENDCLASS.

CLASS zcl_minesweeper IMPLEMENTATION.

  METHOD annotate.
    DATA lt_mine_pos TYPE ty_match_result_tab.
    FIELD-SYMBOLS: <ls_mine_pos> TYPE ty_match_result.

    result = input.
    FIND ALL OCCURRENCES OF '*' IN TABLE input RESULTS lt_mine_pos.
    data(lv_direction) = 1.
    LOOP AT lt_mine_pos ASSIGNING <ls_mine_pos>.
      lv_direction = c_left.
      WHILE lv_direction <= c_all_directions.
        result = add_to_mine_counter( i_direction = lv_direction i_minefield = result i_mine_pos = <ls_mine_pos> ).
        lv_direction = lv_direction + 1.
      ENDWHILE.
    ENDLOOP.
  ENDMETHOD.


  METHOD add_to_mine_counter.
    "Exercism.org doesn't know SAP Type text1000
    TYPES: ty_text1000  TYPE c LENGTH 1000. 
    DATA: lv_counter_position TYPE i,
          lv_out_of_bounds    TYPE abap_bool,
          lv_counter_line     TYPE i.

    CONSTANTS: lc_mine TYPE i VALUE -1.

    DATA(lv_mineposition) = i_mine_pos-offset.
    data(lv_minefield_len) = strlen( i_minefield[ 1 ] ).

    result_field = i_minefield.

    CASE i_direction.
      WHEN c_left.
        lv_counter_position = lv_mineposition - 1.
        lv_counter_line = i_mine_pos-line.
        lv_out_of_bounds = COND abap_bool( WHEN lv_mineposition = 0 THEN abap_true ELSE abap_false ).
      WHEN c_up_left.
        lv_counter_position = lv_mineposition - 1.
        lv_counter_line = i_mine_pos-line - 1.
        lv_out_of_bounds = COND abap_bool( WHEN lv_mineposition = 0 THEN abap_true
                                           WHEN lv_counter_line = 0 THEN abap_true
                                           ELSE abap_false ).
       WHEN c_up.
        lv_counter_position = lv_mineposition.
        lv_counter_line = i_mine_pos-line - 1.
        lv_out_of_bounds = COND abap_bool( WHEN lv_counter_line = 0 THEN abap_true
                                           ELSE abap_false ).
       WHEN c_up_right.
        lv_counter_position = lv_mineposition + 1.
        lv_counter_line = i_mine_pos-line - 1.
        lv_out_of_bounds = COND abap_bool( WHEN lv_counter_line = 0 THEN abap_true
                                           WHEN lv_mineposition = lv_minefield_len - 1 THEN abap_true
                                           ELSE abap_false ).
      WHEN c_right.
        lv_counter_position = lv_mineposition + 1.
        lv_out_of_bounds = COND abap_bool( WHEN lv_mineposition = lv_minefield_len - 1 THEN abap_true ELSE abap_false ).
        lv_counter_line = i_mine_pos-line.
       WHEN c_down_right.
        lv_counter_position = lv_mineposition + 1.
        lv_counter_line = i_mine_pos-line + 1.
        lv_out_of_bounds = COND abap_bool( WHEN lv_counter_line > lines( i_minefield ) THEN abap_true
                                           WHEN lv_mineposition = lv_minefield_len - 1 THEN abap_true
                                           ELSE abap_false ).
        WHEN c_down.
          lv_counter_position = lv_mineposition.
          lv_counter_line = i_mine_pos-line + 1.
          lv_out_of_bounds = COND abap_bool( WHEN lv_counter_line > lines( i_minefield ) THEN abap_true
                                             ELSE abap_false ).
        WHEN c_down_left.
          lv_counter_position = lv_mineposition - 1.
          lv_counter_line = i_mine_pos-line + 1.
          lv_out_of_bounds = COND abap_bool( WHEN lv_mineposition = 0 THEN abap_true
                                             WHEN lv_counter_line > lines( i_minefield ) THEN abap_true
                                             ELSE abap_false ).

    ENDCASE.

    IF  lv_out_of_bounds = abap_false.
      DATA(lv_field_value) = COND i( LET lv_count = substring( val = i_minefield[ lv_counter_line ] off = lv_counter_position len = 1 ) IN
                               WHEN lv_count = ` ` THEN 0
                               WHEN lv_count = `*` THEN lc_mine
                               ELSE lv_count
                             ).
      IF lv_field_value <> lc_mine.
        DATA(lv_line_with_counter) = CONV ty_text1000( result_field[ lv_counter_line ] ).

        lv_line_with_counter+lv_counter_position(1) = |{ lv_field_value + 1 }|.
        result_field[ lv_counter_line ] = |{ lv_line_with_counter WIDTH = lv_minefield_len }|.
      ENDIF.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

Issue with value table constructor, when using BASE

Hello,
there seems to be an issue with the value table constructor, when using the base operator.
In my case, the table was constructed with new entry, but without the existing ones, that should have been preserved by base.
This is the code i used:

CLASS zcl_prime_factors DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    TYPES integertab TYPE STANDARD TABLE OF i WITH EMPTY KEY.
    METHODS factors
      IMPORTING
        input         TYPE int8
      RETURNING
        VALUE(result) TYPE integertab.
  PROTECTED SECTION.
  PRIVATE SECTION.

ENDCLASS.


CLASS zcl_prime_factors IMPLEMENTATION.
  METHOD factors.
    " add solution here
    DATA(l_divi) = 2.
    DATA(remains) = input.
    while remains gt 1.
       if remains mod l_divi eq 0.
         result = value #( base result ( l_divi )  ).                                            <<<<
         remains = remains / l_divi.
       else.
         l_divi = l_divi + switch #( l_divi when 2 then 1 else 2 ).
       endif.
    endwhile.
  ENDMETHOD.

ENDCLASS.

Darts: arithmetic power operator ** leads to wrong results

While doing the Darts exercise I tried using the ** operator like this:

distance = sqrt( x ** 2 + y ** 2 ).

This led to test failures unless forcing operator precedence using

distance = sqrt( ( x ** 2 ) + ( y ** 2 ) ).

It seems the abapLint transpiler handles operator precedence different from the ABAP runtime, just evaluating the expression from left to right.

Minimal example

data n type i.
n = 3 ** 2 + 2 ** 2.
write / n.

AS ABAP: 3 ** 2 + 2 ** 2 = 9 + 4 = 13.
Transpiler: 3 ** 2 + 2 ** 2 --> power(add(power(3,2),2),2) --> (9 + 2) ** 2 = 121.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.