Quote Originally Posted by iCountNTrack View Post
So my code returns 0.0625 which is blatantly incorrect as the correct number is 0.3125 if we do exactly 2 consecutive heads or 0.5 if we do 2 or more consecutive heads (3 or 4 in this case). My code is an adaptation of de Moivre formula which works fairly well when the number of trials increases but fails for small number of trials.

I have of course looked at brute force combinatorial analysis but while the code is fairly simple, the calculation quickly becomes intractable as the number of trials increases because for n trials you have 2^n possible permutations, so you can kiss solving 7000 rounds (2^7000) good bye .

I was able to implement a fairly easy sim that reproduces the values. Below is the implementation in VBA if you want to test it in Excel. @Norm please dont hate me for using the built-in RNG

Code:

Sub TestMe()
    Debug.Print ProbabilityOfStreak(2, 0.5, 4, 100000, True)
End Sub

Function ProbabilityOfStreak(l As Long, p As Double, n As Long, simulations As Long, allowLonger As Boolean) As Double
    Dim streakCount As Long
    Dim currentStreak As Long
    Dim i As Long
    Dim j As Long
    Dim successfulSimulations As Long
    
    successfulSimulations = 0
    
    ' Seed the random number generator
    Randomize
    
    ' Randomly generate each trial and count the number of successful simulations with exactly one streak of length l
    For i = 1 To simulations
        currentStreak = 0
        streakCount = 0
        For j = 1 To n
            If Rnd() < p Then
                ' Increment streak if the event occurs
                currentStreak = currentStreak + 1
            Else
                ' Check if the streak ended and was exactly length l or longer based on allowLonger flag
                If (allowLonger And currentStreak >= l) Or (Not allowLonger And currentStreak = l) Then
                    streakCount = streakCount + 1
                End If
                currentStreak = 0
            End If
        Next j
        ' Check streak at the end of the trials
        If (allowLonger And currentStreak >= l) Or (Not allowLonger And currentStreak = l) Then
            streakCount = streakCount + 1
        End If
        
        ' Check if exactly one streak of length l occurred
        If streakCount = 1 Then
            successfulSimulations = successfulSimulations + 1
        End If
    Next i
    
    ' Calculate probability based on sim results
    ProbabilityOfStreak = successfulSimulations / simulations
End Function
Exactly, that's why using combinatorial analysis is not advisable in this type of problems. Not to mention the use of factorials.
A long simulation is much more reliable. Let me give you an example of why combinatorial analysis fails.
Suppose we want to calculate C (1000, 30). The following are 3 values obtained by different routines:
The first one corresponds to the code you posted above (binomialCoefficient).
The next two correspond to two routines of mine.
The correct one is none of the 3.

BC1 = 6427395792647100880
BC2 = 2429608192173745103000302810053683821765033166213128126464
BC3 = 2429608192173745103170443993514153053496720469929012232192


Here is the correct value:

BC4 = 24296081921737451032703898385767507193022226061986 31438800

Your 0.0625 is correct for 4 consecutive heads in 4 tosses. There might be a bug somewhere. Maybe by fixing that, the program will work for these simpler cases.

Sincerely,
Cac