Skip to content

Instantly share code, notes, and snippets.

@amoerie
Created July 1, 2016 11:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amoerie/8990c4543b5a8e214ff3066ca4bd7bf6 to your computer and use it in GitHub Desktop.
Save amoerie/8990c4543b5a8e214ff3066ca4bd7bf6 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Wordlist {
public class Program {
public static void Main(string[] args) {
IList<IWord> words = ReadWords().ToList();
var stopwatch = new Stopwatch();
stopwatch.Start();
const int requestedLength = 6;
// index all words by their length
ILookup<int, IWord> wordsByLength = words.ToLookup(w => w.Length);
// create a set of all words of the desired total length. This makes "Contains" checks blazing fast
var wordEqualityComparer = new WordEqualityComparer();
ISet<IWord> wordsOfRequestedLength = new HashSet<IWord>(wordsByLength[requestedLength], wordEqualityComparer);
var combinations = Enumerable.Range(1, requestedLength - 1)
// start with all words of length "i"
.SelectMany(i => wordsByLength[i]
// create a combination with all other words of length "total - i"
.SelectMany(word => wordsByLength[requestedLength - i].Select(otherWord => new WordCombination(word, otherWord)))
// verify that combination is in the list
.Where(combination => wordsOfRequestedLength.Contains(combination) )
)
// materialize the results
.ToList();
stopwatch.Stop();
Console.WriteLine("Combinations: " + combinations.Count);
Console.WriteLine("Time taken: " + stopwatch.ElapsedMilliseconds + "ms");
Console.WriteLine("Press [enter] to see all combinations");
Console.ReadLine();
Console.WriteLine(string.Join(Environment.NewLine, combinations));
Console.ReadLine();
}
private static IEnumerable<IWord> ReadWords() {
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "Wordlist.wordlist.txt";
using (var stream = assembly.GetManifestResourceStream(resourceName)) {
using (var reader = new StreamReader(stream, Encoding.UTF8)) {
string line;
while ((line = reader.ReadLine()) != null) {
yield return new Word(line);
}
}
}
}
}
}
namespace Wordlist {
public interface IWord {
string Content { get; }
int Length { get; }
}
}
namespace Wordlist {
public class Word : IWord {
public string Content { get; }
public int Length { get; }
public Word(string content) {
Content = content;
Length = content.Length;
}
}
}
namespace Wordlist {
public class WordCombination : IWord {
private IWord Left { get; }
private IWord Right { get; }
public int Length { get; }
public string Content { get; }
public WordCombination(IWord left, IWord right) {
Left = left;
Right = right;
Content = left.Content + right.Content;
Length = Content.Length;
}
public override string ToString() {
return $"{Left.Content} + {Right.Content} = {Content}";
}
}
}
using System;
using System.Collections.Generic;
namespace Wordlist {
public class WordEqualityComparer : IEqualityComparer<IWord> {
public bool Equals(IWord x, IWord y) {
return x.Length == y.Length && string.Equals(x.Content, y.Content, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(IWord word) {
return word.Content.GetHashCode();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment