Post Reply 
Programming puzzles: processing lists!
03-13-2023, 09:20 PM
Post: #281
RE: Programming puzzles: processing lists!
For #47 (see 1st Post)

Code:

  listIncrDecrElement
  @from http://www.wiki4hp.com/doku.php?id=rpl:start
  \<<
    PICK3 PICK3
    GET + PUT
  \>>

\<<
  @input
  "lvMaxValue" DROP
  "lvPosList" DROP
  
  @local var
  DUP "lvOrigPosList" DROP
  DUP SIZE "lvPosListSize" DROP
  0 "lvElement" DROP
  0 "lvCarry" DROP
  0 "lvIsThereCarry" DROP
  \->
  lvMaxValue
  lvPosList
  lvOrigPosList @if the current list goes overflow
  lvPosListSize
  lvElement
  lvCarry
  lvIsThereCarry
  \<<
    
    @TODO: check the carry with MAP and then addition between list operatons.
    @ - get the initial list
    @ - add one via list operation, do { 1 3 3 } plus { 0 0 1 } => { 1 3 4 }
    @ - check if there is overflow with a map operation
    @   { 1 3 4 } produces { 0 0 1 }
    @ - check if there is carry with \GSLIST on the overflow. If { 0 0 1 } > 0 then we continue
    @ - roll the carry { 0 0 1 } -> { 0 1 0 } but be careful if there is carry in the leading position, it should end.
    @   say maxvalue of 3: { 1 1 } -> { 1 2 } -> { 1 3 } converted to { 2 1 } -> { 2 2 } -> { 2 3 } converted to { 3 2 } 
    @   it should stop.
    @   Thus the carry in leading position, if detected, should never be rolled.
    @ - trim the values of the original number, still with map, note that the overflowing value should go to 1
    @   { 1 3 4 } -> { 1 3 1 }
    @ - add the carry
    @   { 1 3 1 } -> { 1 4 1 }
    @ - verify if there is overflow again with map
    @   { 1 4 1 } yields { 0 1 0 }
    @ - repeat the steps before as long as there is carry
    @ - No carry or carry in the leading position means that the process should end.
    @ - 11:41 13.03.2023 not able to use MAP as it wants to change flags and thus is unpractical 
    @   (I should save and restore flags if needed and I don't want to)
    
    
    @increment the list by 1
    lvPosList
    lvPosListSize
    1
    listIncrDecrElement
    'lvPosList' STO
    
    1 'lvIsThereCarry' STO @setting it to 1 to let the while go.
    WHILE
      lvPosList 1 GET
      lvMaxValue >
      NOT
      @ check if the leading position is over the maxValue, if yes, it should stop
      @ note that the leading position can overflow only due to the carry
      @ process, because the incrementing the list by 1 affects only the trailing element.
      
      lvIsThereCarry @this starts with 1, then get reset to zero for each check
      AND
    REPEAT
    
      @ check if there is carry
      0 'lvIsThereCarry' STO
      1 lvPosListSize
      FOR lvPos @MAP doesn't work without changing flags
        IF @could use IFTE but less readable
          lvPosList lvPos GET
          lvMaxValue > @if it is bigger than the maxvalue
        THEN
          1 @leave carry, as we increment always by 1, there could be only 1 as carry
          1 'lvIsThereCarry' STO @even overriding is ok
        ELSE
          0 @no carry
        END
      NEXT
      lvPosListSize \->LIST
      'lvCarry' STO
      
      
      IF
        lvIsThereCarry @only if there is carry, we can spare operations (also to debug)
      THEN
        @trim the original list, remove the extra values (from  1 3 4 } -> { 1 3 1 } if maxvalue is 3)
        1 lvPosListSize
        FOR lvPos @MAP doesn't work without changing flags
          lvPosList lvPos GET
          DUP @the value read in the list
          IF @could use IFTE but less readable
            lvMaxValue > @if it is bigger than the maxvalue
          THEN
            DROP @removed the original value used by DUP
            1 @leaves 1
          END
          @else it leaves the value used by DUP
        NEXT
        lvPosListSize \->LIST
        'lvPosList' STO
      
        @roll the carry and add it if needed
        lvPosList @prepare for the add
        @roll the carry to then add it.
        lvCarry LRLLD @the first position will always have a value of 0, otherwise the program exited already,
                      @thus can be rolled down.
        @then add it, '+' does concatenation so it doesn#t work.
        ADD
        'lvPosList' STO
      END
    END
    
    @report the result
    IF
      lvPosList 1 GET
      lvMaxValue >
    THEN
      lvOrigPosList
    ELSE
      lvPosList
    END
  \>>
\>>

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 3 Guest(s)