Initial commit

This commit is contained in:
2026-05-07 03:23:56 +00:00
commit 5e8575f42a
42 changed files with 2330 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
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;
}
}
}