static void Main() { string[] input = Console.ReadLine().Split(' '); //int nodes = int.Parse(input[0]); int streets = int.Parse(input[1]); //int hospitals = int.Parse(input[2]); string[] hospitalIds = Console.ReadLine().Split(' '); Dictionary<int, Node> allNodes = new Dictionary<int, Node>(); for (int i = 0; i < streets; i++) { input = Console.ReadLine().Split(' '); int firstNodeId = int.Parse(input[0]); int secondNodeId = int.Parse(input[1]); int distance = int.Parse(input[2]); allNodes.AddSafe(firstNodeId, new Node(firstNodeId)); allNodes.AddSafe(secondNodeId, new Node(secondNodeId)); var firstNode = allNodes[firstNodeId]; var secondNode = allNodes[secondNodeId]; firstNode.Connections.Add(new Connection(secondNode, distance)); secondNode.Connections.Add(new Connection(firstNode, distance)); } int result = int.MaxValue; foreach (string id in hospitalIds) { var hospitalNode = allNodes[int.Parse(id)]; hospitalNode.IsHospital = true; } foreach (string id in hospitalIds) { var startNode = allNodes[int.Parse(id)]; Solve(allNodes, startNode); int tempSum = 0; foreach (var node in allNodes) { if (!node.Value.IsHospital) { tempSum += node.Value.Distance; } } if (tempSum < result) { result = tempSum; } } Console.WriteLine(result); }
/// <summary>Returns a list of child processes of this process.</summary> /// <param name="process">The process to return the children of.</param> /// <param name="recursive">If true, all the children's children are included recursively. If false, only direct children are included.</param> public static List<int> ChildProcessIds(this Process process, bool recursive) { Dictionary<int, List<int>> tree = new Dictionary<int, List<int>>(); foreach (var pair in ParentChildProcessIds()) tree.AddSafe(pair.Item1, pair.Item2); if (!recursive) { if (tree.ContainsKey(process.Id)) return tree[process.Id]; else return new List<int>(); } else { List<int> children = new List<int>(); Queue<int> todo = new Queue<int>(); todo.Enqueue(process.Id); while (todo.Count > 0) { int id = todo.Dequeue(); if (tree.ContainsKey(id)) foreach (int child_id in tree[id]) { children.Add(child_id); todo.Enqueue(child_id); } } return children; } }
static void Main() { #if DEBUG Console.SetIn(new System.IO.StreamReader("../../input.txt")); #endif Dictionary<int, Employer> employers = new Dictionary<int, Employer>(); int n = int.Parse(Console.ReadLine()); for (int i = 0; i < n; i++) { employers.AddSafe(i, new Employer(i)); var employer = employers[i]; string input = Console.ReadLine(); for (int j = 0; j < n; j++) { if (input[j] == 'Y') { employers.AddSafe(j, new Employer(j)); var worker = employers[j]; employer.Employers.Add(worker); } } } long sum = 0; for (int i = 0; i < n; i++) { Solve(employers[i]); } foreach (var employer in employers.Values) { sum += employer.Salary; } Console.WriteLine(sum); }
static void Main() { #if DEBUG Console.SetIn(new System.IO.StreamReader("../../input.txt")); #endif Dictionary<int, Node> nodes = new Dictionary<int, Node>(); int n = int.Parse(Console.ReadLine()); for (int i = 0; i < n - 1; i++) { string[] input = Console.ReadLine().Split(new Char[] { '(', ')', '<', '-' }, StringSplitOptions.RemoveEmptyEntries); int parentId = int.Parse(input[0]); int childrenId = int.Parse(input[1]); Node parentNode = new Node(parentId); nodes.AddSafe(parentId, parentNode); parentNode = nodes[parentId]; Node childrenNode = new Node(childrenId); nodes.AddSafe(childrenId, childrenNode); childrenNode = nodes[childrenId]; parentNode.Childrens.Add(childrenNode); childrenNode.Childrens.Add(parentNode); } foreach (var value in nodes.Values) { if (value.Childrens.Count == 1) { visitedIds.Clear(); DFS(value, 0); } } Console.WriteLine(maxSum); }
public static FncFile Parse(string sourceFile) { var sourceText = File.ReadAllText(sourceFile); var boxes = new List<Box>(); // Turn into array of characters var lines = (sourceText.Replace("\r", "") + "\n\n").Split('\n'); var source = new SourceAsChars(lines); if (lines.Length == 0) return new FncFile { Boxes = boxes, Source = source }; var visited = new Dictionary<int, HashSet<int>>(); // Find boxes for (int y = 0; y < source.NumLines; y++) { for (int x = 0; x < source[y].Length; x++) { // Go looking for a box only if this is a top-left corner of a box if (source.TopLine(x, y) != LineType.None || source.LeftLine(x, y) != LineType.None || source.RightLine(x, y) == LineType.None || source.BottomLine(x, y) == LineType.None) continue; if (visited.Contains(x, y)) continue; // Find width of box by walking along top edge var top = source.RightLine(x, y); var index = x + 1; while (index < source[y].Length && source.RightLine(index, y) == top) index++; if (index == source[y].Length || source.BottomLine(index, y) == LineType.None || source.TopLine(index, y) != LineType.None || source.RightLine(index, y) != LineType.None) continue; var width = index - x; // Find height of box by walking along left edge var left = source.BottomLine(x, y); index = y + 1; while (index < source.NumLines && source.BottomLine(x, index) == left) index++; if (index == source.NumLines || source.RightLine(x, index) == LineType.None || source.LeftLine(x, index) != LineType.None || source.BottomLine(x, index) != LineType.None) continue; var height = index - y; // Verify the bottom edge var bottom = source.RightLine(x, y + height); index = x + 1; while (index < source[y].Length && source.RightLine(index, y + height) == bottom) index++; if (index == source[y].Length || source.TopLine(index, y + height) == LineType.None || source.BottomLine(index, y + height) != LineType.None || source.RightLine(index, y + height) != LineType.None) continue; if (index - x != width) continue; // Verify the right edge var right = source.BottomLine(x + width, y); index = y + 1; while (index < source.NumLines && source.BottomLine(x + width, index) == right) index++; if (index == source.NumLines || source.LeftLine(x + width, index) == LineType.None || source.RightLine(x + width, index) != LineType.None || source.BottomLine(x + width, index) != LineType.None) continue; if (index - y != height) continue; // If all edges are single lines, this is not a box if (top == LineType.Single && right == LineType.Single && bottom == LineType.Single && left == LineType.Single) continue; for (int xx = 0; xx <= width; xx++) { visited.AddSafe(x + xx, y); visited.AddSafe(x + xx, y + height); } for (int yy = 0; yy <= height; yy++) { visited.AddSafe(x, y + yy); visited.AddSafe(x + width, y + yy); } boxes.Add(new Box { X = x, Y = y, Width = width, Height = height, LineTypes = Helpers.MakeDictionary(top, right, bottom, left) }); } } // Determine the location of text lines within every box foreach (var box in boxes) { var curTextLines = new HashSet<TextLine>(); for (int by = 1; by < box.Height; by++) { var y = box.Y + by; TextLine curTextLine = null; var curLineText = new StringBuilder(); for (int bx = 1; bx < box.Width; bx++) { var x = box.X + bx; if (source.AnyLine(x, y)) { if (curTextLine != null) { curTextLine.Content = curLineText.ToString(); curTextLines.Add(curTextLine); curTextLine = null; curLineText.Clear(); } } else { if (curTextLine == null) curTextLine = new TextLine { X = x, Y = y }; curLineText.Append(source[y][x]); } } if (curTextLine != null) { curTextLine.Content = curLineText.ToString(); curTextLines.Add(curTextLine); } } // Group text lines by vertical adjacency var textAreas = new List<TextLine[]>(); while (curTextLines.Count > 0) { var first = curTextLines.First(); curTextLines.Remove(first); var curGroup = new List<TextLine> { first }; while (true) { var next = curTextLines.FirstOrDefault(one => curGroup.Any(two => (one.Y == two.Y + 1 || one.Y == two.Y - 1) && one.X + one.Content.Length > two.X && one.X < two.X + two.Content.Length)); if (next == null) break; curGroup.Add(next); curTextLines.Remove(next); } curGroup.Sort(CustomComparer<TextLine>.By(l => l.Y).ThenBy(l => l.X)); textAreas.Add(curGroup.ToArray()); } box.TextAreas = textAreas.ToArray(); } return new FncFile { Boxes = boxes, Source = source }; }
static void Main() { #if DEBUG Console.SetIn(new System.IO.StreamReader("../../input.txt")); #endif Dictionary<string, House> houses = new Dictionary<string, House>(); PriorityQueue<Connection> connections = new PriorityQueue<Connection>(); List<Queue<House>> housePostion = new List<Queue<House>>(); int n = int.Parse(Console.ReadLine()); for (int i = 0; i < n; i++) { string[] input = Console.ReadLine().Split(' '); var house1 = new House(input[0]); var house2 = new House(input[1]); var distance = int.Parse(input[2]); houses.AddSafe(house1.Name, house1); houses.AddSafe(house2.Name, house2); Connection connection = new Connection() { House1 = houses[house1.Name], House2 = houses[house2.Name], Distance = distance }; connections.Enqueue(connection); houses[house1.Name].Connections.Add(connection); houses[house2.Name].Connections.Add(connection); } int index = 0; while (connections.Count > 0) { var connection = connections.Dequeue(); if (connection.House1.Id == int.MaxValue) { var queue = new Queue<House>(); if (connection.House2.Id == int.MaxValue) { connection.House1.Id = index; connection.House2.Id = index; queue.Enqueue(connection.House1); queue.Enqueue(connection.House2); housePostion.Add(queue); index++; } else { connection.House1.Id = connection.House2.Id; housePostion[connection.House2.Id].Enqueue(connection.House1); } } else { if (connection.House1.Id == connection.House2.Id) { connection.IsMinPath = false; continue; } else { if (connection.House2.Id == int.MaxValue) { connection.House2.Id = connection.House1.Id; housePostion[connection.House1.Id].Enqueue(connection.House2); } else { var queue = housePostion[connection.House2.Id]; while (queue.Count > 0) { var h = queue.Dequeue(); h.Id = connection.House1.Id; housePostion[connection.House1.Id].Enqueue(h); } } } } } }
public void TestAddSafe() { // ** // ** void AddSafe<K, V>(this IDictionary<K, List<V>> dic, K key, V value) // ** { Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>((IDictionary<string, List<string>>) null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>((IDictionary<string, List<string>>) null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>((IDictionary<string, HashSet<string>>) null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>((IDictionary<string, HashSet<string>>) null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>(new Dictionary<string, List<string>>(), null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string>(new Dictionary<string, HashSet<string>>(), null, null); }); Assert.DoesNotThrow(() => { CollectionExtensions.AddSafe<string, string>(new Dictionary<string, List<string>>(), "", null); }); Assert.DoesNotThrow(() => { CollectionExtensions.AddSafe<string, string>(new Dictionary<string, HashSet<string>>(), "", null); }); var dicWithList = new Dictionary<string, List<GenericParameter>>(); Assert.AreEqual(0, dicWithList.Count); Assert.Throws<KeyNotFoundException>(() => { var x = dicWithList["someKey"]; }); dicWithList.AddSafe("someKey", new GenericParameter { SomeString = "someValue" }); Assert.AreEqual(1, dicWithList.Count); var xList = dicWithList["someKey"]; Assert.AreEqual(1, xList.Count); dicWithList.AddSafe("someKey", new GenericParameter { SomeString = "someOtherValue" }); Assert.AreEqual(1, dicWithList.Count); Assert.AreEqual(2, xList.Count); Assert.IsTrue(xList.Select(g => g.SomeString).SequenceEqual(new string[] { "someValue", "someOtherValue" })); var dicWithHash = new Dictionary<string, HashSet<GenericParameter>>(); Assert.AreEqual(0, dicWithHash.Count); Assert.Throws<KeyNotFoundException>(() => { var x = dicWithHash["someKey"]; }); dicWithHash.AddSafe("someKey", new GenericParameter { SomeString = "someValue" }); Assert.AreEqual(1, dicWithHash.Count); var xHash = dicWithHash["someKey"]; Assert.AreEqual(1, xHash.Count); dicWithHash.AddSafe("someKey", new GenericParameter { SomeString = "someOtherValue" }); Assert.AreEqual(1, dicWithHash.Count); Assert.AreEqual(2, xHash.Count); Assert.IsTrue(xHash.Select(g => g.SomeString).OrderBy(e => e).SequenceEqual(new string[] { "someOtherValue", "someValue" })); } // ** // ** void AddSafe<K1, K2, V>(this IDictionary<K1, Dictionary<K2, V>> dic, K1 key1, K2 key2, V value) // ** void RemoveSafe<K1, K2, V>(this IDictionary<K1, Dictionary<K2, V>> dic, K1 key1, K2 key2) // ** { Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(null, null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(null, "", null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(null, null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(null, "", "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), "", null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), null, "", null); }); Assert.DoesNotThrow(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), "", "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(null, null, ""); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(null, "", ""); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.RemoveSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), null, ""); }); Assert.DoesNotThrow(() => { CollectionExtensions.RemoveSafe<string, string, string>(new Dictionary<string, Dictionary<string, string>>(), "", ""); }); var dic = new Dictionary<string, Dictionary<string, GenericParameter>>(); Assert.AreEqual(0, dic.Count); Assert.Throws<KeyNotFoundException>(() => { var x = dic["someKey"]; }); dic.AddSafe("someKey", "someOtherKey", new GenericParameter { SomeString = "someValue" }); Assert.AreEqual(1, dic.Count); var x2 = dic["someKey"]; Assert.AreEqual(1, x2.Count); var x3 = dic["someKey"]["someOtherKey"]; Assert.AreEqual("someValue", x3.SomeString); dic.AddSafe("someKey", "someOtherKey", new GenericParameter { SomeString = "someOtherValue" }); Assert.AreEqual(1, dic.Count); Assert.AreEqual(1, x2.Count); Assert.AreEqual("someValue", x3.SomeString); var result = dic.RemoveSafe("nonExistentKey", "someOtherKey"); Assert.IsFalse(result); Assert.AreEqual(1, dic.Count); result = dic.RemoveSafe("someKey", "nonExistentKey"); Assert.IsFalse(result); Assert.AreEqual(1, dic.Count); result = dic.RemoveSafe("someKey", "someOtherKey"); Assert.IsTrue(result); Assert.AreEqual(0, dic.Count); } // ** // ** void AddSafe<K1, K2, V>(this IDictionary<K1, Dictionary<K2, List<V>>> dic, K1 key1, K2 key2, V value) // ** { Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>((IDictionary<string, Dictionary<string, List<string>>>) null, null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>((IDictionary<string, Dictionary<string, List<string>>>) null, null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>((IDictionary<string, Dictionary<string, List<string>>>) null, "", null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>((IDictionary<string, Dictionary<string, List<string>>>) null, "", "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, List<string>>>(), null, null, null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, List<string>>>(), null, "", null); }); Assert.Throws<ArgumentNullException>(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, List<string>>>(), "", null, null); }); Assert.DoesNotThrow(() => { CollectionExtensions.AddSafe<string, string, string>(new Dictionary<string, Dictionary<string, List<string>>>(), "", "", null); }); var dic = new Dictionary<string, Dictionary<string, List<GenericParameter>>>(); Assert.AreEqual(0, dic.Count); Assert.Throws<KeyNotFoundException>(() => { var x = dic["someKey"]; }); dic.AddSafe("someKey", "someOtherKey", new GenericParameter { SomeString = "someValue" }); Assert.AreEqual(1, dic.Count); var x2 = dic["someKey"]; Assert.AreEqual(1, x2.Count); var x3 = dic["someKey"]["someOtherKey"]; Assert.AreEqual(1, x3.Count); dic.AddSafe("someKey", "someOtherKey", new GenericParameter { SomeString = "someOtherValue" }); Assert.AreEqual(1, dic.Count); Assert.AreEqual(1, x2.Count); Assert.AreEqual(2, x3.Count); Assert.IsTrue(x3.Select(g => g.SomeString).SequenceEqual(new string[] { "someValue", "someOtherValue" })); } }
private static Dictionary<string, List<CsGenericTypeConstraint>> parseGenericTypeConstraints(TokenJar tok, ref int i) { var ret = new Dictionary<string, List<CsGenericTypeConstraint>>(); while (tok[i].IsIdentifier("where")) { var startIndex = tok[i].StartIndex; i++; string genericParameter; try { genericParameter = tok[i].Identifier(); } catch (ParseException e) { throw new ParseException(e.Message, e.Index, ret, e); } if (ret.ContainsKey(genericParameter)) throw new ParseException("A constraint clause has already been specified for type parameter '{0}'. All of the constraints for a type parameter must be specified in a single where clause.".Fmt(genericParameter), tok[i].StartIndex, ret); i++; if (!tok[i].IsBuiltin(":")) throw new ParseException("':' expected.", tok[i].StartIndex, ret); do { i++; if (tok[i].IsBuiltin("new") && tok.IndexExists(i + 2) && tok[i + 1].IsBuiltin("(") && tok[i + 2].IsBuiltin(")")) { i += 3; ret.AddSafe(genericParameter, new CsGenericTypeConstraintNew { StartIndex = startIndex, EndIndex = tok[i - 1].EndIndex }); } else if (tok[i].IsBuiltin("class")) { ret.AddSafe(genericParameter, new CsGenericTypeConstraintClass { StartIndex = startIndex, EndIndex = tok[i].EndIndex }); i++; } else if (tok[i].IsBuiltin("struct")) { ret.AddSafe(genericParameter, new CsGenericTypeConstraintStruct { StartIndex = startIndex, EndIndex = tok[i].EndIndex }); i++; } else if (tok[i].Type != TokenType.Identifier) throw new ParseException("Generic type constraint ('new()', 'class', 'struct', or type identifier) expected.", tok[i].StartIndex, ret); else { try { var typeName = parseTypeName(tok, ref i, typeIdentifierFlags.AllowKeywords).Item1; ret.AddSafe(genericParameter, new CsGenericTypeConstraintBaseClass { StartIndex = startIndex, EndIndex = tok[i - 1].EndIndex, BaseClass = typeName }); } catch (ParseException e) { if (e.IncompleteResult is CsTypeName) ret.AddSafe(genericParameter, new CsGenericTypeConstraintBaseClass { StartIndex = tok[i].StartIndex, BaseClass = (CsTypeName) e.IncompleteResult }); throw new ParseException(e.Message, e.Index, ret, e); } } } while (tok[i].IsBuiltin(",")); } return ret; }
public override ExecutionEnvironment Compile(string source, string input) { var lines = source.Replace("\r", "").Split('\n'); if (lines.Length == 0) throw new CompileException("Program does not contain any arrows.", 0, 0); var width = lines.Max(line => line.Length); var height = lines.Length; var chars = lines.Select(line => line + new string(' ', width - line.Length)).ToArray(); var forEachArrow = Ut.Lambda((Action<int, int, int, bool, int, char> action) => { int x = 0, y = 0; for (int i = 0; i < source.Length; i++) { var ch = source[i]; if (ch == '\r') continue; else if (ch == '\n') { y++; x = 0; continue; } if (chars[y][x] != ch) throw new CompileException("Internal parse error: This is a bug in the parser.", i, 1); if (ch != ' ') { var p = "↖↑↗→↘↓↙←".IndexOf(ch); var single = true; if (p == -1) { p = "⤡↕⤢↔".IndexOf(ch); single = false; } if (p == -1) throw new CompileException("Invalid character: “{0}”.".Fmt(ch), i, 1); action(x, y, i, single, p, ch); } x++; } }); var followArrow = Ut.Lambda((int ax, int ay, int dx, int dy, Action<int, int> found) => { while (true) { ax += dx; ay += dy; if (ax < 0 || ax >= width || ay < 0 || ay >= height) return false; if (chars[ay][ax] != ' ') { found(ax, ay); return true; } } }); // STEP 1: Determine, for each arrow, which incoming directions have other arrows point at it var pointedToBy = new Dictionary<int, Dictionary<int, List<Tuple<int, int, int>>>>(); forEachArrow((x, y, i, single, p, ch) => { for (int dd = 0; dd < 8; dd++) followArrow(x, y, -_dx[dd], -_dy[dd], (fx, fy) => { if (_darr[dd].Contains(chars[fy][fx])) pointedToBy.AddSafe(x, y, Tuple.Create(fx, fy, (p + 8 - dd) % 8)); }); }); // STEP 2: Translate each arrow into a Node instance with the appropriate Instruction var nodes = Ut.NewArray<Node>(height, width); forEachArrow((x, y, i, single, p, ch) => { var pointedToFrom = (pointedToBy.ContainsKey(x) && pointedToBy[x].ContainsKey(y) ? pointedToBy[x][y].Select(tup => tup.Item3) : Enumerable.Empty<int>()).Order().ToList(); nodes[y][x] = new Node(x, y, i, single ? pointedToFrom.SequenceEqual(_zero) ? Instruction.Zero : pointedToFrom.SequenceEqual(_stdin) ? Instruction.Stdin : pointedToFrom.SequenceEqual(_concat) ? Instruction.Concat : pointedToFrom.SequenceEqual(_inverse) ? Instruction.Inverse : pointedToFrom.SequenceEqual(_noop) ? Instruction.NoOp : pointedToFrom.SequenceEqual(_label) ? Instruction.Label : Ut.Throw<Instruction>(new CompileException("Invalid combination of arrows pointing at arrow.", i, 1)) : // double arrow pointedToFrom.SequenceEqual(_splitter[0]) || pointedToFrom.SequenceEqual(_splitter[1]) ? Instruction.Splitter : pointedToFrom.SequenceEqual(_isZero[0]) || pointedToFrom.SequenceEqual(_isZero[1]) ? Instruction.IsZero : pointedToFrom.SequenceEqual(_isEmpty[0]) || pointedToFrom.SequenceEqual(_isEmpty[1]) ? Instruction.IsEmpty : Ut.Throw<Instruction>(new CompileException("Invalid combination of arrows pointing at arrow.", i, 1))); }); // STEP 3: For each node, determine which other nodes it is pointing to and are pointing to it forEachArrow((x, y, i, single, p, ch) => { var pointedToFrom = (pointedToBy.ContainsKey(x) && pointedToBy[x].ContainsKey(y) ? pointedToBy[x][y] : Enumerable.Empty<Tuple<int, int, int>>()).OrderBy(tup => tup.Item3).ToList(); if (single) { if (!followArrow(x, y, _dx[p], _dy[p], (fx, fy) => { nodes[y][x].PointsTo.Add(nodes[fy][fx]); })) nodes[y][x].PointsTo.Add(null); } else { if (!followArrow(x, y, _dx[p], _dy[p], (fx, fy) => { nodes[y][x].PointsTo.Add(nodes[fy][fx]); })) nodes[y][x].PointsTo.Add(null); if (!followArrow(x, y, -_dx[p], -_dy[p], (fx, fy) => { nodes[y][x].PointsTo.Add(nodes[fy][fx]); })) nodes[y][x].PointsTo.Add(null); var pointedToFrom2 = pointedToFrom.Select(tup => tup.Item3); if (pointedToFrom2.SequenceEqual(_isZero[1]) || pointedToFrom2.SequenceEqual(_isEmpty[1])) nodes[y][x].PointsTo.Reverse(); } nodes[y][x].PointedToBy.AddRange(pointedToFrom.Select(tup => nodes[tup.Item2][tup.Item1])); }); var nodesArr = nodes.SelectMany(row => row.Where(n => n != null)).ToArray(); return new ZiimEnv { Nodes = nodesArr, Threads = nodesArr.Where(n => n.Instruction == Instruction.Zero).Select(n => new Thread { CurrentValue = Bits.Zero, CurrentInstruction = n, Suspended = false }).ToList(), Input = input.ToUtf8().SelectMany(b => Enumerable.Range(0, 8).Select(i => (b & (1 << (7 - i))) != 0)).ToQueue() }; }