public PrisonRepresentation transformRepresentation(int[] A, int[] B, int[] C) { int nbRooms = A.Length + 1; bool[] hasPrisonner = new bool[nbRooms]; bool[] isExit = new bool[nbRooms]; List<int>[] neighbour = new List<int>[nbRooms]; List<int> exitList = new List<int>(); for (int idx = 0; idx < A.Length; ++idx) { if (neighbour[B[idx]] == null) neighbour[B[idx]] = new List<int>(); neighbour[B[idx]].Add(A[idx]); if (neighbour[A[idx]] == null) neighbour[A[idx]] = new List<int>(); neighbour[A[idx]].Add(B[idx]); } for (int room = 0; room < neighbour.Length; ++room) { if (neighbour[room].Count == 1) isExit[room] = true; } for (int idx = 0; idx < C.Length; ++idx) { hasPrisonner[C[idx]] = true; } PrisonRepresentation toret = new PrisonRepresentation { hasPrisonner = hasPrisonner, isExit = isExit, nbRooms = nbRooms, neighbour = neighbour }; return toret; }
public int solution(int[] A, int[] B, int[] C, out PrisonRepresentation? representation, string saveSteps) { representation = null; if (C.Length == 0) return 0; int nbRooms = A.Length + 1; bool[] isPrisonner = new bool[nbRooms]; bool[] isExit = new bool[nbRooms]; List<int>[] neighbour = new List<int>[nbRooms]; for (int idx = 0; idx < nbRooms; ++idx) { neighbour[idx] = new List<int>(); } for (int idx = 0; idx < A.Length; ++idx) { if (A[idx] == B[idx]) continue; neighbour[B[idx]].Add(A[idx]); neighbour[A[idx]].Add(B[idx]); } for (int idx = 0; idx < C.Length; ++idx) { if (neighbour[C[idx]].Count == 1) return -1; isPrisonner[C[idx]] = true; } int nbExits = 0; for (int room = 0; room < neighbour.Length; ++room) { if (neighbour[room].Count == 1) { isExit[room] = true; nbExits++; } } // We delete all links between connected exits: for (int room = 0; room < neighbour.Length; ++room) { if (isExit[room]) { for (int neighbourIdx = neighbour[room].Count - 1; neighbourIdx >= 0; --neighbourIdx) { int neighbourRoom = neighbour[room][neighbourIdx]; if (isExit[neighbourRoom]) { neighbour[room].RemoveAt(neighbourIdx); neighbour[neighbourRoom].Remove(room); } } } } bool hasChanged = true; // to delete int stepCount = 0; while (hasChanged) { hasChanged = false; if (saveSteps != null) { // save file Image pic = GenerateGraph(isPrisonner, neighbour, isExit); pic.Save(Path.Combine(saveSteps, "step " + stepCount.ToString() + ".jpg")); using (File.Create(Path.Combine(saveSteps, "step " + stepCount.ToString() + "-" + nbExits))) ; stepCount++; } for (int room = 0; room < neighbour.Length; ++room) { // we do not move prisoners if (isPrisonner[room]) { continue; } else if (neighbour[room].Count == 0) { // if a room has no neighbours and is an exit we destroy it if (isExit[room]) { isExit[room] = false; nbExits--; hasChanged = true; } continue; } else if (neighbour[room].Count == 1) { int room2 = neighbour[room][0]; if (!isPrisonner[room2]) { // if a room has only 1 path // and is not connected to a prisonner // we can remove it if (isExit[room]) { // if it was an exit we adjust the number of exits // or make the other room an exit if (isExit[room2]) { nbExits--; } else { isExit[room2] = true; for (var room2Id = neighbour[room2].Count-1 ; room2Id >= 0 ; --room2Id ) { var newExitNeighbour = neighbour[room2][room2Id]; if (isExit[newExitNeighbour]) { //exits must not be connected to each other neighbour[room2].RemoveAt(room2Id); neighbour[newExitNeighbour].Remove(room2); } } } isExit[room] = false; } neighbour[room].Clear(); neighbour[room2].Remove(room); hasChanged = true; } } else if (neighbour[room].Count == 2) { int roomLeft = neighbour[room][0]; int roomRight = neighbour[room][1]; if (!isExit[room] || (isExit[roomLeft] && isExit[roomRight]) ) { if (isExit[room]) { isExit[room] = false; nbExits--; } neighbour[room].Clear(); neighbour[roomLeft].Remove(room); neighbour[roomRight].Remove(room); neighbour[roomLeft].Add(roomRight); neighbour[roomRight].Add(roomLeft); hasChanged = true; } } if (!hasChanged && !isExit[room] && !isPrisonner[room]) { // if it is a non special nodes surrounded by only special nodes // of the same type we can remove it int nbNeighbourExits = 0; int nbNeighbourPrisonners = 0; bool allNeighbourExits = true; //bool hasConnectedExit = false; foreach (var neighbourRoom in neighbour[room]) { if (isExit[neighbourRoom]) { nbNeighbourExits++; //hasConnectedExit |= neighbour[neighbourRoom].Count != 0; } } foreach (var neighbourRoom in neighbour[room]) { if (isPrisonner[neighbourRoom]) { nbNeighbourPrisonners++; } } int nbNeighbours = neighbour[room].Count; if (nbNeighbourExits == nbNeighbours || nbNeighbourPrisonners == nbNeighbours) { foreach (var neighbourRoom in neighbour[room]) { neighbour[neighbourRoom].Remove(room); } neighbour[room].Clear(); hasChanged = true; } } } } representation = new PrisonRepresentation { hasPrisonner = isPrisonner, isExit = isExit, nbRooms = nbRooms, neighbour = neighbour }; return nbExits; }