' Sliding Window — demonstrates fixed-size sliding window operations
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL arr(1000) AS LONG
    LOCAL n AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL windowSize AS LONG
    LOCAL windowSum AS LONG
    LOCAL maxSum AS LONG
    LOCAL minSum AS LONG
    LOCAL windowAvg AS LONG
    LOCAL maxIdx AS LONG
    LOCAL minIdx AS LONG
    LOCAL lineStr AS STRING
    LOCAL elemStr AS STRING
    n = 50
    windowSize = 5
    PRINT "============================================"
    PRINT "        SLIDING WINDOW DEMONSTRATION"
    PRINT "============================================"
    PRINT ""
    PRINT "Array data:"
    PRINT ""
    FOR i = 0 TO n - 1
        arr(i) = ((i * 17 + 23) MOD 30) + 1
    NEXT i
    lineStr = ""
    FOR i = 0 TO n - 1
        elemStr = STR$(arr(i))
        DO WHILE LEN(elemStr) < 3
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
        IF (i + 1) MOD 10 = 0 THEN
            PRINT lineStr
            lineStr = ""
        END IF
    NEXT i
    IF lineStr <> "" THEN
        PRINT lineStr
    END IF
    PRINT ""
    PRINT "Fixed window size = " + STR$(windowSize)
    PRINT ""
    PRINT "Window sums (using sliding technique):"
    PRINT ""
    windowSum = 0
    FOR i = 0 TO windowSize - 1
        windowSum = windowSum + arr(i)
    NEXT i
    maxSum = windowSum
    minSum = windowSum
    maxIdx = 0
    minIdx = 0
    PRINT "Window [0-" + STR$(windowSize - 1) + "] sum = " + STR$(windowSum)
    FOR i = 1 TO n - windowSize
        windowSum = windowSum - arr(i - 1) + arr(i + windowSize - 1)
        PRINT "Window [" + STR$(i) + "-" + STR$(i + windowSize - 1) + "] sum = " + STR$(windowSum)
        IF windowSum > maxSum THEN
            maxSum = windowSum
            maxIdx = i
        END IF
        IF windowSum < minSum THEN
            minSum = windowSum
            minIdx = i
        END IF
    NEXT i
    PRINT ""
    PRINT "Maximum sum: " + STR$(maxSum) + " at window [" + STR$(maxIdx) + "-" + STR$(maxIdx + windowSize - 1) + "]"
    PRINT "Minimum sum: " + STR$(minSum) + " at window [" + STR$(minIdx) + "-" + STR$(minIdx + windowSize - 1) + "]"
    PRINT ""
    PRINT "============================================"
    PRINT "      VARIABLE WINDOW SIZE"
    PRINT "============================================"
    PRINT ""
    FOR windowSize = 2 TO 8
        windowSum = 0
        FOR i = 0 TO windowSize - 1
            windowSum = windowSum + arr(i)
        NEXT i
        maxSum = windowSum
        FOR i = 1 TO n - windowSize
            windowSum = windowSum - arr(i - 1) + arr(i + windowSize - 1)
            IF windowSum > maxSum THEN
                maxSum = windowSum
            END IF
        NEXT i
        windowSum = 0
        FOR i = 0 TO windowSize - 1
            windowSum = windowSum + arr(i)
        NEXT i
        minSum = windowSum
        FOR i = 1 TO n - windowSize
            windowSum = windowSum - arr(i - 1) + arr(i + windowSize - 1)
            IF windowSum < minSum THEN
                minSum = windowSum
            END IF
        NEXT i
        PRINT "Window size " + STR$(windowSize) + ": max=" + STR$(maxSum) + " min=" + STR$(minSum)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "    SLIDING WINDOW AVERAGE"
    PRINT "============================================"
    PRINT ""
    windowSize = 4
    windowSum = 0
    FOR i = 0 TO windowSize - 1
        windowSum = windowSum + arr(i)
    NEXT i
    windowAvg = windowSum / windowSize
    PRINT "Window averages (size=" + STR$(windowSize) + "):"
    PRINT ""
    lineStr = ""
    elemStr = STR$(windowAvg)
    DO WHILE LEN(elemStr) < 4
        elemStr = " " + elemStr
    LOOP
    lineStr = lineStr + elemStr + " "
    FOR i = 1 TO n - windowSize
        windowSum = windowSum - arr(i - 1) + arr(i + windowSize - 1)
        windowAvg = windowSum / windowSize
        elemStr = STR$(windowAvg)
        DO WHILE LEN(elemStr) < 4
            elemStr = " " + elemStr
        LOOP
        lineStr = lineStr + elemStr + " "
    NEXT i
    PRINT lineStr
    PRINT ""
    PRINT "============================================"
    PRINT "    SLIDING WINDOW MEDIAN (unsorted)"
    PRINT "============================================"
    PRINT ""
    LOCAL windowValues(100) AS LONG
    LOCAL limit AS LONG
    LOCAL k AS LONG
    LOCAL sortedWindow(100) AS LONG
    LOCAL tmpVal AS LONG
    LOCAL midVal AS LONG
    windowSize = 5
    PRINT "Window medians (size=" + STR$(windowSize) + "):"
    PRINT ""
    FOR i = 0 TO n - windowSize
        limit = windowSize
        FOR j = 0 TO limit - 1
            windowValues(j) = arr(i + j)
        NEXT j
        FOR j = 0 TO limit - 2
            FOR k = 0 TO limit - 2 - j
                IF windowValues(k) > windowValues(k + 1) THEN
                    tmpVal = windowValues(k)
                    windowValues(k) = windowValues(k + 1)
                    windowValues(k + 1) = tmpVal
                END IF
            NEXT k
        NEXT j
        midVal = windowValues(limit / 2)
        PRINT "Window [" + STR$(i) + "-" + STR$(i + windowSize - 1) + "] median = " + STR$(midVal)
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "   SLIDING WINDOW PRODUCT"
    PRINT "============================================"
    PRINT ""
    LOCAL windowProd AS LONG
    windowSize = 3
    PRINT "Window products (size=" + STR$(windowSize) + "):"
    PRINT ""
    windowProd = 1
    FOR i = 0 TO windowSize - 1
        windowProd = windowProd * arr(i)
    NEXT i
    PRINT "Window [0-2] product = " + STR$(windowProd)
    FOR i = 1 TO n - windowSize
        IF arr(i + windowSize - 1) <> 0 THEN
            IF arr(i - 1) <> 0 THEN
                windowProd = (windowProd / arr(i - 1)) * arr(i + windowSize - 1)
            ELSE
                windowProd = 1
                FOR j = 0 TO windowSize - 1
                    windowProd = windowProd * arr(i + j)
                NEXT j
            END IF
        ELSE
            windowProd = 1
            FOR j = 0 TO windowSize - 1
                windowProd = windowProd * arr(i + j)
            NEXT j
        END IF
        PRINT "Window [" + STR$(i) + "-" + STR$(i + windowSize - 1) + "] product = " + STR$(windowProd)
    NEXT i
    PRINT ""
    PRINT "Sliding window operations complete"
    FUNCTION = 0
END FUNCTION
