REM > AVCalc
      REM Calculate AV results from General Election results
      :
      DIM array$(0,20),seats%(10),won%(10),lost%(10)
      ON ERROR REPORT:PROCClose_All:PRINT:END
      :
      in% =OPENIN "GEVotes.csv"
      out%=OPENOUT"AVVotes.csv"
      PROCcsv_rd(in%,0,20):PROCclear
      FOR A%=0 TO 10:READ array$(0,A%):NEXT:PROCcsv_wr(out%,0,9)
      DATA Seat,Con,Lab,LD,SNP,PC,Grn,BNP,UKIP,,
      con%=1:lab%=2:ld%=3:snp%=4:pc%=5:grn%=6:bnp%=7:ukip%=8
      :
      REPEAT
        PROCcsv_rd(in%,0,20)
        IFarray$(0,1)<>"" THEN
          PROCav
          PROCcsv_wr(out%,0,9)
          PROCwr(out%,",,,,,,,,,"+CHR$13)
          IF win%:seats%(win%)=seats%(win%)+1
        ENDIF
      UNTILEOF#in%
      PROCclear
      B%=0:FOR A%=0 TO 10:IFseats%(A%):array$(0,A%)=STR$seats%(A%):B%=B%+seats%(A%)
      NEXT:array$(0,0)="Total: "+STR$B%:PROCcsv_wr(out%,0,9)
      RESTORE:FOR A%=0 TO 10:READ array$(0,A%):NEXT:PROCcsv_wr(out%,0,9)
      FOR A%=1 TO 10:array$(0,A%)=STR$(won%(A%)):NEXT
      array$(0,0)="Changes: seats won":PROCcsv_wr(out%,0,9)
      FOR A%=1 TO 10:array$(0,A%)=STR$(lost%(A%)):NEXT
      array$(0,0)="Changes: seats lost":PROCcsv_wr(out%,0,9)
      CLOSE#out%:out%=0
      CLOSE#in%:in%=0
      QUIT
      :
      DEFPROCav
      array$(0,0)=array$(0,1)
      FOR A%=1 TO 8:array$(0,A%)=array$(0,A%+8):NEXT
      FOR A%=9 TO 19:array$(0,A%)="":NEXT
      PROCcsv_wr(out%,0,9):max%=FNmax
      REPEAT
        los%=9:win%=FNwinner:rem%=FNremaining
        IF win%=0 THEN
          array$(0,0)=""
          los%=FNmin
          CASE los% OF
            WHEN 1 : REM Conservative
            REM Con->0Con,10Lab,25LD,5SNP,5PC,5Grn,10BNP,10UKIP
            IFVALarray$(0,lab%) :array$(0,lab%) =STR$(VALarray$(0,lab%) +VALarray$(0,con%)/10)
            IFVALarray$(0,ld%)  :array$(0,ld%)  =STR$(VALarray$(0,ld%)  +VALarray$(0,con%)/4)
            IFVALarray$(0,bnp%) :array$(0,bnp%) =STR$(VALarray$(0,bnp%) +VALarray$(0,con%)/10)
            IFVALarray$(0,snp%) :array$(0,snp%) =STR$(VALarray$(0,snp%) +VALarray$(0,con%)/20)
            IFVALarray$(0,pc%)  :array$(0,pc%)  =STR$(VALarray$(0,pc%)  +VALarray$(0,con%)/20)
            IFVALarray$(0,grn%) :array$(0,grn%) =STR$(VALarray$(0,grn%) +VALarray$(0,con%)/20)
            IFVALarray$(0,ukip%):array$(0,ukip%)=STR$(VALarray$(0,ukip%)+VALarray$(0,con%)/10)
            WHEN 2 : REM Labour
            REM Lab->10Con,0Lab,40LD,5SNP,5PC,20Grn,10BNP,0UKIP
            IFVALarray$(0,con%):array$(0,con%)=STR$(VALarray$(0,con%)+VALarray$(0,lab%)/10)
            IFVALarray$(0,ld%) :array$(0,ld%) =STR$(VALarray$(0,ld%) +VALarray$(0,lab%)*4/10)
            IFVALarray$(0,snp%):array$(0,snp%)=STR$(VALarray$(0,snp%)+VALarray$(0,lab%)/20)
            IFVALarray$(0,pc%) :array$(0,pc%) =STR$(VALarray$(0,pc%) +VALarray$(0,lab%)/20)
            IFVALarray$(0,grn%):array$(0,grn%)=STR$(VALarray$(0,grn%)+VALarray$(0,lab%)/4)
            IFVALarray$(0,bnp%):array$(0,bnp%)=STR$(VALarray$(0,bnp%)+VALarray$(0,lab%)/10)
            WHEN 3 : REM LibDem
            REM LD->20Con,25Lab,0LD,5SNP,5PC,20Grn,0BNP,0UKIP
            IFVALarray$(0,con%):array$(0,con%)=STR$(VALarray$(0,con%)+VALarray$(0,ld%)/5)
            IFVALarray$(0,lab%):array$(0,lab%)=STR$(VALarray$(0,lab%)+VALarray$(0,ld%)/4)
            IFVALarray$(0,snp%):array$(0,snp%)=STR$(VALarray$(0,snp%)+VALarray$(0,ld%)/20)
            IFVALarray$(0,pc%) :array$(0,pc%) =STR$(VALarray$(0,pc%) +VALarray$(0,ld%)/20)
            IFVALarray$(0,grn%):array$(0,grn%)=STR$(VALarray$(0,grn%)+VALarray$(0,ld%)/5)
            WHEN 4 : REM SNP
            REM SNP->0Con,25Lab,25LD,0SNP,0PC,0Grn,0BNP,0UKIP
            IFVALarray$(0,lab%):array$(0,lab%)=STR$(VALarray$(0,lab%)+VALarray$(0,snp%)/4)
            IFVALarray$(0,ld%) :array$(0,ld%) =STR$(VALarray$(0,ld%) +VALarray$(0,snp%)/4)
            WHEN 5 : REM PC
            REM PC->0Con,25Lab,25LD,0SNP,0PC,0Grn,0BNP,0UKIP
            IFVALarray$(0,lab%):array$(0,lab%)=STR$(VALarray$(0,lab%)+VALarray$(0,pc%)/4)
            IFVALarray$(0,ld%) :array$(0,ld%) =STR$(VALarray$(0,ld%) +VALarray$(0,pc%)/4)
            WHEN 6 : REM Green
            REM PC->0Con,20Lab,25LD,5SNP,5PC,0Grn,0BNP,0UKIP
            IFVALarray$(0,lab%):array$(0,lab%)=STR$(VALarray$(0,lab%)+VALarray$(0,grn%)/5)
            IFVALarray$(0,ld%) :array$(0,ld%) =STR$(VALarray$(0,ld%) +VALarray$(0,grn%)/4)
            IFVALarray$(0,snp%):array$(0,snp%)=STR$(VALarray$(0,snp%)+VALarray$(0,grn%)/20)
            IFVALarray$(0,pc%) :array$(0,pc%) =STR$(VALarray$(0,pc%) +VALarray$(0,grn%)/20)
            WHEN 7 : REM BNP
            REM BNP->0Con,0Lab,0LD,0SNP,0PC,0Grn,0BNP,0UKIP
            WHEN 8 : REM UKIP
            REM UKIP->100Con,0Lab,0LD,0SNP,0PC,0Grn,0BNP,0UKIP
            IFVALarray$(0,con%):array$(0,con%)=STR$(VALarray$(0,con%)+VALarray$(0,ukip%))
          ENDCASE
          IF los% THEN
            array$(0,los%)=""
            B=0:FOR A%=0 TO 9:B=B+VALarray$(0,A%):NEXT
            FOR A%=0 TO 9:IF VALarray$(0,A%)<>0 THEN
                array$(0,A%)=STR$(100*VALarray$(0,A%)/B)
              ENDIF
            NEXT
            IF rem%>2:array$(0,los%)="ELIMINATED":PROCcsv_wr(out%,0,9)
            array$(0,los%)=""
          ENDIF
          IF rem%=1:win%=los%
        ENDIF
      UNTILwin% OR los%=0
      PROCclear:array$(0,win%)="*WINNER*"
      IFwin%<>max%:array$(0,max%)="-LOSER-":won%(win%)=won%(win%)+1:lost%(max%)=lost%(max%)+1
      ENDPROC
      :
      DEFFNwinner:A%=0:REPEAT:A%=A%+1:UNTILVALarray$(0,A%)>50 OR A%>8:IF A%>8:=0 ELSE =A%
      DEFFNmax:B=0:C%=0:FOR A%=1 TO 10:IFVALarray$(0,A%)<>0:IFVALarray$(0,A%)>B:C%=A%:B=VALarray$(0,A%)
      NEXT:=C%
      DEFFNmin:B=100:C%=0:FOR A%=1 TO 10:IFVALarray$(0,A%)<>0:IFVALarray$(0,A%)<B:C%=A%:B=VALarray$(0,A%)
      NEXT:=C%
      :
      DEFFNremaining:B%=0:FOR A%=1 TO 10:IFVALarray$(0,A%)<>0:B%=B%+1
      NEXT:=B%
      :
      DEFPROCclear
      FOR A%=0 TO 10:array$(0,A%)="":NEXT
      ENDPROC
      :
      DEFPROCClose_All
      in%=in%:IFin%:A%=in%:in%=0:CLOSE#A%
      out%=out%:IFout%:A%=out%:out%=0:CLOSE#A%
      ENDPROC
      :
      REM Read CSV file from in% to array$()
      REM ----------------------------------
      DEFPROCcsv_rd(i%,imax%,rmax%)
      s$=FNrd(i%)
      FOR record%=0 TO rmax%-1
        i%=INSTR(s$+",",","):r$=LEFT$(s$,i%-1):s$=MID$(s$,i%+1)
        IFLEFT$(r$,1)="""":IF RIGHT$(r$,1)="""":r$=MID$(r$,2,LENr$-2)
        i%=0
        REPEAT
          i%=INSTR(r$,"""",i%+1):IF i%:r$=LEFT$(r$,i%)+MID$(r$,i%+1)
        UNTIL i%=0
        array$(imax%,record%)=r$
      NEXT record%
      imax%=imax%+1
      ENDPROC
      
      REM Write CSV file from array$() to out%
      REM ------------------------------------
      DEFPROCcsv_wr(o%,item%,rmax%)
      FOR record%=0 TO rmax%-1
        r$=array$(item%,record%)
        i%=0
        REPEAT
          i%=INSTR(r$,"""",i%+1):IF i%:r$=LEFT$(r$,i%)+MID$(r$,i%):i%=i%+1
        UNTIL i%=0
        IF INSTR(r$,",")<>0 THEN r$=""""+r$+""""
        PROCwr(o%,r$+",")
      NEXT record%
      PTR#out%=PTR#out%-1:BPUT#out%,13
      ENDPROC
      
      DEFFNrd(i%)=GET$#i%
      DEFPROCwr(o%,A$):BPUT#o%,A$;:ENDPROC