' Version: 2022-01-03
DIM SHARED Alphabet3
(8) AS LetterBin
' 000 001 010 011 100 101 110 111
Alphabet1(1).Signature = "0"
Alphabet1(2).Signature = "1"
CALL NewAlphabet
(Alphabet1
(), Alphabet2
()) CALL NewAlphabet
(Alphabet2
(), Alphabet3
()) CALL NewAlphabet
(Alphabet3
(), Alphabet4
()) CALL NewAlphabet
(Alphabet4
(), Alphabet5
()) CALL NewAlphabet
(Alphabet5
(), Alphabet6
()) CALL NewAlphabet
(Alphabet6
(), Alphabet7
()) CALL NewAlphabet
(Alphabet7
(), Alphabet8
()) CALL NewAlphabet
(Alphabet8
(), Alphabet9
()) CALL NewAlphabet
(Alphabet9
(), Alphabet10
()) CALL NewAlphabet
(Alphabet10
(), Alphabet11
()) CALL NewAlphabet
(Alphabet11
(), Alphabet12
()) CALL NewAlphabet
(Alphabet12
(), Alphabet13
())
' Specification of weight model.
' Array for test sequences.
' Statistics and metrics:
' Working varaibles:
' Load test data from file or from sub.
'''
' Load test cases at bottom of code:
'ReDim _Preserve TestData(LoadTestData(0))
'''
'''
' Play area:
'Call InitializeModelCustom("-1")
'Call InitializeModelLiteral("0010101000")
'Call InitializeModelIndexed(23)
TestData(1) = "00101000111101101011000010000100001100110110100001100001100000000010011001000101000010001000000111011100000100000000010111010110000000010001110010110111000001011010111100101101010000011101110011010000110010011101011111000001000011001000000010011110011000000010101010011100100000010100010010111100100100100001000010011001101101001101110100011001100000010100000010001000010110100010100011000010001010101011110000000000110000011001000000100001110000100100010000001110000010100000101010100010001101000010"
'TestData(1) = Pathological$("1", 25000)
'TestData(1) = ProtoRand$("", 1000)
'TestData(1) = QBPRNG$(1, 1000)
'''
GuessRatioBest = 0
GuessRatioWorst = 1
GuessStreakBest = 0
WorstBinaryModel = 1
' This outer loop is for cycling through models.
BinaryModelIndex = -1
'''
' Automatic increment of model index number.
BinaryModelIndex = BinaryModelIndex + 1
CALL InitializeModelIndexed
(BinaryModelIndex
) '''
' This enclosed loop is for looping through test strings.
GuessPredicted = -1
GuessCorrect = 0
GuessTotal = 0
GuessStreak = 0
GuessStreakMax = 0
' This core loop goes through ine (literal) bit of a test string per iteration.
' Set upper limit to infinity for game mode.
'''
' Auto-feed Mode:
TheString
= LEFT$(TestData
(m
), n
) '''
'''
' Gaming Mode:
'Call InitializeModelIndexed(16) ' This 5-gram case (16) works well for game mode.
'Call InitializeModelIndexed(18) ' Learning algo discoverd this is good against humans.
'Call InitializeModelIndexed(82) ' Learning algo discoverd this is good against humans.
'Call InitializeModelLiteral("0000101000") ' Experimental default.
'Cls
'Locate 1, 1
'Print "Press LEFT or RIGHT."
'k = 0
'Do: k = _KeyHit: Loop Until ((k = 19200) Or (k = 19712))
'Select Case k
' Case 19200
' TheString = TheString + "0"
' Case 19712
' TheString = TheString + "1"
'End Select
'_KeyClear
'''
FOR k
= 1 TO 10 'UBound(AlphaWeight)
' Reconciliation
IF (GuessPredicted
<> -1) THEN PRINT "I am RIGHT this round." GuessCorrect = GuessCorrect + 1
GuessStreak = GuessStreak + 1
IF (GuessStreak
> GuessStreakMax
) THEN GuessStreakMax
= GuessStreak
Grade(n, 2) = 1
PRINT "I am WRONG this round." GuessStreak = 0
Grade(n, 2) = 0
GuessTotal = GuessTotal + 1
Grade(n, 1) = GuessCorrect / GuessTotal
GuessPredicted = Analyze(TheString, AlphaWeight(), 0)
'''
' Reverse polarity if needed for any reason.
'If (GuessPredicted = 0) Then
' GuessPredicted = 1
'Else
' GuessPredicted = 0
'End If
'''
'Print "I have made a new prediction."
'Print "Press LEFT or RIGHT to test me."
' Draw bottom graph if there's enough room.
CALL PrintGraph
(TheString
, Grade
())
'_Delay .02
'_Limit 240
IF (GuessCorrect
/ GuessTotal
>= GuessRatioBest
) THEN BestBinaryModel = BinaryModelIndex
GuessRatioBest = GuessCorrect / GuessTotal
GuessStreakBest = GuessStreakMax
IF (GuessCorrect
/ GuessTotal
<= GuessRatioWorst
) THEN WorstBinaryModel = BinaryModelIndex
GuessRatioWorst = GuessCorrect / GuessTotal
'_Delay 3
StringPhase(1) = TheStringIn
'For n = 2 To UBound(StringPhase) ' Phase analysis.
' StringPhase(n) = Right$(StringPhase(n - 1), Len(StringPhase(n - 1)) - 1) + Left$(StringPhase(n - 1), 1)
'Next
IF (arrweight
(1) <> 0) THEN CALL CreateHisto
(StringPhase
(), 1, Alphabet1
()) IF (arrweight
(2) <> 0) THEN CALL CreateHisto
(StringPhase
(), 2, Alphabet2
()) IF (arrweight
(3) <> 0) THEN CALL CreateHisto
(StringPhase
(), 3, Alphabet3
()) IF (arrweight
(4) <> 0) THEN CALL CreateHisto
(StringPhase
(), 4, Alphabet4
()) IF (arrweight
(5) <> 0) THEN CALL CreateHisto
(StringPhase
(), 5, Alphabet5
()) IF (arrweight
(6) <> 0) THEN CALL CreateHisto
(StringPhase
(), 6, Alphabet6
()) IF (arrweight
(7) <> 0) THEN CALL CreateHisto
(StringPhase
(), 7, Alphabet7
()) IF (arrweight
(8) <> 0) THEN CALL CreateHisto
(StringPhase
(), 8, Alphabet8
()) IF (arrweight
(9) <> 0) THEN CALL CreateHisto
(StringPhase
(), 9, Alphabet9
()) IF (arrweight
(10) <> 0) THEN CALL CreateHisto
(StringPhase
(), 10, Alphabet10
()) IF (arrweight
(11) <> 0) THEN CALL CreateHisto
(StringPhase
(), 11, Alphabet11
()) IF (arrweight
(12) <> 0) THEN CALL CreateHisto
(StringPhase
(), 12, Alphabet12
()) IF (arrweight
(13) <> 0) THEN CALL CreateHisto
(StringPhase
(), 13, Alphabet13
())
IF (pswitch
= 1) THEN ' Set the last argument >=1 to print stats for that histogram. IF ((LEN(TheStringIn
) >= 1) AND (arrweight
(1) <> 0)) THEN CALL PrintHisto
(Alphabet1
(), 0) IF ((LEN(TheStringIn
) >= 2) AND (arrweight
(2) <> 0)) THEN CALL PrintHisto
(Alphabet2
(), 0) IF ((LEN(TheStringIn
) >= 3) AND (arrweight
(3) <> 0)) THEN CALL PrintHisto
(Alphabet3
(), 0) IF ((LEN(TheStringIn
) >= 4) AND (arrweight
(4) <> 0)) THEN CALL PrintHisto
(Alphabet4
(), 0) IF ((LEN(TheStringIn
) >= 5) AND (arrweight
(5) <> 0)) THEN CALL PrintHisto
(Alphabet5
(), 4) IF ((LEN(TheStringIn
) >= 6) AND (arrweight
(6) <> 0)) THEN CALL PrintHisto
(Alphabet6
(), 0) IF ((LEN(TheStringIn
) >= 7) AND (arrweight
(7) <> 0)) THEN CALL PrintHisto
(Alphabet7
(), 0) IF ((LEN(TheStringIn
) >= 8) AND (arrweight
(8) <> 0)) THEN CALL PrintHisto
(Alphabet8
(), 0) IF ((LEN(TheStringIn
) >= 9) AND (arrweight
(9) <> 0)) THEN CALL PrintHisto
(Alphabet9
(), 0) IF ((LEN(TheStringIn
) >= 10) AND (arrweight
(10) <> 0)) THEN CALL PrintHisto
(Alphabet10
(), 0) IF ((LEN(TheStringIn
) >= 11) AND (arrweight
(11) <> 0)) THEN CALL PrintHisto
(Alphabet11
(), 0) IF ((LEN(TheStringIn
) >= 12) AND (arrweight
(12) <> 0)) THEN CALL PrintHisto
(Alphabet12
(), 0) IF ((LEN(TheStringIn
) >= 13) AND (arrweight
(13) <> 0)) THEN CALL PrintHisto
(Alphabet13
(), 0)
' Set the last argument =1 to print guess for that histogram.
IF ((LEN(TheStringIn
) >= 1) AND (arrweight
(1) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 1, Alphabet1
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 2) AND (arrweight
(2) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 2, Alphabet2
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 3) AND (arrweight
(3) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 3, Alphabet3
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 4) AND (arrweight
(4) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 4, Alphabet4
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 5) AND (arrweight
(5) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 5, Alphabet5
(), Partialguess
(), pswitch
) IF ((LEN(TheStringIn
) >= 6) AND (arrweight
(6) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 6, Alphabet6
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 7) AND (arrweight
(7) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 7, Alphabet7
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 8) AND (arrweight
(8) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 8, Alphabet8
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 9) AND (arrweight
(9) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 9, Alphabet9
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 10) AND (arrweight
(10) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 10, Alphabet10
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 11) AND (arrweight
(11) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 11, Alphabet11
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 12) AND (arrweight
(12) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 12, Alphabet12
(), Partialguess
(), 0) IF ((LEN(TheStringIn
) >= 13) AND (arrweight
(13) <> 0)) THEN CALL MakeGuess
(TheStringIn
, 13, Alphabet13
(), Partialguess
(), 0)
PRINT Partialguess
(k
, 1);
j = 0
r = 0
' Weighted average calculation
r = r + arrweight(k) * Partialguess(k, 1)
j = j + arrweight(k)
r = r / j
r = 1
r = 0
TheReturn = r
Analyze = TheReturn
TheReturn = 0
j = 1
k = 0
IF (arralpha
(n
).Count
>= j
) THEN TheReturn
= TheReturn
+ VAL(RIGHT$(arralpha
(n
).Signature
, 1)) k = k + 1
j = arralpha(n).Count
TheReturn = TheReturn / k
TheReturn = .5
arrguess(wid, 1) = TheReturn
arrguess(wid, 2) = j
'0 to 1023
CALL InitializeModelLiteral
(BIN$
(TheIndexIn
))
AlphaWeight
(k
) = VAL(MID$(Weights
, k
, 1)) AlphaWeight(11) = 0
AlphaWeight(12) = 0
AlphaWeight(13) = 0
AlphaWeight(k) = k ^ 2
AlphaWeight(11) = 0
AlphaWeight(12) = 0
AlphaWeight(13) = 0
' Butchered from the Wiki. Ugliest function ever.
b$
= LEFT$(b$
+ "0000000000", 10) BIN$ = b$
arralpha(n).Count = 0
' Hack j=1 to use base string only.
' Let the loop's upper limit =wid for phase analysis.
IF (MID$(arrseqphase
(j
), k
, wid
) = arralpha
(n
).Signature
) THEN arralpha(n).Count = arralpha(n).Count + 1
j = wid
PRINT arr
(n
).Signature; arr
(n
).Count
SUB NewAlphabet
(arrold
() AS LetterBin
, arrnew
() AS LetterBin
) n = 0
n = n + 1
arrnew(n).Signature = arrold(j).Signature
arrnew(j).Signature = "0" + arrnew(j).Signature
arrnew(j).Signature = "1" + arrnew(j).Signature
IF (LowLimit
< HighLimit
) THEN piv = Partition(arr(), LowLimit, HighLimit)
CALL QuickSort
(arr
(), LowLimit
, piv
- 1) CALL QuickSort
(arr
(), piv
+ 1, HighLimit
)
pivot = arr(HighLimit).Count
i = LowLimit - 1
FOR j
= LowLimit
TO HighLimit
- 1 tmp = arr(j).Count - pivot
i = i + 1
SWAP arr
(i
+ 1), arr
(HighLimit
) Partition = i + 1
TheReturn = TheSeed
IF (Analyze
(TheReturn
, AlphaWeight
(), 0) = 1) THEN TheReturn = TheReturn + "0"
TheReturn = TheReturn + "1"
Pathological$ = TheReturn
DIM WorkingString
AS STRING ' So-called working string. TheReturn = ""
WorkingString = "0100100010" + TheSeed ' ...in case user sends blank seed.
' Change prediction model based on working string.
CALL InitializeModelLiteral
(RIGHT$(WorkingString
, 10)) ' Make prediction based on working string.
' Store the opposite result.
IF (Analyze
(WorkingString
, AlphaWeight
(), 0) = 1) THEN TheReturn = TheReturn + "0" ' Analyze returned a 1.
WorkingString = WorkingString + "0"
TheReturn = TheReturn + "1" ' Analyze returned a 0.
WorkingString = WorkingString + "1"
' Keep working string reasonably short so runtime remains O(L).
IF (LEN(WorkingString
) > 80) THEN WorkingString
= RIGHT$(WorkingString
, 80) ProtoRand$ = TheReturn
TheReturn = TheReturn + "1"
TheReturn = TheReturn + "0"
QBPRNG$ = TheReturn
n = alwayszero
n = n + 1
TestData(n) = a
a = TestData(k)
TestData(k) = ""
TestData
(k
) = TestData
(k
) + MID$(a
, j
, 1) LoadTestFile = n
n = alwayszero
'''
' Percussive cases:
'''
n = n + 1: TestData(n) = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
n = n + 1: TestData(n) = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
n = n + 1: TestData(n) = "0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
n = n + 1: TestData(n) = "1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010"
n = n + 1: TestData(n) = "0001110011000111001100011100110001110011000111001100011100110001110011000111001100011100110001110011000111001100011100110001110011000111001100011100110001110011"
n = n + 1: TestData(n) = "0100010111010001011101000101110100010111010001011101000101110100010111010001011101000101110100010111010001011101000101110100010111010001011101000101110100010111"
'''
' Human samples:
'''
' (from Keybone)
n = n + 1: TestData(n) = "101010101010101010101001010101010101001010111001010101010101010101010100010101010101010100101001010101001100101010001010100101010100101010100101010101010101010011011110010101010100100101010110010011001010011001010100010100101010010101010101010010101010101010010101001010101010100110010101010100101010101010011001001010100101010010101010100101010010101001010100101001010010101010111010100110011001010101010100110101001010101010100101001010111010101010101010100101001010101010010101010101001010101001010101001010100101010100101010010101010101001010101001010101010101001010101001010100101010101010010101010010010101010101010101010010100101010101001010100101001010101001111101010101010100101010110011001010101010101010110101010101101010101010100101010010101010010101010101101110010101001010101010110010100101010101001011010101010100110101010100101010010101010100101010101001010101010101001010101010011010101010101110110100101010111010101011011001011001010101001010101010101010101010011001010101010100101010101010101010010100101"
' (from Keybone)
n = n + 1: TestData(n) = "0101110101100011010100101011001110001011001010001110101111010100111011100100101001010011110101101000101010001010101111001010111010101010100001010101000101101100101111101010010101110110111001000101000011010101010001001001001111101011101010100010110101110101100000101010101110111010100100100001110111100101011110101010001010001110010110111110110010101001001011101000101001011100011101000010101010101101010010110100101101000101111010101110111001010011101111010101000010101111100010101011110101011011110100001010110"
' (from Loudar)
n = n + 1: TestData(n) = "1011001010010100100100110010101010101001010101010101011010010101001010101001010010100110101011010101010101011010101101010101010101010010110101010101100101010101010110101101011010010101010010100110101101001010110101011010010101101010110100101111010101010011011011010010110101010010110100101101010100101011010010101001010101010001011101011010010101011100111010010001101011110010011010001011100110101010010011010101001001010010000101010110001"
' (from Luke)
n = n + 1: TestData(n) = "01100101001010001100001101101111011010010101010110110101001000001111001111110101000101111011010101111101010101101010101001010101011000010101010101001011010100110100110100110011010101010101110101010111111101011010100000001101111000010111000110111001000010100001101010110100000111101011111100001011001010110010110"
' (from Sarafromct)
n = n + 1: TestData(n) = "10101010101011101000011101010111010101010101100111001010100111100001011011110101000001111010101101010000001111110011111110111101110111001110110010000100010101010101010100101011010110101010101010101001000000001111110000011110101010101010100010101110101010101101111111111111111111101010101010101000000"
' (from Spriggs)
n = n + 1: TestData(n) = "10111010101010101010101001010101010101001010101001010101010101010101010101010101010101010101010101010101001010100100100101010101010101001010100101010101010100101010100101010101010101010101001010010110010101010010101010101010101010101010100101001001001010101010101010101010101001010101001001101010010"
' (from Spriggs)
n = n + 1: TestData(n) = "11111011110100101011111111110100000011011110101100111100111111110111101110100111100110011111110101111111010111101111100111110111111111111011100111110111111110010000101011111001110101101010110111110"
' (from Hotpants)
n = n + 1: TestData(n) = "01010100011001010010101010101010101000110101010111101010100100011010101010100100101110010010010100001010101001010101010110010001001011000100100110101001001001010000000001010101101111101001010100010101001001010101000100101001100100010011010101010101010111010010101011101011011010110100100010010100100100010010001001"
' (from [banned user])
n = n + 1: TestData(n) = "11011011011101011010001011001110001101011001001111110000110111011101100100101110110001110011001100111110011011001110100000101001011010001100011100011100011100010011100101110100011011001101000111001111100110111011101110110000111011101010010010011000101100011010001111100100100011100111001100011110001"
LoadTestData = n