Post Reply 
[question]userRPL, functions or (sub)subprograms and directories
03-29-2017, 06:30 PM (This post was last modified: 03-29-2017 06:30 PM by pier4r.)
Post: #13
RE: [question]userRPL and functions or (sub)subprograms
So I would like to post the following code to help possible newbies like me (I'm no newcomer, I'm just noob).

I edited with notepad++ using "language ->N - Normal text" and then the chapter J of the AUR to help me with the translation of special chars that are not available in plain text.

The following code contains subprograms that can be easily disabled, for debugging purposes, avoiding to execute EVAL after them or after recalling them.

In the same way, if instead of EVAL, DBUG is used, then the user can DBUG exactly the wanted block and nothing else, simply evaluating the main program (The execution will stop once DBUG is reached, then one can proceed with the RUN & DEBUG menu). Speeding up the identification of problems. Once I discover this the debugging of quirks in the program was way faster than my previous experiences. It is something should be more advertised for newcomers, I wish I would known before.

Then I suppose the directory structure in one source file would be even better but it is something I'm going to use after this post for the first time.

Code:

%%HP: T(0)A(D)F(.);
@ You may edit the T(0)A(D)F(.) parts.
@ The earlier parts of the line are used by Debug4x.

@ in npp, just select encoding "normal" to get rid of the highlight.

@ Objective:
@ - We want to compare the expected performances of teams of a certain
@   average strength in some types of tournaments to determine
@   what is the one that determines the best team.
@   Assuming that the best team is the one is given higher strength
@   a priori. Of course the simulation of the tournaments
@   should be done some times to determine the percentage of winning.
@   1. round robin. Every team meet everyone else, at least twice.
@      (it could be extended with four times, six and so on)
@      Often used in long tournaments.
@      This is assumed as the best format and will be used as reference.
@   2. swiss tournament
@      Random pairings, and then teams with high score meet other teams
@      with high score, if possible avoiding pairings already done.
@      The minimum is that teams meet once.
@      Often used in chess, short but maybe effective.
@   3. knowckout tournaments. Random pairing at the start and then
@      the ones that wins proceed.
@      Often used in "show tournaments", short but maybe not so effective.
@   4. only one match against all the others (like half of a round robin)
@      Often used in show tournaments. Short but maybe not so effective.

