当前位置: 首页 > 工具软件 > calc24 > 使用案例 >

我所见过的最好的计算24的程序

孔鸿云
2023-12-01

本人编写的一个计算24的有趣小程序,可以计算任意多个参数情况下计算任意目标值,如:用{1,7,8,9,10,11,12,13}来计算目标值7,结果是:11 - (1 + 7 + 8 + 9 + 10 + 13) / 12 = 7,计算方法的总入口为calcTarget函数,所以使用该源代码时,需要自己写main函数调用。
程序功能非常强大,以目前我所知道的网络上各种算法来看,本算法是最好的,核心代码其实不多,大多数代码是为了处理细节,比如括号的处理,以最精练的方式处理括号,试试看吧,一定会让你满意。


前言

  本人编写的一个计算24的有趣小程序,可以计算任意多个参数情况下计算任意目标值,如:用{1,7,8,9,10,11,12,13}来计算目标值7,结果是:11 - (1 + 7 + 8 + 9 + 10 + 13) / 12 = 7,计算方法的总入口为calcTarget函数,所以使用该源代码时,需要自己写main函数调用。
  程序功能非常强大,以目前我所知道的网络上各种算法来看,本算法是最好的,核心代码其实不多,大多数代码是为了处理细节,比如括号的处理,以最精练的方式处理括号,试试看吧,一定会让你满意。
  调用举例
  #include "calc24.h"
  int main(int argc, char* argv[])
  {
  		cout << calcTarget(24,{2,3,4,5}) << endl;
  }

1.源代码

代码如下(示例):
c24int.h

#pragma once
#include <string>
using namespace std;

class c24int{
	int a_;
	int b_;
public:
	c24int() :a_(0), b_(1){}
	c24int(int _a) :a_(_a), b_(1){}
	c24int(int _a, int _b) :a_(_a), b_(_b){}
public:
	int a() const{ return a_; }
	int b() const{ return b_; }
public:
	void reduce(){ if(b_ == 0 || b_ == 1)return; int t = a_ / b_; if(a_ == t * b_){ a_ = t; b_ = 1; } }
	bool same(int _v) const{ return a_ == _v && b_ == 1; }
	bool great(int _v) const{ return a_ > _v && b_ == 1; }
	bool great_same(int _v) const{ return a_ >= _v && b_ == 1; }
	bool less(int _v) const{ return a_ < _v&& b_ == 1; }
	bool less_same(int _v) const{ return a_ <= _v && b_ == 1; }
	bool same(const c24int& _v) const{ return a_ * _v.b_ == b_ * _v.a_; }
	bool great(const c24int& _v) const{ return a_ * _v.b_ > b_ * _v.a_; }
	bool great_same(const c24int& _v) const{ return a_ * _v.b_ >= b_ * _v.a_; }
	bool less(const c24int& _v) const{ return a_ * _v.b_ < b_* _v.a_; }
	bool less_same(const c24int& _v) const{ return a_ * _v.b_ <= b_ * _v.a_; }

	double dou() const{ return double(a_) / double(b_); }
	string str() const{ if(b_ == 1)return to_string(a_); return "{" + to_string(a_) + "/" + to_string(b_) + "}"; }
public:
	c24int& operator=(int _v){ a_ = _v, b_ = 1; return *this; }
	c24int& operator=(const c24int& _v){ a_ = _v.a_; b_ = _v.b_; return *this; }
	c24int& operator+=(int _v){ a_ += b_ * _v; return *this; }
	c24int& operator+=(const c24int& _v){
		int t_a = a_ * _v.b_ + b_ * _v.a_;
		b_ = b_ * _v.b_;
		a_ = t_a;
		reduce();
		return *this;
	}

	c24int& operator-=(int _v){ a_ -= b_ * _v; return *this; }
	c24int& operator-=(const c24int& _v){
		int t_a = a_ * _v.b_ - b_ * _v.a_;
		b_ = b_ * _v.b_;
		a_ = t_a;
		reduce();
		return *this;
	}

	c24int& operator*=(int _v){ a_ *= _v; reduce(); return *this; }
	c24int& operator*=(const c24int& _v){
		int t_a = a_ * _v.a_;
		b_ = b_ * _v.b_;
		a_ = t_a;
		reduce();
		return *this;
	}

	c24int& operator/=(int _v){ b_ *= _v; reduce(); return *this; }
	c24int& operator/=(const c24int& _v){
		int t_a = a_ * _v.b_;
		b_ = b_ * _v.a_;
		a_ = t_a;
		reduce();
		return *this;
	}
};

inline bool operator==(const c24int& _x, int _y){ return _x.same(_y); }
inline bool operator==(int _x, const c24int& _y){ return _y.same(_x); }
inline bool operator==(const c24int& _x, const c24int& _y){ return _x.same(_y); }

