2 Star 0 Fork 0

Kenneth-Lee-2012 / card24

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
card24.cpp 3.33 KB
一键复制 编辑 原始数据 按行查看 历史
Kenneth Lee 提交于 2022-10-19 11:01 . card24_v2: add another algorithm
// Copyrights by Kenneth Lee, 2022. All Rights Reserved
#include <iostream>
#include <assert.h>
#include "value.hpp"
using namespace std;
static Val target;
static void enumerate_all_splites(ValComp * set);
static void evaluate(ValComp * set) {
assert(set && set->size > 0);
assert(set->ret.state == ValIf::ST_NON); // don't give evaluated node
if (set->size == 1) {
set->ret = set->vals[0];
} else {
if (set->left)
evaluate(set->left);
if (set->right)
evaluate(set->right);
set->evaluate();
}
}
void cal(ValComp *set, ValComp *set1, ValComp *set2, ValComp::OPS op) {
if (debug_level > 0)
cout << "cal: " << *set1 << op << *set2 << endl;
set->merge_op(set1, set2, op);
ValComp *unsolved = find_unsolved_leaf(set->find_root());
if (unsolved)
enumerate_all_splites(unsolved);
else {
// now the tree is solved
ValComp *root = set->find_root();
evaluate(root);
if (debug_level > 0) {
cout << "evaluate" << *root << ": ";
root->show_expr();
cout << " = " << root->ret << endl;
} else if (root->ret == target) {
root->show_expr();
cout << " = " << root->ret << endl;
}
free_tree(root);
}
}
//enumerate all combination of operations
void cal_all(ValComp *set, ValComp *set1, ValComp *set2) {
if (debug_level > 0)
cout << "cal_all " << *set1 << *set2 << endl;
for (int op = ValComp::ADD; op<ValComp::INV_OP; op++)
cal(set->clone_tree(), set1->clone(), set2->clone(), (ValComp::OPS)op);
cal(set->clone_tree(), set2->clone(), set1->clone(), ValComp::SUB);
cal(set->clone_tree(), set2->clone(), set1->clone(), ValComp::DIV);
free_tree(set);
free_tree(set1);
free_tree(set2);
}
// cur: to where set1 have be initialized
static void enumerate_n(ValComp * set, ValComp *set1, int cur) {
if (debug_level > 0)
cout << "enumerate_n(" << *set << ", " << *set1 << ", " << cur << ")" <<endl;
if (set1->size == cur) {
// now we finish set1, we create set2
ValComp *set2 = new ValComp(set, set1);
cal_all(set, set1, set2);
} else {
for (int i = set1->ids[cur-1] + 1; i < set->size; i++) {
// expand the enumeration, we need clone to both set and set1
ValComp * new_set1 = set1->clone();
new_set1->copy_by_id(set, cur, i);
enumerate_n(set->clone_tree(), new_set1, cur+1);
}
// new enumerated set and set1 were cloned, the input ones are not needed
free(set);
free(set1);
}
}
// enumerate the input set into to disjoin set: set1 & set2, compose them with
// an operator.
static void enumerate_all_splites(ValComp * set) {
assert(set->size > 0);
if (debug_level > 0)
cout << "enumerate_all_splites " << *set << endl;
// loop with power of set1, from 1 to half of its power. but for even
// size of set, the last one is exclusive
for (int i = 0; i < (set->size - 1) / 2; i++) {
for (int j = 0; j < set->size; j++) {
ValComp *set1 = new ValComp(i+1);
set1->copy_by_id(set, 0, j);
enumerate_n(set->clone_tree(), set1, 1);
}
}
// if the set is even power, we enumerate only first column to avoid
// redundancy
if (!(set->size % 2)) {
ValComp *set1 = new ValComp(set->size/2);
set1->copy_by_id(set, 0, 0);
enumerate_n(set->clone_tree(), set1, 1);
}
// todo: size == 1 is senselss, we can still add this logic later
free_tree(set);
}
int main(int argc, char *argv[]) {
if (argc < 2)
return -1;
target = argv[1];
enumerate_all_splites(new ValComp(argc, argv));
return 0;
}
C++
1
https://gitee.com/Kenneth-Lee-2012/card24.git
git@gitee.com:Kenneth-Lee-2012/card24.git
Kenneth-Lee-2012
card24
card24
master

搜索帮助