89 lines
3.4 KiB
C#
89 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using GameOfLife.Entities;
|
|
using GameOfLife.IO;
|
|
|
|
namespace GameOfLife
|
|
{
|
|
public class PatternLibrary
|
|
{
|
|
public const int PatternLoadLimit = 100;
|
|
public const int OscillationMaxPeriod = 50;
|
|
|
|
public IReadOnlyList<Tuple<PatternMetadata, Projections>> PatternProjections;
|
|
public IReadOnlyList<Tuple<PatternMetadata, Pattern>> Patterns;
|
|
public IReadOnlyDictionary<Pattern, PatternMetadata> PatternToMetadata;
|
|
|
|
public PatternLibrary()
|
|
{
|
|
Patterns = ExtractPatterns(GetPatternFileLines()).AsReadOnly();
|
|
PatternProjections = ExtractOscillationsAndProjections(Patterns);
|
|
PatternToMetadata = Patterns.ToDictionary(t => t.Item2, t => t.Item1);
|
|
}
|
|
|
|
private static List<Tuple<PatternMetadata, Projections>> ExtractOscillationsAndProjections(IEnumerable<Tuple<PatternMetadata, Pattern>> patterns)
|
|
{
|
|
var results =
|
|
from pattern in patterns.AsParallel()
|
|
let life = new LifeHashSet(pattern.Item2)
|
|
let oscillation = life.FindOscillation(OscillationMaxPeriod)
|
|
let variations = new Projections(oscillation)
|
|
select Tuple.Create(pattern.Item1, variations);
|
|
|
|
return results.ToList();
|
|
}
|
|
|
|
private static List<Tuple<PatternMetadata, Pattern>> ExtractPatterns(IEnumerable<string> fileLines)
|
|
{
|
|
// first line is the header
|
|
var pattern =
|
|
from line in fileLines.Skip(1).Take(PatternLoadLimit)
|
|
select line.Split(',')
|
|
into split
|
|
let name = split[0].Trim()
|
|
let apgCode = split[1].Trim()
|
|
select new ApgcodeDecoder(apgCode, name)
|
|
into decoder
|
|
select Tuple.Create(decoder.Metadata, decoder.Pattern.Normalize());
|
|
|
|
|
|
var extractPatterns = pattern.ToList();
|
|
|
|
// ensure this patterns are all unique
|
|
var duplicates =
|
|
string.Join(", ",
|
|
extractPatterns
|
|
.GroupBy(tuple => tuple)
|
|
.Where(tuples => tuples.Count() > 1)
|
|
.Select(t => t.Key.Item1.Name));
|
|
if (duplicates.Length > 0)
|
|
throw new Exception($"Duplicate patterns: " + duplicates);
|
|
|
|
return extractPatterns;
|
|
}
|
|
|
|
private static IEnumerable<string> GetPatternFileLines()
|
|
{
|
|
var assembly = Assembly.GetExecutingAssembly();
|
|
//Getting names of all embedded resources
|
|
var allResourceNames = assembly.GetManifestResourceNames();
|
|
|
|
var resourceName = allResourceNames.First(n => n.Contains("CommonPatterns.csv"));
|
|
var fileLines = new List<string>();
|
|
using (var stream = assembly.GetManifestResourceStream(resourceName))
|
|
if (stream != null)
|
|
using (var tx = new StreamReader(stream))
|
|
{
|
|
while (!tx.EndOfStream)
|
|
fileLines.Add(tx.ReadLine());
|
|
}
|
|
|
|
return fileLines;
|
|
}
|
|
}
|
|
} |