inline bool operator!=(const c24int& _x, int _y){ return !_x.same(_y); }
inline bool operator!=(int _x, const c24int& _y){ return !_y.same(_x); }
inline bool operator!=(const c24int& _x, const c24int& _y){ return !_x.same(_y); }

inline bool operator>(const c24int& _x, int _y){ return _x.great(_y); }
inline bool operator>(int _x, const c24int& _y){ return !_y.less_same(_x); }
inline bool operator>(const c24int& _x, const c24int& _y){ return _x.great(_y); }

inline bool operator>=(const c24int& _x, int _y){ return _x.great_same(_y); }
inline bool operator>=(int _x, const c24int& _y){ return !_y.less(_x); }
inline bool operator>=(const c24int& _x, const c24int& _y){ return !_y.great_same(_x); }

inline bool operator<(const c24int& _x, int _y){ return _x.less(_y); }
inline bool operator<(int _x, const c24int& _y){ return !_y.great_same(_x); }
inline bool operator<(const c24int& _x, const c24int& _y){ return _x.less(_y); }

inline bool operator<=(const c24int& _x, int _y){ return _x.less_same(_y); }
inline bool operator<=(int _x, const c24int& _y){ return !_y.great(_x); }
inline bool operator<=(const c24int& _x, const c24int& _y){ return !_y.less_same(_x); }

inline c24int operator+(const c24int& _x, int _y){ c24int ret = _x; ret += _y; return ret; }
inline c24int operator+(int _x, const c24int& _y){ c24int ret(_x); ret += _y; return ret; }
inline c24int operator+(const c24int& _x, const c24int& _y){ c24int ret = _x; ret += _y; return ret; }

inline c24int operator-(const c24int& _x, int _y){ c24int ret = _x; ret -= _y; return ret; }
inline c24int operator-(int _x, const c24int& _y){ c24int ret(_x); ret -= _y; return ret; }
inline c24int operator-(const c24int& _x, const c24int& _y){ c24int ret = _x; ret -= _y; return ret; }

inline c24int operator*(const c24int& _x, int _y){ c24int ret = _x; ret *= _y; return ret; }
inline c24int operator*(int _x, const c24int& _y){ c24int ret(_x); ret *= _y; return ret; }
inline c24int operator*(const c24int& _x, const c24int& _y){ c24int ret = _x; ret *= _y; return ret; }

inline c24int operator/(const c24int& _x, int _y){ c24int ret = _x; ret /= _y; return ret; }
inline c24int operator/(int _x, const c24int& _y){ c24int ret(_x); ret /= _y; return ret; }
inline c24int operator/(const c24int& _x, const c24int& _y){ c24int ret = _x; ret /= _y; return ret; }

calc24.h


