\documentclass[a4paper]{article} \usepackage[utf8]{inputenc} \usepackage{amsthm,amsmath,amsfonts, amssymb} \usepackage[english,russian]{babel} \usepackage{concrete} \usepackage{enumerate} \usepackage{euler} \usepackage{fullpage} \pagestyle{empty} \selectlanguage{russian} \begin{document} \selectlanguage{russian} %1% \end{document}
\hfill %1% $2013$ \hfill %2% \section*{ } \begin{enumerate} \item $$ \varphi = %3%: $$ \begin{enumerate}[(i)] \item ; \item $\varphi$ ; \item $\varphi$ ; \item $[\ast]$ $\varphi$ $x\mid y = \lnot(x\land y)$. \end{enumerate} \pagebreak
class Globals { public: size_t TypesNo; size_t VarType; vector<string> TypesLatex; vector<size_t> TypesArity; boost::random::uniform_int_distribution<> RandomNodeType; boost::random::uniform_int_distribution<> RandomNodeNoVar; boost::random::uniform_int_distribution<> RandomNodeBinary; size_t VarsNo; vector<string> VarNames; boost::random::uniform_int_distribution<> RandomVarType; size_t current_varnum; Globals(size_t types_num, vector<string> types_latex, vector<size_t> types_arity, size_t var_num, vector<string> var_names) : TypesNo(types_num), VarType(types_num - 1), TypesLatex(types_latex), TypesArity(types_arity), RandomNodeType(0, types_num - 1), RandomNodeNoVar(0, types_num - 2), RandomNodeBinary(0, types_num - 3), VarsNo(var_num), VarNames(var_names), RandomVarType(0, var_num - 1), current_varnum(var_num - 1) {} size_t get_next_var() { current_varnum++; if (current_varnum == VarsNo) current_varnum = 0; return current_varnum; } }; Globals GBoolean(7, { "\\land", "\\lor", "\\rightarrow", "\\oplus", "\\equiv", "\\lnot", "\\var" }, { 2, 2, 2, 2, 2, 1, 0 }, 4, { "x", "y", "z", "t" });
Globals GSet(5, { "\\cap", "\\cup", "\\triangle", "\\overline", "\\var" }, { 2, 2, 2, 1, 0 }, 3, { "A", "B", "C" });
class BNode { public: Globals *glob; size_t type; size_t varnum; BNode * left; BNode * right; BNode(Globals *g, size_t t, bool must_be_leaf = false, bool must_not_be_leaf = false, bool must_be_binary = false) : glob(g), type(t), left(NULL), right(NULL) { if (t == g->TypesNo) { // this means we want a random node type = must_be_leaf ? g->VarType : (must_be_binary ? g->RandomNodeBinary(gen) : (must_not_be_leaf ? g->RandomNodeNoVar(gen) : g->RandomNodeType(gen) )); } varnum = (type == g->VarType) ? g->get_next_var() : 0; } ~BNode() { if (left != NULL) delete left; if (right != NULL) delete right; } };
string TypeString() const { if (type == glob->VarType) return glob->VarNames[varnum]; return glob->TypesLatex[type]; } string ToString() const { if (glob->TypesArity[type] == 0) return TypeString(); if (glob->TypesArity[type] == 1) return TypeString() + "{" + left->ToString() + "}"; return "(" + left->ToString() + " " + TypeString() + " " + right->ToString() + ")"; }
bool get_truth_value(const vector<bool> & vals) { switch(type) { case 0: return left->get_truth_value(vals) && right->get_truth_value(vals); break; case 1: return left->get_truth_value(vals) || right->get_truth_value(vals); break; case 2: return (!left->get_truth_value(vals)) || right->get_truth_value(vals); break; case 3: return left->get_truth_value(vals) != right->get_truth_value(vals); break; case 4: return left->get_truth_value(vals) == right->get_truth_value(vals); break; case 5: return !left->get_truth_value(vals); break; case 6: return vals[varnum]; break; default: return false; break; } }
BNode *generate_tree(Globals & g, size_t min_depth, size_t max_depth, bool must_be_binary = false) { if (max_depth == 0) return NULL; BNode *node = new BNode(&g, g.TypesNo, max_depth == 1, min_depth > 0, must_be_binary); if (g.TypesArity[node->type] == 1) { node->left = generate_tree(g, min_depth, max_depth, true); } if (g.TypesArity[node->type] == 2) { node->left = generate_tree(g, min_depth - 1, max_depth - 1); node->right = generate_tree(g, min_depth - 1, max_depth - 1); } return node; }
void process_one_student_file_boolean(string dir, string fname, boost::format & general_tmpl, boost::format & problem_tmpl, boost::format & solution_tmpl) { BNode *node_bool; ostringstream s; vector<string> students = readAllLinesFromFile(dir + "/" + fname + ".txt"); cout << "\t " << fname << endl; for (size_t i=0; i<students.size(); ++i) { if (students[i].size() == 0) continue; // empty line cout << "\t\t[ " << students[i] << " ]" << endl; node_bool = generate_tree(GBoolean, 2, 4); string group_string = "$" + fname + "$"; s << problem_tmpl % students[i] % group_string % node_bool->ToString(); delete node_bool; } ofstream ofs(dir + "/" + fname + ".tex"); ofs << general_tmpl % s.str() << endl; ofs.close(); }
string students_dir = "2013"; vector<string> students_files = { "BoTR" }; int main(int argc, char *argv[]) { boost::format boolean_tpml( read_file_as_string("boolean_problem_minimal.tex") ); boost::format general_tmpl( read_file_as_string("general_template.tex") ); for (size_t i = 0; i < students_files.size(); ++i) { process_one_student_file_boolean(students_dir, students_files[i], general_tmpl, boolean_tpml); } return 0; }
void depth_first(function<void (const BNode * n)> do_with_node) { do_with_node(this); if (left != NULL) left->depth_first(do_with_node); if (right != NULL) right->depth_first(do_with_node); }
bool sanity_check(BNode * node) { vector<bool> vars_present(node->glob->VarsNo, false); vector<bool> connectors_present(node->glob->TypesNo, false); node->depth_first([&] (const BNode * n) { if (n->type == n->glob->VarType) { vars_present[ n->varnum ] = true; } else { connectors_present[ n->type ] = true; } }); return all_of( vars_present.begin(), vars_present.end(), [](bool b) {return b;} ) && (accumulate(connectors_present.begin(), connectors_present.end(), 0) > 2); }
{\footnotesize \subsection*{%1%, %2%} $%3%$: $$ %4% $$ } \pagebreak
bool increment_counter(vector<bool> & v) { for (int i=v.size()-1; i>=0; --i) { if (!v[i]) { v[i] = true; for (size_t j=i+1; j<v.size(); ++j) v[j] = false; return true; } } return false; } string latex_truthtable() { ostringstream os; vector<bool> counter(glob->VarsNo, false); os << "\\begin{array}{"; for(size_t i=0; i<counter.size(); ++i) os << 'c'; os << "|c}\n"; for(size_t i=0; i<counter.size(); ++i) os << glob->VarNames[i] << " & "; os << " \\\\\\hline\n"; do { for(size_t i=0; i<counter.size(); ++i) os << counter[i] << " & "; os << get_truth_value(counter) << "\\\\\n"; } while (increment_counter(counter)); os << "\\end{array}\n"; return os.str(); }
void process_one_student_file_boolean(string dir, string fname, boost::format & general_tmpl, boost::format & problem_tmpl, boost::format & solution_tmpl) { BNode *node_bool; ostringstream s, ssolution; vector<string> students = readAllLinesFromFile(dir + "/" + fname + ".txt"); cout << "\t " << fname << endl; for (size_t i=0; i<students.size(); ++i) { if (students[i].size() == 0) continue; // empty line cout << "\t\t[ " << students[i] << " ]" << endl; do { node_bool = generate_tree(GBoolean, 2, 4); } while (!sanity_check(node_bool)); string group_string = "$" + fname + "$"; s << problem_tmpl % students[i] % group_string % node_bool->ToString(); ssolution << solution_tmpl % students[i] % group_string % node_bool->ToString() % node_bool->latex_truthtable(); delete node_bool; } ofstream ofs; open_for_writing(dir + "/" + fname + ".tex", ofs); ofs << general_tmpl % s.str() << endl; ofs.close(); open_for_writing(dir + "/" + fname + ".sol.tex", ofs); ofs << general_tmpl % ssolution.str() << endl; ofs.close(); } string students_dir = "2013"; vector<string> students_files = { "BoTR" }; int main(int argc, char *argv[]) { boost::format boolean_tpml( read_file_as_string("boolean_problem_minimal.tex") ); boost::format solution_tpml( read_file_as_string("boolean_solution_minimal.tex") ); boost::format general_tmpl( read_file_as_string("general_template.tex") ); for (size_t i = 0; i < students_files.size(); ++i) { process_one_student_file_boolean(students_dir, students_files[i], general_tmpl, boolean_tpml, solution_tpml); } return 0; }
Source: https://habr.com/ru/post/171279/