2023-07-01 11:58:00 -04:00
Option Compare Binary
Option Explicit On
Option Infer On
Option Strict On
Imports System . Text . RegularExpressions
#Const USE_REGEX = False
Module Program
' Supports both local and remote files
2026-02-01 16:33:20 -08:00
Const WORDLIST_URI = " https://web.archive.org/web/20240920144647if_/http://wiki.puzzlers.org/pub/wordlists/unixdict.txt "
2023-07-01 11:58:00 -04:00
' The support factor of a word for EI or IE is the number of occurrences that support the rule minus the number that oppose it.
' I.e., for IE:
' - increased when not preceded by C
' - decreased when preceded by C
' and for EI:
' - increased when preceded by C
' - decreased when not preceded by C
Private Function GetSupportFactor ( word As String ) As ( IE As Integer , EI As Integer )
Dim IE , EI As Integer
' Enumerate the letter pairs in the word.
For i = 0 To word . Length - 2
Dim pair = word . Substring ( i , 2 )
' Instances at the beginning of a word count towards the factor and are treated as not preceded by C.
Dim prevIsC As Boolean = i > 0 AndAlso String . Equals ( word ( i - 1 ) , " c "c , StringComparison . OrdinalIgnoreCase )
If pair . Equals ( " ie " , StringComparison . OrdinalIgnoreCase ) Then
IE += If ( Not prevIsC , 1 , - 1 )
ElseIf pair . Equals ( " ei " , StringComparison . OrdinalIgnoreCase ) Then
EI += If ( prevIsC , 1 , - 1 )
End If
Next
If Math . Abs ( IE ) > 1 Or Math . Abs ( EI ) > 1 Then Debug . WriteLine ( $ " {word}: {GetSupportFactor} " )
Return ( IE , EI )
End Function
' Returns the number of words that support or oppose the rule.
Private Function GetPlausabilities ( words As IEnumerable ( Of String ) ) As ( ieSuppCount As Integer , ieOppCount As Integer , eiSuppCount As Integer , eiOppCount As Integer )
Dim ieSuppCount , ieOppCount , eiSuppCount , eiOppCount As Integer
For Each word In words
Dim status = GetSupportFactor ( word )
If status . IE > 0 Then
ieSuppCount += 1
ElseIf status . IE < 0 Then
ieOppCount += 1
End If
If status . EI > 0 Then
eiSuppCount += 1
ElseIf status . EI < 0 Then
eiOppCount += 1
End If
Next
Return ( ieSuppCount , ieOppCount , eiSuppCount , eiOppCount )
End Function
' Takes entire file instead of individual words.
' Returns the number of instances of IE or EI that support or oppose the rule.
Private Function GetPlausabilitiesRegex ( words As String ) As ( ieSuppCount As Integer , ieOppCount As Integer , eiSuppCount As Integer , eiOppCount As Integer )
' Gets number of occurrences of the pattern, case-insensitive.
Dim count = Function ( pattern As String ) Regex . Matches ( words , pattern , RegexOptions . IgnoreCase ) . Count
Dim ie = count ( " [^c]ie " )
Dim ei = count ( " [^c]ei " )
Dim cie = count ( " cie " )
Dim cei = count ( " cei " )
Return ( ie , cie , cei , ei )
End Function
Sub Main ( )
Dim file As String
Dim wc As New Net . WebClient ( )
Try
Console . WriteLine ( " Fetching file... " )
file = wc . DownloadString ( WORDLIST_URI )
Console . WriteLine ( " Success. " )
Console . WriteLine ( )
Catch ex As Net . WebException
Console . WriteLine ( ex . Message )
Exit Sub
Finally
wc . Dispose ( )
End Try
#If USE_REGEX Then
Dim res = GetPlausabilitiesRegex ( file )
#Else
Dim words = file . Split ( { vbCr , vbLf } , StringSplitOptions . RemoveEmptyEntries )
Dim res = GetPlausabilities ( words )
#End If
Dim PrintResult =
Function ( suppCount As Integer , oppCount As Integer , printEI As Boolean ) As Boolean
Dim ratio = suppCount / oppCount ,
plausible = ratio > 2
#If Not USE_REGEX Then
Console . WriteLine ( $ " Words with no instances of {If(printEI, " EI " , " IE " )} or equal numbers of supporting/opposing occurrences: {words.Length - suppCount - oppCount} " )
#End If
Console . WriteLine ( $ " Number supporting: {suppCount} " )
Console . WriteLine ( $ " Number opposing: {oppCount} " )
Console . WriteLine ( $ " {suppCount}/{oppCount}={ratio:N3} " )
Console . WriteLine ( $ " Rule therefore IS {If(plausible, "" , " NOT " )}plausible. " )
Return plausible
End Function
#If USE_REGEX Then
Console . WriteLine ( $ " Total occurrences of IE: {res.ieOppCount + res.ieSuppCount} " )
Console . WriteLine ( $ " Total occurrences of EI: {res.eiOppCount + res.eiSuppCount} " )
#Else
Console . WriteLine ( $ " Total words: {words.Length} " )
#End If
Console . WriteLine ( )
Console . WriteLine ( " "" IE is not preceded by C "" " )
Dim iePlausible = PrintResult ( res . ieSuppCount , res . ieOppCount , False )
Console . WriteLine ( )
Console . WriteLine ( " "" EI is preceded by C "" " )
Dim eiPlausible = PrintResult ( res . eiSuppCount , res . eiOppCount , True )
Console . WriteLine ( )
Console . WriteLine ( $ " Rule thus overall IS {If(iePlausible AndAlso eiPlausible, "" , " NOT " )}plausible. " )
End Sub
End Module