Initial commit — Wordle/letter word solver and scorer

This commit is contained in:
2026-05-10 03:01:15 +00:00
commit 900ace491f
41 changed files with 391999 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
bin/
obj/
packages/
_ReSharper*/
*.suo
*.user
.vs/
+102
View File
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E9E94A89-0A93-49AC-88CE-71132C079180}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Core.Tests</RootNamespace>
<AssemblyName>Core.Tests</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="CsvHelper, Version=27.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.27.2.1\lib\net47\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="MathNet.Numerics, Version=4.15.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MathNet.Numerics.4.15.0\lib\net40\MathNet.Numerics.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.HashCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.HashCode.1.1.1\lib\net461\Microsoft.Bcl.HashCode.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" />
<Reference Include="nunit.framework">
<HintPath>..\References\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DictionarySearcherTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WordFrequencyTests.cs" />
<Compile Include="WordleUtilTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj">
<Project>{87245554-C14C-4760-9AD8-7948F6506522}</Project>
<Name>Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+185
View File
@@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;
namespace Core.Tests
{
[TestFixture]
public class DictionarySearcherTests
{
[Test]
public void FindWords()
{
var dictionarySearcher = new DictionarySearcher();
var results = dictionarySearcher.FindWords("ztuol");
Console.WriteLine(string.Join(" ", results));
}
[Test]
public void ScoreWords()
{
var strings = new[] {"oneword", "another", "onemores", "z"};
foreach (var s in strings)
{
var score = JangleWordScorer.Score(s);
Console.WriteLine(s + " " + score);
}
}
[Test]
public void GroupByScore()
{
var strings = new[] {"oneword", "another", "onemores", "z"};
var scored = JangleWordScorer.GroupByScore(strings);
foreach (var s in scored) Console.WriteLine(s.Key + " " + string.Join(" ", s.Value));
}
[Test]
public void MatchingWords()
{
var dictionarySearcher = new DictionarySearcher();
var matchingWords = dictionarySearcher.MatchingWords("b", "v");
foreach (var matchingWord in matchingWords)
{
Console.WriteLine($"{matchingWord.Item1}, {matchingWord.Item2}");
}
}
[Test]
public void FindWordsIncludeExclude()
{
//extrachisguby
var dictionarySearcher = new DictionarySearcher();
var results = dictionarySearcher.FindWords("lon", "extrachisguby", 5);
Console.WriteLine(string.Join(" ", results));
}
/*[Test]
public void GetLetterPositionFreqTest()
{
var dictionarySearcher = new DictionarySearcher();
var letterPositionFreq = dictionarySearcher.GetLetterPositionFreq(5);
var index = 1;
foreach (var f in letterPositionFreq)
{
Console.Write(index++);
Console.WriteLine(string.Join(", ", f));
}
}*/
[Test]
public void LetterPositionFrequencyTest1()
{
var dictionarySearcher = new DictionarySearcher();
var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
var allWords = dictionarySearcher.FindWords("","",5);
var scoreWords = frequency.ScoreWords(allWords).OrderByDescending(f => f.Item2);
foreach (var sw in scoreWords)
{
Console.WriteLine(sw);
}
}
[Test]
public void LetterPositionFrequencyTest()
{
var dictionarySearcher = new DictionarySearcher();
var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
var results = dictionarySearcher.FindWords("eyr", "nzmodlchwbf", 5);
results = results.Where(r => Regex.IsMatch(r, ".E..Y"));
var scoreWords = frequency.ScoreWords(results).OrderBy(f => f.Item2);
foreach (var sw in scoreWords.Take(5))
{
Console.WriteLine(sw);
}
}
[Test]
public void WordleTest()
{
var dictionarySearcher = new DictionarySearcher();
var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
var crit = new WordleUtil.PositionCriteria[5];
crit[0] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "O" };
crit[1] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "C" };
crit[2] = new WordleUtil.PositionCriteria() { Correct = 'U'};
crit[3] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "OCD" };
crit[4] = new WordleUtil.PositionCriteria() { Correct = null, OtherPosition = "O" };
var results = dictionarySearcher.FindWords("CODU", "XBWINGEPHS", 5);
results = results.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(crit)));
var scoreWords = frequency.ScoreWords(results).OrderBy(f => f.Item2);
foreach (var sw in scoreWords.Take(10))
{
Console.WriteLine(sw);
}
}
[Test]
public void WordleTest2()
{
var dictionarySearcher = new DictionarySearcher();
var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
var wordleState = new WordleUtil.WordleState();
wordleState.Update("ABEAM", new[]
{
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord
});
wordleState.Update("SORUS", new[]
{
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord
});
wordleState.Update("PINKY", new[]
{
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.NotInWord
});
wordleState.Update("DIGIT", new[]
{
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.OtherPosition,
WordleUtil.CharacterResponse.Actual
});
wordleState.Update("FIGHT", new[]
{
WordleUtil.CharacterResponse.NotInWord,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.Actual,
WordleUtil.CharacterResponse.Actual
});
var results = dictionarySearcher.FindWords(wordleState.InWord, wordleState.NotInWord, 5);
results = results.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)));
var scoreWords = frequency.ScoreWords(results).OrderByDescending(f => f.Item2);
foreach (var sw in scoreWords.Take(10))
{
Console.WriteLine(sw);
}
}
}
}
+36
View File
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Core.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Core.Tests")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("4331dcb2-682b-48b8-8bb5-f8663262eedd")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+19
View File
@@ -0,0 +1,19 @@
using System;
using NUnit.Framework;
namespace Core.Tests
{
[TestFixture]
class WordFrequencyTests
{
[Test]
public void WordFreq()
{
var wordFrequency = new WordFrequency();
var door = wordFrequency.GetWordFreq("door");
var unflappable = wordFrequency.GetWordFreq("unflappable");
Assert.That(door, Is.GreaterThan(unflappable));
}
}
}
+637
View File
@@ -0,0 +1,637 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CsvHelper;
using CsvHelper.Configuration;
using MathNet.Numerics.Statistics;
using NUnit.Framework;
namespace Core.Tests
{
[TestFixture]
public class WordleUtilTests
{
private static readonly char[] Alphabet = Enumerable.Range(0, 26).Select(r => Convert.ToChar('A' + r)).ToArray();
[Test]
public void GameTest()
{
var actual = "NAIVE";
var dictionarySearcher = new DictionarySearcher(5);
var frequency = new LetterPositionFrequency(dictionarySearcher, 5);
dictionarySearcher.SortDictionary(frequency);
var wordleState = new WordleUtil.WordleState();
do
{
var results =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)));
//var guess = frequency.ScoreWords(results).OrderBy(f => f.Item2).Last().Item1;
var guess = results.First();
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
Console.WriteLine(guess);
} while (!wordleState.IsSolved());
}
[Test, Explicit]
public void GameTest_NaiveBayes_WriteOutput()
{
var wordleUtil = new WordleUtil();
var dictionarySearcher = new DictionarySearcher(5);
var wordFrequency = new WordFrequency();
var actual = "NAIVE";
var steps = 0;
var wordleState = new WordleUtil.WordleState();
do
{
var constrainedWords =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)))
.OrderByDescending(w => wordFrequency.GetWordFreq(w))
.ToList();
if (constrainedWords.First() == "NAIVE")
{
constrainedWords.RemoveAt(0);
constrainedWords.Add("NAIVE");
}
if (constrainedWords.Contains("WAIVE"))
{
constrainedWords.Remove("WAIVE");
constrainedWords.Add("WAIVE");
}
var letterCountPercents = GetLetterCountPercents(constrainedWords);
SetWordleConstraints(letterCountPercents, wordleState);
var frequency = new LetterPositionFrequency(constrainedWords.ToList(), 5);
var sortedWords = frequency.SortWords(constrainedWords, wordleUtil);
var guess = sortedWords.First();
var highestCounts =
string.Join("",
Enumerable.Range(0, 5).Select(i => letterCountPercents.Last()[i].OrderByDescending(s => s.Count).First().Letter));
WriteLetterCountPercentsCsv(letterCountPercents, constrainedWords, @"o:\tmp\WordleFreq\" + $"{steps}-{guess}", new[] { highestCounts, guess });
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
Console.WriteLine(guess);
steps++;
} while (!wordleState.IsSolved());
}
[Test, Explicit]
public void GameTest_NaiveBayes()
{
var wordleUtil = new WordleUtil();
var dictionarySearcher = new DictionarySearcher(5);
var wordFrequency = new WordFrequency();
var actual = "NAIVE";
var steps = 0;
var wordleState = new WordleUtil.WordleState();
do
{
var constrainedWords =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)))
.OrderByDescending(w => wordFrequency.GetWordFreq(w))
.ToList();
var frequency = new LetterPositionFrequency(constrainedWords.ToList(), 5);
var sortedWords = frequency.SortWords(constrainedWords, wordleUtil);
//sortedWords.Reverse();
var guess = sortedWords.First();
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
Console.WriteLine(guess);
} while (!wordleState.IsSolved());
}
[Test, Explicit]
public void GameTest_NaiveBayes_Reverse()
{
var wordleUtil = new WordleUtil();
var dictionarySearcher = new DictionarySearcher(5);
var wordFrequency = new WordFrequency();
var actual = "NAIVE";
var steps = 0;
var wordleState = new WordleUtil.WordleState();
do
{
var constrainedWords =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)))
.OrderByDescending(w => wordFrequency.GetWordFreq(w))
.ToList();
if (constrainedWords.First() == "NAIVE")
{
constrainedWords.RemoveAt(0);
constrainedWords.Add("NAIVE");
}
if (constrainedWords.Contains("WAIVE"))
{
constrainedWords.Remove("WAIVE");
constrainedWords.Add("WAIVE");
}
var letterCountPercents = GetLetterCountPercents(constrainedWords);
SetWordleConstraints(letterCountPercents, wordleState);
var frequency = new LetterPositionFrequency(constrainedWords.ToList(), 5);
var sortedWords = frequency.SortWords(constrainedWords, wordleUtil);
sortedWords.Reverse();
var bannedWords = new string[] { "TAINT", "AALII", "LAIGH", "SAIDS", "SAINS" };
sortedWords = sortedWords.SkipWhile(bannedWords.Contains).ToList();
var guess = sortedWords.First();
var highestCounts =
string.Join("",
Enumerable.Range(0, 5).Select(i => letterCountPercents.Last()[i].OrderBy(s => s.Count).First().Letter));
WriteLetterCountPercentsCsv(letterCountPercents, constrainedWords, @"o:\tmp\WordleFreqReverse\" + $"{steps}-{guess}", new[] { highestCounts, guess });
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
Console.WriteLine(guess);
steps++;
} while (!wordleState.IsSolved());
}
private static void SetWordleConstraints(List<LetterCountPercent[][]> letterCountPercents, WordleUtil.WordleState wordleState)
{
foreach (var letter in wordleState.NotInWord)
{
var k = letter - 'A';
foreach (var letterCountPercent in letterCountPercents)
{
for (int j = 0; j < 5; j++)
letterCountPercent[j][k].State = "N";
}
}
for (var j = 0; j < wordleState.Criteria.Length; j++)
{
var criteria = wordleState.Criteria[j];
if (criteria.Correct != null)
{
var k = criteria.Correct.Value - 'A';
foreach (var letterCountPercent in letterCountPercents)
{
letterCountPercent[j][k].State = "C";
}
}
if (!string.IsNullOrEmpty(criteria.OtherPosition))
{
foreach (var letter in criteria.OtherPosition)
{
var k = letter - 'A';
foreach (var letterCountPercent in letterCountPercents)
{
letterCountPercent[j][k].State = "P";
}
}
}
}
}
public class LetterCountPercent
{
public char Letter { get; }
public int Count { get; }
public float Percentage { get; }
/// <summary>
/// C: Correct, P: Present, N: Not Present, G: Guess, A: Active
/// </summary>
public string State { get; set; }
public LetterCountPercent(char letter, int count, double percentage, string state)
{
Letter = letter;
Count = count;
Percentage = (float)percentage;
State = state;
}
}
[Test]
public void NotInWordleList()
{
var dictionarySearcher = new DictionarySearcher(5);
var allFiveLeterWords = dictionarySearcher.FindWords("", "", 5);
var wordFrequency = new WordFrequency();
var wordleUtil = new WordleUtil();
var r =
from w in allFiveLeterWords
where !wordleUtil.Words.Contains(w)
let f = wordFrequency.GetWordFreq(w)
select Tuple.Create(w,f);
foreach (var s in r.OrderByDescending(t => t.Item2).Take(20))
{
Console.WriteLine(s);
}
}
[Test, Explicit]
public void LetterFrequenceStatistics_NoConstraints()
{
var frequency = new WordFrequency();
var wordleUtil = new WordleUtil();
var words = wordleUtil.Words.OrderByDescending(w => frequency.GetWordFreq(w)).ToList();
//var dictionarySearcher = new DictionarySearcher(5);
//var words = dictionarySearcher.GetWords().OrderByDescending(w => frequency.GetWordFreq(w)).ToList();
void MoveToFirst(string w)
{
words.Remove(w);
words.Insert(0, w);
}
MoveToFirst("LATER");
MoveToFirst("AFTER");
MoveToFirst("FIRST");
var results = GetLetterCountPercents(words);
var highestCounts =
string.Join("",
Enumerable.Range(0, 5).Select(i => results.Last()[i].OrderByDescending(s => s.Count).First().Letter));
WriteLetterCountPercentsCsv(results, words, @"o:\tmp\WordleFreq\NoConstraint", new []{ highestCounts, "SORES", "CARES"});
}
[Test, Explicit]
public void LetterFrequenceStatistics_NoConstraints_Reverse()
{
var frequency = new WordFrequency();
var wordleUtil = new WordleUtil();
var words = wordleUtil.Words.OrderByDescending(w => frequency.GetWordFreq(w)).ToList();
//var dictionarySearcher = new DictionarySearcher(5);
//var words = dictionarySearcher.GetWords().OrderByDescending(w => frequency.GetWordFreq(w)).ToList();
void MoveToFirst(string w)
{
words.Remove(w);
words.Insert(0, w);
}
MoveToFirst("LATER");
MoveToFirst("AFTER");
MoveToFirst("FIRST");
var results = GetLetterCountPercents(words);
var highestCounts =
string.Join("",
Enumerable.Range(0, 5).Select(i => results.Last()[i].OrderByDescending(s => s.Count).Last().Letter));
WriteLetterCountPercentsCsv(results, words, @"o:\tmp\WordleFreq\NoConstraint", new[] { highestCounts, "SORES", "CARES" });
}
private static List<LetterCountPercent[][]> GetLetterCountPercents(List<string> words)
{
var freqList = new Dictionary<char, int>[5];
for (var i = 0; i < 5; i++)
freqList[i] = Alphabet.ToDictionary(c => c, j => 0);
var wordCount = 0;
var results = new List<LetterCountPercent[][]> ();
foreach (var word in words)
{
wordCount++;
for (var wordIndex = 0; wordIndex < word.Length; wordIndex++)
{
var c = word[wordIndex];
freqList[wordIndex][c]++;
}
// get percentage
var freqPercents =
freqList.Select(
f => (
from cFreqs in f
select Tuple.Create(cFreqs.Key, cFreqs.Value * 1.0 / wordCount))
.ToDictionary(cp => cp.Item1, cp => cp.Item2))
.ToArray();
// normalize
var maxPercent = freqPercents.Max(fp => fp.Max(p => p.Value));
foreach (var freqPercent in freqPercents)
foreach (var c in freqPercent.Keys.ToArray())
freqPercent[c] /= maxPercent;
var result =
(from letter in Enumerable.Range(0, 5)
let item =
(from freq in freqList[letter]
from freqPercent in freqPercents[letter]
where freq.Key == freqPercent.Key
let state = word[letter] == freq.Key ? "A" : null
select new LetterCountPercent(freq.Key, freq.Value, freqPercent.Value, state)).ToArray()
select item).ToArray();
results.Add(result);
}
return results;
}
private static void WriteLetterCountPercentsCsv(IReadOnlyList<LetterCountPercent[][]> results, IReadOnlyList<string> words, string folder, IList<string> g = null)
{
// hack:
IList<string> guesses = null;
if (g != null)
{
guesses = new List<string>(g);
guesses.Add(guesses.Last());
}
try
{
if (Directory.Exists(folder))
Directory.Delete(folder, true);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Directory.CreateDirectory(folder);
using (var writer = new StreamWriter(Path.Combine(folder, "freq_words.csv")))
{
writer.WriteLine("word");
writer.WriteLine(" ");
writer.WriteLine(" ");
for (int i = 0; i < words.Count; i++)
{
writer.WriteLine(words[i]);
}
writer.WriteLine(" ");
writer.WriteLine(" ");
for (int i = 0; i < (guesses?.Count ?? 0); i++)
{
writer.WriteLine(guesses[i]);
}
}
for (int j = 0; j < 5; j++)
{
using (var writer = new StreamWriter(Path.Combine(folder, "freq_letterCounts_" + j + ".csv")))
{
writer.WriteLine(string.Join(",", Alphabet));
writer.WriteLine(string.Join(",", results[0][j].Select(lcp => 0)));
//writer.WriteLine(string.Join(",", results[0][j].Select(lcp => 0)));
for (var index = 0; index < results.Count + 3 + (guesses?.Count ?? 0); index++)
{
var indexX = index < results.Count ? index : results.Count - 1;
writer.WriteLine(string.Join(",", results[indexX][j].Select(lcp => lcp.Count)));
}
}
}
for (int j = 0; j < 5; j++)
{
using (var writer = new StreamWriter(Path.Combine(folder, "freq_letterPercents_" + j + ".csv")))
{
writer.WriteLine(string.Join(",", Alphabet));
writer.WriteLine(string.Join(",", results[0][j].Select(lcp => 0)));
writer.WriteLine(string.Join(",", results[0][j].Select(lcp => 0)));
for (var index = 0; index < results.Count + 2 + (guesses?.Count ?? 0); index++)
{
var indexX = index < results.Count ? index : results.Count - 1;
writer.WriteLine(string.Join(",", results[indexX][j].Select(lcp => lcp.Percentage)));
}
}
}
for (int j = 0; j < 5; j++)
{
using (var writer = new StreamWriter(Path.Combine(folder, "freq_letterState_" + j + ".csv")))
{
writer.WriteLine(string.Join(",", Alphabet));
writer.WriteLine(string.Join(",", results[0][j].Select(lcp => lcp.State == "A" || string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
writer.WriteLine(string.Join(",", results[0][j].Select(lcp => lcp.State == "A" || string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
for (var index = 0; index < results.Count; index++)
{
writer.WriteLine(string.Join(",", results[index][j].Select(lcp => string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
}
writer.WriteLine(string.Join(",", results[results.Count - 1][j].Select(lcp => lcp.State == "A" || string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
writer.WriteLine(string.Join(",", results[results.Count - 1][j].Select(lcp => lcp.State == "A" || string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
for (int e = 0; e < (guesses?.Count ?? 0); e++)
{
var letter = guesses[e][j];
writer.WriteLine(string.Join(",", results[results.Count - 1][j].Select(lcp => lcp.Letter == letter ? "G" : lcp.State == "A" || string.IsNullOrEmpty(lcp.State) ? " " : lcp.State)));
}
}
}
}
[Test]
public void NotInDictionary()
{
var dictionarySearcher = new DictionarySearcher(5);
var allFiveLeterWords = dictionarySearcher.FindWords("", "", 5);
var wordFrequency = new WordFrequency();
var wordleUtil = new WordleUtil();
var r =
from w in wordleUtil.Words
where !allFiveLeterWords.Contains(w)
let f = wordFrequency.GetWordFreq(w)
select Tuple.Create(w, f);
foreach (var s in r.OrderByDescending(t => t.Item2).Take(20))
{
Console.WriteLine(s);
}
}
[Test, Explicit]
public void WordleStats()
{
var actual = "GROUP";
var dictionarySearcher = new DictionarySearcher(5);
var allFiveLeterWords = dictionarySearcher.FindWords("", "");
var wordleUtil = new WordleUtil();
var frequency = new LetterPositionFrequency(wordleUtil, 5);
dictionarySearcher.SortDictionary(frequency);
// Console.WriteLine(dictionarySearcher.FindWords("", "", 5).Count());
var solutionSteps = new List<double>();
Parallel.ForEach(allFiveLeterWords, nextWord =>
{
var guess = nextWord;
var response = WordleUtil.GetGuessResult(actual, guess);
var wordleState = new WordleUtil.WordleState();
wordleState.Update(guess, response);
//Console.WriteLine("----");
//Console.WriteLine(guess);
var steps = 1;
while (!wordleState.IsSolved())
{
var results =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)));
guess = results.First();
//guess = frequency.ScoreWords(results).OrderBy(f => f.Item2).Last().Item1;
response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
//Console.WriteLine(guess);
steps++;
}
solutionSteps.Add(steps);
});
//Console.WriteLine(string.Join(",", solutionSteps));
Console.WriteLine($"Mean: {solutionSteps.Mean()}, StdDev: {solutionSteps.StandardDeviation()}");
//Console.WriteLine(solutionSteps.Sum() * 1d / solutionSteps.Count );
}
[Test]
public void RepeatedLettersStatistics()
{
var wordleUtil = new WordleUtil();
var re =
from w in wordleUtil.Words
let repeats = WordleUtil.RepeatedLettersCount(w)
group repeats by repeats
into g
select g;
var max = re.Max(r => r.Count());
Console.WriteLine(string.Join(", ", re.Select(r => r.Key + ": " + r.Count() + $" {(r.Count() * 1.0) / max}")));
Console.WriteLine(string.Join(", ", wordleUtil.Words.Where(w => WordleUtil.RepeatedLettersCount(w) == 3)));
Console.WriteLine(string.Join(", ", wordleUtil.Words.Where(w => WordleUtil.RepeatedLettersCount(w) == 2)));
Console.WriteLine(string.Join(", ", wordleUtil.Words.Where(w => WordleUtil.RepeatedLettersCount(w) == 1)));
}
[Test]
public void SolveAllWordleWords_SortedDictionary()
{
var dictionarySearcher = new DictionarySearcher(5);
var wordleUtil = new WordleUtil();
var frequency = new LetterPositionFrequency(wordleUtil, 5);
dictionarySearcher.SortDictionary(frequency);
var solutionSteps = new List<double>();
Parallel.ForEach(wordleUtil.Words, actual =>
{
var steps = 0;
var wordleState = new WordleUtil.WordleState();
do
{
var results =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)));
if (steps <= 1)
results = results.SkipWhile(WordleUtil.RepeatedLetters);
var guess = results.First();
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
//Console.WriteLine(guess);
steps++;
} while (!wordleState.IsSolved());
solutionSteps.Add(steps);
});
Console.WriteLine($"Mean: {solutionSteps.Mean()}, StdDev: {solutionSteps.StandardDeviation()}");
}
[Test]
public void SolveAllWordleWords_NaiveBayes()
{
var dictionarySearcher = new DictionarySearcher(5);
var wordleUtil = new WordleUtil();
var solutionSteps = new List<double>();
Parallel.ForEach(wordleUtil.Words, actual =>
{
var steps = 0;
var wordleState = new WordleUtil.WordleState();
do
{
var results =
dictionarySearcher
.FindWords(wordleState.InWord, wordleState.NotInWord, 5)
.Where(r => Regex.IsMatch(r, WordleUtil.GetRegexRestrictions(wordleState.Criteria)))
.ToList();
var frequency = new LetterPositionFrequency(results, 5);
results = frequency.SortWords(results, wordleUtil);
var guess = results.First();
var response = WordleUtil.GetGuessResult(actual, guess);
wordleState.Update(guess, response);
//Console.WriteLine(guess);
steps++;
} while (!wordleState.IsSolved());
solutionSteps.Add(steps);
});
Console.WriteLine($"Mean: {solutionSteps.Mean()}, StdDev: {solutionSteps.StandardDeviation()}");
}
}
}
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CsvHelper" version="27.2.1" targetFramework="net472" />
<package id="MathNet.Numerics" version="4.15.0" targetFramework="net40" requireReinstallation="true" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net472" />
<package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net472" />
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
</packages>
+81
View File
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{87245554-C14C-4760-9AD8-7948F6506522}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Core</RootNamespace>
<AssemblyName>Core</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="C5">
<HintPath>..\References\C5.dll</HintPath>
</Reference>
<Reference Include="MathNet.Numerics, Version=4.15.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MathNet.Numerics.4.15.0\lib\net40\MathNet.Numerics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DictionarySearcher.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="JangleWordScorer.cs" />
<Compile Include="LetterPositionFrequency.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WordFrequency.cs" />
<Compile Include="WordleUtil.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="all.num.o5.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="TWL06.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="WordleWords.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+146
View File
@@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using C5;
namespace Core
{
public class DictionarySearcher
{
static HashBag<char> GetLettersBag(string letters)
{
var hashBag = new HashBag<char>();
hashBag.AddAll(letters.Canonicalize().ToCharArray());
return hashBag;
}
readonly struct DictWord
{
public readonly string Word;
public readonly HashBag<char> CharBag;
public DictWord(string word) : this()
{
Word = word;
CharBag = GetLettersBag(word);
}
public static implicit operator DictWord(string s) => new DictWord(s);
public static implicit operator string(DictWord dw) => dw.Word;
public char[] ToCharArray() => Word.ToCharArray();
public bool Contains(char c) => Word.Contains(c);
public int Length => Word.Length;
public bool StartsWith(string s) => Word.StartsWith(s);
public string Substring(int startIndex) => Word.Substring(startIndex);
}
private class DictWordComprer : IComparer<DictWord>
{
private readonly IComparer<string> _comparer;
public DictWordComprer(IComparer<string> comparer)
{
_comparer = comparer;
}
public int Compare(DictWord x, DictWord y)
{
return _comparer.Compare(x, y);
}
}
private readonly List<DictWord> _dictionary;
public DictionarySearcher(int? characterCount = null)
: this(@"TWL06.txt", characterCount)
{
}
public DictionarySearcher(string filename, int? characterCount = null)
: this(filename.GetFileLines(), characterCount)
{
}
public DictionarySearcher(IEnumerable<string> words, int? characterCount = null)
{
_dictionary = new List<DictWord>();
foreach (var word in words)
{
if (characterCount != null && word.Length != characterCount)
continue;
var w = word.Canonicalize();
_dictionary.Add(w);
}
}
public System.Collections.Generic.IList<string> GetWords()
{
return _dictionary.Select(d => d.Word).ToList();
}
public void SortDictionary(IComparer<string> comparer)
{
_dictionary.Sort(new DictWordComprer(comparer));
}
public IEnumerable<string> FindWords(string letters)
{
var hashBag = new HashBag<char>();
hashBag.AddAll(letters.Canonicalize().ToCharArray());
return from w in _dictionary
where hashBag.ContainsAll(w.ToCharArray())
select w.Word;
}
public IEnumerable<string> FindWords(string includeLetters, string excludeLetters)
{
var excludeBag = GetLettersBag(excludeLetters);
return from w in _dictionary
where w.CharBag.ContainsAll(includeLetters.Canonicalize())
&& excludeBag.All(c => !w.Contains(c))
select w.Word;
}
public IEnumerable<string> FindWords(string includeLetters, string excludeLetters, int? len)
{
return
from w in FindWords(includeLetters, excludeLetters)
where !len.HasValue || w.Length == len.Value
select w;
}
public IEnumerable<Tuple<string, string>> MatchingWords(string firstSelector, string secondSelector)
{
var firstSet = _dictionary.Where(w => w.StartsWith(firstSelector.Canonicalize())).GroupBy(w => w.Length)
.ToList();
var secondSet = _dictionary.Where(w => w.StartsWith(secondSelector.Canonicalize())).GroupBy(w => w.Length)
.ToList();
return from len in firstSet.Select(g => g.Key)
from w1 in firstSet.Where(g => g.Key == len)
from w2 in secondSet.Where(g => g.Key == len)
from ww1 in w1
from ww2 in w2
where ww1.Substring(1).Equals(ww2.Substring(1))
select Tuple.Create(ww1.Word, ww2.Word);
}
/*public Dictionary<char, int>[] GetLetterPositionFreq(int wordLen)
{
var ws = _dictionary.Where(w => w.Length == wordLen).ToList();
var freqList = new Dictionary<char, int>[wordLen];
for (var i = 0; i < wordLen; i++)
{
var letters = Enumerable.Range(0, 26).Select(r => Convert.ToChar('A' + r));
freqList[i] =
letters.ToDictionary(c => c,
c => ws.Count(w => w.Word[i] == c)
);
}
return freqList;
}*/
}
}
+27
View File
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.IO;
namespace Core
{
public static class Extensions
{
public static string Canonicalize(this string s)
{
return s.ToUpperInvariant();
}
public static IEnumerable<string> GetFileLines(this string filename)
{
using (var sr = File.OpenText(filename))
{
while (true)
{
var line = sr.ReadLine();
if (line == null)
yield break;
yield return line;
}
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.Linq;
namespace Core
{
public static class JangleWordScorer
{
private static readonly IDictionary<char, int> _scores = new Dictionary<char, int>(26);
static JangleWordScorer()
{
foreach (var ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
switch (ch)
{
case 'Z':
case 'J':
case 'Q':
case 'K':
case 'X':
_scores.Add(ch, 3);
break;
case 'H':
case 'B':
case 'Y':
case 'M':
case 'C':
case 'F':
case 'W':
_scores.Add(ch, 2);
break;
default:
_scores.Add(ch, 1);
break;
}
}
public static int Score(string str)
{
return
(from c in str.Canonicalize().ToCharArray()
let score = _scores[c]
select score).Sum();
}
public static IDictionary<int, IEnumerable<string>> GroupByScore(IEnumerable<string> st)
{
return
(from s in st
let score = Score(s)
group s by score
into g
orderby g.Key descending
let vals = g.Select(v => v)
select new {g.Key, vals}).ToDictionary(d => d.Key, d => d.vals);
}
}
}
+83
View File
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Core
{
public class LetterPositionFrequency : IComparer<string>
{
private readonly Dictionary<char, int>[] _letterFrequencies;
private LetterPositionFrequency(Dictionary<char, int>[] letterFrequencies)
{
_letterFrequencies = letterFrequencies;
}
public LetterPositionFrequency(DictionarySearcher dictionarySearcher, int wordLen)
: this(GetLetterPositionFreq(dictionarySearcher.GetWords(), wordLen))
{
}
public LetterPositionFrequency(WordleUtil wordleUtil, int wordLen)
: this(GetLetterPositionFreq(wordleUtil.Words, wordLen))
{
}
public LetterPositionFrequency(IList<string> words, int wordLen)
: this(GetLetterPositionFreq(words, wordLen))
{
}
public static Dictionary<char, int>[] GetLetterPositionFreq(IList<string> words, int wordLen)
{
var ws = words.Where(w => w.Length == wordLen).ToList();
var freqList = new Dictionary<char, int>[wordLen];
for (var i = 0; i < wordLen; i++)
{
var letters = Enumerable.Range(0, 26).Select(r => Convert.ToChar('A' + r));
freqList[i] =
letters.ToDictionary(c => c,
c => ws.Count(w => w[i] == c)
);
}
return freqList;
}
public IEnumerable<Tuple<string, int>> ScoreWords(IEnumerable<string> words, WordleUtil wordleUtil = null)
{
return
from word in words
let score =
word.Select((c, i) => _letterFrequencies[i][c]).Sum()
select
wordleUtil != null
? Tuple.Create(word, Convert.ToInt32(wordleUtil.FactorRepeatedLetters(word, score)))
: Tuple.Create(word, score)
;
}
public List<string> SortWords(IEnumerable<string> words, WordleUtil wordleUtil = null)
{
return ScoreWords(words, wordleUtil)
.OrderByDescending(w => w.Item2)
.Select(w => w.Item1)
.ToList();
}
private int ScoreWord(string word)
{
return word.Select((c, i) => _letterFrequencies[i][c]).Sum();
}
public int Compare(string x, string y)
{
return ScoreWord(y).CompareTo(ScoreWord(x));
}
}
}
+36
View File
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Core")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("40731b2b-b149-4112-887f-21941a4272a0")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+178691
View File
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Core
{
public class WordFrequency : IComparer<string>
{
private readonly Dictionary<string, int> _dictionary;
public WordFrequency()
: this(@"all.num.o5.txt")
{
}
private static IEnumerable<Tuple<string, int>> ParseWordFreq(IEnumerable<string> lines)
{
var regex = new Regex("[a-z]+");
return
from line in lines
select line.Split(' ')
into fields
where fields.Length == 4 && regex.Match(fields[1]).Success
let word = fields[1]
let freq = int.Parse(fields[0])
select new Tuple<string, int>(word.Canonicalize(), freq);
}
public WordFrequency(string filename)
: this(ParseWordFreq(filename.GetFileLines()))
{
}
public WordFrequency(IEnumerable<Tuple<string, int>> words)
{
_dictionary = new Dictionary<string, int>();
foreach (var wf in words.Where(wf => !_dictionary.ContainsKey(wf.Item1)))
_dictionary.Add(wf.Item1, wf.Item2);
}
public int GetWordFreq(string word)
{
return _dictionary.ContainsKey(word) ? _dictionary[word] : 0;
}
public int Compare(string x, string y)
{
return _dictionary[x].CompareTo(_dictionary[y]);
}
}
}
+188
View File
@@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Core
{
public class WordleUtil
{
public enum CharacterResponse
{
Actual,
OtherPosition,
NotInWord
}
public struct PositionCriteria
{
public char? Correct;
public string OtherPosition;
public string GetRegexRestriction() =>
Correct.HasValue
? Correct.Value.ToString()
: !string.IsNullOrEmpty(OtherPosition)
? "[^" + OtherPosition + "]"
: ".";
public void RemoveLetter(char letter)
{
OtherPosition = OtherPosition?.Replace(letter.ToString(), string.Empty);
}
}
public class WordleState
{
public string InWord { get; private set; } = string.Empty;
public string NotInWord { get; private set; } = string.Empty;
public PositionCriteria[] Criteria { get; } = new PositionCriteria[5];
public bool IsSolved() => Criteria.All(c => c.Correct.HasValue);
private void AddInWord(char letter)
{
if (!InWord.Contains(letter))
InWord += letter;
}
private void AddNotInWord(char letter)
{
if (!NotInWord.Contains(letter))
NotInWord += letter;
}
public void Update(string word, CharacterResponse[] response)
{
for (int i = 0; i < 5; i++)
{
var letter = word[i];
switch (response[i])
{
case CharacterResponse.Actual:
// remove this letter from the criteria
foreach (var positionCriteria in Criteria)
positionCriteria.RemoveLetter(letter);
AddInWord(letter);
Criteria[i].Correct = letter;
break;
case CharacterResponse.OtherPosition:
AddInWord(letter);
Criteria[i].OtherPosition += letter;
break;
case CharacterResponse.NotInWord:
AddNotInWord(letter);
break;
}
}
}
}
public static string GetRegexRestrictions(PositionCriteria[] criteria)
{
return
criteria
.Aggregate(string.Empty,
(r, criterion)
=> r + criterion.GetRegexRestriction()
);
}
public IList<string> Words { get; }
private Dictionary<int, double> _repeatedLetterFactor;
public WordleUtil()
: this(@"WordleWords.txt")
{
}
public WordleUtil(string filename)
: this(filename.GetFileLines())
{
}
public WordleUtil(IEnumerable<string> words)
{
Words = new List<string>();
foreach (var word in words)
{
var w = word.Canonicalize();
var split = w.Split(',');
Words.Add(split[0]);
}
Words.Remove("ADMIN");
Words.Remove("INBOX");
var re =
from w in Words
let repeats = RepeatedLettersCount(w)
group repeats by repeats
into g
select g;
var max = re.Max(r => r.Count());
_repeatedLetterFactor =
re.Select(r => Tuple.Create(r.Key, r.Count() * 1.0 / max))
.ToDictionary(s => s.Item1, s => s.Item2);
}
public static CharacterResponse[] GetGuessResult(string actual, string guess)
{
if (actual.Length != 5 || guess.Length != 5)
throw new ArgumentOutOfRangeException("not right size word or guess");
var response = new CharacterResponse[5];
for (var i = 0; i < 5; i++)
{
if (guess[i] == actual[i])
response[i] = CharacterResponse.Actual;
else if (actual.Contains(guess[i]))
response[i] = CharacterResponse.OtherPosition;
else
response[i] = CharacterResponse.NotInWord;
}
return response;
}
public static bool RepeatedLetters(string word)
{
var uniqueLetters = new HashSet<char>();
foreach (var c in word)
uniqueLetters.Add(c);
return uniqueLetters.Count < word.Length;
}
public static int RepeatedLettersCount(string word)
{
var uniqueLetters = new HashSet<char>();
foreach (var c in word)
uniqueLetters.Add(c);
return word.Length - uniqueLetters.Count;
}
public double FactorRepeatedLetters(string word, double score)
{
return score * _repeatedLetterFactor[RepeatedLettersCount(word)];
}
public Dictionary<char, int>[] GetLetterPositionFreq(int wordLen)
{
var ws = Words.Where(w => w.Length == wordLen).ToList();
var freqList = new Dictionary<char, int>[wordLen];
for (var i = 0; i < wordLen; i++)
{
var letters = Enumerable.Range(0, 26).Select(r => Convert.ToChar('A' + r));
freqList[i] =
letters.ToDictionary(c => c,
c => ws.Count(w => w[i] == c)
);
}
return freqList;
}
}
}
+2316
View File
File diff suppressed because it is too large Load Diff
+208657
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MathNet.Numerics" version="4.15.0" targetFramework="net40" />
</packages>
+73
View File
@@ -0,0 +1,73 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30907.101
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LetterWords", "LetterWords\LetterWords.csproj", "{0C0C6B42-4091-4024-BBB2-BED42543DBF4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{87245554-C14C-4760-9AD8-7948F6506522}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Tests", "Core.Tests\Core.Tests.csproj", "{E9E94A89-0A93-49AC-88CE-71132C079180}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WordleSolve", "WordleSolve\WordleSolve.csproj", "{A2B8B113-F917-438D-9738-C14153C35A0C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Debug|Any CPU.ActiveCfg = Debug|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Debug|Mixed Platforms.Build.0 = Debug|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Debug|x86.ActiveCfg = Debug|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Debug|x86.Build.0 = Debug|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Release|Any CPU.ActiveCfg = Release|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Release|Mixed Platforms.ActiveCfg = Release|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Release|Mixed Platforms.Build.0 = Release|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Release|x86.ActiveCfg = Release|x86
{0C0C6B42-4091-4024-BBB2-BED42543DBF4}.Release|x86.Build.0 = Release|x86
{87245554-C14C-4760-9AD8-7948F6506522}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Debug|x86.ActiveCfg = Debug|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Release|Any CPU.Build.0 = Release|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{87245554-C14C-4760-9AD8-7948F6506522}.Release|x86.ActiveCfg = Release|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Debug|x86.ActiveCfg = Debug|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Release|Any CPU.Build.0 = Release|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E9E94A89-0A93-49AC-88CE-71132C079180}.Release|x86.ActiveCfg = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|x86.ActiveCfg = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Debug|x86.Build.0 = Debug|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|Any CPU.Build.0 = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|x86.ActiveCfg = Release|Any CPU
{A2B8B113-F917-438D-9738-C14153C35A0C}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06840DF1-6D7B-4305-B5D1-474F8647FECB}
EndGlobalSection
EndGlobal
+2
View File
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=wordle/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+8
View File
@@ -0,0 +1,8 @@
<Application x:Class="LetterWords.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
+16
View File
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace LetterWords
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
+109
View File
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{0C0C6B42-4091-4024-BBB2-BED42543DBF4}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LetterWords</RootNamespace>
<AssemblyName>LetterWords</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj">
<Project>{87245554-C14C-4760-9AD8-7948F6506522}</Project>
<Name>Core</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+16
View File
@@ -0,0 +1,16 @@
<Window x:Class="LetterWords.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="346" Width="481">
<Viewbox Stretch="Uniform" VerticalAlignment="Top">
<StackPanel Width="379">
<StackPanel Orientation="Horizontal">
<TextBox Name="textBox1" Width="218" AcceptsReturn="False" KeyUp="textBox1_KeyUp" />
<Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" />
</StackPanel>
<DockPanel Height="231" Width="376">
<TextBlock Name="textBlock1" />
</DockPanel>
</StackPanel>
</Viewbox>
</Window>
+51
View File
@@ -0,0 +1,51 @@
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using Core;
namespace LetterWords
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private DictionarySearcher _dictionarySearcher;
private WordFrequency _wordFrequency;
public MainWindow()
{
InitializeComponent();
_dictionarySearcher = new DictionarySearcher();
_wordFrequency = new WordFrequency();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var text = textBox1.Text;
var foundWords = _dictionarySearcher.FindWords(text);
var scoredWords = JangleWordScorer.GroupByScore(foundWords);
textBlock1.Text = string.Empty;
foreach (var s in scoredWords)
{
var words = from w in s.Value
let wordFrequency = _wordFrequency.GetWordFreq(w.ToLower())
orderby wordFrequency descending
select w;
textBlock1.Text += (s.Key + " " + string.Join(" ", words));
textBlock1.Text += Environment.NewLine;
}
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key != Key.Enter) return;
// your event handler here
e.Handled = true;
button1_Click(sender, null);
}
}
}
+55
View File
@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LetterWords")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("LetterWords")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+71
View File
@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.235
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LetterWords.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LetterWords.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
+117
View File
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+30
View File
@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.235
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace LetterWords.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
+7
View File
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
<Application x:Class="WordleSolve.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WordleSolve"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace WordleSolve
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
+10
View File
@@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
+12
View File
@@ -0,0 +1,12 @@
<Window x:Class="WordleSolve.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WordleSolve"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
+28
View File
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WordleSolve
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>