Tags: algo 

Rating:

Let's approach this problem by modelling each hacker and the flow of their virus as a node and an edge respectively in a directed graph. Knowing that each hacker can transmit their virus to only one other hacker, the number of possible graph structures is only three. One of them is shown below.

![](data:image/png;base64,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)

Here, the nodes 3, 4, 5, and 6 are in a "deadlock", and any virus transmitted by one of these nodes pass through that node again. To find cycles like this, the idea is simple: Start at any node and keep traversing along the node it points to, adding each node to an array, say, visited. If at any point, the next node is already in visited, then we have detected a cycle beginning and ending at that node.

To keep track of the nodes that are in a cycle, we'll need two sets, say, good_nodes and deadlocked_nodes, to store the nodes not in a cycle and the nodes in a cycle respectively. We'll then split visited at the node that starts the cycle: Every node to the left of the split goes in to good_nodes and every node to the right of the split (inclusive) goes in to deadlocked_nodes. In our example, by the time we have traversed 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 3, we will see that node 3 is already in visited, so we split at node 3, so that good_nodes will be {1, 2} and deadlocked_nodes will be {3, 4, 5, 6}.

The other structures could be the following.

![](https://gov-ind.github.io/static/media/fig6.ebf517d75a8b6b133e47.png)
![](https://gov-ind.github.io/static/media/fig7.4a89d9c5f6d281ccbb98.png)

Here, node 10 points to a node that is either not in a cycle (ie., in good_nodes) or in one (ie., in deadlocked_nodes). In either case, it is easy to see that the nodes from 7 through to 10 will not be in a cycle. If we ever come across a path like this, we simply add all the visited nodes to good_nodes.

Now that we know the edge cases, it is straightforward to write the following linear-time function to find cycles ([Here's](https://github.com/gov-ind/ctf_solves/raw/main/2022/hsctf/hacking/solve.py) the full solve script).

```
def find_num_deadlocked_nodes(test):
good_nodes = set()
deadlocked_nodes = set()

for idx, target in enumerate(test):
if idx in good_nodes:
good_nodes.add(idx)
continue

visited = [idx]
next_idx = target - 1

while True:
if next_idx in good_nodes or next_idx in deadlocked_nodes:
good_nodes |= set(visited)
break

if next_idx in visited:
good_nodes |= set(visited)

split_idx = visited.index(next_idx)
_deadlocked_nodes = set(visited[split_idx:])

deadlocked_nodes |= _deadlocked_nodes

break

visited.append(next_idx)
next_idx = test[next_idx] - 1

return len(deadlocked_nodes)
```

Original writeup (https://gov-ind.github.io/hsctf_2022).