public PixelGroup Normalize() { var offset = new Position(Pixels.Min(p => p.Position.X), Pixels.Min(p => p.Position.Y)); var newPixels = Pixels.Select(p => new Pixel(p.Fill, p.Position - offset)).ToArray(); var retval = new PixelGroup(newPixels); return(retval); }
public PixelGroup Rotate(int times) { if (times == 0) { return(this); } var newPixels = Pixels.Select(p => new Pixel(p.Fill, p.Position.Rotate(times))).ToArray(); var retval = new PixelGroup(newPixels).Normalize(); return(retval); }
static void Main(string[] args) { var rules = new List <(PixelGroup Source, PixelGroup Target)>(); #if DEBUG foreach (var line in File.ReadAllLines(@"..\..\input.txt")) #else string line; while (!string.IsNullOrEmpty(line = Console.ReadLine())) #endif { var parts = line.Split(new[] { "=>" }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim().Split('/')) .Select(PixelGroup.FromPattern) .ToArray(); rules.Add((parts[0], parts[1])); } foreach (var rule in rules) { var length = rule.Source.SideLength; Console.Out.WriteLine($"{length}\t{rule.Source.CountOn}\t{rule.Target.CountOn}"); } var pattern = new[] { ".#.", "..#", "###" }; var pic = PixelGroup.FromPattern(pattern); var sw = Stopwatch.StartNew(); var ruleCache = new ConcurrentDictionary <PixelGroup, (PixelGroup Source, PixelGroup Target)>(); for (int it = 0; it < 18; it++) { var sideLength = pic.SideLength; var side = new[] { 2, 3 }.First(i => sideLength % i == 0); var split = pic.Split(side); var output = split.Select(p => (p.Position, ruleCache.GetOrAdd(p.Segment, p1 => rules.First(r => p1.Match(r.Source))).Target)).ToArray(); pic = PixelGroup.Combine(output); Console.Out.WriteLine($"{it}, {pic.SideLength}"); } Console.Out.WriteLine(pic.CountOn); sw.Stop(); Console.Out.WriteLine(sw.Elapsed); }