Task: Two bullet roulette


C++: #include <array>
#include <iomanip>
#include <iostream>
#include <random>
#include <sstream>

class Roulette {
private:
    std::array<bool, 6> cylinder;

    std::mt19937 gen;
    std::uniform_int_distribution<> distrib;

    int next_int() {
        return distrib(gen);
    }

    void rshift() {
        std::rotate(cylinder.begin(), cylinder.begin() + 1, cylinder.end());
    }

    void unload() {
        std::fill(cylinder.begin(), cylinder.end(), false);
    }

    void load() {
        while (cylinder[0]) {
            rshift();
        }
        cylinder[0] = true;
        rshift();
    }

    void spin() {
        int lim = next_int();
        for (int i = 1; i < lim; i++) {
            rshift();
        }
    }

    bool fire() {
        auto shot = cylinder[0];
        rshift();
        return shot;
    }

public:
    Roulette() {
        std::random_device rd;
        gen = std::mt19937(rd());
        distrib = std::uniform_int_distribution<>(1, 6);

        unload();
    }

    int method(const std::string &s) {
        unload();
        for (auto c : s) {
            switch (c) {
            case 'L':
                load();
                break;
            case 'S':
                spin();
                break;
            case 'F':
                if (fire()) {
                    return 1;
                }
                break;
            }
        }
        return 0;
    }
};

std::string mstring(const std::string &s) {
    std::stringstream ss;
    bool first = true;

    auto append = [&ss, &first](const std::string s) {
        if (first) {
            first = false;
        } else {
            ss << ", ";
        }
        ss << s;
    };

    for (auto c : s) {
        switch (c) {
        case 'L':
            append("load");
            break;
        case 'S':
            append("spin");
            break;
        case 'F':
            append("fire");
            break;
        }
    }

    return ss.str();
}

void test(const std::string &src) {
    const int tests = 100000;
    int sum = 0;

    Roulette r;
    for (int t = 0; t < tests; t++) {
        sum += r.method(src);
    }

    double pc = 100.0 * sum / tests;

    std::cout << std::left << std::setw(40) << mstring(src) << " produces " << pc << "% deaths.\n";
}

int main() {
    test("LSLSFSF");
    test("LSLSFF");
    test("LLSFSF");
    test("LLSFF");

    return 0;
}






Python: 
import numpy as np

class Revolver:
    

    def __init__(self):
        
        self.cylinder = np.array([False] * 6)

    def unload(self):
        
        self.cylinder[:] = False

    def load(self):
        
        while self.cylinder[1]:
            self.cylinder[:] = np.roll(self.cylinder, 1)
        self.cylinder[1] = True

    def spin(self):
        
        self.cylinder[:] = np.roll(self.cylinder, np.random.randint(1, high=7))

    def fire(self):
        
        shot = self.cylinder[0]
        self.cylinder[:] = np.roll(self.cylinder, 1)
        return shot

    def LSLSFSF(self):
        
        self.unload()
        self.load()
        self.spin()
        self.load()
        self.spin()
        if self.fire():
            return True
        self.spin()
        if self.fire():
            return True
        return False

    def LSLSFF(self):
        
        self.unload()
        self.load()
        self.spin()
        self.load()
        self.spin()
        if self.fire():
            return True
        if self.fire():
            return True
        return False

    def LLSFSF(self):
        
        self.unload()
        self.load()
        self.load()
        self.spin()
        if self.fire():
            return True
        self.spin()
        if self.fire():
            return True
        return False

    def LLSFF(self):
        
        self.unload()
        self.load()
        self.load()
        self.spin()
        if self.fire():
            return True
        if self.fire():
            return True
        return False


if __name__ == '__main__':

    REV = Revolver()
    TESTCOUNT = 100000
    for (name, method) in [['load, spin, load, spin, fire, spin, fire', REV.LSLSFSF],
                           ['load, spin, load, spin, fire, fire', REV.LSLSFF],
                           ['load, load, spin, fire, spin, fire', REV.LLSFSF],
                           ['load, load, spin, fire, fire', REV.LLSFF]]:

        percentage = 100 * sum([method() for _ in range(TESTCOUNT)]) / TESTCOUNT
        print("Method", name, "produces", percentage, "per cent deaths.")