Initial commit — Wordle/letter word solver and scorer
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
bin/
|
||||
obj/
|
||||
packages/
|
||||
_ReSharper*/
|
||||
*.suo
|
||||
*.user
|
||||
.vs/
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+208657
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MathNet.Numerics" version="4.15.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
)]
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user