```cpp
#pragma once
#include "c24int.h"
#include <vector>
#include <iostream>
#include <functional>
#include <set>
using namespace std;

#define OP_ADD 1
#define OP_DEC 2
#define OP_MUL 3
#define OP_DIV 4
#define OP_LEFT true
#define OP_RIGHT false

using result_proc = function<bool(const string& _result)>;
//6, 8, 10, 13, 1, 1, 6, 13, 12, 13
using result_proc = function<bool(const string& _result)>;
bool isSame(double a, double b);

struct c24dat{
	bool isNull_ = true;
	bool isExp_ = false;
	char op_ = 0;
	c24int val_ = 0;
	string exp_ = "";
public:
	bool isNull() const{ return isNull_; }
	c24dat() = default;
	c24dat(int _val) :isNull_(false), val_(_val), exp_(val_.str()){}
	c24dat(const c24int& _val) :isNull_(false), val_(_val), exp_(val_.str()){}
	c24dat clone() const{ return *this; }
	string qexp(char _op, bool _left = true) const;

	c24dat& operator=(int _val){ val_ = _val; isNull_ = false; return *this; }
	string toString() const{
		if(isNull())return "null";
		return exp_ + " = " + val_.str();
	}
};

c24dat operator+(const c24dat& _dat, const c24int& _val);
c24dat operator-(const c24dat& _dat, const c24int& _val);
c24dat operator*(const c24dat& _dat, const c24int& _val);
c24dat operator/(const c24dat& _dat, const c24int& _val);
//
c24dat operator+(const c24int& _val, const c24dat& _dat);
c24dat operator-(const c24int& _val, const c24dat& _dat);
c24dat operator*(const c24int& _val, const c24dat& _dat);
c24dat operator/(const c24int& _val, const c24dat& _dat);
//
c24dat operator+(const c24dat& _val, const c24dat& _dat);
c24dat operator-(const c24dat& _val, const c24dat& _dat);
c24dat operator*(const c24dat& _val, const c24dat& _dat);
c24dat operator/(const c24dat& _val, const c24dat& _dat);

struct c24dats : public vector<c24int>{
public:
	using vector::vector;
public:
	string toString() const{
		string ret;
		for(auto& r : *this){
			if(ret.size() == 0)ret.append(r.str());
			else ret.append(", ").append(r.str());
		}
		return ret;
	}
	c24dats& delIdx(size_t _idx){
		erase(begin() + _idx);
		return *this;
	}
	c24dats clone() const{ return *this; }
};

class calc24{
public:
	c24int target_;
	result_proc resultproc_;
	c24dat result_;
public:
	calc24(const c24int& _target) :target_(_target){}
	bool getResult(const c24dat& _result){result_ = _result;return true;}
public:
	bool calc(const c24dat& _parent, const c24dats& _dats);
};

string calcTarget(const c24int& _target, const c24dats& _dats);

calc24.cpp

#include "calc24.h"
#include <set>

bool isSame(double a, double b)
{
	double r = a - b;
	if(r < 0)r = b - a;
	return r < 0.000000001;
}

string c24dat::qexp(char _op, bool _left) const{
	if(isNull() || exp_ == "" || !isExp_)return exp_;
	if(_op == OP_ADD) return exp_;
	if(_op == OP_DEC){
		if(_left || op_ == OP_MUL || op_ == OP_DIV)return exp_;
		else return "(" + exp_ + ")";
	}
	if(_op == OP_MUL){
		if(op_ == OP_MUL || op_ == OP_DIV)return exp_;
		else return "(" + exp_ + ")";
	} else{
		if(!_left)return "(" + exp_ + ")";
		if(op_ == OP_MUL || op_ == OP_DIV)return exp_;
		return "(" + exp_ + ")";
	}
	return "(" + exp_ + ")";
}

c24dat operator+(const c24dat& _dat, const c24int& _val){
	c24dat ret = _dat;
	ret.val_ += _val;
	ret.exp_ = ret.qexp(OP_ADD, OP_LEFT) + " + " + _val.str();
	ret.op_ = OP_ADD;
	ret.isExp_ = true;
	return ret;
}
c24dat operator-(const c24dat& _dat, const c24int& _val){
	c24dat ret = _dat;
	ret.val_ -= _val;
	ret.exp_ = ret.qexp(OP_DEC, OP_LEFT) + " - " + _val.str();
	ret.op_ = OP_DEC;
	ret.isExp_ = true;
	return ret;
}
c24dat operator*(const c24dat& _dat, const c24int& _val){
	c24dat ret = _dat;
	ret.val_ *= _val;
	ret.exp_ = ret.qexp(OP_MUL, OP_LEFT) + " * " + _val.str();
	ret.op_ = OP_MUL;
	ret.isExp_ = true;
	return ret;
}
c24dat operator/(const c24dat& _dat, const c24int& _val){
	c24dat ret = _dat;
	ret.val_ /= _val;
	ret.exp_ = ret.qexp(OP_DIV, OP_LEFT) + " / " + _val.str();
	ret.op_ = OP_DIV;
	ret.isExp_ = true;
	return ret;
}

//
c24dat operator+(const c24int& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ += _dat.val_;
	ret.exp_ = ret.qexp(OP_ADD, OP_LEFT) + " + " + _dat.qexp(OP_ADD, OP_RIGHT);
	ret.op_ = OP_ADD;
	ret.isExp_ = true;
	return ret;
}
c24dat operator-(const c24int& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ -= _dat.val_;
	ret.exp_ = ret.qexp(OP_DEC, OP_LEFT) + " - " + _dat.qexp(OP_DEC, OP_RIGHT);
	ret.op_ = OP_DEC;
	ret.isExp_ = true;
	return ret;
}
c24dat operator*(const c24int& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ *= _dat.val_;
	ret.exp_ = ret.qexp(OP_MUL, OP_LEFT) + " * " + _dat.qexp(OP_MUL, OP_RIGHT);
	ret.op_ = OP_MUL;
	ret.isExp_ = true;
	return ret;
}
c24dat operator/(const c24int& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ /= _dat.val_;
	ret.exp_ = ret.qexp(OP_DIV, OP_LEFT) + " / " + _dat.qexp(OP_DIV, OP_RIGHT);
	ret.op_ = OP_DIV;
	ret.isExp_ = true;
	return ret;
}

//
c24dat operator+(const c24dat& _val, const c24dat& _dat){
	c24dat ret = _val;
	ret.val_ += _dat.val_;
	ret.exp_ = ret.qexp(OP_ADD, OP_LEFT) + " + " + _dat.qexp(OP_ADD, OP_RIGHT);
	ret.op_ = OP_ADD;
	ret.isExp_ = true;
	return ret;
}
c24dat operator-(const c24dat& _val, const c24dat& _dat){
	c24dat ret = _val;
	ret.val_ -= _dat.val_;
	ret.exp_ = ret.qexp(OP_DEC, OP_LEFT) + " - " + _dat.qexp(OP_DEC, OP_RIGHT);
	ret.op_ = OP_DEC;
	ret.isExp_ = true;
	return ret;
}
c24dat operator*(const c24dat& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ *= _dat.val_;
	ret.exp_ = ret.qexp(OP_MUL, OP_LEFT) + " * " + _dat.qexp(OP_MUL, OP_RIGHT);
	ret.op_ = OP_MUL;
	ret.isExp_ = true;
	return ret;
}
c24dat operator/(const c24dat& _val, const c24dat& _dat){
	c24dat ret(_val);
	ret.val_ /= _dat.val_;
	ret.exp_ = ret.qexp(OP_DIV, OP_LEFT) + " / " + _dat.qexp(OP_DIV, OP_RIGHT);
	ret.op_ = OP_DIV;
	ret.isExp_ = true;
	return ret;
}


bool calc24::calc(const c24dat& _parent, const c24dats& _dats){
	if(_dats.size() == 1){
		if(_parent.isNull()){
			if(_dats[0] == target_)return getResult(_dats[0]);
			return false;
		}
		if(_parent.val_ + _dats[0] == target_)return getResult(_parent + _dats[0]);
		if(_parent.val_ - _dats[0] == target_)return getResult(_parent - _dats[0]);
		if(_dats[0] - _parent.val_ == target_)return getResult(_dats[0] - _parent);
		if(_parent.val_ * _dats[0] == target_)return getResult(_parent * _dats[0]);
		if(_dats[0] != 0 && _parent.val_ / _dats[0] == target_)return getResult(_parent / _dats[0]);
		if(_parent.val_ != 0 && _dats[0] / _parent.val_ == target_)return getResult(_dats[0] / _parent);
		return false;
	}
	//有两个及以上数据
	set<c24int> calced;
	if(_parent.isNull()){
		for(size_t i = 0; i < _dats.size(); i++){
			c24int t = _dats[i];
			if(calced.find(t)!=calced.end())continue;
			if(calc(c24dat{ t }, _dats.clone().delIdx(i)))return true;
			calced.insert(t);
		}
		return false;
	}
	calced.clear();
	for(size_t i = 0; i < _dats.size(); i++){
		c24int t = _dats[i];
		if(calced.find(t) != calced.end())continue;
		c24dats tmp = _dats.clone().delIdx(i);
		if(calc(_parent + t, tmp))return true;
		if(calc(_parent - t, tmp))return true;
		if(calc(_dats[i] - _parent, tmp))return true;
		if(calc(_parent * t, tmp))return true;
		if(t != 0 && calc(_parent / t, tmp))return true;
		if(_parent.val_ != 0 && calc(t / _parent, tmp))return true;
		calced.insert(t);
	}
	calced.clear();
	// a+x=t => x=t-a
	calc24 x_add(target_ - _parent.val_);
	if(x_add.calc(c24dat(), _dats))return getResult(_parent + x_add.result_);
	// a-x=t => x=a-t
	calc24 x_dec(_parent.val_ - target_);
	if(x_dec.calc(c24dat(), _dats))return getResult(_parent - x_dec.result_);
	// x-a=t => x=a+t
	calc24 x_dec2(_parent.val_ + target_);
	if(x_dec2.calc(c24dat(), _dats))return getResult(x_dec2.result_ - _parent);
	// a*x=t => x=t/a
	calc24 x_mult(target_ / _parent.val_);
	if(x_mult.calc(c24dat(), _dats))return getResult(_parent * x_mult.result_);
	// a/x=t => x=a/t
	if(target_ != 0){
		calc24 x_div(_parent.val_ / target_);
		if(x_div.calc(c24dat(), _dats) && x_div.result_.val_ != 0)return getResult(_parent / x_div.result_);
	}
	// x/a=t => x=a*t
	if(_parent.val_ != 0){
		calc24 x_div2(_parent.val_ * target_);
		if(x_div2.calc(c24dat(), _dats))return getResult(x_div2.result_ / _parent);
	}
	return false;
}

//得到以_dats为参数(可以任意多个整数),以_target为目标值的计算方案
string calcTarget(const c24int& _target/*目标值*/, const c24dats& _dats/*计算参数*/){
	calc24 calc(_target);
	if(calc.calc(c24dat(), _dats)){
		//cout << calc.result_.toString() << endl;
		return calc.result_.toString();
	} else{
		//cout << " no solution " << endl;
		string ret = "no solution for: { " + _dats[0].str();
		for(int i=1;i<_dats.size();i++){
			ret.append(", ").append(_dats[i].str());
		}
		ret.append(" } = ").append(_target.str());
		return ret;
	}
}
 类似资料: