Task: 100 prisoners
C#: using System;
using System.Linq;

namespace Prisoners {
    class Program {
        static bool PlayOptimal() {
            var secrets = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

            for (int p = 0; p < 100; p++) {
                bool success = false;

                var choice = p;
                for (int i = 0; i < 50; i++) {
                    if (secrets[choice] == p) {
                        success = true;
                        break;
                    }
                    choice = secrets[choice];
                }

                if (!success) {
                    return false;
                }
            }

            return true;
        }

        static bool PlayRandom() {
            var secrets = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

            for (int p = 0; p < 100; p++) {
                var choices = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

                bool success = false;
                for (int i = 0; i < 50; i++) {
                    if (choices[i] == p) {
                        success = true;
                        break;
                    }
                }

                if (!success) {
                    return false;
                }
            }

            return true;
        }

        static double Exec(uint n, Func<bool> play) {
            uint success = 0;
            for (uint i = 0; i < n; i++) {
                if (play()) {
                    success++;
                }
            }
            return 100.0 * success / n;
        }

        static void Main() {
            const uint N = 1_000_000;
            Console.WriteLine("# of executions: {0}", N);
            Console.WriteLine("Optimal play success rate: {0:0.00000000000}%", Exec(N, PlayOptimal));
            Console.WriteLine(" Random play success rate: {0:0.00000000000}%", Exec(N, PlayRandom));
        }
    }
}

Java: import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {
    private static boolean playOptimal(int n) {
        List<Integer> secretList = IntStream.range(0, n).boxed().collect(Collectors.toList());
        Collections.shuffle(secretList);

        prisoner:
        for (int i = 0; i < secretList.size(); ++i) {
            int prev = i;
            for (int j = 0; j < secretList.size() / 2; ++j) {
                if (secretList.get(prev) == i) {
                    continue prisoner;
                }
                prev = secretList.get(prev);
            }
            return false;
        }
        return true;
    }

    private static boolean playRandom(int n) {
        List<Integer> secretList = IntStream.range(0, n).boxed().collect(Collectors.toList());
        Collections.shuffle(secretList);

        prisoner:
        for (Integer i : secretList) {
            List<Integer> trialList = IntStream.range(0, n).boxed().collect(Collectors.toList());
            Collections.shuffle(trialList);

            for (int j = 0; j < trialList.size() / 2; ++j) {
                if (Objects.equals(trialList.get(j), i)) {
                    continue prisoner;
                }
            }

            return false;
        }
        return true;
    }

    private static double exec(int n, int p, Function<Integer, Boolean> play) {
        int succ = 0;
        for (int i = 0; i < n; ++i) {
            if (play.apply(p)) {
                succ++;
            }
        }
        return (succ * 100.0) / n;
    }

    public static void main(String[] args) {
        final int n = 100_000;
        final int p = 100;
        System.out.printf("# of executions: %d\n", n);
        System.out.printf("Optimal play success rate: %f%%\n", exec(n, p, Main::playOptimal));
        System.out.printf("Random play success rate: %f%%\n", exec(n, p, Main::playRandom));
    }
}