user2597933
user2597933

Reputation: 63

Classic ASP stuck in an infinite loop, makes no sense

I could try and explain what this code is for and why the output is the way it is, but it will take forever.

function Get90nums(G90_TC)
    if NOT isNumeric(G90_TC) then exit function : G90_TC=int(G90_TC) : if G90_TC>6 OR G90_TC<1 then exit function
    dim G90_BA : G90_BA="" : dim G90_CC : G90_CC=false : dim G90_NC : G90_NC=0 : dim G90_RC : G90_RC=0 : dim G90_TBL : G90_TBL=0
    do until G90_CC
        randomize : G90_RN=int((90)*rnd+1)
        if inStr(G90_BA,"["&G90_RN&"]")=0 then
            if G90_NC=5 then
                G90_BA=G90_BA&"[91][91][91][91]NL" : G90_RC=G90_RC+1 : G90_NC=0
                if G90_RC=3 then
                    G90_TBL=G90_TBL+1
                    G90_RC=0
                end if
            else
                G90_BA=G90_BA&"["&G90_RN&"]" : G90_NC=G90_NC+1
            end if
        end if
        if G90_TBL=G90_TC then G90_CC=true : Get90nums=G90_BA
    loop
end function

response.write Get90nums(1)

If you run the function as Get90nums(1) it will return something along the lines of:

[22][15][85][31][14][91][91][91][91]NL[40][10][9][77][54][91][91][91][91]NL[49][71][6][64][4][91][91][91][91]NL

I say "something along the lines" because the output is random. Ignore the fact the numbers are in brackets, ignore all the "91's" and the "NL's", and what you get is:

[22][15][85][31][14][40][10][9][77][54][49][71][6][64][4]

That's 15 unique random numbers between 1 and 90, no number is repeated.

Run the function as Get90nums(5) and you will get 75 unique numbers between 1 and 90.

However, if you run Get90nums(6), rather than returning all 90 numbers, it just get's stuck in an infinite loop, and I have no idea why.

Can anybody please shine some light on this, it's driving me crazy!

Thanks

Upvotes: 0

Views: 563

Answers (3)

user2597933
user2597933

Reputation: 63

I fixed it.

Instead of generating a random number each time I put all 90 numbers into an array beforehand and shuffled it.

UK bingo differs a lot from US bingo. You get six 3*9 cards. Each row has 5 numbers spread out and in ascending order. There are 90 numbers overall and no duplicates.

It's clearly a very early draft, but if you want to play 6 card UK bingo (it works with 1 to 6 cards) here's the script:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%

    '----------------------------------------------------------------------------------

    Dim array90(89)
    for x = 0 to 89
        array90(x)=x+1
    next
    Arr90=ArrReOrder(array90)

    '----------------------------------------------------------------------------------

    function Get90nums(G90_TC)
        if NOT isNumeric(G90_TC) then exit function:G90_TC=G90_TC:if G90_TC>6 OR G90_TC<1 then exit function
        dim G90_BA:G90_BA="":dim G90_CC:G90_CC=false:dim G90_NC:G90_NC=0:dim G90_RC:G90_RC=0:dim G90_TBL:G90_TBL=0
        for x=0 to (G90_TC*15)-1
            G90_RN=Arr90(x)
            G90_BA=G90_BA&"["&G90_RN&"]":G90_NC=G90_NC+1
            if G90_NC=5 then
                G90_BA=G90_BA&"[91][91][91][91]NL":G90_RC=G90_RC+1:G90_NC=0
                if G90_RC=3 then
                    G90_TBL=G90_TBL+1
                    G90_RC=0
                end if
            end if
            if G90_TBL=G90_TC then G90_CC=true:Get90nums=G90_BA
        next
    end function

    '----------------------------------------------------------------------------------

    function ArrReOrder(aArray)
        Dim iUpper,iLower,iLoop,iSwapPos,varTmp
        iUpper=UBound(aArray):iLower=LBound(aArray)
        randomize Timer
        for iLoop=iLower to iUpper
            iSwapPos=Int(Rnd*(iUpper+1))
            varTmp=aArray(iLoop)
            aArray(iLoop)=aArray(iSwapPos)
            aArray(iSwapPos)=varTmp
        next
        ArrReOrder=aArray
    end function

    '----------------------------------------------------------------------------------

    sub arrNumericalAsc(arrArray)
        Dim row,j,StartingKeyValue,NewKeyValue,swap_pos
        for row=0 to uBound(arrArray)-1
            if NOT arrArray(row)=91 then
                StartingKeyValue=int(arrArray(row))
                NewKeyValue=int(arrArray(row))
                swap_pos=row
                for j=row+1 to uBound(arrArray)
                    if int(arrArray(j)) < int(NewKeyValue) then
                        swap_pos=j
                        NewKeyValue=arrArray(j)
                    end if
                next
                if int(swap_pos) <> row then    
                    arrArray(swap_pos)=int(StartingKeyValue)
                    arrArray(row)=int(NewKeyValue)
                end if
            end if
        next
    end sub