@ Remarks: the comments try to give an idea, the values in the comments may
@ be different from the actual code though.
    
  
\<<
  'n*25+1200' 'n' 1 16 1 SEQ 
    @listTeams
    @ list of teams with a priori strength score
  0 @numTeams
  0 @tmpV to use for short time, value can be changed in other functions!
  0 @tmpV2
  0 @maxSumProbV
  0 @numProbV
  0 @mVarProb
  0 @curProbV
  1 @colSumProb
  2 @colProb
  3 @colVar
  0 @getVarFunc
  0 @matchResFunc
  10 @uFteamAwon
  30 @uFmatchingProbFound
  0 @rrFunc
  0 @teamAstrV
  0 @teamBstrV
  0 @teamAtmpV
  0 @teamBtmpV
  0 @rrResArr
  0 @rrResList (not sure what I'll use)
  0 @IncListElFunc
  1 @pointsForWin
  \->
  listTeams
  numTeams
  tmpV
  tmpV2
  maxSumProbV
  numProbV
  mVarProb
  curProbV
  colSumProb
  colProb
  colVar
  getVarFunc
  matchResFunc
  uFteamAwon
  uFmatchingProbFound
  rrFunc
  teamAstrV
  teamBstrV
  teamAtmpV
  teamBtmpV
  rrResArr
  rrResList
  IncListElFunc
  pointsForWin
  \<<
    listTeams SIZE 'numTeams' STO
  
    \<<
      @ creating the matrix containing the probability of the points oscillation
      @ between -400 points and +400 points
      
      @ every drop or increment of the base strength is made in 25 points.
      @ those points have a probability. So I assign "probability tokens" at every
      @ change. For example.
      @ -400  has 25 prob tokens. -375 has 50, -350 has 75 and so on, until the
      @ base value then goes back. +25 has 400 tokens, +50 has 375 and so on.
      @ so I want to model those tokens.
      'n' 'n' 25 400 25 SEQ
      425 +
        @ expanding the previous list with 425
      'n' 'n' 400 25 -25 SEQ
        @ Or REVLIST could have been used.
      + 'tmpV' STO
        @ storing the list
        @ the complete list now goes from 25 to 425 and back to 25.
      
      @ Now we want to create the sum of all this tokens,
      @ one value for each token, We can use STREAM but we need to recall
      @ objects from the tack. I do not like stack operations because
      @ they are unreadable but when they are a little it is ok.
      @ otherwise one should comment the actions.
      1 'tmpV2' STO
        @ counter, it needs to start from 1.
      tmpV 
      \<<
        @ having 25 50 75 100
        @ STREAM  25  2 Pick 25 + 25 STREAM 25 Pick 2 25 + 25  STREAM 25  Pick 2 25   + 25 
        @         50         50   75        75        75   75         75         75     75
        @                    25             75        75   150        150        150    150
        @                                             75              100        100    250
        @                                                                        150    
        2 PICK
        +
        1 'tmpV2' STO+
          @we need to count the objects that we leave on the stack. Plus 1 added at the start.
      \>>
      STREAM
        @now we have the list with all the sums
      @before making a vector out of it we save the last value that is the maximum value.  
      DUP 'maxSumProbV' STO
      @we continue      
      tmpV2
        @ the number of objects.
      \->ARRY    
        @ transformed in a vector
      
      tmpV
        @ the first list
      OBJ\->
        @ exploded
      @before saving it as vector I save the number of elements or
      @probility tokens (equals to variances)
      DUP 'numProbV' STO
      \->ARRY    
        @ transformed in a vector
        
      'n' 'n' -400 -25 25 SEQ
      0 +
      'n' 'n' 25 400 +25 SEQ
      + OBJ\->
        @ added and then exploded
      \->ARRY    
        @ transformed in a vector
      
      3 COL\-> 'mVarProb' STO
        @final matrix with columns: sum of probability tokens, probability tokens for variance, variance in points.
    \>>
    EVAL
      @compute the above program immediately

    \<<
      @program to extract the variance out of the built matrix
      
      @output, the variance of the strength points out of the matrix
      
      maxSumProbV RAND * 1 + IP 'curProbV' STO
        @ we get a random vnumber that has to be compared with the probability sums
      
      1 'tmpV' STO
        @with tmpV we will use it as a counter
      uFmatchingProbFound CF
      WHILE
        uFmatchingProbFound FC?
        tmpV numProbV \<=
        
        AND
      REPEAT
        IF
          curProbV 'mVarProb(tmpV, colSumProb)' EVAL \<=
            @accessing the matrix in algebraic mode, slower but more readable.
            @ than the messy RPN (RPN is not always less readable, but in some cases)
            @maintenance and debug use resources as well that often are more valuable.
        THEN
          @ found a probability sum bigger than the actual random value.
          uFmatchingProbFound SF
        ELSE
          1 'tmpV' STO+
        END
      END
      
      'mVarProb(tmpV, colVar)' EVAL
    \>>
    'getVarFunc' STO
      @get variance function.    
      
    \<<
      @program to compute the result of a match based on the variance and probability of it.
      @ should be used by all the tournaments.
      
      @In input are expected the strength of the two teams 
      @ and a user flag for the result
      @as for of variables already existing.
      @teamA
      @teamB
      @userFlagNumber
      
      @in output a flag is set
      @if teamA won, otherwise teamB
      
      uFteamAwon CF
      
      @ teamA streangth modified
      teamAstrV 
      getVarFunc EVAL
      + 'teamAtmpV' STO
      
      @ teamB streangth modified
      teamBstrV 
      getVarFunc EVAL
      + 'teamBtmpV' STO
      
      @there is no draw possible, at least for now.
      IF
        teamAtmpV teamBtmpV >
      THEN
        @teamA won.
        uFteamAwon SF
      ELSE
        @ teamA with lower or equal strength
        IF
          teamAtmpV teamBtmpV <
        THEN
          @teamA lost
          uFteamAwon CF
        ELSE
          @ same strength
          @ coin toss
          IF
            RAND 10 * IP
            5 <
          THEN
            @teamA won
            uFteamAwon SF
          ELSE
            @teamA lost
            uFteamAwon CF
          END
        END
      END
    \>>
    'matchResFunc' STO
    
    \<<
      @ program to increase the value of element in a list
      
      @ input on the stack see variables
      @ see the following, that if I keep adding variables on the main
      @ program it gets too unreadable.
      \->
      lList 
        @list
      lPosV 
        @position of the element
      lincV 
        @increase
      \<<
        lList lPosV
          @placing list and position on the stack
          @for storing, later.
        lList lPosV GET
        lincV +
          @getting the value and increasing it
        PUT
          @putting the increasing value back
      \>>
    \>>
    'IncListElFunc' STO
    
    \<<
       @program to compute a round robin tournament 
       
       @ given a list of teams with their strength and other
       @already named and set variables.
       
       @output, the list of teams with final points.
       
       '0' 'n' 1 numTeams 1
       SEQ 'rrResList' STO
         @saving the result list that at the start is just zeroes
       
       1 
       numTeams 1 -
       FOR teamPosA
         listTeams teamPosA GET 'teamAstrV' STO
           @get first team
         
         teamPosA 1 + 
         numTeams
         FOR teamPosB
           listTeams teamPosB GET 'teamBstrV' STO
             @get second team team
             
           @compute the result of a match. twice
           @as round robin requirement.
           1 2
           FOR counter
             matchResFunc EVAL
           
             IF
               uFteamAwon FS?
             THEN
               @update results
               rrResList teamPosA pointsForWin
               IncListElFunc EVAL
               'rrResList' STO
             ELSE
               @update results
               rrResList teamPosB pointsForWin
               IncListElFunc EVAL
               'rrResList' STO
             END
           NEXT
         NEXT
       NEXT
       
       rrResList
    \>>
    'rrFunc' STO
    
    rrFunc EVAL
  \>>
\>>


@ log {
@   12:05 29.03.2017{
@     Generating list of 16 teams between 1200 and 1600 strength points
@     'n*25+1200' 'n' 1 16 1 SEQ
@   }
@ }

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


Messages In This Thread
about DIR END - pier4r - 03-29-2017, 06:15 PM
RE: [question]userRPL and functions or (sub)subprograms - pier4r - 03-29-2017 06:30 PM



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