diff --git a/src/generator.cpp b/src/generator.cpp
index 97d2e2f12b39d1a05e6ed0831fafc5d273f37017..d2e6d101afb1422178390497fd87338ba71a8fcc 100644
--- a/src/generator.cpp
+++ b/src/generator.cpp
@@ -11,10 +11,12 @@
 using namespace std;
 
 static const char USAGE[] =
-    R"(Random Mealy machine generator
+R"(Random Mealy machine generator
 
     Usage:
       generator random [-mc] <states> <inputs> <outputs> <machines> [<seed>]
+      generator hopcroft a <states>
+      generator hopcroft b <states>
 
     Options:
       -h, --help       Show this screen
@@ -51,8 +53,8 @@ static mealy generate_random_machine(size_t N, size_t P, size_t Q, mt19937 & gen
 	return m;
 }
 
-static void print_machine(mealy const & m, size_t count) {
-	ofstream file("machine_" + to_string(m.graph_size) + "_" + to_string(m.input_size) + "_"
+static void print_machine(string const & prefix, mealy const & m, size_t count) {
+	ofstream file(prefix + "_" + to_string(m.graph_size) + "_" + to_string(m.input_size) + "_"
 	              + to_string(m.output_size) + "_" + to_string(count) + ".txt");
 	for (state s = 0; s < m.graph_size; ++s) {
 		for (input i = 0; i < m.input_size; ++i) {
@@ -64,38 +66,73 @@ static void print_machine(mealy const & m, size_t count) {
 
 int main(int argc, char * argv[]) {
 	const auto args = docopt::docopt(USAGE, {argv + 1, argv + argc}, true, __DATE__ __TIME__);
-	for (auto const & arg : args) {
-		std::cout << arg.first << arg.second << std::endl;
-	}
 
-	auto gen = [&] {
-		if (args.at("<seed>")) {
-			auto seed = args.at("<seed>").asLong();
-			return mt19937(seed);
+	if (args.at("random").asBool()) {
+		auto gen = [&] {
+			if (args.at("<seed>")) {
+				auto seed = args.at("<seed>").asLong();
+				return mt19937(seed);
+			}
+			random_device rd;
+			return mt19937(rd());
+		}();
+
+		size_t number_of_machines = args.at("<machines>").asLong();
+		size_t constructed = 0;
+
+		while (constructed < number_of_machines) {
+			auto const m = generate_random_machine(args.at("<states>").asLong(),
+			                                       args.at("<inputs>").asLong(),
+			                                       args.at("<outputs>").asLong(), gen);
+
+			if (args.at("--connected").asBool()) {
+				auto const m2 = reachable_submachine(m, 0);
+				if (m2.graph_size != m.graph_size) continue;
+			}
+
+			if (args.at("--minimal").asBool()) {
+				auto const tree = create_splitting_tree(m, min_hopcroft_style, 0).root;
+				if (number_of_leaves(tree) != m.graph_size) continue;
+			}
+
+			constructed++;
+			print_machine("machine", m, constructed);
 		}
-		random_device rd;
-		return mt19937(rd());
-	}();
-
-	size_t number_of_machines = args.at("<machines>").asLong();
-	size_t constructed = 0;
+	} else if (args.at("hopcroft").asBool() && args.at("a").asBool()) {
+		mealy m;
 
-	while (constructed < number_of_machines) {
-		auto const m
-		    = generate_random_machine(args.at("<states>").asLong(), args.at("<inputs>").asLong(),
-		                              args.at("<outputs>").asLong(), gen);
+		m.graph_size = args.at("<states>").asLong();
+		m.input_size = m.output_size = 2;
+		m.graph.assign(m.graph_size, vector<mealy::edge>(m.input_size));
 
-		if (args.at("--connected").asBool()) {
-			auto const m2 = reachable_submachine(m, 0);
-			if (m2.graph_size != m.graph_size) continue;
+		for (state s = 0; s < m.graph_size; ++s) {
+			m.graph[s][0] = mealy::edge(s + 1, 0);
+			m.graph[s][1] = mealy::edge(s, 0);
 		}
 
-		if (args.at("--minimal").asBool()) {
-			auto const tree = create_splitting_tree(m, min_hopcroft_style, 0).root;
-			if (number_of_leaves(tree) != m.graph_size) continue;
+		// "accepting state"
+		m.graph[m.graph_size - 1][0] = mealy::edge(m.graph_size - 1, 1);
+		m.graph[m.graph_size - 1][1] = mealy::edge(m.graph_size - 1, 1);
+
+		print_machine("hopcroft_a", m, 1);
+	} else if (args.at("hopcroft").asBool() && args.at("b").asBool()) {
+		// In the original paper, the machine is not well defined...
+		// So I don't know what Hopcroft had in mind exactly...
+		mealy m;
+
+		auto n = m.graph_size = args.at("<states>").asLong();
+		m.input_size = m.output_size = 2;
+		m.graph.assign(m.graph_size, vector<mealy::edge>(m.input_size));
+
+		for (state s = 0; s < n; ++s) {
+			m.graph[s][0] = mealy::edge(s ? s - 1 : 0, s < n / 2 ? 0 : 1);
+			if (s < n / 2) {
+				m.graph[s][1] = mealy::edge(2 * s + 1, 0);
+			} else {
+				m.graph[s][1] = mealy::edge(s + (n - s) / 2, 0);
+			}
 		}
 
-		constructed++;
-		print_machine(m, constructed);
+		print_machine("hopcroft_b", m, 1);
 	}
 }