Πέμπτη 24 Ιουνίου 2021

Ranking methods

First publish there http://rosettacode.org/wiki/Ranking_methods#M2000_Interpreter

This code use stack object (the current and one as a pointer to stack). Also we have gosub to simple routines (no local variables) like BASIC Gosub label.

Use Win Dir$ to open current directory and double click to ranking.txt

Use statement in M2000 console: Edit "ranking.txt" to open file in M2000 editor.

When output$ is an empty string then the #k handler is -2 (output to screen).

Using the Wide clause we get an UTF-16LE file (else we get an ANSI file, using current Locale value)

Open output$ for wide output as #k




Module Ranking (output$, orderlist) {
      Open output$ for output as #k
      Gosub getdata
      Print #k, "Standard ranking:"
      skip=true
      rankval=1
      oldrank=0
      For i=1 to items
            Read rank, name$
            if skip then
                  skip=false
            else.if oldrank<>rank then
                  rankval=i
            end if
            oldrank=rank
            Print #k, Format$("{0::-5} {2} ({1})", rankval, rank, name$)
      Next
      Gosub getdata
      Print #k, "Modified ranking:"
      skip=true
      rankval=Items
      oldrank=0
      ShiftBack 1, -items*2 ' reverse stack items
      For i=items to 1
            Read name$, rank
            if skip then
                  skip=false
            else.if oldrank<>rank then
                  rankval=i
            end if
            oldrank=rank
            Data Format$("{0::-5} {2} ({1})", rankval, rank, name$)
      Next
      ShiftBack 1, -items ' reverse stack items
      For i=1 to items
            Print #k, letter$
      Next i
      Gosub getdata
      Print #k, "Dense ranking:"
      skip=true
      Dense=Stack
      acc=1
      oldrank=0
      For i=1 to items
            Read rank, name$
            if skip then
                  skip=false
                  oldrank=rank
            else.if oldrank<>rank then
                  oldrank=rank
                  Gosub dense
                  acc=i
            end if
            Stack Dense {data Format$(" {0} ({1})",name$, rank)}      
      Next
      Gosub dense
      Gosub getdata
      Print #k, "Ordinal ranking:"
      For i=1 to items
            Print #k, Format$("{0::-5} {2} ({1})", i, Number, letter$)
      Next
      Gosub getdata
      Print #k, "Fractional ranking:"
      skip=true
      Frac=Stack
      acc=1
      oldrank=0
      For i=1 to items
            Read rank, name$
            if skip then
                  skip=false
                  oldrank=rank
            else.if oldrank<>rank then
                  oldrank=rank
                  Gosub Fractional
                  acc=I
            end if
            Stack Frac {data Format$(" {0} ({1})",name$, rank)}      
      Next
      Gosub Fractional
      Close #k
      End
      Fractional:
            val=((len(Frac)+1)/2+(acc-1))
            Stack Frac {
                  while not empty
                        Print #k, format$("{0:1:-5}{1}", val, letter$)
                  end while
            }
      Return
      dense:
            Stack Dense {
                  while not empty
                        Print #k, format$("{0::-5}{1}", acc, letter$)
                  end while
            }
      Return
      getdata:
            flush
            stack stack(orderlist) // place a copy of items to current stack
            items=stack.size/2
      Return
}
Flush
Data 44, "Solomon", 42, "Jason", 42, "Errol"
Data 41, "Garry", 41, "Bernard", 41, "Barry"
Data 39, "Stephen"
// get all items from current stack to a new stack
alist=[]
// To screen
Ranking "", alist
// To file
Ranking "ranking.txt", alist



Standard ranking:

    1 Solomon (44)

    2 Jason (42)

    2 Errol (42)

    4 Garry (41)

    4 Bernard (41)

    4 Barry (41)

    7 Stephen (39)

Modified ranking:

    1 Solomon (44)

    3 Jason (42)

    3 Errol (42)

    6 Garry (41)

    6 Bernard (41)

    6 Barry (41)

    7 Stephen (39)

Dense ranking:

    1 Solomon (44)

    2 Jason (42)

    2 Errol (42)

    4 Garry (41)

    4 Bernard (41)

    4 Barry (41)

    7 Stephen (39)

Ordinal ranking:

    1 Solomon (44)

    2 Jason (42)

    3 Errol (42)

    4 Garry (41)

    5 Bernard (41)

    6 Barry (41)

    7 Stephen (39)

Fractional ranking:

  1.0 Solomon (44)

  2.5 Jason (42)

  2.5 Errol (42)

  5.0 Garry (41)

  5.0 Bernard (41)

  5.0 Barry (41)

  7.0 Stephen (39)