using System; using System.Collections.Generic; using System.Threading; namespace A323183 { /// /// Cf. http://tilings.math.uni-bielefeld.de/substitution/equithirds/ /// class Program { static void Main(string[] args) { Point[] abc = new Point[3]; for (int i = 0; i < abc.Length; i++) { abc[i] = new Point() { Border = true }; } int depth = Depth; if (args.Length == 1) { depth = int.Parse(args[0]); } Blue(depth, abc[0], abc[1], abc[2]); foreach (Point near in Point.Center.Neighbors) { if (near.Neighbors.Count == 4) { Compute(near); break; } } } const double Radius = 100000; const int Depth = 10; static void Compute(Point p) { HashSet generation = new HashSet(); generation.Add(p); p.Visited = true; for (int g = 0; ; g++) { HashSet newGeneration = new HashSet(); foreach (Point current in generation) { if (current.Border) { return; } foreach (Point neighbor in current.Neighbors) { if (!neighbor.Visited) { neighbor.Visited = true; newGeneration.Add(neighbor); } } } Console.WriteLine("{0} {1}", g, generation.Count); generation = newGeneration; } } static void Blue(int depth, Point a, Point b, Point c) { if (depth-- > 0) { Point m = Point.Middle(a, b, c); Yellow(depth, m, a, b); Yellow(depth, m, b, c); Yellow(depth, m, c, a); } else { Triangle("blue", a, b, c); } } static void Yellow(int depth, Point a, Point b, Point c) { if (depth-- > 0) { Point bb = b.AtThirdDistance(c); Point cc = c.AtThirdDistance(b); Yellow(depth, bb, a, b); Yellow(depth, cc, a, c); Blue(depth, a, bb, cc); } else { Triangle("LemonChiffon", a, b, c); } } static void Triangle(string color, Point a, Point b, Point c) { a.Join(b); b.Join(c); c.Join(a); } } class Point { public Point() { this.Index = Interlocked.Increment(ref Counter); this.Neighbors = new HashSet(); this.atThirdNeighbors = new Dictionary(); } public bool Visited { get; set; } public bool Border { get; set; } public long Index { get; private set; } public HashSet Neighbors { get; private set; } public static Point Middle(Point a, Point b, Point c) { Point middle = new Point(); if (Center == null) { Center = middle; } return middle; } public static Point Center { get; private set; } public Point AtThirdDistance(Point other) { Point atThird = null; if (!this.atThirdNeighbors.TryGetValue(other, out atThird)) { this.atThirdNeighbors[other] = atThird = new Point() { Border = this.Border & other.Border }; } return atThird; } public void Join(Point other) { this.Neighbors.Add(other); other.Neighbors.Add(this); } public override int GetHashCode() { return (int)this.Index ^ (int)(this.Index >> 32); } public override bool Equals(object obj) { Point other = obj as Point; if (other == null) { return false; } else { return this.Index == other.Index; } } private Dictionary atThirdNeighbors; private static long Counter = 0; } }