'
    '----------------------------------------------------------------------------------

    Dim RC,NLarray,CommaArray,lineNums:lineNums=Get90nums(6):RC=0
        lineNums=replace(lineNums,"[","")
        lineNums=replace(lineNums,"]",",")
        NLarray=split(lineNums,",NL")
        for y=0 to uBound(NLarray)
            RC=RC+1
            if RC=1 AND NOT y=uBound(NLarray) then Response.Write("<table width=""0%"" border=""1"" cellspacing=""0"" cellpadding=""10"">")&VBcrlf
            CommaArray=split(NLarray(y),",")
            CommaArray=ArrReOrder(CommaArray)
            arrNumericalAsc CommaArray
            for z=0 to uBound(CommaArray)
                if z=0 then Response.Write("  <tr>")&VBcrlf
                    if CommaArray(z)=91 then CA_val="&nbsp;" else CA_val=CommaArray(z)
                    Response.Write("    <td width=""30"" align=""center"">" & CA_val & "</td>")&VBcrlf
                if z=uBound(CommaArray) then Response.Write("  </tr>")&VBcrlf
            next
            if RC=3 then Response.Write("</table>"&VBcrlf&VBcrlf&"<br><br>")&VBcrlf&VBcrlf:RC=0
        next

%>

Upvotes: 1

T McKeown
T McKeown

Reputation: 12847

Move the randomize out of the loop and notice the change to the G90_RN line, use CInt over Int:

randomize

do until G90_CC

    G90_RN=CInt((90*Rnd())+1)
    if inStr(G90_BA,"["&G90_RN&"]")=0 then
        if G90_NC=5 then
            G90_BA=G90_BA&"[91][91][91][91]NL" : G90_RC=G90_RC+1 : G90_NC=0
            if G90_RC=3 then
                G90_TBL=G90_TBL+1
                G90_RC=0
            end if
        else
            G90_BA=G90_BA&"["&G90_RN&"]" : G90_NC=G90_NC+1
        end if
    end if
    if G90_TBL=G90_TC then G90_CC=true : Get90nums=G90_BA
loop

Upvotes: 0

Ruud Helderman
Ruud Helderman

Reputation: 11018

Once G90_BA has filled up with 90 unique random number in the range 1..90, the expression inStr(G90_BA,"["&G90_RN&"]")=0 will consistently fail. At that point, G90_TBL will no longer be increased. Possibly it is then stuck at a value less than 6, so it will never become equal to G90_TC, G90_CC is never set to true, and the loop never ends. An alternative explanation would be that it is taking increasingly long to find unused numbers to fill the last few slots in the list. In other words, it is just slow. Try it in a debugger and see.

BTW, it is OK if takes forever to explain the code's purpose, but it is not OK if it takes forever to explain what this code is doing. Please refactor.

Upvotes: 0

Related Questions