' Roman Numerals — converts between integers and Roman numeral strings, no string arrays
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL num AS LONG
    LOCAL roman AS STRING
    LOCAL value AS LONG
    LOCAL idx AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL remaining AS LONG
    LOCAL testCount AS LONG
    LOCAL passCount AS LONG
    LOCAL failCount AS LONG
    LOCAL result AS LONG
    LOCAL tempStr AS STRING
    LOCAL ch AS STRING
    LOCAL rlen AS LONG
    LOCAL nextCh AS STRING
    LOCAL expected AS STRING
    LOCAL lineStr AS STRING
    testCount = 0
    passCount = 0
    failCount = 0
    PRINT "============================================"
    PRINT "       ROMAN NUMERAL CONVERTER"
    PRINT "============================================"
    PRINT ""
    PRINT "Integer to Roman numeral conversion"
    PRINT ""
    FOR i = 0 TO 14
        IF i = 0 THEN num = 1
        IF i = 0 THEN expected = "I"
        IF i = 1 THEN num = 4
        IF i = 1 THEN expected = "IV"
        IF i = 2 THEN num = 5
        IF i = 2 THEN expected = "V"
        IF i = 3 THEN num = 9
        IF i = 3 THEN expected = "IX"
        IF i = 4 THEN num = 10
        IF i = 4 THEN expected = "X"
        IF i = 5 THEN num = 40
        IF i = 5 THEN expected = "XL"
        IF i = 6 THEN num = 50
        IF i = 6 THEN expected = "L"
        IF i = 7 THEN num = 90
        IF i = 7 THEN expected = "XC"
        IF i = 8 THEN num = 100
        IF i = 8 THEN expected = "C"
        IF i = 9 THEN num = 400
        IF i = 9 THEN expected = "CD"
        IF i = 10 THEN num = 500
        IF i = 10 THEN expected = "D"
        IF i = 11 THEN num = 900
        IF i = 11 THEN expected = "CM"
        IF i = 12 THEN num = 1000
        IF i = 12 THEN expected = "M"
        IF i = 13 THEN num = 2024
        IF i = 13 THEN expected = "MMXXIV"
        IF i = 14 THEN num = 3999
        IF i = 14 THEN expected = "MMMCMXCIX"
        roman = ""
        remaining = num
        DO WHILE remaining > 0
            IF remaining >= 1000 THEN
                roman = roman + "M"
                remaining = remaining - 1000
            ELSE
                IF remaining >= 900 THEN
                    roman = roman + "CM"
                    remaining = remaining - 900
                ELSE
                    IF remaining >= 500 THEN
                        roman = roman + "D"
                        remaining = remaining - 500
                    ELSE
                        IF remaining >= 400 THEN
                            roman = roman + "CD"
                            remaining = remaining - 400
                        ELSE
                            IF remaining >= 100 THEN
                                roman = roman + "C"
                                remaining = remaining - 100
                            ELSE
                                IF remaining >= 90 THEN
                                    roman = roman + "XC"
                                    remaining = remaining - 90
                                ELSE
                                    IF remaining >= 50 THEN
                                        roman = roman + "L"
                                        remaining = remaining - 50
                                    ELSE
                                        IF remaining >= 40 THEN
                                            roman = roman + "XL"
                                            remaining = remaining - 40
                                        ELSE
                                            IF remaining >= 10 THEN
                                                roman = roman + "X"
                                                remaining = remaining - 10
                                            ELSE
                                                IF remaining >= 9 THEN
                                                    roman = roman + "IX"
                                                    remaining = remaining - 9
                                                ELSE
                                                    IF remaining >= 5 THEN
                                                        roman = roman + "V"
                                                        remaining = remaining - 5
                                                    ELSE
                                                        IF remaining >= 4 THEN
                                                            roman = roman + "IV"
                                                            remaining = remaining - 4
                                                        ELSE
                                                            roman = roman + "I"
                                                            remaining = remaining - 1
                                                        END IF
                                                    END IF
                                                END IF
                                            END IF
                                        END IF
                                    END IF
                                END IF
                            END IF
                        END IF
                    END IF
                END IF
            END IF
        LOOP
        testCount = testCount + 1
        IF roman = expected THEN
            passCount = passCount + 1
            PRINT "PASS: " + STR$(num) + " -> " + roman
        ELSE
            failCount = failCount + 1
            PRINT "FAIL: " + STR$(num) + " -> " + roman + " (expected " + expected + ")"
        END IF
    NEXT i
    PRINT ""
    PRINT "============================================"
    PRINT "     ROMAN NUMERAL TO INTEGER"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO 14
        IF i = 0 THEN expected = "I"
        IF i = 0 THEN num = 1
        IF i = 1 THEN expected = "IV"
        IF i = 1 THEN num = 4
        IF i = 2 THEN expected = "V"
        IF i = 2 THEN num = 5
        IF i = 3 THEN expected = "IX"
        IF i = 3 THEN num = 9
        IF i = 4 THEN expected = "X"
        IF i = 4 THEN num = 10
        IF i = 5 THEN expected = "XL"
        IF i = 5 THEN num = 40
        IF i = 6 THEN expected = "L"
        IF i = 6 THEN num = 50
        IF i = 7 THEN expected = "XC"
        IF i = 7 THEN num = 90
        IF i = 8 THEN expected = "C"
        IF i = 8 THEN num = 100
        IF i = 9 THEN expected = "CD"
        IF i = 9 THEN num = 400
        IF i = 10 THEN expected = "D"
        IF i = 10 THEN num = 500
        IF i = 11 THEN expected = "CM"
        IF i = 11 THEN num = 900
        IF i = 12 THEN expected = "M"
        IF i = 12 THEN num = 1000
        IF i = 13 THEN expected = "MMXXIV"
        IF i = 13 THEN num = 2024
        IF i = 14 THEN expected = "MMMCMXCIX"
        IF i = 14 THEN num = 3999
        roman = expected
        result = 0
        idx = 1
        rlen = LEN(roman)
        DO WHILE idx <= rlen
            ch = MID$(roman, idx, 1)
            IF idx < rlen THEN
                nextCh = MID$(roman, idx + 1, 1)
            ELSE
                nextCh = ""
            END IF
            IF ch = "M" THEN
                result = result + 1000
                idx = idx + 1
            ELSE
                IF ch = "C" AND nextCh = "M" THEN
                    result = result + 900
                    idx = idx + 2
                ELSE
                    IF ch = "D" THEN
                        result = result + 500
                        idx = idx + 1
                    ELSE
                        IF ch = "C" AND nextCh = "D" THEN
                            result = result + 400
                            idx = idx + 2
                        ELSE
                            IF ch = "C" THEN
                                result = result + 100
                                idx = idx + 1
                            ELSE
                                IF ch = "X" AND nextCh = "C" THEN
                                    result = result + 90
                                    idx = idx + 2
                                ELSE
                                    IF ch = "L" THEN
                                        result = result + 50
                                        idx = idx + 1
                                    ELSE
                                        IF ch = "X" AND nextCh = "L" THEN
                                            result = result + 40
                                            idx = idx + 2
                                        ELSE
                                            IF ch = "X" THEN
                                                result = result + 10
                                                idx = idx + 1
                                            ELSE
                                                IF ch = "I" AND nextCh = "X" THEN
                                                    result = result + 9
                                                    idx = idx + 2
                                                ELSE
                                                    IF ch = "V" THEN
                                                        result = result + 5
                                                        idx = idx + 1
                                                    ELSE
                                                        IF ch = "I" AND nextCh = "V" THEN
                                                            result = result + 4
                                                            idx = idx + 2
                                                        ELSE
                                                            result = result + 1
                                                            idx = idx + 1
                                                        END IF
                                                    END IF
                                                END IF
                                            END IF
                                        END IF
                                    END IF
                                END IF
                            END IF
                        END IF
                    END IF
                END IF
            END IF
        LOOP
        testCount = testCount + 1
        IF result = num THEN
            passCount = passCount + 1
            PRINT "PASS: " + roman + " -> " + STR$(result)
        ELSE
            failCount = failCount + 1
            PRINT "FAIL: " + roman + " -> " + STR$(result) + " (expected " + STR$(num) + ")"
        END IF
    NEXT i
    PRINT ""
    PRINT "Results: " + STR$(passCount) + " passed, " + STR$(failCount) + " failed"
    FUNCTION = 0
END FUNCTION
